我有一个基于 java 的核心服务,它通过 grpc 调用与另一个 .NET 服务进行通信。 java 服务接收来自 .NET 服务的 grpc 请求,它将处理该请求并发回 grpc 响应。
我已经使用 opentelemetry java 代理检测了 java 服务,并且手动检测了 .NET 服务。 在生产设置中,这两项服务都将成为单个应用程序的一部分。所以我想在这些服务之间设置正确的上下文传播。我希望能够看到 java 服务的痕迹与 .NET 服务的痕迹一致。
我尝试创建一个
TextMapPropagator
并使用 TextMapGetter
从元数据标头中提取跟踪上下文,并使用父级作为提取的上下文创建跨度。但我从提取的上下文中得到的值为 null。
public class ServerHeadInterceptor implements ServerInterceptor
{
private final Tracer tracer = GlobalOpenTelemetry.getTracer("my-tracer);
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call, Metadata headers, ServerCallHandler<ReqT, RespT> next)
{
TextMapPropagator propagator = GlobalOpenTelemetry.getPropagators().getTextMapPropagator();
Context extractedContext = propagator.extract(Context.current(), headers, new TextMapGetter<Metadata>()
{
@Override
public Iterable<String> keys(Metadata carrier)
{
return carrier.keys();
}
@Nullable
@Override
public String get(@Nullable Metadata carrier, String key)
{
Metadata.Key<String> traceParent = Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER);
String value = carrier.get(traceParent);
System.out.println("VALUE :" + value);
return value;
}
});
Span span = tracer.spanBuilder("my-span).setSpanKind(SpanKind.CONSUMER).setParent(extractedContext).startSpan;
try(Scope scope =span.makeCurrent()
{
return new ForwardingServerCallListener.SimpleForwardingServerCallListener<ReqT>(next.startCall(call, headers)) {};
}
finally
{
span.end()
}
如何从传入的 grpc 请求中提取跟踪上下文并从该上下文创建跨度?
opentelemetry java 代理是否为此提供任何自动功能?
有多个 grpc 请求从 .NET 服务传入 java 服务,因此是否可以通过从每个请求中提取跟踪上下文并从该上下文创建跨度来处理所有这些请求,以便跟踪正确对齐?
注意:我使用 Grafana tempo 作为痕迹导出器。
如何从传入的 grpc 请求中提取跟踪上下文并从该上下文创建跨度?
我认为您描述的使用传播器提取跨度上下文的解决方案是正确的。但默认情况下
GlobalOpenTelemetry.getPropagators().getTextMapPropagator()
是 noop 传播器,所以如果你没有配置它,你就不会从中得到任何东西。您必须使用真实的传播器实例。 OpenTelemetry 支持一些内置的传播器,例如w3c,请参阅此处