@chidchanun/bcp 0.2.16 → 0.2.18
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 +150 -408
- package/docs/README.md +36 -38
- package/docs/api-manifest.json +27 -19
- package/docs/api-reference.md +257 -305
- package/docs/deployment-platform-v2.md +449 -0
- package/docs/docs-web-manifest.json +7 -3
- package/docs/observability-v3.md +402 -0
- package/docs/platform-manifest.json +30 -4
- package/docs/releases/0.2.17.md +166 -0
- package/docs/releases/0.2.18.md +136 -0
- package/package.json +11 -6
- package/packages/bundler/src/client-boundary.ts +1 -0
- package/packages/client/src/auth.mjs +1391 -0
- package/packages/client/src/config.mjs +1132 -0
- package/packages/client/src/deployment.mjs +609 -0
- package/packages/client/src/deployment.ts +20 -0
- package/packages/client/src/observability.mjs +1251 -0
- package/packages/client/src/observability.ts +37 -0
- package/packages/client/src/server.mjs +5615 -0
- package/packages/server/src/deployment.ts +936 -0
- package/packages/server/src/middleware.mjs +631 -0
- package/packages/server/src/observability-v3.ts +878 -0
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
# Observability Platform v3
|
|
2
|
+
|
|
3
|
+
BCP Framework `0.2.17` extends `bcp/observability` from metrics/health into request-to-background distributed tracing and correlation.
|
|
4
|
+
|
|
5
|
+
The existing Observability Platform v2 APIs remain available. v3 adds tracing without changing the public entrypoint.
|
|
6
|
+
|
|
7
|
+
## Goals
|
|
8
|
+
|
|
9
|
+
Observability v3 gives one logical operation a stable trace/correlation identity as it crosses HTTP middleware, background work, workflows, transactional events, realtime delivery and cache operations.
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
HTTP request
|
|
13
|
+
|
|
|
14
|
+
+-- database
|
|
15
|
+
|
|
|
16
|
+
+-- outbox event
|
|
17
|
+
| |
|
|
18
|
+
| +-- durable job
|
|
19
|
+
| |
|
|
20
|
+
| +-- workflow
|
|
21
|
+
| |
|
|
22
|
+
| +-- realtime
|
|
23
|
+
|
|
|
24
|
+
+-- cache
|
|
25
|
+
|
|
26
|
+
traceId + correlationId follow the operation.
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
BCP provides propagation primitives instead of coupling tracing to one vendor or collector.
|
|
30
|
+
|
|
31
|
+
## Create a tracer
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import {
|
|
35
|
+
createMemoryTraceSpanExporter,
|
|
36
|
+
createTracer,
|
|
37
|
+
} from "bcp/observability";
|
|
38
|
+
|
|
39
|
+
const exporter =
|
|
40
|
+
createMemoryTraceSpanExporter();
|
|
41
|
+
|
|
42
|
+
export const tracer =
|
|
43
|
+
createTracer({
|
|
44
|
+
exporter,
|
|
45
|
+
serviceName: "api",
|
|
46
|
+
defaultAttributes: {
|
|
47
|
+
environment: "production",
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
`createMemoryTraceSpanExporter()` is mainly useful for tests and local inspection. Production applications can implement `TraceSpanExporter` and forward completed spans to an OpenTelemetry bridge, APM agent, log pipeline or another collector.
|
|
53
|
+
|
|
54
|
+
## Root and child spans
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
await tracer.withSpan(
|
|
58
|
+
"order.checkout",
|
|
59
|
+
async span => {
|
|
60
|
+
span.setAttribute(
|
|
61
|
+
"order.id",
|
|
62
|
+
order.id
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
await tracer.withSpan(
|
|
66
|
+
"database.order.insert",
|
|
67
|
+
async () => {
|
|
68
|
+
await createOrder();
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
kind: "client",
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
);
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Nested `withSpan()` calls automatically reuse the active `traceId`, create a new `spanId`, and set the active span as `parentSpanId`.
|
|
79
|
+
|
|
80
|
+
The active trace context uses Node `AsyncLocalStorage`, so it flows through normal awaited asynchronous work.
|
|
81
|
+
|
|
82
|
+
## Span kinds
|
|
83
|
+
|
|
84
|
+
Supported kinds are:
|
|
85
|
+
|
|
86
|
+
```text
|
|
87
|
+
internal
|
|
88
|
+
server
|
|
89
|
+
client
|
|
90
|
+
producer
|
|
91
|
+
consumer
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Examples:
|
|
95
|
+
|
|
96
|
+
- HTTP inbound request: `server`
|
|
97
|
+
- SQL/HTTP/cache call: `client`
|
|
98
|
+
- queue/outbox publish: `producer`
|
|
99
|
+
- queue/event handler: `consumer`
|
|
100
|
+
- framework/application operation: `internal`
|
|
101
|
+
|
|
102
|
+
## Span attributes and events
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
await tracer.withSpan(
|
|
106
|
+
"payment.charge",
|
|
107
|
+
async span => {
|
|
108
|
+
span.setAttribute(
|
|
109
|
+
"payment.provider",
|
|
110
|
+
"example"
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
span.addEvent(
|
|
114
|
+
"payment.requested",
|
|
115
|
+
{
|
|
116
|
+
amount: 1490,
|
|
117
|
+
}
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
);
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Attribute values are intentionally limited to strings, finite numbers and booleans.
|
|
124
|
+
|
|
125
|
+
If a `withSpan()` callback throws, BCP marks the span as `error`, records an `exception` event and rethrows the original application error.
|
|
126
|
+
|
|
127
|
+
## HTTP request tracing
|
|
128
|
+
|
|
129
|
+
Use the Middleware System v2 integration:
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
import {
|
|
133
|
+
createRequestTracingMiddleware,
|
|
134
|
+
} from "bcp/observability";
|
|
135
|
+
|
|
136
|
+
export const middleware =
|
|
137
|
+
createRequestTracingMiddleware(
|
|
138
|
+
tracer
|
|
139
|
+
);
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The middleware:
|
|
143
|
+
|
|
144
|
+
1. Reads an incoming W3C `traceparent` header when valid.
|
|
145
|
+
2. Preserves the incoming `x-correlation-id` when supplied.
|
|
146
|
+
3. Starts a server span.
|
|
147
|
+
4. Makes the span context available through `AsyncLocalStorage`.
|
|
148
|
+
5. Adds the current `traceparent` and `x-correlation-id` to the response.
|
|
149
|
+
|
|
150
|
+
The default span name is `HTTP <METHOD>`. Applications can provide a lower-cardinality route name:
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
createRequestTracingMiddleware(
|
|
154
|
+
tracer,
|
|
155
|
+
{
|
|
156
|
+
spanName:
|
|
157
|
+
request =>
|
|
158
|
+
`route ${request.nextUrl.pathname}`,
|
|
159
|
+
}
|
|
160
|
+
);
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Avoid putting unbounded IDs directly into metric labels. Span names can also become labels when explicitly configured in trace metrics.
|
|
164
|
+
|
|
165
|
+
## W3C trace context
|
|
166
|
+
|
|
167
|
+
BCP supports W3C version `00` `traceparent` values:
|
|
168
|
+
|
|
169
|
+
```text
|
|
170
|
+
00-<32 hex trace id>-<16 hex span id>-<2 hex flags>
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Helpers:
|
|
174
|
+
|
|
175
|
+
```ts
|
|
176
|
+
import {
|
|
177
|
+
extractTraceHeaders,
|
|
178
|
+
formatTraceparent,
|
|
179
|
+
injectTraceHeaders,
|
|
180
|
+
parseTraceparent,
|
|
181
|
+
} from "bcp/observability";
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Example outbound request:
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
const headers =
|
|
188
|
+
new Headers();
|
|
189
|
+
|
|
190
|
+
injectTraceHeaders(
|
|
191
|
+
headers
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
await fetch(
|
|
195
|
+
serviceUrl,
|
|
196
|
+
{
|
|
197
|
+
headers,
|
|
198
|
+
}
|
|
199
|
+
);
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
`injectTraceHeaders()` uses the current context by default.
|
|
203
|
+
|
|
204
|
+
## Propagate through jobs, workflows and events
|
|
205
|
+
|
|
206
|
+
For non-HTTP transports use a trace carrier:
|
|
207
|
+
|
|
208
|
+
```ts
|
|
209
|
+
import {
|
|
210
|
+
createTraceCarrier,
|
|
211
|
+
} from "bcp/observability";
|
|
212
|
+
|
|
213
|
+
const trace =
|
|
214
|
+
createTraceCarrier();
|
|
215
|
+
|
|
216
|
+
await jobs.enqueue(
|
|
217
|
+
"order.process",
|
|
218
|
+
{
|
|
219
|
+
orderId,
|
|
220
|
+
trace,
|
|
221
|
+
}
|
|
222
|
+
);
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Consumer:
|
|
226
|
+
|
|
227
|
+
```ts
|
|
228
|
+
import {
|
|
229
|
+
runWithTraceCarrier,
|
|
230
|
+
} from "bcp/observability";
|
|
231
|
+
|
|
232
|
+
jobs.register(
|
|
233
|
+
"order.process",
|
|
234
|
+
async ({ payload }) =>
|
|
235
|
+
runWithTraceCarrier(
|
|
236
|
+
payload.trace,
|
|
237
|
+
() =>
|
|
238
|
+
tracer.withSpan(
|
|
239
|
+
"job order.process",
|
|
240
|
+
async () => {
|
|
241
|
+
await processOrder(
|
|
242
|
+
payload.orderId
|
|
243
|
+
);
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
kind: "consumer",
|
|
247
|
+
}
|
|
248
|
+
)
|
|
249
|
+
)
|
|
250
|
+
);
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
The same carrier can be stored in workflow input, outbox/event metadata or realtime payload metadata when the application needs trace continuity across those boundaries.
|
|
254
|
+
|
|
255
|
+
BCP does not mutate durable job/event schemas automatically in `0.2.17`; propagation remains explicit and provider-neutral.
|
|
256
|
+
|
|
257
|
+
## Correlation IDs
|
|
258
|
+
|
|
259
|
+
Every root trace gets a `correlationId`. Incoming HTTP requests may supply one through:
|
|
260
|
+
|
|
261
|
+
```text
|
|
262
|
+
x-correlation-id
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
Access trace fields for structured logs:
|
|
266
|
+
|
|
267
|
+
```ts
|
|
268
|
+
import {
|
|
269
|
+
getTraceLogFields,
|
|
270
|
+
} from "bcp/observability";
|
|
271
|
+
|
|
272
|
+
logger.info(
|
|
273
|
+
"order created",
|
|
274
|
+
{
|
|
275
|
+
...getTraceLogFields(),
|
|
276
|
+
orderId,
|
|
277
|
+
}
|
|
278
|
+
);
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
Output fields are:
|
|
282
|
+
|
|
283
|
+
```text
|
|
284
|
+
traceId
|
|
285
|
+
spanId
|
|
286
|
+
correlationId
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
This keeps logs searchable even when the log backend does not understand tracing natively.
|
|
290
|
+
|
|
291
|
+
## Trace metrics
|
|
292
|
+
|
|
293
|
+
Bridge completed spans into the existing BCP metrics registry:
|
|
294
|
+
|
|
295
|
+
```ts
|
|
296
|
+
import {
|
|
297
|
+
createCompositeTraceSpanExporter,
|
|
298
|
+
createMetricsRegistry,
|
|
299
|
+
createTraceMetricsExporter,
|
|
300
|
+
createTracer,
|
|
301
|
+
} from "bcp/observability";
|
|
302
|
+
|
|
303
|
+
const metrics =
|
|
304
|
+
createMetricsRegistry();
|
|
305
|
+
|
|
306
|
+
const traceMetrics =
|
|
307
|
+
createTraceMetricsExporter(
|
|
308
|
+
metrics
|
|
309
|
+
);
|
|
310
|
+
|
|
311
|
+
const tracer =
|
|
312
|
+
createTracer({
|
|
313
|
+
exporter:
|
|
314
|
+
createCompositeTraceSpanExporter([
|
|
315
|
+
traceMetrics,
|
|
316
|
+
myProductionExporter,
|
|
317
|
+
]),
|
|
318
|
+
});
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
Default metrics:
|
|
322
|
+
|
|
323
|
+
```text
|
|
324
|
+
bcp_trace_spans_total
|
|
325
|
+
bcp_trace_span_duration_seconds
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
Default labels are only:
|
|
329
|
+
|
|
330
|
+
```text
|
|
331
|
+
kind
|
|
332
|
+
status
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
`includeSpanName: true` adds a `span` label. Use it only when span names are controlled and low-cardinality.
|
|
336
|
+
|
|
337
|
+
## Exporter failure behavior
|
|
338
|
+
|
|
339
|
+
Span-export errors are intentionally isolated from application execution. A failing exporter does not turn a successful business operation into an application failure.
|
|
340
|
+
|
|
341
|
+
Exporter lifecycle can be closed explicitly:
|
|
342
|
+
|
|
343
|
+
```ts
|
|
344
|
+
await tracer.shutdown();
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
Composite exporter shutdown runs in reverse registration order.
|
|
348
|
+
|
|
349
|
+
## Production topology
|
|
350
|
+
|
|
351
|
+
```text
|
|
352
|
+
Application
|
|
353
|
+
|
|
|
354
|
+
+-- createTracer()
|
|
355
|
+
| |
|
|
356
|
+
| +-- memory exporter (tests)
|
|
357
|
+
| +-- trace metrics exporter
|
|
358
|
+
| +-- custom production exporter
|
|
359
|
+
|
|
|
360
|
+
+-- createRequestTracingMiddleware()
|
|
361
|
+
|
|
|
362
|
+
+-- createTraceCarrier()/runWithTraceCarrier()
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
BCP does not install an OpenTelemetry SDK or vendor APM client. Applications own collector/provider dependencies, authentication, batching and transport shutdown.
|
|
366
|
+
|
|
367
|
+
## Compatibility
|
|
368
|
+
|
|
369
|
+
`0.2.17` is intended to be backward-compatible with `0.2.16`.
|
|
370
|
+
|
|
371
|
+
Existing APIs remain available:
|
|
372
|
+
|
|
373
|
+
```text
|
|
374
|
+
createMetricsRegistry()
|
|
375
|
+
createMetricsResponse()
|
|
376
|
+
createRequestMetricsMiddleware()
|
|
377
|
+
createHealthRegistry()
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
The npm-prepared `bcp/observability` runtime is now compiled to `observability.mjs`, matching the hardened runtime packaging already used by cache/jobs/workflow/events/realtime/testing/plugins.
|
|
381
|
+
|
|
382
|
+
## Validation
|
|
383
|
+
|
|
384
|
+
Before releasing `0.2.17` run:
|
|
385
|
+
|
|
386
|
+
```bash
|
|
387
|
+
npm run typecheck
|
|
388
|
+
npm run test:unit
|
|
389
|
+
npm run test:integration
|
|
390
|
+
npm run test:e2e
|
|
391
|
+
npm run test:package
|
|
392
|
+
npm run rc:check
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
Related guides:
|
|
396
|
+
|
|
397
|
+
- [Observability Platform v2](observability.md)
|
|
398
|
+
- [Cache Platform v2](cache-platform-v2.md)
|
|
399
|
+
- [Durable Jobs](durable-jobs.md)
|
|
400
|
+
- [Workflow Orchestration](workflow-orchestration.md)
|
|
401
|
+
- [Transactional Outbox & Events](transactional-outbox-events.md)
|
|
402
|
+
- [Realtime Platform](realtime-platform.md)
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"framework": "bcp",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.18",
|
|
5
5
|
"releaseState": "unreleased",
|
|
6
|
-
"baseline": "
|
|
6
|
+
"baseline": "deployment-platform-v2",
|
|
7
7
|
"runtime": {
|
|
8
8
|
"node": ">=24.11.0",
|
|
9
9
|
"react": "19",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"bcp/testing",
|
|
27
27
|
"bcp/plugins",
|
|
28
28
|
"bcp/observability",
|
|
29
|
+
"bcp/deployment",
|
|
29
30
|
"bcp/server",
|
|
30
31
|
"bcp/server-only",
|
|
31
32
|
"bcp/middleware"
|
|
@@ -71,6 +72,29 @@
|
|
|
71
72
|
"prometheusMetrics": true,
|
|
72
73
|
"requestMetricsMiddleware": true,
|
|
73
74
|
"healthChecks": true,
|
|
75
|
+
"observabilityPlatformV3": true,
|
|
76
|
+
"distributedTracing": true,
|
|
77
|
+
"traceContextPropagation": true,
|
|
78
|
+
"w3cTraceparent": true,
|
|
79
|
+
"correlationIds": true,
|
|
80
|
+
"requestTracingMiddleware": true,
|
|
81
|
+
"memorySpanExporter": true,
|
|
82
|
+
"compositeSpanExporter": true,
|
|
83
|
+
"traceMetricsExporter": true,
|
|
84
|
+
"traceLogFields": true,
|
|
85
|
+
"compiledObservabilityRuntime": true,
|
|
86
|
+
"deploymentPlatformV2": true,
|
|
87
|
+
"deploymentRuntimeLifecycle": true,
|
|
88
|
+
"deploymentResourceRegistry": true,
|
|
89
|
+
"deploymentReadiness": true,
|
|
90
|
+
"deploymentDiagnostics": true,
|
|
91
|
+
"deploymentSignalHandling": true,
|
|
92
|
+
"deploymentShutdownHooks": true,
|
|
93
|
+
"deploymentRuntimeMetadata": true,
|
|
94
|
+
"compiledConfigRuntime": true,
|
|
95
|
+
"compiledAuthRuntime": true,
|
|
96
|
+
"compiledServerRuntime": true,
|
|
97
|
+
"compiledMiddlewareRuntime": true,
|
|
74
98
|
"backgroundJobsPlatform": true,
|
|
75
99
|
"jobQueueAdapterContract": true,
|
|
76
100
|
"inMemoryJobQueue": true,
|
|
@@ -200,7 +224,7 @@
|
|
|
200
224
|
"s3-compatible"
|
|
201
225
|
],
|
|
202
226
|
"compatibility": {
|
|
203
|
-
"previousBaseline": "0.2.
|
|
227
|
+
"previousBaseline": "0.2.17",
|
|
204
228
|
"intentionalBreakingChangesFromPreviousBaseline": false,
|
|
205
229
|
"migrationGuide": "migration-0.2.md"
|
|
206
230
|
},
|
|
@@ -217,6 +241,8 @@
|
|
|
217
241
|
"authSessionStore": "auth-session-store.md",
|
|
218
242
|
"authorizationSecurity": "authorization-security.md",
|
|
219
243
|
"observability": "observability.md",
|
|
244
|
+
"observabilityV3": "observability-v3.md",
|
|
245
|
+
"deploymentPlatformV2": "deployment-platform-v2.md",
|
|
220
246
|
"backgroundJobs": "background-jobs.md",
|
|
221
247
|
"jobScheduling": "job-scheduling.md",
|
|
222
248
|
"durableJobs": "durable-jobs.md",
|
|
@@ -227,6 +253,6 @@
|
|
|
227
253
|
"pluginModulePlatform": "plugin-module-platform.md",
|
|
228
254
|
"cachePlatformV2": "cache-platform-v2.md",
|
|
229
255
|
"migrationGuide": "migration-0.2.md",
|
|
230
|
-
"releaseNotes": "releases/0.2.
|
|
256
|
+
"releaseNotes": "releases/0.2.18.md"
|
|
231
257
|
}
|
|
232
258
|
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# BCP Framework 0.2.17 — Observability Platform v3
|
|
2
|
+
|
|
3
|
+
State: **unreleased**
|
|
4
|
+
|
|
5
|
+
`0.2.17` adds provider-neutral distributed tracing and correlation to the existing `bcp/observability` package while preserving the metrics, Prometheus and health APIs introduced in Observability Platform v2.
|
|
6
|
+
|
|
7
|
+
## Highlights
|
|
8
|
+
|
|
9
|
+
- `createTracer()` root/child span runtime
|
|
10
|
+
- Node `AsyncLocalStorage` trace context
|
|
11
|
+
- W3C `traceparent` parsing/formatting
|
|
12
|
+
- HTTP trace header injection/extraction
|
|
13
|
+
- stable `correlationId`
|
|
14
|
+
- `createRequestTracingMiddleware()` for Middleware System v2
|
|
15
|
+
- `createTraceCarrier()` / `runWithTraceCarrier()` for jobs/workflows/events/realtime payloads
|
|
16
|
+
- span attributes and events
|
|
17
|
+
- automatic error status/exception events for failed callbacks
|
|
18
|
+
- `createMemoryTraceSpanExporter()`
|
|
19
|
+
- `createCompositeTraceSpanExporter()`
|
|
20
|
+
- `createTraceMetricsExporter()`
|
|
21
|
+
- `getTraceLogFields()` for structured logging correlation
|
|
22
|
+
- compiled npm runtime `observability.mjs`
|
|
23
|
+
|
|
24
|
+
## Public API additions
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
createTracer
|
|
28
|
+
currentTraceContext
|
|
29
|
+
runWithTraceContext
|
|
30
|
+
createTraceCarrier
|
|
31
|
+
extractTraceCarrier
|
|
32
|
+
runWithTraceCarrier
|
|
33
|
+
injectTraceHeaders
|
|
34
|
+
extractTraceHeaders
|
|
35
|
+
formatTraceparent
|
|
36
|
+
parseTraceparent
|
|
37
|
+
createRequestTracingMiddleware
|
|
38
|
+
createMemoryTraceSpanExporter
|
|
39
|
+
createCompositeTraceSpanExporter
|
|
40
|
+
createTraceMetricsExporter
|
|
41
|
+
getTraceLogFields
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
New public types include:
|
|
45
|
+
|
|
46
|
+
```text
|
|
47
|
+
TraceContext
|
|
48
|
+
TraceCarrier
|
|
49
|
+
TraceSpan
|
|
50
|
+
TraceSpanRecord
|
|
51
|
+
TraceSpanEvent
|
|
52
|
+
TraceSpanExporter
|
|
53
|
+
TraceSpanKind
|
|
54
|
+
TraceSpanStatus
|
|
55
|
+
TraceAttributes
|
|
56
|
+
Tracer
|
|
57
|
+
TracerOptions
|
|
58
|
+
StartTraceSpanOptions
|
|
59
|
+
RequestTracingOptions
|
|
60
|
+
TraceIdFactory
|
|
61
|
+
TraceMetricsOptions
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Trace model
|
|
65
|
+
|
|
66
|
+
A root operation owns a `traceId` and `correlationId`. Every nested span receives its own `spanId` while inheriting the trace and correlation identity.
|
|
67
|
+
|
|
68
|
+
```text
|
|
69
|
+
traceId
|
|
70
|
+
|
|
|
71
|
+
+-- HTTP span
|
|
72
|
+
|
|
|
73
|
+
+-- database span
|
|
74
|
+
+-- cache span
|
|
75
|
+
+-- producer span
|
|
76
|
+
|
|
|
77
|
+
+-- consumer span
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Normal awaited asynchronous calls retain the active context through `AsyncLocalStorage`.
|
|
81
|
+
|
|
82
|
+
## HTTP propagation
|
|
83
|
+
|
|
84
|
+
The request tracing middleware understands W3C version `00` `traceparent` headers and `x-correlation-id`.
|
|
85
|
+
|
|
86
|
+
Responses include the active span's `traceparent` plus the correlation ID unless `includeResponseHeaders: false` is configured.
|
|
87
|
+
|
|
88
|
+
## Background propagation
|
|
89
|
+
|
|
90
|
+
`0.2.17` intentionally does not add mandatory tracing fields to job, workflow, outbox or realtime schemas.
|
|
91
|
+
|
|
92
|
+
Applications can explicitly transport:
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
const trace =
|
|
96
|
+
createTraceCarrier();
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
and restore it with:
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
runWithTraceCarrier(
|
|
103
|
+
payload.trace,
|
|
104
|
+
handler
|
|
105
|
+
);
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
This keeps tracing provider-neutral and avoids breaking existing persisted data.
|
|
109
|
+
|
|
110
|
+
## Trace metrics
|
|
111
|
+
|
|
112
|
+
`createTraceMetricsExporter()` integrates completed spans with the existing metrics registry.
|
|
113
|
+
|
|
114
|
+
Default metrics:
|
|
115
|
+
|
|
116
|
+
```text
|
|
117
|
+
bcp_trace_spans_total
|
|
118
|
+
bcp_trace_span_duration_seconds
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Default labels:
|
|
122
|
+
|
|
123
|
+
```text
|
|
124
|
+
kind
|
|
125
|
+
status
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Span-name labels remain opt-in to reduce accidental high-cardinality metrics.
|
|
129
|
+
|
|
130
|
+
## Exporter model
|
|
131
|
+
|
|
132
|
+
BCP ships an in-memory exporter for tests and a composite exporter for fan-out. Production collector/APM integration remains application-owned through `TraceSpanExporter`.
|
|
133
|
+
|
|
134
|
+
Exporter delivery failures are isolated from business execution.
|
|
135
|
+
|
|
136
|
+
## Packaging
|
|
137
|
+
|
|
138
|
+
Prepared npm packages now compile `bcp/observability` into:
|
|
139
|
+
|
|
140
|
+
```text
|
|
141
|
+
packages/client/src/observability.mjs
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
The package smoke test imports this compiled runtime and exercises trace creation, context propagation and trace metrics.
|
|
145
|
+
|
|
146
|
+
## Compatibility
|
|
147
|
+
|
|
148
|
+
- Previous baseline: `0.2.16`
|
|
149
|
+
- Intentional breaking changes: **none**
|
|
150
|
+
- Existing Observability v2 metrics/health APIs remain supported.
|
|
151
|
+
- Existing `bcp/observability` import path remains unchanged.
|
|
152
|
+
|
|
153
|
+
## Validation
|
|
154
|
+
|
|
155
|
+
The release candidate must pass:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
npm run typecheck
|
|
159
|
+
npm run test:unit
|
|
160
|
+
npm run test:integration
|
|
161
|
+
npm run test:e2e
|
|
162
|
+
npm run test:package
|
|
163
|
+
npm run rc:check
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Do not tag or publish until the exact release commit passes the full validation sequence.
|