4、日志采集入门:文件采集(tail -f)、网络采集(Syslog)、Agent采集(Filebeat/Logstash)
日志检索这件事,地基就是采集。你想想看,后面再牛的检索分析,如果数据进不来或者进来就是脏的,那全白搭。这一章,咱们就把三种最主流的采集方式掰开揉碎讲清楚。
我个人习惯把采集分为三代:第一代是直接读文件,第二代是收网络流,第三代是专用 Agent。别觉得老方法就该淘汰,实际项目中往往是三代混着用。
4.1 文件采集:最朴素但最可靠
说白了就是读文件。Linux 下 tail -f 大家都会用,但生产环境里可没这么简单。我见过太多人直接用 tail -f 重定向到另一个文件,结果进程一挂,日志全丢。
文件采集的核心机制其实就两个:
- 轮询(Polling):每隔几秒去检查文件有没有新内容。简单,但浪费 IO。
- 通知(inotify/FSEvents):操作系统告诉你文件变了。高效,但实现复杂。
嗯,这里要注意:大部分生产工具用的是「轮询 + inotify 兜底」的策略。Filebeat 就是这么干的——优先用 inotify,如果内核不支持就回退到轮询。
tail -f 完全够用。但要是做长期采集,一定要考虑「断点续传」。我曾经踩过一个坑:服务器重启后,采集脚本从文件头开始重新读,结果把几 GB 的历史日志又发了一遍,直接把下游的 Kafka 打挂了。
文件采集的典型场景:
- 应用日志(Java 的
application.log、Nginx 的access.log) - 系统日志(
/var/log/messages、/var/log/syslog) - 容器日志(Docker 的
stdout/stderr重定向文件)
4.2 网络采集:Syslog 的前世今生
Syslog 是个老古董了,1980 年代就有了。但你别小看它,网络设备、防火墙、路由器到现在还在用。说白了,它就是「设备把日志通过网络扔给你,你爱收不收」。
Syslog 的传输方式:
| 协议 | 端口 | 可靠性 | 适用场景 |
|---|---|---|---|
| UDP | 514 | 低(无确认) | 内网、非关键日志 |
| TCP | 514 / 1468 | 中(有确认) | 需要可靠传输 |
| RELP | 20514 / 2514 | 高(应用层确认) | 关键业务日志 |
我个人建议:能用 TCP 就别用 UDP。UDP 虽然快,但丢包了你根本不知道。我曾经帮一个客户排查问题,发现他们的网络设备用 UDP 发 Syslog,高峰期丢包率超过 30%,但监控面板上一切正常——因为丢包了也不报错。
Syslog 的典型架构:
网络设备/服务器
↓ UDP/TCP
Syslog 接收器(rsyslog/syslog-ng)
↓ 过滤/格式化
日志文件 或 直接转发到 Kafka/ES
4.3 Agent 采集:Filebeat 和 Logstash 怎么选?
这是目前最主流的方式。Agent 说白了就是一个轻量级程序,装在目标机器上,负责读日志、做简单处理、然后发走。
ELK 生态里两个主力:
- Filebeat:轻量级采集器。Go 写的,资源占用极低。适合只做「采集 + 转发」。
- Logstash:重量级处理器。Java 写的,功能强大但吃内存。适合做「采集 + 复杂处理 + 转换」。
我一般这么分:
| 对比维度 | Filebeat | Logstash |
|---|---|---|
| 资源占用 | 低(10-50MB 内存) | 高(256MB-1GB 内存) |
| 处理能力 | 简单过滤(include/exclude) | 复杂转换(grok、mutate、date) |
| 输出插件 | Elasticsearch、Logstash、Kafka | 50+ 种输出 |
| 部署方式 | DaemonSet / 二进制 | 独立服务 / 容器 |
| 典型用法 | 每台机器装一个 | 集中部署几台做处理 |
Filebeat 的配置其实很简单。我贴一个最常用的例子:
# filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/nginx/access.log
- /var/log/nginx/error.log
multiline:
pattern: '^\d{4}-\d{2}-\d{2}'
negate: true
match: after
output.elasticsearch:
hosts: ["http://elasticsearch:9200"]
index: "nginx-%{+yyyy.MM.dd}"
嗯,这里有个关键点:multiline 配置。Java 异常栈、Python traceback 都是多行日志。如果不做 multiline 合并,一条异常会被拆成几十条记录,检索时根本没法看。我刚开始用 Filebeat 时就吃过这个亏,查了半天才发现是 multiline 没配。
Logstash 的配置稍微复杂点,但功能确实强:
# logstash.conf
input {
beats {
port => 5044
}
}
filter {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}" }
}
date {
match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
}
mutate {
remove_field => [ "message" ]
}
}
output {
elasticsearch {
hosts => ["http://elasticsearch:9200"]
index => "weblog-%{+yyyy.MM.dd}"
}
}
你看,Logstash 的 filter 可以做 grok 解析、时间戳转换、字段删除。这些在 Filebeat 里做不了,或者做起来很别扭。
4.4 三种方式怎么选?一张表说清楚
| 场景 | 推荐方式 | 理由 |
|---|---|---|
| 临时排查问题 | tail -f | 零部署,用完即走 |
| 网络设备日志 | Syslog (TCP) | 设备只支持 Syslog |
| 应用日志(标准格式) | Filebeat | 轻量,够用 |
| 应用日志(需解析) | Filebeat + Logstash | 采集轻量,处理灵活 |
| 容器环境(K8s) | Filebeat DaemonSet | 官方支持,配置简单 |
| 高吞吐、低延迟 | Filebeat + Kafka | 削峰填谷,保证不丢 |
最后说一句:采集是日志检索的起点,但也是最容易被忽视的环节。你想想看,如果采集端就丢了数据、乱了格式,后面 Elasticsearch 再牛也救不回来。所以,花时间把采集搞扎实,值得。