3、日志采集技术:日志来源、采集工具与架构设计

聊到日志采集,我脑子里第一个蹦出来的场景,是几年前帮一家金融科技公司做AI风控系统的安全合规审计。那会儿他们模型出了个误判,监管要求提供完整的推理日志。结果呢?日志散落在三台服务器上,格式五花八门,有的连时间戳都没对齐。嗯,那场面,真是让人头大。

所以你看,日志采集这件事,看着简单,其实门道不少。今天我就把这块掰开了讲清楚。

3.1 日志来源:系统、应用、模型

日志从哪来?说白了就三大类:系统层、应用层、模型层。每一层都有自己的脾气。

3.1.1 系统日志

系统日志是基础设施的「体检报告」。我习惯把它分成两类:

  • 操作系统日志:比如Linux的/var/log/messages、/var/log/secure。记录的是谁登录了、什么时候重启了、磁盘有没有报错。
  • 容器与编排日志:Docker的docker logs、K8s的kubectl logs。这些在微服务架构里特别重要。

我记得有一次排查模型训练节点的异常重启,最后就是在/var/log/kern.log里找到了OOM Killer的痕迹。嗯,内存不够用了。

3.1.2 应用日志

应用日志是业务逻辑的「监控摄像头」。常见的包括:

  • API访问日志:谁调了哪个接口、参数是什么、返回了什么。
  • 业务操作日志:用户做了什么事,比如「用户A修改了模型阈值」。
  • 错误日志:异常堆栈、数据库连接失败、超时等。

我个人建议,应用日志一定要带上请求ID和用户ID。为什么?因为出问题的时候,你要能串起一条完整的调用链。我在项目中遇到过,没有请求ID,排查一个线上问题花了整整两天——后来加了ID,半小时定位。

3.1.3 模型日志

这是AI安全合规里最特殊的一层。模型日志记录的是「模型在想什么」。具体包括:

日志类型 记录内容 合规用途
推理日志 输入特征、模型版本、输出结果、置信度 可解释性审计
训练日志 训练数据来源、超参数、loss曲线 数据溯源
漂移日志 特征分布变化、预测偏差 模型监控
反馈日志 用户对模型输出的反馈(点赞/踩) 持续改进
注意:模型日志里经常包含敏感数据。比如推理日志中的用户输入,可能涉及个人隐私。我曾经见过一个团队,把用户输入的明文直接写进了日志——这要是被审计到,合规直接亮红灯。所以,脱敏和加密是必须的。

3.2 采集工具:Filebeat 与 Fluentd

工具选型这块,我踩过不少坑。目前用得最多的两个,一个是Filebeat,一个是Fluentd。它们各有千秋。

3.2.1 Filebeat

Filebeat是Elastic生态里的轻量级采集器。它的特点就一个字:轻。

  • 资源占用极低:我测试过,采集10MB/s的日志流,CPU占用不到5%。
  • 配置简单:一个YAML文件搞定。
  • 原生支持Elasticsearch:如果你用ELK栈,Filebeat是首选。

来个简单的配置示例:

filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /var/log/model-inference/*.log
  fields:
    log_type: model_inference
    environment: production

output.elasticsearch:
  hosts: ["http://elasticsearch:9200"]
  index: "model-logs-%{+yyyy.MM.dd}"

你看,就这么几行,就能把模型推理日志采集到ES里。不过要注意,Filebeat对日志的解析能力有限。它只管采集和转发,复杂的日志解析得靠Logstash。

3.2.2 Fluentd

Fluentd就不一样了。它更像一个「日志路由器」。我习惯用它来做统一采集和预处理。

  • 插件生态丰富:输入、输出、过滤,什么插件都有。
  • 内置解析能力:支持JSON、正则、CSV等多种格式。
  • 缓冲机制可靠:网络断了不会丢日志。

举个例子,假设你的模型日志是JSON格式,但需要脱敏后再发送:

<source>
  @type tail
  path /var/log/model-inference/*.log
  format json
  tag model.inference
</source>

<filter model.inference>
  @type record_transformer
  <record>
    user_id ${record["user_id"].gsub(/.(?=.{4})/, "*")}
  </record>
</filter>

<match model.inference>
  @type elasticsearch
  host elasticsearch
  port 9200
  logstash_format true
</match>
我的建议:如果团队规模小、日志量不大,用Filebeat就够了。如果日志量大、格式复杂、需要灵活路由,Fluentd更合适。我现在的做法是:Filebeat做边缘采集,Fluentd做中心汇聚。

3.3 采集架构设计

架构设计这块,我总结了一个原则:分层采集,统一汇聚。说白了,就是每个节点只负责采集自己的日志,然后统一发到中心。

3.3.1 常见架构模式

我见过三种主流架构:

  1. 直连式:采集器直接写入存储。简单,但耦合度高。
  2. 代理式:采集器发给消息队列(Kafka),再由消费端写入存储。解耦,但多了个组件。
  3. 边车式:每个Pod里跑一个采集器。适合K8s环境。

我个人最推荐的是代理式。为什么?因为AI安全合规要求日志不能丢。Kafka的持久化机制能保证这一点。我曾经遇到过,直连式架构下ES集群挂了,日志直接丢了两个小时——从那以后,我再也不敢不用消息队列了。

3.3.2 一个实战架构

给你看看我现在用的架构:

+----------------+     +--------+     +-----------+     +----------------+
| 模型推理节点    |     |        |     |           |     |                |
| Filebeat采集   |---->| Kafka  |---->| Fluentd   |---->| Elasticsearch  |
| 系统/应用/模型  |     |        |     | 解析/过滤  |     | 存储/检索      |
+----------------+     +--------+     +-----------+     +----------------+
                                                              |
                                                              v
                                                       +----------------+
                                                       | 合规审计平台    |
                                                       | 告警/可视化    |
                                                       +----------------+

这个架构的好处是:

  • 解耦:采集和存储互不影响。
  • 可扩展:加节点只需要部署Filebeat。
  • 高可用:Kafka挂了,日志不会丢。
避坑指南:我曾经在Kafka的配置上栽过跟头。默认的log.retention.hours是168小时(7天),但合规要求日志保留180天。结果呢?审计的时候发现日志已经被删了。所以,一定要根据合规要求调整Kafka的保留策略。

3.3.3 采集策略

最后说说采集策略。不是所有日志都要实时采集。我习惯分三级:

优先级 日志类型 采集频率 说明
P0 模型推理日志、安全告警日志 实时 影响合规和安全的,一秒都不能等
P1 API访问日志、业务操作日志 近实时(1分钟内) 用于监控和排查
P2 系统性能日志、调试日志 批量(每小时) 用于容量规划和事后分析

你想想看,如果所有日志都实时采集,带宽和存储根本扛不住。所以,分级采集是必须的。

嗯,日志采集这块就聊到这儿。说白了,就是搞清楚「采什么、用什么采、怎么采」。下一章我们聊聊日志存储和索引,那又是另一番天地了。