因此,我正在基于以下内容创建自定义的logback布局:
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
}
}
在我的logback.xml中
<appender ...>
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="path.to.MyCustomLayout">
<mySimpleArg>some text</mySimpleArg>
</layout>
</encoder>
...
</appender>
现在的问题是,我还需要从我的XML conf中读取更复杂的参数,并且无法在logback文档以及Google中找到任何信息。具体来说,我需要类似
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
}
}
并在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>
最佳答案
为了使Logback在其域中的自定义对象上填充复杂的集合类型,必须满足以下条件:
Logback必须能够使用简单的XML元素名称->类名称映射来发现复杂的对象
复杂对象必须公开一个“加法”,例如如果复杂类型称为Foo
,并且包含Bar
的集合,则Foo
必须公开public addBar(Bar bar){}
方法。
考虑到这一点,以下配置...
<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>
只要您这样声明
MyCustomLayout
就可以使用...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 "...";
}
}
...,并为
MyComplexArray
和MyComplexElement
提供以下类定义(注意:这些类的名称必须与您在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;
}
}
如果这太尴尬了,那么您可能希望回到简单的String属性(就像
<mySimpleArg>
一样)并传入一个编码的字符串,从中您可以在MyCustomLayout
内派生一个“复杂对象”。例如:<myComplexArg>foo=bar,bas=1|x=y,z=2</myComplexArg>
关于java - 具有复杂属性的Logback自定义布局,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46832815/