@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.
- package/dest/async-pool/index.d.ts +3 -0
- package/dest/async-pool/index.d.ts.map +1 -0
- package/dest/async-pool/index.js +50 -0
- package/dest/collection/array.d.ts +14 -0
- package/dest/collection/array.d.ts.map +1 -1
- package/dest/collection/array.js +23 -1
- package/dest/config/env_var.d.ts +1 -1
- package/dest/config/env_var.d.ts.map +1 -1
- package/dest/config/index.d.ts +1 -1
- package/dest/config/index.d.ts.map +1 -1
- package/dest/config/index.js +2 -2
- package/dest/crypto/random/randomness_singleton.js +2 -2
- package/dest/json-rpc/client/safe_json_rpc_client.d.ts +1 -1
- package/dest/json-rpc/client/safe_json_rpc_client.d.ts.map +1 -1
- package/dest/json-rpc/client/safe_json_rpc_client.js +2 -2
- package/dest/json-rpc/server/safe_json_rpc_server.d.ts +2 -2
- package/dest/json-rpc/server/safe_json_rpc_server.d.ts.map +1 -1
- package/dest/log/index.d.ts +1 -1
- package/dest/log/index.d.ts.map +1 -1
- package/dest/log/index.js +2 -2
- package/dest/log/log-filters.d.ts +7 -0
- package/dest/log/log-filters.d.ts.map +1 -0
- package/dest/log/log-filters.js +43 -0
- package/dest/log/log-levels.d.ts +3 -0
- package/dest/log/log-levels.d.ts.map +1 -0
- package/dest/log/log-levels.js +2 -0
- package/dest/log/pino-logger.d.ts +39 -0
- package/dest/log/pino-logger.d.ts.map +1 -0
- package/dest/log/pino-logger.js +146 -0
- package/dest/queue/base_memory_queue.d.ts +1 -1
- package/dest/queue/base_memory_queue.d.ts.map +1 -1
- package/dest/queue/bounded_serial_queue.d.ts +1 -1
- package/dest/queue/bounded_serial_queue.d.ts.map +1 -1
- package/dest/queue/fifo_memory_queue.d.ts +1 -1
- package/dest/queue/fifo_memory_queue.d.ts.map +1 -1
- package/dest/retry/index.d.ts +1 -1
- package/dest/retry/index.d.ts.map +1 -1
- package/dest/transport/dispatch/create_dispatch_fn.d.ts +1 -1
- package/dest/transport/dispatch/create_dispatch_fn.d.ts.map +1 -1
- package/package.json +6 -2
- package/src/async-pool/index.ts +50 -0
- package/src/collection/array.ts +24 -0
- package/src/config/env_var.ts +25 -3
- package/src/config/index.ts +1 -1
- package/src/crypto/random/randomness_singleton.ts +1 -1
- package/src/json-rpc/client/safe_json_rpc_client.ts +1 -1
- package/src/log/index.ts +1 -1
- package/src/log/log-filters.ts +49 -0
- package/src/log/log-levels.ts +3 -0
- package/src/log/pino-logger.ts +196 -0
- package/src/queue/fifo_memory_queue.ts +1 -1
- package/dest/log/logger.d.ts +0 -57
- package/dest/log/logger.d.ts.map +0 -1
- package/dest/log/logger.js +0 -139
- 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
|
+
}
|
package/dest/log/logger.d.ts
DELETED
|
@@ -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
|
package/dest/log/logger.d.ts.map
DELETED
|
@@ -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"}
|
package/dest/log/logger.js
DELETED
|
@@ -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
|
-
}
|