简体   繁体   English

无法发送 JUL -> Logback

[英]Cannot send JUL -> Logback

I am trying to send the logging from a 3rd party app (which uses a JUL ConsoleHandler) to logback.我正在尝试将日志从 3rd 方应用程序(使用 JUL ConsoleHandler)发送到 logback。 I have followed all the other posts on this website but cannot get it to work.我已经关注了这个网站上的所有其他帖子,但无法让它工作。 Am I doing something wrong?难道我做错了什么?

  • I added the following to the beginning of my RCP class that implements the bundle activator我在实现捆绑激活器的 RCP 类的开头添加了以下内容

    public class MyTestActivator implements BundleActivator { static { LogManager.getLogManager().reset(); SLF4JBridgeHandler.removeHandlersForRootLogger(); SLF4JBridgeHandler.install(); java.util.logging.Logger.getGlobal().setLevel(Level.FINEST); } @Override public void start(final BundleContext bundleContext) throws Exception { try { LoggerContext context = (LoggerContext) LoggerFactory. getILoggerFactory(); JoranConfigurator configurator = new JoranConfigurator(); configurator.setContext(context); try { context.reset(); configurator.doConfigure(getClass(). getResourceAsStream("/logback.xml")); } catch (JoranException e) { throw new IOException(e.getMessage(), e); } StatusPrinter.printInCaseOfErrorsOrWarnings(context); } catch (final IOException e) { e.printStackTrace(); } } }
  • My feature.xml file contains:我的 feature.xml 文件包含:

     <plugin id="jul.to.slf4j" download-size="0" install-size="0" version="0.0.0" unpack="false"/> <plugin id="ch.qos.logback.classic" download-size="0" install-size="0" version="0.0.0" unpack="false"/> <plugin id="ch.qos.logback.core" download-size="0" install-size="0" version="0.0.0" unpack="false"/>
  • My logback.xml contains:我的 logback.xml 包含:

     <configuration> <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"> <resetJUL>true</resetJUL> </contextListener> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern> %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n </pattern> </encoder> </appender> <root level="info"> <appender-ref ref="STDOUT" /> </root> </configuration>

Update: I have also tried the following but it did not work as expected更新:我也尝试了以下但没有按预期工作

    private static final java.util.logging.Logger[] pin;
    static {
        LogManager.getLogManager().reset();
        SLF4JBridgeHandler.removeHandlersForRootLogger();
        SLF4JBridgeHandler.install();
        pin = new java.util.logging.Logger[] { 
            java.util.logging.Logger.getLogger(""),        
            java.util.logging.Logger.getLogger("3rd.party.package") };

        for (java.util.logging.Logger l : pin) {
            l.setLevel(Level.FINEST);
            for (Handler h : l.getHandlers()){
                if (h instanceof ConsoleHandler){
                    h.setFormatter(new Formatter(){
                        public final String format(LogRecord record) { 
                            if (record == null) {
                                return "";
                            } else {
                                return "CONSOLE_MSG:"+record.getMessage();
                            }
                        }
                    });
                }
            }
        }

    }
  • Update I believe I have it working by adding the following code in place of the for loop in the previous section:更新我相信我可以通过添加以下代码来代替上一节中的 for 循环:

     java.util.logging.Logger root = java.util.logging.Logger.getLogger(""); java.util.logging.Logger myLog = java.util.logging.Logger.getLogger("3rd.party.package"); myLog.setParent(root); myLog.setUseParentHandlers(true); java.util.logging.LogManager.getLogManager().getLogger( "" ).setLevel( Level.ALL );

The only downside is that I'll probably have to catch each logger and do this.唯一的缺点是我可能必须捕获每个记录器并执行此操作。 When I looked in the debugger I noticed none of them had a parent (it was null)当我查看调试器时,我注意到它们都没有父级(为空)

Logger.getGlobal() is not the root of all JUL loggers. Logger.getGlobal()不是所有 JUL 记录器的根。 The root of all JUL loggers is Logger.getLogger("") .所有 JUL 记录器的根是Logger.getLogger("") If you make programmatic changes to loggers then you have to pin those loggers so the settings are not reverted when they are garbage collected.如果您对记录器进行编程更改,则必须固定这些记录器,以便在垃圾收集时不会恢复设置。

You need to make sure that log records and being published to the parent handlers and all the way up to the root logger.您需要确保日志记录并发布到父处理程序,一直到根记录器。

private static final java.util.logging.Logger[] pin;
static {
    //Pin first.
    pin = new java.util.logging.Logger[] { 
        java.util.logging.Logger.getLogger(""),
        java.util.logging.Logger.getLogger("3rd.party.package") };

    //Setup SLF4J
    LogManager.getLogManager().reset();
    SLF4JBridgeHandler.removeHandlersForRootLogger();
    //SLF4JBridgeHandler.install();
    java.util.logging.Logger.getLogger("").addHandler(new SLF4JBridgeHandler());

    //Change JUL levels.
    for (java.util.logging.Logger l : pin) {
        l.setLevel(Level.FINEST);
    }
}

You should also try:您还应该尝试:

public class MyTestActivator implements BundleActivator {        
    static {
        //Pin first.
        pin = new java.util.logging.Logger[] { 
        java.util.logging.Logger.getLogger(""),
        java.util.logging.Logger.getLogger("3rd.party.package") };

        //Change JUL levels.
        for (java.util.logging.Logger l : pin) {
           l.setLevel(Level.FINEST);
        }
    }

    @Override
    public void start(final BundleContext bundleContext) throws Exception {
        try {
            LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();

            JoranConfigurator configurator = new JoranConfigurator();
            configurator.setContext(context);
            try {
                context.reset();
                configurator.doConfigure(getClass().getResourceAsStream("/logback.xml"));
                //Setup SLF4J
                SLF4JBridgeHandler.removeHandlersForRootLogger();
                SLF4JBridgeHandler.install();
            } catch (JoranException e) {
                throw new IOException(e.getMessage(), e);
            }
            StatusPrinter.printInCaseOfErrorsOrWarnings(context);
        } catch (final IOException e) {
            e.printStackTrace();
        }
    }
}

Set the logback levels in the for the root logger to debug or trace .将根记录器的 logback 级别设置为debugtrace Same with setting the level for the logback console appender.与设置 logback 控制台 appender 的级别相同。

The only downside is that I'll probably have to catch each logger and do this.唯一的缺点是我可能必须捕获每个记录器并执行此操作。

Iteration over the installed the loggers can be performed but the logger tree will change over time.可以对已安装的记录器进行迭代,但记录器树会随着时间的推移而改变。

The only downside is that I'll probably have to catch each logger and do this.唯一的缺点是我可能必须捕获每个记录器并执行此操作。 When I looked in the debugger I noticed none of them had a parent (it was null)当我查看调试器时,我注意到它们都没有父级(为空)

That is odd.这很奇怪。 The parent should only be null if the logger is the root logger.如果记录器是根记录器,则父记录器只能为 null。 Maybe bug in the LogManager you are using?也许您正在使用的 LogManager 中存在错误?

Alternatively, you could add a new SLF4JBridgeHandler() to every logger you want to monitor but that is not as nice as monitoring the root logger.或者,您可以向要监视的每个记录器添加一个new SLF4JBridgeHandler() ,但这不如监视根记录器那么好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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