using System.Collections.Generic; using System.Diagnostics.Metrics; namespace StellaOps.Scanner.EntryTrace.Diagnostics; public static class EntryTraceInstrumentation { public static readonly Meter Meter = new("stellaops.scanner.entrytrace", "1.0.0"); } public sealed class EntryTraceMetrics { private readonly Counter _resolutions; private readonly Counter _unresolved; public EntryTraceMetrics() { _resolutions = EntryTraceInstrumentation.Meter.CreateCounter( "entrytrace_resolutions_total", description: "Number of entry trace attempts by outcome."); _unresolved = EntryTraceInstrumentation.Meter.CreateCounter( "entrytrace_unresolved_total", description: "Number of unresolved entry trace hops by reason."); } public void RecordOutcome(string imageDigest, string scanId, EntryTraceOutcome outcome) { _resolutions.Add(1, CreateTags(imageDigest, scanId, ("outcome", outcome.ToString().ToLowerInvariant()))); } public void RecordUnknown(string imageDigest, string scanId, EntryTraceUnknownReason reason) { _unresolved.Add(1, CreateTags(imageDigest, scanId, ("reason", reason.ToString().ToLowerInvariant()))); } private static KeyValuePair[] CreateTags(string imageDigest, string scanId, params (string Key, object? Value)[] extras) { var tags = new List>(2 + extras.Length) { new("image", imageDigest), new("scan.id", scanId) }; foreach (var extra in extras) { tags.Add(new KeyValuePair(extra.Key, extra.Value)); } return tags.ToArray(); } }