Files
git.stella-ops.org/src/StellaOps.Concelier.Connector.Kisa/Internal/KisaDiagnostics.cs

170 lines
6.7 KiB
C#

using System.Diagnostics.Metrics;
namespace StellaOps.Concelier.Connector.Kisa.Internal;
public sealed class KisaDiagnostics : IDisposable
{
public const string MeterName = "StellaOps.Concelier.Connector.Kisa";
private const string MeterVersion = "1.0.0";
private readonly Meter _meter;
private readonly Counter<long> _feedAttempts;
private readonly Counter<long> _feedSuccess;
private readonly Counter<long> _feedFailures;
private readonly Counter<long> _feedItems;
private readonly Counter<long> _detailAttempts;
private readonly Counter<long> _detailSuccess;
private readonly Counter<long> _detailUnchanged;
private readonly Counter<long> _detailFailures;
private readonly Counter<long> _parseAttempts;
private readonly Counter<long> _parseSuccess;
private readonly Counter<long> _parseFailures;
private readonly Counter<long> _mapSuccess;
private readonly Counter<long> _mapFailures;
private readonly Counter<long> _cursorUpdates;
public KisaDiagnostics()
{
_meter = new Meter(MeterName, MeterVersion);
_feedAttempts = _meter.CreateCounter<long>(
name: "kisa.feed.attempts",
unit: "operations",
description: "Number of RSS fetch attempts performed for the KISA connector.");
_feedSuccess = _meter.CreateCounter<long>(
name: "kisa.feed.success",
unit: "operations",
description: "Number of RSS fetch attempts that completed successfully.");
_feedFailures = _meter.CreateCounter<long>(
name: "kisa.feed.failures",
unit: "operations",
description: "Number of RSS fetch attempts that failed.");
_feedItems = _meter.CreateCounter<long>(
name: "kisa.feed.items",
unit: "items",
description: "Number of feed items returned by successful RSS fetches.");
_detailAttempts = _meter.CreateCounter<long>(
name: "kisa.detail.attempts",
unit: "documents",
description: "Number of advisory detail fetch attempts.");
_detailSuccess = _meter.CreateCounter<long>(
name: "kisa.detail.success",
unit: "documents",
description: "Number of advisory detail documents fetched successfully.");
_detailUnchanged = _meter.CreateCounter<long>(
name: "kisa.detail.unchanged",
unit: "documents",
description: "Number of advisory detail fetches that returned HTTP 304 (no change).");
_detailFailures = _meter.CreateCounter<long>(
name: "kisa.detail.failures",
unit: "documents",
description: "Number of advisory detail fetch attempts that failed.");
_parseAttempts = _meter.CreateCounter<long>(
name: "kisa.parse.attempts",
unit: "documents",
description: "Number of advisory documents queued for parsing.");
_parseSuccess = _meter.CreateCounter<long>(
name: "kisa.parse.success",
unit: "documents",
description: "Number of advisory documents parsed successfully into DTOs.");
_parseFailures = _meter.CreateCounter<long>(
name: "kisa.parse.failures",
unit: "documents",
description: "Number of advisory documents that failed parsing.");
_mapSuccess = _meter.CreateCounter<long>(
name: "kisa.map.success",
unit: "advisories",
description: "Number of canonical advisories produced by the mapper.");
_mapFailures = _meter.CreateCounter<long>(
name: "kisa.map.failures",
unit: "advisories",
description: "Number of advisories that failed to map.");
_cursorUpdates = _meter.CreateCounter<long>(
name: "kisa.cursor.updates",
unit: "updates",
description: "Number of times the published cursor advanced.");
}
public void FeedAttempt() => _feedAttempts.Add(1);
public void FeedSuccess(int itemCount)
{
_feedSuccess.Add(1);
if (itemCount > 0)
{
_feedItems.Add(itemCount);
}
}
public void FeedFailure(string reason)
=> _feedFailures.Add(1, GetReasonTags(reason));
public void DetailAttempt(string? category)
=> _detailAttempts.Add(1, GetCategoryTags(category));
public void DetailSuccess(string? category)
=> _detailSuccess.Add(1, GetCategoryTags(category));
public void DetailUnchanged(string? category)
=> _detailUnchanged.Add(1, GetCategoryTags(category));
public void DetailFailure(string? category, string reason)
=> _detailFailures.Add(1, GetCategoryReasonTags(category, reason));
public void ParseAttempt(string? category)
=> _parseAttempts.Add(1, GetCategoryTags(category));
public void ParseSuccess(string? category)
=> _parseSuccess.Add(1, GetCategoryTags(category));
public void ParseFailure(string? category, string reason)
=> _parseFailures.Add(1, GetCategoryReasonTags(category, reason));
public void MapSuccess(string? severity)
=> _mapSuccess.Add(1, GetSeverityTags(severity));
public void MapFailure(string? severity, string reason)
=> _mapFailures.Add(1, GetSeverityReasonTags(severity, reason));
public void CursorAdvanced()
=> _cursorUpdates.Add(1);
public Meter Meter => _meter;
public void Dispose() => _meter.Dispose();
private static KeyValuePair<string, object?>[] GetCategoryTags(string? category)
=> new[]
{
new KeyValuePair<string, object?>("category", Normalize(category))
};
private static KeyValuePair<string, object?>[] GetCategoryReasonTags(string? category, string reason)
=> new[]
{
new KeyValuePair<string, object?>("category", Normalize(category)),
new KeyValuePair<string, object?>("reason", Normalize(reason)),
};
private static KeyValuePair<string, object?>[] GetSeverityTags(string? severity)
=> new[]
{
new KeyValuePair<string, object?>("severity", Normalize(severity)),
};
private static KeyValuePair<string, object?>[] GetSeverityReasonTags(string? severity, string reason)
=> new[]
{
new KeyValuePair<string, object?>("severity", Normalize(severity)),
new KeyValuePair<string, object?>("reason", Normalize(reason)),
};
private static KeyValuePair<string, object?>[] GetReasonTags(string reason)
=> new[]
{
new KeyValuePair<string, object?>("reason", Normalize(reason)),
};
private static string Normalize(string? value)
=> string.IsNullOrWhiteSpace(value) ? "unknown" : value!;
}