我是靠谱客的博主 风趣水池,这篇文章主要介绍springboot学习(五十四) springboot中记录审计/访问日志,现在分享给大家,希望可以做个参考。

在web项目中记录每个接口的访问信息做审计是很重要的,下面介绍使用log4j2+拦截器将日志记录到日志文件的一种方式。

1、编写记录日志实体类AccessLog

复制代码
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
package com.iscas.biz.model.common.access; import lombok.Data; import lombok.experimental.Accessors; import java.util.Date; /** * 访问日志的实体 * * @author zhuquanwen * @vesion 1.0 * @date 2021/8/29 20:37 * @since jdk1.8 */ @Data @Accessors(chain = true) public class AccessLog { /**访问用户*/ private String username = "unknown"; /**uri*/ private String uri; /**访问时长*/ private Long duration; /**请求方式*/ private String method; /**客户端IP*/ private String ip; /**状态码*/ private int status; /**时间*/ private Date createTime; }

2、编写拦截器

这里在preHandle中构建基础AccessLog的属性和请求时间并将它们绑定到request中,在postHandle中从request中取出AccessLog并设置访问耗时、访问用户等属性,注意:这里的访问用户的获取方式是我项目中的方式,根据实际情况要做修改。
设置完所有AccessLog的属性后,使用log.debug输出日志。

