如何将结构化日志转换为适合人工阅读的格式?
JSON结构化日志转易读格式的快捷实现方法
我们采用结构化日志提升日志分析效率,但JSON格式的结构化日志不利于人工阅读,例如原日志格式:
{"@timestamp":"2024-03-24T23:03:13.693+08:00","@version":"1","message":"Release executor io.netty.channel.nio.NioEventLoopGroup@1e499f1","logger_name":"io.lettuce.core.resource.DefaultEventLoopGroupProvider","thread_name":"SpringApplicationShutdownHook","level":"DEBUG","level_value":10000}
希望转换为如下易读格式:
【2024-03-24T23:03:13.693+08:00】 【SpringApplicationShutdownHook】io.lettuce.core.resource.DefaultEventLoopGroupProvider【DEBUG】: Release executor io.netty.channel.nio.NioEventLoopGroup@1e499f1
以下是几种快捷实现方式:
1. 命令行工具(jq)
jq是处理JSON的常用命令行工具,直接提取字段并格式化输出:
# 转换单条日志 echo '{"@timestamp":"2024-03-24T23:03:13.693+08:00","@version":"1","message":"Release executor io.netty.channel.nio.NioEventLoopGroup@1e499f1","logger_name":"io.lettuce.core.resource.DefaultEventLoopGroupProvider","thread_name":"SpringApplicationShutdownHook","level":"DEBUG","level_value":10000}' | jq -r '【\(.@timestamp)】 【\(.thread_name)】\(.logger_name)【\(.level)】: \(.message)' # 处理整个日志文件 jq -r '【\(.@timestamp)】 【\(.thread_name)】\(.logger_name)【\(.level)】: \(.message)' logfile.json
2. 日志框架配置(生成时直接输出易读格式)
如果需要同时兼顾结构化分析和人工阅读,可以在日志框架(如Logback、Log4j2)中配置双输出:一个输出JSON格式用于分析,另一个输出易读格式用于人工查看。
以Logback为例,在logback.xml中添加对应appender:
<!-- 易读格式控制台输出 --> <appender name="CONSOLE_HUMAN" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>【%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}】 【%thread】%logger【%level】: %msg%n</pattern> </encoder> </appender> <!-- JSON格式文件输出(用于日志分析) --> <appender name="FILE_JSON" class="ch.qos.logback.core.FileAppender"> <file>logs/json.log</file> <encoder class="net.logstash.logback.encoder.LogstashEncoder"/> </appender> <root level="debug"> <appender-ref ref="CONSOLE_HUMAN"/> <appender-ref ref="FILE_JSON"/> </root>
3. 轻量Python脚本实现
写一个简单脚本自定义处理JSON日志行,适合灵活调整格式:
import json import sys def format_log_line(line): try: log_data = json.loads(line.strip()) return f"【{log_data['@timestamp']}】 【{log_data['thread_name']}】{log_data['logger_name']}【{log_data['level']}】: {log_data['message']}" except json.JSONDecodeError: return line.strip() if __name__ == "__main__": for line in sys.stdin: print(format_log_line(line))
使用方式:
# 处理日志文件 cat logfile.json | python format_log.py # 实时监控日志流 tail -f logfile.json | python format_log.py
内容的提问来源于stack exchange,提问作者Jason
相关产品推荐
相关产品推荐

