fix(localdb): telemetry review fixes — meter naming, snapshot status, session-count Connected

Claude-Session: https://claude.ai/code/session_01BL2Vu1ESDQ9SCN4gVKkdts
This commit is contained in:
Joseph Doherty
2026-07-18 00:14:57 -04:00
parent be4ca76f5f
commit eb40cd8f29
9 changed files with 130 additions and 40 deletions
@@ -3,15 +3,17 @@ using System.Diagnostics.Metrics;
namespace ZB.MOM.WW.LocalDb.Replication;
/// <summary>
/// The replication engine's OpenTelemetry instruments, under the single <c>zb.mom.ww.localdb</c>
/// meter. Optional throughout: the sessions and adapters hold a nullable reference and every call
/// is null-guarded, so replication runs identically whether or not this is registered. Instrument
/// names follow the family metric conventions (lower-case, dot-separated, seconds for durations).
/// The replication engine's OpenTelemetry instruments, under the single
/// <c>ZB.MOM.WW.LocalDb.Replication</c> meter (family METRIC-CONVENTIONS §1: meters are named
/// after their root namespace). Optional throughout: the sessions and adapters hold a nullable
/// reference and every call is null-guarded, so replication runs identically whether or not this
/// is registered. Instrument names follow the family metric conventions (lower-case,
/// dot-separated, seconds for durations).
/// </summary>
public sealed class LocalDbMetrics : IDisposable
{
/// <summary>The single meter name every replication instrument is published under.</summary>
public const string MeterName = "zb.mom.ww.localdb";
public const string MeterName = "ZB.MOM.WW.LocalDb.Replication";
private readonly Meter _meter;
private readonly Counter<long> _applied;
@@ -25,13 +27,13 @@ public sealed class LocalDbMetrics : IDisposable
public LocalDbMetrics(Func<DateTimeOffset>? utcNow = null)
{
_utcNow = utcNow ?? (() => DateTimeOffset.UtcNow);
_meter = new Meter(MeterName, "0.1.0");
_meter = new Meter(MeterName, typeof(LocalDbMetrics).Assembly.GetName().Version?.ToString(3));
_applied = _meter.CreateCounter<long>("localdb.sync.applied");
_conflictsDiscarded = _meter.CreateCounter<long>("localdb.sync.conflicts_discarded");
_deadLettered = _meter.CreateCounter<long>("localdb.sync.dead_lettered");
_reconnects = _meter.CreateCounter<long>("localdb.sync.reconnects");
_snapshots = _meter.CreateCounter<long>("localdb.sync.snapshots");
_meter.CreateObservableGauge("localdb.oplog.depth", ObserveOplogDepth);
_meter.CreateObservableGauge("localdb.oplog.depth", ObserveOplogDepth, "1");
_meter.CreateObservableGauge("localdb.sync.lag.seconds", ObserveSyncLag, "s");
}
@@ -64,8 +66,11 @@ public sealed class LocalDbMetrics : IDisposable
public void RecordReconnect() => _reconnects.Add(1);
public void RecordSnapshot(string direction) =>
_snapshots.Add(1, new KeyValuePair<string, object?>("direction", direction));
public void RecordSnapshotSent() =>
_snapshots.Add(1, new KeyValuePair<string, object?>("direction", "sent"));
public void RecordSnapshotReceived() =>
_snapshots.Add(1, new KeyValuePair<string, object?>("direction", "received"));
private IEnumerable<Measurement<long>> ObserveOplogDepth()
{