API can set env, after set env will add some env info to log. Add: status_code/method/resource/elapsed Like this: {"level_num":1,"level":"INFO","time":"2020-12-01 20:03:19+08:00","message":"test","status_code":200,"method":"POST","resource":"/submit_job","elapsed":"133.68µs"}
Signed-off-by: Wu Zhende wuzhende666@163.com --- src/lib/json_logger.cr | 65 ++++++++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 18 deletions(-)
diff --git a/src/lib/json_logger.cr b/src/lib/json_logger.cr index 371c042..2b5ef6a 100755 --- a/src/lib/json_logger.cr +++ b/src/lib/json_logger.cr @@ -6,27 +6,56 @@ require "json" require "any_merge"
class JSONLogger < Logger - FORMATTER = Logger::Formatter.new do | severity, datetime, progname, msg, io| - level_num = severity.to_i32 - logger_hash = JSON.parse(%({"level_num": #{level_num}, - "level": "#{severity}", - "time": "#{datetime}" - })).as_h - - logger_hash.any_merge!({"progname" => progname}) unless progname.empty? - logger_hash.merge!(JSON.parse(%({"caller": #{caller}})).as_h) if level_num >= 2 - - begin - message = JSON.parse(msg).as_h - rescue - message = {"message" => msg} + def initialize(logdev = STDOUT, formatter = my_formatter) + @env = nil + @env_info = Hash(String, String | Int32).new + super(logdev, formatter: formatter) + end + + def my_formatter + Logger::Formatter.new do | severity, datetime, progname, msg, io| + get_env_info(@env.as(HTTP::Server::Context)) if @env + level_num = severity.to_i32 + logger_hash = JSON.parse(%({"level_num": #{level_num}, + "level": "#{severity}", + "time": "#{datetime}" + })).as_h + + logger_hash.any_merge!({"progname" => progname}) unless progname.empty? + logger_hash.merge!(JSON.parse(%({"caller": #{caller}})).as_h) if level_num >= 2 + + begin + message = JSON.parse(msg).as_h + rescue + message = {"message" => msg} + end + logger_hash.any_merge!(message) + logger_hash.any_merge!(@env_info) + + io << logger_hash.to_json end - logger_hash.any_merge!(message) + end
- io << logger_hash.to_json + private def get_env_info(env : HTTP::Server::Context) + @env_info["status_code"] = env.response.status_code + @env_info["method"] = env.request.method + @env_info["resource"] = env.request.resource + + elapsed = get_elapsed(env) + @env_info["elapsed"] = elapsed.to_s if elapsed end
- def initialize(logdev = STDOUT, formatter = FORMATTER) - super(logdev, formatter: formatter) + private def get_elapsed(env : HTTP::Server::Context) + start_time = env.get?("start_time") + return unless start_time + + elapsed = (Time.monotonic - start_time.as(Time::Span)).total_milliseconds + return "#{elapsed.round(2)}ms" if elapsed >= 1 + + "#{(elapsed * 1000).round(2)}µs" + end + + def set_env(env : HTTP::Server::Context) + @env = env end end