public void GivenAGRPCSpanWithStatus(string responseCode) { var span = _agent.Tracer.StartTransaction("GRPCTransaction", "Test").StartSpan("GRPCSpan", "Test"); span.Outcome = GrpcHelper.GrpcClientReturnCodeToOutcome(responseCode); _lastSpan = span; }
protected override void HandleOnNext(KeyValuePair <string, object> kv) { Logger.Trace() ?.Log("{currentClassName} received diagnosticsource event: {eventKey}", nameof(GrpcClientDiagnosticListener), kv.Key); var currentActivity = Activity.Current; if (kv.Key == "Grpc.Net.Client.GrpcOut.Start") { if (kv.Value.GetType().GetTypeInfo().GetDeclaredProperty("Request")?.GetValue(kv.Value) is HttpRequestMessage requestObject) { var currentTransaction = ApmAgent?.Tracer.CurrentTransaction; if (currentTransaction != null) { var grpcMethodName = currentActivity?.Tags.FirstOrDefault(n => n.Key == "grpc.method").Value; if (string.IsNullOrEmpty(grpcMethodName)) { grpcMethodName = "unknown"; } Logger.Trace()?.Log("Starting span for gRPC call, method:{methodName}", grpcMethodName); var newSpan = currentTransaction.StartSpan(grpcMethodName, ApiConstants.TypeExternal, ApiConstants.SubTypeGrpc, isExitSpan: true); ProcessingRequests.TryAdd(requestObject, newSpan); } } } if (kv.Key == "Grpc.Net.Client.GrpcOut.Stop") { if (kv.Value.GetType().GetTypeInfo().GetDeclaredProperty("Request")?.GetValue(kv.Value) is not HttpRequestMessage requestObject) { return; } if (!ProcessingRequests.TryRemove(requestObject, out var span)) { return; } Logger.Trace()?.Log("Ending span for gRPC call, span:{span}", span); var grpcStatusCode = currentActivity?.Tags?.Where(n => n.Key == "grpc.status_code").FirstOrDefault().Value; if (grpcStatusCode != null) { span.Outcome = GrpcHelper.GrpcClientReturnCodeToOutcome(GrpcHelper.GrpcReturnCodeToString(grpcStatusCode)); } span.Context.Destination = UrlUtils.ExtractDestination(requestObject.RequestUri, Logger); span.Context.Destination.Service = new() { Resource = UrlUtils.ExtractService(requestObject.RequestUri, span) }; span.End(); } } }