@geekmidas/telescope 10.0.0-alpha.98 → 10.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +79 -0
- package/README.md +18 -28
- package/dist/InMemoryMetricsStorage-BbKCL3YL.d.mts +47 -0
- package/dist/InMemoryMetricsStorage-BbKCL3YL.d.mts.map +1 -0
- package/dist/InMemoryMetricsStorage-C4drxT7G.mjs +247 -0
- package/dist/InMemoryMetricsStorage-C4drxT7G.mjs.map +1 -0
- package/dist/InMemoryMetricsStorage-D0njWUSi.cjs +252 -0
- package/dist/InMemoryMetricsStorage-D0njWUSi.cjs.map +1 -0
- package/dist/InMemoryMetricsStorage-TvPdZjL0.d.cts +47 -0
- package/dist/InMemoryMetricsStorage-TvPdZjL0.d.cts.map +1 -0
- package/dist/{MetricsAggregator-BJdIvfEv.d.mts → MetricsAggregator-4SqelGcG.d.cts} +6 -3
- package/dist/MetricsAggregator-4SqelGcG.d.cts.map +1 -0
- package/dist/MetricsAggregator-B7lUICdH.cjs +363 -0
- package/dist/MetricsAggregator-B7lUICdH.cjs.map +1 -0
- package/dist/{MetricsAggregator-CnC3oT5q.d.cts → MetricsAggregator-DZrW8ls6.d.mts} +6 -3
- package/dist/MetricsAggregator-DZrW8ls6.d.mts.map +1 -0
- package/dist/MetricsAggregator-S3DQWNas.mjs +357 -0
- package/dist/MetricsAggregator-S3DQWNas.mjs.map +1 -0
- package/dist/MetricsStorage-B86e4131.d.cts +60 -0
- package/dist/MetricsStorage-B86e4131.d.cts.map +1 -0
- package/dist/MetricsStorage-BWyP2_12.d.mts +60 -0
- package/dist/MetricsStorage-BWyP2_12.d.mts.map +1 -0
- package/dist/MetricsStorage-BypQXWiv.mjs +0 -0
- package/dist/MetricsStorage-Or8pVCe4.cjs +0 -0
- package/dist/Telescope-Cs3fv8jt.cjs +395 -0
- package/dist/Telescope-Cs3fv8jt.cjs.map +1 -0
- package/dist/{Telescope-BVfDvVvY.d.mts → Telescope-D4nmwDRA.d.cts} +7 -4
- package/dist/Telescope-D4nmwDRA.d.cts.map +1 -0
- package/dist/Telescope-Dh5av3FC.mjs +389 -0
- package/dist/Telescope-Dh5av3FC.mjs.map +1 -0
- package/dist/{Telescope-DeqSHfuB.d.cts → Telescope-Dl6VSfxd.d.mts} +7 -4
- package/dist/Telescope-Dl6VSfxd.d.mts.map +1 -0
- package/dist/Telescope.cjs +4 -385
- package/dist/Telescope.d.cts +3 -1
- package/dist/Telescope.d.mts +3 -1
- package/dist/Telescope.mjs +4 -384
- package/dist/adapters/index.d.cts +2 -2
- package/dist/adapters/index.d.mts +2 -2
- package/dist/adapters/index.mjs +0 -1
- package/dist/adapters/lambda.cjs +10 -9
- package/dist/adapters/lambda.cjs.map +1 -1
- package/dist/adapters/lambda.d.cts +13 -9
- package/dist/adapters/lambda.d.cts.map +1 -1
- package/dist/adapters/lambda.d.mts +13 -9
- package/dist/adapters/lambda.d.mts.map +1 -1
- package/dist/adapters/lambda.mjs +4 -3
- package/dist/adapters/lambda.mjs.map +1 -1
- package/dist/adapters/middy.cjs +4 -236
- package/dist/adapters/middy.d.cts +5 -60
- package/dist/adapters/middy.d.mts +5 -60
- package/dist/adapters/middy.mjs +3 -234
- package/dist/adapters/types.d.cts +2 -162
- package/dist/adapters/types.d.mts +2 -162
- package/dist/adapters/types.mjs +0 -1
- package/dist/{rolldown-runtime-VH7oDXx4.cjs → chunk-CUT6urMc.cjs} +10 -8
- package/dist/core--quSp5Qr.d.mts +78 -0
- package/dist/core--quSp5Qr.d.mts.map +1 -0
- package/dist/core-B4Jpia5H.d.cts +78 -0
- package/dist/core-B4Jpia5H.d.cts.map +1 -0
- package/dist/core-CtVHRJGv.cjs +199 -0
- package/dist/core-CtVHRJGv.cjs.map +1 -0
- package/dist/core-D6hJ6exL.mjs +139 -0
- package/dist/core-D6hJ6exL.mjs.map +1 -0
- package/dist/core.cjs +22 -22
- package/dist/core.d.cts +4 -4
- package/dist/core.d.mts +4 -4
- package/dist/core.mjs +4 -3
- package/dist/hono--uKQ7Jgi.d.mts +71 -0
- package/dist/hono--uKQ7Jgi.d.mts.map +1 -0
- package/dist/hono-C4EgpbKQ.cjs +160 -0
- package/dist/hono-C4EgpbKQ.cjs.map +1 -0
- package/dist/hono-CemCKU87.d.cts +71 -0
- package/dist/hono-CemCKU87.d.cts.map +1 -0
- package/dist/hono-DxhvnVbF.mjs +136 -0
- package/dist/hono-DxhvnVbF.mjs.map +1 -0
- package/dist/http-BiNtg85L.d.mts +107 -0
- package/dist/http-BiNtg85L.d.mts.map +1 -0
- package/dist/http-DQzgLczm.mjs +159 -0
- package/dist/http-DQzgLczm.mjs.map +1 -0
- package/dist/http-D_Z8sYXZ.cjs +219 -0
- package/dist/http-D_Z8sYXZ.cjs.map +1 -0
- package/dist/http-Dvca6fC3.d.cts +107 -0
- package/dist/http-Dvca6fC3.d.cts.map +1 -0
- package/dist/index-BL32-cvv.d.cts +1 -0
- package/dist/index-CsuikFeJ.d.mts +1 -0
- package/dist/index.cjs +9 -8
- package/dist/index.d.cts +6 -5
- package/dist/index.d.mts +6 -5
- package/dist/index.mjs +7 -5
- package/dist/instrumentation/core.cjs +11 -147
- package/dist/instrumentation/core.d.cts +3 -74
- package/dist/instrumentation/core.d.mts +3 -74
- package/dist/instrumentation/core.mjs +2 -137
- package/dist/instrumentation/hono.cjs +6 -174
- package/dist/instrumentation/hono.d.cts +2 -86
- package/dist/instrumentation/hono.d.mts +2 -86
- package/dist/instrumentation/hono.mjs +3 -170
- package/dist/instrumentation/http.cjs +11 -189
- package/dist/instrumentation/http.d.cts +2 -119
- package/dist/instrumentation/http.d.mts +2 -119
- package/dist/instrumentation/http.mjs +2 -178
- package/dist/instrumentation/index.cjs +47 -56
- package/dist/instrumentation/index.d.cts +9 -11
- package/dist/instrumentation/index.d.mts +9 -11
- package/dist/instrumentation/index.mjs +9 -10
- package/dist/instrumentation/middleware.cjs +6 -164
- package/dist/instrumentation/middleware.d.cts +2 -83
- package/dist/instrumentation/middleware.d.mts +2 -83
- package/dist/instrumentation/middleware.mjs +3 -160
- package/dist/instrumentation/otel.cjs +3 -137
- package/dist/instrumentation/otel.d.cts +2 -97
- package/dist/instrumentation/otel.d.mts +2 -97
- package/dist/instrumentation/otel.mjs +3 -136
- package/dist/instrumentation/setup.cjs +4 -142
- package/dist/instrumentation/setup.d.cts +3 -139
- package/dist/instrumentation/setup.d.mts +3 -139
- package/dist/instrumentation/setup.mjs +3 -139
- package/dist/instrumentation/tracing.cjs +10 -114
- package/dist/instrumentation/tracing.d.cts +2 -49
- package/dist/instrumentation/tracing.d.mts +2 -49
- package/dist/instrumentation/tracing.mjs +2 -105
- package/dist/logger/console.cjs +12 -18
- package/dist/logger/console.cjs.map +1 -1
- package/dist/logger/console.d.cts +10 -7
- package/dist/logger/console.d.cts.map +1 -1
- package/dist/logger/console.d.mts +10 -7
- package/dist/logger/console.d.mts.map +1 -1
- package/dist/logger/console.mjs +11 -17
- package/dist/logger/console.mjs.map +1 -1
- package/dist/logger/pino.cjs +5 -6
- package/dist/logger/pino.cjs.map +1 -1
- package/dist/logger/pino.d.cts +10 -6
- package/dist/logger/pino.d.cts.map +1 -1
- package/dist/logger/pino.d.mts +10 -6
- package/dist/logger/pino.d.mts.map +1 -1
- package/dist/logger/pino.mjs +3 -2
- package/dist/logger/pino.mjs.map +1 -1
- package/dist/memory--BK4iWiv.d.cts +40 -0
- package/dist/memory--BK4iWiv.d.cts.map +1 -0
- package/dist/memory-6S9H-IF5.mjs +123 -0
- package/dist/memory-6S9H-IF5.mjs.map +1 -0
- package/dist/memory-B0d_n1g5.cjs +129 -0
- package/dist/memory-B0d_n1g5.cjs.map +1 -0
- package/dist/memory-DCirEVFW.d.mts +40 -0
- package/dist/memory-DCirEVFW.d.mts.map +1 -0
- package/dist/metrics/MetricsAggregator.cjs +2 -354
- package/dist/metrics/MetricsAggregator.d.cts +2 -1
- package/dist/metrics/MetricsAggregator.d.mts +2 -1
- package/dist/metrics/MetricsAggregator.mjs +2 -353
- package/dist/metrics/index.cjs +4 -3
- package/dist/metrics/index.d.cts +4 -2
- package/dist/metrics/index.d.mts +4 -2
- package/dist/metrics/index.mjs +4 -2
- package/dist/metrics/storage/InMemoryMetricsStorage.cjs +3 -240
- package/dist/metrics/storage/InMemoryMetricsStorage.d.cts +4 -43
- package/dist/metrics/storage/InMemoryMetricsStorage.d.mts +4 -43
- package/dist/metrics/storage/InMemoryMetricsStorage.mjs +3 -239
- package/dist/metrics/storage/MetricsStorage.cjs +1 -0
- package/dist/metrics/storage/MetricsStorage.d.cts +3 -56
- package/dist/metrics/storage/MetricsStorage.d.mts +3 -56
- package/dist/metrics/storage/MetricsStorage.mjs +1 -1
- package/dist/metrics/storage/index.cjs +6 -6
- package/dist/metrics/storage/index.d.cts +3 -3
- package/dist/metrics/storage/index.d.mts +3 -3
- package/dist/metrics/storage/index.mjs +5 -4
- package/dist/metrics/storage/types.cjs +2 -34
- package/dist/metrics/storage/types.d.cts +2 -207
- package/dist/metrics/storage/types.d.mts +2 -207
- package/dist/metrics/storage/types.mjs +2 -33
- package/dist/metrics-D5YT-Rnq.mjs +0 -0
- package/dist/metrics-fhD3l3C3.cjs +0 -0
- package/dist/middleware-B2jFUukM.cjs +184 -0
- package/dist/middleware-B2jFUukM.cjs.map +1 -0
- package/dist/middleware-BTDncHwm.mjs +160 -0
- package/dist/middleware-BTDncHwm.mjs.map +1 -0
- package/dist/middleware-CA84nsNN.d.cts +74 -0
- package/dist/middleware-CA84nsNN.d.cts.map +1 -0
- package/dist/middleware-DAceVpfw.d.mts +74 -0
- package/dist/middleware-DAceVpfw.d.mts.map +1 -0
- package/dist/middy-B6Btl8XE.d.mts +64 -0
- package/dist/middy-B6Btl8XE.d.mts.map +1 -0
- package/dist/middy-BTR3cyvk.mjs +236 -0
- package/dist/middy-BTR3cyvk.mjs.map +1 -0
- package/dist/middy-Bq0defVg.d.cts +64 -0
- package/dist/middy-Bq0defVg.d.cts.map +1 -0
- package/dist/middy-y5Zp27eG.cjs +247 -0
- package/dist/middy-y5Zp27eG.cjs.map +1 -0
- package/dist/otel-1bJPb2Z7.d.mts +101 -0
- package/dist/otel-1bJPb2Z7.d.mts.map +1 -0
- package/dist/otel-C1HqHA2O.cjs +136 -0
- package/dist/otel-C1HqHA2O.cjs.map +1 -0
- package/dist/otel-SBVoVEHr.d.cts +101 -0
- package/dist/otel-SBVoVEHr.d.cts.map +1 -0
- package/dist/otel-wulj5B-X.mjs +130 -0
- package/dist/otel-wulj5B-X.mjs.map +1 -0
- package/dist/otlp/hono.cjs +15 -9
- package/dist/otlp/hono.cjs.map +1 -1
- package/dist/otlp/hono.d.cts +13 -3
- package/dist/otlp/hono.d.cts.map +1 -1
- package/dist/otlp/hono.d.mts +13 -3
- package/dist/otlp/hono.d.mts.map +1 -1
- package/dist/otlp/hono.mjs +11 -5
- package/dist/otlp/hono.mjs.map +1 -1
- package/dist/otlp/index.cjs +11 -11
- package/dist/otlp/index.d.cts +7 -4
- package/dist/otlp/index.d.mts +7 -4
- package/dist/otlp/index.mjs +5 -4
- package/dist/otlp/receiver.cjs +4 -88
- package/dist/otlp/receiver.d.cts +7 -59
- package/dist/otlp/receiver.d.mts +7 -59
- package/dist/otlp/receiver.mjs +4 -87
- package/dist/otlp/transformer.cjs +5 -214
- package/dist/otlp/transformer.d.cts +3 -1
- package/dist/otlp/transformer.d.mts +3 -1
- package/dist/otlp/transformer.mjs +3 -211
- package/dist/otlp/types.cjs +5 -57
- package/dist/otlp/types.d.cts +1 -1
- package/dist/otlp/types.d.mts +1 -1
- package/dist/otlp/types.mjs +2 -53
- package/dist/receiver-Cj1lbAOO.cjs +94 -0
- package/dist/receiver-Cj1lbAOO.cjs.map +1 -0
- package/dist/receiver-CxVd_9CB.mjs +89 -0
- package/dist/receiver-CxVd_9CB.mjs.map +1 -0
- package/dist/receiver-DLICx5uU.d.cts +63 -0
- package/dist/receiver-DLICx5uU.d.cts.map +1 -0
- package/dist/receiver-UeZT-H8u.d.mts +63 -0
- package/dist/receiver-UeZT-H8u.d.mts.map +1 -0
- package/dist/redact-BzkITCNW.mjs +83 -0
- package/dist/redact-BzkITCNW.mjs.map +1 -0
- package/dist/redact-DVaSSPZT.cjs +95 -0
- package/dist/redact-DVaSSPZT.cjs.map +1 -0
- package/dist/redact.cjs +3 -84
- package/dist/redact.d.cts +8 -4
- package/dist/redact.d.cts.map +1 -1
- package/dist/redact.d.mts +8 -4
- package/dist/redact.d.mts.map +1 -1
- package/dist/redact.mjs +2 -80
- package/dist/server/hono.cjs +54 -33
- package/dist/server/hono.cjs.map +1 -1
- package/dist/server/hono.d.cts +14 -19
- package/dist/server/hono.d.cts.map +1 -1
- package/dist/server/hono.d.mts +14 -19
- package/dist/server/hono.d.mts.map +1 -1
- package/dist/server/hono.mjs +52 -31
- package/dist/server/hono.mjs.map +1 -1
- package/dist/setup-B9jM77Qk.mjs +98 -0
- package/dist/setup-B9jM77Qk.mjs.map +1 -0
- package/dist/setup-Bkxm4g6b.d.mts +87 -0
- package/dist/setup-Bkxm4g6b.d.mts.map +1 -0
- package/dist/setup-CYpff5B9.cjs +110 -0
- package/dist/setup-CYpff5B9.cjs.map +1 -0
- package/dist/setup-D58N1f9O.d.cts +87 -0
- package/dist/setup-D58N1f9O.d.cts.map +1 -0
- package/dist/storage/kysely.cjs +70 -82
- package/dist/storage/kysely.cjs.map +1 -1
- package/dist/storage/kysely.d.cts +20 -36
- package/dist/storage/kysely.d.cts.map +1 -1
- package/dist/storage/kysely.d.mts +20 -36
- package/dist/storage/kysely.d.mts.map +1 -1
- package/dist/storage/kysely.mjs +69 -81
- package/dist/storage/kysely.mjs.map +1 -1
- package/dist/storage/memory.cjs +2 -122
- package/dist/storage/memory.d.cts +3 -36
- package/dist/storage/memory.d.mts +3 -36
- package/dist/storage/memory.mjs +2 -121
- package/dist/tracing-BX8uY2nR.d.cts +53 -0
- package/dist/tracing-BX8uY2nR.d.cts.map +1 -0
- package/dist/tracing-Bt1zWRlb.cjs +167 -0
- package/dist/tracing-Bt1zWRlb.cjs.map +1 -0
- package/dist/tracing-Cijm_5NI.mjs +113 -0
- package/dist/tracing-Cijm_5NI.mjs.map +1 -0
- package/dist/tracing-PnECEbEu.d.mts +53 -0
- package/dist/tracing-PnECEbEu.d.mts.map +1 -0
- package/dist/transformer-BXQPhzql.mjs +215 -0
- package/dist/transformer-BXQPhzql.mjs.map +1 -0
- package/dist/transformer-CLGZ0EQc.cjs +232 -0
- package/dist/transformer-CLGZ0EQc.cjs.map +1 -0
- package/dist/{transformer-BtqjAs0b.d.cts → transformer-CTGsaVfV.d.mts} +8 -4
- package/dist/transformer-CTGsaVfV.d.mts.map +1 -0
- package/dist/{transformer-DI6t8-YA.d.mts → transformer-ICEbxpFf.d.cts} +8 -4
- package/dist/transformer-ICEbxpFf.d.cts.map +1 -0
- package/dist/{types-BVujq4zd.d.mts → types-B1EIa_cQ.d.mts} +4 -3
- package/dist/types-B1EIa_cQ.d.mts.map +1 -0
- package/dist/types-BRzW1NM8.d.cts +166 -0
- package/dist/types-BRzW1NM8.d.cts.map +1 -0
- package/dist/types-BS3Rx8Sk.d.cts +209 -0
- package/dist/types-BS3Rx8Sk.d.cts.map +1 -0
- package/dist/types-Bwm_jNU7.mjs +54 -0
- package/dist/types-Bwm_jNU7.mjs.map +1 -0
- package/dist/types-BzQ78Efw.d.mts +166 -0
- package/dist/types-BzQ78Efw.d.mts.map +1 -0
- package/dist/types-CbNGXnJE.d.mts +209 -0
- package/dist/types-CbNGXnJE.d.mts.map +1 -0
- package/dist/{types-DVETVdpa.d.cts → types-CmOB7CLO.d.cts} +7 -6
- package/dist/types-CmOB7CLO.d.cts.map +1 -0
- package/dist/{types-DVETVdpa.d.mts → types-DBc0q5KD.d.mts} +7 -6
- package/dist/types-DBc0q5KD.d.mts.map +1 -0
- package/dist/types-Dsh-DIO_.cjs +78 -0
- package/dist/types-Dsh-DIO_.cjs.map +1 -0
- package/dist/types-ZW-nfWf6.cjs +40 -0
- package/dist/types-ZW-nfWf6.cjs.map +1 -0
- package/dist/{types-BVujq4zd.d.cts → types-l7Rlb5Mg.d.cts} +4 -3
- package/dist/types-l7Rlb5Mg.d.cts.map +1 -0
- package/dist/types-ojhnLdwz.mjs +34 -0
- package/dist/types-ojhnLdwz.mjs.map +1 -0
- package/dist/types.d.cts +1 -1
- package/dist/types.d.mts +1 -1
- package/dist/types.mjs +0 -1
- package/dist/ui-assets-BEXqOQLe.cjs +48 -0
- package/dist/ui-assets-BEXqOQLe.cjs.map +1 -0
- package/dist/ui-assets-BhTDUsrM.mjs +30 -0
- package/dist/ui-assets-BhTDUsrM.mjs.map +1 -0
- package/dist/ui-assets.cjs +5 -0
- package/dist/ui-assets.d.cts +13 -0
- package/dist/ui-assets.d.cts.map +1 -0
- package/dist/ui-assets.d.mts +13 -0
- package/dist/ui-assets.d.mts.map +1 -0
- package/dist/ui-assets.mjs +3 -0
- package/package.json +46 -46
- package/src/Telescope.ts +561 -0
- package/src/__tests__/Telescope.spec.ts +438 -0
- package/src/__tests__/pino-transport.spec.ts +115 -0
- package/src/__tests__/redact.spec.ts +336 -0
- package/src/adapters/__tests__/lambda.spec.ts +318 -0
- package/src/adapters/__tests__/middy.spec.ts +741 -0
- package/src/adapters/index.ts +22 -0
- package/src/adapters/lambda.ts +432 -0
- package/src/adapters/middy.ts +402 -0
- package/src/adapters/types.ts +181 -0
- package/src/core.ts +51 -0
- package/src/index.ts +34 -0
- package/src/instrumentation/__tests__/core.spec.ts +248 -0
- package/src/instrumentation/__tests__/hono.spec.ts +348 -0
- package/src/instrumentation/__tests__/middleware.spec.ts +528 -0
- package/src/instrumentation/__tests__/otel.spec.ts +291 -0
- package/src/instrumentation/__tests__/tracing.spec.ts +208 -0
- package/src/instrumentation/core.ts +228 -0
- package/src/instrumentation/hono.ts +270 -0
- package/src/instrumentation/http.ts +306 -0
- package/src/instrumentation/index.ts +90 -0
- package/src/instrumentation/middleware.ts +297 -0
- package/src/instrumentation/otel.ts +271 -0
- package/src/instrumentation/setup.ts +246 -0
- package/src/instrumentation/tracing.ts +145 -0
- package/src/logger/__tests__/console.spec.ts +366 -0
- package/src/logger/__tests__/pino.spec.ts +217 -0
- package/src/logger/console.ts +230 -0
- package/src/logger/pino.ts +201 -0
- package/src/metrics/MetricsAggregator.ts +555 -0
- package/src/metrics/__tests__/MetricsAggregator.spec.ts +298 -0
- package/src/metrics/index.ts +2 -0
- package/src/metrics/storage/InMemoryMetricsStorage.ts +380 -0
- package/src/metrics/storage/MetricsStorage.ts +74 -0
- package/src/metrics/storage/index.ts +3 -0
- package/src/metrics/storage/types.ts +243 -0
- package/src/otlp/__tests__/receiver.spec.ts +367 -0
- package/src/otlp/__tests__/transformer.spec.ts +455 -0
- package/src/otlp/hono.ts +120 -0
- package/src/otlp/index.ts +22 -0
- package/src/otlp/receiver.ts +162 -0
- package/src/otlp/transformer.ts +367 -0
- package/src/otlp/types.ts +364 -0
- package/src/redact.ts +116 -0
- package/src/server/__tests__/hono.spec.ts +814 -0
- package/src/server/hono.ts +442 -0
- package/src/storage/__tests__/kysely.spec.ts +715 -0
- package/src/storage/__tests__/memory.spec.ts +694 -0
- package/src/storage/kysely.ts +599 -0
- package/src/storage/memory.ts +204 -0
- package/src/types.ts +447 -0
- package/src/ui-assets.ts +40 -0
- package/tsconfig.json +9 -0
- package/ui/CHANGELOG.md +7 -0
- package/ui/index.html +12 -0
- package/ui/node_modules/.bin/tsc +21 -0
- package/ui/node_modules/.bin/tsserver +21 -0
- package/ui/node_modules/.bin/vite +21 -0
- package/ui/package.json +24 -0
- package/ui/src/App.tsx +595 -0
- package/ui/src/api.ts +88 -0
- package/ui/src/components/ExceptionDetail.tsx +100 -0
- package/ui/src/components/FilterBar.tsx +162 -0
- package/ui/src/components/LogDetail.tsx +91 -0
- package/ui/src/components/RequestDetail.tsx +143 -0
- package/ui/src/main.tsx +10 -0
- package/ui/src/styles.css +11 -0
- package/ui/src/types.ts +63 -0
- package/ui/src/vite-env.d.ts +1 -0
- package/ui/src/vite-plugin-gkm-config.ts +54 -0
- package/ui/tsconfig.json +20 -0
- package/ui/tsconfig.tsbuildinfo +1 -0
- package/ui/vite.config.ts +13 -0
- package/dist/MetricsAggregator-BJdIvfEv.d.mts.map +0 -1
- package/dist/MetricsAggregator-CnC3oT5q.d.cts.map +0 -1
- package/dist/Telescope-BVfDvVvY.d.mts.map +0 -1
- package/dist/Telescope-DeqSHfuB.d.cts.map +0 -1
- package/dist/Telescope.cjs.map +0 -1
- package/dist/Telescope.mjs.map +0 -1
- package/dist/adapters/middy.cjs.map +0 -1
- package/dist/adapters/middy.d.cts.map +0 -1
- package/dist/adapters/middy.d.mts.map +0 -1
- package/dist/adapters/middy.mjs.map +0 -1
- package/dist/adapters/types.d.cts.map +0 -1
- package/dist/adapters/types.d.mts.map +0 -1
- package/dist/instrumentation/core.cjs.map +0 -1
- package/dist/instrumentation/core.d.cts.map +0 -1
- package/dist/instrumentation/core.d.mts.map +0 -1
- package/dist/instrumentation/core.mjs.map +0 -1
- package/dist/instrumentation/hono.cjs.map +0 -1
- package/dist/instrumentation/hono.d.cts.map +0 -1
- package/dist/instrumentation/hono.d.mts.map +0 -1
- package/dist/instrumentation/hono.mjs.map +0 -1
- package/dist/instrumentation/http.cjs.map +0 -1
- package/dist/instrumentation/http.d.cts.map +0 -1
- package/dist/instrumentation/http.d.mts.map +0 -1
- package/dist/instrumentation/http.mjs.map +0 -1
- package/dist/instrumentation/middleware.cjs.map +0 -1
- package/dist/instrumentation/middleware.d.cts.map +0 -1
- package/dist/instrumentation/middleware.d.mts.map +0 -1
- package/dist/instrumentation/middleware.mjs.map +0 -1
- package/dist/instrumentation/otel.cjs.map +0 -1
- package/dist/instrumentation/otel.d.cts.map +0 -1
- package/dist/instrumentation/otel.d.mts.map +0 -1
- package/dist/instrumentation/otel.mjs.map +0 -1
- package/dist/instrumentation/sampler.cjs +0 -54
- package/dist/instrumentation/sampler.cjs.map +0 -1
- package/dist/instrumentation/sampler.d.cts +0 -38
- package/dist/instrumentation/sampler.d.cts.map +0 -1
- package/dist/instrumentation/sampler.d.mts +0 -38
- package/dist/instrumentation/sampler.d.mts.map +0 -1
- package/dist/instrumentation/sampler.mjs +0 -52
- package/dist/instrumentation/sampler.mjs.map +0 -1
- package/dist/instrumentation/setup.cjs.map +0 -1
- package/dist/instrumentation/setup.d.cts.map +0 -1
- package/dist/instrumentation/setup.d.mts.map +0 -1
- package/dist/instrumentation/setup.mjs.map +0 -1
- package/dist/instrumentation/tracing.cjs.map +0 -1
- package/dist/instrumentation/tracing.d.cts.map +0 -1
- package/dist/instrumentation/tracing.d.mts.map +0 -1
- package/dist/instrumentation/tracing.mjs.map +0 -1
- package/dist/instrumentation/trust.cjs +0 -107
- package/dist/instrumentation/trust.cjs.map +0 -1
- package/dist/instrumentation/trust.d.cts +0 -57
- package/dist/instrumentation/trust.d.cts.map +0 -1
- package/dist/instrumentation/trust.d.mts +0 -57
- package/dist/instrumentation/trust.d.mts.map +0 -1
- package/dist/instrumentation/trust.mjs +0 -104
- package/dist/instrumentation/trust.mjs.map +0 -1
- package/dist/metrics/MetricsAggregator.cjs.map +0 -1
- package/dist/metrics/MetricsAggregator.mjs.map +0 -1
- package/dist/metrics/storage/InMemoryMetricsStorage.cjs.map +0 -1
- package/dist/metrics/storage/InMemoryMetricsStorage.d.cts.map +0 -1
- package/dist/metrics/storage/InMemoryMetricsStorage.d.mts.map +0 -1
- package/dist/metrics/storage/InMemoryMetricsStorage.mjs.map +0 -1
- package/dist/metrics/storage/MetricsStorage.d.cts.map +0 -1
- package/dist/metrics/storage/MetricsStorage.d.mts.map +0 -1
- package/dist/metrics/storage/types.cjs.map +0 -1
- package/dist/metrics/storage/types.d.cts.map +0 -1
- package/dist/metrics/storage/types.d.mts.map +0 -1
- package/dist/metrics/storage/types.mjs.map +0 -1
- package/dist/otlp/receiver.cjs.map +0 -1
- package/dist/otlp/receiver.d.cts.map +0 -1
- package/dist/otlp/receiver.d.mts.map +0 -1
- package/dist/otlp/receiver.mjs.map +0 -1
- package/dist/otlp/transformer.cjs.map +0 -1
- package/dist/otlp/transformer.mjs.map +0 -1
- package/dist/otlp/types.cjs.map +0 -1
- package/dist/otlp/types.mjs.map +0 -1
- package/dist/redact.cjs.map +0 -1
- package/dist/redact.mjs.map +0 -1
- package/dist/storage/memory.cjs.map +0 -1
- package/dist/storage/memory.d.cts.map +0 -1
- package/dist/storage/memory.d.mts.map +0 -1
- package/dist/storage/memory.mjs.map +0 -1
- package/dist/transformer-BtqjAs0b.d.cts.map +0 -1
- package/dist/transformer-DI6t8-YA.d.mts.map +0 -1
- package/dist/types-BVujq4zd.d.cts.map +0 -1
- package/dist/types-BVujq4zd.d.mts.map +0 -1
- package/dist/types-DVETVdpa.d.cts.map +0 -1
- package/dist/types-DVETVdpa.d.mts.map +0 -1
package/dist/server/hono.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hono.cjs","names":["Hono"],"sources":["../../src/server/hono.ts"],"sourcesContent":["import type { Context, MiddlewareHandler, Next } from 'hono';\nimport { Hono } from 'hono';\nimport type {\n\tHonoAdapterConfig,\n\tTelescopeHonoContext,\n} from '../adapters/types';\nimport type { Telescope } from '../Telescope';\nimport type { MetricsQueryOptions, QueryOptions } from '../types';\n\n// Lazy-loaded telemetry flush function (only loads @opentelemetry/* when actually used)\nlet _flushTelemetry: (() => Promise<void>) | null = null;\nasync function getFlushTelemetry(): Promise<() => Promise<void>> {\n\tif (!_flushTelemetry) {\n\t\tconst { flushTelemetry } = await import('../instrumentation/core');\n\t\t_flushTelemetry = flushTelemetry;\n\t}\n\treturn _flushTelemetry;\n}\n\nconst CONTEXT_KEY = 'telescope-context';\n\n/** Default Hono adapter configuration */\nconst _DEFAULT_CONFIG: HonoAdapterConfig = {\n\tenvironment: 'server',\n};\n\n/**\n * Options for the Telescope Hono middleware\n */\nexport interface TelescopeMiddlewareOptions {\n\t/**\n\t * Whether to flush telemetry after each request.\n\t * Enable this for serverless environments (Lambda, Edge).\n\t * @default false\n\t */\n\tflushOnResponse?: boolean;\n}\n\n/**\n * Create Hono middleware that captures requests and responses\n */\nexport function createMiddleware(\n\ttelescope: Telescope,\n\toptions: TelescopeMiddlewareOptions = {},\n): MiddlewareHandler {\n\tconst { flushOnResponse = false } = options;\n\n\treturn async (c: Context, next: Next) => {\n\t\tif (!telescope.enabled) {\n\t\t\treturn next();\n\t\t}\n\n\t\tif (telescope.shouldIgnore(c.req.path)) {\n\t\t\treturn next();\n\t\t}\n\n\t\tconst startTime = performance.now();\n\n\t\t// Capture request data\n\t\tconst headers: Record<string, string> = {};\n\t\tc.req.raw.headers.forEach((value, key) => {\n\t\t\theaders[key] = value;\n\t\t});\n\n\t\tconst url = new URL(c.req.url);\n\t\tconst query: Record<string, string> = {};\n\t\turl.searchParams.forEach((value, key) => {\n\t\t\tquery[key] = value;\n\t\t});\n\n\t\tlet body: unknown;\n\t\tlet requestSize: number | undefined;\n\n\t\t// Get request size from Content-Length header\n\t\tconst contentLength = c.req.header('content-length');\n\t\tif (contentLength) {\n\t\t\trequestSize = parseInt(contentLength, 10);\n\t\t}\n\n\t\tif (\n\t\t\ttelescope.recordBody &&\n\t\t\t['POST', 'PUT', 'PATCH'].includes(c.req.method)\n\t\t) {\n\t\t\ttry {\n\t\t\t\tconst contentType = c.req.header('content-type') || '';\n\t\t\t\t// Clone the request to avoid consuming the body stream\n\t\t\t\tconst clonedRequest = c.req.raw.clone();\n\t\t\t\tif (contentType.includes('application/json')) {\n\t\t\t\t\tbody = await clonedRequest.json();\n\t\t\t\t} else if (contentType.includes('application/x-www-form-urlencoded')) {\n\t\t\t\t\tbody = Object.fromEntries((await clonedRequest.formData()).entries());\n\t\t\t\t} else if (contentType.includes('text/')) {\n\t\t\t\t\tbody = await clonedRequest.text();\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Ignore body parsing errors\n\t\t\t}\n\t\t}\n\n\t\tconst ip = c.req.header('x-forwarded-for') || c.req.header('x-real-ip');\n\n\t\ttry {\n\t\t\tawait next();\n\n\t\t\t// Capture response data\n\t\t\tconst duration = performance.now() - startTime;\n\n\t\t\tconst responseHeaders: Record<string, string> = {};\n\t\t\tc.res.headers.forEach((value, key) => {\n\t\t\t\tresponseHeaders[key] = value;\n\t\t\t});\n\n\t\t\tlet responseBody: unknown;\n\t\t\tlet responseSize: number | undefined;\n\n\t\t\t// Get response size - prefer Content-Length header, fallback to body size\n\t\t\tconst responseContentLength = c.res.headers.get('content-length');\n\t\t\tif (responseContentLength) {\n\t\t\t\tresponseSize = parseInt(responseContentLength, 10);\n\t\t\t}\n\n\t\t\tif (telescope.recordBody) {\n\t\t\t\ttry {\n\t\t\t\t\tconst contentType = c.res.headers.get('content-type') || '';\n\t\t\t\t\tif (contentType.includes('application/json')) {\n\t\t\t\t\t\tconst cloned = c.res.clone();\n\t\t\t\t\t\tconst text = await cloned.text();\n\t\t\t\t\t\tresponseSize ??= Buffer.byteLength(text, 'utf8');\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponseBody = JSON.parse(text);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tresponseBody = text;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore body parsing errors\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst requestId = await telescope.recordRequest({\n\t\t\t\tmethod: c.req.method,\n\t\t\t\tpath: c.req.path,\n\t\t\t\turl: c.req.url,\n\t\t\t\theaders,\n\t\t\t\tbody,\n\t\t\t\tquery,\n\t\t\t\tstatus: c.res.status,\n\t\t\t\tresponseHeaders,\n\t\t\t\tresponseBody,\n\t\t\t\tduration,\n\t\t\t\tip,\n\t\t\t\trequestSize,\n\t\t\t\tresponseSize,\n\t\t\t});\n\n\t\t\t// Store context for access by other middleware\n\t\t\tconst ctx: TelescopeHonoContext = {\n\t\t\t\trequestId,\n\t\t\t\tstartTime,\n\t\t\t};\n\t\t\tc.set(CONTEXT_KEY, ctx);\n\n\t\t\t// Flush telemetry for serverless environments\n\t\t\tif (flushOnResponse) {\n\t\t\t\tconst flushTelemetry = await getFlushTelemetry();\n\t\t\t\tawait flushTelemetry();\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tawait telescope.exception(error as Error);\n\t\t\tthrow error;\n\t\t}\n\t};\n}\n\n/**\n * Parse query options from Hono context\n */\nfunction parseQueryOptions(c: Context): QueryOptions {\n\tconst limit = parseInt(c.req.query('limit') || '50', 10);\n\tconst offset = parseInt(c.req.query('offset') || '0', 10);\n\tconst search = c.req.query('search');\n\tconst before = c.req.query('before');\n\tconst after = c.req.query('after');\n\tconst tags = c.req.query('tags')?.split(',').filter(Boolean);\n\tconst method = c.req.query('method');\n\tconst status = c.req.query('status');\n\tconst level = c.req.query('level') as\n\t\t| 'debug'\n\t\t| 'info'\n\t\t| 'warn'\n\t\t| 'error'\n\t\t| undefined;\n\n\treturn {\n\t\tlimit: Math.min(limit, 100),\n\t\toffset,\n\t\tsearch,\n\t\tbefore: before ? new Date(before) : undefined,\n\t\tafter: after ? new Date(after) : undefined,\n\t\ttags,\n\t\tmethod: method || undefined,\n\t\tstatus: status || undefined,\n\t\tlevel: level || undefined,\n\t};\n}\n\n/**\n * Parse metrics query options from Hono context\n */\nfunction parseMetricsQueryOptions(c: Context): MetricsQueryOptions {\n\tconst start = c.req.query('start');\n\tconst end = c.req.query('end');\n\tconst bucketSize = c.req.query('bucketSize');\n\tconst limit = c.req.query('limit');\n\n\treturn {\n\t\trange:\n\t\t\tstart && end ? { start: new Date(start), end: new Date(end) } : undefined,\n\t\tbucketSize: bucketSize ? parseInt(bucketSize, 10) : undefined,\n\t\tlimit: limit ? parseInt(limit, 10) : undefined,\n\t};\n}\n\n/**\n * Telescope's JSON API: requests, exceptions, logs, stats and metrics under\n * `/api/*`. Headless — there is no dashboard; anything can be built on the\n * JSON, and live updates come from the WebSocket feed (`setupWebSocket`).\n *\n * @example\n * ```typescript\n * app.route('/__telescope', createApi(telescope));\n * // GET /__telescope/api/requests\n * ```\n */\nexport function createApi(telescope: Telescope): Hono {\n\tconst app = new Hono();\n\n\t// API routes\n\tapp.get('/api/requests', async (c) => {\n\t\tconst options = parseQueryOptions(c);\n\t\tconst requests = await telescope.getRequests(options);\n\t\treturn c.json(requests);\n\t});\n\n\tapp.get('/api/requests/:id', async (c) => {\n\t\tconst request = await telescope.getRequest(c.req.param('id'));\n\t\tif (!request) {\n\t\t\treturn c.json({ error: 'Request not found' }, 404);\n\t\t}\n\t\treturn c.json(request);\n\t});\n\n\tapp.get('/api/exceptions', async (c) => {\n\t\tconst options = parseQueryOptions(c);\n\t\tconst exceptions = await telescope.getExceptions(options);\n\t\treturn c.json(exceptions);\n\t});\n\n\tapp.get('/api/exceptions/:id', async (c) => {\n\t\tconst exception = await telescope.getException(c.req.param('id'));\n\t\tif (!exception) {\n\t\t\treturn c.json({ error: 'Exception not found' }, 404);\n\t\t}\n\t\treturn c.json(exception);\n\t});\n\n\tapp.get('/api/logs', async (c) => {\n\t\tconst options = parseQueryOptions(c);\n\t\tconst logs = await telescope.getLogs(options);\n\t\treturn c.json(logs);\n\t});\n\n\tapp.get('/api/stats', async (c) => {\n\t\tconst stats = await telescope.getStats();\n\t\treturn c.json(stats);\n\t});\n\n\t// Metrics API\n\tapp.get('/api/metrics', (c) => {\n\t\tconst options = parseMetricsQueryOptions(c);\n\t\tconst metrics = telescope.getMetrics(options);\n\t\treturn c.json(metrics);\n\t});\n\n\tapp.get('/api/metrics/endpoints', (c) => {\n\t\tconst options = parseMetricsQueryOptions(c);\n\t\tconst endpoints = telescope.getEndpointMetrics(options);\n\t\treturn c.json(endpoints);\n\t});\n\n\t// Endpoint details - method and path are query params to avoid URL encoding issues\n\tapp.get('/api/metrics/endpoint', (c) => {\n\t\tconst method = c.req.query('method');\n\t\tconst path = c.req.query('path');\n\n\t\tif (!method || !path) {\n\t\t\treturn c.json({ error: 'method and path are required' }, 400);\n\t\t}\n\n\t\tconst options = parseMetricsQueryOptions(c);\n\t\tconst details = telescope.getEndpointDetails(method, path, options);\n\n\t\tif (!details) {\n\t\t\treturn c.json({ error: 'Endpoint not found' }, 404);\n\t\t}\n\n\t\treturn c.json(details);\n\t});\n\n\tapp.get('/api/metrics/status', (c) => {\n\t\tconst options = parseMetricsQueryOptions(c);\n\t\tconst distribution = telescope.getStatusDistribution(options);\n\t\treturn c.json(distribution);\n\t});\n\n\tapp.delete('/api/metrics', (c) => {\n\t\ttelescope.resetMetrics();\n\t\treturn c.json({ success: true });\n\t});\n\n\treturn app;\n}\n\n/**\n * Options for setupWebSocket\n */\nexport interface WebSocketOptions {\n\t/**\n\t * Enable real-time metrics broadcasting (default: true)\n\t */\n\tbroadcastMetrics?: boolean;\n\t/**\n\t * Metrics broadcast interval in milliseconds (default: 5000)\n\t */\n\tmetricsBroadcastInterval?: number;\n}\n\n/**\n * Set up WebSocket routes for real-time updates.\n * Requires @hono/node-ws for Node.js or Bun's built-in WebSocket.\n */\nexport function setupWebSocket(\n\tapp: Hono,\n\ttelescope: Telescope,\n\tupgradeWebSocket: (handler: any) => any,\n\toptions: WebSocketOptions = {},\n): void {\n\tconst { broadcastMetrics = true, metricsBroadcastInterval = 5000 } = options;\n\n\t// Start metrics broadcast if enabled\n\tif (broadcastMetrics) {\n\t\ttelescope.startMetricsBroadcast(metricsBroadcastInterval);\n\t}\n\n\tapp.get(\n\t\t'/ws',\n\t\tupgradeWebSocket(() => ({\n\t\t\tonOpen: (_event: Event, ws: WebSocket) => {\n\t\t\t\ttelescope.addWsClient(ws);\n\t\t\t},\n\t\t\tonClose: (_event: Event, ws: WebSocket) => {\n\t\t\t\ttelescope.removeWsClient(ws);\n\t\t\t},\n\t\t\tonMessage: (event: MessageEvent, ws: WebSocket) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst data = JSON.parse(event.data);\n\t\t\t\t\tif (data.type === 'ping') {\n\t\t\t\t\t\tws.send(JSON.stringify({ type: 'pong' }));\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore invalid messages\n\t\t\t\t}\n\t\t\t},\n\t\t})),\n\t);\n}\n\n/**\n * Get the Telescope context from Hono context (set by middleware)\n */\nexport function getTelescopeContext(\n\tc: Context,\n): TelescopeHonoContext | undefined {\n\treturn c.get(CONTEXT_KEY);\n}\n\n/**\n * Get the request ID from Hono context (set by middleware)\n */\nexport function getRequestId(c: Context): string | undefined {\n\treturn getTelescopeContext(c)?.requestId;\n}\n\n// Re-export types and utilities\nexport type { Telescope };\nexport type {\n\tHonoAdapterConfig,\n\tTelescopeHonoContext,\n} from '../adapters/types';\n\n/**\n * Get the flushTelemetry function (lazy-loaded to avoid requiring @opentelemetry/* at import time).\n * Use this for serverless environments where you need to flush telemetry before the process freezes.\n *\n * @example\n * ```typescript\n * const flushTelemetry = await getFlushTelemetryFn();\n * await flushTelemetry();\n * ```\n */\nexport { getFlushTelemetry as getFlushTelemetryFn };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"hono.cjs","names":["_flushTelemetry: (() => Promise<void>) | null","telescope: Telescope","options: TelescopeMiddlewareOptions","c: Context","next: Next","headers: Record<string, string>","query: Record<string, string>","body: unknown","requestSize: number | undefined","responseHeaders: Record<string, string>","responseBody: unknown","responseSize: number | undefined","ctx: TelescopeHonoContext","Hono","app: Hono","upgradeWebSocket: (handler: any) => any","options: WebSocketOptions","_event: Event","ws: WebSocket","event: MessageEvent"],"sources":["../../src/server/hono.ts"],"sourcesContent":["import type { Context, MiddlewareHandler, Next } from 'hono';\nimport { Hono } from 'hono';\nimport type {\n\tHonoAdapterConfig,\n\tTelescopeHonoContext,\n} from '../adapters/types';\nimport type { Telescope } from '../Telescope';\nimport type { MetricsQueryOptions, QueryOptions } from '../types';\nimport { getAsset, getIndexHtml } from '../ui-assets';\n\n// Lazy-loaded telemetry flush function (only loads @opentelemetry/* when actually used)\nlet _flushTelemetry: (() => Promise<void>) | null = null;\nasync function getFlushTelemetry(): Promise<() => Promise<void>> {\n\tif (!_flushTelemetry) {\n\t\tconst { flushTelemetry } = await import('../instrumentation/core');\n\t\t_flushTelemetry = flushTelemetry;\n\t}\n\treturn _flushTelemetry;\n}\n\nconst CONTEXT_KEY = 'telescope-context';\n\n/** Default Hono adapter configuration */\nconst _DEFAULT_CONFIG: HonoAdapterConfig = {\n\tenvironment: 'server',\n};\n\n/**\n * Options for the Telescope Hono middleware\n */\nexport interface TelescopeMiddlewareOptions {\n\t/**\n\t * Whether to flush telemetry after each request.\n\t * Enable this for serverless environments (Lambda, Edge).\n\t * @default false\n\t */\n\tflushOnResponse?: boolean;\n}\n\n/**\n * Create Hono middleware that captures requests and responses\n */\nexport function createMiddleware(\n\ttelescope: Telescope,\n\toptions: TelescopeMiddlewareOptions = {},\n): MiddlewareHandler {\n\tconst { flushOnResponse = false } = options;\n\n\treturn async (c: Context, next: Next) => {\n\t\tif (!telescope.enabled) {\n\t\t\treturn next();\n\t\t}\n\n\t\tif (telescope.shouldIgnore(c.req.path)) {\n\t\t\treturn next();\n\t\t}\n\n\t\tconst startTime = performance.now();\n\n\t\t// Capture request data\n\t\tconst headers: Record<string, string> = {};\n\t\tc.req.raw.headers.forEach((value, key) => {\n\t\t\theaders[key] = value;\n\t\t});\n\n\t\tconst url = new URL(c.req.url);\n\t\tconst query: Record<string, string> = {};\n\t\turl.searchParams.forEach((value, key) => {\n\t\t\tquery[key] = value;\n\t\t});\n\n\t\tlet body: unknown;\n\t\tlet requestSize: number | undefined;\n\n\t\t// Get request size from Content-Length header\n\t\tconst contentLength = c.req.header('content-length');\n\t\tif (contentLength) {\n\t\t\trequestSize = parseInt(contentLength, 10);\n\t\t}\n\n\t\tif (\n\t\t\ttelescope.recordBody &&\n\t\t\t['POST', 'PUT', 'PATCH'].includes(c.req.method)\n\t\t) {\n\t\t\ttry {\n\t\t\t\tconst contentType = c.req.header('content-type') || '';\n\t\t\t\t// Clone the request to avoid consuming the body stream\n\t\t\t\tconst clonedRequest = c.req.raw.clone();\n\t\t\t\tif (contentType.includes('application/json')) {\n\t\t\t\t\tbody = await clonedRequest.json();\n\t\t\t\t} else if (contentType.includes('application/x-www-form-urlencoded')) {\n\t\t\t\t\tbody = Object.fromEntries((await clonedRequest.formData()).entries());\n\t\t\t\t} else if (contentType.includes('text/')) {\n\t\t\t\t\tbody = await clonedRequest.text();\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Ignore body parsing errors\n\t\t\t}\n\t\t}\n\n\t\tconst ip = c.req.header('x-forwarded-for') || c.req.header('x-real-ip');\n\n\t\ttry {\n\t\t\tawait next();\n\n\t\t\t// Capture response data\n\t\t\tconst duration = performance.now() - startTime;\n\n\t\t\tconst responseHeaders: Record<string, string> = {};\n\t\t\tc.res.headers.forEach((value, key) => {\n\t\t\t\tresponseHeaders[key] = value;\n\t\t\t});\n\n\t\t\tlet responseBody: unknown;\n\t\t\tlet responseSize: number | undefined;\n\n\t\t\t// Get response size - prefer Content-Length header, fallback to body size\n\t\t\tconst responseContentLength = c.res.headers.get('content-length');\n\t\t\tif (responseContentLength) {\n\t\t\t\tresponseSize = parseInt(responseContentLength, 10);\n\t\t\t}\n\n\t\t\tif (telescope.recordBody) {\n\t\t\t\ttry {\n\t\t\t\t\tconst contentType = c.res.headers.get('content-type') || '';\n\t\t\t\t\tif (contentType.includes('application/json')) {\n\t\t\t\t\t\tconst cloned = c.res.clone();\n\t\t\t\t\t\tconst text = await cloned.text();\n\t\t\t\t\t\tresponseSize ??= Buffer.byteLength(text, 'utf8');\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponseBody = JSON.parse(text);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tresponseBody = text;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore body parsing errors\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst requestId = await telescope.recordRequest({\n\t\t\t\tmethod: c.req.method,\n\t\t\t\tpath: c.req.path,\n\t\t\t\turl: c.req.url,\n\t\t\t\theaders,\n\t\t\t\tbody,\n\t\t\t\tquery,\n\t\t\t\tstatus: c.res.status,\n\t\t\t\tresponseHeaders,\n\t\t\t\tresponseBody,\n\t\t\t\tduration,\n\t\t\t\tip,\n\t\t\t\trequestSize,\n\t\t\t\tresponseSize,\n\t\t\t});\n\n\t\t\t// Store context for access by other middleware\n\t\t\tconst ctx: TelescopeHonoContext = {\n\t\t\t\trequestId,\n\t\t\t\tstartTime,\n\t\t\t};\n\t\t\tc.set(CONTEXT_KEY, ctx);\n\n\t\t\t// Flush telemetry for serverless environments\n\t\t\tif (flushOnResponse) {\n\t\t\t\tconst flushTelemetry = await getFlushTelemetry();\n\t\t\t\tawait flushTelemetry();\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tawait telescope.exception(error as Error);\n\t\t\tthrow error;\n\t\t}\n\t};\n}\n\n/**\n * Parse query options from Hono context\n */\nfunction parseQueryOptions(c: Context): QueryOptions {\n\tconst limit = parseInt(c.req.query('limit') || '50', 10);\n\tconst offset = parseInt(c.req.query('offset') || '0', 10);\n\tconst search = c.req.query('search');\n\tconst before = c.req.query('before');\n\tconst after = c.req.query('after');\n\tconst tags = c.req.query('tags')?.split(',').filter(Boolean);\n\tconst method = c.req.query('method');\n\tconst status = c.req.query('status');\n\tconst level = c.req.query('level') as\n\t\t| 'debug'\n\t\t| 'info'\n\t\t| 'warn'\n\t\t| 'error'\n\t\t| undefined;\n\n\treturn {\n\t\tlimit: Math.min(limit, 100),\n\t\toffset,\n\t\tsearch,\n\t\tbefore: before ? new Date(before) : undefined,\n\t\tafter: after ? new Date(after) : undefined,\n\t\ttags,\n\t\tmethod: method || undefined,\n\t\tstatus: status || undefined,\n\t\tlevel: level || undefined,\n\t};\n}\n\n/**\n * Parse metrics query options from Hono context\n */\nfunction parseMetricsQueryOptions(c: Context): MetricsQueryOptions {\n\tconst start = c.req.query('start');\n\tconst end = c.req.query('end');\n\tconst bucketSize = c.req.query('bucketSize');\n\tconst limit = c.req.query('limit');\n\n\treturn {\n\t\trange:\n\t\t\tstart && end ? { start: new Date(start), end: new Date(end) } : undefined,\n\t\tbucketSize: bucketSize ? parseInt(bucketSize, 10) : undefined,\n\t\tlimit: limit ? parseInt(limit, 10) : undefined,\n\t};\n}\n\n/**\n * Create Hono app with dashboard UI and API routes\n */\nexport function createUI(telescope: Telescope): Hono {\n\tconst app = new Hono();\n\n\t// API routes\n\tapp.get('/api/requests', async (c) => {\n\t\tconst options = parseQueryOptions(c);\n\t\tconst requests = await telescope.getRequests(options);\n\t\treturn c.json(requests);\n\t});\n\n\tapp.get('/api/requests/:id', async (c) => {\n\t\tconst request = await telescope.getRequest(c.req.param('id'));\n\t\tif (!request) {\n\t\t\treturn c.json({ error: 'Request not found' }, 404);\n\t\t}\n\t\treturn c.json(request);\n\t});\n\n\tapp.get('/api/exceptions', async (c) => {\n\t\tconst options = parseQueryOptions(c);\n\t\tconst exceptions = await telescope.getExceptions(options);\n\t\treturn c.json(exceptions);\n\t});\n\n\tapp.get('/api/exceptions/:id', async (c) => {\n\t\tconst exception = await telescope.getException(c.req.param('id'));\n\t\tif (!exception) {\n\t\t\treturn c.json({ error: 'Exception not found' }, 404);\n\t\t}\n\t\treturn c.json(exception);\n\t});\n\n\tapp.get('/api/logs', async (c) => {\n\t\tconst options = parseQueryOptions(c);\n\t\tconst logs = await telescope.getLogs(options);\n\t\treturn c.json(logs);\n\t});\n\n\tapp.get('/api/stats', async (c) => {\n\t\tconst stats = await telescope.getStats();\n\t\treturn c.json(stats);\n\t});\n\n\t// Metrics API\n\tapp.get('/api/metrics', (c) => {\n\t\tconst options = parseMetricsQueryOptions(c);\n\t\tconst metrics = telescope.getMetrics(options);\n\t\treturn c.json(metrics);\n\t});\n\n\tapp.get('/api/metrics/endpoints', (c) => {\n\t\tconst options = parseMetricsQueryOptions(c);\n\t\tconst endpoints = telescope.getEndpointMetrics(options);\n\t\treturn c.json(endpoints);\n\t});\n\n\t// Endpoint details - method and path are query params to avoid URL encoding issues\n\tapp.get('/api/metrics/endpoint', (c) => {\n\t\tconst method = c.req.query('method');\n\t\tconst path = c.req.query('path');\n\n\t\tif (!method || !path) {\n\t\t\treturn c.json({ error: 'method and path are required' }, 400);\n\t\t}\n\n\t\tconst options = parseMetricsQueryOptions(c);\n\t\tconst details = telescope.getEndpointDetails(method, path, options);\n\n\t\tif (!details) {\n\t\t\treturn c.json({ error: 'Endpoint not found' }, 404);\n\t\t}\n\n\t\treturn c.json(details);\n\t});\n\n\tapp.get('/api/metrics/status', (c) => {\n\t\tconst options = parseMetricsQueryOptions(c);\n\t\tconst distribution = telescope.getStatusDistribution(options);\n\t\treturn c.json(distribution);\n\t});\n\n\tapp.delete('/api/metrics', (c) => {\n\t\ttelescope.resetMetrics();\n\t\treturn c.json({ success: true });\n\t});\n\n\t// Static assets\n\tapp.get('/assets/:filename', (c) => {\n\t\tconst filename = c.req.param('filename');\n\t\tconst assetPath = `assets/${filename}`;\n\t\tconst asset = getAsset(assetPath);\n\t\tif (asset) {\n\t\t\treturn c.body(asset.content, 200, {\n\t\t\t\t'Content-Type': asset.contentType,\n\t\t\t\t'Cache-Control': 'public, max-age=31536000, immutable',\n\t\t\t});\n\t\t}\n\t\treturn c.notFound();\n\t});\n\n\t// Dashboard UI - serve React app\n\tapp.get('/', (c) => {\n\t\tconst html = getIndexHtml();\n\t\tif (!html) {\n\t\t\treturn c.text(\n\t\t\t\t'Telescope UI not available. Run \"pnpm build:ui\" first.',\n\t\t\t\t500,\n\t\t\t);\n\t\t}\n\t\treturn c.html(html);\n\t});\n\n\tapp.get('/*', (c) => {\n\t\t// SPA fallback - serve index.html for client-side routing\n\t\tconst html = getIndexHtml();\n\t\tif (!html) {\n\t\t\treturn c.text(\n\t\t\t\t'Telescope UI not available. Run \"pnpm build:ui\" first.',\n\t\t\t\t500,\n\t\t\t);\n\t\t}\n\t\treturn c.html(html);\n\t});\n\n\treturn app;\n}\n\n/**\n * Options for setupWebSocket\n */\nexport interface WebSocketOptions {\n\t/**\n\t * Enable real-time metrics broadcasting (default: true)\n\t */\n\tbroadcastMetrics?: boolean;\n\t/**\n\t * Metrics broadcast interval in milliseconds (default: 5000)\n\t */\n\tmetricsBroadcastInterval?: number;\n}\n\n/**\n * Set up WebSocket routes for real-time updates.\n * Requires @hono/node-ws for Node.js or Bun's built-in WebSocket.\n */\nexport function setupWebSocket(\n\tapp: Hono,\n\ttelescope: Telescope,\n\tupgradeWebSocket: (handler: any) => any,\n\toptions: WebSocketOptions = {},\n): void {\n\tconst { broadcastMetrics = true, metricsBroadcastInterval = 5000 } = options;\n\n\t// Start metrics broadcast if enabled\n\tif (broadcastMetrics) {\n\t\ttelescope.startMetricsBroadcast(metricsBroadcastInterval);\n\t}\n\n\tapp.get(\n\t\t'/ws',\n\t\tupgradeWebSocket(() => ({\n\t\t\tonOpen: (_event: Event, ws: WebSocket) => {\n\t\t\t\ttelescope.addWsClient(ws);\n\t\t\t},\n\t\t\tonClose: (_event: Event, ws: WebSocket) => {\n\t\t\t\ttelescope.removeWsClient(ws);\n\t\t\t},\n\t\t\tonMessage: (event: MessageEvent, ws: WebSocket) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst data = JSON.parse(event.data);\n\t\t\t\t\tif (data.type === 'ping') {\n\t\t\t\t\t\tws.send(JSON.stringify({ type: 'pong' }));\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore invalid messages\n\t\t\t\t}\n\t\t\t},\n\t\t})),\n\t);\n}\n\n/**\n * Get the Telescope context from Hono context (set by middleware)\n */\nexport function getTelescopeContext(\n\tc: Context,\n): TelescopeHonoContext | undefined {\n\treturn c.get(CONTEXT_KEY);\n}\n\n/**\n * Get the request ID from Hono context (set by middleware)\n */\nexport function getRequestId(c: Context): string | undefined {\n\treturn getTelescopeContext(c)?.requestId;\n}\n\n// Re-export types and utilities\nexport type { Telescope };\nexport type {\n\tHonoAdapterConfig,\n\tTelescopeHonoContext,\n} from '../adapters/types';\n\n/**\n * Get the flushTelemetry function (lazy-loaded to avoid requiring @opentelemetry/* at import time).\n * Use this for serverless environments where you need to flush telemetry before the process freezes.\n *\n * @example\n * ```typescript\n * const flushTelemetry = await getFlushTelemetryFn();\n * await flushTelemetry();\n * ```\n */\nexport { getFlushTelemetry as getFlushTelemetryFn };\n"],"mappings":"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"}
|
package/dist/server/hono.d.cts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import "../types-l7Rlb5Mg.cjs";
|
|
2
|
+
import "../MetricsAggregator-4SqelGcG.cjs";
|
|
3
|
+
import { Telescope } from "../Telescope-D4nmwDRA.cjs";
|
|
4
|
+
import { HonoAdapterConfig, TelescopeHonoContext } from "../types-BRzW1NM8.cjs";
|
|
3
5
|
import { Context, Hono, MiddlewareHandler } from "hono";
|
|
6
|
+
|
|
4
7
|
//#region src/server/hono.d.ts
|
|
5
8
|
declare function getFlushTelemetry(): Promise<() => Promise<void>>;
|
|
6
9
|
/**
|
|
7
10
|
* Options for the Telescope Hono middleware
|
|
8
11
|
*/
|
|
9
|
-
|
|
12
|
+
interface TelescopeMiddlewareOptions {
|
|
10
13
|
/**
|
|
11
14
|
* Whether to flush telemetry after each request.
|
|
12
15
|
* Enable this for serverless environments (Lambda, Edge).
|
|
@@ -17,23 +20,15 @@ export interface TelescopeMiddlewareOptions {
|
|
|
17
20
|
/**
|
|
18
21
|
* Create Hono middleware that captures requests and responses
|
|
19
22
|
*/
|
|
20
|
-
|
|
23
|
+
declare function createMiddleware(telescope: Telescope, options?: TelescopeMiddlewareOptions): MiddlewareHandler;
|
|
21
24
|
/**
|
|
22
|
-
*
|
|
23
|
-
* `/api/*`. Headless — there is no dashboard; anything can be built on the
|
|
24
|
-
* JSON, and live updates come from the WebSocket feed (`setupWebSocket`).
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* ```typescript
|
|
28
|
-
* app.route('/__telescope', createApi(telescope));
|
|
29
|
-
* // GET /__telescope/api/requests
|
|
30
|
-
* ```
|
|
25
|
+
* Create Hono app with dashboard UI and API routes
|
|
31
26
|
*/
|
|
32
|
-
|
|
27
|
+
declare function createUI(telescope: Telescope): Hono;
|
|
33
28
|
/**
|
|
34
29
|
* Options for setupWebSocket
|
|
35
30
|
*/
|
|
36
|
-
|
|
31
|
+
interface WebSocketOptions {
|
|
37
32
|
/**
|
|
38
33
|
* Enable real-time metrics broadcasting (default: true)
|
|
39
34
|
*/
|
|
@@ -47,15 +42,15 @@ export interface WebSocketOptions {
|
|
|
47
42
|
* Set up WebSocket routes for real-time updates.
|
|
48
43
|
* Requires @hono/node-ws for Node.js or Bun's built-in WebSocket.
|
|
49
44
|
*/
|
|
50
|
-
|
|
45
|
+
declare function setupWebSocket(app: Hono, telescope: Telescope, upgradeWebSocket: (handler: any) => any, options?: WebSocketOptions): void;
|
|
51
46
|
/**
|
|
52
47
|
* Get the Telescope context from Hono context (set by middleware)
|
|
53
48
|
*/
|
|
54
|
-
|
|
49
|
+
declare function getTelescopeContext(c: Context): TelescopeHonoContext | undefined;
|
|
55
50
|
/**
|
|
56
51
|
* Get the request ID from Hono context (set by middleware)
|
|
57
52
|
*/
|
|
58
|
-
|
|
53
|
+
declare function getRequestId(c: Context): string | undefined;
|
|
59
54
|
//#endregion
|
|
60
|
-
export {
|
|
55
|
+
export { HonoAdapterConfig, Telescope, TelescopeHonoContext, TelescopeMiddlewareOptions, WebSocketOptions, createMiddleware, createUI, getFlushTelemetry as getFlushTelemetryFn, getRequestId, getTelescopeContext, setupWebSocket };
|
|
61
56
|
//# sourceMappingURL=hono.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hono.d.cts","names":[],"sources":["../../src/server/hono.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"hono.d.cts","names":[],"sources":["../../src/server/hono.ts"],"sourcesContent":[],"mappings":";;;;;;;iBAYe,iBAAA,CAAA,GAAqB,cAAc;;;AANJ;AAMd,UAkBf,0BAAA,CAlBe;EAAA;;AAAW;AAkB3C;AAYA;EAAgC,eAAA,CAAA,EAAA,OAAA;;;;AAGZ;AAsLJ,iBAzLA,gBAAA,CAyLQ,SAAA,EAxLZ,SAwLY,EAAA,OAAA,CAAA,EAvLd,0BAuLc,CAAA,EAtLrB,iBAsLqB;;;;AAA4B,iBAApC,QAAA,CAAoC,SAAA,EAAhB,SAAgB,CAAA,EAAJ,IAAI;AAkIpD;AAeA;;AACM,UAhBW,gBAAA,CAgBX;EAAI;;AAGqB;EAmCf,gBAAA,CAAA,EAAA,OAAmB;EAAA;;;EAEZ,wBAAA,CAAA,EAAA,MAAA;AAOvB;;;;;iBAhDgB,cAAA,MACV,iBACM,8DAEF;;;;iBAmCM,mBAAA,IACZ,UACD;;;;iBAOa,YAAA,IAAgB"}
|
package/dist/server/hono.d.mts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import "../types-B1EIa_cQ.mjs";
|
|
2
|
+
import "../MetricsAggregator-DZrW8ls6.mjs";
|
|
3
|
+
import { Telescope } from "../Telescope-Dl6VSfxd.mjs";
|
|
4
|
+
import { HonoAdapterConfig, TelescopeHonoContext } from "../types-BzQ78Efw.mjs";
|
|
3
5
|
import { Context, Hono, MiddlewareHandler } from "hono";
|
|
6
|
+
|
|
4
7
|
//#region src/server/hono.d.ts
|
|
5
8
|
declare function getFlushTelemetry(): Promise<() => Promise<void>>;
|
|
6
9
|
/**
|
|
7
10
|
* Options for the Telescope Hono middleware
|
|
8
11
|
*/
|
|
9
|
-
|
|
12
|
+
interface TelescopeMiddlewareOptions {
|
|
10
13
|
/**
|
|
11
14
|
* Whether to flush telemetry after each request.
|
|
12
15
|
* Enable this for serverless environments (Lambda, Edge).
|
|
@@ -17,23 +20,15 @@ export interface TelescopeMiddlewareOptions {
|
|
|
17
20
|
/**
|
|
18
21
|
* Create Hono middleware that captures requests and responses
|
|
19
22
|
*/
|
|
20
|
-
|
|
23
|
+
declare function createMiddleware(telescope: Telescope, options?: TelescopeMiddlewareOptions): MiddlewareHandler;
|
|
21
24
|
/**
|
|
22
|
-
*
|
|
23
|
-
* `/api/*`. Headless — there is no dashboard; anything can be built on the
|
|
24
|
-
* JSON, and live updates come from the WebSocket feed (`setupWebSocket`).
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* ```typescript
|
|
28
|
-
* app.route('/__telescope', createApi(telescope));
|
|
29
|
-
* // GET /__telescope/api/requests
|
|
30
|
-
* ```
|
|
25
|
+
* Create Hono app with dashboard UI and API routes
|
|
31
26
|
*/
|
|
32
|
-
|
|
27
|
+
declare function createUI(telescope: Telescope): Hono;
|
|
33
28
|
/**
|
|
34
29
|
* Options for setupWebSocket
|
|
35
30
|
*/
|
|
36
|
-
|
|
31
|
+
interface WebSocketOptions {
|
|
37
32
|
/**
|
|
38
33
|
* Enable real-time metrics broadcasting (default: true)
|
|
39
34
|
*/
|
|
@@ -47,15 +42,15 @@ export interface WebSocketOptions {
|
|
|
47
42
|
* Set up WebSocket routes for real-time updates.
|
|
48
43
|
* Requires @hono/node-ws for Node.js or Bun's built-in WebSocket.
|
|
49
44
|
*/
|
|
50
|
-
|
|
45
|
+
declare function setupWebSocket(app: Hono, telescope: Telescope, upgradeWebSocket: (handler: any) => any, options?: WebSocketOptions): void;
|
|
51
46
|
/**
|
|
52
47
|
* Get the Telescope context from Hono context (set by middleware)
|
|
53
48
|
*/
|
|
54
|
-
|
|
49
|
+
declare function getTelescopeContext(c: Context): TelescopeHonoContext | undefined;
|
|
55
50
|
/**
|
|
56
51
|
* Get the request ID from Hono context (set by middleware)
|
|
57
52
|
*/
|
|
58
|
-
|
|
53
|
+
declare function getRequestId(c: Context): string | undefined;
|
|
59
54
|
//#endregion
|
|
60
|
-
export {
|
|
55
|
+
export { HonoAdapterConfig, Telescope, TelescopeHonoContext, TelescopeMiddlewareOptions, WebSocketOptions, createMiddleware, createUI, getFlushTelemetry as getFlushTelemetryFn, getRequestId, getTelescopeContext, setupWebSocket };
|
|
61
56
|
//# sourceMappingURL=hono.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hono.d.mts","names":[],"sources":["../../src/server/hono.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"hono.d.mts","names":[],"sources":["../../src/server/hono.ts"],"sourcesContent":[],"mappings":";;;;;;;iBAYe,iBAAA,CAAA,GAAqB,cAAc;;;AANJ;AAMd,UAkBf,0BAAA,CAlBe;EAAA;;AAAW;AAkB3C;AAYA;EAAgC,eAAA,CAAA,EAAA,OAAA;;;;AAGZ;AAsLJ,iBAzLA,gBAAA,CAyLQ,SAAA,EAxLZ,SAwLY,EAAA,OAAA,CAAA,EAvLd,0BAuLc,CAAA,EAtLrB,iBAsLqB;;;;AAA4B,iBAApC,QAAA,CAAoC,SAAA,EAAhB,SAAgB,CAAA,EAAJ,IAAI;AAkIpD;AAeA;;AACM,UAhBW,gBAAA,CAgBX;EAAI;;AAGqB;EAmCf,gBAAA,CAAA,EAAA,OAAmB;EAAA;;;EAEZ,wBAAA,CAAA,EAAA,MAAA;AAOvB;;;;;iBAhDgB,cAAA,MACV,iBACM,8DAEF;;;;iBAmCM,mBAAA,IACZ,UACD;;;;iBAOa,YAAA,IAAgB"}
|
package/dist/server/hono.mjs
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { getAsset, getIndexHtml } from "../ui-assets-BhTDUsrM.mjs";
|
|
1
2
|
import { Hono } from "hono";
|
|
3
|
+
|
|
2
4
|
//#region src/server/hono.ts
|
|
3
5
|
let _flushTelemetry = null;
|
|
4
6
|
async function getFlushTelemetry() {
|
|
@@ -55,8 +57,10 @@ function createMiddleware(telescope, options = {}) {
|
|
|
55
57
|
const responseContentLength = c.res.headers.get("content-length");
|
|
56
58
|
if (responseContentLength) responseSize = parseInt(responseContentLength, 10);
|
|
57
59
|
if (telescope.recordBody) try {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
+
const contentType = c.res.headers.get("content-type") || "";
|
|
61
|
+
if (contentType.includes("application/json")) {
|
|
62
|
+
const cloned = c.res.clone();
|
|
63
|
+
const text = await cloned.text();
|
|
60
64
|
responseSize ??= Buffer.byteLength(text, "utf8");
|
|
61
65
|
try {
|
|
62
66
|
responseBody = JSON.parse(text);
|
|
@@ -65,26 +69,30 @@ function createMiddleware(telescope, options = {}) {
|
|
|
65
69
|
}
|
|
66
70
|
}
|
|
67
71
|
} catch {}
|
|
72
|
+
const requestId = await telescope.recordRequest({
|
|
73
|
+
method: c.req.method,
|
|
74
|
+
path: c.req.path,
|
|
75
|
+
url: c.req.url,
|
|
76
|
+
headers,
|
|
77
|
+
body,
|
|
78
|
+
query,
|
|
79
|
+
status: c.res.status,
|
|
80
|
+
responseHeaders,
|
|
81
|
+
responseBody,
|
|
82
|
+
duration,
|
|
83
|
+
ip,
|
|
84
|
+
requestSize,
|
|
85
|
+
responseSize
|
|
86
|
+
});
|
|
68
87
|
const ctx = {
|
|
69
|
-
requestId
|
|
70
|
-
method: c.req.method,
|
|
71
|
-
path: c.req.path,
|
|
72
|
-
url: c.req.url,
|
|
73
|
-
headers,
|
|
74
|
-
body,
|
|
75
|
-
query,
|
|
76
|
-
status: c.res.status,
|
|
77
|
-
responseHeaders,
|
|
78
|
-
responseBody,
|
|
79
|
-
duration,
|
|
80
|
-
ip,
|
|
81
|
-
requestSize,
|
|
82
|
-
responseSize
|
|
83
|
-
}),
|
|
88
|
+
requestId,
|
|
84
89
|
startTime
|
|
85
90
|
};
|
|
86
91
|
c.set(CONTEXT_KEY, ctx);
|
|
87
|
-
if (flushOnResponse)
|
|
92
|
+
if (flushOnResponse) {
|
|
93
|
+
const flushTelemetry = await getFlushTelemetry();
|
|
94
|
+
await flushTelemetry();
|
|
95
|
+
}
|
|
88
96
|
} catch (error) {
|
|
89
97
|
await telescope.exception(error);
|
|
90
98
|
throw error;
|
|
@@ -134,17 +142,9 @@ function parseMetricsQueryOptions(c) {
|
|
|
134
142
|
};
|
|
135
143
|
}
|
|
136
144
|
/**
|
|
137
|
-
*
|
|
138
|
-
* `/api/*`. Headless — there is no dashboard; anything can be built on the
|
|
139
|
-
* JSON, and live updates come from the WebSocket feed (`setupWebSocket`).
|
|
140
|
-
*
|
|
141
|
-
* @example
|
|
142
|
-
* ```typescript
|
|
143
|
-
* app.route('/__telescope', createApi(telescope));
|
|
144
|
-
* // GET /__telescope/api/requests
|
|
145
|
-
* ```
|
|
145
|
+
* Create Hono app with dashboard UI and API routes
|
|
146
146
|
*/
|
|
147
|
-
function
|
|
147
|
+
function createUI(telescope) {
|
|
148
148
|
const app = new Hono();
|
|
149
149
|
app.get("/api/requests", async (c) => {
|
|
150
150
|
const options = parseQueryOptions(c);
|
|
@@ -203,6 +203,26 @@ function createApi(telescope) {
|
|
|
203
203
|
telescope.resetMetrics();
|
|
204
204
|
return c.json({ success: true });
|
|
205
205
|
});
|
|
206
|
+
app.get("/assets/:filename", (c) => {
|
|
207
|
+
const filename = c.req.param("filename");
|
|
208
|
+
const assetPath = `assets/${filename}`;
|
|
209
|
+
const asset = getAsset(assetPath);
|
|
210
|
+
if (asset) return c.body(asset.content, 200, {
|
|
211
|
+
"Content-Type": asset.contentType,
|
|
212
|
+
"Cache-Control": "public, max-age=31536000, immutable"
|
|
213
|
+
});
|
|
214
|
+
return c.notFound();
|
|
215
|
+
});
|
|
216
|
+
app.get("/", (c) => {
|
|
217
|
+
const html = getIndexHtml();
|
|
218
|
+
if (!html) return c.text("Telescope UI not available. Run \"pnpm build:ui\" first.", 500);
|
|
219
|
+
return c.html(html);
|
|
220
|
+
});
|
|
221
|
+
app.get("/*", (c) => {
|
|
222
|
+
const html = getIndexHtml();
|
|
223
|
+
if (!html) return c.text("Telescope UI not available. Run \"pnpm build:ui\" first.", 500);
|
|
224
|
+
return c.html(html);
|
|
225
|
+
});
|
|
206
226
|
return app;
|
|
207
227
|
}
|
|
208
228
|
/**
|
|
@@ -221,7 +241,8 @@ function setupWebSocket(app, telescope, upgradeWebSocket, options = {}) {
|
|
|
221
241
|
},
|
|
222
242
|
onMessage: (event, ws) => {
|
|
223
243
|
try {
|
|
224
|
-
|
|
244
|
+
const data = JSON.parse(event.data);
|
|
245
|
+
if (data.type === "ping") ws.send(JSON.stringify({ type: "pong" }));
|
|
225
246
|
} catch {}
|
|
226
247
|
}
|
|
227
248
|
})));
|
|
@@ -238,7 +259,7 @@ function getTelescopeContext(c) {
|
|
|
238
259
|
function getRequestId(c) {
|
|
239
260
|
return getTelescopeContext(c)?.requestId;
|
|
240
261
|
}
|
|
241
|
-
//#endregion
|
|
242
|
-
export { createApi, createMiddleware, getFlushTelemetry as getFlushTelemetryFn, getRequestId, getTelescopeContext, setupWebSocket };
|
|
243
262
|
|
|
263
|
+
//#endregion
|
|
264
|
+
export { createMiddleware, createUI, getFlushTelemetry as getFlushTelemetryFn, getRequestId, getTelescopeContext, setupWebSocket };
|
|
244
265
|
//# sourceMappingURL=hono.mjs.map
|
package/dist/server/hono.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hono.mjs","names":[],"sources":["../../src/server/hono.ts"],"sourcesContent":["import type { Context, MiddlewareHandler, Next } from 'hono';\nimport { Hono } from 'hono';\nimport type {\n\tHonoAdapterConfig,\n\tTelescopeHonoContext,\n} from '../adapters/types';\nimport type { Telescope } from '../Telescope';\nimport type { MetricsQueryOptions, QueryOptions } from '../types';\n\n// Lazy-loaded telemetry flush function (only loads @opentelemetry/* when actually used)\nlet _flushTelemetry: (() => Promise<void>) | null = null;\nasync function getFlushTelemetry(): Promise<() => Promise<void>> {\n\tif (!_flushTelemetry) {\n\t\tconst { flushTelemetry } = await import('../instrumentation/core');\n\t\t_flushTelemetry = flushTelemetry;\n\t}\n\treturn _flushTelemetry;\n}\n\nconst CONTEXT_KEY = 'telescope-context';\n\n/** Default Hono adapter configuration */\nconst _DEFAULT_CONFIG: HonoAdapterConfig = {\n\tenvironment: 'server',\n};\n\n/**\n * Options for the Telescope Hono middleware\n */\nexport interface TelescopeMiddlewareOptions {\n\t/**\n\t * Whether to flush telemetry after each request.\n\t * Enable this for serverless environments (Lambda, Edge).\n\t * @default false\n\t */\n\tflushOnResponse?: boolean;\n}\n\n/**\n * Create Hono middleware that captures requests and responses\n */\nexport function createMiddleware(\n\ttelescope: Telescope,\n\toptions: TelescopeMiddlewareOptions = {},\n): MiddlewareHandler {\n\tconst { flushOnResponse = false } = options;\n\n\treturn async (c: Context, next: Next) => {\n\t\tif (!telescope.enabled) {\n\t\t\treturn next();\n\t\t}\n\n\t\tif (telescope.shouldIgnore(c.req.path)) {\n\t\t\treturn next();\n\t\t}\n\n\t\tconst startTime = performance.now();\n\n\t\t// Capture request data\n\t\tconst headers: Record<string, string> = {};\n\t\tc.req.raw.headers.forEach((value, key) => {\n\t\t\theaders[key] = value;\n\t\t});\n\n\t\tconst url = new URL(c.req.url);\n\t\tconst query: Record<string, string> = {};\n\t\turl.searchParams.forEach((value, key) => {\n\t\t\tquery[key] = value;\n\t\t});\n\n\t\tlet body: unknown;\n\t\tlet requestSize: number | undefined;\n\n\t\t// Get request size from Content-Length header\n\t\tconst contentLength = c.req.header('content-length');\n\t\tif (contentLength) {\n\t\t\trequestSize = parseInt(contentLength, 10);\n\t\t}\n\n\t\tif (\n\t\t\ttelescope.recordBody &&\n\t\t\t['POST', 'PUT', 'PATCH'].includes(c.req.method)\n\t\t) {\n\t\t\ttry {\n\t\t\t\tconst contentType = c.req.header('content-type') || '';\n\t\t\t\t// Clone the request to avoid consuming the body stream\n\t\t\t\tconst clonedRequest = c.req.raw.clone();\n\t\t\t\tif (contentType.includes('application/json')) {\n\t\t\t\t\tbody = await clonedRequest.json();\n\t\t\t\t} else if (contentType.includes('application/x-www-form-urlencoded')) {\n\t\t\t\t\tbody = Object.fromEntries((await clonedRequest.formData()).entries());\n\t\t\t\t} else if (contentType.includes('text/')) {\n\t\t\t\t\tbody = await clonedRequest.text();\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Ignore body parsing errors\n\t\t\t}\n\t\t}\n\n\t\tconst ip = c.req.header('x-forwarded-for') || c.req.header('x-real-ip');\n\n\t\ttry {\n\t\t\tawait next();\n\n\t\t\t// Capture response data\n\t\t\tconst duration = performance.now() - startTime;\n\n\t\t\tconst responseHeaders: Record<string, string> = {};\n\t\t\tc.res.headers.forEach((value, key) => {\n\t\t\t\tresponseHeaders[key] = value;\n\t\t\t});\n\n\t\t\tlet responseBody: unknown;\n\t\t\tlet responseSize: number | undefined;\n\n\t\t\t// Get response size - prefer Content-Length header, fallback to body size\n\t\t\tconst responseContentLength = c.res.headers.get('content-length');\n\t\t\tif (responseContentLength) {\n\t\t\t\tresponseSize = parseInt(responseContentLength, 10);\n\t\t\t}\n\n\t\t\tif (telescope.recordBody) {\n\t\t\t\ttry {\n\t\t\t\t\tconst contentType = c.res.headers.get('content-type') || '';\n\t\t\t\t\tif (contentType.includes('application/json')) {\n\t\t\t\t\t\tconst cloned = c.res.clone();\n\t\t\t\t\t\tconst text = await cloned.text();\n\t\t\t\t\t\tresponseSize ??= Buffer.byteLength(text, 'utf8');\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponseBody = JSON.parse(text);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tresponseBody = text;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore body parsing errors\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst requestId = await telescope.recordRequest({\n\t\t\t\tmethod: c.req.method,\n\t\t\t\tpath: c.req.path,\n\t\t\t\turl: c.req.url,\n\t\t\t\theaders,\n\t\t\t\tbody,\n\t\t\t\tquery,\n\t\t\t\tstatus: c.res.status,\n\t\t\t\tresponseHeaders,\n\t\t\t\tresponseBody,\n\t\t\t\tduration,\n\t\t\t\tip,\n\t\t\t\trequestSize,\n\t\t\t\tresponseSize,\n\t\t\t});\n\n\t\t\t// Store context for access by other middleware\n\t\t\tconst ctx: TelescopeHonoContext = {\n\t\t\t\trequestId,\n\t\t\t\tstartTime,\n\t\t\t};\n\t\t\tc.set(CONTEXT_KEY, ctx);\n\n\t\t\t// Flush telemetry for serverless environments\n\t\t\tif (flushOnResponse) {\n\t\t\t\tconst flushTelemetry = await getFlushTelemetry();\n\t\t\t\tawait flushTelemetry();\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tawait telescope.exception(error as Error);\n\t\t\tthrow error;\n\t\t}\n\t};\n}\n\n/**\n * Parse query options from Hono context\n */\nfunction parseQueryOptions(c: Context): QueryOptions {\n\tconst limit = parseInt(c.req.query('limit') || '50', 10);\n\tconst offset = parseInt(c.req.query('offset') || '0', 10);\n\tconst search = c.req.query('search');\n\tconst before = c.req.query('before');\n\tconst after = c.req.query('after');\n\tconst tags = c.req.query('tags')?.split(',').filter(Boolean);\n\tconst method = c.req.query('method');\n\tconst status = c.req.query('status');\n\tconst level = c.req.query('level') as\n\t\t| 'debug'\n\t\t| 'info'\n\t\t| 'warn'\n\t\t| 'error'\n\t\t| undefined;\n\n\treturn {\n\t\tlimit: Math.min(limit, 100),\n\t\toffset,\n\t\tsearch,\n\t\tbefore: before ? new Date(before) : undefined,\n\t\tafter: after ? new Date(after) : undefined,\n\t\ttags,\n\t\tmethod: method || undefined,\n\t\tstatus: status || undefined,\n\t\tlevel: level || undefined,\n\t};\n}\n\n/**\n * Parse metrics query options from Hono context\n */\nfunction parseMetricsQueryOptions(c: Context): MetricsQueryOptions {\n\tconst start = c.req.query('start');\n\tconst end = c.req.query('end');\n\tconst bucketSize = c.req.query('bucketSize');\n\tconst limit = c.req.query('limit');\n\n\treturn {\n\t\trange:\n\t\t\tstart && end ? { start: new Date(start), end: new Date(end) } : undefined,\n\t\tbucketSize: bucketSize ? parseInt(bucketSize, 10) : undefined,\n\t\tlimit: limit ? parseInt(limit, 10) : undefined,\n\t};\n}\n\n/**\n * Telescope's JSON API: requests, exceptions, logs, stats and metrics under\n * `/api/*`. Headless — there is no dashboard; anything can be built on the\n * JSON, and live updates come from the WebSocket feed (`setupWebSocket`).\n *\n * @example\n * ```typescript\n * app.route('/__telescope', createApi(telescope));\n * // GET /__telescope/api/requests\n * ```\n */\nexport function createApi(telescope: Telescope): Hono {\n\tconst app = new Hono();\n\n\t// API routes\n\tapp.get('/api/requests', async (c) => {\n\t\tconst options = parseQueryOptions(c);\n\t\tconst requests = await telescope.getRequests(options);\n\t\treturn c.json(requests);\n\t});\n\n\tapp.get('/api/requests/:id', async (c) => {\n\t\tconst request = await telescope.getRequest(c.req.param('id'));\n\t\tif (!request) {\n\t\t\treturn c.json({ error: 'Request not found' }, 404);\n\t\t}\n\t\treturn c.json(request);\n\t});\n\n\tapp.get('/api/exceptions', async (c) => {\n\t\tconst options = parseQueryOptions(c);\n\t\tconst exceptions = await telescope.getExceptions(options);\n\t\treturn c.json(exceptions);\n\t});\n\n\tapp.get('/api/exceptions/:id', async (c) => {\n\t\tconst exception = await telescope.getException(c.req.param('id'));\n\t\tif (!exception) {\n\t\t\treturn c.json({ error: 'Exception not found' }, 404);\n\t\t}\n\t\treturn c.json(exception);\n\t});\n\n\tapp.get('/api/logs', async (c) => {\n\t\tconst options = parseQueryOptions(c);\n\t\tconst logs = await telescope.getLogs(options);\n\t\treturn c.json(logs);\n\t});\n\n\tapp.get('/api/stats', async (c) => {\n\t\tconst stats = await telescope.getStats();\n\t\treturn c.json(stats);\n\t});\n\n\t// Metrics API\n\tapp.get('/api/metrics', (c) => {\n\t\tconst options = parseMetricsQueryOptions(c);\n\t\tconst metrics = telescope.getMetrics(options);\n\t\treturn c.json(metrics);\n\t});\n\n\tapp.get('/api/metrics/endpoints', (c) => {\n\t\tconst options = parseMetricsQueryOptions(c);\n\t\tconst endpoints = telescope.getEndpointMetrics(options);\n\t\treturn c.json(endpoints);\n\t});\n\n\t// Endpoint details - method and path are query params to avoid URL encoding issues\n\tapp.get('/api/metrics/endpoint', (c) => {\n\t\tconst method = c.req.query('method');\n\t\tconst path = c.req.query('path');\n\n\t\tif (!method || !path) {\n\t\t\treturn c.json({ error: 'method and path are required' }, 400);\n\t\t}\n\n\t\tconst options = parseMetricsQueryOptions(c);\n\t\tconst details = telescope.getEndpointDetails(method, path, options);\n\n\t\tif (!details) {\n\t\t\treturn c.json({ error: 'Endpoint not found' }, 404);\n\t\t}\n\n\t\treturn c.json(details);\n\t});\n\n\tapp.get('/api/metrics/status', (c) => {\n\t\tconst options = parseMetricsQueryOptions(c);\n\t\tconst distribution = telescope.getStatusDistribution(options);\n\t\treturn c.json(distribution);\n\t});\n\n\tapp.delete('/api/metrics', (c) => {\n\t\ttelescope.resetMetrics();\n\t\treturn c.json({ success: true });\n\t});\n\n\treturn app;\n}\n\n/**\n * Options for setupWebSocket\n */\nexport interface WebSocketOptions {\n\t/**\n\t * Enable real-time metrics broadcasting (default: true)\n\t */\n\tbroadcastMetrics?: boolean;\n\t/**\n\t * Metrics broadcast interval in milliseconds (default: 5000)\n\t */\n\tmetricsBroadcastInterval?: number;\n}\n\n/**\n * Set up WebSocket routes for real-time updates.\n * Requires @hono/node-ws for Node.js or Bun's built-in WebSocket.\n */\nexport function setupWebSocket(\n\tapp: Hono,\n\ttelescope: Telescope,\n\tupgradeWebSocket: (handler: any) => any,\n\toptions: WebSocketOptions = {},\n): void {\n\tconst { broadcastMetrics = true, metricsBroadcastInterval = 5000 } = options;\n\n\t// Start metrics broadcast if enabled\n\tif (broadcastMetrics) {\n\t\ttelescope.startMetricsBroadcast(metricsBroadcastInterval);\n\t}\n\n\tapp.get(\n\t\t'/ws',\n\t\tupgradeWebSocket(() => ({\n\t\t\tonOpen: (_event: Event, ws: WebSocket) => {\n\t\t\t\ttelescope.addWsClient(ws);\n\t\t\t},\n\t\t\tonClose: (_event: Event, ws: WebSocket) => {\n\t\t\t\ttelescope.removeWsClient(ws);\n\t\t\t},\n\t\t\tonMessage: (event: MessageEvent, ws: WebSocket) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst data = JSON.parse(event.data);\n\t\t\t\t\tif (data.type === 'ping') {\n\t\t\t\t\t\tws.send(JSON.stringify({ type: 'pong' }));\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore invalid messages\n\t\t\t\t}\n\t\t\t},\n\t\t})),\n\t);\n}\n\n/**\n * Get the Telescope context from Hono context (set by middleware)\n */\nexport function getTelescopeContext(\n\tc: Context,\n): TelescopeHonoContext | undefined {\n\treturn c.get(CONTEXT_KEY);\n}\n\n/**\n * Get the request ID from Hono context (set by middleware)\n */\nexport function getRequestId(c: Context): string | undefined {\n\treturn getTelescopeContext(c)?.requestId;\n}\n\n// Re-export types and utilities\nexport type { Telescope };\nexport type {\n\tHonoAdapterConfig,\n\tTelescopeHonoContext,\n} from '../adapters/types';\n\n/**\n * Get the flushTelemetry function (lazy-loaded to avoid requiring @opentelemetry/* at import time).\n * Use this for serverless environments where you need to flush telemetry before the process freezes.\n *\n * @example\n * ```typescript\n * const flushTelemetry = await getFlushTelemetryFn();\n * await flushTelemetry();\n * ```\n */\nexport { getFlushTelemetry as getFlushTelemetryFn };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"hono.mjs","names":["_flushTelemetry: (() => Promise<void>) | null","telescope: Telescope","options: TelescopeMiddlewareOptions","c: Context","next: Next","headers: Record<string, string>","query: Record<string, string>","body: unknown","requestSize: number | undefined","responseHeaders: Record<string, string>","responseBody: unknown","responseSize: number | undefined","ctx: TelescopeHonoContext","app: Hono","upgradeWebSocket: (handler: any) => any","options: WebSocketOptions","_event: Event","ws: WebSocket","event: MessageEvent"],"sources":["../../src/server/hono.ts"],"sourcesContent":["import type { Context, MiddlewareHandler, Next } from 'hono';\nimport { Hono } from 'hono';\nimport type {\n\tHonoAdapterConfig,\n\tTelescopeHonoContext,\n} from '../adapters/types';\nimport type { Telescope } from '../Telescope';\nimport type { MetricsQueryOptions, QueryOptions } from '../types';\nimport { getAsset, getIndexHtml } from '../ui-assets';\n\n// Lazy-loaded telemetry flush function (only loads @opentelemetry/* when actually used)\nlet _flushTelemetry: (() => Promise<void>) | null = null;\nasync function getFlushTelemetry(): Promise<() => Promise<void>> {\n\tif (!_flushTelemetry) {\n\t\tconst { flushTelemetry } = await import('../instrumentation/core');\n\t\t_flushTelemetry = flushTelemetry;\n\t}\n\treturn _flushTelemetry;\n}\n\nconst CONTEXT_KEY = 'telescope-context';\n\n/** Default Hono adapter configuration */\nconst _DEFAULT_CONFIG: HonoAdapterConfig = {\n\tenvironment: 'server',\n};\n\n/**\n * Options for the Telescope Hono middleware\n */\nexport interface TelescopeMiddlewareOptions {\n\t/**\n\t * Whether to flush telemetry after each request.\n\t * Enable this for serverless environments (Lambda, Edge).\n\t * @default false\n\t */\n\tflushOnResponse?: boolean;\n}\n\n/**\n * Create Hono middleware that captures requests and responses\n */\nexport function createMiddleware(\n\ttelescope: Telescope,\n\toptions: TelescopeMiddlewareOptions = {},\n): MiddlewareHandler {\n\tconst { flushOnResponse = false } = options;\n\n\treturn async (c: Context, next: Next) => {\n\t\tif (!telescope.enabled) {\n\t\t\treturn next();\n\t\t}\n\n\t\tif (telescope.shouldIgnore(c.req.path)) {\n\t\t\treturn next();\n\t\t}\n\n\t\tconst startTime = performance.now();\n\n\t\t// Capture request data\n\t\tconst headers: Record<string, string> = {};\n\t\tc.req.raw.headers.forEach((value, key) => {\n\t\t\theaders[key] = value;\n\t\t});\n\n\t\tconst url = new URL(c.req.url);\n\t\tconst query: Record<string, string> = {};\n\t\turl.searchParams.forEach((value, key) => {\n\t\t\tquery[key] = value;\n\t\t});\n\n\t\tlet body: unknown;\n\t\tlet requestSize: number | undefined;\n\n\t\t// Get request size from Content-Length header\n\t\tconst contentLength = c.req.header('content-length');\n\t\tif (contentLength) {\n\t\t\trequestSize = parseInt(contentLength, 10);\n\t\t}\n\n\t\tif (\n\t\t\ttelescope.recordBody &&\n\t\t\t['POST', 'PUT', 'PATCH'].includes(c.req.method)\n\t\t) {\n\t\t\ttry {\n\t\t\t\tconst contentType = c.req.header('content-type') || '';\n\t\t\t\t// Clone the request to avoid consuming the body stream\n\t\t\t\tconst clonedRequest = c.req.raw.clone();\n\t\t\t\tif (contentType.includes('application/json')) {\n\t\t\t\t\tbody = await clonedRequest.json();\n\t\t\t\t} else if (contentType.includes('application/x-www-form-urlencoded')) {\n\t\t\t\t\tbody = Object.fromEntries((await clonedRequest.formData()).entries());\n\t\t\t\t} else if (contentType.includes('text/')) {\n\t\t\t\t\tbody = await clonedRequest.text();\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Ignore body parsing errors\n\t\t\t}\n\t\t}\n\n\t\tconst ip = c.req.header('x-forwarded-for') || c.req.header('x-real-ip');\n\n\t\ttry {\n\t\t\tawait next();\n\n\t\t\t// Capture response data\n\t\t\tconst duration = performance.now() - startTime;\n\n\t\t\tconst responseHeaders: Record<string, string> = {};\n\t\t\tc.res.headers.forEach((value, key) => {\n\t\t\t\tresponseHeaders[key] = value;\n\t\t\t});\n\n\t\t\tlet responseBody: unknown;\n\t\t\tlet responseSize: number | undefined;\n\n\t\t\t// Get response size - prefer Content-Length header, fallback to body size\n\t\t\tconst responseContentLength = c.res.headers.get('content-length');\n\t\t\tif (responseContentLength) {\n\t\t\t\tresponseSize = parseInt(responseContentLength, 10);\n\t\t\t}\n\n\t\t\tif (telescope.recordBody) {\n\t\t\t\ttry {\n\t\t\t\t\tconst contentType = c.res.headers.get('content-type') || '';\n\t\t\t\t\tif (contentType.includes('application/json')) {\n\t\t\t\t\t\tconst cloned = c.res.clone();\n\t\t\t\t\t\tconst text = await cloned.text();\n\t\t\t\t\t\tresponseSize ??= Buffer.byteLength(text, 'utf8');\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponseBody = JSON.parse(text);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tresponseBody = text;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore body parsing errors\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst requestId = await telescope.recordRequest({\n\t\t\t\tmethod: c.req.method,\n\t\t\t\tpath: c.req.path,\n\t\t\t\turl: c.req.url,\n\t\t\t\theaders,\n\t\t\t\tbody,\n\t\t\t\tquery,\n\t\t\t\tstatus: c.res.status,\n\t\t\t\tresponseHeaders,\n\t\t\t\tresponseBody,\n\t\t\t\tduration,\n\t\t\t\tip,\n\t\t\t\trequestSize,\n\t\t\t\tresponseSize,\n\t\t\t});\n\n\t\t\t// Store context for access by other middleware\n\t\t\tconst ctx: TelescopeHonoContext = {\n\t\t\t\trequestId,\n\t\t\t\tstartTime,\n\t\t\t};\n\t\t\tc.set(CONTEXT_KEY, ctx);\n\n\t\t\t// Flush telemetry for serverless environments\n\t\t\tif (flushOnResponse) {\n\t\t\t\tconst flushTelemetry = await getFlushTelemetry();\n\t\t\t\tawait flushTelemetry();\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tawait telescope.exception(error as Error);\n\t\t\tthrow error;\n\t\t}\n\t};\n}\n\n/**\n * Parse query options from Hono context\n */\nfunction parseQueryOptions(c: Context): QueryOptions {\n\tconst limit = parseInt(c.req.query('limit') || '50', 10);\n\tconst offset = parseInt(c.req.query('offset') || '0', 10);\n\tconst search = c.req.query('search');\n\tconst before = c.req.query('before');\n\tconst after = c.req.query('after');\n\tconst tags = c.req.query('tags')?.split(',').filter(Boolean);\n\tconst method = c.req.query('method');\n\tconst status = c.req.query('status');\n\tconst level = c.req.query('level') as\n\t\t| 'debug'\n\t\t| 'info'\n\t\t| 'warn'\n\t\t| 'error'\n\t\t| undefined;\n\n\treturn {\n\t\tlimit: Math.min(limit, 100),\n\t\toffset,\n\t\tsearch,\n\t\tbefore: before ? new Date(before) : undefined,\n\t\tafter: after ? new Date(after) : undefined,\n\t\ttags,\n\t\tmethod: method || undefined,\n\t\tstatus: status || undefined,\n\t\tlevel: level || undefined,\n\t};\n}\n\n/**\n * Parse metrics query options from Hono context\n */\nfunction parseMetricsQueryOptions(c: Context): MetricsQueryOptions {\n\tconst start = c.req.query('start');\n\tconst end = c.req.query('end');\n\tconst bucketSize = c.req.query('bucketSize');\n\tconst limit = c.req.query('limit');\n\n\treturn {\n\t\trange:\n\t\t\tstart && end ? { start: new Date(start), end: new Date(end) } : undefined,\n\t\tbucketSize: bucketSize ? parseInt(bucketSize, 10) : undefined,\n\t\tlimit: limit ? parseInt(limit, 10) : undefined,\n\t};\n}\n\n/**\n * Create Hono app with dashboard UI and API routes\n */\nexport function createUI(telescope: Telescope): Hono {\n\tconst app = new Hono();\n\n\t// API routes\n\tapp.get('/api/requests', async (c) => {\n\t\tconst options = parseQueryOptions(c);\n\t\tconst requests = await telescope.getRequests(options);\n\t\treturn c.json(requests);\n\t});\n\n\tapp.get('/api/requests/:id', async (c) => {\n\t\tconst request = await telescope.getRequest(c.req.param('id'));\n\t\tif (!request) {\n\t\t\treturn c.json({ error: 'Request not found' }, 404);\n\t\t}\n\t\treturn c.json(request);\n\t});\n\n\tapp.get('/api/exceptions', async (c) => {\n\t\tconst options = parseQueryOptions(c);\n\t\tconst exceptions = await telescope.getExceptions(options);\n\t\treturn c.json(exceptions);\n\t});\n\n\tapp.get('/api/exceptions/:id', async (c) => {\n\t\tconst exception = await telescope.getException(c.req.param('id'));\n\t\tif (!exception) {\n\t\t\treturn c.json({ error: 'Exception not found' }, 404);\n\t\t}\n\t\treturn c.json(exception);\n\t});\n\n\tapp.get('/api/logs', async (c) => {\n\t\tconst options = parseQueryOptions(c);\n\t\tconst logs = await telescope.getLogs(options);\n\t\treturn c.json(logs);\n\t});\n\n\tapp.get('/api/stats', async (c) => {\n\t\tconst stats = await telescope.getStats();\n\t\treturn c.json(stats);\n\t});\n\n\t// Metrics API\n\tapp.get('/api/metrics', (c) => {\n\t\tconst options = parseMetricsQueryOptions(c);\n\t\tconst metrics = telescope.getMetrics(options);\n\t\treturn c.json(metrics);\n\t});\n\n\tapp.get('/api/metrics/endpoints', (c) => {\n\t\tconst options = parseMetricsQueryOptions(c);\n\t\tconst endpoints = telescope.getEndpointMetrics(options);\n\t\treturn c.json(endpoints);\n\t});\n\n\t// Endpoint details - method and path are query params to avoid URL encoding issues\n\tapp.get('/api/metrics/endpoint', (c) => {\n\t\tconst method = c.req.query('method');\n\t\tconst path = c.req.query('path');\n\n\t\tif (!method || !path) {\n\t\t\treturn c.json({ error: 'method and path are required' }, 400);\n\t\t}\n\n\t\tconst options = parseMetricsQueryOptions(c);\n\t\tconst details = telescope.getEndpointDetails(method, path, options);\n\n\t\tif (!details) {\n\t\t\treturn c.json({ error: 'Endpoint not found' }, 404);\n\t\t}\n\n\t\treturn c.json(details);\n\t});\n\n\tapp.get('/api/metrics/status', (c) => {\n\t\tconst options = parseMetricsQueryOptions(c);\n\t\tconst distribution = telescope.getStatusDistribution(options);\n\t\treturn c.json(distribution);\n\t});\n\n\tapp.delete('/api/metrics', (c) => {\n\t\ttelescope.resetMetrics();\n\t\treturn c.json({ success: true });\n\t});\n\n\t// Static assets\n\tapp.get('/assets/:filename', (c) => {\n\t\tconst filename = c.req.param('filename');\n\t\tconst assetPath = `assets/${filename}`;\n\t\tconst asset = getAsset(assetPath);\n\t\tif (asset) {\n\t\t\treturn c.body(asset.content, 200, {\n\t\t\t\t'Content-Type': asset.contentType,\n\t\t\t\t'Cache-Control': 'public, max-age=31536000, immutable',\n\t\t\t});\n\t\t}\n\t\treturn c.notFound();\n\t});\n\n\t// Dashboard UI - serve React app\n\tapp.get('/', (c) => {\n\t\tconst html = getIndexHtml();\n\t\tif (!html) {\n\t\t\treturn c.text(\n\t\t\t\t'Telescope UI not available. Run \"pnpm build:ui\" first.',\n\t\t\t\t500,\n\t\t\t);\n\t\t}\n\t\treturn c.html(html);\n\t});\n\n\tapp.get('/*', (c) => {\n\t\t// SPA fallback - serve index.html for client-side routing\n\t\tconst html = getIndexHtml();\n\t\tif (!html) {\n\t\t\treturn c.text(\n\t\t\t\t'Telescope UI not available. Run \"pnpm build:ui\" first.',\n\t\t\t\t500,\n\t\t\t);\n\t\t}\n\t\treturn c.html(html);\n\t});\n\n\treturn app;\n}\n\n/**\n * Options for setupWebSocket\n */\nexport interface WebSocketOptions {\n\t/**\n\t * Enable real-time metrics broadcasting (default: true)\n\t */\n\tbroadcastMetrics?: boolean;\n\t/**\n\t * Metrics broadcast interval in milliseconds (default: 5000)\n\t */\n\tmetricsBroadcastInterval?: number;\n}\n\n/**\n * Set up WebSocket routes for real-time updates.\n * Requires @hono/node-ws for Node.js or Bun's built-in WebSocket.\n */\nexport function setupWebSocket(\n\tapp: Hono,\n\ttelescope: Telescope,\n\tupgradeWebSocket: (handler: any) => any,\n\toptions: WebSocketOptions = {},\n): void {\n\tconst { broadcastMetrics = true, metricsBroadcastInterval = 5000 } = options;\n\n\t// Start metrics broadcast if enabled\n\tif (broadcastMetrics) {\n\t\ttelescope.startMetricsBroadcast(metricsBroadcastInterval);\n\t}\n\n\tapp.get(\n\t\t'/ws',\n\t\tupgradeWebSocket(() => ({\n\t\t\tonOpen: (_event: Event, ws: WebSocket) => {\n\t\t\t\ttelescope.addWsClient(ws);\n\t\t\t},\n\t\t\tonClose: (_event: Event, ws: WebSocket) => {\n\t\t\t\ttelescope.removeWsClient(ws);\n\t\t\t},\n\t\t\tonMessage: (event: MessageEvent, ws: WebSocket) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst data = JSON.parse(event.data);\n\t\t\t\t\tif (data.type === 'ping') {\n\t\t\t\t\t\tws.send(JSON.stringify({ type: 'pong' }));\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore invalid messages\n\t\t\t\t}\n\t\t\t},\n\t\t})),\n\t);\n}\n\n/**\n * Get the Telescope context from Hono context (set by middleware)\n */\nexport function getTelescopeContext(\n\tc: Context,\n): TelescopeHonoContext | undefined {\n\treturn c.get(CONTEXT_KEY);\n}\n\n/**\n * Get the request ID from Hono context (set by middleware)\n */\nexport function getRequestId(c: Context): string | undefined {\n\treturn getTelescopeContext(c)?.requestId;\n}\n\n// Re-export types and utilities\nexport type { Telescope };\nexport type {\n\tHonoAdapterConfig,\n\tTelescopeHonoContext,\n} from '../adapters/types';\n\n/**\n * Get the flushTelemetry function (lazy-loaded to avoid requiring @opentelemetry/* at import time).\n * Use this for serverless environments where you need to flush telemetry before the process freezes.\n *\n * @example\n * ```typescript\n * const flushTelemetry = await getFlushTelemetryFn();\n * await flushTelemetry();\n * ```\n */\nexport { getFlushTelemetry as getFlushTelemetryFn };\n"],"mappings":"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"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { createSpanProcessor, getRecommendedStrategy, setGlobalLogProcessor, setGlobalSpanProcessor } from "./core-D6hJ6exL.mjs";
|
|
2
|
+
import { DiagConsoleLogger, DiagLogLevel, diag } from "@opentelemetry/api";
|
|
3
|
+
import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
|
|
4
|
+
import { OTLPLogExporter } from "@opentelemetry/exporter-logs-otlp-http";
|
|
5
|
+
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
|
|
6
|
+
import { PinoInstrumentation } from "@opentelemetry/instrumentation-pino";
|
|
7
|
+
import { Resource } from "@opentelemetry/resources";
|
|
8
|
+
import { BatchLogRecordProcessor, LoggerProvider } from "@opentelemetry/sdk-logs";
|
|
9
|
+
import { NodeSDK } from "@opentelemetry/sdk-node";
|
|
10
|
+
import { ConsoleSpanExporter } from "@opentelemetry/sdk-trace-node";
|
|
11
|
+
import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from "@opentelemetry/semantic-conventions";
|
|
12
|
+
|
|
13
|
+
//#region src/instrumentation/setup.ts
|
|
14
|
+
let sdk = null;
|
|
15
|
+
/**
|
|
16
|
+
* Set up OpenTelemetry instrumentation.
|
|
17
|
+
* Call this BEFORE importing your application code.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* // instrumentation.ts (create this file)
|
|
22
|
+
* import { setupTelemetry } from '@geekmidas/telescope/instrumentation';
|
|
23
|
+
*
|
|
24
|
+
* setupTelemetry({
|
|
25
|
+
* serviceName: 'my-api',
|
|
26
|
+
* endpoint: 'http://localhost:3000/__telescope/v1',
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* // Then in your entry point:
|
|
30
|
+
* // import './instrumentation';
|
|
31
|
+
* // import { app } from './app';
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
function setupTelemetry(options) {
|
|
35
|
+
if (sdk) return;
|
|
36
|
+
const { serviceName, serviceVersion = "1.0.0", endpoint, instrumentPino = true, autoInstrument = true, debug = false, resourceAttributes = {}, headers = {}, spanProcessorStrategy, environment = "server" } = options;
|
|
37
|
+
if (debug) diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG);
|
|
38
|
+
const resource = new Resource({
|
|
39
|
+
[ATTR_SERVICE_NAME]: serviceName,
|
|
40
|
+
[ATTR_SERVICE_VERSION]: serviceVersion,
|
|
41
|
+
...resourceAttributes
|
|
42
|
+
});
|
|
43
|
+
const instrumentations = [];
|
|
44
|
+
if (instrumentPino) instrumentations.push(new PinoInstrumentation({ logHook: (span, record) => {
|
|
45
|
+
record.trace_id = span.spanContext().traceId;
|
|
46
|
+
record.span_id = span.spanContext().spanId;
|
|
47
|
+
record.trace_flags = span.spanContext().traceFlags;
|
|
48
|
+
} }));
|
|
49
|
+
if (autoInstrument) instrumentations.push(getNodeAutoInstrumentations({
|
|
50
|
+
"@opentelemetry/instrumentation-fs": { enabled: false },
|
|
51
|
+
"@opentelemetry/instrumentation-http": { ignoreIncomingRequestHook: (request) => {
|
|
52
|
+
const path = request.url || "";
|
|
53
|
+
return path.includes("/__health") || path.includes("/__telescope") || path.includes("/favicon");
|
|
54
|
+
} }
|
|
55
|
+
}));
|
|
56
|
+
let traceExporter;
|
|
57
|
+
if (endpoint) traceExporter = new OTLPTraceExporter({
|
|
58
|
+
url: `${endpoint}/traces`,
|
|
59
|
+
headers
|
|
60
|
+
});
|
|
61
|
+
else traceExporter = new ConsoleSpanExporter();
|
|
62
|
+
const strategy = spanProcessorStrategy ?? getRecommendedStrategy(environment);
|
|
63
|
+
const spanProcessor = createSpanProcessor(traceExporter, { strategy });
|
|
64
|
+
setGlobalSpanProcessor(spanProcessor);
|
|
65
|
+
sdk = new NodeSDK({
|
|
66
|
+
resource,
|
|
67
|
+
traceExporter,
|
|
68
|
+
spanProcessors: [spanProcessor],
|
|
69
|
+
instrumentations
|
|
70
|
+
});
|
|
71
|
+
if (endpoint) {
|
|
72
|
+
const logExporter = new OTLPLogExporter({
|
|
73
|
+
url: `${endpoint}/logs`,
|
|
74
|
+
headers
|
|
75
|
+
});
|
|
76
|
+
const loggerProvider = new LoggerProvider({ resource });
|
|
77
|
+
const logProcessor = new BatchLogRecordProcessor(logExporter);
|
|
78
|
+
loggerProvider.addLogRecordProcessor(logProcessor);
|
|
79
|
+
setGlobalLogProcessor(logProcessor);
|
|
80
|
+
}
|
|
81
|
+
sdk.start();
|
|
82
|
+
process.on("SIGTERM", () => {
|
|
83
|
+
sdk?.shutdown().then(() => {}).catch((_error) => {}).finally(() => process.exit(0));
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Shut down telemetry (for testing or graceful shutdown)
|
|
88
|
+
*/
|
|
89
|
+
async function shutdownTelemetry() {
|
|
90
|
+
if (sdk) {
|
|
91
|
+
await sdk.shutdown();
|
|
92
|
+
sdk = null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
//#endregion
|
|
97
|
+
export { setupTelemetry, shutdownTelemetry };
|
|
98
|
+
//# sourceMappingURL=setup-B9jM77Qk.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup-B9jM77Qk.mjs","names":["sdk: NodeSDK | null","options: TelemetryOptions","traceExporter: SpanExporter"],"sources":["../src/instrumentation/setup.ts"],"sourcesContent":["import { DiagConsoleLogger, DiagLogLevel, diag } from '@opentelemetry/api';\nimport { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';\nimport { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';\nimport { PinoInstrumentation } from '@opentelemetry/instrumentation-pino';\nimport { Resource } from '@opentelemetry/resources';\nimport {\n\tBatchLogRecordProcessor,\n\tLoggerProvider,\n} from '@opentelemetry/sdk-logs';\nimport { NodeSDK } from '@opentelemetry/sdk-node';\nimport {\n\tConsoleSpanExporter,\n\ttype SpanExporter,\n} from '@opentelemetry/sdk-trace-node';\nimport {\n\tATTR_SERVICE_NAME,\n\tATTR_SERVICE_VERSION,\n} from '@opentelemetry/semantic-conventions';\nimport type { SpanProcessorStrategy } from '../adapters/types';\nimport {\n\tcreateSpanProcessor,\n\tgetRecommendedStrategy,\n\tsetGlobalLogProcessor,\n\tsetGlobalSpanProcessor,\n} from './core';\n\n/**\n * Options for configuring telemetry\n */\nexport interface TelemetryOptions {\n\t/**\n\t * Service name for resource identification\n\t */\n\tserviceName: string;\n\n\t/**\n\t * Service version\n\t */\n\tserviceVersion?: string;\n\n\t/**\n\t * OTLP endpoint URL (e.g., 'http://localhost:3000/__telescope/v1')\n\t * If not provided, traces will be logged to console\n\t */\n\tendpoint?: string;\n\n\t/**\n\t * Whether to instrument Pino for log correlation\n\t * @default true\n\t */\n\tinstrumentPino?: boolean;\n\n\t/**\n\t * Whether to enable auto-instrumentation for common libraries\n\t * (http, fetch, express, etc.)\n\t * @default true\n\t */\n\tautoInstrument?: boolean;\n\n\t/**\n\t * Enable debug logging for OTel SDK\n\t * @default false\n\t */\n\tdebug?: boolean;\n\n\t/**\n\t * Additional resource attributes\n\t */\n\tresourceAttributes?: Record<string, string>;\n\n\t/**\n\t * Headers to send with OTLP requests\n\t */\n\theaders?: Record<string, string>;\n\n\t/**\n\t * Span processor strategy.\n\t * - 'batch': Efficient batching for long-running servers (default)\n\t * - 'simple': Immediate export for serverless environments (Lambda, Edge)\n\t *\n\t * If not specified, automatically selected based on environment detection.\n\t */\n\tspanProcessorStrategy?: SpanProcessorStrategy;\n\n\t/**\n\t * Environment type for automatic configuration\n\t * @default 'server'\n\t */\n\tenvironment?: 'server' | 'lambda' | 'edge' | 'custom';\n}\n\nlet sdk: NodeSDK | null = null;\n\n/**\n * Set up OpenTelemetry instrumentation.\n * Call this BEFORE importing your application code.\n *\n * @example\n * ```typescript\n * // instrumentation.ts (create this file)\n * import { setupTelemetry } from '@geekmidas/telescope/instrumentation';\n *\n * setupTelemetry({\n * serviceName: 'my-api',\n * endpoint: 'http://localhost:3000/__telescope/v1',\n * });\n *\n * // Then in your entry point:\n * // import './instrumentation';\n * // import { app } from './app';\n * ```\n */\nexport function setupTelemetry(options: TelemetryOptions): void {\n\tif (sdk) {\n\t\treturn;\n\t}\n\n\tconst {\n\t\tserviceName,\n\t\tserviceVersion = '1.0.0',\n\t\tendpoint,\n\t\tinstrumentPino = true,\n\t\tautoInstrument = true,\n\t\tdebug = false,\n\t\tresourceAttributes = {},\n\t\theaders = {},\n\t\tspanProcessorStrategy,\n\t\tenvironment = 'server',\n\t} = options;\n\n\t// Enable debug logging if requested\n\tif (debug) {\n\t\tdiag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG);\n\t}\n\n\t// Create resource\n\tconst resource = new Resource({\n\t\t[ATTR_SERVICE_NAME]: serviceName,\n\t\t[ATTR_SERVICE_VERSION]: serviceVersion,\n\t\t...resourceAttributes,\n\t});\n\n\t// Build instrumentations list\n\tconst instrumentations = [];\n\n\t// Add Pino instrumentation for log correlation\n\tif (instrumentPino) {\n\t\tinstrumentations.push(\n\t\t\tnew PinoInstrumentation({\n\t\t\t\t// Inject trace context into log records\n\t\t\t\tlogHook: (span, record) => {\n\t\t\t\t\trecord.trace_id = span.spanContext().traceId;\n\t\t\t\t\trecord.span_id = span.spanContext().spanId;\n\t\t\t\t\trecord.trace_flags = span.spanContext().traceFlags;\n\t\t\t\t},\n\t\t\t}),\n\t\t);\n\t}\n\n\t// Add auto-instrumentations for common libraries\n\tif (autoInstrument) {\n\t\tinstrumentations.push(\n\t\t\tgetNodeAutoInstrumentations({\n\t\t\t\t// Disable file system instrumentation (too noisy)\n\t\t\t\t'@opentelemetry/instrumentation-fs': { enabled: false },\n\t\t\t\t// Configure HTTP instrumentation\n\t\t\t\t'@opentelemetry/instrumentation-http': {\n\t\t\t\t\tignoreIncomingRequestHook: (request) => {\n\t\t\t\t\t\t// Ignore health checks and internal routes\n\t\t\t\t\t\tconst path = request.url || '';\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\tpath.includes('/__health') ||\n\t\t\t\t\t\t\tpath.includes('/__telescope') ||\n\t\t\t\t\t\t\tpath.includes('/favicon')\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t);\n\t}\n\n\t// Create exporters\n\tlet traceExporter: SpanExporter;\n\tif (endpoint) {\n\t\ttraceExporter = new OTLPTraceExporter({\n\t\t\turl: `${endpoint}/traces`,\n\t\t\theaders,\n\t\t});\n\t} else {\n\t\t// Fall back to console exporter for debugging\n\t\ttraceExporter = new ConsoleSpanExporter();\n\t}\n\n\t// Determine span processor strategy\n\tconst strategy = spanProcessorStrategy ?? getRecommendedStrategy(environment);\n\tconst spanProcessor = createSpanProcessor(traceExporter, { strategy });\n\n\t// Register globally for flush operations\n\tsetGlobalSpanProcessor(spanProcessor);\n\n\t// Create and configure SDK\n\tsdk = new NodeSDK({\n\t\tresource,\n\t\ttraceExporter,\n\t\tspanProcessors: [spanProcessor],\n\t\tinstrumentations,\n\t});\n\n\t// Set up log exporter if endpoint is provided\n\tif (endpoint) {\n\t\tconst logExporter = new OTLPLogExporter({\n\t\t\turl: `${endpoint}/logs`,\n\t\t\theaders,\n\t\t});\n\n\t\tconst loggerProvider = new LoggerProvider({ resource });\n\t\tconst logProcessor = new BatchLogRecordProcessor(logExporter);\n\t\tloggerProvider.addLogRecordProcessor(logProcessor);\n\n\t\t// Register for flush operations\n\t\tsetGlobalLogProcessor(logProcessor);\n\t}\n\n\t// Start the SDK\n\tsdk.start();\n\n\t// Graceful shutdown\n\tprocess.on('SIGTERM', () => {\n\t\tsdk\n\t\t\t?.shutdown()\n\t\t\t.then(() => {})\n\t\t\t.catch((_error) => {})\n\t\t\t.finally(() => process.exit(0));\n\t});\n}\n\n/**\n * Shut down telemetry (for testing or graceful shutdown)\n */\nexport async function shutdownTelemetry(): Promise<void> {\n\tif (sdk) {\n\t\tawait sdk.shutdown();\n\t\tsdk = null;\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;AA4FA,IAAIA,MAAsB;;;;;;;;;;;;;;;;;;;;AAqB1B,SAAgB,eAAeC,SAAiC;AAC/D,KAAI,IACH;CAGD,MAAM,EACL,aACA,iBAAiB,SACjB,UACA,iBAAiB,MACjB,iBAAiB,MACjB,QAAQ,OACR,qBAAqB,CAAE,GACvB,UAAU,CAAE,GACZ,uBACA,cAAc,UACd,GAAG;AAGJ,KAAI,MACH,MAAK,UAAU,IAAI,qBAAqB,aAAa,MAAM;CAI5D,MAAM,WAAW,IAAI,SAAS;GAC5B,oBAAoB;GACpB,uBAAuB;EACxB,GAAG;CACH;CAGD,MAAM,mBAAmB,CAAE;AAG3B,KAAI,eACH,kBAAiB,KAChB,IAAI,oBAAoB,EAEvB,SAAS,CAAC,MAAM,WAAW;AAC1B,SAAO,WAAW,KAAK,aAAa,CAAC;AACrC,SAAO,UAAU,KAAK,aAAa,CAAC;AACpC,SAAO,cAAc,KAAK,aAAa,CAAC;CACxC,EACD,GACD;AAIF,KAAI,eACH,kBAAiB,KAChB,4BAA4B;EAE3B,qCAAqC,EAAE,SAAS,MAAO;EAEvD,uCAAuC,EACtC,2BAA2B,CAAC,YAAY;GAEvC,MAAM,OAAO,QAAQ,OAAO;AAC5B,UACC,KAAK,SAAS,YAAY,IAC1B,KAAK,SAAS,eAAe,IAC7B,KAAK,SAAS,WAAW;EAE1B,EACD;CACD,EAAC,CACF;CAIF,IAAIC;AACJ,KAAI,SACH,iBAAgB,IAAI,kBAAkB;EACrC,MAAM,EAAE,SAAS;EACjB;CACA;KAGD,iBAAgB,IAAI;CAIrB,MAAM,WAAW,yBAAyB,uBAAuB,YAAY;CAC7E,MAAM,gBAAgB,oBAAoB,eAAe,EAAE,SAAU,EAAC;AAGtE,wBAAuB,cAAc;AAGrC,OAAM,IAAI,QAAQ;EACjB;EACA;EACA,gBAAgB,CAAC,aAAc;EAC/B;CACA;AAGD,KAAI,UAAU;EACb,MAAM,cAAc,IAAI,gBAAgB;GACvC,MAAM,EAAE,SAAS;GACjB;EACA;EAED,MAAM,iBAAiB,IAAI,eAAe,EAAE,SAAU;EACtD,MAAM,eAAe,IAAI,wBAAwB;AACjD,iBAAe,sBAAsB,aAAa;AAGlD,wBAAsB,aAAa;CACnC;AAGD,KAAI,OAAO;AAGX,SAAQ,GAAG,WAAW,MAAM;AAC3B,OACG,UAAU,CACX,KAAK,MAAM,CAAE,EAAC,CACd,MAAM,CAAC,WAAW,CAAE,EAAC,CACrB,QAAQ,MAAM,QAAQ,KAAK,EAAE,CAAC;CAChC,EAAC;AACF;;;;AAKD,eAAsB,oBAAmC;AACxD,KAAI,KAAK;AACR,QAAM,IAAI,UAAU;AACpB,QAAM;CACN;AACD"}
|