前言
在做项目得时候需要日志记录,就是操作了那个接口得功能记录以及成功情况和操作id
就在这样的情况下,我做了一个全局日志配置
写的不是很好,大佬忽喷~~~
废话不多说,直接开干
首先我们得去创建一个存储日志得表,我这里存储得东西不duo
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for sys_log
-- ----------------------------
DROP TABLE IF EXISTS `sys_log`;
CREATE TABLE `sys_log` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
`url` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '请求得url',
`method_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '请求得方法',
`http_method` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'http请求类型',
`clazz_method` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '请求方法全名称',
`ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '请求ip',
`request_args` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '请求得参数',
`response_result` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '返回得状态信息',
`create_by` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '修改人',
`create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 87 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '日志表' ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
我们要创建表对应得实体类字段
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("sys_log")
public class Log {
//主键
private Long id;
//请求得url
private String url;
//请求得方法
private String methodName;
//http请求类型
private String httpMethod;
//请求方法全名称
private String clazzMethod;
//请求ip
private String ip;
//请求得参数
private String requestArgs;
// 返回得信息
private String responseResult;
//创建时间
private Date createTime;
// 创建人
private String createBy;
}
接下来我们要去创建表对应得mapper层稍后用来存储数据库操作使用
@Mapper
public interface LogMapper extends BaseMapper<Log> {
}
再去创建一个注解用来标注,该接口需要使用日志记录功能
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SystemLog {
String businessName();
}
注意 : 接下里是重点了,我们使用Aop来获取日志
/**
* @Description: 日志
* @Author: 沐光
*/
@Component
@Aspect
@Slf4j
public class LogAspect {
/**
* @description 定义切入点 后面只要方法上面加上@SystemLog 都需要进行日志打印
* @author 沐光
*/
@Pointcut("@annotation(com.muguang.annotation.SystemLog)")
public void pt(){}
public Map<String, String> stringMap = new HashMap<>();
@Autowired
private LogMapper logMapper;
@Around("pt()")
public Object printLog(ProceedingJoinPoint joinPoint) throws Throwable{
Object ret ;
try {
handleBefore(joinPoint);
ret = joinPoint.proceed();
handleAfter(ret);
} finally {
// 结束后换行 System.lineSeparator():获取系统换行符
log.info("=======End=======" + System.lineSeparator());
setSqlLogResult(stringMap);
}
return ret;
}
/**
* description 处理打印前的获取信息
* @author 沐光
* @param joinPoint
*/
private void handleBefore(ProceedingJoinPoint joinPoint) throws Throwable {
// 使用RequestAttributes实现类来获取request请求对象
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = requestAttributes.getRequest();
// 获取被增强方法上的注解对象
SystemLog systemLog = getSystemLog(joinPoint);
// 获取sql语句
// String sql = getSqlStr(joinPoint);
log.info("=======Start=======");
// 打印请求 URL
log.info("URL : {}",request.getRequestURL());
// 打印描述信息
log.info("BusinessName : {}", systemLog.businessName());
// 打印 Http method
log.info("HTTP Method : {}", request.getMethod());
// 打印调用 controller 的全路径以及执行方法
log.info("Class Method : {}.{}", joinPoint.getSignature().getDeclaringTypeName(), ((MethodSignature) joinPoint.getSignature()).getName());
// 打印请求的 IP
log.info("IP : {}",request.getRemoteHost());
// 打印请求入参
log.info("Request Args : {}", joinPoint.getArgs());
stringMap.put("url", request.getRequestURL().toString());
stringMap.put("methodName", systemLog.businessName());
stringMap.put("httpMethod", request.getMethod());
stringMap.put("clazzMethod", joinPoint.getSignature().getDeclaringTypeName()+"."+((MethodSignature) joinPoint.getSignature()).getName());
stringMap.put("ip", request.getRemoteHost());
stringMap.put("requestArgs", joinPoint.getArgs().toString());
// 这里获取操作人得方法,大家可以修改一下,因为我这里使用得SpringSecurity框架里面得东西,所有大家根据自己得实际情况来
// stringMap.put("createBy", SecurityUtils.getUserId().toString());
}
/**
* @description 把aop拦截得MultipartFile类型文件转换为String类型
* args[i] instanceof ServletRequest || args[i] instanceof ServletResponse ||
* @author 沐光
*/
private String filterArgs(ProceedingJoinPoint joinPoint) throws Throwable {
Object[] args = joinPoint.getArgs();
byte[] imageByte = null;
String base64EncoderImg = "";
Object[] arguments = new Object[args.length];
for (int i = 0; i < args.length; i++) {
if ( args[i] instanceof MultipartFile){
imageByte = ((MultipartFile) args[i]).getBytes();
BASE64Encoder base64Encoder = new BASE64Encoder();
base64EncoderImg = base64Encoder.encode(imageByte);
base64EncoderImg = base64EncoderImg.replaceAll("[\\s\t\n\r]", "");
return base64EncoderImg;
}
arguments[i] = args[i];
}
return JSON.toJSONString(arguments);
}
/**
* description 获取方法上注解里面得信息
* @author 沐光
*/
private SystemLog getSystemLog(ProceedingJoinPoint joinPoint) {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
SystemLog systemLog = methodSignature.getMethod().getAnnotation(SystemLog.class);
return systemLog;
}
/**
* description 处理打印后的获取信息
* @author 沐光
* @param ret
*/
private void handleAfter(Object ret) {
// 打印出参
log.info("Response : {}", JSON.toJSONString(ret));
stringMap.put("responseResult", JSON.toJSONString(ret));
}
/**
* description 把日志信息存入数据库中
* @param map 日志信息map
* @return void
* @author 沐光
*/
private void setSqlLogResult(Map<String, String> map){
map.put("createTime", Utils.getTime());
Log log = JSONObject.toJavaObject(JSONObject.parseObject(JSON.toJSONString(map)), Log.class);
logMapper.insert(log);
}
/**
* @description 获取sql语句日志
* @author 沐光
*/
// private String getSqlStr(ProceedingJoinPoint joinPoint) {
// Signature signature = joinPoint.getSignature();
// if (signature instanceof MethodSignature){
// MethodSignature methodSignature = (MethodSignature) signature;
// Class<?> clazz = methodSignature.getDeclaringType();
// String methodName = methodSignature.getName();
// Object[] args = joinPoint.getArgs();
// // 讲args转为map便于解析
// HashMap<String, Object> paramMap = new HashMap<>();
// for (int i = 0; i < args.length; i++) {
// paramMap.put("arg"+i, args[i]);
// }
// // 获取sql语句
// String sql = SqlHelper.getSql(clazz, methodName, paramMap);
// }
// }
}
这样就可以把我们得操作日志记录在数据库里面了,写的并不是很好,希望大佬忽喷,也能给出一点意见。