@lark-apaas/nestjs-logger 0.1.0-alpha.3 → 0.1.0-alpha.5

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/dist/index.d.cts CHANGED
@@ -32,6 +32,14 @@ declare abstract class BasePinoLogger implements LoggerService {
32
32
  debug?(message: unknown, ...optionalParams: unknown[]): void;
33
33
  verbose?(message: unknown, ...optionalParams: unknown[]): void;
34
34
  fatal?(message: unknown, ...optionalParams: unknown[]): void;
35
+ /**
36
+ * 记录结构化日志,将 meta 对象合并到日志字段中
37
+ * @param level 日志级别
38
+ * @param message 消息文本
39
+ * @param meta 要合并的元数据对象
40
+ * @param context 上下文标识
41
+ */
42
+ logStructured(level: LogLevel, message: string, meta: Record<string, unknown>, context?: string): void;
35
43
  protected write(level: LogLevel, message: unknown, optionalParams: unknown[], treatStack?: boolean): void;
36
44
  private extractOptionalParams;
37
45
  private buildMessagePayload;
@@ -40,6 +48,8 @@ declare abstract class BasePinoLogger implements LoggerService {
40
48
  declare class AppLogger extends BasePinoLogger {
41
49
  constructor(logger: Logger, requestContext: RequestContextService);
42
50
  }
51
+ declare class PinoLoggerService extends BasePinoLogger {
52
+ }
43
53
 
44
54
  declare class LoggerModule {
45
55
  }
@@ -59,4 +69,4 @@ declare class LoggerContextMiddleware implements NestMiddleware {
59
69
 
60
70
  declare const TRACE_LOGGER: unique symbol;
61
71
 
62
- export { AppLogger, LoggerContextMiddleware, LoggerModule, TRACE_LOGGER };
72
+ export { AppLogger, LoggerContextMiddleware, LoggerModule, PinoLoggerService, TRACE_LOGGER };
package/dist/index.d.ts CHANGED
@@ -32,6 +32,14 @@ declare abstract class BasePinoLogger implements LoggerService {
32
32
  debug?(message: unknown, ...optionalParams: unknown[]): void;
33
33
  verbose?(message: unknown, ...optionalParams: unknown[]): void;
34
34
  fatal?(message: unknown, ...optionalParams: unknown[]): void;
35
+ /**
36
+ * 记录结构化日志,将 meta 对象合并到日志字段中
37
+ * @param level 日志级别
38
+ * @param message 消息文本
39
+ * @param meta 要合并的元数据对象
40
+ * @param context 上下文标识
41
+ */
42
+ logStructured(level: LogLevel, message: string, meta: Record<string, unknown>, context?: string): void;
35
43
  protected write(level: LogLevel, message: unknown, optionalParams: unknown[], treatStack?: boolean): void;
36
44
  private extractOptionalParams;
37
45
  private buildMessagePayload;
@@ -40,6 +48,8 @@ declare abstract class BasePinoLogger implements LoggerService {
40
48
  declare class AppLogger extends BasePinoLogger {
41
49
  constructor(logger: Logger, requestContext: RequestContextService);
42
50
  }
51
+ declare class PinoLoggerService extends BasePinoLogger {
52
+ }
43
53
 
44
54
  declare class LoggerModule {
45
55
  }
@@ -59,4 +69,4 @@ declare class LoggerContextMiddleware implements NestMiddleware {
59
69
 
60
70
  declare const TRACE_LOGGER: unique symbol;
61
71
 
62
- export { AppLogger, LoggerContextMiddleware, LoggerModule, TRACE_LOGGER };
72
+ export { AppLogger, LoggerContextMiddleware, LoggerModule, PinoLoggerService, TRACE_LOGGER };
package/dist/index.js CHANGED
@@ -14511,6 +14511,36 @@ var BasePinoLogger = class _BasePinoLogger {
14511
14511
  fatal(message, ...optionalParams) {
14512
14512
  this.write("fatal", message, optionalParams, true);
14513
14513
  }
14514
+ /**
14515
+ * 记录结构化日志,将 meta 对象合并到日志字段中
14516
+ * @param level 日志级别
14517
+ * @param message 消息文本
14518
+ * @param meta 要合并的元数据对象
14519
+ * @param context 上下文标识
14520
+ */
14521
+ logStructured(level, message, meta, context) {
14522
+ if (!this.levelState.isEnabled(level)) {
14523
+ return;
14524
+ }
14525
+ const requestState = this.contextStore.getContext();
14526
+ const traceId = requestState?.requestId ?? null;
14527
+ const payload = {
14528
+ trace_id: traceId,
14529
+ path: requestState?.path,
14530
+ method: requestState?.method,
14531
+ user_id: requestState?.userId ?? null,
14532
+ app_id: requestState?.appId ?? null,
14533
+ tenant_id: requestState?.tenantId ?? null,
14534
+ pid: process.pid,
14535
+ ...sanitizeValue(meta)
14536
+ };
14537
+ if (context) {
14538
+ payload.context = context;
14539
+ }
14540
+ const pinoLevel = mapLogLevelToPino(level);
14541
+ const sanitizedPayload = sanitizeValue(payload);
14542
+ this.logger[pinoLevel](sanitizedPayload, message);
14543
+ }
14514
14544
  write(level, message, optionalParams, treatStack = false) {
14515
14545
  if (!this.levelState.isEnabled(level)) {
14516
14546
  return;
@@ -14708,7 +14738,7 @@ var logger_config_default = (0, import_config.registerAs)("logger", () => {
14708
14738
  // src/interceptor/logging.interceptor.ts
14709
14739
  var import_config2 = __toESM(require_config2(), 1);
14710
14740
  var import_operators = __toESM(require_operators(), 1);
14711
- import { Inject as Inject2, Injectable as Injectable3, LoggerService } from "@nestjs/common";
14741
+ import { Inject as Inject2, Injectable as Injectable3 } from "@nestjs/common";
14712
14742
  function _ts_decorate3(decorators, target, key, desc) {
14713
14743
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
14714
14744
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -14732,10 +14762,12 @@ var LoggingInterceptor = class {
14732
14762
  }
14733
14763
  traceLogger;
14734
14764
  requestContext;
14765
+ appLogger;
14735
14766
  config;
14736
- constructor(traceLogger, requestContext, config) {
14767
+ constructor(traceLogger, requestContext, appLogger, config) {
14737
14768
  this.traceLogger = traceLogger;
14738
14769
  this.requestContext = requestContext;
14770
+ this.appLogger = appLogger;
14739
14771
  this.config = config;
14740
14772
  }
14741
14773
  intercept(context, next) {
@@ -14762,45 +14794,60 @@ var LoggingInterceptor = class {
14762
14794
  ip: req.ip ?? null,
14763
14795
  pid: process.pid
14764
14796
  };
14797
+ this.appLogger.logStructured("log", "HTTP request started", baseMeta, "HTTPTraceInterceptor");
14765
14798
  const requestMeta = {
14766
14799
  ...baseMeta
14767
14800
  };
14768
14801
  if (this.config.logRequestBody && req.body) {
14769
- requestMeta["requestBody"] = this.sanitizeAndTruncate(req.body);
14802
+ requestMeta["request_body"] = this.sanitizeAndTruncate(req.body);
14770
14803
  }
14771
14804
  if (this.config.logRequestBody && Object.keys(req.query || {}).length > 0) {
14772
- requestMeta["queryParams"] = this.sanitizeAndTruncate(req.query);
14805
+ requestMeta["query_params"] = this.sanitizeAndTruncate(req.query);
14773
14806
  }
14774
- this.traceLogger.verbose?.("HTTP request started", requestMeta, "HTTP");
14807
+ this.traceLogger.logStructured("verbose", "HTTP request started", requestMeta, "HTTPTraceInterceptor");
14775
14808
  return next.handle().pipe((0, import_operators.tap)((responseData) => {
14776
14809
  const durationMs = Date.now() - startedAt;
14777
14810
  const statusCode = res.statusCode;
14811
+ this.appLogger.logStructured("log", "HTTP request completed", {
14812
+ ...baseMeta,
14813
+ status_code: statusCode,
14814
+ duration_ms: durationMs
14815
+ }, "HTTPTraceInterceptor");
14778
14816
  const responseMeta = {
14779
14817
  ...baseMeta,
14780
- statusCode,
14781
- durationMs
14818
+ status_code: statusCode,
14819
+ duration_ms: durationMs
14782
14820
  };
14783
14821
  if (this.config.logResponseBody && responseData !== void 0) {
14784
- const contentType = res.getHeader("content-type");
14785
- const isJsonResponse = this.isJsonContentType(contentType);
14786
- if (isJsonResponse) {
14787
- responseMeta["responseBody"] = this.sanitizeAndTruncate(responseData);
14788
- }
14822
+ responseMeta["response_body"] = this.sanitizeAndTruncate(responseData);
14789
14823
  }
14790
- this.traceLogger.verbose?.("HTTP request completed", responseMeta, "HTTP");
14824
+ this.traceLogger.logStructured("verbose", "HTTP request completed", responseMeta, "HTTPTraceInterceptor");
14791
14825
  }), (0, import_operators.catchError)((error) => {
14792
14826
  const durationMs = Date.now() - startedAt;
14793
14827
  const statusCode = res.statusCode >= 400 ? res.statusCode : 500;
14828
+ const linkMeta = {
14829
+ ...baseMeta,
14830
+ status_code: statusCode,
14831
+ duration_ms: durationMs
14832
+ };
14833
+ if (error instanceof Error) {
14834
+ linkMeta["error_message"] = error.message;
14835
+ }
14836
+ this.appLogger.logStructured("log", "HTTP request failed", linkMeta, "HTTPTraceInterceptor");
14794
14837
  const meta = {
14795
14838
  ...baseMeta,
14796
- statusCode,
14797
- durationMs
14839
+ status_code: statusCode,
14840
+ duration_ms: durationMs
14798
14841
  };
14799
14842
  if (error instanceof Error) {
14800
- this.traceLogger.error(error, meta, "HTTP");
14843
+ meta["error"] = {
14844
+ message: error.message,
14845
+ stack: error.stack
14846
+ };
14801
14847
  } else {
14802
- this.traceLogger.error("Unknown error thrown", meta, "HTTP");
14848
+ meta["error"] = String(error);
14803
14849
  }
14850
+ this.traceLogger.logStructured("verbose", "HTTP request failed", meta, "HTTPTraceInterceptor");
14804
14851
  throw error;
14805
14852
  }));
14806
14853
  }
@@ -14825,21 +14872,12 @@ var LoggingInterceptor = class {
14825
14872
  } catch (error) {
14826
14873
  return {
14827
14874
  _error: "Failed to serialize data",
14828
- _message: error instanceof Error ? error.message : String(error)
14875
+ _type: typeof data,
14876
+ _constructor: data?.constructor?.name
14829
14877
  };
14830
14878
  }
14831
14879
  }
14832
14880
  /**
14833
- * 判断是否是 JSON 响应类型
14834
- */
14835
- isJsonContentType(contentType) {
14836
- if (typeof contentType !== "string") {
14837
- return false;
14838
- }
14839
- const contentTypeLower = contentType.toLowerCase();
14840
- return contentTypeLower.includes("application/json") || contentTypeLower.includes("application/vnd.api+json") || contentTypeLower.includes("+json");
14841
- }
14842
- /**
14843
14881
  * 脱敏敏感字段
14844
14882
  */
14845
14883
  maskSensitiveFields(data) {
@@ -14870,11 +14908,13 @@ var LoggingInterceptor = class {
14870
14908
  LoggingInterceptor = _ts_decorate3([
14871
14909
  Injectable3(),
14872
14910
  _ts_param2(0, Inject2(TRACE_LOGGER)),
14873
- _ts_param2(2, Inject2(logger_config_default.KEY)),
14911
+ _ts_param2(2, Inject2(AppLogger)),
14912
+ _ts_param2(3, Inject2(logger_config_default.KEY)),
14874
14913
  _ts_metadata2("design:type", Function),
14875
14914
  _ts_metadata2("design:paramtypes", [
14876
- typeof LoggerService === "undefined" ? Object : LoggerService,
14915
+ typeof PinoLoggerService === "undefined" ? Object : PinoLoggerService,
14877
14916
  typeof RequestContextService === "undefined" ? Object : RequestContextService,
14917
+ typeof AppLogger === "undefined" ? Object : AppLogger,
14878
14918
  typeof import_config2.ConfigType === "undefined" ? Object : import_config2.ConfigType
14879
14919
  ])
14880
14920
  ], LoggingInterceptor);
@@ -15040,6 +15080,7 @@ export {
15040
15080
  AppLogger,
15041
15081
  LoggerContextMiddleware,
15042
15082
  LoggerModule,
15083
+ PinoLoggerService,
15043
15084
  TRACE_LOGGER
15044
15085
  };
15045
15086
  //# sourceMappingURL=index.js.map