SpringBoot之日志处理(logback和AOP记录操作日志)
文章目录
- 项目准备
- 数据库
- 新建项目并选择模块安装
- 添加依赖
- 添加application.yml
- 删除demos.web包
- 编写pojo层
- user
- dto/ResultJson
- 编写mapper层
- UserMapper
- 编写service层
- UserService
- 编写controller层
- UserContoller
- 编写配置类
- MybatisPlusConfig
- 编写测试类
- 概述
- 记录操作日志
- 使用AOP对日志注解增强
- 引入aop依赖
- 编写@Log注解
- 编写LogAspect增强类与增强方法
- 在controller进行测试
- 使用操作日志
- 创建数据库sys_log记录操作
- 创建实体类
- 创建操作方法的实现
- 创建获取request的工具类
- 创建获取用户IP的工具类
- 修改LogAspect增强类与增强方法
- 在service的增删改上面添加@Log注解
- 测试
- 记录异常日志
- 1. 创建logback-spring.xml
- 2. 配置application.properties文件
- 3. 编写controller测试
项目准备
数据库
CREATE TABLE `smbms_user` (`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',`userCode` varchar(15) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL COMMENT '用户编码',`userName` varchar(15) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL COMMENT '用户名称',`userPassword` varchar(15) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT '0000000' COMMENT '用户密码',`gender` int NULL DEFAULT NULL COMMENT '性别(1:女、 2:男)',`birthday` datetime NULL DEFAULT NULL COMMENT '出生日期',`phone` varchar(15) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL COMMENT '手机',`address` varchar(30) CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci NULL DEFAULT NULL COMMENT '地址',`userRole` bigint NULL DEFAULT NULL COMMENT '用户角色(取自角色表-角色id)',`createdBy` bigint NULL DEFAULT NULL COMMENT '创建者(userId)',`creationDate` datetime NULL DEFAULT NULL COMMENT '创建时间',`modifyBy` bigint NULL DEFAULT NULL COMMENT '更新者(userId)',`modifyDate` datetime NULL DEFAULT NULL COMMENT '更新时间',PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 129 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_unicode_ci ROW_FORMAT = Dynamic;INSERT INTO `smbms_user` VALUES (1, 'admin', '系统管理员', '1234567', 1, '1983-10-10 00:00:00', '13688889999', '北京市海淀区成府路207号', 1, 1, '2013-03-21 16:52:07', NULL, NULL);
INSERT INTO `smbms_user` VALUES (2, 'liming', '李明', '0000000', 2, '1983-12-10 00:00:00', '13688884457', '北京市东城区前门东大街9号', 3, 1, '2014-12-31 19:52:09', NULL, '2025-09-04 15:57:03');
INSERT INTO `smbms_user` VALUES (5, 'hanlubiao', '韩路彪', '0000000', 2, '1984-06-05 00:00:00', '18567542321', '北京市朝阳区北辰中心12号', 2, 1, '2014-12-31 19:52:09', NULL, NULL);
INSERT INTO `smbms_user` VALUES (6, 'zhanghua', '张华1', '0000000', 1, '1983-06-15 00:00:00', '13544561111', '北京市海淀区学院路61号', 3, 1, '2013-02-11 10:51:17', NULL, '2025-08-19 16:45:43');
INSERT INTO `smbms_user` VALUES (7, 'wangyang', '王洋', '0000000', 2, '1982-12-31 00:00:00', '13444561124', '北京市海淀区西二旗辉煌国际16层', 3, 1, '2014-06-11 19:09:07', NULL, NULL);
INSERT INTO `smbms_user` VALUES (8, 'zhaoyan', '赵燕', '0000000', 1, '1986-03-07 00:00:00', '18098764545', '北京市海淀区回龙观小区10号楼', 3, 1, '2016-04-21 13:54:07', NULL, NULL);
INSERT INTO `smbms_user` VALUES (10, 'sunlei', '孙磊', '0000000', 2, '1981-01-04 00:00:00', '13387676765', '北京市朝阳区管庄新月小区12楼', 3, 1, '2015-05-06 10:52:07', NULL, NULL);
INSERT INTO `smbms_user` VALUES (11, 'sunxing', '孙兴', '0000000', 2, '1978-03-12 00:00:00', '13367890900', '北京市朝阳区建国门南大街10号', 3, 1, '2016-11-09 16:51:17', NULL, NULL);
INSERT INTO `smbms_user` VALUES (12, 'zhangchen', '张晨', '0000000', 1, '1986-03-28 00:00:00', '18098765434', '朝阳区管庄路口北柏林爱乐三期13号楼', 3, 1, '2016-08-09 05:52:37', 1, '2016-04-14 14:15:36');
INSERT INTO `smbms_user` VALUES (13, 'dengchao', '邓超', '0000000', 2, '1981-11-04 00:00:00', '13689674534', '北京市海淀区北航家属院10号楼', 3, 1, '2016-07-11 08:02:47', NULL, NULL);
INSERT INTO `smbms_user` VALUES (14, 'yangguo', '杨过', '0000000', 2, '1980-01-01 00:00:00', '13388886623', '北京市朝阳区北苑家园茉莉园20号楼', 3, 1, '2015-02-01 03:52:07', NULL, NULL);
INSERT INTO `smbms_user` VALUES (15, 'zhaomin', '赵敏1', '0000000', 1, '1992-01-01 00:00:00', '18099897657', '北京市昌平区天通苑3区12号楼', 2, 1, '2015-09-12 12:02:12', NULL, NULL);
INSERT INTO `smbms_user` VALUES (103, '1', '1', '1', 1, '2025-07-17 16:34:35', '1', '1', 1, 1, '2025-07-17 16:34:35', 1, '2025-07-17 16:34:35');
INSERT INTO `smbms_user` VALUES (112, '80', '惠静怡', 'BSu9Y5mIKEZ2C8H', NULL, NULL, NULL, NULL, 1, NULL, '2025-09-03 11:09:07', NULL, NULL);
INSERT INTO `smbms_user` VALUES (113, '山东', '是的是的', '0000000', 2, '2025-09-07 08:00:00', '15457854567', '山东', 2, NULL, '2025-09-03 11:12:28', NULL, '2025-09-04 15:07:54');
INSERT INTO `smbms_user` VALUES (114, '你好', '山东', '0000000', 2, '2025-09-09 08:00:00', '15456874569', '山东', 1, NULL, '2025-09-03 11:18:27', NULL, '2025-09-03 11:30:45');
INSERT INTO `smbms_user` VALUES (115, '山东', '山东', '0000000', 2, '2025-09-01 08:00:00', '14575674578', ' 但是', 1, NULL, '2025-09-03 11:19:43', NULL, NULL);
INSERT INTO `smbms_user` VALUES (116, '山东', '山东', '0000000', 2, '2025-09-09 08:00:00', '18466559854', '山东', 1, NULL, '2025-09-03 11:21:01', NULL, NULL);
INSERT INTO `smbms_user` VALUES (117, '山东', '山东', '0000000', 2, '2025-09-01 08:00:00', '14567854569', '45', 1, NULL, '2025-09-03 11:22:15', NULL, NULL);
INSERT INTO `smbms_user` VALUES (119, NULL, '李四', '0000000', NULL, NULL, NULL, NULL, 1, NULL, NULL, NULL, NULL);
INSERT INTO `smbms_user` VALUES (120, NULL, '李四', '0000000', NULL, NULL, NULL, NULL, 1, NULL, NULL, NULL, NULL);
新建项目并选择模块安装
创建一个空的 Spring Boot 工程
文件–>新建项目
选择模块
SpringBoot
版本选择2.7.6
- 在
DeveloperTools
中选择Lombok
- 在
Web
中选择SpringWeb
- 在
SQL
中选择MySQLDriver
添加依赖
<!-- mybatis-plus依赖 -->
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.1</version><!--sql性能分析插件使用版本--><!-- <version>3.1.2</version> -->
</dependency>
添加application.yml
我们删除application.properties
在resources文件下新建application.yml
.
在 application.yml
中配置文件中添加mysql 数据库相关配置:
server:port: 8080
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://127.0.0.1:3306/smbms?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=trueusername: rootpassword: root
# mybatis-plus 相关配置
mybatis-plus:type-aliases-package: com.hsh.pojo #类型别名所在的包#控制台打印sql语句configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImplmap-underscore-to-camel-case: false #关闭驼峰映射
注意你要写你的
数据库端口号
,账号
,密码
,你要简化的包名
这些一定要看一下。
删除demos.web包
编写pojo层
user
com/hsh/pojo/user
package com.hsh.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.time.LocalDateTime;@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("smbms_user")
public class User {private Long id;// 主键IDprivate String userCode;// 用户编码private String userName;// 用户名称private String userPassword;// 用户密码private Integer gender;// 性别(1:女、 2:男)private LocalDateTime birthday;// 出生日期private String phone;// 手机private String address;// 地址private Long userRole;// 用户角色(取自角色表-角色id)private Long createdBy;// 创建者(userId)private LocalDateTime creationDate;// 创建时间private Long modifyBy; // 更新者(userId)private LocalDateTime modifyDate; // 更新时间
}
dto/ResultJson
package com.hsh.pojo.tdo;
import java.io.Serializable;@Data
public class ResultJSON<T> implements Serializable {private Integer code;private String msg;private T data;public ResultJSON(Integer code, String msg, T data) {this.code = code;this.msg = msg;this.data = data;}/*** 操作成功或者失败* @param c 受影响行数* @return 当前传入的受影响行数>0则返回成功,否则返回失败*/public static ResultJSON successORerror(int c){return c>0?new ResultJSON(200,"操作成功",c):new ResultJSON(400,"操作失败",c);}public static ResultJSON success(){return new ResultJSON(200,"操作成功",null);}public static ResultJSON success(String msg){return new ResultJSON(200,msg,null);}public static <T> ResultJSON success(T data){return new ResultJSON(200,"操作成功",data);}public static ResultJSON success(Integer code,String msg){return new ResultJSON(code,msg,null);}public static <T> ResultJSON success(String msg,T data){return new ResultJSON(200,msg,data);}public static <T> ResultJSON success(Integer code,String msg,T data){return new ResultJSON(code,msg,data);}public static ResultJSON error(){return new ResultJSON(500,"操作失败",null);}public static ResultJSON error(String msg){return new ResultJSON(500,msg,null);}public static ResultJSON error(Integer code,String msg){return new ResultJSON(code,msg,null);}}
编写mapper层
UserMapper
package com.hsh.mapper;public interface UserMapper extends BaseMapper<User> {}
编写service层
UserService
// 接口
package com.hsh.service;
public interface UserService {ResultJSON<User> getUserById(Long id);ResultJSON<User> editUser(User user);ResultJSON<User> deleteUser(Long id);ResultJSON<User> addUser(User user);
}// 实现类
package com.hsh.service.impl;
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {@Autowiredprivate UserMapper userMapper;@Overridepublic ResultJSON<User> getUserById(Long id) {User user = userMapper.selectById(id);return ResultJSON.success(user);}@Overridepublic ResultJSON<User> editUser(User user) {int i = userMapper.updateById(user);return ResultJSON.successORerror(i);}@Overridepublic ResultJSON<User> deleteUser(Long id) {int i = userMapper.deleteById(id);return ResultJSON.successORerror(i);}@Overridepublic ResultJSON<User> addUser(User user) {int i = userMapper.insert(user);return ResultJSON.successORerror(i);}
}
编写controller层
UserContoller
package com.hsh.controller;@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;@RequestMapping("/getUserById")public ResultJSON getUserById(Long id){return ResultJSON.success(userService.getUserById(id));}@RequestMapping("/addUser")public ResultJSON addUser(@RequestBody User user){return userService.addUser(user);}@RequestMapping("/deleteUser")public ResultJSON deleteUser(Long id){return userService.deleteUser(id);}@RequestMapping("/editUser")public ResultJSON editUser(@RequestBody User user){return userService.editUser(user);}
}
编写配置类
MybatisPlusConfig
package com.hsh.config;@Configuration
@MapperScan("com.hsh.mapper")
public class MybatisPlusConfig {}
编写测试类
package com.hsh;import com.hsh.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
class MybatisPlus01ApplicationTests {@Autowiredprivate UserMapper userMapper;@Testvoid contextLoads() {System.out.println(userMapper.selectById(1));}
}
概述
日志处理分两种
- 异常日志:当程序报异常进行记录。
- 使用技术:log4j,logback,slf4j,
- 操作日志:当用户进行修改,更新,删除,操作时需要记录。查询不需要记录。
- 使用技术:AOP。使用AOP需要自定义注解进行使用。当我在方法上写这个自定义注解,我就去捕获这方法进行操作日志记录。
我们这些日志如何存贮呢?
- 数据库:当数据库满了需要手动备份然后清空数据库。(若依框架就是使用的这一套)
- Redis:虽然redis能持久化,但是一次要拿很多数据,只能用stream流过滤,当数据过大会出问题。
- 记事本:数据量过大会卡顿。
- 搜索引擎:solr(单体式项目),ES(分布式项目)。
记录操作日志
我们使用数据库存储,因为若依使用的就是这一套。
我们的记录日志操作是对某些方法进行操作,所以aop就可以对某些方法进行操作。
使用AOP对日志注解增强
引入aop依赖
<!-- aop依赖 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>
编写@Log注解
在com/hsh
文件夹下新建aop文件夹,并在com/hsh/aop
下新建Log类
package com.hsh.aop;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;// @Target 用来说明该注解可以被声明在那些元素之前
// ElementType.METHOD说明该注解只能被声明在一个类的方法前
@Target(ElementType.METHOD)
// @Retention 用来说明注解的声明周期
// RetentionPolicy.RUNTIME注解保留在程序运行期间,
// 此时可以通过反射获得定义在某个类上的所有注解。
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {// @interface 注解类,自定义注解String value() default "";
}
编写LogAspect增强类与增强方法
编写LogAspect增强类与增强方法(我们使用环绕增强around)
在com/hsh
文件夹下新建aop文件夹,并在com/hsh/aop
下新建LogAspect类
package com.hsh.aop;@Aspect
@Component
public class LogAspect {//切入点,指定当使用Log注解时进入环绕增强@Pointcut("@annotation(com.hsh.aop.Log)")public void pointcut() {}@Around("pointcut()")public Object around(ProceedingJoinPoint point) {try {System.out.println("执行环绕增强..............开始");Object result = point.proceed();//执行方法System.out.println("结束..........");return result;} catch (Throwable throwable) {throwable.printStackTrace();}return null;}
}
在controller进行测试
package com.hsh.controller;@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;// 加入@Log注解测试@RequestMapping("/getUserById")@Log("获取所有用户集合")public ResultJSON getUserById(Long id){return ResultJSON.success(userService.getUserById(id));}
}
浏览器输入http://localhost:8080/user/getUserById?id=1
查看idea控制台说明对注解的增强生效。
使用操作日志
创建数据库sys_log记录操作
创建日志记录表sys_log
DROP TABLE IF EXISTS `sys_log`;
CREATE TABLE `sys_log` (`ID` bigint(20) NOT NULL AUTO_INCREMENT,`USERNAME` varchar(50) DEFAULT NULL COMMENT '用户名',`OPERATION` varchar(50) DEFAULT NULL COMMENT '用户操作',`TIME` int(11) DEFAULT NULL COMMENT '响应时间',`METHOD` varchar(200) DEFAULT NULL COMMENT '请求方法',`PARAMS` varchar(500) DEFAULT NULL COMMENT '请求参数',`IP` varchar(64) DEFAULT NULL COMMENT 'IP地址',`CREATE_TIME` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
创建实体类
package com.hsh.pojo;
@TableName("sys_log")
@Data
public class SysLog {// 设置自动递增@TableId(value = "id", type = IdType.AUTO)private Long id;private String username;private String operation;private Integer time;private String method;private String params;private String ip;private Date createTime;
}
创建操作方法的实现
编写DAO层接口与实现,向表中插入数据
package com.hsh.mapper;public interface SysLogMapper extends BaseMapper<SysLog> {}
创建获取request的工具类
在com/hsh
文件夹下新建utils文件夹,并在com/hsh/utils
下新建HttpContextUtils 类
package com.hsh.utils;public class HttpContextUtils {public static HttpServletRequest getHttpServletRequest() {return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();}
}
创建获取用户IP的工具类
在com/hsh/utils
下新建IPUtils 类
package com.hsh.utils;public class IPUtils {public static String getIpAddr(HttpServletRequest request){String ip = request.getHeader("x-forwarded-for");if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("Proxy-Client-IP");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getHeader("WL-Proxy-Client-IP");}if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {ip = request.getRemoteAddr();}return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;}
}
修改LogAspect增强类与增强方法
package com.hsh.aop;import com.hsh.mapper.SysLogMapper;
import com.hsh.pojo.SysLog;
import com.hsh.utils.HttpContextUtils;
import com.hsh.utils.IPUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.stereotype.Component;import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;@Aspect
@Component
public class LogAspect {@Autowiredprivate SysLogMapper sysLogMapper;//切入点,指定当使用Log注解时进入环绕增强@Pointcut("@annotation(com.hsh.aop.Log)")public void pointcut() {}@Around("pointcut()")public Object around(ProceedingJoinPoint point) {try {//实例化日志类SysLog sysLog = new SysLog();sysLog.setUsername("xrkhy");//模拟一个用户名 实际可以从session中获取//开始执行时间long beginTime = System.currentTimeMillis();//执行方法Object result = point.proceed();// 执行时长(毫秒)long time = System.currentTimeMillis() - beginTime;//执行时长(毫秒)sysLog.setTime((int) time);// 获取requestHttpServletRequest request = HttpContextUtils.getHttpServletRequest();// 设置IP地址sysLog.setIp(IPUtils.getIpAddr(request));// 通过反射获取方法名MethodSignature signature = (MethodSignature) point.getSignature();Method method = signature.getMethod();// 获取操作名称Log logAnnotation = method.getAnnotation(Log.class);if (logAnnotation != null) {// 注解上的描述sysLog.setOperation(logAnnotation.value());}// 请求的方法名String className = point.getTarget().getClass().getName();String methodName = signature.getName();sysLog.setMethod(className + "." + methodName + "()");// 请求的方法参数值Object[] args = point.getArgs();// 请求的方法参数名称LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();String[] paramNames = u.getParameterNames(method);if (args != null && paramNames != null) {String params = "";for (int i = 0; i < args.length; i++) {params += " " + paramNames[i] + ": " + args[i];}sysLog.setParams(params);}// 保存系统日志sysLogMapper.insert(sysLog);return result;} catch (Throwable throwable) {throwable.printStackTrace();}return null;}
}
在service的增删改上面添加@Log注解
package com.hsh.controller;@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;@RequestMapping("/getUserById")public ResultJSON getUserById(Long id){return ResultJSON.success(userService.getUserById(id));}@RequestMapping("/addUser")@Log("添加用户")public ResultJSON addUser(User user){return userService.addUser(user);}@RequestMapping("/deleteUser")@Log("删除用户")public ResultJSON deleteUser(Long id){return userService.deleteUser(id);}@RequestMapping("/editUser")@Log("修改用户")public ResultJSON editUser(User user){return userService.editUser(user);}
}
测试
打开接口测试工具
apifox或者postman进行测试。
检查sys_log数据库。
记录异常日志
1. 创建logback-spring.xml
创建logback-spring.xml文件放入resource下,并复制内容到该文件
<?xml version="1.0" encoding="UTF-8"?>
<configuration><property name="LOG_CONTEXT_NAME" value="log"/><!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径--><property name="LOG_HOME" value="D:/logs"/><!-- 定义日志上下文的名称 --><contextName>${LOG_CONTEXT_NAME}</contextName><!-- 控制台输出 --><!--<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">--><!-- <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">--><!-- <!–格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个--><!-- 字符宽度%msg:日志消息,%n是换行符–>--><!-- <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %highlight(%-5level)--><!-- %cyan(%logger{50}:%L) - %msg%n</pattern>--><!-- <charset>utf-8</charset>--><!-- </encoder>--><!-- <filter class="ch.qos.logback.classic.filter.ThresholdFilter">--><!-- <level>INFO</level>--><!-- </filter>--><!--</appender>--><!-- 彩色日志依赖的渲染类 --><conversionRule conversionWord="clr"converterClass="org.springframework.boot.logging.logback.ColorConverter"/><conversionRule conversionWord="wex"converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/><conversionRule conversionWord="wEx"converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/><!-- 彩色日志格式 --><property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p})%clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint}%clr(%-40.40logger{39}){cyan} %clr(:){faint}%m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/><!--1. 输出到控制台--><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息--><filter class="ch.qos.logback.classic.filter.ThresholdFilter"><level>INFO</level></filter><encoder><Pattern>${CONSOLE_LOG_PATTERN}</Pattern><!-- 设置字符集 --><charset>UTF-8</charset></encoder></appender><!--info日志统一输出到这里--><appender name="file.info" class="ch.qos.logback.core.rolling.RollingFileAppender"><Prudent>true</Prudent><rollingPolicyclass="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!--日志文件输出的文件名,按小时生成--><FileNamePattern>${LOG_HOME}/%d{yyyy-MM-dd}/info/info.%d{yyyy-MM-dd-HH}.%i.log</FileNamePattern><!--日志文件保留天数--><MaxHistory>30</MaxHistory><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><!-- 除按日志记录之外,还配置了日志文件不能超过10M(默认),若超过10M,日志文件会以索引0开始, --><maxFileSize>10MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy></rollingPolicy><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %method 方法名 %L 行数 %msg:日志消息,%n是换行符--><pattern> %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level%logger{56}.%method:%L - %msg%n</pattern><charset>utf-8</charset></encoder><!-- 此日志文件只记录info级别的 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>INFO</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><!--错误日志统一输出到这里--><appender name="file.error"class="ch.qos.logback.core.rolling.RollingFileAppender"><Prudent>true</Prudent><rollingPolicyclass="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!--日志文件输出的文件名,按天生成--><FileNamePattern>${LOG_HOME}/%d{yyyy-MM-dd}/error/error.%d{yyyy-MM-dd}.%i.log</FileNamePattern><!--日志文件保留天数--><MaxHistory>30</MaxHistory><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><!-- 除按日志记录之外,还配置了日志文件不能超过10M(默认),若超过10M,日志文件会以索引0开始, --><maxFileSize>10MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy></rollingPolicy><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %method 方法名 %L 行数 %msg:日志消息,%n是换行符--><pattern> %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level%logger{56}.%method:%L - %msg%n</pattern><charset>utf-8</charset></encoder><!-- 此日志文件只记录error级别的 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>ERROR</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><!--warn日志统一输出到这里--><appender name="file.warn"class="ch.qos.logback.core.rolling.RollingFileAppender"><Prudent>true</Prudent><rollingPolicyclass="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><FileNamePattern>${LOG_HOME}/%d{yyyy-MM-dd}/warn/warn.%d{yyyy-MM-dd}.%i.log</FileNamePattern><!--日志文件保留天数--><MaxHistory>30</MaxHistory><timeBasedFileNamingAndTriggeringPolicyclass="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><!-- 除按日志记录之外,还配置了日志文件不能超过10M(默认),若超过10M,日志文件会以索引0开始, --><maxFileSize>10MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy></rollingPolicy><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %method 方法名 %L 行数 %msg:日志消息,%n是换行符--><pattern> %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level%logger{56}.%method:%L - %msg%n</pattern><charset>utf-8</charset></encoder><!-- 此日志文件只记录warn级别的 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>WARN</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><!-- 日志输出级别 --><root level="DEBUG"><appender-ref ref="STDOUT" /><appender-ref ref="file.error" /><appender-ref ref="file.info" /><appender-ref ref="file.warn" /></root></configuration>
2. 配置application.properties文件
下面两种读取方式二选一
#读取配置文件
logging.config=classpath:logback-spring.xml
yml配置
#读取配置文件
logging:config: classpath:logback-spring.xml
3. 编写controller测试
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;@RequestMapping("/getUserById")@Log("获取指定用户集合")public ResultJSON getUserById(Long id){log.info("获取指定用户集合");//输出信息return ResultJSON.success(userService.getUserById(id));}
}
等级可分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL,如果配置OFF则不打出任何信息,如果配置为INFO这样只显示INFO, WARN, ERROR的log信息,而DEBUG信息不会被显示