// $Id: PatternFormatter.java,v 1.2 2009-06-08 17:47:18 mike Exp $ package org.faceless.util.log; import java.text.*; import java.util.logging.*; import java.util.logging.Formatter; import java.io.*; import java.util.*; /** * A simple, configurable formatter for the java.util.logging package. * It works like the * * PatternLayout class for Log4J - the codes are the closest analogous matches from the * java.util.logging package. See that class for full details. *
*
%%
the percent sign
*
%c
the name of the logger, which unlike Log4j may be null
*
%C
the class name of the class that created the LogRecord, which may be null
*
%d
the formatted date - eg %d, %d{dd-MMM-yyyy}
*
%m
the formatted message included in the LogRecord, which may be localized
*
%M
the method name that created the LogRecord, which unlike Log4j may be null
*
%n
the newline character
*
%p
the level of the message, eg FINEST, WARNING, SEVERE
*
%t
the Thread ID of the thread that created the message
*
%x
the Throwable object included with the LogRecord: %x{notrace} will just print the exception name and message
*
%i
the sequence number of the LogRecord (not part of Log4j
*
%nP
the specified parameter - %1p for the first, %2p for the second and so on (not part of Log4j)
*
* The format is initialized using the logging.properties file, and may be * set for each level. Here's an example: *
 * org.faceless.util.log.PatternFormatter.format = %d{yyyy-MM-dd} %p: %m %x
 * org.faceless.util.log.PatternFormatter.SEVERE.format = %d: ERROR: %s at %c(%m)
 * 
*

* Alternatively the {@link #setFormat setFormat()} methods may be called to set the message formats *

* This code was originally written 2009-06-08 by Mike Bremford and is in the public domain. *

*/ public class PatternFormatter extends Formatter { private static final String[] LEVELS = { "FINEST", "FINER", "FINE", "CONFIG", "INFO", "WARNING", "SEVERE" }; private static final String DEFAULT = "%d %p: %m %x"; private Map levelformats, dateformats; private String format = DEFAULT; /** * Create a new PatternFormatter */ public PatternFormatter() { LogManager manager = LogManager.getLogManager(); this.format = DEFAULT; this.dateformats = Collections.synchronizedMap(new HashMap()); String s = manager.getProperty(getClass().getName()+".format"); if (s != null && s.trim().length() > 0) { setFormat(null, s); } for (int i=0;i 0) { setFormat(LEVELS[i], s); } } } /** * Set the format for the specified level, or (if level is null) * for all levels * @param level one of FINEST, FINER, FINE, CONFIG, INFO, WARNING, SEVERE or null * @param format the format string */ public synchronized void setFormat(String level, String format) { if (level==null) { this.format = format; } else { if (levelformats==null) { levelformats = new HashMap(); } levelformats.put(level, format); } } public String format(LogRecord record) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); StringBuffer premod = new StringBuffer(); String thisformat = null; if (levelformats!=null) { thisformat = (String)levelformats.get(record.getLevel().getName()); } if (thisformat==null) { thisformat = this.format; } for (int i=0;i=0;j++) { p = s.lastIndexOf(".", p-1); } if (p!=-1) { s = s.substring(p+1); } } catch (Exception e) { } } pw.print(s); break; case 'd': if (postmod==null) { postmod = "dd-MMM-yyyy HH:mm:ss"; } ThreadLocal tl = (ThreadLocal)dateformats.get(postmod); if (tl==null) { final String format = postmod; tl = new ThreadLocal() { protected synchronized Object initialValue() { return new SimpleDateFormat(format); } }; dateformats.put(postmod, tl); } DateFormat df = (DateFormat)tl.get(); pw.print(df.format(new Date(record.getMillis()))); break; case 'C': s = record.getSourceClassName(); if (s!=null) { if (postmod!=null) { try { int num = Integer.parseInt(postmod); int p = s.length(); for (int j=0;j=0;j++) { p = s.lastIndexOf(".", p-1); } if (p!=-1) { s = s.substring(p+1); } } catch (Exception e) { } } pw.print(s); } break; case 'M': if (record.getSourceMethodName()!=null) { pw.print(record.getSourceMethodName()); } break; case 'm': pw.print(formatMessage(record)); break; case 'n': pw.print("\n"); break; case 'p': pw.print(record.getLevel().getName()); break; case 't': pw.print(record.getThreadID()); break; case 'x': if (record.getThrown()!=null) { if ("notrace".equals(postmod)) { pw.print(record.getThrown()); } else { record.getThrown().printStackTrace(pw); } } break; case '%': pw.print("%"); break; case 'i': pw.print(record.getSequenceNumber()); break; case 'P': Object[] params = record.getParameters(); try { if (postmod!=null) { int mod = Integer.parseInt(postmod); if (params!=null && params.length > mod) { pw.print(params[mod]); } } else if (params==null) { pw.print(params); } else { pw.print(Arrays.asList(params)); } } catch (Exception e) { } break; } premod.setLength(0); } else { pw.write(c); } } return sw.toString().trim() + "\n"; } }