第2章 日志基础:定义、分类与格式标准

做日志审计做了这么多年,见过最多的坑就是——连日志是什么都不统一。有人说“我把错误输出到控制台就算日志了”,有人直接把数据库写入记录当日志用。所以我习惯先把基础打牢:日志到底是个什么东西,它长什么样,我们为什么要给它分类。

2.1 日志的定义

说白了,日志就是一个系统在运行过程中产生的时序化记录。每条日志至少包含三个要素:时间、来源、内容。有时候还有严重级别、会话ID、用户标识等额外字段。

我的经验:在生产环境里,日志就是“黑匣子”。有一次线上服务突然挂了,重启后所有内存数据都没了,就是靠几分钟前的access log定位到了异常请求。如果连时间戳都不准,那这日志就是废纸。

2.2 日志的分类

按来源和用途,日志通常分成下面三类。记住,很多系统会把它们混着写,但审计时必须分开看。

分类典型来源常见内容我遇到的坑
系统日志OS、内核、驱动、cron系统启动记录、磁盘错误、进程存活、内存使用内核日志默认只有环形缓冲区,重启就没了
应用日志Web服务器、DB、中间件、自研业务API访问、业务操作、异常栈、慢查询应用日志格式不统一,解析起来想骂人
安全日志防火墙、WAF、VPN、认证系统登录失败、权限变更、攻击告警、策略命中安全日志往往有敏感信息,审计时要脱敏

你看,三类日志的用途完全不同。系统日志告诉你机器有没有坏,应用日志告诉你业务跑得顺不顺,安全日志告诉你有没有人在搞破坏。但有一点是相同的——它们都需要统一格式,否则后面的异常检测根本无从下手。

2.3 日志格式标准

我个人最烦那种“自定义格式”,每家公司自创一套,解析代码比业务逻辑还复杂。所以这里必须讲三个主流标准:JSON、Syslog、CEF。你会经常在实际项目中碰到它们。

2.3.1 JSON 格式

JSON 现在是事实标准,因为它可读性好、容易扩展、各种日志库都能直接输出。我习惯让团队把每条日志都写成一行 JSON,不要有多行,不然 Logstash 处理时会断行。

{
  "@timestamp": "2025-04-07T14:32:10.123+08:00",
  "level": "ERROR",
  "logger": "com.example.api.AuthController",
  "message": "登录失败:用户不存在",
  "request_id": "req-abc-123",
  "user_agent": "Mozilla/5.0",
  "src_ip": "192.168.1.100"
}

嗯,关键字段都要带上。我建议至少包含:@timestamp、level、logger、message。其余业务字段按需加。

2.3.2 Syslog 格式

Syslog 是老前辈了,RFC 5424 定义了标准格式。这玩意儿在 Linux 网络设备上遍地都是。它的结构是固定的:PRI + HEADER + MSG。你看下面这个例子:

<14>1 2025-04-07T14:32:10.123+08:00 srv-web01 sshd 12345 - - Failed password for root from 10.0.0.5 port 22

拆开来说:<14> 是优先级(facility+severity),1 是版本号,后面是时间戳、主机名、进程名、PID、消息ID、结构化数据(这里两个横杠表示无),最后是自由格式的文本。

但是注意,很多设备(比如老旧交换机的 Console 日志)不是标准 Syslog,而是 BSD-syslog(RFC 3164),格式乱得很,解析时一定要做兼容。

我曾经掉过这个坑:某次对接防火墙上送的安全日志,时间戳写的是 Apr 7 14:32:10 这种没有年份的格式。结果跨年审计时数据全乱套了。所以解析 Syslog 时,务必先确认是对标 RFC 5424 还是 3164。

2.3.3 CEF 格式

CEF 全称 Common Event Format,是 ArcSight 定义的安全设备日志格式。它在 SIEM 领域特别常见。结构是固定的字段顺序,每段用竖线 | 隔开:

CEF:0|Security|Firewall|1.0|10001|暴力破解告警|5|src=10.0.0.5 dst=192.168.1.254 spt=5000 dpt=22 msg=来自不明IP的SSH暴力尝试

拆开说说:

  • CEF:0 表示版本号
  • Security|Firewall|1.0 是设备厂商、产品名、版本
  • 10001|暴力破解告警|5 是事件ID、名称、严重级别(5 是最高)
  • 后面是键值对扩展字段

CEF 的好处是标准且紧凑,设备端生成压力小。但缺点也很明显——字段顺序不能错,而且扩展字段的 KV 格式有时会跟 Syslog 的混在一起,解析时要特别小心。

2.4 核心知识结构图

为了让你更清楚地理解这三类日志和三种格式之间的关系,我画了一张图。请你重点关注:不同来源的日志应该选择哪种格式输出,以及审计时如何统一解析。

日志基础结构图:分类与格式 日志基础:分类与格式标准 系统日志 OS/内核/驱动/cron 应用日志 Web/DB/中间件/业务 安全日志 防火墙/WAF/VPN/认证 日志收集 → 格式标准化 JSON 格式 现代应用首选,易解析易扩展 Syslog (RFC 5424) 网络设备、Linux 系统标准 CEF 格式 安全设备 SIEM 常用 ➡ 审计时统一用 JSON 做中间格式,再分别适配 Syslog 和 CEF 解析器

你看这张图就清楚了:不管日志来自哪个系统,最终要进入审计流程,就得有三种格式之一作为标准。我个人建议团队统一用 JSON 作为内部交换格式,然后加一层适配器去处理遗留的 Syslog 和 CEF 日志。这样上游改了格式,下游不用跟着改。

2.5 格式对比与选型建议

对比维度JSONSyslogCEF
可读性★★★★★ 对人和机器都友好★★☆☆☆ 自由格式部分难读★★★☆☆ 竖线分隔有点反直觉
扩展性★★★★★ 随意嵌套字段★☆☆☆☆ 结构定死,扩展全靠自由文本★★★☆☆ 通过KV扩展,有最大长度
解析性能★★★☆☆ 需要完整解析整行★★★★☆ 固定前缀可快速拆解★★★★☆ 固定字段数,可快速定界
生态兼容性★★★★★ 几乎全支持★★★★☆ Linux/网络设备原生★★★☆☆ 主要在安全领域
适用场景应用日志、审计日志系统日志、网络设备日志安全设备日志、SIEM上报
我的最终建议:新系统能上 JSON 就上 JSON。遗留系统如果是网络设备,保留 Syslog;安全设备优先转 CEF。如果日志量非常大(每秒几十万条),可以考虑混合方案——Syslog 做快速路由,CEF 做安全告警上层聚合,JSON 留做离线分析。别试图用一把钥匙开所有锁。

2.6 避坑指南

  • 时间戳必须带时区。 我见过两个机房用不同的时区格式,审计时全乱序。强制对时并统一为 UTC +08:00 或者 UTC+0,不然根本没法做关联分析。
  • 多行日志要小心。 Java 的异常栈经常跨好几行。我习惯在预处理阶段就把多行合并成单行,用 \n 转义保留内容。否则 Logstash 会拆成多条乱序记录。
  • 敏感信息别直接写日志。 密码、身份证号、 这些,脱敏后再输出。有一次我在安全日志里发现有人在明文记录用户密码哈希值……这种日志一旦泄露,审计对象直接变审计嫌疑人。

好了,这一节的内容就这么多。记住理解了日志的分类和三种标准格式,后面做异常检测时,你才能快速判断:这条日志该不该报警,它从哪来的,质量够不够。