Linux 日志集中收集与分析方法

3次阅读

rsyslog远程转发丢日志因未启用磁盘队列,需配置$actionqueuefilename、$actionqueuemaxdiskspace和$actionresumeretrycount,并检查防火墙514端口。

Linux 日志集中收集与分析方法

rsyslog 配置远程转发时收不到日志?检查 $ActionQueue* 参数和防火墙

默认 rsyslog 不启用磁盘队列,网络抖动或接收端宕机时日志直接丢弃,不是配置写错了,是没开可靠传输。

  • $ActionQueueFileName 必须设置(如 rsyslog_queue),否则队列仅在内存中,重启即清空
  • $ActionQueueMaxDiskSpace 建议设为 1g 以上,小值会导致队列满后静默丢日志
  • $ActionResumeRetryCount -1 让它无限重试,别用默认的 360 次(约 1 小时)
  • 确认 firewall-cmd --list-ports 包含 514/udp514/tcp,UDP 转发尤其容易被防火墙吞掉包

用 Filebeat 抓 nginx access.log 却漏日志?注意 logrotate 和 inotify 限制

Filebeat 默认靠 inotify 监听文件变化,但 logrotate 切日志时可能 rename + create,inotify 会丢失中间段;更糟的是,如果日志轮转太快,Filebeat 还没读完就被 mv 走了。

  • filebeat.ymlinput 下加 close_inactive: 5mclean_inactive: 72h,避免过早关闭或清理句柄
  • 确保 logrotate 配置里有 copytruncate(不推荐)或改用 create + delaycompress,让 Filebeat 能自然追到新文件
  • 若日志量大、轮转频繁,把 harvester_buffer_size 提到 16384,减少 read() 系统调用次数

Logstash Filter 中 grok 失败率高?先用 dissect 替代,再针对性补 grok

grok 在正则匹配上开销大,且一旦 pattern 写错就整条日志丢弃或卡住字段;而 Nginx、Syslog 这类结构化程度高的日志,dissect 更快更稳。

  • nginx.access 日志优先用 dissect { mapping => { "message" => "%{clientip} - %{ident} [%{timestamp}] "%{method} %{url} %{http_version}" %{status} %{size}" } }
  • 只有 timestamp、useragent 等需解析的字段,再套一层 dateuseragent filter,别全在 grok 里
  • 上线前务必用 logstash -f test.conf --config.test_and_exit 验证语法,grok 错误不会报错,只会让 [tags] 出现 _grokparsefailure

Elasticsearch 存日志查得慢?别只加节点,先关掉不必要的 mapping 动态推断

日志字段名千奇百怪(比如 trace_id_v2traceIdVersion2),ES 默认开启 dynamic: true,每来个新字段就自动建 mapping,索引变胖、查询变慢、甚至触发 circuit_breaking_exception。

  • 在 index template 里显式设 "dynamic": "strict",字段不在 mapping 里就直接拒收,逼着你提前规范日志格式
  • 所有 text 字段加 "index": false(除非真要全文搜),比如 message 保留,但 request_idtrace_id 改成 keyword
  • 时间字段必须用 date 类型,并确保 date_detection: false,否则 ES 可能把 "2024-05-20"字符串索引

真正难的不是堆工具链,而是让每一行日志从产生那一刻起,字段名、类型、生命周期都可控。轮转策略、队列参数、mapping 定义——这些地方不动手压一压,后面查不出、存不下、丢得悄无声息。

text=ZqhQzanResources