workers-axiom 0.1.0 → 0.1.1
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/README.md +3 -0
- package/dist/producer/index.d.ts +3 -3
- package/dist/producer/index.d.ts.map +1 -1
- package/dist/producer/index.js +2 -2
- package/dist/producer/index.js.map +1 -1
- package/dist/producer/logger.d.ts +24 -3
- package/dist/producer/logger.d.ts.map +1 -1
- package/dist/producer/logger.js +21 -5
- package/dist/producer/logger.js.map +1 -1
- package/dist/producer/tracing/index.d.ts +2 -2
- package/dist/producer/tracing/index.d.ts.map +1 -1
- package/dist/producer/tracing/index.js +2 -2
- package/dist/producer/tracing/index.js.map +1 -1
- package/dist/producer/tracing/span.d.ts +53 -4
- package/dist/producer/tracing/span.d.ts.map +1 -1
- package/dist/producer/tracing/span.js +68 -21
- package/dist/producer/tracing/span.js.map +1 -1
- package/dist/tail/index.d.ts +1 -1
- package/dist/tail/index.d.ts.map +1 -1
- package/dist/tail/index.js +3 -3
- package/dist/tail/index.js.map +1 -1
- package/dist/tail/spans.d.ts +1 -1
- package/dist/tail/spans.d.ts.map +1 -1
- package/package.json +6 -7
- package/src/producer/index.ts +4 -3
- package/src/producer/logger.ts +49 -6
- package/src/producer/tracing/index.ts +5 -2
- package/src/producer/tracing/span.ts +108 -23
- package/src/tail/index.ts +3 -3
- package/src/tail/spans.ts +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# workers-axiom
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/workers-axiom)
|
|
4
|
+
[](./LICENSE)
|
|
5
|
+
|
|
3
6
|
Structured logging, tracing, and metrics for Cloudflare Workers, with an Axiom tail-worker sink.
|
|
4
7
|
|
|
5
8
|
> **Status:** used internally by Sapt. Open source, MIT-licensed. PRs welcome, support is best-effort.
|
package/dist/producer/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { LogLevel, createLogger, noopLogger, withTrace, type KVLike, type LogContext, type Logger, type LoggerOptions, type WithTraceOptions, } from './logger';
|
|
2
|
-
export type { SpanOptions, TraceContext } from './tracing';
|
|
3
|
-
export { SPAN_EVENT_TYPE, SUMMARY_PROPERTIES_TYPE, isSpanEvent, parseTraceparent, formatTraceparent, type AttributeValue, type SpanEvent, type SpanKind, type SpanStatus, type TraceParent, } from '../protocol';
|
|
1
|
+
export { LogLevel, createLogger, noopLogger, withTrace, type KVLike, type LogContext, type Logger, type LoggerOptions, type LoggerSpanHandle, type WithTraceOptions, } from './logger.js';
|
|
2
|
+
export type { Exit, SpanHandle, SpanOptions, TraceContext } from './tracing/index.js';
|
|
3
|
+
export { SPAN_EVENT_TYPE, SUMMARY_PROPERTIES_TYPE, isSpanEvent, parseTraceparent, formatTraceparent, type AttributeValue, type SpanEvent, type SpanKind, type SpanStatus, type TraceParent, } from '../protocol/index.js';
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/producer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,SAAS,EACT,KAAK,MAAM,EACX,KAAK,UAAU,EACf,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,KAAK,gBAAgB,GACtB,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/producer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,SAAS,EACT,KAAK,MAAM,EACX,KAAK,UAAU,EACf,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,GACtB,MAAM,aAAa,CAAA;AAEpB,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAIrF,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,cAAc,EACnB,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,UAAU,EACf,KAAK,WAAW,GACjB,MAAM,sBAAsB,CAAA"}
|
package/dist/producer/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { LogLevel, createLogger, noopLogger, withTrace, } from './logger';
|
|
1
|
+
export { LogLevel, createLogger, noopLogger, withTrace, } from './logger.js';
|
|
2
2
|
// Re-export wire-format types that consumers commonly need when extending
|
|
3
3
|
// the producer (custom attributes, propagation helpers in middleware, etc.).
|
|
4
|
-
export { SPAN_EVENT_TYPE, SUMMARY_PROPERTIES_TYPE, isSpanEvent, parseTraceparent, formatTraceparent, } from '../protocol';
|
|
4
|
+
export { SPAN_EVENT_TYPE, SUMMARY_PROPERTIES_TYPE, isSpanEvent, parseTraceparent, formatTraceparent, } from '../protocol/index.js';
|
|
5
5
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/producer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,SAAS,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/producer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,SAAS,GAOV,MAAM,aAAa,CAAA;AAIpB,0EAA0E;AAC1E,6EAA6E;AAC7E,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,WAAW,EACX,gBAAgB,EAChB,iBAAiB,GAMlB,MAAM,sBAAsB,CAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type AttributeValue, type SpanKind } from '../protocol';
|
|
2
|
-
import { type SpanOptions, type TraceContext } from './tracing';
|
|
1
|
+
import { type AttributeValue, type SpanKind } from '../protocol/index.js';
|
|
2
|
+
import { type Exit, type SpanOptions, type TraceContext } from './tracing/index.js';
|
|
3
3
|
/**
|
|
4
4
|
* Bag of correlation fields (requestId, actorId, etc.). Has no semantic meaning
|
|
5
5
|
* to the logger — it's just merged into emitted JSON. First-class metadata
|
|
@@ -39,7 +39,21 @@ export interface Logger {
|
|
|
39
39
|
* creation) are recorded as `status: 'ok'` — they're expected user-facing
|
|
40
40
|
* failures, not span failures.
|
|
41
41
|
*/
|
|
42
|
-
|
|
42
|
+
withSpan<T>(name: string, options: SpanOptions, fn: (logger: Logger) => Promise<T>): Promise<T>;
|
|
43
|
+
/**
|
|
44
|
+
* Open a span whose lifetime is settled later. Use when the span's duration
|
|
45
|
+
* doesn't align with a function scope (typically driven by external
|
|
46
|
+
* callbacks like a streaming API's `onFinish`/`onError`/`onAbort`).
|
|
47
|
+
*
|
|
48
|
+
* Returns a handle bundling a `Logger` already bound to the new span (so
|
|
49
|
+
* logs/metrics emitted via it correlate automatically) and an `end(exit)`
|
|
50
|
+
* method that settles the span with an `Exit` outcome. `end` is idempotent —
|
|
51
|
+
* first call wins, later calls are ignored.
|
|
52
|
+
*
|
|
53
|
+
* Prefer `withSpan` when the span's lifetime aligns with a function — that
|
|
54
|
+
* form can't leak.
|
|
55
|
+
*/
|
|
56
|
+
startSpan(name: string, options: SpanOptions): LoggerSpanHandle;
|
|
43
57
|
/**
|
|
44
58
|
* Returns headers to propagate the current trace context on outbound calls.
|
|
45
59
|
* Always include the result on outbound `fetch` calls (including service
|
|
@@ -47,6 +61,13 @@ export interface Logger {
|
|
|
47
61
|
*/
|
|
48
62
|
tracingHeaders(): Headers;
|
|
49
63
|
}
|
|
64
|
+
/** Handle returned by `Logger.startSpan` — span-bound logger plus `end(exit)`. */
|
|
65
|
+
export interface LoggerSpanHandle {
|
|
66
|
+
/** Child logger bound to the new span; pass into work that should correlate. */
|
|
67
|
+
readonly logger: Logger;
|
|
68
|
+
/** Settle the span. Idempotent: first call wins. */
|
|
69
|
+
end(exit: Exit<unknown>): void;
|
|
70
|
+
}
|
|
50
71
|
export declare const LogLevel: {
|
|
51
72
|
readonly debug: 0;
|
|
52
73
|
readonly info: 1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/producer/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,cAAc,EAInB,KAAK,QAAQ,EAEd,MAAM,
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/producer/logger.ts"],"names":[],"mappings":"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"}
|
package/dist/producer/logger.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { formatTraceparent, generateTraceId, parseTraceparent, SUMMARY_PROPERTIES_TYPE, } from '../protocol';
|
|
2
|
-
import { createClock, runSpan, toSpanException, } from './tracing';
|
|
1
|
+
import { formatTraceparent, generateTraceId, parseTraceparent, SUMMARY_PROPERTIES_TYPE, } from '../protocol/index.js';
|
|
2
|
+
import { createClock, runSpan, startSpan, toSpanException, } from './tracing/index.js';
|
|
3
3
|
const BASE_LOG_LEVEL_KEY = 'logLevel';
|
|
4
4
|
export const LogLevel = {
|
|
5
5
|
debug: 0,
|
|
@@ -117,7 +117,7 @@ function _createLogger(options, clock, trace) {
|
|
|
117
117
|
child(newContext) {
|
|
118
118
|
return _createLogger({ ...options, context: { ...context, ...newContext } }, clock, trace);
|
|
119
119
|
},
|
|
120
|
-
async
|
|
120
|
+
async withSpan(name, spanOptions, fn) {
|
|
121
121
|
return runSpan({
|
|
122
122
|
parent: trace,
|
|
123
123
|
resource: { service, environment },
|
|
@@ -129,6 +129,21 @@ function _createLogger(options, clock, trace) {
|
|
|
129
129
|
onUnexpectedError: (err, childCtx) => _createLogger(options, clock, childCtx).error(err, `span "${name}" failed`),
|
|
130
130
|
});
|
|
131
131
|
},
|
|
132
|
+
startSpan(name, spanOptions) {
|
|
133
|
+
const handle = startSpan({
|
|
134
|
+
parent: trace,
|
|
135
|
+
resource: { service, environment },
|
|
136
|
+
name,
|
|
137
|
+
options: spanOptions,
|
|
138
|
+
clock,
|
|
139
|
+
isExpectedError,
|
|
140
|
+
onUnexpectedError: (err, childCtx) => _createLogger(options, clock, childCtx).error(err, `span "${name}" failed`),
|
|
141
|
+
});
|
|
142
|
+
return {
|
|
143
|
+
logger: _createLogger(options, clock, handle.trace),
|
|
144
|
+
end: handle.end,
|
|
145
|
+
};
|
|
146
|
+
},
|
|
132
147
|
tracingHeaders() {
|
|
133
148
|
const headers = new Headers();
|
|
134
149
|
if (trace.span_id !== undefined) {
|
|
@@ -151,7 +166,7 @@ export async function withTrace(options, fn, hooks) {
|
|
|
151
166
|
const { name, kind = 'server', attributes, ...loggerOptions } = options;
|
|
152
167
|
const logger = await createLogger(loggerOptions);
|
|
153
168
|
try {
|
|
154
|
-
return await logger.
|
|
169
|
+
return await logger.withSpan(name, { kind, attributes }, fn);
|
|
155
170
|
}
|
|
156
171
|
catch (err) {
|
|
157
172
|
if (hooks?.onError) {
|
|
@@ -173,7 +188,8 @@ export const noopLogger = {
|
|
|
173
188
|
metric: () => { },
|
|
174
189
|
summary: () => { },
|
|
175
190
|
child: () => noopLogger,
|
|
176
|
-
|
|
191
|
+
withSpan: (_name, _options, fn) => fn(noopLogger),
|
|
192
|
+
startSpan: () => ({ logger: noopLogger, end: () => { } }),
|
|
177
193
|
tracingHeaders: () => new Headers(),
|
|
178
194
|
};
|
|
179
195
|
//# sourceMappingURL=logger.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/producer/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAEhB,uBAAuB,GACxB,MAAM,
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/producer/logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { createClock, type Clock } from './clock';
|
|
2
|
-
export { runSpan, toSpanException, type ChildTraceContext, type SpanOptions, type TraceContext, } from './span';
|
|
1
|
+
export { createClock, type Clock } from './clock.js';
|
|
2
|
+
export { runSpan, startSpan, toSpanException, type ChildTraceContext, type Exit, type SpanHandle, type SpanOptions, type TraceContext, } from './span.js';
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/producer/tracing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,KAAK,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/producer/tracing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,KAAK,KAAK,EAAE,MAAM,YAAY,CAAA;AACpD,OAAO,EACL,OAAO,EACP,SAAS,EACT,eAAe,EACf,KAAK,iBAAiB,EACtB,KAAK,IAAI,EACT,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,YAAY,GAClB,MAAM,WAAW,CAAA"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { createClock } from './clock';
|
|
2
|
-
export { runSpan, toSpanException, } from './span';
|
|
1
|
+
export { createClock } from './clock.js';
|
|
2
|
+
export { runSpan, startSpan, toSpanException, } from './span.js';
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/producer/tracing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAc,MAAM,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/producer/tracing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAc,MAAM,YAAY,CAAA;AACpD,OAAO,EACL,OAAO,EACP,SAAS,EACT,eAAe,GAMhB,MAAM,WAAW,CAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type AttributeValue, type SpanException, type SpanKind } from '../../protocol';
|
|
2
|
-
import type { Clock } from './clock';
|
|
1
|
+
import { type AttributeValue, type SpanException, type SpanKind } from '../../protocol/index.js';
|
|
2
|
+
import type { Clock } from './clock.js';
|
|
3
3
|
export interface SpanOptions {
|
|
4
4
|
kind: SpanKind;
|
|
5
5
|
attributes?: Record<string, AttributeValue>;
|
|
@@ -35,7 +35,41 @@ export interface TraceContext {
|
|
|
35
35
|
export interface ChildTraceContext extends TraceContext {
|
|
36
36
|
readonly span_id: string;
|
|
37
37
|
}
|
|
38
|
-
|
|
38
|
+
/**
|
|
39
|
+
* Tagged outcome of a span's lifetime. Callers settle a span with one of these
|
|
40
|
+
* tags so success / failure / cancellation each have a first-class encoding —
|
|
41
|
+
* no overloading of return values vs thrown exceptions, no "the error path is
|
|
42
|
+
* implicit." Borrowed from Effect's `Exit` shape.
|
|
43
|
+
*
|
|
44
|
+
* - `ok` — work completed successfully; carries the result value.
|
|
45
|
+
* - `error` — work failed; carries the thrown value. `isExpectedError` decides
|
|
46
|
+
* whether the span records `status: error` or `status: ok` (expected user-facing
|
|
47
|
+
* failures like `SaptError` shouldn't pollute error dashboards).
|
|
48
|
+
* - `aborted` — work was cancelled (e.g. user clicked stop, client disconnected).
|
|
49
|
+
* Recorded as `status: ok` with a `span.aborted: true` attribute so dashboards
|
|
50
|
+
* can distinguish abandonment from completion without inflating error rates.
|
|
51
|
+
*/
|
|
52
|
+
export type Exit<T> = {
|
|
53
|
+
tag: 'ok';
|
|
54
|
+
value: T;
|
|
55
|
+
} | {
|
|
56
|
+
tag: 'error';
|
|
57
|
+
error: unknown;
|
|
58
|
+
} | {
|
|
59
|
+
tag: 'aborted';
|
|
60
|
+
};
|
|
61
|
+
/** Handle for a span whose lifetime is driven by external callbacks. */
|
|
62
|
+
export interface SpanHandle {
|
|
63
|
+
/** Trace identifiers for the span. Use to build a child logger. */
|
|
64
|
+
readonly trace: ChildTraceContext;
|
|
65
|
+
/**
|
|
66
|
+
* Emit the span event. Idempotent — second and later calls are ignored, so
|
|
67
|
+
* racing callbacks (e.g. `onError` after `onAbort`) settle deterministically
|
|
68
|
+
* on first-write-wins.
|
|
69
|
+
*/
|
|
70
|
+
end(exit: Exit<unknown>): void;
|
|
71
|
+
}
|
|
72
|
+
export interface StartSpanInput {
|
|
39
73
|
parent: TraceContext;
|
|
40
74
|
resource: {
|
|
41
75
|
service: string;
|
|
@@ -45,13 +79,28 @@ export interface RunSpanInput<T> {
|
|
|
45
79
|
options: SpanOptions;
|
|
46
80
|
clock: Clock;
|
|
47
81
|
isExpectedError?: (err: unknown) => boolean;
|
|
48
|
-
|
|
82
|
+
/** Invoked with the unexpected error once `end({ tag: 'error', error })` runs. */
|
|
49
83
|
onUnexpectedError?: (err: unknown, child: ChildTraceContext) => void;
|
|
50
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Open a span whose lifetime is settled later by `handle.end(exit)`. Use when
|
|
87
|
+
* the span's duration doesn't align with a function scope — for example a span
|
|
88
|
+
* driven by streaming callbacks (`onFinish` / `onError` / `onAbort`).
|
|
89
|
+
*
|
|
90
|
+
* For function-scoped work prefer `runSpan` (or `logger.withSpan`), which can't
|
|
91
|
+
* leak because the function boundary settles the span automatically.
|
|
92
|
+
*/
|
|
93
|
+
export declare function startSpan(input: StartSpanInput): SpanHandle;
|
|
94
|
+
export interface RunSpanInput<T> extends StartSpanInput {
|
|
95
|
+
fn: (child: ChildTraceContext) => Promise<T>;
|
|
96
|
+
}
|
|
51
97
|
/**
|
|
52
98
|
* Run an async function inside a span. Emits a SpanEvent on completion (success or
|
|
53
99
|
* failure). Errors matched by `isExpectedError` are recorded as `status: 'ok'` but
|
|
54
100
|
* still re-thrown — they're expected user-facing failures, not span failures.
|
|
101
|
+
*
|
|
102
|
+
* Thin wrapper over `startSpan` for the common case where the span's lifetime
|
|
103
|
+
* aligns with a function call.
|
|
55
104
|
*/
|
|
56
105
|
export declare function runSpan<T>(input: RunSpanInput<T>): Promise<T>;
|
|
57
106
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"span.d.ts","sourceRoot":"","sources":["../../../src/producer/tracing/span.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,cAAc,EAInB,KAAK,aAAa,EAClB,KAAK,QAAQ,EACd,MAAM,
|
|
1
|
+
{"version":3,"file":"span.d.ts","sourceRoot":"","sources":["../../../src/producer/tracing/span.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,cAAc,EAInB,KAAK,aAAa,EAClB,KAAK,QAAQ,EACd,MAAM,yBAAyB,CAAA;AAChC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAEvC,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,CAAA;IACd,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;CAC5C;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAC1B;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAkB,SAAQ,YAAY;IACrD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACzB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,IAAI,CAAC,CAAC,IACd;IAAE,GAAG,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GACvB;IAAE,GAAG,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAChC;IAAE,GAAG,EAAE,SAAS,CAAA;CAAE,CAAA;AAEtB,wEAAwE;AACxE,MAAM,WAAW,UAAU;IACzB,mEAAmE;IACnE,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAA;IACjC;;;;OAIG;IACH,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI,CAAA;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,YAAY,CAAA;IACpB,QAAQ,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAA;IAC9D,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,WAAW,CAAA;IACpB,KAAK,EAAE,KAAK,CAAA;IACZ,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAA;IAC3C,kFAAkF;IAClF,iBAAiB,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAA;CACrE;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,UAAU,CA8D3D;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,CAAE,SAAQ,cAAc;IACrD,EAAE,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;CAC7C;AAED;;;;;;;GAOG;AACH,wBAAsB,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAWnE;AAQD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,aAAa,CAU3D"}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import { generateSpanId, SPAN_EVENT_TYPE, } from '../../protocol';
|
|
1
|
+
import { generateSpanId, SPAN_EVENT_TYPE, } from '../../protocol/index.js';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
3
|
+
* Open a span whose lifetime is settled later by `handle.end(exit)`. Use when
|
|
4
|
+
* the span's duration doesn't align with a function scope — for example a span
|
|
5
|
+
* driven by streaming callbacks (`onFinish` / `onError` / `onAbort`).
|
|
6
|
+
*
|
|
7
|
+
* For function-scoped work prefer `runSpan` (or `logger.withSpan`), which can't
|
|
8
|
+
* leak because the function boundary settles the span automatically.
|
|
6
9
|
*/
|
|
7
|
-
export
|
|
8
|
-
const { parent, resource, name, options, clock, isExpectedError,
|
|
10
|
+
export function startSpan(input) {
|
|
11
|
+
const { parent, resource, name, options, clock, isExpectedError, onUnexpectedError } = input;
|
|
9
12
|
const child = {
|
|
10
13
|
trace_id: parent.trace_id,
|
|
11
14
|
span_id: generateSpanId(),
|
|
@@ -18,26 +21,70 @@ export async function runSpan(input) {
|
|
|
18
21
|
...resource,
|
|
19
22
|
name,
|
|
20
23
|
kind: options.kind,
|
|
21
|
-
attributes: options.attributes,
|
|
22
24
|
};
|
|
25
|
+
let settled = false;
|
|
26
|
+
return {
|
|
27
|
+
trace: child,
|
|
28
|
+
end(exit) {
|
|
29
|
+
if (settled)
|
|
30
|
+
return;
|
|
31
|
+
settled = true;
|
|
32
|
+
const endTimeUnixNano = clock.nowUnixNano();
|
|
33
|
+
if (exit.tag === 'ok') {
|
|
34
|
+
emitSpan({
|
|
35
|
+
...base,
|
|
36
|
+
attributes: options.attributes,
|
|
37
|
+
status: 'ok',
|
|
38
|
+
startTimeUnixNano,
|
|
39
|
+
endTimeUnixNano,
|
|
40
|
+
});
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (exit.tag === 'aborted') {
|
|
44
|
+
emitSpan({
|
|
45
|
+
...base,
|
|
46
|
+
attributes: { ...options.attributes, 'span.aborted': true },
|
|
47
|
+
status: 'ok',
|
|
48
|
+
startTimeUnixNano,
|
|
49
|
+
endTimeUnixNano,
|
|
50
|
+
});
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
// tag === 'error'
|
|
54
|
+
const expected = isExpectedError?.(exit.error) === true;
|
|
55
|
+
const exception = expected ? undefined : toSpanException(exit.error);
|
|
56
|
+
emitSpan({
|
|
57
|
+
...base,
|
|
58
|
+
attributes: options.attributes,
|
|
59
|
+
status: expected ? 'ok' : 'error',
|
|
60
|
+
statusMessage: exception?.message,
|
|
61
|
+
exception,
|
|
62
|
+
startTimeUnixNano,
|
|
63
|
+
endTimeUnixNano,
|
|
64
|
+
});
|
|
65
|
+
if (!expected)
|
|
66
|
+
onUnexpectedError?.(exit.error, child);
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Run an async function inside a span. Emits a SpanEvent on completion (success or
|
|
72
|
+
* failure). Errors matched by `isExpectedError` are recorded as `status: 'ok'` but
|
|
73
|
+
* still re-thrown — they're expected user-facing failures, not span failures.
|
|
74
|
+
*
|
|
75
|
+
* Thin wrapper over `startSpan` for the common case where the span's lifetime
|
|
76
|
+
* aligns with a function call.
|
|
77
|
+
*/
|
|
78
|
+
export async function runSpan(input) {
|
|
79
|
+
const { fn, ...rest } = input;
|
|
80
|
+
const handle = startSpan(rest);
|
|
23
81
|
try {
|
|
24
|
-
const result = await fn(
|
|
25
|
-
|
|
82
|
+
const result = await fn(handle.trace);
|
|
83
|
+
handle.end({ tag: 'ok', value: result });
|
|
26
84
|
return result;
|
|
27
85
|
}
|
|
28
86
|
catch (err) {
|
|
29
|
-
|
|
30
|
-
const exception = expected ? undefined : toSpanException(err);
|
|
31
|
-
emitSpan({
|
|
32
|
-
...base,
|
|
33
|
-
status: expected ? 'ok' : 'error',
|
|
34
|
-
statusMessage: exception?.message,
|
|
35
|
-
exception,
|
|
36
|
-
startTimeUnixNano,
|
|
37
|
-
endTimeUnixNano: clock.nowUnixNano(),
|
|
38
|
-
});
|
|
39
|
-
if (!expected)
|
|
40
|
-
onUnexpectedError?.(err, child);
|
|
87
|
+
handle.end({ tag: 'error', error: err });
|
|
41
88
|
throw err;
|
|
42
89
|
}
|
|
43
90
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"span.js","sourceRoot":"","sources":["../../../src/producer/tracing/span.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,cAAc,EACd,eAAe,GAIhB,MAAM,
|
|
1
|
+
{"version":3,"file":"span.js","sourceRoot":"","sources":["../../../src/producer/tracing/span.ts"],"names":[],"mappings":"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"}
|
package/dist/tail/index.d.ts
CHANGED
|
@@ -39,5 +39,5 @@ export type TailHandler = (events: TraceItem[], env: unknown, ctx: ExecutionCont
|
|
|
39
39
|
* ```
|
|
40
40
|
*/
|
|
41
41
|
export declare function createTailHandler(config: AxiomConfig): TailHandler;
|
|
42
|
-
export { sendSpansToAxiom } from './spans';
|
|
42
|
+
export { sendSpansToAxiom } from './spans.js';
|
|
43
43
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/tail/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tail/index.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,uBAAuB;IACvB,UAAU,EAAE,MAAM,CAAA;IAClB,kEAAkE;IAClE,YAAY,EAAE,MAAM,CAAA;IACpB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,MAAM,WAAW,GAAG,CACxB,MAAM,EAAE,SAAS,EAAE,EACnB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,gBAAgB,KAClB,OAAO,CAAC,IAAI,CAAC,CAAA;AAElB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CA6FlE;AA8FD,OAAO,EAAE,gBAAgB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tail/index.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,uBAAuB;IACvB,UAAU,EAAE,MAAM,CAAA;IAClB,kEAAkE;IAClE,YAAY,EAAE,MAAM,CAAA;IACpB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,MAAM,WAAW,GAAG,CACxB,MAAM,EAAE,SAAS,EAAE,EACnB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,gBAAgB,KAClB,OAAO,CAAC,IAAI,CAAC,CAAA;AAElB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CA6FlE;AA8FD,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA"}
|
package/dist/tail/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { isSpanEvent, SUMMARY_PROPERTIES_TYPE } from '../protocol';
|
|
2
|
-
import { sendSpansToAxiom } from './spans';
|
|
1
|
+
import { isSpanEvent, SUMMARY_PROPERTIES_TYPE } from '../protocol/index.js';
|
|
2
|
+
import { sendSpansToAxiom } from './spans.js';
|
|
3
3
|
/**
|
|
4
4
|
* Build a Cloudflare Workers `tail()` handler that forwards logs, metrics,
|
|
5
5
|
* errors, and spans from any number of producing workers to Axiom.
|
|
@@ -151,5 +151,5 @@ async function sendToAxiom(params) {
|
|
|
151
151
|
throw new Error(`Failed to send logs to Axiom: ${response.status} ${response.statusText} — ${text}`);
|
|
152
152
|
}
|
|
153
153
|
}
|
|
154
|
-
export { sendSpansToAxiom } from './spans';
|
|
154
|
+
export { sendSpansToAxiom } from './spans.js';
|
|
155
155
|
//# sourceMappingURL=index.js.map
|
package/dist/tail/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tail/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,uBAAuB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tail/index.ts"],"names":[],"mappings":"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"}
|
package/dist/tail/spans.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* router that forwards only `sampled === true` spans. Logs/metrics/errors are
|
|
8
8
|
* forwarded unconditionally by the caller — sampling gates traces, not log visibility.
|
|
9
9
|
*/
|
|
10
|
-
import type { SpanEvent } from '../protocol';
|
|
10
|
+
import type { SpanEvent } from '../protocol/index.js';
|
|
11
11
|
export interface SendSpansInput {
|
|
12
12
|
spans: SpanEvent[];
|
|
13
13
|
axiomToken: string;
|
package/dist/tail/spans.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spans.d.ts","sourceRoot":"","sources":["../../src/tail/spans.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"spans.d.ts","sourceRoot":"","sources":["../../src/tail/spans.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAA;AAUrD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,SAAS,EAAE,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,8FAA8F;IAC9F,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAuB3E"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "workers-axiom",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Structured logging, tracing, and metrics for Cloudflare Workers, with an Axiom tail-worker sink.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -29,13 +29,12 @@
|
|
|
29
29
|
"dist",
|
|
30
30
|
"src"
|
|
31
31
|
],
|
|
32
|
-
"scripts": {
|
|
33
|
-
"build": "rm -rf dist && tsc -p tsconfig.build.json",
|
|
34
|
-
"typecheck": "tsc --noEmit",
|
|
35
|
-
"prepublishOnly": "pnpm run build"
|
|
36
|
-
},
|
|
37
32
|
"devDependencies": {
|
|
38
33
|
"@cloudflare/workers-types": "^4.20250101.0",
|
|
39
34
|
"typescript": "^5.6.0"
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "rm -rf dist && tsc -p tsconfig.build.json",
|
|
38
|
+
"typecheck": "tsc --noEmit"
|
|
40
39
|
}
|
|
41
|
-
}
|
|
40
|
+
}
|
package/src/producer/index.ts
CHANGED
|
@@ -7,10 +7,11 @@ export {
|
|
|
7
7
|
type LogContext,
|
|
8
8
|
type Logger,
|
|
9
9
|
type LoggerOptions,
|
|
10
|
+
type LoggerSpanHandle,
|
|
10
11
|
type WithTraceOptions,
|
|
11
|
-
} from './logger'
|
|
12
|
+
} from './logger.js'
|
|
12
13
|
|
|
13
|
-
export type { SpanOptions, TraceContext } from './tracing'
|
|
14
|
+
export type { Exit, SpanHandle, SpanOptions, TraceContext } from './tracing/index.js'
|
|
14
15
|
|
|
15
16
|
// Re-export wire-format types that consumers commonly need when extending
|
|
16
17
|
// the producer (custom attributes, propagation helpers in middleware, etc.).
|
|
@@ -25,4 +26,4 @@ export {
|
|
|
25
26
|
type SpanKind,
|
|
26
27
|
type SpanStatus,
|
|
27
28
|
type TraceParent,
|
|
28
|
-
} from '../protocol'
|
|
29
|
+
} from '../protocol/index.js'
|
package/src/producer/logger.ts
CHANGED
|
@@ -5,15 +5,18 @@ import {
|
|
|
5
5
|
parseTraceparent,
|
|
6
6
|
type SpanKind,
|
|
7
7
|
SUMMARY_PROPERTIES_TYPE,
|
|
8
|
-
} from '../protocol'
|
|
8
|
+
} from '../protocol/index.js'
|
|
9
9
|
import {
|
|
10
10
|
type Clock,
|
|
11
11
|
createClock,
|
|
12
|
+
type Exit,
|
|
12
13
|
runSpan,
|
|
14
|
+
type SpanHandle,
|
|
13
15
|
type SpanOptions,
|
|
16
|
+
startSpan,
|
|
14
17
|
toSpanException,
|
|
15
18
|
type TraceContext,
|
|
16
|
-
} from './tracing'
|
|
19
|
+
} from './tracing/index.js'
|
|
17
20
|
|
|
18
21
|
/**
|
|
19
22
|
* Bag of correlation fields (requestId, actorId, etc.). Has no semantic meaning
|
|
@@ -55,7 +58,21 @@ export interface Logger {
|
|
|
55
58
|
* creation) are recorded as `status: 'ok'` — they're expected user-facing
|
|
56
59
|
* failures, not span failures.
|
|
57
60
|
*/
|
|
58
|
-
|
|
61
|
+
withSpan<T>(name: string, options: SpanOptions, fn: (logger: Logger) => Promise<T>): Promise<T>
|
|
62
|
+
/**
|
|
63
|
+
* Open a span whose lifetime is settled later. Use when the span's duration
|
|
64
|
+
* doesn't align with a function scope (typically driven by external
|
|
65
|
+
* callbacks like a streaming API's `onFinish`/`onError`/`onAbort`).
|
|
66
|
+
*
|
|
67
|
+
* Returns a handle bundling a `Logger` already bound to the new span (so
|
|
68
|
+
* logs/metrics emitted via it correlate automatically) and an `end(exit)`
|
|
69
|
+
* method that settles the span with an `Exit` outcome. `end` is idempotent —
|
|
70
|
+
* first call wins, later calls are ignored.
|
|
71
|
+
*
|
|
72
|
+
* Prefer `withSpan` when the span's lifetime aligns with a function — that
|
|
73
|
+
* form can't leak.
|
|
74
|
+
*/
|
|
75
|
+
startSpan(name: string, options: SpanOptions): LoggerSpanHandle
|
|
59
76
|
/**
|
|
60
77
|
* Returns headers to propagate the current trace context on outbound calls.
|
|
61
78
|
* Always include the result on outbound `fetch` calls (including service
|
|
@@ -64,6 +81,14 @@ export interface Logger {
|
|
|
64
81
|
tracingHeaders(): Headers
|
|
65
82
|
}
|
|
66
83
|
|
|
84
|
+
/** Handle returned by `Logger.startSpan` — span-bound logger plus `end(exit)`. */
|
|
85
|
+
export interface LoggerSpanHandle {
|
|
86
|
+
/** Child logger bound to the new span; pass into work that should correlate. */
|
|
87
|
+
readonly logger: Logger
|
|
88
|
+
/** Settle the span. Idempotent: first call wins. */
|
|
89
|
+
end(exit: Exit<unknown>): void
|
|
90
|
+
}
|
|
91
|
+
|
|
67
92
|
const BASE_LOG_LEVEL_KEY = 'logLevel'
|
|
68
93
|
|
|
69
94
|
export const LogLevel = {
|
|
@@ -261,7 +286,7 @@ function _createLogger(options: LoggerOptions, clock: Clock, trace: TraceContext
|
|
|
261
286
|
)
|
|
262
287
|
},
|
|
263
288
|
|
|
264
|
-
async
|
|
289
|
+
async withSpan<T>(
|
|
265
290
|
name: string,
|
|
266
291
|
spanOptions: SpanOptions,
|
|
267
292
|
fn: (logger: Logger) => Promise<T>
|
|
@@ -279,6 +304,23 @@ function _createLogger(options: LoggerOptions, clock: Clock, trace: TraceContext
|
|
|
279
304
|
})
|
|
280
305
|
},
|
|
281
306
|
|
|
307
|
+
startSpan(name: string, spanOptions: SpanOptions): LoggerSpanHandle {
|
|
308
|
+
const handle = startSpan({
|
|
309
|
+
parent: trace,
|
|
310
|
+
resource: { service, environment },
|
|
311
|
+
name,
|
|
312
|
+
options: spanOptions,
|
|
313
|
+
clock,
|
|
314
|
+
isExpectedError,
|
|
315
|
+
onUnexpectedError: (err, childCtx) =>
|
|
316
|
+
_createLogger(options, clock, childCtx).error(err, `span "${name}" failed`),
|
|
317
|
+
})
|
|
318
|
+
return {
|
|
319
|
+
logger: _createLogger(options, clock, handle.trace),
|
|
320
|
+
end: handle.end,
|
|
321
|
+
}
|
|
322
|
+
},
|
|
323
|
+
|
|
282
324
|
tracingHeaders(): Headers {
|
|
283
325
|
const headers = new Headers()
|
|
284
326
|
if (trace.span_id !== undefined) {
|
|
@@ -315,7 +357,7 @@ export async function withTrace<T>(
|
|
|
315
357
|
const { name, kind = 'server', attributes, ...loggerOptions } = options
|
|
316
358
|
const logger = await createLogger(loggerOptions)
|
|
317
359
|
try {
|
|
318
|
-
return await logger.
|
|
360
|
+
return await logger.withSpan(name, { kind, attributes }, fn)
|
|
319
361
|
} catch (err) {
|
|
320
362
|
if (hooks?.onError) {
|
|
321
363
|
return await hooks.onError(err, logger)
|
|
@@ -337,7 +379,8 @@ export const noopLogger: Logger = {
|
|
|
337
379
|
metric: () => {},
|
|
338
380
|
summary: () => {},
|
|
339
381
|
child: () => noopLogger,
|
|
340
|
-
|
|
382
|
+
withSpan: <T>(_name: string, _options: SpanOptions, fn: (logger: Logger) => Promise<T>) =>
|
|
341
383
|
fn(noopLogger),
|
|
384
|
+
startSpan: () => ({ logger: noopLogger, end: () => {} }),
|
|
342
385
|
tracingHeaders: () => new Headers(),
|
|
343
386
|
}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
export { createClock, type Clock } from './clock'
|
|
1
|
+
export { createClock, type Clock } from './clock.js'
|
|
2
2
|
export {
|
|
3
3
|
runSpan,
|
|
4
|
+
startSpan,
|
|
4
5
|
toSpanException,
|
|
5
6
|
type ChildTraceContext,
|
|
7
|
+
type Exit,
|
|
8
|
+
type SpanHandle,
|
|
6
9
|
type SpanOptions,
|
|
7
10
|
type TraceContext,
|
|
8
|
-
} from './span'
|
|
11
|
+
} from './span.js'
|
|
@@ -5,8 +5,8 @@ import {
|
|
|
5
5
|
type SpanEvent,
|
|
6
6
|
type SpanException,
|
|
7
7
|
type SpanKind,
|
|
8
|
-
} from '../../protocol'
|
|
9
|
-
import type { Clock } from './clock'
|
|
8
|
+
} from '../../protocol/index.js'
|
|
9
|
+
import type { Clock } from './clock.js'
|
|
10
10
|
|
|
11
11
|
export interface SpanOptions {
|
|
12
12
|
kind: SpanKind
|
|
@@ -46,24 +46,58 @@ export interface ChildTraceContext extends TraceContext {
|
|
|
46
46
|
readonly span_id: string
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Tagged outcome of a span's lifetime. Callers settle a span with one of these
|
|
51
|
+
* tags so success / failure / cancellation each have a first-class encoding —
|
|
52
|
+
* no overloading of return values vs thrown exceptions, no "the error path is
|
|
53
|
+
* implicit." Borrowed from Effect's `Exit` shape.
|
|
54
|
+
*
|
|
55
|
+
* - `ok` — work completed successfully; carries the result value.
|
|
56
|
+
* - `error` — work failed; carries the thrown value. `isExpectedError` decides
|
|
57
|
+
* whether the span records `status: error` or `status: ok` (expected user-facing
|
|
58
|
+
* failures like `SaptError` shouldn't pollute error dashboards).
|
|
59
|
+
* - `aborted` — work was cancelled (e.g. user clicked stop, client disconnected).
|
|
60
|
+
* Recorded as `status: ok` with a `span.aborted: true` attribute so dashboards
|
|
61
|
+
* can distinguish abandonment from completion without inflating error rates.
|
|
62
|
+
*/
|
|
63
|
+
export type Exit<T> =
|
|
64
|
+
| { tag: 'ok'; value: T }
|
|
65
|
+
| { tag: 'error'; error: unknown }
|
|
66
|
+
| { tag: 'aborted' }
|
|
67
|
+
|
|
68
|
+
/** Handle for a span whose lifetime is driven by external callbacks. */
|
|
69
|
+
export interface SpanHandle {
|
|
70
|
+
/** Trace identifiers for the span. Use to build a child logger. */
|
|
71
|
+
readonly trace: ChildTraceContext
|
|
72
|
+
/**
|
|
73
|
+
* Emit the span event. Idempotent — second and later calls are ignored, so
|
|
74
|
+
* racing callbacks (e.g. `onError` after `onAbort`) settle deterministically
|
|
75
|
+
* on first-write-wins.
|
|
76
|
+
*/
|
|
77
|
+
end(exit: Exit<unknown>): void
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface StartSpanInput {
|
|
50
81
|
parent: TraceContext
|
|
51
82
|
resource: { service: string; environment: string | undefined }
|
|
52
83
|
name: string
|
|
53
84
|
options: SpanOptions
|
|
54
85
|
clock: Clock
|
|
55
86
|
isExpectedError?: (err: unknown) => boolean
|
|
56
|
-
|
|
87
|
+
/** Invoked with the unexpected error once `end({ tag: 'error', error })` runs. */
|
|
57
88
|
onUnexpectedError?: (err: unknown, child: ChildTraceContext) => void
|
|
58
89
|
}
|
|
59
90
|
|
|
60
91
|
/**
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
92
|
+
* Open a span whose lifetime is settled later by `handle.end(exit)`. Use when
|
|
93
|
+
* the span's duration doesn't align with a function scope — for example a span
|
|
94
|
+
* driven by streaming callbacks (`onFinish` / `onError` / `onAbort`).
|
|
95
|
+
*
|
|
96
|
+
* For function-scoped work prefer `runSpan` (or `logger.withSpan`), which can't
|
|
97
|
+
* leak because the function boundary settles the span automatically.
|
|
64
98
|
*/
|
|
65
|
-
export
|
|
66
|
-
const { parent, resource, name, options, clock, isExpectedError,
|
|
99
|
+
export function startSpan(input: StartSpanInput): SpanHandle {
|
|
100
|
+
const { parent, resource, name, options, clock, isExpectedError, onUnexpectedError } = input
|
|
67
101
|
const child: ChildTraceContext = {
|
|
68
102
|
trace_id: parent.trace_id,
|
|
69
103
|
span_id: generateSpanId(),
|
|
@@ -77,25 +111,76 @@ export async function runSpan<T>(input: RunSpanInput<T>): Promise<T> {
|
|
|
77
111
|
...resource,
|
|
78
112
|
name,
|
|
79
113
|
kind: options.kind,
|
|
80
|
-
attributes: options.attributes,
|
|
81
114
|
}
|
|
82
115
|
|
|
116
|
+
let settled = false
|
|
117
|
+
return {
|
|
118
|
+
trace: child,
|
|
119
|
+
end(exit: Exit<unknown>): void {
|
|
120
|
+
if (settled) return
|
|
121
|
+
settled = true
|
|
122
|
+
const endTimeUnixNano = clock.nowUnixNano()
|
|
123
|
+
|
|
124
|
+
if (exit.tag === 'ok') {
|
|
125
|
+
emitSpan({
|
|
126
|
+
...base,
|
|
127
|
+
attributes: options.attributes,
|
|
128
|
+
status: 'ok',
|
|
129
|
+
startTimeUnixNano,
|
|
130
|
+
endTimeUnixNano,
|
|
131
|
+
})
|
|
132
|
+
return
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (exit.tag === 'aborted') {
|
|
136
|
+
emitSpan({
|
|
137
|
+
...base,
|
|
138
|
+
attributes: { ...options.attributes, 'span.aborted': true },
|
|
139
|
+
status: 'ok',
|
|
140
|
+
startTimeUnixNano,
|
|
141
|
+
endTimeUnixNano,
|
|
142
|
+
})
|
|
143
|
+
return
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// tag === 'error'
|
|
147
|
+
const expected = isExpectedError?.(exit.error) === true
|
|
148
|
+
const exception = expected ? undefined : toSpanException(exit.error)
|
|
149
|
+
emitSpan({
|
|
150
|
+
...base,
|
|
151
|
+
attributes: options.attributes,
|
|
152
|
+
status: expected ? 'ok' : 'error',
|
|
153
|
+
statusMessage: exception?.message,
|
|
154
|
+
exception,
|
|
155
|
+
startTimeUnixNano,
|
|
156
|
+
endTimeUnixNano,
|
|
157
|
+
})
|
|
158
|
+
if (!expected) onUnexpectedError?.(exit.error, child)
|
|
159
|
+
},
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export interface RunSpanInput<T> extends StartSpanInput {
|
|
164
|
+
fn: (child: ChildTraceContext) => Promise<T>
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Run an async function inside a span. Emits a SpanEvent on completion (success or
|
|
169
|
+
* failure). Errors matched by `isExpectedError` are recorded as `status: 'ok'` but
|
|
170
|
+
* still re-thrown — they're expected user-facing failures, not span failures.
|
|
171
|
+
*
|
|
172
|
+
* Thin wrapper over `startSpan` for the common case where the span's lifetime
|
|
173
|
+
* aligns with a function call.
|
|
174
|
+
*/
|
|
175
|
+
export async function runSpan<T>(input: RunSpanInput<T>): Promise<T> {
|
|
176
|
+
const { fn, ...rest } = input
|
|
177
|
+
const handle = startSpan(rest)
|
|
83
178
|
try {
|
|
84
|
-
const result = await fn(
|
|
85
|
-
|
|
179
|
+
const result = await fn(handle.trace)
|
|
180
|
+
handle.end({ tag: 'ok', value: result })
|
|
86
181
|
return result
|
|
87
182
|
} catch (err) {
|
|
88
|
-
|
|
89
|
-
const exception = expected ? undefined : toSpanException(err)
|
|
90
|
-
emitSpan({
|
|
91
|
-
...base,
|
|
92
|
-
status: expected ? 'ok' : 'error',
|
|
93
|
-
statusMessage: exception?.message,
|
|
94
|
-
exception,
|
|
95
|
-
startTimeUnixNano,
|
|
96
|
-
endTimeUnixNano: clock.nowUnixNano(),
|
|
97
|
-
})
|
|
98
|
-
if (!expected) onUnexpectedError?.(err, child)
|
|
183
|
+
handle.end({ tag: 'error', error: err })
|
|
99
184
|
throw err
|
|
100
185
|
}
|
|
101
186
|
}
|
package/src/tail/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { isSpanEvent, type SpanEvent, SUMMARY_PROPERTIES_TYPE } from '../protocol'
|
|
2
|
-
import { sendSpansToAxiom } from './spans'
|
|
1
|
+
import { isSpanEvent, type SpanEvent, SUMMARY_PROPERTIES_TYPE } from '../protocol/index.js'
|
|
2
|
+
import { sendSpansToAxiom } from './spans.js'
|
|
3
3
|
|
|
4
4
|
export interface AxiomConfig {
|
|
5
5
|
/** Axiom API token. */
|
|
@@ -234,4 +234,4 @@ async function sendToAxiom(params: {
|
|
|
234
234
|
}
|
|
235
235
|
}
|
|
236
236
|
|
|
237
|
-
export { sendSpansToAxiom } from './spans'
|
|
237
|
+
export { sendSpansToAxiom } from './spans.js'
|
package/src/tail/spans.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* router that forwards only `sampled === true` spans. Logs/metrics/errors are
|
|
8
8
|
* forwarded unconditionally by the caller — sampling gates traces, not log visibility.
|
|
9
9
|
*/
|
|
10
|
-
import type { SpanEvent } from '../protocol'
|
|
10
|
+
import type { SpanEvent } from '../protocol/index.js'
|
|
11
11
|
|
|
12
12
|
const SPAN_KIND_TO_OTLP: Record<SpanEvent['kind'], number> = {
|
|
13
13
|
internal: 1,
|