Exemplo n.º 1
0
        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();
            }
        }
    }
Exemplo n.º 2
0
        private void DeduceDestination()
        {
            if (!_context.IsValueCreated)
            {
                return;
            }

            if (Context.Http != null)
            {
                var destination = DeduceHttpDestination();
                if (destination == null)
                {
                    // In case of invalid destination just return
                    return;
                }

                CopyMissingProperties(destination);
            }

            FillDestinationService();

            // Fills Context.Destination.Service
            void FillDestinationService()
            {
                // Context.Destination must be set by the instrumentation part - otherwise we won't fill Context.Destination.Service
                if (Context.Destination == null)
                {
                    return;
                }

                // Context.Destination.Service can be set by the instrumentation part - only fill it if needed.
                if (Context.Destination.Service != null)
                {
                    return;
                }

                Context.Destination.Service = new Destination.DestinationService {
                    Type = Type
                };

                if (_context.Value.Http != null)
                {
                    if (!_context.Value.Http.OriginalUrl.IsAbsoluteUri)
                    {
                        // Can't fill Destination.Service - we just set it to null and return
                        Context.Destination.Service = null;
                        return;
                    }

                    Context.Destination.Service = UrlUtils.ExtractService(_context.Value.Http.OriginalUrl, this);
                }
                else
                {
                    // Once messaging is added, for messaging, we'll additionally need to add the queue name here
                    Context.Destination.Service.Resource = Subtype;
                    Context.Destination.Service.Name     = Subtype;
                }
            }

            void CopyMissingProperties(Destination src)
            {
                if (src == null)
                {
                    return;
                }

                if (Context.Destination == null)
                {
                    Context.Destination = src;
                }
                else
                {
                    Context.Destination.CopyMissingPropertiesFrom(src);
                }
            }
        }