@rawnodes/logger 2.0.1 → 2.2.0

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.mts CHANGED
@@ -77,6 +77,18 @@ interface LevelConfigObject {
77
77
  rules?: LevelRule[];
78
78
  }
79
79
  type LevelConfig = LogLevel | LevelConfigObject;
80
+ interface CallerConfig {
81
+ /** Stack depth to capture (default: 1). Higher values trace further up the call stack */
82
+ depth?: number;
83
+ /** Include full file path (default: false). If false, shows relative or basename only */
84
+ fullPath?: boolean;
85
+ }
86
+ interface CallerInfo {
87
+ file: string;
88
+ line: number;
89
+ column?: number;
90
+ function?: string;
91
+ }
80
92
  interface LoggerConfig {
81
93
  level: LevelConfig;
82
94
  console: ConsoleConfig;
@@ -84,6 +96,8 @@ interface LoggerConfig {
84
96
  discord?: DiscordConfig | DiscordConfig[];
85
97
  telegram?: TelegramConfig | TelegramConfig[];
86
98
  cloudwatch?: CloudWatchConfig | CloudWatchConfig[];
99
+ /** Enable caller info (file:line) in logs. Pass true for defaults or CallerConfig for options */
100
+ caller?: boolean | CallerConfig;
87
101
  }
88
102
  type LoggerContext = Record<string, unknown>;
89
103
  type LevelOverrideMatch<TContext extends LoggerContext> = Partial<TContext> & {
@@ -264,6 +278,9 @@ interface MaskSecretsOptions {
264
278
  declare function maskSecrets(obj: unknown, options?: MaskSecretsOptions): unknown;
265
279
  declare function createMasker(options?: MaskSecretsOptions): (obj: unknown) => unknown;
266
280
 
281
+ declare function getCallerInfo(config: CallerConfig, additionalOffset?: number): CallerInfo | undefined;
282
+ declare function formatCallerInfo(info: CallerInfo): string;
283
+
267
284
  declare function flattenObject(obj: Record<string, unknown>, prefix?: string): Record<string, unknown>;
268
285
  declare function formatLogfmtValue(value: unknown): string;
269
286
  declare function formatLogfmt(data: Record<string, unknown>): string;
@@ -279,6 +296,7 @@ declare const TelegramConfigSchema: z.ZodType<TelegramConfig>;
279
296
  declare const CloudWatchConfigSchema: z.ZodType<CloudWatchConfig>;
280
297
  declare const LevelConfigObjectSchema: z.ZodType<LevelConfigObject>;
281
298
  declare const LevelConfigSchema: z.ZodType<LevelConfig>;
299
+ declare const CallerConfigSchema: z.ZodType<CallerConfig>;
282
300
  declare const LoggerConfigSchema: z.ZodObject<{
283
301
  level: z.ZodType<LevelConfig, unknown, z.core.$ZodTypeInternals<LevelConfig, unknown>>;
284
302
  console: z.ZodType<ConsoleConfig, unknown, z.core.$ZodTypeInternals<ConsoleConfig, unknown>>;
@@ -286,6 +304,7 @@ declare const LoggerConfigSchema: z.ZodObject<{
286
304
  discord: z.ZodOptional<z.ZodUnion<readonly [z.ZodType<DiscordConfig, unknown, z.core.$ZodTypeInternals<DiscordConfig, unknown>>, z.ZodArray<z.ZodType<DiscordConfig, unknown, z.core.$ZodTypeInternals<DiscordConfig, unknown>>>]>>;
287
305
  telegram: z.ZodOptional<z.ZodUnion<readonly [z.ZodType<TelegramConfig, unknown, z.core.$ZodTypeInternals<TelegramConfig, unknown>>, z.ZodArray<z.ZodType<TelegramConfig, unknown, z.core.$ZodTypeInternals<TelegramConfig, unknown>>>]>>;
288
306
  cloudwatch: z.ZodOptional<z.ZodUnion<readonly [z.ZodType<CloudWatchConfig, unknown, z.core.$ZodTypeInternals<CloudWatchConfig, unknown>>, z.ZodArray<z.ZodType<CloudWatchConfig, unknown, z.core.$ZodTypeInternals<CloudWatchConfig, unknown>>>]>>;
307
+ caller: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodType<CallerConfig, unknown, z.core.$ZodTypeInternals<CallerConfig, unknown>>]>>;
289
308
  }, z.core.$strip>;
290
309
  declare function validateConfig(config: unknown): z.infer<typeof LoggerConfigSchema>;
291
310
  declare function safeValidateConfig(config: unknown): z.ZodSafeParseResult<{
@@ -295,6 +314,7 @@ declare function safeValidateConfig(config: unknown): z.ZodSafeParseResult<{
295
314
  discord?: DiscordConfig | DiscordConfig[] | undefined;
296
315
  telegram?: TelegramConfig | TelegramConfig[] | undefined;
297
316
  cloudwatch?: CloudWatchConfig | CloudWatchConfig[] | undefined;
317
+ caller?: boolean | CallerConfig | undefined;
298
318
  }>;
299
319
 
300
- export { BaseHttpTransport, type BaseHttpTransportOptions, type BufferOptions, type BufferedMessage, type CloudWatchConfig, CloudWatchConfigSchema, CloudWatchTransport, type ConsoleConfig, ConsoleConfigSchema, type DiscordConfig, DiscordConfigSchema, DiscordTransport, type FileConfig, FileConfigSchema, type HttpTransportBaseConfig, HttpTransportBaseConfigSchema, LOG_LEVELS, type LevelConfig, type LevelConfigObject, LevelConfigObjectSchema, LevelConfigSchema, type LevelOverride, type LevelOverrideMatch, type LevelRule, LevelRuleSchema, type LogFormat, LogFormatSchema, type LogLevel, LogLevelSchema, Logger, type LoggerConfig, LoggerConfigSchema, type LoggerContext, LoggerStore, type MaskSecretsOptions, MessageBuffer, type Meta, type RequestIdOptions, type SingletonLogger, type TelegramConfig, TelegramConfigSchema, TelegramTransport, type TimingResult, assertLogLevel, createMasker, createSingletonLogger, extractRequestId, flattenObject, formatLogfmt, formatLogfmtValue, generateRequestId, getOrGenerateRequestId, isValidLogLevel, maskSecrets, matchesContext, measureAsync, measureSync, safeValidateConfig, validateConfig };
320
+ export { BaseHttpTransport, type BaseHttpTransportOptions, type BufferOptions, type BufferedMessage, type CallerConfig, CallerConfigSchema, type CallerInfo, type CloudWatchConfig, CloudWatchConfigSchema, CloudWatchTransport, type ConsoleConfig, ConsoleConfigSchema, type DiscordConfig, DiscordConfigSchema, DiscordTransport, type FileConfig, FileConfigSchema, type HttpTransportBaseConfig, HttpTransportBaseConfigSchema, LOG_LEVELS, type LevelConfig, type LevelConfigObject, LevelConfigObjectSchema, LevelConfigSchema, type LevelOverride, type LevelOverrideMatch, type LevelRule, LevelRuleSchema, type LogFormat, LogFormatSchema, type LogLevel, LogLevelSchema, Logger, type LoggerConfig, LoggerConfigSchema, type LoggerContext, LoggerStore, type MaskSecretsOptions, MessageBuffer, type Meta, type RequestIdOptions, type SingletonLogger, type TelegramConfig, TelegramConfigSchema, TelegramTransport, type TimingResult, assertLogLevel, createMasker, createSingletonLogger, extractRequestId, flattenObject, formatCallerInfo, formatLogfmt, formatLogfmtValue, generateRequestId, getCallerInfo, getOrGenerateRequestId, isValidLogLevel, maskSecrets, matchesContext, measureAsync, measureSync, safeValidateConfig, validateConfig };
package/dist/index.d.ts CHANGED
@@ -77,6 +77,18 @@ interface LevelConfigObject {
77
77
  rules?: LevelRule[];
78
78
  }
79
79
  type LevelConfig = LogLevel | LevelConfigObject;
80
+ interface CallerConfig {
81
+ /** Stack depth to capture (default: 1). Higher values trace further up the call stack */
82
+ depth?: number;
83
+ /** Include full file path (default: false). If false, shows relative or basename only */
84
+ fullPath?: boolean;
85
+ }
86
+ interface CallerInfo {
87
+ file: string;
88
+ line: number;
89
+ column?: number;
90
+ function?: string;
91
+ }
80
92
  interface LoggerConfig {
81
93
  level: LevelConfig;
82
94
  console: ConsoleConfig;
@@ -84,6 +96,8 @@ interface LoggerConfig {
84
96
  discord?: DiscordConfig | DiscordConfig[];
85
97
  telegram?: TelegramConfig | TelegramConfig[];
86
98
  cloudwatch?: CloudWatchConfig | CloudWatchConfig[];
99
+ /** Enable caller info (file:line) in logs. Pass true for defaults or CallerConfig for options */
100
+ caller?: boolean | CallerConfig;
87
101
  }
88
102
  type LoggerContext = Record<string, unknown>;
89
103
  type LevelOverrideMatch<TContext extends LoggerContext> = Partial<TContext> & {
@@ -264,6 +278,9 @@ interface MaskSecretsOptions {
264
278
  declare function maskSecrets(obj: unknown, options?: MaskSecretsOptions): unknown;
265
279
  declare function createMasker(options?: MaskSecretsOptions): (obj: unknown) => unknown;
266
280
 
281
+ declare function getCallerInfo(config: CallerConfig, additionalOffset?: number): CallerInfo | undefined;
282
+ declare function formatCallerInfo(info: CallerInfo): string;
283
+
267
284
  declare function flattenObject(obj: Record<string, unknown>, prefix?: string): Record<string, unknown>;
268
285
  declare function formatLogfmtValue(value: unknown): string;
269
286
  declare function formatLogfmt(data: Record<string, unknown>): string;
@@ -279,6 +296,7 @@ declare const TelegramConfigSchema: z.ZodType<TelegramConfig>;
279
296
  declare const CloudWatchConfigSchema: z.ZodType<CloudWatchConfig>;
280
297
  declare const LevelConfigObjectSchema: z.ZodType<LevelConfigObject>;
281
298
  declare const LevelConfigSchema: z.ZodType<LevelConfig>;
299
+ declare const CallerConfigSchema: z.ZodType<CallerConfig>;
282
300
  declare const LoggerConfigSchema: z.ZodObject<{
283
301
  level: z.ZodType<LevelConfig, unknown, z.core.$ZodTypeInternals<LevelConfig, unknown>>;
284
302
  console: z.ZodType<ConsoleConfig, unknown, z.core.$ZodTypeInternals<ConsoleConfig, unknown>>;
@@ -286,6 +304,7 @@ declare const LoggerConfigSchema: z.ZodObject<{
286
304
  discord: z.ZodOptional<z.ZodUnion<readonly [z.ZodType<DiscordConfig, unknown, z.core.$ZodTypeInternals<DiscordConfig, unknown>>, z.ZodArray<z.ZodType<DiscordConfig, unknown, z.core.$ZodTypeInternals<DiscordConfig, unknown>>>]>>;
287
305
  telegram: z.ZodOptional<z.ZodUnion<readonly [z.ZodType<TelegramConfig, unknown, z.core.$ZodTypeInternals<TelegramConfig, unknown>>, z.ZodArray<z.ZodType<TelegramConfig, unknown, z.core.$ZodTypeInternals<TelegramConfig, unknown>>>]>>;
288
306
  cloudwatch: z.ZodOptional<z.ZodUnion<readonly [z.ZodType<CloudWatchConfig, unknown, z.core.$ZodTypeInternals<CloudWatchConfig, unknown>>, z.ZodArray<z.ZodType<CloudWatchConfig, unknown, z.core.$ZodTypeInternals<CloudWatchConfig, unknown>>>]>>;
307
+ caller: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodType<CallerConfig, unknown, z.core.$ZodTypeInternals<CallerConfig, unknown>>]>>;
289
308
  }, z.core.$strip>;
290
309
  declare function validateConfig(config: unknown): z.infer<typeof LoggerConfigSchema>;
291
310
  declare function safeValidateConfig(config: unknown): z.ZodSafeParseResult<{
@@ -295,6 +314,7 @@ declare function safeValidateConfig(config: unknown): z.ZodSafeParseResult<{
295
314
  discord?: DiscordConfig | DiscordConfig[] | undefined;
296
315
  telegram?: TelegramConfig | TelegramConfig[] | undefined;
297
316
  cloudwatch?: CloudWatchConfig | CloudWatchConfig[] | undefined;
317
+ caller?: boolean | CallerConfig | undefined;
298
318
  }>;
299
319
 
300
- export { BaseHttpTransport, type BaseHttpTransportOptions, type BufferOptions, type BufferedMessage, type CloudWatchConfig, CloudWatchConfigSchema, CloudWatchTransport, type ConsoleConfig, ConsoleConfigSchema, type DiscordConfig, DiscordConfigSchema, DiscordTransport, type FileConfig, FileConfigSchema, type HttpTransportBaseConfig, HttpTransportBaseConfigSchema, LOG_LEVELS, type LevelConfig, type LevelConfigObject, LevelConfigObjectSchema, LevelConfigSchema, type LevelOverride, type LevelOverrideMatch, type LevelRule, LevelRuleSchema, type LogFormat, LogFormatSchema, type LogLevel, LogLevelSchema, Logger, type LoggerConfig, LoggerConfigSchema, type LoggerContext, LoggerStore, type MaskSecretsOptions, MessageBuffer, type Meta, type RequestIdOptions, type SingletonLogger, type TelegramConfig, TelegramConfigSchema, TelegramTransport, type TimingResult, assertLogLevel, createMasker, createSingletonLogger, extractRequestId, flattenObject, formatLogfmt, formatLogfmtValue, generateRequestId, getOrGenerateRequestId, isValidLogLevel, maskSecrets, matchesContext, measureAsync, measureSync, safeValidateConfig, validateConfig };
320
+ export { BaseHttpTransport, type BaseHttpTransportOptions, type BufferOptions, type BufferedMessage, type CallerConfig, CallerConfigSchema, type CallerInfo, type CloudWatchConfig, CloudWatchConfigSchema, CloudWatchTransport, type ConsoleConfig, ConsoleConfigSchema, type DiscordConfig, DiscordConfigSchema, DiscordTransport, type FileConfig, FileConfigSchema, type HttpTransportBaseConfig, HttpTransportBaseConfigSchema, LOG_LEVELS, type LevelConfig, type LevelConfigObject, LevelConfigObjectSchema, LevelConfigSchema, type LevelOverride, type LevelOverrideMatch, type LevelRule, LevelRuleSchema, type LogFormat, LogFormatSchema, type LogLevel, LogLevelSchema, Logger, type LoggerConfig, LoggerConfigSchema, type LoggerContext, LoggerStore, type MaskSecretsOptions, MessageBuffer, type Meta, type RequestIdOptions, type SingletonLogger, type TelegramConfig, TelegramConfigSchema, TelegramTransport, type TimingResult, assertLogLevel, createMasker, createSingletonLogger, extractRequestId, flattenObject, formatCallerInfo, formatLogfmt, formatLogfmtValue, generateRequestId, getCallerInfo, getOrGenerateRequestId, isValidLogLevel, maskSecrets, matchesContext, measureAsync, measureSync, safeValidateConfig, validateConfig };
package/dist/index.js CHANGED
@@ -8,6 +8,7 @@ var rotatingFileStream = require('rotating-file-stream');
8
8
  var events = require('events');
9
9
  var clientCloudwatchLogs = require('@aws-sdk/client-cloudwatch-logs');
10
10
  var zod = require('zod');
11
+ var path = require('path');
11
12
  var crypto = require('crypto');
12
13
 
13
14
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -664,6 +665,9 @@ function createStreams(config, store) {
664
665
  const fileConfig = config.file;
665
666
  promises.mkdir(fileConfig.dirname, { recursive: true }).catch(() => {
666
667
  });
668
+ const normalizeSize = (size) => {
669
+ return size.replace(/([kmg])$/i, (match) => match.toUpperCase());
670
+ };
667
671
  const rotatingStream = rotatingFileStream.createStream(
668
672
  (time, index) => {
669
673
  const date = time instanceof Date ? time : /* @__PURE__ */ new Date();
@@ -673,7 +677,7 @@ function createStreams(config, store) {
673
677
  },
674
678
  {
675
679
  path: fileConfig.dirname,
676
- size: fileConfig.maxSize || "20M",
680
+ size: normalizeSize(fileConfig.maxSize || "20M"),
677
681
  interval: fileConfig.datePattern === "YYYY-MM-DD-HH" ? "1h" : "1d",
678
682
  compress: fileConfig.zippedArchive ? "gzip" : false,
679
683
  maxFiles: parseInt(fileConfig.maxFiles?.replace("d", "") || "14")
@@ -809,13 +813,20 @@ function createState(config, store) {
809
813
  // Disable pid and hostname
810
814
  };
811
815
  const pinoLogger = pino__default.default(options, streams);
816
+ let callerConfig;
817
+ if (config.caller === true) {
818
+ callerConfig = {};
819
+ } else if (config.caller && typeof config.caller === "object") {
820
+ callerConfig = config.caller;
821
+ }
812
822
  return {
813
823
  pino: pinoLogger,
814
824
  store: loggerStore,
815
825
  defaultLevel,
816
826
  levelOverrides,
817
827
  contextIndex,
818
- complexRules
828
+ complexRules,
829
+ callerConfig
819
830
  };
820
831
  }
821
832
  function rebuildIndexes(state) {
@@ -938,13 +949,18 @@ var LevelConfigSchema = zod.z.union([
938
949
  LogLevelSchema,
939
950
  LevelConfigObjectSchema
940
951
  ]);
952
+ var CallerConfigSchema = zod.z.object({
953
+ depth: zod.z.number().int().nonnegative().optional(),
954
+ fullPath: zod.z.boolean().optional()
955
+ });
941
956
  var LoggerConfigSchema = zod.z.object({
942
957
  level: LevelConfigSchema,
943
958
  console: ConsoleConfigSchema,
944
959
  file: FileConfigSchema.optional(),
945
960
  discord: zod.z.union([DiscordConfigSchema, zod.z.array(DiscordConfigSchema)]).optional(),
946
961
  telegram: zod.z.union([TelegramConfigSchema, zod.z.array(TelegramConfigSchema)]).optional(),
947
- cloudwatch: zod.z.union([CloudWatchConfigSchema, zod.z.array(CloudWatchConfigSchema)]).optional()
962
+ cloudwatch: zod.z.union([CloudWatchConfigSchema, zod.z.array(CloudWatchConfigSchema)]).optional(),
963
+ caller: zod.z.union([zod.z.boolean(), CallerConfigSchema]).optional()
948
964
  });
949
965
  function validateConfig(config) {
950
966
  return LoggerConfigSchema.parse(config);
@@ -952,6 +968,66 @@ function validateConfig(config) {
952
968
  function safeValidateConfig(config) {
953
969
  return LoggerConfigSchema.safeParse(config);
954
970
  }
971
+ var BASE_STACK_OFFSET = 4;
972
+ var STACK_LINE_REGEX = /^\s*at\s+(?:(.+?)\s+\()?(.+):(\d+):(\d+)\)?$/;
973
+ function getCallerInfo(config, additionalOffset = 0) {
974
+ const depth = config.depth ?? 0;
975
+ const targetFrame = BASE_STACK_OFFSET + depth + additionalOffset;
976
+ const originalPrepare = Error.prepareStackTrace;
977
+ const originalLimit = Error.stackTraceLimit;
978
+ try {
979
+ Error.stackTraceLimit = targetFrame + 5;
980
+ const err = new Error();
981
+ const stack = err.stack;
982
+ if (!stack) {
983
+ return void 0;
984
+ }
985
+ const lines = stack.split("\n");
986
+ const targetLine = lines[targetFrame];
987
+ if (!targetLine) {
988
+ return void 0;
989
+ }
990
+ const match = targetLine.match(STACK_LINE_REGEX);
991
+ if (!match) {
992
+ return void 0;
993
+ }
994
+ const [, fnName, filePath, lineStr, colStr] = match;
995
+ const line = parseInt(lineStr, 10);
996
+ const column = parseInt(colStr, 10);
997
+ let file = filePath;
998
+ if (file.startsWith("file://")) {
999
+ file = file.slice(7);
1000
+ }
1001
+ if (!config.fullPath) {
1002
+ try {
1003
+ const relativePath = path.relative(process.cwd(), file);
1004
+ if (relativePath.startsWith("..") && relativePath.split("/").filter((p) => p === "..").length > 2) {
1005
+ file = path.basename(file);
1006
+ } else {
1007
+ file = relativePath;
1008
+ }
1009
+ } catch {
1010
+ file = path.basename(file);
1011
+ }
1012
+ }
1013
+ return {
1014
+ file,
1015
+ line,
1016
+ column: isNaN(column) ? void 0 : column,
1017
+ function: fnName && fnName !== "<anonymous>" ? fnName : void 0
1018
+ };
1019
+ } finally {
1020
+ Error.prepareStackTrace = originalPrepare;
1021
+ Error.stackTraceLimit = originalLimit;
1022
+ }
1023
+ }
1024
+ function formatCallerInfo(info) {
1025
+ const location = `${info.file}:${info.line}`;
1026
+ if (info.function) {
1027
+ return `${info.function} (${location})`;
1028
+ }
1029
+ return location;
1030
+ }
955
1031
 
956
1032
  // src/logger.ts
957
1033
  var Logger = class _Logger {
@@ -1054,13 +1130,19 @@ var Logger = class _Logger {
1054
1130
  this.log("silly", message, meta);
1055
1131
  }
1056
1132
  // Private
1057
- log(level, message, meta, error) {
1133
+ log(level, message, meta, error, callerOffset = 0) {
1058
1134
  const resolved = typeof meta === "function" ? meta() : meta;
1059
1135
  const logMeta = { context: this.context, ...resolved };
1060
1136
  const storeContext = this.state.store.getStore();
1061
1137
  if (storeContext) {
1062
1138
  Object.assign(logMeta, storeContext);
1063
1139
  }
1140
+ if (this.state.callerConfig) {
1141
+ const callerInfo = getCallerInfo(this.state.callerConfig, callerOffset);
1142
+ if (callerInfo) {
1143
+ logMeta.caller = formatCallerInfo(callerInfo);
1144
+ }
1145
+ }
1064
1146
  if (error instanceof Error) {
1065
1147
  logMeta.errorMessage = error.message;
1066
1148
  logMeta.stack = error.stack;
@@ -1304,6 +1386,7 @@ function formatLogfmt(data) {
1304
1386
  }
1305
1387
 
1306
1388
  exports.BaseHttpTransport = BaseHttpTransport;
1389
+ exports.CallerConfigSchema = CallerConfigSchema;
1307
1390
  exports.CloudWatchConfigSchema = CloudWatchConfigSchema;
1308
1391
  exports.CloudWatchTransport = CloudWatchTransport;
1309
1392
  exports.ConsoleConfigSchema = ConsoleConfigSchema;
@@ -1328,9 +1411,11 @@ exports.createMasker = createMasker;
1328
1411
  exports.createSingletonLogger = createSingletonLogger;
1329
1412
  exports.extractRequestId = extractRequestId;
1330
1413
  exports.flattenObject = flattenObject;
1414
+ exports.formatCallerInfo = formatCallerInfo;
1331
1415
  exports.formatLogfmt = formatLogfmt;
1332
1416
  exports.formatLogfmtValue = formatLogfmtValue;
1333
1417
  exports.generateRequestId = generateRequestId;
1418
+ exports.getCallerInfo = getCallerInfo;
1334
1419
  exports.getOrGenerateRequestId = getOrGenerateRequestId;
1335
1420
  exports.isValidLogLevel = isValidLogLevel;
1336
1421
  exports.maskSecrets = maskSecrets;