Open Tracing instrumentation for running process
Open tracing allows you to trace calls between (micro)services . It has also calls for HTTP and Sql. For a ASP.NET Core application the code is at follows ( for exporting at Jaeger, for example):
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | services.AddOpenTelemetryTracing(b => { string nameAssemblyEntry = Assembly.GetEntryAssembly().GetName().Name; var rb = ResourceBuilder.CreateDefault(); rb.AddService(nameAssemblyEntry); var data = new Dictionary< string , object >() { { "PC" , Environment.MachineName } }; data.Add( "Exe" , nameAssemblyEntry); rb.AddAttributes(data); _ = b .AddAspNetCoreInstrumentation() .AddHttpClientInstrumentation() .AddSqlClientInstrumentation() .AddSource( "MySource" ) .SetResourceBuilder(rb) .AddJaegerExporter(c => { var s = Configuration.GetSection( "Jaeger" ); s.Bind(c); }); }) ; |
This code was made with
<PackageReference Include=”OpenTelemetry” Version=”1.1.0-beta1″ />
<PackageReference Include=”OpenTelemetry.Instrumentation.AspNetCore” Version=”1.0.0-rc3″ />
<PackageReference Include=”OpenTelemetry.Exporter.Jaeger” Version=”1.1.0-beta1″ />
<PackageReference Include=”OpenTelemetry.Extensions.Hosting” Version=”1.0.0-rc3″ />
<PackageReference Include=”OpenTelemetry.Instrumentation.Http” Version=”1.0.0-rc3″ />
<PackageReference Include=”OpenTelemetry.Instrumentation.SqlClient” Version=”1.0.0-rc3″ />
For a .NET Core console, the code is :
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 | string nameAssemblyEntry = Assembly.GetEntryAssembly().GetName().Name; var rb = ResourceBuilder.CreateDefault(); rb.AddService(nameAssemblyEntry); var data = new Dictionary< string , object >() { { "PC" , Environment.MachineName } }; data.Add( "Exe" , nameAssemblyEntry); rb.AddAttributes(data); openTelemetry = Sdk.CreateTracerProviderBuilder() .AddSource( "MySource" ) .AddHttpClientInstrumentation() .AddSqlClientInstrumentation() .SetResourceBuilder(rb) .AddJaegerExporter(o => { var s = config.GetSection( "Jaeger" ); s.Bind(o); }) .Build(); |
But how to transmit data for a Web that calls a process and not modify the command line ? Simple : via environment variable
The code for running the process is :
01 02 03 04 05 06 07 08 09 10 11 | var pi = new ProcessStartInfo(); pi.FileName = ...; pi.WorkingDirectory = ...; var act = Activity.Current; if (act != null ) { pi.EnvironmentVariables.Add(nameof(act.TraceId), act.TraceId.ToHexString()); pi.EnvironmentVariables.Add(nameof(act.SpanId), act.SpanId.ToHexString()); } var p = Process.Start(pi); |
For the console, the code is:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | using ( var act = MyActivitySource.StartActivity( "StartProcess" , ActivityKind.Producer)) { act.SetTag( "proc" , "main" ); var traceStr = (Environment.GetEnvironmentVariable(nameof(act.TraceId))); if (! string .IsNullOrWhiteSpace(traceStr)) { var trace = ActivityTraceId.CreateFromString(traceStr); var span = ActivitySpanId.CreateFromString(Environment.GetEnvironmentVariable(nameof(act.SpanId))); act.SetParentId(trace, span, ActivityTraceFlags.Recorded); } try { //executing code act.SetStatus(Status.Ok); } catch (Exception ex) { act.SetStatus(Status.Error); throw ; } } |