loggily 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/context.d.mts +91 -0
- package/dist/context.d.mts.map +1 -0
- package/dist/context.mjs +145 -0
- package/dist/context.mjs.map +1 -0
- package/dist/core-7D7sstHl.d.mts +239 -0
- package/dist/core-7D7sstHl.d.mts.map +1 -0
- package/dist/core-BDFU50FQ.mjs +570 -0
- package/dist/core-BDFU50FQ.mjs.map +1 -0
- package/dist/file-writer-BuQGFGRs.d.mts +46 -0
- package/dist/file-writer-BuQGFGRs.d.mts.map +1 -0
- package/dist/file-writer.d.mts +2 -0
- package/dist/file-writer.mjs +75 -0
- package/dist/file-writer.mjs.map +1 -0
- package/dist/index.d.mts +4 -0
- package/dist/index.mjs +4 -0
- package/dist/metrics.d.mts +48 -0
- package/dist/metrics.d.mts.map +1 -0
- package/dist/metrics.mjs +130 -0
- package/dist/metrics.mjs.map +1 -0
- package/dist/tracing-2kv3HZ07.d.mts +65 -0
- package/dist/tracing-2kv3HZ07.d.mts.map +1 -0
- package/dist/tracing.d.mts +2 -0
- package/dist/tracing.mjs +96 -0
- package/dist/tracing.mjs.map +1 -0
- package/dist/worker.d.mts +173 -0
- package/dist/worker.d.mts.map +1 -0
- package/dist/worker.mjs +468 -0
- package/dist/worker.mjs.map +1 -0
- package/package.json +18 -15
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
//#region src/context.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* AsyncLocalStorage-based context propagation for loggily — Node.js/Bun only.
|
|
4
|
+
*
|
|
5
|
+
* Separated from core logger to allow tree-shaking in browser bundles.
|
|
6
|
+
* When enabled, new spans automatically parent to the current context span,
|
|
7
|
+
* and writeLog() auto-tags with trace_id/span_id from context.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { enableContextPropagation, getCurrentSpan } from "loggily/context"
|
|
12
|
+
*
|
|
13
|
+
* enableContextPropagation()
|
|
14
|
+
*
|
|
15
|
+
* const log = createLogger("myapp")
|
|
16
|
+
* {
|
|
17
|
+
* using span = log.span("request")
|
|
18
|
+
* // All logs and child spans within this async context
|
|
19
|
+
* // automatically inherit trace_id and span_id
|
|
20
|
+
* log.info("inside span") // auto-tagged with trace_id, span_id
|
|
21
|
+
*
|
|
22
|
+
* const current = getCurrentSpan()
|
|
23
|
+
* // current === { spanId: "sp_1", traceId: "tr_1", parentId: null }
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
/** Minimal span context stored in AsyncLocalStorage */
|
|
28
|
+
interface SpanContext {
|
|
29
|
+
readonly spanId: string;
|
|
30
|
+
readonly traceId: string;
|
|
31
|
+
readonly parentId: string | null;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Enable AsyncLocalStorage-based context propagation.
|
|
35
|
+
* Once enabled, new spans automatically parent to the current context span,
|
|
36
|
+
* and log messages are auto-tagged with trace_id/span_id.
|
|
37
|
+
*
|
|
38
|
+
* **Node.js/Bun only** — not available in browser environments.
|
|
39
|
+
*/
|
|
40
|
+
declare function enableContextPropagation(): void;
|
|
41
|
+
/**
|
|
42
|
+
* Disable context propagation.
|
|
43
|
+
* Existing spans continue to work, but new spans won't auto-parent.
|
|
44
|
+
*/
|
|
45
|
+
declare function disableContextPropagation(): void;
|
|
46
|
+
/** Check if context propagation is enabled */
|
|
47
|
+
declare function isContextPropagationEnabled(): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Get the current span context from AsyncLocalStorage.
|
|
50
|
+
* Returns null if no span is active in the current async context,
|
|
51
|
+
* or if context propagation is not enabled.
|
|
52
|
+
*/
|
|
53
|
+
declare function getCurrentSpan(): SpanContext | null;
|
|
54
|
+
/**
|
|
55
|
+
* Enter a span context for the remainder of the current synchronous execution
|
|
56
|
+
* and any async operations started from it. Used by the logger when creating
|
|
57
|
+
* spans with `using` — since `using` doesn't wrap user code in a callback,
|
|
58
|
+
* `enterWith()` is the right primitive.
|
|
59
|
+
*
|
|
60
|
+
* Captures the full previous SpanContext snapshot so it can be restored
|
|
61
|
+
* exactly on exit, even with non-LIFO end() ordering.
|
|
62
|
+
*
|
|
63
|
+
* @internal
|
|
64
|
+
*/
|
|
65
|
+
declare function enterSpanContext(spanId: string, traceId: string, parentId: string | null): void;
|
|
66
|
+
/**
|
|
67
|
+
* Restore the previous span context (called when a span ends).
|
|
68
|
+
* Restores the exact SpanContext snapshot captured at enter time,
|
|
69
|
+
* preventing corruption from non-LIFO end() ordering.
|
|
70
|
+
*
|
|
71
|
+
* @internal
|
|
72
|
+
*/
|
|
73
|
+
declare function exitSpanContext(spanId: string): void;
|
|
74
|
+
/**
|
|
75
|
+
* Run a function within a span context.
|
|
76
|
+
* Used for explicit context scoping (e.g., in request handlers).
|
|
77
|
+
*
|
|
78
|
+
* @param context - The span context to set
|
|
79
|
+
* @param fn - The function to run within the context
|
|
80
|
+
* @returns The return value of fn
|
|
81
|
+
*/
|
|
82
|
+
declare function runInSpanContext<T>(context: SpanContext, fn: () => T): T;
|
|
83
|
+
/**
|
|
84
|
+
* Get the context tags (trace_id, span_id) for the current async context.
|
|
85
|
+
* Used by writeLog() to auto-tag log messages.
|
|
86
|
+
* Returns empty object if context propagation is disabled or no span is active.
|
|
87
|
+
*/
|
|
88
|
+
declare function getContextTags(): Record<string, string>;
|
|
89
|
+
//#endregion
|
|
90
|
+
export { SpanContext, disableContextPropagation, enableContextPropagation, enterSpanContext, exitSpanContext, getContextTags, getCurrentSpan, isContextPropagationEnabled, runInSpanContext };
|
|
91
|
+
//# sourceMappingURL=context.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.mts","names":[],"sources":["../src/context.ts"],"mappings":";;AAgCA;;;;;;;;;AA2BA;;;;;AAuBA;;;;;AAMA;;;;;AASA;AAAA,UAjEiB,WAAA;EAAA,SACN,MAAA;EAAA,SACA,OAAA;EAAA,SACA,QAAA;AAAA;;;;;;;;iBAwBK,wBAAA,CAAA;AAuEhB;;;;AAAA,iBAhDgB,yBAAA,CAAA;AAsEhB;AAAA,iBAhEgB,2BAAA,CAAA;;;;;;iBASA,cAAA,CAAA,GAAkB,WAAA;;;;;;;;;AAiElC;;;iBAjDgB,gBAAA,CAAiB,MAAA,UAAgB,OAAA,UAAiB,QAAA;;;;;;;;iBAiBlD,eAAA,CAAgB,MAAA;;;;;;;;;iBAsBhB,gBAAA,GAAA,CAAoB,OAAA,EAAS,WAAA,EAAa,EAAA,QAAU,CAAA,GAAI,CAAA;;;;;;iBAUxD,cAAA,CAAA,GAAkB,MAAA"}
|
package/dist/context.mjs
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { i as _setContextHooks, n as _clearContextHooks } from "./core-BDFU50FQ.mjs";
|
|
2
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
3
|
+
//#region src/context.ts
|
|
4
|
+
/**
|
|
5
|
+
* AsyncLocalStorage-based context propagation for loggily — Node.js/Bun only.
|
|
6
|
+
*
|
|
7
|
+
* Separated from core logger to allow tree-shaking in browser bundles.
|
|
8
|
+
* When enabled, new spans automatically parent to the current context span,
|
|
9
|
+
* and writeLog() auto-tags with trace_id/span_id from context.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { enableContextPropagation, getCurrentSpan } from "loggily/context"
|
|
14
|
+
*
|
|
15
|
+
* enableContextPropagation()
|
|
16
|
+
*
|
|
17
|
+
* const log = createLogger("myapp")
|
|
18
|
+
* {
|
|
19
|
+
* using span = log.span("request")
|
|
20
|
+
* // All logs and child spans within this async context
|
|
21
|
+
* // automatically inherit trace_id and span_id
|
|
22
|
+
* log.info("inside span") // auto-tagged with trace_id, span_id
|
|
23
|
+
*
|
|
24
|
+
* const current = getCurrentSpan()
|
|
25
|
+
* // current === { spanId: "sp_1", traceId: "tr_1", parentId: null }
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
let storage = null;
|
|
30
|
+
let contextEnabled = false;
|
|
31
|
+
/**
|
|
32
|
+
* Map from spanId → the SpanContext that was active when the span was entered.
|
|
33
|
+
* Used to restore the exact previous context on exit, avoiding corruption
|
|
34
|
+
* from non-LIFO end() ordering.
|
|
35
|
+
*/
|
|
36
|
+
const previousContexts = /* @__PURE__ */ new Map();
|
|
37
|
+
/**
|
|
38
|
+
* Enable AsyncLocalStorage-based context propagation.
|
|
39
|
+
* Once enabled, new spans automatically parent to the current context span,
|
|
40
|
+
* and log messages are auto-tagged with trace_id/span_id.
|
|
41
|
+
*
|
|
42
|
+
* **Node.js/Bun only** — not available in browser environments.
|
|
43
|
+
*/
|
|
44
|
+
function enableContextPropagation() {
|
|
45
|
+
if (!storage) storage = new AsyncLocalStorage();
|
|
46
|
+
contextEnabled = true;
|
|
47
|
+
_setContextHooks({
|
|
48
|
+
getContextTags,
|
|
49
|
+
getContextParent() {
|
|
50
|
+
const span = getCurrentSpan();
|
|
51
|
+
if (!span) return null;
|
|
52
|
+
return {
|
|
53
|
+
spanId: span.spanId,
|
|
54
|
+
traceId: span.traceId
|
|
55
|
+
};
|
|
56
|
+
},
|
|
57
|
+
enterContext: enterSpanContext,
|
|
58
|
+
exitContext: exitSpanContext
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Disable context propagation.
|
|
63
|
+
* Existing spans continue to work, but new spans won't auto-parent.
|
|
64
|
+
*/
|
|
65
|
+
function disableContextPropagation() {
|
|
66
|
+
contextEnabled = false;
|
|
67
|
+
_clearContextHooks();
|
|
68
|
+
}
|
|
69
|
+
/** Check if context propagation is enabled */
|
|
70
|
+
function isContextPropagationEnabled() {
|
|
71
|
+
return contextEnabled;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Get the current span context from AsyncLocalStorage.
|
|
75
|
+
* Returns null if no span is active in the current async context,
|
|
76
|
+
* or if context propagation is not enabled.
|
|
77
|
+
*/
|
|
78
|
+
function getCurrentSpan() {
|
|
79
|
+
if (!contextEnabled || !storage) return null;
|
|
80
|
+
return storage.getStore() ?? null;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Enter a span context for the remainder of the current synchronous execution
|
|
84
|
+
* and any async operations started from it. Used by the logger when creating
|
|
85
|
+
* spans with `using` — since `using` doesn't wrap user code in a callback,
|
|
86
|
+
* `enterWith()` is the right primitive.
|
|
87
|
+
*
|
|
88
|
+
* Captures the full previous SpanContext snapshot so it can be restored
|
|
89
|
+
* exactly on exit, even with non-LIFO end() ordering.
|
|
90
|
+
*
|
|
91
|
+
* @internal
|
|
92
|
+
*/
|
|
93
|
+
function enterSpanContext(spanId, traceId, parentId) {
|
|
94
|
+
if (!contextEnabled || !storage) return;
|
|
95
|
+
const previous = storage.getStore() ?? null;
|
|
96
|
+
previousContexts.set(spanId, previous);
|
|
97
|
+
storage.enterWith({
|
|
98
|
+
spanId,
|
|
99
|
+
traceId,
|
|
100
|
+
parentId
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Restore the previous span context (called when a span ends).
|
|
105
|
+
* Restores the exact SpanContext snapshot captured at enter time,
|
|
106
|
+
* preventing corruption from non-LIFO end() ordering.
|
|
107
|
+
*
|
|
108
|
+
* @internal
|
|
109
|
+
*/
|
|
110
|
+
function exitSpanContext(spanId) {
|
|
111
|
+
if (!contextEnabled || !storage) return;
|
|
112
|
+
const previous = previousContexts.get(spanId);
|
|
113
|
+
previousContexts.delete(spanId);
|
|
114
|
+
if (previous) storage.enterWith(previous);
|
|
115
|
+
else storage.enterWith(void 0);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Run a function within a span context.
|
|
119
|
+
* Used for explicit context scoping (e.g., in request handlers).
|
|
120
|
+
*
|
|
121
|
+
* @param context - The span context to set
|
|
122
|
+
* @param fn - The function to run within the context
|
|
123
|
+
* @returns The return value of fn
|
|
124
|
+
*/
|
|
125
|
+
function runInSpanContext(context, fn) {
|
|
126
|
+
if (!contextEnabled || !storage) return fn();
|
|
127
|
+
return storage.run(context, fn);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Get the context tags (trace_id, span_id) for the current async context.
|
|
131
|
+
* Used by writeLog() to auto-tag log messages.
|
|
132
|
+
* Returns empty object if context propagation is disabled or no span is active.
|
|
133
|
+
*/
|
|
134
|
+
function getContextTags() {
|
|
135
|
+
const span = getCurrentSpan();
|
|
136
|
+
if (!span) return {};
|
|
137
|
+
return {
|
|
138
|
+
trace_id: span.traceId,
|
|
139
|
+
span_id: span.spanId
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
//#endregion
|
|
143
|
+
export { disableContextPropagation, enableContextPropagation, enterSpanContext, exitSpanContext, getContextTags, getCurrentSpan, isContextPropagationEnabled, runInSpanContext };
|
|
144
|
+
|
|
145
|
+
//# sourceMappingURL=context.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.mjs","names":[],"sources":["../src/context.ts"],"sourcesContent":["/**\n * AsyncLocalStorage-based context propagation for loggily — Node.js/Bun only.\n *\n * Separated from core logger to allow tree-shaking in browser bundles.\n * When enabled, new spans automatically parent to the current context span,\n * and writeLog() auto-tags with trace_id/span_id from context.\n *\n * @example\n * ```typescript\n * import { enableContextPropagation, getCurrentSpan } from \"loggily/context\"\n *\n * enableContextPropagation()\n *\n * const log = createLogger(\"myapp\")\n * {\n * using span = log.span(\"request\")\n * // All logs and child spans within this async context\n * // automatically inherit trace_id and span_id\n * log.info(\"inside span\") // auto-tagged with trace_id, span_id\n *\n * const current = getCurrentSpan()\n * // current === { spanId: \"sp_1\", traceId: \"tr_1\", parentId: null }\n * }\n * ```\n */\n\nimport { AsyncLocalStorage } from \"node:async_hooks\"\nimport { _setContextHooks, _clearContextHooks } from \"./core.js\"\n\n// ============ Types ============\n\n/** Minimal span context stored in AsyncLocalStorage */\nexport interface SpanContext {\n readonly spanId: string\n readonly traceId: string\n readonly parentId: string | null\n}\n\n// ============ State ============\n\nlet storage: AsyncLocalStorage<SpanContext> | null = null\nlet contextEnabled = false\n\n/**\n * Map from spanId → the SpanContext that was active when the span was entered.\n * Used to restore the exact previous context on exit, avoiding corruption\n * from non-LIFO end() ordering.\n */\nconst previousContexts = new Map<string, SpanContext | null>()\n\n// ============ API ============\n\n/**\n * Enable AsyncLocalStorage-based context propagation.\n * Once enabled, new spans automatically parent to the current context span,\n * and log messages are auto-tagged with trace_id/span_id.\n *\n * **Node.js/Bun only** — not available in browser environments.\n */\nexport function enableContextPropagation(): void {\n if (!storage) {\n storage = new AsyncLocalStorage<SpanContext>()\n }\n contextEnabled = true\n\n // Register hooks with core.ts\n _setContextHooks({\n getContextTags,\n getContextParent() {\n const span = getCurrentSpan()\n if (!span) return null\n return { spanId: span.spanId, traceId: span.traceId }\n },\n enterContext: enterSpanContext,\n exitContext: exitSpanContext,\n })\n}\n\n/**\n * Disable context propagation.\n * Existing spans continue to work, but new spans won't auto-parent.\n */\nexport function disableContextPropagation(): void {\n contextEnabled = false\n _clearContextHooks()\n}\n\n/** Check if context propagation is enabled */\nexport function isContextPropagationEnabled(): boolean {\n return contextEnabled\n}\n\n/**\n * Get the current span context from AsyncLocalStorage.\n * Returns null if no span is active in the current async context,\n * or if context propagation is not enabled.\n */\nexport function getCurrentSpan(): SpanContext | null {\n if (!contextEnabled || !storage) return null\n return storage.getStore() ?? null\n}\n\n/**\n * Enter a span context for the remainder of the current synchronous execution\n * and any async operations started from it. Used by the logger when creating\n * spans with `using` — since `using` doesn't wrap user code in a callback,\n * `enterWith()` is the right primitive.\n *\n * Captures the full previous SpanContext snapshot so it can be restored\n * exactly on exit, even with non-LIFO end() ordering.\n *\n * @internal\n */\nexport function enterSpanContext(spanId: string, traceId: string, parentId: string | null): void {\n if (!contextEnabled || !storage) return\n\n // Capture the full previous context before overwriting\n const previous = storage.getStore() ?? null\n previousContexts.set(spanId, previous)\n\n storage.enterWith({ spanId, traceId, parentId })\n}\n\n/**\n * Restore the previous span context (called when a span ends).\n * Restores the exact SpanContext snapshot captured at enter time,\n * preventing corruption from non-LIFO end() ordering.\n *\n * @internal\n */\nexport function exitSpanContext(spanId: string): void {\n if (!contextEnabled || !storage) return\n\n const previous = previousContexts.get(spanId)\n previousContexts.delete(spanId)\n\n if (previous) {\n storage.enterWith(previous)\n } else {\n // No previous context — exit entirely\n storage.enterWith(undefined as unknown as SpanContext)\n }\n}\n\n/**\n * Run a function within a span context.\n * Used for explicit context scoping (e.g., in request handlers).\n *\n * @param context - The span context to set\n * @param fn - The function to run within the context\n * @returns The return value of fn\n */\nexport function runInSpanContext<T>(context: SpanContext, fn: () => T): T {\n if (!contextEnabled || !storage) return fn()\n return storage.run(context, fn)\n}\n\n/**\n * Get the context tags (trace_id, span_id) for the current async context.\n * Used by writeLog() to auto-tag log messages.\n * Returns empty object if context propagation is disabled or no span is active.\n */\nexport function getContextTags(): Record<string, string> {\n const span = getCurrentSpan()\n if (!span) return {}\n return {\n trace_id: span.traceId,\n span_id: span.spanId,\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCA,IAAI,UAAiD;AACrD,IAAI,iBAAiB;;;;;;AAOrB,MAAM,mCAAmB,IAAI,KAAiC;;;;;;;;AAW9D,SAAgB,2BAAiC;AAC/C,KAAI,CAAC,QACH,WAAU,IAAI,mBAAgC;AAEhD,kBAAiB;AAGjB,kBAAiB;EACf;EACA,mBAAmB;GACjB,MAAM,OAAO,gBAAgB;AAC7B,OAAI,CAAC,KAAM,QAAO;AAClB,UAAO;IAAE,QAAQ,KAAK;IAAQ,SAAS,KAAK;IAAS;;EAEvD,cAAc;EACd,aAAa;EACd,CAAC;;;;;;AAOJ,SAAgB,4BAAkC;AAChD,kBAAiB;AACjB,qBAAoB;;;AAItB,SAAgB,8BAAuC;AACrD,QAAO;;;;;;;AAQT,SAAgB,iBAAqC;AACnD,KAAI,CAAC,kBAAkB,CAAC,QAAS,QAAO;AACxC,QAAO,QAAQ,UAAU,IAAI;;;;;;;;;;;;;AAc/B,SAAgB,iBAAiB,QAAgB,SAAiB,UAA+B;AAC/F,KAAI,CAAC,kBAAkB,CAAC,QAAS;CAGjC,MAAM,WAAW,QAAQ,UAAU,IAAI;AACvC,kBAAiB,IAAI,QAAQ,SAAS;AAEtC,SAAQ,UAAU;EAAE;EAAQ;EAAS;EAAU,CAAC;;;;;;;;;AAUlD,SAAgB,gBAAgB,QAAsB;AACpD,KAAI,CAAC,kBAAkB,CAAC,QAAS;CAEjC,MAAM,WAAW,iBAAiB,IAAI,OAAO;AAC7C,kBAAiB,OAAO,OAAO;AAE/B,KAAI,SACF,SAAQ,UAAU,SAAS;KAG3B,SAAQ,UAAU,KAAA,EAAoC;;;;;;;;;;AAY1D,SAAgB,iBAAoB,SAAsB,IAAgB;AACxE,KAAI,CAAC,kBAAkB,CAAC,QAAS,QAAO,IAAI;AAC5C,QAAO,QAAQ,IAAI,SAAS,GAAG;;;;;;;AAQjC,SAAgB,iBAAyC;CACvD,MAAM,OAAO,gBAAgB;AAC7B,KAAI,CAAC,KAAM,QAAO,EAAE;AACpB,QAAO;EACL,UAAU,KAAK;EACf,SAAS,KAAK;EACf"}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
//#region src/core.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* loggily - Structured logging with spans
|
|
4
|
+
*
|
|
5
|
+
* Logger-first architecture: Span = Logger + Duration
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* const log = createLogger('myapp')
|
|
9
|
+
*
|
|
10
|
+
* // Simple logging
|
|
11
|
+
* log.info('starting')
|
|
12
|
+
*
|
|
13
|
+
* // Lazy messages (function not called when level is disabled)
|
|
14
|
+
* log.debug?.(() => `expensive: ${computeState()}`)
|
|
15
|
+
*
|
|
16
|
+
* // Child loggers with context fields
|
|
17
|
+
* const reqLog = log.child({ requestId: 'abc' })
|
|
18
|
+
* reqLog.info('handling request') // includes requestId in every message
|
|
19
|
+
*
|
|
20
|
+
* // With timing (span)
|
|
21
|
+
* {
|
|
22
|
+
* using task = log.span('import', { file: 'data.csv' })
|
|
23
|
+
* task.info('importing')
|
|
24
|
+
* task.spanData.count = 42 // Set span attributes
|
|
25
|
+
* // Auto-disposal on block exit → SPAN myapp:import (15ms)
|
|
26
|
+
* }
|
|
27
|
+
*/
|
|
28
|
+
/** Data passed to span recorders on disposal */
|
|
29
|
+
interface SpanRecord {
|
|
30
|
+
readonly name: string;
|
|
31
|
+
readonly durationMs: number;
|
|
32
|
+
}
|
|
33
|
+
/** Interface for span duration recording — implemented by createMetricsCollector() in metrics.ts */
|
|
34
|
+
interface SpanRecorder {
|
|
35
|
+
recordSpan(data: SpanRecord): void;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Ambient span recorder — auto-records when TRACE is active.
|
|
39
|
+
* Set by metrics.ts on import; can be replaced for testing.
|
|
40
|
+
* @internal
|
|
41
|
+
*/
|
|
42
|
+
declare let _ambientRecorder: SpanRecorder | null;
|
|
43
|
+
declare function _setAmbientRecorder(recorder: SpanRecorder | null): void;
|
|
44
|
+
/** Log levels that produce output */
|
|
45
|
+
type OutputLogLevel = "trace" | "debug" | "info" | "warn" | "error";
|
|
46
|
+
/** All log levels including silent (for filtering) */
|
|
47
|
+
type LogLevel = OutputLogLevel | "silent";
|
|
48
|
+
/** Message can be a string or a lazy function that returns a string */
|
|
49
|
+
type LazyMessage = string | (() => string);
|
|
50
|
+
/** Span props can be an object or a lazy function (skipped entirely via ?. when tracing is off) */
|
|
51
|
+
type LazyProps = Record<string, unknown> | (() => Record<string, unknown>);
|
|
52
|
+
/** Span data accessible via logger.spanData */
|
|
53
|
+
interface SpanData {
|
|
54
|
+
readonly id: string;
|
|
55
|
+
readonly traceId: string;
|
|
56
|
+
readonly parentId: string | null;
|
|
57
|
+
readonly startTime: number;
|
|
58
|
+
readonly endTime: number | null;
|
|
59
|
+
readonly duration: number | null;
|
|
60
|
+
/** Custom attributes - set via direct property assignment */
|
|
61
|
+
[key: string]: unknown;
|
|
62
|
+
}
|
|
63
|
+
/** Logger interface */
|
|
64
|
+
interface Logger {
|
|
65
|
+
/** Logger namespace (e.g., 'myapp:import') */
|
|
66
|
+
readonly name: string;
|
|
67
|
+
/** Props inherited from parent + own props */
|
|
68
|
+
readonly props: Readonly<Record<string, unknown>>;
|
|
69
|
+
/** Span data (non-null for span loggers, null for regular loggers) */
|
|
70
|
+
readonly spanData: SpanData | null;
|
|
71
|
+
trace(message: LazyMessage, data?: Record<string, unknown>): void;
|
|
72
|
+
debug(message: LazyMessage, data?: Record<string, unknown>): void;
|
|
73
|
+
info(message: LazyMessage, data?: Record<string, unknown>): void;
|
|
74
|
+
warn(message: LazyMessage, data?: Record<string, unknown>): void;
|
|
75
|
+
error(message: LazyMessage, data?: Record<string, unknown>): void;
|
|
76
|
+
/** Error overload - extracts message, stack, code from Error */
|
|
77
|
+
error(error: Error, data?: Record<string, unknown>): void;
|
|
78
|
+
/** Create child logger (extends namespace, inherits props) */
|
|
79
|
+
logger(namespace?: string, props?: Record<string, unknown>): Logger;
|
|
80
|
+
/** Create child span (extends namespace, inherits props, adds timing). Props can be lazy. */
|
|
81
|
+
span(namespace?: string, props?: LazyProps): SpanLogger;
|
|
82
|
+
/** Create child logger with context fields merged into every message */
|
|
83
|
+
child(context: Record<string, unknown>): Logger;
|
|
84
|
+
/** @deprecated Use .logger() instead for namespace-based children */
|
|
85
|
+
child(context: string): Logger;
|
|
86
|
+
/** End span manually (alternative to using keyword) */
|
|
87
|
+
end(): void;
|
|
88
|
+
}
|
|
89
|
+
/** Span logger - Logger with active span (spanData is non-null, implements Disposable) */
|
|
90
|
+
interface SpanLogger extends Logger, Disposable {
|
|
91
|
+
readonly spanData: SpanData & {
|
|
92
|
+
/** Mutable attributes - set directly */[key: string]: unknown;
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
type LogWriter = (formatted: string, level: string) => void;
|
|
96
|
+
/** Add a writer that receives all formatted log output. Returns unsubscribe. */
|
|
97
|
+
declare function addWriter(writer: LogWriter): () => void;
|
|
98
|
+
/** Suppress console output from the logger (writers still receive output). */
|
|
99
|
+
declare function setSuppressConsole(value: boolean): void;
|
|
100
|
+
/** Output mode for writeLog */
|
|
101
|
+
type OutputMode = "console" | "stderr" | "writers-only";
|
|
102
|
+
/** Set output mode for log messages (not spans — spans always use stderr). */
|
|
103
|
+
declare function setOutputMode(mode: OutputMode): void;
|
|
104
|
+
/** Get current output mode */
|
|
105
|
+
declare function getOutputMode(): OutputMode;
|
|
106
|
+
/** Set minimum log level */
|
|
107
|
+
declare function setLogLevel(level: LogLevel): void;
|
|
108
|
+
/** Get current log level */
|
|
109
|
+
declare function getLogLevel(): LogLevel;
|
|
110
|
+
/** Enable span output */
|
|
111
|
+
declare function enableSpans(): void;
|
|
112
|
+
/** Disable span output */
|
|
113
|
+
declare function disableSpans(): void;
|
|
114
|
+
/** Check if spans are enabled */
|
|
115
|
+
declare function spansAreEnabled(): boolean;
|
|
116
|
+
/**
|
|
117
|
+
* Set trace filter for namespace-based span output control.
|
|
118
|
+
* Only spans matching these namespace prefixes will be output.
|
|
119
|
+
* @param namespaces - Array of namespace prefixes, or null to disable filtering
|
|
120
|
+
*/
|
|
121
|
+
declare function setTraceFilter(namespaces: string[] | null): void;
|
|
122
|
+
/** Get current trace filter (null means no filtering) */
|
|
123
|
+
declare function getTraceFilter(): string[] | null;
|
|
124
|
+
/**
|
|
125
|
+
* Set debug namespace filter (like the `debug` npm package).
|
|
126
|
+
* When set, only loggers matching these namespace prefixes produce output.
|
|
127
|
+
* Supports negative patterns with `-` prefix (e.g., ["-km:noisy"]).
|
|
128
|
+
* Also ensures log level is at least `debug`.
|
|
129
|
+
* @param namespaces - Array of namespace prefixes (prefix with `-` to exclude), or null to disable
|
|
130
|
+
*/
|
|
131
|
+
declare function setDebugFilter(namespaces: string[] | null): void;
|
|
132
|
+
/** Get current debug namespace filter (null means no filtering) */
|
|
133
|
+
declare function getDebugFilter(): string[] | null;
|
|
134
|
+
/** Output format: human-readable console or structured JSON */
|
|
135
|
+
type LogFormat = "console" | "json";
|
|
136
|
+
/** Set log output format */
|
|
137
|
+
declare function setLogFormat(format: LogFormat): void;
|
|
138
|
+
/** Get current log output format */
|
|
139
|
+
declare function getLogFormat(): LogFormat;
|
|
140
|
+
declare function resetIds(): void;
|
|
141
|
+
/**
|
|
142
|
+
* Register context propagation hooks (called by context.ts).
|
|
143
|
+
* @internal
|
|
144
|
+
*/
|
|
145
|
+
declare function _setContextHooks(hooks: {
|
|
146
|
+
getContextTags: () => Record<string, string>;
|
|
147
|
+
getContextParent: () => {
|
|
148
|
+
spanId: string;
|
|
149
|
+
traceId: string;
|
|
150
|
+
} | null;
|
|
151
|
+
enterContext: (spanId: string, traceId: string, parentId: string | null) => void;
|
|
152
|
+
exitContext: (spanId: string) => void;
|
|
153
|
+
}): void;
|
|
154
|
+
/**
|
|
155
|
+
* Clear context propagation hooks (called by disableContextPropagation).
|
|
156
|
+
* @internal
|
|
157
|
+
*/
|
|
158
|
+
declare function _clearContextHooks(): void;
|
|
159
|
+
declare function writeSpan(namespace: string, duration: number, attrs: Record<string, unknown>): void;
|
|
160
|
+
interface SpanDataFields {
|
|
161
|
+
id: string;
|
|
162
|
+
traceId: string;
|
|
163
|
+
parentId: string | null;
|
|
164
|
+
startTime: number;
|
|
165
|
+
endTime: number | null;
|
|
166
|
+
duration: number | null;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Create a proxy that exposes span metadata as readonly and custom attributes as writable.
|
|
170
|
+
* Shared between core logger spans and worker logger spans.
|
|
171
|
+
*/
|
|
172
|
+
declare function createSpanDataProxy(getFields: () => SpanDataFields, attrs: Record<string, unknown>): SpanData;
|
|
173
|
+
/** Enable span collection for analysis */
|
|
174
|
+
declare function startCollecting(): void;
|
|
175
|
+
/** Stop collecting and return collected spans */
|
|
176
|
+
declare function stopCollecting(): SpanData[];
|
|
177
|
+
/** Get collected spans */
|
|
178
|
+
declare function getCollectedSpans(): SpanData[];
|
|
179
|
+
/** Clear collected spans */
|
|
180
|
+
declare function clearCollectedSpans(): void;
|
|
181
|
+
/**
|
|
182
|
+
* Logger with optional methods — returns undefined for disabled levels.
|
|
183
|
+
* Use with optional chaining: `log.debug?.("msg")` for zero-overhead when disabled.
|
|
184
|
+
*
|
|
185
|
+
* Defined as an explicit interface (not Omit<Logger,...>) so that
|
|
186
|
+
* oxlint's type-aware mode can resolve it without advanced type inference.
|
|
187
|
+
*/
|
|
188
|
+
interface ConditionalLogger {
|
|
189
|
+
readonly name: string;
|
|
190
|
+
readonly props: Readonly<Record<string, unknown>>;
|
|
191
|
+
readonly spanData: SpanData | null;
|
|
192
|
+
trace?: (message: LazyMessage, data?: Record<string, unknown>) => void;
|
|
193
|
+
debug?: (message: LazyMessage, data?: Record<string, unknown>) => void;
|
|
194
|
+
info?: (message: LazyMessage, data?: Record<string, unknown>) => void;
|
|
195
|
+
warn?: (message: LazyMessage, data?: Record<string, unknown>) => void;
|
|
196
|
+
error?: {
|
|
197
|
+
(message: LazyMessage, data?: Record<string, unknown>): void;
|
|
198
|
+
(error: Error, data?: Record<string, unknown>): void;
|
|
199
|
+
};
|
|
200
|
+
logger(namespace?: string, props?: Record<string, unknown>): Logger;
|
|
201
|
+
span(namespace?: string, props?: LazyProps): SpanLogger;
|
|
202
|
+
child(context: Record<string, unknown>): Logger;
|
|
203
|
+
child(context: string): Logger;
|
|
204
|
+
end(): void;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Create a logger for a component.
|
|
208
|
+
* Returns undefined for disabled levels - use with optional chaining for zero overhead.
|
|
209
|
+
*
|
|
210
|
+
* Log levels (most → least verbose): trace < debug < info < warn < error < silent
|
|
211
|
+
* Default level: info (trace and debug disabled)
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* const log = createLogger('myapp')
|
|
215
|
+
*
|
|
216
|
+
* // All methods support ?. for zero-overhead when disabled
|
|
217
|
+
* log.trace?.(`very verbose: ${expensiveDebug()}`) // Skipped at info level
|
|
218
|
+
* log.debug?.(`debug: ${getState()}`) // Skipped at info level
|
|
219
|
+
* log.info?.('starting') // Enabled at info level
|
|
220
|
+
* log.warn?.('deprecated') // Enabled at info level
|
|
221
|
+
* log.error?.('failed') // Enabled at info level
|
|
222
|
+
*
|
|
223
|
+
* // With -q flag or LOG_LEVEL=warn:
|
|
224
|
+
* log.info?.('starting') // Now skipped - info < warn
|
|
225
|
+
*
|
|
226
|
+
* // With initial props
|
|
227
|
+
* const log = createLogger('myapp', { version: '1.0' })
|
|
228
|
+
*
|
|
229
|
+
* // Create spans
|
|
230
|
+
* {
|
|
231
|
+
* using task = log.span('import', { file: 'data.csv' })
|
|
232
|
+
* task.info?.('importing')
|
|
233
|
+
* task.spanData.count = 42
|
|
234
|
+
* }
|
|
235
|
+
*/
|
|
236
|
+
declare function createLogger(name: string, props?: Record<string, unknown>): ConditionalLogger;
|
|
237
|
+
//#endregion
|
|
238
|
+
export { setDebugFilter as A, getCollectedSpans as C, getOutputMode as D, getLogLevel as E, setTraceFilter as F, spansAreEnabled as I, startCollecting as L, setLogLevel as M, setOutputMode as N, getTraceFilter as O, setSuppressConsole as P, stopCollecting as R, enableSpans as S, getLogFormat as T, addWriter as _, LogLevel as a, createSpanDataProxy as b, OutputMode as c, SpanRecord as d, SpanRecorder as f, _setContextHooks as g, _setAmbientRecorder as h, LogFormat as i, setLogFormat as j, resetIds as k, SpanData as l, _clearContextHooks as m, LazyMessage as n, Logger as o, _ambientRecorder as p, LazyProps as r, OutputLogLevel as s, ConditionalLogger as t, SpanLogger as u, clearCollectedSpans as v, getDebugFilter as w, disableSpans as x, createLogger as y, writeSpan as z };
|
|
239
|
+
//# sourceMappingURL=core-7D7sstHl.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core-7D7sstHl.d.mts","names":[],"sources":["../src/core.ts"],"mappings":";;AAgCA;;;;;AAMA;;;;;;;;;AASA;;;;;AACA;;;;;AA0BA;;UA1CiB,UAAA;EAAA,SACN,IAAA;EAAA,SACA,UAAA;AAAA;;UAIM,YAAA;EACf,UAAA,CAAW,IAAA,EAAM,UAAA;AAAA;AAyCnB;;;;;AAAA,YAjCW,gBAAA,EAAkB,YAAA;AAAA,iBACb,mBAAA,CAAoB,QAAA,EAAU,YAAA;;KA0BlC,cAAA;;KAGA,QAAA,GAAW,cAAA;;KAGX,WAAA;;KAGA,SAAA,GAAY,MAAA,2BAAiC,MAAA;;UAGxC,QAAA;EAAA,SACN,EAAA;EAAA,SACA,OAAA;EAAA,SACA,QAAA;EAAA,SACA,SAAA;EAAA,SACA,OAAA;EAAA,SACA,QAAA;EAMM;EAAA,CAJd,GAAA;AAAA;;UAIc,MAAA;EAMI;EAAA,SAJV,IAAA;EAO0B;EAAA,SAL1B,KAAA,EAAO,QAAA,CAAS,MAAA;EAMU;EAAA,SAJ1B,QAAA,EAAU,QAAA;EAGnB,KAAA,CAAM,OAAA,EAAS,WAAA,EAAa,IAAA,GAAO,MAAA;EACnC,KAAA,CAAM,OAAA,EAAS,WAAA,EAAa,IAAA,GAAO,MAAA;EACnC,IAAA,CAAK,OAAA,EAAS,WAAA,EAAa,IAAA,GAAO,MAAA;EAClC,IAAA,CAAK,OAAA,EAAS,WAAA,EAAa,IAAA,GAAO,MAAA;EAClC,KAAA,CAAM,OAAA,EAAS,WAAA,EAAa,IAAA,GAAO,MAAA;EAEtB;EAAb,KAAA,CAAM,KAAA,EAAO,KAAA,EAAO,IAAA,GAAO,MAAA;EAIQ;EAAnC,MAAA,CAAO,SAAA,WAAoB,KAAA,GAAQ,MAAA,oBAA0B,MAAA;EAE5B;EAAjC,IAAA,CAAK,SAAA,WAAoB,KAAA,GAAQ,SAAA,GAAY,UAAA;EAG9B;EAAf,KAAA,CAAM,OAAA,EAAS,MAAA,oBAA0B,MAAA;EAEjB;EAAxB,KAAA,CAAM,OAAA,WAAkB,MAAA;EAAM;EAG9B,GAAA;AAAA;;UAIe,UAAA,SAAmB,MAAA,EAAQ,UAAA;EAAA,SACjC,QAAA,EAAU,QAAA;IA5BA,yCA8BhB,GAAA;EAAA;AAAA;AAAA,KAMA,SAAA,IAAa,SAAA,UAAmB,KAAA;;iBAIrB,SAAA,CAAU,MAAA,EAAQ,SAAA;;iBAWlB,kBAAA,CAAmB,KAAA;;KAKvB,UAAA;;iBAII,aAAA,CAAc,IAAA,EAAM,UAAA;;iBAKpB,aAAA,CAAA,GAAiB,UAAA;;iBA8EjB,WAAA,CAAY,KAAA,EAAO,QAAA;;iBAKnB,WAAA,CAAA,GAAe,QAAA;;iBAKf,WAAA,CAAA;;iBAKA,YAAA,CAAA;;iBAKA,eAAA,CAAA;;;;;;iBASA,cAAA,CAAe,UAAA;;iBAUf,cAAA,CAAA;;;;;;;;iBAWA,cAAA,CAAe,UAAA;;iBAef,cAAA,CAAA;;KAWJ,SAAA;;iBAOI,YAAA,CAAa,MAAA,EAAQ,SAAA;;iBAKrB,YAAA,CAAA,GAAgB,SAAA;AAAA,iBAchB,QAAA,CAAA;;AA1NhB;;;iBAmPgB,gBAAA,CAAiB,KAAA;EAC/B,cAAA,QAAsB,MAAA;EACtB,gBAAA;IAA0B,MAAA;IAAgB,OAAA;EAAA;EAC1C,YAAA,GAAe,MAAA,UAAgB,OAAA,UAAiB,QAAA;EAChD,WAAA,GAAc,MAAA;AAAA;;;;AAlPf;iBA8Pe,kBAAA,CAAA;AAAA,iBA4JA,SAAA,CAAU,SAAA,UAAmB,QAAA,UAAkB,KAAA,EAAO,MAAA;AAAA,UAe5D,cAAA;EACR,EAAA;EACA,OAAA;EACA,QAAA;EACA,SAAA;EACA,OAAA;EACA,QAAA;AAAA;;;;;iBAOc,mBAAA,CAAoB,SAAA,QAAiB,cAAA,EAAgB,KAAA,EAAO,MAAA,oBAA0B,QAAA;;iBAkNtF,eAAA,CAAA;;iBAMA,cAAA,CAAA,GAAkB,QAAA;AAlnBlC;AAAA,iBAwnBgB,iBAAA,CAAA,GAAqB,QAAA;;iBAKrB,mBAAA,CAAA;;AAxnBhB;;;;;AA8EA;UAujBiB,iBAAA;EAAA,SACN,IAAA;EAAA,SACA,KAAA,EAAO,QAAA,CAAS,MAAA;EAAA,SAChB,QAAA,EAAU,QAAA;EAEnB,KAAA,IAAS,OAAA,EAAS,WAAA,EAAa,IAAA,GAAO,MAAA;EACtC,KAAA,IAAS,OAAA,EAAS,WAAA,EAAa,IAAA,GAAO,MAAA;EACtC,IAAA,IAAQ,OAAA,EAAS,WAAA,EAAa,IAAA,GAAO,MAAA;EACrC,IAAA,IAAQ,OAAA,EAAS,WAAA,EAAa,IAAA,GAAO,MAAA;EACrC,KAAA;IAAA,CACG,OAAA,EAAS,WAAA,EAAa,IAAA,GAAO,MAAA;IAAA,CAC7B,KAAA,EAAO,KAAA,EAAO,IAAA,GAAO,MAAA;EAAA;EAGxB,MAAA,CAAO,SAAA,WAAoB,KAAA,GAAQ,MAAA,oBAA0B,MAAA;EAC7D,IAAA,CAAK,SAAA,WAAoB,KAAA,GAAQ,SAAA,GAAY,UAAA;EAC7C,KAAA,CAAM,OAAA,EAAS,MAAA,oBAA0B,MAAA;EACzC,KAAA,CAAM,OAAA,WAAkB,MAAA;EACxB,GAAA;AAAA;;AArjBF;;;;;AASA;;;;;AAUA;;;;;AAWA;;;;;AAeA;;;;;AAWA;;;;iBA8hBgB,YAAA,CAAa,IAAA,UAAc,KAAA,GAAQ,MAAA,oBAA0B,iBAAA"}
|