internal static CallTargetState OnMethodBegin <TTarget>(TTarget instance) { var tracer = Tracer.Instance; if (GrpcCoreApiVersionHelper.IsSupported && tracer.Settings.IsIntegrationEnabled(IntegrationId.Grpc) && tracer.ActiveScope?.Span is Span { Tags : GrpcServerTags } span) { var callContext = instance.DuckCast <HttpContextServerCallContextStruct>(); var status = callContext.StatusCore; GrpcCommon.RecordFinalStatus(span, status.StatusCode, status.Detail, status.DebugException); if (callContext.RequestHeaders is { Count : > 0 } requestMetadata) { span.SetHeaderTags(new MetadataHeadersCollection(requestMetadata), tracer.Settings.GrpcTags, defaultTagPrefix : GrpcCommon.RequestMetadataTagPrefix); } if (callContext.ResponseTrailers is { Count : > 0 } responseMetadata) { span.SetHeaderTags(new MetadataHeadersCollection(responseMetadata), tracer.Settings.GrpcTags, defaultTagPrefix : GrpcCommon.ResponseMetadataTagPrefix); } } return(CallTargetState.GetDefault()); }
public static Scope?CreateClientSpan <TGrpcCall, TRequest>(Tracer tracer, TGrpcCall instance, TRequest requestMessage) where TRequest : IHttpRequestMessage { if (!tracer.Settings.IsIntegrationEnabled(IntegrationId.Grpc) || instance is null) { return(null); } Scope?scope = null; // Can't use constraints for this one, as we're in a generic class var grpcCall = instance.DuckCast <IGrpcCall>(); try { var tags = new GrpcClientTags(); var method = grpcCall.Method; GrpcCommon.AddGrpcTags(tags, tracer, method.GrpcType, name: method.Name, path: method.FullName, serviceName: method.ServiceName); var serviceName = tracer.Settings.GetServiceName(tracer, GrpcCommon.ServiceName); scope = tracer.StartActiveInternal(GrpcCommon.OperationName, tags: tags, serviceName: serviceName, startTime: null); var span = scope.Span; span.Type = SpanTypes.Grpc; span.ResourceName = method.FullName; // add distributed tracing headers to the HTTP request // These will be overwritten by the HttpClient integration if that is enabled, per the RFC SpanContextPropagator.Instance.Inject(span.Context, new HttpHeadersCollection(requestMessage.Headers)); // Add the request metadata as tags if (grpcCall.Options.Headers is { Count : > 0 }) { var metadata = new MetadataHeadersCollection(grpcCall.Options.Headers); span.SetHeaderTags(metadata, tracer.Settings.GrpcTags, defaultTagPrefix: GrpcCommon.RequestMetadataTagPrefix); } tracer.TracerManager.Telemetry.IntegrationGeneratedSpan(IntegrationId.Grpc); }
public static Scope?CreateServerSpan <TTarget>(Tracer tracer, TTarget target, IMetadata?metadata) { var serverHandler = target.DuckCast <ServerCallHandlerStruct>(); var method = serverHandler.Method; Scope?scope = null; try { var tags = new GrpcServerTags(); // Grpc.Core server tags are typically the root span, so use enabledWithGlobalSetting=true GrpcCommon.AddGrpcTags(tags, tracer, method.GrpcType, name: method.Name, path: method.FullName, serviceName: method.ServiceName, analyticsEnabledWithGlobalSetting: true); // If we have a local span (e.g. from aspnetcore) then use that as the parent // Otherwise, use the distributed context as the parent var spanContext = tracer.ActiveScope?.Span.Context; if (spanContext is null) { spanContext = ExtractPropagatedContext(metadata); } var serviceName = tracer.DefaultServiceName ?? "grpc-server"; scope = tracer.StartActiveInternal(GrpcCommon.OperationName, parent: spanContext, tags: tags, serviceName: serviceName); var span = scope.Span; span.Type = SpanTypes.Grpc; span.ResourceName = method.FullName; if (metadata?.Count > 0) { span.SetHeaderTags(new MetadataHeadersCollection(metadata), tracer.Settings.GrpcTags, GrpcCommon.RequestMetadataTagPrefix); } } catch (Exception ex) { Log.Error(ex, "Error creating server span for GRPC call"); } return(scope); }
internal static CallTargetState OnMethodBegin(HttpResponse response, int httpStatusCode, int grpcStatusCode, string message) { var tracer = Tracer.Instance; if (GrpcCoreApiVersionHelper.IsSupported && tracer.Settings.IsIntegrationEnabled(IntegrationId.Grpc) && tracer.ActiveScope?.Span is Span { Tags : GrpcServerTags } span) { // This code path is only called when there's a fundamental failure that isn't even processed // (e.g. wrong Http protocol, invalid content-type etc) GrpcCommon.RecordFinalStatus(span, grpcStatusCode, message, ex : null); // There won't be any response metadata, as interceptors haven't executed, but we can grab // the request metadata directly from the HttpRequest var request = response.HttpContext.Request; span.SetHeaderTags(new HeadersCollectionAdapter(request.Headers), tracer.Settings.GrpcTags, defaultTagPrefix: GrpcCommon.RequestMetadataTagPrefix); } return(CallTargetState.GetDefault()); }
public static Scope?CreateServerSpan <T>(Tracer tracer, T instance, HttpRequest requestMessage) { if (!tracer.Settings.IsIntegrationEnabled(IntegrationId.Grpc)) { return(null); } Scope?scope = null; var method = instance.DuckCast <ServerCallHandlerBaseStruct>().MethodInvoker.Method; try { var tags = new GrpcServerTags(); GrpcCommon.AddGrpcTags(tags, tracer, method.GrpcType, name: method.Name, path: method.FullName, serviceName: method.ServiceName); // If we have a local span (e.g. from aspnetcore) then use that as the parent // Otherwise, use the distributed context as the parent var spanContext = tracer.ActiveScope?.Span.Context; if (spanContext is null) { spanContext = ExtractPropagatedContext(requestMessage); } var serviceName = tracer.DefaultServiceName ?? "grpc-server"; scope = tracer.StartActiveInternal(GrpcCommon.OperationName, parent: spanContext, tags: tags, serviceName: serviceName); var span = scope.Span; span.Type = SpanTypes.Grpc; span.ResourceName = method.FullName; tracer.TracerManager.Telemetry.IntegrationGeneratedSpan(IntegrationId.Grpc); } catch (Exception ex) { Log.Error(ex, "Error creating server span for GRPC call"); } return(scope); }