Using OpenTelemetry with Generic Host #3048
-
How can I implement OpenTelemetry with Generic Host, here is my code, but something going wrong, using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
// var providerBuilder = Sdk.CreateMeterProviderBuilder();
// See https://aka.ms/new-console-template for more information
namespace ConsoleNetApp
{
public static class Program
{
public static async Task Main(string[] args)
{
var host = CreateHostBuilder(args).Build();
await host.RunAsync();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
var env = hostingContext.HostingEnvironment;
config.AddEnvironmentVariables();
config.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
config.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
})
.ConfigureServices((hostContext, services) =>
{
services.AddLogging();
services.AddHostedService<Worker>();
services.AddHttpClient("MyClient", (client) =>
{
client.BaseAddress = new Uri("https://localhost:7092");
});
services.AddAppInstrumentatins(hostContext.Configuration);
});
}
} using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using OpenTelemetry;
using OpenTelemetry.Exporter;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
namespace ConsoleNetApp
{
public static class AppInstrumentatins
{
public static void AddAppInstrumentatins(this IServiceCollection services, IConfiguration configuration)
{
Sdk.CreateMeterProviderBuilder();
var otelCollector = new OtelCollectorSettings();
var numberCycles = Source.Meter.CreateCounter<int>(Source.ServiceName + "_cycles", "number", "Number of cycles.");
services.AddSingleton(Source.ActivitySource);
services.AddSingleton(Source.Meter);
services.AddSingleton(numberCycles);
// This is required if the collector doesn't expose an https endpoint as .NET by default
// only allow http2 (required for gRPC) to secure endpoints
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
configuration.Bind(nameof(OtelCollectorSettings), otelCollector);
services.AddOpenTelemetryTracing(builder =>
{
builder
.AddSource(Source.ServiceName)
.SetResourceBuilder(
ResourceBuilder.CreateDefault()
.AddService(serviceName: Source.ServiceName, serviceVersion: Source.ServiceVersion))
.AddHttpClientInstrumentation()
.AddOtlpExporter((exporterOptions) =>
{
exporterOptions.Endpoint = new Uri(otelCollector.Uri);
exporterOptions.Protocol = OtlpExportProtocol.Grpc;
});
});
services.AddOpenTelemetryMetrics(builder =>
{
builder
.SetResourceBuilder(
ResourceBuilder.CreateDefault()
.AddService(serviceName: Source.ServiceName, serviceVersion: Source.ServiceVersion))
.AddMeter(Source.ServiceName)
.AddHttpClientInstrumentation()
.AddOtlpExporter((exporterOptions, metricReaderOptions) =>
{
exporterOptions.Endpoint = new Uri(otelCollector.Uri);
exporterOptions.Protocol = OtlpExportProtocol.Grpc;
metricReaderOptions.MetricReaderType = MetricReaderType.Periodic;
metricReaderOptions.PeriodicExportingMetricReaderOptions.ExportIntervalMilliseconds = 1000;
metricReaderOptions.Temporality = AggregationTemporality.Cumulative;
});
});
}
}
} using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System.Diagnostics;
using System.Diagnostics.Metrics;
namespace ConsoleNetApp
{
public class Worker : BackgroundService
{
private readonly IHttpClientFactory httpClientFactory;
private readonly IHostApplicationLifetime hostLifetime;
private readonly ActivitySource activitySource;
private readonly Counter<int> counter;
private readonly ILogger<Worker> logger;
public Worker(
IHttpClientFactory httpClientFactory,
IHostApplicationLifetime hostLifetime,
ActivitySource activitySource,
Counter<int> counter,
ILogger<Worker> logger)
{
this.httpClientFactory = httpClientFactory;
this.hostLifetime = hostLifetime;
this.activitySource = activitySource;
this.counter = counter;
this.logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
logger.LogInformation("Begin worker execution ...");
var client = httpClientFactory.CreateClient("MyClient");
while (!stoppingToken.IsCancellationRequested)
{
counter.Add(1);
var activity_1 = Activity.Current;
using (var activity = activitySource.StartActivity("my.console.woker.activity"))
{
var activity_3 = Activity.Current;
activity?.SetTag("my.console.tag", 10);
var weather = await client.GetStringAsync("/WeatherForecast").ConfigureAwait(false);
}
await Task.Delay(1000);
}
logger.LogInformation("End worker execution ...");
hostLifetime.StopApplication();
}
}
} using System.Diagnostics;
using System.Diagnostics.Metrics;
namespace ConsoleNetApp
{
public static class Source
{
public static readonly string ServiceName = ApplicationInformation.Name;
public static readonly string ServiceVersion = ApplicationInformation.Version.ToString();
public static readonly ActivitySource ActivitySource = new ActivitySource(ServiceName, ServiceVersion);
public static readonly Meter Meter = new Meter(ServiceName, ServiceVersion);
}
} |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 6 replies
-
Its not clear which part is not working. If it is about activitySource.StartActivity returning null, need to make sure the source is added to provider. And also try setting sampler to be AlwaysOnSampler. |
Beta Was this translation helpful? Give feedback.
-
Here is the code: https://github.com/luboid/open-telemetry-tests/blob/master/src/ConsoleNetApp/Worker.cs It appears that if I wait some time before I start the activity everything is working fine, but if I don't wait any time before the first call to start the activity, it returns null |
Beta Was this translation helpful? Give feedback.
-
services.AddHostedService(); --> could you try adding this after adding the OpenTelemetry things.. |
Beta Was this translation helpful? Give feedback.
services.AddHostedService(); --> could you try adding this after adding the OpenTelemetry things..