复制代码
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
package com.iscas.biz.config.log; import com.iscas.base.biz.model.auth.AuthContext; import com.iscas.base.biz.util.AuthContextHolder; import com.iscas.base.biz.util.SpringUtils; import com.iscas.biz.model.common.access.AccessLog; import lombok.extern.slf4j.Slf4j; import org.springframework.lang.Nullable; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Date; /** * 访问/审计日志 * @author zhuquanwen * @vesion 1.0 * @date 2021/8/29 20:42 * @since jdk1.8 */ @Slf4j public class AccessLogInterceptor implements HandlerInterceptor { /**访问开始时间*/ private static final String KEY_REQUEST_START_TIME = "KEY_REQUEST_START_TIME"; /**访问开始时间*/ private static final String KEY_ACCESS_LOG = "KEY_ACCESS_LOG"; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { AccessLog accessLog = new AccessLog(); accessLog.setIp(SpringUtils.getIpAddr()) .setMethod(request.getMethod()) .setUri(request.getRequestURI()); //将信息绑定在request中 request.setAttribute(KEY_REQUEST_START_TIME, System.currentTimeMillis()); request.setAttribute(KEY_ACCESS_LOG, accessLog); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { AccessLog accessLog = (AccessLog) request.getAttribute(KEY_ACCESS_LOG); Long startTime = (Long) request.getAttribute(KEY_REQUEST_START_TIME); if (accessLog != null) { Date createTime = new Date(); AuthContext context = AuthContextHolder.getContext(); accessLog.setCreateTime(createTime) .setDuration(createTime.getTime() - startTime) .setStatus(response.getStatus()) .setUsername(context == null ? null : context.getUsername()); log.debug(accessLog.toString()); } } }

3、注册拦截器

复制代码
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
package com.iscas.biz.config; import com.iscas.biz.config.log.AccessLogInterceptor; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * * @author zhuquanwen * @vesion 1.0 * @date 2021/8/29 21:02 * @since jdk1.8 */ @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { // 添加拦截器,配置拦截地址 registry.addInterceptor(new AccessLogInterceptor()) .addPathPatterns("/**"); // .excludePathPatterns("/login","/userLogin") // .excludePathPatterns("/image/**"); } }

4、配置log4j2对审计日志的支持
log4j2的配置方式见上一篇文章介绍:https://blog.csdn.net/u011943534/article/details/119876319

在上一篇的配置基础上,添加审计日志的RollingFile,日志级别为debug

复制代码
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
<!--访问日志--> <RollingFile name="accessAppender" fileName="${FILE_PATH}/${FILE_NAME}/log_access.log" filePattern="${FILE_PATH}/${FILE_NAME}/access/log-access-%d{yyyy-MM-dd}_%i.log.gz" append="true"> <!--设置日志格式--> <PatternLayout pattern="${ACCESS_LOG_PATTERN}" charset="UTF-8"/> <Filters> <ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"/> </Filters> <Policies> <!-- 基于时间的触发策略。该策略主要是完成周期性的log文件封存工作。有两个参数: interval,integer型,指定两次封存动作之间的时间间隔。单位:以日志的命名精度来确定单位, 比如yyyy-MM-dd-HH 单位为小时,yyyy-MM-dd-HH-mm 单位为分钟 modulate,boolean型,说明是否对封存时间进行调制。若modulate=true, 则封存时间将以0点为边界进行偏移计算。比如,modulate=true,interval=4hours, 那么假设上次封存日志的时间为00:00,则下次封存日志的时间为04:00, 之后的封存时间依次为08:00,12:00,16:00--> <TimeBasedTriggeringPolicy interval="1"/> <SizeBasedTriggeringPolicy size="10MB"/> </Policies> <!-- DefaultRolloverStrategy 属性如不设置,则默认为最多同一文件夹下当天 7 个文件后开始覆盖--> <DefaultRolloverStrategy max="30"> <!-- 删除处理策略,在配置的路径中搜索,maxDepth 表示往下搜索的最大深度 --> <Delete basePath="${FILE_PATH}/${FILE_NAME}/" maxDepth="2"> <!-- 文件名搜索匹配,支持正则 --> <IfFileName glob="*.log.gz"/> <!--!Note: 这里的 age 必须和 filePattern 协调, 后者是精确到 dd, 这里就要写成 xd, xD 就不起作用 另外, 数字最好 >2, 否则可能造成删除的时候, 最近的文件还处于被占用状态,导致删除不成功!--> <!--7天--> <IfLastModified age="7d"/> </Delete> </DefaultRolloverStrategy> </RollingFile>

ACCESS_LOG_PATTERN的格式如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
<!--变量配置--> <properties> <!-- 格式化输出:%date 表示日期,%thread 表示线程名,%-5level:级别从左显示 5 个字符宽度 %msg:日志消息,%n 是换行符--> <!-- %logger{36} 表示 Logger 名字最长 36 个字符 --> <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level [%logger{50}:%L] - %msg%n"/> <property name="LOG_CONSOLE_PATTERN" value="%style{%d{ISO8601}}{bright,green} %highlight{%-5level} [%style{%t}{bright,blue}] %style{%C{}}{bright,yellow}: %msg%n%style{%throwable}{red}"/> <property name="ACCESS_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} - %msg%n"/> <!-- 定义日志存储的路径 --> <property name="FILE_PATH" value="logs"/> <property name="FILE_NAME" value="newframe"/> </properties>

将拦截器类单独配置一个Logger:

复制代码
1
2
3
4
5
<AsyncLogger name="com.iscas.biz.config.log.AccessLogInterceptor" level="debug" includeLocation="true" additivity="false"> <AppenderRef ref="accessAppender"/> <AppenderRef ref="consoleAppender"/> </AsyncLogger>

大功告成,看下我生成的access_log.log文件:

复制代码
1
2
3
4
2021-08-29 21:11:36.822 - AccessLog(username=null, uri=/demo/ttt, duration=7, method=GET, ip=0:0:0:0:0:0:0:1, status=404, createTime=Sun Aug 29 21:11:36 CST 2021) 2021-08-29 21:11:39.639 - AccessLog(username=null, uri=/demo/404, duration=23, method=GET, ip=0:0:0:0:0:0:0:1, status=404, createTime=Sun Aug 29 21:11:39 CST 2021)

最后

以上就是风趣水池最近收集整理的关于springboot学习(五十四) springboot中记录审计/访问日志的全部内容,更多相关springboot学习(五十四)内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(72)

评论列表共有 0 条评论

立即
投稿
返回
顶部