[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,"datetime":"2020-11-19 16:57:17+0800","progname":null,"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":null,"message":"", "job_id":"1","job_state":"submit","caller":["/usr/share/ruby/logger.rb:545:in `error'","./test.rb:6:in`<main>'"]}
Signed-off-by: Wu Zhende wuzhende666@163.com --- lib/log.rb | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 lib/log.rb
diff --git a/lib/log.rb b/lib/log.rb new file mode 100644 index 0000000..aad00ca --- /dev/null +++ b/lib/log.rb @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: MulanPSL-2.0+ +# Copyright (c) 2020 Huawei Technologies Co., Ltd. All rights reserved. +# frozen_string_literal: true + +require 'logger' +require 'json' + +# print logs in JSON format +class Log < Logger + LEVEL_INFO = { + 'DEBUG' => 0, + 'INFO' => 1, + 'WARN' => 2, + 'ERROR' => 3, + 'FATAL' => 4, + 'UNKNOWN' => 5 + }.freeze + + FORMATTER = proc { |severity, datetime, progname, msg| + level_num = LEVEL_INFO[severity] + begin + message = JSON.parse(msg) + rescue JSON::ParserError + message = { 'message' => msg } + end + h = { + 'level' => severity.to_s, + 'level_num' => level_num, + 'datetime' => datetime, + 'progname' => progname, + 'message' => '' + } + h.merge!(message) + h.merge!({ 'caller' => caller }) if level_num >= 2 + h.to_json + } + + def initialize(logdev = STDOUT, formatter = FORMATTER) + super(logdev, formatter: formatter) + end +end
- LEVEL_INFO = {
- 'DEBUG' => 0,
- 'INFO' => 1,
- 'WARN' => 2,
- 'ERROR' => 3,
- 'FATAL' => 4,
- 'UNKNOWN' => 5
- }.freeze
That matches
https://github.com/ruby/logger/blob/master/lib/logger/severity.rb
However does not match
/c/linux/include/linux/kern_levels.h
#define KERN_EMERG KERN_SOH "0" /* system is unusable */ #define KERN_ALERT KERN_SOH "1" /* action must be taken immediately */ #define KERN_CRIT KERN_SOH "2" /* critical conditions */ #define KERN_ERR KERN_SOH "3" /* error conditions */ #define KERN_WARNING KERN_SOH "4" /* warning conditions */ #define KERN_NOTICE KERN_SOH "5" /* normal but significant condition */ #define KERN_INFO KERN_SOH "6" /* informational */ #define KERN_DEBUG KERN_SOH "7" /* debug-level messages */
or https://www.ietf.org/rfc/rfc3164.txt
Numerical Severity Code
0 Emergency: system is unusable 1 Alert: action must be taken immediately 2 Critical: critical conditions 3 Error: error conditions 4 Warning: warning conditions 5 Notice: normal but significant condition 6 Informational: informational messages 7 Debug: debug-level messages
Table 2. syslog Message Severities
And here's python's https://docs.python.org/3/library/logging.html#logging-levels
Java:
https://www.tutorialspoint.com/log4j/log4j_logging_levels.htm ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF
看起来语言级和系统级的log level编号大小正好相反。。 我们会同时收集两者吧?
Thanks, Fengguang
Some similar JSON logging projects for your reference.
https://github.com/trentm/node-bunyan
{ "name": "myserver", "hostname": "banana.local", "pid": 123, "req": { "method": "GET", "url": "/path?q=1#anchor", "headers": { "x-hi": "Mom", "connection": "close" }, "remoteAddress": "120.0.0.1", "remotePort": 51244 }, "level": 3, "msg": "start request", "time": "2012-02-03T19:02:57.534Z", "v": 0 }
https://github.com/madzak/python-json-logger
{ "threadName": "MainThread", "name": "root", "thread": 140735202359648, "created": 1336281068.506248, "process": 41937, "processName": "MainProcess", "relativeCreated": 9.100914001464844, "module": "tests", "funcName": "testFormatKeys", "levelno": 20, "msecs": 506.24799728393555, "pathname": "tests/tests.py", "lineno": 60, "asctime": ["12-05-05 22:11:08,506248"], "message": "testing logging format", "filename": "tests.py", "levelname": "INFO", "special": "value", "run": 12 }