22

我正在使用播放 2.1。我正在使用默认记录器 play.api.Logger。我对它是如何工作的感到困惑。

在我的scala代码中,方法“getPayment()”中的“com.myapp.tickets”类中的一行如下所示

Logger.info("getTickets")

生成这样的日志消息。

14:58:58.005 INFO  application play.api.LoggerLike$class info  getTickets

我的 application-logger.xml 模式是

%d{HH:mm:ss.SSS} %-5level %logger %class %method  %msg%n

我遇到的问题是 %logger 告诉我“应用程序”,%class 告诉我“play.api.LoggerLike$class”和 %method 告诉我“信息”。我知道所有这些。我当然想避免添加更多内容进入消息本身(如类名或方法)。

如果我打印出调用堆栈(%caller),那么级别 2 就有我想要的,但这似乎不是生成日志的可行方法。

如何配置它以输出应用程序特定的类和方法,而不是记录器本身的类和方法?

4

6 回答 6

34

%class{0}只会输出类名,而不是:

com.something.MyClass

你会得到:

MyClass

这就是我的 logback 模式通常的样子:

%d{HH:mm:ss} [%thread] %-5p %class{0} - %m%n

如果您有兴趣,还可以通过以下方式添加方法和行:

%d{HH:mm:ss} [%thread] %-5p %class{0}.%method:%L - %m%n
于 2013-03-18T11:16:58.513 回答
19

回溯模式:

%d{HH:mm:ss.SSS} [%thread] %-5level %class{36}.%M %L - %msg%n

结果 :

14:53:47.816 [http-bio-8080-exec-3] DEBUG  c.f.s.w.s.i.example.ExServiceImpl.getStatus 993 - blocked-->0
  • [http-bio-8080-exec-3]是线程名称

  • c.f.s.w.s.i.example是包名

  • ExServiceImpl是类名

  • getStatus是方法名

  • 993是行号

于 2013-11-13T09:29:21.477 回答
4

旧线程,但常见问题。Play 使用 slf4j 的包装器,这会导致所有内容都记录为 [Logger$ALogger] 或 [application]。有几种方法可以记录实际的类名。

把它放在你的课堂上:

private static org.slf4j.Logger logger = play.logger.underlying();

并将其放入您的方法中:

logger.info("Your message");

另一种选择是用它替换所有 Logger 调用,但它会增加开销,因为它必须在每次要记录某些内容时获取底层对象:

Logger.underlying().info("Your message");
于 2015-03-02T22:10:07.290 回答
1

我不确定这真的是你想要的,但你试试这个吗?:

记录器(this.getClass()).info("getTickets")

于 2013-03-08T08:10:29.820 回答
1

我正在放弃 Play 似乎默认使用其 Logger 的单一 application.log 方法。我的应用程序需要一种细粒度的日志记录和运行时调整,当 classname == Logger name 时直接 logback 做得很好。我在控制器中仅使用“老派”就取得了相当大的成功,例如...

package controllers
import play.api._
import play.api.mvc._
import org.slf4j.LoggerFactory

object Application extends Controller {
  val log = LoggerFactory.getLogger(getClass())

  def index = Action {
    log.trace("index")
    NotFound
  }

  def hb = Action {
    log.trace("hb")
    val message = makeMessage()
    log.info(message)
    Ok(message)
  }

  def makeMessage(): String = {
    val version = "@buildsig.version@"
    val tag = "@buildsig.tag@"
    val timestamp = "@buildsig.timestamp@"
    val status = makeStatus()
    return "DM2 [Version: %s] [Build: %s] [Date: %s] [Status: %s]".format(version, tag, timestamp, status)
  }

  def makeStatus(): String = {
    // TODO: Implement datastore healthcheck
    return "TODO"
  }
}

对于任何习惯使用 slf4j/logback 或 log4j 的开发人员来说,这种方法似乎很熟悉。另一方面,我目前正在努力通过“play dist”的启动 shell 脚本无法在 JAR 文件中找到 logger.xml,在该文件中,启动脚本无法使用我的 conf/logger.xml,它被“play dist”命令。

如果我只是稍微好一点的 Scala 开发人员,我认为使用 Logging trait 之类的东西可以达到同样的效果。

于 2013-06-03T22:27:40.427 回答
0

由于 Play 的 Logger 包装了底层的 SLF4J 调用,因此 logger 类始终是“应用程序”:

13:45:21 INFO  application: - Some message

但是有一个简单的方法来解决这个问题。

创建一个特征:

import play.api.Logger

trait WithLogging {
   val logger: Logger = Logger(this.getClass())
}

在您的课程中,只需混合以下特征:

import WithLogging

class Foobarr extends WithLogging {
   def doFoo = {
      logger.info("Im in foooo")
   }
}

现在应该是:

13:45:21 INFO  models.Foobarr: - Im in foooo
于 2017-06-20T13:27:13.147 回答