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]>

Reply via email to