第2章 日志基础:定义、分类与格式标准
做日志审计做了这么多年,见过最多的坑就是——连日志是什么都不统一。有人说“我把错误输出到控制台就算日志了”,有人直接把数据库写入记录当日志用。所以我习惯先把基础打牢:日志到底是个什么东西,它长什么样,我们为什么要给它分类。
2.1 日志的定义
说白了,日志就是一个系统在运行过程中产生的时序化记录。每条日志至少包含三个要素:时间、来源、内容。有时候还有严重级别、会话ID、用户标识等额外字段。
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 核心知识结构图
为了让你更清楚地理解这三类日志和三种格式之间的关系,我画了一张图。请你重点关注:不同来源的日志应该选择哪种格式输出,以及审计时如何统一解析。
你看这张图就清楚了:不管日志来自哪个系统,最终要进入审计流程,就得有三种格式之一作为标准。我个人建议团队统一用 JSON 作为内部交换格式,然后加一层适配器去处理遗留的 Syslog 和 CEF 日志。这样上游改了格式,下游不用跟着改。
2.5 格式对比与选型建议
| 对比维度 | JSON | Syslog | CEF |
|---|---|---|---|
| 可读性 | ★★★★★ 对人和机器都友好 | ★★☆☆☆ 自由格式部分难读 | ★★★☆☆ 竖线分隔有点反直觉 |
| 扩展性 | ★★★★★ 随意嵌套字段 | ★☆☆☆☆ 结构定死,扩展全靠自由文本 | ★★★☆☆ 通过KV扩展,有最大长度 |
| 解析性能 | ★★★☆☆ 需要完整解析整行 | ★★★★☆ 固定前缀可快速拆解 | ★★★★☆ 固定字段数,可快速定界 |
| 生态兼容性 | ★★★★★ 几乎全支持 | ★★★★☆ Linux/网络设备原生 | ★★★☆☆ 主要在安全领域 |
| 适用场景 | 应用日志、审计日志 | 系统日志、网络设备日志 | 安全设备日志、SIEM上报 |
2.6 避坑指南
- 时间戳必须带时区。 我见过两个机房用不同的时区格式,审计时全乱序。强制对时并统一为 UTC +08:00 或者 UTC+0,不然根本没法做关联分析。
- 多行日志要小心。 Java 的异常栈经常跨好几行。我习惯在预处理阶段就把多行合并成单行,用
\n转义保留内容。否则 Logstash 会拆成多条乱序记录。 - 敏感信息别直接写日志。 密码、身份证号、 这些,脱敏后再输出。有一次我在安全日志里发现有人在明文记录用户密码哈希值……这种日志一旦泄露,审计对象直接变审计嫌疑人。
好了,这一节的内容就这么多。记住理解了日志的分类和三种标准格式,后面做异常检测时,你才能快速判断:这条日志该不该报警,它从哪来的,质量够不够。