5.使用日志+自定义全局异常过滤器

这篇具有很好参考价值的文章主要介绍了5.使用日志+自定义全局异常过滤器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

刚开始写文章,封装Base基类的时候,添加了trycatch异常块,不过当时没有去记录日志,直接return了。有小伙伴劝我不要吃了Exception

5.使用日志+自定义全局异常过滤器

 其实没有啦,项目刚开始,我觉得先做好整体结构比较好。像是盖楼一样。先把楼体建造出来,然后再一步一步的美化完善。

基础的仓储模式已经ok,Autofac已经注入了项目的实现层。上篇文章新建了一个Test类主要用于测试,加了4个接口增删改查,执行也是完全没有问题的。这篇文章开始就是逐步完善优化项目。


关于日志有很多选择,我记得上篇我也提到过几个,好,那我就再重复一下:Nlog,Log4,Serilog……

我这里使用的是Nlog,以前用的Log4,都是自己封装一个Helper类,后来学NetCore的时候看到Nlog使用着好简单,而且后面也搜了下大佬们对两者的对比,综合对比我觉得Nlog更好一点~性能现在应该差不多,因为那篇文章14年的,放个当时大佬的对比(现在应该也差不多少吧,看个人习惯了,用习惯了怎么都好用)

项目 log4net nlog
流行程度
易用性
动态配置
输出目标
跨平台
开源持续维护
日志性能

 

先稍微梳理一下逻辑。日志这东西一般程序都会有,但是你真没有的话,其实也不影响程序跑对吧~再者依赖注入你肯定要在程序层有Nlog的直接或间接引用的,要么你哪个地方(类库)用到就安装一个Nlog包,要么在最底层仓储层安装一个Nlog包,间接引用到程序层。好像也没啥影响,但我就是觉得怪怪的,感觉这样会不会增加耦合? 唉,这方面我还真是学的不到家,希望关于这块儿有了解的可以讨论一下,我再学学~

我的做法呢,就是把Nlog安装到Common公共类库中。这个类库是在上个文章新建的。用意就是专门弄一些很多地方都会用到的东西,但是我即便不用也不影响程序跑的东西。比如Autofac……所以日志我也打算加到此处……

在Common类库安装Nlog程序包:NLog.Extensions.Logging

5.使用日志+自定义全局异常过滤器

 在Common类库下新建一个文件  Logs\Nlog\NlogModule.cs 。我搞这么多文件夹一方面看着比较容易看得懂,另一方面,后面打算添加一些其他的日志给大家一个参考。

NlogModule是静态类,添加静态方法AddNlogModule,注入Nlog:

        public static void AddNlogModule(this IServiceCollection Services)
        {
            Services.AddLogging(logging =>
            {
                logging.AddNLog();
            });
        }

然后,好像没然后咯~

上篇文章中,将Common添加到IRepository层的项目引用。可以说已经贯穿了整个项目(直接或间接引用)。所以只需要在API程序层的Programs中添加Nlog模块就好。

        builder.Services.AddNlogModule();//Nlog

(拍头)忘了一个重要的地方。Nlog的config配置:主要配置你的日志怎么记录,记录到哪里,记录格式等

5.使用日志+自定义全局异常过滤器

 配置如下,也无需花心思在这上面,官网和网上都有模板,自己简单配置一下,保存,以后用到了直接拷贝就好,我做了简单的注释,应该都看的明白,所以不多说什么啦~

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <targets async="true">
        <!--maxArchiveDays最长保存N天,archiveAboveSize一个文件最大为N字节-->
        <target name="LogDebug" xsi:type="File" maxArchiveDays="7" archiveAboveSize="10485760"  fileName="Logs/Debug信息/【${shortdate}】.txt" layout="【${date}】【${logger}】${newline}${message:withexception=true}${newline}${newline} " />
        <target name="LogInfo" xsi:type="File" maxArchiveDays="7" archiveAboveSize="10485760"  fileName="Logs/Info信息/【${shortdate}】.txt" layout="【${date}】【${logger}】${newline}${message:withexception=true}${newline}${newline} " />
        <target name="LogError" xsi:type="File" maxArchiveDays="7" archiveAboveSize="10485760"  fileName="Logs/Error信息/【${shortdate}】.txt" layout="【${date}】【${logger}】${newline}${message:withexception=true}${newline}${newline} " />
    </targets>

    <rules>
        <!--日志记录规则,符合规则的writeTo到相应的日志目标中-->
        <logger name="Microsoft.*"  writeTo="" final="true" />
        <!--日志记录规则,符合规则的writeTo到相应的日志目标中-->
        <logger name="*" level="Error" writeTo="LogError" final="true" />
        <logger name="*" level="Info"  writeTo="LogInfo" final="true" />
        <logger name="*" level="Debug" writeTo="LogDebug" final="true" />
    </rules>
