文本格式数据转换为多个logstash event
需求:最近在做用ELK进行用户行为日志采集分析的工作,遇到一个问题,就是前端上报的数据是批量的,类似于header:a=1&b=2;body:c=3&d=4,c=5&d=6,c=7&d=8...
我要通过logstash将其解析为
{
"a":"1",
"b":"2",
"c":"3",
"d":"4"
}
{
"a":"1",
"b":"2",
"c":"5",
"d":"6"
}
{
"a":"1",
"b":"2",
"c":"7",
"d":"8"
}
怎么做呢?当然是通过logstash来debug一步一步来做
http客户端使用postman,
logstash的conf文件
input使用http input plugin
主要看filter部分
思路:
1. 先把header和body部分提取出来,使用grok
grok{
match=>{
"message"=>"%{HEADER:header}%{BODY:body}"
}
pattern_definitions => {
"HEADER"=>"header:.*?;"
}
pattern_definitions => {
"BODY"=>"body:.*?;"
}
}
2. 把header和body部分进行数据清洗,保留我们需要的内容
mutate{
gsub=>["header","header:",""]
gsub=>["header",";",""]
}
mutate{
gsub=>["body","body:",""]
gsub=>["header",";",""]
}
3. 把body部分转换为数组
mutate{
split => {"body"=>","}
}
4. 关键点:使用split filter plugin
split{ field => "body"}
5. 更改message的内容
mutate {
add_field =>{
"new_message" => "%{header}&%{body}"
}
}
mutate{
update=>{"message"=>"%{new_message}"}
}
6. 使用dissect进行解析
dissect{
mapping=>{"message"=>"%{?key1}=%{&key1}&%{?key2}=%{&key2}&%{?key3}=%{&key3}&%{?key4}=%{&key4}"}
}
7. 删除不必要的field
mutate{
remove_field=>["message","new_message","body","header","host","@version"]
}
}
这样,就达到了我们需要的效果。也是刚刚开始使用logstash的plugin,还不是很熟悉。
json数据转换为多个logstash event
后来呢,技术方案变更了,前端传的是json文件,类似于
{
"a":"1",
"b":"2",
"params":{
"actionList":[
{"c"="3","d"="4"},
{"c"="5","d"="6"},
{"c"="7","d"="8"}
]
}
}
同样也是要转换为多条logstash event的情况
由于logstash有json codec,所以转换起来要比字符串方便
这里由于是json字符串,那么我们使用filebeat来作为input,进行debug
input {
beats {
port => 5044
codec => "json"
}
}
思路是类似的,只是处理的是json字符串,语法格式上有区别
1. 由于json codec已经帮我们处理为json了,而且params.actionList已经是数组格式了,那么直接用split
split{ field => "[params][actionList]"}
2. 接下来要把c,d field移动到json根路径下,去掉没用的params和actionList
mutate{
add_field => {"c"=>"%{[params][actionList][c]}"}
}
3. 移除没用的field
mutate {
remove_field => [ "params" ]
}
完成