So, I am creating a custom logback layout based:
public class MyCustomLayout extends LayoutBase<ILoggingEvent> {
private String mySimpleArg;
public void setMySimpleArg(String mySimpleArg) {
this.mySimpleArg = mySimpleArg;
}
public String doLayout(IlogginEvent iLoggingEvent) {
//generate log in my format and use mySimpleArg
}
}
and in my logback.xml I have
<appender ...>
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="path.to.MyCustomLayout">
<mySimpleArg>some text</mySimpleArg>
</layout>
</encoder>
...
</appender>
Now, the problem is, I also need to read more complex arguments from my XML conf and I cannot find any info in logback docs as well as on Google. To be specific, I need something like
public class MyCustomLayout extends LayoutBase<ILoggingEvent> {
private String mySimpleArg;
//the Pair here is just to show I need something key -> value based
private Pair<String, Object>[] myComplexArray;
public void setMySimpleArg(String mySimpleArg) {
this.mySimpleArg = mySimpleArg;
}
public void setMyComplexArray(Pair<String, Object>[] myComplexArray) {
this.myComplexArray = myComplexArray;
}
public String doLayout(IlogginEvent iLoggingEvent) {
//generate log in my format and use mySimpleArg and myComplexArray
}
}
and in logback.xml
<appender ...>
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="path.to.MyCustomLayout">
<mySimpleArg>some text</mySimpleArg>
<myComplexArray>
<myComplexElement key="key1" value="value1"/>
<myComplexElement key="key2" value=5/>
</myComplexArray>
</layout>
</encoder>
...
</appender>
In order for Logback to populate a complex, collection type on a custom object in its domain the following must hold true:
Foo
and it contains a collection of Bar
then Foo
must expose a public addBar(Bar bar){}
method.With this in mind, the following config ...
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="path.to.MyCustomLayout">
<mySimpleArg>some text</mySimpleArg>
<myComplexArray>
<myComplexElement>
<key>key1</key>
<value>value1</value>
</myComplexElement>
<myComplexElement>
<key>key2</key>
<value>value2</value>
</myComplexElement>
</myComplexArray>
</layout>
</encoder>
... will work as long as you declare MyCustomLayout
like this ...
public class MyCustomLayout extends LayoutBase<ILoggingEvent> {
private String mySimpleArg;
private MyComplexArray myComplexArray;
public void setMySimpleArg(String mySimpleArg) {
this.mySimpleArg = mySimpleArg;
}
public void setMyComplexArray(MyComplexArray myComplexArray) {
this.myComplexArray = myComplexArray;
}
public String doLayout(ILoggingEvent iLoggingEvent) {
// generate log in my format and use mySimpleArg and myComplexArray
return "...";
}
}
... and you provide the following class definitions for MyComplexArray
and MyComplexElement
(note: the names of these classes must match the element names you use in logback.xml
):
public class MyComplexArray {
private List<MyComplexElement> myComplexElements = new ArrayList<>();
public MyComplexArray() {
}
public void addMyComplexElement(MyComplexElement myComplexElement) {
myComplexElements.add(myComplexElement);
}
}
public class MyComplexElement {
private String key;
private String value;
public MyComplexElement() {
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
If that's all too awkward then you may want to fall back to a simple String property (just like <mySimpleArg>
) and pass in an encoded string from which you derive a 'complex object' inside MyCustomLayout
. For example:
<myComplexArg>foo=bar,bas=1|x=y,z=2</myComplexArg>