夫天地者,万物之逆旅;光阴者,百代之过客。而浮生若梦,为欢几何?
.Net Core 项目实战:请求记录中间件

组件需求

能够记录客户端的每次请求,需要记录的属性为:

Host ==> ConnectId ==> Scheme ==> Method ==> Path ==> QueryString ==>Response Status ==> Response ContentLength ==> Response Time

RequestLogMiddleware 核心实现

/// <summary>
    /// 请求记录中间件
    /// </summary>
    public class RequestLogMiddleware
    {
        /// <summary>
        /// 
        /// </summary>
        private readonly RequestDelegate _next;
        /// <summary>
        /// 
        /// </summary>
        private readonly ILogger _Logger;
        /// <summary>
        /// 
        /// </summary>
        private readonly IOptionsMonitor<RequestLogOptions> _RequestLogOptions;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="next"></param>
        public RequestLogMiddleware(RequestDelegate next, ILogger<RequestLogMiddleware> logger,
            IOptionsMonitor<RequestLogOptions> requestLogOptions)
        {
            _next = next;
            _Logger = logger;
            _RequestLogOptions = requestLogOptions;
        }
        /// <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
                    {
                        // 记录访问日志 Host ==> ConnectId ==> Scheme ==> Method ==> Path ==> QueryString ==>Response Status ==> Response Time
                        _Logger.LogTrace($"{context.Request.Host.Value} ==> {context.TraceIdentifier} ==> {context.Request.Scheme} ==>" +
                            $"{context.Request.Method} ==> {context.Request.Path.Value} ==> {context.Request.QueryString.Value} ==> " +
                            $"{context.Response.StatusCode} ==> {watch.ElapsedMilliseconds}");
                    }
                    finally
                    {
                    }
                    return Task.CompletedTask;
                });
            }
            await _next.Invoke(context);
        }
    }

创建IApplicationBuilder扩展方法UseIMRequestLogHandler

/// <summary>
    /// 请求记录中间件扩展类
    /// </summary>
    public static class RequestLogHandlerBuilderExtensions
    {
        /// <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 UseIMRequestLogHandler(this IApplicationBuilder builder)
        {
            builder.UseMiddleware<RequestLogMiddleware>();
            return builder;
        }
    }

Startup 使用

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseIMRequestLogHandler();
            app.UseMvc();
        }

使用注意:该组件请尽量放到异常处理组件之后其他组件之前,这样对于响应时间的记录将更精确。

作者:暗夜余晖

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

0

支持

0

反对

posted @2019-2-3  拜读(785)

评论列表

评论内容:



喜欢请打赏

支付宝 微信

请放心支付