mirror of
https://github.com/continew-org/continew-starter.git
synced 2025-09-09 20:57:23 +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,
|
MODULE,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 请求头
|
* 请求头(默认)
|
||||||
*/
|
*/
|
||||||
REQUEST_HEADERS,
|
REQUEST_HEADERS,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 请求体
|
* 请求体(如包含请求体,则请求参数无效)
|
||||||
*/
|
*/
|
||||||
REQUEST_BODY,
|
REQUEST_BODY,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 请求参数
|
* 请求参数(默认)
|
||||||
*/
|
*/
|
||||||
REQUEST_PARAM,
|
REQUEST_PARAM,
|
||||||
|
|
||||||
@@ -72,32 +72,29 @@ public enum Include {
|
|||||||
OS,
|
OS,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 响应头
|
* 响应头(默认)
|
||||||
*/
|
*/
|
||||||
RESPONSE_HEADERS,
|
RESPONSE_HEADERS,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 响应体
|
* 响应体(如包含响应体,则响应参数无效)
|
||||||
*/
|
*/
|
||||||
RESPONSE_BODY,
|
RESPONSE_BODY,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 响应参数
|
* 响应参数(默认)
|
||||||
*/
|
*/
|
||||||
RESPONSE_PARAM,
|
RESPONSE_PARAM,
|
||||||
|
;
|
||||||
/**
|
|
||||||
* 耗时
|
|
||||||
*/
|
|
||||||
TIME_TAKEN;
|
|
||||||
|
|
||||||
private static final Set<Include> DEFAULT_INCLUDES;
|
private static final Set<Include> DEFAULT_INCLUDES;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
Set<Include> defaultIncludes = new LinkedHashSet<>();
|
Set<Include> defaultIncludes = new LinkedHashSet<>();
|
||||||
defaultIncludes.add(Include.TIME_TAKEN);
|
|
||||||
defaultIncludes.add(Include.REQUEST_HEADERS);
|
defaultIncludes.add(Include.REQUEST_HEADERS);
|
||||||
defaultIncludes.add(Include.RESPONSE_HEADERS);
|
defaultIncludes.add(Include.RESPONSE_HEADERS);
|
||||||
|
defaultIncludes.add(Include.REQUEST_PARAM);
|
||||||
|
defaultIncludes.add(Include.RESPONSE_PARAM);
|
||||||
DEFAULT_INCLUDES = Collections.unmodifiableSet(defaultIncludes);
|
DEFAULT_INCLUDES = Collections.unmodifiableSet(defaultIncludes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -131,7 +131,7 @@ public class LogRecord {
|
|||||||
public LogRecord finish(Clock clock, RecordableHttpResponse response, Set<Include> includes) {
|
public LogRecord finish(Clock clock, RecordableHttpResponse response, Set<Include> includes) {
|
||||||
LogRequest logRequest = new LogRequest(this.request, includes);
|
LogRequest logRequest = new LogRequest(this.request, includes);
|
||||||
LogResponse logResponse = new LogResponse(response, 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);
|
return new LogRecord(this.timestamp, logRequest, logResponse, duration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -87,8 +87,11 @@ public class LogRequest {
|
|||||||
this.uri = request.getUri();
|
this.uri = request.getUri();
|
||||||
this.ip = request.getIp();
|
this.ip = request.getIp();
|
||||||
this.headers = (includes.contains(Include.REQUEST_HEADERS)) ? request.getHeaders() : null;
|
this.headers = (includes.contains(Include.REQUEST_HEADERS)) ? request.getHeaders() : null;
|
||||||
this.body = (includes.contains(Include.REQUEST_BODY)) ? request.getBody() : null;
|
if (includes.contains(Include.REQUEST_BODY)) {
|
||||||
this.param = (includes.contains(Include.RESPONSE_PARAM)) ? request.getParam() : null;
|
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;
|
this.address = (includes.contains(Include.IP_ADDRESS)) ? IpUtils.getAddress(this.ip) : null;
|
||||||
String userAgentString = ExceptionUtils.exToNull(() -> this.headers.get(HttpHeaders.USER_AGENT).get(0));
|
String userAgentString = ExceptionUtils.exToNull(() -> this.headers.get(HttpHeaders.USER_AGENT).get(0));
|
||||||
this.browser = (includes.contains(Include.BROWSER)) ? ServletUtils.getBrowser(userAgentString) : null;
|
this.browser = (includes.contains(Include.BROWSER)) ? ServletUtils.getBrowser(userAgentString) : null;
|
||||||
|
@@ -52,8 +52,11 @@ public class LogResponse {
|
|||||||
|
|
||||||
public LogResponse(RecordableHttpResponse response, Set<Include> includes) {
|
public LogResponse(RecordableHttpResponse response, Set<Include> includes) {
|
||||||
this.status = response.getStatus();
|
this.status = response.getStatus();
|
||||||
this.headers = (includes.contains(Include.REQUEST_HEADERS)) ? response.getHeaders() : null;
|
this.headers = (includes.contains(Include.RESPONSE_HEADERS)) ? response.getHeaders() : null;
|
||||||
this.body = (includes.contains(Include.REQUEST_BODY)) ? response.getBody() : null;
|
if (includes.contains(Include.RESPONSE_BODY)) {
|
||||||
this.param = (includes.contains(Include.RESPONSE_PARAM)) ? response.getParam() : null;
|
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;
|
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.dao.LogDao;
|
||||||
import top.charles7c.continew.starter.log.common.enums.Include;
|
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.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 top.charles7c.continew.starter.log.httptracepro.autoconfigure.LogProperties;
|
||||||
|
|
||||||
import java.time.Clock;
|
import java.time.Clock;
|
||||||
@@ -48,13 +50,19 @@ public class LogInterceptor implements HandlerInterceptor {
|
|||||||
|
|
||||||
private final LogDao dao;
|
private final LogDao dao;
|
||||||
private final LogProperties properties;
|
private final LogProperties properties;
|
||||||
private final TransmittableThreadLocal<Clock> timestampTtl = new TransmittableThreadLocal<>();
|
private final TransmittableThreadLocal<LogRecord.Started> timestampTtl = new TransmittableThreadLocal<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean preHandle(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response,
|
public boolean preHandle(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response,
|
||||||
@NonNull Object handler) {
|
@NonNull Object handler) {
|
||||||
|
Clock timestamp = Clock.systemUTC();
|
||||||
if (this.isRequestRecord(handler)) {
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -62,26 +70,28 @@ public class LogInterceptor implements HandlerInterceptor {
|
|||||||
@Override
|
@Override
|
||||||
public void afterCompletion(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response,
|
public void afterCompletion(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response,
|
||||||
@NonNull Object handler, Exception e) {
|
@NonNull Object handler, Exception e) {
|
||||||
Clock timestamp = timestampTtl.get();
|
LogRecord.Started startedLogRecord = timestampTtl.get();
|
||||||
if (null == timestamp) {
|
if (null == startedLogRecord) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
timestampTtl.remove();
|
timestampTtl.remove();
|
||||||
Set<Include> includeSet = properties.getInclude();
|
Set<Include> includeSet = properties.getInclude();
|
||||||
RecordableServletHttpRequest sourceRequest = new RecordableServletHttpRequest(request);
|
|
||||||
try {
|
try {
|
||||||
LogRecord.Started startedLogRecord = LogRecord.start(timestamp, sourceRequest);
|
LogRecord finishedLogRecord = startedLogRecord.finish(new RecordableServletHttpResponse(response, response.getStatus()), includeSet);
|
||||||
RecordableServletHttpResponse sourceResponse = new RecordableServletHttpResponse(response, response.getStatus());
|
|
||||||
LogRecord finishedLogRecord = startedLogRecord.finish(sourceResponse, includeSet);
|
|
||||||
HandlerMethod handlerMethod = (HandlerMethod) handler;
|
HandlerMethod handlerMethod = (HandlerMethod) handler;
|
||||||
|
// 记录日志描述
|
||||||
if (includeSet.contains(Include.DESCRIPTION)) {
|
if (includeSet.contains(Include.DESCRIPTION)) {
|
||||||
// 记录日志描述
|
|
||||||
this.logDescription(finishedLogRecord, handlerMethod);
|
this.logDescription(finishedLogRecord, handlerMethod);
|
||||||
}
|
}
|
||||||
|
// 记录所属模块
|
||||||
if (includeSet.contains(Include.MODULE)) {
|
if (includeSet.contains(Include.MODULE)) {
|
||||||
// 记录所属模块
|
|
||||||
this.logModule(finishedLogRecord, handlerMethod);
|
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);
|
dao.add(finishedLogRecord);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
log.error("Logging http log occurred an error: {}.", ex.getMessage(), 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() {
|
public URI getUri() {
|
||||||
String queryString = request.getQueryString();
|
String queryString = request.getQueryString();
|
||||||
if (StrUtil.isBlank(queryString)) {
|
if (StrUtil.isBlank(queryString)) {
|
||||||
return URI.create(request.getRequestURL().toString());
|
return URI.create(request.getRequestURI());
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
StringBuffer urlBuffer = this.appendQueryString(queryString);
|
return new URI(this.appendQueryString(queryString));
|
||||||
return new URI(urlBuffer.toString());
|
|
||||||
} catch (URISyntaxException e) {
|
} catch (URISyntaxException e) {
|
||||||
String encoded = UriUtils.encodeQuery(queryString, StandardCharsets.UTF_8);
|
String encoded = UriUtils.encodeQuery(queryString, StandardCharsets.UTF_8);
|
||||||
StringBuffer urlBuffer = this.appendQueryString(encoded);
|
return URI.create(this.appendQueryString(encoded));
|
||||||
return URI.create(urlBuffer.toString());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +91,7 @@ public final class RecordableServletHttpRequest implements RecordableHttpRequest
|
|||||||
: Collections.unmodifiableMap(request.getParameterMap());
|
: Collections.unmodifiableMap(request.getParameterMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
private StringBuffer appendQueryString(String queryString) {
|
private String appendQueryString(String queryString) {
|
||||||
return request.getRequestURL().append(StringConstants.QUESTION_MARK).append(queryString);
|
return request.getRequestURI() + StringConstants.QUESTION_MARK + queryString;
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user