通过日志,记录每个接口请求的耗时情况
结合 <logger name="*" level="Trace" writeTo="tracefile"/> 配置使用,NLog 热生效不需要重启服务
增加 RequestLogMiddleware.cs
public class RequestLogMiddleware { /// <summary> /// /// </summary> private readonly RequestDelegate _next; /// <summary> /// /// </summary> private readonly Logger logger = LogManager.GetCurrentClassLogger(); /// <summary> /// /// </summary> /// <param name="next"></param> public RequestLogMiddleware(RequestDelegate next, ILogger<RequestLogMiddleware> logger) { _next = next; } /// <summary> /// 访问日志记录 /// </summary> /// <param name="context"></param> /// <returns></returns> public async Task Invoke(HttpContext context) { //if (_RequestLogOptions != null & _RequestLogOptions.CurrentValue != null & _RequestLogOptions.CurrentValue.Enable) { var watch = new Stopwatch(); watch.Start(); context.Response.OnStarting(() => { watch.Stop(); try { //排序 .jpg .css .js 等资源文件 if (!context.Request.Path.Value.Contains(".")) { var headers = context.Request.Headers; if (headers.ContainsKey("X-Forwarded-For")) { context.Connection.RemoteIpAddress = IPAddress.Parse(headers["X-Forwarded-For"].ToString().Split(',', StringSplitOptions.RemoveEmptyEntries)[0]); } var ip = context.Connection.RemoteIpAddress.MapToIPv4().ToString(); logger.Trace($"{ip}|{context.Response.StatusCode}|{watch.ElapsedMilliseconds}|{context.Request.Method} => {context.Request.Path.Value}{context.Request.QueryString}"); } } finally { } return Task.CompletedTask; }); } await _next.Invoke(context); } } /// <summary> /// 请求记录中间件扩展类 /// </summary> public static class RequestLogMiddlewareExtensions { /// <summary> /// 添加请求日志记录中间件 /// </summary> /// <param name="builder"></param> /// <remarks> /// 日志格式 Host ==> ConnectId ==> Scheme ==> Method ==> Path ==> QueryString ==>Response Status ==> Response ContentLength ==> Response Time /// 日志记录级别为 Trace /// </remarks> /// <returns></returns> public static IApplicationBuilder UseRequestLogHandler(this IApplicationBuilder builder) { builder.UseMiddleware<RequestLogMiddleware>(); return builder; } }