The Java Logging API and Lumberjack

Size: px
Start display at page:

Download "The Java Logging API and Lumberjack"

Transcription

1 The Java Logging API and Lumberjack

2 Please Turn off audible ringing of cell phones/pagers Take calls/pages outside

3 About this talk Discusses the Java Logging API Discusses Lumberjack Does not discuss log4j Another open source logging library Does not compare log4j to the Java Logging API I don't know log4j Can't tell you which is better for your situation The two API's seem pretty similar Please don't try to engage me in an argument about which is better, log4j or Java Logging :-)

4 Overview - what is Java Logging? Copyright 2001 Brian R. Gilstrap First introduced in Java Specification Request (JSR) 47 Title: Logging API Specification Description: Define standard logging APIs for the error and trace logging. Included in JDK 1.4 (currently in late beta) Free implementation for JDK 1.2/1.3 available Called Lumberjack Available from Designed for messages related to Program debugging Error reporting General diagnostics

5 Overview (cont) Copyright 2001 Brian R. Gilstrap A Java Class Library Designed to be: * Simple to use *Fast Leave logging code in production executable * Configurable Suppress generation of records that are not of interest *Flexible Provide a number of common output formats * Extensible * Usable out-of-the-box Default configuration - can be overridden Default set of handlers

6 Overview (cont) Copyright 2001 Brian R. Gilstrap Dynamically configurable at runtime: Change what gets logged Levels Filters Change where log records are output Handlers Change output format Formatters Extensible classes/interfaces include: Level Filter Handler Formatter LogManager

7 Basic Architecture Copyright 2001 Brian R. Gilstrap Application Logger Handler Outside World Filter Filter Formatter

8 Level Copyright 2001 Brian R. Gilstrap Indicates the importance of a record Used to perform a quick filter to weed out irrelevant messages Standard levels: SEVERE (most important) WARNING INFO CONFIG FINE FINER FINEST (least important)

9 Logger Copyright 2001 Brian R. Gilstrap Application Logger Handler Outside World Filter Filter Formatter Used to generate logging messages Do preliminary filtering of messages Only those of high enough importance actually logged Can use a Filter to further filter records Can have Handlers attached to handle records Generally have a name Can have anonymous loggers, but not generally used. If record is not filtered, forwards record to parent Loggers' Handlers Can be turned off

10 Logger (cont) Copyright 2001 Brian R. Gilstrap Created or retrieved via a static method: public static Logger getlogger( String aname ); Logger awtlogger = Logger.getLogger( "java.awt" ); Assures only one Logger with a given name in a VM. Two pieces of code that ask for a Logger with the same name will share the same Logger object.

