往期精彩推荐
SpringBoot系列(一)idea新建Springboot项目
SpringBoot系列(二)入门知识
springBoot系列(三)配置文件详解
SpringBoot系列(四)web静态资源配置详解
SpringBoot系列(五)Mybatis整合完整详细版
SpringBoot系列(六)集成thymeleaf详解版
Springboot系列(七) 集成接口文档swagger,使用,测试
SpringBoot系列(八)分分钟学会Springboot多种解决跨域方式
SpringBoot系列(九)单,多文件上传的正确姿势
SpringBoot系列(十)优雅的处理统一异常处理与统一结果返回
SpringBoot系列(十一)拦截器与拦截器链的配置与使用详解,你知道多少?
SpringBoot系列(十二)过滤器配置详解
本文目录
- 一、SpringBoot中的日志
- 二、自定义日志常用配置
- 1. 日志输出级别
- 2. 日志输出到文件
- 3. 自定义日志输出格式
- 三、xml文件实现日志配置的方式
- 四、AOP + 自定义注解实现统一日志处理
- 五、总结
一、SpringBoot中的日志
在我们运行项目的时候,你会发现控制台是有日志打印的,这个日志就是SpringBoot默认配置的日志框架处理的。SpringBoot默认是运用logback+slf4j处理日志,slf4j是抽象层,logback是实现层。
但是不同的框架可能会有不同日志处理方式,如果我们在SpringBoot中集成了不同的框架的话,是不是日志的输出也会混乱呢?很显然,如果你有一点经验的话,你会发现,只要你不修改SpringBoot的默认日志配置,它的日志输出格式是不会变得。这是因为,在SpringBoot管理日志的时候,它都将其他框架的日志通过一些中间包的形式将其他的日志抽象成了slf4j接口,而统一用logback的形式实现。
本文我们来讲讲怎么来配置日志格式以及运用AOP+自定义注解简化日志的记录。
二、自定义日志常用配置
1. 日志输出级别
SpringBoot中默认的日志输出级别是info,也就是说我们平常在控制台输出的那些日志都是info级别以及更高级别的日志。我们可以自己定义日志的输出级别,一般有以下几个级别:
trace,debug,info,warn,error //级别递增
trace 是追踪日志,debug是调式日志,info一般是自定义日志或者是信息日志,warn是警告日志,error则是错误日志。
可能这么说你也不知道这个级别有什么用,来看看这个代码:
@RestController
public class TestLogController {
Logger logger = LoggerFactory.getLogger(TestLogController.class);
@GetMapping("/testLog")
public void testLog(){
logger.trace("这是trace级别的日志");
logger.debug("这是debug级别的日志");
logger.info("这是正常自定义日志");
logger.warn("这是警告日志");
logger.error("这是错误日志");
}
}
代码说明:(上面的Logger包这里是使用的org.slf4j.Logger)
首先我们获取一个日志记录器Logger对象,然后分别在代码中记录不同级别日志的输出。运行项目,然后访问接口。
你会发现前面的trace日志和debug日志是不会输出的,这你就知道了吧,不同等级的日志有不同的功效,只会在特定的情况下输出。这时候我们也可以自定义日志级别了,在配置文件(yml)
logging:
level:
com:
example:
demolog: debug
配置说明:
这是什么意思呢?我的包名是com.example.demolog,所以说这个配置就是说配置日志所在包的输出级别,是不是很高级。这样就能输出debug日志了。如果你想输出trace日志你就将等级设置为trace就行了。
2. 日志输出到文件
日志输出到控制台查看起来不是很方便,怎么办?没关系,SpringBoot中还能将日志输出到指定的文件中,yml,添加如下配置。
logging:
file:
path: /spring/test/
这个配置是说将日志输出到指定的目录文件,并且会生成一个spring.log的日志文件用来记录日志(如果你自己指定了文件名,它就会按照你自己设定的名字生成文件。),运行项目你就能直接看到生成的日志所在,这个目录如果你写的和上面一致,那么你的日志文件就会在项目的运行根路径,比如D盘,然后在D盘生成你写的文件目录/spring/test/,最后在文件目录下面生成spring.log的日志文件。这个路径你也可以直接写绝对路径(直接指定这个文件在那个盘,那个文件夹)。
file下面还有一个配置就是name属性,
logging:
file:
name: test.log
这个是直接指定你的日志的文件名称,默认生成的位置是在项目所在的目录,你也可以自己写绝对路径配置日志文件的位置,但是必须要自己设定文件的名称。
file的name属性和path属性只能指定一个,如果两个同时指定的话,只有name属性会生效。
3. 自定义日志输出格式
有时候你可能会觉得这个日志的输出格式太难看了,想自己定义一个日志输出格式,完全ojbk!SpringBoot说:满足你,自己想怎么玩就怎么玩!
logging:
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss}----- 这是全栈学习笔记 [%thread] %-5level %logger{50} - %msg%n"
file: "%d{yyyy-MM-dd HH:mm:ss}----- 这是全栈学习笔记 [%thread] %-5level %logger{50} - %msg%n"
# d表示日期时间,
# %thread表示线程名,
# %‐5level:级别从左显示5个字符宽度
# %logger{50} 表示logger名字最长50个字符,否则按照句点分割。
# %msg:日志消息,
# %n是换行符
上面的配置分别定义了控制台的日志输出格式与文件的日志输出格式,是不是很方便。输出的格式大概就是这样。
当然我们还有一个更好的日志配置,利用xml文件进行配置,一步到位就是这么爽。
三、xml文件实现日志配置的方式
直接上xml文件的内容,建议将文件命名为logback-spring.xml
%d{yyyy-MM-dd HH:mm:ss.SSS} --学习笔记--[%thread] %-5level %logger{50} - %msg%n
${LOG_HOME}/${appName}.log
${LOG_HOME}/${appName}-%d{yyyy-MM-dd}-%i.log
365
100MB
%d{yyyy-MM-dd HH:mm:ss.SSS} [ %thread ] - [ %-5level ] [ %logger{50} : %line ] - %msg%n
上面的xml配置文件配置就不细说了,里面都有详细的注释说明。配置文件默认位置应该是直接放在resources下面,和yml,properties文件同级,当然你也可以自己配置文件位置的。
logging
config: classpath:static/logback.xml
这样就将xml配置文件放在static路径下面时能自动识别了。也可以设置为绝对路径。
上面我们建议将日志文件设置为logback-spring.xml,如果我们的xml文件的名称是logback.xml,它就会直接被日志框架识别,如果你的xml文件是用logback-spring.xml命名,那么他会被SpringBoot来识别并解析日志配置,可以使用SpringBoot的高级Profile功能。这个高级功能我在xml文件中有注释说明。往上看。你也可以去看Spring的官网,有详细的配置说明。
四、AOP + 自定义注解实现统一日志处理
引入aop依赖:
org.springframework.boot
spring-boot-starter-aop
自定义注解,还不会注解的,看这里,注解详细介绍注解干货
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyLog {
String value() default "";
}
自定义切面类:
@Aspect
@Component
public class LogAspect {
private Logger logger = LoggerFactory.getLogger(LogAspect.class);
@Pointcut("@annotation(com.example.demolog.annotation.MyLog)")
public void myPointCut(){
//签名,可以理解成这个切入点的一个名称
}
@Before("myPointCut()")
public void doBefore(JoinPoint joinPoint){
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
//获取url,请求方法,ip地址,类名以及方法名,参数
logger.info("url={},method={},ip={},class_method={},args={}", request.getRequestURI(),request.getMethod(),request.getRemoteAddr(),joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName(),joinPoint.getArgs());
}
@AfterReturning(pointcut = "myPointCut()")
public void printLog(JoinPoint joinPoint){
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method method = methodSignature.getMethod();
MyLog myLog = method.getAnnotation(MyLog.class);
String value = null;
if (myLog!=null){
value = myLog.value();
}
logger.info(new Date()+"-----"+value);
}
}
上面配置完成之后再去controller的方法之上添加一个自定义的 @Mylog注解
@GetMapping("/testLog")
@MyLog("测试一个日志")
public void testLog(){
//和上面的一致
}
代码说明:
-
@Aspect:标明这是一个切面类
-
@Component:标明这是一个bean
-
@Pointcut("@annotation(com.example.demolog.annotation.MyLog)") 定义切入点为自定义的注解,也可以是一个类或者是一个包,包的写法如下:
@Pointcut("execution(public * com.example.demolog.*(..))")
上面的意思是切入点是 所有在com.example,demolog包下面的以public为修饰,不限制返回值(*),不限制参数不限制名称的类。
扩展知识:
- @befor:前置通知,在一个方法执行之前被调用。
- @after:在方法执行之后调用的通知,无论方法执行是否成功。
- @after-returning:仅当方法成功完成之后通知。
- @after-throwing:在方法抛出异常退出时执行的通知。
- @around:在方法执行之前和之后调用的通知。
然后我们再来测试一下接口:localhost:8098/testLog
本期分享到此结束,总结一下下!
五、总结
本文先讲解SpringBoot的默认日志配置,然后自己在配置文件配置日志的输出等级,输出格式,将日志输出到文件中,然后通过xml文件来配置日志。最后我们引出了利用aop,简化日志的输出,并且统一日志的输出格式。如果你觉得本文有用的话,点个赞吧!另外需要源码的看下面。