logstash multi pipeline的使用(一)
默认logstash只有一个管道,当conf.d下有多个配置文件时,其实走的都是一个管道,针对不同业务场景,需要配置不同管道进行数据流通。logstash启动后会把多个配置文件自动合并成一个,比如有两个conf文件,每个都有 filter、ouput,写入一条数据,会执行两次filter和output,重复写入
https://blog.csdn.net/tiancityycf/article/details/116171676
这显然跟我们期望的不同,我们希望Logstash按以下的方式来处理,也就是各自区分,独立处理:
解决方案
官方提供有 type 和tags 配置项进行区分,type 和 tags 是 logstash 事件中两个特殊的字段。
通常来说我们会在输入区段中通过 type 来标记事件类型 —— 我们肯定是提前能知道这个事件属于什么类型的。而tags 则是在数据处理过程中,由具体的插件来添加或者删除的。
input { jdbc { jdbc_connection_string => "jdbc:mysql://localhost:3306/igp?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull" jdbc_user => "es_igper" jdbc_password => "password" jdbc_driver_library => "/usr/local/logstash/tools/mysql-connector-java-8.0.23.jar" jdbc_driver_class => "com.mysql.jdbc.Driver" jdbc_paging_enabled => "true" jdbc_page_size => "10000" plugin_timezone => "local" clean_run => false use_column_value => true tracking_column => update_time tracking_column_type => "timestamp" record_last_run => true last_run_metadata_path => "/usr/local/logstash/config/igp/run/live_v4_run" statement => "select live.* from live where live.update_time>:sql_last_value order by live.update_time asc,live.id asc" schedule => "* * * * *" type => "live" } } filter { if [type]=="live" { mutate { remove_field => ["username","passwd","wx_openid"] } } } output { if [type]=="live" { elasticsearch { hosts => ["localhost:9200"] index => "live_v4" document_id => "%{id}" user => "elastic" password => "password" } stdout { codec => json_lines } } }
以上是通过type区分,传入的数据中带有type字段/tags字段,会覆盖logstash配置文件设置的type属性值,这是个大坑,注意。推进使用下面的方式
input { jdbc { jdbc_connection_string => "jdbc:mysql://localhost:3306/igp?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull" jdbc_user => "es_igper" jdbc_password => "password" jdbc_driver_library => "/usr/local/logstash/tools/mysql-connector-java-8.0.23.jar" jdbc_driver_class => "com.mysql.jdbc.Driver" jdbc_paging_enabled => "true" jdbc_page_size => "10000" plugin_timezone => "local" clean_run => false use_column_value => true tracking_column => update_time tracking_column_type => "timestamp" record_last_run => true last_run_metadata_path => "/usr/local/logstash/config/igp/run/live_v4_run" statement => "select live.* from live where live.update_time>:sql_last_value order by live.update_time asc,live.id asc" schedule => "* * * * *" tags=> ["live"] } } filter { if "live" in [tags]{ mutate { remove_field => ["username","passwd","wx_openid"] } } } output { if "live" in [tags]{ elasticsearch { hosts => ["localhost:9200"] index => "live_v4" document_id => "%{id}" user => "elastic" password => "password" } stdout { codec => json_lines } } if "user" in [tags]{ elasticsearch { hosts => ["localhost:9200"] index => "user_v4" document_id => "%{id}" user => "elastic" password => "password" } stdout { codec => json_lines } } }
通过以上方式配置,就能将pipeline各自区分开。大家可以试下,如果把type参数去掉,最后的elasticsearch数据会混或者数据重复等奇怪问题
原因
logstash启动后会把多个配置文件自动合并成一个,比如有两个conf文件,每个都有 filter、ouput,写入一条数据,会执行两次filter和output,重复写入
我们来看下面的这样的一个案例
https://www.bbsmax.com/A/QW5YvgVYdm/
在使用 logstash 编写多个配置文件,写入到 elasticsearch 时,会出现数据写入混乱的问题,举例来说:
多个配置文件中规则如下:
- A -> es-logstash-A
- B -> es-logstash-B
- A 写入到 es-logstash-A 索引中
- B 写入到 es-logstash-B 索引中
然而当 logstash 服务运行起来的时候并不是这样的,可能出现如下想象:
- A-> es-logstash-A
- B-> es-logstash-A
究其原因,是因为 logstash 运行起来的时候,会将所有的配置文件合并执行。因此,每个 input 的数据都必须有一个唯一的标识,在 filter 和 output 时,通过这个唯一标识来实现过滤或者存储到不同的索引。
2. 多配置文件的实现方式
如上所说,写入需要唯一标识,在logstash 中唯一标识推荐使用 type 或 tags 字段,然后通过 if 条件判断来实现。
首先来看下面一个示例:
在 /etc/logstash/conf.d 目录下有这样两个配置文件 [1.conf a.conf ]
[root@192.168.118.14 /etc/logstash/conf.d]#ls 1.conf a.conf 1.conf input { file { path => "/data/log/1.log" start_position => "beginning" sincedb_path => "/tmp/1_progress" } } output { elasticsearch { hosts => ["192.168.118.14"] index => "1-log-%{+YYYY.MM.dd}" } } a.conf input { file { path => "/data/log/a.log" start_position => "beginning" sincedb_path => "/tmp/a_progress" } } output { elasticsearch { hosts => ["192.168.118.14"] index => "a-log-%{+YYYY.MM.dd}" } } /data/log/a.log [root@192.168.118.14 ~]#cat /data/log/a.log a /data/log/1.log [root@192.168.118.14 ~]#cat /data/log/1.log
这两个配置很简单,规则:
- 1.conf 读取 /data/log/1.log 写入到 1-log-[date] 索引
- a.conf 读取 /data/log/a.log 写入到 a-log-[date] 索引
两个日志文件,都只有 1 行日志记录。
正确的结果是 生成两个索引,每个索引里只有一条记录。
接下来启动服务查看,多配置文件 命令启动方式如下:
正确的启动方式:
- [root@192.168.118.14~]#logstash -f /etc/logstash/conf.d/
错误的启动方式:
- [root@192.168.118.14~]#logstash -f /etc/logstash/conf.d/*
启动成功后,通过 elasticsearch-head 查看 索引及数据
发现每个 索引里却有 2 条记录,这不符合正常的逻辑,查看数据发现,每个索引里都是 1.log 和 a.log 的数据总和。
这也证明了 logstash 在写入数据的时候,是将所有的配置文件合并在一起的,运行起来数据写入就会混乱。要解决这种混乱就需要通过唯一标识和if 判断,logstash配置文件调整如下:
1.conf input { file { path => "/data/log/1.log" start_position => "beginning" sincedb_path => "/tmp/1_progress" type => "1-log" } } output { if [type] == "1-log" { elasticsearch { hosts => ["192.168.118.14"] index => "1-log-%{+YYYY.MM.dd}" } } } a.conf input { file { path => "/data/log/a.log" start_position => "beginning" sincedb_path => "/tmp/a_progress" type => "a-log" } } output { if [type] == "a-log" { elasticsearch { hosts => ["192.168.118.14"] index => "a-log-%{+YYYY.MM.dd}" } } }
启动服务:
- [root@192.168.118.14~]#logstash -f /etc/logstash/conf.d/
通过 elasticsearch-head 查看:
这次就完全符合预期的标准了。
背景假设现在给Logstash的pipeline配置了2个conf,也就是2个输入源。如果不做任何处理,那么所有的Filter和Output都会同时触发,如下图:这显然跟我们期望的不同,我们希望Logstash按以下的方式来处理,也就是各自区分,独立处理:
解决方案官方提供有 type 和tags 配置项进行区分,type 和 tags 是 logstash 事件中两个特殊的字段。
通常来说我们会在输入区段中通过 type 来标记事件类型 —— 我们肯定是提前能知道这个事件属于什么类型的。而tags 则是在数据处理过程中,由具体的插件来添加或者删除的。
如下所示:————————————————版权声明:本文为CSDN博主「私念」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/tiancityycf/article/details/116171676
posted on 2022-09-25 20:48 luzhouxiaoshuai 阅读(577) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
2021-09-25 图灵学院skywalking的学习