Reworked project

This commit is contained in:
Tristan Ancelet
2026-08-21 08:38:24 -05:00
parent 82e671ba58
commit 26e679a5d5
+45 -110
View File
@@ -1,120 +1,55 @@
require "time" require "log"
require "colorize"
module Logger module Logger
macro included
annotation LoggerWatcher annotation LogContext
end
struct LOG_LEVEL
getter value : Int32
getter color : Symbol
delegate in?, to: @value
def initialize(@value : Int32, @color : Symbol)
end end
def to_s Log = ::Log
LOG_LEVELS.keys[@value].to_s.downcase
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"]
@@log_file : String = ""
@@debug : Bool = false
LOG_MUTEX = ::Mutex.new
macro generate_log_line
{% verbatim do %} {% verbatim do %}
{% if @type && @def %} macro finished
"{{(@type.module? ? "Module" : "Class").id}}({{@type.name.id}})" + " : " + "Method({{@def.name}})" + " : " {% defined_level_methods = [] of MacroId %}
{% elsif @type %} {% levels = %i[ debug info notice error fatal ] %}
"{{(@type.module? ? "Module" : "Class").id}}({{@type.name.id}})" + " : " {% for level in levels %}
{% elsif @def %} {% defined_level_methods << level if @type.has_method? level %}
"Method({{@def.name}})" + " : " {% end %}
{% else %} {% raise "ERROR : You can't include ::Logger when you have the following defined as instance methods: #{defined_level_methods.join(", ").id}" unless defined_level_methods.empty? %}
{{message}} end
{% end %}
{% end %}
end
{% for level in LOG_LEVELS.keys %} macro log_with_context(level, message)
macro {{level.downcase.id}}(message, *args) {% if @type.class? %}
::Logger.log({{level}}, Logger.generate_log_line + \{{message}}, \{{*args}}) {% if vars = @type.instance_vars.select(&.annotation(LogContext)) %}
end Log.with_context( {% for var in vars %} {{var.name}}: @{{var.name}}, {% end %} ) do
{% end %} Log.{{level}} { [ generate_log_line, {{message}}].join(" : ") }
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.min=(selection : String) : Nil
Logger.debug "Entering with #{selection}"
raise "ERROR : {{level.id}}= : Invalid level" unless _level = LOG_LEVELS[selection.upcase]
synchronize {
@@min_level = _level
}
end
def self.min : String
@@min_level.to_s.downcase
end
def self.log_file=(@@log_file : String)
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 : String, message : String, *args) : Nil
_level = LOG_LEVELS[level]
message = message % args unless args.empty?
if valid?(_level) || debug?
synchronize {
time = Time.local
message = [time, level.to_s.colorize(_level.color), message].join(" : ")
STDERR.puts message
unless @@log_file.empty?
File.open(@@log_file, "a") do |file|
file.puts message
end end
end {% else %}
raise "ERROR : Fatal error detected (#{message})" if level == "FATAL" Log.{{level}} { [ generate_log_line, {{message}}].join(" : ") }
} {% end %}
end {% else %}
Log.{{level}} { [ generate_log_line, {{message}}].join(" : ") }
{% end %}
end
macro generate_log_line
{% verbatim do %}
{% if @type && @def %}
"{{(@type.module? ? "Module" : "Class").id}}({{@type.name}})" + " : " + "Method({{@def.name}})"
{% elsif @type %}
"{{(@type.module? ? "Module" : "Class").id}}({{@type.name}})"
{% elsif @def %}
"Method({{@def.name}})"
{% else %}
{{message}}
{% end %}
{% end %}
end
{% for level in %i[ trace debug info notice error fatal ].map(&.id) %}
macro {{level.downcase}}(message, *args)
log_with_context {{level}}, (\{{message}} \{% unless args.empty? %} % \{{args}} \{% end %})
end
{% end %}
{% end %}
end end
end end