using System; using System.Collections.Generic; using System.Reflection; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using OpenTelemetry.Metrics; using OpenTelemetry.Resources; using OpenTelemetry.Trace; using StellaOps.Scanner.Worker.Options; namespace StellaOps.Scanner.Worker.Diagnostics; public static class TelemetryExtensions { public static void ConfigureScannerWorkerTelemetry(this IHostApplicationBuilder builder, ScannerWorkerOptions options) { ArgumentNullException.ThrowIfNull(builder); ArgumentNullException.ThrowIfNull(options); var telemetry = options.Telemetry; if (!telemetry.EnableTelemetry) { return; } var openTelemetry = builder.Services.AddOpenTelemetry(); openTelemetry.ConfigureResource(resource => { var version = Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? "unknown"; resource.AddService(telemetry.ServiceName, serviceVersion: version, serviceInstanceId: Environment.MachineName); resource.AddAttributes(new[] { new KeyValuePair("deployment.environment", builder.Environment.EnvironmentName), }); foreach (var kvp in telemetry.ResourceAttributes) { if (string.IsNullOrWhiteSpace(kvp.Key) || kvp.Value is null) { continue; } resource.AddAttributes(new[] { new KeyValuePair(kvp.Key, kvp.Value) }); } }); if (telemetry.EnableTracing) { openTelemetry.WithTracing(tracing => { tracing.AddSource(ScannerWorkerInstrumentation.ActivitySourceName); ConfigureExporter(tracing, telemetry); }); } if (telemetry.EnableMetrics) { openTelemetry.WithMetrics(metrics => { metrics .AddMeter( ScannerWorkerInstrumentation.MeterName, "StellaOps.Scanner.Analyzers.Lang.Node", "StellaOps.Scanner.Analyzers.Lang.Go") .AddRuntimeInstrumentation() .AddProcessInstrumentation(); ConfigureExporter(metrics, telemetry); }); } } private static void ConfigureExporter(TracerProviderBuilder tracing, ScannerWorkerOptions.TelemetryOptions telemetry) { if (!string.IsNullOrWhiteSpace(telemetry.OtlpEndpoint)) { tracing.AddOtlpExporter(options => { options.Endpoint = new Uri(telemetry.OtlpEndpoint); }); } if (telemetry.ExportConsole || string.IsNullOrWhiteSpace(telemetry.OtlpEndpoint)) { tracing.AddConsoleExporter(); } } private static void ConfigureExporter(MeterProviderBuilder metrics, ScannerWorkerOptions.TelemetryOptions telemetry) { if (!string.IsNullOrWhiteSpace(telemetry.OtlpEndpoint)) { metrics.AddOtlpExporter(options => { options.Endpoint = new Uri(telemetry.OtlpEndpoint); }); } if (telemetry.ExportConsole || string.IsNullOrWhiteSpace(telemetry.OtlpEndpoint)) { metrics.AddConsoleExporter(); } } }