public void ToSpanData_NoRecordEvents() { ISpan span = Span.StartSpan( spanContext, noRecordSpanOptions, SPAN_NAME, parentSpanId, false, TraceParams.DEFAULT, startEndHandler, timestampConverter, testClock); // Check that adding trace events after Span#End() does not throw any exception. span.PutAttributes(attributes); span.AddAnnotation(Annotation.FromDescription(ANNOTATION_DESCRIPTION)); span.AddAnnotation(ANNOTATION_DESCRIPTION, attributes); span.AddMessageEvent( MessageEvent.Builder(MessageEventType.RECEIVED, 1).SetUncompressedMessageSize(3).Build()); span.AddLink(Link.FromSpanContext(spanContext, LinkType.CHILD_LINKED_SPAN)); span.End(); //exception.expect(IllegalStateException); Assert.Throws <InvalidOperationException>(() => ((Span)span).ToSpanData()); }
protected internal void HandleStopEvent(HttpContext context) { var spanContext = active.Value; if (spanContext == null) { Logger?.LogDebug("HandleStopEvent: Missing span context"); return; } ISpan span = spanContext.Active; span.PutHttpStatusCodeAttribute(context.Response.StatusCode); if (context.Response.Headers != null) { span.PutHttpResponseHeadersAttribute(AsList(context.Response.Headers)); } long? reqSize = ExtractRequestSize(context); if (reqSize != null) { span.PutHttpRequestSizeAttribute(reqSize.Value); } long? respSize = ExtractResponseSize(context); if (respSize != null) { span.PutHttpResponseSizeAttribute(respSize.Value); } span.End(); AsyncLocalContext.CurrentSpan = spanContext.Previous; active.Value = null; }
public async Task EmptyCartAsync(string userId) { Log.Information("EmptyCartAsync called with userId={userId}", userId); var transaction = Elastic.Apm.Agent.Tracer.CurrentTransaction; ISpan span = transaction.StartSpan("EmptyCartAsync", ApiConstants.TypeDb, ApiConstants.ActionQuery); span.Labels["userId"] = userId; try { EnsureRedisConnected(); var db = redis.GetDatabase(); // Update the cache with empty cart for given user await db.HashSetAsync(userId, new[] { new HashEntry(CART_FIELD_NAME, emptyCartBytes) }); } catch (Exception ex) { Log.Error(ex, "Can't access cart storage"); span.CaptureException(ex); throw new RpcException(new Status(StatusCode.FailedPrecondition, $"Can't access cart storage. {ex}")); } finally { span.End(); } }
public async Task <Hipstershop.Cart> GetCartAsync(string userId) { Log.Information("GetCartAsync called with userId={userId}", userId); var transaction = Elastic.Apm.Agent.Tracer.CurrentTransaction; ISpan span = transaction.StartSpan("GetCartAsync", ApiConstants.TypeDb, ApiConstants.ActionQuery); span.Labels["userId"] = userId; try { EnsureRedisConnected(); var db = redis.GetDatabase(); // Access the cart from the cache var value = await db.HashGetAsync(userId, CART_FIELD_NAME); if (!value.IsNull) { return(Hipstershop.Cart.Parser.ParseFrom(value)); } // We decided to return empty cart in cases when user wasn't in the cache before return(new Hipstershop.Cart()); } catch (Exception ex) { Log.Error(ex, "Can't access cart storage"); span.CaptureException(ex); throw new RpcException(new Status(StatusCode.FailedPrecondition, $"Can't access cart storage. {ex}")); } finally { span.End(); } }
internal void EndSpan(ISpan span, IDbCommand dbCommand, Outcome outcome, TimeSpan?duration = null) { if (span is Span capturedSpan) { if (duration.HasValue) { capturedSpan.Duration = duration.Value.TotalMilliseconds; } GetDefaultProperties(dbCommand.Connection.GetType().FullName, out var spanSubtype, out var defaultPort); capturedSpan.Subtype = spanSubtype; capturedSpan.Action = GetSpanAction(dbCommand.CommandType); if (capturedSpan.ShouldBeSentToApmServer) { capturedSpan.Context.Db = new Database { Statement = GetDbSpanName(dbCommand), Instance = dbCommand.Connection.Database, Type = Database.TypeSql }; capturedSpan.Context.Destination = GetDestination(dbCommand.Connection?.ConnectionString, defaultPort); } else { capturedSpan.ServiceResource = !string.IsNullOrEmpty(capturedSpan.Subtype) ? capturedSpan.Subtype : Database.TypeSql + dbCommand.Connection.Database; } capturedSpan.Outcome = outcome; } span.End(); }
internal void EndSpan(ISpan span, IDbCommand dbCommand, Outcome outcome, TimeSpan?duration = null) { if (span is Span capturedSpan) { if (duration.HasValue) { capturedSpan.Duration = duration.Value.TotalMilliseconds; } GetDefaultProperties(dbCommand.Connection.GetType().FullName, out var spanSubtype, out var isEmbeddedDb, out var defaultPort); capturedSpan.Subtype = spanSubtype; capturedSpan.Action = GetSpanAction(dbCommand.CommandType); if (capturedSpan.ShouldBeSentToApmServer) { capturedSpan.Context.Db = new Database { Statement = dbCommand.CommandText.Replace(Environment.NewLine, " "), Instance = dbCommand.Connection.Database, Type = Database.TypeSql }; capturedSpan.Context.Destination = GetDestination(dbCommand.Connection?.ConnectionString, isEmbeddedDb, defaultPort); } capturedSpan.Outcome = outcome; capturedSpan.End(); } span.End(); }
public void NoEventsRecordedAfterEnd() { ISpan span = Span.StartSpan( spanContext, recordSpanOptions, SPAN_NAME, SpanKind.Internal, parentSpanId, TraceParams.Default, startEndHandler, timestampConverter); span.End(); // Check that adding trace events after Span#End() does not throw any exception and are not // recorded. foreach (var attribute in attributes) { span.SetAttribute(attribute.Key, attribute.Value); } span.SetAttribute( "MySingleStringAttributeKey", AttributeValue.StringAttributeValue("MySingleStringAttributeValue")); span.AddEvent(Event.Create(EVENT_DESCRIPTION)); span.AddEvent(EVENT_DESCRIPTION, attributes); span.AddLink(Link.FromSpanContext(spanContext)); SpanData spanData = ((Span)span).ToSpanData(); Assert.Equal(timestamp, spanData.StartTimestamp); Assert.Empty(spanData.Attributes.AttributeMap); Assert.Empty(spanData.Events.Events); Assert.Empty(spanData.Links.Links); Assert.Equal(Status.Ok, spanData.Status); Assert.Equal(timestamp, spanData.EndTimestamp); }
public void GetSummary_SpansWithDifferentNames() { ISpan span1 = CreateSpan(SPAN_NAME_1); ISpan span2 = CreateSpan(SPAN_NAME_2); Assert.Equal(2, activeSpansExporter.Summary.PerSpanNameSummary.Count); Assert.Equal(1, activeSpansExporter .Summary .PerSpanNameSummary[SPAN_NAME_1] .NumRunningSpans); Assert.Equal(1, activeSpansExporter .Summary .PerSpanNameSummary[SPAN_NAME_2] .NumRunningSpans); span1.End(); Assert.Equal(1, activeSpansExporter.Summary.PerSpanNameSummary.Count); Assert.False(activeSpansExporter.Summary.PerSpanNameSummary.ContainsKey(SPAN_NAME_1)); Assert.Equal(1, activeSpansExporter .Summary .PerSpanNameSummary[SPAN_NAME_2] .NumRunningSpans); span2.End(); Assert.Equal(0, activeSpansExporter.Summary.PerSpanNameSummary.Count); }
public void GetSummary_SpansWithSameName() { ISpan span1 = CreateSpan(SPAN_NAME_1); ISpan span2 = CreateSpan(SPAN_NAME_1); ISpan span3 = CreateSpan(SPAN_NAME_1); Assert.Equal(1, activeSpansExporter.Summary.PerSpanNameSummary.Count); Assert.Equal(3, activeSpansExporter .Summary .PerSpanNameSummary[SPAN_NAME_1] .NumRunningSpans); span1.End(); Assert.Equal(1, activeSpansExporter.Summary.PerSpanNameSummary.Count); Assert.Equal(2, activeSpansExporter .Summary .PerSpanNameSummary[SPAN_NAME_1] .NumRunningSpans); span2.End(); Assert.Equal(1, activeSpansExporter.Summary.PerSpanNameSummary.Count); Assert.Equal(1, activeSpansExporter .Summary .PerSpanNameSummary[SPAN_NAME_1] .NumRunningSpans); span3.End(); Assert.Equal(0, activeSpansExporter.Summary.PerSpanNameSummary.Count); }
public void Status_ViaSetStatus() { ISpan span = Span.StartSpan( spanContext, recordSpanOptions, SPAN_NAME, parentSpanId, false, TraceParams.Default, startEndHandler, timestampConverter, testClock); testClock.AdvanceTime(Duration.Create(0, 100)); Assert.Equal(Status.Ok, span.Status); ((Span)span).Status = Status.Cancelled; Assert.Equal(Status.Cancelled, span.Status); span.End(); Assert.Equal(Status.Cancelled, span.Status); var startEndMock = Mock.Get <IStartEndHandler>(startEndHandler); var spanBase = span as SpanBase; startEndMock.Verify(s => s.OnStart(spanBase), Times.Once); }
public void status_ViaEndSpanOptions() { ISpan span = Span.StartSpan( spanContext, recordSpanOptions, SPAN_NAME, parentSpanId, false, TraceParams.Default, startEndHandler, timestampConverter); interval = TimeSpan.FromMilliseconds(100); Assert.Equal(Status.Ok, span.Status); ((Span)span).Status = Status.Cancelled; Assert.Equal(Status.Cancelled, span.Status); span.End(EndSpanOptions.Builder().SetStatus(Status.Aborted).Build()); Assert.Equal(Status.Aborted, span.Status); var startEndMock = Mock.Get <IStartEndHandler>(startEndHandler); var spanBase = span as SpanBase; startEndMock.Verify(s => s.OnStart(spanBase), Times.Once); }
public void status_ViaEndSpanOptions() { ISpan span = Span.StartSpan( spanContext, recordSpanOptions, SPAN_NAME, parentSpanId, false, TraceParams.DEFAULT, startEndHandler, timestampConverter, testClock); testClock.AdvanceTime(Duration.Create(0, 100)); Assert.Equal(Status.OK, span.Status); ((Span)span).Status = Status.CANCELLED; Assert.Equal(Status.CANCELLED, span.Status); span.End(EndSpanOptions.Builder().SetStatus(Status.ABORTED).Build()); Assert.Equal(Status.ABORTED, span.Status); var startEndMock = Mock.Get <IStartEndHandler>(startEndHandler); var spanBase = span as SpanBase; startEndMock.Verify(s => s.OnStart(spanBase), Times.Once); }
public void ErrorShouldContainTransactionData(bool isSampled, bool captureOnSpan, bool captureAsError) { var payloadSender = new MockPayloadSender(); var expectedErrorContext = new Context(); expectedErrorContext.Labels["one"] = "1"; expectedErrorContext.Labels["twenty two"] = "22"; ITransaction capturedTransaction = null; IExecutionSegment errorCapturingExecutionSegment = null; using (var agent = new ApmAgent(new TestAgentComponents(payloadSender: payloadSender))) { agent.TracerInternal.Sampler = new Sampler(isSampled ? 1 : 0); agent.Tracer.CaptureTransaction(TestTransaction, CustomTransactionTypeForTests, transaction => { capturedTransaction = transaction; foreach (var keyValue in expectedErrorContext.Labels) { transaction.Context.Labels[keyValue.Key] = keyValue.Value; } ISpan span = null; if (captureOnSpan) { span = transaction.StartSpan(TestSpan1, ApiConstants.TypeExternal); errorCapturingExecutionSegment = span; } else { errorCapturingExecutionSegment = transaction; } if (captureAsError) { errorCapturingExecutionSegment.CaptureError("Test error message", "Test error culprit", new StackTrace(true).GetFrames()); } else { errorCapturingExecutionSegment.CaptureException(new TestException("test exception")); } // Immutable snapshot of the context should be captured instead of reference to a mutable object // transaction.Context.Labels["three hundred thirty three"] = "333"; span?.End(); }); } payloadSender.Errors.Count.Should().Be(1); payloadSender.FirstError.Transaction.IsSampled.Should().Be(isSampled); payloadSender.FirstError.Transaction.Type.Should().Be(CustomTransactionTypeForTests); payloadSender.FirstError.TransactionId.Should().Be(capturedTransaction.Id); payloadSender.FirstError.TraceId.Should().Be(capturedTransaction.TraceId); payloadSender.FirstError.ParentId.Should().Be(errorCapturingExecutionSegment.Id); payloadSender.FirstError.Context.Should().BeEquivalentTo(expectedErrorContext); }
public async Task AddItemAsync(string userId, string productId, int quantity) { Log.Information("AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity}", userId, productId, quantity); var transaction = Elastic.Apm.Agent.Tracer.CurrentTransaction; ISpan span = transaction.StartSpan("AddItemAsync", ApiConstants.TypeDb, ApiConstants.ActionQuery); span.Labels["userId"] = userId; span.Labels["productId"] = productId; span.Labels["quantity"] = quantity.ToString(); try { EnsureRedisConnected(); var db = redis.GetDatabase(); // Access the cart from the cache var value = await db.HashGetAsync(userId, CART_FIELD_NAME); Hipstershop.Cart cart; if (value.IsNull) { cart = new Hipstershop.Cart(); cart.UserId = userId; cart.Items.Add(new Hipstershop.CartItem { ProductId = productId, Quantity = quantity }); } else { cart = Hipstershop.Cart.Parser.ParseFrom(value); var existingItem = cart.Items.SingleOrDefault(i => i.ProductId == productId); if (existingItem == null) { cart.Items.Add(new Hipstershop.CartItem { ProductId = productId, Quantity = quantity }); } else { existingItem.Quantity += quantity; } } await db.HashSetAsync(userId, new[] { new HashEntry(CART_FIELD_NAME, cart.ToByteArray()) }); } catch (Exception ex) { Log.Error(ex, "Can't access cart storage"); span.CaptureException(ex); throw new RpcException(new Status(StatusCode.FailedPrecondition, $"Can't access cart storage. {ex}")); } finally { span.End(); } }
public void GoSpanData_EndedSpan() { ISpan span = Span.StartSpan( spanContext, recordSpanOptions, SPAN_NAME, parentSpanId, false, TraceParams.Default, startEndHandler, timestampConverter); span.SetAttribute( "MySingleStringAttributeKey", AttributeValue.StringAttributeValue("MySingleStringAttributeValue")); span.SetAttributes(attributes); interval = TimeSpan.FromMilliseconds(100); span.AddEvent(Event.Create(EVENT_DESCRIPTION)); interval = TimeSpan.FromMilliseconds(200); span.AddEvent(EVENT_DESCRIPTION, attributes); interval = TimeSpan.FromMilliseconds(300); ILink link = Link.FromSpanContext(spanContext, LinkType.ChildLinkedSpan); span.AddLink(link); interval = TimeSpan.FromMilliseconds(400); span.End(EndSpanOptions.Builder().SetStatus(Status.Cancelled).Build()); ISpanData spanData = ((Span)span).ToSpanData(); Assert.Equal(spanContext, spanData.Context); Assert.Equal(SPAN_NAME, spanData.Name); Assert.Equal(parentSpanId, spanData.ParentSpanId); Assert.False(spanData.HasRemoteParent); Assert.Equal(0, spanData.Attributes.DroppedAttributesCount); Assert.Equal(expectedAttributes, spanData.Attributes.AttributeMap); Assert.Equal(0, spanData.Events.DroppedEventsCount); Assert.Equal(2, spanData.Events.Events.Count()); Assert.Equal(timestamp.AddDuration(Duration.Create(TimeSpan.FromMilliseconds(100))), spanData.Events.Events.ToList()[0].Timestamp); Assert.Equal(Event.Create(EVENT_DESCRIPTION), spanData.Events.Events.ToList()[0].Event); Assert.Equal(timestamp.AddDuration(Duration.Create(TimeSpan.FromMilliseconds(200))), spanData.Events.Events.ToList()[1].Timestamp); Assert.Equal(Event.Create(EVENT_DESCRIPTION, attributes), spanData.Events.Events.ToList()[1].Event); Assert.Equal(0, spanData.Links.DroppedLinksCount); Assert.Single(spanData.Links.Links); Assert.Equal(link, spanData.Links.Links.First()); Assert.Equal(timestamp, spanData.StartTimestamp); Assert.Equal(Status.Cancelled, spanData.Status); Assert.Equal(timestamp.AddDuration(Duration.Create(TimeSpan.FromMilliseconds(400))), spanData.EndTimestamp); var startEndMock = Mock.Get <IStartEndHandler>(startEndHandler); var spanBase = span as SpanBase; startEndMock.Verify(s => s.OnStart(spanBase), Times.Once); startEndMock.Verify(s => s.OnEnd(spanBase), Times.Once); }
private void AddSpanNameToAllLatencyBuckets(string spanName) { foreach (LatencyBucketBoundaries boundaries in LatencyBucketBoundaries.Values) { ISpan sampledSpan = CreateSampledSpan(spanName); ISpan notSampledSpan = CreateNotSampledSpan(spanName); interval += boundaries.LatencyLower; sampledSpan.End(); notSampledSpan.End(); } }
internal static void CaptureSpan(ISpan span, Action capturedAction) { try { capturedAction(); } catch (Exception e) when(ExceptionFilter.Capture(e, span)) { } finally { span.End(); } }
private void AddSpanNameToAllErrorBuckets(String spanName) { foreach (CanonicalCode code in Enum.GetValues(typeof(CanonicalCode)).Cast <CanonicalCode>()) { if (code != CanonicalCode.Ok) { ISpan sampledSpan = CreateSampledSpan(spanName); ISpan notSampledSpan = CreateNotSampledSpan(spanName); testClock.AdvanceTime(Duration.Create(0, 1000)); sampledSpan.End(EndSpanOptions.Builder().SetStatus(code.ToStatus()).Build()); notSampledSpan.End(EndSpanOptions.Builder().SetStatus(code.ToStatus()).Build()); } } }
private void AddSpanNameToAllErrorBuckets(String spanName) { foreach (CanonicalCode code in Enum.GetValues(typeof(CanonicalCode)).Cast <CanonicalCode>()) { if (code != CanonicalCode.Ok) { ISpan sampledSpan = CreateSampledSpan(spanName); ISpan notSampledSpan = CreateNotSampledSpan(spanName); interval += TimeSpan.FromTicks(10); sampledSpan.End(EndSpanOptions.Builder().SetStatus(code.ToStatus()).Build()); notSampledSpan.End(EndSpanOptions.Builder().SetStatus(code.ToStatus()).Build()); } } }
public void DroppingAttributes() { int maxNumberOfAttributes = 8; TraceParams traceParams = TraceParams.Default.ToBuilder().SetMaxNumberOfAttributes(maxNumberOfAttributes).Build(); ISpan span = Span.StartSpan( spanContext, recordSpanOptions, SPAN_NAME, SpanKind.Internal, parentSpanId, traceParams, startEndHandler, timestampConverter); for (int i = 0; i < 2 * maxNumberOfAttributes; i++) { IDictionary <String, IAttributeValue> attributes = new Dictionary <String, IAttributeValue>(); attributes.Add("MyStringAttributeKey" + i, AttributeValue.LongAttributeValue(i)); foreach (var attribute in attributes) { span.SetAttribute(attribute.Key, attribute.Value); } } SpanData spanData = ((Span)span).ToSpanData(); Assert.Equal(maxNumberOfAttributes, spanData.Attributes.DroppedAttributesCount); Assert.Equal(maxNumberOfAttributes, spanData.Attributes.AttributeMap.Count); for (int i = 0; i < maxNumberOfAttributes; i++) { Assert.Equal( AttributeValue.LongAttributeValue(i + maxNumberOfAttributes), spanData .Attributes .AttributeMap["MyStringAttributeKey" + (i + maxNumberOfAttributes)]); } span.End(); spanData = ((Span)span).ToSpanData(); Assert.Equal(maxNumberOfAttributes, spanData.Attributes.DroppedAttributesCount); Assert.Equal(maxNumberOfAttributes, spanData.Attributes.AttributeMap.Count); for (int i = 0; i < maxNumberOfAttributes; i++) { Assert.Equal( AttributeValue.LongAttributeValue(i + maxNumberOfAttributes), spanData .Attributes .AttributeMap["MyStringAttributeKey" + (i + maxNumberOfAttributes)]); } }
public void DroppingNetworkEvents() { int maxNumberOfNetworkEvents = 8; TraceParams traceParams = TraceParams.Default .ToBuilder() .SetMaxNumberOfMessageEvents(maxNumberOfNetworkEvents) .Build(); ISpan span = Span.StartSpan( spanContext, recordSpanOptions, SPAN_NAME, parentSpanId, false, traceParams, startEndHandler, timestampConverter, testClock); IMessageEvent networkEvent = MessageEvent.Builder(MessageEventType.Received, 1).SetUncompressedMessageSize(3).Build(); for (int i = 0; i < 2 * maxNumberOfNetworkEvents; i++) { span.AddMessageEvent(networkEvent); testClock.AdvanceTime(Duration.Create(0, 100)); } ISpanData spanData = ((Span)span).ToSpanData(); Assert.Equal(maxNumberOfNetworkEvents, spanData.MessageEvents.DroppedEventsCount); Assert.Equal(maxNumberOfNetworkEvents, spanData.MessageEvents.Events.Count()); var list = spanData.MessageEvents.Events.ToList(); for (int i = 0; i < maxNumberOfNetworkEvents; i++) { Assert.Equal(timestamp.AddNanos(100 * (maxNumberOfNetworkEvents + i)), list[i].Timestamp); Assert.Equal(networkEvent, list[i].Event); } span.End(); spanData = ((Span)span).ToSpanData(); Assert.Equal(maxNumberOfNetworkEvents, spanData.MessageEvents.DroppedEventsCount); Assert.Equal(maxNumberOfNetworkEvents, spanData.MessageEvents.Events.Count()); list = spanData.MessageEvents.Events.ToList(); for (int i = 0; i < maxNumberOfNetworkEvents; i++) { Assert.Equal(timestamp.AddNanos(100 * (maxNumberOfNetworkEvents + i)), list[i].Timestamp); Assert.Equal(networkEvent, list[i].Event); } }
public void Dispose() { if (span == null) { return; } if (timer?.IsRunning == true) { timer.Stop(); span.Duration = timer.ElapsedMilliseconds; } span.End(); }
public void DroppingAttributes() { int maxNumberOfAttributes = 8; TraceParams traceParams = TraceParams.DEFAULT.ToBuilder().SetMaxNumberOfAttributes(maxNumberOfAttributes).Build(); ISpan span = Span.StartSpan( spanContext, recordSpanOptions, SPAN_NAME, parentSpanId, false, traceParams, startEndHandler, timestampConverter, testClock); for (int i = 0; i < 2 * maxNumberOfAttributes; i++) { IDictionary <string, IAttributeValue> attributes = new Dictionary <string, IAttributeValue> { { "MyStringAttributeKey" + i, AttributeValue.LongAttributeValue(i) } }; span.PutAttributes(attributes); } ISpanData spanData = ((Span)span).ToSpanData(); Assert.Equal(maxNumberOfAttributes, spanData.Attributes.DroppedAttributesCount); Assert.Equal(maxNumberOfAttributes, spanData.Attributes.AttributeMap.Count); for (int i = 0; i < maxNumberOfAttributes; i++) { Assert.Equal( AttributeValue.LongAttributeValue(i + maxNumberOfAttributes), spanData.Attributes.AttributeMap["MyStringAttributeKey" + (i + maxNumberOfAttributes)]); } span.End(); spanData = ((Span)span).ToSpanData(); Assert.Equal(maxNumberOfAttributes, spanData.Attributes.DroppedAttributesCount); Assert.Equal(maxNumberOfAttributes, spanData.Attributes.AttributeMap.Count); for (int i = 0; i < maxNumberOfAttributes; i++) { Assert.Equal( AttributeValue.LongAttributeValue(i + maxNumberOfAttributes), spanData.Attributes.AttributeMap["MyStringAttributeKey" + (i + maxNumberOfAttributes)]); } }
private Span CreateNotSampledEndedSpan(string spanName) { ISpan span = Span.StartSpan( notSampledSpanContext, recordSpanOptions, spanName, SpanKind.Internal, null, TraceParams.Default, startEndHandler, null); span.End(); return(span as Span); }
public void Dispose() { var current = AsyncLocalContext.CurrentSpan; AsyncLocalContext.CurrentSpan = origContext; if (current != origContext) { // Log } if (endSpan) { span.End(); } }
private Span CreateNotSampledEndedSpan(string spanName) { ISpan span = Span.StartSpan( notSampledSpanContext, recordSpanOptions, spanName, null, false, TraceParams.DEFAULT, startEndHandler, null, DateTimeOffsetClock.INSTANCE); span.End(); return span as Span; }
#pragma warning disable SA1202 // Elements must be ordered by access public void GetSummary_SpansWithDifferentNames() #pragma warning restore SA1202 // Elements must be ordered by access { ISpan span1 = CreateSpan(SPAN_NAME_1); ISpan span2 = CreateSpan(SPAN_NAME_2); Assert.Equal(2, activeSpansExporter.Summary.PerSpanNameSummary.Count); Assert.Equal(1, activeSpansExporter.Summary.PerSpanNameSummary[SPAN_NAME_1].NumRunningSpans); Assert.Equal(1, activeSpansExporter.Summary.PerSpanNameSummary[SPAN_NAME_2].NumRunningSpans); span1.End(); Assert.Equal(1, activeSpansExporter.Summary.PerSpanNameSummary.Count); Assert.False(activeSpansExporter.Summary.PerSpanNameSummary.ContainsKey(SPAN_NAME_1)); Assert.Equal(1, activeSpansExporter.Summary.PerSpanNameSummary[SPAN_NAME_2].NumRunningSpans); span2.End(); Assert.Equal(0, activeSpansExporter.Summary.PerSpanNameSummary.Count); }
public void ErrorShouldContainTransactionData(bool isSampled, bool captureOnSpan, bool captureAsError) { var payloadSender = new MockPayloadSender(); var expectedErrorContext = new Context(); expectedErrorContext.Labels["one"] = "1"; expectedErrorContext.Labels["twenty two"] = "22"; ITransaction capturedTransaction = null; IExecutionSegment errorCapturingExecutionSegment = null; var mockConfig = new MockConfigSnapshot(transactionSampleRate: isSampled ? "1" : "0"); using (var agent = new ApmAgent(new TestAgentComponents(config: mockConfig, payloadSender: payloadSender))) { agent.Tracer.CaptureTransaction(TestTransaction, CustomTransactionTypeForTests, transaction => { capturedTransaction = transaction; foreach (var(key, value) in expectedErrorContext.Labels) { transaction.Context.Labels[key] = value; } ISpan span = null; if (captureOnSpan) { span = transaction.StartSpan(TestSpan1, ApiConstants.TypeExternal); errorCapturingExecutionSegment = span; } else { errorCapturingExecutionSegment = transaction; } if (captureAsError) { errorCapturingExecutionSegment.CaptureError("Test error message", "Test error culprit", new StackTrace(true).GetFrames()); } else { errorCapturingExecutionSegment.CaptureException(new TestException("test exception")); } // Immutable snapshot of the context should be captured instead of reference to a mutable object // transaction.Context.Labels["three hundred thirty three"] = "333"; span?.End(); });
public void DroppingAnnotations() { int maxNumberOfAnnotations = 8; TraceParams traceParams = TraceParams.Default.ToBuilder().SetMaxNumberOfAnnotations(maxNumberOfAnnotations).Build(); ISpan span = Span.StartSpan( spanContext, recordSpanOptions, SPAN_NAME, parentSpanId, false, traceParams, startEndHandler, timestampConverter, testClock); IAnnotation annotation = Annotation.FromDescription(ANNOTATION_DESCRIPTION); int i = 0; for (i = 0; i < 2 * maxNumberOfAnnotations; i++) { span.AddAnnotation(annotation); testClock.AdvanceTime(Duration.Create(0, 100)); } ISpanData spanData = ((Span)span).ToSpanData(); Assert.Equal(maxNumberOfAnnotations, spanData.Annotations.DroppedEventsCount); Assert.Equal(maxNumberOfAnnotations, spanData.Annotations.Events.Count()); i = 0; foreach (var te in spanData.Annotations.Events) { Assert.Equal(timestamp.AddNanos(100 * (maxNumberOfAnnotations + i)), te.Timestamp); Assert.Equal(annotation, te.Event); i++; } span.End(); spanData = ((Span)span).ToSpanData(); Assert.Equal(maxNumberOfAnnotations, spanData.Annotations.DroppedEventsCount); Assert.Equal(maxNumberOfAnnotations, spanData.Annotations.Events.Count()); i = 0; foreach (var te in spanData.Annotations.Events) { Assert.Equal(timestamp.AddNanos(100 * (maxNumberOfAnnotations + i)), te.Timestamp); Assert.Equal(annotation, te.Event); i++; } }
public void DroppingEvents() { int maxNumberOfEvents = 8; TraceParams traceParams = TraceParams.Default.ToBuilder().SetMaxNumberOfEvents(maxNumberOfEvents).Build(); ISpan span = Span.StartSpan( spanContext, recordSpanOptions, SPAN_NAME, SpanKind.Internal, parentSpanId, traceParams, startEndHandler, timestampConverter); IEvent testEvent = Event.Create(EVENT_DESCRIPTION); int i = 0; for (i = 0; i < 2 * maxNumberOfEvents; i++) { span.AddEvent(testEvent); interval += TimeSpan.FromMilliseconds(100); } SpanData spanData = ((Span)span).ToSpanData(); Assert.Equal(maxNumberOfEvents, spanData.Events.DroppedEventsCount); Assert.Equal(maxNumberOfEvents, spanData.Events.Events.Count()); i = 0; foreach (var te in spanData.Events.Events) { Assert.Equal(timestamp.AddDuration(Duration.Create(TimeSpan.FromMilliseconds(100 * (maxNumberOfEvents + i)))), te.Timestamp); Assert.Equal(testEvent, te.Event); i++; } span.End(); spanData = ((Span)span).ToSpanData(); Assert.Equal(maxNumberOfEvents, spanData.Events.DroppedEventsCount); Assert.Equal(maxNumberOfEvents, spanData.Events.Events.Count()); i = 0; foreach (var te in spanData.Events.Events) { Assert.Equal(timestamp.AddDuration(Duration.Create(TimeSpan.FromMilliseconds(100 * (maxNumberOfEvents + i)))), te.Timestamp); Assert.Equal(testEvent, te.Event); i++; } }