【问题标题】:sl4j/logback under weblogicweblogic下的sl4j/logback
【发布时间】:2012-05-14 13:19:58
【问题描述】:

我正在尝试在 Weblogic12 下配置 sl4j/logback。 我部署了具有war文件的ear文件,该文件具有WEB-INF\classes\logback.xml
这是配置:

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
</appender>

<root level="debug">
    <appender-ref ref="STDOUT" />
</root>

</configuration>

我要记录的代码:

private static final Logger logger = LoggerFactory.getLogger(FrontEndServlet.class);
//......
logger.info("info test");
logger.debug("debug test");
logger.error("error test");

我在标准输出中看到的是:

ьрщ 14, 2012 5:09:29 PM .....FrontEndServlet doPost
INFO: info test
ьрщ 14, 2012 5:09:29 PM .....FrontEndServlet doPost
SEVERE: error test

所以,配置文件似乎没有被拾取。 我究竟做错了什么?

【问题讨论】:

    标签: weblogic slf4j logback


    【解决方案1】:

    问题在这里详细讨论:https://stagingthinking.wordpress.com/2012/06/02/annoying-slf4j-problem-in-weblogic-server-12c/

    你需要放入prefer-application-packages机制的确切包是org.slf4j,像这样:

    <?xml version='1.0' encoding='UTF-8'?>
    <weblogic-application>
      <prefer-application-packages>
        <package-name>org.slf4j</package-name>
      </prefer-application-packages>
    </weblogic-application>
    

    【讨论】:

      【解决方案2】:

      注意:另外这个问题已经回答了,我想补充一下,你也应该加prefer-application-resources

      答案: 将名为 META-INF/weblogic-application.xml 的文件添加到您的耳朵中,其中包含 prefer-application-packagesprefer-application-resources

      <?xml version="1.0" encoding="UTF-8"?>
      <weblogic-application
              xmlns="http://xmlns.oracle.com/weblogic/weblogic-application"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-application http://xmlns.oracle.com/weblogic/weblogic-application/1.5/weblogic-application.xsd"
              version="6">
      
          <!-- http://www.torsten-horn.de/techdocs/jee-oracleweblogic.htm -->
          <prefer-application-packages>
              <package-name>org.slf4j.*</package-name>
          </prefer-application-packages>
      
      
          <!-- if not using prefer-application-resources you will get a warning like this: -->
          <!-- Class path contains multiple SLF4J bindings -->
          <!-- SLF4J: Found binding in [jar:file:/C:/wls1211/modules/org.slf4j.jdk14_1.6.1.0.jar!/org/slf4j/impl/StaticLoggerBinder.class] -->
          <prefer-application-resources>
              <resource-name>org/slf4j/impl/StaticLoggerBinder.class</resource-name>
          </prefer-application-resources>
      
      
      </weblogic-application>
      

      【讨论】:

      • 当你解释如何以及需要使用哪个文件时非常清楚。谢谢!
      【解决方案3】:

      问题是 - sl4j 没有选择 logback,而是使用了 Weblogic 的 slf4j-jdk 日志记录。可以通过 Weblogic 的配置 weblogic-application.xml,选项 prefer-application-packages

      修复

      【讨论】:

        【解决方案4】:

        或者,如果您遇到的问题不仅仅是 slf4j,您可以使用

        <wls:container-descriptor>
            <wls:prefer-web-inf-classes>true</wls:prefer-web-inf-classes>
        </wls:container-descriptor>
        

        代替

        <prefer-application-packages>
            <package-name>org.slf4j.*</package-name>
        </prefer-application-packages>
        

        来源:Oracle

        【讨论】:

          【解决方案5】:

          环境:Weblogic 12.2.1 日志框架:Slf4j 和 Logback 要求:记录到我选择的文件(每个应用程序)以及 Weblogic 服务器日志

          在 weblogic.xml 中使用 &lt;prefer-application-packages/&gt;&lt;prefer-web-inf-classes&gt; 不满足要求。在我的测试中,使用一个或其他标签(不能同时使用)将导致应用程序 logback.xml 被拾取,并且日志记录将转到 logback.xml 中定义的文件。但是,使用 logback 的 ConsoleAppender 的典型 STDOUT 定义不会记录到服务器日志。

          <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
          

          从 weblogic.xml 中删除以下内容

          <wls:prefer-application-packages>
              <wls:package-name>org.slf4j.*</wls:package-name>
          </wls:prefer-application-packages>
          

          将导致使用捆绑的 SLF4j 绑定,在 Weblogic 12.2.1 中,它是 Java Util 日志记录。在这种情况下,日志语句将转到服务器日志,而不是应用程序级别 logback.xml 中的文件定义。在我的研究中,有时 Weblogic 12 的某些版本允许内部 SLF4j 绑定到 Log4j,但在其中一个次要版本中被删除。这是我的情况;我没有通过管理控制台启用 Log4j 作为 Weblogic 中的主要日志框架的选项。我很确定这对我没有帮助,但我确实想指出这一点,因为我阅读的几份文件表明这是可用的。

          经过大量研究和使用 weblogic.xml 进行配置、POM 配置(排除等)并尝试使用不同的绑定和桥接后,我无法实现我想要的日志记录配置。似乎 Weblogic 的 slf4j 绑定到 Java 实用程序日志记录,无论好坏。如果您选择自己的 slf4j 和绑定实现(在我的情况下为 Logback),我无法通过配置将这些消息路由到 Weblogic 服务器日志。 slf4j 中只能有一个绑定,虽然很多框架都可以路由到那个绑定,(我发现this 图表很有用)Weblogic 12.2.1 仅使用 Java util 日志绑定,没有办法(在应用程序配置级别)连接 Weblogic 以使用您提供的 Logback 绑定来记录到其服务器日志。可能有一些方法可以使用 log4j 和 bridges 来完成此任务,但对我来说,完成一个简单的日志记录任务完全过于臃肿和配置。

          放弃尝试通过配置来解决这个问题,我决定简单地编写自己的 logback appender,将日志事件转换为 JUL 日志事件。我用我的own 实现 Logback 的 AppenderBase 替换了在许多 Logback 示例中看到的标准 STDOUT 定义。此时,我现在可以使用每个应用程序日志记录配置进行日志记录,还可以记录到 Weblogic Server 日志。

          相关的 POM 依赖:

          <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
              <dependency>
                  <groupId>org.slf4j</groupId>
                  <artifactId>slf4j-api</artifactId>
                  <version>1.7.25</version>
              </dependency>
              <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
              <dependency>
                  <groupId>ch.qos.logback</groupId>
                  <artifactId>logback-classic</artifactId>
                  <version>1.2.3</version>
              </dependency>
              <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-core -->
              <dependency>
                  <groupId>ch.qos.logback</groupId>
                  <artifactId>logback-core</artifactId>
                  <version>1.2.3</version>
              </dependency>
          

          weblogic.xml(注意 Hibernate 自带 JbossLogging 会自动桥接到 slf4j)

          <?xml version="1.0" encoding="UTF-8"?>
          <weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app"
          xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/2.0/weblogic-web-app.xsd">
          <jsp-descriptor>
              <keepgenerated>true</keepgenerated>
              <debug>true</debug>
          </jsp-descriptor>
          <context-root>YourContextRoot</context-root>
          <wls:container-descriptor>
              <wls:prefer-application-packages>
                  <wls:package-name>ch.qos.logback.*</wls:package-name>
                  <wls:package-name>org.jboss.logging.*</wls:package-name>
                  <wls:package-name>org.slf4j.*</wls:package-name>
              </wls:prefer-application-packages>
              <wls:prefer-application-resources>
                  <wls:resource-name>org/slf4j/impl/StaticLoggerBinder.class</wls:resource-name>
              </wls:prefer-application-resources>
          </wls:container-descriptor>
          

          Logback AppenderBase 实现

          import java.util.logging.Logger;
          
          import ch.qos.logback.classic.spi.ILoggingEvent;
          import ch.qos.logback.core.AppenderBase;
          
          public class WeblogicAppender extends AppenderBase<ILoggingEvent> {
          
          private final Logger logger = Logger.getLogger(WeblogicAppender.class.getName());
          ILoggingEvent event = null;
          
          @Override
          protected void append(ILoggingEvent event) {
              this.event = event;
              logger.log(getJULLevel(), event.getFormattedMessage());
          }
          
          private java.util.logging.Level getJULLevel() {
          
              if (this.event == null) {
                  return java.util.logging.Level.SEVERE;
              } else if (this.event.getLevel() == ch.qos.logback.classic.Level.ALL) {
                  return java.util.logging.Level.ALL;
              } else if (this.event.getLevel() == ch.qos.logback.classic.Level.DEBUG) {
                  return java.util.logging.Level.FINE;
              } else if (this.event.getLevel() == ch.qos.logback.classic.Level.ERROR) {
                  return java.util.logging.Level.SEVERE;
              } else if (this.event.getLevel() == ch.qos.logback.classic.Level.INFO) {
                  return java.util.logging.Level.INFO;
              } else if (this.event.getLevel() == ch.qos.logback.classic.Level.TRACE) {
                  return java.util.logging.Level.FINEST;
              } else if (this.event.getLevel() == ch.qos.logback.classic.Level.WARN) {
                  return java.util.logging.Level.WARNING;
              } else if (this.event.getLevel() == ch.qos.logback.classic.Level.OFF) {
                  return java.util.logging.Level.OFF;
              } else {
                  return java.util.logging.Level.INFO;
              }
          }
          

          }

          Logback.xml 配置

          <?xml version="1.0" encoding="UTF-8"?>
           <configuration>
          <appender name="STDOUT" class="com.your.package.WeblogicAppender">
              <encoder>
                  <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger: LineNumber:%L - %message%n</pattern>
              </encoder>
          </appender>
          <appender name="FILE"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
              <file>yourlog.log
              </file>
              <rollingPolicy
                  class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
                  <fileNamePattern>yourlog.%d{yyyy-MM-dd}.%i.log
                  </fileNamePattern>
                  <maxFileSize>25MB</maxFileSize>
                  <maxHistory>60</maxHistory>
                  <totalSizeCap>10GB</totalSizeCap>
              </rollingPolicy>
              <encoder>
                  <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger: LineNumber:%L - %message%n</pattern>
              </encoder>
          </appender>
          
          <root level="TRACE">
              <appender-ref ref="STDOUT" />
              <appender-ref ref="FILE" />
          </root>
          </configuration>
          

          希望我可以为其他人省去一些痛苦,因为我试图让它按照我想要的方式工作。

          【讨论】:

          • 您好,请问您将 logback.xml 文件放在哪里?似乎 weblogic 12c 只是忽略了它。部署描述符配置正确,实际上我可以在控制台级别看到我的日志,但我需要定义几个文件附加程序,并且无论我把 logback.xml 文件放在哪里,它似乎都不起作用。不幸的是,将配置放在另一个 Maven 模块中的解决方案不适用于我的情况。有什么建议吗?
          • 嗨。 logback.xml 进入 src/main/resources。一旦你构建了战争,探索它并验证 logback.xml 是否在 /WEB-INF/classes 中结束。如果 weblogic 仍然忽略它,则容器描述符和首选应用程序包可能在语法上不正确。确保您定义了正确的 wls 命名空间(就像我发布的示例中一样)。您可以通过将一些垃圾字符串放入并部署战争来验证 weblogic.xml 是否被 weblogic 看到。如果 Weblogic 无法解析 weblogic.xml,它会阻塞。祝你好运!如果您需要更多帮助,请 PM 我。
          • @senape 另外,请记住,如果控制台正在记录,这意味着 weblogic 内部日志记录 (JUL) 正在捕获您的语句,或者正在使用内部 Weblogic logback。一旦您的应用程序 logback 正常工作,您应该会在控制台日志中看到 NO 语句,并且只能在您在 logback.xml 中定义的文件中看到。然后,您可以添加我上面显示的 weblogic appender 和类以登录到控制台。
          猜你喜欢
          • 1970-01-01
          • 2017-12-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-11
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多