@geekmidas/telescope 1.1.1 → 10.0.0-alpha.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.
Files changed (167) hide show
  1. package/README.md +14 -4
  2. package/dist/{hono-Bz9PQQzj.mjs → hono-Bw-ey6CT.mjs} +2 -2
  3. package/dist/{hono-Bz9PQQzj.mjs.map → hono-Bw-ey6CT.mjs.map} +1 -1
  4. package/dist/{hono-Z_JIICmt.cjs → hono-CPHX7FAm.cjs} +2 -2
  5. package/dist/{hono-Z_JIICmt.cjs.map → hono-CPHX7FAm.cjs.map} +1 -1
  6. package/dist/{http-Crsriv32.mjs → http-BIvr0YdI.mjs} +1 -1
  7. package/dist/{http-Crsriv32.mjs.map → http-BIvr0YdI.mjs.map} +1 -1
  8. package/dist/{http-JycFRfSe.cjs → http-BsqmhurZ.cjs} +1 -1
  9. package/dist/{http-JycFRfSe.cjs.map → http-BsqmhurZ.cjs.map} +1 -1
  10. package/dist/{http-D5kn3_Mt.d.mts → http-DULM1u2L.d.cts} +3 -3
  11. package/dist/{http-D5kn3_Mt.d.mts.map → http-DULM1u2L.d.cts.map} +1 -1
  12. package/dist/{http-Dvca6fC3.d.cts → http-GB-Nlvwc.d.mts} +3 -3
  13. package/dist/{http-Dvca6fC3.d.cts.map → http-GB-Nlvwc.d.mts.map} +1 -1
  14. package/dist/instrumentation/hono.cjs +2 -2
  15. package/dist/instrumentation/hono.mjs +2 -2
  16. package/dist/instrumentation/http.cjs +1 -1
  17. package/dist/instrumentation/http.d.cts +1 -1
  18. package/dist/instrumentation/http.d.mts +1 -1
  19. package/dist/instrumentation/http.mjs +1 -1
  20. package/dist/instrumentation/index.cjs +5 -5
  21. package/dist/instrumentation/index.d.cts +3 -3
  22. package/dist/instrumentation/index.d.mts +3 -3
  23. package/dist/instrumentation/index.mjs +5 -5
  24. package/dist/instrumentation/middleware.cjs +2 -2
  25. package/dist/instrumentation/middleware.d.cts +1 -1
  26. package/dist/instrumentation/middleware.d.mts +1 -1
  27. package/dist/instrumentation/middleware.mjs +2 -2
  28. package/dist/instrumentation/otel.cjs +2 -2
  29. package/dist/instrumentation/otel.d.cts +1 -1
  30. package/dist/instrumentation/otel.d.mts +1 -1
  31. package/dist/instrumentation/otel.mjs +2 -2
  32. package/dist/instrumentation/setup.cjs +1 -1
  33. package/dist/instrumentation/setup.mjs +1 -1
  34. package/dist/logger/console.d.cts.map +1 -1
  35. package/dist/{middleware-D3v5SnSs.cjs → middleware-Bcq6XXGG.cjs} +3 -3
  36. package/dist/middleware-Bcq6XXGG.cjs.map +1 -0
  37. package/dist/{middleware-Dy1ctr2N.mjs → middleware-D1XEHvyy.mjs} +3 -3
  38. package/dist/middleware-D1XEHvyy.mjs.map +1 -0
  39. package/dist/{middleware-CA84nsNN.d.cts → middleware-PeyS-9Ny.d.cts} +2 -2
  40. package/dist/{middleware-CA84nsNN.d.cts.map → middleware-PeyS-9Ny.d.cts.map} +1 -1
  41. package/dist/{middleware-DAceVpfw.d.mts → middleware-oHvo_ZgU.d.mts} +2 -2
  42. package/dist/{middleware-DAceVpfw.d.mts.map → middleware-oHvo_ZgU.d.mts.map} +1 -1
  43. package/dist/{otel-DPKNyJ0t.mjs → otel-B9bNoeZ2.mjs} +4 -4
  44. package/dist/otel-B9bNoeZ2.mjs.map +1 -0
  45. package/dist/{otel-1bJPb2Z7.d.mts → otel-Bk89b1lX.d.cts} +3 -3
  46. package/dist/{otel-1bJPb2Z7.d.mts.map → otel-Bk89b1lX.d.cts.map} +1 -1
  47. package/dist/{otel-DuiBeBPU.cjs → otel-BzjOtVxZ.cjs} +4 -4
  48. package/dist/otel-BzjOtVxZ.cjs.map +1 -0
  49. package/dist/{otel-SBVoVEHr.d.cts → otel-lPMsM26e.d.mts} +3 -3
  50. package/dist/{otel-SBVoVEHr.d.cts.map → otel-lPMsM26e.d.mts.map} +1 -1
  51. package/dist/otlp/hono.cjs +3 -3
  52. package/dist/otlp/hono.mjs +3 -3
  53. package/dist/otlp/index.cjs +3 -3
  54. package/dist/otlp/index.mjs +3 -3
  55. package/dist/otlp/receiver.cjs +3 -3
  56. package/dist/otlp/receiver.mjs +3 -3
  57. package/dist/otlp/transformer.cjs +2 -2
  58. package/dist/otlp/transformer.mjs +2 -2
  59. package/dist/otlp/types.cjs +1 -1
  60. package/dist/otlp/types.mjs +1 -1
  61. package/dist/{receiver-q4f7eirs.mjs → receiver-D46dfkYI.mjs} +2 -2
  62. package/dist/{receiver-q4f7eirs.mjs.map → receiver-D46dfkYI.mjs.map} +1 -1
  63. package/dist/{receiver-BW_4go_X.cjs → receiver-slCoAFat.cjs} +2 -2
  64. package/dist/{receiver-BW_4go_X.cjs.map → receiver-slCoAFat.cjs.map} +1 -1
  65. package/dist/{setup-BhCp2LUp.mjs → setup-DC9JMEYZ.mjs} +1 -1
  66. package/dist/{setup-BhCp2LUp.mjs.map → setup-DC9JMEYZ.mjs.map} +1 -1
  67. package/dist/{setup-_uT4L_x5.cjs → setup-DufxQpi9.cjs} +1 -1
  68. package/dist/{setup-_uT4L_x5.cjs.map → setup-DufxQpi9.cjs.map} +1 -1
  69. package/dist/storage/kysely.cjs +48 -38
  70. package/dist/storage/kysely.cjs.map +1 -1
  71. package/dist/storage/kysely.d.cts +29 -9
  72. package/dist/storage/kysely.d.cts.map +1 -1
  73. package/dist/storage/kysely.d.mts +29 -9
  74. package/dist/storage/kysely.d.mts.map +1 -1
  75. package/dist/storage/kysely.mjs +48 -38
  76. package/dist/storage/kysely.mjs.map +1 -1
  77. package/dist/tracing-BX8uY2nR.d.cts.map +1 -1
  78. package/dist/tracing-PnECEbEu.d.mts.map +1 -1
  79. package/dist/{transformer-CFrJQkUg.mjs → transformer-CFQ4WFk6.mjs} +2 -2
  80. package/dist/{transformer-CFrJQkUg.mjs.map → transformer-CFQ4WFk6.mjs.map} +1 -1
  81. package/dist/{transformer-DvDYyFRQ.cjs → transformer-Csl6fbgv.cjs} +2 -2
  82. package/dist/{transformer-DvDYyFRQ.cjs.map → transformer-Csl6fbgv.cjs.map} +1 -1
  83. package/dist/types-B1EIa_cQ.d.mts.map +1 -1
  84. package/dist/{types-BBeTDpHr.cjs → types-BMiHgsi4.cjs} +1 -1
  85. package/dist/{types-BBeTDpHr.cjs.map → types-BMiHgsi4.cjs.map} +1 -1
  86. package/dist/{types-CXYLhG_G.mjs → types-Cj59nqy7.mjs} +1 -1
  87. package/dist/{types-CXYLhG_G.mjs.map → types-Cj59nqy7.mjs.map} +1 -1
  88. package/dist/types-l7Rlb5Mg.d.cts.map +1 -1
  89. package/package.json +6 -3
  90. package/CHANGELOG.md +0 -51
  91. package/dist/middleware-D3v5SnSs.cjs.map +0 -1
  92. package/dist/middleware-Dy1ctr2N.mjs.map +0 -1
  93. package/dist/otel-DPKNyJ0t.mjs.map +0 -1
  94. package/dist/otel-DuiBeBPU.cjs.map +0 -1
  95. package/src/Telescope.ts +0 -561
  96. package/src/__tests__/Telescope.spec.ts +0 -438
  97. package/src/__tests__/pino-transport.spec.ts +0 -115
  98. package/src/__tests__/redact.spec.ts +0 -336
  99. package/src/adapters/__tests__/lambda.spec.ts +0 -318
  100. package/src/adapters/__tests__/middy.spec.ts +0 -741
  101. package/src/adapters/index.ts +0 -22
  102. package/src/adapters/lambda.ts +0 -432
  103. package/src/adapters/middy.ts +0 -402
  104. package/src/adapters/types.ts +0 -181
  105. package/src/core.ts +0 -51
  106. package/src/index.ts +0 -34
  107. package/src/instrumentation/__tests__/core.spec.ts +0 -248
  108. package/src/instrumentation/__tests__/hono.spec.ts +0 -348
  109. package/src/instrumentation/__tests__/middleware.spec.ts +0 -528
  110. package/src/instrumentation/__tests__/otel.spec.ts +0 -291
  111. package/src/instrumentation/__tests__/tracing.spec.ts +0 -208
  112. package/src/instrumentation/core.ts +0 -228
  113. package/src/instrumentation/hono.ts +0 -270
  114. package/src/instrumentation/http.ts +0 -306
  115. package/src/instrumentation/index.ts +0 -90
  116. package/src/instrumentation/middleware.ts +0 -297
  117. package/src/instrumentation/otel.ts +0 -271
  118. package/src/instrumentation/setup.ts +0 -246
  119. package/src/instrumentation/tracing.ts +0 -145
  120. package/src/logger/__tests__/console.spec.ts +0 -366
  121. package/src/logger/__tests__/pino.spec.ts +0 -217
  122. package/src/logger/console.ts +0 -230
  123. package/src/logger/pino.ts +0 -201
  124. package/src/metrics/MetricsAggregator.ts +0 -555
  125. package/src/metrics/__tests__/MetricsAggregator.spec.ts +0 -298
  126. package/src/metrics/index.ts +0 -2
  127. package/src/metrics/storage/InMemoryMetricsStorage.ts +0 -380
  128. package/src/metrics/storage/MetricsStorage.ts +0 -74
  129. package/src/metrics/storage/index.ts +0 -3
  130. package/src/metrics/storage/types.ts +0 -243
  131. package/src/otlp/__tests__/receiver.spec.ts +0 -367
  132. package/src/otlp/__tests__/transformer.spec.ts +0 -455
  133. package/src/otlp/hono.ts +0 -120
  134. package/src/otlp/index.ts +0 -22
  135. package/src/otlp/receiver.ts +0 -162
  136. package/src/otlp/transformer.ts +0 -367
  137. package/src/otlp/types.ts +0 -364
  138. package/src/redact.ts +0 -116
  139. package/src/server/__tests__/hono.spec.ts +0 -814
  140. package/src/server/hono.ts +0 -442
  141. package/src/storage/__tests__/kysely.spec.ts +0 -715
  142. package/src/storage/__tests__/memory.spec.ts +0 -694
  143. package/src/storage/kysely.ts +0 -599
  144. package/src/storage/memory.ts +0 -204
  145. package/src/types.ts +0 -447
  146. package/src/ui-assets.ts +0 -40
  147. package/tsconfig.json +0 -9
  148. package/ui/CHANGELOG.md +0 -7
  149. package/ui/index.html +0 -12
  150. package/ui/node_modules/.bin/tsc +0 -21
  151. package/ui/node_modules/.bin/tsserver +0 -21
  152. package/ui/node_modules/.bin/vite +0 -21
  153. package/ui/package.json +0 -24
  154. package/ui/src/App.tsx +0 -595
  155. package/ui/src/api.ts +0 -88
  156. package/ui/src/components/ExceptionDetail.tsx +0 -100
  157. package/ui/src/components/FilterBar.tsx +0 -162
  158. package/ui/src/components/LogDetail.tsx +0 -91
  159. package/ui/src/components/RequestDetail.tsx +0 -143
  160. package/ui/src/main.tsx +0 -10
  161. package/ui/src/styles.css +0 -11
  162. package/ui/src/types.ts +0 -63
  163. package/ui/src/vite-env.d.ts +0 -1
  164. package/ui/src/vite-plugin-gkm-config.ts +0 -54
  165. package/ui/tsconfig.json +0 -20
  166. package/ui/tsconfig.tsbuildinfo +0 -1
  167. package/ui/vite.config.ts +0 -13
