简体   繁体   中英

log4j: cannot set logging to DEBUG

I am having a problem with log4j --- I am trying to set the logging level to DEBUG with a log4j.properties file. I know that this partially works because another component .netty ) works but by the time it gets to me logging is set to ERROR and above.

Here is my log4j.properties file:

#Define root logger options
log4j.rootLogger=DEBUG, console

log4j.logger.com.ltsllc.miranda=DEBUG

#Define console appender

log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Target=System.out
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%-5p %c{1} - %m%n

here is the code that checks the debugging level:

    if (l.isDebugEnabled()) {
        l.debug("DEBUG is enabled");
    } else {
        l.error ("Debug is disabled");
        l.error ("level is: " + l.getLevel());
    }

here is the output:

DEBUG ResourceLeakDetector - -Dio.netty.leakDetection.level: simple
DEBUG ResourceLeakDetector - -Dio.netty.leakDetection.targetRecords: 4
DEBUG ResourceLeakDetectorFactory - Loaded default ResourceLeakDetector: io.netty.util.ResourceLeakDetector@44b3606b
22:43:46.696 \[main\] ERROR com.ltsllc.miranda.Miranda - Debug is disabled
22:43:46.700 \[main\] ERROR com.ltsllc.miranda.Miranda - level is: ERROR
DEBUG DefaultChannelId - -Dio.netty.processId: 30572 (auto-detected)
DEBUG NetUtil - -Djava.net.preferIPv4Stack: false

I expected something like this

DEGUG com.ltsllc.miranda.Miranda - DEBUG is enabled

From the look of your provided details, the issue could stem from various sources:

  1. Verify the logger initialisation : Make sure the "l" logger is initialised correctly for the "com.ltsllc.miranda" package. It's possible you may be using a logger intended for a different package, causing it not to pick up the DEBUG setting.

    Here's an example:

     import org.apache.log4j.Logger; public class Miranda { private static final Logger l = Logger.getLogger(Miranda.class); }
  2. Confirm the location of your configuration file : Check that the log4j.properties file is properly located. It needs to be on the classpath. Typically for a Maven project, you would place it in the src/main/resources directory.

  3. Inspect for multiple configurations : Log4j could be pulling from the wrong file if you have multiple log4j configuration files (like log4j.xml and log4j.properties). It's best to only have one configuration file, or to specifically indicate which one to use.

  4. Potential overriding of log4j configuration : Certain libraries or frameworks could unintentionally override your log4j configuration. For instance, Spring Boot automatically configures logging by default. It's worth considering if something similar may be occurring in your case.

  5. Consider the order of initialisation : Your logging system might be initialised later than some of your code. Make sure to initialise it as early as possible in your application life-cycle.

Examining these potential causes should help you identify and resolve the issue.

When no configuration is provided the Log4j2 Reference Implementation ( log4j-core ) uses a %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n pattern and an ERROR level. This is what you are observing on your standard output.

The logging APIs and backends are probably bound as follows:

  • Netty's internal logging API (cf. InternalLoggerFactory ) binds to SLF4J ( slf4j-api ), which uses Log4j 1.x or Reload4j as backend. This backend is the one you configured .
  • the Log4j2 API you use in your code(cf.API separation ) binds to Log4j2 Reference Implementation, which you didn't configure . I am guessing that the fully qualified class name of l in your code is org.apache.logging.log4j.Logger .

I am assuming you don't want to use Log4j 1.x as backend (it was declared end-of-life 8 years ago) so you need to:

  1. Configure log4j-core by adding a log4j2.xml file with content:
     <Configuration> <Appenders> <Console name="console"> <PatternLayout pattern="%-5p %c{1} - %m%n"/> </Console> </Appenders> <Loggers> <Root level="DEBUG"> <AppenderRef ref="console"/> </Root> </Loggers> </Configuration>
  2. Fix up your dependencies, by:
    • Removing the log4j:log4j and ch.qos.reload4j:reload4j artifacts from your classpath. This also includes the SLF4J bindings org.slf4j:slf4j-log4j12 and org.slf4j:slf4j-reload4j .
    • Netty binds to Log4j2 API if SLF4J ( slf4j-api ) is not present, but other libraries might be using SLF4J directly. If you are using Maven you need these 3 artifacts:
       <dependencyManagement> <,-- Add the BOM. so you don't need to specify version --> <dependencies> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-bom</artifactId> <version>2.20.0</version> <scope>import</scope> <type>pom</type> </dependency> </dependencies> </dependencyManagement> <dependencies> <.-- Used in your code --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> </dependency> <.-- Only necessary at runtime --> <dependency> <groupId>org:apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <scope>runtime</scope> </dependency> <.-- ~ If some of your libraries use SLF4J API directly ~ bind them to `log4j-api`. --> <dependency> <groupId>org.apache.logging.log4j</groupId> <!-- Replace with log4j-slf4j2-impl if SLF4J 2.x is used --> <artifactId>log4j-slf4j-impl</artifactId> <scope>runtime</scope> </dependency> </dependencies>
      If your libraries use other logging APIs (eg Jakarta Apache Commons Logging, java.util.logging , JBoss Logging), you'll also need to bind them to log4j-api .

Edit : I would advise against using the properties configuration format for Log4j 2.x, since it is extremely verbose to store a tree-like structure in a flat format. Besides when Log4j 1.x was released the JRE did not have an XML parser, now it has it.

The XML configuration above can be translated to properties as:

appender.0.type = Console
appender.0.name = console
appender.0.0.type = PatternLayout
appender.0.0.pattern = %-5p %c{1} - %m%n

logger.rootLogger.level = DEBUG
logger.rootLogger.appenderRef.0.ref = console
##
# The `rootLogger` config can be abbreviated in recent versions to
#   logger.rootLogger = DEBUG, console

I found the answer in a question relating to how to set the logging level programmatically:

LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
Configuration config = ctx.getConfiguration();
LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME); 
loggerConfig.setLevel(level);
ctx.updateLoggers();  // This causes all Loggers to refetch information from their LoggerConfig.

This was the answer to this question

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM