实现打印异常日志_老生常谈SpringAop日志收集与处理做的工具包

a4c09e7d9aab01bf38c346d4d368355d.png

场景 :

  1. 使用Spring Aop拦截参数日志目前大部分做法都基本上大同小异,不想日后每个项目工程都写一份这样的Aop拦截处理日志的代码,甚至代码侵入。
  2. 我想知道一些相对重要的请求方法的请求参数,响应参数,请求头,以及内部耗时,方法是成功还是失败等等信息。发生错误时我也不知道执行到哪一步发生了异常,是不是某个参数导致出的逻辑问题。
  3. 普通的log.info或warn信息没有所属请求的上下关系,并不方便查看和分析。
  4. 正式环境中,我并不想打印太多无意义的info日志(有些只是为了排查问题打印的日志,程序正常运行时其实毫无意义),只希望在发生异常时记录日志或者只希望每次请求只记录一条关键的请求信息。
  5. 日志的收集,我希望将这些请求的日志记录下来,记录的实现方式我自己决定,比如正常的日志打印,常见的日志写入数据库,日志写入到文件,日志入队列等等。
  6. 整个日志的记录完全不干扰正常请求方法的流程,日志的收集处理异步化,完全不影响正常请求方法的性能与响应。
  7. 只需要通过@AopLog注解决定是否记录。

快速开始

项目通过maven的pom.xml引入

<dependency>
    <groupId>com.github.ealenxiegroupId>
    <artifactId>aop-logartifactId>
    <version>2.2version>
dependency>

或者通过gradle引入

compile group: 'com.github.ealenxie', name: 'aop-log', version: '2.2'

@AopLog注解使用,进行日志记录

直接在类(作用类的所有方法)或类方法(作用于方法)上加上注解@AopLog,进行日志记录

例如 :

import com.github.AopLog;
import name.ealen.infra.base.resp.RespBody;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author EalenXie create on 2020/6/22 14:28
 */
@AopLog(type = "测试",stackTraceOnErr = true)
@RestController
public class AppController {

    @GetMapping("/app/sayHello")
    public RespBody sayHello() {
        return RespBody.ok("hello EalenXie");
    }

}

自定义全局的日志收集器实现收集 LogCollector

例如只是简单打印,或写入到库等等。

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.LogData;
import com.github.collector.LogCollector;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * @author EalenXie create on 2020/9/15 13:46
 * 此为样例参考
 * 配置一个简单的日志收集器 这里只是做了一个log.info打印一下,可以在这里写入到数据库中或者写入
 */
@Slf4j
@Component
public class AopLogCollector implements LogCollector {
    private ObjectMapper objectMapper = new ObjectMapper();
    @Override
    public void collect(LogData logData) {
        try {
            log.info(objectMapper.writeValueAsString(logData));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }
}

配置@Component的全局日志收集器只能配置一个。

接口调用 /say/hello 测试即可看看到控制台打印出结果 :

2020-09-16 16:01:04.782  INFO 2012 --- [AsyncExecutor-2] name.ealen.infra.advice.AopLogCollector  : {"appName":"app-template","host":"127.0.0.1","port":8080,"clientIp":"192.168.110.1","reqUrl":"http://localhost:8080/app/sayHello","httpMethod":"GET","headers":{"User-Agent":"Apache-HttpClient/4.5.10 (Java/11.0.5)"},"type":"测试","content":"","method":"name.ealen.api.facade.AppController#sayHello","args":null,"respBody":{"code":"200","desc":"OK","message":"请求成功","dateTime":"2020-09-16 16:01:04","body":"hello EalenXie"},"logDate":1600243264780,"costTime":1,"threadName":"http-nio-8080-exec-3","threadId":33,"success":true}

记录的日志对象LogData属性说明

「LogData 记录的内容」

字段类型注释
appNameString应用名称
hostString主机
portint端口号
clientIpString请求客户端的Ip
reqUrlString请求地址
headersObject请求头部信息(可选择记录) 默认记录user-agent,content-type
typeString操作类型,默认值undefined
contentString方法步骤内容,默认是空,可使用LogData.step进行内容步骤记录
methodString请求的本地java方法
argsObject方法请求参数
respBodyObject方法响应参数
costTimelong整个方法耗时
logDateDateLog产生时间,LogData对象初始化的时间
threadNameString线程名称
threadIdlong线程Id
successboolean执行状态,成功(true)/异常(false)

AopLog 注解选项说明

选项类型说明默认
logOnErrboolean仅当发生异常时才记录收集false
typeString操作类型默认值"undefined"
headersString[]记录的header信息 ,选择要记录哪些header信息默认"User-Agent","content-type"
argsboolean是否记录请求参数true
respBodyboolean是否记录响应参数true
stackTraceOnErrboolean当目标方法发生异常时,是否追加异常堆栈信息到LogData的content中false
asyncModeboolean异步方式收集true
collectorClass extends LogCollector>指定日志收集器默认不调整收集器,使用全局的日志收集器

LogData的step方法。

记录步骤。(如果某些重要步骤希望被记录下来) 例如 :

import com.github.AopLog;
import com.github.LogData;
import name.ealen.infra.base.resp.RespBody;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;


/**
 * @author EalenXie create on 2020/6/22 14:28
 */
@AopLog(type = "测试",stackTraceOnErr = true)
@RestController
public class AppController {


