首页 > 解决方案 > 尽管配置了 logback,但 Play 2.6x Scala 应用程序不记录

问题描述

我正在尝试在我的 Play 2.6 Scala 应用程序中启用日志记录。

我基本上实现了这个日志过滤器来记录服务器处理的每个请求:https ://www.playframework.com/documentation/2.6.x/ScalaHttpFilters 。

我一生都无法将日志显示在控制台或特定log/目录中。我已经尝试了一切,从玩弄我的logback.xml文件和我的应用程序配置。

有谁知道我哪里出错了?我编写的过滤器正在根据请求进行处理(我设置了一个断点以确保)。

logback.xml:

<!-- https://www.playframework.com/documentation/latest/SettingsLogger -->
<configuration>

    <conversionRule conversionWord="coloredLevel" converterClass="play.api.libs.logback.ColoredLevel" />

    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>${application.home:-.}/logs/application.log</file>
        <encoder>
            <pattern>%date [%level] from %logger in %thread - %message%n%xException</pattern>
        </encoder>
    </appender>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%coloredLevel %logger{15} - %message%n%xException{10}</pattern>
        </encoder>
    </appender>

    <appender name="ASYNCFILE" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="FILE" />
    </appender>

    <appender name="ASYNCSTDOUT" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="STDOUT" />
    </appender>

    <logger name="play" level="INFO" />
    <logger name="application" level="DEBUG" />

    <!-- Off these ones as they are annoying, and anyway we manage configuration ourselves -->
    <logger name="com.avaje.ebean.config.PropertyMapLoader" level="OFF" />
    <logger name="com.avaje.ebeaninternal.server.core.XmlConfigLoader" level="OFF" />
    <logger name="com.avaje.ebeaninternal.server.lib.BackgroundThread" level="OFF" />
    <!--<logger name="org.jdbcdslog.StatementLogger"  level="DEBUG" /> &lt;!&ndash; Will log all statements &ndash;&gt;-->
    <!--<logger name="slick.jdbc.JdbcBackend.statement"  level="DEBUG" />-->

    <logger name="com.gargoylesoftware.htmlunit.javascript" level="OFF" />

    <root level="INFO">
        <appender-ref ref="ASYNCFILE" />
        <appender-ref ref="ASYNCSTDOUT" />
    </root>

</configuration>

LoggingFilter.scala:

package filters

import javax.inject.Inject
import akka.stream.Materializer
import play.api.Logger
import play.api.mvc._
import scala.concurrent.{ExecutionContext, Future}

class LoggingFilter @Inject() (implicit val mat: Materializer, ec: ExecutionContext) extends Filter {

  def apply(nextFilter: RequestHeader => Future[Result])
           (requestHeader: RequestHeader): Future[Result] = {

    Logger.debug("Hi!") // Why you no work!!

    val startTime = System.currentTimeMillis

    nextFilter(requestHeader).map { result =>

      val endTime = System.currentTimeMillis
      val requestTime = endTime - startTime

      Logger.info(s"${requestHeader.method} ${requestHeader.uri} took ${requestTime}ms and returned ${result.header.status}")

      result.withHeaders("Request-Time" -> requestTime.toString)
    }
  }
}

标签: scalaplayframework

解决方案


好吧,经过几个小时的调试,我终于找到了原因(可能对其他人有帮助,所以在这里发布)。

原因:

问题的根本原因是捆绑在play-silhoutte. 我的应用程序使用的play-silhoutte版本显然包含一个错误,导致 Play 记录器被( )5.0.3的子依赖项中的日志记录配置覆盖。play-silhouttecom.typesafe.play:play-openid_2.12:2.6.9

诊断:

不幸的是,这需要很长时间来调试 -Logger在初始化时读取 Play 源代码 + 调试堆栈帧的组合。我注意到 Logger 被初始化了两次——一次用于实际的 Play 记录器(由于(有效地覆盖了良好的记录器)logback.xml,再次使用了我在 then 中指定的正确配置。play-silhoutte

查看初始化参数,它正在logback.xml/Users/.../.ivy2/cache/com.typesafe.play/play-openid_2.12/jars/play-openid_2.12-2.6.9.jar!logback.xml. 我展开 jar 并找到以下日志记录配置:

<!--
  ~ Copyright (C) 2009-2017 Lightbend Inc. <https://www.lightbend.com>
  -->
<configuration>
    <!-- Suppress logback complaining about multiple logback-test.xml files -->
    <statusListener class="ch.qos.logback.core.status.NopStatusListener" />

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!-- We use short exception stack trace logging to limit output for travis. -->
            <!-- Change to full if you need to do further debugging, but never commit that. -->
            <pattern>%level %logger{15} - %message%n%ex{short}</pattern>
        </encoder>
    </appender>

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

</configuration>

在这一点上,我知道这是一个相互矛盾的依赖问题。

解决方案:

在进行了一些挖掘之后,我实际上在 Github 上发现了一个错误,描述了我的问题。我正在运行play-silhoutte版本5.0.3,所以碰到它来5.0.4解决问题。


推荐阅读