在印度跑日志采集,Filebeat 时区字段差半小时的排查过程

印度区服务器的系统时区是 IST(UTC+5:30),这个半小时偏移在日志采集链路上会以很隐蔽的方式暴露出来。我用 Filebeat 7.17 往 Elasticsearch 7.17 推 nginx access 日志,单机每天约 400 万行,压测阶段就发现时间戳对不上。

现象是:nginx 日志里的时间是 10:00:00 +0530,Filebeat 送进 ES 的 @timestamp 落在 04:30:00Z,看起来没问题;但用 Kibana 按小时做直方图时,柱子和本地时间错开半格,运营同事看“上午 10 点”的流量会落到 9:30 的桶里。

先确认输入格式。nginx 的 log_format 里带 $time_iso8601,输出的就是 2024-03-11T10:00:00+05:30。Filebeat 的配置最初是这样的:

processors:
  - add_locale:
      format: abbreviation

问题出在 add_locale 只往事件里加一个本地时区缩写 event.timezone: IST,它不改任何时间字段。Kibana 的 date_histogram 默认按 UTC 分桶,所以半格偏移不是采集错了,是展示层没指定时区。

我的做法分两步。第一步不改采集端,先在 Kibana 的索引模式里把 Advanced 的 timezone 设成 Asia/Kolkata。直方图立刻对齐,但导出 CSV 时又回到 UTC,说明这只能救看板。第二步在 Filebeat 里明确解析时间,确保 ES 里存的是正确 UTC 点:

filebeat.inputs:
  - type: filestream
    paths:
      - /var/log/nginx/access.log
    parsers:
      - ndjson:
          target: ""
          overwrite_keys: true
          add_error_key: true
processors:
  - timestamp:
      field: time_iso8601
      layouts:
        - '2006-01-02T15:04:05-07:00'
      test:
        - '2024-03-11T10:00:00+05:30'
      timezone: 'Asia/Kolkata'

解析之后 @timestamp 是 04:30:00Z,跨时区查询才不会错。代价是每条事件多一次时间解析开销,400 万行的量在 2 核 4G 机器上 CPU 涨了约 5%,可以接受。

会失效的地方有三个。一是如果 nginx 用的是 $time_local(格式 11/Mar/2024:10:00:00 +0530),layout 要换成 02/Jan/2006:15:04:05 -0700,写成 ISO 的 layout 会整批丢弃并落到 error.message。二是 timezone 字段在 Filebeat 识别不了区域名时静默退化为 UTC,我一开始写成 IST 就中招,它不报错,只在日志里打一行 warning。三是用 Logstash 的 date filter 时如果同时配置了 timezone 和带偏移量的 pattern,偏移量会覆盖 timezone,两种写法不要混用。

你们那边日志时间戳是让采集端解析,还是靠 ingest pipeline 的 date processor 兜底?

0
赞同度 100% · 0 条评论 · 8 阅读

0 条评论

支持 Markdown · 回复会实时推送给对方

还没有评论,写下第一条。