繁体   English   中英

如何在Play框架中执行基于会话的日志记录

[英]How can I perform session based logging in Play Framework

我们当前正在使用Play框架,并且正在使用标准的日志记录机制。 我们实现了一个隐式上下文,以支持将用户名和会话ID传递给所有服务方法。 我们要实现日志记录,使其基于会话。 这需要实现我们自己的记录器。 这适用于我们自己的日志,但是对于基本的异常处理和结果日志,我们该如何做同样的事情。 也许有更好的方法可以使用隐式捕获,或者如何覆盖异常处理日志记录。 本质上,我们希望获得与会话关联的尽可能多的日志消息。

这取决于您要进行反应式样式开发还是标准同步开发:

  • 如果是标准同步开发(即没有期货,每个请求1个线程),那么我建议您只使用MDC,它将MDC的值添加到Threadlocal进行日志记录。 然后,您可以在logback / log4j中自定义输出。 当获得用户名/会话时(可能在过滤器中或在控制器中),您可以在此处设置值,然后就不需要使用隐式传递它们。

如果您正在进行反应式开发,则有两种选择:

  • 您仍然可以使用MDC,除非必须使用自定义的执行上下文将有效的MDC值复制到线程,因为理论上每个请求都可以由多个线程处理。 (如此处所述: http : //code.hootsuite.com/logging-contextual-info-in-an-asynchronous-scala-application/

  • 另一种选择是我倾向于使用的解决方案(接近于现在的解决方案):您可以创建一个代表MyAppRequest的类。 设置用户名,会话信息以及其他内容。 您可以继续将其作为隐式传递。 但是,您可以创建自己的MyAction类,而不是使用Action.async,如下所示

    myAction.async {隐式myRequest => //一些代码}

    在myAction内部,您必须捕获所有Exceptions并处理将来的失败,并手动执行错误处理,而不是依赖ErrorHandler。 我经常将myAction注入到我的Controller中,并在其中添加常见的过滤器功能。

    缺点是,这只是手动方法。 另外,我还使MyAppRequest拥有一个可记录值的映射,该映射可以在任何地方设置,这意味着它必须是可变的映射。 另外,有时您需要制作多个myAction.async。 优点是,它非常明确,并且在您的控制下没有太多ExecutionContext / ThreadLocal魔术。

下面是一些非常粗略的示例代码,作为手动解决方案的入门:

def logErrorAndRethrow(myrequest:MyRequest, x:Throwable): Nothing = {
  //log your error here in the format you like
  throw x //you can do this or handle errors how you like
}

class MyRequest {
  val attr : mutable.Map[String, String] = new mutable.HashMap[String, String]()
}

//make this a util to inject, or move it into a common parent controller
def myAsync(block: MyRequest => Future[Result] ): Action[AnyContent] = {
  val myRequest = new MyRequest()
  try {
    Action.async(
      block(myRequest).recover { case cause => logErrorAndRethrow(myRequest, cause) }
    )
  } catch {
    case x:Throwable =>
      logErrorAndRethrow(myRequest, x)
  }
}

//the method your Route file refers to
def getStuff = myAsync { request:MyRequest =>
  //execute your code here, passing around request as an implicit
  Future.successful(Results.Ok)
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM