通過日誌,記錄每個接口請求的耗時情況
結合 <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; } }