log4j2 to print each level logs in seperate file

房东的猫 提交于 2019-12-08 11:08:43

问题


I need to print each level logs in a seperate file. For example, Debug msg alone should print in debug file and not other level logs should print in debug file.. I am new to logs , so can you correct the code.

<?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:


There are at least 2 different ways you could achieve what you want. One way is to use the LevelRangeFilter (see log4j2 javadoc) as shown in the following example configuration:

<?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>

The above configuration ensures that each appender accepts log events of exactly one level only.

Another option is to use the RoutingAppender (see log4j2 manual) as demonstrated in the following configuration:

<?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>

In this configuration the appenders are indifferent toward the level of the log event. The RoutingAppender is the decision maker with regard to which events go to which appender. I tend to prefer using RoutingAppender because it can be made more compact by taking advantage of the log4j2 plugin system. If you add your own lookup which returns the name of the level associated with the log event you can use that lookup to dynamically create appenders on the fly. The code for the lookup and the revised configuration are shown below:

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();
    }
}

Here is the revised configuration that takes advantage of the new lookup:

<?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>

As with the other configurations this will send log messages to a file based on the log level of the log event. For example INFO level events will be logged to logs/INFO.log

I hope this helps you.



来源:https://stackoverflow.com/questions/48708779/log4j2-to-print-each-level-logs-in-seperate-file

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!