Logstash 学习使用
一、概要
1.1、官网地址
https://www.elastic.co/cn/logstash/
1.2、介绍
Logstash 能够动态地采集、转换和传输数据,不受格式或复杂度的影响。利用 Grok 从非结构化数据中派生出结构,从 IP 地址解码出地理坐标,匿名化或排除敏感字段,并简化整体处理过程。也就是一个采集-------> 过滤------> 输出的过程,从哪里采集,采集后到哪里去,中间要不要过滤掉一下东西。
1.3、input输入
input 就是Logstash的入口,数据首先需要经过这一步。它支持采集很多输入选择,比如syslog、redis、file、es、exec、log4j、jdbc、kafka等。
1.4、filter过滤
filter是个负责筛选的部分,数据从源传输到输出的过程中,Logstash 过滤器能够解析各个事件,识别已命名的字段以构建结构,并将它们转换成通用格式。它支持很多过滤库,如下:
.5、输出
Elasticsearch 是首选输出方向,但也支持很多选择(与输入差不多),可以将数据发送到您要指定的地方,并且能够灵活地解锁众多下游用例。
1.6、应用场景
Logstash最常用于ELK(elasticsearch + logstash + kibane)中作为日志收集器使用。可同步mysql数据到es等。这里我的案例是订阅kafka到es的过称。
二、安装
2.1、下载地址
2.2、启动
logstash是基于JDK的,所以必须先安装Jdk环境
在安装目录下执行命令./bin/logstash,但一般需要指定配置文件,例如:
nohup ./bin/logstash -f conf.conf &
1|0logstash参数配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | input配置: file:读取文件 input { file{ path => [ "/var/log/*.log" , "/var/log/message" ] type => "system" start_position => "beginning" } } start_position 代表logstash初次采集文件内容的位置,。取值:beginning或者end。end代表每次都是从文件尾部开始。 start_position:logstash从什么位置读取文件数据,默认是结束的位置,也就是说logstash会以类似tail -f的形式运行。 如果需要导入原始数据,需要把这个设定为: "beginnning" ,logstash就从头开始读取. stdin:标准输入 input { stdin { add_filed =>{ "key" => "value" } codec => "plain" tags => [ "add" ] type => "std" } } input { stdin { type => "web" } } filter{ if [type] == "web" { gork{ match => [ "message" ,%{COMBINEDAPACHELOG}] } } } output { if "_grokparsefailure" in [tags] { nagios_nsca{ nagios_status => "1" } } else { elasticsearch { } } } filter配置: data:时间处理 %{+YYYY.MM.dd}这种写法必须读取@timestamp数据,所以一定不要直接删除这个字段保留自己的字段,而是应该用filter/date转换后删除自己的字段. filter { grok { match => [ "message" , "%{HTTPDATE:logdate}" ] } date { match => [ "logstash" , "dd/MMM/yyyy:HH:mm:ss Z" ] } } 时区偏移量使用Z. output配置: elasticsearch: output { elasticsearch { hosts => [ "192.168.0.2:9200" ] index => "logstash-%{type}-%{+YYYY.MM.dd}" document_type => "%{type}" flush_size => 20000 idle_flush_time => 10 sniffing => true template_overwrite => true } } ?logstash在有多个conf文件的情况下,进入es的数据会重复,几个conf数据就会重复几次. !output段顺序执行,没有对日志type进行判断的各插件配置都会全部执行一次. output { if [type] == "nginxaccess" { elasticsearch { } } } email:发送邮件 output { email { to => "admin@website.com,root@website.com" cc => "other@website.com" via => "smtp" subject => "Warning: %{title}" options => { smtpIporHost => "localhost" , port => 25, domain => 'localhost.localdomain' , userName => nil, password => nil, authenticationType => nil, # (plain, login and cram_md5) starttls => true } htmlbody => "" body => "" attachments => [ "/path/to/filename" ] } } 注意:option参数在logstash2.0以后已经被移除. output { email { port => "25" address => "smtp.126.com" username => "test@126.com" password => "" authentication => "plain" use_tls => true from => "test@126.com" subject => "Warning: %{title}" to => "test@qq.com" via => "smtp" body => "%{message}" } } file:保存成文件 output { file { path => "/path/to/%{+yyyy}/%{+MM}/%{+dd}/%{host}.log.gz" message_format => "%{message}" gzip => true } } |
三、简单配置使用
3.1、简单配置(控制台输出,只要用于调试)
创建一个test.conf的文件
1 2 3 4 5 6 | input{ stdin {} } output { stdout {} } |
启动
1 | ./bin/logstash -f ./test.conf |
启动后,在控制台输入什么就会发现它message也输出内容,其他字段是它模版自带的
1 2 3 4 5 6 7 8 9 10 | # 输入 sfghfghfgh # 输出 { "message" => "sfghfghfgh" , "host" => "iZ2ze7b12m7993dl7fyi22Z" , "@timestamp" => 2021-08-11T03:07:34.719Z, "@version" => "1" } |
3.2、简单配置添加过滤器
在刚才的文件里加入一个过滤器,输入字母的小写转化为大写
我的心得:修改数据后不能使用新的字段接收,是重新赋值覆盖旧的数据而已。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | input{ stdin {} } filter { mutate { uppercase => [ "message" ] } } output { stdout { } } # 输入 asdf # 输出 { "message" => "ASDF" , "host" => "iZ2ze7b12m7993dl7fyi22Z" , "@timestamp" => 2021-08-11T03:07:34.719Z, "@version" => "1" } |
3.3、读取文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | input{ file { # 收集的文件,多个用,隔开,用绝对路径 path => [ "/data/test/*.log" ] start_position => "end" } } filter { mutate { add_field => { "add_msg" => "%{[message]}" } } } output { stdout { } } |
start_position 代表logstash初次采集文件内容的位置,。取值:beginning或者end。end代表每次都是从文件尾部开始。add_field为添加输出字段
如果想输出到文件里,那么就是
1 2 3 4 5 6 | output { file { path => "/data/test2/test.log" codec => line { format => "格式化后数据: %{message}" } } } |
这是一个简单的一个输出,codec 定义输出内容格式,默认为json_lines(已json格式输出)。
3.4、从文件输出到es
1 2 3 4 5 6 7 8 9 10 11 12 13 | input{ file { # 收集的文件,多个用,隔开,用绝对路径 path => [ "/data/test/*.log" ] start_position => "end" } } output { elasticsearch { hosts => [ "xxx:9200" ] index => "log-%{+YYYY-MM}" } } |
3.5、与Redis、Kafka集成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | input { kafka { #kafaka服务地址 bootstrap_servers => "xx:9092" #订阅的topic名 topics => [ "logTopic" ] } } output { redis { host => "127.0.0.1" port => 6379 key => "test" # key的类型,list或者channel data_type => "list" } } |
3.6、总结
前面讲的主要都是demo级别的,作为理解,然后在升级到实战,这过程需要查看官方文档
四、logstash集成es,自定义模版字段
4.1、准备工作
kafka,Elaseicsearch 和 logstash,es和logstash版本尽量保持一致。
4.2、logstash配置
这三个中,其他两个比较好处理,所以先解决logstash,直接放配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | input { kafka { #kafaka服务地址 bootstrap_servers => "xxx:9092" topics => [ "logTopic" ] } } filter { mutate{ # 将message内容用|切割 split => [ "message" , "|" ] # 添加字段 add_field => { "moduleName" => "%{[message][0]}" } add_field => { "value" => "%{[message][1]}" } add_field => { "url" => "%{[message][2]}" } add_field => { "param" => "%{[message][3]}" } add_field => { "className" => "%{[message][4]}" } add_field => { "methodName" => "%{[message][5]}" } add_field => { "returnResult" => "%{[message][6]}" } add_field => { "elapsedTime" => "%{[message][7]}" } add_field => { "errorMsg" => "%{[message][8]}" } remove_field => "message" remove_field => "@version" } } output { elasticsearch { hosts => [ "xxx:9200" ] # 在es的索引 index => "log_record-%{+YYYY-MM}" } #打印,调试的时候用,默认为rubydebug stdout { codec => json } } |
注意点就是message的内容,将内容推到fafka时就规定好格式,然后使用分隔符进行切割,赋值到其他字段上。 也可以使用其他方式,比如json解析的方式,logstash支持json解析赋值,这里我使用了分隔符切割的方式。
4.3、kafka内容
在推送到kafka上就规定格式使用 | 来分割,因为到logstash订阅是我使用|来分割。
4.4、elasticsearch 模版配置
是用logstash传输到es会使用默认的一套模版,具体是用哪个模版是更具索引名来确定的。
- 查看模版信息
#GET请求方式 es地址:9200/_template/logstash
- 添加新的模版
注意这里的索引名称和logstash在es创建的索引名要有联系才行。注意我是用的是log_record*
# PUT请求方式 , log_record 为模版名称 http://123.56.97.130:9200/_template/log_record
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | { "template" : "log_record*" , "order" : 1, "version" : 1, "index_patterns" : [ "*" ], "settings" : { "number_of_shards" : 1, "number_of_replicas" : 0 }, "mappings" : { "properties" : { "@timestamp" : { "type" : "date" , "format" : "dateOptionalTime" , "doc_values" : true }, "className" : { "index" : false , "type" : "text" }, "createTime" : { "format" : "strict_date_optional_time||epoch_millis" , "type" : "date" , "index" : "false" }, "elapsedTime" : { "type" : "long" , "index" : true }, "methodName" : { "index" : false , "type" : "text" }, "moduleName" : { "index" : false , "type" : "text" }, "param" : { "search_analyzer" : "ik_smart" , "analyzer" : "ik_max_word" , "store" : true , "type" : "text" , "index" : "true" , "fields" : { "keyword" : { "type" : "keyword" } } }, "returnResult" : { "type" : "text" , "search_analyzer" : "ik_max_word" , "analyzer" : "ik_max_word" , "index" : true }, "url" : { "type" : "text" , "index" : false }, "value" : { "search_analyzer" : "ik_max_word" , "analyzer" : "ik_max_word" , "store" : true , "type" : "text" , "index" : true }, "errorMsg" : { "search_analyzer" : "ik_max_word" , "analyzer" : "ik_max_word" , "store" : true , "type" : "text" , "index" : true } } } } |
配完模版后,就可以测试了
五、总结
logstash对接其他组件是非常方便的,但灵活使用就稍微有些麻烦,因为需要根据场景定制化一些字段或者过滤一些数据这才是难点。这次的案例也只是我收集日志的一次分享,希望能帮助到大家!
__EOF__

本文链接:https://www.cnblogs.com/Jeffrey1172417122/p/16853761.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
· [翻译] 为什么 Tracebit 用 C# 开发
· 腾讯ima接入deepseek-r1,借用别人脑子用用成真了~
· Deepseek官网太卡,教你白嫖阿里云的Deepseek-R1满血版
· DeepSeek崛起:程序员“饭碗”被抢,还是职业进化新起点?
· RFID实践——.NET IoT程序读取高频RFID卡/标签