11 Logger Methods Copyright 2001 Brian R. Gilstrap General logging methods boolean isloggable( Level alevel ) Perform filtering check void log( Level l, No class and method names specified, String amessage ), String amessage, Object param ) void logp( Level l,, String amessage, Object[] params ) String sourceclass, String sourcemethod, Class name and method name void logrb( Level l, String sourceclass, String sourcemethod, String rsrcbundle, Class name, method name, and resource bundle (internationalization)

12 Logger Methods (cont) Copyright 2001 Brian R. Gilstrap Convenience methods entering(...) (message == "ENTRY"; Level == FINER) exiting(...) (message == "RETURN"; Level == FINER) fine( ) finer( ) finest( ) info( ) severe( ) warning( ) ( String amessage ) ( String amessage, Object param ) ( String amessage, Object[] params ) caught( Level l, Throwable t ); throwing( Level l, Throwable t ); ( String amessage, Object param ) ( String amessage, Object[] params )

13 Logger Methods (cont) Configuration public Level getlevel(); public setlevel( Level alevel ); public Filter getfilter() public setfilter( Filter afilter ); public Handler[] gethandlers(); public addhandler( Handler ahandler ); public removehandler( Handler ahandler ); public boolean getuseparenthandlers(); public setuseparenthandlers( boolean useparenthandlers );

14 A Simple Example Copyright 2001 Brian R. Gilstrap public class HelloWorld { private static Logger thelogger = Logger.getLogger( HelloWorld.class.getName() ); public static void main( String[] args ) { HelloWorld hello = new HelloWorld( "Hello Everybody!" ); hello.sayhello(); } private String themessage; public HelloWorld( String message ) { themessage = message; } } public void sayhello() { thelogger.info( HelloWorld.class.getName(), "sayhello" themessage ); }

15 Logger Hierarchy Copyright 2001 Brian R. Gilstrap Organized by name Pieces of the names are separated by dots ('.') Follow the package naming of the Java Classes e.g. java.util.logging Root Logger Name is the empty string Root of Logger tree Names can be for packages and not just classes java.util net "" Sourceforge.javalogging hello installer test Root Logger java util

16 Logger Hierarchy (cont) Loggers with no Level inherit from immediate parent. net.sourceforge.javalogging.installer.installer would inherit from: net.sourceforge.javalogging.installer net.sourceforge.javalogging net.sourceforge net "" (Root Logger)

17 Logger Hierarchy (cont) Examples: net.sourceforge == WARNING net.sourceforge == WARNING net.sourceforge.javalogging == INFO net.sourceforge.javalogging == null Effective level is WARNING net.sourceforge.javalogging.installer.installer == null Effective level is INFO net.sourceforge.javalogging.installer.installer == null Effective level is WARNING

18 Logger Hierarchy (cont) Loggers forward records to parents' Handlers No further Logger checks are made Record goes directly to the Handlers of each parent in the chain Filters attached to a Handler may still filter record Call to Logger No level check No level check 1 10 net 8 Handler 7 9 net.sourceforge 5 4 Handler Filter does not pass Filter Net.sourceforge.javalogging.installer.Installer 6 Outside world Passes Level check 2 Handler 3 Outside world

19 Anonymous loggers Have no name Their parent is the Root Logger By default their messages go to any handlers attached to the Root Logger Do not affect other Loggers Generally only used by things like applets

20 The "global" logger Static field of the Logger class public static final Logger global = Logger.getLogger( "global" ); Has name global Root Logger is its parent Intended for "casual" use of the Logging API.

21 LogRecord Contains the message plus some additional information Not generated until Logger level test is passed Must be >= Logger Level Can be created by programmer directly

22 LogRecord - Highlights Level - level of message Logger name - name of logger that created the record Message - the message passed to the logger Millis - when record was generated (in milliseconds) Parameters - any parameters specified to the Logger Seq # - a unique sequence number for the record Source class name - name of class whose code called Logger Guessed if not specified Guess is not always right Source method name - name of method which called the Logger Guessed if not specified Guess is not always right Thrown - any Throwable (exception) that was provided

23 LogManager Copyright 2001 Brian R. Gilstrap Singleton LogManager.getLogManager(); Used to bootstrap logging Keeps track of all named Loggers Reads a configuration file when created JRE lib/logging.properties Change file read by setting java.util.logging.config.file property Can be sub-classed for special-purposes EJB Containers Custom behavior Etc.

24 logging.properties Copyright 2001 Brian R. Gilstrap Read by LogManager System Properties are defaults Useful for setting logging properties using java -D... Values retrieved via LogManager's getproperty() method Java Properties file. Lives in $JAVA_HOME/lib/logging.properties JRE lib directory

25 logging.properties contents *.level - any property ending in '.level' is assumed to specify a logging Level for some Logger net.sourceforge.javalogging.installer.installer=finer java.util.level=error ".level" - used to specify the Level for the Root Logger etc. "handlers" - defines a whitespace separated list of class names Classes to load and register as Handlers on the root Logger Must extend Handler Properties for specific logging classes (more later)

26 logging.properties contents (cont) "config" - defines a whitespace separated list of class names Intended to allow arbitrary configuration code to be run. One new instance will be created for each class named using default constructor (no args) constructor must be public Constructor may execute arbitrary code update the logging configuration setting logger levels adding handlers adding filters etc. perform other initialization All Handlers and Config classes must be on the bootstrap classpath.

27 Handlers Application Logger Handler Outside World Filter Filter Formatter Process LogRecords Can do anything with the record Typically send it outside the program Can do other things (e.g. MemoryHandler) Have their own Level LogRecords with too low a level won't be output Can have a Filter After Level test, must also pass Filter to be output

28 Handlers (cont) Handlers get properties from LogManager LogManager gets them from logging.properties Can have more than one Handler attached to the same Logger Handler Application Logger Handler Handler

29 Handlers (cont) Each Handler is asked to handle the LogRecord Order in which Handlers are called is not specified Don't assume a particular order Handler Application Logger Handler Handler

30 java.util.logging.consolehandler Sends output to standard error java.util.logging.consolehandler.level Level for Handler (default: Level.INFO) java.util.logging.consolehandler.filter Name of Filter (default: no Filter) java.util.logging.consolehandler.formatter Name of Formatter (default: SimpleFormatter) java.util.logging.consolehandler.encoding Character set encoding (default: default platform encoding)

31 java.util.logging.filehandler Sends output to a file or cycles through a collection of files java.util.logging.filehandler.level Level for Handler (default: Level.ALL) java.util.logging.filehandler.filter Name of Filter (default: no Filter) java.util.logging.filehandler.formatter Name of Formatter (default: XMLFormatter) java.util.logging.filehandler.encoding Character set encoding (default: default platform encoding) java.util.logging.filehandler.limit Maximum file size (bytes) (default: 0 => no limit).

32 FileHandler Properties (cont) java.util.logging.filehandler.count # output files (default: 1) java.util.logging.filehandler.append Append onto existing files (default: false) java.util.logging.filehandler.pattern Pattern for generating the output file name (default: "%h/java%u.log")

33 java.util.logging.filehandler.pattern Copyright 2001 Brian R. Gilstrap Supports several special components replaced at runtime "/" - Replaced by the local pathname separator "%t" - System temporary directory /tmp C:\temp etc. "%h" - Value of the "user.home" system property "%g" - "%u" - Generation number to distinguish rotated logs Starts with 0 If not specified and file count > 1, ".%g" is added to pattern automatically Unique number to resolve conflicts between multiple Java programs "%%" - Literal percent sign "%"

34 java.util.logging.sockethandler Sends output through a socket java.util.logging.sockethandler.level Level for Handler (default: Level.ALL) java.util.logging.sockethandler.host Host to send to (default: no default) java.util.logging.sockethandler.port TCP port to use (default: no default) java.util.logging.sockethandler.filter Name of Filter (default: no Filter) java.util.logging.sockethandler.formatter Name of Formatter (XMLFormatter) java.util.logging.sockethandler.encoding Character set encoding (default: default platform encoding)

35 java.util.logging.memoryhandler Logger MemoryHandler Handler Outside World LogRecords Circular ("ring") buffer of LogRecords Holds N most recent records until triggered to push them to another handler When buffer filled, new records cause oldest record to be discarded Doesn't format its own records Has a level called the "push level" Forwards records to another handler whenever push is called An incoming LogRecord's Level meets the push level default push level is Level.SEVERE push is called explicitly. A subclass overrides log method and calls push on some condition.

36 java.util.logging.memoryhandler (cont) java.util.logging.memoryhandler.level Level for Handler (default: Level.ALL) java.util.logging.memoryhandler.filter Name of Filter (default: no Filter) java.util.logging.memoryhandler.size Buffer size (in records) (default: 1000) java.util.logging.memoryhandler.push PushLevel (default: level.severe) java.util.logging.memoryhandler.target Target Handler class (default: no default)

37 Formatters Copyright 2001 Brian R. Gilstrap Application Logger Handler Outside World Filter Filter Formatter Format LogRecords for output Supports notion of a head and tail Head gets printed at the start of the file Tail gets printed at the end of the file Can be null Can be attached to any Handler Two Standard formatters SimpleFormatter XMLFormatter

38 java.util.logging.simpleformatter Prints a brief textual representation of a LogRecord Has no head or tail Nov 27, :26:04 PM net.sourceforge.javalogging.test.helloworld sayhello INFO: Hello Everybody!

39 java.util.logging.xmlformatter Creates an XML document for a set of records Has a head <?xml version="1.0" encoding="utf-8" standalone="no"?> <!DOCTYPE log SYSTEM "logger.dtd"> <log> Has a tail </log> Each LogRecord produces a <record> element

40 java.util.logging.xmlformatter Output <?xml version="1.0" encoding="utf-8" standalone="no"?> <!DOCTYPE log SYSTEM "logger.dtd"> <log> <record> <date> t12:38:52</date> <millis> </millis> <sequence>3244</sequence> <logger>com.foo</logger> <level>info</level> <class>com.foo.testxmlformatter</class> <method>writearecord</method> <thread>15</thread> <message>hello world!</message> </record> </log>

41 java.util.logging.filter Application Logger Handler Outside World Filter Filter Formatter Interface One method boolean isloggable(logrecord record) Returns true if the LogRecord should be logged/handled. Can be attached to Loggers and Handlers No pre-built filters

42 java.util.logging.errormanager Won't use unless you are implementing a Handler Used by Handlers to report problems public void error( String msg, Exception ex, int code ); Default behavior is to write a message to standard error Has some predefined codes to indicate the nature of the problem CLOSE_FAILURE FLUSH_FAILURE FORMAT_FAILURE GENERIC_FAILURE OPEN_FAILURE WRITE_FAILURE

43 Extending the Framework Custom Levels For new levels of importance Need to take care to fit into existing Levels Done as part of ESI Event Logging tie-in Custom Filters - allow for other criteria Time of day, day of week, etc. Contents of message Any field of LogRecord Etc. Custom Handlers Custom Formatters Custom LogManager

44 Lumberjack Open Source (LGPL) implementation of Java Logging API Home Page: javalogging.sourceforge.net Written by Brian Gilstrap Contributors welcome Bug reports welcome

45 Using Lumberjack with JDK 1.2/1.3 Provides logging API for JDK 1.2 & 1.3 Get Lumberjack Download from javalogging.sourceforge.net Unpack JAR Run installer

46 Installing Lumberjack java -jar logging.jar Brings up a GUI that installs Lumberjack Checks to make sure it's compatible with your JRE Won't install on top of 1.4's implementation Won't install into a JDK < 1.2

47 Installing Lumberjack (cont) Asks if you want to overwrite any existing installation Even if you overwrite, also asks if you want to overwrite any existing logging.properties Requires that you have permission to alter the JRE directories

48 Using Lumberjack without installing (no permissions or on MacOS X) Put logging.jar on your bootstrap classpath -Xbootclasspath/a:$HOME/Library/logging.jar Put logging.properties into JRE lib /System/Library/Frameworks/JavaVM.framework/Home/lib This is ugly I'm working to make the GUI work on MacOS X too Can't give you permissions to alter JRE directories :-)

49 A Few Statistics java.util.logging 16 Source files 2924 lines of code 20 Classes (including nested classes) net.sourceforge.javalogging.installer 2 Source files 242 lines of Code 5 Classes (including nested classes) logging.jar bytes 18 Source files 3166 lines of Code

50 The Dodgy Bits areas where Lumberjack is currently weak or non-comformant Copyright 2001 Brian R. Gilstrap Resource Bundles (fixable) Doesn't implement latest spec: search order to find resource bundles Any resource bundle guru's want to vett the code? FileHandler (fixable) Has a number of open bugs Source class and method guessing (not fixable?) Slow (requires parsing stack trace generated from a Throwable) 1.4 has a StackFrame API that should make it much faster (need to measure) Serialization of LogRecord exception (not fixable?) 1.4 Serialization of a Throwable includes any stack trace 1.3 & prior do not Can't do RMI between 1.4 & earlier systems involving LogRecords

51 References Copyright 2001 Brian R. Gilstrap JSR 47 (the Logging API specification) JDK 1.4 beta 3 documentation of Logging ml e-summary.html Project page for Lumberjack Article on the Logging API

52 Thanks Please use Lumberjack, that's why I wrote it :-)