This commit is contained in:
oneao committed 2026-10-14 17:25:47 +08:00
1 parent 15e0ae5b67
commit e434374db5
71 files changed
+5726 -329

No files matched your search

+4 -1
View File
@@ -41,6 +41,9 @@
控制台输出彩色文本;文件输出**结构化 JSON**(每行一个对象,logstash 格式),默认落在 `server/logs/`
(相对进程工作目录的 `./logs`,根 `.gitignore` 已忽略)。
控制台字段顺序:`时间 级别 [traceId] [orgId/userId] method uri logger: message`。logger 列**不做定宽补齐**
(短名 `ACCESS` 补齐会留下一大段空白),需要精确定位时看文件 JSON 的 `logger_name`。
| 文件 | 内容 |
|---|---|
| `logs/erp-api.jsonl` | 全量日志 |
@@ -62,7 +65,7 @@
> 入参 `X-Request-Id` 需匹配 `^[A-Za-z0-9._-]{8,64}$` 才会被复用,否则**静默忽略并自行生成**(防日志注入 / 换行伪造)。
> 若发现上游的 traceId 没串起来,先检查这个格式约束。W3C `traceparent` 则要求标准 `00-<32hex>-<16hex>-<2hex>` 格式。
访问日志每请求一行(`logger_name=ACCESS`、`message=http_access`)。主要字段(均为 JSON 顶层字段):
访问日志每请求一行(`logger_name=ACCESS`,`message` 形如 `200 45ms`,慢请求带 `SLOW` 后缀)。主要字段(均为 JSON 顶层字段):
| 字段 | 说明 |
|---|---|
@@ -81,6 +81,7 @@ public class RequestLoggingFilter extends OncePerRequestFilter {
status = response.getStatus();
} finally {
long durationMs = (System.nanoTime() - startNanos) / 1_000_000L;
boolean slow = durationMs > logProperties.getSlowRequestMs();
try {
// traceId / orgId / userId / method / uri 由 MDC 自动平铺进此行 JSON
LoggingEventBuilder event = ACCESS.atInfo()
@@ -88,7 +89,7 @@ public class RequestLoggingFilter extends OncePerRequestFilter {
.addKeyValue("durationMs", durationMs)
.addKeyValue("clientIp", IpUtils.getClientIp(request))
.addKeyValue("userAgent", truncate(request.getHeader(HEADER_USER_AGENT), 256));
if (durationMs > logProperties.getSlowRequestMs()) {
if (slow) {
event.addKeyValue("slow", true);
if (!logProperties.isParamLoggingExcluded(request.getServletPath())) {
String params = RequestParams.collect(effectiveRequest, logProperties.getMaxParamBytes());
@@ -97,7 +98,8 @@ public class RequestLoggingFilter extends OncePerRequestFilter {
}
}
}
event.log("http_access");
// 消息只给控制台看:状态码 + 耗时;其余信息在 MDC 和 KV 字段里
event.log(slow ? status + " " + durationMs + "ms SLOW" : status + " " + durationMs + "ms");
} finally {
// 线程池复用线程,必须清理,避免上下文串到下一个请求
MDC.clear();
@@ -15,8 +15,11 @@
<conversionRule conversionWord="wex" class="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
<conversionRule conversionWord="wEx" class="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<!-- 字段顺序:时间 级别 [traceId] [orgId/userId] method uri logger: message
注意 logger 不补齐宽度。只有访问日志的 logger 是短名 ACCESS,
若写成 %-40.40logger 会在它后面补 34 个空格,出现一大段无意义空白 -->
<property name="CONSOLE_PATTERN"
value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p){} %clr([%X{traceId:-}]){magenta} %clr([%X{orgId:-}/%X{userId:-}]){green} %clr(%X{method:-} %X{uri:-}){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx"/>
value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%5p){} %clr([%X{traceId:-}]){magenta} %clr([%X{orgId:-}/%X{userId:-}]){green} %clr(%X{method:-} %X{uri:-}){faint} %clr(%logger{39}){cyan}%clr(:){faint} %m%n%wEx"/>
<!-- 控制台:彩色文本,MDC 内联 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">