使用Spring的AOP编程来对请求进行写入日志的一个demo。
技术栈:springboot
代码:
1、首先新建controller、dao、pojo。
@Slf4j
@RestController
@RequestMapping("/log")
public class LogController {
@GetMapping("/insertSuccessLog")
public Result insertSuccessLog(String name) {
log.info("触发了成功的测试请求....");
return Result.successResult(name);
}
@GetMapping("/insertErrorLog")
public Result insertErrorLog() {
log.info("触发了失败的测试请求....");
int i = 0;
try {
i = 10 / 0;
} catch (Exception e) {
return Result.failResult(e.getMessage());
}
return Result.successResult("失败的居然成功了?");
}
}
----------------------------------------
@Component
public interface LogDao {
@Insert("insert into log_controller (log_type, log_text, ip, url, method, class_method, args, result_msg, time_span) \n" +
"values (#{logType},#{logText}, #{ip},#{url},#{method},#{classMethod},#{args},#{res},#{timeSpan}) ")
void addLog(Log log);
}
----------------------------------------
@Data
public class Log {
private String logType;
private String ip;
private String url;
private String logText;
private String method;
private String classMethod;
private String args;
private String res;
private long timeSpan;
private Date createTime;
private Date lastUpdateTime;
}
2、使用@Aspect注解进行切面编程
@Component
@Slf4j
@Aspect
public class ApiLog {
@Value("${spring.application.name}")
private String appName;
@Resource
private LogDao logDao;
ThreadLocal<Long> startTime = new ThreadLocal<Long>();
@Pointcut("execution(* com.yl.controller..*.*(..))")
public void controller() {
}
@Around(value = "controller()")
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
startTime.set(System.currentTimeMillis());
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
Log log = null;
if (request.getRequestURL() != null) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
log = new Log();
log.setLogType(appName); // 获取到YML中的配置
// 记录下请求内容
log.setUrl(request.getRequestURL().toString());
log.setMethod(request.getMethod());
log.setClassMethod(signature.getName());
log.setLogText("暂时不写....");
}
//注意,如果调用joinPoint.proceed()方法,则修改的参数值不会生效,必须调用joinPoint.proceed(Object[] args)
//获取方法参数值数组
Object[] args = joinPoint.getArgs();
//这个方法就是进行请求接口去了.....如果这里不返回result,则目标对象实际返回值会被置为null
Object result = joinPoint.proceed(args);
// 记录日志
logMethodTime(request, log, args, result);
return result;
}
private void logMethodTime(HttpServletRequest request, Log log, Object[] args, Object res) {
// 证明不是从前端发来的请求
if (log == null) {
return;
}
String json = "";
for (Object item : args) {
json = JSON.toJSONString(item);
}
log.setArgs(json);
if (res instanceof Result) {
log.setRes( ((Result) res).getMsg() );
}
log.setIp("127.0.0.1"); // 获取ip
log.setTimeSpan((System.currentTimeMillis() - startTime.get()));
logDao.addLog(log);
}
}
SQL表:
CREATE TABLE `log_controller` (
`id` bigint NOT NULL AUTO_INCREMENT,
`log_type` varchar(32) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '日志类型,可选:service-nm,exec-cmd-log,business-log,cmd-group-log',
`log_text` varchar(128) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '日志text',
`ip` varchar(32) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT 'ip',
`url` varchar(500) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT 'url',
`method` varchar(128) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT 'controller对应方法',
`class_method` varchar(128) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL,
`args` varchar(1024) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '参数',
`result_msg` varchar(10240) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '返回结果',
`time_span` bigint NOT NULL DEFAULT '0' COMMENT '耗时(ms)',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间 格式:YYYY-MM-DD HH:mm:ss',
`last_update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最后更新时间 格式:YYYY-MM-DD HH:mm:ss',
PRIMARY KEY (`id`) USING BTREE
);