日志数据基础

要说日志,得先聊聊我入行时的一个教训。刚做运维那会儿,系统半夜报警,我翻了一小时日志才找到根因——原来是个空指针异常。那时候我就想,要是日志能规规矩矩地待在一起,有个统一格式,该多省事。后来我才明白,日志的格式、类型、收集方式,是所有自动化分析的地基。这一节,咱们就把地基打扎实。

日志格式

日志格式五花八门。但归类下来,绝大多数逃不出下面这几种。

格式特点典型场景
Syslog标准协议,时间/主机/严重级别/消息Linux系统日志、网络设备
JSON结构化,键值对,解析方便微服务、API网关、云平台
CSV / TSV定界符分隔,批量导入快传统应用、数据库审计
自定义文本非结构化,正则匹配噩梦老旧业务系统
二进制日志MySQL binlog 这类,需专用工具数据库、中间件
我的习惯: 只要是我经手的项目,我都会强制要求应用输出 JSON 格式日志。原因很简单——后期想做什么分析,不用再写一堆正则去拆字符串。

说到自定义文本,我记得有一次排查线上故障。日志里混着时间戳、线程ID、换行符全乱。我用 awk 和 sed 拆了一天,才把能用数据洗出来。从那以后,我特别推崇结构化日志。

日志类型

日志可以按来源区分为三大类:系统日志、应用日志、安全日志。咱们一个个看。

系统日志

系统日志由操作系统内核和系统服务产生。比如 /var/log/messages、/var/log/syslog。它们记录着硬件状态、进程启停、网络连接。我经常说,系统日志是服务器的“心电图”,心跳有没有乱,一看便知。

  • 来源:内核、systemd、cron、网络服务
  • 频率:持续不断,量很大
  • 关键字段:时间、模块、严重级别、进程ID

应用日志

应用日志的范围最广。Java 的 log4j、Python 的 logging、Nginx access log……哪个程序不写日志?应用日志通常包含业务层面的信息,比如用户登录、订单创建、接口耗时。异常检测最喜欢处理这类日志——因为异常直接反映在业务指标上。

  • 来源:业务代码、应用服务器、Web容器
  • 频率:跟用户流量正相关,有峰值
  • 关键字段:traceId、方法名、耗时、状态码

安全日志

安全日志来自防火墙、入侵检测、审计系统。它们记录着“谁、在什么时间、做了什么操作”。比如 /var/log/auth.log 记录 SSH 登录尝试。安全日志一般比较敏感,采集和存储都得注意合规。

  • 来源:auditd、firewalld、SELinux、WAF
  • 频率:偶发但重要
  • 关键字段:源IP、目标端口、动作、结果

在异常检测项目中,我一般会优先采集应用日志和系统日志。安全日志虽然量少,但误报率低,适合作为辅助特征。

日志收集工具

日志从分散的机器到集中分析平台,中间需要一根“管道”。目前业界最主流的管道有两个:ELK Stack 和 Flume。我工作中两个都用过,说说我的感受。

ELK Stack(Elasticsearch, Logstash, Kibana)

ELK 现在已经成了日志领域的“瑞士军刀”。Logstash 负责采集和转换,Elasticsearch 负责存储和搜索,Kibana 做可视化。整个链路从 agent 到展板,半小时就能搭起来。

# Logstash 配置片段(采集 syslog 并输出到 ES)
input {
  syslog {
    port => 514
    type => "syslog"
  }
}
output {
  elasticsearch {
    hosts => ["localhost:9200"]
    index => "syslog-%{+YYYY.MM.dd}"
  }
}

但这套方案也有坑。Logstash 虽然插件丰富,但内存消耗惊人。我曾经在 4G 的机器上跑 Logstash,直接 OOM 挂掉。后来我用 Filebeat 代替 Logstash 做 agent,Logstash 只做集中处理,总算稳定了。

Flume

Flume 是 Apache 家的老牌工具,架构是 agent → collector → sink。它的强项是可靠性和大吞吐量。Hadoop 生态里常用 Flume 把日志灌进 HDFS 或者 Kafka。

# Flume 配置:监控日志目录,写到 HDFS
agent.sources = s1
agent.sinks = k1
agent.channels = c1

agent.sources.s1.type = spooldir
agent.sources.s1.spoolDir = /var/log/app

agent.sinks.k1.type = hdfs
agent.sinks.k1.hdfs.path = /logs/app/dt=%Y%m%d

agent.channels.c1.type = memory
agent.channels.c1.capacity = 1000

agent.sources.s1.channels = c1
agent.sinks.k1.channel = c1
避坑提醒: Flume 的 memory channel 在宕机时会丢数据。如果业务要求不丢,换成 file channel 或者 Kafka channel。我曾经在生产环境用 file channel,虽然性能差一点,但数据一条没丢——放心。

日志数据流程概览

上面讲了格式、类型、工具,它们怎么串起来?我画了一张图,帮你快速建立整体认识。

日志数据从产生到分析的典型流程 应用日志(JSON) 系统日志(Syslog) 安全日志(Audit) 日志收集 Logstash / Filebeat / Flume 数据存储 Elasticsearch / HDFS 异常检测引擎 机器学习模型 → 告警 / 仪表盘 说明:收集层是关键——它决定了后面能拿到什么质量的数据。 我建议先统一日志格式(JSON),再用收集工具集中存储,最后喂给异常检测模型。

这张图就是典型的日志处理流水线。从各式各样的日志源,经过收集工具汇聚,存到搜索或大数据库里,最后交给异常检测模型。你想想看,如果日志格式不统一,第一个环节就得反复调配正则;如果选错了收集工具,后面清洗都困难。

小结