一. 简介
记录日志方便排错,记录操作记录。通常有俩层需要加日志:controller层和service层。
controller层的日志使用Log打印信息,service层的日志使用数据库记录操作日志。
Controller层 | 通过添加一个AOP切面,监控controller层的所有方法: 调用之前打印请求信息,包含URL,HTTP_METHOD,IP,CLASS_METHOD,ARGS; 在方法完成后,打印返回的请求结果,包含code, msg。 |
ServiceImpl层 | 创建一张日志表sys_log, 创建一个SysLogService接口和一个SysLogServiceImpl实现类。里面包含一个saveSysLog(...)方法,该方法加@Transactional注解,内置的传播行为为PROPAGATION_REQUIRES_NEW。 在每个其他的service层中注入SysLogService,在每个方法最后加一个插入日志表的操作。 此处不展示。 |
二. 代码
2.1 切面类
复制代码
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74package com.yss.shopping.aspect; import com.alibaba.fastjson.JSONObject; import com.yss.shopping.vo.ResultVO; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; /** * 日志切面类 */ @Aspect @Component @Slf4j public class LogAspect { /** * ..表示包及子包 该方法代表controller层的所有方法 TODO 路径需要根据自己项目定义 */ @Pointcut("execution(public * com.yss.shopping.controller..*.*(..))") public void controllerMethod() { } /** * 方法执行前 * * @param joinPoint * @throws Exception */ @Before("controllerMethod()") public void LogRequestInfo(JoinPoint joinPoint) throws Exception { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); StringBuilder requestLog = new StringBuilder(); Signature signature = joinPoint.getSignature(); requestLog.append(((MethodSignature) signature).getMethod().getAnnotation(ApiOperation.class).value()).append("t") .append("请求信息:").append("URL = {").append(request.getRequestURI()).append("},t") .append("请求方式 = {").append(request.getMethod()).append("},t") .append("请求IP = {").append(request.getRemoteAddr()).append("},t") .append("类方法 = {").append(signature.getDeclaringTypeName()).append(".") .append(signature.getName()).append("},t"); // 处理请求参数 String[] paramNames = ((MethodSignature) signature).getParameterNames(); Object[] paramValues = joinPoint.getArgs(); int paramLength = null == paramNames ? 0 : paramNames.length; if (paramLength == 0) { requestLog.append("请求参数 = {} "); } else { requestLog.append("请求参数 = ["); for (int i = 0; i < paramLength - 1; i++) { requestLog.append(paramNames[i]).append("=").append(JSONObject.toJSONString(paramValues[i])).append(","); } requestLog.append(paramNames[paramLength - 1]).append("=").append(JSONObject.toJSONString(paramValues[paramLength - 1])).append("]"); } log.info(requestLog.toString()); } /** * 方法执行后 * * @param resultVO * @throws Exception */ @AfterReturning(returning = "resultVO", pointcut = "controllerMethod()") public void logResultVOInfo(ResultVO resultVO) throws Exception { log.info("请求结果:" + resultVO.getCode() + "t" + resultVO.getMsg()); } }
注意:
如果有BaseController的话,不需要被日志扫描,可以通过添加不扫描路径即可。如下:
2.2 ResultVO类
复制代码
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93package com.yzx.codedemo.vo; import io.swagger.annotations.ApiModelProperty; /** * 返回结果类 * * @param <T> 类型 */ public class ResultVO<T> { @ApiModelProperty("状态码 0失败 1成功 ") private Integer code; @ApiModelProperty("返回信息") private String msg; @ApiModelProperty("返回数据") private T data; public ResultVO(Integer code, String msg) { this.code = code; this.msg = msg; } public ResultVO(Integer code, String msg, T data) { this.code = code; this.msg = msg; this.data = data; } /** * 请求成功 状态码 1 * * @param msg 返回信息 * @param <T> 类型 * @return ResultVO */ public static <T> ResultVO getSuccess(String msg) { return new ResultVO(1, msg); } /** * 请求成功 状态码 1 * * @param msg 返回信息 * @param data 返回对象 * @param <T> 类型 * @return ResultVO */ public static <T> ResultVO getSuccess(String msg, T data) { return new ResultVO(1, msg, data); } /** * 请求失败 状态码 0 * * @param msg 返回信息 * @param <T> 类型 * @return ResultVO */ public static <T> ResultVO getFailed(String msg) { return new ResultVO(0, msg); } /** * 请求失败 状态 0 * * @param msg 返回信息 * @param data 返回数据 * @param <T> 类型 * @return ResultVO */ public static <T> ResultVO getFailed(String msg, T data) { return new ResultVO(0, msg, data); } public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public T getData() { return data; } public void setData(T data) { this.data = data; } }
2.3 Controller类
复制代码
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
38package com.yzx.codedemo.controller.user; import com.yzx.codedemo.entity.user.SysUser; import com.yzx.codedemo.service.user.SysUserService; import com.yzx.codedemo.vo.PageVO; import com.yzx.codedemo.vo.ResultVO; import com.yzx.codedemo.vo.user.SysUserVO; import io.swagger.annotations.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import springfox.documentation.annotations.ApiIgnore; import java.util.List; @Api(tags = {"SysUserController"}, description = "用户Controller") @RestController @RequestMapping(value = "/sysuser") public class SysUserController { @Autowired private SysUserService sysUserService; @ApiOperation("查询用户分页列表") @ApiImplicitParams({ @ApiImplicitParam(paramType = "query", dataType = "Long", name = "currentPage", value = "当前页码", required = true), @ApiImplicitParam(paramType = "query", dataType = "Long", name = "pageSize", value = "每页记录数", required = true), @ApiImplicitParam(paramType = "query", dataType = "String", name = "userName", value = "用户名称", required = false), @ApiImplicitParam(paramType = "query", dataType = "String", name = "phone", value = "手机号", required = false), @ApiImplicitParam(paramType = "query", dataType = "Long", name = "userState", value = "用户状态: 0删除 1正常", required = false), @ApiImplicitParam(paramType = "query", dataType = "String", name = "starttime", value = "开始时间 格式:yyyy-MM-dd HH:mm:ss", required = false), @ApiImplicitParam(paramType = "query", dataType = "String", name = "endtime", value = "结束时间 格式:yyyy-MM-dd HH:mm:ss", required = false) }) @GetMapping(value = "/page") public ResultVO<PageVO<SysUserVO>> selectSysUserPage(@ApiIgnore SysUserVO sysUserVO) { try { return this.sysUserService.selectSysUserPage(sysUserVO); } catch (Exception e) { e.printStackTrace(); return ResultVO.getSuccess("查询用户分页列表失败"); } } }
2.3 测试
每次调用controller层的代码的方法,都会打印日志信息:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
222018-08-22 16:17:12.251 INFO 12200 --- [nio-8080-exec-1] com.yzx.codedemo.aspect.LogAspect : 请求信息:URL = {/sysuser/page}, HTTP_METHOD = {GET}, IP = {0:0:0:0:0:0:0:1}, CLASS_METHOD = {com.yzx.codedemo.controller.user.SysUserController.selectSysUserPage}, ARGS = {"currentPage":1,"pageSize":10} 2018-08-22 16:17:12.319 DEBUG 12200 --- [nio-8080-exec-1] c.y.c.m.u.S.selectSysUserPage_COUNT : ==> Preparing: SELECT count(0) FROM sys_user WHERE 1 = 1 2018-08-22 16:17:12.336 DEBUG 12200 --- [nio-8080-exec-1] c.y.c.m.u.S.selectSysUserPage_COUNT : ==> Parameters: 2018-08-22 16:17:12.351 DEBUG 12200 --- [nio-8080-exec-1] c.y.c.m.u.S.selectSysUserPage_COUNT : <== Total: 1 2018-08-22 16:17:12.356 DEBUG 12200 --- [nio-8080-exec-1] c.y.c.m.u.S.selectSysUserPage : ==> Preparing: SELECT id AS user_id, user_name, password, phone, createtime FROM sys_user WHERE 1=1 ORDER BY createtime DESC LIMIT ? 2018-08-22 16:17:12.357 DEBUG 12200 --- [nio-8080-exec-1] c.y.c.m.u.S.selectSysUserPage : ==> Parameters: 10(Integer) 2018-08-22 16:17:12.363 DEBUG 12200 --- [nio-8080-exec-1] c.y.c.m.u.S.selectSysUserPage : <== Total: 10 2018-08-22 16:17:12.365 INFO 12200 --- [nio-8080-exec-1] com.yzx.codedemo.aspect.LogAspect : 请求结果:1 查询分页列表成功
最后
以上就是单身热狗最近收集整理的关于springboot + AOP 日志一. 简介二. 代码的全部内容,更多相关springboot内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复