常见日志格式:吃透这五种,大部分场景都能搞定
日志格式这东西,看着简单,但坑不少。我见过不少团队,日志是产了,格式乱七八糟,解析脚本写了一堆,运维成本直线上升。其实搞来搞去,常用的就五种:JSON、Syslog、Apache/Nginx 访问日志、应用日志、Windows Event Log。把它们摸透了,你手头至少能覆盖 90% 的场景。
嗯,咱们一个一个来过。
1. JSON 格式:结构化数据的首选
说白了,JSON 就是给机器看的。自带键值对,解析起来快,扩展也方便。我个人习惯在新建日志系统时,优先推 JSON 格式。为什么?因为字段清晰,上游消费端不用猜。
{
"timestamp": "2025-03-21T14:30:00.123Z",
"level": "ERROR",
"logger": "com.example.OrderService",
"thread": "http-nio-8080-exec-3",
"message": "订单支付超时,订单号: ORD20250321001",
"stack_trace": "java.util.concurrent.TimeoutException: ...",
"context": {
"order_id": "ORD20250321001",
"user_id": "U12345",
"amount": 299.00
}
}
stack_trace 当普通字符串塞进去,换行符会搞乱你的行协议。我建议 Base64 编码,或者单独放到一个字段里,消费端按需解码。
JSON 的缺点也有:占用空间大,每行重复的 key 名挺浪费。但考虑到可读性和解析效率,这点代价可以接受。实际项目里,我一般用 Logstash 或者 Fluentd 去 parse,配置写起来也顺手。
2. Syslog 格式:老牌协议,网络设备必备
Syslog 是历史最悠久的日志协议之一。很多网络设备、交换机、防火墙、Linux 系统默认都在用。它的格式有几个变体,最典型的是 RFC 3164 和 RFC 5424。
先看 RFC 3164(老版,但很常见):
<34>Oct 11 22:14:15 mymachine su[12345]: 'su root' failed for john on /dev/pts/8
再看 RFC 5424(新版,结构化更好):
<34>1 2025-03-21T14:30:00.123Z mymachine.example.com su 12345 - \x0a] 'su root' failed for john on /dev/pts/8
| 版本 | 优点 | 槽点(我踩过的) |
|---|---|---|
| RFC 3164 | 格式简单,兼容性强 | 时间戳没有年份,时区也不明确。我做过一个跨时区的项目,补年份补到怀疑人生 |
| RFC 5424 | 结构清晰,支持结构化数据 | 解析器不多,需要额外适配 |
3. Apache/Nginx 访问日志:Web 运维的必修课
访问日志,说白了就是记录了谁在什么时候访问了你哪个页面,结果怎么样。它的默认格式通常叫 combined,包含 IP、时间、请求方法、状态码、响应大小、Referer、User-Agent 这些。
192.168.1.1 - - [21/Mar/2025:14:30:00 +0800] "POST /api/order/create HTTP/1.1" 200 532 "https://www.example.com/cart" "Mozilla/5.0 Chrome/120.0"
我个人觉得,默认的 combined 格式够用了。但如果你做复杂分析,比如按用户、按地域聚合,我建议在 Nginx 配置里自定义 log_format,加入一些自定义变量。
log_format json_analytics escape=json '{'
'"time_local":"$time_local",'
'"remote_addr":"$remote_addr",'
'"request":"$request",'
'"status":$status,'
'"body_bytes_sent":$body_bytes_sent,'
'"http_referer":"$http_referer",'
'"http_user_agent":"$http_user_agent",'
'"upstream_addr":"$upstream_addr",'
'"upstream_response_time":"$upstream_response_time"'
'}';
为什么这么改? 有一次线上故障,我追踪一个慢请求,默认日志看不到后端响应时间。我立刻在 log_format 里加上了 $upstream_response_time,问题瞬间定位。像这种调整,一个配置项就能救你一次。
平时没事多看看访问日志,你能发现很多异常:大量 404 可能是扫描器在搞鬼,突然飙高的 5xx 说明后端有状况。嗯,这个习惯我一直保持着。
4. 应用日志:花样最多,也最乱
应用日志最灵活,也最让人头疼。你想想看,每个开发人员都有自己的风格——有的用 log4j,有的用 SLF4J,还有的直接 System.out.println。格式千奇百怪。
举几个我见过的例子:
- 普通文本日志:
2025-03-21 14:30:00.123 [http-nio-8080-exec-3] ERROR c.e.OrderService - 订单支付超时。这种最普遍,解析起来用正则,维护成本高。 - 多行日志: 典型的如 Java 异常堆栈,一个异常占几十行。采集时如果不做多行合并,你会看到碎片化的日志,根本没法分析。
- 混合日志: 同一个文件里既有访问日志,又有业务日志,还有系统日志。我见过最离谱的是,一个日志文件里同时用了三种时间格式。
5. Windows Event Log:Windows 环境的专属语言
Windows 环境下的日志就靠它了。不像 Linux 下面你可以随便写文件,Windows Event Log 有系统自带的管理。它分为几类:Application、Security、Setup、System。通过 Event Viewer 可以直接看,但大规模采集就得用工具了。
它的格式是 XML 结构,字段很多。一个典型的日志条目长这样:
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="Microsoft-Windows-Security-Auditing"/>
<EventID>4625</EventID>
<Level>0</Level>
<TimeCreated SystemTime="2025-03-21T14:30:00.123Z"/>
<Computer>DC-01.contoso.com</Computer>
</System>
<EventData>
<Data Name="TargetUserName">Administrator</Data>
<Data Name="WorkstationName">WS-001</Data>
</EventData>
</Event>
EventID 4625 表示登录失败,是所有安全运维人员最关注的事件之一。我当年做一个内网安全审计项目,就是靠采集所有 DC 的 4625 事件,发现了一个暴力破解的 IP。你看,日志关键字段抓准了,能救命。
多格式并存的策略
现实世界里,很少只用一种日志格式。我做过一个项目,前端 Nginx 输出 JSON 格式的访问日志,后端 Java 服务用文本格式应用日志,数据库服务器又跑着 Syslog。你想想看,三个系统三种格式,怎么统一处理?
我当时用了两个步骤:
- 统一采集层: 用 Filebeat 或者 Fluent Bit 去收不同源的日志,配置对应解析规则。
- 统一存储层: 在 Logstash 或 Vector 里做二次处理,转成统一的 JSON 结构,写进 Elasticsearch 或者 ClickHouse。
这套流程跑通之后,你就不用操心「这个日志是谁写的,格式是什么」了。只要源端能输出,采集层能收到,剩下的事全由管道处理掉。
总结:格式是基础,统一是目标
五种格式,各有各的适用场景。JSON 结构化强、Syslog 覆盖面广、访问日志定位精准、应用日志细节丰富、Windows Event Log 安全性高。你不可能只用一种,但你可以通过工具链把它们统一起来。
嗯,这部分内容先讲到这。后面讲采集工具的时候,我会反复引用这几种格式,到时候你就明白为什么现在要花功夫把它们理清楚了。