@matter/general 0.13.0-alpha.0-20250322-f085fa576 → 0.13.0-alpha.0-20250323-770919c6a
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/cjs/log/Console.d.ts +21 -0
- package/dist/cjs/log/Console.d.ts.map +1 -0
- package/dist/cjs/log/Console.js +58 -0
- package/dist/cjs/log/Console.js.map +6 -0
- package/dist/cjs/log/Diagnostic.d.ts +6 -0
- package/dist/cjs/log/Diagnostic.d.ts.map +1 -1
- package/dist/cjs/log/Diagnostic.js +16 -0
- package/dist/cjs/log/Diagnostic.js.map +1 -1
- package/dist/cjs/log/LogDestination.d.ts +67 -0
- package/dist/cjs/log/LogDestination.d.ts.map +1 -0
- package/dist/cjs/log/LogDestination.js +65 -0
- package/dist/cjs/log/LogDestination.js.map +6 -0
- package/dist/cjs/log/LogFormat.d.ts +18 -12
- package/dist/cjs/log/LogFormat.d.ts.map +1 -1
- package/dist/cjs/log/LogFormat.js +17 -24
- package/dist/cjs/log/LogFormat.js.map +1 -1
- package/dist/cjs/log/LogLevel.d.ts +19 -9
- package/dist/cjs/log/LogLevel.d.ts.map +1 -1
- package/dist/cjs/log/LogLevel.js +40 -25
- package/dist/cjs/log/LogLevel.js.map +1 -1
- package/dist/cjs/log/Logger.d.ts +157 -106
- package/dist/cjs/log/Logger.d.ts.map +1 -1
- package/dist/cjs/log/Logger.js +298 -256
- package/dist/cjs/log/Logger.js.map +2 -2
- package/dist/cjs/log/index.d.ts +1 -0
- package/dist/cjs/log/index.d.ts.map +1 -1
- package/dist/cjs/log/index.js +1 -0
- package/dist/cjs/log/index.js.map +1 -1
- package/dist/cjs/transaction/Transaction.d.ts +19 -19
- package/dist/esm/log/Console.d.ts +21 -0
- package/dist/esm/log/Console.d.ts.map +1 -0
- package/dist/esm/log/Console.js +38 -0
- package/dist/esm/log/Console.js.map +6 -0
- package/dist/esm/log/Diagnostic.d.ts +6 -0
- package/dist/esm/log/Diagnostic.d.ts.map +1 -1
- package/dist/esm/log/Diagnostic.js +16 -0
- package/dist/esm/log/Diagnostic.js.map +1 -1
- package/dist/esm/log/LogDestination.d.ts +67 -0
- package/dist/esm/log/LogDestination.d.ts.map +1 -0
- package/dist/esm/log/LogDestination.js +45 -0
- package/dist/esm/log/LogDestination.js.map +6 -0
- package/dist/esm/log/LogFormat.d.ts +18 -12
- package/dist/esm/log/LogFormat.d.ts.map +1 -1
- package/dist/esm/log/LogFormat.js +17 -24
- package/dist/esm/log/LogFormat.js.map +1 -1
- package/dist/esm/log/LogLevel.d.ts +19 -9
- package/dist/esm/log/LogLevel.d.ts.map +1 -1
- package/dist/esm/log/LogLevel.js +40 -25
- package/dist/esm/log/LogLevel.js.map +1 -1
- package/dist/esm/log/Logger.d.ts +157 -106
- package/dist/esm/log/Logger.d.ts.map +1 -1
- package/dist/esm/log/Logger.js +298 -256
- package/dist/esm/log/Logger.js.map +2 -2
- package/dist/esm/log/index.d.ts +1 -0
- package/dist/esm/log/index.d.ts.map +1 -1
- package/dist/esm/log/index.js +1 -0
- package/dist/esm/log/index.js.map +1 -1
- package/dist/esm/transaction/Transaction.d.ts +19 -19
- package/package.json +2 -2
- package/src/log/Console.ts +52 -0
- package/src/log/Diagnostic.ts +21 -0
- package/src/log/LogDestination.ts +113 -0
- package/src/log/LogFormat.ts +39 -36
- package/src/log/LogLevel.ts +55 -25
- package/src/log/Logger.ts +379 -314
- package/src/log/index.ts +1 -0
package/src/log/Logger.ts
CHANGED
|
@@ -10,97 +10,264 @@ import { ImplementationError, NotImplementedError } from "../MatterError.js";
|
|
|
10
10
|
import { Time } from "../time/Time.js";
|
|
11
11
|
import { Bytes } from "../util/Bytes.js";
|
|
12
12
|
import { Diagnostic } from "./Diagnostic.js";
|
|
13
|
+
import { LogDestination, LogDestinations } from "./LogDestination.js";
|
|
13
14
|
import { LogFormat } from "./LogFormat.js";
|
|
14
15
|
import { LogLevel } from "./LogLevel.js";
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
|
-
*
|
|
18
|
-
*/
|
|
19
|
-
export function consoleLogger(level: LogLevel, formattedLog: string, _facility?: string) {
|
|
20
|
-
const console = (<any>consoleLogger).console;
|
|
21
|
-
switch (level) {
|
|
22
|
-
case LogLevel.DEBUG:
|
|
23
|
-
console.debug(formattedLog);
|
|
24
|
-
break;
|
|
25
|
-
case LogLevel.INFO:
|
|
26
|
-
console.info(formattedLog);
|
|
27
|
-
break;
|
|
28
|
-
case LogLevel.NOTICE:
|
|
29
|
-
console.info(formattedLog);
|
|
30
|
-
break;
|
|
31
|
-
case LogLevel.WARN:
|
|
32
|
-
console.warn(formattedLog);
|
|
33
|
-
break;
|
|
34
|
-
case LogLevel.ERROR:
|
|
35
|
-
console.error(formattedLog);
|
|
36
|
-
break;
|
|
37
|
-
case LogLevel.FATAL:
|
|
38
|
-
console.error(formattedLog);
|
|
39
|
-
break;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const globalConsole = console;
|
|
44
|
-
export namespace consoleLogger {
|
|
45
|
-
/**
|
|
46
|
-
* The target for consoleLogger.
|
|
47
|
-
*/
|
|
48
|
-
// eslint-disable-next-line prefer-const
|
|
49
|
-
export let console = globalConsole;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Create a log formatter for a given format.
|
|
54
|
-
*/
|
|
55
|
-
function logFormatterFor(formatName: string): LoggerDefinition["logFormatter"] {
|
|
56
|
-
const format = LogFormat(formatName);
|
|
57
|
-
|
|
58
|
-
return (now, level, facility, prefix, ...values) =>
|
|
59
|
-
format(Diagnostic.message({ now, level, facility, prefix, values }));
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Definition of one registered Logger.
|
|
64
|
-
*/
|
|
65
|
-
type LoggerDefinition = {
|
|
66
|
-
logIdentifier: string;
|
|
67
|
-
logFormatter: (now: Date, level: LogLevel, facility: string, prefix: string, ...values: any[]) => string;
|
|
68
|
-
log: (level: LogLevel, formattedLog: string, facility?: string) => void;
|
|
69
|
-
defaultLogLevel: LogLevel;
|
|
70
|
-
logLevels: { [facility: string]: LogLevel };
|
|
71
|
-
context?: Diagnostic.Context;
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Logger that can be used to emit traces.
|
|
76
|
-
*
|
|
77
|
-
* The class supports adding multiple loggers for different targets. A default logger (identifier "default") is added on
|
|
78
|
-
* startup which logs to "console".
|
|
18
|
+
* matter.js logging API
|
|
79
19
|
*
|
|
80
20
|
* Usage:
|
|
81
21
|
*
|
|
82
|
-
* const
|
|
83
|
-
*
|
|
22
|
+
* const logger = Logger.get("loggerName");
|
|
23
|
+
* logger.debug("My debug message", "my extra value to log");
|
|
84
24
|
*
|
|
85
|
-
*
|
|
25
|
+
* matter.js writes logs to each {@link LogDestination} in {@link Logger.destinations}. By default a single destination
|
|
26
|
+
* named "default" writes to the JS console.
|
|
86
27
|
*
|
|
87
|
-
*
|
|
88
|
-
* - Logger.logLevels = { loggerName: Level.DEBUG } can set the level for the specific loggers
|
|
89
|
-
* - Logger.format = Format.ANSI enables colorization via ANSI escape sequences in default formatter
|
|
28
|
+
* You may adjust log verbosity and format by modifying the properties on destinations. For example:
|
|
90
29
|
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
* - Logger.setLogLevelsForLogger("loggerName", { loggerName: Level.DEBUG })
|
|
96
|
-
* - Logger.setDefaultLoglevelForLogger("loggerName", Level.DEBUG)
|
|
30
|
+
* `Logger.format = LogFormat.PLAIN` sets all destinations to write plaintext
|
|
31
|
+
* `Logger.destinations.default.format = LogFormat.format.ansi` sets one destination to write ANSI
|
|
32
|
+
* `Logger.level = LogLevel.NOTICE` sets "notice" as the minimum level for all destinations
|
|
33
|
+
* `Logger.destinations.default.level = LogLevel.NOTICE` sets "notice" as level for one destination
|
|
97
34
|
*/
|
|
98
35
|
export class Logger {
|
|
99
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Log destinations.
|
|
38
|
+
*
|
|
39
|
+
* By default there is a single destination named "default". You can create new destinations using
|
|
40
|
+
* {@link LogDestination}. Add or remove destinations by modifying this object.
|
|
41
|
+
*
|
|
42
|
+
* Throws an error if you access a destination that doesn't exist.
|
|
43
|
+
*/
|
|
44
|
+
static destinations = LogDestinations();
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* The number of indents to print with messages.
|
|
48
|
+
*/
|
|
100
49
|
static nestingLevel: number;
|
|
50
|
+
|
|
101
51
|
readonly #name: string;
|
|
102
52
|
|
|
103
|
-
/**
|
|
53
|
+
/**
|
|
54
|
+
* Create a new logger for a facility.
|
|
55
|
+
*
|
|
56
|
+
* @param name the name of the facility
|
|
57
|
+
* @returns a new facility
|
|
58
|
+
*/
|
|
59
|
+
static get(name: string) {
|
|
60
|
+
return new Logger(name);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Get the default log level.
|
|
65
|
+
*/
|
|
66
|
+
static get level() {
|
|
67
|
+
return LogDestination.defaults.level;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Set log level as name or number for all destinations.
|
|
72
|
+
*/
|
|
73
|
+
static set level(level: LogLevel | string) {
|
|
74
|
+
level = LogLevel(level);
|
|
75
|
+
|
|
76
|
+
LogDestination.defaults.level = level;
|
|
77
|
+
|
|
78
|
+
for (const name in this.destinations) {
|
|
79
|
+
this.destinations[name].level = level;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Get the default facility levels.
|
|
85
|
+
*/
|
|
86
|
+
static get facilityLevels() {
|
|
87
|
+
return LogDestination.defaults.facilityLevels;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Set log level as name or number for facilities in all destinations.
|
|
92
|
+
*
|
|
93
|
+
* Existing levels that are not named in {@link levels} will remain unchanged.
|
|
94
|
+
*/
|
|
95
|
+
static set facilityLevels(levels: Record<string, LogLevel | string>) {
|
|
96
|
+
for (const name in levels) {
|
|
97
|
+
levels[name] = LogLevel(levels[name]);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
Object.assign(LogDestination.defaults.facilityLevels, levels);
|
|
101
|
+
|
|
102
|
+
for (const name in this.destinations) {
|
|
103
|
+
Object.assign(this.destinations[name].facilityLevels, levels);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Get the default format name.
|
|
109
|
+
*/
|
|
110
|
+
static get format(): string {
|
|
111
|
+
return LogDestination.defaults.format.name;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Set the format for all destinations.
|
|
116
|
+
*/
|
|
117
|
+
static set format(format: string | LogFormat.Formatter) {
|
|
118
|
+
format = LogFormat(format);
|
|
119
|
+
|
|
120
|
+
LogDestination.defaults.format = format;
|
|
121
|
+
|
|
122
|
+
for (const name in this.destinations) {
|
|
123
|
+
this.destinations[name].format = format;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Mask a string with a given character. If unmaskedLength is provided then these number of characters will be
|
|
129
|
+
* shown unmasked.
|
|
130
|
+
*
|
|
131
|
+
* @param str String to mask
|
|
132
|
+
* @param maskChar character to mask with
|
|
133
|
+
* @param unmaskedLength number of characters to show unmasked in the beginning
|
|
134
|
+
*/
|
|
135
|
+
static maskString(str: string, maskChar = "*", unmaskedLength?: number) {
|
|
136
|
+
return str.substring(0, unmaskedLength ?? 0) + str.substring(unmaskedLength ?? 0).replace(/./g, maskChar);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Perform operations in a nested logging context. Messages will be
|
|
141
|
+
* indented while the context executes.
|
|
142
|
+
*/
|
|
143
|
+
static nest<T>(context: () => T): T {
|
|
144
|
+
this.nestingLevel++;
|
|
145
|
+
try {
|
|
146
|
+
return context();
|
|
147
|
+
} finally {
|
|
148
|
+
this.nestingLevel--;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Async version of nest().
|
|
154
|
+
*/
|
|
155
|
+
static async nestAsync(context: () => Promise<any>) {
|
|
156
|
+
this.nestingLevel++;
|
|
157
|
+
try {
|
|
158
|
+
return await context();
|
|
159
|
+
} finally {
|
|
160
|
+
this.nestingLevel--;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Unhandled error reporter.
|
|
166
|
+
*
|
|
167
|
+
* Some environments do not report full error details such as {@link Error#cause} and {@link AggregateError#errors}.
|
|
168
|
+
*
|
|
169
|
+
* To ensure these details are always recorded somewhere, unhandled errors may be reported here.
|
|
170
|
+
*
|
|
171
|
+
* To disable this behavior replace this function.
|
|
172
|
+
*/
|
|
173
|
+
static reportUnhandledError(error: Error) {
|
|
174
|
+
try {
|
|
175
|
+
Logger.get("Logger").fatal("Unhandled error detected:", error);
|
|
176
|
+
} catch (e) {
|
|
177
|
+
// We do not want to cause yet another error so if logging fails for any reason it goes unreported
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
constructor(name: string) {
|
|
182
|
+
this.#name = name;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
debug(...values: unknown[]) {
|
|
186
|
+
this.#log(LogLevel.DEBUG, values);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
info(...values: unknown[]) {
|
|
190
|
+
this.#log(LogLevel.INFO, values);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
notice(...values: unknown[]) {
|
|
194
|
+
this.#log(LogLevel.NOTICE, values);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
warn(...values: unknown[]) {
|
|
198
|
+
this.#log(LogLevel.WARN, values);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
error(...values: unknown[]) {
|
|
202
|
+
this.#log(LogLevel.ERROR, values);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
fatal(...values: unknown[]) {
|
|
206
|
+
this.#log(LogLevel.FATAL, values);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
log(level: LogLevel, ...values: unknown[]) {
|
|
210
|
+
this.#log(level, values);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
#log(level: LogLevel, values: unknown[]) {
|
|
214
|
+
for (const name in Logger.destinations) {
|
|
215
|
+
const dest = Logger.destinations[name];
|
|
216
|
+
|
|
217
|
+
if (level < (dest.facilityLevels?.[this.#name] ?? dest.level)) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (!dest.context) {
|
|
222
|
+
dest.context = Diagnostic.Context();
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
dest.context.run(() =>
|
|
226
|
+
dest.add(
|
|
227
|
+
Diagnostic.message({
|
|
228
|
+
now: Time.now(),
|
|
229
|
+
facility: this.#name,
|
|
230
|
+
level,
|
|
231
|
+
prefix: nestingPrefix(),
|
|
232
|
+
values,
|
|
233
|
+
}),
|
|
234
|
+
),
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
//
|
|
240
|
+
// DEPRECATED API SURFACE FOLLOWS
|
|
241
|
+
//
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Stringify a value (BigInt aware) as JSON.
|
|
245
|
+
*
|
|
246
|
+
* @param data the value to stringify
|
|
247
|
+
* @returns the stringified value
|
|
248
|
+
*
|
|
249
|
+
* @deprecated use {@link Diagnostic.json}
|
|
250
|
+
*/
|
|
251
|
+
static toJSON(data: any) {
|
|
252
|
+
return JSON.stringify(data, (_, value) => {
|
|
253
|
+
if (typeof value === "bigint") {
|
|
254
|
+
return value.toString();
|
|
255
|
+
}
|
|
256
|
+
if (value instanceof Uint8Array) {
|
|
257
|
+
return Bytes.toHex(value);
|
|
258
|
+
}
|
|
259
|
+
if (value === undefined) {
|
|
260
|
+
return "undefined";
|
|
261
|
+
}
|
|
262
|
+
return value;
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Add additional logger to the list of loggers including the default configuration.
|
|
268
|
+
*
|
|
269
|
+
* @deprecated use {@link destinations}
|
|
270
|
+
*/
|
|
104
271
|
public static addLogger(
|
|
105
272
|
identifier: string,
|
|
106
273
|
logger: (level: LogLevel, formattedLog: string) => void,
|
|
@@ -110,87 +277,70 @@ export class Logger {
|
|
|
110
277
|
logFormat?: string;
|
|
111
278
|
},
|
|
112
279
|
) {
|
|
113
|
-
if (
|
|
114
|
-
throw new
|
|
280
|
+
if (identifier in this.destinations) {
|
|
281
|
+
throw new ImplementationError(`Logger "${identifier}" already exists`);
|
|
115
282
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
defaultLogLevel
|
|
121
|
-
|
|
122
|
-
|
|
283
|
+
const dest = LogDestination({ name: identifier });
|
|
284
|
+
const legacy = adaptDestinationToLegacy(dest);
|
|
285
|
+
legacy.log = logger;
|
|
286
|
+
if (options?.defaultLogLevel !== undefined) {
|
|
287
|
+
legacy.defaultLogLevel = options.defaultLogLevel;
|
|
288
|
+
}
|
|
289
|
+
if (options?.logLevels !== undefined) {
|
|
290
|
+
legacy.logLevels = options.logLevels;
|
|
291
|
+
}
|
|
292
|
+
if (options?.logFormat !== undefined) {
|
|
293
|
+
legacy.logFormatter = logFormatterFor(options.logFormat);
|
|
294
|
+
}
|
|
295
|
+
this.destinations[identifier] = dest;
|
|
123
296
|
}
|
|
124
297
|
|
|
298
|
+
/**
|
|
299
|
+
* @deprecated use {@link destinations}
|
|
300
|
+
*/
|
|
125
301
|
public static removeLogger(identifier: string) {
|
|
126
|
-
|
|
127
|
-
if (index === -1) {
|
|
302
|
+
if (!(identifier in this.destinations)) {
|
|
128
303
|
throw new NotImplementedError(`Logger "${identifier}" does not exist`);
|
|
129
304
|
}
|
|
130
|
-
|
|
305
|
+
delete this.destinations[identifier];
|
|
131
306
|
}
|
|
132
307
|
|
|
133
308
|
/**
|
|
134
309
|
* Check if a logger with the matching identifier exists.
|
|
135
310
|
* @param identifier The identifier of the logger
|
|
311
|
+
*
|
|
312
|
+
* @deprecated use {@link destinations}
|
|
136
313
|
*/
|
|
137
314
|
public static hasLoggerForIdentifier(identifier: string) {
|
|
138
|
-
return
|
|
315
|
+
return identifier in this.destinations;
|
|
139
316
|
}
|
|
140
317
|
|
|
141
318
|
/**
|
|
142
319
|
* Get the logger with the matching identifier.
|
|
143
320
|
* @param identifier The identifier of the logger
|
|
321
|
+
*
|
|
322
|
+
* @deprecated use {@link destinations}
|
|
144
323
|
*/
|
|
145
324
|
public static getLoggerForIdentifier(identifier: string) {
|
|
146
|
-
const
|
|
147
|
-
if (
|
|
325
|
+
const dest = this.destinations[identifier];
|
|
326
|
+
if (dest === undefined) {
|
|
148
327
|
throw new NotImplementedError(`Unknown logger "${identifier}"`);
|
|
149
328
|
}
|
|
150
|
-
return
|
|
329
|
+
return adaptDestinationToLegacy(dest);
|
|
151
330
|
}
|
|
152
331
|
|
|
153
332
|
/**
|
|
154
|
-
*
|
|
333
|
+
* @deprecated use {@link destinations}
|
|
155
334
|
*/
|
|
156
|
-
static
|
|
157
|
-
|
|
158
|
-
level = LogLevel.DEBUG;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
let levelNum;
|
|
162
|
-
if (typeof level === "string") {
|
|
163
|
-
if (level.match(/^\d+$/)) {
|
|
164
|
-
levelNum = Number.parseInt(level);
|
|
165
|
-
} else {
|
|
166
|
-
levelNum = (LogLevel as unknown as Record<string, number | undefined>)[level.toUpperCase()];
|
|
167
|
-
if (levelNum === undefined) {
|
|
168
|
-
throw new ImplementationError(`Unsupported log level "${level}"`);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
} else {
|
|
172
|
-
levelNum = level;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
if (LogLevel[levelNum] === undefined) {
|
|
176
|
-
throw new ImplementationError(`Unsupported log level "${level}"`);
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
Logger.defaultLogLevel = levelNum;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Set logFormatter using configuration-style format name.
|
|
184
|
-
*
|
|
185
|
-
* @param format the name of the formatter (see Format enum)
|
|
186
|
-
*/
|
|
187
|
-
static set format(format: string) {
|
|
188
|
-
Logger.setLogFormatterForLogger("default", logFormatterFor(format));
|
|
335
|
+
public static getLoggerforIdentifier(identifier: string) {
|
|
336
|
+
return this.getLoggerForIdentifier(identifier);
|
|
189
337
|
}
|
|
190
338
|
|
|
191
339
|
/**
|
|
192
340
|
* Set facility loglevels for the default logger.
|
|
193
341
|
* @param levels The levels to set
|
|
342
|
+
*
|
|
343
|
+
* @deprecated use {@link destinations}
|
|
194
344
|
*/
|
|
195
345
|
public static set logLevels(levels: { [facility: string]: LogLevel }) {
|
|
196
346
|
Logger.setLogLevelsForLogger("default", levels);
|
|
@@ -198,6 +348,8 @@ export class Logger {
|
|
|
198
348
|
|
|
199
349
|
/**
|
|
200
350
|
* Get facility loglevels for the default logger.
|
|
351
|
+
*
|
|
352
|
+
* @deprecated use {@link Logger.facilityLevels}
|
|
201
353
|
*/
|
|
202
354
|
public static get logLevels() {
|
|
203
355
|
return Logger.getLoggerForIdentifier("default").logLevels;
|
|
@@ -207,6 +359,8 @@ export class Logger {
|
|
|
207
359
|
* Set default loglevel for the default logger.
|
|
208
360
|
*
|
|
209
361
|
* @param level The level to set
|
|
362
|
+
*
|
|
363
|
+
* @deprecated use {@link Logger.level}
|
|
210
364
|
*/
|
|
211
365
|
public static set defaultLogLevel(level: LogLevel) {
|
|
212
366
|
Logger.setDefaultLoglevelForLogger("default", level);
|
|
@@ -214,6 +368,8 @@ export class Logger {
|
|
|
214
368
|
|
|
215
369
|
/**
|
|
216
370
|
* Get default loglevel for the default logger.
|
|
371
|
+
*
|
|
372
|
+
* @deprecated use {@link destinations}
|
|
217
373
|
*/
|
|
218
374
|
public static get defaultLogLevel() {
|
|
219
375
|
return Logger.getLoggerForIdentifier("default").defaultLogLevel;
|
|
@@ -223,6 +379,8 @@ export class Logger {
|
|
|
223
379
|
* Set the log function for the default logger.
|
|
224
380
|
*
|
|
225
381
|
* @param log The log function to set
|
|
382
|
+
*
|
|
383
|
+
* @deprecated use {@link destinations}
|
|
226
384
|
*/
|
|
227
385
|
public static set log(log: (level: LogLevel, formattedLog: string, facility?: string) => void) {
|
|
228
386
|
Logger.setLogger("default", log);
|
|
@@ -230,6 +388,8 @@ export class Logger {
|
|
|
230
388
|
|
|
231
389
|
/**
|
|
232
390
|
* Get the log function for the default logger.
|
|
391
|
+
*
|
|
392
|
+
* @deprecated use {@link destinations}
|
|
233
393
|
*/
|
|
234
394
|
public static get log() {
|
|
235
395
|
return Logger.getLoggerForIdentifier("default").log;
|
|
@@ -239,6 +399,8 @@ export class Logger {
|
|
|
239
399
|
* Set the log formatter for the default logger.
|
|
240
400
|
*
|
|
241
401
|
* @param logFormatter
|
|
402
|
+
*
|
|
403
|
+
* @deprecated use {@link destinations}
|
|
242
404
|
*/
|
|
243
405
|
public static set logFormatter(
|
|
244
406
|
logFormatter: (now: Date, level: LogLevel, facility: string, nestingPrefix: string, values: any[]) => string,
|
|
@@ -248,6 +410,8 @@ export class Logger {
|
|
|
248
410
|
|
|
249
411
|
/**
|
|
250
412
|
* Get the log formatter for the default logger.
|
|
413
|
+
*
|
|
414
|
+
* @deprecated use {@link destinations}
|
|
251
415
|
*/
|
|
252
416
|
public static get logFormatter() {
|
|
253
417
|
return Logger.getLoggerForIdentifier("default").logFormatter;
|
|
@@ -258,14 +422,11 @@ export class Logger {
|
|
|
258
422
|
*
|
|
259
423
|
* @param identifier The identifier of the logger
|
|
260
424
|
* @param format the name of the formatter (see Format enum)
|
|
425
|
+
*
|
|
426
|
+
* @deprecated use {@link destinations}
|
|
261
427
|
*/
|
|
262
428
|
public static setFormatForLogger(identifier: string, format: string) {
|
|
263
|
-
|
|
264
|
-
if (logger) {
|
|
265
|
-
logger.logFormatter = logFormatterFor(format);
|
|
266
|
-
} else {
|
|
267
|
-
throw new NotImplementedError(`Unknown logger "${identifier}"`);
|
|
268
|
-
}
|
|
429
|
+
this.getLoggerForIdentifier(identifier).logFormatter = logFormatterFor(format);
|
|
269
430
|
}
|
|
270
431
|
|
|
271
432
|
/**
|
|
@@ -273,14 +434,11 @@ export class Logger {
|
|
|
273
434
|
*
|
|
274
435
|
* @param identifier The identifier of the logger
|
|
275
436
|
* @param level The level to set
|
|
437
|
+
*
|
|
438
|
+
* @deprecated use {@link destinations}
|
|
276
439
|
*/
|
|
277
440
|
public static setDefaultLoglevelForLogger(identifier: string, level: LogLevel) {
|
|
278
|
-
|
|
279
|
-
if (logger) {
|
|
280
|
-
logger.defaultLogLevel = level;
|
|
281
|
-
} else {
|
|
282
|
-
throw new NotImplementedError(`Unknown logger "${identifier}"`);
|
|
283
|
-
}
|
|
441
|
+
this.getLoggerForIdentifier(identifier).defaultLogLevel = level;
|
|
284
442
|
}
|
|
285
443
|
|
|
286
444
|
/**
|
|
@@ -288,14 +446,11 @@ export class Logger {
|
|
|
288
446
|
*
|
|
289
447
|
* @param identifier The identifier of the logger
|
|
290
448
|
* @param levels The levels to set
|
|
449
|
+
*
|
|
450
|
+
* @deprecated use {@link destinations}
|
|
291
451
|
*/
|
|
292
452
|
public static setLogLevelsForLogger(identifier: string, levels: { [facility: string]: LogLevel }) {
|
|
293
|
-
|
|
294
|
-
if (logger) {
|
|
295
|
-
logger.logLevels = levels;
|
|
296
|
-
} else {
|
|
297
|
-
throw new NotImplementedError(`Unknown logger "${identifier}"`);
|
|
298
|
-
}
|
|
453
|
+
this.getLoggerForIdentifier(identifier).logLevels = levels;
|
|
299
454
|
}
|
|
300
455
|
|
|
301
456
|
/**
|
|
@@ -303,17 +458,14 @@ export class Logger {
|
|
|
303
458
|
*
|
|
304
459
|
* @param identifier The identifier of the logger
|
|
305
460
|
* @param log The log function to set
|
|
461
|
+
*
|
|
462
|
+
* @deprecated use {@link destinations}
|
|
306
463
|
*/
|
|
307
464
|
public static setLogger(
|
|
308
465
|
identifier: string,
|
|
309
466
|
log: (level: LogLevel, formattedLog: string, facility?: string) => void,
|
|
310
467
|
) {
|
|
311
|
-
|
|
312
|
-
if (logger) {
|
|
313
|
-
logger.log = log;
|
|
314
|
-
} else {
|
|
315
|
-
throw new NotImplementedError(`Unknown logger "${identifier}"`);
|
|
316
|
-
}
|
|
468
|
+
this.getLoggerForIdentifier(identifier).log = log;
|
|
317
469
|
}
|
|
318
470
|
|
|
319
471
|
/**
|
|
@@ -321,168 +473,14 @@ export class Logger {
|
|
|
321
473
|
*
|
|
322
474
|
* @param identifier The identifier of the logger
|
|
323
475
|
* @param logFormatter The log formatter to set
|
|
476
|
+
*
|
|
477
|
+
* @deprecated use {@link destinations}
|
|
324
478
|
*/
|
|
325
479
|
static setLogFormatterForLogger(
|
|
326
480
|
identifier: string,
|
|
327
481
|
logFormatter: (now: Date, level: LogLevel, facility: string, nestingPrefix: string, values: any[]) => string,
|
|
328
482
|
) {
|
|
329
|
-
|
|
330
|
-
if (logger) {
|
|
331
|
-
logger.logFormatter = logFormatter;
|
|
332
|
-
} else {
|
|
333
|
-
throw new NotImplementedError(`Unknown logger "${identifier}"`);
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
/**
|
|
338
|
-
* Create a new facility.
|
|
339
|
-
*
|
|
340
|
-
* @param name the name of the facility
|
|
341
|
-
* @returns a new facility
|
|
342
|
-
*/
|
|
343
|
-
static get(name: string) {
|
|
344
|
-
return new Logger(name);
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
/**
|
|
348
|
-
* Stringify a value (BigInt aware) as JSON.
|
|
349
|
-
*
|
|
350
|
-
* @param data the value to stringify
|
|
351
|
-
* @returns the stringified value
|
|
352
|
-
*/
|
|
353
|
-
static toJSON(data: any) {
|
|
354
|
-
return JSON.stringify(data, (_, value) => {
|
|
355
|
-
if (typeof value === "bigint") {
|
|
356
|
-
return value.toString();
|
|
357
|
-
}
|
|
358
|
-
if (value instanceof Uint8Array) {
|
|
359
|
-
return Bytes.toHex(value);
|
|
360
|
-
}
|
|
361
|
-
if (value === undefined) {
|
|
362
|
-
return "undefined";
|
|
363
|
-
}
|
|
364
|
-
return value;
|
|
365
|
-
});
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
/**
|
|
369
|
-
* Mask a string with a given character. If unmaskedLength is provided then these number of characters will be
|
|
370
|
-
* shown unmasked.
|
|
371
|
-
*
|
|
372
|
-
* @param str String to mask
|
|
373
|
-
* @param maskChar character to mask with
|
|
374
|
-
* @param unmaskedLength number of characters to show unmasked in the beginning
|
|
375
|
-
*/
|
|
376
|
-
static maskString(str: string, maskChar = "*", unmaskedLength?: number) {
|
|
377
|
-
return str.substring(0, unmaskedLength ?? 0) + str.substring(unmaskedLength ?? 0).replace(/./g, maskChar);
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
/**
|
|
381
|
-
* Perform operations in a nested logging context. Messages will be
|
|
382
|
-
* indented while the context executes.
|
|
383
|
-
*/
|
|
384
|
-
static nest<T>(context: () => T): T {
|
|
385
|
-
this.nestingLevel++;
|
|
386
|
-
try {
|
|
387
|
-
return context();
|
|
388
|
-
} finally {
|
|
389
|
-
this.nestingLevel--;
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
/**
|
|
394
|
-
* Async version of nest().
|
|
395
|
-
*/
|
|
396
|
-
static async nestAsync(context: () => Promise<any>) {
|
|
397
|
-
this.nestingLevel++;
|
|
398
|
-
try {
|
|
399
|
-
return await context();
|
|
400
|
-
} finally {
|
|
401
|
-
this.nestingLevel--;
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
/**
|
|
406
|
-
* Unhandled error reporter.
|
|
407
|
-
*
|
|
408
|
-
* Some environments do not report full error details such as {@link Error#cause} and {@link AggregateError#errors}.
|
|
409
|
-
*
|
|
410
|
-
* To ensure these details are always recorded somewhere, unhandled errors may be reported here.
|
|
411
|
-
*
|
|
412
|
-
* To disable this behavior replace this function.
|
|
413
|
-
*/
|
|
414
|
-
static reportUnhandledError(error: Error) {
|
|
415
|
-
try {
|
|
416
|
-
Logger.get("Logger").fatal("Unhandled error detected:", error);
|
|
417
|
-
} catch (e) {
|
|
418
|
-
// We do not want to cause yet another error so if logging fails for any reason it goes unreported
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
/**
|
|
423
|
-
* Invoke logic and return any log messages produced.
|
|
424
|
-
*/
|
|
425
|
-
static capture(fn: () => void, fromLogger = "default") {
|
|
426
|
-
if (!Logger) {
|
|
427
|
-
throw new Error("No logger loaded, cannot capture logs");
|
|
428
|
-
}
|
|
429
|
-
const logger = Logger.getLoggerForIdentifier(fromLogger);
|
|
430
|
-
const actualLogSettings = {
|
|
431
|
-
logFormatter: logger.logFormatter,
|
|
432
|
-
log: logger.log,
|
|
433
|
-
defaultLogLevel: logger.defaultLogLevel,
|
|
434
|
-
logLevels: { ...logger.logLevels },
|
|
435
|
-
};
|
|
436
|
-
|
|
437
|
-
try {
|
|
438
|
-
Logger.setFormatForLogger(fromLogger, LogFormat.PLAIN);
|
|
439
|
-
const captured = new Array<{ level: LogLevel; message: string }>();
|
|
440
|
-
Logger.setLogger(fromLogger, (level, message) =>
|
|
441
|
-
captured.push({
|
|
442
|
-
level,
|
|
443
|
-
message: message.replace(/\d{4}-\d\d-\d\d \d\d:\d\d:\d\d\.\d\d\d/, "xxxx-xx-xx xx:xx:xx.xxx"),
|
|
444
|
-
}),
|
|
445
|
-
);
|
|
446
|
-
fn();
|
|
447
|
-
return captured;
|
|
448
|
-
} finally {
|
|
449
|
-
Logger.setLogFormatterForLogger(fromLogger, actualLogSettings.logFormatter);
|
|
450
|
-
Logger.setDefaultLoglevelForLogger(fromLogger, actualLogSettings.defaultLogLevel);
|
|
451
|
-
Logger.setLogLevelsForLogger(fromLogger, actualLogSettings.logLevels);
|
|
452
|
-
Logger.setLogger(fromLogger, actualLogSettings.log);
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
constructor(name: string) {
|
|
457
|
-
this.#name = name;
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
debug = (...values: any[]) => this.#log(LogLevel.DEBUG, values);
|
|
461
|
-
info = (...values: any[]) => this.#log(LogLevel.INFO, values);
|
|
462
|
-
notice = (...values: any[]) => this.#log(LogLevel.NOTICE, values);
|
|
463
|
-
warn = (...values: any[]) => this.#log(LogLevel.WARN, values);
|
|
464
|
-
error = (...values: any[]) => this.#log(LogLevel.ERROR, values);
|
|
465
|
-
fatal = (...values: any[]) => this.#log(LogLevel.FATAL, values);
|
|
466
|
-
log = (level: LogLevel, ...values: any[]) => this.#log(level, values);
|
|
467
|
-
|
|
468
|
-
#log(level: LogLevel, values: any[]) {
|
|
469
|
-
for (const logger of Logger.logger) {
|
|
470
|
-
if (level < (logger.logLevels[this.#name] ?? logger.defaultLogLevel)) {
|
|
471
|
-
return;
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
if (!logger.context) {
|
|
475
|
-
logger.context = Diagnostic.Context();
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
logger.context.run(() =>
|
|
479
|
-
logger.log(
|
|
480
|
-
level,
|
|
481
|
-
logger.logFormatter(Time.now(), level, this.#name, nestingPrefix(), values),
|
|
482
|
-
this.#name,
|
|
483
|
-
),
|
|
484
|
-
);
|
|
485
|
-
}
|
|
483
|
+
this.getLoggerForIdentifier(identifier).logFormatter = logFormatter;
|
|
486
484
|
}
|
|
487
485
|
}
|
|
488
486
|
|
|
@@ -494,13 +492,7 @@ function nestingPrefix() {
|
|
|
494
492
|
}
|
|
495
493
|
|
|
496
494
|
Boot.init(() => {
|
|
497
|
-
Logger.
|
|
498
|
-
logIdentifier: "default",
|
|
499
|
-
logFormatter: LogFormat.plain,
|
|
500
|
-
log: consoleLogger,
|
|
501
|
-
defaultLogLevel: LogLevel.DEBUG,
|
|
502
|
-
logLevels: {},
|
|
503
|
-
});
|
|
495
|
+
Logger.destinations = LogDestinations();
|
|
504
496
|
Logger.nestingLevel = 0;
|
|
505
497
|
|
|
506
498
|
// Hook for testing frameworks
|
|
@@ -510,3 +502,76 @@ Boot.init(() => {
|
|
|
510
502
|
});
|
|
511
503
|
|
|
512
504
|
CancelablePromise.logger = Logger.get("CancelablePromise");
|
|
505
|
+
|
|
506
|
+
/**
|
|
507
|
+
* Create a log formatter for a given format.
|
|
508
|
+
*
|
|
509
|
+
* @deprecated
|
|
510
|
+
*/
|
|
511
|
+
function logFormatterFor(formatName: string): LoggerDefinition["logFormatter"] {
|
|
512
|
+
const format = LogFormat(formatName);
|
|
513
|
+
|
|
514
|
+
return (now, level, facility, prefix, ...values) =>
|
|
515
|
+
format(Diagnostic.message({ now, level, facility, prefix, values }));
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* Definition of one registered Logger.
|
|
520
|
+
*
|
|
521
|
+
* @deprecated
|
|
522
|
+
*/
|
|
523
|
+
type LoggerDefinition = {
|
|
524
|
+
logIdentifier: string;
|
|
525
|
+
logFormatter: (now: Date, level: LogLevel, facility: string, prefix: string, values: any[]) => string;
|
|
526
|
+
log: (level: LogLevel, formattedLog: string, facility?: string) => void;
|
|
527
|
+
defaultLogLevel: LogLevel;
|
|
528
|
+
logLevels: { [facility: string]: LogLevel };
|
|
529
|
+
context?: Diagnostic.Context;
|
|
530
|
+
};
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* @deprecated
|
|
534
|
+
*/
|
|
535
|
+
function adaptDestinationToLegacy(destination: LogDestination): LoggerDefinition {
|
|
536
|
+
return {
|
|
537
|
+
get logIdentifier() {
|
|
538
|
+
return destination.name;
|
|
539
|
+
},
|
|
540
|
+
|
|
541
|
+
get logFormatter() {
|
|
542
|
+
return (now: Date, level: LogLevel, facility: string, prefix: string, values: any[]) =>
|
|
543
|
+
destination.format(Diagnostic.message({ now, level, facility, prefix, values }));
|
|
544
|
+
},
|
|
545
|
+
|
|
546
|
+
set logFormatter(logFormatter: LoggerDefinition["logFormatter"]) {
|
|
547
|
+
destination.format = (message: Diagnostic.Message) =>
|
|
548
|
+
logFormatter(message.now, message.level, message.facility, message.prefix, message.values);
|
|
549
|
+
},
|
|
550
|
+
|
|
551
|
+
get log() {
|
|
552
|
+
return (level: LogLevel, formattedLog: string, facility?: string) =>
|
|
553
|
+
destination.write(formattedLog, Diagnostic.message({ level, facility }));
|
|
554
|
+
},
|
|
555
|
+
|
|
556
|
+
set log(log: LoggerDefinition["log"]) {
|
|
557
|
+
destination.write = (text: string, message: Diagnostic.Message) =>
|
|
558
|
+
log(message.level, text, message.facility);
|
|
559
|
+
},
|
|
560
|
+
|
|
561
|
+
get defaultLogLevel() {
|
|
562
|
+
return destination.level;
|
|
563
|
+
},
|
|
564
|
+
|
|
565
|
+
set defaultLogLevel(level: LogLevel) {
|
|
566
|
+
destination.level = level;
|
|
567
|
+
},
|
|
568
|
+
|
|
569
|
+
get logLevels() {
|
|
570
|
+
return destination.facilityLevels;
|
|
571
|
+
},
|
|
572
|
+
|
|
573
|
+
set logLevels(levels: Record<string, LogLevel>) {
|
|
574
|
+
destination.facilityLevels = levels;
|
|
575
|
+
},
|
|
576
|
+
};
|
|
577
|
+
}
|