示例#1
0
        public async void StartWork()
        {
            var httpClient = new HttpClient
            {
                BaseAddress = _serverUrlBase
            };

            while (true)
            {
                var item = _payloads.Take();

                try
                {
                    var json = JsonConvert.SerializeObject(item,
                                                           new JsonSerializerSettings {
                        ContractResolver = new CamelCasePropertyNamesContractResolver()
                    });
                    var content = new StringContent(json, Encoding.UTF8, "application/json");

                    HttpResponseMessage result = null;
                    switch (item)
                    {
                    case Payload p:
                        result = await httpClient.PostAsync(Consts.IntakeV1Transactions, content);

                        break;

                    case Error e:
                        result = await httpClient.PostAsync(Consts.IntakeV1Errors, content);

                        break;
                    }

                    var isSucc = result.IsSuccessStatusCode;
                    var str    = await result.Content.ReadAsStringAsync();
                }
                catch (Exception e)
                {
                    switch (item)
                    {
                    case Payload p:
                        _logger.LogWarning($"Failed sending transaction {p.Transactions.FirstOrDefault()?.Name}");
                        _logger.LogDebug($"{e.GetType().Name}: {e.Message}");
                        break;

                    case Error err:
                        _logger.LogWarning($"Failed sending Error {err.Errors[0]?.Id}");
                        _logger.LogDebug($"{e.GetType().Name}: {e.Message}");
                        break;
                    }
                }
            }
        }
        /// <summary>
        /// Turns a System.Diagnostic.StackFrame[] into a <see cref="Stacktrace"/> list which can be reported to the APM Server
        /// </summary>
        /// <param name="capturingFor">Just for logging.</param>
        /// <returns>A prepared List that can be passed to the APM server</returns>
        public static List <Stacktrace> GenerateApmStackTrace(StackFrame[] frames, AbstractLogger logger, string capturingFor)
        {
            var retVal = new List <Stacktrace>(frames.Length);

            try
            {
                foreach (var item in frames)
                {
                    var fileName = item?.GetMethod()?.DeclaringType?.Assembly?.GetName()?.Name;
                    if (String.IsNullOrEmpty(fileName))
                    {
                        continue; //since filename is required by the server, if we don't have it we skip the frame
                    }

                    retVal.Add(new Stacktrace
                    {
                        Function = item?.GetMethod()?.Name,
                        Filename = fileName,
                        Module   = item?.GetMethod()?.ReflectedType?.Name
                    });
                }
            }
            catch (Exception e)
            {
                logger.LogWarning($"Failed capturing stacktrace for {capturingFor}");
                logger.LogDebug($"{e.GetType().Name}: {e.Message}");
            }

            return(retVal);
        }
示例#3
0
        /// <summary>
        /// Turns a System.Diagnostic.StackFrame[] into a <see cref="Stacktrace" /> list which can be reported to the APM Server
        /// </summary>
        /// <param name="capturingFor">Just for logging.</param>
        /// <returns>A prepared List that can be passed to the APM server</returns>
        internal static List <Stacktrace> GenerateApmStackTrace(StackFrame[] frames, AbstractLogger logger, string capturingFor)
        {
            var retVal = new List <Stacktrace>(frames.Length);

            try
            {
                retVal.AddRange(from item in frames
                                let fileName = item?.GetMethod()?.DeclaringType?.Assembly?.GetName()?.Name
                                               where !string.IsNullOrEmpty(fileName)
                                               select new Stacktrace
                {
                    Function = item?.GetMethod()?.Name,
                    FileName = fileName,
                    Module   = item?.GetMethod()?.ReflectedType?.Name,
                    LineNo   = item?.GetFileLineNumber() ?? 0
                });
            }
            catch (Exception e)
            {
                logger.LogWarning($"Failed capturing stacktrace for {capturingFor}");
                logger.LogDebug($"{e.GetType().Name}: {e.Message}");
            }

            return(retVal);
        }
