public void BuildSpan()
        {
            var span = new NewRelicSpan(
                traceId: "traceId",
                spanId: "spanId",
                timestamp: 1L,
                parentSpanId: "parentId",
                attributes: new Dictionary <string, object>()
            {
                { "attrKey", "attrValue" },
                { "adsfasdf", 12 },
                { NewRelicConsts.Tracing.AttribNameDurationMs, 67 },
                { NewRelicConsts.Tracing.AttribNameServiceName, "serviceName" },
                { NewRelicConsts.Tracing.AttribNameName, "name" },
            });

            Assert.Equal("spanId", span.Id);
            Assert.Equal("traceId", span.TraceId);
            Assert.Equal(1L, span.Timestamp);
            Assert.Equal("serviceName", span.Attributes?["service.name"]);
            Assert.Equal(67, span.Attributes?["duration.ms"]);
            Assert.Equal("name", span.Attributes?["name"]);
            Assert.Equal("parentId", span.Attributes?["parent.id"]);
            Assert.Equal("attrValue", span.Attributes?["attrKey"]);
        }
Example #2
0
        public void SendANonEmptySpanBatch()
        {
            var traceId = "123";

            var span = new NewRelicSpan(
                traceId: null,
                spanId: "Span1",
                timestamp: DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
                parentSpanId: null,
                attributes: new Dictionary <string, object>()
            {
                { NewRelicConsts.Tracing.AttribNameName, "TestSpan" },
            });

            var spanBatch = new NewRelicSpanBatch(
                spans: new[] { span },
                commonProperties: new NewRelicSpanBatchCommonProperties(traceId));

            var dataSender = new TraceDataSender(new TelemetryConfiguration()
            {
                ApiKey = "123456"
            }, null);

            dataSender.WithHttpHandlerImpl((serializedJson) =>
            {
                var response = new HttpResponseMessage(System.Net.HttpStatusCode.OK);
                return(Task.FromResult(response));
            });

            var response = dataSender.SendDataAsync(spanBatch).Result;

            Assert.Equal(NewRelicResponseStatus.Success, response.ResponseStatus);
        }
Example #3
0
        public async Task <IEnumerable <WeatherForecast> > Get()
        {
            // Each span must have a unique identifier.  In this example, we are using a Guid.
            var spanId        = Guid.NewGuid().ToString();
            var spanTimeStamp = DateTimeOffset.UtcNow;
            var spanAttribs   = new Dictionary <string, object>();

            // Wrapping the unit of work inside a try/catch is helpful to ensure that
            // spans are always reported to the endpoint, even if they have exceptions.
            try
            {
                // This is the unit of work being tracked by the span.
                var rng    = new Random();
                var result = Enumerable.Range(1, 5)
                             .Select(index => new WeatherForecast()
                {
                    Date         = DateTime.Now.AddDays(index),
                    TemperatureC = rng.Next(-20, 55),
                    Summary      = Summaries[rng.Next(Summaries.Length)]
                })
                             .ToArray();

                return(result);
            }
            // If an unhandled exception occurs, it can be denoted on the span.
            catch (Exception ex)
            {
                spanAttribs[NewRelicConsts.Tracing.AttribNameErrorMsg] = ex;

                //This ensures that tracking of spans doesn't interfere with the normal execution flow
                throw;
            }
            // In all cases, the span is sent up to the New Relic endpoint.
            finally
            {
                spanAttribs[NewRelicConsts.Tracing.AttribNameName]       = "WeatherForecast/Get";
                spanAttribs[NewRelicConsts.Tracing.AttribNameDurationMs] = DateTimeOffset.UtcNow.Subtract(spanTimeStamp).TotalMilliseconds;


                var span = new NewRelicSpan(
                    traceId: Guid.NewGuid().ToString(),
                    spanId: spanId,
                    timestamp: spanTimeStamp.ToUnixTimeMilliseconds(),
                    parentSpanId: null,
                    attributes: spanAttribs);

                // Send it to the New Relic endpoint.
                var newRelicResult = await _spanDataSender.SendDataAsync(new[] { span });

                if (newRelicResult.ResponseStatus == NewRelicResponseStatus.Failure)
                {
                    _logger.LogWarning("There was a problem sending the SpanBatch to New Relic endpoint");
                }
            }
        }
        /// <summary>
        /// In this example, multiple traces will be reported in the same batch.
        /// Accordingly, the TraceId is applied to the individual spans, and NOT on
        /// the SpanBatch.
        /// </summary>
        private static async Task Example_SpanBatchForMultipleTraces()
        {
            // The collection of Spans
            var spans = new List <NewRelicSpan>();

            for (var traceIdx = 0; traceIdx < 3; traceIdx++)
            {
                var traceId = Guid.NewGuid().ToString();

                // Perform 10 units of work as part of this trace/spanBatch
                for (var spanIdx = 0; spanIdx < 5; spanIdx++)
                {
                    var spanStartTime = DateTime.UtcNow;
                    var spanAttribs   = new Dictionary <string, object>();

                    try
                    {
                        // Attempt to perform a unit of work
                        DoWork($"Hello World #{spanIdx}");
                    }
                    catch (Exception ex)
                    {
                        // In the event of an exception, mark the span
                        // as having an error and record a custom attribute
                        // with the details about the exception.
                        spanAttribs[NewRelicConsts.Tracing.AttribNameErrorMsg] = ex.Message;
                    }
                    finally
                    {
                        spanAttribs[NewRelicConsts.Tracing.AttribNameName]       = $"{traceId} - {spanIdx}";
                        spanAttribs[NewRelicConsts.Tracing.AttribNameDurationMs] = DateTime.UtcNow.Subtract(spanStartTime).TotalMilliseconds;

                        // Create a new Span assigning it a random guid as the spanId
                        var span = new NewRelicSpan(
                            traceId: traceId,         //Since we're mixing traces in the same batch, the trace id is supplied on each span
                            spanId: Guid.NewGuid().ToString(),
                            parentSpanId: null,
                            timestamp: DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
                            attributes: spanAttribs);

                        spans.Add(span);
                    }
                }
            }

            var spanBatch = new NewRelicSpanBatch(spans);

            // Send the SpanBatch to the New Relic endpoint.
            await SendDataToNewRelic(spanBatch);
        }