简体   繁体   中英

Why are some logs not caught by log4j?

I have configured log4j as logging back-end in my container, however not all logs are filtered through log4j apparently.

The logs from my application are written to my console/logfile as expected.

I am using openwebbeans for example and the logs from this library are still in the default format and written to system out even though the library is using log4j internally.

Why is my log4j configuration not directing those log statements to my console/logfile? I would have expected that they would at least be written to the root logger but they do not pass through the appender that the root logger writes to.

log4j.appender.Stdout=org.apache.log4j.ConsoleAppender
log4j.appender.Stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.Stdout.layout.conversionPattern=%d{yyyy-MM-dd HH:mm:ss}|%-5p|%c|%m%n
log4j.rootLogger=DEBUG,Stdout
log4j.logger.org.apache.wicket=INFO
log4j.logger.org.apache.webbeans=WARN
...

Thanks to Mark's comment above I managed to solve my problem by configuring java.util.logging to redirect to slf4j. This is not an elegant solution but for the purposes I need, it suffices:

private static void configureJavaUtilLogging() {
    final java.util.logging.Logger rootLogger = java.util.logging.Logger.getLogger("");
    for (final java.util.logging.Handler handler : rootLogger.getHandlers()) {
        handler.setLevel(Level.OFF);
    }
    rootLogger.setLevel(Level.INFO);
    rootLogger.addHandler(new java.util.logging.Handler() {

        @Override
        public void publish(final LogRecord record) {
            final Logger log = LoggerFactory.getLogger(record.getSourceClassName());
            if (record.getLevel() == Level.SEVERE) {
                if (record.getThrown() == null) {
                    log.error(record.getMessage());
                } else {
                    log.error(record.getMessage(), record.getThrown());
                }
            } else if (record.getLevel() == Level.WARNING) {
                log.warn(record.getMessage());
            } else if (record.getLevel() == Level.INFO) {
                log.info(record.getMessage());
            } else {
                log.debug(record.getMessage());
            }

        }

        @Override
        public void flush() {

        }

        @Override
        public void close() throws SecurityException {

        }

    });
}

With this I can configure log output for everyone in my one configuration. Basically the code above overwrites the default configuration for java.util.logging that is stored somewhere within the jdk or jre.

I am not sure what to do with the flush and close methods. Before using this kind of stuff ina production environment those would need to be checked out.

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