一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第28天,点击查看活动详情
无入侵式记录日志
最近项目需要给每个接口方法都加上日志记录,记录一些关键信息,比如方法执行的时间、方法执行的ip、执行的方法是哪个、以及方法入参和方法出参等等。
如果按照传统的日志记录比如方法执行时间那就是在每个方法的开始和结束记录一下执行时间然后相减获得方法执行时间,但是这样子操作很麻烦第一是每个方法都有加上这些臃肿的日志代码,第二是原本和业务不想关的日志代码嵌入到业务代码里了需要额外维护这些日志代码,这一系列操作会将会造成业务代码臃肿和代码重复性非常高,这里我们可以将能复用的公共代码抽取到一个方法内可以有效减少一些日志代码的重复,但是不可能全部都可以复用,比如每个方法的入参和出参这种就无法抽取。
那么有没有更好的方式可以更加优雅且简洁的实现方式呢?答案是肯定的,比如使用spring的aspect切面,aspect切面有五种通知,这里使用around环绕通知,环绕通知可以在方法执行前后做一些操作比如获取出入参数记录执行时间。
1.第一步定义切点pointcut,指定需要记录日志信息的接口方法,这里我指定的是项目controller层下所有的controller类的所有方法,如下图:
2.第二步就是编写around环绕通知的方法体了,首先环绕通知需要有一个ProceedingJoinPoint参数,这个参数是固定的,可以获取到方法的入参也可以执行方法,首先获取到HttpServletRequest请求,根据请求可以获取到当前执行方法的URL、执行方法名称、入参以及执行方法的类型,比如是post还是get,如果是post请求那么参数一般都是一个对象,日志打印需要使用json格式,这里由于每个方法传参不一样,所以可以先将入参对象转为class对象再去获取其filed字段信息存入map转为json输出即可,如果是get直接将参数转字符串即可,也可以根据请求头里的token去获取当前执行方法的账户信息,如下图: