2. 审计日志收集与存储:从源头到仓库

日志收集和存储,说白了就是给审计模型「喂料」。料不好,模型再牛也白搭。我在前公司接过一个告警泛滥的项目,查了半天才发现是日志采集端重复投递——同一个登录行为被送了三次。你想想看,模型学到的全是假相关,能不误报吗?

这一节,咱们就聊透日志怎么收、存成什么样、怎么压缩最划算。

2.1 主流日志收集工具怎么选

工具有很多,但真正在生产环境里扛过大流量的,我个人常用这三类。

工具 架构特点 吞吐能力 我的选择场景
ELK (Elastic + Logstash + Kibana) 开源,插件丰富,Logstash 可做过滤 单机 10~50k events/s 中小团队、快速搭建
Splunk 商用,自带搜索语言 SPL,索引快 单节点百万级 events/s 安全审计合规严格、预算充裕
Filebeat + Kafka + Logstash 轻量采集 + 缓冲 + 过滤 分布式可达百万级 高并发、要求零丢失
个人习惯:我会先用 Filebeat 做边缘采集,保证不影响业务性能;中间放 Kafka 做削峰填谷;后端再用 Logstash 或 Elasticsearch Ingest Pipeline 做结构化。三步分离,排查方便很多。

2.1.1 ELK 典型部署

ELK 的组件分工很清晰:Filebeat 负责扛采集压力,Logstash 做转换,Elasticsearch 存和搜,Kibana 展示。我曾在一个日均 5 亿条审计日志的客户现场,直接用 Filebeat + Logstash 压垮了 Logstash 的 heap——原因很简单,没加 Kafka 缓冲。后来加了 Kafka 做缓冲,稳如老狗。

# Filebeat 配置示例(采集系统审计日志)
filebeat.inputs:
- type: log
  paths:
    - /var/log/audit/audit.log
  fields:
    log_source: linux_audit

output.kafka:
  hosts: ["kafka1:9092", "kafka2:9092"]
  topic: "audit-logs"
  required_acks: 1

2.1.2 Splunk 的通用转发器

Splunk 虽然贵,但它的索引器性能确实强。我记得有一次合规检查需要保留 1 年日志,用 ELK 算了一下存储成本,最后换成 Splunk 的智能压缩,总存储反而省了 40%。它的采集端叫 Universal Forwarder,非常轻量,大约只占 5% CPU。

2.2 存储格式:结构化 vs 半结构化

审计日志最头疼的就是格式不统一。有的系统输出 JSON,有的输出 syslog,还有的是自定义二进制。咱们必须统一成一种方便分析的结构。

  • JSON:可读性好,支持嵌套,Elasticsearch 原生支持。缺点是冗余较大,每条日志都带字段名。
  • Avro:带 Schema 的二进制格式,序列化后体积小。适合 Kafka 存储。
  • Parquet:列式存储,压缩率极高。适合历史归档和批量分析(比如 Spark 查询)。

避坑指南:我曾经把审计日志全存成 JSON 放在 Elasticsearch 里,结果字段数量爆炸——每个日志源自定义字段不一样,导致 mapping 膨胀。后来强制使用 flatten 模式,把嵌套打平,索引速度提升了 3 倍。

下面是我常用的一条审计日志标准化字段清单:

字段 类型 说明
timestamp ISO8601 事件发生时间
source_ip string 源 IP
user_id string 操作者 ID
action string 操作类型(login, delete, modify)
target_resource string 操作对象
result string 成功/失败/拒绝
raw_data text 原始日志全文(用于回溯)

2.3 压缩策略:省多少?怎么省?

日志量一大,存储成本就变成大头。我见过有人直接用 gzip 压缩 Elasticsearch 的索引,结果查询性能从 200ms 变成了 2s。嗯,这里要注意——压缩要分场景。

  • 实时索引(Hot 层):Elasticsearch 默认使用 best_compression(LZ4 变种),压缩比约 1:3,不影响搜索速度。我个人不推荐额外加 gzip。
  • 温存储(Warm 层):可以使用 zstd,压缩比 1:5~1:8,解压速度比 gzip 快。适合 7~30 天内的数据。
  • 冷归档(Cold 层):使用 gzip -9 或 bzip2,压缩比可达 1:10~1:15。查询时需要解压到临时检索区。
注意:不要在压缩的同时做行内加密,否则压缩率会急剧下降。我在一个项目里看到有人用 AES 加密后再 gzip,结果压缩比只有 1:1.2——几乎没压缩。应该先压缩后加密,或者使用支持加密的压缩格式如 zip -e。

2.4 整体知识结构图

下面这张图概括了日志从采集、传输、存储到压缩的全链路。你可以把它当作本节的思维导图。

审计日志收集与存储知识结构 日志采集 Filebeat Splunk UF Syslog-ng 传输缓冲 Kafka Redis RabbitMQ 转换过滤 Logstash Grok/正则 字段标准化 存储引擎 Elasticsearch Splunk Indexer 压缩策略 LZ4 / Zstd Gzip / Parquet 冷归档 HDFS / S3 💡 核心原则 先缓冲再过滤 → 先压缩再归档

2.5 存储架构的实际选择经验

选型时别光看 benchmark。我遇到过一家金融客户,要求日志不能出数据中心,那就只能放弃云上的 S3。最后用了本地 HDFS + Parquet 压缩,每天 8TB 的审计日志压缩到 1.2TB。还有个场景——你要做实时异常检测,就不能等 Logstash 慢慢解析,得用 Elasticsearch Ingest Pipeline 边收边解析,延迟控制在 5 秒以内。

个人建议:先把审计日志按标签分为「热」(最近7天)、「温」(8~30天)、「冷」(30天以上)。热层用 Elasticsearch + LZ4,温层用 Elasticsearch + Zstd + 索引滚动,冷层用 Parquet + Gzip 存放 HDFS。这样成本和性能就能平衡好。

关于压缩策略,我再补充一个细节——broker-side compression 在 Kafka 里也很关键。如果日志被打成 JSON 直接发 Kafka,可以把 producer 的压缩设为 snappy 或 zstd,吞吐能提升 2~3 倍。嗯,这算是我踩过的坑之一:一开始没开压缩,Kafka 磁盘直接写爆。