@aztec/foundation 0.65.1 → 0.66.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.
Files changed (55) hide show
  1. package/dest/async-pool/index.d.ts +3 -0
  2. package/dest/async-pool/index.d.ts.map +1 -0
  3. package/dest/async-pool/index.js +50 -0
  4. package/dest/collection/array.d.ts +14 -0
  5. package/dest/collection/array.d.ts.map +1 -1
  6. package/dest/collection/array.js +23 -1
  7. package/dest/config/env_var.d.ts +1 -1
  8. package/dest/config/env_var.d.ts.map +1 -1
  9. package/dest/config/index.d.ts +1 -1
  10. package/dest/config/index.d.ts.map +1 -1
  11. package/dest/config/index.js +2 -2
  12. package/dest/crypto/random/randomness_singleton.js +2 -2
  13. package/dest/json-rpc/client/safe_json_rpc_client.d.ts +1 -1
  14. package/dest/json-rpc/client/safe_json_rpc_client.d.ts.map +1 -1
  15. package/dest/json-rpc/client/safe_json_rpc_client.js +2 -2
  16. package/dest/json-rpc/server/safe_json_rpc_server.d.ts +2 -2
  17. package/dest/json-rpc/server/safe_json_rpc_server.d.ts.map +1 -1
  18. package/dest/log/index.d.ts +1 -1
  19. package/dest/log/index.d.ts.map +1 -1
  20. package/dest/log/index.js +2 -2
  21. package/dest/log/log-filters.d.ts +7 -0
  22. package/dest/log/log-filters.d.ts.map +1 -0
  23. package/dest/log/log-filters.js +43 -0
  24. package/dest/log/log-levels.d.ts +3 -0
  25. package/dest/log/log-levels.d.ts.map +1 -0
  26. package/dest/log/log-levels.js +2 -0
  27. package/dest/log/pino-logger.d.ts +39 -0
  28. package/dest/log/pino-logger.d.ts.map +1 -0
  29. package/dest/log/pino-logger.js +146 -0
  30. package/dest/queue/base_memory_queue.d.ts +1 -1
  31. package/dest/queue/base_memory_queue.d.ts.map +1 -1
  32. package/dest/queue/bounded_serial_queue.d.ts +1 -1
  33. package/dest/queue/bounded_serial_queue.d.ts.map +1 -1
  34. package/dest/queue/fifo_memory_queue.d.ts +1 -1
  35. package/dest/queue/fifo_memory_queue.d.ts.map +1 -1
  36. package/dest/retry/index.d.ts +1 -1
  37. package/dest/retry/index.d.ts.map +1 -1
  38. package/dest/transport/dispatch/create_dispatch_fn.d.ts +1 -1
  39. package/dest/transport/dispatch/create_dispatch_fn.d.ts.map +1 -1
  40. package/package.json +6 -2
  41. package/src/async-pool/index.ts +50 -0
  42. package/src/collection/array.ts +24 -0
  43. package/src/config/env_var.ts +25 -3
  44. package/src/config/index.ts +1 -1
  45. package/src/crypto/random/randomness_singleton.ts +1 -1
  46. package/src/json-rpc/client/safe_json_rpc_client.ts +1 -1
  47. package/src/log/index.ts +1 -1
  48. package/src/log/log-filters.ts +49 -0
  49. package/src/log/log-levels.ts +3 -0
  50. package/src/log/pino-logger.ts +196 -0
  51. package/src/queue/fifo_memory_queue.ts +1 -1
  52. package/dest/log/logger.d.ts +0 -57
  53. package/dest/log/logger.d.ts.map +0 -1
  54. package/dest/log/logger.js +0 -139
  55. package/src/log/logger.ts +0 -179
