3. 日志来源与类型:系统日志、应用日志、数据库日志、网络设备日志、安全设备日志
日志采集的第一步,也是最容易被忽略的一步,是搞清楚日志到底从哪来。你想想看,如果我们连源头都搞不清,后面谈什么安全存储、关联分析,都是空谈。我个人习惯把日志来源分成五大类:系统、应用、数据库、网络设备、安全设备。每一类的脾气秉性都不一样,采集策略也得对症下药。
好,我们一个一个来过。
3.1 系统日志
系统日志是所有日志的基础设施。说白了,它记录的是操作系统本身的运行状态。Linux 下主要是 syslog/rsyslog,Windows 下则是 Event Log。我在这里踩过最大的坑,是以为系统日志不重要。
常见系统日志类型:
- 系统启动/关机日志:记录系统启停时间、异常重启原因
- 用户登录/登出日志:SSH 登录、本地登录记录(
/var/log/wtmp) - 内核日志:驱动加载、硬件错误、OOM 事件
- Cron 日志:定时任务执行情况
- sudo 日志:特权命令执行记录(审计必备)
logrotate 按天压缩 + rsyslog 按来源分离目录。记住,系统日志量虽然不大,但集中存放必须有清理策略。
采集系统日志时,我建议做三件事:一是开启时间戳精确到毫秒,二是补全主机名,三是带上原始日志级别。嗯,级别很重要,很多安全基线分析都依赖它。
3.2 应用日志
应用日志是开发人员写出来的,格式千奇百怪。有的框架自带结构化日志(比如 log4j 的 JSON 格式),有的只是 console.log 一堆字符串。作为日志管理者,我们得统一胃口。
应用日志的关键字段必须包含:
{
"@timestamp": "2024-05-12T10:30:00.123Z",
"level": "ERROR",
"logger_name": "com.example.OrderService",
"thread_name": "http-nio-8080-exec-3",
"message": "订单支付超时,订单号: ORD20240512001",
"trace_id": "abc123-def456-ghi789",
"stack_trace": "java.lang.Exception..."
}
核心字段解释:
| 字段 | 说明 | 采集必备性 |
|---|---|---|
@timestamp |
事件发生时间(非到达时间) | 必须 |
level |
日志级别(TRACE/DEBUG/INFO/WARN/ERROR/FATAL) | 必须 |
logger_name |
记录日志的类或模块名 | 建议 |
trace_id |
分布式链路追踪 ID | 强烈建议 |
message |
业务描述信息 | 必须 |
stack_trace |
异常堆栈(仅 Error 级别含) | 建议采集并截断 |
采集应用日志时,有个常见陷阱:日志输出到文件 vs 直接输出到 stdout,然后在容器内由日志 agent 采集。如果是容器环境,千万别用 sidecar 模式硬读文件——容易读到截断的半行数据。我建议直接用标准输出的采集方案,比如 Docker 的 json-file driver 配合 fluentd。
3.3 数据库日志
数据库日志是审计日志里最「硬」的一类。因为它直接记录数据的变更行为。你想想看,谁动了数据库,什么时候动的,动了哪条记录,这些信息都藏在数据库日志里。
主流数据库的日志类型:
- MySQL:General Query Log、Slow Query Log、Binary Log(binlog)、Error Log
- PostgreSQL:Write-Ahead Log(WAL)、CSV Log(审计日志)
- Oracle:Redo Log、Archive Log、Audit Trail
- MongoDB:OpLog、Diagnostic Log
以 MySQL 为例,我们最常采集的是 binlog(二进制日志)和 slow query log。binlog 可以记录所有数据变更,用于回滚和审计。但它的格式是二进制的,采集后需要解析成可读的 JSON。业界有 canal、Debezium 这样的工具能做到实时解析。
# MySQL 开启审计相关的日志配置示例(my.cnf)
[mysqld]
log-bin = /var/log/mysql/mysql-bin.log
binlog-format = ROW
expire_logs_days = 30
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
数据库日志的采集频率要与业务量匹配。我曾经见过一个电商平台,每秒产生 8 万条 binlog 事件,采集 agent 直接撑爆了。最终用 Kafka 做了缓冲层,才把下游 sink 扛住。
3.4 网络设备日志
网络设备日志主要指交换机、路由器、防火墙(注意防火墙也归在网络设备类,但安全日志另成一类)、负载均衡器产生的日志。它们最常用的协议是 syslog(UDP 514)和 SNMP Trap。
网络日志的特点是:格式碎片化。各家厂商(Cisco、Huawei、H3C、Juniper)的 syslog 前缀和字段位置都不一样。举个例子:
Cisco: %ASA-6-302015: Built inbound TCP connection 12345 for outside:192.168.1.1/80 ...
Huawei: %IFNET/4/LINK_STATUS(l): Interface GigabitEthernet0/0/1, changed state to UP
所以在采集网络日志时,我个人的习惯是进系统之前先做一层「格式归一化」。把不同厂商的时间戳、设备名、事件类型、源目 IP 全部提取成统一字段。这样后续写告警规则才能一条通杀。
网络日志的归并也很关键。交换机会频繁发送链路振荡、端口 up/down 的消息,如果不做归并,一个小时内可能收到几十万条一模一样的日志。归并后再入库,既能节省存储也能保留趋势信息。
3.5 安全设备日志
安全设备日志包括:IDS/IPS、WAF、VPN、终端安全软件、DLP、蜜罐等。这些日志可以说是安全审计中最「含金量」最高的,因为它们直接反映攻击行为。
安全日志的典型特征:
- 告警级别高:大量 ERROR、CRITICAL 级别事件
- 字段丰富:通常包含源 IP、目的 IP、攻击类型、payload 摘要、风险评分
- 误报多:安全设备很多基于规则匹配,规则太严则误报如潮
我举个例子,WAF 日志通常长这样:
{
"timestamp": "2024-05-12T10:30:00.000Z",
"client_ip": "203.0.113.42",
"method": "POST",
"uri": "/api/login",
"rule_id": "942100",
"action": "block",
"severity": "2",
"payload": "username=admin' OR '1'='1",
"device_vendor": "ModSecurity"
}
3.6 一张图看清所有日志来源
讲了这么多,是不是觉得有点乱?我画了一张图,把五类日志和它们的核心特征、采集关键点串起来。你看一眼就清楚了。
图中五种日志类型各有侧重,但最终采集流程都要经过「采集→解析→归一→缓冲→存储」这五步。不同之处在于采集协议和解析器——syslog 用 rsyslog 或 syslog-ng,应用日志用 filebeat 或 fluentd,数据库日志用 canal 或 Debezium。
3.7 课后碎片:一些我踩过的坑
最后,我分享几个真实教训:
- 别信设备的时间戳——我有一次查安全事件,WAF 日志时间和系统日志时间差了 4 个小时,就因为它 NTP 配置错了。从那以后,我每条日志都加上采集端的接收时间。
- 应用日志别打超大 payload——一个项目中接口传了 base64 图片,日志一行 2MB,采集 agent 直接 OOM。现在我在代码规范里强制限定日志单条不超过 10KB。
- 网络日志的归并窗口要够大——有些链路振荡每秒钟发 200 条 up/down,如果归并窗口只有 30 秒,还是会被刷爆。我一般设 5 分钟。
日志来源搞清楚之后,下一步就是设计采集架构了。不过别急,我们后面会专门讲采集层的拓扑和可靠性设计。你先把这张图的五类日志和各自的采集要点记住,后面遇到具体项目,就能直接对号入座。