playframework - Play Framework logback 自定义布局

标签 playframework logback

我正在尝试使用自定义布局类进行 Play Framework 2.0 logback 日志记录。

首先,我在包 utils 中定义了一个自定义布局类:

package utils;

public class MonitorLayoutForLogback extends LayoutBase<ILoggingEvent> {
...
}

在我的 conf/logging.xml 文件中,我输入:
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="utils.MonitorLayoutForLogback">
                             <param name="programName" value="uowVisualizer" />
                             <param name="serviceGroup" value="shared" />
                             <param name="serviceIdentifier" value="uowVisualizer" />
            </layout>
        </encoder>
    </appender>

但是当我在游戏中奔跑时,例如,
play run

我看到:
14:20:18,387 |-ERROR in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Could not create component [layout] of type [utils.MonitorLayoutForLogback] java.lang.ClassNotFoundException: utils.M
onitorLayoutForLogback
    at java.lang.ClassNotFoundException: utils.MonitorLayoutForLogback
    at      at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at      at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at      at java.security.AccessController.doPrivileged(Native Method)
    at      at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
    at      at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
    at      at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
    at      at sbt.PlayCommands$$anonfun$53$$anonfun$55$$anon$2.loadClass(PlayCommands.scala:535)
    at      at ch.qos.logback.core.util.Loader.loadClass(Loader.java:124)
    at      at ch.qos.logback.core.joran.action.NestedComplexPropertyIA.begin(NestedComplexPropertyIA.java:100)
    at      at ch.qos.logback.core.joran.spi.Interpreter.callBeginAction(Interpreter.java:276)
    at      at ch.qos.logback.core.joran.spi.Interpreter.startElement(Interpreter.java:148)
    at      at ch.qos.logback.core.joran.spi.Interpreter.startElement(Interpreter.java:130)
    at      at ch.qos.logback.core.joran.spi.EventPlayer.play(EventPlayer.java:50)
    at      at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:157)
    at      at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:143)
    at      at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:106)
    at      at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:56)
    at      at play.api.Logger$$anonfun$configure$8.apply(Logger.scala:248)
    at      at play.api.Logger$$anonfun$configure$8.apply(Logger.scala:247)
    at      at scala.Option.map(Option.scala:145)
    at      at play.api.Logger$.configure(Logger.scala:247)
    at      at play.api.Application$class.$init$(Application.scala:266)

所以,play 找不到我创建的布局类。如何将布局类放在类路径上?

请注意,我还尝试通过以下方式暂存项目,
play clean compile stage

然后通过
target/start

从打包版本启动项目,没有看到上面缺少的类错误。但是,我也从未看到任何输出,甚至也没有看到构建的类。我将 System.out.println 语句添加到该类的每个构造函数中,如下所示,以验证是否正在构造该类:
    public MonitorLayoutForLogback() {
        System.out.println("MonitorLayoutForLogback Constructor without arguments");
    }

    public MonitorLayoutForLogback(String program) {
        System.out.println("MonitorLayoutForLogback Constructor with program "+program);
        _program = program;
    }

    public MonitorLayoutForLogback(String program, String sGroup, String sid) {
        System.out.println("MonitorLayoutForLogback Constructor with program "+program+" sGroup "+sGroup+" sid "+sid);
        _program = program;
        MonitoringInfo.setServiceGroup(sGroup);
        MonitoringInfo.setServiceIdentifier(sid);
    }

我是 logback 配置的新手,所以我确定我错过了一些明显的东西。感谢您的帮助。

最佳答案

您看到的问题源于 logback 如何将类加载器用于配置为过滤器、布局、编码器等的类。

问题是对于所有依赖项,包括 logback,类都加载在 DependencyClassloader 中。这是稳定的,而项目代码加载在 ReloadableClassloader 中它是稳定类加载器的子类,并且在项目源代码更改时被丢弃。

由于 logback 不允许传递自定义类加载器,也不允许查找上下文类加载器,因此它尝试在稳定的类加载器中解析项目类,但无法找到项目类。

有一个declined pull request在 logback 中改变这种行为
evidence there are no plans改变这种行为

有两种解决方法:

  • 如果您正在使用子项目,请将您的类(class)放入子项目
  • 如果您不使用子项目,请将您的类打包成 jar文件并把那个 jar文件放入 lib/ directory您的项目
  • 关于playframework - Play Framework logback 自定义布局,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17845135/

    相关文章:

    java - 处理所有异常

    spring-boot - 如何在 log-back.xml 中包含 xml

    java - 在 logback 中使用条件处理时找不到 FileExistsPropertyDefiner 类

    java - 用于存储游戏分数和历史记录的良好数据模型

    java - Play Framework 2.2 : How to define an ebean ManyToMany query

    java - 引导 Play 应用程序

    java - 如何在 Sql 中转义分号

    logging - 将 logrotate 与 logback 一起使用

    java - JVM 错误? java.lang.VerifyError : Bad type on operand stack

    java - 停止 Logback 系统以进行干净关闭