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(a)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
--
2.23.0