Initialize slf4j with log4j2.xml

好久不见. 提交于 2021-02-08 09:24:40

问题


I want to use slf4j over log4j. I added the following dependencies in my pom.xml (I used 1.7.25 for slf4j and 2.10.0 for log4j2):

<dependencies>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>${slf4j.version}</version>
    </dependency>


    <dependency>
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-slf4j-impl</artifactId>
       <version>${log4j.version}</version>
    </dependency>

    <dependency>
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-api</artifactId>
       <version>${log4j.version}</version>
    </dependency>

    <dependency>
       <groupId>org.apache.logging.log4j</groupId>
       <artifactId>log4j-core</artifactId>
       <version>${log4j.version}</version>
    </dependency>
</dependencies> 

Everything builds just fine, no compilation errors or lack of dependencies, but I failed to specify the configuration (log4j2.xml) file in my class that is responsible for the initialization of the Logger. In this situation it always prints the same warning

log4j:WARN No appenders could be found for logger (com.mypackage.etc).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

I searched for a proper way to provide the configuration file and ended up with this:

LoggerContext context = (org.apache.logging.log4j.core.LoggerContext) LogManager.getContext(false);
File file = new File("path/to/a/different/log4j2.xml");
context.setConfigLocation(file.toURI());

The problem is that in my case LogManager.getContext(false) will always return an instance of Slf4JLoggerContext (considering that I use slf4j as a facade for the logger) and the initialization will fail with ClassCastException. I tried to store that instance of Slf4JLoggerContext, but it doesn't offer a setter for the context. Also I failed to find a way to retrieve a LoggerContext from log4j.

Is there any way to provide the configuration file (log4j2.xml) to slf4j in order to see all the appenders and loggers?

Update Consider this my configuration file (I replaced the original packages and appenders name):

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
    <Properties>
        <Property name="def.files.backup.count">10</Property>
        <Property name="log.file.path">${oo.home}/var/logs</Property>
        <Property name="def.file.max.size">10MB</Property>
        <Property name="log.level">WARN</Property>
    </Properties>

    <ThresholdFilter/>

    <Appenders>
        <RollingFile name="Appender1" fileName="${log.file.path}/file1.log" maxFileSize="${def.file.max.size}"
                     maxBackupIndex="${def.files.backup.count}">
            <PatternLayout>org.apache.log4j.PatternLayout</PatternLayout>
            <Policies>
                <SizeBasedTriggeringPolicy size="10MB"/>
            </Policies>
        </RollingFile>

        <RollingFile name="Appender2" fileName="${log.file.path}/file2.log"
                     maxFileSize="${def.file.max.size}"
                     maxBackupIndex="${def.files.backup.count}">
            <PatternLayout>org.apache.log4j.PatternLayout</PatternLayout>
            <Policies>
                <SizeBasedTriggeringPolicy size="10MB"/>
            </Policies>
        </RollingFile>

        <RollingFile name="Appender3" fileName="${log.file.path}/file3.log"
                     maxFileSize="${def.file.max.size}"
                     maxBackupIndex="${def.files.backup.count}">
            <PatternLayout>org.apache.log4j.PatternLayout</PatternLayout>
            <Policies>
                <SizeBasedTriggeringPolicy size="10MB"/>
            </Policies>
        </RollingFile>

    </Appenders>

    <Loggers>
        <AsyncLogger name="com.package1.oo" level="${log.level}" additivity="false">
            <AppenderRef ref="Appender1"/>
        </AsyncLogger>

        <AsyncLogger name="io.package2" level="${log.level}" additivity="false">
            <AppenderRef ref="Appender2"/>
        </AsyncLogger>

        <AsyncLogger name="com.package3.package3" level="${log.level}" additivity="false">
            <AppenderRef ref="Appender3"/>
        </AsyncLogger>

        <AsyncLogger name="org.package4" level="${log.level}">

        </AsyncLogger>

        <AsyncLogger name="com.package5.Class1" level="${log.level}">

        </AsyncLogger>

        <AsyncRoot level="${log.level}">
            <AppenderRef ref="Appender1"/>
            <AppenderRef ref="Appender2"/>
            <AppenderRef ref="Appender3"/>

        </AsyncRoot>
    </Loggers>

</Configuration>

回答1:


I have tested this configuration. The log4j2 file has to be in your classpath.

Maven

<dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-slf4j-impl</artifactId>
    </dependency>

log4j2.xml

Also, adding xsd helps you with creating configuration. I have added Logger for spring framework. Note, that jcl-over-slf4j is needed to work with spring's internal logging

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error"
               xmlns="http://logging.apache.org/log4j/2.0/config"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://logging.apache.org/log4j/2.0/config
                https://raw.githubusercontent.com/apache/logging-log4j2/master/log4j-core/src/main/resources/Log4j-config.xsd">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%highlight{%d{HH:mm:ss.SSS} [%t] %-5level %logger{36}} - %msg%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="debug">
            <AppenderRef ref="Console"/>
        </Root>
        <Logger name="org.springframework" level="error">
            <AppenderRef ref="Console"/>
        </Logger>
    </Loggers>
</Configuration>



回答2:


It doesn't seem to me from your question you're trying to specify a custom configuration location! See the Automatic Configuration section in the docs:

Log4j has the ability to automatically configure itself during initialization. When Log4j starts it will locate all the ConfigurationFactory plugins and arrange them in weighted order from highest to lowest. As delivered, Log4j contains four ConfigurationFactory implementations: one for JSON, one for YAML, one for properties, and one for XML.

Log4j will inspect the "log4j.configurationFile" system property and, if set, will attempt to load the configuration using the ConfigurationFactory that matches the file extension.

  • If no system property is set the properties ConfigurationFactory will look for log4j2-test.properties in the classpath.

  • If no such file is found the YAML ConfigurationFactory will look for log4j2-test.yaml or log4j2-test.yml in the classpath.

  • If no such file is found the JSON ConfigurationFactory will look for log4j2-test.json or log4j2-test.jsn in the classpath.

  • If no such file is found the XML ConfigurationFactory will look for log4j2-test.xml in the classpath.

  • If a test file cannot be located the properties ConfigurationFactory will look for log4j2.properties on the classpath.

  • If a properties file cannot be located the YAML ConfigurationFactory will look for log4j2.yaml or log4j2.yml on the classpath.

  • If a YAML file cannot be located the JSON ConfigurationFactory will look for log4j2.json or log4j2.jsn on the classpath.

  • If a JSON file cannot be located the XML ConfigurationFactory will try to locate log4j2.xml on the classpath.

  • If no configuration file could be located the DefaultConfiguration will be used. This will cause logging output to go to the console.

You might be overthinking it here.

You can put it "on the classpath" by placing it in the src/main/resources folder or specifying it on the command line with -cp/-classpath.



来源:https://stackoverflow.com/questions/52300045/initialize-slf4j-with-log4j2-xml

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