@rawnodes/logger 2.1.0 → 2.3.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
@@ -33,6 +33,7 @@ interface FileConfig {
33
33
  dirname: string;
34
34
  filename: string;
35
35
  datePattern?: string;
36
+ interval?: string;
36
37
  zippedArchive?: boolean;
37
38
  maxSize?: string;
38
39
  maxFiles?: string;
@@ -77,6 +78,18 @@ interface LevelConfigObject {
77
78
  rules?: LevelRule[];
78
79
  }
79
80
  type LevelConfig = LogLevel | LevelConfigObject;
81
+ interface CallerConfig {
82
+ /** Stack depth to capture (default: 1). Higher values trace further up the call stack */
83
+ depth?: number;
84
+ /** Include full file path (default: false). If false, shows relative or basename only */
85
+ fullPath?: boolean;
86
+ }
87
+ interface CallerInfo {
88
+ file: string;
89
+ line: number;
90
+ column?: number;
91
+ function?: string;
92
+ }
80
93
  interface LoggerConfig {
81
94
  level: LevelConfig;
82
95
  console: ConsoleConfig;
@@ -84,6 +97,8 @@ interface LoggerConfig {
84
97
  discord?: DiscordConfig | DiscordConfig[];
85
98
  telegram?: TelegramConfig | TelegramConfig[];
86
99
  cloudwatch?: CloudWatchConfig | CloudWatchConfig[];
100
+ /** Enable caller info (file:line) in logs. Pass true for defaults or CallerConfig for options */
101
+ caller?: boolean | CallerConfig;
87
102
  }
88
103
  type LoggerContext = Record<string, unknown>;
89
104
  type LevelOverrideMatch<TContext extends LoggerContext> = Partial<TContext> & {
@@ -264,6 +279,9 @@ interface MaskSecretsOptions {
264
279
  declare function maskSecrets(obj: unknown, options?: MaskSecretsOptions): unknown;
265
280
  declare function createMasker(options?: MaskSecretsOptions): (obj: unknown) => unknown;
266
281
 
282
+ declare function getCallerInfo(config: CallerConfig, additionalOffset?: number): CallerInfo | undefined;
283
+ declare function formatCallerInfo(info: CallerInfo): string;
284
+
267
285
  declare function flattenObject(obj: Record<string, unknown>, prefix?: string): Record<string, unknown>;
268
286
  declare function formatLogfmtValue(value: unknown): string;
269
287
  declare function formatLogfmt(data: Record<string, unknown>): string;
@@ -279,6 +297,7 @@ declare const TelegramConfigSchema: z.ZodType<TelegramConfig>;
279
297
  declare const CloudWatchConfigSchema: z.ZodType<CloudWatchConfig>;
280
298
  declare const LevelConfigObjectSchema: z.ZodType<LevelConfigObject>;
281
299
  declare const LevelConfigSchema: z.ZodType<LevelConfig>;
300
+ declare const CallerConfigSchema: z.ZodType<CallerConfig>;
282
301
  declare const LoggerConfigSchema: z.ZodObject<{
283
302
  level: z.ZodType<LevelConfig, unknown, z.core.$ZodTypeInternals<LevelConfig, unknown>>;
284
303
  console: z.ZodType<ConsoleConfig, unknown, z.core.$ZodTypeInternals<ConsoleConfig, unknown>>;
@@ -286,6 +305,7 @@ declare const LoggerConfigSchema: z.ZodObject<{
286
305
  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
306
  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
307
  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>>>]>>;
308
+ caller: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodType<CallerConfig, unknown, z.core.$ZodTypeInternals<CallerConfig, unknown>>]>>;
289
309
  }, z.core.$strip>;
290
310
  declare function validateConfig(config: unknown): z.infer<typeof LoggerConfigSchema>;
291
311
  declare function safeValidateConfig(config: unknown): z.ZodSafeParseResult<{
@@ -295,6 +315,7 @@ declare function safeValidateConfig(config: unknown): z.ZodSafeParseResult<{
295
315
  discord?: DiscordConfig | DiscordConfig[] | undefined;
296
316
  telegram?: TelegramConfig | TelegramConfig[] | undefined;
297
317
  cloudwatch?: CloudWatchConfig | CloudWatchConfig[] | undefined;
318
+ caller?: boolean | CallerConfig | undefined;
298
319
  }>;
299
320
 
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 };
321
+ 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
@@ -33,6 +33,7 @@ interface FileConfig {
33
33
  dirname: string;
34
34
  filename: string;
35
35
  datePattern?: string;
36
+ interval?: string;
36
37
  zippedArchive?: boolean;
37
38
  maxSize?: string;
38
39
  maxFiles?: string;
@@ -77,6 +78,18 @@ interface LevelConfigObject {
77
78
  rules?: LevelRule[];
78
79
  }
79
80
  type LevelConfig = LogLevel | LevelConfigObject;
81
+ interface CallerConfig {
82
+ /** Stack depth to capture (default: 1). Higher values trace further up the call stack */
83
+ depth?: number;
84
+ /** Include full file path (default: false). If false, shows relative or basename only */
85
+ fullPath?: boolean;
86
+ }
87
+ interface CallerInfo {
88
+ file: string;
89
+ line: number;
90
+ column?: number;
91
+ function?: string;
92
+ }
80
93
  interface LoggerConfig {
81
94
  level: LevelConfig;
82
95
  console: ConsoleConfig;
@@ -84,6 +97,8 @@ interface LoggerConfig {
84
97
  discord?: DiscordConfig | DiscordConfig[];
85
98
  telegram?: TelegramConfig | TelegramConfig[];
86
99
  cloudwatch?: CloudWatchConfig | CloudWatchConfig[];
100
+ /** Enable caller info (file:line) in logs. Pass true for defaults or CallerConfig for options */
101
+ caller?: boolean | CallerConfig;
87
102
  }
88
103
  type LoggerContext = Record<string, unknown>;
89
104
  type LevelOverrideMatch<TContext extends LoggerContext> = Partial<TContext> & {
@@ -264,6 +279,9 @@ interface MaskSecretsOptions {
264
279
  declare function maskSecrets(obj: unknown, options?: MaskSecretsOptions): unknown;
265
280
  declare function createMasker(options?: MaskSecretsOptions): (obj: unknown) => unknown;
266
281
 
282
+ declare function getCallerInfo(config: CallerConfig, additionalOffset?: number): CallerInfo | undefined;
283
+ declare function formatCallerInfo(info: CallerInfo): string;
284
+
267
285
  declare function flattenObject(obj: Record<string, unknown>, prefix?: string): Record<string, unknown>;
268
286
  declare function formatLogfmtValue(value: unknown): string;
269
287
  declare function formatLogfmt(data: Record<string, unknown>): string;
@@ -279,6 +297,7 @@ declare const TelegramConfigSchema: z.ZodType<TelegramConfig>;
279
297
  declare const CloudWatchConfigSchema: z.ZodType<CloudWatchConfig>;
280
298
  declare const LevelConfigObjectSchema: z.ZodType<LevelConfigObject>;
281
299
  declare const LevelConfigSchema: z.ZodType<LevelConfig>;
300
+ declare const CallerConfigSchema: z.ZodType<CallerConfig>;
282
301
  declare const LoggerConfigSchema: z.ZodObject<{
283
302
  level: z.ZodType<LevelConfig, unknown, z.core.$ZodTypeInternals<LevelConfig, unknown>>;
284
303
  console: z.ZodType<ConsoleConfig, unknown, z.core.$ZodTypeInternals<ConsoleConfig, unknown>>;
@@ -286,6 +305,7 @@ declare const LoggerConfigSchema: z.ZodObject<{
286
305
  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
306
  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
307
  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>>>]>>;
308
+ caller: z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodType<CallerConfig, unknown, z.core.$ZodTypeInternals<CallerConfig, unknown>>]>>;
289
309
  }, z.core.$strip>;
290
310
  declare function validateConfig(config: unknown): z.infer<typeof LoggerConfigSchema>;
291
311
  declare function safeValidateConfig(config: unknown): z.ZodSafeParseResult<{
@@ -295,6 +315,7 @@ declare function safeValidateConfig(config: unknown): z.ZodSafeParseResult<{
295
315
  discord?: DiscordConfig | DiscordConfig[] | undefined;
296
316
  telegram?: TelegramConfig | TelegramConfig[] | undefined;
297
317
  cloudwatch?: CloudWatchConfig | CloudWatchConfig[] | undefined;
318
+ caller?: boolean | CallerConfig | undefined;
298
319
  }>;
299
320
 
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 };
321
+ 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 }; }
@@ -677,7 +678,7 @@ function createStreams(config, store) {
677
678
  {
678
679
  path: fileConfig.dirname,
679
680
  size: normalizeSize(fileConfig.maxSize || "20M"),
680
- interval: fileConfig.datePattern === "YYYY-MM-DD-HH" ? "1h" : "1d",
681
+ interval: fileConfig.interval || (fileConfig.datePattern === "YYYY-MM-DD-HH" ? "1h" : "1d"),
681
682
  compress: fileConfig.zippedArchive ? "gzip" : false,
682
683
  maxFiles: parseInt(fileConfig.maxFiles?.replace("d", "") || "14")
683
684
  }
@@ -812,13 +813,20 @@ function createState(config, store) {
812
813
  // Disable pid and hostname
813
814
  };
814
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
+ }
815
822
  return {
816
823
  pino: pinoLogger,
817
824
  store: loggerStore,
818
825
  defaultLevel,
819
826
  levelOverrides,
820
827
  contextIndex,
821
- complexRules
828
+ complexRules,
829
+ callerConfig
822
830
  };
823
831
  }
824
832
  function rebuildIndexes(state) {
@@ -876,6 +884,7 @@ var FileConfigSchema = zod.z.object({
876
884
  dirname: zod.z.string().min(1, "dirname is required"),
877
885
  filename: zod.z.string().min(1, "filename is required"),
878
886
  datePattern: zod.z.string().optional(),
887
+ interval: zod.z.string().regex(/^\d+[Mdhms]$/).optional(),
879
888
  zippedArchive: zod.z.boolean().optional(),
880
889
  maxSize: zod.z.string().optional(),
881
890
  maxFiles: zod.z.string().optional()
@@ -941,13 +950,18 @@ var LevelConfigSchema = zod.z.union([
941
950
  LogLevelSchema,
942
951
  LevelConfigObjectSchema
943
952
  ]);
953
+ var CallerConfigSchema = zod.z.object({
954
+ depth: zod.z.number().int().nonnegative().optional(),
955
+ fullPath: zod.z.boolean().optional()
956
+ });
944
957
  var LoggerConfigSchema = zod.z.object({
945
958
  level: LevelConfigSchema,
946
959
  console: ConsoleConfigSchema,
947
960
  file: FileConfigSchema.optional(),
948
961
  discord: zod.z.union([DiscordConfigSchema, zod.z.array(DiscordConfigSchema)]).optional(),
949
962
  telegram: zod.z.union([TelegramConfigSchema, zod.z.array(TelegramConfigSchema)]).optional(),
950
- cloudwatch: zod.z.union([CloudWatchConfigSchema, zod.z.array(CloudWatchConfigSchema)]).optional()
963
+ cloudwatch: zod.z.union([CloudWatchConfigSchema, zod.z.array(CloudWatchConfigSchema)]).optional(),
964
+ caller: zod.z.union([zod.z.boolean(), CallerConfigSchema]).optional()
951
965
  });
952
966
  function validateConfig(config) {
953
967
  return LoggerConfigSchema.parse(config);
@@ -955,6 +969,66 @@ function validateConfig(config) {
955
969
  function safeValidateConfig(config) {
956
970
  return LoggerConfigSchema.safeParse(config);
957
971
  }
972
+ var BASE_STACK_OFFSET = 4;
973
+ var STACK_LINE_REGEX = /^\s*at\s+(?:(.+?)\s+\()?(.+):(\d+):(\d+)\)?$/;
974
+ function getCallerInfo(config, additionalOffset = 0) {
975
+ const depth = config.depth ?? 0;
976
+ const targetFrame = BASE_STACK_OFFSET + depth + additionalOffset;
977
+ const originalPrepare = Error.prepareStackTrace;
978
+ const originalLimit = Error.stackTraceLimit;
979
+ try {
980
+ Error.stackTraceLimit = targetFrame + 5;
981
+ const err = new Error();
982
+ const stack = err.stack;
983
+ if (!stack) {
984
+ return void 0;
985
+ }
986
+ const lines = stack.split("\n");
987
+ const targetLine = lines[targetFrame];
988
+ if (!targetLine) {
989
+ return void 0;
990
+ }
991
+ const match = targetLine.match(STACK_LINE_REGEX);
992
+ if (!match) {
993
+ return void 0;
994
+ }
995
+ const [, fnName, filePath, lineStr, colStr] = match;
996
+ const line = parseInt(lineStr, 10);
997
+ const column = parseInt(colStr, 10);
998
+ let file = filePath;
999
+ if (file.startsWith("file://")) {
1000
+ file = file.slice(7);
1001
+ }
1002
+ if (!config.fullPath) {
1003
+ try {
1004
+ const relativePath = path.relative(process.cwd(), file);
1005
+ if (relativePath.startsWith("..") && relativePath.split("/").filter((p) => p === "..").length > 2) {
1006
+ file = path.basename(file);
1007
+ } else {
1008
+ file = relativePath;
1009
+ }
1010
+ } catch {
1011
+ file = path.basename(file);
1012
+ }
1013
+ }
1014
+ return {
1015
+ file,
1016
+ line,
1017
+ column: isNaN(column) ? void 0 : column,
1018
+ function: fnName && fnName !== "<anonymous>" ? fnName : void 0
1019
+ };
1020
+ } finally {
1021
+ Error.prepareStackTrace = originalPrepare;
1022
+ Error.stackTraceLimit = originalLimit;
1023
+ }
1024
+ }
1025
+ function formatCallerInfo(info) {
1026
+ const location = `${info.file}:${info.line}`;
1027
+ if (info.function) {
1028
+ return `${info.function} (${location})`;
1029
+ }
1030
+ return location;
1031
+ }
958
1032
 
959
1033
  // src/logger.ts
960
1034
  var Logger = class _Logger {
@@ -1057,13 +1131,19 @@ var Logger = class _Logger {
1057
1131
  this.log("silly", message, meta);
1058
1132
  }
1059
1133
  // Private
1060
- log(level, message, meta, error) {
1134
+ log(level, message, meta, error, callerOffset = 0) {
1061
1135
  const resolved = typeof meta === "function" ? meta() : meta;
1062
1136
  const logMeta = { context: this.context, ...resolved };
1063
1137
  const storeContext = this.state.store.getStore();
1064
1138
  if (storeContext) {
1065
1139
  Object.assign(logMeta, storeContext);
1066
1140
  }
1141
+ if (this.state.callerConfig) {
1142
+ const callerInfo = getCallerInfo(this.state.callerConfig, callerOffset);
1143
+ if (callerInfo) {
1144
+ logMeta.caller = formatCallerInfo(callerInfo);
1145
+ }
1146
+ }
1067
1147
  if (error instanceof Error) {
1068
1148
  logMeta.errorMessage = error.message;
1069
1149
  logMeta.stack = error.stack;
@@ -1307,6 +1387,7 @@ function formatLogfmt(data) {
1307
1387
  }
1308
1388
 
1309
1389
  exports.BaseHttpTransport = BaseHttpTransport;
1390
+ exports.CallerConfigSchema = CallerConfigSchema;
1310
1391
  exports.CloudWatchConfigSchema = CloudWatchConfigSchema;
1311
1392
  exports.CloudWatchTransport = CloudWatchTransport;
1312
1393
  exports.ConsoleConfigSchema = ConsoleConfigSchema;
@@ -1331,9 +1412,11 @@ exports.createMasker = createMasker;
1331
1412
  exports.createSingletonLogger = createSingletonLogger;
1332
1413
  exports.extractRequestId = extractRequestId;
1333
1414
  exports.flattenObject = flattenObject;
1415
+ exports.formatCallerInfo = formatCallerInfo;
1334
1416
  exports.formatLogfmt = formatLogfmt;
1335
1417
  exports.formatLogfmtValue = formatLogfmtValue;
1336
1418
  exports.generateRequestId = generateRequestId;
1419
+ exports.getCallerInfo = getCallerInfo;
1337
1420
  exports.getOrGenerateRequestId = getOrGenerateRequestId;
1338
1421
  exports.isValidLogLevel = isValidLogLevel;
1339
1422
  exports.maskSecrets = maskSecrets;