代码之家  ›  专栏  ›  技术社区  ›  ekjcfn3902039

无法发送JUL->Logback

  •  2
  • ekjcfn3902039  · 技术社区  · 7 年前

    我正试图将日志从第三方应用程序(使用JUL控制台手柄)发送回logback。我已经关注了这个网站上的所有其他帖子,但无法让它工作。我做错什么了吗?

    • 我在实现bundle激活器的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();
              }
          }
      }
      
    • <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"/>
      
    • <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();
                                }
                            }
                        });
                    }
                }
            }
    
        }
    
    • 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 );
      

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

    1 回复  |  直到 7 年前
        1
  •  2
  •   jmehrens    7 年前

    Logger.getGlobal() 不是所有七月伐木者的根源。所有七月伐木者的根源是 Logger.getLogger("") 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级别设置为 debug trace 。与设置logback控制台附加程序的级别相同。

    唯一的缺点是,我可能必须捕捉每个记录器并执行此操作。

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

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

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