[Why] The built-in log system prints logs in string format by default. The logs should be formatted in json format for subsequent analysis and processing.
[Example1] use: log.info("test") output: {"level":"INFO","level_num":1,"time":"2020-11-19 16:57:17+0800","progname":"test","message":"test"}
[Example2] use: log.error({"job_id" => "1", "job_state" => "submit"}.to_json) output: {"level":"ERROR","level_num":3,"datetime":"2020-11-19 16:57:17+0800","progname":"test", "job_id":"1","job_state":"submit","caller":["./test.rb:6:in`<main>'"]}
Signed-off-by: Wu Zhende wuzhende666@163.com --- src/lib/json_logger.cr | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100755 src/lib/json_logger.cr
diff --git a/src/lib/json_logger.cr b/src/lib/json_logger.cr new file mode 100755 index 0000000..371c042 --- /dev/null +++ b/src/lib/json_logger.cr @@ -0,0 +1,32 @@ +# SPDX-License-Identifier: MulanPSL-2.0+ +# Copyright (c) 2020 Huawei Technologies Co., Ltd. All rights reserved. + +require "logger" +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} + end + logger_hash.any_merge!(message) + + io << logger_hash.to_json + end + + def initialize(logdev = STDOUT, formatter = FORMATTER) + super(logdev, formatter: formatter) + end +end
`Logger` is deprecated in version 0.35.1, use `Log` module instead. May can use `Log::StaticFormatter` to do a json formatter. FYI: https://crystal-lang.org/api/0.35.1/Log/StaticFormatter.html
Thanks, RenWen
On Sat, Nov 21, 2020 at 03:00:37PM +0800, Wu Zhende wrote:
[Why] The built-in log system prints logs in string format by default. The logs should be formatted in json format for subsequent analysis and processing.
[Example1] use: log.info("test") output: {"level":"INFO","level_num":1,"time":"2020-11-19 16:57:17+0800","progname":"test","message":"test"}
[Example2] use: log.error({"job_id" => "1", "job_state" => "submit"}.to_json) output: {"level":"ERROR","level_num":3,"datetime":"2020-11-19 16:57:17+0800","progname":"test", "job_id":"1","job_state":"submit","caller":["./test.rb:6:in`<main>'"]}
Signed-off-by: Wu Zhende wuzhende666@163.com
src/lib/json_logger.cr | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100755 src/lib/json_logger.cr
diff --git a/src/lib/json_logger.cr b/src/lib/json_logger.cr new file mode 100755 index 0000000..371c042 --- /dev/null +++ b/src/lib/json_logger.cr @@ -0,0 +1,32 @@ +# SPDX-License-Identifier: MulanPSL-2.0+ +# Copyright (c) 2020 Huawei Technologies Co., Ltd. All rights reserved.
+require "logger" +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}
- end
- logger_hash.any_merge!(message)
- io << logger_hash.to_json
- end
- def initialize(logdev = STDOUT, formatter = FORMATTER)
- super(logdev, formatter: formatter)
- end
+end
2.23.0