🍒 refactor(HttpRemote): 重构远程调用日志记录逻辑,增加忽略记录日志配置

This commit is contained in:
喵你个汪呀 2025-08-24 16:15:05 +08:00
parent b04324848c
commit 491b0270ac
6 changed files with 83 additions and 29 deletions

View File

@ -35,6 +35,11 @@ public class HttpRemoteApiAttribute : Attribute
/// 参数类型
/// </summary>
public HttpParameterTypeEnum? Type { get; set; }
/// <summary>
/// 忽略记录日志
/// </summary>
public bool IgnoreLog { get; set; }
}
/// <summary>

View File

@ -39,13 +39,8 @@ public class CommonConst
public const string SendErrorMail = "Send:ErrorMail";
/// <summary>
/// 远程请求配置客户端名称键名
/// 远程请求请求头参数键值
/// </summary>
public const string HttpRemoteClientName = "__HTTP_CLIENT_NAME__";
/// <summary>
/// 远程请求请求头接口描述键值
/// </summary>
public const string HttpRemoteApiDescHeaderName = "__HTTP_CLIENT_API_DESC__";
public const string HttpRemoteHeaderKeyPrefix = "__HTTP_CLIENT_";
}

View File

@ -40,10 +40,10 @@ public static class HttpRemotesExtension {
/// </summary>
/// <param name="builder"></param>
/// <param name="httpName"></param>
/// <param name="desc"></param>
/// <param name="attr"></param>
/// <returns></returns>
public static HttpRequestBuilder SetRemoteApiAttr(this HttpRequestBuilder builder, string httpName, string desc = "")
public static HttpRequestBuilder SetRemoteApiAttr(this HttpRequestBuilder builder, string httpName, HttpRemoteApiAttribute attr)
{
return HttpLoggingHandler.SetRemoteApiAttr(builder, httpName, desc);
return HttpLoggingHandler.SetRemoteApiAttr(builder, httpName, attr);
}
}

View File

