feat(shared-web): add shared swagger and tracing utilities
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using TakeoutSaaS.Shared.Abstractions.Diagnostics;
|
||||
|
||||
namespace TakeoutSaaS.Shared.Web.Middleware;
|
||||
|
||||
/// <summary>
|
||||
/// 统一 TraceId/CorrelationId,贯穿日志与响应。
|
||||
/// </summary>
|
||||
public sealed class CorrelationIdMiddleware
|
||||
{
|
||||
private const string TraceHeader = "X-Trace-Id";
|
||||
private const string RequestHeader = "X-Request-Id";
|
||||
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly ILogger<CorrelationIdMiddleware> _logger;
|
||||
|
||||
public CorrelationIdMiddleware(RequestDelegate next, ILogger<CorrelationIdMiddleware> logger)
|
||||
{
|
||||
_next = next;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task InvokeAsync(HttpContext context)
|
||||
{
|
||||
var traceId = ResolveTraceId(context);
|
||||
context.TraceIdentifier = traceId;
|
||||
TraceContext.TraceId = traceId;
|
||||
|
||||
context.Response.OnStarting(() =>
|
||||
{
|
||||
context.Response.Headers[TraceHeader] = traceId;
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
|
||||
using (_logger.BeginScope(new Dictionary<string, object>
|
||||
{
|
||||
["TraceId"] = traceId
|
||||
}))
|
||||
{
|
||||
try
|
||||
{
|
||||
await _next(context);
|
||||
}
|
||||
finally
|
||||
{
|
||||
TraceContext.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string ResolveTraceId(HttpContext context)
|
||||
{
|
||||
if (TryGetHeader(context, TraceHeader, out var traceId))
|
||||
{
|
||||
return traceId;
|
||||
}
|
||||
|
||||
if (TryGetHeader(context, RequestHeader, out var requestId))
|
||||
{
|
||||
return requestId;
|
||||
}
|
||||
|
||||
return Guid.NewGuid().ToString("N");
|
||||
}
|
||||
|
||||
private static bool TryGetHeader(HttpContext context, string headerName, out string value)
|
||||
{
|
||||
if (context.Request.Headers.TryGetValue(headerName, out var values))
|
||||
{
|
||||
var headerValue = values.ToString();
|
||||
if (!string.IsNullOrWhiteSpace(headerValue))
|
||||
{
|
||||
value = headerValue;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
value = string.Empty;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user