Beruflich Dokumente
Kultur Dokumente
Logging
or System.out.println() 2.0 author: Alex Maskovyak date: 2012-04-27
Metadata
Agenda
S Objectives
S Overview
S Principles S Next Steps
Objectives
Objectives
Motivation
Overview
Definition
computer program, in a certain scope in order to provide an audit trail that can be used to understand the activity of the system and to diagnose problems
Definition
computer program, in a certain scope in order to provide an audit trail that can be used to understand the activity of the system and to diagnose problems
What it is
system.
audience-appropriate manner.
Purposes
S Trace execution
S Document configuration state S Monitor for errors/warnings S Debug code S Provide system performance/timing
What it isnt
S Calls to System.out.println()
and testing.
Java Logging
Libraries
S
S
S S S
Common frameworks
S S
Chainsaw Lilith
slf4j
S S S S S
Simple Logging Facade for Java Designed by log4j creator Binds to logging frameworks Bridges to legacy logging APIs Provides a migrator
S
S S
LogBack
S Successor to log4j
public class AwesomeObject { private static Logger logger = Logger.getLogger(AwesomeObject.class.getName()); public static void main(String args) { logger.log(Level.INFO, Starting app, explicit Level ex.); logger.finer(Got arg0=+args[0]+ arg1+args[1]);
try { crash(); } catch( Exception e ) { logger.severe(Encountered a problem! See exc, e); } logger.log(Level.FINER, Exiting application.);
public class AwesomeObject { private static Logger logger = Logger.getLogger(AwesomeObject.class.getName()); public static void main(String args) { logger.log(Level.INFO, Starting app, explicit Level ex.); logger.finer(Got arg0=+args[0]+ arg1+args[1]);
try { crash(); } catch( Exception e ) { logger.severe(Encountered a problem! See exc, e); } logger.log(Level.FINER, Exiting application.);
public class AwesomeObject { private static Logger logger = Logger.getLogger(AwesomeObject.class.getName()); public static void main(String args) { logger.log(Level.INFO, Starting app, explicit Level ex.); logger.finer(Got arg0=+args[0]+ arg1+args[1]);
try { crash(); } catch( Exception e ) { logger.severe(Encountered a problem! See exc, e); } logger.log(Level.FINER, Exiting application.);
public class AwesomeObject { private static Logger logger = Logger.getLogger(AwesomeObject.class.getName()); public static void main(String args) { logger.log(Level.INFO, Starting app, explicit Level ex.); logger.finer(Got arg0=+args[0]+ arg1+args[1]);
try { crash(); } catch( Exception e ) { logger.severe(Encountered a problem! See exc, e); } logger.log(Level.FINER, Exiting application.);
public class AwesomeObject { private static Logger logger = Logger.getLogger(AwesomeObject.class.getName()); public static void main(String args) { logger.log(Level.INFO, Starting app, explicit Level ex.); logger.finer(Got arg0=+args[0]+ arg1+args[1]);
try { crash(); } catch( Exception e ) { logger.severe(Encountered a problem! See exc, e); } logger.log(Level.FINER, Exiting application.);
public class AwesomeObject { private static Logger logger = Logger.getLogger(AwesomeObject.class.getName()); public static void main(String args) { logger.log(Level.INFO, Starting app, explicit Level ex.); logger.finer(Got arg0=+args[0]+ arg1+args[1]);
try { crash(); } catch( Exception e ) { logger.severe(Encountered a problem! See exc, e); } logger.log(Level.FINER, Exiting application.);
public static void main(String args) { logger.entering( AwesomeObject.class.getName(), main, args); try { crash(); } catch( Exception e ) { logger.logp( Level.SEVERE, AwesomeObject.class.getName(), main, Encountered a problem! See exc, e); } logger.exiting( AwesomeObject.class.getName(), main, Exiting application., 0);
public static void main(String args) { logger.entering( AwesomeObject.class.getName(), main, args); try { crash(); } catch( Exception e ) { logger.logp( Level.SEVERE, AwesomeObject.class.getName(), main, Encountered a problem! See exc, e); } logger.exiting( AwesomeObject.class.getName(), main, Exiting application., 0);
public static void main(String args) { logger.entering( AwesomeObject.class.getName(), main, args); try { crash(); } catch( Exception e ) { logger.logp( Level.SEVERE, AwesomeObject.class.getName(), main, Encountered a problem! See exc, e); } logger.exiting( AwesomeObject.class.getName(), main, Exiting application., 0);
public class AwesomeObject { private static Logger logger = Logger.getLogger(AwesomeObject.class.getName()); public static void main(String args) { logger.info(Starting application.); logger.finer(Got arg0=+args[0]+ arg1+args[1]);
try { crash(); } catch( Exception e ) { logger.severe(Encountered a problem! See exc, e); } logger.log(Level.FINER, Exiting application.);
public class AwesomeObject { private static Logger logger = LoggerFactory.getLogger(AwesomeObject.class.getName()); public static void main(String args) { logger.info(Starting application.); logger.finer(Got arg0=+args[0]+ arg1+args[1]);
try { crash(); } catch( Exception e ) { logger.severe(Encountered a problem! See exc, e); } logger.log(Level.FINER, Exiting application.);
public class AwesomeObject { private static Logger logger = LoggerFactory.getLogger(AwesomeObject.class.getName()); public static void main(String args) { logger.info(Starting application.); logger.finer(Got arg0=+args[0]+ arg1+args[1]);
try { crash(); } catch( Exception e ) { logger.severe(Encountered a problem! See exc, e); } logger.log(Level.FINER, Exiting application.);
public class AwesomeObject { private static Logger logger = LoggerFactory.getLogger(AwesomeObject.class.getName()); public static void main(String args) { logger.info(Starting application.); logger.debug(Got args: {}, args);
try { crash(); } catch( Exception e ) { logger.severe(Encountered a problem! See exc, e); } logger.log(Level.FINER, Exiting application.);
public class AwesomeObject { private static Logger logger = LoggerFactory.getLogger(AwesomeObject.class.getName()); public static void main(String args) { logger.info(Starting application.); logger.debug(Got args: {}, args);
try { crash(); } catch( Exception e ) { logger.severe(Encountered a problem! See exc, e); } logger.log(Level.FINER, Exiting application.);
public class AwesomeObject { private static Logger logger = LoggerFactory.getLogger(AwesomeObject.class.getName()); public static void main(String args) { logger.info(Starting application.); logger.debug(Got args: {}, args);
try { crash(); } catch( Exception e ) { logger.error(Encountered a problem! See exc, e); } logger.log(Level.FINER, Exiting application.);
public class AwesomeObject { private static Logger logger = LoggerFactory.getLogger(AwesomeObject.class.getName()); public static void main(String args) { logger.info(Starting application.); logger.debug(Got args: {}, args);
try { crash(); } catch( Exception e ) { logger.error(Encountered a problem! See exc, e); } logger.log(Level.FINER, Exiting application.);
public class AwesomeObject { private static Logger logger = LoggerFactory.getLogger(AwesomeObject.class.getName()); public static void main(String args) { logger.info(Starting application.); logger.debug(Got args: {}, args);
try { crash(); } catch( Exception e ) { logger.error(Encountered a problem! See exc, e); } logger.log(new myExitMarker(), Exiting application.);
S System administrators/operators
S Installing application.
S Starting application. S Shutting down application.
S Support Personnel
S Monitors of application.
S Developers
S Debugging applications.
S Measuring performance. S Using your class/API.
S Machines
S Scripts
S Automation tools S Operation tools
Severity Levels
Not Triage-able
S S S S S
DEBUG: Began session DEBUG: DB access pass for user_id=154314, measure_id=14. DEBUG: DB access fail for user_id=41234113, measure_id=15. DEBUG: DB access pass for user_id=1341234, measure_id=14. DEBUG: DB access pass for user_id=8224122, measure_id=14.
S
S S S S
DEBUG: Began session DEBUG: DB access pass for user_id=154314, measure_id=14. ERROR: DB access fail for user_id=41234113, measure_id=15. DEBUG: DB access pass for user_id=1341234, measure_id=14. DEBUG: DB access pass for user_id=8224122, measure_id=14.
S
S S S S
Severity Levels
S FATAL
S Application down.
S Application inaccessible. S High-level features are inaccessible. S Application aborted.
Severity Levels
S ERROR (SEVERE)
S Application was unable to recover from a problem.
S Application was able to recover but was unable to
Severity Levels
S WARN
S Potentially harmful problem has occurred that warrants
Severity Levels
S INFO
S Broad-brush
S High-level S Coarse-grain S System progress or state.
Severity Levels
S DEBUG (FINE)
S Low-level
S Fine-grain S Information for debugging S Generally turned off on production systems unless a
Hierarchies
Hierarchies
Hierarchies
Hierarchies
S AUDIT
S Completed / Failed business transactions.
S DB access. S Service access.
Hierarchies
Persistence
S Multiple files.
S Per application.
S Per date. S Per hierarchy/concerns.
Persistence
S /usr/local/explorys/[application-name]/
S [application-name]-[date].log
Principles
What, Where, When, & How
Principle #1
Principle #2
Principle #3
Principle #3 Ex.1
S NO (does not contain valuable information):
S log.debug(Here);
S log.debug(+++DEBUG+++); S log.debug(randomVariableWithoutLogComment);
Principle #3 Ex.2
S NO: S log.debug(Array values: {}, myArray); S Will print out a reference identity: Array@4dc911a5 S Does not have an overloaded toString();
S YES S log.debug(Array values: {}, Arrays.toString(myArray)); S Prints out a human-readable string value.
S Root cause.
/ Affected use-case.
/ Effect on Use-case
S User needs to repeat action, or did it succeed? S Did entire batch fail, or did just a single step?
S Values of parameters
S Packages/Libraries
Principle #3 Ex.3
public Measures[] getMeasures(User user, String type) { log.debug( BEGIN getMeasures(user={}, type={}), user, type); Measures[] res = ; log.debug(END getMeasures() => {}, res.length); return res; }
Principle #3 Ex.4
S NO:
try {} catch(Exception e) { log.error(Caught exception, did nothing, e); throw e; } Exception e = ; log.error( Created exc and printed it redundantly here, e); throw e;
S NO:
IO
S File S DB
Principle #4
Principle #5
Principle #5 Ex.1
S ADMIN: S log.error( PDV failed to start because the datasource {} could not be accessed, please ensure that {} is accessible by); S DEV: S log.error( PDV attempted to do {} but was unable to because of exception {});
Principle #6
Be mindful of performance
Principle #6 Ex.1
S Acquire a single logger instance.
S private Logger logger =
Principle #6 Ex.2
S Logging info quantity/size can/should be altered
Principle #7
Principle #7 Ex.1
S Yes:
Principle #8
S Be safe
Principle #8 Ex.1
S log.debug(Obtained {}, user.getId()); S are you sure user isnt null? S log.debug(Obtained {}, collection.get(1)); S are you sure there there are enough elements? S log.debug(Connection closed: {}, conn.close()); S are you sure debug level statements are enabled? S are you sure theyll be enabled in production?
Next Steps
Action Items
S Alex
S Test slf4j and LogBack integration in current environment.
S Test slf4j migrator. S Test LogBack Eclipse tool.
S Team
S Study logger use. S Begin using standard jdk logging in the areas identified. S Be mindful of best-practices and principles.