常见日志格式:吃透这五种,大部分场景都能搞定

日志格式这东西,看着简单,但坑不少。我见过不少团队,日志是产了,格式乱七八糟,解析脚本写了一堆,运维成本直线上升。其实搞来搞去,常用的就五种: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 结构清晰,支持结构化数据 解析器不多,需要额外适配
注意: Syslog 默认使用 UDP 514 端口传日志,会丢包。我曾经负责过一个监控网络设备的项目,日志量特别大,UDP 一丢就是大段。后来我全改 TCP 了,虽然连接开销大了点,但安心。

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 异常堆栈,一个异常占几十行。采集时如果不做多行合并,你会看到碎片化的日志,根本没法分析。
  • 混合日志: 同一个文件里既有访问日志,又有业务日志,还有系统日志。我见过最离谱的是,一个日志文件里同时用了三种时间格式。
曾经我踩过一个坑: 一个支付系统,用 Log4j 1.x,配置里没做日志轮转,结果跑了一个月,单日志文件 20GB 以上。最后磁盘满了,服务挂掉。这个问题很难查,因为日志先挂了,服务才挂。我后来强制推行了日志轮转和保留天数,才把这个隐患解决。

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。你看,日志关键字段抓准了,能救命。

小技巧: 用 WinRM 或 WEC(Windows Event Collector)把多台机器的 Event Log 集中收集,然后转发到你的集中式日志平台。别一台一台登录去看 Event Viewer,那是 2000 年的做法。

多格式并存的策略

现实世界里,很少只用一种日志格式。我做过一个项目,前端 Nginx 输出 JSON 格式的访问日志,后端 Java 服务用文本格式应用日志,数据库服务器又跑着 Syslog。你想想看,三个系统三种格式,怎么统一处理?

我当时用了两个步骤:

  1. 统一采集层: 用 Filebeat 或者 Fluent Bit 去收不同源的日志,配置对应解析规则。
  2. 统一存储层: 在 Logstash 或 Vector 里做二次处理,转成统一的 JSON 结构,写进 Elasticsearch 或者 ClickHouse。
常见日志格式流转与处理图 JSON 应用日志 REST API / 微服务 Syslog 格式 网络设备 / Linux Nginx 访问日志 Web 服务器 Windows Event Log Windows 系统 采集代理层 Filebeat / Fluent Bit 多行合并 / 字段提取 统一处理管道 Logstash / Vector 格式归一化 / 解析 统一存储 ES / ClickHouse / Loki 最终输出统一 JSON 结构 便于消费端按字段查询

这套流程跑通之后,你就不用操心「这个日志是谁写的,格式是什么」了。只要源端能输出,采集层能收到,剩下的事全由管道处理掉。

总结:格式是基础,统一是目标

五种格式,各有各的适用场景。JSON 结构化强、Syslog 覆盖面广、访问日志定位精准、应用日志细节丰富、Windows Event Log 安全性高。你不可能只用一种,但你可以通过工具链把它们统一起来。

嗯,这部分内容先讲到这。后面讲采集工具的时候,我会反复引用这几种格式,到时候你就明白为什么现在要花功夫把它们理清楚了。