Skip to content

Commit

Permalink
feat(log): 不记录日志也支持开启打印访问日志
Browse files Browse the repository at this point in the history
  • Loading branch information
Charles7c committed Aug 30, 2024
1 parent eac5c1f commit 16b6e9b
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -106,17 +106,6 @@ private Started(Clock clock, RecordableHttpRequest request) {
this.request = request;
}

/**
* 结束日志记录
*
* @param response 响应信息
* @param includes 包含信息
* @return 日志记录
*/
public LogRecord finish(RecordableHttpResponse response, Set<Include> includes) {
return finish(Clock.systemUTC(), response, includes);
}

/**
* 结束日志记录
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
import org.springframework.boot.context.properties.ConfigurationProperties;
import top.continew.starter.core.constant.PropertiesConstants;
import top.continew.starter.log.core.enums.Include;
import top.continew.starter.web.util.SpringWebUtils;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

Expand All @@ -41,6 +41,9 @@ public class LogProperties {

/**
* 是否打印日志,开启后可打印访问日志(类似于 Nginx access log)
* <p>
* 不记录日志也支持开启打印访问日志
* </p>
*/
private Boolean isPrint = false;

Expand Down Expand Up @@ -85,4 +88,14 @@ public List<String> getExcludePatterns() {
public void setExcludePatterns(List<String> excludePatterns) {
this.excludePatterns = excludePatterns;
}

/**
* 是否匹配放行路由
*
* @param uri 请求 URI
* @return 是否匹配
*/
public boolean isMatch(String uri) {
return this.getExcludePatterns().stream().anyMatch(pattern -> SpringWebUtils.isMatch(pattern, uri));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import org.springframework.web.util.WebUtils;
import top.continew.starter.log.core.enums.Include;
import top.continew.starter.log.interceptor.autoconfigure.LogProperties;
import top.continew.starter.web.util.SpringWebUtils;

import java.io.IOException;
import java.net.URI;
Expand Down Expand Up @@ -70,12 +69,13 @@ protected void doFilterInternal(@NonNull HttpServletRequest request,
filterChain.doFilter(request, response);
return;
}
boolean isMatch = logProperties.isMatch(request.getRequestURI());
// 包装输入流,可重复读取
if (this.isRequestWrapper(request)) {
if (!isMatch && this.isRequestWrapper(request)) {
request = new ContentCachingRequestWrapper(request);
}
// 包装输出流,可重复读取
boolean isResponseWrapper = this.isResponseWrapper(response);
boolean isResponseWrapper = !isMatch && this.isResponseWrapper(response);
if (isResponseWrapper) {
response = new ContentCachingResponseWrapper(response);
}
Expand All @@ -98,14 +98,7 @@ private boolean isFilter(HttpServletRequest request) {
}
// 不拦截 /error
ServerProperties serverProperties = SpringUtil.getBean(ServerProperties.class);
if (request.getRequestURI().equals(serverProperties.getError().getPath())) {
return false;
}
// 放行
boolean isMatch = logProperties.getExcludePatterns()
.stream()
.anyMatch(pattern -> SpringWebUtils.isMatch(pattern, request.getRequestURI()));
return !isMatch;
return !request.getRequestURI().equals(serverProperties.getError().getPath());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@
import top.continew.starter.log.core.dao.LogDao;
import top.continew.starter.log.core.enums.Include;
import top.continew.starter.log.core.model.LogRecord;
import top.continew.starter.log.core.model.LogResponse;
import top.continew.starter.log.interceptor.autoconfigure.LogProperties;

import java.time.Clock;
import java.time.Duration;
import java.time.Instant;
import java.util.HashSet;
import java.util.Set;

Expand All @@ -50,7 +51,8 @@ public class LogInterceptor implements HandlerInterceptor {
private static final Logger log = LoggerFactory.getLogger(LogInterceptor.class);
private final LogDao logDao;
private final LogProperties logProperties;
private final TransmittableThreadLocal<LogRecord.Started> timestampTtl = new TransmittableThreadLocal<>();
private final TransmittableThreadLocal<Clock> timeTtl = new TransmittableThreadLocal<>();
private final TransmittableThreadLocal<LogRecord.Started> logTtl = new TransmittableThreadLocal<>();

public LogInterceptor(LogDao logDao, LogProperties logProperties) {
this.logDao = logDao;
Expand All @@ -61,13 +63,14 @@ public LogInterceptor(LogDao logDao, LogProperties logProperties) {
public boolean preHandle(@NonNull HttpServletRequest request,
@NonNull HttpServletResponse response,
@NonNull Object handler) {
Clock timestamp = Clock.systemUTC();
if (this.isRequestRecord(handler)) {
if (Boolean.TRUE.equals(logProperties.getIsPrint())) {
log.info("[{}] {}", request.getMethod(), request.getRequestURI());
}
LogRecord.Started startedLogRecord = LogRecord.start(timestamp, new RecordableServletHttpRequest(request));
timestampTtl.set(startedLogRecord);
Clock startTime = Clock.systemUTC();
if (Boolean.TRUE.equals(logProperties.getIsPrint())) {
log.info("[{}] {}", request.getMethod(), request.getRequestURI());
timeTtl.set(startTime);
}
if (this.isRequestRecord(handler, request)) {
LogRecord.Started startedLogRecord = LogRecord.start(startTime, new RecordableServletHttpRequest(request));
logTtl.set(startedLogRecord);
}
return true;
}
Expand All @@ -77,18 +80,23 @@ public void afterCompletion(@NonNull HttpServletRequest request,
@NonNull HttpServletResponse response,
@NonNull Object handler,
Exception e) {
LogRecord.Started startedLogRecord = timestampTtl.get();
if (null == startedLogRecord) {
return;
}
timestampTtl.remove();
try {
Clock endTime = Clock.systemUTC();
if (Boolean.TRUE.equals(logProperties.getIsPrint())) {
Duration timeTaken = Duration.between(Instant.now(timeTtl.get()), Instant.now(endTime));
log.info("[{}] {} {} {}ms", request.getMethod(), request.getRequestURI(), response
.getStatus(), timeTaken.toMillis());
}
LogRecord.Started startedLogRecord = logTtl.get();
if (null == startedLogRecord) {
return;
}
HandlerMethod handlerMethod = (HandlerMethod)handler;
Log methodLog = handlerMethod.getMethodAnnotation(Log.class);
Log classLog = handlerMethod.getBeanType().getDeclaredAnnotation(Log.class);
Set<Include> includeSet = this.getIncludes(methodLog, classLog);
LogRecord finishedLogRecord = startedLogRecord.finish(new RecordableServletHttpResponse(response, response
.getStatus()), includeSet);
LogRecord finishedLogRecord = startedLogRecord
.finish(endTime, new RecordableServletHttpResponse(response, response.getStatus()), includeSet);
// 记录日志描述
if (includeSet.contains(Include.DESCRIPTION)) {
this.logDescription(finishedLogRecord, methodLog, handlerMethod);
Expand All @@ -97,14 +105,12 @@ public void afterCompletion(@NonNull HttpServletRequest request,
if (includeSet.contains(Include.MODULE)) {
this.logModule(finishedLogRecord, methodLog, classLog, handlerMethod);
}
if (Boolean.TRUE.equals(logProperties.getIsPrint())) {
LogResponse logResponse = finishedLogRecord.getResponse();
log.info("[{}] {} {} {}ms", request.getMethod(), request.getRequestURI(), logResponse
.getStatus(), finishedLogRecord.getTimeTaken().toMillis());
}
logDao.add(finishedLogRecord);
} catch (Exception ex) {
log.error("Logging http log occurred an error: {}.", ex.getMessage(), ex);
} finally {
timeTtl.remove();
logTtl.remove();
}
}

Expand All @@ -116,8 +122,7 @@ public void afterCompletion(@NonNull HttpServletRequest request,
* @return 日志包含信息
*/
private Set<Include> getIncludes(Log methodLog, Log classLog) {
Set<Include> oriIncludeSet = logProperties.getIncludes();
Set<Include> includeSet = new HashSet<>(oriIncludeSet);
Set<Include> includeSet = new HashSet<>(logProperties.getIncludes());
if (null != classLog) {
this.processInclude(includeSet, classLog);
}
Expand Down Expand Up @@ -196,10 +201,14 @@ private void logModule(LogRecord logRecord, Log methodLog, Log classLog, Handler
* @param handler 处理器
* @return true:需要记录;false:不需要记录
*/
private boolean isRequestRecord(Object handler) {
private boolean isRequestRecord(Object handler, HttpServletRequest request) {
if (!(handler instanceof HandlerMethod handlerMethod)) {
return false;
}
// 如果接口匹配排除列表,不记录日志
if (logProperties.isMatch(request.getRequestURI())) {
return false;
}
// 如果接口被隐藏,不记录日志
Operation methodOperation = handlerMethod.getMethodAnnotation(Operation.class);
if (null != methodOperation && methodOperation.hidden()) {
Expand Down

0 comments on commit 16b6e9b

Please sign in to comment.