initial commit
This commit is contained in:
9
.editorconfig
Normal file
9
.editorconfig
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
[*.cr]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
trim_trailing_whitespace = true
|
||||||
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
/docs/
|
||||||
|
/lib/
|
||||||
|
/bin/
|
||||||
|
/.shards/
|
||||||
|
*.dwarf
|
||||||
|
|
||||||
|
# Libraries don't need dependency lock
|
||||||
|
# Dependencies will be locked in applications that use them
|
||||||
|
/shard.lock
|
||||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 Tristan Ancelet <tristan.ancelet@acumera.com>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
39
README.md
Normal file
39
README.md
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# logger
|
||||||
|
|
||||||
|
TODO: Write a description here
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
1. Add the dependency to your `shard.yml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
dependencies:
|
||||||
|
logger:
|
||||||
|
github: your-github-user/logger
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Run `shards install`
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```crystal
|
||||||
|
require "logger"
|
||||||
|
```
|
||||||
|
|
||||||
|
TODO: Write usage instructions here
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
TODO: Write development instructions here
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
1. Fork it (<https://github.com/your-github-user/logger/fork>)
|
||||||
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
||||||
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
||||||
|
4. Push to the branch (`git push origin my-new-feature`)
|
||||||
|
5. Create a new Pull Request
|
||||||
|
|
||||||
|
## Contributors
|
||||||
|
|
||||||
|
- [Tristan Ancelet](https://github.com/your-github-user) - creator and maintainer
|
||||||
9
shard.yml
Normal file
9
shard.yml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
name: logger
|
||||||
|
version: 0.1.0
|
||||||
|
|
||||||
|
authors:
|
||||||
|
- Tristan Ancelet <tristan.ancelet@acumera.com>
|
||||||
|
|
||||||
|
crystal: '>= 1.19.1'
|
||||||
|
|
||||||
|
license: MIT
|
||||||
9
spec/logger_spec.cr
Normal file
9
spec/logger_spec.cr
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
require "./spec_helper"
|
||||||
|
|
||||||
|
describe Logger do
|
||||||
|
# TODO: Write tests
|
||||||
|
|
||||||
|
it "works" do
|
||||||
|
false.should eq(true)
|
||||||
|
end
|
||||||
|
end
|
||||||
2
spec/spec_helper.cr
Normal file
2
spec/spec_helper.cr
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
require "spec"
|
||||||
|
require "../src/logger"
|
||||||
114
src/logger.cr
Normal file
114
src/logger.cr
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
require "time"
|
||||||
|
require "colorize"
|
||||||
|
|
||||||
|
module Logger
|
||||||
|
|
||||||
|
annotation LoggerWatcher
|
||||||
|
end
|
||||||
|
|
||||||
|
struct LOG_LEVEL
|
||||||
|
getter value : Int32
|
||||||
|
getter color : Symbol
|
||||||
|
delegate in?, to: @value
|
||||||
|
|
||||||
|
def initialize(@value : Int32, @color : Symbol)
|
||||||
|
end
|
||||||
|
|
||||||
|
{% for op, i in %w[ < > == <= >= ] %}
|
||||||
|
def {{op.id}} (other : LOG_LEVEL)
|
||||||
|
@value {{op.id}} other.value
|
||||||
|
end
|
||||||
|
{% end %}
|
||||||
|
end
|
||||||
|
|
||||||
|
LOG_LEVELS = {
|
||||||
|
DEBUG: LOG_LEVEL.new(value: 0, color: :green),
|
||||||
|
INFO: LOG_LEVEL.new(value: 1, color: :blue),
|
||||||
|
WARN: LOG_LEVEL.new(value: 2, color: :yellow),
|
||||||
|
ERROR: LOG_LEVEL.new(value: 3, color: :red),
|
||||||
|
FATAL: LOG_LEVEL.new(value: 4, color: :red)
|
||||||
|
}
|
||||||
|
|
||||||
|
@@min_level : LOG_LEVEL = LOG_LEVELS[:INFO]
|
||||||
|
@@max_level : LOG_LEVEL = LOG_LEVELS[:FATAL]
|
||||||
|
@@debug : Bool = false
|
||||||
|
|
||||||
|
LOG_MUTEX = ::Mutex.new
|
||||||
|
|
||||||
|
macro generate_log_line(message)
|
||||||
|
{% _def = @def %}
|
||||||
|
{% _class = @type %}
|
||||||
|
{% _type = @type.module? ? "Module" : "Class" %}
|
||||||
|
{% if _class && _class.name.stringify != "Logger" && _def %}
|
||||||
|
"{{_type.id}}({{_class.name.id}})" + " : " + "Method({{_def.name}})" + " : " + {{message}}
|
||||||
|
{% elsif _class && _class.name.stringify != "Logger" %}
|
||||||
|
"{{_type.id}}({{_class.name.id}})" + " : " + {{message}}
|
||||||
|
{% elsif _def %}
|
||||||
|
"Method({{_def.name}})" + " : " + {{message}}
|
||||||
|
{% else %}
|
||||||
|
{{message}}
|
||||||
|
{% end %}
|
||||||
|
end
|
||||||
|
|
||||||
|
macro debug(message)
|
||||||
|
::Logger.log :DEBUG, Logger.generate_log_line({{message}})
|
||||||
|
end
|
||||||
|
|
||||||
|
macro info(message)
|
||||||
|
::Logger.log :INFO, Logger.generate_log_line({{message}})
|
||||||
|
end
|
||||||
|
|
||||||
|
macro error(message)
|
||||||
|
::Logger.log :ERROR, Logger.generate_log_line({{message}})
|
||||||
|
end
|
||||||
|
|
||||||
|
macro warn(message)
|
||||||
|
::Logger.log :WARN, Logger.generate_log_line({{message}})
|
||||||
|
end
|
||||||
|
|
||||||
|
macro fatal(message)
|
||||||
|
::Logger.log :FATAL, Logger.generate_log_line({{message}})
|
||||||
|
end
|
||||||
|
|
||||||
|
{% for level, i in %w[ min max ] %}
|
||||||
|
def self.{{level.id}}=(level : Symbol)
|
||||||
|
synchronize {
|
||||||
|
@@{{level.id}}_level = LOG_LEVELS[level] if LOG_LEVELS.keys.includes? level
|
||||||
|
}
|
||||||
|
Logger.debug "Logger : {{level.id}}= : Minimum log level set to #{level}"
|
||||||
|
end
|
||||||
|
{% end %}
|
||||||
|
|
||||||
|
protected def self.synchronize(&block : -> )
|
||||||
|
LOG_MUTEX.synchronize do
|
||||||
|
yield
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.debug? : Bool
|
||||||
|
LOG_MUTEX.synchronize do
|
||||||
|
@@debug
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.valid?(level : LOG_LEVEL) : Bool
|
||||||
|
level.in?(@@min_level.value..@@max_level.value)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.debug= (state : Bool) : Nil
|
||||||
|
synchronize {
|
||||||
|
@@debug = state
|
||||||
|
}
|
||||||
|
Logger.debug "Debug set to #{state}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.log(level : Symbol, message : String)
|
||||||
|
_level = LOG_LEVELS[level]
|
||||||
|
if valid?(_level) || debug?
|
||||||
|
synchronize {
|
||||||
|
time = Time.local
|
||||||
|
STDERR.puts [time, level.to_s.colorize(_level.color), message].join(" : ")
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user