@ -4,6 +4,8 @@
// 邮箱ir0nmax@wogof.com
////////////////////////////////////////////////////////////////////
using System.Net.Http.Headers;
namespace Admin.NET.Core;
/// <summary>
@ -11,6 +13,10 @@ namespace Admin.NET.Core;
/// </summary>
public class HttpLoggingHandler : DelegatingHandler, ITransient
{
private static readonly string HttpNameKey = CommonConst.HttpRemoteHeaderKeyPrefix + "NAME__";
private static readonly string ApiDescKey = CommonConst.HttpRemoteHeaderKeyPrefix + "API_DESC__";
private static readonly string IgnoreLogKey = CommonConst.HttpRemoteHeaderKeyPrefix + "IGNORE_LOG__";
private readonly Dictionary<string, bool> _enabledLogMap;
private readonly SysConfigService _sysConfigService;
private readonly IEventPublisher _eventPublisher;
@ -34,21 +40,19 @@ public class HttpLoggingHandler : DelegatingHandler, ITransient
if (!enabledLog) return await base.SendAsync(request, cancellationToken);
// 判断当前配置日志开关
request.Options.TryGetValue<string>(CommonConst.HttpRemoteClientName, out var clientName);
if (!string.IsNullOrWhiteSpace(clientName)) enabledLog = _enabledLogMap.GetOrDefault(clientName);
if (!enabledLog) return await base.SendAsync(request, cancellationToken);
var attrInfo = GetRemoteApiAttrAndRemove(request.Headers);
if (!string.IsNullOrWhiteSpace(attrInfo.HttpName)) enabledLog = _enabledLogMap.GetOrDefault(attrInfo.HttpName);
if (!enabledLog || attrInfo.IgnoreLog) return await base.SendAsync(request, cancellationToken);
var stopWatch = Stopwatch.StartNew();
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();
var sysLogHttp = new SysLogHttp
{
HttpApiDesc = attrInfo.ApiDesc,
HttpClientName = attrInfo.HttpName,
HttpMethod = request.Method.Method,
RequestUrl = request.RequestUri?.ToString(),
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;
@ -78,17 +82,67 @@ public class HttpLoggingHandler : DelegatingHandler, ITransient
}
}
/// <summary>
/// 获取接口描述相关属性
/// </summary>
/// <param name="headers"></param>
/// <returns></returns>
private static HttpRemoteApiAttrDto GetRemoteApiAttrAndRemove(HttpRequestHeaders headers)
{
var result = new HttpRemoteApiAttrDto
{
HttpName = headers?.FirstOrDefault(u => u.Key == HttpNameKey).Value?.ToString(),
ApiDesc = headers?.FirstOrDefault(u => u.Key == ApiDescKey).Value?.ToString(),
IgnoreLog = headers?.FirstOrDefault(u => u.Key == IgnoreLogKey).Value?.ToBoolean() ?? false,
};
RemoveRemoteApiAttr(headers);
return result;
}
/// <summary>
/// 移除接口描述相关属性
/// </summary>
/// <param name="headers"></param>
/// <returns></returns>
private static void RemoveRemoteApiAttr(HttpRequestHeaders headers)
{
if (headers == null) return;
foreach (var kv in headers.Where(kv => kv.Key.StartsWith(CommonConst.HttpRemoteHeaderKeyPrefix))) headers.Remove(kv.Key);
}
/// <summary>
/// 设置接口描述相关属性
/// </summary>
/// <param name="builder"></param>
/// <param name="httpName"></param>
/// <param name="desc"></param>
/// <param name="attr"></param>
/// <returns></returns>
public static HttpRequestBuilder SetRemoteApiAttr(HttpRequestBuilder builder, string httpName, string desc = "")
public static HttpRequestBuilder SetRemoteApiAttr(HttpRequestBuilder builder, string httpName, HttpRemoteApiAttribute attr)
{
builder.WithHeader(CommonConst.HttpRemoteApiDescHeaderName, desc, replace:true);
builder.WithHeader(IgnoreLogKey, attr.IgnoreLog, replace:true);
builder.WithHeader(HttpNameKey, attr.Desc, replace:true);
builder.SetHttpClientName(httpName);
return builder;
}
}
/// <summary>
/// 远程请求相关属性
/// </summary>
public class HttpRemoteApiAttrDto
{
/// <summary>
/// 客户端名称
/// </summary>
public string HttpName { get; set; }
/// <summary>
/// 接口描述
/// </summary>
public string ApiDesc { get; set; }
/// <summary>
/// 是否忽略日志
/// </summary>
public bool IgnoreLog { get; set; }
}

View File

@ -59,7 +59,7 @@ public class BaseIdWorkWxOutput : BaseWorkWxOutput
/// 获取接口凭证输入参数
/// </summary>
/// https://developer.work.weixin.qq.com/document/path/91039
[HttpRemoteApi(Action = "gettoken", Desc = "获取接口凭证", HttpMethod = HttpMethodEnum.Get)]
[HttpRemoteApi(Action = "gettoken", Desc = "获取接口凭证", HttpMethod = HttpMethodEnum.Get, IgnoreLog = true)]
public class TokenWorkWxInput
{
/// <summary>

View File

@ -69,9 +69,9 @@ public class WorkWxBaseService(
{
HttpMethodEnum.Get => await httpRemoteService.GetAsync(
url + input.ToCustomJsonPropertyQueryString(),
builder => builder.SetRemoteApiAttr(opt.HttpName, attr.Desc)),
builder => builder.SetRemoteApiAttr(opt.HttpName, attr)),
HttpMethodEnum.Post => await httpRemoteService.PostAsync(url,
builder => builder.SetRemoteApiAttr(opt.HttpName, attr.Desc)
builder => builder.SetRemoteApiAttr(opt.HttpName, attr)
.SetContent(new StringContent(JSON.Serialize(input, CustomJsonPropertyConverter.Options), Encoding.UTF8, "application/json"))),
_ => throw Oops.Oh($"[企业微信] 不支持的请求方式{attr.HttpMethod.ToString()}({typeof(T).FullName})"),
};