ELK日志收集和备份填坑实战 (滞后8个小时等时区问题)

ES的备份:ES快照备份
根据时间,每天零点在Linux机器crontab来调用api接口实现快照备份,通过快照备份,可以定准恢复到某一天的日志。
现象:(坑:但是恢复某一天日志,发现会少8小时的日志,基本是:0:00 - 08:00 时间段)

1、引言:

在大规模分布式系统中,ELK(Elasticsearch、Logstash、Kibana)栈已成为日志管理和分析的标准工具集。然而,实际部署与运维过程中,往往会遭遇各种挑战,其中时区问题导致的日志时间滞后尤为常见。本文将聚焦于解决ELK日志收集与备份过程中出现的滞后8小时等时区问题,分享实战经验与填坑策略。

2、问题现象与原因

1、剖析滞后8小时时区

现象描述:在Kibana上观察到的一个典型现象是,即使日志事件是在当地时间上午9点发生的,但在日志系统中显示的时间却是下午5点。这种时差问题会导致运维团队在实时监控和响应中遭遇不少困难,因为所有的日志数据都显示为8小时前的事件。

问题根源

这一问题通常由以下几个因素造成:

  1. 日志源端时区设置错误:
    日志生成时,很多系统默认使用格林尼治标准时间(GMT)来记录时间戳,而不是当地时间。如果日志源设备或服务的时区设置不正确,或未明确指定时区,就会在源头产生时间偏差。

  2. 传输过程中的时区处理不当:
    在日志数据的收集过程中,如使用Logstash或Filebeat等工具,若这些工具没有被正确配置为转换或识别正确的时区,它们在处理日志时会继续使用GMT时间戳,从而进一步传递错误的时间信息。

  3. Elasticsearch存储与展示的时区配置不当:
    Elasticsearch在存储时间数据时,默认使用UTC时间。如果在Elasticsearch或Kibana中没有设置正确的时区,即使原始日志的时间戳是正确的,展示时也会因为时区转换错误而导致时间显示不正确

2、时区问题拆解

Elasticserch 默认时区是?能改吗?
官方文档强调:在 Elasticsearch 内部,日期被转换为 UTC时区并存储为一个表示自1970-01-01 00:00:00 以来经过的毫秒数的值。

Internally, dates are converted to UTC (if the time-zone is specified) and stored as a long number representing milliseconds-since-the-epoch.

https://www.elastic.co/guide/en/elasticsearch/reference/current/date.html

Elasticsearch date 类型默认时区:UTC。

正如官方工程师强调(如下截图所示):Elasticsearch 默认时区不可以修改
在这里插入图片描述
https://discuss.elastic.co/t/index-creates-in-different-timezone-other-than-utc/148941但,我们可以“曲线救国”,通过:

ingest pipeline 预处理方式写入的时候修改时区;
logstash filter 环节做时区转换;
查询时指定时区;
聚合时指定时区。

Kibana 默认时区是?能改吗?
kibana 默认时区是浏览器时区。可以修改,修改方式如下:Stack Management -> Advanced Settings ->Timezone for data formatting.
在这里插入图片描述
Logstash 默认时区是?能改吗?

默认:UTC。可以通过中间:filter 环节进行日期数据处理,包括:转时区操作。
在这里插入图片描述

  • logstash 默认 UTC 时区。
  • Elasticsearch 默认 UTC 时区。
  • Kibana 默认浏览器时区,基本我们用就是:东八区。
  • 如果基于Mysql 同步数据,Mysql 数据是:东八区。

3、填坑实战与解决方案

基于上面的分析,如何解决时区问题呢?。
实战项目中,时间问题就转嫁为:写入的时候转换成给定时区(如:东8区)就可以。
1、查看机器的时区和日志

/ # date
Mon Apr 15 11:21:29 CST 2024

在这里插入图片描述
2、Filebeaet 收集配置

filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /app/logs/app/*.log
  multiline.pattern: ^\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}[.,:]0{0,1}\d{3}
  multiline.negate: true
  multiline.match: after
  fields:
    logtype: ${LOGTYPE:app}

fields_under_root: true
fields:
  ip: ${POD_IP}

output.logstash:
  hosts: ["logstash-server.default.svc.cloudcs.fjf:5044"]

3、logstash 中间 filter 环节处理
数据源端:APP日志;
数据目的端:Elasticsearch;
同步方式:logstash,本质借助:logstash_input_jdbc 插件同步;
时区处理:logstash filter 环节 ruby 脚本处理。

{"@timestamp":"2024-04-15T10:48:34.518811962+08:00","severity":"INFO","service":"cat-outer-gateway","trace":"","span":"","parent":"","exportable":"","pid":"1","thread":"reactor-http-epoll-2","class":"c.fujfu.gateway.filter.CallBackUriFilter","rest":"path:/cat-payment-dock/api/minSheng/notify,method:POST\n"}
{"@timestamp":"2024-04-15T10:55:29.711692942+08:00","severity":"INFO","service":"cat-outer-gateway","trace":"","span":"","parent":"","exportable":"","pid":"1","thread":"reactor-http-epoll-4","class":"c.fujfu.gateway.filter.CallBackUriFilter","rest":"path:/cat-payment-dock/api/minSheng/notify,method:POST\n"}
2024-04-15 11:32:57.582  INFO [HzgDfyOvQqCH4DsY5Al7Jw] 1 --- [nio-8050-exec-9] c.f.f.s.impl.FpProductCfgServiceImpl     : capitalId:1724007481146916866-该用户渠道被限制,channelCodeList:[huawei, oppo, vivo, xiaomi, yingyongbao, yingyongbaotuiguang, Android_oppo, Android_yingyongbao, Android_huawei, Android_xiaomi, FYH-rongyao, FYH-vivo, FYH-xiaomi, FYH-huawei] ,userReqVO.getRegisterChannel():huawei
2024-04-15 11:32:57.695  INFO [TtPg4TgCQI+MFkLxSCZzMA] 1 --- [nio-8050-exec-2] c.f.f.s.f.request.JUZIFundProductCaller  : 【桔子数科】请求明文:https://api-gateway.jzhlkj.com/bus/standard/credit/queryQuota,参数:{"channelUid":"29443d29067c4182baec1115026cf8d5"}

下方的脚本就实现收集上方两种日志格式写入的时候转换成给定时区这个功能。

date 的数据 就是 东八区 的时间。我直接把 东八区的时间 写入@timestamp 在传入到ES(东八区) 。然后在 Kibana中访问 也是东八区,形成一个闭环

    input {
      beats {
        port => 5044
      }
    }

    filter {
      if [fields][json] == "true" {
        json {
          source => "message"
          remove_field => ["message","agent","tags","ecs"]
          add_field => {
            "loglevel" => "%{[severity]}"
          }
        }
      } else if [fields][logtype] == "powerjob" {
        grok {
          match => { "message" => "%{TIMESTAMP_ISO8601:date} \s{0,1}(?<severity>.*?) (?<pid>.*?) --- \[(?<thread>.*?)\] (?<class>.*?) \s*: (?<rest>.*+?)" }
          remove_field => ["message","agent","tags"]
          add_field => {
            "loglevel" => "%{[severity]}"
          }
        }
        mutate {
          update => { "[fields][logtype]" => "logstash" }
        }
      } else {
        grok {
          match => { "message" => [
                    "%{TIMESTAMP_ISO8601:date} (?<loglevel>.*?)\s{1,2}\| \[(?<threadname>.*?)\] (?<classname>.*?) \[(?<codeline>.*?)\] \| \[(?<traceid>.*?)\] \| (?<msg>.*+?)",
                    "%{TIMESTAMP_ISO8601:date} (?<loglevel>.*?)\s{1,2}\| \[(?<threadname>.*?)\] (?<classname>.*?) \[(?<codeline>.*?)\] \| (?<msg>.*+?)",
                    "\[%{TIMESTAMP_ISO8601:date}\] \[(?<loglevel>.*?)\s{0,2}\] \[(?<threadname>.*?)\] (?<classname>.*?) (?<codeline>.*?) - (?<msg>.*+?)",
                     "%{TIMESTAMP_ISO8601:date} \[(?<threadname>.*?)\] (?<loglevel>.*?)\s{0,2} (?<classname>.*?) (?<codeline>.*?) - (?<msg>.*+?)",
                     "\[%{TIMESTAMP_ISO8601:date}\] \[\s{0,2}(?<loglevel>.*?)\] \[(?<threadid>.*?)\] \[(?<threadname>.*?)\] \[(?<classname>.*?)\] : (?<msg>.*+?)"
                   ]}
          remove_field => ["message","agent","tags"]
        }
      }
      ruby {
        code =>'
        arr = event.get("host")["name"].split(".")[0]
        event.set("projectname",arr)
        '
      }
      date {
        match => ["date","ISO8601","yyyy-MM-dd HH:mm:ss.SSS"] #获取date的时间
        target => "@timestamp" # 复制给@timestamp 字段
        timezone => "Asia/Shanghai" # 设置 上海地区
      }

    }
    output {

      elasticsearch {
        hosts => ["elasticsearch-log.prod.server.fjf:9200"]
        user => "xxxxx"
        password => "xxxxx"
        manage_template => false
        index => "%{[fields][logtype]}-prod-%{+YYYY.MM.dd}"
      }
    }

修改前

在这里插入图片描述

修改后
在这里插入图片描述

在这里插入图片描述

4、总结

数据写入时间不一致、数据滞后8小时等时区问题的本质是:各个处理端时区不一致,写入源的时区、Kibana默认是本地时区(如中国为:东8区时区),而 logstash、Elasticsearch 是UTC时区。

参考文档:https://www.cnblogs.com/fat-girl-spring/p/15122906.html

  • 8
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Logstash可以将处理过的数据输出到Elasticsearch中,实现数据的存储和检索。具体的步骤如下: 1. 在Logstash的配置文件中,添加Elasticsearch的输出插件,指定Elasticsearch的地址和索引名称等参数。 2. 启动Logstash,它会读取指定的数据源,对数据进行处理,并将处理后的数据输出到Elasticsearch中。 3. 在Elasticsearch中,可以使用Kibana等工具进行数据的可视化和检索。 总的来说,Logstash和Elasticsearch是一对非常强大的组合,可以帮助我们快速构建数据处理和检索系统。 ### 回答2: Logstash是一个用于数据收集、处理和转换的工具,可以从不同的源获取数据并将其输出到各种目标存储。而Elasticsearch则是一个开源的分布式搜索引擎,它能够在高效、安全、可伸缩的基础上索引与搜索海量实时数据。 Logstash输出到Elasticsearch,是一种常见的数据处理和存储的方案,也是Elastic Stack(ELK)的一部分。这种方案可以结合多个数据源和数据格式,并通过logstash进行数据转换和处理,最终将收集的数据存储到Elasticsearch中,同时在Kibana中进行数据展示和分析。 为了实现这种方案,需要在Logstash中配置Elasticsearch插件,通过设置输出插件的类型和参数来指定Elasticsearch作为输出目标。在数据从不同源收集后,Logstash会将其进行过滤和转换处理,然后将处理后的数据输出到Elasticsearch中。 当数据存储到Elasticsearch中后,可以使用Kibana进行数据展示和分析。通过Kibana的图表和仪表盘 ,我们可以对数据进行实时监控,进行查询分析和可视化。同时,Elasticsearch还具有高效、可伸缩的实时搜索和分布式存储特性,可以支持海量数据的存储和查询。 总的来说,Logstash输出到Elasticsearch是一个实现实时数据收集和分析的强大工具和技术,可以帮助我们更好的理解数据,以便做出更好的决策和优化业务。 ### 回答3: Logstash是一种开源数据收集引擎,可以将不同来源的数据进行过滤、转换和聚合,最终输出到不同目的地。其中,输出到Elasticsearch是最常见的用例之一。 首先,我们需要安装和配置Logstash和Elasticsearch。Logstash的配置文件中需要指定输出插件为Elasticsearch,并配置Elasticsearch的IP地址和端口等参数。例如: ``` output { elasticsearch { hosts => ["127.0.0.1:9200"] index => "myindex-%{+YYYY.MM.dd}" } } ``` 上面的配置表示将数据输出到本地的Elasticsearch实例,并将索引的名称设为“myindex-年月日”的格式,可以实现按天切分索引,方便后续的查询和维护。 在Logstash中,我们可以使用不同的插件对数据进行处理和转换,以满足不同的需求。比如,使用grok插件将日志中的格式化信息提取出来,使用date插件解析时间戳等等。这些插件都可以在Logstash的插件库中找到,也可以自己编写插件满足特定的需求。 在输出到Elasticsearch时,Logstash会将数据转化为JSON格式,并根据指定的索引名称和类型进行索引。Elasticsearch提供了强大的搜索和聚合功能,可以对数据进行复杂的查询和分析。同时,Elasticsearch也支持分布式架构,可以横向扩展以处理海量数据和高并发量。 总之,Logstash输出到Elasticsearch是一种非常方便和实用的数据处理和分析方案,实现了数据的集中化和可视化,可以帮助我们更好地理解和利用数据。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南宫乘风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值