Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
- Added `LedgerMetrics` class to record write latency and total events for ledger operations. - Created comprehensive tests for Ruby packages endpoints, covering scenarios for missing inventory, successful retrieval, and identifier handling. - Introduced `TestSurfaceSecretsScope` for managing environment variables during tests. - Developed `ProvenanceMongoExtensions` for attaching DSSE provenance and trust information to event documents. - Implemented `EventProvenanceWriter` and `EventWriter` classes for managing event provenance in MongoDB. - Established MongoDB indexes for efficient querying of events based on provenance and trust. - Added models and JSON parsing logic for DSSE provenance and trust information.
143 lines
4.5 KiB
C#
143 lines
4.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using OpenTelemetry.Metrics;
|
|
using OpenTelemetry.Resources;
|
|
using OpenTelemetry.Trace;
|
|
using StellaOps.Excititor.WebService.Options;
|
|
using StellaOps.Excititor.WebService.Telemetry;
|
|
using StellaOps.Ingestion.Telemetry;
|
|
|
|
namespace StellaOps.Excititor.WebService.Extensions;
|
|
|
|
internal static class TelemetryExtensions
|
|
{
|
|
public static void ConfigureExcititorTelemetry(this WebApplicationBuilder builder)
|
|
{
|
|
var telemetryOptions = new ExcititorTelemetryOptions();
|
|
builder.Configuration.GetSection("Excititor:Telemetry").Bind(telemetryOptions);
|
|
|
|
if (!telemetryOptions.Enabled || (!telemetryOptions.EnableTracing && !telemetryOptions.EnableMetrics))
|
|
{
|
|
return;
|
|
}
|
|
|
|
var openTelemetry = builder.Services.AddOpenTelemetry();
|
|
|
|
openTelemetry.ConfigureResource(resource =>
|
|
{
|
|
var serviceName = telemetryOptions.ServiceName ?? builder.Environment.ApplicationName ?? "StellaOps.Excititor.WebService";
|
|
var version = Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? "unknown";
|
|
resource.AddService(serviceName, serviceVersion: version, serviceInstanceId: Environment.MachineName);
|
|
|
|
foreach (var attribute in telemetryOptions.ResourceAttributes)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(attribute.Key) || string.IsNullOrWhiteSpace(attribute.Value))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
resource.AddAttributes(new[]
|
|
{
|
|
new KeyValuePair<string, object>(attribute.Key, attribute.Value)
|
|
});
|
|
}
|
|
});
|
|
|
|
if (telemetryOptions.EnableTracing)
|
|
{
|
|
openTelemetry.WithTracing(tracing =>
|
|
{
|
|
tracing
|
|
.AddSource(IngestionTelemetry.ActivitySourceName)
|
|
.AddAspNetCoreInstrumentation()
|
|
.AddHttpClientInstrumentation();
|
|
|
|
ConfigureExporters(telemetryOptions, tracing);
|
|
});
|
|
}
|
|
|
|
if (telemetryOptions.EnableMetrics)
|
|
{
|
|
openTelemetry.WithMetrics(metrics =>
|
|
{
|
|
metrics
|
|
.AddMeter(IngestionTelemetry.MeterName)
|
|
.AddMeter(EvidenceTelemetry.MeterName)
|
|
.AddAspNetCoreInstrumentation()
|
|
.AddHttpClientInstrumentation()
|
|
.AddRuntimeInstrumentation();
|
|
|
|
ConfigureExporters(telemetryOptions, metrics);
|
|
});
|
|
}
|
|
}
|
|
|
|
private static void ConfigureExporters(ExcititorTelemetryOptions options, TracerProviderBuilder tracing)
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(options.OtlpEndpoint))
|
|
{
|
|
tracing.AddOtlpExporter(otlp =>
|
|
{
|
|
otlp.Endpoint = new Uri(options.OtlpEndpoint, UriKind.Absolute);
|
|
var headers = BuildHeaders(options.OtlpHeaders);
|
|
if (!string.IsNullOrEmpty(headers))
|
|
{
|
|
otlp.Headers = headers;
|
|
}
|
|
});
|
|
return;
|
|
}
|
|
|
|
if (options.ExportConsole)
|
|
{
|
|
tracing.AddConsoleExporter();
|
|
}
|
|
}
|
|
|
|
private static void ConfigureExporters(ExcititorTelemetryOptions options, MeterProviderBuilder metrics)
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(options.OtlpEndpoint))
|
|
{
|
|
metrics.AddOtlpExporter(otlp =>
|
|
{
|
|
otlp.Endpoint = new Uri(options.OtlpEndpoint, UriKind.Absolute);
|
|
var headers = BuildHeaders(options.OtlpHeaders);
|
|
if (!string.IsNullOrEmpty(headers))
|
|
{
|
|
otlp.Headers = headers;
|
|
}
|
|
});
|
|
return;
|
|
}
|
|
|
|
if (options.ExportConsole)
|
|
{
|
|
metrics.AddConsoleExporter();
|
|
}
|
|
}
|
|
|
|
private static string? BuildHeaders(IReadOnlyDictionary<string, string> headers)
|
|
{
|
|
if (headers.Count == 0)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var parts = new List<string>(headers.Count);
|
|
foreach (var header in headers)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(header.Key) || string.IsNullOrWhiteSpace(header.Value))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
parts.Add($"{header.Key}={header.Value}");
|
|
}
|
|
|
|
return parts.Count == 0 ? null : string.Join(',', parts);
|
|
}
|
|
}
|