排查线上问题时,最怕日志乱成一团。比如凌晨三点,服务器突然报警,你打开日志文件,看到的却是这样的内容:
2024-05-13 03:21:05 ERROR User login failed for user=admin from IP=192.168.3.111, reason=invalid password, duration=230ms
想查来源IP?得靠字符串匹配。想统计失败次数?写脚本切字段。时间一长,光是解析日志就累得够呛。
JSON让日志变“结构化”
{"timestamp": "2024-05-13T03:21:05Z", "level": "ERROR", "event": "user_login_failed", "user": "admin", "client_ip": "192.168.3.111", "reason": "invalid password", "duration_ms": 230}
每个字段都清清楚楚,不用再靠正则去“猜”数据。IP就是client_ip,错误原因就是reason,直接拿就能用。
排查效率提升不止一点点
在实际排错中,这种差别特别明显。比如你想查某个IP在10分钟内触发了多少次登录失败,用JSON日志配合ELK或Loki这类工具,一条查询语句就行:
{job="auth-service"} |~ `\"client_ip\":\"192.168.3.111\"` | json | reason == "invalid password"
如果是纯文本日志,你得先处理引号、转义、字段位置偏移,稍不注意就漏数据。
服务之间传日志也更省心
现在大多是微服务架构,A服务调B服务,中间经过网关、鉴权、缓存。如果每层都用JSON输出日志,并带上同一个request_id,那你从头到尾追踪一次请求就像看流水线一样顺畅。
比如你在网关看到一个失败请求,复制它的request_id,直接去其他服务的日志里搜索,所有相关操作一目了然,不用再靠时间和IP去拼凑线索。
也不是所有场景都适合
当然,JSON也不是万能的。有些嵌入式设备或者老系统,资源紧张,拼JSON字符串反而增加负担。还有些运维人员习惯看文本日志,一下子切换不适应。
但如果你在做新项目,尤其是基于容器、云原生的环境,直接上JSON格式输出日志,后续对接Prometheus、Grafana、Fluentd这些工具会轻松很多。
别等到出问题才后悔日志难查。从第一行日志开始,就让它规规矩矩地输出成JSON,后面少踩不少坑。