public void Trace_Simple_Buffer() { string rootSpanName = EntryData.GetMessage(nameof(Trace_Simple_Buffer), _testId); // Create annotations with very large labels to ensure the buffer is flushed. string label = string.Join("", Enumerable.Repeat("1234567890", 1000)); var labels = new Dictionary <string, string> { { "key-one", label }, { "key-two", label }, { "key-three", label }, { "key-four", label }, { "key-five", label }, }; using (var consumer = SizedBufferingConsumer <TraceProto> .Create(_grpcConsumer, MessageSizer <TraceProto> .GetSize, BufferOptions.DefaultBufferSize / 2)) { var tracer = CreateSimpleManagedTracer(consumer); using (tracer.StartSpan(rootSpanName)) { BlockUntilClockTick(); tracer.AnnotateSpan(labels); } } TraceProto trace = TraceEntryPolling.Default.GetTrace(rootSpanName, _startTime); TraceEntryVerifiers.AssertSingleSpan(trace, rootSpanName); }
private void Flush() { var old = _trace; _trace = CreateTraceProto(); _consumer.Receive(new[] { old }); }
/// <summary> /// Gets a trace that contains a span with the given name. /// </summary> /// <param name="expectTrace">True if the trace is expected to exist. This is used /// to minimize RPC calls.</param> private async Task <TraceProto> GetTrace(string spanName, bool expectTrace = true) { TimeSpan totalSleepTime = TimeSpan.Zero; while (totalSleepTime <= _timeout) { TimeSpan sleepTime = expectTrace ? _sleepInterval : _timeout; totalSleepTime += sleepTime; Thread.Sleep(sleepTime); ListTracesRequest request = new ListTracesRequest { ProjectId = _projectId, StartTime = _startTime, View = ListTracesRequest.Types.ViewType.Complete }; var traces = _client.ListTracesAsync(request); TraceProto trace = await traces.FirstOrDefault(t => t.Spans.Any(s => s.Name.Equals(spanName))); if (trace != null) { return(trace); } } return(null); }
public void Trace_Simple_Buffer() { string rootSpanName = CreateRootSpanName(nameof(Trace_Simple_Buffer)); var consumer = SizedBufferingConsumer <TraceProto> .Create( CreateGrpcTraceConsumer(), MessageSizer <TraceProto> .GetSize, BufferOptions.DefaultBufferSize / 2); var tracer = CreateSimpleManagedTracer(consumer); // Create annotations with very large labels to ensure the buffer is flushed. string label = string.Join("", Enumerable.Repeat("1234567890", 1000)); var annotation = new Dictionary <string, string> { { "key-one", label }, { "key-two", label }, { "key-three", label }, { "key-four", label }, { "key-five", label }, }; using (tracer.StartSpan(rootSpanName)) { BlockUntilClockTick(); tracer.AnnotateSpan(annotation); } TraceProto trace = _polling.GetTrace(rootSpanName, _startTime); Assert.NotNull(trace); Assert.Single(trace.Spans); }
/// <summary> /// Checks a trace for the following: /// <list type="bullet"> /// <term>The trace is not null.</term> /// <term>The trace has one span.</term> /// <term>The span name is spanName</term> /// </list> /// </summary> /// <param name="trace">The trace to check.</param> /// <param name="spanName">The expected name of the span.</param> public static void AssertSingleSpan(TraceProto trace, string spanName) { Assert.NotNull(trace); var span = trace.Spans.Single(); Assert.Equal(spanName, span.Name); }
private void BeginRequest(object sender, EventArgs e) { TraceHeaderContext headerContext = TraceHeaderContext.FromRequest(HttpContext.Current.Request); TraceOptions headerOptions = _headerFactory.CreateOptions(headerContext); // If the trace header says to trace or if the rate limiter allows tracing continue. if (!headerOptions.ShouldTrace) { TraceOptions options = _rateFactory.CreateOptions(); if (!options.ShouldTrace) { return; } } // Create and set the tracer for the request. TraceProto trace = new TraceProto { ProjectId = _projectId, TraceId = headerContext.TraceId ?? _traceIdfactory.NextId(), }; IManagedTracer tracer = SimpleManagedTracer.Create(_consumer, trace, headerContext.SpanId); TracerManager.SetCurrentTracer(tracer); // Start the span and annotate it with information from the current request. tracer.StartSpan(HttpContext.Current.Request.Path); tracer.AnnotateSpan(Labels.FromHttpRequest(HttpContext.Current.Request)); }
private SimpleManagedTracer(IConsumer <TraceProto> consumer, TraceProto trace, ulong?rootSpanParentId = null) { _consumer = GaxPreconditions.CheckNotNull(consumer, nameof(consumer)); _trace = GaxPreconditions.CheckNotNull(trace, nameof(trace)); _traceStack = new Stack <TraceSpan>(); _spanIdFactory = SpanIdFactory.Create(); _rootSpanParentId = rootSpanParentId; }
private SimpleManagedTracer(IConsumer <TraceProto> consumer, string projectId, string traceId, ulong?rootSpanParentId = null) { _consumer = GaxPreconditions.CheckNotNull(consumer, nameof(consumer)); _traceId = GaxPreconditions.CheckNotNull(traceId, nameof(traceId)); _projectId = GaxPreconditions.CheckNotNull(projectId, nameof(projectId)); _trace = CreateTraceProto(); _spanIdFactory = SpanIdFactory.Create(); _rootSpanParentId = rootSpanParentId; }
public void Trace_MultipleSpans() { string rootSpanName = EntryData.GetMessage(nameof(Trace_MultipleSpans), _testId); var labels = new Dictionary <string, string> { { "annotation-key", "annotation-value" } }; var tracer = CreateSimpleManagedTracer(_grpcConsumer); using (tracer.StartSpan(rootSpanName)) { BlockUntilClockTick(); using (tracer.StartSpan("child-one")) { tracer.SetStackTrace(TraceEntryData.CreateStackTrace()); BlockUntilClockTick(); } using (tracer.StartSpan("child-two")) { BlockUntilClockTick(); using (tracer.StartSpan("grandchild-one", StartSpanOptions.Create(SpanKind.RpcClient))) { BlockUntilClockTick(); } using (tracer.StartSpan("grandchild-two")) { BlockUntilClockTick(); tracer.AnnotateSpan(labels); } } } TraceProto trace = TraceEntryPolling.Default.GetTrace(rootSpanName, _startTime); Assert.NotNull(trace); Assert.Equal(5, trace.Spans.Count); TraceSpan root = trace.Spans.First(s => s.Name.Equals(rootSpanName)); TraceSpan childOne = trace.Spans.First(s => s.Name.Equals("child-one")); TraceSpan childTwo = trace.Spans.First(s => s.Name.Equals("child-two")); TraceSpan grandchildOne = trace.Spans.First(s => s.Name.Equals("grandchild-one")); TraceSpan grandchildTwo = trace.Spans.First(s => s.Name.Equals("grandchild-two")); Assert.Equal(root.SpanId, childOne.ParentSpanId); TraceEntryVerifiers.AssertContainsStackTrace(childOne, nameof(TraceEntryData.CreateStackTrace), nameof(SimpleManagedTracerTest)); Assert.Equal(root.SpanId, childTwo.ParentSpanId); Assert.Equal(childTwo.SpanId, grandchildOne.ParentSpanId); Assert.Equal(TraceSpan.Types.SpanKind.RpcClient, grandchildOne.Kind); Assert.Equal(childTwo.SpanId, grandchildTwo.ParentSpanId); Assert.Equal(TraceSpan.Types.SpanKind.Unspecified, grandchildTwo.Kind); TraceEntryVerifiers.AssertSpanLabelsExact(grandchildTwo, labels); }
public void Trace_MultipleSpans() { string rootSpanName = CreateRootSpanName(nameof(Trace_MultipleSpans)); var consumer = CreateGrpcTraceConsumer(); var tracer = CreateSimpleManagedTracer(consumer); var annotation = new Dictionary <string, string> { { "annotation-key", "annotation-value" } }; tracer.StartSpan(rootSpanName); BlockUntilClockTick(); tracer.StartSpan("child-one"); tracer.SetStackTrace(new StackTrace(CreateException(), true)); BlockUntilClockTick(); tracer.EndSpan(); tracer.StartSpan("child-two"); BlockUntilClockTick(); tracer.StartSpan("grandchild-one", StartSpanOptions.Create(SpanKind.RpcClient)); BlockUntilClockTick(); tracer.EndSpan(); tracer.StartSpan("grandchild-two"); BlockUntilClockTick(); tracer.AnnotateSpan(annotation); tracer.EndSpan(); tracer.EndSpan(); tracer.EndSpan(); TraceProto trace = _polling.GetTrace(rootSpanName, _startTime); Assert.NotNull(trace); Assert.Equal(5, trace.Spans.Count); TraceSpan root = trace.Spans.First(s => s.Name.Equals(rootSpanName)); TraceSpan childOne = trace.Spans.First(s => s.Name.Equals("child-one")); TraceSpan childTwo = trace.Spans.First(s => s.Name.Equals("child-two")); TraceSpan grandchildOne = trace.Spans.First(s => s.Name.Equals("grandchild-one")); TraceSpan grandchildTwo = trace.Spans.First(s => s.Name.Equals("grandchild-two")); Assert.Equal(root.SpanId, childOne.ParentSpanId); var labels = childOne.Labels; Assert.True(labels.ContainsKey(TraceLabels.StackTrace)); Assert.Contains(nameof(CreateException), labels[TraceLabels.StackTrace]); Assert.Contains(nameof(SimpleManagedTracerTest), labels[TraceLabels.StackTrace]); Assert.Equal(root.SpanId, childTwo.ParentSpanId); Assert.Equal(childTwo.SpanId, grandchildOne.ParentSpanId); Assert.Equal(TraceSpan.Types.SpanKind.RpcClient, grandchildOne.Kind); Assert.Equal(childTwo.SpanId, grandchildTwo.ParentSpanId); Assert.Equal(TraceSpan.Types.SpanKind.Unspecified, grandchildTwo.Kind); Assert.True(TraceUtils.IsValidAnnotation(grandchildTwo, annotation)); }
private SimpleManagedTracer CreateSimpleManagedTracer(IConsumer <TraceProto> consumer) { TraceProto trace = new TraceProto { ProjectId = _projectId, TraceId = _traceIdFactory.NextId() }; return(SimpleManagedTracer.Create(consumer, trace, null)); }
/// <summary> /// Creates a <see cref="SimpleManagedTracer"/> with a <see cref="GrpcTraceConsumer"/>. /// </summary> private SimpleManagedTracer CreateTracer() { string traceId = _traceIdFactory.NextId(); var traceProto = new TraceProto { ProjectId = _projectId, TraceId = traceId }; var consumer = new GrpcTraceConsumer(TraceServiceClient.CreateAsync()); return(SimpleManagedTracer.Create(consumer, traceProto, null)); }
/// <summary> /// Checks a trace for the following: /// <list type="bullet"> /// <term>The trace is not null.</term> /// <term>The trace has two spans.</term> /// <term>The trace has a root span with name rootSpanName</term> /// <term>The root span has a single child span with name childSpanName</term> /// </list> /// </summary> /// <param name="trace">The trace to check.</param> /// <param name="rootSpanName">The name of the root span.</param> /// <param name="childSpanName">The name of the child span.</param> private void CheckTrace(TraceProto trace, string rootSpanName, string childSpanName) { Assert.NotNull(trace); var spans = trace.Spans; Assert.Equal(2, spans.Count); var mainSpan = spans.Single(s => s.Name == rootSpanName); var innerSpan = spans.Single(s => s.Name != rootSpanName); Assert.Equal(childSpanName, innerSpan.Name); Assert.Equal(mainSpan.SpanId, innerSpan.ParentSpanId); }
public void Trace_Simple() { string rootSpanName = EntryData.GetMessage(nameof(Trace_Simple), _testId); using (CreateSimpleManagedTracer(_grpcConsumer).StartSpan(rootSpanName)) { BlockUntilClockTick(); } TraceProto trace = TraceEntryPolling.Default.GetTrace(rootSpanName, _startTime); TraceEntryVerifiers.AssertSingleSpan(trace, rootSpanName); }
public void Trace_Simple() { string rootSpanName = CreateRootSpanName(nameof(Trace_Simple)); var consumer = CreateGrpcTraceConsumer(); var tracer = CreateSimpleManagedTracer(consumer); tracer.StartSpan(rootSpanName); BlockUntilClockTick(); tracer.EndSpan(); TraceProto trace = _polling.GetTrace(rootSpanName, _startTime); Assert.NotNull(trace); Assert.Single(trace.Spans); }
public void Trace_Simple_BufferNoTrace() { string rootSpanName = CreateRootSpanName(nameof(Trace_Simple_BufferNoTrace)); var consumer = SizedBufferingConsumer <TraceProto> .Create( CreateGrpcTraceConsumer(), MessageSizer <TraceProto> .GetSize, BufferOptions.DefaultBufferSize); var tracer = CreateSimpleManagedTracer(consumer); tracer.StartSpan(rootSpanName); BlockUntilClockTick(); tracer.EndSpan(); TraceProto trace = _polling.GetTrace(rootSpanName, _startTime, false); Assert.Null(trace); }
public async Task Trace_Simple_BufferNoTrace() { string rootSpanName = CreateRootSpanName(nameof(Trace_Simple_BufferNoTrace)); var consumer = SizedBufferingConsumer <TraceProto> .Create( CreateGrpcTraceConsumer(), TraceSizer.Instance, BufferOptions.DefaultBufferSize); var tracer = CreateSimpleManagedTracer(consumer); tracer.StartSpan(rootSpanName); BlockUntilClockTick(); tracer.EndSpan(); TraceProto trace = await GetTrace(rootSpanName, false); Assert.Null(trace); }
public void Trace_SimpleStacktrace() { string rootSpanName = EntryData.GetMessage(nameof(Trace_SimpleStacktrace), _testId); var tracer = CreateSimpleManagedTracer(_grpcConsumer); using (tracer.StartSpan(rootSpanName)) { BlockUntilClockTick(); tracer.SetStackTrace(TraceEntryData.CreateStackTrace()); } TraceProto trace = TraceEntryPolling.Default.GetTrace(rootSpanName, _startTime); TraceEntryVerifiers.AssertSingleSpan(trace, rootSpanName); TraceEntryVerifiers.AssertContainsStackTrace(trace.Spans[0], nameof(TraceEntryData.CreateStackTrace), nameof(SimpleManagedTracerTest)); }
public void Trace_IncompleteSpans() { string rootSpanName = CreateRootSpanName(nameof(Trace_IncompleteSpans)); var consumer = CreateGrpcTraceConsumer(); var tracer = CreateSimpleManagedTracer(consumer); tracer.StartSpan(rootSpanName); tracer.StartSpan("span-name-1"); BlockUntilClockTick(); tracer.StartSpan("span-name-2"); BlockUntilClockTick(); tracer.EndSpan(); tracer.EndSpan(); TraceProto trace = _polling.GetTrace(rootSpanName, _startTime, false); Assert.Null(trace); }
public void Trace_Simple_BufferNoTrace() { string rootSpanName = EntryData.GetMessage(nameof(Trace_Simple_BufferNoTrace), _testId); using (var consumer = SizedBufferingConsumer <TraceProto> .Create(_grpcConsumer, MessageSizer <TraceProto> .GetSize, BufferOptions.DefaultBufferSize)) { using (CreateSimpleManagedTracer(consumer).StartSpan(rootSpanName)) { BlockUntilClockTick(); } // Verifying before disposing of the consumer so as to check that the buffer // wasn't flush because of the size of the messages. If we verify after disposing // any message, big or small, would have been flushed on disposing. TraceProto trace = TraceEntryPolling.NoEntry.GetTrace(rootSpanName, _startTime, false); Assert.Null(trace); } }
public void Trace_IncompleteSpans() { string rootSpanName = EntryData.GetMessage(nameof(Trace_IncompleteSpans), _testId); var tracer = CreateSimpleManagedTracer(_grpcConsumer); tracer.StartSpan(rootSpanName); using (tracer.StartSpan("span-name-1")) { BlockUntilClockTick(); using (tracer.StartSpan("span-name-2")) { BlockUntilClockTick(); } } TraceProto trace = TraceEntryPolling.NoEntry.GetTrace(rootSpanName, _startTime, false); Assert.Null(trace); }
/// <summary> /// Checks a trace for the following: /// <list type="bullet"> /// <term>The trace is not null.</term> /// <term>The trace has <code>2 + <paramref name="subsequentDescendants"/>.Length</code> spans.</term> /// <term>The trace has a root span with name rootSpanName</term> /// <term>The root span has a single child span with name childSpanName</term> /// <term>Subsequent descendants are present (in depth, not width) in the same order as they are present on <paramref name="subsequentDescendants"/>.</term> /// </list> /// </summary> /// <param name="trace">The trace to check.</param> /// <param name="rootSpanName">The name of the root span.</param> /// <param name="childSpanName">The name of the child span.</param> /// <param name="subsequentDescendants">The names of extra descendtans of child span.</param> public static void AssertParentChildSpan(TraceProto trace, string rootSpanName, string childSpanName, params string[] subsequentDescendants) { Assert.NotNull(trace); var spans = trace.Spans; Assert.Equal(2 + subsequentDescendants?.Length ?? 0, spans.Count); var mainSpan = spans.Single(s => s.Name == rootSpanName); var innerSpan = spans.Single(s => s.Name == childSpanName); Assert.Equal(mainSpan.SpanId, innerSpan.ParentSpanId); if (subsequentDescendants != null) { mainSpan = innerSpan; foreach (string spanName in subsequentDescendants) { innerSpan = spans.Single(s => s.Name == spanName); Assert.Equal(mainSpan.SpanId, innerSpan.ParentSpanId); mainSpan = innerSpan; } } }
public async Task Trace_SimpleStacktrace() { string rootSpanName = CreateRootSpanName(nameof(Trace_SimpleStacktrace)); var consumer = CreateGrpcTraceConsumer(); var tracer = CreateSimpleManagedTracer(consumer); tracer.StartSpan(rootSpanName); BlockUntilClockTick(); tracer.SetStackTrace(new StackTrace(true)); tracer.EndSpan(); TraceProto trace = await GetTrace(rootSpanName); Assert.NotNull(trace); Assert.Single(trace.Spans); var labels = trace.Spans[0].Labels; Assert.True(labels.ContainsKey(Labels.StackTrace)); Assert.Contains(nameof(Trace_SimpleStacktrace), labels[Labels.StackTrace]); Assert.Contains(nameof(TraceTest), labels[Labels.StackTrace]); }
public void Trace_SimpleStacktrace() { string rootSpanName = CreateRootSpanName(nameof(Trace_SimpleStacktrace)); var consumer = CreateGrpcTraceConsumer(); var tracer = CreateSimpleManagedTracer(consumer); tracer.StartSpan(rootSpanName); BlockUntilClockTick(); tracer.SetStackTrace(new StackTrace(CreateException(), true)); tracer.EndSpan(); TraceProto trace = _polling.GetTrace(rootSpanName, _startTime); Assert.NotNull(trace); Assert.Single(trace.Spans); var labels = trace.Spans[0].Labels; Assert.True(labels.ContainsKey(TraceLabels.StackTrace)); Assert.Contains(nameof(CreateException), labels[TraceLabels.StackTrace]); Assert.Contains(nameof(SimpleManagedTracerTest), labels[TraceLabels.StackTrace]); }
public void Trace_SimpleAnnotation() { string rootSpanName = EntryData.GetMessage(nameof(Trace_SimpleAnnotation), _testId); var labels = new Dictionary <string, string> { { "annotation-key", "annotation-value" }, { "some-key", "some-value" } }; var tracer = CreateSimpleManagedTracer(_grpcConsumer); using (tracer.StartSpan(rootSpanName)) { BlockUntilClockTick(); tracer.AnnotateSpan(labels); } TraceProto trace = TraceEntryPolling.Default.GetTrace(rootSpanName, _startTime); TraceEntryVerifiers.AssertSingleSpan(trace, rootSpanName); TraceEntryVerifiers.AssertSpanLabelsExact(trace.Spans.First(), labels); }
public void Trace_SimpleAnnotation() { string rootSpanName = CreateRootSpanName(nameof(Trace_SimpleAnnotation)); var consumer = CreateGrpcTraceConsumer(); var tracer = CreateSimpleManagedTracer(consumer); var annotation = new Dictionary <string, string> { { "annotation-key", "annotation-value" }, { "some-key", "some-value" } }; tracer.StartSpan(rootSpanName); BlockUntilClockTick(); tracer.AnnotateSpan(annotation); tracer.EndSpan(); TraceProto trace = _polling.GetTrace(rootSpanName, _startTime); Assert.NotNull(trace); Assert.Single(trace.Spans); Assert.True(TraceUtils.IsValidAnnotation(trace.Spans[0], annotation)); }
/// <summary> /// Creates a <see cref="SimpleManagedTracer"/>> /// </summary> /// <param name="consumer">The consumer to push finished traces to.</param> /// <param name="trace">The current trace.</param> /// <param name="rootSpanParentId">Optional, the parent span id of the root span of the passed in trace.</param> public static SimpleManagedTracer Create(IConsumer <TraceProto> consumer, TraceProto trace, ulong?rootSpanParentId = null) => new SimpleManagedTracer(consumer, trace, rootSpanParentId);