JAX: Logging best practices #
The ideal outcome of Peter RoÃbach’s talk on logging best practices was to have
attendees leave the room
thinking ``we know all this already and are applying
it successfully’’ - most likely though the majority left
thinking about how to
implement even the most basic advise discussed.
From his consultancy and fire
fighter background he has a good overview of what
logging in the average corporate environment looks like: No
logging plan, no
rules, dozens of logging frameworks in active use, output in many different
languages, no
structured log events but a myriad of different quoting,
formatting and bracketing standards
instead.
So what should the ideal log line contain? First of all it should really be a
log line
instead of a multi line something that cannot be reconstructed when
interleaved with other messages. The line should
not only contain the class
name that logged the information (actually that is the least important piece
of
information), it should contain the thread id, server name, a (standardised and
always consistently formatted)
timestamp in a decent resolution (hint: one new
timestamp per second is not helpful when facing several hundred
requests per
second). Make sure to have timing aligned across machines if timestamps are
needed for correlating
logs. Ideally there should be context in the form of
request id, flow id, session id.
When thinking
about logs, do not think too much about human readability - think
more in terms of machine readability and
parsability. Treat your logging system
as the db in your data center that has to deal with most traffic. It is
what
holds user interactions and system metrics that can be used as business
metrics, for debugging performance
problems, for digging up functional issues.
Most likely you will want to turn free text that provides lots of
flexibility
for screwing up into a more structured format like json, or even some binary
format that is storage
efficient (think protocol buffers, thrift, avro).
In terms of log levels, make sure to log development
traces on trace, provide
detailed problem analysis stuff on debug, put normal behaviour onto info. In
case of
degraded functionality, log to warn. In case of things you cannot
easily recovered from put them on error. When it
comes to logging hierarchies -
do not only think in class hierarchies but also in terms of use cases:
Just
because your http connector is used in two modules doesn’t mean that there
should be no way to turn logging
on just for one of the modules alone.
When designing your logging make sure to talk to all stakeholders
to get clear
requirements. Make sure you can find out how the system is being used in the
wild, be able to
quantify the number of exceptions; max, min and average
duration of a request and similar
metrics.
Tools you could look at for help include but are not limited to splunk, jmx,
jconsole,
syslog, logstash, statd, redis for log collection and queuing.
As a parting exercise: Look at all of your
own logfiles and count the different
formats used for storing time.