Isso é realmente um pouco mais difícil do que parece, já que o campo gsub
para mutate
não faz realmente o que você deseja. Parece não ser tão inteligente quanto você pensa.
Tive que modificar os padrões que você está usando para capturar tudo antes e depois do request
( pre_req
e post_req
respectivamente), mas parece possível.
Não faço ideia de quão bem ele será dimensionado em termos de desempenho, já que há muita filtragem acontecendo aqui, mas funciona.
Eu testei com esta configuração:
input {
stdin {}
}
filter {
grok {
match => [
"message" , "(?<pre_req>%{IPORHOST:clientip} (?<ident>[a-zA-Z\.\@\-\+_%]+) (?<auth>[a-zA-Z\.\@\-\+_%]+) \[%{HTTPDATE:timestamp}\] \"%{WORD:verb} )%{URIPATHPARAM:request}(?<post_req> HTTP/%{NUMBER:httpversion}\" %{NUMBER:response} (?:%{NUMBER:bytes}|-) (?:\"(?:%{URI:referrer}|-)\"|%{QS:referrer}) %{QS:agent} %{QS:xforwardedfor} %{NUMBER:request_time} %{NUMBER:upstream_time})",
"message" , "(?<pre_req>%{IPORHOST:clientip} (?<ident>[a-zA-Z\.\@\-\+_%]+) (?<auth>[a-zA-Z\.\@\-\+_%]+) \[%{HTTPDATE:timestamp}\] \"%{WORD:verb} )%{URIPATHPARAM:request}(?<post_req> HTTP/%{NUMBER:httpversion}\" %{NUMBER:response} (?:%{NUMBER:bytes}|-) (?:\"(?:%{URI:referrer}|-)\"|%{QS:referrer}) %{QS:agent} %{QS:xforwardedfor} %{NUMBER:request_time})"
]
break_on_match => true
}
grok {
match => { "request" => "(?<request_path>[^?]*)?(?<request_params>.*)"
}
}
mutate {
gsub => [ "request_params" , "[?]", "" ]
}
kv {
field_split => "&"
source => "request_params"
prefix => "request_params_"
}
mutate {
replace => { "request" => "%{request_path}?api_key=%{request_params_api_key}&api_secret=XXXXXXXXXXXXXXXXXXXXXXXXXXXXX" }
replace => { "message" => "%{pre_req}%{request}%{post_req}" }
remove_field => [ "request_path", "request_params", "request_params_api_key", "request_params_api_secret", "pre_req", "post_req" ]
}
}
output {
stdout { codec => rubydebug }
}
E parece ter feito exatamente o que você quer ..
# /opt/logstash/bin/logstash -f config.conf
Logstash startup completed
10.120.40.105 - - [29/Jul/2015:16:41:09 +0000] "PUT /v1/resources/scenes/455IrIBcRsa0kkIs6mv9lQ?api_key=11111111111111111&api_secret=2222222222222222222222222 HTTP/1.1" 200 689 "-" "python-requests/2.6.0 CPython/2.7.9 Linux/2.6.32-504.30.3.el6.x86_64" "10.120.40.105" 0.180 0.180
{
"message" => "10.120.40.105 - - [29/Jul/2015:16:41:09 +0000] \"PUT /v1/resources/scenes/455IrIBcRsa0kkIs6mv9lQ?api_key=11111111111111111&api_secret=XXXXXXXXXXXXXXXXXXXXXXXXXXXXX HTTP/1.1\" 200 689 \"-\" \"python-requests/2.6.0 CPython/2.7.9 Linux/2.6.32-504.30.3.el6.x86_64\" \"10.120.40.105\" 0.180 0.180",
"@version" => "1",
"@timestamp" => "2015-07-29T19:21:14.678Z",
"host" => "elk.example.com",
"clientip" => "10.120.40.105",
"ident" => "-",
"auth" => "-",
"timestamp" => "29/Jul/2015:16:41:09 +0000",
"verb" => "PUT",
"request" => "/v1/resources/scenes/455IrIBcRsa0kkIs6mv9lQ?api_key=11111111111111111&api_secret=XXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"httpversion" => "1.1",
"response" => "200",
"bytes" => "689",
"agent" => "\"python-requests/2.6.0 CPython/2.7.9 Linux/2.6.32-504.30.3.el6.x86_64\"",
"xforwardedfor" => "\"10.120.40.105\"",
"request_time" => "0.180",
"upstream_time" => "0.180"
}