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):


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 :

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 :

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:

 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;
                }
                
            }