@dxos/log 0.8.4-main.84f28bd → 0.8.4-main.8baae0fced
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/LICENSE +102 -5
- package/dist/lib/browser/chunk-IEP6GGEX.mjs +23 -0
- package/dist/lib/browser/chunk-IEP6GGEX.mjs.map +7 -0
- package/dist/lib/browser/chunk-V7FYKT4H.mjs +311 -0
- package/dist/lib/browser/chunk-V7FYKT4H.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +352 -200
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/platform/browser/index.mjs +26 -0
- package/dist/lib/browser/platform/browser/index.mjs.map +7 -0
- package/dist/lib/browser/platform/node/index.mjs +21 -0
- package/dist/lib/browser/platform/node/index.mjs.map +7 -0
- package/dist/lib/browser/processors/console-processor.mjs +102 -0
- package/dist/lib/browser/processors/console-processor.mjs.map +7 -0
- package/dist/lib/browser/processors/console-stub.mjs +9 -0
- package/dist/lib/browser/processors/console-stub.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-2SZHAWBN.mjs +24 -0
- package/dist/lib/node-esm/chunk-2SZHAWBN.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-5TBDXMQF.mjs +313 -0
- package/dist/lib/node-esm/chunk-5TBDXMQF.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +354 -287
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/platform/browser/index.mjs +27 -0
- package/dist/lib/node-esm/platform/browser/index.mjs.map +7 -0
- package/dist/lib/node-esm/platform/node/index.mjs +22 -0
- package/dist/lib/node-esm/platform/node/index.mjs.map +7 -0
- package/dist/lib/node-esm/processors/console-processor.mjs +103 -0
- package/dist/lib/node-esm/processors/console-processor.mjs.map +7 -0
- package/dist/lib/node-esm/processors/console-stub.mjs +10 -0
- package/dist/lib/node-esm/processors/console-stub.mjs.map +7 -0
- package/dist/types/src/config.d.ts +2 -3
- package/dist/types/src/config.d.ts.map +1 -1
- package/dist/types/src/context.d.ts +79 -3
- package/dist/types/src/context.d.ts.map +1 -1
- package/dist/types/src/dbg.d.ts +23 -0
- package/dist/types/src/dbg.d.ts.map +1 -0
- package/dist/types/src/decorators.d.ts +1 -1
- package/dist/types/src/decorators.d.ts.map +1 -1
- package/dist/types/src/environment.d.ts +24 -0
- package/dist/types/src/environment.d.ts.map +1 -0
- package/dist/types/src/environment.test.d.ts +2 -0
- package/dist/types/src/environment.test.d.ts.map +1 -0
- package/dist/types/src/experimental/ownership.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +7 -3
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/jsonl.d.ts +53 -0
- package/dist/types/src/jsonl.d.ts.map +1 -0
- package/dist/types/src/jsonl.test.d.ts +2 -0
- package/dist/types/src/jsonl.test.d.ts.map +1 -0
- package/dist/types/src/log-buffer.d.ts +20 -0
- package/dist/types/src/log-buffer.d.ts.map +1 -0
- package/dist/types/src/log-buffer.test.d.ts +2 -0
- package/dist/types/src/log-buffer.test.d.ts.map +1 -0
- package/dist/types/src/log.d.ts +55 -18
- package/dist/types/src/log.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +20 -1
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/options.d.ts +1 -6
- package/dist/types/src/options.d.ts.map +1 -1
- package/dist/types/src/platform/browser/index.d.ts.map +1 -1
- package/dist/types/src/platform/index.d.ts +1 -1
- package/dist/types/src/platform/index.d.ts.map +1 -1
- package/dist/types/src/platform/node/index.d.ts.map +1 -1
- package/dist/types/src/processors/browser-processor.d.ts.map +1 -1
- package/dist/types/src/processors/common.d.ts.map +1 -1
- package/dist/types/src/processors/console-processor.d.ts +1 -1
- package/dist/types/src/processors/console-processor.d.ts.map +1 -1
- package/dist/types/src/processors/file-processor.d.ts.map +1 -1
- package/dist/types/src/processors/index.d.ts +3 -3
- package/dist/types/src/processors/index.d.ts.map +1 -1
- package/dist/types/src/scope.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +33 -18
- package/src/config.ts +3 -2
- package/src/context.ts +280 -10
- package/src/dbg.ts +34 -0
- package/src/decorators.ts +3 -3
- package/src/environment.test.ts +222 -0
- package/src/environment.ts +129 -0
- package/src/experimental/classes.test.ts +1 -1
- package/src/index.ts +7 -4
- package/src/jsonl.test.ts +121 -0
- package/src/jsonl.ts +104 -0
- package/src/log-buffer.test.ts +158 -0
- package/src/log-buffer.ts +89 -0
- package/src/log.test.ts +58 -23
- package/src/log.ts +147 -60
- package/src/meta.ts +29 -1
- package/src/options.ts +27 -11
- package/src/platform/index.ts +1 -1
- package/src/processors/browser-processor.ts +32 -29
- package/src/processors/console-processor.ts +11 -15
- package/src/processors/file-processor.ts +9 -8
- package/src/processors/index.ts +3 -3
- package/src/scope.ts +1 -1
package/src/options.ts
CHANGED
|
@@ -7,37 +7,53 @@ import defaultsDeep from 'lodash.defaultsdeep';
|
|
|
7
7
|
import { type LogConfig, type LogFilter, LogLevel, type LogOptions, LogProcessorType, levels } from './config';
|
|
8
8
|
import { type LogProcessor } from './context';
|
|
9
9
|
import { loadOptions } from './platform';
|
|
10
|
-
import { CONSOLE_PROCESSOR, DEBUG_PROCESSOR
|
|
10
|
+
import { BROWSER_PROCESSOR, CONSOLE_PROCESSOR, DEBUG_PROCESSOR } from './processors';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Processor variants.
|
|
14
14
|
*/
|
|
15
|
-
export const processors:
|
|
15
|
+
export const processors: Record<string, LogProcessor> = {
|
|
16
16
|
[LogProcessorType.CONSOLE]: CONSOLE_PROCESSOR,
|
|
17
17
|
[LogProcessorType.BROWSER]: BROWSER_PROCESSOR,
|
|
18
18
|
[LogProcessorType.DEBUG]: DEBUG_PROCESSOR,
|
|
19
19
|
};
|
|
20
20
|
|
|
21
|
-
const
|
|
21
|
+
const browser =
|
|
22
|
+
(typeof window !== 'undefined' || typeof navigator !== 'undefined') &&
|
|
23
|
+
!(typeof process !== 'undefined' && process?.env?.VITEST);
|
|
22
24
|
|
|
23
|
-
export const DEFAULT_PROCESSORS = [
|
|
25
|
+
export const DEFAULT_PROCESSORS = [browser ? BROWSER_PROCESSOR : CONSOLE_PROCESSOR];
|
|
24
26
|
|
|
27
|
+
const parseLogLevel = (level: string, defValue = LogLevel.WARN) => levels[level.toLowerCase()] ?? defValue;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @internal
|
|
31
|
+
*/
|
|
25
32
|
export const parseFilter = (filter: string | string[] | LogLevel): LogFilter[] => {
|
|
26
33
|
if (typeof filter === 'number') {
|
|
27
34
|
return [{ level: filter }];
|
|
28
35
|
}
|
|
29
36
|
|
|
30
|
-
const parseLogLevel = (level: string, defValue = LogLevel.WARN) => levels[level.toLowerCase()] ?? defValue;
|
|
31
|
-
|
|
32
37
|
const lines = typeof filter === 'string' ? filter.split(/,\s*/) : filter;
|
|
33
38
|
return lines.map((filter) => {
|
|
34
39
|
const [pattern, level] = filter.split(':');
|
|
35
|
-
return level
|
|
40
|
+
return level
|
|
41
|
+
? {
|
|
42
|
+
level: parseLogLevel(level),
|
|
43
|
+
pattern,
|
|
44
|
+
}
|
|
45
|
+
: {
|
|
46
|
+
level: parseLogLevel(pattern),
|
|
47
|
+
};
|
|
36
48
|
});
|
|
37
49
|
};
|
|
38
50
|
|
|
39
|
-
|
|
40
|
-
|
|
51
|
+
/**
|
|
52
|
+
* @internal
|
|
53
|
+
*/
|
|
54
|
+
export const createConfig = (options?: LogOptions): LogConfig => {
|
|
55
|
+
// Node only.
|
|
56
|
+
const envOptions: LogOptions | undefined =
|
|
41
57
|
'process' in globalThis
|
|
42
58
|
? {
|
|
43
59
|
file: process!.env.LOG_CONFIG,
|
|
@@ -46,12 +62,12 @@ export const getConfig = (options?: LogOptions): LogConfig => {
|
|
|
46
62
|
}
|
|
47
63
|
: undefined;
|
|
48
64
|
|
|
49
|
-
const mergedOptions: LogOptions = defaultsDeep({}, loadOptions(
|
|
65
|
+
const mergedOptions: LogOptions = defaultsDeep({}, loadOptions(envOptions?.file), envOptions, options);
|
|
50
66
|
return {
|
|
51
67
|
options: mergedOptions,
|
|
52
68
|
filters: parseFilter(mergedOptions.filter ?? LogLevel.INFO),
|
|
53
69
|
captureFilters: parseFilter(mergedOptions.captureFilter ?? LogLevel.WARN),
|
|
54
|
-
processors: mergedOptions.processor ? [processors[mergedOptions.processor]] : DEFAULT_PROCESSORS,
|
|
70
|
+
processors: mergedOptions.processor ? [processors[mergedOptions.processor]] : [...DEFAULT_PROCESSORS],
|
|
55
71
|
prefix: mergedOptions.prefix,
|
|
56
72
|
};
|
|
57
73
|
};
|
package/src/platform/index.ts
CHANGED
|
@@ -2,22 +2,10 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { safariCheck } from '@dxos/util';
|
|
6
6
|
|
|
7
7
|
import { LogLevel } from '../config';
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
const getRelativeFilename = (filename: string) => {
|
|
11
|
-
// TODO(burdon): Hack uses "packages" as an anchor (pre-parse NX?)
|
|
12
|
-
// Including `packages/` part of the path so that excluded paths (e.g. from dist) are clickable in vscode.
|
|
13
|
-
const match = filename.match(/.+\/(packages\/.+\/.+)/);
|
|
14
|
-
if (match) {
|
|
15
|
-
const [, filePath] = match;
|
|
16
|
-
return filePath;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
return filename;
|
|
20
|
-
};
|
|
8
|
+
import { type LogProcessor, getContextFromEntry, shouldLog } from '../context';
|
|
21
9
|
|
|
22
10
|
type Config = {
|
|
23
11
|
useTestProcessor: boolean;
|
|
@@ -47,31 +35,38 @@ const APP_BROWSER_PROCESSOR: LogProcessor = (config, entry) => {
|
|
|
47
35
|
// const LOG_BROWSER_CSS = ['color:gray; font-size:10px; padding-bottom: 4px', 'color:#B97852; font-size:14px;'];
|
|
48
36
|
const LOG_BROWSER_CSS: string[] = [];
|
|
49
37
|
|
|
38
|
+
const { filename, line: lineNumber, context: scopeDebugName } = entry.computedMeta;
|
|
39
|
+
|
|
50
40
|
let link = '';
|
|
51
|
-
if (
|
|
52
|
-
const filename = getRelativeFilename(entry.meta.F);
|
|
41
|
+
if (filename !== undefined && lineNumber !== undefined) {
|
|
53
42
|
const filepath = `${LOG_BROWSER_PREFIX.replace(/\/$/, '')}/${filename}`;
|
|
54
43
|
// TODO(burdon): Line numbers not working for app link, even with colons.
|
|
55
44
|
// https://stackoverflow.com/a/54459820/2804332
|
|
56
|
-
link = `${filepath}#L${
|
|
45
|
+
link = `${filepath}#L${lineNumber}`;
|
|
57
46
|
}
|
|
58
47
|
|
|
59
48
|
let args = [];
|
|
60
49
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const scopeName = scope.name ||
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
50
|
+
const scope = entry.meta?.S;
|
|
51
|
+
if (scope) {
|
|
52
|
+
const scopeName = scope.name || scopeDebugName;
|
|
53
|
+
if (scopeName) {
|
|
54
|
+
const processPrefix = scope.hostSessionId ? '[worker] ' : '';
|
|
55
|
+
// TODO(dmaretskyi): Those can be made clickable with a custom formatter.
|
|
56
|
+
args.push(`%c${processPrefix}${scopeName}`, 'color:#C026D3;font-weight:bold');
|
|
57
|
+
}
|
|
67
58
|
}
|
|
68
59
|
|
|
69
|
-
|
|
60
|
+
if (entry.message) {
|
|
61
|
+
args.push(entry.message);
|
|
62
|
+
}
|
|
70
63
|
|
|
71
64
|
const context = getContextFromEntry(entry);
|
|
72
65
|
if (context) {
|
|
73
66
|
if (Object.keys(context).length === 1 && 'error' in context) {
|
|
74
|
-
args.push(context.error);
|
|
67
|
+
args.push(unwrapEffectError(context.error));
|
|
68
|
+
} else if (Object.keys(context).length === 1 && 'err' in context) {
|
|
69
|
+
args.push(unwrapEffectError(context.err));
|
|
75
70
|
} else {
|
|
76
71
|
args.push(context);
|
|
77
72
|
}
|
|
@@ -110,10 +105,8 @@ const TEST_BROWSER_PROCESSOR: LogProcessor = (config, entry) => {
|
|
|
110
105
|
return;
|
|
111
106
|
}
|
|
112
107
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
path = `${getRelativeFilename(entry.meta.F)}:${entry.meta.L}`;
|
|
116
|
-
}
|
|
108
|
+
const { filename, line: lineNumber } = entry.computedMeta;
|
|
109
|
+
const path = filename !== undefined && lineNumber !== undefined ? `${filename}:${lineNumber}` : '';
|
|
117
110
|
|
|
118
111
|
let args = [];
|
|
119
112
|
|
|
@@ -144,3 +137,13 @@ const TEST_BROWSER_PROCESSOR: LogProcessor = (config, entry) => {
|
|
|
144
137
|
};
|
|
145
138
|
|
|
146
139
|
export const BROWSER_PROCESSOR: LogProcessor = CONFIG.useTestProcessor ? TEST_BROWSER_PROCESSOR : APP_BROWSER_PROCESSOR;
|
|
140
|
+
|
|
141
|
+
// effect-specific
|
|
142
|
+
const originalSymbol = Symbol.for('effect/OriginalAnnotation');
|
|
143
|
+
|
|
144
|
+
const unwrapEffectError = (error: any) => {
|
|
145
|
+
if (typeof error === 'object' && error !== null && originalSymbol in error) {
|
|
146
|
+
return error[originalSymbol];
|
|
147
|
+
}
|
|
148
|
+
return error;
|
|
149
|
+
};
|
|
@@ -7,9 +7,8 @@ import { inspect } from 'node:util';
|
|
|
7
7
|
|
|
8
8
|
import { getPrototypeSpecificInstanceId, pickBy } from '@dxos/util';
|
|
9
9
|
|
|
10
|
-
import { getRelativeFilename } from './common';
|
|
11
10
|
import { type LogConfig, LogLevel, shortLevelName } from '../config';
|
|
12
|
-
import {
|
|
11
|
+
import { type LogProcessor, getContextFromEntry, shouldLog } from '../context';
|
|
13
12
|
|
|
14
13
|
const LEVEL_COLORS: Record<LogLevel, typeof chalk.ForegroundColor> = {
|
|
15
14
|
[LogLevel.TRACE]: 'gray',
|
|
@@ -21,7 +20,7 @@ const LEVEL_COLORS: Record<LogLevel, typeof chalk.ForegroundColor> = {
|
|
|
21
20
|
};
|
|
22
21
|
|
|
23
22
|
export const truncate = (text?: string, length = 0, right = false) => {
|
|
24
|
-
const str = text && length ? (right ? text.slice(-length) : text.substring(0, length)) : text ?? '';
|
|
23
|
+
const str = text && length ? (right ? text.slice(-length) : text.substring(0, length)) : (text ?? '');
|
|
25
24
|
return right ? str.padStart(length, ' ') : str.padEnd(length, ' ');
|
|
26
25
|
};
|
|
27
26
|
|
|
@@ -32,7 +31,7 @@ export type FormatParts = {
|
|
|
32
31
|
line?: number;
|
|
33
32
|
timestamp?: string;
|
|
34
33
|
level: LogLevel;
|
|
35
|
-
message
|
|
34
|
+
message?: string;
|
|
36
35
|
context?: any;
|
|
37
36
|
error?: Error;
|
|
38
37
|
scope?: any;
|
|
@@ -50,8 +49,10 @@ export const DEFAULT_FORMATTER: Formatter = (
|
|
|
50
49
|
let instance;
|
|
51
50
|
if (scope) {
|
|
52
51
|
const prototype = Object.getPrototypeOf(scope);
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
if (prototype !== null) {
|
|
53
|
+
const id = getPrototypeSpecificInstanceId(scope);
|
|
54
|
+
instance = chalk.magentaBright(`${prototype.constructor.name}#${id}`);
|
|
55
|
+
}
|
|
55
56
|
}
|
|
56
57
|
|
|
57
58
|
const formattedTimestamp = config.options?.formatter?.timestamp ? new Date().toISOString() : undefined;
|
|
@@ -91,22 +92,17 @@ export const CONSOLE_PROCESSOR: LogProcessor = (config, entry) => {
|
|
|
91
92
|
return;
|
|
92
93
|
}
|
|
93
94
|
|
|
95
|
+
const { filename, line: lineNumber } = entry.computedMeta;
|
|
94
96
|
const parts: FormatParts = {
|
|
95
97
|
level,
|
|
96
98
|
message,
|
|
97
99
|
error,
|
|
98
|
-
path:
|
|
99
|
-
line:
|
|
100
|
-
scope:
|
|
100
|
+
path: filename,
|
|
101
|
+
line: lineNumber,
|
|
102
|
+
scope: meta?.S,
|
|
101
103
|
context: undefined,
|
|
102
104
|
};
|
|
103
105
|
|
|
104
|
-
if (meta) {
|
|
105
|
-
parts.path = getRelativeFilename(meta.F);
|
|
106
|
-
parts.line = meta.L;
|
|
107
|
-
parts.scope = meta.S;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
106
|
const context = getContextFromEntry(entry);
|
|
111
107
|
if (context) {
|
|
112
108
|
// Remove undefined fields.
|
|
@@ -5,14 +5,12 @@
|
|
|
5
5
|
import { appendFileSync, mkdirSync, openSync } from 'node:fs';
|
|
6
6
|
import { dirname } from 'node:path';
|
|
7
7
|
|
|
8
|
-
import { jsonlogify } from '@dxos/util';
|
|
9
|
-
|
|
10
|
-
import { getRelativeFilename } from './common';
|
|
11
8
|
import { type LogFilter, LogLevel } from '../config';
|
|
12
|
-
import { type LogProcessor,
|
|
9
|
+
import { type LogProcessor, shouldLog } from '../context';
|
|
13
10
|
|
|
14
11
|
// Amount of time to retry writing after encountering EAGAIN before giving up.
|
|
15
12
|
const EAGAIN_MAX_DURATION = 1000;
|
|
13
|
+
|
|
16
14
|
/**
|
|
17
15
|
* Create a file processor.
|
|
18
16
|
* @param path - Path to log file to create or append to, or existing open file descriptor e.g. stdout.
|
|
@@ -37,6 +35,7 @@ export const createFileProcessor = ({
|
|
|
37
35
|
if (!shouldLog(entry, filters)) {
|
|
38
36
|
return;
|
|
39
37
|
}
|
|
38
|
+
|
|
40
39
|
if (typeof pathOrFd === 'number') {
|
|
41
40
|
fd = pathOrFd;
|
|
42
41
|
} else {
|
|
@@ -47,10 +46,12 @@ export const createFileProcessor = ({
|
|
|
47
46
|
}
|
|
48
47
|
|
|
49
48
|
const record = {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
level: entry.level,
|
|
50
|
+
message: entry.message,
|
|
51
|
+
timestamp: entry.timestamp,
|
|
52
|
+
meta: entry.computedMeta,
|
|
53
|
+
context: entry.computedContext,
|
|
54
|
+
error: entry.computedError,
|
|
54
55
|
};
|
|
55
56
|
let retryTS: number = 0;
|
|
56
57
|
|
package/src/processors/index.ts
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
export * from './console-processor';
|
|
6
|
-
export * from './debug-processor';
|
|
7
5
|
export * from './browser-processor';
|
|
8
|
-
export * from './file-processor';
|
|
9
6
|
export * from './common';
|
|
7
|
+
export * from '#console-processor';
|
|
8
|
+
export * from './debug-processor';
|
|
9
|
+
export * from './file-processor';
|
package/src/scope.ts
CHANGED
|
@@ -33,7 +33,7 @@ export const gatherLogInfoFromScope = (scope: any): Record<string, any> => {
|
|
|
33
33
|
const res: Record<string, any> = {};
|
|
34
34
|
|
|
35
35
|
const prototype = Object.getPrototypeOf(scope);
|
|
36
|
-
const infoProps = prototype[logInfoProperties] ?? [];
|
|
36
|
+
const infoProps = (typeof prototype === 'object' && prototype !== null ? prototype[logInfoProperties] : []) ?? [];
|
|
37
37
|
for (const prop of infoProps) {
|
|
38
38
|
try {
|
|
39
39
|
res[prop] = typeof scope[prop] === 'function' ? scope[prop]() : scope[prop];
|