@tracewayapp/backend 1.0.1 → 1.0.2
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/index.d.mts +9 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +15 -5
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +14 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -71,6 +71,8 @@ interface TraceContext {
|
|
|
71
71
|
bodySize?: number;
|
|
72
72
|
/** For HTTP traces: client IP address */
|
|
73
73
|
clientIP?: string;
|
|
74
|
+
/** Distributed trace ID for cross-service correlation */
|
|
75
|
+
distributedTraceId?: string;
|
|
74
76
|
}
|
|
75
77
|
/**
|
|
76
78
|
* Options for creating a new trace context.
|
|
@@ -86,6 +88,8 @@ interface TraceContextOptions {
|
|
|
86
88
|
endpoint?: string;
|
|
87
89
|
/** Client IP address */
|
|
88
90
|
clientIP?: string;
|
|
91
|
+
/** Distributed trace ID from incoming request header */
|
|
92
|
+
distributedTraceId?: string;
|
|
89
93
|
}
|
|
90
94
|
declare const asyncLocalStorage: AsyncLocalStorage<TraceContext>;
|
|
91
95
|
/**
|
|
@@ -97,6 +101,10 @@ declare function getTraceContext(): TraceContext | undefined;
|
|
|
97
101
|
* Get the current trace ID, if within a trace context.
|
|
98
102
|
*/
|
|
99
103
|
declare function getTraceId(): string | undefined;
|
|
104
|
+
/**
|
|
105
|
+
* Get the distributed trace ID from the current trace context, if any.
|
|
106
|
+
*/
|
|
107
|
+
declare function getDistributedTraceId(): string | undefined;
|
|
100
108
|
/**
|
|
101
109
|
* Check if currently within a trace context.
|
|
102
110
|
*/
|
|
@@ -230,4 +238,4 @@ declare class CollectionFrameStore {
|
|
|
230
238
|
shutdown(timeoutMs?: number): Promise<void>;
|
|
231
239
|
}
|
|
232
240
|
|
|
233
|
-
export { CollectionFrameStore, type CollectionFrameStoreOptions, type SpanHandle, type TraceContext, type TraceContextOptions, addSpanToContext, captureCurrentTrace, captureException, captureExceptionWithAttributes, captureMessage, captureMetric, captureMetricWithTags, captureTask, captureTrace, collectMetrics, endSpan, forkTraceContext, formatErrorStackTrace, getTraceContext, getTraceDuration, getTraceId, getTraceSpans, hasTraceContext, init, measureTask, resetCpuTracking, runWithTraceContext, setTraceAttribute, setTraceAttributes, setTraceResponseInfo, shouldSample, shutdown, startSpan, asyncLocalStorage as traceContextStorage, withTraceContext };
|
|
241
|
+
export { CollectionFrameStore, type CollectionFrameStoreOptions, type SpanHandle, type TraceContext, type TraceContextOptions, addSpanToContext, captureCurrentTrace, captureException, captureExceptionWithAttributes, captureMessage, captureMetric, captureMetricWithTags, captureTask, captureTrace, collectMetrics, endSpan, forkTraceContext, formatErrorStackTrace, getDistributedTraceId, getTraceContext, getTraceDuration, getTraceId, getTraceSpans, hasTraceContext, init, measureTask, resetCpuTracking, runWithTraceContext, setTraceAttribute, setTraceAttributes, setTraceResponseInfo, shouldSample, shutdown, startSpan, asyncLocalStorage as traceContextStorage, withTraceContext };
|
package/dist/index.d.ts
CHANGED
|
@@ -71,6 +71,8 @@ interface TraceContext {
|
|
|
71
71
|
bodySize?: number;
|
|
72
72
|
/** For HTTP traces: client IP address */
|
|
73
73
|
clientIP?: string;
|
|
74
|
+
/** Distributed trace ID for cross-service correlation */
|
|
75
|
+
distributedTraceId?: string;
|
|
74
76
|
}
|
|
75
77
|
/**
|
|
76
78
|
* Options for creating a new trace context.
|
|
@@ -86,6 +88,8 @@ interface TraceContextOptions {
|
|
|
86
88
|
endpoint?: string;
|
|
87
89
|
/** Client IP address */
|
|
88
90
|
clientIP?: string;
|
|
91
|
+
/** Distributed trace ID from incoming request header */
|
|
92
|
+
distributedTraceId?: string;
|
|
89
93
|
}
|
|
90
94
|
declare const asyncLocalStorage: AsyncLocalStorage<TraceContext>;
|
|
91
95
|
/**
|
|
@@ -97,6 +101,10 @@ declare function getTraceContext(): TraceContext | undefined;
|
|
|
97
101
|
* Get the current trace ID, if within a trace context.
|
|
98
102
|
*/
|
|
99
103
|
declare function getTraceId(): string | undefined;
|
|
104
|
+
/**
|
|
105
|
+
* Get the distributed trace ID from the current trace context, if any.
|
|
106
|
+
*/
|
|
107
|
+
declare function getDistributedTraceId(): string | undefined;
|
|
100
108
|
/**
|
|
101
109
|
* Check if currently within a trace context.
|
|
102
110
|
*/
|
|
@@ -230,4 +238,4 @@ declare class CollectionFrameStore {
|
|
|
230
238
|
shutdown(timeoutMs?: number): Promise<void>;
|
|
231
239
|
}
|
|
232
240
|
|
|
233
|
-
export { CollectionFrameStore, type CollectionFrameStoreOptions, type SpanHandle, type TraceContext, type TraceContextOptions, addSpanToContext, captureCurrentTrace, captureException, captureExceptionWithAttributes, captureMessage, captureMetric, captureMetricWithTags, captureTask, captureTrace, collectMetrics, endSpan, forkTraceContext, formatErrorStackTrace, getTraceContext, getTraceDuration, getTraceId, getTraceSpans, hasTraceContext, init, measureTask, resetCpuTracking, runWithTraceContext, setTraceAttribute, setTraceAttributes, setTraceResponseInfo, shouldSample, shutdown, startSpan, asyncLocalStorage as traceContextStorage, withTraceContext };
|
|
241
|
+
export { CollectionFrameStore, type CollectionFrameStoreOptions, type SpanHandle, type TraceContext, type TraceContextOptions, addSpanToContext, captureCurrentTrace, captureException, captureExceptionWithAttributes, captureMessage, captureMetric, captureMetricWithTags, captureTask, captureTrace, collectMetrics, endSpan, forkTraceContext, formatErrorStackTrace, getDistributedTraceId, getTraceContext, getTraceDuration, getTraceId, getTraceSpans, hasTraceContext, init, measureTask, resetCpuTracking, runWithTraceContext, setTraceAttribute, setTraceAttributes, setTraceResponseInfo, shouldSample, shutdown, startSpan, asyncLocalStorage as traceContextStorage, withTraceContext };
|
package/dist/index.js
CHANGED
|
@@ -44,6 +44,7 @@ __export(index_exports, {
|
|
|
44
44
|
endSpan: () => endSpan,
|
|
45
45
|
forkTraceContext: () => forkTraceContext,
|
|
46
46
|
formatErrorStackTrace: () => formatErrorStackTrace,
|
|
47
|
+
getDistributedTraceId: () => getDistributedTraceId,
|
|
47
48
|
getTraceContext: () => getTraceContext,
|
|
48
49
|
getTraceDuration: () => getTraceDuration,
|
|
49
50
|
getTraceId: () => getTraceId,
|
|
@@ -435,6 +436,9 @@ function getTraceContext() {
|
|
|
435
436
|
function getTraceId() {
|
|
436
437
|
return asyncLocalStorage.getStore()?.traceId;
|
|
437
438
|
}
|
|
439
|
+
function getDistributedTraceId() {
|
|
440
|
+
return asyncLocalStorage.getStore()?.distributedTraceId;
|
|
441
|
+
}
|
|
438
442
|
function hasTraceContext() {
|
|
439
443
|
return asyncLocalStorage.getStore() !== void 0;
|
|
440
444
|
}
|
|
@@ -446,7 +450,8 @@ function withTraceContext(options, fn) {
|
|
|
446
450
|
spans: [],
|
|
447
451
|
attributes: options.attributes ?? {},
|
|
448
452
|
endpoint: options.endpoint,
|
|
449
|
-
clientIP: options.clientIP
|
|
453
|
+
clientIP: options.clientIP,
|
|
454
|
+
distributedTraceId: options.distributedTraceId
|
|
450
455
|
};
|
|
451
456
|
return asyncLocalStorage.run(context, fn);
|
|
452
457
|
}
|
|
@@ -554,7 +559,8 @@ function captureExceptionWithAttributes(error, attributes, traceId) {
|
|
|
554
559
|
stackTrace: formatErrorStackTrace(error),
|
|
555
560
|
recordedAt: (0, import_core4.nowISO)(),
|
|
556
561
|
attributes: resolvedAttrs,
|
|
557
|
-
isMessage: false
|
|
562
|
+
isMessage: false,
|
|
563
|
+
distributedTraceId: ctx?.distributedTraceId ?? null
|
|
558
564
|
});
|
|
559
565
|
}
|
|
560
566
|
function captureMessage(msg, attributes) {
|
|
@@ -569,7 +575,8 @@ function captureMessage(msg, attributes) {
|
|
|
569
575
|
stackTrace: msg,
|
|
570
576
|
recordedAt: (0, import_core4.nowISO)(),
|
|
571
577
|
attributes: resolvedAttrs,
|
|
572
|
-
isMessage: true
|
|
578
|
+
isMessage: true,
|
|
579
|
+
distributedTraceId: ctx?.distributedTraceId ?? null
|
|
573
580
|
});
|
|
574
581
|
}
|
|
575
582
|
function captureMetric(name, value) {
|
|
@@ -658,7 +665,8 @@ function captureCurrentTrace() {
|
|
|
658
665
|
clientIP: "",
|
|
659
666
|
attributes: Object.keys(ctx.attributes).length > 0 ? ctx.attributes : void 0,
|
|
660
667
|
spans: ctx.spans.length > 0 ? ctx.spans : void 0,
|
|
661
|
-
isTask: true
|
|
668
|
+
isTask: true,
|
|
669
|
+
distributedTraceId: ctx.distributedTraceId
|
|
662
670
|
});
|
|
663
671
|
} else {
|
|
664
672
|
store.addTrace({
|
|
@@ -670,7 +678,8 @@ function captureCurrentTrace() {
|
|
|
670
678
|
bodySize: ctx.bodySize ?? 0,
|
|
671
679
|
clientIP: ctx.clientIP ?? "",
|
|
672
680
|
attributes: Object.keys(ctx.attributes).length > 0 ? ctx.attributes : void 0,
|
|
673
|
-
spans: ctx.spans.length > 0 ? ctx.spans : void 0
|
|
681
|
+
spans: ctx.spans.length > 0 ? ctx.spans : void 0,
|
|
682
|
+
distributedTraceId: ctx.distributedTraceId
|
|
674
683
|
});
|
|
675
684
|
}
|
|
676
685
|
}
|
|
@@ -742,6 +751,7 @@ async function shutdown(timeoutMs) {
|
|
|
742
751
|
endSpan,
|
|
743
752
|
forkTraceContext,
|
|
744
753
|
formatErrorStackTrace,
|
|
754
|
+
getDistributedTraceId,
|
|
745
755
|
getTraceContext,
|
|
746
756
|
getTraceDuration,
|
|
747
757
|
getTraceId,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/traceway.ts","../src/collection-frame-store.ts","../src/typed-ring.ts","../src/metrics.ts","../src/stack-trace.ts","../src/context.ts"],"sourcesContent":["export {\n init,\n captureException,\n captureExceptionWithAttributes,\n captureMessage,\n captureMetric,\n captureMetricWithTags,\n captureTrace,\n captureTask,\n captureCurrentTrace,\n startSpan,\n endSpan,\n shouldSample,\n measureTask,\n shutdown,\n} from \"./traceway.js\";\nexport type { SpanHandle } from \"./traceway.js\";\n\n// Context propagation (AsyncLocalStorage-based)\nexport {\n withTraceContext,\n runWithTraceContext,\n getTraceContext,\n getTraceId,\n hasTraceContext,\n addSpanToContext,\n setTraceAttribute,\n setTraceAttributes,\n setTraceResponseInfo,\n getTraceSpans,\n getTraceDuration,\n forkTraceContext,\n traceContextStorage,\n} from \"./context.js\";\nexport type { TraceContext, TraceContextOptions } from \"./context.js\";\n\nexport { formatErrorStackTrace } from \"./stack-trace.js\";\nexport { collectMetrics, resetCpuTracking } from \"./metrics.js\";\nexport { CollectionFrameStore } from \"./collection-frame-store.js\";\nexport type { CollectionFrameStoreOptions } from \"./collection-frame-store.js\";\n\nexport type {\n ExceptionStackTrace,\n MetricRecord,\n Span,\n Trace,\n CollectionFrame,\n ReportRequest,\n TracewayOptions,\n} from \"@tracewayapp/core\";\n","import {\n generateUUID,\n parseConnectionString,\n nowISO,\n msToNanoseconds,\n} from \"@tracewayapp/core\";\nimport type {\n TracewayOptions,\n ExceptionStackTrace,\n Trace,\n Span,\n} from \"@tracewayapp/core\";\nimport { CollectionFrameStore } from \"./collection-frame-store.js\";\nimport { formatErrorStackTrace } from \"./stack-trace.js\";\nimport {\n getTraceContext,\n getTraceId,\n addSpanToContext,\n type TraceContext,\n} from \"./context.js\";\nimport * as os from \"os\";\n\nlet store: CollectionFrameStore | null = null;\n\nfunction getHostname(): string {\n try {\n const hostname = os.hostname();\n const dotIdx = hostname.indexOf(\".\");\n return dotIdx >= 0 ? hostname.slice(0, dotIdx) : hostname;\n } catch {\n return \"unknown\";\n }\n}\n\nexport function init(\n connectionString: string,\n options: TracewayOptions = {},\n): void {\n if (store !== null) {\n throw new Error(\"Traceway: already initialized. Call shutdown() first.\");\n }\n\n const { token, apiUrl } = parseConnectionString(connectionString);\n\n store = new CollectionFrameStore({\n apiUrl,\n token,\n debug: options.debug ?? false,\n maxCollectionFrames: options.maxCollectionFrames ?? 12,\n collectionInterval: options.collectionInterval ?? 5000,\n uploadThrottle: options.uploadThrottle ?? 2000,\n metricsInterval: options.metricsInterval ?? 30000,\n version: options.version ?? \"\",\n serverName: options.serverName ?? getHostname(),\n sampleRate: options.sampleRate ?? 1,\n errorSampleRate: options.errorSampleRate ?? 1,\n });\n}\n\nexport function captureException(error: Error): void {\n if (!store) return;\n // Auto-detect trace context\n const ctx = getTraceContext();\n captureExceptionWithAttributes(\n error,\n ctx?.attributes,\n ctx?.traceId,\n );\n}\n\nexport function captureExceptionWithAttributes(\n error: Error,\n attributes?: Record<string, string>,\n traceId?: string,\n): void {\n if (!store) return;\n // Auto-detect trace context if not explicitly provided\n const ctx = getTraceContext();\n const resolvedTraceId = traceId ?? ctx?.traceId ?? null;\n const resolvedAttrs = attributes ?? ctx?.attributes;\n const isTask = ctx?.isTask ?? false;\n\n store.addException({\n traceId: resolvedTraceId,\n isTask: isTask || undefined,\n stackTrace: formatErrorStackTrace(error),\n recordedAt: nowISO(),\n attributes: resolvedAttrs,\n isMessage: false,\n });\n}\n\nexport function captureMessage(\n msg: string,\n attributes?: Record<string, string>,\n): void {\n if (!store) return;\n // Auto-detect trace context\n const ctx = getTraceContext();\n const resolvedTraceId = ctx?.traceId ?? null;\n const resolvedAttrs = attributes ?? ctx?.attributes;\n const isTask = ctx?.isTask ?? false;\n\n store.addException({\n traceId: resolvedTraceId,\n isTask: isTask || undefined,\n stackTrace: msg,\n recordedAt: nowISO(),\n attributes: resolvedAttrs,\n isMessage: true,\n });\n}\n\nexport function captureMetric(name: string, value: number): void {\n if (!store) return;\n store.addMetric({\n name,\n value,\n recordedAt: nowISO(),\n });\n}\n\nexport function captureMetricWithTags(\n name: string,\n value: number,\n tags: Record<string, string>,\n): void {\n if (!store) return;\n store.addMetric({\n name,\n value,\n recordedAt: nowISO(),\n tags,\n });\n}\n\nexport function captureTrace(\n traceId: string,\n endpoint: string,\n durationMs: number,\n startedAt: Date,\n statusCode: number,\n bodySize: number,\n clientIP: string,\n attributes?: Record<string, string>,\n spans?: Span[],\n): void {\n if (!store) return;\n store.addTrace({\n id: traceId,\n endpoint,\n duration: msToNanoseconds(durationMs),\n recordedAt: startedAt.toISOString(),\n statusCode,\n bodySize,\n clientIP,\n attributes,\n spans,\n });\n}\n\nexport function captureTask(\n traceId: string,\n taskName: string,\n durationMs: number,\n startedAt: Date,\n attributes?: Record<string, string>,\n spans?: Span[],\n): void {\n if (!store) return;\n store.addTrace({\n id: traceId,\n endpoint: taskName,\n duration: msToNanoseconds(durationMs),\n recordedAt: startedAt.toISOString(),\n statusCode: 0,\n bodySize: 0,\n clientIP: \"\",\n attributes,\n spans,\n isTask: true,\n });\n}\n\n/** Handle returned by startSpan for tracking span timing */\nexport interface SpanHandle {\n id: string;\n name: string;\n startTime: string;\n startedAt: number;\n}\n\n/**\n * Start a new span. If within a trace context, the span will be\n * automatically added to the trace when ended.\n */\nexport function startSpan(name: string): SpanHandle {\n const now = Date.now();\n return {\n id: generateUUID(),\n name,\n startTime: new Date(now).toISOString(),\n startedAt: now,\n };\n}\n\n/**\n * End a span and get the completed Span object.\n * If within a trace context, automatically adds the span to the trace.\n *\n * @param addToContext - If true (default), adds span to current trace context\n */\nexport function endSpan(span: SpanHandle, addToContext: boolean = true): Span {\n const durationMs = Date.now() - span.startedAt;\n const completedSpan: Span = {\n id: span.id,\n name: span.name,\n startTime: span.startTime,\n duration: msToNanoseconds(durationMs),\n };\n\n // Auto-add to trace context if available\n if (addToContext) {\n addSpanToContext(completedSpan);\n }\n\n return completedSpan;\n}\n\n/**\n * Capture the current trace context as a trace.\n * Call this at the end of a request/task to record the trace.\n *\n * @example\n * ```ts\n * // In Express middleware (after response)\n * withTraceContext({ endpoint: `${req.method} ${req.path}` }, async () => {\n * await handleRequest(req, res);\n * setTraceResponseInfo(res.statusCode, contentLength);\n * captureCurrentTrace(); // Records the trace with all spans\n * });\n * ```\n */\nexport function captureCurrentTrace(): void {\n if (!store) return;\n\n const ctx = getTraceContext();\n if (!ctx) return;\n\n const durationMs = Date.now() - ctx.startedAt.getTime();\n const isError = (ctx.statusCode ?? 0) >= 500;\n\n if (!shouldSample(isError)) return;\n\n if (ctx.isTask) {\n store.addTrace({\n id: ctx.traceId,\n endpoint: ctx.endpoint ?? \"unknown-task\",\n duration: msToNanoseconds(durationMs),\n recordedAt: ctx.startedAt.toISOString(),\n statusCode: 0,\n bodySize: 0,\n clientIP: \"\",\n attributes: Object.keys(ctx.attributes).length > 0 ? ctx.attributes : undefined,\n spans: ctx.spans.length > 0 ? ctx.spans : undefined,\n isTask: true,\n });\n } else {\n store.addTrace({\n id: ctx.traceId,\n endpoint: ctx.endpoint ?? \"unknown\",\n duration: msToNanoseconds(durationMs),\n recordedAt: ctx.startedAt.toISOString(),\n statusCode: ctx.statusCode ?? 0,\n bodySize: ctx.bodySize ?? 0,\n clientIP: ctx.clientIP ?? \"\",\n attributes: Object.keys(ctx.attributes).length > 0 ? ctx.attributes : undefined,\n spans: ctx.spans.length > 0 ? ctx.spans : undefined,\n });\n }\n}\n\nexport function shouldSample(isError: boolean): boolean {\n if (!store) return false;\n const rate = isError ? store.errorSampleRate : store.sampleRate;\n if (rate >= 1) return true;\n if (rate <= 0) return false;\n return Math.random() < rate;\n}\n\nexport function measureTask(\n title: string,\n fn: () => void | Promise<void>,\n): void {\n const traceId = generateUUID();\n const start = Date.now();\n const startDate = new Date(start);\n\n try {\n const result = fn();\n if (result && typeof (result as Promise<void>).then === \"function\") {\n (result as Promise<void>)\n .then(() => {\n const durationMs = Date.now() - start;\n if (shouldSample(false)) {\n captureTask(traceId, title, durationMs, startDate);\n }\n })\n .catch((err: unknown) => {\n const durationMs = Date.now() - start;\n if (shouldSample(true)) {\n captureTask(traceId, title, durationMs, startDate);\n if (err instanceof Error) {\n captureExceptionWithAttributes(err, undefined, traceId);\n }\n }\n throw err;\n });\n } else {\n const durationMs = Date.now() - start;\n if (shouldSample(false)) {\n captureTask(traceId, title, durationMs, startDate);\n }\n }\n } catch (err) {\n const durationMs = Date.now() - start;\n if (shouldSample(true)) {\n captureTask(traceId, title, durationMs, startDate);\n if (err instanceof Error) {\n captureExceptionWithAttributes(err, undefined, traceId);\n }\n }\n throw err;\n }\n}\n\nexport async function shutdown(timeoutMs?: number): Promise<void> {\n if (!store) return;\n const s = store;\n store = null;\n await s.shutdown(timeoutMs);\n}\n","import * as zlib from \"zlib\";\nimport {\n nowISO,\n generateUUID,\n msToNanoseconds,\n} from \"@tracewayapp/core\";\nimport { TypedRing } from \"./typed-ring.js\";\nimport type {\n CollectionFrame,\n ExceptionStackTrace,\n MetricRecord,\n Trace,\n Span,\n ReportRequest,\n} from \"@tracewayapp/core\";\nimport { collectMetrics } from \"./metrics.js\";\n\nexport interface CollectionFrameStoreOptions {\n apiUrl: string;\n token: string;\n debug: boolean;\n maxCollectionFrames: number;\n collectionInterval: number;\n uploadThrottle: number;\n metricsInterval: number;\n version: string;\n serverName: string;\n sampleRate: number;\n errorSampleRate: number;\n}\n\nexport class CollectionFrameStore {\n private current: CollectionFrame | null = null;\n private currentSetAt: number = Date.now();\n private sendQueue: TypedRing<CollectionFrame>;\n private lastUploadStarted: number | null = null;\n\n private collectionTimer: ReturnType<typeof setInterval> | null = null;\n private metricsTimer: ReturnType<typeof setInterval> | null = null;\n\n private readonly apiUrl: string;\n private readonly token: string;\n private readonly debug: boolean;\n private readonly collectionInterval: number;\n private readonly uploadThrottle: number;\n private readonly metricsInterval: number;\n private readonly version: string;\n private readonly serverName: string;\n\n readonly sampleRate: number;\n readonly errorSampleRate: number;\n\n constructor(options: CollectionFrameStoreOptions) {\n this.apiUrl = options.apiUrl;\n this.token = options.token;\n this.debug = options.debug;\n this.collectionInterval = options.collectionInterval;\n this.uploadThrottle = options.uploadThrottle;\n this.metricsInterval = options.metricsInterval;\n this.version = options.version;\n this.serverName = options.serverName;\n this.sampleRate = options.sampleRate;\n this.errorSampleRate = options.errorSampleRate;\n this.sendQueue = new TypedRing<CollectionFrame>(\n options.maxCollectionFrames,\n );\n\n this.collectionTimer = setInterval(() => {\n this.tick();\n }, this.collectionInterval);\n if (this.collectionTimer && typeof this.collectionTimer.unref === \"function\") {\n this.collectionTimer.unref();\n }\n\n this.metricsTimer = setInterval(() => {\n this.collectSystemMetrics();\n }, this.metricsInterval);\n if (this.metricsTimer && typeof this.metricsTimer.unref === \"function\") {\n this.metricsTimer.unref();\n }\n }\n\n private tick(): void {\n if (this.current !== null) {\n if (this.currentSetAt < Date.now() - this.collectionInterval) {\n this.rotateCurrentCollectionFrame();\n this.processSendQueue();\n }\n } else if (this.sendQueue.length > 0) {\n this.processSendQueue();\n }\n }\n\n private ensureCurrent(): CollectionFrame {\n if (this.current === null) {\n this.current = { stackTraces: [], metrics: [], traces: [] };\n this.currentSetAt = Date.now();\n }\n return this.current;\n }\n\n addException(exception: ExceptionStackTrace): void {\n this.ensureCurrent().stackTraces.push(exception);\n }\n\n addMetric(metric: MetricRecord): void {\n this.ensureCurrent().metrics.push(metric);\n }\n\n addTrace(trace: Trace): void {\n this.ensureCurrent().traces.push(trace);\n }\n\n private rotateCurrentCollectionFrame(): void {\n if (this.current !== null) {\n this.sendQueue.push(this.current);\n this.current = null;\n }\n }\n\n private processSendQueue(): void {\n if (\n this.lastUploadStarted === null ||\n this.lastUploadStarted < Date.now() - this.uploadThrottle\n ) {\n this.lastUploadStarted = Date.now();\n const frames = this.sendQueue.readAll();\n if (frames.length > 0) {\n this.triggerUpload(frames);\n }\n }\n }\n\n private triggerUpload(framesToSend: CollectionFrame[]): void {\n const payload: ReportRequest = {\n collectionFrames: framesToSend,\n appVersion: this.version,\n serverName: this.serverName,\n };\n\n let jsonData: string;\n try {\n jsonData = JSON.stringify(payload);\n } catch (err) {\n if (this.debug) {\n console.error(\"Traceway: failed to serialize frames:\", err);\n }\n return;\n }\n\n let gzipped: Uint8Array;\n try {\n gzipped = new Uint8Array(zlib.gzipSync(Buffer.from(jsonData)));\n } catch (err) {\n if (this.debug) {\n console.error(\"Traceway: failed to gzip:\", err);\n }\n return;\n }\n\n fetch(this.apiUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Content-Encoding\": \"gzip\",\n Authorization: `Bearer ${this.token}`,\n },\n body: gzipped as unknown as BodyInit,\n })\n .then((resp) => {\n if (resp.status === 200) {\n this.sendQueue.remove(framesToSend);\n } else if (this.debug) {\n console.error(`Traceway: upload returned status ${resp.status}`);\n }\n })\n .catch((err) => {\n if (this.debug) {\n console.error(\"Traceway: upload failed:\", err);\n }\n });\n }\n\n private collectSystemMetrics(): void {\n try {\n const metrics = collectMetrics();\n for (const metric of metrics) {\n this.addMetric(metric);\n }\n } catch (err) {\n if (this.debug) {\n console.error(\"Traceway: failed to collect metrics:\", err);\n }\n }\n }\n\n async shutdown(timeoutMs?: number): Promise<void> {\n if (this.collectionTimer !== null) {\n clearInterval(this.collectionTimer);\n this.collectionTimer = null;\n }\n if (this.metricsTimer !== null) {\n clearInterval(this.metricsTimer);\n this.metricsTimer = null;\n }\n\n this.rotateCurrentCollectionFrame();\n\n const frames = this.sendQueue.readAll();\n if (frames.length === 0) return;\n\n const uploadPromise = (async () => {\n const payload: ReportRequest = {\n collectionFrames: frames,\n appVersion: this.version,\n serverName: this.serverName,\n };\n\n try {\n const jsonData = JSON.stringify(payload);\n const gzipped = new Uint8Array(zlib.gzipSync(Buffer.from(jsonData)));\n\n const resp = await fetch(this.apiUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Content-Encoding\": \"gzip\",\n Authorization: `Bearer ${this.token}`,\n },\n body: gzipped as unknown as BodyInit,\n });\n\n if (resp.status === 200) {\n this.sendQueue.remove(frames);\n }\n } catch (err) {\n if (this.debug) {\n console.error(\"Traceway: shutdown upload failed:\", err);\n }\n }\n })();\n\n if (timeoutMs !== undefined) {\n await Promise.race([\n uploadPromise,\n new Promise<void>((resolve) => setTimeout(resolve, timeoutMs)),\n ]);\n } else {\n await uploadPromise;\n }\n }\n}\n","export class TypedRing<T> {\n private arr: (T | null)[];\n private head: number = 0;\n private _capacity: number;\n private _len: number = 0;\n\n constructor(capacity: number) {\n this._capacity = capacity;\n this.arr = new Array<T | null>(capacity).fill(null);\n }\n\n get length(): number {\n return this._len;\n }\n\n get capacity(): number {\n return this._capacity;\n }\n\n push(val: T): void {\n this.arr[this.head] = val;\n this.head = (this.head + 1) % this._capacity;\n if (this._len < this._capacity) {\n this._len += 1;\n }\n }\n\n readAll(): T[] {\n const result: T[] = [];\n for (let i = 0; i < this._len; i++) {\n const idx =\n (this.head - this._len + i + this._capacity) % this._capacity;\n result.push(this.arr[idx] as T);\n }\n return result;\n }\n\n clear(): void {\n for (let i = 0; i < this.arr.length; i++) {\n this.arr[i] = null;\n }\n this.head = 0;\n this._len = 0;\n }\n\n remove(vals: T[]): number {\n if (vals.length === 0) return 0;\n\n const toRemove = new Set<T>(vals);\n let writeIdx = 0;\n let removed = 0;\n\n for (let i = 0; i < this._len; i++) {\n const readIdx =\n (this.head - this._len + i + this._capacity) % this._capacity;\n if (toRemove.has(this.arr[readIdx] as T)) {\n removed++;\n } else {\n if (writeIdx !== i) {\n const destIdx =\n (this.head - this._len + writeIdx + this._capacity) %\n this._capacity;\n this.arr[destIdx] = this.arr[readIdx];\n }\n writeIdx++;\n }\n }\n\n for (let i = writeIdx; i < this._len; i++) {\n const idx =\n (this.head - this._len + i + this._capacity) % this._capacity;\n this.arr[idx] = null;\n }\n\n this._len = writeIdx;\n this.head = (this.head - removed + this._capacity) % this._capacity;\n\n return removed;\n }\n}\n","import * as os from \"os\";\nimport { METRIC_MEM_USED, METRIC_MEM_TOTAL, METRIC_CPU_USED_PCNT } from \"@tracewayapp/core\";\nimport type { MetricRecord } from \"@tracewayapp/core\";\nimport { nowISO } from \"@tracewayapp/core\";\n\nlet prevCpuUsage: NodeJS.CpuUsage | null = null;\nlet prevCpuTime: number | null = null;\n\nexport function collectMetrics(): MetricRecord[] {\n const metrics: MetricRecord[] = [];\n const recordedAt = nowISO();\n\n const mem = process.memoryUsage();\n metrics.push({\n name: METRIC_MEM_USED,\n value: Math.round((mem.rss / 1024 / 1024) * 100) / 100,\n recordedAt,\n });\n\n const totalMem = os.totalmem();\n metrics.push({\n name: METRIC_MEM_TOTAL,\n value: Math.round((totalMem / 1024 / 1024) * 100) / 100,\n recordedAt,\n });\n\n const currentCpuUsage = process.cpuUsage();\n const currentTime = Date.now();\n if (prevCpuUsage !== null && prevCpuTime !== null) {\n const elapsedMs = currentTime - prevCpuTime;\n if (elapsedMs > 0) {\n const userDelta = currentCpuUsage.user - prevCpuUsage.user;\n const systemDelta = currentCpuUsage.system - prevCpuUsage.system;\n const totalDeltaMs = (userDelta + systemDelta) / 1000;\n const cpuCount = os.cpus().length || 1;\n const cpuPercent = (totalDeltaMs / elapsedMs / cpuCount) * 100;\n metrics.push({\n name: METRIC_CPU_USED_PCNT,\n value: Math.round(cpuPercent * 100) / 100,\n recordedAt,\n });\n }\n }\n prevCpuUsage = currentCpuUsage;\n prevCpuTime = currentTime;\n\n return metrics;\n}\n\nexport function resetCpuTracking(): void {\n prevCpuUsage = null;\n prevCpuTime = null;\n}\n","export function formatErrorStackTrace(error: Error): string {\n const lines: string[] = [];\n\n const typeName = error.constructor.name || \"Error\";\n lines.push(`${typeName}: ${error.message}`);\n\n if (error.stack) {\n const stackLines = error.stack.split(\"\\n\");\n for (const line of stackLines) {\n const match = line.match(/^\\s+at\\s+(.+?)\\s+\\((.+):(\\d+):\\d+\\)$/);\n if (match) {\n const funcName = shortenFunctionName(match[1]);\n const file = shortenFilePath(match[2]);\n const lineNum = match[3];\n lines.push(`${funcName}()`);\n lines.push(` ${file}:${lineNum}`);\n continue;\n }\n\n const matchNoParens = line.match(/^\\s+at\\s+(.+):(\\d+):\\d+$/);\n if (matchNoParens) {\n const file = shortenFilePath(matchNoParens[1]);\n const lineNum = matchNoParens[2];\n lines.push(`<anonymous>()`);\n lines.push(` ${file}:${lineNum}`);\n continue;\n }\n\n const matchFnOnly = line.match(/^\\s+at\\s+(.+)$/);\n if (matchFnOnly) {\n const funcName = shortenFunctionName(matchFnOnly[1]);\n lines.push(`${funcName}()`);\n lines.push(` <unknown>:0`);\n }\n }\n }\n\n return lines.join(\"\\n\") + \"\\n\";\n}\n\nfunction shortenFunctionName(fn: string): string {\n const slashIdx = fn.lastIndexOf(\"/\");\n if (slashIdx >= 0) {\n fn = fn.slice(slashIdx + 1);\n }\n const dotIdx = fn.indexOf(\".\");\n if (dotIdx >= 0) {\n fn = fn.slice(dotIdx + 1);\n }\n return fn;\n}\n\nfunction shortenFilePath(filePath: string): string {\n const parts = filePath.split(\"/\");\n return parts[parts.length - 1];\n}\n","import { AsyncLocalStorage } from \"async_hooks\";\nimport { generateUUID } from \"@tracewayapp/core\";\nimport type { Span } from \"@tracewayapp/core\";\n\n/**\n * Trace context stored in AsyncLocalStorage.\n * Automatically propagates through async operations.\n */\nexport interface TraceContext {\n /** Unique trace identifier (UUID v4) */\n traceId: string;\n /** Whether this is a background task (vs HTTP request) */\n isTask: boolean;\n /** When the trace started */\n startedAt: Date;\n /** Collected spans within this trace */\n spans: Span[];\n /** Key-value attributes for this trace */\n attributes: Record<string, string>;\n /** For HTTP traces: endpoint like \"GET /api/users\" */\n endpoint?: string;\n /** For HTTP traces: response status code */\n statusCode?: number;\n /** For HTTP traces: response body size */\n bodySize?: number;\n /** For HTTP traces: client IP address */\n clientIP?: string;\n}\n\n/**\n * Options for creating a new trace context.\n */\nexport interface TraceContextOptions {\n /** Custom trace ID (auto-generated if not provided) */\n traceId?: string;\n /** Mark as background task instead of HTTP trace */\n isTask?: boolean;\n /** Initial attributes */\n attributes?: Record<string, string>;\n /** HTTP endpoint (e.g., \"GET /api/users\") */\n endpoint?: string;\n /** Client IP address */\n clientIP?: string;\n}\n\n// The AsyncLocalStorage instance for trace context\nconst asyncLocalStorage = new AsyncLocalStorage<TraceContext>();\n\n/**\n * Get the current trace context, if any.\n * Returns undefined if not within a trace context.\n */\nexport function getTraceContext(): TraceContext | undefined {\n return asyncLocalStorage.getStore();\n}\n\n/**\n * Get the current trace ID, if within a trace context.\n */\nexport function getTraceId(): string | undefined {\n return asyncLocalStorage.getStore()?.traceId;\n}\n\n/**\n * Check if currently within a trace context.\n */\nexport function hasTraceContext(): boolean {\n return asyncLocalStorage.getStore() !== undefined;\n}\n\n/**\n * Run a function within a new trace context.\n * All async operations within will have access to this context.\n *\n * @example\n * ```ts\n * // HTTP request handler\n * withTraceContext({ endpoint: \"GET /api/users\", clientIP: req.ip }, async () => {\n * const users = await db.query(\"SELECT * FROM users\");\n * captureException(new Error(\"oops\")); // Auto-linked to trace\n * return users;\n * });\n *\n * // Background task\n * withTraceContext({ isTask: true, endpoint: \"process-emails\" }, async () => {\n * await processEmails();\n * });\n * ```\n */\nexport function withTraceContext<T>(\n options: TraceContextOptions,\n fn: () => T,\n): T {\n const context: TraceContext = {\n traceId: options.traceId ?? generateUUID(),\n isTask: options.isTask ?? false,\n startedAt: new Date(),\n spans: [],\n attributes: options.attributes ?? {},\n endpoint: options.endpoint,\n clientIP: options.clientIP,\n };\n return asyncLocalStorage.run(context, fn);\n}\n\n/**\n * Run a function within a trace context, automatically capturing the trace on completion.\n * This is a convenience wrapper that handles timing and capture automatically.\n *\n * @example\n * ```ts\n * // In Express middleware\n * app.use((req, res, next) => {\n * runWithTraceContext(\n * {\n * endpoint: `${req.method} ${req.path}`,\n * clientIP: req.ip,\n * attributes: { userId: req.user?.id },\n * },\n * async () => {\n * await next();\n * // Status code and body size set via setTraceResponseInfo()\n * },\n * { captureOnEnd: true }\n * );\n * });\n * ```\n */\nexport function runWithTraceContext<T>(\n options: TraceContextOptions,\n fn: () => T | Promise<T>,\n): T | Promise<T> {\n return withTraceContext(options, fn);\n}\n\n/**\n * Add a completed span to the current trace context.\n * No-op if not within a trace context.\n */\nexport function addSpanToContext(span: Span): void {\n const ctx = asyncLocalStorage.getStore();\n if (ctx) {\n ctx.spans.push(span);\n }\n}\n\n/**\n * Set an attribute on the current trace context.\n * No-op if not within a trace context.\n */\nexport function setTraceAttribute(key: string, value: string): void {\n const ctx = asyncLocalStorage.getStore();\n if (ctx) {\n ctx.attributes[key] = value;\n }\n}\n\n/**\n * Set multiple attributes on the current trace context.\n * No-op if not within a trace context.\n */\nexport function setTraceAttributes(attributes: Record<string, string>): void {\n const ctx = asyncLocalStorage.getStore();\n if (ctx) {\n Object.assign(ctx.attributes, attributes);\n }\n}\n\n/**\n * Set HTTP response info on the current trace context.\n * Used by framework adapters after the response is sent.\n */\nexport function setTraceResponseInfo(\n statusCode: number,\n bodySize?: number,\n): void {\n const ctx = asyncLocalStorage.getStore();\n if (ctx) {\n ctx.statusCode = statusCode;\n ctx.bodySize = bodySize;\n }\n}\n\n/**\n * Get all spans from the current trace context.\n * Returns empty array if not within a trace context.\n */\nexport function getTraceSpans(): Span[] {\n return asyncLocalStorage.getStore()?.spans ?? [];\n}\n\n/**\n * Get the duration in milliseconds since the trace started.\n * Returns 0 if not within a trace context.\n */\nexport function getTraceDuration(): number {\n const ctx = asyncLocalStorage.getStore();\n if (!ctx) return 0;\n return Date.now() - ctx.startedAt.getTime();\n}\n\n/**\n * Fork the current trace context for a sub-operation.\n * Useful for parallel operations that should have isolated spans.\n * Returns undefined if not within a trace context.\n */\nexport function forkTraceContext<T>(fn: () => T): T | undefined {\n const parentCtx = asyncLocalStorage.getStore();\n if (!parentCtx) return undefined;\n\n const forkedContext: TraceContext = {\n ...parentCtx,\n spans: [], // Forked context gets its own spans\n attributes: { ...parentCtx.attributes },\n };\n\n return asyncLocalStorage.run(forkedContext, () => {\n const result = fn();\n // Merge spans back to parent after completion\n parentCtx.spans.push(...forkedContext.spans);\n return result;\n });\n}\n\n// Export the AsyncLocalStorage instance for advanced use cases\nexport { asyncLocalStorage as traceContextStorage };\n"],"mappings":"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","names":["import_core","import_core","import_core","os","hostname"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/traceway.ts","../src/collection-frame-store.ts","../src/typed-ring.ts","../src/metrics.ts","../src/stack-trace.ts","../src/context.ts"],"sourcesContent":["export {\n init,\n captureException,\n captureExceptionWithAttributes,\n captureMessage,\n captureMetric,\n captureMetricWithTags,\n captureTrace,\n captureTask,\n captureCurrentTrace,\n startSpan,\n endSpan,\n shouldSample,\n measureTask,\n shutdown,\n} from \"./traceway.js\";\nexport type { SpanHandle } from \"./traceway.js\";\n\n// Context propagation (AsyncLocalStorage-based)\nexport {\n withTraceContext,\n runWithTraceContext,\n getTraceContext,\n getTraceId,\n getDistributedTraceId,\n hasTraceContext,\n addSpanToContext,\n setTraceAttribute,\n setTraceAttributes,\n setTraceResponseInfo,\n getTraceSpans,\n getTraceDuration,\n forkTraceContext,\n traceContextStorage,\n} from \"./context.js\";\nexport type { TraceContext, TraceContextOptions } from \"./context.js\";\n\nexport { formatErrorStackTrace } from \"./stack-trace.js\";\nexport { collectMetrics, resetCpuTracking } from \"./metrics.js\";\nexport { CollectionFrameStore } from \"./collection-frame-store.js\";\nexport type { CollectionFrameStoreOptions } from \"./collection-frame-store.js\";\n\nexport type {\n ExceptionStackTrace,\n MetricRecord,\n Span,\n Trace,\n CollectionFrame,\n ReportRequest,\n TracewayOptions,\n} from \"@tracewayapp/core\";\n","import {\n generateUUID,\n parseConnectionString,\n nowISO,\n msToNanoseconds,\n} from \"@tracewayapp/core\";\nimport type {\n TracewayOptions,\n ExceptionStackTrace,\n Trace,\n Span,\n} from \"@tracewayapp/core\";\nimport { CollectionFrameStore } from \"./collection-frame-store.js\";\nimport { formatErrorStackTrace } from \"./stack-trace.js\";\nimport {\n getTraceContext,\n getTraceId,\n getDistributedTraceId,\n addSpanToContext,\n type TraceContext,\n} from \"./context.js\";\nimport * as os from \"os\";\n\nlet store: CollectionFrameStore | null = null;\n\nfunction getHostname(): string {\n try {\n const hostname = os.hostname();\n const dotIdx = hostname.indexOf(\".\");\n return dotIdx >= 0 ? hostname.slice(0, dotIdx) : hostname;\n } catch {\n return \"unknown\";\n }\n}\n\nexport function init(\n connectionString: string,\n options: TracewayOptions = {},\n): void {\n if (store !== null) {\n throw new Error(\"Traceway: already initialized. Call shutdown() first.\");\n }\n\n const { token, apiUrl } = parseConnectionString(connectionString);\n\n store = new CollectionFrameStore({\n apiUrl,\n token,\n debug: options.debug ?? false,\n maxCollectionFrames: options.maxCollectionFrames ?? 12,\n collectionInterval: options.collectionInterval ?? 5000,\n uploadThrottle: options.uploadThrottle ?? 2000,\n metricsInterval: options.metricsInterval ?? 30000,\n version: options.version ?? \"\",\n serverName: options.serverName ?? getHostname(),\n sampleRate: options.sampleRate ?? 1,\n errorSampleRate: options.errorSampleRate ?? 1,\n });\n}\n\nexport function captureException(error: Error): void {\n if (!store) return;\n // Auto-detect trace context\n const ctx = getTraceContext();\n captureExceptionWithAttributes(\n error,\n ctx?.attributes,\n ctx?.traceId,\n );\n}\n\nexport function captureExceptionWithAttributes(\n error: Error,\n attributes?: Record<string, string>,\n traceId?: string,\n): void {\n if (!store) return;\n // Auto-detect trace context if not explicitly provided\n const ctx = getTraceContext();\n const resolvedTraceId = traceId ?? ctx?.traceId ?? null;\n const resolvedAttrs = attributes ?? ctx?.attributes;\n const isTask = ctx?.isTask ?? false;\n\n store.addException({\n traceId: resolvedTraceId,\n isTask: isTask || undefined,\n stackTrace: formatErrorStackTrace(error),\n recordedAt: nowISO(),\n attributes: resolvedAttrs,\n isMessage: false,\n distributedTraceId: ctx?.distributedTraceId ?? null,\n });\n}\n\nexport function captureMessage(\n msg: string,\n attributes?: Record<string, string>,\n): void {\n if (!store) return;\n // Auto-detect trace context\n const ctx = getTraceContext();\n const resolvedTraceId = ctx?.traceId ?? null;\n const resolvedAttrs = attributes ?? ctx?.attributes;\n const isTask = ctx?.isTask ?? false;\n\n store.addException({\n traceId: resolvedTraceId,\n isTask: isTask || undefined,\n stackTrace: msg,\n recordedAt: nowISO(),\n attributes: resolvedAttrs,\n isMessage: true,\n distributedTraceId: ctx?.distributedTraceId ?? null,\n });\n}\n\nexport function captureMetric(name: string, value: number): void {\n if (!store) return;\n store.addMetric({\n name,\n value,\n recordedAt: nowISO(),\n });\n}\n\nexport function captureMetricWithTags(\n name: string,\n value: number,\n tags: Record<string, string>,\n): void {\n if (!store) return;\n store.addMetric({\n name,\n value,\n recordedAt: nowISO(),\n tags,\n });\n}\n\nexport function captureTrace(\n traceId: string,\n endpoint: string,\n durationMs: number,\n startedAt: Date,\n statusCode: number,\n bodySize: number,\n clientIP: string,\n attributes?: Record<string, string>,\n spans?: Span[],\n): void {\n if (!store) return;\n store.addTrace({\n id: traceId,\n endpoint,\n duration: msToNanoseconds(durationMs),\n recordedAt: startedAt.toISOString(),\n statusCode,\n bodySize,\n clientIP,\n attributes,\n spans,\n });\n}\n\nexport function captureTask(\n traceId: string,\n taskName: string,\n durationMs: number,\n startedAt: Date,\n attributes?: Record<string, string>,\n spans?: Span[],\n): void {\n if (!store) return;\n store.addTrace({\n id: traceId,\n endpoint: taskName,\n duration: msToNanoseconds(durationMs),\n recordedAt: startedAt.toISOString(),\n statusCode: 0,\n bodySize: 0,\n clientIP: \"\",\n attributes,\n spans,\n isTask: true,\n });\n}\n\n/** Handle returned by startSpan for tracking span timing */\nexport interface SpanHandle {\n id: string;\n name: string;\n startTime: string;\n startedAt: number;\n}\n\n/**\n * Start a new span. If within a trace context, the span will be\n * automatically added to the trace when ended.\n */\nexport function startSpan(name: string): SpanHandle {\n const now = Date.now();\n return {\n id: generateUUID(),\n name,\n startTime: new Date(now).toISOString(),\n startedAt: now,\n };\n}\n\n/**\n * End a span and get the completed Span object.\n * If within a trace context, automatically adds the span to the trace.\n *\n * @param addToContext - If true (default), adds span to current trace context\n */\nexport function endSpan(span: SpanHandle, addToContext: boolean = true): Span {\n const durationMs = Date.now() - span.startedAt;\n const completedSpan: Span = {\n id: span.id,\n name: span.name,\n startTime: span.startTime,\n duration: msToNanoseconds(durationMs),\n };\n\n // Auto-add to trace context if available\n if (addToContext) {\n addSpanToContext(completedSpan);\n }\n\n return completedSpan;\n}\n\n/**\n * Capture the current trace context as a trace.\n * Call this at the end of a request/task to record the trace.\n *\n * @example\n * ```ts\n * // In Express middleware (after response)\n * withTraceContext({ endpoint: `${req.method} ${req.path}` }, async () => {\n * await handleRequest(req, res);\n * setTraceResponseInfo(res.statusCode, contentLength);\n * captureCurrentTrace(); // Records the trace with all spans\n * });\n * ```\n */\nexport function captureCurrentTrace(): void {\n if (!store) return;\n\n const ctx = getTraceContext();\n if (!ctx) return;\n\n const durationMs = Date.now() - ctx.startedAt.getTime();\n const isError = (ctx.statusCode ?? 0) >= 500;\n\n if (!shouldSample(isError)) return;\n\n if (ctx.isTask) {\n store.addTrace({\n id: ctx.traceId,\n endpoint: ctx.endpoint ?? \"unknown-task\",\n duration: msToNanoseconds(durationMs),\n recordedAt: ctx.startedAt.toISOString(),\n statusCode: 0,\n bodySize: 0,\n clientIP: \"\",\n attributes: Object.keys(ctx.attributes).length > 0 ? ctx.attributes : undefined,\n spans: ctx.spans.length > 0 ? ctx.spans : undefined,\n isTask: true,\n distributedTraceId: ctx.distributedTraceId,\n });\n } else {\n store.addTrace({\n id: ctx.traceId,\n endpoint: ctx.endpoint ?? \"unknown\",\n duration: msToNanoseconds(durationMs),\n recordedAt: ctx.startedAt.toISOString(),\n statusCode: ctx.statusCode ?? 0,\n bodySize: ctx.bodySize ?? 0,\n clientIP: ctx.clientIP ?? \"\",\n attributes: Object.keys(ctx.attributes).length > 0 ? ctx.attributes : undefined,\n spans: ctx.spans.length > 0 ? ctx.spans : undefined,\n distributedTraceId: ctx.distributedTraceId,\n });\n }\n}\n\nexport function shouldSample(isError: boolean): boolean {\n if (!store) return false;\n const rate = isError ? store.errorSampleRate : store.sampleRate;\n if (rate >= 1) return true;\n if (rate <= 0) return false;\n return Math.random() < rate;\n}\n\nexport function measureTask(\n title: string,\n fn: () => void | Promise<void>,\n): void {\n const traceId = generateUUID();\n const start = Date.now();\n const startDate = new Date(start);\n\n try {\n const result = fn();\n if (result && typeof (result as Promise<void>).then === \"function\") {\n (result as Promise<void>)\n .then(() => {\n const durationMs = Date.now() - start;\n if (shouldSample(false)) {\n captureTask(traceId, title, durationMs, startDate);\n }\n })\n .catch((err: unknown) => {\n const durationMs = Date.now() - start;\n if (shouldSample(true)) {\n captureTask(traceId, title, durationMs, startDate);\n if (err instanceof Error) {\n captureExceptionWithAttributes(err, undefined, traceId);\n }\n }\n throw err;\n });\n } else {\n const durationMs = Date.now() - start;\n if (shouldSample(false)) {\n captureTask(traceId, title, durationMs, startDate);\n }\n }\n } catch (err) {\n const durationMs = Date.now() - start;\n if (shouldSample(true)) {\n captureTask(traceId, title, durationMs, startDate);\n if (err instanceof Error) {\n captureExceptionWithAttributes(err, undefined, traceId);\n }\n }\n throw err;\n }\n}\n\nexport async function shutdown(timeoutMs?: number): Promise<void> {\n if (!store) return;\n const s = store;\n store = null;\n await s.shutdown(timeoutMs);\n}\n","import * as zlib from \"zlib\";\nimport {\n nowISO,\n generateUUID,\n msToNanoseconds,\n} from \"@tracewayapp/core\";\nimport { TypedRing } from \"./typed-ring.js\";\nimport type {\n CollectionFrame,\n ExceptionStackTrace,\n MetricRecord,\n Trace,\n Span,\n ReportRequest,\n} from \"@tracewayapp/core\";\nimport { collectMetrics } from \"./metrics.js\";\n\nexport interface CollectionFrameStoreOptions {\n apiUrl: string;\n token: string;\n debug: boolean;\n maxCollectionFrames: number;\n collectionInterval: number;\n uploadThrottle: number;\n metricsInterval: number;\n version: string;\n serverName: string;\n sampleRate: number;\n errorSampleRate: number;\n}\n\nexport class CollectionFrameStore {\n private current: CollectionFrame | null = null;\n private currentSetAt: number = Date.now();\n private sendQueue: TypedRing<CollectionFrame>;\n private lastUploadStarted: number | null = null;\n\n private collectionTimer: ReturnType<typeof setInterval> | null = null;\n private metricsTimer: ReturnType<typeof setInterval> | null = null;\n\n private readonly apiUrl: string;\n private readonly token: string;\n private readonly debug: boolean;\n private readonly collectionInterval: number;\n private readonly uploadThrottle: number;\n private readonly metricsInterval: number;\n private readonly version: string;\n private readonly serverName: string;\n\n readonly sampleRate: number;\n readonly errorSampleRate: number;\n\n constructor(options: CollectionFrameStoreOptions) {\n this.apiUrl = options.apiUrl;\n this.token = options.token;\n this.debug = options.debug;\n this.collectionInterval = options.collectionInterval;\n this.uploadThrottle = options.uploadThrottle;\n this.metricsInterval = options.metricsInterval;\n this.version = options.version;\n this.serverName = options.serverName;\n this.sampleRate = options.sampleRate;\n this.errorSampleRate = options.errorSampleRate;\n this.sendQueue = new TypedRing<CollectionFrame>(\n options.maxCollectionFrames,\n );\n\n this.collectionTimer = setInterval(() => {\n this.tick();\n }, this.collectionInterval);\n if (this.collectionTimer && typeof this.collectionTimer.unref === \"function\") {\n this.collectionTimer.unref();\n }\n\n this.metricsTimer = setInterval(() => {\n this.collectSystemMetrics();\n }, this.metricsInterval);\n if (this.metricsTimer && typeof this.metricsTimer.unref === \"function\") {\n this.metricsTimer.unref();\n }\n }\n\n private tick(): void {\n if (this.current !== null) {\n if (this.currentSetAt < Date.now() - this.collectionInterval) {\n this.rotateCurrentCollectionFrame();\n this.processSendQueue();\n }\n } else if (this.sendQueue.length > 0) {\n this.processSendQueue();\n }\n }\n\n private ensureCurrent(): CollectionFrame {\n if (this.current === null) {\n this.current = { stackTraces: [], metrics: [], traces: [] };\n this.currentSetAt = Date.now();\n }\n return this.current;\n }\n\n addException(exception: ExceptionStackTrace): void {\n this.ensureCurrent().stackTraces.push(exception);\n }\n\n addMetric(metric: MetricRecord): void {\n this.ensureCurrent().metrics.push(metric);\n }\n\n addTrace(trace: Trace): void {\n this.ensureCurrent().traces.push(trace);\n }\n\n private rotateCurrentCollectionFrame(): void {\n if (this.current !== null) {\n this.sendQueue.push(this.current);\n this.current = null;\n }\n }\n\n private processSendQueue(): void {\n if (\n this.lastUploadStarted === null ||\n this.lastUploadStarted < Date.now() - this.uploadThrottle\n ) {\n this.lastUploadStarted = Date.now();\n const frames = this.sendQueue.readAll();\n if (frames.length > 0) {\n this.triggerUpload(frames);\n }\n }\n }\n\n private triggerUpload(framesToSend: CollectionFrame[]): void {\n const payload: ReportRequest = {\n collectionFrames: framesToSend,\n appVersion: this.version,\n serverName: this.serverName,\n };\n\n let jsonData: string;\n try {\n jsonData = JSON.stringify(payload);\n } catch (err) {\n if (this.debug) {\n console.error(\"Traceway: failed to serialize frames:\", err);\n }\n return;\n }\n\n let gzipped: Uint8Array;\n try {\n gzipped = new Uint8Array(zlib.gzipSync(Buffer.from(jsonData)));\n } catch (err) {\n if (this.debug) {\n console.error(\"Traceway: failed to gzip:\", err);\n }\n return;\n }\n\n fetch(this.apiUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Content-Encoding\": \"gzip\",\n Authorization: `Bearer ${this.token}`,\n },\n body: gzipped as unknown as BodyInit,\n })\n .then((resp) => {\n if (resp.status === 200) {\n this.sendQueue.remove(framesToSend);\n } else if (this.debug) {\n console.error(`Traceway: upload returned status ${resp.status}`);\n }\n })\n .catch((err) => {\n if (this.debug) {\n console.error(\"Traceway: upload failed:\", err);\n }\n });\n }\n\n private collectSystemMetrics(): void {\n try {\n const metrics = collectMetrics();\n for (const metric of metrics) {\n this.addMetric(metric);\n }\n } catch (err) {\n if (this.debug) {\n console.error(\"Traceway: failed to collect metrics:\", err);\n }\n }\n }\n\n async shutdown(timeoutMs?: number): Promise<void> {\n if (this.collectionTimer !== null) {\n clearInterval(this.collectionTimer);\n this.collectionTimer = null;\n }\n if (this.metricsTimer !== null) {\n clearInterval(this.metricsTimer);\n this.metricsTimer = null;\n }\n\n this.rotateCurrentCollectionFrame();\n\n const frames = this.sendQueue.readAll();\n if (frames.length === 0) return;\n\n const uploadPromise = (async () => {\n const payload: ReportRequest = {\n collectionFrames: frames,\n appVersion: this.version,\n serverName: this.serverName,\n };\n\n try {\n const jsonData = JSON.stringify(payload);\n const gzipped = new Uint8Array(zlib.gzipSync(Buffer.from(jsonData)));\n\n const resp = await fetch(this.apiUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Content-Encoding\": \"gzip\",\n Authorization: `Bearer ${this.token}`,\n },\n body: gzipped as unknown as BodyInit,\n });\n\n if (resp.status === 200) {\n this.sendQueue.remove(frames);\n }\n } catch (err) {\n if (this.debug) {\n console.error(\"Traceway: shutdown upload failed:\", err);\n }\n }\n })();\n\n if (timeoutMs !== undefined) {\n await Promise.race([\n uploadPromise,\n new Promise<void>((resolve) => setTimeout(resolve, timeoutMs)),\n ]);\n } else {\n await uploadPromise;\n }\n }\n}\n","export class TypedRing<T> {\n private arr: (T | null)[];\n private head: number = 0;\n private _capacity: number;\n private _len: number = 0;\n\n constructor(capacity: number) {\n this._capacity = capacity;\n this.arr = new Array<T | null>(capacity).fill(null);\n }\n\n get length(): number {\n return this._len;\n }\n\n get capacity(): number {\n return this._capacity;\n }\n\n push(val: T): void {\n this.arr[this.head] = val;\n this.head = (this.head + 1) % this._capacity;\n if (this._len < this._capacity) {\n this._len += 1;\n }\n }\n\n readAll(): T[] {\n const result: T[] = [];\n for (let i = 0; i < this._len; i++) {\n const idx =\n (this.head - this._len + i + this._capacity) % this._capacity;\n result.push(this.arr[idx] as T);\n }\n return result;\n }\n\n clear(): void {\n for (let i = 0; i < this.arr.length; i++) {\n this.arr[i] = null;\n }\n this.head = 0;\n this._len = 0;\n }\n\n remove(vals: T[]): number {\n if (vals.length === 0) return 0;\n\n const toRemove = new Set<T>(vals);\n let writeIdx = 0;\n let removed = 0;\n\n for (let i = 0; i < this._len; i++) {\n const readIdx =\n (this.head - this._len + i + this._capacity) % this._capacity;\n if (toRemove.has(this.arr[readIdx] as T)) {\n removed++;\n } else {\n if (writeIdx !== i) {\n const destIdx =\n (this.head - this._len + writeIdx + this._capacity) %\n this._capacity;\n this.arr[destIdx] = this.arr[readIdx];\n }\n writeIdx++;\n }\n }\n\n for (let i = writeIdx; i < this._len; i++) {\n const idx =\n (this.head - this._len + i + this._capacity) % this._capacity;\n this.arr[idx] = null;\n }\n\n this._len = writeIdx;\n this.head = (this.head - removed + this._capacity) % this._capacity;\n\n return removed;\n }\n}\n","import * as os from \"os\";\nimport { METRIC_MEM_USED, METRIC_MEM_TOTAL, METRIC_CPU_USED_PCNT } from \"@tracewayapp/core\";\nimport type { MetricRecord } from \"@tracewayapp/core\";\nimport { nowISO } from \"@tracewayapp/core\";\n\nlet prevCpuUsage: NodeJS.CpuUsage | null = null;\nlet prevCpuTime: number | null = null;\n\nexport function collectMetrics(): MetricRecord[] {\n const metrics: MetricRecord[] = [];\n const recordedAt = nowISO();\n\n const mem = process.memoryUsage();\n metrics.push({\n name: METRIC_MEM_USED,\n value: Math.round((mem.rss / 1024 / 1024) * 100) / 100,\n recordedAt,\n });\n\n const totalMem = os.totalmem();\n metrics.push({\n name: METRIC_MEM_TOTAL,\n value: Math.round((totalMem / 1024 / 1024) * 100) / 100,\n recordedAt,\n });\n\n const currentCpuUsage = process.cpuUsage();\n const currentTime = Date.now();\n if (prevCpuUsage !== null && prevCpuTime !== null) {\n const elapsedMs = currentTime - prevCpuTime;\n if (elapsedMs > 0) {\n const userDelta = currentCpuUsage.user - prevCpuUsage.user;\n const systemDelta = currentCpuUsage.system - prevCpuUsage.system;\n const totalDeltaMs = (userDelta + systemDelta) / 1000;\n const cpuCount = os.cpus().length || 1;\n const cpuPercent = (totalDeltaMs / elapsedMs / cpuCount) * 100;\n metrics.push({\n name: METRIC_CPU_USED_PCNT,\n value: Math.round(cpuPercent * 100) / 100,\n recordedAt,\n });\n }\n }\n prevCpuUsage = currentCpuUsage;\n prevCpuTime = currentTime;\n\n return metrics;\n}\n\nexport function resetCpuTracking(): void {\n prevCpuUsage = null;\n prevCpuTime = null;\n}\n","export function formatErrorStackTrace(error: Error): string {\n const lines: string[] = [];\n\n const typeName = error.constructor.name || \"Error\";\n lines.push(`${typeName}: ${error.message}`);\n\n if (error.stack) {\n const stackLines = error.stack.split(\"\\n\");\n for (const line of stackLines) {\n const match = line.match(/^\\s+at\\s+(.+?)\\s+\\((.+):(\\d+):\\d+\\)$/);\n if (match) {\n const funcName = shortenFunctionName(match[1]);\n const file = shortenFilePath(match[2]);\n const lineNum = match[3];\n lines.push(`${funcName}()`);\n lines.push(` ${file}:${lineNum}`);\n continue;\n }\n\n const matchNoParens = line.match(/^\\s+at\\s+(.+):(\\d+):\\d+$/);\n if (matchNoParens) {\n const file = shortenFilePath(matchNoParens[1]);\n const lineNum = matchNoParens[2];\n lines.push(`<anonymous>()`);\n lines.push(` ${file}:${lineNum}`);\n continue;\n }\n\n const matchFnOnly = line.match(/^\\s+at\\s+(.+)$/);\n if (matchFnOnly) {\n const funcName = shortenFunctionName(matchFnOnly[1]);\n lines.push(`${funcName}()`);\n lines.push(` <unknown>:0`);\n }\n }\n }\n\n return lines.join(\"\\n\") + \"\\n\";\n}\n\nfunction shortenFunctionName(fn: string): string {\n const slashIdx = fn.lastIndexOf(\"/\");\n if (slashIdx >= 0) {\n fn = fn.slice(slashIdx + 1);\n }\n const dotIdx = fn.indexOf(\".\");\n if (dotIdx >= 0) {\n fn = fn.slice(dotIdx + 1);\n }\n return fn;\n}\n\nfunction shortenFilePath(filePath: string): string {\n const parts = filePath.split(\"/\");\n return parts[parts.length - 1];\n}\n","import { AsyncLocalStorage } from \"async_hooks\";\nimport { generateUUID } from \"@tracewayapp/core\";\nimport type { Span } from \"@tracewayapp/core\";\n\n/**\n * Trace context stored in AsyncLocalStorage.\n * Automatically propagates through async operations.\n */\nexport interface TraceContext {\n /** Unique trace identifier (UUID v4) */\n traceId: string;\n /** Whether this is a background task (vs HTTP request) */\n isTask: boolean;\n /** When the trace started */\n startedAt: Date;\n /** Collected spans within this trace */\n spans: Span[];\n /** Key-value attributes for this trace */\n attributes: Record<string, string>;\n /** For HTTP traces: endpoint like \"GET /api/users\" */\n endpoint?: string;\n /** For HTTP traces: response status code */\n statusCode?: number;\n /** For HTTP traces: response body size */\n bodySize?: number;\n /** For HTTP traces: client IP address */\n clientIP?: string;\n /** Distributed trace ID for cross-service correlation */\n distributedTraceId?: string;\n}\n\n/**\n * Options for creating a new trace context.\n */\nexport interface TraceContextOptions {\n /** Custom trace ID (auto-generated if not provided) */\n traceId?: string;\n /** Mark as background task instead of HTTP trace */\n isTask?: boolean;\n /** Initial attributes */\n attributes?: Record<string, string>;\n /** HTTP endpoint (e.g., \"GET /api/users\") */\n endpoint?: string;\n /** Client IP address */\n clientIP?: string;\n /** Distributed trace ID from incoming request header */\n distributedTraceId?: string;\n}\n\n// The AsyncLocalStorage instance for trace context\nconst asyncLocalStorage = new AsyncLocalStorage<TraceContext>();\n\n/**\n * Get the current trace context, if any.\n * Returns undefined if not within a trace context.\n */\nexport function getTraceContext(): TraceContext | undefined {\n return asyncLocalStorage.getStore();\n}\n\n/**\n * Get the current trace ID, if within a trace context.\n */\nexport function getTraceId(): string | undefined {\n return asyncLocalStorage.getStore()?.traceId;\n}\n\n/**\n * Get the distributed trace ID from the current trace context, if any.\n */\nexport function getDistributedTraceId(): string | undefined {\n return asyncLocalStorage.getStore()?.distributedTraceId;\n}\n\n/**\n * Check if currently within a trace context.\n */\nexport function hasTraceContext(): boolean {\n return asyncLocalStorage.getStore() !== undefined;\n}\n\n/**\n * Run a function within a new trace context.\n * All async operations within will have access to this context.\n *\n * @example\n * ```ts\n * // HTTP request handler\n * withTraceContext({ endpoint: \"GET /api/users\", clientIP: req.ip }, async () => {\n * const users = await db.query(\"SELECT * FROM users\");\n * captureException(new Error(\"oops\")); // Auto-linked to trace\n * return users;\n * });\n *\n * // Background task\n * withTraceContext({ isTask: true, endpoint: \"process-emails\" }, async () => {\n * await processEmails();\n * });\n * ```\n */\nexport function withTraceContext<T>(\n options: TraceContextOptions,\n fn: () => T,\n): T {\n const context: TraceContext = {\n traceId: options.traceId ?? generateUUID(),\n isTask: options.isTask ?? false,\n startedAt: new Date(),\n spans: [],\n attributes: options.attributes ?? {},\n endpoint: options.endpoint,\n clientIP: options.clientIP,\n distributedTraceId: options.distributedTraceId,\n };\n return asyncLocalStorage.run(context, fn);\n}\n\n/**\n * Run a function within a trace context, automatically capturing the trace on completion.\n * This is a convenience wrapper that handles timing and capture automatically.\n *\n * @example\n * ```ts\n * // In Express middleware\n * app.use((req, res, next) => {\n * runWithTraceContext(\n * {\n * endpoint: `${req.method} ${req.path}`,\n * clientIP: req.ip,\n * attributes: { userId: req.user?.id },\n * },\n * async () => {\n * await next();\n * // Status code and body size set via setTraceResponseInfo()\n * },\n * { captureOnEnd: true }\n * );\n * });\n * ```\n */\nexport function runWithTraceContext<T>(\n options: TraceContextOptions,\n fn: () => T | Promise<T>,\n): T | Promise<T> {\n return withTraceContext(options, fn);\n}\n\n/**\n * Add a completed span to the current trace context.\n * No-op if not within a trace context.\n */\nexport function addSpanToContext(span: Span): void {\n const ctx = asyncLocalStorage.getStore();\n if (ctx) {\n ctx.spans.push(span);\n }\n}\n\n/**\n * Set an attribute on the current trace context.\n * No-op if not within a trace context.\n */\nexport function setTraceAttribute(key: string, value: string): void {\n const ctx = asyncLocalStorage.getStore();\n if (ctx) {\n ctx.attributes[key] = value;\n }\n}\n\n/**\n * Set multiple attributes on the current trace context.\n * No-op if not within a trace context.\n */\nexport function setTraceAttributes(attributes: Record<string, string>): void {\n const ctx = asyncLocalStorage.getStore();\n if (ctx) {\n Object.assign(ctx.attributes, attributes);\n }\n}\n\n/**\n * Set HTTP response info on the current trace context.\n * Used by framework adapters after the response is sent.\n */\nexport function setTraceResponseInfo(\n statusCode: number,\n bodySize?: number,\n): void {\n const ctx = asyncLocalStorage.getStore();\n if (ctx) {\n ctx.statusCode = statusCode;\n ctx.bodySize = bodySize;\n }\n}\n\n/**\n * Get all spans from the current trace context.\n * Returns empty array if not within a trace context.\n */\nexport function getTraceSpans(): Span[] {\n return asyncLocalStorage.getStore()?.spans ?? [];\n}\n\n/**\n * Get the duration in milliseconds since the trace started.\n * Returns 0 if not within a trace context.\n */\nexport function getTraceDuration(): number {\n const ctx = asyncLocalStorage.getStore();\n if (!ctx) return 0;\n return Date.now() - ctx.startedAt.getTime();\n}\n\n/**\n * Fork the current trace context for a sub-operation.\n * Useful for parallel operations that should have isolated spans.\n * Returns undefined if not within a trace context.\n */\nexport function forkTraceContext<T>(fn: () => T): T | undefined {\n const parentCtx = asyncLocalStorage.getStore();\n if (!parentCtx) return undefined;\n\n const forkedContext: TraceContext = {\n ...parentCtx,\n spans: [], // Forked context gets its own spans\n attributes: { ...parentCtx.attributes },\n };\n\n return asyncLocalStorage.run(forkedContext, () => {\n const result = fn();\n // Merge spans back to parent after completion\n parentCtx.spans.push(...forkedContext.spans);\n return result;\n });\n}\n\n// Export the AsyncLocalStorage instance for advanced use cases\nexport { asyncLocalStorage as traceContextStorage };\n"],"mappings":"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","names":["import_core","import_core","import_core","os","hostname"]}
|
package/dist/index.mjs
CHANGED
|
@@ -374,6 +374,9 @@ function getTraceContext() {
|
|
|
374
374
|
function getTraceId() {
|
|
375
375
|
return asyncLocalStorage.getStore()?.traceId;
|
|
376
376
|
}
|
|
377
|
+
function getDistributedTraceId() {
|
|
378
|
+
return asyncLocalStorage.getStore()?.distributedTraceId;
|
|
379
|
+
}
|
|
377
380
|
function hasTraceContext() {
|
|
378
381
|
return asyncLocalStorage.getStore() !== void 0;
|
|
379
382
|
}
|
|
@@ -385,7 +388,8 @@ function withTraceContext(options, fn) {
|
|
|
385
388
|
spans: [],
|
|
386
389
|
attributes: options.attributes ?? {},
|
|
387
390
|
endpoint: options.endpoint,
|
|
388
|
-
clientIP: options.clientIP
|
|
391
|
+
clientIP: options.clientIP,
|
|
392
|
+
distributedTraceId: options.distributedTraceId
|
|
389
393
|
};
|
|
390
394
|
return asyncLocalStorage.run(context, fn);
|
|
391
395
|
}
|
|
@@ -493,7 +497,8 @@ function captureExceptionWithAttributes(error, attributes, traceId) {
|
|
|
493
497
|
stackTrace: formatErrorStackTrace(error),
|
|
494
498
|
recordedAt: nowISO2(),
|
|
495
499
|
attributes: resolvedAttrs,
|
|
496
|
-
isMessage: false
|
|
500
|
+
isMessage: false,
|
|
501
|
+
distributedTraceId: ctx?.distributedTraceId ?? null
|
|
497
502
|
});
|
|
498
503
|
}
|
|
499
504
|
function captureMessage(msg, attributes) {
|
|
@@ -508,7 +513,8 @@ function captureMessage(msg, attributes) {
|
|
|
508
513
|
stackTrace: msg,
|
|
509
514
|
recordedAt: nowISO2(),
|
|
510
515
|
attributes: resolvedAttrs,
|
|
511
|
-
isMessage: true
|
|
516
|
+
isMessage: true,
|
|
517
|
+
distributedTraceId: ctx?.distributedTraceId ?? null
|
|
512
518
|
});
|
|
513
519
|
}
|
|
514
520
|
function captureMetric(name, value) {
|
|
@@ -597,7 +603,8 @@ function captureCurrentTrace() {
|
|
|
597
603
|
clientIP: "",
|
|
598
604
|
attributes: Object.keys(ctx.attributes).length > 0 ? ctx.attributes : void 0,
|
|
599
605
|
spans: ctx.spans.length > 0 ? ctx.spans : void 0,
|
|
600
|
-
isTask: true
|
|
606
|
+
isTask: true,
|
|
607
|
+
distributedTraceId: ctx.distributedTraceId
|
|
601
608
|
});
|
|
602
609
|
} else {
|
|
603
610
|
store.addTrace({
|
|
@@ -609,7 +616,8 @@ function captureCurrentTrace() {
|
|
|
609
616
|
bodySize: ctx.bodySize ?? 0,
|
|
610
617
|
clientIP: ctx.clientIP ?? "",
|
|
611
618
|
attributes: Object.keys(ctx.attributes).length > 0 ? ctx.attributes : void 0,
|
|
612
|
-
spans: ctx.spans.length > 0 ? ctx.spans : void 0
|
|
619
|
+
spans: ctx.spans.length > 0 ? ctx.spans : void 0,
|
|
620
|
+
distributedTraceId: ctx.distributedTraceId
|
|
613
621
|
});
|
|
614
622
|
}
|
|
615
623
|
}
|
|
@@ -680,6 +688,7 @@ export {
|
|
|
680
688
|
endSpan,
|
|
681
689
|
forkTraceContext,
|
|
682
690
|
formatErrorStackTrace,
|
|
691
|
+
getDistributedTraceId,
|
|
683
692
|
getTraceContext,
|
|
684
693
|
getTraceDuration,
|
|
685
694
|
getTraceId,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/traceway.ts","../src/collection-frame-store.ts","../src/typed-ring.ts","../src/metrics.ts","../src/stack-trace.ts","../src/context.ts"],"sourcesContent":["import {\n generateUUID,\n parseConnectionString,\n nowISO,\n msToNanoseconds,\n} from \"@tracewayapp/core\";\nimport type {\n TracewayOptions,\n ExceptionStackTrace,\n Trace,\n Span,\n} from \"@tracewayapp/core\";\nimport { CollectionFrameStore } from \"./collection-frame-store.js\";\nimport { formatErrorStackTrace } from \"./stack-trace.js\";\nimport {\n getTraceContext,\n getTraceId,\n addSpanToContext,\n type TraceContext,\n} from \"./context.js\";\nimport * as os from \"os\";\n\nlet store: CollectionFrameStore | null = null;\n\nfunction getHostname(): string {\n try {\n const hostname = os.hostname();\n const dotIdx = hostname.indexOf(\".\");\n return dotIdx >= 0 ? hostname.slice(0, dotIdx) : hostname;\n } catch {\n return \"unknown\";\n }\n}\n\nexport function init(\n connectionString: string,\n options: TracewayOptions = {},\n): void {\n if (store !== null) {\n throw new Error(\"Traceway: already initialized. Call shutdown() first.\");\n }\n\n const { token, apiUrl } = parseConnectionString(connectionString);\n\n store = new CollectionFrameStore({\n apiUrl,\n token,\n debug: options.debug ?? false,\n maxCollectionFrames: options.maxCollectionFrames ?? 12,\n collectionInterval: options.collectionInterval ?? 5000,\n uploadThrottle: options.uploadThrottle ?? 2000,\n metricsInterval: options.metricsInterval ?? 30000,\n version: options.version ?? \"\",\n serverName: options.serverName ?? getHostname(),\n sampleRate: options.sampleRate ?? 1,\n errorSampleRate: options.errorSampleRate ?? 1,\n });\n}\n\nexport function captureException(error: Error): void {\n if (!store) return;\n // Auto-detect trace context\n const ctx = getTraceContext();\n captureExceptionWithAttributes(\n error,\n ctx?.attributes,\n ctx?.traceId,\n );\n}\n\nexport function captureExceptionWithAttributes(\n error: Error,\n attributes?: Record<string, string>,\n traceId?: string,\n): void {\n if (!store) return;\n // Auto-detect trace context if not explicitly provided\n const ctx = getTraceContext();\n const resolvedTraceId = traceId ?? ctx?.traceId ?? null;\n const resolvedAttrs = attributes ?? ctx?.attributes;\n const isTask = ctx?.isTask ?? false;\n\n store.addException({\n traceId: resolvedTraceId,\n isTask: isTask || undefined,\n stackTrace: formatErrorStackTrace(error),\n recordedAt: nowISO(),\n attributes: resolvedAttrs,\n isMessage: false,\n });\n}\n\nexport function captureMessage(\n msg: string,\n attributes?: Record<string, string>,\n): void {\n if (!store) return;\n // Auto-detect trace context\n const ctx = getTraceContext();\n const resolvedTraceId = ctx?.traceId ?? null;\n const resolvedAttrs = attributes ?? ctx?.attributes;\n const isTask = ctx?.isTask ?? false;\n\n store.addException({\n traceId: resolvedTraceId,\n isTask: isTask || undefined,\n stackTrace: msg,\n recordedAt: nowISO(),\n attributes: resolvedAttrs,\n isMessage: true,\n });\n}\n\nexport function captureMetric(name: string, value: number): void {\n if (!store) return;\n store.addMetric({\n name,\n value,\n recordedAt: nowISO(),\n });\n}\n\nexport function captureMetricWithTags(\n name: string,\n value: number,\n tags: Record<string, string>,\n): void {\n if (!store) return;\n store.addMetric({\n name,\n value,\n recordedAt: nowISO(),\n tags,\n });\n}\n\nexport function captureTrace(\n traceId: string,\n endpoint: string,\n durationMs: number,\n startedAt: Date,\n statusCode: number,\n bodySize: number,\n clientIP: string,\n attributes?: Record<string, string>,\n spans?: Span[],\n): void {\n if (!store) return;\n store.addTrace({\n id: traceId,\n endpoint,\n duration: msToNanoseconds(durationMs),\n recordedAt: startedAt.toISOString(),\n statusCode,\n bodySize,\n clientIP,\n attributes,\n spans,\n });\n}\n\nexport function captureTask(\n traceId: string,\n taskName: string,\n durationMs: number,\n startedAt: Date,\n attributes?: Record<string, string>,\n spans?: Span[],\n): void {\n if (!store) return;\n store.addTrace({\n id: traceId,\n endpoint: taskName,\n duration: msToNanoseconds(durationMs),\n recordedAt: startedAt.toISOString(),\n statusCode: 0,\n bodySize: 0,\n clientIP: \"\",\n attributes,\n spans,\n isTask: true,\n });\n}\n\n/** Handle returned by startSpan for tracking span timing */\nexport interface SpanHandle {\n id: string;\n name: string;\n startTime: string;\n startedAt: number;\n}\n\n/**\n * Start a new span. If within a trace context, the span will be\n * automatically added to the trace when ended.\n */\nexport function startSpan(name: string): SpanHandle {\n const now = Date.now();\n return {\n id: generateUUID(),\n name,\n startTime: new Date(now).toISOString(),\n startedAt: now,\n };\n}\n\n/**\n * End a span and get the completed Span object.\n * If within a trace context, automatically adds the span to the trace.\n *\n * @param addToContext - If true (default), adds span to current trace context\n */\nexport function endSpan(span: SpanHandle, addToContext: boolean = true): Span {\n const durationMs = Date.now() - span.startedAt;\n const completedSpan: Span = {\n id: span.id,\n name: span.name,\n startTime: span.startTime,\n duration: msToNanoseconds(durationMs),\n };\n\n // Auto-add to trace context if available\n if (addToContext) {\n addSpanToContext(completedSpan);\n }\n\n return completedSpan;\n}\n\n/**\n * Capture the current trace context as a trace.\n * Call this at the end of a request/task to record the trace.\n *\n * @example\n * ```ts\n * // In Express middleware (after response)\n * withTraceContext({ endpoint: `${req.method} ${req.path}` }, async () => {\n * await handleRequest(req, res);\n * setTraceResponseInfo(res.statusCode, contentLength);\n * captureCurrentTrace(); // Records the trace with all spans\n * });\n * ```\n */\nexport function captureCurrentTrace(): void {\n if (!store) return;\n\n const ctx = getTraceContext();\n if (!ctx) return;\n\n const durationMs = Date.now() - ctx.startedAt.getTime();\n const isError = (ctx.statusCode ?? 0) >= 500;\n\n if (!shouldSample(isError)) return;\n\n if (ctx.isTask) {\n store.addTrace({\n id: ctx.traceId,\n endpoint: ctx.endpoint ?? \"unknown-task\",\n duration: msToNanoseconds(durationMs),\n recordedAt: ctx.startedAt.toISOString(),\n statusCode: 0,\n bodySize: 0,\n clientIP: \"\",\n attributes: Object.keys(ctx.attributes).length > 0 ? ctx.attributes : undefined,\n spans: ctx.spans.length > 0 ? ctx.spans : undefined,\n isTask: true,\n });\n } else {\n store.addTrace({\n id: ctx.traceId,\n endpoint: ctx.endpoint ?? \"unknown\",\n duration: msToNanoseconds(durationMs),\n recordedAt: ctx.startedAt.toISOString(),\n statusCode: ctx.statusCode ?? 0,\n bodySize: ctx.bodySize ?? 0,\n clientIP: ctx.clientIP ?? \"\",\n attributes: Object.keys(ctx.attributes).length > 0 ? ctx.attributes : undefined,\n spans: ctx.spans.length > 0 ? ctx.spans : undefined,\n });\n }\n}\n\nexport function shouldSample(isError: boolean): boolean {\n if (!store) return false;\n const rate = isError ? store.errorSampleRate : store.sampleRate;\n if (rate >= 1) return true;\n if (rate <= 0) return false;\n return Math.random() < rate;\n}\n\nexport function measureTask(\n title: string,\n fn: () => void | Promise<void>,\n): void {\n const traceId = generateUUID();\n const start = Date.now();\n const startDate = new Date(start);\n\n try {\n const result = fn();\n if (result && typeof (result as Promise<void>).then === \"function\") {\n (result as Promise<void>)\n .then(() => {\n const durationMs = Date.now() - start;\n if (shouldSample(false)) {\n captureTask(traceId, title, durationMs, startDate);\n }\n })\n .catch((err: unknown) => {\n const durationMs = Date.now() - start;\n if (shouldSample(true)) {\n captureTask(traceId, title, durationMs, startDate);\n if (err instanceof Error) {\n captureExceptionWithAttributes(err, undefined, traceId);\n }\n }\n throw err;\n });\n } else {\n const durationMs = Date.now() - start;\n if (shouldSample(false)) {\n captureTask(traceId, title, durationMs, startDate);\n }\n }\n } catch (err) {\n const durationMs = Date.now() - start;\n if (shouldSample(true)) {\n captureTask(traceId, title, durationMs, startDate);\n if (err instanceof Error) {\n captureExceptionWithAttributes(err, undefined, traceId);\n }\n }\n throw err;\n }\n}\n\nexport async function shutdown(timeoutMs?: number): Promise<void> {\n if (!store) return;\n const s = store;\n store = null;\n await s.shutdown(timeoutMs);\n}\n","import * as zlib from \"zlib\";\nimport {\n nowISO,\n generateUUID,\n msToNanoseconds,\n} from \"@tracewayapp/core\";\nimport { TypedRing } from \"./typed-ring.js\";\nimport type {\n CollectionFrame,\n ExceptionStackTrace,\n MetricRecord,\n Trace,\n Span,\n ReportRequest,\n} from \"@tracewayapp/core\";\nimport { collectMetrics } from \"./metrics.js\";\n\nexport interface CollectionFrameStoreOptions {\n apiUrl: string;\n token: string;\n debug: boolean;\n maxCollectionFrames: number;\n collectionInterval: number;\n uploadThrottle: number;\n metricsInterval: number;\n version: string;\n serverName: string;\n sampleRate: number;\n errorSampleRate: number;\n}\n\nexport class CollectionFrameStore {\n private current: CollectionFrame | null = null;\n private currentSetAt: number = Date.now();\n private sendQueue: TypedRing<CollectionFrame>;\n private lastUploadStarted: number | null = null;\n\n private collectionTimer: ReturnType<typeof setInterval> | null = null;\n private metricsTimer: ReturnType<typeof setInterval> | null = null;\n\n private readonly apiUrl: string;\n private readonly token: string;\n private readonly debug: boolean;\n private readonly collectionInterval: number;\n private readonly uploadThrottle: number;\n private readonly metricsInterval: number;\n private readonly version: string;\n private readonly serverName: string;\n\n readonly sampleRate: number;\n readonly errorSampleRate: number;\n\n constructor(options: CollectionFrameStoreOptions) {\n this.apiUrl = options.apiUrl;\n this.token = options.token;\n this.debug = options.debug;\n this.collectionInterval = options.collectionInterval;\n this.uploadThrottle = options.uploadThrottle;\n this.metricsInterval = options.metricsInterval;\n this.version = options.version;\n this.serverName = options.serverName;\n this.sampleRate = options.sampleRate;\n this.errorSampleRate = options.errorSampleRate;\n this.sendQueue = new TypedRing<CollectionFrame>(\n options.maxCollectionFrames,\n );\n\n this.collectionTimer = setInterval(() => {\n this.tick();\n }, this.collectionInterval);\n if (this.collectionTimer && typeof this.collectionTimer.unref === \"function\") {\n this.collectionTimer.unref();\n }\n\n this.metricsTimer = setInterval(() => {\n this.collectSystemMetrics();\n }, this.metricsInterval);\n if (this.metricsTimer && typeof this.metricsTimer.unref === \"function\") {\n this.metricsTimer.unref();\n }\n }\n\n private tick(): void {\n if (this.current !== null) {\n if (this.currentSetAt < Date.now() - this.collectionInterval) {\n this.rotateCurrentCollectionFrame();\n this.processSendQueue();\n }\n } else if (this.sendQueue.length > 0) {\n this.processSendQueue();\n }\n }\n\n private ensureCurrent(): CollectionFrame {\n if (this.current === null) {\n this.current = { stackTraces: [], metrics: [], traces: [] };\n this.currentSetAt = Date.now();\n }\n return this.current;\n }\n\n addException(exception: ExceptionStackTrace): void {\n this.ensureCurrent().stackTraces.push(exception);\n }\n\n addMetric(metric: MetricRecord): void {\n this.ensureCurrent().metrics.push(metric);\n }\n\n addTrace(trace: Trace): void {\n this.ensureCurrent().traces.push(trace);\n }\n\n private rotateCurrentCollectionFrame(): void {\n if (this.current !== null) {\n this.sendQueue.push(this.current);\n this.current = null;\n }\n }\n\n private processSendQueue(): void {\n if (\n this.lastUploadStarted === null ||\n this.lastUploadStarted < Date.now() - this.uploadThrottle\n ) {\n this.lastUploadStarted = Date.now();\n const frames = this.sendQueue.readAll();\n if (frames.length > 0) {\n this.triggerUpload(frames);\n }\n }\n }\n\n private triggerUpload(framesToSend: CollectionFrame[]): void {\n const payload: ReportRequest = {\n collectionFrames: framesToSend,\n appVersion: this.version,\n serverName: this.serverName,\n };\n\n let jsonData: string;\n try {\n jsonData = JSON.stringify(payload);\n } catch (err) {\n if (this.debug) {\n console.error(\"Traceway: failed to serialize frames:\", err);\n }\n return;\n }\n\n let gzipped: Uint8Array;\n try {\n gzipped = new Uint8Array(zlib.gzipSync(Buffer.from(jsonData)));\n } catch (err) {\n if (this.debug) {\n console.error(\"Traceway: failed to gzip:\", err);\n }\n return;\n }\n\n fetch(this.apiUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Content-Encoding\": \"gzip\",\n Authorization: `Bearer ${this.token}`,\n },\n body: gzipped as unknown as BodyInit,\n })\n .then((resp) => {\n if (resp.status === 200) {\n this.sendQueue.remove(framesToSend);\n } else if (this.debug) {\n console.error(`Traceway: upload returned status ${resp.status}`);\n }\n })\n .catch((err) => {\n if (this.debug) {\n console.error(\"Traceway: upload failed:\", err);\n }\n });\n }\n\n private collectSystemMetrics(): void {\n try {\n const metrics = collectMetrics();\n for (const metric of metrics) {\n this.addMetric(metric);\n }\n } catch (err) {\n if (this.debug) {\n console.error(\"Traceway: failed to collect metrics:\", err);\n }\n }\n }\n\n async shutdown(timeoutMs?: number): Promise<void> {\n if (this.collectionTimer !== null) {\n clearInterval(this.collectionTimer);\n this.collectionTimer = null;\n }\n if (this.metricsTimer !== null) {\n clearInterval(this.metricsTimer);\n this.metricsTimer = null;\n }\n\n this.rotateCurrentCollectionFrame();\n\n const frames = this.sendQueue.readAll();\n if (frames.length === 0) return;\n\n const uploadPromise = (async () => {\n const payload: ReportRequest = {\n collectionFrames: frames,\n appVersion: this.version,\n serverName: this.serverName,\n };\n\n try {\n const jsonData = JSON.stringify(payload);\n const gzipped = new Uint8Array(zlib.gzipSync(Buffer.from(jsonData)));\n\n const resp = await fetch(this.apiUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Content-Encoding\": \"gzip\",\n Authorization: `Bearer ${this.token}`,\n },\n body: gzipped as unknown as BodyInit,\n });\n\n if (resp.status === 200) {\n this.sendQueue.remove(frames);\n }\n } catch (err) {\n if (this.debug) {\n console.error(\"Traceway: shutdown upload failed:\", err);\n }\n }\n })();\n\n if (timeoutMs !== undefined) {\n await Promise.race([\n uploadPromise,\n new Promise<void>((resolve) => setTimeout(resolve, timeoutMs)),\n ]);\n } else {\n await uploadPromise;\n }\n }\n}\n","export class TypedRing<T> {\n private arr: (T | null)[];\n private head: number = 0;\n private _capacity: number;\n private _len: number = 0;\n\n constructor(capacity: number) {\n this._capacity = capacity;\n this.arr = new Array<T | null>(capacity).fill(null);\n }\n\n get length(): number {\n return this._len;\n }\n\n get capacity(): number {\n return this._capacity;\n }\n\n push(val: T): void {\n this.arr[this.head] = val;\n this.head = (this.head + 1) % this._capacity;\n if (this._len < this._capacity) {\n this._len += 1;\n }\n }\n\n readAll(): T[] {\n const result: T[] = [];\n for (let i = 0; i < this._len; i++) {\n const idx =\n (this.head - this._len + i + this._capacity) % this._capacity;\n result.push(this.arr[idx] as T);\n }\n return result;\n }\n\n clear(): void {\n for (let i = 0; i < this.arr.length; i++) {\n this.arr[i] = null;\n }\n this.head = 0;\n this._len = 0;\n }\n\n remove(vals: T[]): number {\n if (vals.length === 0) return 0;\n\n const toRemove = new Set<T>(vals);\n let writeIdx = 0;\n let removed = 0;\n\n for (let i = 0; i < this._len; i++) {\n const readIdx =\n (this.head - this._len + i + this._capacity) % this._capacity;\n if (toRemove.has(this.arr[readIdx] as T)) {\n removed++;\n } else {\n if (writeIdx !== i) {\n const destIdx =\n (this.head - this._len + writeIdx + this._capacity) %\n this._capacity;\n this.arr[destIdx] = this.arr[readIdx];\n }\n writeIdx++;\n }\n }\n\n for (let i = writeIdx; i < this._len; i++) {\n const idx =\n (this.head - this._len + i + this._capacity) % this._capacity;\n this.arr[idx] = null;\n }\n\n this._len = writeIdx;\n this.head = (this.head - removed + this._capacity) % this._capacity;\n\n return removed;\n }\n}\n","import * as os from \"os\";\nimport { METRIC_MEM_USED, METRIC_MEM_TOTAL, METRIC_CPU_USED_PCNT } from \"@tracewayapp/core\";\nimport type { MetricRecord } from \"@tracewayapp/core\";\nimport { nowISO } from \"@tracewayapp/core\";\n\nlet prevCpuUsage: NodeJS.CpuUsage | null = null;\nlet prevCpuTime: number | null = null;\n\nexport function collectMetrics(): MetricRecord[] {\n const metrics: MetricRecord[] = [];\n const recordedAt = nowISO();\n\n const mem = process.memoryUsage();\n metrics.push({\n name: METRIC_MEM_USED,\n value: Math.round((mem.rss / 1024 / 1024) * 100) / 100,\n recordedAt,\n });\n\n const totalMem = os.totalmem();\n metrics.push({\n name: METRIC_MEM_TOTAL,\n value: Math.round((totalMem / 1024 / 1024) * 100) / 100,\n recordedAt,\n });\n\n const currentCpuUsage = process.cpuUsage();\n const currentTime = Date.now();\n if (prevCpuUsage !== null && prevCpuTime !== null) {\n const elapsedMs = currentTime - prevCpuTime;\n if (elapsedMs > 0) {\n const userDelta = currentCpuUsage.user - prevCpuUsage.user;\n const systemDelta = currentCpuUsage.system - prevCpuUsage.system;\n const totalDeltaMs = (userDelta + systemDelta) / 1000;\n const cpuCount = os.cpus().length || 1;\n const cpuPercent = (totalDeltaMs / elapsedMs / cpuCount) * 100;\n metrics.push({\n name: METRIC_CPU_USED_PCNT,\n value: Math.round(cpuPercent * 100) / 100,\n recordedAt,\n });\n }\n }\n prevCpuUsage = currentCpuUsage;\n prevCpuTime = currentTime;\n\n return metrics;\n}\n\nexport function resetCpuTracking(): void {\n prevCpuUsage = null;\n prevCpuTime = null;\n}\n","export function formatErrorStackTrace(error: Error): string {\n const lines: string[] = [];\n\n const typeName = error.constructor.name || \"Error\";\n lines.push(`${typeName}: ${error.message}`);\n\n if (error.stack) {\n const stackLines = error.stack.split(\"\\n\");\n for (const line of stackLines) {\n const match = line.match(/^\\s+at\\s+(.+?)\\s+\\((.+):(\\d+):\\d+\\)$/);\n if (match) {\n const funcName = shortenFunctionName(match[1]);\n const file = shortenFilePath(match[2]);\n const lineNum = match[3];\n lines.push(`${funcName}()`);\n lines.push(` ${file}:${lineNum}`);\n continue;\n }\n\n const matchNoParens = line.match(/^\\s+at\\s+(.+):(\\d+):\\d+$/);\n if (matchNoParens) {\n const file = shortenFilePath(matchNoParens[1]);\n const lineNum = matchNoParens[2];\n lines.push(`<anonymous>()`);\n lines.push(` ${file}:${lineNum}`);\n continue;\n }\n\n const matchFnOnly = line.match(/^\\s+at\\s+(.+)$/);\n if (matchFnOnly) {\n const funcName = shortenFunctionName(matchFnOnly[1]);\n lines.push(`${funcName}()`);\n lines.push(` <unknown>:0`);\n }\n }\n }\n\n return lines.join(\"\\n\") + \"\\n\";\n}\n\nfunction shortenFunctionName(fn: string): string {\n const slashIdx = fn.lastIndexOf(\"/\");\n if (slashIdx >= 0) {\n fn = fn.slice(slashIdx + 1);\n }\n const dotIdx = fn.indexOf(\".\");\n if (dotIdx >= 0) {\n fn = fn.slice(dotIdx + 1);\n }\n return fn;\n}\n\nfunction shortenFilePath(filePath: string): string {\n const parts = filePath.split(\"/\");\n return parts[parts.length - 1];\n}\n","import { AsyncLocalStorage } from \"async_hooks\";\nimport { generateUUID } from \"@tracewayapp/core\";\nimport type { Span } from \"@tracewayapp/core\";\n\n/**\n * Trace context stored in AsyncLocalStorage.\n * Automatically propagates through async operations.\n */\nexport interface TraceContext {\n /** Unique trace identifier (UUID v4) */\n traceId: string;\n /** Whether this is a background task (vs HTTP request) */\n isTask: boolean;\n /** When the trace started */\n startedAt: Date;\n /** Collected spans within this trace */\n spans: Span[];\n /** Key-value attributes for this trace */\n attributes: Record<string, string>;\n /** For HTTP traces: endpoint like \"GET /api/users\" */\n endpoint?: string;\n /** For HTTP traces: response status code */\n statusCode?: number;\n /** For HTTP traces: response body size */\n bodySize?: number;\n /** For HTTP traces: client IP address */\n clientIP?: string;\n}\n\n/**\n * Options for creating a new trace context.\n */\nexport interface TraceContextOptions {\n /** Custom trace ID (auto-generated if not provided) */\n traceId?: string;\n /** Mark as background task instead of HTTP trace */\n isTask?: boolean;\n /** Initial attributes */\n attributes?: Record<string, string>;\n /** HTTP endpoint (e.g., \"GET /api/users\") */\n endpoint?: string;\n /** Client IP address */\n clientIP?: string;\n}\n\n// The AsyncLocalStorage instance for trace context\nconst asyncLocalStorage = new AsyncLocalStorage<TraceContext>();\n\n/**\n * Get the current trace context, if any.\n * Returns undefined if not within a trace context.\n */\nexport function getTraceContext(): TraceContext | undefined {\n return asyncLocalStorage.getStore();\n}\n\n/**\n * Get the current trace ID, if within a trace context.\n */\nexport function getTraceId(): string | undefined {\n return asyncLocalStorage.getStore()?.traceId;\n}\n\n/**\n * Check if currently within a trace context.\n */\nexport function hasTraceContext(): boolean {\n return asyncLocalStorage.getStore() !== undefined;\n}\n\n/**\n * Run a function within a new trace context.\n * All async operations within will have access to this context.\n *\n * @example\n * ```ts\n * // HTTP request handler\n * withTraceContext({ endpoint: \"GET /api/users\", clientIP: req.ip }, async () => {\n * const users = await db.query(\"SELECT * FROM users\");\n * captureException(new Error(\"oops\")); // Auto-linked to trace\n * return users;\n * });\n *\n * // Background task\n * withTraceContext({ isTask: true, endpoint: \"process-emails\" }, async () => {\n * await processEmails();\n * });\n * ```\n */\nexport function withTraceContext<T>(\n options: TraceContextOptions,\n fn: () => T,\n): T {\n const context: TraceContext = {\n traceId: options.traceId ?? generateUUID(),\n isTask: options.isTask ?? false,\n startedAt: new Date(),\n spans: [],\n attributes: options.attributes ?? {},\n endpoint: options.endpoint,\n clientIP: options.clientIP,\n };\n return asyncLocalStorage.run(context, fn);\n}\n\n/**\n * Run a function within a trace context, automatically capturing the trace on completion.\n * This is a convenience wrapper that handles timing and capture automatically.\n *\n * @example\n * ```ts\n * // In Express middleware\n * app.use((req, res, next) => {\n * runWithTraceContext(\n * {\n * endpoint: `${req.method} ${req.path}`,\n * clientIP: req.ip,\n * attributes: { userId: req.user?.id },\n * },\n * async () => {\n * await next();\n * // Status code and body size set via setTraceResponseInfo()\n * },\n * { captureOnEnd: true }\n * );\n * });\n * ```\n */\nexport function runWithTraceContext<T>(\n options: TraceContextOptions,\n fn: () => T | Promise<T>,\n): T | Promise<T> {\n return withTraceContext(options, fn);\n}\n\n/**\n * Add a completed span to the current trace context.\n * No-op if not within a trace context.\n */\nexport function addSpanToContext(span: Span): void {\n const ctx = asyncLocalStorage.getStore();\n if (ctx) {\n ctx.spans.push(span);\n }\n}\n\n/**\n * Set an attribute on the current trace context.\n * No-op if not within a trace context.\n */\nexport function setTraceAttribute(key: string, value: string): void {\n const ctx = asyncLocalStorage.getStore();\n if (ctx) {\n ctx.attributes[key] = value;\n }\n}\n\n/**\n * Set multiple attributes on the current trace context.\n * No-op if not within a trace context.\n */\nexport function setTraceAttributes(attributes: Record<string, string>): void {\n const ctx = asyncLocalStorage.getStore();\n if (ctx) {\n Object.assign(ctx.attributes, attributes);\n }\n}\n\n/**\n * Set HTTP response info on the current trace context.\n * Used by framework adapters after the response is sent.\n */\nexport function setTraceResponseInfo(\n statusCode: number,\n bodySize?: number,\n): void {\n const ctx = asyncLocalStorage.getStore();\n if (ctx) {\n ctx.statusCode = statusCode;\n ctx.bodySize = bodySize;\n }\n}\n\n/**\n * Get all spans from the current trace context.\n * Returns empty array if not within a trace context.\n */\nexport function getTraceSpans(): Span[] {\n return asyncLocalStorage.getStore()?.spans ?? [];\n}\n\n/**\n * Get the duration in milliseconds since the trace started.\n * Returns 0 if not within a trace context.\n */\nexport function getTraceDuration(): number {\n const ctx = asyncLocalStorage.getStore();\n if (!ctx) return 0;\n return Date.now() - ctx.startedAt.getTime();\n}\n\n/**\n * Fork the current trace context for a sub-operation.\n * Useful for parallel operations that should have isolated spans.\n * Returns undefined if not within a trace context.\n */\nexport function forkTraceContext<T>(fn: () => T): T | undefined {\n const parentCtx = asyncLocalStorage.getStore();\n if (!parentCtx) return undefined;\n\n const forkedContext: TraceContext = {\n ...parentCtx,\n spans: [], // Forked context gets its own spans\n attributes: { ...parentCtx.attributes },\n };\n\n return asyncLocalStorage.run(forkedContext, () => {\n const result = fn();\n // Merge spans back to parent after completion\n parentCtx.spans.push(...forkedContext.spans);\n return result;\n });\n}\n\n// Export the AsyncLocalStorage instance for advanced use cases\nexport { asyncLocalStorage as traceContextStorage };\n"],"mappings":"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","names":["generateUUID","nowISO","os","hostname","nowISO","generateUUID"]}
|
|
1
|
+
{"version":3,"sources":["../src/traceway.ts","../src/collection-frame-store.ts","../src/typed-ring.ts","../src/metrics.ts","../src/stack-trace.ts","../src/context.ts"],"sourcesContent":["import {\n generateUUID,\n parseConnectionString,\n nowISO,\n msToNanoseconds,\n} from \"@tracewayapp/core\";\nimport type {\n TracewayOptions,\n ExceptionStackTrace,\n Trace,\n Span,\n} from \"@tracewayapp/core\";\nimport { CollectionFrameStore } from \"./collection-frame-store.js\";\nimport { formatErrorStackTrace } from \"./stack-trace.js\";\nimport {\n getTraceContext,\n getTraceId,\n getDistributedTraceId,\n addSpanToContext,\n type TraceContext,\n} from \"./context.js\";\nimport * as os from \"os\";\n\nlet store: CollectionFrameStore | null = null;\n\nfunction getHostname(): string {\n try {\n const hostname = os.hostname();\n const dotIdx = hostname.indexOf(\".\");\n return dotIdx >= 0 ? hostname.slice(0, dotIdx) : hostname;\n } catch {\n return \"unknown\";\n }\n}\n\nexport function init(\n connectionString: string,\n options: TracewayOptions = {},\n): void {\n if (store !== null) {\n throw new Error(\"Traceway: already initialized. Call shutdown() first.\");\n }\n\n const { token, apiUrl } = parseConnectionString(connectionString);\n\n store = new CollectionFrameStore({\n apiUrl,\n token,\n debug: options.debug ?? false,\n maxCollectionFrames: options.maxCollectionFrames ?? 12,\n collectionInterval: options.collectionInterval ?? 5000,\n uploadThrottle: options.uploadThrottle ?? 2000,\n metricsInterval: options.metricsInterval ?? 30000,\n version: options.version ?? \"\",\n serverName: options.serverName ?? getHostname(),\n sampleRate: options.sampleRate ?? 1,\n errorSampleRate: options.errorSampleRate ?? 1,\n });\n}\n\nexport function captureException(error: Error): void {\n if (!store) return;\n // Auto-detect trace context\n const ctx = getTraceContext();\n captureExceptionWithAttributes(\n error,\n ctx?.attributes,\n ctx?.traceId,\n );\n}\n\nexport function captureExceptionWithAttributes(\n error: Error,\n attributes?: Record<string, string>,\n traceId?: string,\n): void {\n if (!store) return;\n // Auto-detect trace context if not explicitly provided\n const ctx = getTraceContext();\n const resolvedTraceId = traceId ?? ctx?.traceId ?? null;\n const resolvedAttrs = attributes ?? ctx?.attributes;\n const isTask = ctx?.isTask ?? false;\n\n store.addException({\n traceId: resolvedTraceId,\n isTask: isTask || undefined,\n stackTrace: formatErrorStackTrace(error),\n recordedAt: nowISO(),\n attributes: resolvedAttrs,\n isMessage: false,\n distributedTraceId: ctx?.distributedTraceId ?? null,\n });\n}\n\nexport function captureMessage(\n msg: string,\n attributes?: Record<string, string>,\n): void {\n if (!store) return;\n // Auto-detect trace context\n const ctx = getTraceContext();\n const resolvedTraceId = ctx?.traceId ?? null;\n const resolvedAttrs = attributes ?? ctx?.attributes;\n const isTask = ctx?.isTask ?? false;\n\n store.addException({\n traceId: resolvedTraceId,\n isTask: isTask || undefined,\n stackTrace: msg,\n recordedAt: nowISO(),\n attributes: resolvedAttrs,\n isMessage: true,\n distributedTraceId: ctx?.distributedTraceId ?? null,\n });\n}\n\nexport function captureMetric(name: string, value: number): void {\n if (!store) return;\n store.addMetric({\n name,\n value,\n recordedAt: nowISO(),\n });\n}\n\nexport function captureMetricWithTags(\n name: string,\n value: number,\n tags: Record<string, string>,\n): void {\n if (!store) return;\n store.addMetric({\n name,\n value,\n recordedAt: nowISO(),\n tags,\n });\n}\n\nexport function captureTrace(\n traceId: string,\n endpoint: string,\n durationMs: number,\n startedAt: Date,\n statusCode: number,\n bodySize: number,\n clientIP: string,\n attributes?: Record<string, string>,\n spans?: Span[],\n): void {\n if (!store) return;\n store.addTrace({\n id: traceId,\n endpoint,\n duration: msToNanoseconds(durationMs),\n recordedAt: startedAt.toISOString(),\n statusCode,\n bodySize,\n clientIP,\n attributes,\n spans,\n });\n}\n\nexport function captureTask(\n traceId: string,\n taskName: string,\n durationMs: number,\n startedAt: Date,\n attributes?: Record<string, string>,\n spans?: Span[],\n): void {\n if (!store) return;\n store.addTrace({\n id: traceId,\n endpoint: taskName,\n duration: msToNanoseconds(durationMs),\n recordedAt: startedAt.toISOString(),\n statusCode: 0,\n bodySize: 0,\n clientIP: \"\",\n attributes,\n spans,\n isTask: true,\n });\n}\n\n/** Handle returned by startSpan for tracking span timing */\nexport interface SpanHandle {\n id: string;\n name: string;\n startTime: string;\n startedAt: number;\n}\n\n/**\n * Start a new span. If within a trace context, the span will be\n * automatically added to the trace when ended.\n */\nexport function startSpan(name: string): SpanHandle {\n const now = Date.now();\n return {\n id: generateUUID(),\n name,\n startTime: new Date(now).toISOString(),\n startedAt: now,\n };\n}\n\n/**\n * End a span and get the completed Span object.\n * If within a trace context, automatically adds the span to the trace.\n *\n * @param addToContext - If true (default), adds span to current trace context\n */\nexport function endSpan(span: SpanHandle, addToContext: boolean = true): Span {\n const durationMs = Date.now() - span.startedAt;\n const completedSpan: Span = {\n id: span.id,\n name: span.name,\n startTime: span.startTime,\n duration: msToNanoseconds(durationMs),\n };\n\n // Auto-add to trace context if available\n if (addToContext) {\n addSpanToContext(completedSpan);\n }\n\n return completedSpan;\n}\n\n/**\n * Capture the current trace context as a trace.\n * Call this at the end of a request/task to record the trace.\n *\n * @example\n * ```ts\n * // In Express middleware (after response)\n * withTraceContext({ endpoint: `${req.method} ${req.path}` }, async () => {\n * await handleRequest(req, res);\n * setTraceResponseInfo(res.statusCode, contentLength);\n * captureCurrentTrace(); // Records the trace with all spans\n * });\n * ```\n */\nexport function captureCurrentTrace(): void {\n if (!store) return;\n\n const ctx = getTraceContext();\n if (!ctx) return;\n\n const durationMs = Date.now() - ctx.startedAt.getTime();\n const isError = (ctx.statusCode ?? 0) >= 500;\n\n if (!shouldSample(isError)) return;\n\n if (ctx.isTask) {\n store.addTrace({\n id: ctx.traceId,\n endpoint: ctx.endpoint ?? \"unknown-task\",\n duration: msToNanoseconds(durationMs),\n recordedAt: ctx.startedAt.toISOString(),\n statusCode: 0,\n bodySize: 0,\n clientIP: \"\",\n attributes: Object.keys(ctx.attributes).length > 0 ? ctx.attributes : undefined,\n spans: ctx.spans.length > 0 ? ctx.spans : undefined,\n isTask: true,\n distributedTraceId: ctx.distributedTraceId,\n });\n } else {\n store.addTrace({\n id: ctx.traceId,\n endpoint: ctx.endpoint ?? \"unknown\",\n duration: msToNanoseconds(durationMs),\n recordedAt: ctx.startedAt.toISOString(),\n statusCode: ctx.statusCode ?? 0,\n bodySize: ctx.bodySize ?? 0,\n clientIP: ctx.clientIP ?? \"\",\n attributes: Object.keys(ctx.attributes).length > 0 ? ctx.attributes : undefined,\n spans: ctx.spans.length > 0 ? ctx.spans : undefined,\n distributedTraceId: ctx.distributedTraceId,\n });\n }\n}\n\nexport function shouldSample(isError: boolean): boolean {\n if (!store) return false;\n const rate = isError ? store.errorSampleRate : store.sampleRate;\n if (rate >= 1) return true;\n if (rate <= 0) return false;\n return Math.random() < rate;\n}\n\nexport function measureTask(\n title: string,\n fn: () => void | Promise<void>,\n): void {\n const traceId = generateUUID();\n const start = Date.now();\n const startDate = new Date(start);\n\n try {\n const result = fn();\n if (result && typeof (result as Promise<void>).then === \"function\") {\n (result as Promise<void>)\n .then(() => {\n const durationMs = Date.now() - start;\n if (shouldSample(false)) {\n captureTask(traceId, title, durationMs, startDate);\n }\n })\n .catch((err: unknown) => {\n const durationMs = Date.now() - start;\n if (shouldSample(true)) {\n captureTask(traceId, title, durationMs, startDate);\n if (err instanceof Error) {\n captureExceptionWithAttributes(err, undefined, traceId);\n }\n }\n throw err;\n });\n } else {\n const durationMs = Date.now() - start;\n if (shouldSample(false)) {\n captureTask(traceId, title, durationMs, startDate);\n }\n }\n } catch (err) {\n const durationMs = Date.now() - start;\n if (shouldSample(true)) {\n captureTask(traceId, title, durationMs, startDate);\n if (err instanceof Error) {\n captureExceptionWithAttributes(err, undefined, traceId);\n }\n }\n throw err;\n }\n}\n\nexport async function shutdown(timeoutMs?: number): Promise<void> {\n if (!store) return;\n const s = store;\n store = null;\n await s.shutdown(timeoutMs);\n}\n","import * as zlib from \"zlib\";\nimport {\n nowISO,\n generateUUID,\n msToNanoseconds,\n} from \"@tracewayapp/core\";\nimport { TypedRing } from \"./typed-ring.js\";\nimport type {\n CollectionFrame,\n ExceptionStackTrace,\n MetricRecord,\n Trace,\n Span,\n ReportRequest,\n} from \"@tracewayapp/core\";\nimport { collectMetrics } from \"./metrics.js\";\n\nexport interface CollectionFrameStoreOptions {\n apiUrl: string;\n token: string;\n debug: boolean;\n maxCollectionFrames: number;\n collectionInterval: number;\n uploadThrottle: number;\n metricsInterval: number;\n version: string;\n serverName: string;\n sampleRate: number;\n errorSampleRate: number;\n}\n\nexport class CollectionFrameStore {\n private current: CollectionFrame | null = null;\n private currentSetAt: number = Date.now();\n private sendQueue: TypedRing<CollectionFrame>;\n private lastUploadStarted: number | null = null;\n\n private collectionTimer: ReturnType<typeof setInterval> | null = null;\n private metricsTimer: ReturnType<typeof setInterval> | null = null;\n\n private readonly apiUrl: string;\n private readonly token: string;\n private readonly debug: boolean;\n private readonly collectionInterval: number;\n private readonly uploadThrottle: number;\n private readonly metricsInterval: number;\n private readonly version: string;\n private readonly serverName: string;\n\n readonly sampleRate: number;\n readonly errorSampleRate: number;\n\n constructor(options: CollectionFrameStoreOptions) {\n this.apiUrl = options.apiUrl;\n this.token = options.token;\n this.debug = options.debug;\n this.collectionInterval = options.collectionInterval;\n this.uploadThrottle = options.uploadThrottle;\n this.metricsInterval = options.metricsInterval;\n this.version = options.version;\n this.serverName = options.serverName;\n this.sampleRate = options.sampleRate;\n this.errorSampleRate = options.errorSampleRate;\n this.sendQueue = new TypedRing<CollectionFrame>(\n options.maxCollectionFrames,\n );\n\n this.collectionTimer = setInterval(() => {\n this.tick();\n }, this.collectionInterval);\n if (this.collectionTimer && typeof this.collectionTimer.unref === \"function\") {\n this.collectionTimer.unref();\n }\n\n this.metricsTimer = setInterval(() => {\n this.collectSystemMetrics();\n }, this.metricsInterval);\n if (this.metricsTimer && typeof this.metricsTimer.unref === \"function\") {\n this.metricsTimer.unref();\n }\n }\n\n private tick(): void {\n if (this.current !== null) {\n if (this.currentSetAt < Date.now() - this.collectionInterval) {\n this.rotateCurrentCollectionFrame();\n this.processSendQueue();\n }\n } else if (this.sendQueue.length > 0) {\n this.processSendQueue();\n }\n }\n\n private ensureCurrent(): CollectionFrame {\n if (this.current === null) {\n this.current = { stackTraces: [], metrics: [], traces: [] };\n this.currentSetAt = Date.now();\n }\n return this.current;\n }\n\n addException(exception: ExceptionStackTrace): void {\n this.ensureCurrent().stackTraces.push(exception);\n }\n\n addMetric(metric: MetricRecord): void {\n this.ensureCurrent().metrics.push(metric);\n }\n\n addTrace(trace: Trace): void {\n this.ensureCurrent().traces.push(trace);\n }\n\n private rotateCurrentCollectionFrame(): void {\n if (this.current !== null) {\n this.sendQueue.push(this.current);\n this.current = null;\n }\n }\n\n private processSendQueue(): void {\n if (\n this.lastUploadStarted === null ||\n this.lastUploadStarted < Date.now() - this.uploadThrottle\n ) {\n this.lastUploadStarted = Date.now();\n const frames = this.sendQueue.readAll();\n if (frames.length > 0) {\n this.triggerUpload(frames);\n }\n }\n }\n\n private triggerUpload(framesToSend: CollectionFrame[]): void {\n const payload: ReportRequest = {\n collectionFrames: framesToSend,\n appVersion: this.version,\n serverName: this.serverName,\n };\n\n let jsonData: string;\n try {\n jsonData = JSON.stringify(payload);\n } catch (err) {\n if (this.debug) {\n console.error(\"Traceway: failed to serialize frames:\", err);\n }\n return;\n }\n\n let gzipped: Uint8Array;\n try {\n gzipped = new Uint8Array(zlib.gzipSync(Buffer.from(jsonData)));\n } catch (err) {\n if (this.debug) {\n console.error(\"Traceway: failed to gzip:\", err);\n }\n return;\n }\n\n fetch(this.apiUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Content-Encoding\": \"gzip\",\n Authorization: `Bearer ${this.token}`,\n },\n body: gzipped as unknown as BodyInit,\n })\n .then((resp) => {\n if (resp.status === 200) {\n this.sendQueue.remove(framesToSend);\n } else if (this.debug) {\n console.error(`Traceway: upload returned status ${resp.status}`);\n }\n })\n .catch((err) => {\n if (this.debug) {\n console.error(\"Traceway: upload failed:\", err);\n }\n });\n }\n\n private collectSystemMetrics(): void {\n try {\n const metrics = collectMetrics();\n for (const metric of metrics) {\n this.addMetric(metric);\n }\n } catch (err) {\n if (this.debug) {\n console.error(\"Traceway: failed to collect metrics:\", err);\n }\n }\n }\n\n async shutdown(timeoutMs?: number): Promise<void> {\n if (this.collectionTimer !== null) {\n clearInterval(this.collectionTimer);\n this.collectionTimer = null;\n }\n if (this.metricsTimer !== null) {\n clearInterval(this.metricsTimer);\n this.metricsTimer = null;\n }\n\n this.rotateCurrentCollectionFrame();\n\n const frames = this.sendQueue.readAll();\n if (frames.length === 0) return;\n\n const uploadPromise = (async () => {\n const payload: ReportRequest = {\n collectionFrames: frames,\n appVersion: this.version,\n serverName: this.serverName,\n };\n\n try {\n const jsonData = JSON.stringify(payload);\n const gzipped = new Uint8Array(zlib.gzipSync(Buffer.from(jsonData)));\n\n const resp = await fetch(this.apiUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Content-Encoding\": \"gzip\",\n Authorization: `Bearer ${this.token}`,\n },\n body: gzipped as unknown as BodyInit,\n });\n\n if (resp.status === 200) {\n this.sendQueue.remove(frames);\n }\n } catch (err) {\n if (this.debug) {\n console.error(\"Traceway: shutdown upload failed:\", err);\n }\n }\n })();\n\n if (timeoutMs !== undefined) {\n await Promise.race([\n uploadPromise,\n new Promise<void>((resolve) => setTimeout(resolve, timeoutMs)),\n ]);\n } else {\n await uploadPromise;\n }\n }\n}\n","export class TypedRing<T> {\n private arr: (T | null)[];\n private head: number = 0;\n private _capacity: number;\n private _len: number = 0;\n\n constructor(capacity: number) {\n this._capacity = capacity;\n this.arr = new Array<T | null>(capacity).fill(null);\n }\n\n get length(): number {\n return this._len;\n }\n\n get capacity(): number {\n return this._capacity;\n }\n\n push(val: T): void {\n this.arr[this.head] = val;\n this.head = (this.head + 1) % this._capacity;\n if (this._len < this._capacity) {\n this._len += 1;\n }\n }\n\n readAll(): T[] {\n const result: T[] = [];\n for (let i = 0; i < this._len; i++) {\n const idx =\n (this.head - this._len + i + this._capacity) % this._capacity;\n result.push(this.arr[idx] as T);\n }\n return result;\n }\n\n clear(): void {\n for (let i = 0; i < this.arr.length; i++) {\n this.arr[i] = null;\n }\n this.head = 0;\n this._len = 0;\n }\n\n remove(vals: T[]): number {\n if (vals.length === 0) return 0;\n\n const toRemove = new Set<T>(vals);\n let writeIdx = 0;\n let removed = 0;\n\n for (let i = 0; i < this._len; i++) {\n const readIdx =\n (this.head - this._len + i + this._capacity) % this._capacity;\n if (toRemove.has(this.arr[readIdx] as T)) {\n removed++;\n } else {\n if (writeIdx !== i) {\n const destIdx =\n (this.head - this._len + writeIdx + this._capacity) %\n this._capacity;\n this.arr[destIdx] = this.arr[readIdx];\n }\n writeIdx++;\n }\n }\n\n for (let i = writeIdx; i < this._len; i++) {\n const idx =\n (this.head - this._len + i + this._capacity) % this._capacity;\n this.arr[idx] = null;\n }\n\n this._len = writeIdx;\n this.head = (this.head - removed + this._capacity) % this._capacity;\n\n return removed;\n }\n}\n","import * as os from \"os\";\nimport { METRIC_MEM_USED, METRIC_MEM_TOTAL, METRIC_CPU_USED_PCNT } from \"@tracewayapp/core\";\nimport type { MetricRecord } from \"@tracewayapp/core\";\nimport { nowISO } from \"@tracewayapp/core\";\n\nlet prevCpuUsage: NodeJS.CpuUsage | null = null;\nlet prevCpuTime: number | null = null;\n\nexport function collectMetrics(): MetricRecord[] {\n const metrics: MetricRecord[] = [];\n const recordedAt = nowISO();\n\n const mem = process.memoryUsage();\n metrics.push({\n name: METRIC_MEM_USED,\n value: Math.round((mem.rss / 1024 / 1024) * 100) / 100,\n recordedAt,\n });\n\n const totalMem = os.totalmem();\n metrics.push({\n name: METRIC_MEM_TOTAL,\n value: Math.round((totalMem / 1024 / 1024) * 100) / 100,\n recordedAt,\n });\n\n const currentCpuUsage = process.cpuUsage();\n const currentTime = Date.now();\n if (prevCpuUsage !== null && prevCpuTime !== null) {\n const elapsedMs = currentTime - prevCpuTime;\n if (elapsedMs > 0) {\n const userDelta = currentCpuUsage.user - prevCpuUsage.user;\n const systemDelta = currentCpuUsage.system - prevCpuUsage.system;\n const totalDeltaMs = (userDelta + systemDelta) / 1000;\n const cpuCount = os.cpus().length || 1;\n const cpuPercent = (totalDeltaMs / elapsedMs / cpuCount) * 100;\n metrics.push({\n name: METRIC_CPU_USED_PCNT,\n value: Math.round(cpuPercent * 100) / 100,\n recordedAt,\n });\n }\n }\n prevCpuUsage = currentCpuUsage;\n prevCpuTime = currentTime;\n\n return metrics;\n}\n\nexport function resetCpuTracking(): void {\n prevCpuUsage = null;\n prevCpuTime = null;\n}\n","export function formatErrorStackTrace(error: Error): string {\n const lines: string[] = [];\n\n const typeName = error.constructor.name || \"Error\";\n lines.push(`${typeName}: ${error.message}`);\n\n if (error.stack) {\n const stackLines = error.stack.split(\"\\n\");\n for (const line of stackLines) {\n const match = line.match(/^\\s+at\\s+(.+?)\\s+\\((.+):(\\d+):\\d+\\)$/);\n if (match) {\n const funcName = shortenFunctionName(match[1]);\n const file = shortenFilePath(match[2]);\n const lineNum = match[3];\n lines.push(`${funcName}()`);\n lines.push(` ${file}:${lineNum}`);\n continue;\n }\n\n const matchNoParens = line.match(/^\\s+at\\s+(.+):(\\d+):\\d+$/);\n if (matchNoParens) {\n const file = shortenFilePath(matchNoParens[1]);\n const lineNum = matchNoParens[2];\n lines.push(`<anonymous>()`);\n lines.push(` ${file}:${lineNum}`);\n continue;\n }\n\n const matchFnOnly = line.match(/^\\s+at\\s+(.+)$/);\n if (matchFnOnly) {\n const funcName = shortenFunctionName(matchFnOnly[1]);\n lines.push(`${funcName}()`);\n lines.push(` <unknown>:0`);\n }\n }\n }\n\n return lines.join(\"\\n\") + \"\\n\";\n}\n\nfunction shortenFunctionName(fn: string): string {\n const slashIdx = fn.lastIndexOf(\"/\");\n if (slashIdx >= 0) {\n fn = fn.slice(slashIdx + 1);\n }\n const dotIdx = fn.indexOf(\".\");\n if (dotIdx >= 0) {\n fn = fn.slice(dotIdx + 1);\n }\n return fn;\n}\n\nfunction shortenFilePath(filePath: string): string {\n const parts = filePath.split(\"/\");\n return parts[parts.length - 1];\n}\n","import { AsyncLocalStorage } from \"async_hooks\";\nimport { generateUUID } from \"@tracewayapp/core\";\nimport type { Span } from \"@tracewayapp/core\";\n\n/**\n * Trace context stored in AsyncLocalStorage.\n * Automatically propagates through async operations.\n */\nexport interface TraceContext {\n /** Unique trace identifier (UUID v4) */\n traceId: string;\n /** Whether this is a background task (vs HTTP request) */\n isTask: boolean;\n /** When the trace started */\n startedAt: Date;\n /** Collected spans within this trace */\n spans: Span[];\n /** Key-value attributes for this trace */\n attributes: Record<string, string>;\n /** For HTTP traces: endpoint like \"GET /api/users\" */\n endpoint?: string;\n /** For HTTP traces: response status code */\n statusCode?: number;\n /** For HTTP traces: response body size */\n bodySize?: number;\n /** For HTTP traces: client IP address */\n clientIP?: string;\n /** Distributed trace ID for cross-service correlation */\n distributedTraceId?: string;\n}\n\n/**\n * Options for creating a new trace context.\n */\nexport interface TraceContextOptions {\n /** Custom trace ID (auto-generated if not provided) */\n traceId?: string;\n /** Mark as background task instead of HTTP trace */\n isTask?: boolean;\n /** Initial attributes */\n attributes?: Record<string, string>;\n /** HTTP endpoint (e.g., \"GET /api/users\") */\n endpoint?: string;\n /** Client IP address */\n clientIP?: string;\n /** Distributed trace ID from incoming request header */\n distributedTraceId?: string;\n}\n\n// The AsyncLocalStorage instance for trace context\nconst asyncLocalStorage = new AsyncLocalStorage<TraceContext>();\n\n/**\n * Get the current trace context, if any.\n * Returns undefined if not within a trace context.\n */\nexport function getTraceContext(): TraceContext | undefined {\n return asyncLocalStorage.getStore();\n}\n\n/**\n * Get the current trace ID, if within a trace context.\n */\nexport function getTraceId(): string | undefined {\n return asyncLocalStorage.getStore()?.traceId;\n}\n\n/**\n * Get the distributed trace ID from the current trace context, if any.\n */\nexport function getDistributedTraceId(): string | undefined {\n return asyncLocalStorage.getStore()?.distributedTraceId;\n}\n\n/**\n * Check if currently within a trace context.\n */\nexport function hasTraceContext(): boolean {\n return asyncLocalStorage.getStore() !== undefined;\n}\n\n/**\n * Run a function within a new trace context.\n * All async operations within will have access to this context.\n *\n * @example\n * ```ts\n * // HTTP request handler\n * withTraceContext({ endpoint: \"GET /api/users\", clientIP: req.ip }, async () => {\n * const users = await db.query(\"SELECT * FROM users\");\n * captureException(new Error(\"oops\")); // Auto-linked to trace\n * return users;\n * });\n *\n * // Background task\n * withTraceContext({ isTask: true, endpoint: \"process-emails\" }, async () => {\n * await processEmails();\n * });\n * ```\n */\nexport function withTraceContext<T>(\n options: TraceContextOptions,\n fn: () => T,\n): T {\n const context: TraceContext = {\n traceId: options.traceId ?? generateUUID(),\n isTask: options.isTask ?? false,\n startedAt: new Date(),\n spans: [],\n attributes: options.attributes ?? {},\n endpoint: options.endpoint,\n clientIP: options.clientIP,\n distributedTraceId: options.distributedTraceId,\n };\n return asyncLocalStorage.run(context, fn);\n}\n\n/**\n * Run a function within a trace context, automatically capturing the trace on completion.\n * This is a convenience wrapper that handles timing and capture automatically.\n *\n * @example\n * ```ts\n * // In Express middleware\n * app.use((req, res, next) => {\n * runWithTraceContext(\n * {\n * endpoint: `${req.method} ${req.path}`,\n * clientIP: req.ip,\n * attributes: { userId: req.user?.id },\n * },\n * async () => {\n * await next();\n * // Status code and body size set via setTraceResponseInfo()\n * },\n * { captureOnEnd: true }\n * );\n * });\n * ```\n */\nexport function runWithTraceContext<T>(\n options: TraceContextOptions,\n fn: () => T | Promise<T>,\n): T | Promise<T> {\n return withTraceContext(options, fn);\n}\n\n/**\n * Add a completed span to the current trace context.\n * No-op if not within a trace context.\n */\nexport function addSpanToContext(span: Span): void {\n const ctx = asyncLocalStorage.getStore();\n if (ctx) {\n ctx.spans.push(span);\n }\n}\n\n/**\n * Set an attribute on the current trace context.\n * No-op if not within a trace context.\n */\nexport function setTraceAttribute(key: string, value: string): void {\n const ctx = asyncLocalStorage.getStore();\n if (ctx) {\n ctx.attributes[key] = value;\n }\n}\n\n/**\n * Set multiple attributes on the current trace context.\n * No-op if not within a trace context.\n */\nexport function setTraceAttributes(attributes: Record<string, string>): void {\n const ctx = asyncLocalStorage.getStore();\n if (ctx) {\n Object.assign(ctx.attributes, attributes);\n }\n}\n\n/**\n * Set HTTP response info on the current trace context.\n * Used by framework adapters after the response is sent.\n */\nexport function setTraceResponseInfo(\n statusCode: number,\n bodySize?: number,\n): void {\n const ctx = asyncLocalStorage.getStore();\n if (ctx) {\n ctx.statusCode = statusCode;\n ctx.bodySize = bodySize;\n }\n}\n\n/**\n * Get all spans from the current trace context.\n * Returns empty array if not within a trace context.\n */\nexport function getTraceSpans(): Span[] {\n return asyncLocalStorage.getStore()?.spans ?? [];\n}\n\n/**\n * Get the duration in milliseconds since the trace started.\n * Returns 0 if not within a trace context.\n */\nexport function getTraceDuration(): number {\n const ctx = asyncLocalStorage.getStore();\n if (!ctx) return 0;\n return Date.now() - ctx.startedAt.getTime();\n}\n\n/**\n * Fork the current trace context for a sub-operation.\n * Useful for parallel operations that should have isolated spans.\n * Returns undefined if not within a trace context.\n */\nexport function forkTraceContext<T>(fn: () => T): T | undefined {\n const parentCtx = asyncLocalStorage.getStore();\n if (!parentCtx) return undefined;\n\n const forkedContext: TraceContext = {\n ...parentCtx,\n spans: [], // Forked context gets its own spans\n attributes: { ...parentCtx.attributes },\n };\n\n return asyncLocalStorage.run(forkedContext, () => {\n const result = fn();\n // Merge spans back to parent after completion\n parentCtx.spans.push(...forkedContext.spans);\n return result;\n });\n}\n\n// Export the AsyncLocalStorage instance for advanced use cases\nexport { asyncLocalStorage as traceContextStorage };\n"],"mappings":"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","names":["generateUUID","nowISO","os","hostname","nowISO","generateUUID"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tracewayapp/backend",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Traceway SDK for Node.js backends",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -23,6 +23,6 @@
|
|
|
23
23
|
"dev": "tsup --watch"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@tracewayapp/core": "1.0.
|
|
26
|
+
"@tracewayapp/core": "1.0.2"
|
|
27
27
|
}
|
|
28
28
|
}
|