Hi, I tried to add my own field in a pattern layout and the simple way I found was to used %m to do this. The goal is to have a pattern like that:
%r [%t] %-5p %c - ERROR: %m{ERROR} - %m{MESSAGE}%n ========================== ========================== The object store in the logEvent must implements a special interface: public interface IMyObject { public Hashtable getValues(); public int getCountValue(); // return the number of value. public String getValueName(int n); // return the name of the key n. } With getValues(), you can get from this object a table (<key,value>) with all the value of the object. ========================== ========================== So i create my own PatternParser which extends PatternParser: public class MyPatternParser extends PatternParser { public MyPatternParser(String pattern) { super(pattern); } protected void finalizeConverter(char c) { PatternConverter pc = null; switch(c) { case 'm': // Get extra option String xOptM = extractOption(); if(xOptM!=null) { // if there is one option use my pattern converter pc = new MessagePatternConverter(formattingInfo, xOptM); currentLiteral.setLength(0); } else { // else use the default pattern converter super.finalizeConverter(c); return; } break; default: super.finalizeConverter(c); return; } addConverter(pc); } // --------------------------------------------------------------------- // PatternConverters // --------------------------------------------------------------------- private static class MessagePatternConverter extends PatternConverter { private String key; MessagePatternConverter(FormattingInfo formattingInfo, String key) { super(formattingInfo); this.key = key; } public String convert(LoggingEvent event) { if(event.getMessage() instanceof IMyObject) // return the String contains in the hashtable return (String) ((IMyObject) event.getMessage()).getValues().get(key); else return null; } } } ========================== ========================== So now i only need a layout that used parser public class MyPatternLayout extends PatternLayout { public MyPatternLayout() { super(); } public MyPatternLayout(String pattern) { super(pattern); } protected PatternParser createPatternParser(String pattern) { return (PatternParser) new MyPatternParser(pattern); } } ========================== ========================== An exemple of a program that used this layout: public class Test { private static Category cat = Category.getInstance(Test.class.getName()); private static class MyObject implements IMyObject { private int error; private String message; public MyObject(int error, String message) { this.error = error; this.message = message; } public Hashtable getValues() { Hashtable table = new Hashtable(); table.put("ERROR", String.valueOf(error)); table.put("MESSAGE", message); return table; } public int getCountValue() { return 2; } public String getValueName(int n) { switch(n) { case 0: return "ERROR"; case 1: return "MESSAGE"; default: return null; } } } public static void main(String[] args) { PropertyConfigurator.configure("log4j.properties"); MyObject obj = new MyObject(1, "error 1"); cat.info(obj); obj = new MyObject(2, "error 2"); cat.info(obj); } } ========================== ========================== And finally, a log4j.properties exemple: # Level.INFO, attach appender A1. log4j.rootLogger=INFO, A1 # Appender A1 writes to the file "test.log". log4j.appender.A1=org.apache.log4j.FileAppender log4j.appender.A1.File=test.log # Truncate 'test.log' if it aleady exists. log4j.appender.A1.Append=false # Appender A1 uses the MyPatternLayout. log4j.appender.A1.layout=test.log4j.MyPatternLayout log4j.appender.A1.layout.ConversionPattern=%r [%t] %-5p %c - ERROR: %m{ERROR} (%m{MESSAGE})%n I hope this will help you. [EMAIL PROTECTED] -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>