当前位置: 首页 > 工具软件 > Kamon > 使用案例 >

kamon文档翻译(六)--操作TraceContext

晋功
2023-12-01

操作 TraceContext

收集trace信息全都在于与tracing API以及当前的存储了信息的TraceContext交互,因为他是由你的应用程序产生的。这一节将教你能创建的所有基本的操作,并实关闭一个TraceContext和与它有关的segment。
注意:即使你了解到如何操作TraceContext很重要,一些kamon模块如Akka,Scala,Spray和Play!模块也已经提供了而记之的基本组件,而且能够自动的创建、传播和关闭trace,在某些特定条件下还可以关闭segment。因此,你好像不需要自己操作TraceContext。

创建和关闭TraceContext

你可以通过使用Kamon.tracer 中的成员提供的.newContext(...) 方法创建一个新的TraceContext 。如开始章节描述的,你需要保证你通过这个API启动Kamon。当你创建了一个县的context,你至少需要提供一个名字。这样你举可以在关闭这个trace之前在任何时候修改它。此外,你可以提供一个trace-token, 如果你不愿意,kamon会为你生成一个。

Scala:
val testTrace = Kamon.tracer.newContext("test-trace")
val testTraceWithToken = Kamon.tracer.newContext("trace-with-token", Some("token-42"))

// You can rename a trace before it is finished.
testTrace.rename("cool-functinality-X")
testTrace.finish()

// And you can also access it's token if you want to.
println("Test Trace Token: " + testTrace.token)
Java :
final TraceContext testTrace = Kamon.tracer().newContext("test-trace");
final TraceContext testTraceWithToken = Kamon.tracer().newContext("trace-with-token", Some.apply("token-42"));

// You can rename a trace before it is finished.
testTrace.rename("cool-functinality-X");
testTrace.finish();

// And you can also access it's token if you want to.
System.out.println("Test Trace Token: " + testTrace.token());

如上面所示,你可以通过调用.finish() 方法关闭一个TraceContext。一旦你关闭了trace,你就不能对其进行重命名了。
此外,Tracer伴随对象提供了一个可选的.withNewTraceContext(...),他不仅仅创建了一个TraceContext ,它还将当前trace的context赋值给它,并选择在这段代码结束后结束这个context.执行情况如以下代码所示:

Scala:
Java
Tracer.withNewContext("GetUserDetails", autoFinish = true) {
  // While this block of codes executes a new TraceContext
  // is set as the current context and finished after the
  // block returns.
  println("Current Trace Token: " + Tracer.currentContext.token)

  "Some awesome result";
}

// No TraceContext is present when you reach this point.
Java:
Tracer.withNewContext("GetUserDetails", true, ()-> {
  // While this block of codes executes a new TraceContext
  // is set as the current context and finished after the
  // block returns.
  System.out.println("Current Trace Token: " + Tracer.currentContext().token());

  return "Some awesome result";
});

// No TraceContext is present when you reach this point.

新的TraceContext仅仅是在当前代码块中可以使用的,一旦方法退出,则会移除掉TraceContext,理解这一点很重要。

TraceContext 存储

你也许已经注意到上一节我们提到了”当前trace的context”,当我们提到这个时,我们指的是与当前线程中运行的这个trace关联的TraceContext 。他被存储在线程的局部trace变量中。确保一旦你不在需要TraceContext, 你总是能够关闭所有的线程。因此,如果你使用Tracer.withContext(...) 而不是直接使用Tracer.setCueentContext(...)Tracer.clearCurrentContext(...)函数则更好。一旦代码结束执行,将确保trace context存储被设置,无论以前是什么样子。

Scala:
val context = Kamon.tracer.newContext("example-trace")

Tracer.withContext(context) {
  // While this code executes, `context` is the current
  // TraceContext.
  println("Current Trace Token: " + Tracer.currentContext.token)
}
Java:
final TraceContext context = Kamon.tracer().newContext("example-trace");

Tracer.withContext(context, () -> {
  // While this code executes, `context` is the current
  // TraceContext.
  System.out.println("Current Trace Token: " + Tracer.currentContext().token());

  return "Some awesome result";
});

注意:一旦完成,Tracer.withContext(...) 变量将会关闭一个trace。

创建和关闭Segment

Tracer伴随对象没有直接提供创建segment的API,但是通过TraceContext实例,你可以创建你segment。一旦你访问了TraceContext,你就能够调用.startSegment(…)方法,从而获得一个与这个TraceContext关联的segment。

Scala:
Tracer.withNewContext("trace-with-segments", autoFinish = true) {
  val segment = Tracer.currentContext.startSegment("some-cool-section", "business-logic", "kamon")
  // Some application code here.
  segment.finish()
}
java:
Tracer.withNewContext("trace-with-segments", true, () -> {
  final Segment segment = Tracer.currentContext().startSegment("some-cool-section", "business-logic", "kamon");
  // Some application code here.
  segment.finish();

  return "done";
});

记住:关闭trace之后,与之对应的segment也会被关闭。因此不要在还在.withContext(...) 代码块中强制关闭segment。segment清晰的知道它属于哪个TraceContext.
上面提到的方法更灵活。你可以通过segment实例做任何你想做的,除了TraceContext也提供了一个.withNewSegment(…)方法,他创建一个segment,并在代码执行结束的时候自动的关闭它。

Scala:
Tracer.withNewContext("trace-with-segments", autoFinish = true) {

  Tracer.currentContext.withNewSegment("some-cool-section", "business-logic", "kamon") {
    // Here is where the segment does it's job.

  }
}
java:
Tracer.withNewContext("trace-with-segments", true, () -> {

  Tracer.currentContext().withNewSegment("some-cool-section", "business-logic", "kamon", () -> {
    // Here is where the segment does it's job.

    return 0;
  });

  return "done";
});

显然,你不需要通关过Tracer.currentContext获得context,但那时你可以在任何以恶搞TraceContext中启动一个segment。
最后,另一个对Scala开发者友好的方法是.withAsyncSegment,它可以从代码中创建一个新的segment兵返回一个Future[T],还能在future完成时自动的关闭这个segment。代码:

Scala:
Scala
Tracer.withNewContext("trace-with-segments", autoFinish = true) {

  Tracer.currentContext.withNewAsyncSegment("some-cool-section", "business-logic", "kamon") {
    Future {
      // Some code that will be executed asynchronously.
    }
  }
}
 类似资料: