//////////////////////////////////////////////////////////////////// // 作者: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); } } }