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>