ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2020-06-07 18:06:04  阅读:281  来源: 互联网

标签:Core set 记录 get public HttpContext context 全局 logModel


在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);
            
        }

  

标签:Core,set,记录,get,public,HttpContext,context,全局,logModel
来源: https://www.cnblogs.com/binbinxu/p/13061446.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有