因此,我正在基于以下内容创建自定义的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 "...";
    }
}


...,并为MyComplexArrayMyComplexElement提供以下类定义(注意:这些类的名称必须与您在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/

10-13 01:16