3. 日志来源与类型:系统日志、应用日志、数据库日志、网络设备日志、安全设备日志

日志采集的第一步,也是最容易被忽略的一步,是搞清楚日志到底从哪来。你想想看,如果我们连源头都搞不清,后面谈什么安全存储、关联分析,都是空谈。我个人习惯把日志来源分成五大类:系统、应用、数据库、网络设备、安全设备。每一类的脾气秉性都不一样,采集策略也得对症下药。

好,我们一个一个来过。

3.1 系统日志

系统日志是所有日志的基础设施。说白了,它记录的是操作系统本身的运行状态。Linux 下主要是 syslog/rsyslog,Windows 下则是 Event Log。我在这里踩过最大的坑,是以为系统日志不重要。

实用经验:Linux 系统日志的 PID(进程ID)是排查故障的关键线索。很多人在采集时会把 PID 丢掉,觉得省空间,结果事后根本定位不了是哪个进程出了问题。

常见系统日志类型:

  • 系统启动/关机日志:记录系统启停时间、异常重启原因
  • 用户登录/登出日志:SSH 登录、本地登录记录(/var/log/wtmp)
  • 内核日志:驱动加载、硬件错误、OOM 事件
  • Cron 日志:定时任务执行情况
  • sudo 日志:特权命令执行记录(审计必备)

避坑指南(我曾经…):我曾经遇到过客户把全部 syslog 存为一个文件,不做轮转,结果单文件 300GB 打不开。后来改造的时候用了 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 级别含) 建议采集并截断

个人经验:我见过最头疼的应用日志是那种把敏感信息直接打在 message 里的——身份证、银行卡号、密码明文。采集层一定要加脱敏过滤,否则安全审计就是搬起石头砸自己的脚。

采集应用日志时,有个常见陷阱:日志输出到文件 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 的 General Log 开启后,生产环境 QPS 可能直接掉 20%。我一般不推荐全量开启。正确的做法是只开审计相关的前置规则——比如只记录 DDL 和 DCL,不记录 DML。

以 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 的消息,如果不做归并,一个小时内可能收到几十万条一模一样的日志。归并后再入库,既能节省存储也能保留趋势信息。

实用建议:采集网络设备日志,一定要做时间偏差校准。很多老设备 NTP 没配好,日志时间可能差好几个小时。我通常的做法是,在采集时用系统时间覆盖设备时间字段,并保留设备原始时间作为 meta。

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"
}

核心观点:安全设备日志不能单独看。你要把 WAF 拦截的 IP 和系统日志里暴力破解的 IP 做关联,才能发现真正的攻击链。所以我的建议是:安全日志一定要和系统/应用日志走同一个时序数据库,否则关联分析就是纸上谈兵。

3.6 一张图看清所有日志来源

讲了这么多,是不是觉得有点乱?我画了一张图,把五类日志和它们的核心特征、采集关键点串起来。你看一眼就清楚了。

五类日志来源与采集关键点 日志来源分类 1. 系统日志 syslog / Event Log 内核、登录、sudo、cron 采集关键:PID + 主机名 2. 应用日志 log4j / Logback / Fluentd 结构化+trace_id 采集关键:脱敏+标准字段 3. 数据库日志 binlog / WAL / redo log DDL/DCL 优先 采集关键:Kafka缓冲+解析 4. 网络设备日志 Cisco / Huawei / Juniper syslog / SNMP Trap 采集关键:格式归一+归并 5. 安全设备日志 IDS/IPS/WAF/DLP 告警关联+误报过滤 采集关键:时序+关联分析 核心原则:统一时间、统一格式、统一存储 —— 无论来源,最终都要归一化

图中五种日志类型各有侧重,但最终采集流程都要经过「采集→解析→归一→缓冲→存储」这五步。不同之处在于采集协议和解析器——syslog 用 rsyslog 或 syslog-ng,应用日志用 filebeat 或 fluentd,数据库日志用 canal 或 Debezium。

3.7 课后碎片:一些我踩过的坑

最后,我分享几个真实教训:

  1. 别信设备的时间戳——我有一次查安全事件,WAF 日志时间和系统日志时间差了 4 个小时,就因为它 NTP 配置错了。从那以后,我每条日志都加上采集端的接收时间。
  2. 应用日志别打超大 payload——一个项目中接口传了 base64 图片,日志一行 2MB,采集 agent 直接 OOM。现在我在代码规范里强制限定日志单条不超过 10KB。
  3. 网络日志的归并窗口要够大——有些链路振荡每秒钟发 200 条 up/down,如果归并窗口只有 30 秒,还是会被刷爆。我一般设 5 分钟。

日志来源搞清楚之后,下一步就是设计采集架构了。不过别急,我们后面会专门讲采集层的拓扑和可靠性设计。你先把这张图的五类日志和各自的采集要点记住,后面遇到具体项目,就能直接对号入座。