Implement ledger metrics for observability and add tests for Ruby packages endpoints
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
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.
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
using System.Diagnostics.Metrics;
|
||||
|
||||
namespace StellaOps.Findings.Ledger.Observability;
|
||||
|
||||
internal static class LedgerMetrics
|
||||
{
|
||||
private static readonly Meter Meter = new("StellaOps.Findings.Ledger");
|
||||
|
||||
private static readonly Histogram<double> WriteLatencySeconds = Meter.CreateHistogram<double>(
|
||||
"ledger_write_latency_seconds",
|
||||
unit: "s",
|
||||
description: "Latency of successful ledger append operations.");
|
||||
|
||||
private static readonly Counter<long> EventsTotal = Meter.CreateCounter<long>(
|
||||
"ledger_events_total",
|
||||
description: "Number of ledger events appended.");
|
||||
|
||||
public static void RecordWriteSuccess(TimeSpan duration, string? tenantId, string? eventType, string? source)
|
||||
{
|
||||
var tags = new TagList
|
||||
{
|
||||
{ "tenant", tenantId ?? string.Empty },
|
||||
{ "event_type", eventType ?? string.Empty },
|
||||
{ "source", source ?? string.Empty }
|
||||
};
|
||||
|
||||
WriteLatencySeconds.Record(duration.TotalSeconds, tags);
|
||||
EventsTotal.Add(1, tags);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
using System.Diagnostics;
|
||||
using System.Text.Json.Nodes;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StellaOps.Findings.Ledger.Domain;
|
||||
using StellaOps.Findings.Ledger.Hashing;
|
||||
using StellaOps.Findings.Ledger.Infrastructure;
|
||||
using StellaOps.Findings.Ledger.Observability;
|
||||
|
||||
namespace StellaOps.Findings.Ledger.Services;
|
||||
|
||||
@@ -29,6 +31,8 @@ public sealed class LedgerEventWriteService : ILedgerEventWriteService
|
||||
|
||||
public async Task<LedgerWriteResult> AppendAsync(LedgerEventDraft draft, CancellationToken cancellationToken)
|
||||
{
|
||||
var stopwatch = Stopwatch.StartNew();
|
||||
|
||||
var validationErrors = ValidateDraft(draft);
|
||||
if (validationErrors.Count > 0)
|
||||
{
|
||||
@@ -95,6 +99,9 @@ public sealed class LedgerEventWriteService : ILedgerEventWriteService
|
||||
{
|
||||
await _repository.AppendAsync(record, cancellationToken).ConfigureAwait(false);
|
||||
await _merkleAnchorScheduler.EnqueueAsync(record, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
stopwatch.Stop();
|
||||
LedgerMetrics.RecordWriteSuccess(stopwatch.Elapsed, draft.TenantId, draft.EventType, DetermineSource(draft));
|
||||
}
|
||||
catch (Exception ex) when (IsDuplicateKeyException(ex))
|
||||
{
|
||||
@@ -116,6 +123,21 @@ public sealed class LedgerEventWriteService : ILedgerEventWriteService
|
||||
return LedgerWriteResult.Success(record);
|
||||
}
|
||||
|
||||
private static string DetermineSource(LedgerEventDraft draft)
|
||||
{
|
||||
if (draft.SourceRunId.HasValue)
|
||||
{
|
||||
return "policy_run";
|
||||
}
|
||||
|
||||
return draft.ActorType switch
|
||||
{
|
||||
"operator" => "workflow",
|
||||
"integration" => "integration",
|
||||
_ => "system"
|
||||
};
|
||||
}
|
||||
|
||||
private static bool IsDuplicateKeyException(Exception exception)
|
||||
{
|
||||
if (exception is null)
|
||||
|
||||
Reference in New Issue
Block a user