mirror of
				https://github.com/continew-org/continew-starter.git
				synced 2025-10-31 10:57:15 +08:00 
			
		
		
		
	refactor(log/httptrace-pro): 优化日志记录
1.新增是否打印配置,开启后可打印访问日志(类似于 Nginx access log) 2.TIME_TAKEN 请求耗时,调整为必然记录 3.REQUEST_PARAM 请求参数、RESPONSE_PARAM 响应参数调整为默认记录 4.包含信息配置:BODY 和 PARAM 调整为互斥,包含 BODY 则对应 PARAM 不记录 5.请求 URI 不再记录协议、域名等信息 6.修复部分请求、响应信息记录错误
This commit is contained in:
		| @@ -42,17 +42,17 @@ public enum Include { | ||||
|     MODULE, | ||||
|  | ||||
|     /** | ||||
|      * 请求头 | ||||
|      * 请求头(默认) | ||||
|      */ | ||||
|     REQUEST_HEADERS, | ||||
|  | ||||
|     /** | ||||
|      * 请求体 | ||||
|      * 请求体(如包含请求体,则请求参数无效) | ||||
|      */ | ||||
|     REQUEST_BODY, | ||||
|  | ||||
|     /** | ||||
|      * 请求参数 | ||||
|      * 请求参数(默认) | ||||
|      */ | ||||
|     REQUEST_PARAM, | ||||
|  | ||||
| @@ -72,32 +72,29 @@ public enum Include { | ||||
|     OS, | ||||
|  | ||||
|     /** | ||||
|      * 响应头 | ||||
|      * 响应头(默认) | ||||
|      */ | ||||
|     RESPONSE_HEADERS, | ||||
|  | ||||
|     /** | ||||
|      * 响应体 | ||||
|      * 响应体(如包含响应体,则响应参数无效) | ||||
|      */ | ||||
|     RESPONSE_BODY, | ||||
|  | ||||
|     /** | ||||
|      * 响应参数 | ||||
|      * 响应参数(默认) | ||||
|      */ | ||||
|     RESPONSE_PARAM, | ||||
|  | ||||
|     /** | ||||
|      * 耗时 | ||||
|      */ | ||||
|     TIME_TAKEN; | ||||
|     ; | ||||
|  | ||||
|     private static final Set<Include> DEFAULT_INCLUDES; | ||||
|  | ||||
|     static { | ||||
|         Set<Include> defaultIncludes = new LinkedHashSet<>(); | ||||
|         defaultIncludes.add(Include.TIME_TAKEN); | ||||
|         defaultIncludes.add(Include.REQUEST_HEADERS); | ||||
|         defaultIncludes.add(Include.RESPONSE_HEADERS); | ||||
|         defaultIncludes.add(Include.REQUEST_PARAM); | ||||
|         defaultIncludes.add(Include.RESPONSE_PARAM); | ||||
|         DEFAULT_INCLUDES = Collections.unmodifiableSet(defaultIncludes); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -131,7 +131,7 @@ public class LogRecord { | ||||
|         public LogRecord finish(Clock clock, RecordableHttpResponse response, Set<Include> includes) { | ||||
|             LogRequest logRequest = new LogRequest(this.request, includes); | ||||
|             LogResponse logResponse = new LogResponse(response, includes); | ||||
|             Duration duration = (includes.contains(Include.TIME_TAKEN)) ? Duration.between(this.timestamp, Instant.now(clock)) : null; | ||||
|             Duration duration = Duration.between(this.timestamp, Instant.now(clock)); | ||||
|             return new LogRecord(this.timestamp, logRequest, logResponse, duration); | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -87,8 +87,11 @@ public class LogRequest { | ||||
|         this.uri = request.getUri(); | ||||
|         this.ip = request.getIp(); | ||||
|         this.headers = (includes.contains(Include.REQUEST_HEADERS)) ? request.getHeaders() : null; | ||||
|         this.body = (includes.contains(Include.REQUEST_BODY)) ? request.getBody() : null; | ||||
|         this.param = (includes.contains(Include.RESPONSE_PARAM)) ? request.getParam() : null; | ||||
|         if (includes.contains(Include.REQUEST_BODY)) { | ||||
|             this.body = request.getBody(); | ||||
|         } else if (includes.contains(Include.REQUEST_PARAM)) { | ||||
|             this.param = request.getParam(); | ||||
|         } | ||||
|         this.address = (includes.contains(Include.IP_ADDRESS)) ? IpUtils.getAddress(this.ip) : null; | ||||
|         String userAgentString = ExceptionUtils.exToNull(() -> this.headers.get(HttpHeaders.USER_AGENT).get(0)); | ||||
|         this.browser = (includes.contains(Include.BROWSER)) ? ServletUtils.getBrowser(userAgentString) : null; | ||||
|   | ||||
| @@ -52,8 +52,11 @@ public class LogResponse { | ||||
|  | ||||
|     public LogResponse(RecordableHttpResponse response, Set<Include> includes) { | ||||
|         this.status = response.getStatus(); | ||||
|         this.headers = (includes.contains(Include.REQUEST_HEADERS)) ? response.getHeaders() : null; | ||||
|         this.body = (includes.contains(Include.REQUEST_BODY)) ? response.getBody() : null; | ||||
|         this.param = (includes.contains(Include.RESPONSE_PARAM)) ? response.getParam() : null; | ||||
|         this.headers = (includes.contains(Include.RESPONSE_HEADERS)) ? response.getHeaders() : null; | ||||
|         if (includes.contains(Include.RESPONSE_BODY)) { | ||||
|             this.body = response.getBody(); | ||||
|         } else if (includes.contains(Include.RESPONSE_PARAM)) { | ||||
|             this.param = response.getParam(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -38,6 +38,11 @@ public class LogProperties { | ||||
|      */ | ||||
|     private boolean enabled = false; | ||||
|  | ||||
|     /** | ||||
|      * 是否打印日志,开启后可打印访问日志(类似于 Nginx access log) | ||||
|      */ | ||||
|     private Boolean isPrint = false; | ||||
|  | ||||
|     /** | ||||
|      * 包含信息 | ||||
|      */ | ||||
|   | ||||
| @@ -31,6 +31,8 @@ import top.charles7c.continew.starter.log.common.annotation.Log; | ||||
| import top.charles7c.continew.starter.log.common.dao.LogDao; | ||||
| import top.charles7c.continew.starter.log.common.enums.Include; | ||||
| import top.charles7c.continew.starter.log.common.model.LogRecord; | ||||
| import top.charles7c.continew.starter.log.common.model.LogRequest; | ||||
| import top.charles7c.continew.starter.log.common.model.LogResponse; | ||||
| import top.charles7c.continew.starter.log.httptracepro.autoconfigure.LogProperties; | ||||
|  | ||||
| import java.time.Clock; | ||||
| @@ -48,13 +50,19 @@ public class LogInterceptor implements HandlerInterceptor { | ||||
|  | ||||
|     private final LogDao dao; | ||||
|     private final LogProperties properties; | ||||
|     private final TransmittableThreadLocal<Clock> timestampTtl = new TransmittableThreadLocal<>(); | ||||
|     private final TransmittableThreadLocal<LogRecord.Started> timestampTtl = new TransmittableThreadLocal<>(); | ||||
|  | ||||
|     @Override | ||||
|     public boolean preHandle(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, | ||||
|                              @NonNull Object handler) { | ||||
|         Clock timestamp = Clock.systemUTC(); | ||||
|         if (this.isRequestRecord(handler)) { | ||||
|             timestampTtl.set(Clock.systemUTC()); | ||||
|             RecordableServletHttpRequest sourceRequest = new RecordableServletHttpRequest(request); | ||||
|             if (Boolean.TRUE.equals(properties.getIsPrint())) { | ||||
|                 log.info("[{}] {}", sourceRequest.getMethod(), sourceRequest.getUri()); | ||||
|             } | ||||
|             LogRecord.Started startedLogRecord = LogRecord.start(timestamp, sourceRequest); | ||||
|             timestampTtl.set(startedLogRecord); | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
| @@ -62,26 +70,28 @@ public class LogInterceptor implements HandlerInterceptor { | ||||
|     @Override | ||||
|     public void afterCompletion(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, | ||||
|                                 @NonNull Object handler, Exception e) { | ||||
|         Clock timestamp = timestampTtl.get(); | ||||
|         if (null == timestamp) { | ||||
|         LogRecord.Started startedLogRecord = timestampTtl.get(); | ||||
|         if (null == startedLogRecord) { | ||||
|             return; | ||||
|         } | ||||
|         timestampTtl.remove(); | ||||
|         Set<Include> includeSet = properties.getInclude(); | ||||
|         RecordableServletHttpRequest sourceRequest = new RecordableServletHttpRequest(request); | ||||
|         try { | ||||
|             LogRecord.Started startedLogRecord = LogRecord.start(timestamp, sourceRequest); | ||||
|             RecordableServletHttpResponse sourceResponse = new RecordableServletHttpResponse(response, response.getStatus()); | ||||
|             LogRecord finishedLogRecord = startedLogRecord.finish(sourceResponse, includeSet); | ||||
|             LogRecord finishedLogRecord = startedLogRecord.finish(new RecordableServletHttpResponse(response, response.getStatus()), includeSet); | ||||
|             HandlerMethod handlerMethod = (HandlerMethod) handler; | ||||
|             if (includeSet.contains(Include.DESCRIPTION)) { | ||||
|             // 记录日志描述 | ||||
|             if (includeSet.contains(Include.DESCRIPTION)) { | ||||
|                 this.logDescription(finishedLogRecord, handlerMethod); | ||||
|             } | ||||
|             if (includeSet.contains(Include.MODULE)) { | ||||
|             // 记录所属模块 | ||||
|             if (includeSet.contains(Include.MODULE)) { | ||||
|                 this.logModule(finishedLogRecord, handlerMethod); | ||||
|             } | ||||
|             if (Boolean.TRUE.equals(properties.getIsPrint())) { | ||||
|                 LogRequest logRequest = finishedLogRecord.getRequest(); | ||||
|                 LogResponse logResponse = finishedLogRecord.getResponse(); | ||||
|                 log.info("[{}] {} {} {}ms", logRequest.getMethod(), logRequest.getUri(), logResponse.getStatus(), finishedLogRecord.getTimeTaken().toMillis()); | ||||
|             } | ||||
|             dao.add(finishedLogRecord); | ||||
|         } catch (Exception ex) { | ||||
|             log.error("Logging http log occurred an error: {}.", ex.getMessage(), ex); | ||||
|   | ||||
| @@ -54,15 +54,13 @@ public final class RecordableServletHttpRequest implements RecordableHttpRequest | ||||
|     public URI getUri() { | ||||
|         String queryString = request.getQueryString(); | ||||
|         if (StrUtil.isBlank(queryString)) { | ||||
|             return URI.create(request.getRequestURL().toString()); | ||||
|             return URI.create(request.getRequestURI()); | ||||
|         } | ||||
|         try { | ||||
|             StringBuffer urlBuffer = this.appendQueryString(queryString); | ||||
|             return new URI(urlBuffer.toString()); | ||||
|             return new URI(this.appendQueryString(queryString)); | ||||
|         } catch (URISyntaxException e) { | ||||
|             String encoded = UriUtils.encodeQuery(queryString, StandardCharsets.UTF_8); | ||||
|             StringBuffer urlBuffer = this.appendQueryString(encoded); | ||||
|             return URI.create(urlBuffer.toString()); | ||||
|             return URI.create(this.appendQueryString(encoded)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -93,7 +91,7 @@ public final class RecordableServletHttpRequest implements RecordableHttpRequest | ||||
|                 : Collections.unmodifiableMap(request.getParameterMap()); | ||||
|     } | ||||
|  | ||||
|     private StringBuffer appendQueryString(String queryString) { | ||||
|         return request.getRequestURL().append(StringConstants.QUESTION_MARK).append(queryString); | ||||
|     private String appendQueryString(String queryString) { | ||||
|         return request.getRequestURI() + StringConstants.QUESTION_MARK + queryString; | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user