@lark-apaas/nestjs-logger 1.0.1-alpha.0 → 1.0.1-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -1
- package/dist/index.cjs +14 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +14 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -99,6 +99,14 @@ HTTP 请求追踪日志使用 **`verbose` 级别**(对应 Pino 的 `trace` 级
|
|
|
99
99
|
- **需要显式启用**:要查看 HTTP 请求追踪日志,需要将 `LOGGER_LEVEL` 设置为 `verbose`
|
|
100
100
|
- **细粒度控制**:可以通过日志级别控制是否打印请求追踪,而无需修改 `LOG_REQUEST_BODY` 和 `LOG_RESPONSE_BODY` 配置
|
|
101
101
|
|
|
102
|
+
### 响应体记录规则
|
|
103
|
+
|
|
104
|
+
**只针对 JSON 响应记录 body**:
|
|
105
|
+
- 自动检测 `Content-Type` 是否包含 `application/json`
|
|
106
|
+
- 只有 JSON 响应才会记录 `response_body` 字段
|
|
107
|
+
- 文件下载、HTML 页面等非 JSON 响应不会记录 body,避免日志污染
|
|
108
|
+
- 这样可以显著减少日志体积,同时保持日志的可读性
|
|
109
|
+
|
|
102
110
|
### 启用方式
|
|
103
111
|
|
|
104
112
|
通过环境变量启用:
|
|
@@ -121,7 +129,11 @@ LOG_RESPONSE_BODY=true
|
|
|
121
129
|
|
|
122
130
|
2. **默认不限制长度**:如果不设置 `LOG_MAX_BODY_LENGTH` 环境变量,日志体不会被截断。建议在生产环境设置合理的限制值。
|
|
123
131
|
|
|
124
|
-
3.
|
|
132
|
+
3. **响应体过滤**:
|
|
133
|
+
- 只记录 JSON 响应的 body(检测 Content-Type)
|
|
134
|
+
- 文件下载、HTML、图片等非 JSON 响应不会记录 body
|
|
135
|
+
- 避免记录无法序列化的数据(如 Buffer、Stream)
|
|
136
|
+
- 显著减少日志体积,提高日志可读性
|
|
125
137
|
|
|
126
138
|
### 日志输出示例
|
|
127
139
|
|
|
@@ -250,6 +262,7 @@ NestJS LoggerService 级别到 Pino 级别的映射:
|
|
|
250
262
|
|
|
251
263
|
3. **实现原理**:
|
|
252
264
|
- **拦截响应方法**:在 Interceptor 中拦截 `res.json()` 和 `res.send()`,存储响应体到 `res.__finalResponseBody`
|
|
265
|
+
- **类型检测**:通过 `Content-Type` header 判断是否为 JSON 响应,只记录 JSON 类型的 body
|
|
253
266
|
- **延迟记录**:不在 Interceptor 的 `tap()` 或 `catchError()` 中记录日志,而是在 `finish` 事件中统一记录
|
|
254
267
|
- **完整信息**:此时可以获取 Exception Filter 处理后的最终状态码和响应体,确保日志准确性
|
|
255
268
|
|
package/dist/index.cjs
CHANGED
|
@@ -14890,16 +14890,27 @@ var LoggingInterceptor = class {
|
|
|
14890
14890
|
duration_ms: durationMs
|
|
14891
14891
|
};
|
|
14892
14892
|
const finalResponseBody = res.__finalResponseBody;
|
|
14893
|
-
|
|
14893
|
+
const contentType = res.getHeader("content-type");
|
|
14894
|
+
const isJsonResponse = typeof contentType === "string" && contentType.includes("application/json");
|
|
14895
|
+
if (this.config.logResponseBody && finalResponseBody !== void 0 && isJsonResponse) {
|
|
14894
14896
|
responseMeta["response_body"] = this.sanitizeAndTruncate(finalResponseBody);
|
|
14895
14897
|
}
|
|
14896
14898
|
const isError = statusCode >= 400;
|
|
14897
14899
|
const appLog = this.appLogger[isError ? "error" : "log"].bind(this.appLogger);
|
|
14898
14900
|
const traceLevel = isError ? "error" : "verbose";
|
|
14901
|
+
const shouldLogBody = this.config.logResponseBody && isJsonResponse && finalResponseBody !== void 0;
|
|
14899
14902
|
if (isError) {
|
|
14900
|
-
|
|
14903
|
+
if (shouldLogBody) {
|
|
14904
|
+
appLog("HTTP request failed\n url=%s \n status_code=%d \n duration_ms=%d \n response_body=%o", req.url, statusCode, durationMs, finalResponseBody);
|
|
14905
|
+
} else {
|
|
14906
|
+
appLog("HTTP request failed\n url=%s \n status_code=%d \n duration_ms=%d", req.url, statusCode, durationMs);
|
|
14907
|
+
}
|
|
14901
14908
|
} else {
|
|
14902
|
-
|
|
14909
|
+
if (shouldLogBody) {
|
|
14910
|
+
appLog("HTTP request completed\n url=%s \n status_code=%d \n duration_ms=%d \n response_body=%o", req.url, statusCode, durationMs, finalResponseBody);
|
|
14911
|
+
} else {
|
|
14912
|
+
appLog("HTTP request completed\n url=%s \n status_code=%d \n duration_ms=%d", req.url, statusCode, durationMs);
|
|
14913
|
+
}
|
|
14903
14914
|
}
|
|
14904
14915
|
this.traceLogger.logStructured(traceLevel, isError ? "HTTP request failed" : "HTTP request completed", responseMeta, "HTTPTraceInterceptor");
|
|
14905
14916
|
});
|