Logstash 不适合直接采集 Linux 系统日志,因其 file 插件无法可靠处理 logrotate 切割、inode 变更、权限限制及 journald 二进制格式,易导致丢行、乱序、漏日志;应由 rsyslog 或 journald 先标准化转发至 Logstash 的 tcp/syslog 输入插件。

Logstash 不适合直接采集 Linux 系统日志(如 /var/log/messages 或 journald),它本身不监听文件变化、不轮询、不处理二进制日志格式,强行用 file 输入插件读取系统日志文件极易丢行、乱序、漏权限错误,且无法感知 logrotate 切割行为。
为什么别用 Logstash 直接读 /var/log/ 下的原始日志文件
Logstash 的 file 输入插件基于 inotify + offset 记录,但系统日志文件常被 rsyslog 或 systemd-journald 持续追加写入,同时又被 logrotate 重命名或清空 —— 这会导致:
-
logrotate执行copytruncate时,Logstash 会丢失从截断点到下一次扫描之间的所有日志 - 多个进程(如 rsyslog + Logstash)同时写/读同一文件,触发 inode 变更,offset 记录失效
- 日志权限通常为
root:adm,Logstash 若非 root 运行则根本打不开/var/log/auth.log等敏感文件 - journalctl 输出是二进制结构化数据,
file插件只能当纯文本读,丢失UNIT、PRIORITY、_HOSTNAME等关键字段
正确做法:让 rsyslog 或 journald 先把日志转成 Logstash 能稳收的格式
Logstash 是管道型工具,不是日志源头代理。应由系统日志服务完成采集、缓冲、格式标准化,再通过网络协议转发给 Logstash:
- 若用
rsyslog:在客户端配@@192.168.1.100:5044(TCP)转发到 Logstash 的tcp输入插件,服务端 Logstash 配codec => "json"或"syslog" - 若用
systemd-journald:启用ForwardToSyslog=yes,再让 rsyslog 转发;或直接用 Logstash 的syslog输入插件监听 UDP/TCP 514(不推荐);最优是启用journald的export接口,配合exec输入调用journalctl -o json --no-tail -n 1000增量拉取 - 绝对不要在 Logstash 配置里写
path => "/var/log/*.log"—— 这是生产环境最常见误配,排查时会发现日志断层、时间戳错乱、重复发送
Logstash 安装后必须改的三个配置点
Debian/Ubuntu 上用 APT 安装后,/etc/logstash/conf.d/ 下默认无有效配置。需手动创建一个,例如 01-syslog-input.conf,并确保以下三项明确设置:
-
input { tcp { port => 5044 codec => "json" } }:用 JSON 格式接收,比 syslog 原生格式更易解析字段;客户端 rsyslog 必须配RSYSLOG_ForwardFormat模板输出 JSON -
filter { if [host] == "localhost" { mutate { add_field => { "host_ip" => "%{[host]}" } } } }:避免host字段被覆盖为容器名或主机名,显式提取真实 IP -
output { elasticsearch { hosts => ["http://192.168.1.100:9200"] index => "syslog-%{+YYYY.MM.dd}" } }:强制按天分索引,否则单索引过大导致 Elasticsearch 写入阻塞或查询变慢
验证日志是否真正进到 Logstash 而非“看似通了”
很多用户看到 systemctl status logstash 显示 active,就以为通了,其实可能卡在编码、字段映射或防火墙。检查要点:
- 在 Logstash 服务器上执行
sudo ss -tlnp | grep :5044,确认logstash进程真正在监听,而非被 systemd-journald 占用该端口 - 客户端临时用
logger "test from $(hostname)"发一条日志,然后立刻在 Logstash 服务器上tail -f /var/log/logstash/logstash-plain.log查看是否有 decode error 或 connection refused - 如果用 JSON 格式,但客户端没加
$ActionForwardDefaultTemplate RSYSLOG_ForwardFormat,Logstash 会收到纯文本,codec => "json"解析失败,日志直接进dead_letter_queue而不报错 - Logstash 默认不开启
dead_letter_queue,需在/etc/logstash/logstash.yml中设dead_letter_queue.enable: true并指定路径,否则解析失败的日志静默丢弃
真正难的不是装 Logstash,而是让它和系统日志服务之间不抢资源、不错位、不丢字段。只要绕开直接读文件这个坑,剩下的就是配好输入协议、字段提取和输出目标 —— 其他都是体力活。











