• .Net Core全局过滤器之全局异常记录和全局日志的记录


    在webapi 项目中,经常需要记录异常信息和接口的请求详情,同时记录调用的接口异常的参数等数据以便后续追查,但是又不想在项目到处写try catch,此时可以通过全局过滤器进行记录,

    代码如下

    全局异常过滤器

    WebApiExceptionFilterAttribute 
    namespace NetCore3WebApiTemplate.Filters
    {
        /// <summary>
        /// api请求异常日志类
        /// </summary>
        [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)]
        public class WebApiExceptionFilterAttribute : ExceptionFilterAttribute, IActionFilter
        {
    
            /// <summary>
            /// 控制器中的操作执行之前调用此方法
            /// </summary>
            /// <param name="context"></param>
            public void OnActionExecuting(ActionExecutingContext context)
            {
    //将请求的参数带上,后续使用 context.HttpContext.Items.Add("params", context.ActionArguments);
    //请求开始实际带上 context.HttpContext.Items.Add("executeStartTime", DateTime.Now); } /// <summary> /// 控制器中的操作执行之后调用此方法 /// </summary> /// <param name="context"></param> public void OnActionExecuted(ActionExecutedContext context) { // do nothing } /// <summary> /// 控制器中的操作异常调用此方法 /// </summary> /// <param name="actionExecutedContext"></param> /// <returns></returns> public override Task OnExceptionAsync(ExceptionContext actionExecutedContext) { if (actionExecutedContext.Exception != null) { ///取消操作导致的异常忽略 if (actionExecutedContext.Exception is OperationCanceledException) { } else { WriteErrorAsync(actionExecutedContext); } } HttpResponseResultModel<string> result = new HttpResponseResultModel<string>(); result.HttpStatusCode = (HttpStatusCode)actionExecutedContext.HttpContext.Response.StatusCode; result.IsSuccess = false; result.ErrorMessage = "出现异常,请稍后重试"; result.ExceptionMessage = actionExecutedContext.Exception.ToString(); actionExecutedContext.Result = new ObjectResult(result); return base.OnExceptionAsync(actionExecutedContext); } /// <summary> /// 写异常日志 /// </summary> /// <param name="exceptionContext"></param> /// <returns></returns> private async Task WriteErrorAsync(ExceptionContext exceptionContext) { WebApiExceptionLogModel logModel = new WebApiExceptionLogModel(); //获取Action 参数 var items = exceptionContext.HttpContext.Items; logModel.ExecuteStartTime = DateTime.Parse(items["executeStartTime"].ToString()); logModel.ExecuteEndTime = DateTime.Now; IDictionary<string, object> actionArguments = null; if (items.ContainsKey("params")) { actionArguments = (IDictionary<string, object>)items["params"]; } logModel.ActionParams = new Dictionary<string, object>(actionArguments); logModel.HttpRequestHeaders = exceptionContext.HttpContext.Request.Headers.ToString(); logModel.HttpRequestPath = exceptionContext.HttpContext.Request.Path; logModel.HttpMethod = exceptionContext.HttpContext.Request.Method; logModel.ActionName = ((ControllerActionDescriptor)exceptionContext.ActionDescriptor).ActionName; logModel.ControllerName = ((ControllerActionDescriptor)exceptionContext.ActionDescriptor).ControllerName; logModel.TotalSeconds = (logModel.ExecuteEndTime - logModel.ExecuteStartTime).TotalSeconds; logModel.ExceptionMessage = exceptionContext.Exception.ToString(); logModel.IP = CommonHttpContext.Current.Connection.RemoteIpAddress.ToString(); logModel.StatusCode = exceptionContext.HttpContext.Response.StatusCode; } } }

    全局日志过滤器 WebApiTrackerAttribute 代码如下

    namespace NetCore3WebApiTemplate.Filters
    {
        /// <summary>
        /// api 日志跟踪类
        /// </summary>
        public class WebApiTrackerAttribute : ActionFilterAttribute
        {
            
            /// <summary>
            /// 控制器方法执行之前执行此方法
            /// </summary>
            /// <param name="context"></param>
            /// <param name="next"></param>
            /// <returns></returns>
            public override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
            {
                context.HttpContext.Items.Add("executeStartTime", DateTime.Now);
                WriteLogAsync(context);
                return base.OnActionExecutionAsync(context, next);
    
            }
    
            /// <summary>
            /// 控制器操作结果执行之前调用此方法
            /// </summary>
            /// <param name="context"></param>
            /// <param name="next"></param>
            /// <returns></returns>
            public override Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
            {
                return base.OnResultExecutionAsync(context, next);
            }
    
            /// <summary>
            /// 控制器操作结果执行之后调用此方法
            /// </summary>
            /// <param name="context"></param>
            public override void OnActionExecuted(ActionExecutedContext context)
            {
                base.OnActionExecuted(context);
            }
    
            /// <summary>
            /// 写日志
            /// </summary>
            /// <param name="actionContext"></param>
            /// <returns></returns>
            private async Task WriteLogAsync(ActionExecutingContext actionContext)
            {
                var items = actionContext.HttpContext.Items;
                DateTime executeStartTime = DateTime.Parse(items["executeStartTime"].ToString());
                 WebApiLogModel logModel = new WebApiLogModel();
                logModel.ExecuteStartTime = executeStartTime;
                logModel.ExecuteEndTime = DateTime.Now;
                //获取Action 参数
                logModel.ActionParams = new Dictionary<string, object>(actionContext.ActionArguments);
                logModel.HttpRequestHeaders = actionContext.HttpContext.Request.Headers.ToString();
                logModel.HttpRequestPath = actionContext.HttpContext.Request.Path;
                logModel.HttpMethod = actionContext.HttpContext.Request.Method;
                logModel.ActionName = ((ControllerActionDescriptor)actionContext.ActionDescriptor).ActionName;
                logModel.ControllerName = ((ControllerActionDescriptor)actionContext.ActionDescriptor).ControllerName;
                logModel.TotalSeconds = (logModel.ExecuteEndTime - logModel.ExecuteStartTime).TotalSeconds;
                logModel.IP = CommonHttpContext.Current.Connection.RemoteIpAddress.ToString();
    
            }
        }
    }
    

      

    using System.Net;
    
    namespace NetCore3WebApiTemplate.Core
    {
    
        /// <summary>
        ///  http请求结果类
        /// </summary>
        /// <typeparam name="T"></typeparam>
        public class HttpResponseResultModel<T>
        {
            /// <summary>
            /// http码
            /// </summary>
            public HttpStatusCode HttpStatusCode { get; set; }
    
            /// <summary>
            /// 是否成功
            /// </summary>
            public bool IsSuccess { get; set; }
    
            /// <summary>
            /// 返回结果
            /// </summary>
            public T BackResult { get; set; }
    
            /// <summary>
            /// 错误信息
            /// </summary>
            public string ErrorMessage { get; set; }
    
            /// <summary>
            /// 异常信息
            /// </summary>
            public string ExceptionMessage { get; set; }
        }
    }
    
    namespace NetCore3WebApiTemplate.Utility
    {
        /// <summary>
        /// webapi异常日志类
        /// </summary>
        public class WebApiExceptionLogModel: WebApiLogModel
        {
            /// <summary>
            /// 异常信息
            /// </summary>
            public string ExceptionMessage { get; set; }
    
            /// <summary>
            /// 状态码
            /// </summary>
            public int StatusCode { get; set; }
        }
    }
    

      

    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace NetCore3WebApiTemplate.Utility
    {
        /// <summary>
        /// webapi 日志类
        /// </summary>
        public class WebApiLogModel
        {
            /// <summary>
            /// 控制器名称
            /// </summary>
            public string ControllerName { get; set; }
    
            /// <summary>
            /// 方法名称
            /// </summary>
            public string ActionName { get; set; }
    
            /// <summary>
            /// 执行开始时间
            /// </summary>
            public DateTime ExecuteStartTime { get; set; }
    
            /// <summary>
            /// 执行结束时间
            /// </summary>
            public DateTime ExecuteEndTime { get; set; }
    
            /// <summary>
            /// 总耗时(秒)
            /// </summary>
    
            public double TotalSeconds { get; set; }
    
            /// <summary>
            /// 请求的Action 参数
            /// </summary>
            public Dictionary<string, object> ActionParams { get; set; }
    
            /// <summary>
            /// Http请求头
            /// </summary>
            public string HttpRequestHeaders { get; set; }
    
            /// <summary>
            /// 请求的路径
            /// </summary>
            public string HttpRequestPath { get; set; }
    
            /// <summary>
            /// 请求方法类型(POST,GET等)
            /// </summary>
            public string HttpMethod { get; set; }
    
            /// <summary>
            /// 请求的IP地址
            /// </summary>
            public string IP { get; set; }
        }
    }
    

      

    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Http;
    using Microsoft.Extensions.DependencyInjection;
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace NetCore3WebApiTemplate.Utility
    {
        public static class CommonHttpContext
        {
            private static IHttpContextAccessor accessor;
    
           
    
            public static HttpContext Current => accessor.HttpContext;
    
            internal static void Configure(IHttpContextAccessor accessor)
            {
                CommonHttpContext.accessor = accessor;
            }
        }
    
        public static class StaticHttpContextExtensions
        {
    
    
            public static IApplicationBuilder UseStaticHttpContext(this IApplicationBuilder app)
            {
                var httpContextAccessor = app.ApplicationServices.GetRequiredService<IHttpContextAccessor>();
                CommonHttpContext.Configure(httpContextAccessor);
                return app;
            }
        }
    
    
        public static class CommonServiceProvider
        {
            public static IServiceProvider ServiceProvider
            {
                get; set;
            }
        }
    }
    

      

    在startup的ConfigureServices中设置或禁用WebApiExceptionFilterAttribute或WebApiTrackerAttribute

      /// <summary>
            /// This method gets called by the runtime. Use this method to add services to the container.
            /// </summary>
            /// <param name="services"></param>
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddControllers(ops =>
                {
                    ops.Filters.Add(new WebApiExceptionFilterAttribute());
                    ops.Filters.Add(new WebApiTrackerAttribute());
                }).SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
                
            }
    

      

  • 相关阅读:
    IIS中安全证书更新
    mac权限相关命令
    Nlog配置Seq日志服务
    WPF Prism8.0中注册Nlog日志服务
    .NET MAUI Preview7 状态预览(8月)
    RPA剖析浏览器API(获取指定页面数据)
    .NET Core Worker Service
    .NET MAUI Preview6 状态预览(7月)
    Digicert GeoTrusy Cloud DV
    【Tomcat8】开启Https及挂载静态文件
  • 原文地址:https://www.cnblogs.com/binbinxu/p/13061446.html
Copyright © 2020-2023  润新知