////////////////////////////////////////////////////////////////////
// 作者:Ir0nMax
// 时间:2025/03/05
// 邮箱:ir0nmax@wogof.com
////////////////////////////////////////////////////////////////////
namespace Admin.NET.Core;
///
/// http日志处理
///
public class HttpLoggingHandler : DelegatingHandler, ITransient
{
private readonly Dictionary _enabledLogMap;
private readonly SysConfigService _sysConfigService;
private readonly IEventPublisher _eventPublisher;
public HttpLoggingHandler(IEventPublisher eventPublisher, SysConfigService sysConfigService, IOptions options)
{
_eventPublisher = eventPublisher;
HttpRemotesOptions httpRemotesOptions = options.Value;
_sysConfigService = sysConfigService;
_enabledLogMap = typeof(HttpRemotesOptions).GetProperties()
.Where(u => u.PropertyType == typeof(HttpRemoteItem))
.ToDictionary(u => u.GetValue(httpRemotesOptions) is HttpRemoteItem opt ? opt.HttpName : "",
u => u.GetValue(httpRemotesOptions) is HttpRemoteItem { EnabledLog: true });
}
protected override async Task SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken)
{
// 判断全局Http日志开关
var enabledLog = await _sysConfigService.GetConfigValueByCode(ConfigConst.SysLogHttp);
if (!enabledLog) return await base.SendAsync(request, cancellationToken);
// 判断当前配置日志开关
request.Options.TryGetValue(CommonConst.HttpRemoteClientName, out var clientName);
if (!string.IsNullOrWhiteSpace(clientName)) enabledLog = _enabledLogMap.GetOrDefault(clientName);
if (!enabledLog) return await base.SendAsync(request, cancellationToken);
var sysLogHttp = new SysLogHttp();
sysLogHttp.HttpClientName = clientName;
// 获取接口描述,并移除
sysLogHttp.HttpApiDesc = request.Headers.FirstOrDefault(u => u.Key == CommonConst.HttpRemoteApiDescHeaderName).Value?.FirstOrDefault();
request.Headers.Remove(CommonConst.HttpRemoteApiDescHeaderName);
sysLogHttp.HttpMethod = request.Method.Method;
sysLogHttp.RequestUrl = request.RequestUri?.ToString();
sysLogHttp.RequestHeaders = request.Headers.ToDictionary(u => u.Key, u => u.Value.Join(";")).ToJson();
if (request.Content != null) sysLogHttp.RequestBody = await request.Content.ReadAsStringAsync(cancellationToken);
sysLogHttp.StartTime = DateTime.Now;
var stopWatch = Stopwatch.StartNew();
try
{
var response = await base.SendAsync(request, cancellationToken);
stopWatch.Stop();
sysLogHttp.EndTime = DateTime.Now;
sysLogHttp.ResponseHeaders = response.Headers.ToDictionary(u => u.Key, u => u.Value.Join(";")).ToJson();
sysLogHttp.IsSuccessStatusCode = response.IsSuccessStatusCode ? YesNoEnum.Y : YesNoEnum.N;
sysLogHttp.StatusCode = response.StatusCode;
sysLogHttp.ResponseBody = await response.Content.ReadAsStringAsync(cancellationToken);
return response;
}
catch (Exception ex)
{
stopWatch.Stop();
sysLogHttp.EndTime = DateTime.Now;
sysLogHttp.IsSuccessStatusCode = YesNoEnum.N;
sysLogHttp.Exception = JSON.Serialize(SerializableException.FromException(ex));
throw;
}
finally
{
sysLogHttp.Elapsed = stopWatch.ElapsedMilliseconds;
await _eventPublisher.PublishAsync(nameof(AppEventSubscriber.CreateHttpLog), sysLogHttp, cancellationToken);
}
}
}