@geekmidas/telescope 10.0.0-alpha.16 → 10.0.0-alpha.160
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 +37 -14
- package/dist/{MetricsAggregator-BxBLQUPj.d.cts → MetricsAggregator-BJdIvfEv.d.mts} +2 -2
- package/dist/{MetricsAggregator-BxBLQUPj.d.cts.map → MetricsAggregator-BJdIvfEv.d.mts.map} +1 -1
- package/dist/{MetricsAggregator-j9wmZ0K_.d.mts → MetricsAggregator-CnC3oT5q.d.cts} +2 -2
- package/dist/{MetricsAggregator-j9wmZ0K_.d.mts.map → MetricsAggregator-CnC3oT5q.d.cts.map} +1 -1
- package/dist/{Telescope-BcrWTaar.d.mts → Telescope-BVfDvVvY.d.mts} +3 -3
- package/dist/{Telescope-BcrWTaar.d.mts.map → Telescope-BVfDvVvY.d.mts.map} +1 -1
- package/dist/{Telescope-DnCMZT7V.d.cts → Telescope-DeqSHfuB.d.cts} +3 -3
- package/dist/{Telescope-DnCMZT7V.d.cts.map → Telescope-DeqSHfuB.d.cts.map} +1 -1
- package/dist/Telescope.d.cts +1 -1
- package/dist/Telescope.d.mts +1 -1
- package/dist/adapters/lambda.d.cts +1 -1
- package/dist/adapters/lambda.d.mts +1 -1
- package/dist/adapters/middy.d.cts +1 -1
- package/dist/adapters/middy.d.mts +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.mts +3 -3
- package/dist/instrumentation/core.cjs +28 -0
- package/dist/instrumentation/core.cjs.map +1 -1
- package/dist/instrumentation/core.d.cts +17 -0
- package/dist/instrumentation/core.d.cts.map +1 -1
- package/dist/instrumentation/core.d.mts +17 -0
- package/dist/instrumentation/core.d.mts.map +1 -1
- package/dist/instrumentation/core.mjs +27 -1
- package/dist/instrumentation/core.mjs.map +1 -1
- package/dist/instrumentation/hono.cjs +67 -8
- package/dist/instrumentation/hono.cjs.map +1 -1
- package/dist/instrumentation/hono.d.cts +19 -0
- package/dist/instrumentation/hono.d.cts.map +1 -1
- package/dist/instrumentation/hono.d.mts +19 -0
- package/dist/instrumentation/hono.d.mts.map +1 -1
- package/dist/instrumentation/hono.mjs +68 -9
- package/dist/instrumentation/hono.mjs.map +1 -1
- package/dist/instrumentation/http.cjs +29 -4
- package/dist/instrumentation/http.cjs.map +1 -1
- package/dist/instrumentation/http.d.cts +18 -2
- package/dist/instrumentation/http.d.cts.map +1 -1
- package/dist/instrumentation/http.d.mts +18 -2
- package/dist/instrumentation/http.d.mts.map +1 -1
- package/dist/instrumentation/http.mjs +30 -6
- package/dist/instrumentation/http.mjs.map +1 -1
- package/dist/instrumentation/index.cjs +14 -0
- package/dist/instrumentation/index.d.cts +7 -4
- package/dist/instrumentation/index.d.mts +7 -4
- package/dist/instrumentation/index.mjs +7 -4
- package/dist/instrumentation/metrics.cjs +87 -0
- package/dist/instrumentation/metrics.cjs.map +1 -0
- package/dist/instrumentation/metrics.d.cts +28 -0
- package/dist/instrumentation/metrics.d.cts.map +1 -0
- package/dist/instrumentation/metrics.d.mts +28 -0
- package/dist/instrumentation/metrics.d.mts.map +1 -0
- package/dist/instrumentation/metrics.mjs +85 -0
- package/dist/instrumentation/metrics.mjs.map +1 -0
- package/dist/instrumentation/middleware.cjs +29 -3
- package/dist/instrumentation/middleware.cjs.map +1 -1
- package/dist/instrumentation/middleware.d.cts +13 -0
- package/dist/instrumentation/middleware.d.cts.map +1 -1
- package/dist/instrumentation/middleware.d.mts +13 -0
- package/dist/instrumentation/middleware.d.mts.map +1 -1
- package/dist/instrumentation/middleware.mjs +30 -4
- package/dist/instrumentation/middleware.mjs.map +1 -1
- package/dist/instrumentation/otel.cjs +18 -1
- package/dist/instrumentation/otel.cjs.map +1 -1
- package/dist/instrumentation/otel.d.cts.map +1 -1
- package/dist/instrumentation/otel.d.mts.map +1 -1
- package/dist/instrumentation/otel.mjs +18 -1
- package/dist/instrumentation/otel.mjs.map +1 -1
- package/dist/instrumentation/sampler.cjs +54 -0
- package/dist/instrumentation/sampler.cjs.map +1 -0
- package/dist/instrumentation/sampler.d.cts +38 -0
- package/dist/instrumentation/sampler.d.cts.map +1 -0
- package/dist/instrumentation/sampler.d.mts +38 -0
- package/dist/instrumentation/sampler.d.mts.map +1 -0
- package/dist/instrumentation/sampler.mjs +52 -0
- package/dist/instrumentation/sampler.mjs.map +1 -0
- package/dist/instrumentation/setup.cjs +102 -21
- package/dist/instrumentation/setup.cjs.map +1 -1
- package/dist/instrumentation/setup.d.cts +72 -3
- package/dist/instrumentation/setup.d.cts.map +1 -1
- package/dist/instrumentation/setup.d.mts +72 -3
- package/dist/instrumentation/setup.d.mts.map +1 -1
- package/dist/instrumentation/setup.mjs +104 -24
- package/dist/instrumentation/setup.mjs.map +1 -1
- package/dist/instrumentation/trust.cjs +116 -0
- package/dist/instrumentation/trust.cjs.map +1 -0
- package/dist/instrumentation/trust.d.cts +59 -0
- package/dist/instrumentation/trust.d.cts.map +1 -0
- package/dist/instrumentation/trust.d.mts +59 -0
- package/dist/instrumentation/trust.d.mts.map +1 -0
- package/dist/instrumentation/trust.mjs +113 -0
- package/dist/instrumentation/trust.mjs.map +1 -0
- package/dist/logger/console.d.cts +1 -1
- package/dist/logger/console.d.mts +1 -1
- package/dist/logger/pino.d.cts +1 -1
- package/dist/logger/pino.d.mts +1 -1
- package/dist/metrics/MetricsAggregator.d.cts +1 -1
- package/dist/metrics/MetricsAggregator.d.mts +1 -1
- package/dist/metrics/index.d.cts +1 -1
- package/dist/metrics/index.d.mts +1 -1
- package/dist/otlp/index.d.cts +1 -1
- package/dist/otlp/index.d.mts +1 -1
- package/dist/otlp/receiver.d.cts +2 -2
- package/dist/otlp/receiver.d.mts +2 -2
- package/dist/otlp/transformer.d.cts +1 -1
- package/dist/otlp/transformer.d.mts +1 -1
- package/dist/redact.d.cts +1 -1
- package/dist/redact.d.mts +1 -1
- package/dist/server/hono.cjs +14 -24
- package/dist/server/hono.cjs.map +1 -1
- package/dist/server/hono.d.cts +11 -3
- package/dist/server/hono.d.cts.map +1 -1
- package/dist/server/hono.d.mts +11 -3
- package/dist/server/hono.d.mts.map +1 -1
- package/dist/server/hono.mjs +14 -24
- package/dist/server/hono.mjs.map +1 -1
- package/dist/storage/kysely.d.cts +1 -1
- package/dist/storage/kysely.d.mts +1 -1
- package/dist/storage/memory.d.cts +1 -1
- package/dist/storage/memory.d.mts +1 -1
- package/dist/{transformer-DlESim6Q.d.cts → transformer-BtqjAs0b.d.cts} +2 -2
- package/dist/{transformer-BBBXCjHP.d.mts.map → transformer-BtqjAs0b.d.cts.map} +1 -1
- package/dist/{transformer-BBBXCjHP.d.mts → transformer-DI6t8-YA.d.mts} +2 -2
- package/dist/{transformer-DlESim6Q.d.cts.map → transformer-DI6t8-YA.d.mts.map} +1 -1
- package/dist/{types-a9Vistj1.d.cts → types-BVujq4zd.d.cts} +2 -2
- package/dist/{types-a9Vistj1.d.cts.map → types-BVujq4zd.d.cts.map} +1 -1
- package/dist/{types-a9Vistj1.d.mts → types-BVujq4zd.d.mts} +2 -2
- package/dist/{types-a9Vistj1.d.mts.map → types-BVujq4zd.d.mts.map} +1 -1
- package/dist/types.d.cts +1 -1
- package/dist/types.d.mts +1 -1
- package/package.json +19 -7
- package/dist/ui-assets.cjs +0 -32
- package/dist/ui-assets.cjs.map +0 -1
- package/dist/ui-assets.d.cts +0 -11
- package/dist/ui-assets.d.cts.map +0 -1
- package/dist/ui-assets.d.mts +0 -11
- package/dist/ui-assets.d.mts.map +0 -1
- package/dist/ui-assets.mjs +0 -29
- package/dist/ui-assets.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @geekmidas/telescope
|
|
2
2
|
|
|
3
|
-
Laravel Telescope-style debugging and monitoring for web applications. Capture
|
|
3
|
+
Laravel Telescope-style debugging and monitoring for web applications. Capture HTTP requests, exceptions and logs, and read them back as a JSON API with a WebSocket feed. Headless: there is no dashboard — build whatever UI you want on the JSON.
|
|
4
4
|
|
|
5
5
|
**Framework-agnostic core** with adapters for Hono, AWS Lambda, and more.
|
|
6
6
|
|
|
@@ -17,7 +17,7 @@ pnpm add @geekmidas/telescope
|
|
|
17
17
|
```typescript
|
|
18
18
|
import { Hono } from 'hono';
|
|
19
19
|
import { Telescope, InMemoryStorage } from '@geekmidas/telescope';
|
|
20
|
-
import {
|
|
20
|
+
import { createApi, createMiddleware } from '@geekmidas/telescope/server/hono';
|
|
21
21
|
|
|
22
22
|
const telescope = new Telescope({
|
|
23
23
|
storage: new InMemoryStorage(),
|
|
@@ -28,8 +28,8 @@ const app = new Hono();
|
|
|
28
28
|
// Add middleware to capture requests
|
|
29
29
|
app.use('*', createMiddleware(telescope));
|
|
30
30
|
|
|
31
|
-
// Mount the
|
|
32
|
-
app.route('/__telescope',
|
|
31
|
+
// Mount the JSON API
|
|
32
|
+
app.route('/__telescope', createApi(telescope));
|
|
33
33
|
|
|
34
34
|
// Your routes
|
|
35
35
|
app.get('/users', (c) => c.json({ users: [] }));
|
|
@@ -37,7 +37,7 @@ app.get('/users', (c) => c.json({ users: [] }));
|
|
|
37
37
|
export default app;
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
Read the data at `http://localhost:3000/__telescope/api/requests` (and `/api/exceptions`, `/api/logs`, …).
|
|
41
41
|
|
|
42
42
|
### Framework-Agnostic Core
|
|
43
43
|
|
|
@@ -80,7 +80,7 @@ try {
|
|
|
80
80
|
- **Request Recording**: Capture HTTP requests with headers, body, query params, and response
|
|
81
81
|
- **Exception Tracking**: Record exceptions with stack traces and source context
|
|
82
82
|
- **Log Aggregation**: Collect application logs with context
|
|
83
|
-
- **Real-time Updates**: WebSocket
|
|
83
|
+
- **Real-time Updates**: a WebSocket feed of new entries
|
|
84
84
|
- **Storage Agnostic**: Use in-memory for dev, database for production
|
|
85
85
|
- **Hono Integration**: First-class middleware and route mounting
|
|
86
86
|
- **Lambda Integration**: Wrapper and Middy middleware for AWS Lambda with auto-flush
|
|
@@ -95,7 +95,7 @@ const telescope = new Telescope({
|
|
|
95
95
|
// Optional: Enable/disable telescope (default: true)
|
|
96
96
|
enabled: true,
|
|
97
97
|
|
|
98
|
-
// Optional:
|
|
98
|
+
// Optional: where the JSON API is mounted (default: '/__telescope')
|
|
99
99
|
path: '/__telescope',
|
|
100
100
|
|
|
101
101
|
// Optional: Record request/response bodies (default: true)
|
|
@@ -344,7 +344,7 @@ telescope.destroy();
|
|
|
344
344
|
Import from `@geekmidas/telescope/server/hono`:
|
|
345
345
|
|
|
346
346
|
```typescript
|
|
347
|
-
import {
|
|
347
|
+
import { createApi, createMiddleware, setupWebSocket, getRequestId } from '@geekmidas/telescope/server/hono';
|
|
348
348
|
```
|
|
349
349
|
|
|
350
350
|
#### `createMiddleware(telescope)`
|
|
@@ -355,12 +355,12 @@ Returns Hono middleware that captures requests and responses.
|
|
|
355
355
|
app.use('*', createMiddleware(telescope));
|
|
356
356
|
```
|
|
357
357
|
|
|
358
|
-
#### `
|
|
358
|
+
#### `createApi(telescope)`
|
|
359
359
|
|
|
360
|
-
Returns a Hono app
|
|
360
|
+
Returns a Hono app serving the JSON API under `/api`.
|
|
361
361
|
|
|
362
362
|
```typescript
|
|
363
|
-
app.route('/__telescope',
|
|
363
|
+
app.route('/__telescope', createApi(telescope));
|
|
364
364
|
```
|
|
365
365
|
|
|
366
366
|
#### `setupWebSocket(app, telescope, upgradeWebSocket)`
|
|
@@ -371,7 +371,7 @@ Set up WebSocket routes for real-time updates.
|
|
|
371
371
|
import { createNodeWebSocket } from '@hono/node-ws';
|
|
372
372
|
|
|
373
373
|
const { upgradeWebSocket } = createNodeWebSocket({ app });
|
|
374
|
-
setupWebSocket(
|
|
374
|
+
setupWebSocket(createApi(telescope), telescope, upgradeWebSocket);
|
|
375
375
|
```
|
|
376
376
|
|
|
377
377
|
#### `getRequestId(c)`
|
|
@@ -542,9 +542,9 @@ const requestLogger = logger.withRequestId('req-abc123');
|
|
|
542
542
|
requestLogger.info('Processing request');
|
|
543
543
|
```
|
|
544
544
|
|
|
545
|
-
##
|
|
545
|
+
## JSON API
|
|
546
546
|
|
|
547
|
-
|
|
547
|
+
`createApi` serves a read API at the path it is mounted on:
|
|
548
548
|
|
|
549
549
|
| Endpoint | Description |
|
|
550
550
|
|----------|-------------|
|
|
@@ -714,6 +714,29 @@ export default {
|
|
|
714
714
|
: new InMemoryStorage();
|
|
715
715
|
```
|
|
716
716
|
|
|
717
|
+
## Optional peers
|
|
718
|
+
|
|
719
|
+
<!-- optional-peers:start -->
|
|
720
|
+
|
|
721
|
+
<!-- Generated by `node scripts/check-optional-peers.mjs --write-docs`; CI fails when it drifts. -->
|
|
722
|
+
|
|
723
|
+
Each of these entries imports an optional peer when it loads, so using it means installing that peer:
|
|
724
|
+
|
|
725
|
+
| Entry | Install |
|
|
726
|
+
| --- | --- |
|
|
727
|
+
| `@geekmidas/telescope/core` | `@opentelemetry/api`, `@opentelemetry/sdk-trace-base` |
|
|
728
|
+
| `@geekmidas/telescope/hono` | `hono` |
|
|
729
|
+
| `@geekmidas/telescope/instrumentation` | `@opentelemetry/api`, `@opentelemetry/auto-instrumentations-node`, `@opentelemetry/exporter-logs-otlp-http`, `@opentelemetry/exporter-metrics-otlp-http`, `@opentelemetry/exporter-trace-otlp-http`, `@opentelemetry/instrumentation-pino`, `@opentelemetry/resources`, `@opentelemetry/sdk-logs`, `@opentelemetry/sdk-metrics`, `@opentelemetry/sdk-node`, `@opentelemetry/sdk-trace-base`, `@opentelemetry/sdk-trace-node`, `@opentelemetry/semantic-conventions`, `hono` |
|
|
730
|
+
| `@geekmidas/telescope/instrumentation/hono` | `@opentelemetry/api`, `hono` |
|
|
731
|
+
| `@geekmidas/telescope/lambda` | `@opentelemetry/api`, `@opentelemetry/sdk-trace-base` |
|
|
732
|
+
| `@geekmidas/telescope/logger/pino` | `pino-abstract-transport` |
|
|
733
|
+
| `@geekmidas/telescope/otlp/hono` | `hono` |
|
|
734
|
+
| `@geekmidas/telescope/server/hono` | `hono` |
|
|
735
|
+
|
|
736
|
+
No other entry imports an optional peer when it loads. `@middy/core`, `@types/aws-lambda`, `kysely` are loaded only when a feature that uses one runs (an `import()` inside a `try`, whose error names the package to install), or named only in types.
|
|
737
|
+
|
|
738
|
+
<!-- optional-peers:end -->
|
|
739
|
+
|
|
717
740
|
## License
|
|
718
741
|
|
|
719
742
|
MIT
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { f as RequestEntry, g as StatusDistribution, n as EndpointDetails, p as RequestMetrics, r as EndpointMetrics, s as MetricsQueryOptions } from "./types-
|
|
1
|
+
import { f as RequestEntry, g as StatusDistribution, n as EndpointDetails, p as RequestMetrics, r as EndpointMetrics, s as MetricsQueryOptions } from "./types-BVujq4zd.mjs";
|
|
2
2
|
//#region src/metrics/MetricsAggregator.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* Configuration for MetricsAggregator
|
|
@@ -55,4 +55,4 @@ declare class MetricsAggregator {
|
|
|
55
55
|
}
|
|
56
56
|
//#endregion
|
|
57
57
|
export { MetricsAggregatorOptions as n, MetricsAggregator as t };
|
|
58
|
-
//# sourceMappingURL=MetricsAggregator-
|
|
58
|
+
//# sourceMappingURL=MetricsAggregator-BJdIvfEv.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MetricsAggregator-
|
|
1
|
+
{"version":3,"file":"MetricsAggregator-BJdIvfEv.d.mts","names":[],"sources":["../src/metrics/MetricsAggregator.ts"],"mappings":";;;;;UAgBiB;;EAEhB;;EAEA;;EAEA;;cAwBY;UACJ;UACA;UACA;UAEA;EAGR,YAAY,UAAS;;;;EAOrB,OAAO,OAAO;;;;EAiBd,WAAW,UAAS,sBAA2B;;;;EAwD/C,mBAAmB,UAAS,sBAA2B;;;;EAiCvD,sBAAsB,UAAS,sBAA2B;;;;EAwB1D,mBACC,gBACA,cACA,UAAS,sBACP;;;;EAyEH;UAUQ;UAMA;UAuCA;UAuCA;UAsDA;UAmBA;UAgBA;UAMA;UAcA;UAqDA;UAiBA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { f as RequestEntry, g as StatusDistribution, n as EndpointDetails, p as RequestMetrics, r as EndpointMetrics, s as MetricsQueryOptions } from "./types-
|
|
1
|
+
import { f as RequestEntry, g as StatusDistribution, n as EndpointDetails, p as RequestMetrics, r as EndpointMetrics, s as MetricsQueryOptions } from "./types-BVujq4zd.cjs";
|
|
2
2
|
//#region src/metrics/MetricsAggregator.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* Configuration for MetricsAggregator
|
|
@@ -55,4 +55,4 @@ declare class MetricsAggregator {
|
|
|
55
55
|
}
|
|
56
56
|
//#endregion
|
|
57
57
|
export { MetricsAggregatorOptions as n, MetricsAggregator as t };
|
|
58
|
-
//# sourceMappingURL=MetricsAggregator-
|
|
58
|
+
//# sourceMappingURL=MetricsAggregator-CnC3oT5q.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MetricsAggregator-
|
|
1
|
+
{"version":3,"file":"MetricsAggregator-CnC3oT5q.d.cts","names":[],"sources":["../src/metrics/MetricsAggregator.ts"],"mappings":";;;;;UAgBiB;;EAEhB;;EAEA;;EAEA;;cAwBY;UACJ;UACA;UACA;UAEA;EAGR,YAAY,UAAS;;;;EAOrB,OAAO,OAAO;;;;EAiBd,WAAW,UAAS,sBAA2B;;;;EAwD/C,mBAAmB,UAAS,sBAA2B;;;;EAiCvD,sBAAsB,UAAS,sBAA2B;;;;EAwB1D,mBACC,gBACA,cACA,UAAS,sBACP;;;;EAyEH;UAUQ;UAMA;UAuCA;UAuCA;UAsDA;UAmBA;UAgBA;UAMA;UAcA;UAqDA;UAiBA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { _ as TelescopeEvent, a as LogEntry, c as MetricsSnapshot, f as RequestEntry, g as StatusDistribution, i as ExceptionEntry, n as EndpointDetails, p as RequestMetrics, r as EndpointMetrics, s as MetricsQueryOptions, u as QueryOptions, x as TelescopeStats, y as TelescopeOptions } from "./types-
|
|
2
|
-
import { n as MetricsAggregatorOptions } from "./MetricsAggregator-
|
|
1
|
+
import { _ as TelescopeEvent, a as LogEntry, c as MetricsSnapshot, f as RequestEntry, g as StatusDistribution, i as ExceptionEntry, n as EndpointDetails, p as RequestMetrics, r as EndpointMetrics, s as MetricsQueryOptions, u as QueryOptions, x as TelescopeStats, y as TelescopeOptions } from "./types-BVujq4zd.mjs";
|
|
2
|
+
import { n as MetricsAggregatorOptions } from "./MetricsAggregator-BJdIvfEv.mjs";
|
|
3
3
|
//#region src/Telescope.d.ts
|
|
4
4
|
/**
|
|
5
5
|
* Framework-agnostic Telescope class for debugging and monitoring applications.
|
|
@@ -166,4 +166,4 @@ declare class Telescope {
|
|
|
166
166
|
}
|
|
167
167
|
//#endregion
|
|
168
168
|
export { Telescope as t };
|
|
169
|
-
//# sourceMappingURL=Telescope-
|
|
169
|
+
//# sourceMappingURL=Telescope-BVfDvVvY.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Telescope-
|
|
1
|
+
{"version":3,"file":"Telescope-BVfDvVvY.d.mts","names":["_$__types0.TelescopeStats"],"sources":["../src/Telescope.ts"],"mappings":";;;;;;;cA4Ba;UACJ;UACA;UACA;UACA;UACA;UACA;UACA;EAER,YACC,SAAS;IAAqB,UAAU;;;;;EAuBnC,cACL,OAAO,KAAK,oCACV;;;;UA+BW;;;;;;;;;;;EAsBR,IACL,SAAS;IACR;IACA;IACA,UAAU;IACV;OAEC;;;;EAsBG,MACL,iBACA,UAAU,yBACV,qBACE;;;;EAOG,KACL,iBACA,UAAU,yBACV,qBACE;;;;EAOG,KACL,iBACA,UAAU,yBACV,qBACE;;;;EAOG,MACL,iBACA,UAAU,yBACV,qBACE;UAIW;;;;EA4BR,UAAU,OAAO,OAAO,qBAAqB;;;;EA8B7C,YAAY,UAAU,eAAe,QAAQ;;;;EAO7C,WAAW,aAAa,QAAQ;;;;EAOhC,cAAc,UAAU,eAAe,QAAQ;;;;EAO/C,aAAa,aAAa,QAAQ;;;;EAOlC,QAAQ,UAAU,eAAe,QAAQ;;;;EAOzC,YAAQ,QAPyBA;;;;EAkBvC,WAAW,UAAU,sBAAsB;;;;EAO3C,mBAAmB,UAAU,sBAAsB;;;;EAOnD,mBACC,gBACA,cACA,UAAU,sBACR;;;;EAOH,sBAAsB,UAAU,sBAAsB;;;;EAOtD;;;;EAOA,sBAAsB;;;;;;;EAuBtB,sBAAsB;;;;EAoBtB;;;;EAcA,YAAY,IAAI;;;;EAYhB,eAAe,IAAI;;;;EAOnB,UAAU,OAAO;;;;EAkBX,MAAM,WAAW,OAAO;;;;EAO9B;;;;MAeI;;;;MAOA;;;;MAOA;;;;MAOA;;;;EAOJ,aAAa;UAqBL;UAeA;UA2CM"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { _ as TelescopeEvent, a as LogEntry, c as MetricsSnapshot, f as RequestEntry, g as StatusDistribution, i as ExceptionEntry, n as EndpointDetails, p as RequestMetrics, r as EndpointMetrics, s as MetricsQueryOptions, u as QueryOptions, x as TelescopeStats, y as TelescopeOptions } from "./types-
|
|
2
|
-
import { n as MetricsAggregatorOptions } from "./MetricsAggregator-
|
|
1
|
+
import { _ as TelescopeEvent, a as LogEntry, c as MetricsSnapshot, f as RequestEntry, g as StatusDistribution, i as ExceptionEntry, n as EndpointDetails, p as RequestMetrics, r as EndpointMetrics, s as MetricsQueryOptions, u as QueryOptions, x as TelescopeStats, y as TelescopeOptions } from "./types-BVujq4zd.cjs";
|
|
2
|
+
import { n as MetricsAggregatorOptions } from "./MetricsAggregator-CnC3oT5q.cjs";
|
|
3
3
|
//#region src/Telescope.d.ts
|
|
4
4
|
/**
|
|
5
5
|
* Framework-agnostic Telescope class for debugging and monitoring applications.
|
|
@@ -166,4 +166,4 @@ declare class Telescope {
|
|
|
166
166
|
}
|
|
167
167
|
//#endregion
|
|
168
168
|
export { Telescope as t };
|
|
169
|
-
//# sourceMappingURL=Telescope-
|
|
169
|
+
//# sourceMappingURL=Telescope-DeqSHfuB.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Telescope-
|
|
1
|
+
{"version":3,"file":"Telescope-DeqSHfuB.d.cts","names":["_$__types0.TelescopeStats"],"sources":["../src/Telescope.ts"],"mappings":";;;;;;;cA4Ba;UACJ;UACA;UACA;UACA;UACA;UACA;UACA;EAER,YACC,SAAS;IAAqB,UAAU;;;;;EAuBnC,cACL,OAAO,KAAK,oCACV;;;;UA+BW;;;;;;;;;;;EAsBR,IACL,SAAS;IACR;IACA;IACA,UAAU;IACV;OAEC;;;;EAsBG,MACL,iBACA,UAAU,yBACV,qBACE;;;;EAOG,KACL,iBACA,UAAU,yBACV,qBACE;;;;EAOG,KACL,iBACA,UAAU,yBACV,qBACE;;;;EAOG,MACL,iBACA,UAAU,yBACV,qBACE;UAIW;;;;EA4BR,UAAU,OAAO,OAAO,qBAAqB;;;;EA8B7C,YAAY,UAAU,eAAe,QAAQ;;;;EAO7C,WAAW,aAAa,QAAQ;;;;EAOhC,cAAc,UAAU,eAAe,QAAQ;;;;EAO/C,aAAa,aAAa,QAAQ;;;;EAOlC,QAAQ,UAAU,eAAe,QAAQ;;;;EAOzC,YAAQ,QAPyBA;;;;EAkBvC,WAAW,UAAU,sBAAsB;;;;EAO3C,mBAAmB,UAAU,sBAAsB;;;;EAOnD,mBACC,gBACA,cACA,UAAU,sBACR;;;;EAOH,sBAAsB,UAAU,sBAAsB;;;;EAOtD;;;;EAOA,sBAAsB;;;;;;;EAuBtB,sBAAsB;;;;EAoBtB;;;;EAcA,YAAY,IAAI;;;;EAYhB,eAAe,IAAI;;;;EAOnB,UAAU,OAAO;;;;EAkBX,MAAM,WAAW,OAAO;;;;EAO9B;;;;MAeI;;;;MAOA;;;;MAOA;;;;MAOA;;;;EAOJ,aAAa;UAqBL;UAeA;UA2CM"}
|
package/dist/Telescope.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as Telescope } from "./Telescope-
|
|
1
|
+
import { t as Telescope } from "./Telescope-DeqSHfuB.cjs";
|
|
2
2
|
export { Telescope };
|
package/dist/Telescope.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as Telescope } from "./Telescope-
|
|
1
|
+
import { t as Telescope } from "./Telescope-BVfDvVvY.mjs";
|
|
2
2
|
export { Telescope };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as Telescope } from "../Telescope-
|
|
1
|
+
import { t as Telescope } from "../Telescope-DeqSHfuB.cjs";
|
|
2
2
|
import { AdapterRequestContext, AdapterResponseContext, LambdaAdapterConfig, TelescopeAdapter } from "./types.cjs";
|
|
3
3
|
import { TelescopeMiddlewareOptions, createTelescopeHandler, telescopeMiddleware } from "./middy.cjs";
|
|
4
4
|
import { Context } from "aws-lambda";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as Telescope } from "../Telescope-
|
|
1
|
+
import { t as Telescope } from "../Telescope-BVfDvVvY.mjs";
|
|
2
2
|
import { AdapterRequestContext, AdapterResponseContext, LambdaAdapterConfig, TelescopeAdapter } from "./types.mjs";
|
|
3
3
|
import { TelescopeMiddlewareOptions, createTelescopeHandler, telescopeMiddleware } from "./middy.mjs";
|
|
4
4
|
import { Context } from "aws-lambda";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as Telescope } from "../Telescope-
|
|
1
|
+
import { t as Telescope } from "../Telescope-DeqSHfuB.cjs";
|
|
2
2
|
import { APIGatewayProxyEvent, APIGatewayProxyEventV2, Context } from "aws-lambda";
|
|
3
3
|
import { MiddlewareObj } from "@middy/core";
|
|
4
4
|
//#region src/adapters/middy.d.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as Telescope } from "../Telescope-
|
|
1
|
+
import { t as Telescope } from "../Telescope-BVfDvVvY.mjs";
|
|
2
2
|
import { APIGatewayProxyEvent, APIGatewayProxyEventV2, Context } from "aws-lambda";
|
|
3
3
|
import { MiddlewareObj } from "@middy/core";
|
|
4
4
|
//#region src/adapters/middy.d.ts
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as TimeRange, S as TelescopeStorage, _ as TelescopeEvent, a as LogEntry, d as RequestContext, f as RequestEntry, g as StatusDistribution, h as StackFrame, i as ExceptionEntry, l as NormalizedTelescopeOptions, m as SourceContext, o as MetricsBucket, p as RequestMetrics, r as EndpointMetrics, s as MetricsQueryOptions, t as EndpointBucket, u as QueryOptions, v as TelescopeEventType, w as TimeSeriesPoint, x as TelescopeStats, y as TelescopeOptions } from "./types-
|
|
2
|
-
import { n as MetricsAggregatorOptions, t as MetricsAggregator } from "./MetricsAggregator-
|
|
3
|
-
import { t as Telescope } from "./Telescope-
|
|
1
|
+
import { C as TimeRange, S as TelescopeStorage, _ as TelescopeEvent, a as LogEntry, d as RequestContext, f as RequestEntry, g as StatusDistribution, h as StackFrame, i as ExceptionEntry, l as NormalizedTelescopeOptions, m as SourceContext, o as MetricsBucket, p as RequestMetrics, r as EndpointMetrics, s as MetricsQueryOptions, t as EndpointBucket, u as QueryOptions, v as TelescopeEventType, w as TimeSeriesPoint, x as TelescopeStats, y as TelescopeOptions } from "./types-BVujq4zd.cjs";
|
|
2
|
+
import { n as MetricsAggregatorOptions, t as MetricsAggregator } from "./MetricsAggregator-CnC3oT5q.cjs";
|
|
3
|
+
import { t as Telescope } from "./Telescope-DeqSHfuB.cjs";
|
|
4
4
|
import { InMemoryStorage, InMemoryStorageOptions } from "./storage/memory.cjs";
|
|
5
5
|
export { type EndpointBucket, type EndpointMetrics, type ExceptionEntry, InMemoryStorage, type InMemoryStorageOptions, type LogEntry, MetricsAggregator, type MetricsAggregatorOptions, type MetricsBucket, type MetricsQueryOptions, type NormalizedTelescopeOptions, type QueryOptions, type RequestContext, type RequestEntry, type RequestMetrics, type SourceContext, type StackFrame, type StatusDistribution, Telescope, type TelescopeEvent, type TelescopeEventType, type TelescopeOptions, type TelescopeStats, type TelescopeStorage, type TimeRange, type TimeSeriesPoint };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as TimeRange, S as TelescopeStorage, _ as TelescopeEvent, a as LogEntry, d as RequestContext, f as RequestEntry, g as StatusDistribution, h as StackFrame, i as ExceptionEntry, l as NormalizedTelescopeOptions, m as SourceContext, o as MetricsBucket, p as RequestMetrics, r as EndpointMetrics, s as MetricsQueryOptions, t as EndpointBucket, u as QueryOptions, v as TelescopeEventType, w as TimeSeriesPoint, x as TelescopeStats, y as TelescopeOptions } from "./types-
|
|
2
|
-
import { n as MetricsAggregatorOptions, t as MetricsAggregator } from "./MetricsAggregator-
|
|
3
|
-
import { t as Telescope } from "./Telescope-
|
|
1
|
+
import { C as TimeRange, S as TelescopeStorage, _ as TelescopeEvent, a as LogEntry, d as RequestContext, f as RequestEntry, g as StatusDistribution, h as StackFrame, i as ExceptionEntry, l as NormalizedTelescopeOptions, m as SourceContext, o as MetricsBucket, p as RequestMetrics, r as EndpointMetrics, s as MetricsQueryOptions, t as EndpointBucket, u as QueryOptions, v as TelescopeEventType, w as TimeSeriesPoint, x as TelescopeStats, y as TelescopeOptions } from "./types-BVujq4zd.mjs";
|
|
2
|
+
import { n as MetricsAggregatorOptions, t as MetricsAggregator } from "./MetricsAggregator-BJdIvfEv.mjs";
|
|
3
|
+
import { t as Telescope } from "./Telescope-BVfDvVvY.mjs";
|
|
4
4
|
import { InMemoryStorage, InMemoryStorageOptions } from "./storage/memory.mjs";
|
|
5
5
|
export { type EndpointBucket, type EndpointMetrics, type ExceptionEntry, InMemoryStorage, type InMemoryStorageOptions, type LogEntry, MetricsAggregator, type MetricsAggregatorOptions, type MetricsBucket, type MetricsQueryOptions, type NormalizedTelescopeOptions, type QueryOptions, type RequestContext, type RequestEntry, type RequestMetrics, type SourceContext, type StackFrame, type StatusDistribution, Telescope, type TelescopeEvent, type TelescopeEventType, type TelescopeOptions, type TelescopeStats, type TelescopeStorage, type TimeRange, type TimeSeriesPoint };
|
|
@@ -2,9 +2,19 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
2
2
|
let _opentelemetry_api = require("@opentelemetry/api");
|
|
3
3
|
let _opentelemetry_sdk_trace_base = require("@opentelemetry/sdk-trace-base");
|
|
4
4
|
//#region src/instrumentation/core.ts
|
|
5
|
+
/** A metric flush that did not finish in time; the process carries on. */
|
|
6
|
+
var MetricFlushTimeout = class extends Error {
|
|
7
|
+
timeoutMs;
|
|
8
|
+
constructor(timeoutMs) {
|
|
9
|
+
super(`Metrics were not exported within ${timeoutMs}ms. Check that the collector is reachable, or pass flushTelemetry a longer timeout.`);
|
|
10
|
+
this.timeoutMs = timeoutMs;
|
|
11
|
+
this.name = "MetricFlushTimeout";
|
|
12
|
+
}
|
|
13
|
+
};
|
|
5
14
|
const state = {
|
|
6
15
|
spanProcessor: null,
|
|
7
16
|
logProcessor: null,
|
|
17
|
+
metricReader: null,
|
|
8
18
|
initialized: false
|
|
9
19
|
};
|
|
10
20
|
/**
|
|
@@ -44,6 +54,12 @@ function setGlobalLogProcessor(processor) {
|
|
|
44
54
|
state.logProcessor = processor;
|
|
45
55
|
}
|
|
46
56
|
/**
|
|
57
|
+
* Set the global metric reader for flush operations
|
|
58
|
+
*/
|
|
59
|
+
function setGlobalMetricReader(reader) {
|
|
60
|
+
state.metricReader = reader;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
47
63
|
* Check if telemetry is initialized
|
|
48
64
|
*/
|
|
49
65
|
function isTelemetryInitialized() {
|
|
@@ -75,6 +91,12 @@ async function flushTelemetry(timeoutMs = 3e4) {
|
|
|
75
91
|
if (state.logProcessor && typeof state.logProcessor.forceFlush === "function") promises.push(Promise.race([state.logProcessor.forceFlush(), new Promise((_, reject) => setTimeout(() => reject(/* @__PURE__ */ new Error("Log flush timeout")), timeoutMs))]).catch((error) => {
|
|
76
92
|
if (_opentelemetry_api.diag.debug) _opentelemetry_api.diag.debug(`Log flush error: ${error.message}`);
|
|
77
93
|
}));
|
|
94
|
+
if (state.metricReader) {
|
|
95
|
+
const reader = state.metricReader;
|
|
96
|
+
promises.push(Promise.race([reader.forceFlush(), new Promise((_, reject) => setTimeout(() => reject(new MetricFlushTimeout(timeoutMs)), timeoutMs))]).catch((error) => {
|
|
97
|
+
if (_opentelemetry_api.diag.debug) _opentelemetry_api.diag.debug(`Metric flush error: ${error.message}`);
|
|
98
|
+
}));
|
|
99
|
+
}
|
|
78
100
|
await Promise.all(promises);
|
|
79
101
|
}
|
|
80
102
|
/**
|
|
@@ -90,6 +112,10 @@ async function shutdownTelemetry() {
|
|
|
90
112
|
promises.push(state.logProcessor.shutdown());
|
|
91
113
|
state.logProcessor = null;
|
|
92
114
|
}
|
|
115
|
+
if (state.metricReader) {
|
|
116
|
+
promises.push(state.metricReader.shutdown());
|
|
117
|
+
state.metricReader = null;
|
|
118
|
+
}
|
|
93
119
|
state.initialized = false;
|
|
94
120
|
await Promise.all(promises);
|
|
95
121
|
}
|
|
@@ -134,6 +160,7 @@ var NoopSpanProcessor = class {
|
|
|
134
160
|
}
|
|
135
161
|
};
|
|
136
162
|
//#endregion
|
|
163
|
+
exports.MetricFlushTimeout = MetricFlushTimeout;
|
|
137
164
|
exports.NoopSpanProcessor = NoopSpanProcessor;
|
|
138
165
|
exports.createSpanProcessor = createSpanProcessor;
|
|
139
166
|
exports.enableTelemetryDebug = enableTelemetryDebug;
|
|
@@ -141,6 +168,7 @@ exports.flushTelemetry = flushTelemetry;
|
|
|
141
168
|
exports.getRecommendedStrategy = getRecommendedStrategy;
|
|
142
169
|
exports.isTelemetryInitialized = isTelemetryInitialized;
|
|
143
170
|
exports.setGlobalLogProcessor = setGlobalLogProcessor;
|
|
171
|
+
exports.setGlobalMetricReader = setGlobalMetricReader;
|
|
144
172
|
exports.setGlobalSpanProcessor = setGlobalSpanProcessor;
|
|
145
173
|
exports.shutdownTelemetry = shutdownTelemetry;
|
|
146
174
|
exports.withTelemetryFlush = withTelemetryFlush;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.cjs","names":["SimpleSpanProcessor","BatchSpanProcessor","diag","DiagConsoleLogger","DiagLogLevel"],"sources":["../../src/instrumentation/core.ts"],"sourcesContent":["import { DiagConsoleLogger, DiagLogLevel, diag } from '@opentelemetry/api';\nimport {\n\tBatchSpanProcessor,\n\ttype ReadableSpan,\n\tSimpleSpanProcessor,\n\ttype Span,\n\ttype SpanExporter,\n\ttype SpanProcessor,\n} from '@opentelemetry/sdk-trace-base';\nimport type {\n\tSpanProcessorOptions,\n\tSpanProcessorStrategy,\n} from '../adapters/types';\n\n/**\n * Global telemetry state for flush operations\n */\ninterface TelemetryState {\n\tspanProcessor: SpanProcessor | null;\n\tlogProcessor: unknown | null;\n\tinitialized: boolean;\n}\n\nconst state: TelemetryState = {\n\tspanProcessor: null,\n\tlogProcessor: null,\n\tinitialized: false,\n};\n\n/**\n * Create a span processor based on the strategy\n */\nexport function createSpanProcessor(\n\texporter: SpanExporter,\n\toptions: SpanProcessorOptions,\n): SpanProcessor {\n\tconst { strategy, ...config } = options;\n\n\tif (strategy === 'simple') {\n\t\treturn new SimpleSpanProcessor(exporter);\n\t}\n\n\treturn new BatchSpanProcessor(exporter, {\n\t\tmaxQueueSize: config.maxQueueSize ?? 2048,\n\t\tscheduledDelayMillis: config.scheduledDelayMillis ?? 5000,\n\t\texportTimeoutMillis: config.exportTimeoutMillis ?? 30000,\n\t\tmaxExportBatchSize: config.maxExportBatchSize ?? 512,\n\t});\n}\n\n/**\n * Get the recommended span processor strategy for an environment\n */\nexport function getRecommendedStrategy(\n\tenvironment: 'server' | 'lambda' | 'edge' | 'custom',\n): SpanProcessorStrategy {\n\tswitch (environment) {\n\t\tcase 'lambda':\n\t\tcase 'edge':\n\t\t\t// Use simple processor for serverless - immediate export\n\t\t\treturn 'simple';\n\t\tdefault:\n\t\t\t// Use batch processor for long-running servers - efficient batching\n\t\t\treturn 'batch';\n\t}\n}\n\n/**\n * Set the global span processor for flush operations\n */\nexport function setGlobalSpanProcessor(processor: SpanProcessor): void {\n\tstate.spanProcessor = processor;\n\tstate.initialized = true;\n}\n\n/**\n * Set the global log processor for flush operations\n */\nexport function setGlobalLogProcessor(processor: unknown): void {\n\tstate.logProcessor = processor;\n}\n\n/**\n * Check if telemetry is initialized\n */\nexport function isTelemetryInitialized(): boolean {\n\treturn state.initialized;\n}\n\n/**\n * Flush all pending telemetry data.\n * This is critical for serverless environments where the process may freeze.\n *\n * @example\n * ```typescript\n * // In a Lambda handler\n * export const handler = async (event, context) => {\n * try {\n * const result = await processRequest(event);\n * return result;\n * } finally {\n * // Flush before Lambda freezes\n * await flushTelemetry();\n * }\n * };\n * ```\n */\nexport async function flushTelemetry(timeoutMs = 30000): Promise<void> {\n\tconst promises: Promise<void>[] = [];\n\n\t// Flush span processor\n\tif (state.spanProcessor) {\n\t\tpromises.push(\n\t\t\tPromise.race([\n\t\t\t\tstate.spanProcessor.forceFlush(),\n\t\t\t\tnew Promise<void>((_, reject) =>\n\t\t\t\t\tsetTimeout(() => reject(new Error('Span flush timeout')), timeoutMs),\n\t\t\t\t),\n\t\t\t]).catch((error) => {\n\t\t\t\tif (diag.debug) {\n\t\t\t\t\tdiag.debug(`Span flush error: ${error.message}`);\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\t}\n\n\t// Flush log processor if it has forceFlush method\n\tif (\n\t\tstate.logProcessor &&\n\t\ttypeof (state.logProcessor as { forceFlush?: () => Promise<void> })\n\t\t\t.forceFlush === 'function'\n\t) {\n\t\tpromises.push(\n\t\t\tPromise.race([\n\t\t\t\t(\n\t\t\t\t\tstate.logProcessor as { forceFlush: () => Promise<void> }\n\t\t\t\t).forceFlush(),\n\t\t\t\tnew Promise<void>((_, reject) =>\n\t\t\t\t\tsetTimeout(() => reject(new Error('Log flush timeout')), timeoutMs),\n\t\t\t\t),\n\t\t\t]).catch((error) => {\n\t\t\t\tif (diag.debug) {\n\t\t\t\t\tdiag.debug(`Log flush error: ${error.message}`);\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\t}\n\n\tawait Promise.all(promises);\n}\n\n/**\n * Shutdown all telemetry processors\n */\nexport async function shutdownTelemetry(): Promise<void> {\n\tconst promises: Promise<void>[] = [];\n\n\tif (state.spanProcessor) {\n\t\tpromises.push(state.spanProcessor.shutdown());\n\t\tstate.spanProcessor = null;\n\t}\n\n\tif (\n\t\tstate.logProcessor &&\n\t\ttypeof (state.logProcessor as { shutdown?: () => Promise<void> })\n\t\t\t.shutdown === 'function'\n\t) {\n\t\tpromises.push(\n\t\t\t(state.logProcessor as { shutdown: () => Promise<void> }).shutdown(),\n\t\t);\n\t\tstate.logProcessor = null;\n\t}\n\n\tstate.initialized = false;\n\tawait Promise.all(promises);\n}\n\n/**\n * Enable debug logging for telemetry\n */\nexport function enableTelemetryDebug(): void {\n\tdiag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG);\n}\n\n/**\n * Wraps a handler function to ensure telemetry is flushed before returning.\n * Useful for Lambda handlers.\n *\n * @example\n * ```typescript\n * export const handler = withTelemetryFlush(async (event, context) => {\n * // Your Lambda logic here\n * return { statusCode: 200, body: 'OK' };\n * });\n * ```\n */\nexport function withTelemetryFlush<TEvent, TResult>(\n\thandler: (event: TEvent, context: unknown) => Promise<TResult>,\n): (event: TEvent, context: unknown) => Promise<TResult> {\n\treturn async (event: TEvent, context: unknown): Promise<TResult> => {\n\t\ttry {\n\t\t\treturn await handler(event, context);\n\t\t} finally {\n\t\t\tawait flushTelemetry();\n\t\t}\n\t};\n}\n\n/**\n * Noop span processor for testing or when telemetry is disabled\n */\nexport class NoopSpanProcessor implements SpanProcessor {\n\tforceFlush(): Promise<void> {\n\t\treturn Promise.resolve();\n\t}\n\n\tonStart(_span: Span): void {\n\t\t// noop\n\t}\n\n\tonEnd(_span: ReadableSpan): void {\n\t\t// noop\n\t}\n\n\tshutdown(): Promise<void> {\n\t\treturn Promise.resolve();\n\t}\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"core.cjs","names":["SimpleSpanProcessor","BatchSpanProcessor","diag","DiagConsoleLogger","DiagLogLevel"],"sources":["../../src/instrumentation/core.ts"],"sourcesContent":["import { DiagConsoleLogger, DiagLogLevel, diag } from '@opentelemetry/api';\nimport {\n\tBatchSpanProcessor,\n\ttype ReadableSpan,\n\tSimpleSpanProcessor,\n\ttype Span,\n\ttype SpanExporter,\n\ttype SpanProcessor,\n} from '@opentelemetry/sdk-trace-base';\nimport type {\n\tSpanProcessorOptions,\n\tSpanProcessorStrategy,\n} from '../adapters/types';\n\n/**\n * Global telemetry state for flush operations\n */\ninterface TelemetryState {\n\tspanProcessor: SpanProcessor | null;\n\tlogProcessor: unknown | null;\n\tmetricReader: FlushableMetricReader | null;\n\tinitialized: boolean;\n}\n\n/**\n * What flushing needs of a metric reader — the shape, so this module loads\n * without `@opentelemetry/sdk-metrics`.\n */\nexport interface FlushableMetricReader {\n\tforceFlush(): Promise<void>;\n\tshutdown(): Promise<void>;\n}\n\n/** A metric flush that did not finish in time; the process carries on. */\nexport class MetricFlushTimeout extends Error {\n\tconstructor(readonly timeoutMs: number) {\n\t\tsuper(\n\t\t\t`Metrics were not exported within ${timeoutMs}ms. Check that the collector is reachable, or pass flushTelemetry a longer timeout.`,\n\t\t);\n\t\tthis.name = 'MetricFlushTimeout';\n\t}\n}\n\nconst state: TelemetryState = {\n\tspanProcessor: null,\n\tlogProcessor: null,\n\tmetricReader: null,\n\tinitialized: false,\n};\n\n/**\n * Create a span processor based on the strategy\n */\nexport function createSpanProcessor(\n\texporter: SpanExporter,\n\toptions: SpanProcessorOptions,\n): SpanProcessor {\n\tconst { strategy, ...config } = options;\n\n\tif (strategy === 'simple') {\n\t\treturn new SimpleSpanProcessor(exporter);\n\t}\n\n\treturn new BatchSpanProcessor(exporter, {\n\t\tmaxQueueSize: config.maxQueueSize ?? 2048,\n\t\tscheduledDelayMillis: config.scheduledDelayMillis ?? 5000,\n\t\texportTimeoutMillis: config.exportTimeoutMillis ?? 30000,\n\t\tmaxExportBatchSize: config.maxExportBatchSize ?? 512,\n\t});\n}\n\n/**\n * Get the recommended span processor strategy for an environment\n */\nexport function getRecommendedStrategy(\n\tenvironment: 'server' | 'lambda' | 'edge' | 'custom',\n): SpanProcessorStrategy {\n\tswitch (environment) {\n\t\tcase 'lambda':\n\t\tcase 'edge':\n\t\t\t// Use simple processor for serverless - immediate export\n\t\t\treturn 'simple';\n\t\tdefault:\n\t\t\t// Use batch processor for long-running servers - efficient batching\n\t\t\treturn 'batch';\n\t}\n}\n\n/**\n * Set the global span processor for flush operations\n */\nexport function setGlobalSpanProcessor(processor: SpanProcessor): void {\n\tstate.spanProcessor = processor;\n\tstate.initialized = true;\n}\n\n/**\n * Set the global log processor for flush operations\n */\nexport function setGlobalLogProcessor(processor: unknown): void {\n\tstate.logProcessor = processor;\n}\n\n/**\n * Set the global metric reader for flush operations\n */\nexport function setGlobalMetricReader(reader: FlushableMetricReader): void {\n\tstate.metricReader = reader;\n}\n\n/**\n * Check if telemetry is initialized\n */\nexport function isTelemetryInitialized(): boolean {\n\treturn state.initialized;\n}\n\n/**\n * Flush all pending telemetry data.\n * This is critical for serverless environments where the process may freeze.\n *\n * @example\n * ```typescript\n * // In a Lambda handler\n * export const handler = async (event, context) => {\n * try {\n * const result = await processRequest(event);\n * return result;\n * } finally {\n * // Flush before Lambda freezes\n * await flushTelemetry();\n * }\n * };\n * ```\n */\nexport async function flushTelemetry(timeoutMs = 30000): Promise<void> {\n\tconst promises: Promise<void>[] = [];\n\n\t// Flush span processor\n\tif (state.spanProcessor) {\n\t\tpromises.push(\n\t\t\tPromise.race([\n\t\t\t\tstate.spanProcessor.forceFlush(),\n\t\t\t\tnew Promise<void>((_, reject) =>\n\t\t\t\t\tsetTimeout(() => reject(new Error('Span flush timeout')), timeoutMs),\n\t\t\t\t),\n\t\t\t]).catch((error) => {\n\t\t\t\tif (diag.debug) {\n\t\t\t\t\tdiag.debug(`Span flush error: ${error.message}`);\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\t}\n\n\t// Flush log processor if it has forceFlush method\n\tif (\n\t\tstate.logProcessor &&\n\t\ttypeof (state.logProcessor as { forceFlush?: () => Promise<void> })\n\t\t\t.forceFlush === 'function'\n\t) {\n\t\tpromises.push(\n\t\t\tPromise.race([\n\t\t\t\t(\n\t\t\t\t\tstate.logProcessor as { forceFlush: () => Promise<void> }\n\t\t\t\t).forceFlush(),\n\t\t\t\tnew Promise<void>((_, reject) =>\n\t\t\t\t\tsetTimeout(() => reject(new Error('Log flush timeout')), timeoutMs),\n\t\t\t\t),\n\t\t\t]).catch((error) => {\n\t\t\t\tif (diag.debug) {\n\t\t\t\t\tdiag.debug(`Log flush error: ${error.message}`);\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\t}\n\n\t// Flush metrics — a Lambda freezes between invocations, so its periodic\n\t// export would otherwise wait for an invocation that may never come.\n\tif (state.metricReader) {\n\t\tconst reader = state.metricReader;\n\t\tpromises.push(\n\t\t\tPromise.race([\n\t\t\t\treader.forceFlush(),\n\t\t\t\tnew Promise<void>((_, reject) =>\n\t\t\t\t\tsetTimeout(\n\t\t\t\t\t\t() => reject(new MetricFlushTimeout(timeoutMs)),\n\t\t\t\t\t\ttimeoutMs,\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t]).catch((error) => {\n\t\t\t\tif (diag.debug) {\n\t\t\t\t\tdiag.debug(`Metric flush error: ${error.message}`);\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\t}\n\n\tawait Promise.all(promises);\n}\n\n/**\n * Shutdown all telemetry processors\n */\nexport async function shutdownTelemetry(): Promise<void> {\n\tconst promises: Promise<void>[] = [];\n\n\tif (state.spanProcessor) {\n\t\tpromises.push(state.spanProcessor.shutdown());\n\t\tstate.spanProcessor = null;\n\t}\n\n\tif (\n\t\tstate.logProcessor &&\n\t\ttypeof (state.logProcessor as { shutdown?: () => Promise<void> })\n\t\t\t.shutdown === 'function'\n\t) {\n\t\tpromises.push(\n\t\t\t(state.logProcessor as { shutdown: () => Promise<void> }).shutdown(),\n\t\t);\n\t\tstate.logProcessor = null;\n\t}\n\n\tif (state.metricReader) {\n\t\tpromises.push(state.metricReader.shutdown());\n\t\tstate.metricReader = null;\n\t}\n\n\tstate.initialized = false;\n\tawait Promise.all(promises);\n}\n\n/**\n * Enable debug logging for telemetry\n */\nexport function enableTelemetryDebug(): void {\n\tdiag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG);\n}\n\n/**\n * Wraps a handler function to ensure telemetry is flushed before returning.\n * Useful for Lambda handlers.\n *\n * @example\n * ```typescript\n * export const handler = withTelemetryFlush(async (event, context) => {\n * // Your Lambda logic here\n * return { statusCode: 200, body: 'OK' };\n * });\n * ```\n */\nexport function withTelemetryFlush<TEvent, TResult>(\n\thandler: (event: TEvent, context: unknown) => Promise<TResult>,\n): (event: TEvent, context: unknown) => Promise<TResult> {\n\treturn async (event: TEvent, context: unknown): Promise<TResult> => {\n\t\ttry {\n\t\t\treturn await handler(event, context);\n\t\t} finally {\n\t\t\tawait flushTelemetry();\n\t\t}\n\t};\n}\n\n/**\n * Noop span processor for testing or when telemetry is disabled\n */\nexport class NoopSpanProcessor implements SpanProcessor {\n\tforceFlush(): Promise<void> {\n\t\treturn Promise.resolve();\n\t}\n\n\tonStart(_span: Span): void {\n\t\t// noop\n\t}\n\n\tonEnd(_span: ReadableSpan): void {\n\t\t// noop\n\t}\n\n\tshutdown(): Promise<void> {\n\t\treturn Promise.resolve();\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
import { SpanProcessorOptions, SpanProcessorStrategy } from "../adapters/types.cjs";
|
|
2
2
|
import { ReadableSpan, Span, SpanExporter, SpanProcessor } from "@opentelemetry/sdk-trace-base";
|
|
3
3
|
//#region src/instrumentation/core.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* What flushing needs of a metric reader — the shape, so this module loads
|
|
6
|
+
* without `@opentelemetry/sdk-metrics`.
|
|
7
|
+
*/
|
|
8
|
+
export interface FlushableMetricReader {
|
|
9
|
+
forceFlush(): Promise<void>;
|
|
10
|
+
shutdown(): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
/** A metric flush that did not finish in time; the process carries on. */
|
|
13
|
+
export declare class MetricFlushTimeout extends Error {
|
|
14
|
+
readonly timeoutMs: number;
|
|
15
|
+
constructor(timeoutMs: number);
|
|
16
|
+
}
|
|
4
17
|
/**
|
|
5
18
|
* Create a span processor based on the strategy
|
|
6
19
|
*/
|
|
@@ -17,6 +30,10 @@ export declare function setGlobalSpanProcessor(processor: SpanProcessor): void;
|
|
|
17
30
|
* Set the global log processor for flush operations
|
|
18
31
|
*/
|
|
19
32
|
export declare function setGlobalLogProcessor(processor: unknown): void;
|
|
33
|
+
/**
|
|
34
|
+
* Set the global metric reader for flush operations
|
|
35
|
+
*/
|
|
36
|
+
export declare function setGlobalMetricReader(reader: FlushableMetricReader): void;
|
|
20
37
|
/**
|
|
21
38
|
* Check if telemetry is initialized
|
|
22
39
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.cts","names":[],"sources":["../../src/instrumentation/core.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"core.d.cts","names":[],"sources":["../../src/instrumentation/core.ts"],"mappings":";;;;;;;iBA4BiB;EAChB,cAAc;EACd,YAAY;;;qBAIA,2BAA2B;WAClB;EAArB,YAAqB;;;;;wBAkBN,oBACf,UAAU,cACV,SAAS,uBACP;;;;wBAkBa,uBACf,uDACE;;;;wBAea,uBAAuB,WAAW;;;;wBAQlC,sBAAsB;;;;wBAOtB,sBAAsB,QAAQ;;;;wBAO9B;;;;;;;;;;;;;;;;;;;wBAsBM,eAAe,qBAAoB;;;;wBAoEnC,qBAAqB;;;;wBA+B3B;;;;;;;;;;;;;wBAgBA,mBAAmB,QAAQ,SAC1C,UAAU,OAAO,QAAQ,qBAAqB,QAAQ,YACnD,OAAO,QAAQ,qBAAqB,QAAQ;;;;qBAanC,6BAA6B;EACzC,cAAc;EAId,QAAQ,OAAO;EAIf,MAAM,OAAO;EAIb,YAAY"}
|
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
import { SpanProcessorOptions, SpanProcessorStrategy } from "../adapters/types.mjs";
|
|
2
2
|
import { ReadableSpan, Span, SpanExporter, SpanProcessor } from "@opentelemetry/sdk-trace-base";
|
|
3
3
|
//#region src/instrumentation/core.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* What flushing needs of a metric reader — the shape, so this module loads
|
|
6
|
+
* without `@opentelemetry/sdk-metrics`.
|
|
7
|
+
*/
|
|
8
|
+
export interface FlushableMetricReader {
|
|
9
|
+
forceFlush(): Promise<void>;
|
|
10
|
+
shutdown(): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
/** A metric flush that did not finish in time; the process carries on. */
|
|
13
|
+
export declare class MetricFlushTimeout extends Error {
|
|
14
|
+
readonly timeoutMs: number;
|
|
15
|
+
constructor(timeoutMs: number);
|
|
16
|
+
}
|
|
4
17
|
/**
|
|
5
18
|
* Create a span processor based on the strategy
|
|
6
19
|
*/
|
|
@@ -17,6 +30,10 @@ export declare function setGlobalSpanProcessor(processor: SpanProcessor): void;
|
|
|
17
30
|
* Set the global log processor for flush operations
|
|
18
31
|
*/
|
|
19
32
|
export declare function setGlobalLogProcessor(processor: unknown): void;
|
|
33
|
+
/**
|
|
34
|
+
* Set the global metric reader for flush operations
|
|
35
|
+
*/
|
|
36
|
+
export declare function setGlobalMetricReader(reader: FlushableMetricReader): void;
|
|
20
37
|
/**
|
|
21
38
|
* Check if telemetry is initialized
|
|
22
39
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.mts","names":[],"sources":["../../src/instrumentation/core.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"core.d.mts","names":[],"sources":["../../src/instrumentation/core.ts"],"mappings":";;;;;;;iBA4BiB;EAChB,cAAc;EACd,YAAY;;;qBAIA,2BAA2B;WAClB;EAArB,YAAqB;;;;;wBAkBN,oBACf,UAAU,cACV,SAAS,uBACP;;;;wBAkBa,uBACf,uDACE;;;;wBAea,uBAAuB,WAAW;;;;wBAQlC,sBAAsB;;;;wBAOtB,sBAAsB,QAAQ;;;;wBAO9B;;;;;;;;;;;;;;;;;;;wBAsBM,eAAe,qBAAoB;;;;wBAoEnC,qBAAqB;;;;wBA+B3B;;;;;;;;;;;;;wBAgBA,mBAAmB,QAAQ,SAC1C,UAAU,OAAO,QAAQ,qBAAqB,QAAQ,YACnD,OAAO,QAAQ,qBAAqB,QAAQ;;;;qBAanC,6BAA6B;EACzC,cAAc;EAId,QAAQ,OAAO;EAIf,MAAM,OAAO;EAIb,YAAY"}
|
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
import { DiagConsoleLogger, DiagLogLevel, diag } from "@opentelemetry/api";
|
|
2
2
|
import { BatchSpanProcessor, SimpleSpanProcessor } from "@opentelemetry/sdk-trace-base";
|
|
3
3
|
//#region src/instrumentation/core.ts
|
|
4
|
+
/** A metric flush that did not finish in time; the process carries on. */
|
|
5
|
+
var MetricFlushTimeout = class extends Error {
|
|
6
|
+
timeoutMs;
|
|
7
|
+
constructor(timeoutMs) {
|
|
8
|
+
super(`Metrics were not exported within ${timeoutMs}ms. Check that the collector is reachable, or pass flushTelemetry a longer timeout.`);
|
|
9
|
+
this.timeoutMs = timeoutMs;
|
|
10
|
+
this.name = "MetricFlushTimeout";
|
|
11
|
+
}
|
|
12
|
+
};
|
|
4
13
|
const state = {
|
|
5
14
|
spanProcessor: null,
|
|
6
15
|
logProcessor: null,
|
|
16
|
+
metricReader: null,
|
|
7
17
|
initialized: false
|
|
8
18
|
};
|
|
9
19
|
/**
|
|
@@ -43,6 +53,12 @@ function setGlobalLogProcessor(processor) {
|
|
|
43
53
|
state.logProcessor = processor;
|
|
44
54
|
}
|
|
45
55
|
/**
|
|
56
|
+
* Set the global metric reader for flush operations
|
|
57
|
+
*/
|
|
58
|
+
function setGlobalMetricReader(reader) {
|
|
59
|
+
state.metricReader = reader;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
46
62
|
* Check if telemetry is initialized
|
|
47
63
|
*/
|
|
48
64
|
function isTelemetryInitialized() {
|
|
@@ -74,6 +90,12 @@ async function flushTelemetry(timeoutMs = 3e4) {
|
|
|
74
90
|
if (state.logProcessor && typeof state.logProcessor.forceFlush === "function") promises.push(Promise.race([state.logProcessor.forceFlush(), new Promise((_, reject) => setTimeout(() => reject(/* @__PURE__ */ new Error("Log flush timeout")), timeoutMs))]).catch((error) => {
|
|
75
91
|
if (diag.debug) diag.debug(`Log flush error: ${error.message}`);
|
|
76
92
|
}));
|
|
93
|
+
if (state.metricReader) {
|
|
94
|
+
const reader = state.metricReader;
|
|
95
|
+
promises.push(Promise.race([reader.forceFlush(), new Promise((_, reject) => setTimeout(() => reject(new MetricFlushTimeout(timeoutMs)), timeoutMs))]).catch((error) => {
|
|
96
|
+
if (diag.debug) diag.debug(`Metric flush error: ${error.message}`);
|
|
97
|
+
}));
|
|
98
|
+
}
|
|
77
99
|
await Promise.all(promises);
|
|
78
100
|
}
|
|
79
101
|
/**
|
|
@@ -89,6 +111,10 @@ async function shutdownTelemetry() {
|
|
|
89
111
|
promises.push(state.logProcessor.shutdown());
|
|
90
112
|
state.logProcessor = null;
|
|
91
113
|
}
|
|
114
|
+
if (state.metricReader) {
|
|
115
|
+
promises.push(state.metricReader.shutdown());
|
|
116
|
+
state.metricReader = null;
|
|
117
|
+
}
|
|
92
118
|
state.initialized = false;
|
|
93
119
|
await Promise.all(promises);
|
|
94
120
|
}
|
|
@@ -133,6 +159,6 @@ var NoopSpanProcessor = class {
|
|
|
133
159
|
}
|
|
134
160
|
};
|
|
135
161
|
//#endregion
|
|
136
|
-
export { NoopSpanProcessor, createSpanProcessor, enableTelemetryDebug, flushTelemetry, getRecommendedStrategy, isTelemetryInitialized, setGlobalLogProcessor, setGlobalSpanProcessor, shutdownTelemetry, withTelemetryFlush };
|
|
162
|
+
export { MetricFlushTimeout, NoopSpanProcessor, createSpanProcessor, enableTelemetryDebug, flushTelemetry, getRecommendedStrategy, isTelemetryInitialized, setGlobalLogProcessor, setGlobalMetricReader, setGlobalSpanProcessor, shutdownTelemetry, withTelemetryFlush };
|
|
137
163
|
|
|
138
164
|
//# sourceMappingURL=core.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.mjs","names":[],"sources":["../../src/instrumentation/core.ts"],"sourcesContent":["import { DiagConsoleLogger, DiagLogLevel, diag } from '@opentelemetry/api';\nimport {\n\tBatchSpanProcessor,\n\ttype ReadableSpan,\n\tSimpleSpanProcessor,\n\ttype Span,\n\ttype SpanExporter,\n\ttype SpanProcessor,\n} from '@opentelemetry/sdk-trace-base';\nimport type {\n\tSpanProcessorOptions,\n\tSpanProcessorStrategy,\n} from '../adapters/types';\n\n/**\n * Global telemetry state for flush operations\n */\ninterface TelemetryState {\n\tspanProcessor: SpanProcessor | null;\n\tlogProcessor: unknown | null;\n\tinitialized: boolean;\n}\n\nconst state: TelemetryState = {\n\tspanProcessor: null,\n\tlogProcessor: null,\n\tinitialized: false,\n};\n\n/**\n * Create a span processor based on the strategy\n */\nexport function createSpanProcessor(\n\texporter: SpanExporter,\n\toptions: SpanProcessorOptions,\n): SpanProcessor {\n\tconst { strategy, ...config } = options;\n\n\tif (strategy === 'simple') {\n\t\treturn new SimpleSpanProcessor(exporter);\n\t}\n\n\treturn new BatchSpanProcessor(exporter, {\n\t\tmaxQueueSize: config.maxQueueSize ?? 2048,\n\t\tscheduledDelayMillis: config.scheduledDelayMillis ?? 5000,\n\t\texportTimeoutMillis: config.exportTimeoutMillis ?? 30000,\n\t\tmaxExportBatchSize: config.maxExportBatchSize ?? 512,\n\t});\n}\n\n/**\n * Get the recommended span processor strategy for an environment\n */\nexport function getRecommendedStrategy(\n\tenvironment: 'server' | 'lambda' | 'edge' | 'custom',\n): SpanProcessorStrategy {\n\tswitch (environment) {\n\t\tcase 'lambda':\n\t\tcase 'edge':\n\t\t\t// Use simple processor for serverless - immediate export\n\t\t\treturn 'simple';\n\t\tdefault:\n\t\t\t// Use batch processor for long-running servers - efficient batching\n\t\t\treturn 'batch';\n\t}\n}\n\n/**\n * Set the global span processor for flush operations\n */\nexport function setGlobalSpanProcessor(processor: SpanProcessor): void {\n\tstate.spanProcessor = processor;\n\tstate.initialized = true;\n}\n\n/**\n * Set the global log processor for flush operations\n */\nexport function setGlobalLogProcessor(processor: unknown): void {\n\tstate.logProcessor = processor;\n}\n\n/**\n * Check if telemetry is initialized\n */\nexport function isTelemetryInitialized(): boolean {\n\treturn state.initialized;\n}\n\n/**\n * Flush all pending telemetry data.\n * This is critical for serverless environments where the process may freeze.\n *\n * @example\n * ```typescript\n * // In a Lambda handler\n * export const handler = async (event, context) => {\n * try {\n * const result = await processRequest(event);\n * return result;\n * } finally {\n * // Flush before Lambda freezes\n * await flushTelemetry();\n * }\n * };\n * ```\n */\nexport async function flushTelemetry(timeoutMs = 30000): Promise<void> {\n\tconst promises: Promise<void>[] = [];\n\n\t// Flush span processor\n\tif (state.spanProcessor) {\n\t\tpromises.push(\n\t\t\tPromise.race([\n\t\t\t\tstate.spanProcessor.forceFlush(),\n\t\t\t\tnew Promise<void>((_, reject) =>\n\t\t\t\t\tsetTimeout(() => reject(new Error('Span flush timeout')), timeoutMs),\n\t\t\t\t),\n\t\t\t]).catch((error) => {\n\t\t\t\tif (diag.debug) {\n\t\t\t\t\tdiag.debug(`Span flush error: ${error.message}`);\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\t}\n\n\t// Flush log processor if it has forceFlush method\n\tif (\n\t\tstate.logProcessor &&\n\t\ttypeof (state.logProcessor as { forceFlush?: () => Promise<void> })\n\t\t\t.forceFlush === 'function'\n\t) {\n\t\tpromises.push(\n\t\t\tPromise.race([\n\t\t\t\t(\n\t\t\t\t\tstate.logProcessor as { forceFlush: () => Promise<void> }\n\t\t\t\t).forceFlush(),\n\t\t\t\tnew Promise<void>((_, reject) =>\n\t\t\t\t\tsetTimeout(() => reject(new Error('Log flush timeout')), timeoutMs),\n\t\t\t\t),\n\t\t\t]).catch((error) => {\n\t\t\t\tif (diag.debug) {\n\t\t\t\t\tdiag.debug(`Log flush error: ${error.message}`);\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\t}\n\n\tawait Promise.all(promises);\n}\n\n/**\n * Shutdown all telemetry processors\n */\nexport async function shutdownTelemetry(): Promise<void> {\n\tconst promises: Promise<void>[] = [];\n\n\tif (state.spanProcessor) {\n\t\tpromises.push(state.spanProcessor.shutdown());\n\t\tstate.spanProcessor = null;\n\t}\n\n\tif (\n\t\tstate.logProcessor &&\n\t\ttypeof (state.logProcessor as { shutdown?: () => Promise<void> })\n\t\t\t.shutdown === 'function'\n\t) {\n\t\tpromises.push(\n\t\t\t(state.logProcessor as { shutdown: () => Promise<void> }).shutdown(),\n\t\t);\n\t\tstate.logProcessor = null;\n\t}\n\n\tstate.initialized = false;\n\tawait Promise.all(promises);\n}\n\n/**\n * Enable debug logging for telemetry\n */\nexport function enableTelemetryDebug(): void {\n\tdiag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG);\n}\n\n/**\n * Wraps a handler function to ensure telemetry is flushed before returning.\n * Useful for Lambda handlers.\n *\n * @example\n * ```typescript\n * export const handler = withTelemetryFlush(async (event, context) => {\n * // Your Lambda logic here\n * return { statusCode: 200, body: 'OK' };\n * });\n * ```\n */\nexport function withTelemetryFlush<TEvent, TResult>(\n\thandler: (event: TEvent, context: unknown) => Promise<TResult>,\n): (event: TEvent, context: unknown) => Promise<TResult> {\n\treturn async (event: TEvent, context: unknown): Promise<TResult> => {\n\t\ttry {\n\t\t\treturn await handler(event, context);\n\t\t} finally {\n\t\t\tawait flushTelemetry();\n\t\t}\n\t};\n}\n\n/**\n * Noop span processor for testing or when telemetry is disabled\n */\nexport class NoopSpanProcessor implements SpanProcessor {\n\tforceFlush(): Promise<void> {\n\t\treturn Promise.resolve();\n\t}\n\n\tonStart(_span: Span): void {\n\t\t// noop\n\t}\n\n\tonEnd(_span: ReadableSpan): void {\n\t\t// noop\n\t}\n\n\tshutdown(): Promise<void> {\n\t\treturn Promise.resolve();\n\t}\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"core.mjs","names":[],"sources":["../../src/instrumentation/core.ts"],"sourcesContent":["import { DiagConsoleLogger, DiagLogLevel, diag } from '@opentelemetry/api';\nimport {\n\tBatchSpanProcessor,\n\ttype ReadableSpan,\n\tSimpleSpanProcessor,\n\ttype Span,\n\ttype SpanExporter,\n\ttype SpanProcessor,\n} from '@opentelemetry/sdk-trace-base';\nimport type {\n\tSpanProcessorOptions,\n\tSpanProcessorStrategy,\n} from '../adapters/types';\n\n/**\n * Global telemetry state for flush operations\n */\ninterface TelemetryState {\n\tspanProcessor: SpanProcessor | null;\n\tlogProcessor: unknown | null;\n\tmetricReader: FlushableMetricReader | null;\n\tinitialized: boolean;\n}\n\n/**\n * What flushing needs of a metric reader — the shape, so this module loads\n * without `@opentelemetry/sdk-metrics`.\n */\nexport interface FlushableMetricReader {\n\tforceFlush(): Promise<void>;\n\tshutdown(): Promise<void>;\n}\n\n/** A metric flush that did not finish in time; the process carries on. */\nexport class MetricFlushTimeout extends Error {\n\tconstructor(readonly timeoutMs: number) {\n\t\tsuper(\n\t\t\t`Metrics were not exported within ${timeoutMs}ms. Check that the collector is reachable, or pass flushTelemetry a longer timeout.`,\n\t\t);\n\t\tthis.name = 'MetricFlushTimeout';\n\t}\n}\n\nconst state: TelemetryState = {\n\tspanProcessor: null,\n\tlogProcessor: null,\n\tmetricReader: null,\n\tinitialized: false,\n};\n\n/**\n * Create a span processor based on the strategy\n */\nexport function createSpanProcessor(\n\texporter: SpanExporter,\n\toptions: SpanProcessorOptions,\n): SpanProcessor {\n\tconst { strategy, ...config } = options;\n\n\tif (strategy === 'simple') {\n\t\treturn new SimpleSpanProcessor(exporter);\n\t}\n\n\treturn new BatchSpanProcessor(exporter, {\n\t\tmaxQueueSize: config.maxQueueSize ?? 2048,\n\t\tscheduledDelayMillis: config.scheduledDelayMillis ?? 5000,\n\t\texportTimeoutMillis: config.exportTimeoutMillis ?? 30000,\n\t\tmaxExportBatchSize: config.maxExportBatchSize ?? 512,\n\t});\n}\n\n/**\n * Get the recommended span processor strategy for an environment\n */\nexport function getRecommendedStrategy(\n\tenvironment: 'server' | 'lambda' | 'edge' | 'custom',\n): SpanProcessorStrategy {\n\tswitch (environment) {\n\t\tcase 'lambda':\n\t\tcase 'edge':\n\t\t\t// Use simple processor for serverless - immediate export\n\t\t\treturn 'simple';\n\t\tdefault:\n\t\t\t// Use batch processor for long-running servers - efficient batching\n\t\t\treturn 'batch';\n\t}\n}\n\n/**\n * Set the global span processor for flush operations\n */\nexport function setGlobalSpanProcessor(processor: SpanProcessor): void {\n\tstate.spanProcessor = processor;\n\tstate.initialized = true;\n}\n\n/**\n * Set the global log processor for flush operations\n */\nexport function setGlobalLogProcessor(processor: unknown): void {\n\tstate.logProcessor = processor;\n}\n\n/**\n * Set the global metric reader for flush operations\n */\nexport function setGlobalMetricReader(reader: FlushableMetricReader): void {\n\tstate.metricReader = reader;\n}\n\n/**\n * Check if telemetry is initialized\n */\nexport function isTelemetryInitialized(): boolean {\n\treturn state.initialized;\n}\n\n/**\n * Flush all pending telemetry data.\n * This is critical for serverless environments where the process may freeze.\n *\n * @example\n * ```typescript\n * // In a Lambda handler\n * export const handler = async (event, context) => {\n * try {\n * const result = await processRequest(event);\n * return result;\n * } finally {\n * // Flush before Lambda freezes\n * await flushTelemetry();\n * }\n * };\n * ```\n */\nexport async function flushTelemetry(timeoutMs = 30000): Promise<void> {\n\tconst promises: Promise<void>[] = [];\n\n\t// Flush span processor\n\tif (state.spanProcessor) {\n\t\tpromises.push(\n\t\t\tPromise.race([\n\t\t\t\tstate.spanProcessor.forceFlush(),\n\t\t\t\tnew Promise<void>((_, reject) =>\n\t\t\t\t\tsetTimeout(() => reject(new Error('Span flush timeout')), timeoutMs),\n\t\t\t\t),\n\t\t\t]).catch((error) => {\n\t\t\t\tif (diag.debug) {\n\t\t\t\t\tdiag.debug(`Span flush error: ${error.message}`);\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\t}\n\n\t// Flush log processor if it has forceFlush method\n\tif (\n\t\tstate.logProcessor &&\n\t\ttypeof (state.logProcessor as { forceFlush?: () => Promise<void> })\n\t\t\t.forceFlush === 'function'\n\t) {\n\t\tpromises.push(\n\t\t\tPromise.race([\n\t\t\t\t(\n\t\t\t\t\tstate.logProcessor as { forceFlush: () => Promise<void> }\n\t\t\t\t).forceFlush(),\n\t\t\t\tnew Promise<void>((_, reject) =>\n\t\t\t\t\tsetTimeout(() => reject(new Error('Log flush timeout')), timeoutMs),\n\t\t\t\t),\n\t\t\t]).catch((error) => {\n\t\t\t\tif (diag.debug) {\n\t\t\t\t\tdiag.debug(`Log flush error: ${error.message}`);\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\t}\n\n\t// Flush metrics — a Lambda freezes between invocations, so its periodic\n\t// export would otherwise wait for an invocation that may never come.\n\tif (state.metricReader) {\n\t\tconst reader = state.metricReader;\n\t\tpromises.push(\n\t\t\tPromise.race([\n\t\t\t\treader.forceFlush(),\n\t\t\t\tnew Promise<void>((_, reject) =>\n\t\t\t\t\tsetTimeout(\n\t\t\t\t\t\t() => reject(new MetricFlushTimeout(timeoutMs)),\n\t\t\t\t\t\ttimeoutMs,\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t]).catch((error) => {\n\t\t\t\tif (diag.debug) {\n\t\t\t\t\tdiag.debug(`Metric flush error: ${error.message}`);\n\t\t\t\t}\n\t\t\t}),\n\t\t);\n\t}\n\n\tawait Promise.all(promises);\n}\n\n/**\n * Shutdown all telemetry processors\n */\nexport async function shutdownTelemetry(): Promise<void> {\n\tconst promises: Promise<void>[] = [];\n\n\tif (state.spanProcessor) {\n\t\tpromises.push(state.spanProcessor.shutdown());\n\t\tstate.spanProcessor = null;\n\t}\n\n\tif (\n\t\tstate.logProcessor &&\n\t\ttypeof (state.logProcessor as { shutdown?: () => Promise<void> })\n\t\t\t.shutdown === 'function'\n\t) {\n\t\tpromises.push(\n\t\t\t(state.logProcessor as { shutdown: () => Promise<void> }).shutdown(),\n\t\t);\n\t\tstate.logProcessor = null;\n\t}\n\n\tif (state.metricReader) {\n\t\tpromises.push(state.metricReader.shutdown());\n\t\tstate.metricReader = null;\n\t}\n\n\tstate.initialized = false;\n\tawait Promise.all(promises);\n}\n\n/**\n * Enable debug logging for telemetry\n */\nexport function enableTelemetryDebug(): void {\n\tdiag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG);\n}\n\n/**\n * Wraps a handler function to ensure telemetry is flushed before returning.\n * Useful for Lambda handlers.\n *\n * @example\n * ```typescript\n * export const handler = withTelemetryFlush(async (event, context) => {\n * // Your Lambda logic here\n * return { statusCode: 200, body: 'OK' };\n * });\n * ```\n */\nexport function withTelemetryFlush<TEvent, TResult>(\n\thandler: (event: TEvent, context: unknown) => Promise<TResult>,\n): (event: TEvent, context: unknown) => Promise<TResult> {\n\treturn async (event: TEvent, context: unknown): Promise<TResult> => {\n\t\ttry {\n\t\t\treturn await handler(event, context);\n\t\t} finally {\n\t\t\tawait flushTelemetry();\n\t\t}\n\t};\n}\n\n/**\n * Noop span processor for testing or when telemetry is disabled\n */\nexport class NoopSpanProcessor implements SpanProcessor {\n\tforceFlush(): Promise<void> {\n\t\treturn Promise.resolve();\n\t}\n\n\tonStart(_span: Span): void {\n\t\t// noop\n\t}\n\n\tonEnd(_span: ReadableSpan): void {\n\t\t// noop\n\t}\n\n\tshutdown(): Promise<void> {\n\t\treturn Promise.resolve();\n\t}\n}\n"],"mappings":"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"}
|