@@ -0,0 +1,196 @@
1
+ import { createColors } from 'colorette';
2
+ import isNode from 'detect-node';
3
+ import { pino, symbols } from 'pino';
4
+ import pretty from 'pino-pretty';
5
+ import { type Writable } from 'stream';
6
+ import { inspect } from 'util';
7
+
8
+ import { compactArray } from '../collection/array.js';
9
+ import { getLogLevelFromFilters, parseEnv } from './log-filters.js';
10
+ import { type LogLevel } from './log-levels.js';
11
+ import { type LogData, type LogFn } from './log_fn.js';
12
+
13
+ // TODO(palla/log): Rename to createLogger
14
+ export function createDebugLogger(module: string): DebugLogger {
15
+ // TODO(palla/log): Rename all module names to remove the aztec prefix
16
+ const pinoLogger = logger.child(
17
+ { module: module.replace(/^aztec:/, '') },
18
+ { level: getLogLevelFromFilters(logFilters, module) },
19
+ );
20
+
21
+ // We check manually for isLevelEnabled to avoid calling processLogData unnecessarily.
22
+ // Note that isLevelEnabled is missing from the browser version of pino.
23
+ const logFn = (level: LogLevel, msg: string, data?: LogData) =>
24
+ isLevelEnabled(pinoLogger, level) && pinoLogger[level](processLogData(data ?? {}), msg);
25
+
26
+ return {
27
+ silent: () => {},
28
+ // TODO(palla/log): Should we move err to data instead of the text message?
29
+ /** Log as fatal. Use when an error has brought down the system. */
30
+ fatal: (msg: string, err?: unknown, data?: LogData) => logFn('fatal', formatErr(msg, err), data),
31
+ /** Log as error. Use for errors in general. */
32
+ error: (msg: string, err?: unknown, data?: LogData) => logFn('error', formatErr(msg, err), data),
33
+ /** Log as warn. Use for when we stray from the happy path. */
34
+ warn: (msg: string, data?: LogData) => logFn('warn', msg, data),
35
+ /** Log as info. Use for providing an operator with info on what the system is doing. */
36
+ info: (msg: string, data?: LogData) => logFn('info', msg, data),
37
+ /** Log as verbose. Use for when we need additional insight on what a subsystem is doing. */
38
+ verbose: (msg: string, data?: LogData) => logFn('verbose', msg, data),
39
+ /** Log as debug. Use for when we need debugging info to troubleshoot an issue on a specific component. */
40
+ debug: (msg: string, data?: LogData) => logFn('debug', msg, data),
41
+ /** Log as trace. Use for when we want to denial-of-service any recipient of the logs. */
42
+ trace: (msg: string, data?: LogData) => logFn('trace', msg, data),
43
+ level: pinoLogger.level as LogLevel,
44
+ isLevelEnabled: (level: LogLevel) => isLevelEnabled(pinoLogger, level),
45
+ };
46
+ }
47
+
48
+ // Allow global hooks for processing log data.
49
+ // Used for injecting OTEL trace_id in telemetry client.
50
+ type LogDataHandler = (data: LogData) => LogData;
51
+ const logDataHandlers: LogDataHandler[] = [];
52
+
53
+ export function addLogDataHandler(handler: LogDataHandler): void {
54
+ logDataHandlers.push(handler);
55
+ }
56
+
57
+ function processLogData(data: LogData): LogData {
58
+ return logDataHandlers.reduce((accum, handler) => handler(accum), data);
59
+ }
60
+
61
+ // Patch isLevelEnabled missing from pino/browser.
62
+ function isLevelEnabled(logger: pino.Logger<'verbose', boolean>, level: LogLevel): boolean {
63
+ return typeof logger.isLevelEnabled === 'function'
64
+ ? logger.isLevelEnabled(level)
65
+ : logger.levels.values[level] >= logger.levels.values[logger.level];
66
+ }
67
+
68
+ // Load log levels from environment variables.
69
+ const defaultLogLevel = process.env.NODE_ENV === 'test' ? 'silent' : 'info';
70
+ const [logLevel, logFilters] = parseEnv(process.env.LOG_LEVEL, defaultLogLevel);
71
+
72
+ // Transport options for pretty logging to stderr via pino-pretty.
73
+ const useColor = true;
74
+ const { bold, reset } = createColors({ useColor });
75
+ const pinoPrettyOpts = {
76
+ destination: 2,
77
+ sync: true,
78
+ colorize: useColor,
79
+ ignore: 'module,pid,hostname,trace_id,span_id,trace_flags',
80
+ messageFormat: `${bold('{module}')} ${reset('{msg}')}`,
81
+ customLevels: 'fatal:60,error:50,warn:40,info:30,verbose:25,debug:20,trace:10',
82
+ customColors: 'fatal:bgRed,error:red,warn:yellow,info:green,verbose:magenta,debug:blue,trace:gray',
83
+ minimumLevel: 'trace' as const,
84
+ };
85
+ const prettyTransport: pino.TransportSingleOptions = {
86
+ target: 'pino-pretty',
87
+ options: pinoPrettyOpts,
88
+ };
89
+
90
+ // Transport for vanilla stdio logging as JSON.
91
+ const stdioTransport: pino.TransportSingleOptions = {
92
+ target: 'pino/file',
93
+ options: { destination: 2 },
94
+ };
95
+
96
+ // Define custom logging levels for pino.
97
+ const customLevels = { verbose: 25 };
98
+ const pinoOpts = { customLevels, useOnlyCustomLevels: false, level: logLevel };
99
+
100
+ export const levels = {
101
+ labels: { ...pino.levels.labels, ...Object.fromEntries(Object.entries(customLevels).map(e => e.reverse())) },
102
+ values: { ...pino.levels.values, ...customLevels },
103
+ };
104
+
105
+ // Transport for OpenTelemetry logging. While defining this here is an abstraction leakage since this
106
+ // should live in the telemetry-client, it is necessary to ensure that the logger is initialized with
107
+ // the correct transport. Tweaking transports of a live pino instance is tricky, and creating a new instance
108
+ // would mean that all child loggers created before the telemetry-client is initialized would not have
109
+ // this transport configured. Note that the target is defined as the export in the telemetry-client,
110
+ // since pino will load this transport separately on a worker thread, to minimize disruption to the main loop.
111
+ const otlpEndpoint = process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT;
112
+ const otelOpts = { levels };
113
+ const otelTransport: pino.TransportSingleOptions = {
114
+ target: '@aztec/telemetry-client/otel-pino-stream',
115
+ options: otelOpts,
116
+ };
117
+
118
+ function makeLogger() {
119
+ if (!isNode) {
120
+ // We are on the browser
121
+ return pino({ ...pinoOpts, browser: { asObject: false } });
122
+ } else if (process.env.JEST_WORKER_ID) {
123
+ // We are on jest, so we need sync logging. We stream to stderr with pretty.
124
+ return pino(pinoOpts, pretty(pinoPrettyOpts));
125
+ } else {
126
+ // Regular nodejs with transports on worker thread, using pino-pretty for console logging if LOG_JSON
127
+ // is not set, and an optional OTLP transport if the OTLP endpoint is provided.
128
+ const targets: pino.TransportSingleOptions[] = compactArray([
129
+ ['1', 'true', 'TRUE'].includes(process.env.LOG_JSON ?? '') ? stdioTransport : prettyTransport,
130
+ otlpEndpoint ? otelTransport : undefined,
131
+ ]);
132
+ return pino(pinoOpts, pino.transport({ targets }));
133
+ }
134
+ }
135
+
136
+ const logger = makeLogger();
137
+
138
+ // Log the logger configuration.
139
+ logger.verbose(
140
+ {
141
+ module: 'logger',
142
+ ...logFilters.reduce((accum, [module, level]) => ({ ...accum, [`log.${module}`]: level }), {}),
143
+ },
144
+ isNode
145
+ ? `Logger initialized with level ${logLevel}` + (otlpEndpoint ? ` with OTLP exporter to ${otlpEndpoint}` : '')
146
+ : `Browser console logger initialized with level ${logLevel}`,
147
+ );
148
+
149
+ /**
150
+ * Registers an additional destination to the pino logger.
151
+ * Use only when working with destinations, not worker transports.
152
+ */
153
+ export function registerLoggingStream(stream: Writable): void {
154
+ logger.verbose({ module: 'logger' }, `Registering additional logging stream`);
155
+ const original = (logger as any)[symbols.streamSym];
156
+ const destination = original
157
+ ? pino.multistream(
158
+ [
159
+ // Set streams to lowest logging level, and control actual logging from the parent logger
160
+ // otherwise streams default to info and refuse to log anything below that.
161
+ { level: 'trace', stream: original },
162
+ { level: 'trace', stream },
163
+ ],
164
+ { levels: levels.values },
165
+ )
166
+ : stream;
167
+ (logger as any)[symbols.streamSym] = destination;
168
+ }
169
+
170
+ /** Log function that accepts an exception object */
171
+ type ErrorLogFn = (msg: string, err?: Error | unknown, data?: LogData) => void;
172
+
173
+ /**
174
+ * Logger that supports multiple severity levels.
175
+ */
176
+ export type Logger = { [K in LogLevel]: LogFn } & { /** Error log function */ error: ErrorLogFn } & {
177
+ level: LogLevel;
178
+ isLevelEnabled: (level: LogLevel) => boolean;
179
+ };
180
+
181
+ /**
182
+ * Logger that supports multiple severity levels and can be called directly to issue a debug statement.
183
+ * Intended as a drop-in replacement for the debug module.
184
+ * TODO(palla/log): Remove this alias
185
+ */
186
+ export type DebugLogger = Logger;
187
+
188
+ /**
189
+ * Concatenates a log message and an exception.
190
+ * @param msg - Log message
191
+ * @param err - Error to log
192
+ * @returns A string with both the log message and the error message.
193
+ */
194
+ function formatErr(msg: string, err?: Error | unknown): string {
195
+ return err ? `${msg}: ${inspect(err)}` : msg;
196
+ }
@@ -1,4 +1,4 @@
1
- import { type DebugLogger } from '../log/logger.js';
1
+ import { type DebugLogger } from '../log/index.js';
2
2
  import { BaseMemoryQueue } from './base_memory_queue.js';
