关于可能是logstash导致的接口超时,同时附上filebeath代替logstash的案例

文章讲述了在SpringCloud项目中,由于日志收集系统(Logstash)出现问题导致服务接口超时,后来发现是由于云服务商网络异常和ES服务挂掉引起。为了解决日志收集与项目之间的耦合以及提高稳定性,作者决定弃用Logstash,改用Filebeat直接读取日志文件,同时对日志进行处理并直接发送到Elasticsearch,减少了中间环节,优化了资源使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目场景

本人在springcloud项目中引入了logstash的依赖然后通过logback往logstash里写: 如下


    <dependency>
        <groupId>net.logstash.logback</groupId>
        <artifactId>logstash-logback-encoder</artifactId>
        <version>5.3</version>
    </dependency>
   
    <appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
        <!--可以访问的logstash日志收集端口-->
        <destination>logstash的ip:4560</destination>
        <!-- 此处配置logstash的索引名称,在logstash.conf中配置了使用appname作为索引名称的一部分 -->
        <encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder">
            <customFields>{"appname":"back"}</customFields>
        </encoder>
    </appender>

    <!--root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性
         level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
         不能设置为INHERITED或者同义词NULL。默认是DEBUG
         可以包含零个或多个元素,标识这个appender将会添加到这个logger-->
    <root level="INFO">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="APPLICATION" />
        <appender-ref ref="LOGSTASH"/>
    </root>





问题描述

突然有一天晚上离奇的反馈说所有的接口均出现各种超时现象, 如下(部分超时截图)
部分超时截图

接着我打开云厂商管理页面查看CPU和内存和连接数和慢sql指标均正常,就特别离谱,我不知道是不是见鬼了。

唯一有个不正常的就是我搭建的ELK里面的es挂了,紧接着我联系云厂商的客服询问的同时把这个es重新启动,超时立马就没有了。

过了一段时间收到云厂商的回复,告知说这段时间云厂商服务器的网络设备有异常,已紧急修复。

看他回复的修复时间正好是我es的重启时间,我不相信什么巧合,我觉得这可能就是logstash等待es连接超时导致的问题,但是这次既然已经甩锅给云厂商那我就顺着台阶下了哈哈哈。

这个小疑问也只有我自己知道。





解决方案:

这个事情结束时候,我知道还是得有个后续的处理措施。

这边准备把收集日志跟项目做一下解耦, 不采取logback发送日志给logstash的方式。

而且公司给的服务器也抠门,一个2核4G的机器来做一个日志服务器,平时运行一个logstah和es内存就跑满了,这边准备淘汰掉logstash,采用filebeat部署在每台应用服务器上,使用filebeat直接读取日志文件的方式以此达到与java应用之间的一个解耦。

这边采用的也是多个java项目传输到多个es的索引中, filebeat.yml如下:


# filebeat读取文件的配置,可以配置多个
filebeat.inputs:


- type: log

  enabled: true

  paths:
    - /data/api/logs/api.log
  fields: 
    appname: api
  fields_under_root: true
    
    # 这里是为了保证多行日志插入到es里面是算一条,是按照时间前缀来将多条整合成一条,可以看下打印的异常栈,异常栈是打印多行,但实际上本身是一行
    # 是按照年-月-日的形式进行分割的,也就是上一步骤中的日志形式,这里需要根据自身实际的日志来进行配置。
  multiline.type: pattern
  multiline.pattern: '^[0-9]{4}-[0-9]{2}-[0-9]{2}'
  #multiline.pattern: '^\20'
  multiline.negate: true
  multiline.match: after

- type: log

  enabled: true

  paths:
    - /data/back/logs/back.log
  fields: 
    appname: back
  fields_under_root: true
  
    # 这里是为了保证多行日志插入到es里面是算一条,是按照时间前缀来将多条整合成一条,可以看下打印的异常栈,异常栈是打印多行,但实际上本身是一行
    # 是按照年-月-日的形式进行分割的,也就是上一步骤中的日志形式,这里需要根据自身实际的日志来进行配置。
  multiline.type: pattern
  multiline.pattern: '^[0-9]{4}-[0-9]{2}-[0-9]{2}'
  #multiline.pattern: '^\20'
  multiline.negate: true
  multiline.match: after
  
  
  

- type: filestream

  # Change to true to enable this input configuration.
  enabled: false

  # Paths that should be crawled and fetched. Glob based paths.
  paths:
    - /var/log/*.log


# ============================== Filebeat modules ==============================

filebeat.config.modules:
  # Glob pattern for configuration loading
  path: ${path.config}/modules.d/*.yml

  # Set to true to enable config reloading
  reload.enabled: false

setup.template.settings:
  index.number_of_shards: 1
  #index.codec: best_compression
  #_source.enabled: false


# This requires a Kibana endpoint configuration.
setup.kibana:


#根据读取文件时传入的字段决定插入哪个索引
# ---------------------------- Elasticsearch Output ----------------------------
output.elasticsearch:
  # Array of hosts to connect to.
  hosts: ["es的ip:9200"]
  indices:
    - index: "api-%{+yyyy.MM.dd}"
      when.contains:
        appname: "api"
    - index: "back-%{+yyyy.MM.dd}"
      when.contains:
        appname: "back"
       
        
        

processors:
  - script:
        lang: javascript
        id: my_filter
        tag: enable
        source: >
            function process(event){
              var str= event.Get("message");
              var time=str.split(" ").slice(0,2).join(" ");
              event.Put("start_time",time);
              var hostname = event.Get("agent.hostname");
              event.Put("hostname", hostname);
            }

  - timestamp:
      field: start_time
      timezone: Asia/Shanghai
      layouts:
        - '2006-01-02 15:04:05'
        - '2006-01-02 15:04:05.999'
      test:
        - '2019-06-22 16:33:51'
        - '2019-11-18 04:59:51.123'
  - drop_fields:
      fields: ["start_time","input", "agent", "ecs", "log", "host"]
     # fields: [start_time]



在配置中还把日志进行了一些处理再传送给es。

比如将java日志的开头中的时间戳传入到es里面的timestamp字段,如果不这样的话不方便查询(因为filebeat会把日志的所有内容都推送给es,而时间则是插入es的时间而不是日志的时间)。

还有比如把一些filebeat自动生成的字段给删掉,避免占用过大的存储空间。

经过了这些数据处理就不用再使用logstash进行了一道中间的传输。

关键配置是

processors:
  - script:
        lang: javascript
        id: my_filter
        tag: enable
        source: >
            function process(event){
              var str= event.Get("message");
              var time=str.split(" ").slice(0,2).join(" ");
              event.Put("start_time",time);
              var hostname = event.Get("agent.hostname");
              event.Put("hostname", hostname);
            }

  - timestamp:
      field: start_time
      timezone: Asia/Shanghai
      layouts:
        - '2006-01-02 15:04:05'
        - '2006-01-02 15:04:05.999'
      test:
        - '2019-06-22 16:33:51'
        - '2019-11-18 04:59:51.123'
  - drop_fields:
      fields: ["start_time","input", "agent", "ecs", "log", "host"]
     # fields: [start_time]





效果图

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值