java - Send log4j2 stack traces over syslog -
i trying log stack traces logstash.
the logging stack elk (elasticsearch, logstash, kibana).
the application producing logs java application, using slf4j
logging interface, , log4j2
logging implementation.
the log4j2.xml
declares syslog
appender, rfc5424
format:
<appenders> <syslog name="rfc5424" format="rfc5424" host="localhost" port="8514" protocol="tcp" appname="myapp" includemdc="true" mdcid="mdc" facility="local0" enterprisenumber="18060" newline="true" messageid="audit" id="app"> <loggerfields> <keyvaluepair key="thread" value="%t"/> <keyvaluepair key="priority" value="%p"/> <keyvaluepair key="category" value="%c"/> <keyvaluepair key="exception" value="%ex{full}"/> </loggerfields> </syslog> </appenders>
i log throwable java application so:
org.slf4j.loggerfactory.getlogger("exception_test").error("testing errors", new runtimeexception("exception message"));
when exception logged, logstash traces show me persists:
{ "@timestamp":"2016-11-08t11:08:10.387z", "port":60397, "@version":"1", "host":"127.0.0.1", "message":"<131>1 2016-11-08t11:08:10.386z mycomputer.local myapp - audit [mdc@18060 category=\"exception_test\" exception=\"java.lang.runtimeexception: exception message", "type":"syslog", "tags":[ "_grokparsefailure" ] }
and confirm kibana displays same json within _source
field of 1 of log entries.
there's problem here: no stack trace saved. , message, "testing errors", lost.
the "tags":["_grokparsefailure"]
unfortunate not related question.
i tried adding <exceptionpattern/>
see if change anything:
<syslog name="rfc5424" format="rfc5424" host="localhost" port="8514" protocol="tcp" appname="myapp" includemdc="true" mdcid="mdc" facility="local0" enterprisenumber="18060" newline="true" messageid="audit" id="app"> <loggerfields> <keyvaluepair key="thread" value="%t"/> <keyvaluepair key="priority" value="%p"/> <keyvaluepair key="category" value="%c"/> <keyvaluepair key="exception" value="%ex{full}"/> </loggerfields> <exceptionpattern>%ex{full}</exceptionpattern> </syslog>
<exceptionpattern/>
replaces log message, , also (sadly) omits loggerfields
. give me class name , line number:
{ "@timestamp":"2016-11-08t11:54:03.835z", "port":60397, "@version":"1", "host":"127.0.0.1", "message":"at com.stackoverflow.logtest.throw(logtest.java:149)", "type":"syslog", "tags":[ "_grokparsefailure" ] }
again: no stack trace. , again: message, "testing errors", lost.
how can use log4j2
log stack traces logstash? don't have use syslog
appender.
essentially constraints are:
- not locked in particular logging infrastructure (this why used syslog)
- multi-line stack traces need understood being single log entry. it's undesirable "each line of stack trace" "a separate log message"
- stack traces must able subjected filters. typical exception of mine can have page-long stack trace. want filter out frames spring.
log4j 2.5's syslogappender can only send stack traces on udp.
<syslog name="rfc5424" format="rfc5424" host="localhost" port="8514" protocol="udp" appname="myapp" includemdc="true" mdcid="mdc" facility="local0" enterprisenumber="18060" newline="true" messageid="logtest" id="app"> <loggerfields> <keyvaluepair key="thread" value="%t"/> <keyvaluepair key="priority" value="%p"/> <keyvaluepair key="category" value="%c"/> <keyvaluepair key="exception" value="%ex{full}"/> </loggerfields> <exceptionpattern>%ex{full}</exceptionpattern> </syslog>
with udp: both exceptionpattern
and loggerfields.keyvaluepair["exception"]
start working solutions multiline stack traces.
this logstash
prints when sent exception on udp via syslog:
{ "@timestamp" => 2016-11-14t13:23:38.304z, "@version" => "1", "host" => "127.0.0.1", "message" => "<131>1 2016-11-14t13:23:38.302z birchbox.local myapp - logtest [mdc@18060 category=\"com.stackoverflow.deeply\" exception=\"java.lang.runtimeexception: exception message\n\tat com.stackoverflow.deeply.complain(deeply.java:10)\n\tat com.stackoverflow.nested.complain(nested.java:8)\n\tat com.stackoverflow.main.main(main.java:20)\n\" priority=\"error\" thread=\"main\"] example error\njava.lang.runtimeexception: exception message\n\tat com.stackoverflow.deeply.complain(deeply.java:10)\n\tat com.stackoverflow.nested.complain(nested.java:8)\n\tat com.stackoverflow.main.main(main.java:20)", "type" => "syslog", "tags" => [ [0] "_grokparsefailure" ] }
inside [mdc@18060 exception=\"…\"]
loggerfields.keyvaluepair["exception"]
stack trace.
in addition this: stack trace inserted into logged message itself, exceptionpattern
.
for reference: logstash
prints when send exception on tcp via syslog (i.e. same syslogappender described above, protocol="tcp"
instead):
{ "@timestamp" => 2016-11-14t19:56:30.293z, "port" => 63179, "@version" => "1", "host" => "127.0.0.1", "message" => "<131>1 2016-11-14t19:56:30.277z birchbox.local myapp - audit [mdc@18060 category=\"com.stackoverflow.deeply\" exception=\"java.lang.runtimeexception: exception message", "type" => "syslog", "tags" => [ [0] "_grokparsefailure" ] } { "@timestamp" => 2016-11-14t19:56:30.296z, "port" => 63179, "@version" => "1", "host" => "127.0.0.1", "message" => "at com.stackoverflow.deeply.complain(deeply.java:10)", "type" => "syslog", "tags" => [ [0] "_grokparsefailure" ] } { "@timestamp" => 2016-11-14t19:56:30.296z, "port" => 63179, "@version" => "1", "host" => "127.0.0.1", "message" => "at com.stackoverflow.nested.complain(nested.java:8)", "type" => "syslog", "tags" => [ [0] "_grokparsefailure" ] } { "@timestamp" => 2016-11-14t19:56:30.296z, "port" => 63179, "@version" => "1", "host" => "127.0.0.1", "message" => "at com.stackoverflow.main.main(main.java:20)", "type" => "syslog", "tags" => [ [0] "_grokparsefailure" ] } { "@timestamp" => 2016-11-14t19:56:30.296z, "port" => 63179, "@version" => "1", "host" => "127.0.0.1", "message" => "\" priority=\"error\" thread=\"main\"] example error", "type" => "syslog", "tags" => [ [0] "_grokparsefailure" ] } { "@timestamp" => 2016-11-14t19:56:30.296z, "port" => 63179, "@version" => "1", "host" => "127.0.0.1", "message" => "java.lang.runtimeexception: exception message", "type" => "syslog", "tags" => [ [0] "_grokparsefailure" ] } { "@timestamp" => 2016-11-14t19:56:30.297z, "port" => 63179, "@version" => "1", "host" => "127.0.0.1", "message" => "at com.stackoverflow.deeply.complain(deeply.java:10)", "type" => "syslog", "tags" => [ [0] "_grokparsefailure" ] } { "@timestamp" => 2016-11-14t19:56:30.298z, "port" => 63179, "@version" => "1", "host" => "127.0.0.1", "message" => "at com.stackoverflow.nested.complain(nested.java:8)", "type" => "syslog", "tags" => [ [0] "_grokparsefailure" ] } { "@timestamp" => 2016-11-14t19:56:30.298z, "port" => 63179, "@version" => "1", "host" => "127.0.0.1", "message" => "at com.stackoverflow.main.main(main.java:20)", "type" => "syslog", "tags" => [ [0] "_grokparsefailure" ] } { "@timestamp" => 2016-11-14t19:56:30.299z, "port" => 63179, "@version" => "1", "host" => "127.0.0.1", "message" => "", "type" => "syslog", "tags" => [ [0] "_grokparsefailure" ] }
it looks tcp "work", splits single log message many syslog messages (for example when \n
encountered).
Comments
Post a Comment