文章目录

  • 背景和问题分析
  • 问题一
  • 解决方式参考


背景和问题分析

将多个服务的日志通过Filebeat写入到Logstash,其中Filebeat是以SideCar模式容器部署的,现在需要通过tag的方式将多个来源的数据写入到一个ES索引中。
我的操作步骤:
【1】修改K8S上fileBeat对应的configMap配置
【2】修改logstash配置,首先复制一个配置备份,然后添加额外的tag标签。

问题一

logstash[]: java.util.concurrent.RejectedExecutionException: event executor terminated

启动后出现该问题,出现以上问题的原因是我在logstash配置目录下cp了一份配置文件,最终导致配置目录下存在多份conf文件。这个需要注意配置目录下不允许有多份配置文件,如果需要备份可以放到外面的目录中去。
问题二
在解决该问题后,又发现一个问题,ES索引中只看到了其中一个服务的日志数据,其他服务的数据没有入库,而且本来可以入库的服务日志数据也没有入库。

检查FileBeat服务,正常运行没有问题。

logstashjava处理多行日志 logstash日志清理_logstashjava处理多行日志


检查Logstash服务,观察其日志数据

[logstash.outputs.elasticsearch] Could not index event to Elasticsearch. {:status=>400, :action=>["index", {:_id=>nil, :_index=>"logstash-info-2022.07.13", :_type=>"_doc", :routing=>nil},
 #<LogStash::Event:0x12e88cb2>], :response=>{"index"=>{"_index"=>"logstash-info-2022.07.13", "_type"=>"_doc", "_id"=>"LzhC9oEB0ca6UQlyyblY", "status"=>400, "error"=>{"type"=>"mapper_parsing_exception", 
 "reason"=>"failed to parse field [message] of type [text] in document with id 'LzhC9oEB0ca6UQlyyblY'", "caused_by"=>{"type"=>"illegal_state_exception", "reason"=>"Can't get text on a START_OBJECT at 1:378"}}}}}

有部分日志可以正常的输出,但是有部分日志数据出现如上图所示的警告。可以看到错误原因是message在映射到ES索引时发生了类型不匹配的问题。考虑到之前日志是正常运行的,所以将当前正常插入的索引记录和之前的索引记录进行比较,

logstashjava处理多行日志 logstash日志清理_数据_02


上图是我拿昨天和当前可以入库的索引记录进行的对比,可以发现两个在message的存储结构是不一样的。由于索引的字段数据类型不一致,导致了两个JSON格式不一样的日志无法映射到一个索引中去。

因为目前应用的日志是经过自定义的,需要按照统一的格式去写,而这个有问题的服务它是之前的旧项目,并没有按照统一的日志格式去写,所以这样混乱的将日志写入到一起,是有问题。

解决方式参考

【1】备份当前日志索引数据,然后删除该索引数据重新创建,并取消未按照统一格式日志输出的服务到当前索引中,经过处理后问题得到解决,日志正常落到索引中。这里非常粗暴的删除索引,因为这个只是半天的日志数据,非业务信息,而且已经进行了备份。
【2】如果是索引不能重建的话,那么只能将对应服务的日志数据记录删除,然后再进行日志的抽取。
【3】出现该问题的另一个原因是,从logstash到ES索引的数据是动态映射生成索引(表)结构的,如果是要求比较严格的数据可以通过设置索引模板的方式,我们项目中关于人员信息的存储时就是使用了索引模板的方式,从索引(表)结构上限制数据格式。