问题
I have a Logstash configuration that I've been using to forward log messages in emails. It uses json
and json_encode
to parse and re-encode JSON log messages.
json_encode
used to pretty-print the JSON, which made for very nice looking emails. Unfortunately, with recent Logstash upgrades, it no longer pretty prints.
Is there any way I can get a pretty form of the event into a field that I can use for the email bodies? I'm fine with JSON, Ruby debug, or most other human readable formats.
filter {
if [type] == "bunyan" {
# Save a copy of the message, in case we need to pretty-print later
mutate {
add_field => { "@orig_message" => "%{message}" }
}
json {
source => "message"
add_tag => "json"
}
}
// other filters that might add an "email" tag
if "email" in [tags] {
# pretty-print JSON for the email
if "json" in [tags] {
# re-parse the message into a field we can encode
json {
source => "@orig_message"
target => "body"
}
# encode the message, but pretty this time
json_encode {
source => "body"
target => "body"
}
}
# escape the body for HTML output
mutate {
add_field => { htmlbody => "%{body}" }
}
mutate {
gsub => [
'htmlbody', '&', '&',
'htmlbody', '<', '<'
]
}
}
}
output {
if "email" in [tags] and "throttled" not in [tags] {
email {
options => {
# config stuff...
}
body => "%{body}"
htmlbody => "
<table>
<tr><td>host:</td><td>%{host}</td></tr>
<tr><td>when:</td><td>%{@timestamp}</td></tr>
</table>
<pre>%{htmlbody}</pre>
"
}
}
}
回答1:
As said by approxiblue, this issue is caused by logstash's new JSON parser (JrJackson). You can use the old parser as a workaround until pretty-print support is added again. Here is how:
You need to change two lines of the plugin's ruby file. Path should be something like:
LS_HOME/vendor/bundle/jruby/1.9/gems/logstash-filter-json_encode-0.1.5/lib/logstash/filters/json_encode.rb
Change line 5
require "logstash/json"
into
require "json"
And change line 44
event[@target] = LogStash::Json.dump(event[@source])
into
event[@target] = JSON.pretty_generate(event[@source])
That's all. After restarting logstash should pretty-print again.
Supplement:
In case you don't like changing your ruby sources you could also use a ruby filter instead of json_encode:
# encode the message, but pretty this time
ruby {
init => "require 'json'"
code => "event['body'] = JSON.pretty_generate(event['body'])"
}
来源:https://stackoverflow.com/questions/32077228/how-do-i-pretty-print-json-for-an-email-body-in-logstash