有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java无法发送JUL>Logback

我正在尝试从第三方应用程序(使用JUL ConsoleHandler)将日志发送回logback。我已经关注了该网站上的所有其他帖子,但无法使其发挥作用。我做错什么了吗

  • 我在实现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();
            }
        }
    }
    
  • 我的特征。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"/>
    
  • 我的日志。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>
    

更新:我也尝试了以下方法,但没有达到预期效果

    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();
                            }
                        }
                    });
                }
            }
        }

    }
  • 更新我相信我已经通过添加以下代码来代替上一节中的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 );
    

唯一的缺点是,我可能必须捕获每个记录器并执行此操作。当我查看调试器时,我注意到它们都没有父级(它是空的)


共 (1) 个答案

  1. # 1 楼答案

    ^{}不是所有七月伐木者的根。所有七月记录者的根是^{}。如果对记录器进行编程更改,则必须pin those loggers,以便在垃圾收集设置时不会恢复设置

    您需要确保日志记录被发布到parent handlers并一直发布到根日志记录器

    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);
        }
    }
    

    您还应该尝试:

    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();
            }
        }
    }
    

    在中为根记录器将logback级别设置为debugtrace。与设置logback控制台appender的级别相同

    The only downside is that I'll probably have to catch each logger and do this.

    Iteration over the installed the loggers可以执行,但记录器树将随时间而改变

    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)

    这很奇怪。仅当记录器是根记录器时,父记录器才应为null。也许你正在使用的LogManager中有bug

    或者,您可以向要监视的每个记录器添加一个new SLF4JBridgeHandler(),但这不如监视根记录器好