|
1 | 1 | namespace Samples |
2 | 2 | { |
3 | 3 | using System; |
| 4 | + using System.Collections.Generic; |
4 | 5 | using System.Threading; |
5 | 6 | using OpenCensus.Exporter.Zipkin; |
6 | 7 | using OpenCensus.Trace; |
| 8 | + using OpenCensus.Trace.Config; |
7 | 9 | using OpenCensus.Trace.Sampler; |
8 | 10 |
|
9 | 11 | internal class TestZipkin |
10 | 12 | { |
11 | | - private static ITracer tracer = Tracing.Tracer; |
12 | | - |
13 | | - internal static object Run() |
| 13 | + internal static object Run(string zipkinUri) |
14 | 14 | { |
15 | | - Console.WriteLine("Hello World!"); |
16 | | - |
| 15 | + // 1. Configure exporter to export traces to Zipkin |
17 | 16 | var exporter = new ZipkinTraceExporter( |
18 | 17 | new ZipkinTraceExporterOptions() |
19 | 18 | { |
20 | | - Endpoint = new Uri("https://zipkin.azurewebsites.net/api/v2/spans"), |
21 | | - ServiceName = typeof(Program).Assembly.GetName().Name, |
| 19 | + Endpoint = new Uri(zipkinUri), |
| 20 | + ServiceName = "tracing-to-zipkin-service", |
22 | 21 | }, |
23 | 22 | Tracing.ExportComponent); |
24 | 23 | exporter.Start(); |
25 | 24 |
|
26 | | - var span = tracer.SpanBuilder("incoming request").SetSampler(Samplers.AlwaysSample).StartScopedSpan(); |
| 25 | + // 2. Configure 100% sample rate for the purposes of the demo |
| 26 | + ITraceConfig traceConfig = Tracing.TraceConfig; |
| 27 | + ITraceParams currentConfig = traceConfig.ActiveTraceParams; |
| 28 | + var newConfig = currentConfig.ToBuilder() |
| 29 | + .SetSampler(Samplers.AlwaysSample) |
| 30 | + .Build(); |
| 31 | + traceConfig.UpdateActiveTraceParams(newConfig); |
| 32 | + |
| 33 | + // 3. Tracer is global singleton. You can register it via dependency injection if it exists |
| 34 | + // but if not - you can use it as follows: |
| 35 | + var tracer = Tracing.Tracer; |
27 | 36 |
|
28 | | - Thread.Sleep(TimeSpan.FromSeconds(1)); |
29 | | - var span2 = tracer.CurrentSpan; |
30 | | - span2.End(); |
| 37 | + // 4. Create a scoped span. It will end automatically when using statement ends |
| 38 | + using (var scope = tracer.SpanBuilder("Main").StartScopedSpan()) |
| 39 | + { |
| 40 | + Console.WriteLine("About to do a busy work"); |
| 41 | + for (int i = 0; i < 10; i++) |
| 42 | + { |
| 43 | + DoWork(i); |
| 44 | + } |
| 45 | + } |
31 | 46 |
|
32 | | - Console.ReadLine(); |
| 47 | + // 5. Gracefully shutdown the exporter so it'll flush queued traces to Zipkin. |
| 48 | + Tracing.ExportComponent.SpanExporter.Dispose(); |
33 | 49 |
|
34 | 50 | return null; |
35 | 51 | } |
| 52 | + |
| 53 | + private static void DoWork(int i) |
| 54 | + { |
| 55 | + // 6. Get the global singleton Tracer object |
| 56 | + ITracer tracer = Tracing.Tracer; |
| 57 | + |
| 58 | + // 7. Start another span. If another span was already started, it'll use that span as the parent span. |
| 59 | + // In this example, the main method already started a span, so that'll be the parent span, and this will be |
| 60 | + // a child span. |
| 61 | + using (OpenCensus.Common.IScope scope = tracer.SpanBuilder("DoWork").StartScopedSpan()) |
| 62 | + { |
| 63 | + // Simulate some work. |
| 64 | + ISpan span = tracer.CurrentSpan; |
| 65 | + |
| 66 | + try |
| 67 | + { |
| 68 | + Console.WriteLine("Doing busy work"); |
| 69 | + Thread.Sleep(1000); |
| 70 | + } |
| 71 | + catch (ArgumentOutOfRangeException e) |
| 72 | + { |
| 73 | + // 6. Set status upon error |
| 74 | + span.Status = Status.Internal.WithDescription(e.ToString()); |
| 75 | + } |
| 76 | + |
| 77 | + // 7. Annotate our span to capture metadata about our operation |
| 78 | + var attributes = new Dictionary<string, IAttributeValue>(); |
| 79 | + attributes.Add("use", AttributeValue.StringAttributeValue("demo")); |
| 80 | + span.AddAnnotation("Invoking DoWork", attributes); |
| 81 | + } |
| 82 | + } |
36 | 83 | } |
37 | 84 | } |
0 commit comments