</nlog>

 到这里已经完成了。在你需要的地方通过构造函数注入即可,例如:

5.使用日志+自定义全局异常过滤器

 这种Ilogger<T>是泛型接口,可以通过尖括号里的类名找到相关的依赖,简单来说记录日志的时候可以输出错误信息是在哪个地方产生的。也可以根据这个来设置过滤,或输出日志到不同的地方。

上上篇文章的代码生成器是默认是没有添加Nlog的,所以构造函数里也没有添加,如果你需要在服务层或仓储层记录详细信息Info或者Debug的话,根据自己的需求去构造注入吧。正常情况下,记录异常就足够用了。

欸,那问题就来了,你说我仓储层服务层没有构造函数注入,那我异常了怎么记录呢?有的人说,throw丢出去呀,丢到程序层……确实可以,但是稍微微有点麻烦吧?仓储层裹一层,丢到服务层,服务层裹一层丢到程序层,然后程序层再记录日志?so~封装一个全局异常记录模块儿~

这个是官方的接口,同时程序一定要对异常进行处理,这个是必要的。不然既不好排查问题,生产使用的时候一报错就挂掉,那可就凉了……所以这个全局异常处理我将添加在程序层下

新建一个类(自己随便起名哈,里面的内容一样就行)GlobalExceptionFilter,继承接口IExceptionFilter:异常过滤器

public class GlobalExceptionFilter : IExceptionFilter
    {
        //构造注入Nlog
        private readonly ILogger<GlobalExceptionFilter> logger;
        public GlobalExceptionFilter(ILogger<GlobalExceptionFilter> _)
        {
            logger = _;
        }

        //实现接口,对异常进行处理
        public void OnException(ExceptionContext context)
        {
            //记录异常到日志
            StringBuilder exMsg = new();
            exMsg.AppendLine($"【异常方法:】{context.HttpContext.Request.Path}");
            exMsg.AppendLine($"【请求类型:】{context.HttpContext.Request.Method}");
            exMsg.AppendLine($"【异常错误:】{context.Exception.Message}");
            exMsg.AppendLine($"【堆栈跟踪:】{context.Exception.StackTrace}");
            logger.LogError(exMsg.ToString());
            // 创建自定义错误响应
            var result = new ObjectResult(new { error = context.Exception.Message })
            {
                StatusCode = 400, // 设置适当的HTTP状态码
                DeclaredType = typeof(object) // 声明类型,以确保内容被正确序列化
            };
            // 取消异常的传播,以防止默认的500错误
            context.ExceptionHandled = true;
            // 设置响应结果
            context.Result = result;
        }
    }

Programs里面添加注入,将其注入进控制器服务。松耦合,控制器相关的依赖,只要里面有trycatch都可以接收并处理,简单来说你这程序里面的异常最终都到这个方法里面进行处理,并且可以重写返回结果,不会只报一个500错误和一堆的堆栈错误信息。注入的代码如下,我还是单独弄成模块类,感觉这样拆除比较方便,不知道我这种做法是否合理,还是多余。但我自己看着还是比较顺眼的,希望有更多的建议~~~

    public static class ExceptionModule
    {
        public static void AddExceptionModule(this IServiceCollection Services)
        {
            Services.AddControllers(Ex =>
            {
                Ex.Filters.Add<GlobalExceptionFilter>();
            });
        }
    }
builder.Services.AddExceptionModule();//全局异常

撒花~~~结束~~~手动搞个错误信息看下返回内容并且看下记录的日志~

5.使用日志+自定义全局异常过滤器

5.使用日志+自定义全局异常过滤器

 欢迎留言,虚心听取大家建议,听人劝吃饱饭~~~掰掰~~文章来源地址https://www.toymoban.com/news/detail-712125.html

