@dxos/log 0.6.12 → 0.6.13-main.548ca8d
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/lib/browser/index.mjs +16 -4
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node/index.cjs +17 -4
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +622 -0
- package/dist/lib/node-esm/index.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -0
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/log.d.ts +4 -0
- package/dist/types/src/log.d.ts.map +1 -1
- package/dist/types/src/processors/browser-processor.d.ts.map +1 -1
- package/package.json +6 -9
- package/src/experimental/classes.test.ts +1 -1
- package/src/index.ts +0 -1
- package/src/log.test.ts +2 -3
- package/src/log.ts +18 -0
- package/src/processors/browser-processor.ts +4 -10
- package/src/scope.test.ts +1 -1
|
@@ -0,0 +1,622 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
|
|
2
|
+
|
|
3
|
+
// packages/common/log/src/index.ts
|
|
4
|
+
import omit from "lodash.omit";
|
|
5
|
+
import { pick } from "@dxos/util";
|
|
6
|
+
|
|
7
|
+
// packages/common/log/src/config.ts
|
|
8
|
+
var LogLevel;
|
|
9
|
+
(function(LogLevel2) {
|
|
10
|
+
LogLevel2[LogLevel2["TRACE"] = 5] = "TRACE";
|
|
11
|
+
LogLevel2[LogLevel2["DEBUG"] = 10] = "DEBUG";
|
|
12
|
+
LogLevel2[LogLevel2["INFO"] = 11] = "INFO";
|
|
13
|
+
LogLevel2[LogLevel2["WARN"] = 12] = "WARN";
|
|
14
|
+
LogLevel2[LogLevel2["ERROR"] = 13] = "ERROR";
|
|
15
|
+
})(LogLevel || (LogLevel = {}));
|
|
16
|
+
var levels = {
|
|
17
|
+
trace: 5,
|
|
18
|
+
debug: 10,
|
|
19
|
+
info: 11,
|
|
20
|
+
warn: 12,
|
|
21
|
+
error: 13
|
|
22
|
+
};
|
|
23
|
+
var shortLevelName = {
|
|
24
|
+
[5]: "T",
|
|
25
|
+
[10]: "D",
|
|
26
|
+
[11]: "I",
|
|
27
|
+
[12]: "W",
|
|
28
|
+
[13]: "E"
|
|
29
|
+
};
|
|
30
|
+
var LogProcessorType;
|
|
31
|
+
(function(LogProcessorType2) {
|
|
32
|
+
LogProcessorType2["CONSOLE"] = "console";
|
|
33
|
+
LogProcessorType2["BROWSER"] = "browser";
|
|
34
|
+
LogProcessorType2["DEBUG"] = "debug";
|
|
35
|
+
})(LogProcessorType || (LogProcessorType = {}));
|
|
36
|
+
|
|
37
|
+
// packages/common/log/src/scope.ts
|
|
38
|
+
var logInfoProperties = Symbol("logInfoProperties");
|
|
39
|
+
var logInfo = (target, propertyKey, descriptor) => {
|
|
40
|
+
(target[logInfoProperties] ??= []).push(propertyKey);
|
|
41
|
+
};
|
|
42
|
+
var gatherLogInfoFromScope = (scope) => {
|
|
43
|
+
if (!scope) {
|
|
44
|
+
return {};
|
|
45
|
+
}
|
|
46
|
+
const res = {};
|
|
47
|
+
const prototype = Object.getPrototypeOf(scope);
|
|
48
|
+
const infoProps = prototype[logInfoProperties] ?? [];
|
|
49
|
+
for (const prop of infoProps) {
|
|
50
|
+
try {
|
|
51
|
+
res[prop] = typeof scope[prop] === "function" ? scope[prop]() : scope[prop];
|
|
52
|
+
} catch (err) {
|
|
53
|
+
res[prop] = err.message;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return res;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// packages/common/log/src/context.ts
|
|
60
|
+
var matchFilter = (filter, level, path) => {
|
|
61
|
+
return level >= filter.level && (!filter.pattern || path.includes(filter.pattern));
|
|
62
|
+
};
|
|
63
|
+
var shouldLog = (entry, filters) => {
|
|
64
|
+
if (filters === void 0) {
|
|
65
|
+
return true;
|
|
66
|
+
} else {
|
|
67
|
+
return filters.some((filter) => matchFilter(filter, entry.level, entry.meta?.F ?? ""));
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
var getContextFromEntry = (entry) => {
|
|
71
|
+
let context;
|
|
72
|
+
if (entry.meta) {
|
|
73
|
+
const scopeInfo = gatherLogInfoFromScope(entry.meta.S);
|
|
74
|
+
if (Object.keys(scopeInfo).length > 0) {
|
|
75
|
+
context = Object.assign(context ?? {}, scopeInfo);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const entryContext = typeof entry.context === "function" ? entry.context() : entry.context;
|
|
79
|
+
if (entryContext) {
|
|
80
|
+
if (entryContext instanceof Error) {
|
|
81
|
+
const c = entryContext.context;
|
|
82
|
+
context = Object.assign(context ?? {}, {
|
|
83
|
+
error: entryContext.stack,
|
|
84
|
+
...c
|
|
85
|
+
});
|
|
86
|
+
} else if (typeof entryContext === "object") {
|
|
87
|
+
context = Object.assign(context ?? {}, entryContext);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (entry.error) {
|
|
91
|
+
const errorContext = entry.error.context;
|
|
92
|
+
context = Object.assign(context ?? {}, {
|
|
93
|
+
error: entry.error,
|
|
94
|
+
...errorContext
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
return context && Object.keys(context).length > 0 ? context : void 0;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
// packages/common/log/src/decorators.ts
|
|
101
|
+
import chalk from "chalk";
|
|
102
|
+
import { inspect } from "node:util";
|
|
103
|
+
var nextPromiseId = 0;
|
|
104
|
+
var createMethodLogDecorator = (log2) => (arg0, arg1, meta) => (target, propertyKey, descriptor) => {
|
|
105
|
+
const method = descriptor.value;
|
|
106
|
+
const methodName = propertyKey;
|
|
107
|
+
descriptor.value = function(...args) {
|
|
108
|
+
const combinedMeta = {
|
|
109
|
+
F: "",
|
|
110
|
+
L: 0,
|
|
111
|
+
...meta ?? {},
|
|
112
|
+
S: this
|
|
113
|
+
};
|
|
114
|
+
const formattedArgs = args.map((arg) => inspect(arg, false, 1, true)).join(", ");
|
|
115
|
+
try {
|
|
116
|
+
const startTime = performance.now();
|
|
117
|
+
const result = method.apply(this, args);
|
|
118
|
+
if (isThenable(result)) {
|
|
119
|
+
const id = nextPromiseId++;
|
|
120
|
+
logAsyncBegin(log2, methodName, formattedArgs, id, combinedMeta);
|
|
121
|
+
result.then((resolvedValue) => {
|
|
122
|
+
logAsyncResolved(log2, methodName, resolvedValue, id, startTime, combinedMeta);
|
|
123
|
+
}, (err) => {
|
|
124
|
+
logAsyncRejected(log2, methodName, err, id, startTime, combinedMeta);
|
|
125
|
+
});
|
|
126
|
+
} else {
|
|
127
|
+
logSyncCall(log2, methodName, formattedArgs, result, combinedMeta);
|
|
128
|
+
}
|
|
129
|
+
return result;
|
|
130
|
+
} catch (err) {
|
|
131
|
+
logSyncError(log2, methodName, formattedArgs, err, combinedMeta);
|
|
132
|
+
throw err;
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
Object.defineProperty(descriptor.value, "name", {
|
|
136
|
+
value: methodName + "$log"
|
|
137
|
+
});
|
|
138
|
+
};
|
|
139
|
+
var isThenable = (obj) => obj && typeof obj.then === "function";
|
|
140
|
+
var logSyncCall = (log2, methodName, formattedArgs, result, combinedMeta) => {
|
|
141
|
+
log2.info(`.${formatFunction(methodName)} (${formattedArgs}) ${chalk.gray("=>")} ${inspect(result, false, 1, true)}`, {}, combinedMeta);
|
|
142
|
+
};
|
|
143
|
+
var logSyncError = (log2, methodName, formattedArgs, err, combinedMeta) => {
|
|
144
|
+
log2.error(`.${formatFunction(methodName)} (${formattedArgs}) \u{1F525} ${err}`, {}, combinedMeta);
|
|
145
|
+
};
|
|
146
|
+
var logAsyncBegin = (log2, methodName, formattedArgs, promiseId, combinedMeta) => {
|
|
147
|
+
log2.info(`.${formatFunction(methodName)} \u21B4 (${formattedArgs}) ${chalk.gray("=>")} ${formatPromise(promiseId)}`, {}, combinedMeta);
|
|
148
|
+
};
|
|
149
|
+
var logAsyncResolved = (log2, methodName, resolvedValue, promiseId, startTime, combinedMeta) => {
|
|
150
|
+
if (resolvedValue !== void 0) {
|
|
151
|
+
log2.info(`.${formatFunction(methodName)} \u21B2 ${greenCheck} ${chalk.gray("resolve")} ${formatPromise(promiseId)} ${formatTimeElapsed(startTime)} ${chalk.gray("=>")} ${inspect(resolvedValue, false, 1, true)}`, {}, combinedMeta);
|
|
152
|
+
} else {
|
|
153
|
+
log2.info(`.${formatFunction(methodName)} \u21B2 ${greenCheck} ${chalk.gray("resolve")} ${formatPromise(promiseId)} ${formatTimeElapsed(startTime)}`, {}, combinedMeta);
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
var logAsyncRejected = (log2, methodName, err, promiseId, startTime, combinedMeta) => {
|
|
157
|
+
log2.info(`.${formatFunction(methodName)} \u21B2 \u{1F525} ${chalk.gray("reject")} ${formatPromise(promiseId)} ${formatTimeElapsed(startTime)} ${chalk.gray("=>")} ${err}`, {}, combinedMeta);
|
|
158
|
+
};
|
|
159
|
+
var greenCheck = typeof chalk.green === "function" ? chalk.green("\u2714") : "\u2714";
|
|
160
|
+
var formatTimeElapsed = (startTime) => chalk.gray(`${(performance.now() - startTime).toFixed(0)}ms`);
|
|
161
|
+
var COLOR_FUNCTION = [
|
|
162
|
+
220,
|
|
163
|
+
220,
|
|
164
|
+
170
|
|
165
|
+
];
|
|
166
|
+
var formatFunction = (name) => chalk.bold(chalk.rgb(...COLOR_FUNCTION)(name));
|
|
167
|
+
var formatPromise = (id) => chalk.blue(`Promise#${id}`);
|
|
168
|
+
|
|
169
|
+
// packages/common/log/src/options.ts
|
|
170
|
+
import defaultsDeep from "lodash.defaultsdeep";
|
|
171
|
+
|
|
172
|
+
// packages/common/log/src/platform/node/index.ts
|
|
173
|
+
import yaml from "js-yaml";
|
|
174
|
+
import fs from "node:fs";
|
|
175
|
+
var loadOptions = (filepath) => {
|
|
176
|
+
if (filepath) {
|
|
177
|
+
try {
|
|
178
|
+
const text = fs.readFileSync(filepath, "utf-8");
|
|
179
|
+
if (text) {
|
|
180
|
+
return yaml.load(text);
|
|
181
|
+
}
|
|
182
|
+
} catch (err) {
|
|
183
|
+
console.warn(`Invalid log file: ${filepath}`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
// packages/common/log/src/processors/console-processor.ts
|
|
189
|
+
import chalk2 from "chalk";
|
|
190
|
+
import { inspect as inspect2 } from "node:util";
|
|
191
|
+
import { getPrototypeSpecificInstanceId, pickBy } from "@dxos/util";
|
|
192
|
+
|
|
193
|
+
// packages/common/log/src/processors/common.ts
|
|
194
|
+
var getRelativeFilename = (filename) => {
|
|
195
|
+
const match = filename.match(/.+\/(packages\/.+\/.+)/);
|
|
196
|
+
if (match) {
|
|
197
|
+
const [, filePath] = match;
|
|
198
|
+
return filePath;
|
|
199
|
+
}
|
|
200
|
+
return filename;
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
// packages/common/log/src/processors/console-processor.ts
|
|
204
|
+
var LEVEL_COLORS = {
|
|
205
|
+
[LogLevel.TRACE]: "gray",
|
|
206
|
+
[LogLevel.DEBUG]: "gray",
|
|
207
|
+
[LogLevel.INFO]: "white",
|
|
208
|
+
[LogLevel.WARN]: "yellow",
|
|
209
|
+
[LogLevel.ERROR]: "red"
|
|
210
|
+
};
|
|
211
|
+
var truncate = (text, length = 0, right = false) => {
|
|
212
|
+
const str = text && length ? right ? text.slice(-length) : text.substring(0, length) : text ?? "";
|
|
213
|
+
return right ? str.padStart(length, " ") : str.padEnd(length, " ");
|
|
214
|
+
};
|
|
215
|
+
var DEFAULT_FORMATTER = (config, { path, line, level, message, context, error, scope }) => {
|
|
216
|
+
const column = config.options?.formatter?.column;
|
|
217
|
+
const filepath = path !== void 0 && line !== void 0 ? chalk2.grey(`${path}:${line}`) : void 0;
|
|
218
|
+
let instance;
|
|
219
|
+
if (scope) {
|
|
220
|
+
const prototype = Object.getPrototypeOf(scope);
|
|
221
|
+
const id = getPrototypeSpecificInstanceId(scope);
|
|
222
|
+
instance = chalk2.magentaBright(`${prototype.constructor.name}#${id}`);
|
|
223
|
+
}
|
|
224
|
+
const formattedTimestamp = config.options?.formatter?.timestamp ? (/* @__PURE__ */ new Date()).toISOString() : void 0;
|
|
225
|
+
const formattedLevel = chalk2[LEVEL_COLORS[level]](column ? shortLevelName[level] : LogLevel[level]);
|
|
226
|
+
const padding = column && filepath ? "".padStart(column - filepath.length) : void 0;
|
|
227
|
+
return config.options?.formatter?.timestampFirst ? [
|
|
228
|
+
formattedTimestamp,
|
|
229
|
+
filepath,
|
|
230
|
+
padding,
|
|
231
|
+
formattedLevel,
|
|
232
|
+
instance,
|
|
233
|
+
message,
|
|
234
|
+
context,
|
|
235
|
+
error
|
|
236
|
+
] : [
|
|
237
|
+
// NOTE: File path must come fist for console hyperlinks.
|
|
238
|
+
// Must not truncate for terminal output.
|
|
239
|
+
filepath,
|
|
240
|
+
padding,
|
|
241
|
+
formattedTimestamp,
|
|
242
|
+
formattedLevel,
|
|
243
|
+
instance,
|
|
244
|
+
message,
|
|
245
|
+
context,
|
|
246
|
+
error
|
|
247
|
+
];
|
|
248
|
+
};
|
|
249
|
+
var SHORT_FORMATTER = (config, { path, level, message }) => {
|
|
250
|
+
return [
|
|
251
|
+
chalk2.grey(truncate(path, 16, true)),
|
|
252
|
+
chalk2[LEVEL_COLORS[level]](shortLevelName[level]),
|
|
253
|
+
message
|
|
254
|
+
];
|
|
255
|
+
};
|
|
256
|
+
var formatter = DEFAULT_FORMATTER;
|
|
257
|
+
var CONSOLE_PROCESSOR = (config, entry) => {
|
|
258
|
+
const { level, message, meta, error } = entry;
|
|
259
|
+
if (!shouldLog(entry, config.filters)) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
const parts = {
|
|
263
|
+
level,
|
|
264
|
+
message,
|
|
265
|
+
error,
|
|
266
|
+
path: void 0,
|
|
267
|
+
line: void 0,
|
|
268
|
+
scope: void 0,
|
|
269
|
+
context: void 0
|
|
270
|
+
};
|
|
271
|
+
if (meta) {
|
|
272
|
+
parts.path = getRelativeFilename(meta.F);
|
|
273
|
+
parts.line = meta.L;
|
|
274
|
+
parts.scope = meta.S;
|
|
275
|
+
}
|
|
276
|
+
const context = getContextFromEntry(entry);
|
|
277
|
+
if (context) {
|
|
278
|
+
parts.context = inspect2(pickBy(context, (value) => value !== void 0), {
|
|
279
|
+
depth: config.options.depth,
|
|
280
|
+
colors: true,
|
|
281
|
+
maxArrayLength: 8,
|
|
282
|
+
sorted: false
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
const line = formatter(config, parts).filter(Boolean).join(" ");
|
|
286
|
+
console.log(line);
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
// packages/common/log/src/processors/debug-processor.ts
|
|
290
|
+
import { inspect as inspect3 } from "node:util";
|
|
291
|
+
var DEBUG_PROCESSOR = (config, entry) => {
|
|
292
|
+
console.log(inspect3(entry, false, null, true));
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
// packages/common/log/src/processors/browser-processor.ts
|
|
296
|
+
import { getDebugName, safariCheck } from "@dxos/util";
|
|
297
|
+
var getRelativeFilename2 = (filename) => {
|
|
298
|
+
const match = filename.match(/.+\/(packages\/.+\/.+)/);
|
|
299
|
+
if (match) {
|
|
300
|
+
const [, filePath] = match;
|
|
301
|
+
return filePath;
|
|
302
|
+
}
|
|
303
|
+
return filename;
|
|
304
|
+
};
|
|
305
|
+
var CONFIG = {
|
|
306
|
+
useTestProcessor: false,
|
|
307
|
+
printFileLinks: false
|
|
308
|
+
};
|
|
309
|
+
var APP_BROWSER_PROCESSOR = (config, entry) => {
|
|
310
|
+
if (!shouldLog(entry, config.filters)) {
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
const LOG_BROWSER_PREFIX = config.prefix ?? "https://vscode.dev/github.com/dxos/dxos/blob/main/";
|
|
314
|
+
const LOG_BROWSER_CSS = [];
|
|
315
|
+
let link = "";
|
|
316
|
+
if (entry.meta) {
|
|
317
|
+
const filename = getRelativeFilename2(entry.meta.F);
|
|
318
|
+
const filepath = `${LOG_BROWSER_PREFIX.replace(/\/$/, "")}/${filename}`;
|
|
319
|
+
link = `${filepath}#L${entry.meta.L}`;
|
|
320
|
+
}
|
|
321
|
+
let args = [];
|
|
322
|
+
if (entry.meta?.S) {
|
|
323
|
+
const scope = entry.meta?.S;
|
|
324
|
+
const scopeName = scope.name || getDebugName(scope);
|
|
325
|
+
const processPrefix = entry.meta.S?.hostSessionId ? "[worker] " : "";
|
|
326
|
+
args.push(`%c${processPrefix}${scopeName}`, "color:#C026D3;font-weight:bold");
|
|
327
|
+
}
|
|
328
|
+
args.push(entry.message);
|
|
329
|
+
const context = getContextFromEntry(entry);
|
|
330
|
+
if (context) {
|
|
331
|
+
args.push(context);
|
|
332
|
+
}
|
|
333
|
+
const levels2 = {
|
|
334
|
+
[LogLevel.ERROR]: console.error.bind(console),
|
|
335
|
+
[LogLevel.WARN]: console.warn.bind(console),
|
|
336
|
+
[LogLevel.DEBUG]: console.log.bind(console)
|
|
337
|
+
};
|
|
338
|
+
if (CONFIG.printFileLinks || safariCheck()) {
|
|
339
|
+
if (LOG_BROWSER_CSS?.length) {
|
|
340
|
+
args = [
|
|
341
|
+
`%c${link}
|
|
342
|
+
%c${args.join(" ")}`,
|
|
343
|
+
...LOG_BROWSER_CSS
|
|
344
|
+
];
|
|
345
|
+
} else {
|
|
346
|
+
args = [
|
|
347
|
+
link + "\n",
|
|
348
|
+
...args
|
|
349
|
+
];
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
const level = levels2[entry.level] ?? console.log.bind(console);
|
|
353
|
+
if (typeof entry.meta?.C === "function") {
|
|
354
|
+
entry.meta.C(level, args);
|
|
355
|
+
} else {
|
|
356
|
+
level(...args);
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
var TEST_BROWSER_PROCESSOR = (config, entry) => {
|
|
360
|
+
if (!shouldLog(entry, config.filters)) {
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
let path = "";
|
|
364
|
+
if (entry.meta) {
|
|
365
|
+
path = `${getRelativeFilename2(entry.meta.F)}:${entry.meta.L}`;
|
|
366
|
+
}
|
|
367
|
+
let args = [];
|
|
368
|
+
const processPrefix = entry.meta?.S?.hostSessionId ? "[worker] " : "";
|
|
369
|
+
args.push(`${processPrefix}${entry.message}`);
|
|
370
|
+
const context = getContextFromEntry(entry);
|
|
371
|
+
if (context) {
|
|
372
|
+
args.push(context);
|
|
373
|
+
}
|
|
374
|
+
const levels2 = {
|
|
375
|
+
[LogLevel.ERROR]: console.error,
|
|
376
|
+
[LogLevel.WARN]: console.warn,
|
|
377
|
+
[LogLevel.DEBUG]: console.log
|
|
378
|
+
};
|
|
379
|
+
if (CONFIG.printFileLinks) {
|
|
380
|
+
args = [
|
|
381
|
+
path,
|
|
382
|
+
...args
|
|
383
|
+
];
|
|
384
|
+
}
|
|
385
|
+
const level = levels2[entry.level] ?? console.log;
|
|
386
|
+
if (typeof entry.meta?.C === "function") {
|
|
387
|
+
entry.meta.C(level, args);
|
|
388
|
+
} else {
|
|
389
|
+
level(...args);
|
|
390
|
+
}
|
|
391
|
+
};
|
|
392
|
+
var BROWSER_PROCESSOR = CONFIG.useTestProcessor ? TEST_BROWSER_PROCESSOR : APP_BROWSER_PROCESSOR;
|
|
393
|
+
|
|
394
|
+
// packages/common/log/src/processors/file-processor.ts
|
|
395
|
+
import { appendFileSync, mkdirSync, openSync } from "node:fs";
|
|
396
|
+
import { dirname } from "node:path";
|
|
397
|
+
import { jsonlogify } from "@dxos/util";
|
|
398
|
+
var EAGAIN_MAX_DURATION = 1e3;
|
|
399
|
+
var createFileProcessor = ({ pathOrFd, levels: levels2, filters }) => {
|
|
400
|
+
let fd;
|
|
401
|
+
return (config, entry) => {
|
|
402
|
+
if (levels2.length > 0 && !levels2.includes(entry.level)) {
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
if (!shouldLog(entry, filters)) {
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
if (typeof pathOrFd === "number") {
|
|
409
|
+
fd = pathOrFd;
|
|
410
|
+
} else {
|
|
411
|
+
try {
|
|
412
|
+
mkdirSync(dirname(pathOrFd));
|
|
413
|
+
} catch {
|
|
414
|
+
}
|
|
415
|
+
fd = openSync(pathOrFd, "a");
|
|
416
|
+
}
|
|
417
|
+
const record = {
|
|
418
|
+
...entry,
|
|
419
|
+
timestamp: Date.now(),
|
|
420
|
+
...entry.meta ? {
|
|
421
|
+
meta: {
|
|
422
|
+
file: getRelativeFilename(entry.meta.F),
|
|
423
|
+
line: entry.meta.L
|
|
424
|
+
}
|
|
425
|
+
} : {},
|
|
426
|
+
context: jsonlogify(getContextFromEntry(entry))
|
|
427
|
+
};
|
|
428
|
+
let retryTS = 0;
|
|
429
|
+
while (true) {
|
|
430
|
+
try {
|
|
431
|
+
return appendFileSync(fd, JSON.stringify(record) + "\n");
|
|
432
|
+
} catch (err) {
|
|
433
|
+
if (err.code !== "EAGAIN") {
|
|
434
|
+
throw err;
|
|
435
|
+
}
|
|
436
|
+
if (retryTS === 0) {
|
|
437
|
+
retryTS = performance.now();
|
|
438
|
+
} else {
|
|
439
|
+
if (performance.now() - retryTS > EAGAIN_MAX_DURATION) {
|
|
440
|
+
console.log(`could not write after ${EAGAIN_MAX_DURATION}ms of EAGAIN failures, giving up`);
|
|
441
|
+
throw err;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
};
|
|
447
|
+
};
|
|
448
|
+
var logFilePath;
|
|
449
|
+
var getLogFilePath = () => {
|
|
450
|
+
logFilePath ??= process.env.LOG_FILE ?? (process.env.HOME ? `${process.env.HOME}/.dxlog/${(/* @__PURE__ */ new Date()).toISOString()}.log` : void 0);
|
|
451
|
+
return logFilePath;
|
|
452
|
+
};
|
|
453
|
+
var FILE_PROCESSOR = createFileProcessor({
|
|
454
|
+
pathOrFd: getLogFilePath(),
|
|
455
|
+
levels: [
|
|
456
|
+
LogLevel.ERROR,
|
|
457
|
+
LogLevel.WARN,
|
|
458
|
+
LogLevel.INFO,
|
|
459
|
+
LogLevel.TRACE
|
|
460
|
+
]
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
// packages/common/log/src/options.ts
|
|
464
|
+
var processors = {
|
|
465
|
+
[LogProcessorType.CONSOLE]: CONSOLE_PROCESSOR,
|
|
466
|
+
[LogProcessorType.BROWSER]: BROWSER_PROCESSOR,
|
|
467
|
+
[LogProcessorType.DEBUG]: DEBUG_PROCESSOR
|
|
468
|
+
};
|
|
469
|
+
var IS_BROWSER = typeof window !== "undefined" || typeof navigator !== "undefined";
|
|
470
|
+
var DEFAULT_PROCESSORS = [
|
|
471
|
+
IS_BROWSER ? BROWSER_PROCESSOR : CONSOLE_PROCESSOR
|
|
472
|
+
];
|
|
473
|
+
var parseFilter = (filter) => {
|
|
474
|
+
if (typeof filter === "number") {
|
|
475
|
+
return [
|
|
476
|
+
{
|
|
477
|
+
level: filter
|
|
478
|
+
}
|
|
479
|
+
];
|
|
480
|
+
}
|
|
481
|
+
const parseLogLevel = (level, defValue = LogLevel.WARN) => levels[level.toLowerCase()] ?? defValue;
|
|
482
|
+
const lines = typeof filter === "string" ? filter.split(/,\s*/) : filter;
|
|
483
|
+
return lines.map((filter2) => {
|
|
484
|
+
const [pattern, level] = filter2.split(":");
|
|
485
|
+
return level ? {
|
|
486
|
+
level: parseLogLevel(level),
|
|
487
|
+
pattern
|
|
488
|
+
} : {
|
|
489
|
+
level: parseLogLevel(pattern)
|
|
490
|
+
};
|
|
491
|
+
});
|
|
492
|
+
};
|
|
493
|
+
var getConfig = (options) => {
|
|
494
|
+
const nodeOptions = "process" in globalThis ? {
|
|
495
|
+
file: process.env.LOG_CONFIG,
|
|
496
|
+
filter: process.env.LOG_FILTER,
|
|
497
|
+
processor: process.env.LOG_PROCESSOR
|
|
498
|
+
} : void 0;
|
|
499
|
+
const mergedOptions = defaultsDeep({}, loadOptions(nodeOptions?.file), nodeOptions, options);
|
|
500
|
+
return {
|
|
501
|
+
options: mergedOptions,
|
|
502
|
+
filters: parseFilter(mergedOptions.filter ?? LogLevel.INFO),
|
|
503
|
+
captureFilters: parseFilter(mergedOptions.captureFilter ?? LogLevel.WARN),
|
|
504
|
+
processors: mergedOptions.processor ? [
|
|
505
|
+
processors[mergedOptions.processor]
|
|
506
|
+
] : DEFAULT_PROCESSORS,
|
|
507
|
+
prefix: mergedOptions.prefix
|
|
508
|
+
};
|
|
509
|
+
};
|
|
510
|
+
|
|
511
|
+
// packages/common/log/src/log.ts
|
|
512
|
+
var createLog = () => {
|
|
513
|
+
const log2 = (...params) => processLog(LogLevel.DEBUG, ...params);
|
|
514
|
+
log2._config = getConfig();
|
|
515
|
+
Object.defineProperty(log2, "runtimeConfig", {
|
|
516
|
+
get: () => log2._config
|
|
517
|
+
});
|
|
518
|
+
log2.addProcessor = (processor) => {
|
|
519
|
+
if (DEFAULT_PROCESSORS.filter((p) => p === processor).length === 0) {
|
|
520
|
+
DEFAULT_PROCESSORS.push(processor);
|
|
521
|
+
}
|
|
522
|
+
if (log2._config.processors.filter((p) => p === processor).length === 0) {
|
|
523
|
+
log2._config.processors.push(processor);
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
log2.config = (options) => {
|
|
527
|
+
log2._config = getConfig(options);
|
|
528
|
+
};
|
|
529
|
+
log2.trace = (...params) => processLog(LogLevel.TRACE, ...params);
|
|
530
|
+
log2.debug = (...params) => processLog(LogLevel.DEBUG, ...params);
|
|
531
|
+
log2.info = (...params) => processLog(LogLevel.INFO, ...params);
|
|
532
|
+
log2.warn = (...params) => processLog(LogLevel.WARN, ...params);
|
|
533
|
+
log2.error = (...params) => processLog(LogLevel.ERROR, ...params);
|
|
534
|
+
log2.catch = (error, context, meta) => processLog(LogLevel.ERROR, error.message, context, meta, error);
|
|
535
|
+
log2.break = () => log2.info("\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014");
|
|
536
|
+
log2.stack = (message, context, meta) => processLog(LogLevel.INFO, `${message ?? "Stack Dump"}
|
|
537
|
+
${getFormattedStackTrace()}`, context, meta);
|
|
538
|
+
log2.method = createMethodLogDecorator(log2);
|
|
539
|
+
const processLog = (level, message, context = {}, meta, error) => {
|
|
540
|
+
log2._config.processors.forEach((processor) => processor(log2._config, {
|
|
541
|
+
level,
|
|
542
|
+
message,
|
|
543
|
+
context,
|
|
544
|
+
meta,
|
|
545
|
+
error
|
|
546
|
+
}));
|
|
547
|
+
};
|
|
548
|
+
return log2;
|
|
549
|
+
};
|
|
550
|
+
var log = globalThis.dx_log ??= createLog();
|
|
551
|
+
var start = Date.now();
|
|
552
|
+
var last = start;
|
|
553
|
+
var debug = (label, args) => {
|
|
554
|
+
const now = Date.now();
|
|
555
|
+
const err = new Error();
|
|
556
|
+
console.group(`DEBUG[${label}]`, JSON.stringify({
|
|
557
|
+
t: Number(now - start).toLocaleString(),
|
|
558
|
+
dt: Number(now - last).toLocaleString(),
|
|
559
|
+
...args
|
|
560
|
+
}));
|
|
561
|
+
console.warn(err.stack);
|
|
562
|
+
console.groupEnd();
|
|
563
|
+
last = Date.now();
|
|
564
|
+
};
|
|
565
|
+
var getFormattedStackTrace = () => new Error().stack.split("\n").slice(3).join("\n");
|
|
566
|
+
|
|
567
|
+
// packages/common/log/src/experimental/ownership.ts
|
|
568
|
+
import { inspect as inspect4 } from "node:util";
|
|
569
|
+
var kOwnershipScope = Symbol("kOwnershipScope");
|
|
570
|
+
var kCurrentOwnershipScope = Symbol("kCurrentOwnershipScope");
|
|
571
|
+
var kDebugInfoProperties = Symbol("kDebugInfoProperties");
|
|
572
|
+
var OwnershipScope = class {
|
|
573
|
+
constructor(constr, parent) {
|
|
574
|
+
this.constr = constr;
|
|
575
|
+
this.parent = parent;
|
|
576
|
+
}
|
|
577
|
+
getInfo() {
|
|
578
|
+
if (!this.instance) {
|
|
579
|
+
return {};
|
|
580
|
+
}
|
|
581
|
+
const props = this.constr.prototype[kDebugInfoProperties] ?? [];
|
|
582
|
+
const info = {};
|
|
583
|
+
for (const prop of props) {
|
|
584
|
+
info[prop] = this.instance[prop];
|
|
585
|
+
}
|
|
586
|
+
return info;
|
|
587
|
+
}
|
|
588
|
+
[inspect4.custom]() {
|
|
589
|
+
return {
|
|
590
|
+
className: this.constr.name,
|
|
591
|
+
info: this.getInfo(),
|
|
592
|
+
parent: this.parent
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
};
|
|
596
|
+
var getCurrentOwnershipScope = (thisRef) => thisRef;
|
|
597
|
+
export {
|
|
598
|
+
BROWSER_PROCESSOR,
|
|
599
|
+
CONSOLE_PROCESSOR,
|
|
600
|
+
DEBUG_PROCESSOR,
|
|
601
|
+
DEFAULT_FORMATTER,
|
|
602
|
+
FILE_PROCESSOR,
|
|
603
|
+
LogLevel,
|
|
604
|
+
LogProcessorType,
|
|
605
|
+
SHORT_FORMATTER,
|
|
606
|
+
createFileProcessor,
|
|
607
|
+
debug,
|
|
608
|
+
gatherLogInfoFromScope,
|
|
609
|
+
getContextFromEntry,
|
|
610
|
+
getCurrentOwnershipScope,
|
|
611
|
+
getRelativeFilename,
|
|
612
|
+
levels,
|
|
613
|
+
log,
|
|
614
|
+
logInfo,
|
|
615
|
+
omit,
|
|
616
|
+
parseFilter,
|
|
617
|
+
pick,
|
|
618
|
+
shortLevelName,
|
|
619
|
+
shouldLog,
|
|
620
|
+
truncate
|
|
621
|
+
};
|
|
622
|
+
//# sourceMappingURL=index.mjs.map
|