@spanhq/bullmq 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +171 -0
- package/dist/cjs/context.d.ts +42 -0
- package/dist/cjs/context.d.ts.map +1 -0
- package/dist/cjs/context.js +59 -0
- package/dist/cjs/context.js.map +1 -0
- package/dist/cjs/index.d.ts +47 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +59 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/sender.d.ts +37 -0
- package/dist/cjs/sender.d.ts.map +1 -0
- package/dist/cjs/sender.js +116 -0
- package/dist/cjs/sender.js.map +1 -0
- package/dist/cjs/tracer.d.ts +38 -0
- package/dist/cjs/tracer.d.ts.map +1 -0
- package/dist/cjs/tracer.js +259 -0
- package/dist/cjs/tracer.js.map +1 -0
- package/dist/esm/context.d.ts +42 -0
- package/dist/esm/context.d.ts.map +1 -0
- package/dist/esm/context.js +53 -0
- package/dist/esm/context.js.map +1 -0
- package/dist/esm/index.d.ts +47 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +54 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/sender.d.ts +37 -0
- package/dist/esm/sender.d.ts.map +1 -0
- package/dist/esm/sender.js +112 -0
- package/dist/esm/sender.js.map +1 -0
- package/dist/esm/tracer.d.ts +38 -0
- package/dist/esm/tracer.d.ts.map +1 -0
- package/dist/esm/tracer.js +255 -0
- package/dist/esm/tracer.js.map +1 -0
- package/package.json +54 -0
package/README.md
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# @spanhq/bullmq
|
|
2
|
+
|
|
3
|
+
Distributed tracing SDK for BullMQ background jobs. Automatically captures job execution traces, retry timelines, and failure details without modifying your processor code.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @spanhq/bullmq
|
|
9
|
+
# or
|
|
10
|
+
bun add @spanhq/bullmq
|
|
11
|
+
# or
|
|
12
|
+
yarn add @spanhq/bullmq
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
**Peer dependency:** `bullmq >= 4.0.0`
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { createTracer } from '@spanhq/bullmq'
|
|
21
|
+
import { Worker, Queue } from 'bullmq'
|
|
22
|
+
|
|
23
|
+
const tracer = createTracer({ apiKey: 'jt_live_xxxx' })
|
|
24
|
+
|
|
25
|
+
const worker = tracer.traceWorker(new Worker('my-queue', async (job) => {
|
|
26
|
+
// your existing processor logic — no changes needed
|
|
27
|
+
}, { connection: redis }))
|
|
28
|
+
|
|
29
|
+
const queue = tracer.traceQueue(new Queue('my-queue', { connection: redis }))
|
|
30
|
+
|
|
31
|
+
// On shutdown:
|
|
32
|
+
process.on('SIGTERM', async () => {
|
|
33
|
+
await tracer.shutdown()
|
|
34
|
+
process.exit(0)
|
|
35
|
+
})
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
That's it. Every job processed by the worker will automatically generate tracing spans.
|
|
39
|
+
|
|
40
|
+
## API Reference
|
|
41
|
+
|
|
42
|
+
### `createTracer(config)`
|
|
43
|
+
|
|
44
|
+
Creates a new tracer instance.
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
const tracer = createTracer({
|
|
48
|
+
apiKey: 'jt_live_xxxx', // required
|
|
49
|
+
endpoint: 'https://api.spanhq.dev', // optional (default: production)
|
|
50
|
+
debug: false, // optional (default: false)
|
|
51
|
+
})
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
| Option | Type | Required | Default | Description |
|
|
55
|
+
|------------|----------|----------|----------------------------------|---------------------------------|
|
|
56
|
+
| `apiKey` | `string` | Yes | `process.env.SPANHQ_API_KEY` | Your project API key |
|
|
57
|
+
| `endpoint` | `string` | No | `https://api.spanhq.dev` | Backend URL (for self-hosted) |
|
|
58
|
+
| `debug` | `boolean`| No | `false` | Enable console logging |
|
|
59
|
+
|
|
60
|
+
### `tracer.traceWorker(worker)`
|
|
61
|
+
|
|
62
|
+
Instruments a BullMQ Worker to capture lifecycle events.
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
const worker = tracer.traceWorker(new Worker('queue', processor, opts))
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Events captured:**
|
|
69
|
+
- `active` — Job starts processing. Generates trace ID if not inherited.
|
|
70
|
+
- `completed` — Job finishes successfully. Records duration.
|
|
71
|
+
- `failed` — Job fails. Records error message and stack trace. Marks as `dead` if all retries exhausted.
|
|
72
|
+
- `stalled` — Job stalled. Records as a failure event.
|
|
73
|
+
|
|
74
|
+
Returns the same worker instance (pass-through).
|
|
75
|
+
|
|
76
|
+
### `tracer.traceQueue(queue)`
|
|
77
|
+
|
|
78
|
+
Instruments a BullMQ Queue to propagate trace context to child jobs.
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
const queue = tracer.traceQueue(new Queue('child-queue', opts))
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
When `queue.add()` is called inside a traced worker processor, the SDK automatically injects `__trace_id` and `__parent_id` into the child job's data. This enables distributed trace propagation across job chains.
|
|
85
|
+
|
|
86
|
+
Returns the same queue instance (pass-through).
|
|
87
|
+
|
|
88
|
+
### `tracer.shutdown()`
|
|
89
|
+
|
|
90
|
+
Gracefully shuts down the tracer. Flushes all buffered spans to the backend.
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
await tracer.shutdown()
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Important:** Always await `shutdown()` before exiting the process to prevent span loss.
|
|
97
|
+
|
|
98
|
+
## How Trace Context Propagation Works
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
Job A (Worker 1)
|
|
102
|
+
└─ queue.add('child-job', data)
|
|
103
|
+
└─ Job B (Worker 2) ← inherits trace_id from Job A
|
|
104
|
+
└─ queue.add('grandchild', data)
|
|
105
|
+
└─ Job C (Worker 3) ← inherits trace_id from Job A
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
1. When a root job starts, the SDK generates a unique `trace_id`
|
|
109
|
+
2. If the worker processor calls `queue.add()`, the SDK injects `__trace_id` and `__parent_id` into the child job data
|
|
110
|
+
3. When the child job starts, the SDK reads `__trace_id` from the job data and continues the trace
|
|
111
|
+
4. This works across any number of job chain levels
|
|
112
|
+
|
|
113
|
+
**AsyncLocalStorage:** The SDK uses Node.js `AsyncLocalStorage` to maintain context across async boundaries within a single worker processor execution.
|
|
114
|
+
|
|
115
|
+
## Batching & Performance
|
|
116
|
+
|
|
117
|
+
- Spans are buffered in memory and flushed every **2 seconds**
|
|
118
|
+
- If the buffer reaches **10 spans**, an immediate flush is triggered
|
|
119
|
+
- The SDK **never blocks** your job processing
|
|
120
|
+
- All network errors are silently caught (logged in debug mode)
|
|
121
|
+
|
|
122
|
+
## Environment Variables
|
|
123
|
+
|
|
124
|
+
| Variable | Description |
|
|
125
|
+
|-----------------------|------------------------------------------|
|
|
126
|
+
| `SPANHQ_API_KEY` | API key (alternative to config) |
|
|
127
|
+
| `SPANHQ_ENDPOINT` | Backend URL (alternative to config) |
|
|
128
|
+
|
|
129
|
+
## Safety Guarantees
|
|
130
|
+
|
|
131
|
+
The SDK is designed to **never crash your application**:
|
|
132
|
+
|
|
133
|
+
- All event handlers are wrapped in try-catch blocks
|
|
134
|
+
- Network failures are silently caught and optionally logged
|
|
135
|
+
- The SDK uses fire-and-forget for span delivery
|
|
136
|
+
- If the backend is unreachable, spans are dropped (not queued indefinitely)
|
|
137
|
+
- The `traceWorker` and `traceQueue` functions return the original instances
|
|
138
|
+
|
|
139
|
+
## Troubleshooting
|
|
140
|
+
|
|
141
|
+
### Spans not appearing in the dashboard
|
|
142
|
+
|
|
143
|
+
1. **Check your API key:** Ensure `apiKey` is correct and the project exists
|
|
144
|
+
2. **Enable debug mode:** Set `debug: true` to see SDK logs in the console
|
|
145
|
+
3. **Check the endpoint:** If self-hosted, ensure `endpoint` points to your backend
|
|
146
|
+
4. **Verify network access:** The SDK needs to reach the backend via HTTP POST
|
|
147
|
+
|
|
148
|
+
### Debug mode output
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
const tracer = createTracer({ apiKey: '...', debug: true })
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Debug mode logs:
|
|
155
|
+
- Every span buffered
|
|
156
|
+
- Every flush (with span count)
|
|
157
|
+
- Backend responses
|
|
158
|
+
- Errors (network, validation, etc.)
|
|
159
|
+
|
|
160
|
+
### Self-hosted setup
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
const tracer = createTracer({
|
|
164
|
+
apiKey: 'jt_live_xxxx',
|
|
165
|
+
endpoint: 'http://localhost:3000',
|
|
166
|
+
})
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## License
|
|
170
|
+
|
|
171
|
+
MIT
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
/** Trace context propagated via AsyncLocalStorage */
|
|
3
|
+
export interface TraceContext {
|
|
4
|
+
traceId: string;
|
|
5
|
+
spanId: string;
|
|
6
|
+
}
|
|
7
|
+
/** AsyncLocalStorage instance for trace context propagation */
|
|
8
|
+
export declare const storage: AsyncLocalStorage<TraceContext>;
|
|
9
|
+
/**
|
|
10
|
+
* Active job context tracking.
|
|
11
|
+
*
|
|
12
|
+
* We maintain a Map of ALL currently active job contexts (keyed by
|
|
13
|
+
* "queueName:jobId"). When a worker processor calls traceQueue.add(),
|
|
14
|
+
* we look up the context from the correct active job.
|
|
15
|
+
*
|
|
16
|
+
* Since BullMQ workers with concurrency > 1 may have multiple active
|
|
17
|
+
* jobs simultaneously, a single global variable is insufficient.
|
|
18
|
+
* Instead, we track each active job separately.
|
|
19
|
+
*
|
|
20
|
+
* The key insight: traceQueue.add() is called FROM WITHIN a worker
|
|
21
|
+
* processor, so the "current" context is the one for whichever job's
|
|
22
|
+
* processor is executing. We use a stack-like approach: each add()
|
|
23
|
+
* reads the MOST RECENT context that hasn't been completed yet.
|
|
24
|
+
*
|
|
25
|
+
* For single-concurrency queues (the pipeline use case), the Map
|
|
26
|
+
* will have at most one entry per queue, making lookups unambiguous.
|
|
27
|
+
*/
|
|
28
|
+
export declare const activeJobContexts: Map<string, TraceContext>;
|
|
29
|
+
/**
|
|
30
|
+
* Set context for a specific active job.
|
|
31
|
+
*/
|
|
32
|
+
export declare function setJobContext(key: string, ctx: TraceContext): void;
|
|
33
|
+
/**
|
|
34
|
+
* Remove context when a job completes or fails.
|
|
35
|
+
*/
|
|
36
|
+
export declare function clearJobContext(key: string): void;
|
|
37
|
+
/**
|
|
38
|
+
* Get the current trace context.
|
|
39
|
+
* Priority: AsyncLocalStorage → most recently activated job context.
|
|
40
|
+
*/
|
|
41
|
+
export declare function getCurrentContext(): TraceContext | undefined;
|
|
42
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,qDAAqD;AACrD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,+DAA+D;AAC/D,eAAO,MAAM,OAAO,iCAAwC,CAAC;AAE7D;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,iBAAiB,2BAAkC,CAAC;AAEjE;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,QAE3D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,QAE1C;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,YAAY,GAAG,SAAS,CAY5D"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.activeJobContexts = exports.storage = void 0;
|
|
4
|
+
exports.setJobContext = setJobContext;
|
|
5
|
+
exports.clearJobContext = clearJobContext;
|
|
6
|
+
exports.getCurrentContext = getCurrentContext;
|
|
7
|
+
const node_async_hooks_1 = require("node:async_hooks");
|
|
8
|
+
/** AsyncLocalStorage instance for trace context propagation */
|
|
9
|
+
exports.storage = new node_async_hooks_1.AsyncLocalStorage();
|
|
10
|
+
/**
|
|
11
|
+
* Active job context tracking.
|
|
12
|
+
*
|
|
13
|
+
* We maintain a Map of ALL currently active job contexts (keyed by
|
|
14
|
+
* "queueName:jobId"). When a worker processor calls traceQueue.add(),
|
|
15
|
+
* we look up the context from the correct active job.
|
|
16
|
+
*
|
|
17
|
+
* Since BullMQ workers with concurrency > 1 may have multiple active
|
|
18
|
+
* jobs simultaneously, a single global variable is insufficient.
|
|
19
|
+
* Instead, we track each active job separately.
|
|
20
|
+
*
|
|
21
|
+
* The key insight: traceQueue.add() is called FROM WITHIN a worker
|
|
22
|
+
* processor, so the "current" context is the one for whichever job's
|
|
23
|
+
* processor is executing. We use a stack-like approach: each add()
|
|
24
|
+
* reads the MOST RECENT context that hasn't been completed yet.
|
|
25
|
+
*
|
|
26
|
+
* For single-concurrency queues (the pipeline use case), the Map
|
|
27
|
+
* will have at most one entry per queue, making lookups unambiguous.
|
|
28
|
+
*/
|
|
29
|
+
exports.activeJobContexts = new Map();
|
|
30
|
+
/**
|
|
31
|
+
* Set context for a specific active job.
|
|
32
|
+
*/
|
|
33
|
+
function setJobContext(key, ctx) {
|
|
34
|
+
exports.activeJobContexts.set(key, ctx);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Remove context when a job completes or fails.
|
|
38
|
+
*/
|
|
39
|
+
function clearJobContext(key) {
|
|
40
|
+
exports.activeJobContexts.delete(key);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Get the current trace context.
|
|
44
|
+
* Priority: AsyncLocalStorage → most recently activated job context.
|
|
45
|
+
*/
|
|
46
|
+
function getCurrentContext() {
|
|
47
|
+
const alsCtx = exports.storage.getStore();
|
|
48
|
+
if (alsCtx)
|
|
49
|
+
return alsCtx;
|
|
50
|
+
// Fallback: return the most recently added active context.
|
|
51
|
+
// In single-concurrency workers this is always correct.
|
|
52
|
+
// In multi-concurrency workers, there's a small risk of picking
|
|
53
|
+
// the wrong context, but for tracing purposes this is acceptable.
|
|
54
|
+
if (exports.activeJobContexts.size === 0)
|
|
55
|
+
return undefined;
|
|
56
|
+
const entries = Array.from(exports.activeJobContexts.values());
|
|
57
|
+
return entries[entries.length - 1];
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":";;;AAmCA,sCAEC;AAKD,0CAEC;AAMD,8CAYC;AA9DD,uDAAqD;AAQrD,+DAA+D;AAClD,QAAA,OAAO,GAAG,IAAI,oCAAiB,EAAgB,CAAC;AAE7D;;;;;;;;;;;;;;;;;;GAkBG;AACU,QAAA,iBAAiB,GAAG,IAAI,GAAG,EAAwB,CAAC;AAEjE;;GAEG;AACH,SAAgB,aAAa,CAAC,GAAW,EAAE,GAAiB;IAC1D,yBAAiB,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,GAAW;IACzC,yBAAiB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAChC,CAAC;AAED;;;GAGG;AACH,SAAgB,iBAAiB;IAC/B,MAAM,MAAM,GAAG,eAAO,CAAC,QAAQ,EAAE,CAAC;IAClC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,2DAA2D;IAC3D,wDAAwD;IACxD,gEAAgE;IAChE,kEAAkE;IAClE,IAAI,yBAAiB,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAEnD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,yBAAiB,CAAC,MAAM,EAAE,CAAC,CAAC;IACvD,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACrC,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { TracerConfig } from "@spanhq/shared";
|
|
2
|
+
export { getCurrentContext } from "./context.js";
|
|
3
|
+
export type { TraceContext } from "./context.js";
|
|
4
|
+
export type { TracerConfig } from "@spanhq/shared";
|
|
5
|
+
/** BullMQ Worker type (minimal interface) */
|
|
6
|
+
interface BullMQWorker {
|
|
7
|
+
name: string;
|
|
8
|
+
on(event: string, callback: (...args: unknown[]) => void): unknown;
|
|
9
|
+
}
|
|
10
|
+
/** BullMQ Queue type (minimal interface) */
|
|
11
|
+
interface BullMQQueue {
|
|
12
|
+
name: string;
|
|
13
|
+
add(name: string, data: Record<string, unknown>, opts?: Record<string, unknown>): Promise<unknown>;
|
|
14
|
+
}
|
|
15
|
+
/** The tracer object returned by createTracer */
|
|
16
|
+
export interface Tracer {
|
|
17
|
+
/** Instrument a BullMQ Worker to emit tracing spans */
|
|
18
|
+
traceWorker<T extends BullMQWorker>(worker: T): T;
|
|
19
|
+
/** Instrument a BullMQ Queue to propagate trace context */
|
|
20
|
+
traceQueue<T extends BullMQQueue>(queue: T): T;
|
|
21
|
+
/** Gracefully shutdown — flushes remaining spans before resolving */
|
|
22
|
+
shutdown(): Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Create a SpanHQ instance.
|
|
26
|
+
*
|
|
27
|
+
* ```ts
|
|
28
|
+
* import { createTracer } from '@spanhq/bullmq'
|
|
29
|
+
*
|
|
30
|
+
* const tracer = createTracer({
|
|
31
|
+
* apiKey: 'jt_live_xxxx',
|
|
32
|
+
* endpoint: 'https://api.spanhq.dev',
|
|
33
|
+
* debug: false,
|
|
34
|
+
* })
|
|
35
|
+
*
|
|
36
|
+
* const worker = tracer.traceWorker(new Worker(...))
|
|
37
|
+
* const queue = tracer.traceQueue(new Queue(...))
|
|
38
|
+
*
|
|
39
|
+
* // On shutdown:
|
|
40
|
+
* await tracer.shutdown()
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* @param config - API key (required), optional endpoint and debug flag
|
|
44
|
+
* @returns A tracer object with traceWorker, traceQueue, and shutdown methods
|
|
45
|
+
*/
|
|
46
|
+
export declare function createTracer(config: TracerConfig): Tracer;
|
|
47
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,gBAAgB,CAAC;AAIjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAInD,6CAA6C;AAC7C,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,OAAO,CAAC;CACpE;AAED,4CAA4C;AAC5C,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CACD,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CAAC,OAAO,CAAC,CAAC;CACrB;AAED,iDAAiD;AACjD,MAAM,WAAW,MAAM;IACrB,uDAAuD;IACvD,WAAW,CAAC,CAAC,SAAS,YAAY,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC;IAClD,2DAA2D;IAC3D,UAAU,CAAC,CAAC,SAAS,WAAW,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC;IAC/C,qEAAqE;IACrE,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAoCzD"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getCurrentContext = void 0;
|
|
4
|
+
exports.createTracer = createTracer;
|
|
5
|
+
const sender_js_1 = require("./sender.js");
|
|
6
|
+
const tracer_js_1 = require("./tracer.js");
|
|
7
|
+
var context_js_1 = require("./context.js");
|
|
8
|
+
Object.defineProperty(exports, "getCurrentContext", { enumerable: true, get: function () { return context_js_1.getCurrentContext; } });
|
|
9
|
+
const DEFAULT_ENDPOINT = "https://api.spanhq.dev";
|
|
10
|
+
/**
|
|
11
|
+
* Create a SpanHQ instance.
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { createTracer } from '@spanhq/bullmq'
|
|
15
|
+
*
|
|
16
|
+
* const tracer = createTracer({
|
|
17
|
+
* apiKey: 'jt_live_xxxx',
|
|
18
|
+
* endpoint: 'https://api.spanhq.dev',
|
|
19
|
+
* debug: false,
|
|
20
|
+
* })
|
|
21
|
+
*
|
|
22
|
+
* const worker = tracer.traceWorker(new Worker(...))
|
|
23
|
+
* const queue = tracer.traceQueue(new Queue(...))
|
|
24
|
+
*
|
|
25
|
+
* // On shutdown:
|
|
26
|
+
* await tracer.shutdown()
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @param config - API key (required), optional endpoint and debug flag
|
|
30
|
+
* @returns A tracer object with traceWorker, traceQueue, and shutdown methods
|
|
31
|
+
*/
|
|
32
|
+
function createTracer(config) {
|
|
33
|
+
const apiKey = config.apiKey || process.env.SPANHQ_API_KEY || "";
|
|
34
|
+
const endpoint = config.endpoint ||
|
|
35
|
+
process.env.SPANHQ_ENDPOINT ||
|
|
36
|
+
DEFAULT_ENDPOINT;
|
|
37
|
+
const debug = config.debug ?? false;
|
|
38
|
+
if (!apiKey && debug) {
|
|
39
|
+
console.warn("[spanhq] No API key provided. Spans will be buffered but will fail to send.");
|
|
40
|
+
}
|
|
41
|
+
const senderConfig = {
|
|
42
|
+
apiKey,
|
|
43
|
+
endpoint: endpoint.replace(/\/$/, ""), // Strip trailing slash
|
|
44
|
+
debug,
|
|
45
|
+
};
|
|
46
|
+
const sender = new sender_js_1.SpanSender(senderConfig);
|
|
47
|
+
return {
|
|
48
|
+
traceWorker(worker) {
|
|
49
|
+
return (0, tracer_js_1.traceWorker)(worker, sender, senderConfig);
|
|
50
|
+
},
|
|
51
|
+
traceQueue(queue) {
|
|
52
|
+
return (0, tracer_js_1.traceQueue)(queue, sender, senderConfig);
|
|
53
|
+
},
|
|
54
|
+
async shutdown() {
|
|
55
|
+
await sender.shutdown();
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AA0DA,oCAoCC;AA7FD,2CAAyC;AACzC,2CAAsD;AAEtD,2CAAiD;AAAxC,+GAAA,iBAAiB,OAAA;AAI1B,MAAM,gBAAgB,GAAG,wBAAwB,CAAC;AA4BlD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,SAAgB,YAAY,CAAC,MAAoB;IAC/C,MAAM,MAAM,GACV,MAAM,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,EAAE,CAAC;IACpD,MAAM,QAAQ,GACZ,MAAM,CAAC,QAAQ;QACf,OAAO,CAAC,GAAG,CAAC,eAAe;QAC3B,gBAAgB,CAAC;IACnB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC;IAEpC,IAAI,CAAC,MAAM,IAAI,KAAK,EAAE,CAAC;QACrB,OAAO,CAAC,IAAI,CACV,6EAA6E,CAC9E,CAAC;IACJ,CAAC;IAED,MAAM,YAAY,GAAiB;QACjC,MAAM;QACN,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,uBAAuB;QAC9D,KAAK;KACN,CAAC;IAEF,MAAM,MAAM,GAAG,IAAI,sBAAU,CAAC,YAAY,CAAC,CAAC;IAE5C,OAAO;QACL,WAAW,CAAyB,MAAS;YAC3C,OAAO,IAAA,uBAAW,EAAC,MAAM,EAAE,MAAM,EAAE,YAAY,CAAM,CAAC;QACxD,CAAC;QAED,UAAU,CAAwB,KAAQ;YACxC,OAAO,IAAA,sBAAU,EAAC,KAAK,EAAE,MAAM,EAAE,YAAY,CAAM,CAAC;QACtD,CAAC;QAED,KAAK,CAAC,QAAQ;YACZ,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC1B,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Span, SenderConfig } from "@spanhq/shared";
|
|
2
|
+
/**
|
|
3
|
+
* SpanSender batches spans and sends them to the SpanHQ backend.
|
|
4
|
+
*
|
|
5
|
+
* Safety guarantees:
|
|
6
|
+
* - NEVER throws an error — all exceptions are caught and optionally logged
|
|
7
|
+
* - Flushes remaining spans on shutdown before resolving
|
|
8
|
+
* - Uses a timer-based flush every 2 seconds + size-based flush at 10 spans
|
|
9
|
+
*/
|
|
10
|
+
export declare class SpanSender {
|
|
11
|
+
private batch;
|
|
12
|
+
private timer;
|
|
13
|
+
private readonly config;
|
|
14
|
+
private inflight;
|
|
15
|
+
constructor(config: SenderConfig);
|
|
16
|
+
/**
|
|
17
|
+
* Add a span to the batch buffer.
|
|
18
|
+
* Triggers an immediate flush if batch reaches MAX_BATCH_SIZE.
|
|
19
|
+
*/
|
|
20
|
+
add(span: Span): void;
|
|
21
|
+
/**
|
|
22
|
+
* Flush the current batch to the backend.
|
|
23
|
+
* Copies the batch to a local variable and clears the buffer immediately
|
|
24
|
+
* to avoid blocking new span additions.
|
|
25
|
+
*/
|
|
26
|
+
flush(): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Send a batch of spans to the backend. Never throws.
|
|
29
|
+
*/
|
|
30
|
+
private sendBatch;
|
|
31
|
+
/**
|
|
32
|
+
* Shutdown the sender. Clears the timer and flushes remaining spans.
|
|
33
|
+
* Await this to ensure no spans are lost on process exit.
|
|
34
|
+
*/
|
|
35
|
+
shutdown(): Promise<void>;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=sender.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sender.d.ts","sourceRoot":"","sources":["../../src/sender.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAKzD;;;;;;;GAOG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAoC;gBAExC,MAAM,EAAE,YAAY;IAYhC;;;OAGG;IACH,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAoBrB;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAW5B;;OAEG;YACW,SAAS;IAoCvB;;;OAGG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAehC"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SpanSender = void 0;
|
|
4
|
+
const MAX_BATCH_SIZE = 10;
|
|
5
|
+
const FLUSH_INTERVAL_MS = 2000;
|
|
6
|
+
/**
|
|
7
|
+
* SpanSender batches spans and sends them to the SpanHQ backend.
|
|
8
|
+
*
|
|
9
|
+
* Safety guarantees:
|
|
10
|
+
* - NEVER throws an error — all exceptions are caught and optionally logged
|
|
11
|
+
* - Flushes remaining spans on shutdown before resolving
|
|
12
|
+
* - Uses a timer-based flush every 2 seconds + size-based flush at 10 spans
|
|
13
|
+
*/
|
|
14
|
+
class SpanSender {
|
|
15
|
+
batch = [];
|
|
16
|
+
timer = null;
|
|
17
|
+
config;
|
|
18
|
+
inflight = Promise.resolve();
|
|
19
|
+
constructor(config) {
|
|
20
|
+
this.config = config;
|
|
21
|
+
this.timer = setInterval(() => {
|
|
22
|
+
void this.flush();
|
|
23
|
+
}, FLUSH_INTERVAL_MS);
|
|
24
|
+
// Prevent the timer from keeping the process alive
|
|
25
|
+
if (this.timer && typeof this.timer === "object" && "unref" in this.timer) {
|
|
26
|
+
this.timer.unref();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Add a span to the batch buffer.
|
|
31
|
+
* Triggers an immediate flush if batch reaches MAX_BATCH_SIZE.
|
|
32
|
+
*/
|
|
33
|
+
add(span) {
|
|
34
|
+
try {
|
|
35
|
+
this.batch.push(span);
|
|
36
|
+
if (this.config.debug) {
|
|
37
|
+
console.log(`[spanhq] Span buffered: ${span.job_name} (${span.status}), batch size: ${this.batch.length}`);
|
|
38
|
+
}
|
|
39
|
+
if (this.batch.length >= MAX_BATCH_SIZE) {
|
|
40
|
+
void this.flush();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
if (this.config.debug) {
|
|
45
|
+
console.error("[spanhq] Failed to add span to batch:", err);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Flush the current batch to the backend.
|
|
51
|
+
* Copies the batch to a local variable and clears the buffer immediately
|
|
52
|
+
* to avoid blocking new span additions.
|
|
53
|
+
*/
|
|
54
|
+
async flush() {
|
|
55
|
+
if (this.batch.length === 0)
|
|
56
|
+
return;
|
|
57
|
+
const toSend = this.batch.slice();
|
|
58
|
+
this.batch = [];
|
|
59
|
+
const promise = this.sendBatch(toSend);
|
|
60
|
+
this.inflight = this.inflight.then(() => promise);
|
|
61
|
+
await promise;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Send a batch of spans to the backend. Never throws.
|
|
65
|
+
*/
|
|
66
|
+
async sendBatch(batch) {
|
|
67
|
+
try {
|
|
68
|
+
if (this.config.debug) {
|
|
69
|
+
console.log(`[spanhq] Flushing ${batch.length} spans to ${this.config.endpoint}`);
|
|
70
|
+
}
|
|
71
|
+
const response = await fetch(`${this.config.endpoint}/v1/spans`, {
|
|
72
|
+
method: "POST",
|
|
73
|
+
headers: {
|
|
74
|
+
"Content-Type": "application/json",
|
|
75
|
+
"x-api-key": this.config.apiKey,
|
|
76
|
+
},
|
|
77
|
+
body: JSON.stringify({ spans: batch }),
|
|
78
|
+
});
|
|
79
|
+
if (!response.ok) {
|
|
80
|
+
const text = await response.text();
|
|
81
|
+
if (this.config.debug) {
|
|
82
|
+
console.error(`[spanhq] Backend returned ${response.status}: ${text}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
else if (this.config.debug) {
|
|
86
|
+
const data = await response.json();
|
|
87
|
+
console.log(`[spanhq] Successfully sent ${batch.length} spans`, data);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
if (this.config.debug) {
|
|
92
|
+
console.error("[spanhq] Failed to flush spans:", err);
|
|
93
|
+
}
|
|
94
|
+
// Silently drop — never crash the host application
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Shutdown the sender. Clears the timer and flushes remaining spans.
|
|
99
|
+
* Await this to ensure no spans are lost on process exit.
|
|
100
|
+
*/
|
|
101
|
+
async shutdown() {
|
|
102
|
+
if (this.timer) {
|
|
103
|
+
clearInterval(this.timer);
|
|
104
|
+
this.timer = null;
|
|
105
|
+
}
|
|
106
|
+
// Flush any remaining spans
|
|
107
|
+
await this.flush();
|
|
108
|
+
// Wait for any in-flight requests
|
|
109
|
+
await this.inflight;
|
|
110
|
+
if (this.config.debug) {
|
|
111
|
+
console.log("[spanhq] Sender shut down successfully");
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
exports.SpanSender = SpanSender;
|
|
116
|
+
//# sourceMappingURL=sender.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sender.js","sourceRoot":"","sources":["../../src/sender.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { SpanSender } from "./sender.js";
|
|
2
|
+
import type { SenderConfig } from "@spanhq/shared";
|
|
3
|
+
/** BullMQ Worker type (minimal interface to avoid tight coupling) */
|
|
4
|
+
interface BullMQWorker {
|
|
5
|
+
name: string;
|
|
6
|
+
on(event: string, callback: (...args: unknown[]) => void): unknown;
|
|
7
|
+
}
|
|
8
|
+
/** BullMQ Queue type (minimal interface) */
|
|
9
|
+
interface BullMQQueue {
|
|
10
|
+
name: string;
|
|
11
|
+
add(name: string, data: Record<string, unknown>, opts?: Record<string, unknown>): Promise<unknown>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Instrument a BullMQ Worker to emit spans for every job lifecycle event.
|
|
15
|
+
*
|
|
16
|
+
* Events tracked: active, completed, failed, stalled.
|
|
17
|
+
*
|
|
18
|
+
* Trace context propagation:
|
|
19
|
+
* - On "active": Store trace context in the global activeJobContexts map.
|
|
20
|
+
* - During processor: traceQueue.add() reads the context from the map.
|
|
21
|
+
* - On "completed"/"failed": Remove context from the map, emit span.
|
|
22
|
+
*
|
|
23
|
+
* All errors are caught — this function NEVER crashes the host app.
|
|
24
|
+
*/
|
|
25
|
+
export declare function traceWorker(worker: BullMQWorker, sender: SpanSender, config: SenderConfig): BullMQWorker;
|
|
26
|
+
/**
|
|
27
|
+
* Instrument a BullMQ Queue to inject trace context into job data.
|
|
28
|
+
*
|
|
29
|
+
* When queue.add() is called inside a traced worker processor,
|
|
30
|
+
* the trace_id and parent span_id are automatically injected into
|
|
31
|
+
* the child job's data. This enables distributed trace propagation
|
|
32
|
+
* across job chains (e.g., ingest → transform → validate → publish).
|
|
33
|
+
*
|
|
34
|
+
* All errors are caught — this function NEVER crashes the host app.
|
|
35
|
+
*/
|
|
36
|
+
export declare function traceQueue(queue: BullMQQueue, sender: SpanSender, config: SenderConfig): BullMQQueue;
|
|
37
|
+
export {};
|
|
38
|
+
//# sourceMappingURL=tracer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracer.d.ts","sourceRoot":"","sources":["../../src/tracer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAQ,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEzD,qEAAqE;AACrE,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,GAAG,OAAO,CAAC;CACpE;AAED,4CAA4C;AAC5C,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CACD,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CAAC,OAAO,CAAC,CAAC;CACrB;AAwBD;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,YAAY,GACnB,YAAY,CA+Nd;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,YAAY,GACnB,WAAW,CA6Cb"}
|