@@ -1,402 +0,0 @@
1
- import type { MiddlewareObj } from '@middy/core';
2
- import type {
3
- APIGatewayProxyEvent,
4
- APIGatewayProxyEventV2,
5
- Context,
6
- } from 'aws-lambda';
7
- import { flushTelemetry } from '../instrumentation/core';
8
- import type { Telescope } from '../Telescope';
9
-
10
- /**
11
- * Options for the Telescope Middy middleware
12
- */
13
- export interface TelescopeMiddlewareOptions {
14
- /**
15
- * Minimum remaining time (ms) before forcing a flush.
16
- * If remaining time drops below this, flush immediately.
17
- * @default 1000 (1 second)
18
- */
19
- flushThresholdMs?: number;
20
-
21
- /**
22
- * Whether to record request/response bodies
23
- * @default true
24
- */
25
- recordBody?: boolean;
26
-
27
- /**
28
- * Timeout for flush operation in ms
29
- * @default 5000
30
- */
31
- flushTimeoutMs?: number;
32
- }
33
-
34
- // Track if we've registered the process hooks
35
- let processHooksRegistered = false;
36
-
37
- /**
38
- * Register process-level hooks for telemetry flush.
39
- * Called once per Lambda cold start.
40
- */
41
- function registerProcessHooks(): void {
42
- if (processHooksRegistered) return;
43
- processHooksRegistered = true;
44
-
45
- // Flush on SIGTERM (Lambda shutdown)
46
- process.on('SIGTERM', async () => {
47
- await flushTelemetry(5000).catch(() => {});
48
- });
49
-
50
- // Note: beforeExit doesn't work reliably in Lambda
51
- // because Lambda freezes rather than exits
52
- }
53
-
54
- /**
55
- * Extract request data from API Gateway event (v1 or v2)
56
- */
57
- function extractRequestData(
58
- event: APIGatewayProxyEvent | APIGatewayProxyEventV2,
59
- ): {
60
- method: string;
61
- path: string;
62
- url: string;
63
- headers: Record<string, string>;
64
- query: Record<string, string>;
65
- body: unknown;
66
- ip?: string;
67
- requestId?: string;
68
- requestSize?: number;
69
- } {
70
- const headers: Record<string, string> = {};
71
- if (event.headers) {
72
- for (const [key, value] of Object.entries(event.headers)) {
73
- if (value) headers[key.toLowerCase()] = value;
74
- }
75
- }
76
-
77
- // Get request size from Content-Length header
78
- const contentLength = headers['content-length'];
79
- const requestSize = contentLength ? parseInt(contentLength, 10) : undefined;
80
-
81
- // API Gateway v2 (HTTP API)
82
- if ('rawPath' in event && event.requestContext?.http) {
83
- const v2Event = event as APIGatewayProxyEventV2;
84
- // Filter out undefined values from query parameters
85
- const query: Record<string, string> = {};
86
- if (v2Event.queryStringParameters) {
87
- for (const [key, value] of Object.entries(
88
- v2Event.queryStringParameters,
89
- )) {
90
- if (value !== undefined) {
91
- query[key] = value;
92
- }
93
- }
94
- }
95
- return {
96
- method: v2Event.requestContext.http.method,
97
- path: v2Event.rawPath,
98
- url:
99
- v2Event.rawPath +
100
- (v2Event.rawQueryString ? `?${v2Event.rawQueryString}` : ''),
101
- headers,
102
- query,
103
- body: parseBody(v2Event.body, v2Event.isBase64Encoded),
104
- ip: v2Event.requestContext.http.sourceIp,
105
- requestId: v2Event.requestContext.requestId,
106
- requestSize,
107
- };
108
- }
109
-
110
- // API Gateway v1 (REST API)
111
- const v1Event = event as APIGatewayProxyEvent;
112
- const queryString = v1Event.queryStringParameters
113
- ? new URLSearchParams(
114
- v1Event.queryStringParameters as Record<string, string>,
115
- ).toString()
116
- : '';
117
-
118
- return {
119
- method: v1Event.httpMethod,
120
- path: v1Event.path,
121
- url: v1Event.path + (queryString ? `?${queryString}` : ''),
122
- headers,
123
- query: (v1Event.queryStringParameters as Record<string, string>) || {},
124
- body: parseBody(v1Event.body, v1Event.isBase64Encoded),
125
- ip: v1Event.requestContext?.identity?.sourceIp,
126
- requestId: v1Event.requestContext?.requestId,
127
- requestSize,
128
- };
129
- }
130
-
131
- /**
132
- * Parse request body
133
- */
134
- function parseBody(
135
- body: string | null | undefined,
136
- isBase64Encoded?: boolean,
137
- ): unknown {
138
- if (!body) return undefined;
139
-
140
- try {
141
- const decoded = isBase64Encoded
142
- ? Buffer.from(body, 'base64').toString('utf-8')
143
- : body;
144
- return JSON.parse(decoded);
145
- } catch {
146
- return body;
147
- }
148
- }
149
-
150
- /**
151
- * Extract response data from Lambda response
152
- */
153
- function extractResponseData(response: unknown): {
154
- status: number;
155
- headers: Record<string, string>;
156
- body: unknown;
157
- responseSize?: number;
158
- } {
159
- if (response && typeof response === 'object' && 'statusCode' in response) {
160
- const res = response as {
161
- statusCode?: number;
162
- headers?: Record<string, string>;
163
- body?: string;
164
- };
165
- const headers = res.headers || {};
166
- // Get response size from Content-Length header (case-insensitive)
167
- const contentLengthKey = Object.keys(headers).find(
168
- (k) => k.toLowerCase() === 'content-length',
169
- );
170
- const contentLengthValue = contentLengthKey
171
- ? headers[contentLengthKey]
172
- : undefined;
173
- // Prefer Content-Length header, fallback to body size
174
- const responseSize = contentLengthValue
175
- ? parseInt(contentLengthValue, 10)
176
- : res.body
177
- ? Buffer.byteLength(res.body, 'utf8')
178
- : undefined;
179
- return {
180
- status: res.statusCode || 200,
181
- headers,
182
- body: res.body ? tryParseJson(res.body) : undefined,
183
- responseSize,
184
- };
185
- }
186
-
187
- return { status: 200, headers: {}, body: response };
188
- }
189
-
190
- function tryParseJson(str: string): unknown {
191
- try {
192
- return JSON.parse(str);
193
- } catch {
194
- return str;
195
- }
196
- }
197
-
198
- /**
199
- * Middy middleware that integrates Telescope with Lambda handlers.
200
- *
201
- * Features:
202
- * - Records all requests and responses to Telescope
203
- * - Captures exceptions automatically
204
- * - Flushes telemetry before Lambda freezes
205
- * - Uses Lambda context for smart flush timing
206
- *
207
- * @example
208
- * ```typescript
209
- * import middy from '@middy/core';
210
- * import { telescopeMiddleware } from '@geekmidas/telescope/lambda';
211
- *
212
- * const handler = middy(baseHandler)
213
- * .use(telescopeMiddleware(telescope));
214
- * ```
215
- */
216
- export function telescopeMiddleware(
217
- telescope: Telescope,
218
- options: TelescopeMiddlewareOptions = {},
219
- ): MiddlewareObj<
220
- APIGatewayProxyEvent | APIGatewayProxyEventV2,
221
- any,
222
- Error,
223
- Context
224
- > {
225
- const {
226
- flushThresholdMs = 1000,
227
- recordBody = true,
228
- flushTimeoutMs = 5000,
229
- } = options;
230
-
231
- // Register process hooks on first use
232
- registerProcessHooks();
233
-
234
- return {
235
- before: async (request) => {
236
- // Store start time for duration calculation
237
- (request as any).__telescopeStartTime = Date.now();
238
-
239
- // Don't wait for empty event loop - we'll flush manually
240
- request.context.callbackWaitsForEmptyEventLoop = false;
241
- },
242
-
243
- after: async (request) => {
244
- const startTime = (request as any).__telescopeStartTime || Date.now();
245
- const duration = Date.now() - startTime;
246
-
247
- try {
248
- const reqData = extractRequestData(request.event);
249
- const resData = extractResponseData(request.response);
250
-
251
- await telescope.recordRequest({
252
- method: reqData.method,
253
- path: reqData.path,
254
- url: reqData.url,
255
- headers: reqData.headers,
256
- query: reqData.query,
257
- body: recordBody ? reqData.body : undefined,
258
- ip: reqData.ip,
259
- status: resData.status,
260
- responseHeaders: resData.headers,
261
- responseBody: recordBody ? resData.body : undefined,
262
- duration,
263
- requestSize: reqData.requestSize,
264
- responseSize: resData.responseSize,
265
- });
266
- } catch {
267
- // Don't let telescope errors break the response
268
- }
269
-
270
- // Smart flush: check remaining time
271
- await smartFlush(request.context, flushThresholdMs, flushTimeoutMs);
272
- },
273
-
274
- onError: async (request) => {
275
- const startTime = (request as any).__telescopeStartTime || Date.now();
276
- const duration = Date.now() - startTime;
277
-
278
- try {
279
- // Record the exception
280
- if (request.error) {
281
- await telescope.exception(request.error);
282
- }
283
-
284
- // Also record the failed request
285
- const reqData = extractRequestData(request.event);
286
- await telescope.recordRequest({
287
- method: reqData.method,
288
- path: reqData.path,
289
- url: reqData.url,
290
- headers: reqData.headers,
291
- query: reqData.query,
292
- body: recordBody ? reqData.body : undefined,
293
- ip: reqData.ip,
294
- status: 500,
295
- responseHeaders: {},
296
- responseBody: { error: request.error?.message },
297
- duration,
298
- requestSize: reqData.requestSize,
299
- });
300
- } catch {
301
- // Don't let telescope errors mask the original error
302
- }
303
-
304
- // Always flush on error
305
- await smartFlush(request.context, flushThresholdMs, flushTimeoutMs);
306
- },
307
- };
308
- }
309
-
310
- /**
311
- * Smart flush that respects Lambda's remaining execution time
312
- */
313
- async function smartFlush(
314
- context: Context,
315
- thresholdMs: number,
316
- timeoutMs: number,
317
- ): Promise<void> {
318
- const remaining = context.getRemainingTimeInMillis();
319
-
320
- // If we have plenty of time, use normal timeout
321
- // If time is running low, use a shorter timeout
322
- const effectiveTimeout = Math.min(
323
- timeoutMs,
324
- Math.max(remaining - thresholdMs, 100), // Leave at least threshold ms for response
325
- );
326
-
327
- if (effectiveTimeout > 0) {
328
- await flushTelemetry(effectiveTimeout).catch(() => {});
329
- }
330
- }
331
-
332
- /**
333
- * Create a wrapped Lambda handler with Telescope integration.
334
- * Alternative to using Middy middleware directly.
335
- *
336
- * @example
337
- * ```typescript
338
- * import { createTelescopeHandler } from '@geekmidas/telescope/lambda';
339
- *
340
- * export const handler = createTelescopeHandler(telescope, async (event, context) => {
341
- * return { statusCode: 200, body: 'OK' };
342
- * });
343
- * ```
344
- */
345
- export function createTelescopeHandler<TEvent, TResult>(
346
- telescope: Telescope,
347
- handler: (event: TEvent, context: Context) => Promise<TResult>,
348
- options: TelescopeMiddlewareOptions = {},
349
- ): (event: TEvent, context: Context) => Promise<TResult> {
350
- const {
351
- flushThresholdMs = 1000,
352
- recordBody = true,
353
- flushTimeoutMs = 5000,
354
- } = options;
355
-
356
- registerProcessHooks();
357
-
358
- return async (event: TEvent, context: Context): Promise<TResult> => {
359
- const startTime = Date.now();
360
- context.callbackWaitsForEmptyEventLoop = false;
361
-
362
- try {
363
- const result = await handler(event, context);
364
- const duration = Date.now() - startTime;
365
-
366
- // Record successful request
367
- try {
368
- const reqData = extractRequestData(event as any);
369
- const resData = extractResponseData(result);
370
-
371
- await telescope.recordRequest({
372
- method: reqData.method,
373
- path: reqData.path,
374
- url: reqData.url,
375
- headers: reqData.headers,
376
- query: reqData.query,
377
- body: recordBody ? reqData.body : undefined,
378
- ip: reqData.ip,
379
- status: resData.status,
380
- responseHeaders: resData.headers,
381
- responseBody: recordBody ? resData.body : undefined,
382
- duration,
383
- requestSize: reqData.requestSize,
384
- responseSize: resData.responseSize,
385
- });
386
- } catch {
387
- // Ignore telescope errors
388
- }
389
-
390
- await smartFlush(context, flushThresholdMs, flushTimeoutMs);
391
- return result;
392
- } catch (error) {
393
- // Record exception
394
- if (error instanceof Error) {
395
- await telescope.exception(error).catch(() => {});
396
- }
397
-
398
- await smartFlush(context, flushThresholdMs, flushTimeoutMs);
399
- throw error;
400
- }
401
- };
402
- }
@@ -1,181 +0,0 @@
1
- import type { Context as HonoContext } from 'hono';
2
-
3
- /**
4
- * Environment types for adapter configuration
5
- */
6
- export type TelescopeEnvironment = 'server' | 'lambda' | 'edge' | 'custom';
7
-
8
- /**
9
- * Request context passed to adapters
10
- */
11
- export interface AdapterRequestContext {
12
- /** Unique request ID */
13
- id: string;
14
- /** HTTP method */
15
- method: string;
16
- /** Request path */
17
- path: string;
18
- /** Full URL */
19
- url: string;
20
- /** Request headers */
21
- headers: Record<string, string>;
22
- /** Query parameters */
23
- query: Record<string, string>;
24
- /** Request body (if recorded) */
25
- body?: unknown;
26
- /** Client IP address */
27
- ip?: string;
28
- /** Request start time */
29
- startTime: number;
30
- /** Request body size in bytes */
31
- requestSize?: number;
32
- }
33
-
34
- /**
35
- * Response context passed to adapters
36
- */
37
- export interface AdapterResponseContext {
38
- /** HTTP status code */
39
- status: number;
40
- /** Response headers */
41
- headers: Record<string, string>;
42
- /** Response body (if recorded) */
43
- body?: unknown;
44
- /** Request duration in milliseconds */
45
- duration: number;
46
- /** Response body size in bytes */
47
- responseSize?: number;
48
- }
49
-
50
- /**
51
- * Error context for exception handling
52
- */
53
- export interface AdapterErrorContext {
54
- /** The error that occurred */
55
- error: Error;
56
- /** Associated request ID */
57
- requestId?: string;
58
- /** Whether the error was handled */
59
- handled: boolean;
60
- }
61
-
62
- /**
63
- * Span processor strategy for telemetry export
64
- */
65
- export type SpanProcessorStrategy = 'batch' | 'simple';
66
-
67
- /**
68
- * Options for span processor configuration
69
- */
70
- export interface SpanProcessorOptions {
71
- /** Processor strategy (batch for servers, simple for Lambda) */
72
- strategy: SpanProcessorStrategy;
73
- /** Maximum queue size for batch processor (default: 2048) */
74
- maxQueueSize?: number;
75
- /** Scheduled delay for batch processor in ms (default: 5000) */
76
- scheduledDelayMillis?: number;
77
- /** Export timeout in ms (default: 30000) */
78
- exportTimeoutMillis?: number;
79
- /** Maximum export batch size (default: 512) */
80
- maxExportBatchSize?: number;
81
- }
82
-
83
- /**
84
- * Adapter lifecycle hooks
85
- */
86
- export interface AdapterLifecycle {
87
- /**
88
- * Called when the adapter is initialized
89
- */
90
- onSetup?(): Promise<void> | void;
91
-
92
- /**
93
- * Called before the adapter is destroyed
94
- */
95
- onDestroy?(): Promise<void> | void;
96
- }
97
-
98
- /**
99
- * Base adapter configuration
100
- */
101
- export interface AdapterConfig {
102
- /** Environment type */
103
- environment: TelescopeEnvironment;
104
- /** Span processor options */
105
- spanProcessor?: SpanProcessorOptions;
106
- /** Whether to auto-flush on response */
107
- autoFlush?: boolean;
108
- }
109
-
110
- /**
111
- * Interface for environment-specific adapters.
112
- * Adapters handle the integration between Telescope core and the runtime environment.
113
- */
114
- export interface TelescopeAdapter<TConfig extends AdapterConfig = AdapterConfig>
115
- extends AdapterLifecycle {
116
- /** Adapter configuration */
117
- readonly config: TConfig;
118
-
119
- /**
120
- * Extract request context from the runtime's request object.
121
- * This is called at the start of request processing.
122
- */
123
- extractRequestContext(request: unknown): AdapterRequestContext;
124
-
125
- /**
126
- * Extract response context from the runtime's response object.
127
- * This is called after the response is generated.
128
- */
129
- extractResponseContext(
130
- response: unknown,
131
- startTime: number,
132
- ): AdapterResponseContext;
133
-
134
- /**
135
- * Flush any pending telemetry data.
136
- * Critical for serverless environments where the process may be frozen.
137
- */
138
- flush(): Promise<void>;
139
- }
140
-
141
- /**
142
- * Hono-specific adapter configuration
143
- */
144
- export interface HonoAdapterConfig extends AdapterConfig {
145
- environment: 'server' | 'lambda' | 'edge';
146
- }
147
-
148
- /**
149
- * Lambda-specific adapter configuration
150
- */
151
- export interface LambdaAdapterConfig extends AdapterConfig {
152
- environment: 'lambda';
153
- /** Whether to detect Lambda resource attributes */
154
- detectResource?: boolean;
155
- /** Custom resource attributes */
156
- resourceAttributes?: Record<string, string>;
157
- }
158
-
159
- /**
160
- * Type helper for Hono context with Telescope
161
- */
162
- export interface TelescopeHonoContext {
163
- /** Request ID for correlation */
164
- requestId: string;
165
- /** Request start time */
166
- startTime: number;
167
- }
168
-
169
- /**
170
- * Hono context variables type
171
- */
172
- export interface TelescopeHonoVariables {
173
- telescope: TelescopeHonoContext;
174
- }
175
-
176
- /**
177
- * Extended Hono context with Telescope variables
178
- */
179
- export type HonoContextWithTelescope = HonoContext<{
180
- Variables: TelescopeHonoVariables;
181
- }>;
package/src/core.ts DELETED
@@ -1,51 +0,0 @@
1
- /**
2
- * Telescope Core
3
- *
4
- * Core types, interfaces, and utilities for Telescope.
5
- * This module is environment-agnostic and can be used anywhere.
6
- */
7
-
8
- // Adapter types and interfaces
9
- export type {
10
- AdapterConfig,
11
- AdapterErrorContext,
12
- AdapterLifecycle,
13
- AdapterRequestContext,
14
- AdapterResponseContext,
15
- HonoAdapterConfig,
16
- HonoContextWithTelescope,
17
- LambdaAdapterConfig,
18
- SpanProcessorOptions,
19
- SpanProcessorStrategy,
20
- TelescopeAdapter,
21
- TelescopeEnvironment,
22
- TelescopeHonoContext,
23
- TelescopeHonoVariables,
24
- } from './adapters/types';
25
-
26
- // Instrumentation core utilities
27
- export {
28
- createSpanProcessor,
29
- enableTelemetryDebug,
30
- flushTelemetry,
31
- getRecommendedStrategy,
32
- isTelemetryInitialized,
33
- NoopSpanProcessor,
34
- setGlobalLogProcessor,
35
- setGlobalSpanProcessor,
36
- shutdownTelemetry,
37
- withTelemetryFlush,
38
- } from './instrumentation/core';
39
-
40
- // Tracing utilities
41
- export {
42
- addSpanEvent,
43
- createSpan,
44
- getActiveSpan,
45
- getSpanId,
46
- getTraceId,
47
- recordException,
48
- setSpanAttributes,
49
- withSpan,
50
- withSpanSync,
51
- } from './instrumentation/tracing';
package/src/index.ts DELETED
@@ -1,34 +0,0 @@
1
- // Core
2
-
3
- export type { MetricsAggregatorOptions } from './metrics';
4
- // Metrics
5
- export { MetricsAggregator } from './metrics';
6
- export type { InMemoryStorageOptions } from './storage/memory';
7
- // Storage
8
- export { InMemoryStorage } from './storage/memory';
9
- export { Telescope } from './Telescope';
10
-
11
- // Types
12
- export type {
13
- EndpointBucket,
14
- EndpointMetrics,
15
- ExceptionEntry,
16
- LogEntry,
17
- MetricsBucket,
18
- MetricsQueryOptions,
19
- NormalizedTelescopeOptions,
20
- QueryOptions,
21
- RequestContext,
22
- RequestEntry,
23
- RequestMetrics,
24
- SourceContext,
25
- StackFrame,
26
- StatusDistribution,
27
- TelescopeEvent,
28
- TelescopeEventType,
29
- TelescopeOptions,
30
- TelescopeStats,
31
- TelescopeStorage,
32
- TimeRange,
33
- TimeSeriesPoint,
34
- } from './types';