到了这里,关于5.使用日志+自定义全局异常过滤器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringCloudGateway过滤器(全局认证、IP拦截、请求参数过滤、响应参数过滤)

    全局过滤器(认证) IP网关过滤器 请求参数网关过滤器

    2024年02月14日
    浏览(28)
  • Spring Cloud GateWay 全局过滤器

    这是一个自定义的 Spring Cloud Gateway 全局过滤器(Global Filter)。在 Spring Cloud Gateway 中,全局过滤器可以在请求被路由到目标服务之前或之后执行一些操作。这个过滤器实现了 GlobalFilter 接口和 Ordered 接口,这两个接口的作用如下: GlobalFilter 接口: 这是一个 Spring Cloud Gateway 提

    2024年02月11日
    浏览(33)
  • 【Spring Cloud】深入探索统一网关 Gateway 的搭建,断言工厂,过滤器工厂,全局过滤器以及跨域问题

    在微服务架构中,网关是至关重要的组件,具有多重职责,为整个系统提供了一系列关键功能。从下面的微服务结构图中,我们可以明确网关的几项主要作用: 微服务结构图: 请求过滤与安全: 用户的所有请求首先经过网关,这使得网关成为系统的第一道防线。通过对传入

    2024年02月07日
    浏览(43)
  • NestJS 的 异常过滤器学习

    NestJS 带有一个内置的异常层,负责处理应用程序中所有未处理的异常。当应用程序代码未处理异常时,该层会捕获异常,然后自动发送对应的异常响应给用户。 在 NestJs 中默认异常过滤器为 HttpException 及其子类,当异常无法不属于 HttpException 或者子类的时候,内置的异常过滤

    2024年02月14日
    浏览(35)
  • Spring Cloud Gateway GlobalFilter(全局过滤器)详解(官方原版)

    GlobalFilter接口具有与GatewayFilter相同的签名。这些是有条件地应用于所有路由的特殊过滤器。 当请求与路由匹配时,过滤web处理程序会将GlobalFilter的所有实例和GatewayFilter的所有路由特定实例添加到过滤器链中。这个组合过滤器链由org.springframework.core.Ordered接口排序,您可以通

    2024年02月09日
    浏览(36)
  • gateway过滤器中实现记录访问日志

    SpringCloud多服务项目环境,前端请求经过网关中转发到各个服务节点。日志中需要记录请求头中的部分参数、请求的body、响应状态及响应内容,并在请求头中新增一个标识。 PS: 1.Order 最高优先级。 2.Request Header 不可添加值,需重新创建后绑定。 3.Request Body IO流,读取一次后

    2024年02月15日
    浏览(33)
  • SpringCloud GateWay 在全局过滤器中注入OpenFeign网关后无法启动

    目录 一、问题 二、原因 1、修改配置 2、添加@Lazy注解在client上面  3、启动成功 当在gateway的全局过滤器GlobalFilter中注入OpenFeign接口的时候会一直卡在路由中,但是不会进一步,导致启动未成功也未报错失败 在gateway网关中不能使用openfeign同步调用 三、解决方法 在注入的Aut

    2024年01月19日
    浏览(33)
  • Druid作为数据源(连接池、过滤器、日志)

    name :数据源名称如果存在多个数据源,监控的时候可以通过名字来区分开来 如果没有配置,将会生成一个名字,格式是\\\"DataSource-\\\"+System.identityHashCode(this) jdbcUrl :连接数据库的 url,不同数据库不一样 username :连接数据库的用户名 password :连接数据库的密码 driverClassName :数

    2024年01月18日
    浏览(36)
  • 开发笔记 | JAVA过滤器Filter实现全局接口入参去除前后空格

    目录 思考过程 遇到的问题 过滤器Filter使用步骤 全局去除入参前后空格代码实现 处理过程中自己造成的一些问题 需求背景: 前端所有的条件查询去除前后空格,如搜 【\\\"   测试    \\\"】后端将其转为【测试】。之前都是前端统一处理的,但是这次要后端处理,那么就得考虑

    2024年02月12日
    浏览(30)
  • 登录页面jwt密钥,过滤器,拦截器,异常处理

    需求: 用户未登录时,访问其他也没面,操作添加、删除等操作时,强行跳转至登录页面。 实现方法: 1.使用Cookie,登录后后端添加一个cookie,每次页面判断是否有cookie, 2。使用session,原理同上,只不过session是存储在服务器里的,cookie是在浏览器里。 3。使用jwt令牌,登

    2023年04月25日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包