Logs

Post on 13-Apr-2017

31 views 0 download

Transcript of Logs

Logs

Objective

• all activities that affect user state or balances are formally trackedAuditable

• it’s possible to determine where an activity occurs in all tiers of the application

Traceable

• logs cannot be overwritten or tampered with by local or remote users

High integrity

Message Priorities/Levels

• Severe errors that cause premature termination. fatal • Other runtime errors or unexpected conditions. error • are undesirable or unexpected, but not necessarily

"wrong". Warn• Interesting runtime events (startup/shutdown). Info• detailed information on the flow through the system.Debug• more detailed information. Trace

What to log?

Log all the thingsWork Smarter, not Harder

Default Message Priority/Level

By default the message priority should be no lower than info.

That is, by default debug message should not be seen in the logs.

Default production log level

WARNING

Where to define logger layout?

• private static Logger log = Logger.getLogger( MyClass.class )– log.error()– log.warn()– log.info()– log.debug()

• "%r [%t] %-5p %c - %m%n" – 176 [main] INFO org.foo.Bar - Located nearest gas

station.

What format to use?

• A SINGLE LINE• Timestamps with timezone, to the

millisecond or nanosecond• Class name + line number• Meaningful context

Best practices for app

• Do not allow exceptions to go unhandled/reach the browser

• Display custom error pages to users with an email link for feedback

• Do not enable “Robust Exception Information” in production.

• Rotate log files to keep them current

Use parameterized logging

• LOG.debug("Method called with arg " + arg);• BAD: string varies with argument

Use parameterized logging

• if (LOG.isDebugEnabled()) { LOG.debug("Method called with arg {}", arg);

• BAD: code clutter

Use parameterized logging

• LOG.debug("arg is {}", arg);• BAD: wrong level of language, this would be

okay on TRACE

Use parameterized logging

• LOG.debug("Method called with arg {}", arg);• GOOD: string literal, no dynamic objects

Exception example

• catch (SomeException ex) { LOG.warn("Failed to do something with {}, continuing", arg, ex); }

• GOOD: note how there is no "{}" for ex

Provide useful event context

• LOG.debug(arg.toString());• VERY BAD: – no context provided– non-constant message string– assumes useful toString()

Provide useful event context

• LOG.debug("{}", arg);• VERY BAD– no context provided

Provide useful event context

• try { doSomething(arg); ... } catch (SomeException ex) { }

• COMPLETELY BAD– silently ignoring errors!!!

Provide useful event context

• try { doSomething(arg);} catch (SomeException ex) { LOG.warn(ex.getMessage()); }

• EXTREMELY BAD– message is not constant– no context is provided– ex.getCause() is lost– call stack is lost

Provide useful event context

• try { doSomething(arg); ... } catch (SomeException ex) { LOG.warn("Failed to do something with {}, ignoring it", arg, ex); }

• GOOD– string literal– we explain what we tried to do– we pass along information we have about the failure – we explain that we recovered from the failure

Provide useful event context• try { doSomething(arg); ... }

catch (SomeException ex) { LOG.error("Failed to do something with {}", arg, ex); throw new RuntimeException("Failed to do something", ex); }

• GOOD– string literal– we explain what we tried to do– we pass along information we have about the failure – we escalate the failure to our caller– we also 'chain' the exception so it is not lost and can be correlated

Anything else?

• Separate files for different areas of interest• Always Log To Local Disk

• http://juliusdavies.ca/logging.html