9cad9ed0fc
v2-ci / build (push) Failing after 41s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
Adds <summary>/<param>/<returns>/<inheritdoc> where missing and removes project bookkeeping IDs (task/tracking refs) from shipped code comments, so the docs read cleanly and CommentChecker is quiet except for known false positives (PLC/protocol terms, event/IEqualityComparer inheritdoc). Doc/comment-only; no logic changed; solution builds clean.
63 lines
3.0 KiB
C#
63 lines
3.0 KiB
C#
using Serilog.Context;
|
|
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.Core.Observability;
|
|
|
|
/// <summary>
|
|
/// Convenience wrapper around Serilog <see cref="LogContext"/> — attaches the set of
|
|
/// structured properties a capability call should carry (DriverInstanceId, DriverType,
|
|
/// CapabilityName, CorrelationId). Callers wrap their call-site body in a <c>using</c>
|
|
/// block; inner <c>Log.Information</c> / <c>Log.Warning</c> calls emit the context
|
|
/// automatically via the Serilog enricher chain.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// The correlation ID should be the OPC UA <c>RequestHeader.RequestHandle</c> when in-flight;
|
|
/// otherwise a short random GUID. Callers supply whichever is available.
|
|
/// </remarks>
|
|
public static class LogContextEnricher
|
|
{
|
|
/// <summary>Attach the capability-call property set. Dispose the returned scope to pop.</summary>
|
|
/// <param name="driverInstanceId">The unique identifier for the driver instance.</param>
|
|
/// <param name="driverType">The driver type name.</param>
|
|
/// <param name="capability">The driver capability being invoked.</param>
|
|
/// <param name="correlationId">The correlation ID for tracing the call.</param>
|
|
/// <returns>A disposable scope that pops the pushed properties when disposed.</returns>
|
|
public static IDisposable Push(string driverInstanceId, string driverType, DriverCapability capability, string correlationId)
|
|
{
|
|
ArgumentException.ThrowIfNullOrWhiteSpace(driverInstanceId);
|
|
ArgumentException.ThrowIfNullOrWhiteSpace(driverType);
|
|
ArgumentException.ThrowIfNullOrWhiteSpace(correlationId);
|
|
|
|
var a = LogContext.PushProperty("DriverInstanceId", driverInstanceId);
|
|
var b = LogContext.PushProperty("DriverType", driverType);
|
|
var c = LogContext.PushProperty("CapabilityName", capability.ToString());
|
|
var d = LogContext.PushProperty("CorrelationId", correlationId);
|
|
return new CompositeScope(a, b, c, d);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generate a short correlation ID when no OPC UA RequestHandle is available.
|
|
/// 12-hex-char slice of a GUID — long enough for log correlation, short enough to
|
|
/// scan visually.
|
|
/// </summary>
|
|
/// <returns>A 12-hex-character correlation ID.</returns>
|
|
public static string NewCorrelationId() => Guid.NewGuid().ToString("N")[..12];
|
|
|
|
private sealed class CompositeScope : IDisposable
|
|
{
|
|
private readonly IDisposable[] _inner;
|
|
|
|
/// <summary>Initializes a new instance of the CompositeScope with the given inner scopes.</summary>
|
|
/// <param name="inner">The inner scopes to composite and dispose together.</param>
|
|
public CompositeScope(params IDisposable[] inner) => _inner = inner;
|
|
|
|
/// <summary>Disposes all inner scopes in reverse order.</summary>
|
|
public void Dispose()
|
|
{
|
|
// Reverse-order disposal matches Serilog's stack semantics.
|
|
for (var i = _inner.Length - 1; i >= 0; i--)
|
|
_inner[i].Dispose();
|
|
}
|
|
}
|
|
}
|