    @GetMapping("/app/sayHello")
    public RespBody sayHello() {
        LogData.step("1. 第一步执行完成");
        //......
        LogData.step("2. 第二步执行完成");
        //.....
        LogData.step("3. service的方法执行完成");
        //.....return RespBody.ok("hello EalenXie");
    }
}

此时再次接口调用 /say/hello 测试即可看看到控制台打印出结果,重点观察content字段 :

2020-09-16 17:26:20.285  INFO 3284 --- [AsyncExecutor-2] name.ealen.infra.advice.AopLogCollector  : {"appName":"app-template","host":"127.0.0.1","port":8080,"clientIp":"192.168.110.1","reqUrl":"http://localhost:8080/app/sayHello","httpMethod":"GET","headers":{"User-Agent":"Apache-HttpClient/4.5.10 (Java/11.0.5)"},"type":"测试","content":"1. 第一步执行完成\n2. 第二步执行完成\n3. service的方法执行完成\n","method":"name.ealen.api.facade.AppController#sayHello","args":null,"respBody":{"code":"200","desc":"OK","message":"请求成功","dateTime":"2020-09-16 17:26:20","body":"hello EalenXie"},"logDate":1600248380283,"costTime":1,"threadName":"http-nio-8080-exec-2","threadId":32,"success":true}

关于

开源Github地址 : https://github.com/EalenXie/aop-log

作者:风雪漫中州

https://www.cnblogs.com/ealenxie/p/13685216.html

a6a0291d507a06f109208af63c2fe313.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/397247.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

服务器128g内存显示64g,64g内存服务器

64g内存服务器 内容精选换一换华为云帮助中心&#xff0c;为用户提供产品简介、价格说明、购买指南、用户指南、API参考、最佳实践、常见问题、视频帮助等技术文档&#xff0c;帮助您快速上手使用华为云服务。接口名称GetCloudPhoneServerModelsGetCloudPhoneServerModels功能描…

IOPLL动态重配

连接 Avalon -MM接口 mgmt_waitrequest:当 PLL 重配置进程开始后&#xff0c;此端口变高并在 PLL 重配置期间保持高电平。 PLL 重配置进程完成后&#xff0c;此端口变低。 I/O PLL重配写操作步骤&#xff1a; 1、 为mgmt_address和mgmt_writedata设置有效值&#xff0c;并且…

qt中如何模拟按钮点击_如何快速在 Shopify 中加入按钮

假如你会 CSS , HTML , JS 三件套&#xff0c;那么修改 Shopify 代码将不会太难&#xff08;毕竟一个模板中的代码量还是挺多的&#xff0c;除非深入研究了代码&#xff0c;不然改起来还是会比较麻烦的&#xff09;。但挺多玩家是不会这三件套的&#xff0c;修改代码来达到添加…

浅谈关于java中的深浅拷贝

一.浅拷贝(shallow copy) 1.如何实现浅拷贝? Object类 是所有类的直接或间接父类,Object中存在clone方法,如下 protected native Object clone() throws CloneNotSupportedException; 如果想要使一个类的对象能够调用clone方法 ,则需要实现Cloneable接口, 并重写 clone方法: p…

iOS开发-Protocol协议及委托代理(Delegate)传值

前言&#xff1a;因为Object&#xff0d;C是不支持多继承的&#xff0c;所以很多时候都是用Protocol&#xff08;协议&#xff09;来代替。Protocol&#xff08;协议&#xff09;只能定义公用的一套接口&#xff0c;但不能提供具体的实现方法。也就是说&#xff0c;它只告诉你要…

git 查看分支编码_12个常用的Git命令,赶紧记一波!

今天齐姐简单讲下 Git 的实现原理&#xff0c;知其所以然才能知其然&#xff1b;并且梳理了日常最常用的 12 个命令&#xff0c;分为三大类分享给你。本文的结构如下&#xff1a;作者和开发原由Git 的数据模型常用命令资源推荐作者和开发原由Talk is cheap. Show me the code.这…

会做饭的机器人曰记_颜真卿《麻姑仙坛记》:苍劲古朴,体态沉雄,气象宏大...

《麻姑仙坛记》&#xff0c;全称《有唐抚州南城县麻姑山仙坛记》&#xff0c;或称《麻姑山仙坛记》。颜真卿撰并书于大历六年&#xff08;771&#xff09;四月。此碑有大、中、小三种刻本&#xff0c;且原石均佚&#xff0c;原拓佳本亦难得。大字本&#xff0c;字径约5厘米&…

Metro UI 菜单(Winform)

我有个项目需要要到菜单导航&#xff0c;就自己动作做了一个&#xff0c;感觉还可以&#xff0c;分享给大家。下载地址:http://files.cnblogs.com/files/dyj057/MetroUIMenu.zip 主要代码&#xff1a; private void SetElements(){if (Elements null) return;int eWidth Bord…

echarts 山东地图_用Python画中国地图,实现各省份数据可视化

第一步&#xff1a;安装pyechartspyecharts是一款将python与echarts结合的强大的数据可视化工具&#xff0c;本文使用了0.1.9.4版本pip install pyecharts0.1.9.4第二步&#xff1a;读取数据我的数据是在Excel表格里&#xff0c;如下图&#xff1a;Execel数据使用xlrd(没有就通…

mysql 中某个字段相同的数据拼接起来

2019独角兽企业重金招聘Python工程师标准>>> mysql> select name, GROUP_CONCAT( age SEPARATOR ‘#’) from student group by name; ——————————————————— | name | GROUP_CONCAT( age SEPARATOR ‘#’) | ———————————————…

微信红包系统架构的设计和优化分享

微信红包系统架构的设计和优化分享 编者按&#xff1a;经过2014年一年的酝酿&#xff0c;2015微信红包总量创下历史新高&#xff0c;峰值1400万次/秒&#xff0c;8.1亿次每分钟&#xff0c;微信红包收发达10.1亿次&#xff0c;系统整体运行平稳, 在这里我分享下微信红包背后的技…

FastDFS单机版安装教程

安装清单如下&#xff1a; 一、安装FastDFS 1. 安装libfastcommon 先解压安装包到目录 # unzip libfastcommon-1.0.36.zip 安装编译工具及环境&#xff08;后面Nginx也会用到这些依赖环境&#xff09; # yum -y install gcc gcc gcc-c openssl openssl-devel pcre pcre-deve #…

【原创】Chrome最新版(53-55)再次爆出BUG!

2019独角兽企业重金招聘Python工程师标准>>> 前言 今年十月份&#xff0c;我曾发布一篇文章《Chrome53 最新版惊现无厘头卡死 BUG&#xff01;》&#xff0c;不过那个BUG在最新的 Chrome 54 中已经修正。 而今天即将发布的Chrome弱智BUG&#xff1a; 仅 Chrome 53 -…

进程kswapd0与events/0消耗大量CPU的问题

http://www.nowamagic.net/librarys/veda/detail/2539 今天下午网站宕了两次机&#xff0c;发工单给阿里云&#xff0c;发现原因是服务器的CPU 100%了。 重启服务器后&#xff0c;使用 top 命令看看是哪些进程消耗那么大的 CPU 使用。盯了有好十几分钟&#xff0c;主要消耗 CPU…

跑三小时的monkey测试该怎么算_浅谈App测试(下)~带音频

文 | Vicky采编&#xff5c;Emily浅谈App测试(上)&#xff5e;带音频一、功能测试​二、性能测试(1)耗电量影响因素&#xff1a;定位、传感器、蓝牙&#xff0c;其中CPU、持续定位是两个平台造成耗电的主要因素。(2)流量也就是常说的耗流量&#xff0c;影响因素有重复请求&…

2016-2017-2 《Java程序设计》课程学生博客和代码托管链接

2016-2017-2 《Java程序设计》课程学生博客和代码托管链接 博客 1552 20155201 李卓雯20155202 张 旭20155203 杜可欣20155204 王 昊20155205 郝博雅20155206 赵 飞20155207 王雪纯20155208 徐子涵20155209 林虹宇20155210 潘滢昊20155211 解雪莹20155212 江振思20155213 陆忠民…

回顾一年的工作历程_【设备管理公司】召开20202021年度总结计划表彰暨工作述职会议...

点击上方蓝字关注我们2020年即将过去&#xff0c;为了总结2020年各项工作开展情况&#xff0c;同时做好2021年工作计划与部署&#xff0c;2020年12月30日-31日&#xff0c;设备管理公司组织召开了2020-2021年度总结计划表彰暨工作述职会议。公司领导、各部门经理、部门主管、车…

注册验证的时候一直出现的报错问题,终于解决了

今天再注册验证表单的时候一直报错&#xff0c;但是什么都没有改&#xff0c;就报错了&#xff0c;后面才知道原来是和我上次上传图片的时候&#xff0c;导入的2个js的顺序有关系的&#xff0c; 45行和41行互相换一下位置就好了 转载于:https://www.cnblogs.com/likeji/p/61433…

重排序

一、重排序。 1、为什么需要重排序&#xff1f; 现在的CPU一般采用流水线来执行指令。一个指令的执行被分成&#xff1a;取指、译码、访存、执行、写回、等若干个阶段。然后&#xff0c;多条指令可以同时存在于流水线中&#xff0c;同时被执行。 指令流水线并不是串行的&#x…

tableau三轴该怎么做_如何用tableau绘制城市地铁线路图?

在用tableau绘制地铁线路图之前&#xff0c;当然是要获取相关的数据啦我们以郑州目前已开通的地铁为例&#xff0c;分别是1、2、5号线经度、维度可在 网页上自行搜索哦&#xff08;以谷歌地图为准&#xff09;有了这些下面我们就要开始啦将Excel中你所需要的数据直接导入到tabl…