示例#4
0
        private void LogWithLevel(LogLevel logLevel)
        {
            Apm.Agent.Config.LogLevel = logLevel;

            logger.LogError("Error log");
            logger.LogWarning("Warning log");
            logger.LogInfo("Info log");
            logger.LogDebug("Debug log");
        }
示例#5
0
        public void OnNext(KeyValuePair <string, object> kv)
        {
            if (kv.Value == null || String.IsNullOrEmpty(kv.Key))
            {
                return;
            }

            if (!(kv.Value.GetType().GetTypeInfo().GetDeclaredProperty("Request")?.GetValue(kv.Value) is HttpRequestMessage request))
            {
                return;
            }

            if (IsRequestFiltered(request?.RequestUri))
            {
                return;
            }

            switch (kv.Key)
            {
            case "System.Net.Http.Exception":
                var exception   = kv.Value.GetType().GetTypeInfo().GetDeclaredProperty("Exception").GetValue(kv.Value) as Exception;
                var transaction = TransactionContainer.Transactions?.Value[0];

                var error = new Error
                {
                    Errors = new List <Error.Err>
                    {
                        new Error.Err
                        {
                            Culprit   = "Failed outgoing HTTP request",
                            Exception = new CapturedException
                            {
                                Message = exception.Message,
                                Type    = exception.GetType().FullName
                                          //Handled  TODO: this exception can be handled later
                            },
                            Transaction = new Error.Err.Trans
                            {
                                Id = transaction.Id
                            },
                            Id        = Guid.NewGuid(),
                            Timestamp = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.FFFZ")
                        }
                    },

                    Service = transaction.service
                };

                if (!String.IsNullOrEmpty(exception.StackTrace))
                {
                    error.Errors[0].Exception.Stacktrace
                        = StacktraceHelper.GenerateApmStackTrace(new System.Diagnostics.StackTrace(exception).GetFrames(), logger, "failed outgoing HTTP request");
                }

                if (transaction.Context != null)
                {
                    error.Errors[0].Context = transaction.Context;
                }

                Agent.PayloadSender.QueueError(error);

                break;

            case "System.Net.Http.HttpRequestOut.Start":     //TODO: look for consts
                if (TransactionContainer.Transactions == null || TransactionContainer.Transactions.Value == null)
                {
                    return;
                }

                var transactionStartTime = TransactionContainer.Transactions.Value[0].TimestampInDateTime;
                var utcNow = DateTime.UtcNow;

                var http = new Http
                {
                    Url    = request?.RequestUri?.ToString(),
                    Method = request?.Method?.Method,
                };

                var span = new Span
                {
                    Start   = (decimal)(utcNow - transactionStartTime).TotalMilliseconds,
                    Name    = $"{request?.Method} {request?.RequestUri?.Host?.ToString()}",
                    Type    = Consts.EXTERNAL,
                    Subtype = Consts.HTTP,
                    Context = new Span.ContextC
                    {
                        Http = http
                    }
                };

                if (processingRequests.TryAdd(request, span))
                {
                    var frames      = new System.Diagnostics.StackTrace().GetFrames();
                    var stackFrames = StacktraceHelper.GenerateApmStackTrace(frames, logger, span.Name);
                    span.Stacktrace = stackFrames;
                }
                break;

            case "System.Net.Http.HttpRequestOut.Stop":
                var response = kv.Value.GetType().GetTypeInfo().GetDeclaredProperty("Response").GetValue(kv.Value) as HttpResponseMessage;

                if (processingRequests.TryRemove(request, out Span mspan))
                {
                    //TODO: response can be null if for example the request Task is Faulted.
                    //E.g. writing this from an airplane without internet, and requestTaskStatus is "Faulted" and response is null
                    //How do we report this? There is no response code in that case.
                    if (response != null)
                    {
                        mspan.Context.Http.Status_code = (int)response.StatusCode;
                    }

                    //TODO: there are better ways
                    var endTime = (DateTime.UtcNow - TransactionContainer.Transactions.Value[0].TimestampInDateTime).TotalMilliseconds;
                    mspan.Duration = endTime - (double)mspan.Start;

                    TransactionContainer.Transactions?.Value[0]?.Spans?.Add(mspan);
                }
                else
                {
                    logger.LogWarning($"Failed capturing request"
                                      + (!String.IsNullOrEmpty(request?.RequestUri?.AbsoluteUri) && !String.IsNullOrEmpty(request?.Method?.ToString()) ? $" '{request?.Method.ToString()} " : " ")
                                      + (String.IsNullOrEmpty(request?.RequestUri?.AbsoluteUri) ? "" : $"{request?.RequestUri.AbsoluteUri}' ")
                                      + "in System.Net.Http.HttpRequestOut.Stop. This Span will be skipped in case it wasn't captured before.");
                }
                break;
            }
        }
