SpringBoot日志
概念
- 日志文件:日志文件是用于记录系统操作事件的文件集合,可分为调试日志和系统日志。具有处理历史数据、诊断问题的追踪以及理解系统的活动等重要作用。
- 调试日志文件:软件开发中,我们经常需要去调试程序,做一些信息,状态的输出便于我们查询程序的运行状况,调试日志就可以帮我们记录下来方便查看
- 系统日志:系统日志是记录系统中硬件、软件和系统问题的信息,同时还可以监视系统中发生的事件。用户可以通过它来检查错误发生的原因,或者寻找受到攻击时攻击者留下的痕迹。系统日志包括系统日志、应用程序日志和安全日志。
日志框架介绍
日志门面:
日志实现:
日志门面就是在日志框架和应用程序之间架设一个沟通的桥梁(如JDBC),主要是为了给Java日志访问提供一套标准、规范的API框架。但是日志的配置文件还是写日志实现自身的配置文件
常用选择(SpringBoot底层也是这样的搭配):SLF4j(门面)+ Logback(实现)
SLF4j使用
最基本的使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @Slf4j @SpringBootTest class ApplicationTests { @Test void logTest() { log.trace("trace级别"); log.debug("debug级别"); log.info("info级别"); log.warn("warning级别"); log.error("error级别"); } }
|
效果:
SpringBoot默认是INFO级别
相关配置
- 修改级别:
logging.level.包名=级别
- 输出日志文件:可以配置
logging.file=文件名/路径
或者logging.path=目录
- 修改输出日志的格式:
logging.pattern.console/file=格式
- 如果需要指定完整的配置,可以将logback的配置文件(logback.xml/logback-spring.xml)放在类路径下
通过AOP来打日志
如果一个一个接口的自己手动打日志相当麻烦,完全就可以通过注解+AOP的方式来打日志,这样也比较灵活方便,只需要给想打日志的方法上加上注解,aop会自动对方法进行代理增强,切入日志进来
自定义的日志注解
1 2 3 4 5 6 7 8 9 10 11 12
|
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface SystemLog {
String businessName(); }
|
配置切面类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| @Component @Aspect @Slf4j public class LogAspect {
@Pointcut("@annotation(com.wht.annotation.SystemLog)") public void pt(){};
@Around("pt()") public Object printLog(ProceedingJoinPoint joinPoint) throws Throwable { Object res; try { handleBefore(joinPoint); res = joinPoint.proceed(); handleAfter(res); } finally { log.info("=======END======="+System.lineSeparator()); } return res; } private void handleAfter(Object res) { log.info("Response :{}",JSON.toJSONString(res));
} private void handleBefore(ProceedingJoinPoint joinPoint) { ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = requestAttributes.getRequest();
SystemLog systemLog = getSystemLog(joinPoint);
log.info("=======Start======="); log.info("URL : {}",request.getRequestURI()); log.info("BusinessName : {}",systemLog.businessName()); log.info("HTTP Method : {}",request.getMethod() ); log.info("Class Method : {}.{}", joinPoint.getSignature().getDeclaringTypeName(),((MethodSignature) joinPoint.getSignature()).getName()); log.info("IP : {}",request.getRemoteHost()); log.info("Request Args : {}", JSON.toJSONString(joinPoint.getArgs()));
}
private SystemLog getSystemLog(ProceedingJoinPoint joinPoint) { MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); SystemLog systemLog = methodSignature.getMethod().getAnnotation(SystemLog.class); return systemLog; }
}
|
注意需要导入AOP依赖:
1 2 3 4 5
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
|
测试:
1 2 3 4 5
| @SystemLog(businessName = "测试校验") @PostMapping("/insert") public String insertTestUser(@RequestBody @Validated TestDemo testUser){ return "success"; }
|
效果: