SpringBoot项目中使用切面记录系统日志

在SpringBoot项目中使用切面记录系统日志

导入aop依赖

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

创建日志类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Data
public class SysLog {

private Long id;

@JsonFormat(pattern = "yyy-MM-dd HH:mm:ss")
private Date visitTime;

private String ip;
private String uri;
private String username;

/** 访问的方法 */
private String method;
/** 执行时间*/
private Long execTime;
}

先创建查看日志的接口

  • controller
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@RestController
@RequestMapping("/syslog")
public class SysLogController {

@Autowired
private SysLogService sysLogService;

@GetMapping
public ResponseEntity<List<SysLog>> querySysLog() {
List<SysLog> sysLogs = sysLogService.querySysLog();
if (CollectionUtils.isEmpty(sysLogs)) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
}
return ResponseEntity.ok(sysLogs);
}
}
  • service
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
@Service
public class SysLogService {

@Autowired
private StringRedisTemplate redisTemplate;

private ObjectMapper objectMapper = new ObjectMapper();

/** redis key */
private final String KEY = "syslog";

public List<SysLog> querySysLog() {
BoundListOperations<String, String> ops = redisTemplate.boundListOps(KEY);

return ops.range(0, -1).stream()
.map(s -> {
try {
return objectMapper.readValue(s, SysLog.class);
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
}
}).collect(Collectors.toList());
}

public void save(SysLog sysLog) {
if (sysLog == null) {
return;
}

BoundListOperations<String, String> ops = redisTemplate.boundListOps(KEY);
try {
ops.rightPush(objectMapper.writeValueAsString(sysLog));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
}

创建AOP切面

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
@Component
@Aspect
@Slf4j
public class SysLogAop {

/** 访问的类 */
private Class clazz;
/** 访问的方法 */
private String methodName;
/** 访问时间 */
private Date visitTime;

@Autowired
private HttpServletRequest request;
@Autowired
private SysLogService sysLogService;

/** 切点 */
@Pointcut("execution(* com.tan.controller.*.*(..))")
public void controllerPointcut() {
}

/** 前置通知 */
@Before("controllerPointcut()")
public void before(JoinPoint joinPoint) {
visitTime = new Date();
// 获取访问的类、方法
clazz = joinPoint.getTarget().getClass();
methodName = joinPoint.getSignature().getName();
}

/** 后置通知 */
@After("controllerPointcut()")
public void after(JoinPoint joinPoint) {
// 不记录查看日志操作
if (clazz == SysLogController.class) {
return;
}

// 获取用户 这里我是用user简单模拟一下
String username = "user";
// 执行时间
long execTime = System.currentTimeMillis() - visitTime.getTime();
// ip
String ip = request.getRemoteAddr();
// uri
String uri = request.getRequestURI();
// 封装数据
SysLog sysLog = new SysLog();
sysLog.setVisitTime(visitTime);
sysLog.setExecTime(execTime);
sysLog.setMethod(methodName);
sysLog.setIp(ip);
sysLog.setUri(uri);
sysLog.setUsername(username);
// 持久化
sysLogService.save(sysLog);
log.info("SysLog: {}", sysLog);
}
}

重启服务,此后我们所访问controller都会被记录下来啦。


 

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×