| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- using System;
- using System.Threading;
- namespace Aivfo.OperationLog
- {
- /// <summary>
- /// 进程内 traceId / parentId / operator / 设备上下文 透传(AsyncLocal,跨 async/线程切换)。
- /// 对称 Java 的 Trace(TransmittableThreadLocal)。
- /// </summary>
- public static class OperationLogContext
- {
- private static readonly AsyncLocal<string> _traceId = new AsyncLocal<string>();
- private static readonly AsyncLocal<string> _parentId = new AsyncLocal<string>();
- private static readonly AsyncLocal<string> _operator = new AsyncLocal<string>();
- private static readonly AsyncLocal<int?> _houseSn = new AsyncLocal<int?>();
- private static readonly AsyncLocal<int?> _wellSn = new AsyncLocal<int?>();
- /// <summary>当前 traceId(无则返回 null)。</summary>
- public static string TraceId
- {
- get => _traceId.Value;
- set => _traceId.Value = value;
- }
- /// <summary>当前 parentId。</summary>
- public static string ParentId
- {
- get => _parentId.Value;
- set => _parentId.Value = value;
- }
- /// <summary>当前操作者(登录用户)。可在登录后设置一次。</summary>
- public static string Operator
- {
- get => _operator.Value;
- set => _operator.Value = value;
- }
- /// <summary>当前舱号。</summary>
- public static int? HouseSn
- {
- get => _houseSn.Value;
- set => _houseSn.Value = value;
- }
- /// <summary>当前 well 号。</summary>
- public static int? WellSn
- {
- get => _wellSn.Value;
- set => _wellSn.Value = value;
- }
- /// <summary>生成一个新的 traceId(去横线的 Guid,紧凑唯一)。</summary>
- public static string NewTraceId()
- {
- return Guid.NewGuid().ToString("N");
- }
- /// <summary>
- /// 开启一次操作 scope:设置/继承 traceId,把当前 traceId 作为新 parentId。
- /// 释放时恢复原值。用 using 包裹一次完整操作。
- /// </summary>
- public static IDisposable BeginScope(string traceId = null)
- {
- var prevTrace = _traceId.Value;
- var prevParent = _parentId.Value;
- // 新 scope 的 parentId = 外层的 traceId(构成父子链);最外层为 null。
- _parentId.Value = prevTrace;
- _traceId.Value = string.IsNullOrEmpty(traceId)
- ? (string.IsNullOrEmpty(prevTrace) ? NewTraceId() : prevTrace)
- : traceId;
- return new ScopeRestore(prevTrace, prevParent);
- }
- private sealed class ScopeRestore : IDisposable
- {
- private readonly string _prevTrace;
- private readonly string _prevParent;
- private bool _done;
- public ScopeRestore(string prevTrace, string prevParent)
- {
- _prevTrace = prevTrace;
- _prevParent = prevParent;
- }
- public void Dispose()
- {
- if (_done) return;
- _done = true;
- _traceId.Value = _prevTrace;
- _parentId.Value = _prevParent;
- }
- }
- }
- }
|