房产中介管理软件第12课:使用Serilog做全局的错误处理

发布时间 2023-03-22 21:16:53作者: RandyTech

因为代码用于学习,把前端框架从Ant Design Vue改为了vue-admin-plus,正版购买。

后面教程和界面可能和前11课差距较大。

本文介绍如何使用Serilog来进行全局的错误处理。

一、nuget引用Serilog

二、appsettings.json中进行serilog的配置

//Serilog日志组件配置
  "Serilog": {
    "MinimumLevel": {
      "Default": "Debug", //最小日志记录级别
      "Override": { //系统日志最小记录级别
        "Default": "Information",
        "System": "Information",
        "Microsoft": "Information"
      }
    },
    "WriteTo": [
      { "Name": "Console" } //输出到控制台
    ]
  }

目前只配置到显示console,后期会配置输出到seq

为了在console中展示效果,override里的级别都设置成了Information,不然部分信息不会显示,后期可以根据需要调整为Warning

三、Program.cs中加载配置

//Serilog日志
builder.Host.UseSerilog((context, logger) =>
{
    logger.ReadFrom.Configuration(context.Configuration);
    logger.Enrich.FromLogContext();
});

配置完成后会接管系统的log输出,.net 6没有Startup.cs文件,配置直接卸载Program.cs文件里

四、全局错误处理中间件

新建文件ExceptionHandlingMiddleware.cs,用于拦截所有全局错误

/// <summary>
    /// 全局Exception处理
    /// </summary>
    public class ExceptionHandlingMiddleware
    {
        private readonly RequestDelegate _next;  // 用来处理上下文请求  
        private readonly ILogger<ExceptionHandlingMiddleware> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="next"></param>
        /// <param name="logger"></param>
        public ExceptionHandlingMiddleware(RequestDelegate next, ILogger<ExceptionHandlingMiddleware> logger) {
            _next = next;
            _logger = logger;
        }

        /// <summary>
        /// InvokeAsync
        /// </summary>
        /// <param name="httpContext"></param>
        /// <returns></returns>
        public async Task InvokeAsync(HttpContext httpContext)
        {
            try
            {
                await _next(httpContext); //要么在中间件中处理,要么被传递到下一个中间件中去
            }
            catch (Exception ex)
            {
                await HandleExceptionAsync(httpContext, ex); // 捕获异常了 在HandleExceptionAsync中处理
            }
        }

        /// <summary>
        /// 异步处理
        /// </summary>
        /// <param name="context"></param>
        /// <param name="exception"></param>
        /// <returns></returns>
        private async Task HandleExceptionAsync(HttpContext context, Exception exception)
        {
            // 记录日志
            _logger.LogError(exception.StackTrace);

            //返回信息
            //context.Response.Clear();
            context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
            context.Response.ContentType = "application/json;charset=utf-8";  // 返回json 类型
            
            var errorResponse = new BaseResponse{
                code = (int)HttpStatusCode.InternalServerError,
                msg = exception.Message
            };
            
            var result = JsonUtility.ToString(errorResponse);
            await context.Response.WriteAsync(result);
        }

    }

此代码的含义是拦截错误并进行记录,然后返回。

BaseRespone是自定义的一个方法,用于通用的返回,主要是code、msg、data字段。

JsonUtility的ToString方法是把Object转为String字符串。

五、Program.cs文件中使用全局错误处理中间件

//使用全局错误控制中间件
app.UseMiddleware<ExceptionHandlingMiddleware>();

六、建立一个测试路由和函数,进行全局文件的测试

直接在接口中调用如下方法,检查console窗口是否会记录错误,并且页面会返回正常json数据

//测试全局异常
throw new System.IO.IOException();

(本文完)