2

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 
0

2 Answers 2

1

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 (e.g. 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 
Sign up to request clarification or add additional context in comments.

6 Comments

My maven could not find log4j-slf4j2-impl. Please let me know what (which version of maven) you tried this with.
Also --- could you restate the changes in log4j.xml as properties for log4j.properties?
@ClarkHobbie: log4j-slf4j2-impl is available since version 2.19.0 (cf. MvnRepository) (first version after the release of SLF4J 2.x).
I added a properties configuration to the answer. Remark that the autodetected configuration files in Log4j 2.x must start with log4j2 (notice the 2): log4j2.xml or log4j2.properties.
The version of maven that comes with IDEA cannont resolve this dependency: <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> I integrated your other changes and it still doesn't work.
|
0

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.