log4j2在单独的文件中打印每个级别的日志

时间:2018-02-09 15:12:10

标签: log4j2

我需要在单独的文件中打印每个级别的日志。例如,单独的Debug msg应该在调试文件中打印,而不应该在调试文件中打印其他级别的日志。 我是新手,所以你可以更正代码。

<?xml version="1.0" encoding="UTF-8"?>
<Configuration monitorinterval="30" status="info" strict="true">
    <Properties>
        <Property name="debug">D://logs/debug.log</Property>
        <Property name="info">D://logs/info.log</Property>
        <Property name="warn">D://logs/warn.log</Property>
        <Property name="error">D://logs/error.log</Property>
        <Property name="fatal">D://logs/fatal.log</Property>
    </Properties>
    <Appenders>    
        <Appender type="File" name="Debug_file" fileName="${debug}">
            <Layout type="PatternLayout" pattern="%d %p %C{1.} [%t] %m%n" />
        </Appender>
        <Appender type="File" name="Info_file" fileName="${info}">
            <Layout type="PatternLayout" pattern="%d %p %C{1.} [%t] %m%n" />
        </Appender>
        <Appender type="File" name="Warn_file" fileName="${warn}">
            <Layout type="PatternLayout" pattern="%d %p %C{1.} [%t] %m%n" />
        </Appender>
        <Appender type="File" name="Error_file" fileName="${error}">
            <Layout type="PatternLayout" pattern="%d %p %C{1.} [%t] %m%n" />
        </Appender>
        <Appender type="File" name="Fatal_file" fileName="${fatal}">
            <Layout type="PatternLayout" pattern="%d %p %C{1.} [%t] %m%n" />
        </Appender>      
    </Appenders>
    <Loggers>
        <Root level="debug">
            <AppenderRef ref="File" />
        </Root>
    </Loggers>
</Configuration>

1 个答案:

答案 0 :(得分:0)

至少有2种不同的方法可以实现所需的目标。一种方法是使用LevelRangeFilter(请参见log4j2 javadoc),如以下示例配置所示:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Properties>
        <Property name="LOG_PATTERN">%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</Property>
    </Properties>
    <Appenders>
        <File name="TraceFile" fileName="logs/Trace.log" immediateFlush="true"
            append="true">
            <PatternLayout pattern="${LOG_PATTERN}" />
            <LevelRangeFilter minLevel="TRACE" maxLevel="TRACE" onMatch="ACCEPT" onMismatch="DENY"/>
        </File>
        <File name="DebugFile" fileName="logs/Debug.log" immediateFlush="true"
            append="true">
            <PatternLayout pattern="${LOG_PATTERN}" />
            <LevelRangeFilter minLevel="DEBUG" maxLevel="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
        </File>
        <File name="InfoFile" fileName="logs/Info.log" immediateFlush="true"
            append="true">
            <PatternLayout pattern="${LOG_PATTERN}" />
            <LevelRangeFilter minLevel="INFO" maxLevel="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
        </File>
        <File name="WarnFile" fileName="logs/Warn.log" immediateFlush="true"
            append="true">
            <PatternLayout pattern="${LOG_PATTERN}" />
            <LevelRangeFilter minLevel="WARN" maxLevel="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
        </File>
        <File name="ErrorFile" fileName="logs/Error.log" immediateFlush="true"
            append="true">
            <PatternLayout pattern="${LOG_PATTERN}" />
            <LevelRangeFilter minLevel="ERROR" maxLevel="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
        </File>
        <File name="FatalFile" fileName="logs/Fatal.log" immediateFlush="true"
            append="true">
            <PatternLayout pattern="${LOG_PATTERN}" />
            <LevelRangeFilter minLevel="FATAL" maxLevel="FATAL" onMatch="ACCEPT" onMismatch="DENY"/>
        </File>
    </Appenders>

    <Loggers>
        <Root level="TRACE">
            <AppenderRef ref="TraceFile" />
            <AppenderRef ref="DebugFile" />
            <AppenderRef ref="InfoFile" />
            <AppenderRef ref="WarnFile" />
            <AppenderRef ref="ErrorFile" />
            <AppenderRef ref="FatalFile" />
        </Root>
    </Loggers>
