我们有一个庞大的遗留代码,其中包含具有同步和异步操作的复杂流程。因此,我们需要在所有日志消息中记录特定请求的唯一ID,其中执行的操作在不同的线程中运行,并且线程在多个执行上下文中。
我尝试使用MDC并在logger.xml中指定 - %X {req_id}并使用自定义akka调度程序在下面提到的博客中给出解决方案,但它在多个执行上下文中不起作用,并且它也无法可靠地工作在单个执行上下文中,有时它返回req_id null。 (http://yanns.github.io/blog/2014/05/04/slf4j-mapped-diagnostic-context-mdc-with-play-framework/)
由于复杂且庞大的代码库,因此无法在每个函数调用中传递请求ID。我们有什么方法可以实现这一目标,但变化最小?我们在play框架生成的日志中也需要该请求id。
答案 0 :(得分:0)
我有同样的需要,记录一些跟踪令牌以进行调试。 Kamon图书馆已经具有此功能http://kamon.io/integrations/logback/trace-token-converter/。
在我的Global.java中:我在onStart()中执行Kamon.start()
并在onRequest()中维护上下文。还可以在日志记录模式中使用traceToken
。
public Action onRequest(Http.Request request, Method actionMethod) {
TraceContext tx = Kamon.tracer().newContext("reqc", new Some<>(Utils.randStr(8)));
Tracer.setCurrentContext(tx);
Logger.info("Request: " + request.toString());
Action x = super.onRequest(request, actionMethod);
tx.finish();
return x;
}
答案 1 :(得分:0)
我们通过转移到单个执行器上下文来解决这个问题,并且播放2.5也建议这样做。在这种情况下,mdc上下文将起作用。
答案 2 :(得分:0)
您应该可以使用marker context来完成这项工作。从示例中:
trait RequestMarkerContext {
// Adding 'implicit request' enables implicit conversion chaining
// See http://docs.scala-lang.org/tutorials/FAQ/chaining-implicits.html
implicit def requestHeaderToMarkerContext(implicit request: RequestHeader): MarkerContext = {
import net.logstash.logback.marker.LogstashMarker
import net.logstash.logback.marker.Markers._
val requestMarkers: LogstashMarker = append("host", request.host)
.and(append("path", request.path))
MarkerContext(requestMarkers)
}
}
然后
def asyncIndex = Action.async { implicit request =>
Future {
methodInOtherExecutionContext() // implicit conversion here
}(otherExecutionContext)
}
def methodInOtherExecutionContext()(implicit mc: MarkerContext): Result = {
logger.debug("index: ") // same as above
Ok("testing")
}