You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-user@logging.apache.org by Datoh <da...@free.fr> on 2002/05/12 18:17:25 UTC

Add your own field in a pattern layout

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.
	datoh@free.fr


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>