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