Beispiel #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();
            }
        }
    }
Beispiel #2
0
        internal static void StopTransaction(Transaction transaction, HttpContext context, IApmLogger logger)
        {
            if (transaction == null)
            {
                return;
            }

            var grpcCallInfo = CollectGrpcInfo();

            try
            {
                if (!transaction.HasCustomName)
                {
                    //fixup Transaction.Name - e.g. /user/profile/1 -> /user/profile/{id}
                    var routeData = context.GetRouteData()?.Values;

                    if (routeData != null && context.Response.StatusCode != StatusCodes.Status404NotFound)
                    {
                        logger?.Trace()?.Log("Calculating transaction name based on route data");
                        var name = Transaction.GetNameFromRouteContext(routeData);

                        if (!string.IsNullOrWhiteSpace(name))
                        {
                            transaction.Name = $"{context.Request.Method} {name}";
                        }
                    }
                    else if (context.Response.StatusCode == StatusCodes.Status404NotFound)
                    {
                        logger?.Trace()
                                                        ?
                        .Log("No route data found or status code is 404 - setting transaction name to 'unknown route");
                        transaction.Name = $"{context.Request.Method} unknown route";
                    }
                }

                if (grpcCallInfo == default)
                {
                    transaction.Result = Transaction.StatusCodeToResult(GetProtocolName(context.Request.Protocol), context.Response.StatusCode);

                    if (context.Response.StatusCode >= 500)
                    {
                        transaction.Outcome = Outcome.Failure;
                    }
                    else
                    {
                        transaction.Outcome = Outcome.Success;
                    }
                }
                else
                {
                    transaction.Name   = grpcCallInfo.methodname;
                    transaction.Result = GrpcHelper.GrpcReturnCodeToString(grpcCallInfo.result);

                    if (transaction.Result == "OK")
                    {
                        transaction.Outcome = Outcome.Success;
                    }
                    else
                    {
                        transaction.Outcome = Outcome.Failure;
                    }
                }

                if (transaction.IsSampled)
                {
                    FillSampledTransactionContextResponse(context, transaction, logger);
                    FillSampledTransactionContextUser(context, transaction, logger);
                }
            }
            catch (Exception ex)
            {
                logger?.Error()?.LogException(ex, "Exception thrown while trying to stop transaction");
            }
            finally
            {
                transaction.End();
            }
        }