3
3
 
4
4
  /**
@@ -1,57 +0,0 @@
1
- import { type LogData, type LogFn } from './log_fn.js';
2
- declare const LogLevels: readonly ["silent", "error", "warn", "info", "verbose", "debug"];
3
- /**
4
- * A valid log severity level.
5
- */
6
- export type LogLevel = (typeof LogLevels)[number];
7
- export declare let currentLevel: "silent" | "error" | "warn" | "info" | "verbose" | "debug";
8
- /** Log function that accepts an exception object */
9
- type ErrorLogFn = (msg: string, err?: Error | unknown, data?: LogData) => void;
10
- /**
11
- * Logger that supports multiple severity levels.
12
- */
13
- export type Logger = {
14
- [K in LogLevel]: LogFn;
15
- } & {
16
- error: ErrorLogFn;
17
- };
18
- /**
19
- * Logger that supports multiple severity levels and can be called directly to issue a debug statement.
20
- * Intended as a drop-in replacement for the debug module.
21
- */
22
- export type DebugLogger = Logger;
23
- /**
24
- * Creates a new DebugLogger for the current module, defaulting to the LOG_LEVEL env var.
25
- * If DEBUG="[module]" env is set, will enable debug logging if the module matches.
26
- * Uses npm debug for debug level and console.error for other levels.
27
- * @param name - Name of the module.
28
- * @param fixedLogData - Additional data to include in the log message.
29
- * @usage createDebugLogger('aztec:validator');
30
- * // will always add the validator address to the log labels
31
- * @returns A debug logger.
32
- */
33
- export declare function createDebugLogger(name: string): DebugLogger;
34
- /**
35
- * A function to create a logger that automatically includes fixed data in each log entry.
36
- * @param debugLogger - The base DebugLogger instance to which we attach fixed log data.
37
- * @param fixedLogData - The data to be included in every log entry.
38
- * @returns A DebugLogger with log level methods (error, warn, info, verbose, debug) that
39
- * automatically attach `fixedLogData` to every log message.
40
- */
41
- export declare function attachedFixedDataToLogger(debugLogger: DebugLogger, fixedLogData: LogData): DebugLogger;
42
- /** A callback to capture all logs. */
43
- export type LogHandler = (level: LogLevel, namespace: string, msg: string, data?: LogData) => void;
44
- /**
45
- * Registers a callback for all logs, whether they are emitted in the current log level or not.
46
- * @param handler - Callback to be called on every log.
47
- */
48
- export declare function onLog(handler: LogHandler): void;
49
- /** Overrides current log level. */
50
- export declare function setLevel(level: LogLevel): void;
51
- /**
52
- * Formats structured log data as a string for console output.
53
- * @param data - Optional log data.
54
- */
55
- export declare function fmtLogData(data?: LogData): string;
56
- export {};
57
- //# sourceMappingURL=logger.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/log/logger.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AAEvD,QAAA,MAAM,SAAS,kEAAmE,CAAC;AAEnF;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AAelD,eAAO,IAAI,YAAY,4DAAgB,CAAC;AAwBxC,oDAAoD;AACpD,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,GAAG,OAAO,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;AAE/E;;GAEG;AACH,MAAM,MAAM,MAAM,GAAG;KAAG,CAAC,IAAI,QAAQ,GAAG,KAAK;CAAE,GAAG;IAA4B,KAAK,EAAE,UAAU,CAAA;CAAE,CAAC;AAElG;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC;AAEjC;;;;;;;;;GASG;AAEH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAqB3D;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,OAAO,GAAG,WAAW,CActG;AAED,sCAAsC;AACtC,MAAM,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;AAInG;;;GAGG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,UAAU,QAExC;AAED,mCAAmC;AACnC,wBAAgB,QAAQ,CAAC,KAAK,EAAE,QAAQ,QAEvC;AAkCD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAIjD"}
@@ -1,139 +0,0 @@
1
- import debug from 'debug';
2
- import { inspect } from 'util';
3
- const LogLevels = ['silent', 'error', 'warn', 'info', 'verbose', 'debug'];
4
- function getLogLevel() {
5
- const envLogLevel = process.env.LOG_LEVEL?.toLowerCase();
6
- let defaultLogLevel = 'info';
7
- if (process.env.DEBUG) {
8
- // if we set DEBUG to a non-empty string, use debug as default
9
- defaultLogLevel = 'debug';
10
- }
11
- else if (process.env.NODE_ENV === 'test') {
12
- // otherwise, be silent in tests as these are frequently ran en-masse
13
- defaultLogLevel = 'silent';
14
- }
15
- return LogLevels.includes(envLogLevel) ? envLogLevel : defaultLogLevel;
16
- }
17
- export let currentLevel = getLogLevel();
18
- const logElapsedTime = ['1', 'true'].includes(process.env.LOG_ELAPSED_TIME ?? '');
19
- const firstTimestamp = Date.now();
20
- function filterNegativePatterns(debugString) {
21
- return debugString
22
- .split(',')
23
- .filter(p => !p.startsWith('-'))
24
- .join(',');
25
- }
26
- function extractNegativePatterns(debugString) {
27
- return (debugString
28
- .split(',')
29
- .filter(p => p.startsWith('-'))
30
- // Remove the leading '-' from the pattern
31
- .map(p => p.slice(1)));
32
- }
33
- const namespaces = process.env.DEBUG ?? 'aztec:*';
34
- debug.enable(filterNegativePatterns(namespaces));
35
- /**
36
- * Creates a new DebugLogger for the current module, defaulting to the LOG_LEVEL env var.
37
- * If DEBUG="[module]" env is set, will enable debug logging if the module matches.
38
- * Uses npm debug for debug level and console.error for other levels.
39
- * @param name - Name of the module.
40
- * @param fixedLogData - Additional data to include in the log message.
41
- * @usage createDebugLogger('aztec:validator');
42
- * // will always add the validator address to the log labels
43
- * @returns A debug logger.
44
- */
45
- export function createDebugLogger(name) {
46
- const debugLogger = debug(name);
47
- const negativePatterns = extractNegativePatterns(namespaces);
48
- const accepted = () => {
49
- return !negativePatterns.some(pattern => name.match(pattern));
50
- };
51
- const log = (level, msg, data) => {
52
- if (accepted()) {
53
- logWithDebug(debugLogger, level, msg, data);
54
- }
55
- };
56
- const logger = {
57
- silent: () => { },
58
- error: (msg, err, data) => log('error', fmtErr(msg, err), data),
59
- warn: (msg, data) => log('warn', msg, data),
60
- info: (msg, data) => log('info', msg, data),
61
- verbose: (msg, data) => log('verbose', msg, data),
62
- debug: (msg, data) => log('debug', msg, data),
63
- };
64
- return Object.assign((msg, data) => log('debug', msg, data), logger);
65
- }
66
- /**
67
- * A function to create a logger that automatically includes fixed data in each log entry.
68
- * @param debugLogger - The base DebugLogger instance to which we attach fixed log data.
69
- * @param fixedLogData - The data to be included in every log entry.
70
- * @returns A DebugLogger with log level methods (error, warn, info, verbose, debug) that
71
- * automatically attach `fixedLogData` to every log message.
72
- */
73
- export function attachedFixedDataToLogger(debugLogger, fixedLogData) {
74
- // Helper function to merge fixed data with additional data passed to log entries.
75
- const attach = (data) => ({ ...fixedLogData, ...data });
76
- // Define the logger with all the necessary log level methods.
77
- const logger = {
78
- // Silent log level does nothing.
79
- silent: () => { },
80
- error: (msg, err, data) => debugLogger.error(fmtErr(msg, err), attach(data)),
81
- warn: (msg, data) => debugLogger.warn(msg, attach(data)),
82
- info: (msg, data) => debugLogger.info(msg, attach(data)),
83
- verbose: (msg, data) => debugLogger.verbose(msg, attach(data)),
84
- debug: (msg, data) => debugLogger.debug(msg, attach(data)),
85
- };
86
- return Object.assign((msg, data) => debugLogger.debug(msg, attach(data)), logger);
87
- }
88
- const logHandlers = [];
89
- /**
90
- * Registers a callback for all logs, whether they are emitted in the current log level or not.
91
- * @param handler - Callback to be called on every log.
92
- */
93
- export function onLog(handler) {
94
- logHandlers.push(handler);
95
- }
96
- /** Overrides current log level. */
97
- export function setLevel(level) {
98
- currentLevel = level;
99
- }
100
- /**
101
- * Logs args to npm debug if enabled or log level is debug, console.error otherwise.
102
- * @param debug - Instance of npm debug.
103
- * @param level - Intended log level.
104
- * @param args - Args to log.
105
- */
106
- function logWithDebug(debug, level, msg, data) {
107
- for (const handler of logHandlers) {
108
- handler(level, debug.namespace, msg, data);
109
- }
110
- msg = data ? `${msg} ${fmtLogData(data)}` : msg;
111
- if (debug.enabled && LogLevels.indexOf(level) <= LogLevels.indexOf(currentLevel)) {
112
- if (logElapsedTime) {
113
- const ts = ((Date.now() - firstTimestamp) / 1000).toFixed(3);
114
- debug('%ss [%s] %s', ts, level.toUpperCase(), msg);
115
- }
116
- else {
117
- debug('[%s] %s', level.toUpperCase(), msg);
118
- }
119
- }
120
- }
121
- /**
122
- * Concatenates a log message and an exception.
123
- * @param msg - Log message
124
- * @param err - Error to log
125
- * @returns A string with both the log message and the error message.
126
- */
127
- function fmtErr(msg, err) {
128
- return err ? `${msg}: ${inspect(err)}` : msg;
129
- }
130
- /**
131
- * Formats structured log data as a string for console output.
132
- * @param data - Optional log data.
133
- */
134
- export function fmtLogData(data) {
135
- return Object.entries(data ?? {})
136
- .map(([key, value]) => `${key}=${typeof value === 'object' && 'toString' in value ? value.toString() : value}`)
137
- .join(' ');
138
- }
139
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2xvZy9sb2dnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE1BQU0sT0FBTyxDQUFDO0FBQzFCLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFJL0IsTUFBTSxTQUFTLEdBQUcsQ0FBQyxRQUFRLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBVSxDQUFDO0FBT25GLFNBQVMsV0FBVztJQUNsQixNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxXQUFXLEVBQWMsQ0FBQztJQUNyRSxJQUFJLGVBQWUsR0FBYSxNQUFNLENBQUM7SUFDdkMsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3RCLDhEQUE4RDtRQUM5RCxlQUFlLEdBQUcsT0FBTyxDQUFDO0lBQzVCLENBQUM7U0FBTSxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxLQUFLLE1BQU0sRUFBRSxDQUFDO1FBQzNDLHFFQUFxRTtRQUNyRSxlQUFlLEdBQUcsUUFBUSxDQUFDO0lBQzdCLENBQUM7SUFDRCxPQUFPLFNBQVMsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDO0FBQ3pFLENBQUM7QUFFRCxNQUFNLENBQUMsSUFBSSxZQUFZLEdBQUcsV0FBVyxFQUFFLENBQUM7QUFFeEMsTUFBTSxjQUFjLEdBQUcsQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLElBQUksRUFBRSxDQUFDLENBQUM7QUFDbEYsTUFBTSxjQUFjLEdBQVcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBRTFDLFNBQVMsc0JBQXNCLENB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
package/src/log/logger.ts DELETED
@@ -1,179 +0,0 @@
1
- import debug from 'debug';
2
- import { inspect } from 'util';
3
-
4
- import { type LogData, type LogFn } from './log_fn.js';
5
-
6
- const LogLevels = ['silent', 'error', 'warn', 'info', 'verbose', 'debug'] as const;
7
-
8
- /**
9
- * A valid log severity level.
10
- */
11
- export type LogLevel = (typeof LogLevels)[number];
12
-
13
- function getLogLevel() {
14
- const envLogLevel = process.env.LOG_LEVEL?.toLowerCase() as LogLevel;
15
- let defaultLogLevel: LogLevel = 'info';
16
- if (process.env.DEBUG) {
17
- // if we set DEBUG to a non-empty string, use debug as default
18
- defaultLogLevel = 'debug';
19
- } else if (process.env.NODE_ENV === 'test') {
20
- // otherwise, be silent in tests as these are frequently ran en-masse
21
- defaultLogLevel = 'silent';
22
- }
23
- return LogLevels.includes(envLogLevel) ? envLogLevel : defaultLogLevel;
24
- }
25
-
26
- export let currentLevel = getLogLevel();
27
-
28
- const logElapsedTime = ['1', 'true'].includes(process.env.LOG_ELAPSED_TIME ?? '');
29
- const firstTimestamp: number = Date.now();
30
-
31
- function filterNegativePatterns(debugString: string): string {
32
- return debugString
33
- .split(',')
34
- .filter(p => !p.startsWith('-'))
35
- .join(',');
36
- }
37
- function extractNegativePatterns(debugString: string): string[] {
38
- return (
39
- debugString
40
- .split(',')
41
- .filter(p => p.startsWith('-'))
42
- // Remove the leading '-' from the pattern
43
- .map(p => p.slice(1))
44
- );
45
- }
46
-
47
- const namespaces = process.env.DEBUG ?? 'aztec:*';
48
- debug.enable(filterNegativePatterns(namespaces));
49
-
50
- /** Log function that accepts an exception object */
51
- type ErrorLogFn = (msg: string, err?: Error | unknown, data?: LogData) => void;
52
-
53
- /**
54
- * Logger that supports multiple severity levels.
55
- */
56
- export type Logger = { [K in LogLevel]: LogFn } & { /** Error log function */ error: ErrorLogFn };
57
-
58
- /**
59
- * Logger that supports multiple severity levels and can be called directly to issue a debug statement.
60
- * Intended as a drop-in replacement for the debug module.
61
- */
62
- export type DebugLogger = Logger;
63
-
64
- /**
65
- * Creates a new DebugLogger for the current module, defaulting to the LOG_LEVEL env var.
66
- * If DEBUG="[module]" env is set, will enable debug logging if the module matches.
67
- * Uses npm debug for debug level and console.error for other levels.
68
- * @param name - Name of the module.
69
- * @param fixedLogData - Additional data to include in the log message.
70
- * @usage createDebugLogger('aztec:validator');
71
- * // will always add the validator address to the log labels
72
- * @returns A debug logger.
73
- */
74
-
75
- export function createDebugLogger(name: string): DebugLogger {
76
- const debugLogger = debug(name);
77
-
78
- const negativePatterns = extractNegativePatterns(namespaces);
79
- const accepted = () => {
80
- return !negativePatterns.some(pattern => name.match(pattern));
81
- };
82
- const log = (level: LogLevel, msg: string, data?: LogData) => {
83
- if (accepted()) {
84
- logWithDebug(debugLogger, level, msg, data);
85
- }
86
- };
87
- const logger = {
88
- silent: () => {},
89
- error: (msg: string, err?: unknown, data?: LogData) => log('error', fmtErr(msg, err), data),
90
- warn: (msg: string, data?: LogData) => log('warn', msg, data),
91
- info: (msg: string, data?: LogData) => log('info', msg, data),
92
- verbose: (msg: string, data?: LogData) => log('verbose', msg, data),
93
- debug: (msg: string, data?: LogData) => log('debug', msg, data),
94
- };
95
- return Object.assign((msg: string, data?: LogData) => log('debug', msg, data), logger);
96
- }
97
-
98
- /**
99
- * A function to create a logger that automatically includes fixed data in each log entry.
100
- * @param debugLogger - The base DebugLogger instance to which we attach fixed log data.
101
- * @param fixedLogData - The data to be included in every log entry.
102
- * @returns A DebugLogger with log level methods (error, warn, info, verbose, debug) that
103
- * automatically attach `fixedLogData` to every log message.
104
- */
105
- export function attachedFixedDataToLogger(debugLogger: DebugLogger, fixedLogData: LogData): DebugLogger {
106
- // Helper function to merge fixed data with additional data passed to log entries.
107
- const attach = (data?: LogData) => ({ ...fixedLogData, ...data });
108
- // Define the logger with all the necessary log level methods.
109
- const logger = {
110
- // Silent log level does nothing.
111
- silent: () => {},
112
- error: (msg: string, err?: unknown, data?: LogData) => debugLogger.error(fmtErr(msg, err), attach(data)),
113
- warn: (msg: string, data?: LogData) => debugLogger.warn(msg, attach(data)),
114
- info: (msg: string, data?: LogData) => debugLogger.info(msg, attach(data)),
115
- verbose: (msg: string, data?: LogData) => debugLogger.verbose(msg, attach(data)),
116
- debug: (msg: string, data?: LogData) => debugLogger.debug(msg, attach(data)),
117
- };
118
- return Object.assign((msg: string, data?: LogData) => debugLogger.debug(msg, attach(data)), logger);
119
- }
120
-
121
- /** A callback to capture all logs. */
122
- export type LogHandler = (level: LogLevel, namespace: string, msg: string, data?: LogData) => void;
123
-
124
- const logHandlers: LogHandler[] = [];
125
-
126
- /**
127
- * Registers a callback for all logs, whether they are emitted in the current log level or not.
128
- * @param handler - Callback to be called on every log.
129
- */
130
- export function onLog(handler: LogHandler) {
131
- logHandlers.push(handler);
132
- }
133
-
134
- /** Overrides current log level. */
135
- export function setLevel(level: LogLevel) {
136
- currentLevel = level;
137
- }
138
-
139
- /**
140
- * Logs args to npm debug if enabled or log level is debug, console.error otherwise.
141
- * @param debug - Instance of npm debug.
142
- * @param level - Intended log level.
143
- * @param args - Args to log.
144
- */
145
- function logWithDebug(debug: debug.Debugger, level: LogLevel, msg: string, data?: LogData) {
146
- for (const handler of logHandlers) {
147
- handler(level, debug.namespace, msg, data);
148
- }
149
-
150
- msg = data ? `${msg} ${fmtLogData(data)}` : msg;
151
- if (debug.enabled && LogLevels.indexOf(level) <= LogLevels.indexOf(currentLevel)) {
152
- if (logElapsedTime) {
153
- const ts = ((Date.now() - firstTimestamp) / 1000).toFixed(3);
154
- debug('%ss [%s] %s', ts, level.toUpperCase(), msg);
155
- } else {
156
- debug('[%s] %s', level.toUpperCase(), msg);
157
- }
158
- }
159
- }
160
-
161
- /**
162
- * Concatenates a log message and an exception.
163
- * @param msg - Log message
164
- * @param err - Error to log
165
- * @returns A string with both the log message and the error message.
166
- */
167
- function fmtErr(msg: string, err?: Error | unknown): string {
168
- return err ? `${msg}: ${inspect(err)}` : msg;
169
- }
170
-
171
- /**
172
- * Formats structured log data as a string for console output.
173
- * @param data - Optional log data.
174
- */
175
- export function fmtLogData(data?: LogData): string {
176
- return Object.entries(data ?? {})
177
- .map(([key, value]) => `${key}=${typeof value === 'object' && 'toString' in value ? value.toString() : value}`)
178
- .join(' ');
179
- }