@dxos/log 0.8.4-main.fbb7a13 → 0.8.4-main.fcfe5033a5
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/{chunk-GPOFUMLO.mjs → chunk-M2YHSBML.mjs} +2 -2
- package/dist/lib/browser/{chunk-GPOFUMLO.mjs.map → chunk-M2YHSBML.mjs.map} +1 -1
- package/dist/lib/browser/index.mjs +92 -8
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/platform/node/index.mjs +1 -1
- package/dist/lib/browser/platform/node/index.mjs.map +3 -3
- package/dist/lib/browser/processors/console-processor.mjs +2 -2
- package/dist/lib/browser/processors/console-processor.mjs.map +3 -3
- package/dist/lib/node-esm/{chunk-QPYJZ4SO.mjs → chunk-62VKC2WQ.mjs} +2 -2
- package/dist/lib/node-esm/{chunk-QPYJZ4SO.mjs.map → chunk-62VKC2WQ.mjs.map} +1 -1
- package/dist/lib/node-esm/index.mjs +92 -8
- 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/node/index.mjs +1 -1
- package/dist/lib/node-esm/platform/node/index.mjs.map +3 -3
- package/dist/lib/node-esm/processors/console-processor.mjs +2 -2
- package/dist/lib/node-esm/processors/console-processor.mjs.map +3 -3
- 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.map +1 -1
- package/dist/types/src/index.d.ts +3 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/log-buffer.d.ts +40 -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 +3 -1
- package/dist/types/src/log.d.ts.map +1 -1
- package/dist/types/src/platform/node/index.d.ts.map +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/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -6
- package/src/dbg.ts +34 -0
- package/src/decorators.ts +1 -2
- package/src/experimental/classes.test.ts +0 -1
- package/src/index.ts +3 -3
- package/src/log-buffer.test.ts +155 -0
- package/src/log-buffer.ts +117 -0
- package/src/log.test.ts +0 -1
- package/src/log.ts +4 -2
- package/src/platform/node/index.ts +1 -2
- package/src/processors/console-processor.ts +1 -3
- package/src/processors/file-processor.ts +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/log",
|
|
3
|
-
"version": "0.8.4-main.
|
|
3
|
+
"version": "0.8.4-main.fcfe5033a5",
|
|
4
4
|
"description": "Logger",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -54,14 +54,12 @@
|
|
|
54
54
|
"chalk": "^4.1.2",
|
|
55
55
|
"js-yaml": "4.1.1",
|
|
56
56
|
"lodash.defaultsdeep": "^4.6.1",
|
|
57
|
-
"
|
|
58
|
-
"@dxos/
|
|
59
|
-
"@dxos/util": "0.8.4-main.fbb7a13"
|
|
57
|
+
"@dxos/node-std": "0.8.4-main.fcfe5033a5",
|
|
58
|
+
"@dxos/util": "0.8.4-main.fcfe5033a5"
|
|
60
59
|
},
|
|
61
60
|
"devDependencies": {
|
|
62
61
|
"@types/js-yaml": "^4.0.5",
|
|
63
|
-
"@types/lodash.defaultsdeep": "^4.6.6"
|
|
64
|
-
"@types/lodash.omit": "^4.5.7"
|
|
62
|
+
"@types/lodash.defaultsdeep": "^4.6.6"
|
|
65
63
|
},
|
|
66
64
|
"publishConfig": {
|
|
67
65
|
"access": "public"
|
package/src/dbg.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2026 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type CallMetadata } from './meta';
|
|
6
|
+
/**
|
|
7
|
+
* Debug-log value to console.
|
|
8
|
+
* Log's the expression being evaluated.
|
|
9
|
+
*
|
|
10
|
+
* If only one argument is provided, it will also be returned.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* dbg(foo, bar);
|
|
15
|
+
* // foo = 1
|
|
16
|
+
* // bar = 2
|
|
17
|
+
*
|
|
18
|
+
* bar = dbg(foo * 2);
|
|
19
|
+
* // foo * 2 = 2
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* NOTE: The second argument is injected by the log transform plugin.
|
|
23
|
+
*/
|
|
24
|
+
export const dbg: {
|
|
25
|
+
<T>(value: T, _meta?: CallMetadata): T;
|
|
26
|
+
} = <T>(arg: T, meta?: CallMetadata): T => {
|
|
27
|
+
if (meta?.A) {
|
|
28
|
+
console.log(`${meta.A[0]} =`, arg);
|
|
29
|
+
} else {
|
|
30
|
+
console.log(arg);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return arg;
|
|
34
|
+
};
|
package/src/decorators.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -2,9 +2,7 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import omit from '
|
|
6
|
-
|
|
7
|
-
import { pick } from '@dxos/util';
|
|
5
|
+
import { omit, pick } from '@dxos/util';
|
|
8
6
|
|
|
9
7
|
export { omit, pick };
|
|
10
8
|
|
|
@@ -15,5 +13,7 @@ export { parseFilter } from './options';
|
|
|
15
13
|
export * from './processors';
|
|
16
14
|
export * from './scope';
|
|
17
15
|
export type * from './meta';
|
|
16
|
+
export { dbg } from './dbg';
|
|
17
|
+
export * from './log-buffer';
|
|
18
18
|
|
|
19
19
|
export { getCurrentOwnershipScope } from './experimental/ownership';
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { describe, test } from 'vitest';
|
|
6
|
+
|
|
7
|
+
import { type LogConfig, type LogEntry, LogLevel } from './index';
|
|
8
|
+
import { LogBuffer } from './log-buffer';
|
|
9
|
+
|
|
10
|
+
const baseConfig: LogConfig = {
|
|
11
|
+
options: {},
|
|
12
|
+
filters: [{ level: LogLevel.DEBUG }],
|
|
13
|
+
processors: [],
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const createEntry = (overrides: Partial<LogEntry> = {}): LogEntry => ({
|
|
17
|
+
level: LogLevel.INFO,
|
|
18
|
+
message: 'test message',
|
|
19
|
+
...overrides,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
describe('LogBuffer', () => {
|
|
23
|
+
test('pushes and serializes log entries', ({ expect }) => {
|
|
24
|
+
const buffer = new LogBuffer(10);
|
|
25
|
+
buffer.logProcessor(baseConfig, createEntry({ message: 'hello' }));
|
|
26
|
+
buffer.logProcessor(baseConfig, createEntry({ message: 'world' }));
|
|
27
|
+
|
|
28
|
+
expect(buffer.size).toBe(2);
|
|
29
|
+
const lines = buffer.serialize().split('\n');
|
|
30
|
+
expect(lines).toHaveLength(2);
|
|
31
|
+
|
|
32
|
+
const first = JSON.parse(lines[0]);
|
|
33
|
+
expect(first.m).toBe('hello');
|
|
34
|
+
expect(first.l).toBe('I');
|
|
35
|
+
expect(first.t).toBeDefined();
|
|
36
|
+
|
|
37
|
+
const second = JSON.parse(lines[1]);
|
|
38
|
+
expect(second.m).toBe('world');
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('evicts oldest entries when buffer is full', ({ expect }) => {
|
|
42
|
+
const buffer = new LogBuffer(3);
|
|
43
|
+
buffer.logProcessor(baseConfig, createEntry({ message: 'a' }));
|
|
44
|
+
buffer.logProcessor(baseConfig, createEntry({ message: 'b' }));
|
|
45
|
+
buffer.logProcessor(baseConfig, createEntry({ message: 'c' }));
|
|
46
|
+
buffer.logProcessor(baseConfig, createEntry({ message: 'd' }));
|
|
47
|
+
|
|
48
|
+
expect(buffer.size).toBe(3);
|
|
49
|
+
const lines = buffer.serialize().split('\n');
|
|
50
|
+
const messages = lines.map((line) => JSON.parse(line).m);
|
|
51
|
+
expect(messages).toEqual(['b', 'c', 'd']);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test('skips TRACE-level logs', ({ expect }) => {
|
|
55
|
+
const buffer = new LogBuffer(10);
|
|
56
|
+
buffer.logProcessor(baseConfig, createEntry({ level: LogLevel.TRACE, message: 'trace' }));
|
|
57
|
+
expect(buffer.size).toBe(0);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test('captures DEBUG-level and above', ({ expect }) => {
|
|
61
|
+
const buffer = new LogBuffer(10);
|
|
62
|
+
buffer.logProcessor(baseConfig, createEntry({ level: LogLevel.DEBUG, message: 'debug' }));
|
|
63
|
+
buffer.logProcessor(baseConfig, createEntry({ level: LogLevel.WARN, message: 'warn' }));
|
|
64
|
+
buffer.logProcessor(baseConfig, createEntry({ level: LogLevel.ERROR, message: 'error' }));
|
|
65
|
+
|
|
66
|
+
expect(buffer.size).toBe(3);
|
|
67
|
+
const lines = buffer.serialize().split('\n');
|
|
68
|
+
expect(JSON.parse(lines[0]).l).toBe('D');
|
|
69
|
+
expect(JSON.parse(lines[1]).l).toBe('W');
|
|
70
|
+
expect(JSON.parse(lines[2]).l).toBe('E');
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test('captures file and line metadata', ({ expect }) => {
|
|
74
|
+
const buffer = new LogBuffer(10);
|
|
75
|
+
buffer.logProcessor(
|
|
76
|
+
baseConfig,
|
|
77
|
+
createEntry({
|
|
78
|
+
meta: { F: '/home/user/project/packages/sdk/test.ts', L: 42, S: undefined },
|
|
79
|
+
}),
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
const lines = buffer.serialize().split('\n');
|
|
83
|
+
const record = JSON.parse(lines[0]);
|
|
84
|
+
expect(record.f).toBe('packages/sdk/test.ts');
|
|
85
|
+
expect(record.n).toBe(42);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test('captures error stack', ({ expect }) => {
|
|
89
|
+
const buffer = new LogBuffer(10);
|
|
90
|
+
const error = new Error('boom');
|
|
91
|
+
buffer.logProcessor(baseConfig, createEntry({ error }));
|
|
92
|
+
|
|
93
|
+
const lines = buffer.serialize().split('\n');
|
|
94
|
+
const record = JSON.parse(lines[0]);
|
|
95
|
+
expect(record.e).toContain('boom');
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
test('truncates context to 500 chars', ({ expect }) => {
|
|
99
|
+
const buffer = new LogBuffer(10);
|
|
100
|
+
const longValue = 'x'.repeat(1000);
|
|
101
|
+
buffer.logProcessor(baseConfig, createEntry({ context: { data: longValue } }));
|
|
102
|
+
|
|
103
|
+
const lines = buffer.serialize().split('\n');
|
|
104
|
+
const record = JSON.parse(lines[0]);
|
|
105
|
+
expect(record.c).toBeDefined();
|
|
106
|
+
expect(record.c!.length).toBe(500);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test('skips Error context objects', ({ expect }) => {
|
|
110
|
+
const buffer = new LogBuffer(10);
|
|
111
|
+
buffer.logProcessor(baseConfig, createEntry({ context: new Error('ctx error') }));
|
|
112
|
+
|
|
113
|
+
const lines = buffer.serialize().split('\n');
|
|
114
|
+
const record = JSON.parse(lines[0]);
|
|
115
|
+
expect(record.c).toBeUndefined();
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
test('handles non-serializable context gracefully', ({ expect }) => {
|
|
119
|
+
const buffer = new LogBuffer(10);
|
|
120
|
+
const circular: Record<string, any> = {};
|
|
121
|
+
circular.self = circular;
|
|
122
|
+
buffer.logProcessor(baseConfig, createEntry({ context: circular }));
|
|
123
|
+
|
|
124
|
+
const lines = buffer.serialize().split('\n');
|
|
125
|
+
const record = JSON.parse(lines[0]);
|
|
126
|
+
expect(record.c).toBeUndefined();
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
test('serialize returns empty string for empty buffer', ({ expect }) => {
|
|
130
|
+
const buffer = new LogBuffer(10);
|
|
131
|
+
expect(buffer.serialize()).toBe('');
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
test('clear discards all entries', ({ expect }) => {
|
|
135
|
+
const buffer = new LogBuffer(10);
|
|
136
|
+
buffer.logProcessor(baseConfig, createEntry({ message: 'a' }));
|
|
137
|
+
buffer.logProcessor(baseConfig, createEntry({ message: 'b' }));
|
|
138
|
+
expect(buffer.size).toBe(2);
|
|
139
|
+
|
|
140
|
+
buffer.clear();
|
|
141
|
+
expect(buffer.size).toBe(0);
|
|
142
|
+
expect(buffer.serialize()).toBe('');
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
test('clear allows new entries', ({ expect }) => {
|
|
146
|
+
const buffer = new LogBuffer(10);
|
|
147
|
+
buffer.logProcessor(baseConfig, createEntry({ message: 'old' }));
|
|
148
|
+
buffer.clear();
|
|
149
|
+
buffer.logProcessor(baseConfig, createEntry({ message: 'new' }));
|
|
150
|
+
|
|
151
|
+
expect(buffer.size).toBe(1);
|
|
152
|
+
const record = JSON.parse(buffer.serialize());
|
|
153
|
+
expect(record.m).toBe('new');
|
|
154
|
+
});
|
|
155
|
+
});
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2025 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { CircularBuffer, getDebugName } from '@dxos/util';
|
|
6
|
+
|
|
7
|
+
import { type LogConfig, LogLevel, shortLevelName } from './config';
|
|
8
|
+
import { type LogEntry, type LogProcessor } from './context';
|
|
9
|
+
|
|
10
|
+
const DEFAULT_BUFFER_SIZE = 2_000;
|
|
11
|
+
const MAX_CONTEXT_LENGTH = 500;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Compact log record with short property names for small serialized size.
|
|
15
|
+
*/
|
|
16
|
+
export type LogRecord = {
|
|
17
|
+
/** ISO timestamp. */
|
|
18
|
+
t: string;
|
|
19
|
+
/** Level letter (D, V, I, W, E). */
|
|
20
|
+
l: string;
|
|
21
|
+
/** Message. */
|
|
22
|
+
m: string;
|
|
23
|
+
/** File path. */
|
|
24
|
+
f?: string;
|
|
25
|
+
/** Line number. */
|
|
26
|
+
n?: number;
|
|
27
|
+
/* Object from which the log was emitted. */
|
|
28
|
+
o?: string;
|
|
29
|
+
/** Error stack. */
|
|
30
|
+
e?: string;
|
|
31
|
+
/** Context JSON. */
|
|
32
|
+
c?: string;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Captures recent log entries in a circular buffer for debug log dump.
|
|
37
|
+
*/
|
|
38
|
+
export class LogBuffer {
|
|
39
|
+
private readonly _buffer: CircularBuffer<LogRecord>;
|
|
40
|
+
|
|
41
|
+
constructor(size = DEFAULT_BUFFER_SIZE) {
|
|
42
|
+
this._buffer = new CircularBuffer<LogRecord>(size);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Log processor that can be registered with `log.runtimeConfig.processors`.
|
|
47
|
+
* Captures every level except TRACE (does not apply `shouldLog` / filter; use for full debug dumps).
|
|
48
|
+
*/
|
|
49
|
+
readonly logProcessor: LogProcessor = (_config: LogConfig, entry: LogEntry) => {
|
|
50
|
+
if (entry.level <= LogLevel.TRACE) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const record: LogRecord = {
|
|
55
|
+
t: new Date().toISOString(),
|
|
56
|
+
l: shortLevelName[entry.level] ?? '?',
|
|
57
|
+
m: entry.message ?? '',
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
if (entry.meta) {
|
|
61
|
+
record.f = getRelativeFilename(entry.meta.F);
|
|
62
|
+
record.n = entry.meta.L;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (entry.error) {
|
|
66
|
+
record.e = entry.error.stack ?? entry.error.message;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (entry.context != null) {
|
|
70
|
+
try {
|
|
71
|
+
const ctx = typeof entry.context === 'function' ? entry.context() : entry.context;
|
|
72
|
+
if (ctx != null && !(ctx instanceof Error)) {
|
|
73
|
+
let json = JSON.stringify(ctx);
|
|
74
|
+
if (json.length > MAX_CONTEXT_LENGTH) {
|
|
75
|
+
json = json.slice(0, MAX_CONTEXT_LENGTH);
|
|
76
|
+
}
|
|
77
|
+
record.c = json;
|
|
78
|
+
}
|
|
79
|
+
} catch {
|
|
80
|
+
// Skip context that throws or is non-serializable.
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const scope = entry.meta?.S;
|
|
84
|
+
if (typeof scope === 'object' && scope !== null && Object.getPrototypeOf(scope) !== Object.prototype) {
|
|
85
|
+
record.o = getDebugName(scope);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
this._buffer.push(record);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
/** Number of entries currently in the buffer. */
|
|
92
|
+
get size(): number {
|
|
93
|
+
return this._buffer.elementCount;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Discard all buffered entries. */
|
|
97
|
+
clear(): void {
|
|
98
|
+
this._buffer.clear();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Serialize buffer contents as NDJSON (newline-delimited JSON). */
|
|
102
|
+
serialize(): string {
|
|
103
|
+
const lines: string[] = [];
|
|
104
|
+
for (const record of this._buffer) {
|
|
105
|
+
lines.push(JSON.stringify(record));
|
|
106
|
+
}
|
|
107
|
+
return lines.join('\n');
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const getRelativeFilename = (filename: string): string => {
|
|
112
|
+
const match = filename.match(/.+\/(packages\/.+\/.+)/);
|
|
113
|
+
if (match) {
|
|
114
|
+
return match[1];
|
|
115
|
+
}
|
|
116
|
+
return filename;
|
|
117
|
+
};
|
package/src/log.test.ts
CHANGED
package/src/log.ts
CHANGED
|
@@ -10,6 +10,8 @@ import { createConfig } from './options';
|
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Accessible from browser console.
|
|
13
|
+
* Example: `DX_LOG.config({ filter: 'ERROR' })`
|
|
14
|
+
* NOTE: File level filtering isn't supported in storybooks.
|
|
13
15
|
*/
|
|
14
16
|
declare global {
|
|
15
17
|
const DX_LOG: Log;
|
|
@@ -24,7 +26,7 @@ type LogFunction = (message: string, context?: LogContext, meta?: CallMetadata)
|
|
|
24
26
|
* Logging methods.
|
|
25
27
|
*/
|
|
26
28
|
export interface LogMethods {
|
|
27
|
-
config: (options
|
|
29
|
+
config: (options?: LogOptions) => Log;
|
|
28
30
|
addProcessor: (processor: LogProcessor, addDefault?: boolean) => () => void;
|
|
29
31
|
|
|
30
32
|
trace: LogFunction;
|
|
@@ -116,7 +118,7 @@ export const createLog = (): LogImp => {
|
|
|
116
118
|
* NOTE: Preserves any processors that were already added to this logger instance
|
|
117
119
|
* unless an explicit processor option is provided.
|
|
118
120
|
*/
|
|
119
|
-
config: ({ processor, ...options }) => {
|
|
121
|
+
config: ({ processor, ...options } = {}) => {
|
|
120
122
|
const config = createConfig(options);
|
|
121
123
|
// TODO(burdon): This could be buggy since the behavior is not reentrant.
|
|
122
124
|
const processors = processor ? config.processors : log._config.processors;
|
|
@@ -2,15 +2,13 @@
|
|
|
2
2
|
// Copyright 2022 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { inspect } from 'node:util';
|
|
6
|
-
|
|
7
5
|
import chalk from 'chalk';
|
|
6
|
+
import { inspect } from 'node:util';
|
|
8
7
|
|
|
9
8
|
import { getPrototypeSpecificInstanceId, pickBy } from '@dxos/util';
|
|
10
9
|
|
|
11
10
|
import { type LogConfig, LogLevel, shortLevelName } from '../config';
|
|
12
11
|
import { type LogProcessor, getContextFromEntry, shouldLog } from '../context';
|
|
13
|
-
|
|
14
12
|
import { getRelativeFilename } from './common';
|
|
15
13
|
|
|
16
14
|
const LEVEL_COLORS: Record<LogLevel, typeof chalk.ForegroundColor> = {
|
|
@@ -9,7 +9,6 @@ import { jsonlogify } from '@dxos/util';
|
|
|
9
9
|
|
|
10
10
|
import { type LogFilter, LogLevel } from '../config';
|
|
11
11
|
import { type LogProcessor, getContextFromEntry, shouldLog } from '../context';
|
|
12
|
-
|
|
13
12
|
import { getRelativeFilename } from './common';
|
|
14
13
|
|
|
15
14
|
// Amount of time to retry writing after encountering EAGAIN before giving up.
|