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;
                }
                
            }  
Leave a Reply