Refactor code structure for improved readability and maintainability

This commit is contained in:
StellaOps Bot
2025-12-06 10:23:40 +02:00
parent 6beb9d7c4e
commit 37304cf819
78 changed files with 5471 additions and 104 deletions

View File

@@ -264,6 +264,184 @@ internal static class LedgerMetrics
StalenessValidationFailures.Add(1, tags);
}
private static readonly Counter<long> ScoredFindingsExports = Meter.CreateCounter<long>(
"ledger_scored_findings_exports_total",
description: "Count of scored findings export operations.");
private static readonly Histogram<double> ScoredFindingsExportDuration = Meter.CreateHistogram<double>(
"ledger_scored_findings_export_duration_seconds",
unit: "s",
description: "Duration of scored findings export operations.");
public static void RecordScoredFindingsExport(string? tenantId, int recordCount, double durationSeconds)
{
var tags = new KeyValuePair<string, object?>[]
{
new("tenant", tenantId ?? "unknown"),
new("record_count", recordCount)
};
ScoredFindingsExports.Add(1, tags);
ScoredFindingsExportDuration.Record(durationSeconds, tags);
}
// LEDGER-RISK-69-001: Scoring metrics/dashboards
private static readonly Histogram<double> ScoringLatencySeconds = Meter.CreateHistogram<double>(
"ledger_scoring_latency_seconds",
unit: "s",
description: "Latency of risk scoring operations per finding.");
private static readonly Counter<long> ScoringOperationsTotal = Meter.CreateCounter<long>(
"ledger_scoring_operations_total",
description: "Total number of scoring operations by result.");
private static readonly Counter<long> ScoringProviderGaps = Meter.CreateCounter<long>(
"ledger_scoring_provider_gaps_total",
description: "Count of findings where scoring provider was unavailable or returned no data.");
private static readonly ConcurrentDictionary<string, SeveritySnapshot> SeverityByTenantPolicy = new(StringComparer.Ordinal);
private static readonly ConcurrentDictionary<string, double> ScoreFreshnessByTenant = new(StringComparer.Ordinal);
private static readonly ObservableGauge<long> SeverityCriticalGauge =
Meter.CreateObservableGauge("ledger_severity_distribution_critical", ObserveSeverityCritical,
description: "Current count of critical severity findings by tenant and policy.");
private static readonly ObservableGauge<long> SeverityHighGauge =
Meter.CreateObservableGauge("ledger_severity_distribution_high", ObserveSeverityHigh,
description: "Current count of high severity findings by tenant and policy.");
private static readonly ObservableGauge<long> SeverityMediumGauge =
Meter.CreateObservableGauge("ledger_severity_distribution_medium", ObserveSeverityMedium,
description: "Current count of medium severity findings by tenant and policy.");
private static readonly ObservableGauge<long> SeverityLowGauge =
Meter.CreateObservableGauge("ledger_severity_distribution_low", ObserveSeverityLow,
description: "Current count of low severity findings by tenant and policy.");
private static readonly ObservableGauge<long> SeverityUnknownGauge =
Meter.CreateObservableGauge("ledger_severity_distribution_unknown", ObserveSeverityUnknown,
description: "Current count of unknown/unscored findings by tenant and policy.");
private static readonly ObservableGauge<double> ScoreFreshnessGauge =
Meter.CreateObservableGauge("ledger_score_freshness_seconds", ObserveScoreFreshness, unit: "s",
description: "Time since last scoring operation completed by tenant.");
public static void RecordScoringLatency(TimeSpan duration, string? tenantId, string? policyVersion, string result)
{
var tags = new KeyValuePair<string, object?>[]
{
new("tenant", tenantId ?? string.Empty),
new("policy_version", policyVersion ?? string.Empty),
new("result", result)
};
ScoringLatencySeconds.Record(duration.TotalSeconds, tags);
ScoringOperationsTotal.Add(1, tags);
}
public static void RecordScoringProviderGap(string? tenantId, string? provider, string reason)
{
var tags = new KeyValuePair<string, object?>[]
{
new("tenant", tenantId ?? string.Empty),
new("provider", provider ?? "unknown"),
new("reason", reason)
};
ScoringProviderGaps.Add(1, tags);
}
public static void UpdateSeverityDistribution(
string tenantId,
string? policyVersion,
int critical,
int high,
int medium,
int low,
int unknown)
{
var key = BuildTenantPolicyKey(tenantId, policyVersion);
SeverityByTenantPolicy[key] = new SeveritySnapshot(tenantId, policyVersion ?? "default", critical, high, medium, low, unknown);
}
public static void UpdateScoreFreshness(string tenantId, double secondsSinceLastScoring)
{
var key = NormalizeTenant(tenantId);
ScoreFreshnessByTenant[key] = secondsSinceLastScoring < 0 ? 0 : secondsSinceLastScoring;
}
private static string BuildTenantPolicyKey(string? tenantId, string? policyVersion)
{
var t = string.IsNullOrWhiteSpace(tenantId) ? string.Empty : tenantId;
var p = string.IsNullOrWhiteSpace(policyVersion) ? "default" : policyVersion;
return $"{t}|{p}";
}
private sealed record SeveritySnapshot(
string TenantId,
string PolicyVersion,
int Critical,
int High,
int Medium,
int Low,
int Unknown);
private static IEnumerable<Measurement<long>> ObserveSeverityCritical()
{
foreach (var kvp in SeverityByTenantPolicy)
{
yield return new Measurement<long>(kvp.Value.Critical,
new KeyValuePair<string, object?>("tenant", kvp.Value.TenantId),
new KeyValuePair<string, object?>("policy_version", kvp.Value.PolicyVersion));
}
}
private static IEnumerable<Measurement<long>> ObserveSeverityHigh()
{
foreach (var kvp in SeverityByTenantPolicy)
{
yield return new Measurement<long>(kvp.Value.High,
new KeyValuePair<string, object?>("tenant", kvp.Value.TenantId),
new KeyValuePair<string, object?>("policy_version", kvp.Value.PolicyVersion));
}
}
private static IEnumerable<Measurement<long>> ObserveSeverityMedium()
{
foreach (var kvp in SeverityByTenantPolicy)
{
yield return new Measurement<long>(kvp.Value.Medium,
new KeyValuePair<string, object?>("tenant", kvp.Value.TenantId),
new KeyValuePair<string, object?>("policy_version", kvp.Value.PolicyVersion));
}
}
private static IEnumerable<Measurement<long>> ObserveSeverityLow()
{
foreach (var kvp in SeverityByTenantPolicy)
{
yield return new Measurement<long>(kvp.Value.Low,
new KeyValuePair<string, object?>("tenant", kvp.Value.TenantId),
new KeyValuePair<string, object?>("policy_version", kvp.Value.PolicyVersion));
}
}
private static IEnumerable<Measurement<long>> ObserveSeverityUnknown()
{
foreach (var kvp in SeverityByTenantPolicy)
{
yield return new Measurement<long>(kvp.Value.Unknown,
new KeyValuePair<string, object?>("tenant", kvp.Value.TenantId),
new KeyValuePair<string, object?>("policy_version", kvp.Value.PolicyVersion));
}
}
private static IEnumerable<Measurement<double>> ObserveScoreFreshness()
{
foreach (var kvp in ScoreFreshnessByTenant)
{
yield return new Measurement<double>(kvp.Value, new KeyValuePair<string, object?>("tenant", kvp.Key));
}
}
private static IEnumerable<Measurement<double>> ObserveProjectionLag()
{
foreach (var kvp in ProjectionLagByTenant)