示例#6
0
        public void OnNext(KeyValuePair <string, object> kv)
        {
            if (kv.Value == null || String.IsNullOrEmpty(kv.Key))
            {
                return;
            }

            if (!(kv.Value.GetType().GetTypeInfo().GetDeclaredProperty("Request")?.GetValue(kv.Value) is HttpRequestMessage request))
            {
                return;
            }

            if (IsRequestFiltered(request?.RequestUri))
            {
                return;
            }

            switch (kv.Key)
            {
            case "System.Net.Http.Exception":
                var exception   = kv.Value.GetType().GetTypeInfo().GetDeclaredProperty("Exception").GetValue(kv.Value) as Exception;
                var transaction = TransactionContainer.Transactions?.Value;

                transaction.CaptureException(exception, "Failed outgoing HTTP request");
                //TODO: we don't know if exception is handled, currently reports handled = false
                break;

            case "System.Net.Http.HttpRequestOut.Start":     //TODO: look for consts
                if (TransactionContainer.Transactions == null || TransactionContainer.Transactions.Value == null)
                {
                    return;
                }

                transaction = TransactionContainer.Transactions.Value;

                var span = transaction.StartSpan($"{request?.Method} {request?.RequestUri?.Host?.ToString()}", Span.TYPE_EXTERNAL,
                                                 Span.SUBTYPE_HTTP);

                if (processingRequests.TryAdd(request, span))
                {
                    span.Context = new Span.ContextC
                    {
                        Http = new Http
                        {
                            Url    = request?.RequestUri?.ToString(),
                            Method = request?.Method?.Method,
                        }
                    };

                    var frames      = new System.Diagnostics.StackTrace().GetFrames();
                    var stackFrames = StacktraceHelper.GenerateApmStackTrace(frames, logger, span.Name);
                    span.Stacktrace = stackFrames;
                }
                break;

            case "System.Net.Http.HttpRequestOut.Stop":
                var response = kv.Value.GetType().GetTypeInfo().GetDeclaredProperty("Response").GetValue(kv.Value) as HttpResponseMessage;

                if (processingRequests.TryRemove(request, out ISpan mspan))
                {
                    //TODO: response can be null if for example the request Task is Faulted.
                    //E.g. writing this from an airplane without internet, and requestTaskStatus is "Faulted" and response is null
                    //How do we report this? There is no response code in that case.
                    if (response != null)
                    {
                        mspan.Context.Http.Status_code = (int)response.StatusCode;
                    }

                    mspan.End();
                }
                else
                {
                    logger.LogWarning($"Failed capturing request"
                                      + (!String.IsNullOrEmpty(request?.RequestUri?.AbsoluteUri) && !String.IsNullOrEmpty(request?.Method?.ToString()) ? $" '{request?.Method.ToString()} " : " ")
                                      + (String.IsNullOrEmpty(request?.RequestUri?.AbsoluteUri) ? "" : $"{request?.RequestUri.AbsoluteUri}' ")
                                      + "in System.Net.Http.HttpRequestOut.Stop. This Span will be skipped in case it wasn't captured before.");
                }
                break;
            }
        }