</Configuration>

以上配置可确保每个附加程序仅接受仅一个级别的日志事件。

另一种选择是使用RoutingAppender(请参阅log4j2 manual),如以下配置所示:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Properties>
        <Property name="LOG_PATTERN">%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</Property>
    </Properties>
    <Appenders>
        <File name="TraceFile" fileName="logs/Trace.log" immediateFlush="true"
            append="true">
            <PatternLayout pattern="${LOG_PATTERN}" />
        </File>
        <File name="DebugFile" fileName="logs/Debug.log" immediateFlush="true"
            append="true">
            <PatternLayout pattern="${LOG_PATTERN}" />
        </File>
        <File name="InfoFile" fileName="logs/Info.log" immediateFlush="true"
            append="true">
            <PatternLayout pattern="${LOG_PATTERN}" />
        </File>
        <File name="WarnFile" fileName="logs/Warn.log" immediateFlush="true"
            append="true">
            <PatternLayout pattern="${LOG_PATTERN}" />
        </File>
        <File name="ErrorFile" fileName="logs/Error.log" immediateFlush="true"
            append="true">
            <PatternLayout pattern="${LOG_PATTERN}" />
        </File>
        <File name="FatalFile" fileName="logs/Fatal.log" immediateFlush="true"
            append="true">
            <PatternLayout pattern="${LOG_PATTERN}" />
        </File>

        <Routing name="Routing">
            <Routes>
                <Script name="RoutingInit" language="JavaScript"><![CDATA[
                    logEvent.getLevel();]]>
                </Script>
                <Route ref="TraceFile" key="TRACE" />
                <Route ref="DebugFile" key="DEBUG" />
                <Route ref="InfoFile" key="INFO" />
                <Route ref="WarnFile" key="WARN" />
                <Route ref="ErrorFile" key="ERROR" />
                <Route ref="FatalFile" key="FATAL" />
            </Routes>
        </Routing>
    </Appenders>

    <Loggers>
        <Root level="TRACE">
            <AppenderRef ref="Routing" />
        </Root>
    </Loggers>
</Configuration>

在此配置中,附加程序对日志事件的级别无关紧要。 RoutingAppender是有关哪个事件到达哪个追加程序的决策者。我倾向于使用RoutingAppender,因为可以利用log4j2 plugin system使它更紧凑。如果添加your own lookup来返回与日志事件关联的级别的名称,则可以使用该查找动态地动态创建附加程序。查找和修改后的配置代码如下所示:

import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.lookup.StrLookup;

@Plugin(name = "level", category = "Lookup")
public class LevelLookup implements StrLookup{
    /**
     * Lookup the value for the key.
     * @param key  the key to be looked up, may be null
     * @return The value for the key.
     */
    public String lookup(String key) {
        return null;
    }


    /**
     * Lookup the value for the key using the data in the LogEvent.
     * @param event The current LogEvent.
     * @param key  the key to be looked up, may be null
     * @return The value associated with the key.
     */
    public String lookup(LogEvent event, String key) {
        return event.getLevel().name();
    }
}

以下是修改后的配置,它利用了新的查找功能:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Properties>
        <Property name="LOG_PATTERN">%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</Property>
    </Properties>
    <Appenders>
        <Routing name="Routing">
            <Routes pattern="$${level:}">
                <Route>
                    <File name="${level:}File" fileName="logs/${level:}.log" immediateFlush="true"
                        append="true">
                        <PatternLayout pattern="${LOG_PATTERN}" />
                    </File>
                </Route>
            </Routes>
        </Routing>
    </Appenders>

    <Loggers>
        <Root level="TRACE">
            <AppenderRef ref="Routing" />
        </Root>
    </Loggers>
</Configuration>

与其他配置一样,它将根据日志事件的日志级别将日志消息发送到文件。例如,INFO级事件将记录到logs / INFO.log

希望对您有帮助。