apitally 0.25.8 → 1.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +228 -178
- package/dist/activation.cjs +393 -0
- package/dist/activation.cjs.map +1 -0
- package/dist/activation.d.cts +42 -0
- package/dist/activation.d.ts +42 -0
- package/dist/activation.js +383 -0
- package/dist/activation.js.map +1 -0
- package/dist/adonisjs/configure.cjs +86 -30
- package/dist/adonisjs/configure.cjs.map +1 -1
- package/dist/adonisjs/configure.d.cts +0 -4
- package/dist/adonisjs/configure.d.ts +0 -4
- package/dist/adonisjs/configure.js +83 -29
- package/dist/adonisjs/configure.js.map +1 -1
- package/dist/adonisjs/index.cjs +38 -21
- package/dist/adonisjs/index.cjs.map +1 -1
- package/dist/adonisjs/index.d.cts +5 -14
- package/dist/adonisjs/index.d.ts +5 -14
- package/dist/adonisjs/index.js +39 -18
- package/dist/adonisjs/index.js.map +1 -1
- package/dist/adonisjs/middleware.cjs +43 -109
- package/dist/adonisjs/middleware.cjs.map +1 -1
- package/dist/adonisjs/middleware.d.cts +1 -16
- package/dist/adonisjs/middleware.d.ts +1 -16
- package/dist/adonisjs/middleware.js +43 -110
- package/dist/adonisjs/middleware.js.map +1 -1
- package/dist/adonisjs/provider.cjs +19 -87
- package/dist/adonisjs/provider.cjs.map +1 -1
- package/dist/adonisjs/provider.d.cts +0 -22
- package/dist/adonisjs/provider.d.ts +0 -22
- package/dist/adonisjs/provider.js +19 -88
- package/dist/adonisjs/provider.js.map +1 -1
- package/dist/adonisjs/stubs/config/apitally.stub +11 -15
- package/dist/bodyCapture.cjs +128 -0
- package/dist/bodyCapture.cjs.map +1 -0
- package/dist/bodyCapture.d.cts +31 -0
- package/dist/bodyCapture.d.ts +31 -0
- package/dist/bodyCapture.js +101 -0
- package/dist/bodyCapture.js.map +1 -0
- package/dist/config.cjs +227 -0
- package/dist/config.cjs.map +1 -0
- package/dist/config.d.cts +45 -0
- package/dist/config.d.ts +45 -0
- package/dist/config.js +192 -0
- package/dist/config.js.map +1 -0
- package/dist/consumer.cjs +98 -0
- package/dist/consumer.cjs.map +1 -0
- package/dist/consumer.d.cts +15 -0
- package/dist/consumer.d.ts +15 -0
- package/dist/consumer.js +78 -0
- package/dist/consumer.js.map +1 -0
- package/dist/context.cjs +68 -0
- package/dist/context.cjs.map +1 -0
- package/dist/context.d.cts +33 -0
- package/dist/context.d.ts +33 -0
- package/dist/context.js +40 -0
- package/dist/context.js.map +1 -0
- package/dist/elysia/index.cjs +12 -3
- package/dist/elysia/index.cjs.map +1 -1
- package/dist/elysia/index.d.cts +8 -16
- package/dist/elysia/index.d.ts +8 -16
- package/dist/elysia/index.js +10 -2
- package/dist/elysia/index.js.map +1 -1
- package/dist/elysia/middleware.cjs +261 -0
- package/dist/elysia/middleware.cjs.map +1 -0
- package/dist/elysia/middleware.d.cts +14 -0
- package/dist/elysia/middleware.d.ts +14 -0
- package/dist/elysia/middleware.js +250 -0
- package/dist/elysia/middleware.js.map +1 -0
- package/dist/{otel/index.cjs → elysia/routes.cjs} +16 -7
- package/dist/elysia/routes.cjs.map +1 -0
- package/dist/elysia/routes.d.cts +7 -0
- package/dist/elysia/routes.d.ts +7 -0
- package/dist/elysia/routes.js +14 -0
- package/dist/elysia/routes.js.map +1 -0
- package/dist/exceptions.cjs +81 -0
- package/dist/exceptions.cjs.map +1 -0
- package/dist/exceptions.d.cts +7 -0
- package/dist/exceptions.d.ts +7 -0
- package/dist/exceptions.js +55 -0
- package/dist/exceptions.js.map +1 -0
- package/dist/exportSerialization.cjs +56 -0
- package/dist/exportSerialization.cjs.map +1 -0
- package/dist/exportSerialization.d.cts +7 -0
- package/dist/exportSerialization.d.ts +7 -0
- package/dist/exportSerialization.js +32 -0
- package/dist/exportSerialization.js.map +1 -0
- package/dist/exportWorker.cjs +305 -0
- package/dist/exportWorker.cjs.map +1 -0
- package/dist/exportWorker.d.cts +46 -0
- package/dist/exportWorker.d.ts +46 -0
- package/dist/exportWorker.js +279 -0
- package/dist/exportWorker.js.map +1 -0
- package/dist/express/index.cjs +9 -4
- package/dist/express/index.cjs.map +1 -1
- package/dist/express/index.d.cts +7 -10
- package/dist/express/index.d.ts +7 -10
- package/dist/express/index.js +8 -2
- package/dist/express/index.js.map +1 -1
- package/dist/express/install.cjs +45 -0
- package/dist/express/install.cjs.map +1 -0
- package/dist/express/install.d.cts +10 -0
- package/dist/express/install.d.ts +10 -0
- package/dist/express/install.js +21 -0
- package/dist/express/install.js.map +1 -0
- package/dist/express/middleware.cjs +87 -331
- package/dist/express/middleware.cjs.map +1 -1
- package/dist/express/middleware.d.cts +3 -21
- package/dist/express/middleware.d.ts +3 -21
- package/dist/express/middleware.js +91 -327
- package/dist/express/middleware.js.map +1 -1
- package/dist/express/register.cjs +20 -0
- package/dist/express/register.cjs.map +1 -0
- package/dist/express/register.d.cts +2 -0
- package/dist/express/register.d.ts +2 -0
- package/dist/express/register.js +19 -0
- package/dist/express/register.js.map +1 -0
- package/dist/express/routes.cjs +429 -0
- package/dist/express/routes.cjs.map +1 -0
- package/dist/express/routes.d.cts +14 -0
- package/dist/express/routes.d.ts +14 -0
- package/dist/express/routes.js +401 -0
- package/dist/express/routes.js.map +1 -0
- package/dist/fastify/index.cjs +10 -5
- package/dist/fastify/index.cjs.map +1 -1
- package/dist/fastify/index.d.cts +7 -11
- package/dist/fastify/index.d.ts +7 -11
- package/dist/fastify/index.js +9 -3
- package/dist/fastify/index.js.map +1 -1
- package/dist/{loggers/index.cjs → fastify/install.cjs} +17 -19
- package/dist/fastify/install.cjs.map +1 -0
- package/dist/fastify/install.d.cts +10 -0
- package/dist/fastify/install.d.ts +10 -0
- package/dist/fastify/install.js +15 -0
- package/dist/fastify/install.js.map +1 -0
- package/dist/fastify/middleware.cjs +135 -0
- package/dist/fastify/middleware.cjs.map +1 -0
- package/dist/fastify/middleware.d.cts +7 -0
- package/dist/fastify/middleware.d.ts +7 -0
- package/dist/fastify/middleware.js +114 -0
- package/dist/fastify/middleware.js.map +1 -0
- package/dist/{common/paramValidation.cjs → fastify/routes.cjs} +15 -17
- package/dist/fastify/routes.cjs.map +1 -0
- package/dist/fastify/routes.d.cts +8 -0
- package/dist/fastify/routes.d.ts +8 -0
- package/dist/fastify/routes.js +14 -0
- package/dist/fastify/routes.js.map +1 -0
- package/dist/h3/index.cjs +28 -4
- package/dist/h3/index.cjs.map +1 -1
- package/dist/h3/index.d.cts +8 -10
- package/dist/h3/index.d.ts +8 -10
- package/dist/h3/index.js +26 -2
- package/dist/h3/index.js.map +1 -1
- package/dist/h3/middleware.cjs +210 -0
- package/dist/h3/middleware.cjs.map +1 -0
- package/dist/h3/middleware.d.cts +5 -0
- package/dist/h3/middleware.d.ts +5 -0
- package/dist/h3/middleware.js +194 -0
- package/dist/h3/middleware.js.map +1 -0
- package/dist/h3/routes.cjs +66 -0
- package/dist/h3/routes.cjs.map +1 -0
- package/dist/h3/routes.d.cts +8 -0
- package/dist/h3/routes.d.ts +8 -0
- package/dist/h3/routes.js +41 -0
- package/dist/h3/routes.js.map +1 -0
- package/dist/hapi/index.cjs +15 -4
- package/dist/hapi/index.cjs.map +1 -1
- package/dist/hapi/index.d.cts +8 -10
- package/dist/hapi/index.d.ts +8 -10
- package/dist/hapi/index.js +13 -2
- package/dist/hapi/index.js.map +1 -1
- package/dist/{loggers/hapi.cjs → hapi/install.cjs} +20 -26
- package/dist/hapi/install.cjs.map +1 -0
- package/dist/hapi/install.d.cts +8 -0
- package/dist/hapi/install.d.ts +8 -0
- package/dist/hapi/install.js +22 -0
- package/dist/hapi/install.js.map +1 -0
- package/dist/hapi/middleware.cjs +158 -0
- package/dist/hapi/middleware.cjs.map +1 -0
- package/dist/hapi/middleware.d.cts +5 -0
- package/dist/hapi/middleware.d.ts +5 -0
- package/dist/hapi/middleware.js +137 -0
- package/dist/hapi/middleware.js.map +1 -0
- package/dist/{common/logging.cjs → hapi/routes.cjs} +14 -17
- package/dist/hapi/routes.cjs.map +1 -0
- package/dist/hapi/routes.d.cts +8 -0
- package/dist/hapi/routes.d.ts +8 -0
- package/dist/hapi/routes.js +12 -0
- package/dist/hapi/routes.js.map +1 -0
- package/dist/hono/index.cjs +13 -3
- package/dist/hono/index.cjs.map +1 -1
- package/dist/hono/index.d.cts +7 -10
- package/dist/hono/index.d.ts +7 -10
- package/dist/hono/index.js +13 -2
- package/dist/hono/index.js.map +1 -1
- package/dist/hono/middleware.cjs +219 -127
- package/dist/hono/middleware.cjs.map +1 -1
- package/dist/hono/middleware.d.cts +3 -18
- package/dist/hono/middleware.d.ts +3 -18
- package/dist/hono/middleware.js +229 -126
- package/dist/hono/middleware.js.map +1 -1
- package/dist/hono/routes.cjs +74 -0
- package/dist/hono/routes.cjs.map +1 -0
- package/dist/hono/routes.d.cts +8 -0
- package/dist/hono/routes.d.ts +8 -0
- package/dist/hono/routes.js +49 -0
- package/dist/hono/routes.js.map +1 -0
- package/dist/index.cjs +108 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -1
- package/dist/index.d.ts +29 -1
- package/dist/index.js +77 -0
- package/dist/index.js.map +1 -1
- package/dist/koa/index.cjs +13 -3
- package/dist/koa/index.cjs.map +1 -1
- package/dist/koa/index.d.cts +7 -10
- package/dist/koa/index.d.ts +7 -10
- package/dist/koa/index.js +13 -2
- package/dist/koa/index.js.map +1 -1
- package/dist/koa/middleware.cjs +85 -184
- package/dist/koa/middleware.cjs.map +1 -1
- package/dist/koa/middleware.d.cts +3 -13
- package/dist/koa/middleware.d.ts +3 -13
- package/dist/koa/middleware.js +88 -183
- package/dist/koa/middleware.js.map +1 -1
- package/dist/koa/routes.cjs +71 -0
- package/dist/koa/routes.cjs.map +1 -0
- package/dist/koa/routes.d.cts +8 -0
- package/dist/koa/routes.d.ts +8 -0
- package/dist/koa/routes.js +46 -0
- package/dist/koa/routes.js.map +1 -0
- package/dist/logCapture.cjs +417 -0
- package/dist/logCapture.cjs.map +1 -0
- package/dist/logCapture.d.cts +18 -0
- package/dist/logCapture.d.ts +18 -0
- package/dist/logCapture.js +390 -0
- package/dist/logCapture.js.map +1 -0
- package/dist/logRecordExporter.cjs +51 -0
- package/dist/logRecordExporter.cjs.map +1 -0
- package/dist/logRecordExporter.d.cts +14 -0
- package/dist/logRecordExporter.d.ts +14 -0
- package/dist/logRecordExporter.js +27 -0
- package/dist/logRecordExporter.js.map +1 -0
- package/dist/logRecordProcessor.cjs +137 -0
- package/dist/logRecordProcessor.cjs.map +1 -0
- package/dist/logRecordProcessor.d.cts +27 -0
- package/dist/logRecordProcessor.d.ts +27 -0
- package/dist/logRecordProcessor.js +113 -0
- package/dist/logRecordProcessor.js.map +1 -0
- package/dist/logger.cjs +62 -0
- package/dist/logger.cjs.map +1 -0
- package/dist/logger.d.cts +7 -0
- package/dist/logger.d.ts +7 -0
- package/dist/logger.js +34 -0
- package/dist/logger.js.map +1 -0
- package/dist/metrics.cjs +171 -0
- package/dist/metrics.cjs.map +1 -0
- package/dist/metrics.d.cts +26 -0
- package/dist/metrics.d.ts +26 -0
- package/dist/metrics.js +153 -0
- package/dist/metrics.js.map +1 -0
- package/dist/nestjs/index.cjs +81 -71
- package/dist/nestjs/index.cjs.map +1 -1
- package/dist/nestjs/index.d.cts +4 -11
- package/dist/nestjs/index.d.ts +4 -11
- package/dist/nestjs/index.js +81 -61
- package/dist/nestjs/index.js.map +1 -1
- package/dist/packageVersion.cjs +67 -0
- package/dist/packageVersion.cjs.map +1 -0
- package/dist/packageVersion.d.cts +5 -0
- package/dist/packageVersion.d.ts +5 -0
- package/dist/packageVersion.js +39 -0
- package/dist/packageVersion.js.map +1 -0
- package/dist/providers.cjs +149 -0
- package/dist/providers.cjs.map +1 -0
- package/dist/providers.d.cts +15 -0
- package/dist/providers.d.ts +15 -0
- package/dist/providers.js +136 -0
- package/dist/providers.js.map +1 -0
- package/dist/redaction.cjs +116 -0
- package/dist/redaction.cjs.map +1 -0
- package/dist/redaction.d.cts +17 -0
- package/dist/redaction.d.ts +17 -0
- package/dist/redaction.js +98 -0
- package/dist/redaction.js.map +1 -0
- package/dist/{common/packageVersions.cjs → requestAttributes.cjs} +21 -19
- package/dist/requestAttributes.cjs.map +1 -0
- package/dist/requestAttributes.d.cts +10 -0
- package/dist/requestAttributes.d.ts +10 -0
- package/dist/requestAttributes.js +22 -0
- package/dist/requestAttributes.js.map +1 -0
- package/dist/requestObservation.cjs +246 -0
- package/dist/requestObservation.cjs.map +1 -0
- package/dist/requestObservation.d.cts +62 -0
- package/dist/requestObservation.d.ts +62 -0
- package/dist/requestObservation.js +226 -0
- package/dist/requestObservation.js.map +1 -0
- package/dist/requestObservationNode.cjs +193 -0
- package/dist/requestObservationNode.cjs.map +1 -0
- package/dist/requestObservationNode.d.cts +31 -0
- package/dist/requestObservationNode.d.ts +31 -0
- package/dist/requestObservationNode.js +170 -0
- package/dist/requestObservationNode.js.map +1 -0
- package/dist/requestObservationWeb.cjs +202 -0
- package/dist/requestObservationWeb.cjs.map +1 -0
- package/dist/requestObservationWeb.d.cts +34 -0
- package/dist/requestObservationWeb.d.ts +34 -0
- package/dist/requestObservationWeb.js +182 -0
- package/dist/requestObservationWeb.js.map +1 -0
- package/dist/sentry.cjs +103 -0
- package/dist/sentry.cjs.map +1 -0
- package/dist/sentry.d.cts +3 -0
- package/dist/sentry.d.ts +3 -0
- package/dist/sentry.js +79 -0
- package/dist/sentry.js.map +1 -0
- package/dist/serverErrors.cjs +118 -0
- package/dist/serverErrors.cjs.map +1 -0
- package/dist/serverErrors.d.cts +8 -0
- package/dist/serverErrors.d.ts +8 -0
- package/dist/serverErrors.js +91 -0
- package/dist/serverErrors.js.map +1 -0
- package/dist/spanExporter.cjs +217 -0
- package/dist/spanExporter.cjs.map +1 -0
- package/dist/spanExporter.d.cts +34 -0
- package/dist/spanExporter.d.ts +34 -0
- package/dist/spanExporter.js +193 -0
- package/dist/spanExporter.js.map +1 -0
- package/dist/spanProcessor.cjs +535 -0
- package/dist/spanProcessor.cjs.map +1 -0
- package/dist/spanProcessor.d.cts +70 -0
- package/dist/spanProcessor.d.ts +70 -0
- package/dist/spanProcessor.js +513 -0
- package/dist/spanProcessor.js.map +1 -0
- package/dist/spool.cjs +314 -0
- package/dist/spool.cjs.map +1 -0
- package/dist/spool.d.cts +49 -0
- package/dist/spool.d.ts +49 -0
- package/dist/spool.js +297 -0
- package/dist/spool.js.map +1 -0
- package/dist/startup.cjs +98 -0
- package/dist/startup.cjs.map +1 -0
- package/dist/startup.d.cts +15 -0
- package/dist/startup.d.ts +15 -0
- package/dist/startup.js +73 -0
- package/dist/startup.js.map +1 -0
- package/dist/tracing.cjs +116 -0
- package/dist/tracing.cjs.map +1 -0
- package/dist/tracing.d.cts +5 -0
- package/dist/tracing.d.ts +5 -0
- package/dist/tracing.js +96 -0
- package/dist/tracing.js.map +1 -0
- package/dist/validationErrors.cjs +229 -0
- package/dist/validationErrors.cjs.map +1 -0
- package/dist/validationErrors.d.cts +21 -0
- package/dist/validationErrors.d.ts +21 -0
- package/dist/validationErrors.js +195 -0
- package/dist/validationErrors.js.map +1 -0
- package/package.json +113 -154
- package/dist/common/client.cjs +0 -335
- package/dist/common/client.cjs.map +0 -1
- package/dist/common/client.d.cts +0 -50
- package/dist/common/client.d.ts +0 -50
- package/dist/common/client.js +0 -302
- package/dist/common/client.js.map +0 -1
- package/dist/common/consumerRegistry.cjs +0 -86
- package/dist/common/consumerRegistry.cjs.map +0 -1
- package/dist/common/consumerRegistry.d.cts +0 -20
- package/dist/common/consumerRegistry.d.ts +0 -20
- package/dist/common/consumerRegistry.js +0 -62
- package/dist/common/consumerRegistry.js.map +0 -1
- package/dist/common/headers.cjs +0 -55
- package/dist/common/headers.cjs.map +0 -1
- package/dist/common/headers.d.cts +0 -6
- package/dist/common/headers.d.ts +0 -6
- package/dist/common/headers.js +0 -31
- package/dist/common/headers.js.map +0 -1
- package/dist/common/instance.cjs +0 -158
- package/dist/common/instance.cjs.map +0 -1
- package/dist/common/instance.d.cts +0 -4
- package/dist/common/instance.d.ts +0 -4
- package/dist/common/instance.js +0 -134
- package/dist/common/instance.js.map +0 -1
- package/dist/common/logging.cjs.map +0 -1
- package/dist/common/logging.d.cts +0 -11
- package/dist/common/logging.d.ts +0 -11
- package/dist/common/logging.js +0 -17
- package/dist/common/logging.js.map +0 -1
- package/dist/common/packageVersions.cjs.map +0 -1
- package/dist/common/packageVersions.d.cts +0 -3
- package/dist/common/packageVersions.d.ts +0 -3
- package/dist/common/packageVersions.js +0 -21
- package/dist/common/packageVersions.js.map +0 -1
- package/dist/common/paramValidation.cjs.map +0 -1
- package/dist/common/paramValidation.d.cts +0 -4
- package/dist/common/paramValidation.d.ts +0 -4
- package/dist/common/paramValidation.js +0 -17
- package/dist/common/paramValidation.js.map +0 -1
- package/dist/common/requestCounter.cjs +0 -114
- package/dist/common/requestCounter.cjs.map +0 -1
- package/dist/common/requestCounter.d.cts +0 -24
- package/dist/common/requestCounter.d.ts +0 -24
- package/dist/common/requestCounter.js +0 -91
- package/dist/common/requestCounter.js.map +0 -1
- package/dist/common/requestLogger.cjs +0 -543
- package/dist/common/requestLogger.cjs.map +0 -1
- package/dist/common/requestLogger.d.cts +0 -85
- package/dist/common/requestLogger.d.ts +0 -85
- package/dist/common/requestLogger.js +0 -508
- package/dist/common/requestLogger.js.map +0 -1
- package/dist/common/resources.cjs +0 -49
- package/dist/common/resources.cjs.map +0 -1
- package/dist/common/resources.d.cts +0 -6
- package/dist/common/resources.d.ts +0 -6
- package/dist/common/resources.js +0 -26
- package/dist/common/resources.js.map +0 -1
- package/dist/common/response.cjs +0 -104
- package/dist/common/response.cjs.map +0 -1
- package/dist/common/response.d.cts +0 -15
- package/dist/common/response.d.ts +0 -15
- package/dist/common/response.js +0 -80
- package/dist/common/response.js.map +0 -1
- package/dist/common/sentry.cjs +0 -56
- package/dist/common/sentry.cjs.map +0 -1
- package/dist/common/sentry.d.cts +0 -6
- package/dist/common/sentry.d.ts +0 -6
- package/dist/common/sentry.js +0 -23
- package/dist/common/sentry.js.map +0 -1
- package/dist/common/serverErrorCounter.cjs +0 -123
- package/dist/common/serverErrorCounter.cjs.map +0 -1
- package/dist/common/serverErrorCounter.d.cts +0 -23
- package/dist/common/serverErrorCounter.d.ts +0 -23
- package/dist/common/serverErrorCounter.js +0 -98
- package/dist/common/serverErrorCounter.js.map +0 -1
- package/dist/common/spanCollector.cjs +0 -201
- package/dist/common/spanCollector.cjs.map +0 -1
- package/dist/common/spanCollector.d.cts +0 -45
- package/dist/common/spanCollector.d.ts +0 -45
- package/dist/common/spanCollector.js +0 -177
- package/dist/common/spanCollector.js.map +0 -1
- package/dist/common/tempGzipFile.cjs +0 -127
- package/dist/common/tempGzipFile.cjs.map +0 -1
- package/dist/common/tempGzipFile.d.cts +0 -19
- package/dist/common/tempGzipFile.d.ts +0 -19
- package/dist/common/tempGzipFile.js +0 -103
- package/dist/common/tempGzipFile.js.map +0 -1
- package/dist/common/types.cjs +0 -17
- package/dist/common/types.cjs.map +0 -1
- package/dist/common/types.d.cts +0 -95
- package/dist/common/types.d.ts +0 -95
- package/dist/common/types.js +0 -1
- package/dist/common/types.js.map +0 -1
- package/dist/common/validationErrorCounter.cjs +0 -79
- package/dist/common/validationErrorCounter.cjs.map +0 -1
- package/dist/common/validationErrorCounter.d.cts +0 -20
- package/dist/common/validationErrorCounter.d.ts +0 -20
- package/dist/common/validationErrorCounter.js +0 -56
- package/dist/common/validationErrorCounter.js.map +0 -1
- package/dist/elysia/plugin.cjs +0 -242
- package/dist/elysia/plugin.cjs.map +0 -1
- package/dist/elysia/plugin.d.cts +0 -70
- package/dist/elysia/plugin.d.ts +0 -70
- package/dist/elysia/plugin.js +0 -219
- package/dist/elysia/plugin.js.map +0 -1
- package/dist/elysia/utils.cjs +0 -77
- package/dist/elysia/utils.cjs.map +0 -1
- package/dist/elysia/utils.d.cts +0 -14
- package/dist/elysia/utils.d.ts +0 -14
- package/dist/elysia/utils.js +0 -54
- package/dist/elysia/utils.js.map +0 -1
- package/dist/express/utils.cjs +0 -217
- package/dist/express/utils.cjs.map +0 -1
- package/dist/express/utils.d.cts +0 -37
- package/dist/express/utils.d.ts +0 -37
- package/dist/express/utils.js +0 -189
- package/dist/express/utils.js.map +0 -1
- package/dist/fastify/plugin.cjs +0 -319
- package/dist/fastify/plugin.cjs.map +0 -1
- package/dist/fastify/plugin.d.cts +0 -34
- package/dist/fastify/plugin.d.ts +0 -34
- package/dist/fastify/plugin.js +0 -284
- package/dist/fastify/plugin.js.map +0 -1
- package/dist/h3/plugin.cjs +0 -183
- package/dist/h3/plugin.cjs.map +0 -1
- package/dist/h3/plugin.d.cts +0 -27
- package/dist/h3/plugin.d.ts +0 -27
- package/dist/h3/plugin.js +0 -159
- package/dist/h3/plugin.js.map +0 -1
- package/dist/h3/utils.cjs +0 -77
- package/dist/h3/utils.cjs.map +0 -1
- package/dist/h3/utils.d.cts +0 -14
- package/dist/h3/utils.d.ts +0 -14
- package/dist/h3/utils.js +0 -54
- package/dist/h3/utils.js.map +0 -1
- package/dist/hapi/plugin.cjs +0 -212
- package/dist/hapi/plugin.cjs.map +0 -1
- package/dist/hapi/plugin.d.cts +0 -40
- package/dist/hapi/plugin.d.ts +0 -40
- package/dist/hapi/plugin.js +0 -188
- package/dist/hapi/plugin.js.map +0 -1
- package/dist/hapi/utils.cjs +0 -77
- package/dist/hapi/utils.cjs.map +0 -1
- package/dist/hapi/utils.d.cts +0 -16
- package/dist/hapi/utils.d.ts +0 -16
- package/dist/hapi/utils.js +0 -53
- package/dist/hapi/utils.js.map +0 -1
- package/dist/hono/utils.cjs +0 -113
- package/dist/hono/utils.cjs.map +0 -1
- package/dist/hono/utils.d.cts +0 -16
- package/dist/hono/utils.d.ts +0 -16
- package/dist/hono/utils.js +0 -88
- package/dist/hono/utils.js.map +0 -1
- package/dist/loggers/console.cjs +0 -67
- package/dist/loggers/console.cjs.map +0 -1
- package/dist/loggers/console.d.cts +0 -11
- package/dist/loggers/console.d.ts +0 -11
- package/dist/loggers/console.js +0 -44
- package/dist/loggers/console.js.map +0 -1
- package/dist/loggers/hapi.cjs.map +0 -1
- package/dist/loggers/hapi.d.cts +0 -12
- package/dist/loggers/hapi.d.ts +0 -12
- package/dist/loggers/hapi.js +0 -29
- package/dist/loggers/hapi.js.map +0 -1
- package/dist/loggers/index.cjs.map +0 -1
- package/dist/loggers/index.d.cts +0 -13
- package/dist/loggers/index.d.ts +0 -13
- package/dist/loggers/index.js +0 -13
- package/dist/loggers/index.js.map +0 -1
- package/dist/loggers/nestjs.cjs +0 -104
- package/dist/loggers/nestjs.cjs.map +0 -1
- package/dist/loggers/nestjs.d.cts +0 -11
- package/dist/loggers/nestjs.d.ts +0 -11
- package/dist/loggers/nestjs.js +0 -71
- package/dist/loggers/nestjs.js.map +0 -1
- package/dist/loggers/pino.cjs +0 -152
- package/dist/loggers/pino.cjs.map +0 -1
- package/dist/loggers/pino.d.cts +0 -11
- package/dist/loggers/pino.d.ts +0 -11
- package/dist/loggers/pino.js +0 -119
- package/dist/loggers/pino.js.map +0 -1
- package/dist/loggers/utils.cjs +0 -64
- package/dist/loggers/utils.cjs.map +0 -1
- package/dist/loggers/utils.d.cts +0 -6
- package/dist/loggers/utils.d.ts +0 -6
- package/dist/loggers/utils.js +0 -40
- package/dist/loggers/utils.js.map +0 -1
- package/dist/loggers/winston.cjs +0 -101
- package/dist/loggers/winston.cjs.map +0 -1
- package/dist/loggers/winston.d.cts +0 -11
- package/dist/loggers/winston.d.ts +0 -11
- package/dist/loggers/winston.js +0 -68
- package/dist/loggers/winston.js.map +0 -1
- package/dist/otel/index.cjs.map +0 -1
- package/dist/otel/index.d.cts +0 -2
- package/dist/otel/index.d.ts +0 -2
- package/dist/otel/index.js +0 -5
- package/dist/otel/index.js.map +0 -1
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var requestObservation_exports = {};
|
|
20
|
+
__export(requestObservation_exports, {
|
|
21
|
+
finalizeRequestObservation: () => finalizeRequestObservation,
|
|
22
|
+
finalizeRequestObservationWithError: () => finalizeRequestObservationWithError,
|
|
23
|
+
resolveHttpRequestStartAttributes: () => resolveHttpRequestStartAttributes,
|
|
24
|
+
startRequestObservation: () => startRequestObservation
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(requestObservation_exports);
|
|
27
|
+
var import_api = require("@opentelemetry/api");
|
|
28
|
+
var import_core = require("@opentelemetry/core");
|
|
29
|
+
var import_config = require('./config.cjs');
|
|
30
|
+
var import_context = require('./context.cjs');
|
|
31
|
+
var import_exceptions = require('./exceptions.cjs');
|
|
32
|
+
var import_logger = require('./logger.cjs');
|
|
33
|
+
var import_requestAttributes = require('./requestAttributes.cjs');
|
|
34
|
+
var import_serverErrors = require('./serverErrors.cjs');
|
|
35
|
+
var import_spanProcessor = require('./spanProcessor.cjs');
|
|
36
|
+
var import_validationErrors = require('./validationErrors.cjs');
|
|
37
|
+
function resolveHttpRequestStartAttributes(input) {
|
|
38
|
+
const attributes = { "http.request.method": input.method };
|
|
39
|
+
const optionalAttributes = [
|
|
40
|
+
["url.path", input.path],
|
|
41
|
+
["url.query", input.query],
|
|
42
|
+
["url.scheme", input.scheme],
|
|
43
|
+
["url.full", input.fullUrl],
|
|
44
|
+
["server.address", input.serverAddress],
|
|
45
|
+
["client.address", input.clientAddress],
|
|
46
|
+
["user_agent.original", input.userAgent],
|
|
47
|
+
["http.request.body.size", input.requestBodySize]
|
|
48
|
+
];
|
|
49
|
+
for (const [name, value] of optionalAttributes) {
|
|
50
|
+
if (value !== void 0) {
|
|
51
|
+
attributes[name] = value;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return attributes;
|
|
55
|
+
}
|
|
56
|
+
function startRequestObservation(options) {
|
|
57
|
+
const {
|
|
58
|
+
activeContext,
|
|
59
|
+
extractedContext,
|
|
60
|
+
tracerName,
|
|
61
|
+
method,
|
|
62
|
+
startAttributes,
|
|
63
|
+
requestBodyCapture
|
|
64
|
+
} = options;
|
|
65
|
+
const requestRecord = { attributes: {} };
|
|
66
|
+
const spanHandle = {};
|
|
67
|
+
const consumerHolder = (0, import_context.getConsumerHolder)(activeContext) ?? {};
|
|
68
|
+
Object.assign(requestRecord.attributes, startAttributes);
|
|
69
|
+
const activeSpan = import_api.trace.getSpan(activeContext);
|
|
70
|
+
const resolveUnavailableSpanDropReason = () => (0, import_spanProcessor.getActiveSpanPipeline)()?.resolveRequestDropReasonBeforeSampling(startAttributes) ?? "sampled-out";
|
|
71
|
+
let requestContext;
|
|
72
|
+
if (activeSpan?.isRecording() && activeSpan.kind === import_api.SpanKind.SERVER) {
|
|
73
|
+
spanHandle.span = activeSpan;
|
|
74
|
+
requestRecord.serverSpanId = activeSpan.spanContext().spanId;
|
|
75
|
+
(0, import_spanProcessor.getActiveSpanPipeline)()?.attachRequestRecord(requestRecord.serverSpanId, requestRecord);
|
|
76
|
+
if ((0, import_spanProcessor.getActiveSpanPipeline)()?.isRequestInFlight(requestRecord.serverSpanId) !== true) {
|
|
77
|
+
requestRecord.dropReason = resolveUnavailableSpanDropReason();
|
|
78
|
+
}
|
|
79
|
+
requestContext = (0, import_context.withRequestHolders)(activeContext, spanHandle, requestRecord, consumerHolder);
|
|
80
|
+
} else if (activeSpan && !activeSpan.isRecording() && !activeSpan.spanContext().isRemote) {
|
|
81
|
+
requestRecord.dropReason = resolveUnavailableSpanDropReason();
|
|
82
|
+
if (requestRecord.dropReason === "sampled-out") {
|
|
83
|
+
warnAboutNonRecordingServerSpan();
|
|
84
|
+
}
|
|
85
|
+
requestContext = (0, import_context.withRequestHolders)(activeContext, spanHandle, requestRecord, consumerHolder);
|
|
86
|
+
} else {
|
|
87
|
+
requestContext = (0, import_context.withRequestHolders)(
|
|
88
|
+
extractedContext,
|
|
89
|
+
spanHandle,
|
|
90
|
+
requestRecord,
|
|
91
|
+
consumerHolder
|
|
92
|
+
);
|
|
93
|
+
const ownSpan = import_api.trace.getTracer(tracerName).startSpan(method, { kind: import_api.SpanKind.SERVER, attributes: startAttributes }, requestContext);
|
|
94
|
+
if (!ownSpan.isRecording()) {
|
|
95
|
+
requestRecord.dropReason = resolveUnavailableSpanDropReason();
|
|
96
|
+
if (requestRecord.dropReason === "sampled-out") {
|
|
97
|
+
warnAboutNonRecordingServerSpan();
|
|
98
|
+
}
|
|
99
|
+
} else {
|
|
100
|
+
spanHandle.span = ownSpan;
|
|
101
|
+
spanHandle.ownSpan = ownSpan;
|
|
102
|
+
if ((0, import_spanProcessor.isApitallySpanProcessorDeclared)() && requestRecord.serverSpanId === void 0) {
|
|
103
|
+
requestRecord.dropReason = resolveUnavailableSpanDropReason();
|
|
104
|
+
if (requestRecord.dropReason === "sampled-out") {
|
|
105
|
+
warnAboutUnattachedSpanProcessor();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
requestContext = import_api.trace.setSpan(requestContext, ownSpan);
|
|
110
|
+
}
|
|
111
|
+
let rpcMetadata = (0, import_core.getRPCMetadata)(requestContext);
|
|
112
|
+
if (!rpcMetadata && spanHandle.span) {
|
|
113
|
+
rpcMetadata = { type: import_core.RPCType.HTTP, span: spanHandle.span };
|
|
114
|
+
requestContext = (0, import_core.setRPCMetadata)(requestContext, rpcMetadata);
|
|
115
|
+
}
|
|
116
|
+
(0, import_context.attachRequestRecordToRpcMetadata)(rpcMetadata, requestRecord);
|
|
117
|
+
if (requestRecord.dropReason !== void 0) {
|
|
118
|
+
requestBodyCapture.stopBuffering();
|
|
119
|
+
}
|
|
120
|
+
return { requestRecord, requestContext, spanHandle, rpcMetadata };
|
|
121
|
+
}
|
|
122
|
+
function finalizeRequestObservation(options) {
|
|
123
|
+
const { observation, statusCode, route } = options;
|
|
124
|
+
const { requestRecord, spanHandle, rpcMetadata, method } = observation;
|
|
125
|
+
requestRecord.durationSeconds = (options.completedAtMillis - observation.startTimeMillis) / 1e3;
|
|
126
|
+
const { span, ownSpan } = spanHandle;
|
|
127
|
+
if (options.clientAddress !== void 0) {
|
|
128
|
+
(0, import_requestAttributes.writeRequestAttribute)(span, requestRecord, "client.address", options.clientAddress);
|
|
129
|
+
}
|
|
130
|
+
(0, import_requestAttributes.writeRequestAttribute)(span, requestRecord, "http.response.status_code", statusCode);
|
|
131
|
+
const requestBodySize = options.capturedRequestBody?.size;
|
|
132
|
+
if (requestBodySize !== void 0) {
|
|
133
|
+
(0, import_requestAttributes.writeRequestAttribute)(span, requestRecord, "http.request.body.size", requestBodySize);
|
|
134
|
+
}
|
|
135
|
+
const responseBodySize = options.capturedResponseBody?.size;
|
|
136
|
+
if (responseBodySize !== void 0) {
|
|
137
|
+
(0, import_requestAttributes.writeRequestAttribute)(span, requestRecord, "http.response.body.size", responseBodySize);
|
|
138
|
+
}
|
|
139
|
+
if (route !== void 0) {
|
|
140
|
+
(0, import_requestAttributes.writeRequestAttribute)(span, requestRecord, "http.route", route);
|
|
141
|
+
if (rpcMetadata) {
|
|
142
|
+
rpcMetadata.route = route;
|
|
143
|
+
}
|
|
144
|
+
if (ownSpan?.isRecording()) {
|
|
145
|
+
ownSpan.updateName(`${method} ${route}`);
|
|
146
|
+
}
|
|
147
|
+
} else {
|
|
148
|
+
requestRecord.attributes["http.route"] = "";
|
|
149
|
+
}
|
|
150
|
+
if (ownSpan && statusCode >= 500) {
|
|
151
|
+
ownSpan.setStatus({ code: import_api.SpanStatusCode.ERROR });
|
|
152
|
+
}
|
|
153
|
+
const consumer = requestRecord.attributes["apitally.consumer.identifier"];
|
|
154
|
+
const consumerIdentifier = typeof consumer === "string" ? consumer : void 0;
|
|
155
|
+
if (requestRecord.validationErrors && (0, import_validationErrors.isValidationResponseStatus)(statusCode)) {
|
|
156
|
+
(0, import_validationErrors.addValidationErrors)(consumerIdentifier, method, route ?? "", requestRecord.validationErrors);
|
|
157
|
+
}
|
|
158
|
+
if (statusCode === 500 && requestRecord.exception !== void 0) {
|
|
159
|
+
const sentryEventId = requestRecord.attributes["apitally.exception.sentry_event_id"];
|
|
160
|
+
(0, import_serverErrors.addServerError)(
|
|
161
|
+
consumerIdentifier,
|
|
162
|
+
method,
|
|
163
|
+
route ?? "",
|
|
164
|
+
requestRecord.exception,
|
|
165
|
+
typeof sentryEventId === "string" ? sentryEventId : void 0
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
if (requestRecord.serverSpanId !== void 0 && requestRecord.dropReason === void 0) {
|
|
169
|
+
const config = (0, import_config.getConfig)();
|
|
170
|
+
const stash = {};
|
|
171
|
+
if (config.captureRequestHeaders) {
|
|
172
|
+
stash.requestHeaders = normalizeHeaders(options.requestHeaders);
|
|
173
|
+
}
|
|
174
|
+
if (config.captureResponseHeaders) {
|
|
175
|
+
stash.responseHeaders = normalizeHeaders(options.responseHeaders);
|
|
176
|
+
}
|
|
177
|
+
const requestBody = options.capturedRequestBody?.body;
|
|
178
|
+
if (requestBody) {
|
|
179
|
+
stash.requestBody = requestBody;
|
|
180
|
+
}
|
|
181
|
+
const responseBody = options.capturedResponseBody?.body;
|
|
182
|
+
if (responseBody && config.captureResponseBody) {
|
|
183
|
+
stash.responseBody = responseBody;
|
|
184
|
+
}
|
|
185
|
+
if (Object.keys(stash).length > 0) {
|
|
186
|
+
(0, import_spanProcessor.getActiveSpanPipeline)()?.updateStash(requestRecord.serverSpanId, stash);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
ownSpan?.end(options.completedAtMillis);
|
|
190
|
+
(0, import_spanProcessor.getActiveSpanPipeline)()?.handleTransportCompletion(requestRecord);
|
|
191
|
+
}
|
|
192
|
+
function finalizeRequestObservationWithError(options) {
|
|
193
|
+
const { requestRecord, spanHandle, error, durationSeconds } = options;
|
|
194
|
+
requestRecord.durationSeconds = durationSeconds;
|
|
195
|
+
if (spanHandle.span?.isRecording()) {
|
|
196
|
+
spanHandle.span.recordException((0, import_exceptions.coerceToException)(error));
|
|
197
|
+
}
|
|
198
|
+
if (spanHandle.ownSpan) {
|
|
199
|
+
spanHandle.ownSpan.setStatus({ code: import_api.SpanStatusCode.ERROR });
|
|
200
|
+
spanHandle.ownSpan.end();
|
|
201
|
+
}
|
|
202
|
+
(0, import_spanProcessor.getActiveSpanPipeline)()?.handleTransportCompletion(requestRecord);
|
|
203
|
+
}
|
|
204
|
+
function normalizeHeaders(headers) {
|
|
205
|
+
const normalized = {};
|
|
206
|
+
if (isWebHeaders(headers)) {
|
|
207
|
+
for (const [name, value] of headers) {
|
|
208
|
+
const existing = normalized[name];
|
|
209
|
+
if (existing === void 0) {
|
|
210
|
+
normalized[name] = value;
|
|
211
|
+
} else if (Array.isArray(existing)) {
|
|
212
|
+
existing.push(value);
|
|
213
|
+
} else {
|
|
214
|
+
normalized[name] = [existing, value];
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return normalized;
|
|
218
|
+
}
|
|
219
|
+
for (const [name, value] of Object.entries(headers)) {
|
|
220
|
+
if (value !== void 0) {
|
|
221
|
+
normalized[name.toLowerCase()] = Array.isArray(value) ? value : String(value);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return normalized;
|
|
225
|
+
}
|
|
226
|
+
function isWebHeaders(headers) {
|
|
227
|
+
return typeof headers[Symbol.iterator] === "function";
|
|
228
|
+
}
|
|
229
|
+
function warnAboutNonRecordingServerSpan() {
|
|
230
|
+
(0, import_logger.logWarning)(
|
|
231
|
+
"The OpenTelemetry sampler did not sample the SERVER span of a request. Only sampled requests are exported to Apitally as traces and request logs. Request metrics include all requests."
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
function warnAboutUnattachedSpanProcessor() {
|
|
235
|
+
(0, import_logger.logWarning)(
|
|
236
|
+
"The recording OpenTelemetry SERVER span created for a request did not reach ApitallySpanProcessor. Traces and request logs are unavailable while request metrics continue. To resolve this, add the ApitallySpanProcessor instance to your tracer provider's spanProcessors constructor option or the NodeSDK spanProcessors option."
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
240
|
+
0 && (module.exports = {
|
|
241
|
+
finalizeRequestObservation,
|
|
242
|
+
finalizeRequestObservationWithError,
|
|
243
|
+
resolveHttpRequestStartAttributes,
|
|
244
|
+
startRequestObservation
|
|
245
|
+
});
|
|
246
|
+
//# sourceMappingURL=requestObservation.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/requestObservation.ts"],"sourcesContent":["import { type Attributes, type Context, SpanKind, SpanStatusCode, trace } from \"@opentelemetry/api\";\nimport { getRPCMetadata, type RPCMetadata, RPCType, setRPCMetadata } from \"@opentelemetry/core\";\nimport type { BodyCapture, CapturedBody } from \"./bodyCapture.js\";\nimport { getConfig } from \"./config.js\";\nimport {\n attachRequestRecordToRpcMetadata,\n getConsumerHolder,\n type RequestRecord,\n type SpanHandle,\n withRequestHolders,\n} from \"./context.js\";\nimport { coerceToException } from \"./exceptions.js\";\nimport { logWarning } from \"./logger.js\";\nimport { writeRequestAttribute } from \"./requestAttributes.js\";\nimport { addServerError } from \"./serverErrors.js\";\nimport {\n getActiveSpanPipeline,\n isApitallySpanProcessorDeclared,\n type RequestStash,\n} from \"./spanProcessor.js\";\nimport { addValidationErrors, isValidationResponseStatus } from \"./validationErrors.js\";\n\ninterface StartRequestObservationOptions {\n activeContext: Context;\n extractedContext: Context;\n tracerName: string;\n method: string;\n startAttributes: Attributes;\n requestBodyCapture: BodyCapture;\n}\n\nexport interface StartedRequestObservation {\n requestRecord: RequestRecord;\n requestContext: Context;\n spanHandle: SpanHandle;\n rpcMetadata?: RPCMetadata;\n}\n\nexport interface HttpRequestStartAttributeInput {\n method: string;\n path?: string;\n query?: string;\n scheme?: string;\n serverAddress?: string;\n fullUrl?: string;\n clientAddress?: string;\n userAgent?: string;\n requestBodySize?: number;\n}\n\nexport function resolveHttpRequestStartAttributes(\n input: HttpRequestStartAttributeInput,\n): Attributes {\n const attributes: Attributes = { \"http.request.method\": input.method };\n const optionalAttributes: [string, string | number | undefined][] = [\n [\"url.path\", input.path],\n [\"url.query\", input.query],\n [\"url.scheme\", input.scheme],\n [\"url.full\", input.fullUrl],\n [\"server.address\", input.serverAddress],\n [\"client.address\", input.clientAddress],\n [\"user_agent.original\", input.userAgent],\n [\"http.request.body.size\", input.requestBodySize],\n ];\n for (const [name, value] of optionalAttributes) {\n if (value !== undefined) {\n attributes[name] = value;\n }\n }\n return attributes;\n}\n\nexport function startRequestObservation(\n options: StartRequestObservationOptions,\n): StartedRequestObservation {\n const {\n activeContext,\n extractedContext,\n tracerName,\n method,\n startAttributes,\n requestBodyCapture,\n } = options;\n const requestRecord: RequestRecord = { attributes: {} };\n const spanHandle: SpanHandle = {};\n const consumerHolder = getConsumerHolder(activeContext) ?? {};\n // Metrics and the exported span copy read from the request record, so the\n // start attributes are mirrored into it on every path, span or no span.\n Object.assign(requestRecord.attributes, startAttributes);\n const activeSpan = trace.getSpan(activeContext);\n const resolveUnavailableSpanDropReason = (): RequestRecord[\"dropReason\"] =>\n getActiveSpanPipeline()?.resolveRequestDropReasonBeforeSampling(startAttributes) ??\n \"sampled-out\";\n let requestContext: Context;\n // Span kind is not part of the OTel API surface, so read the SDK-level\n // property from whichever package copy produced the span.\n if (activeSpan?.isRecording() && (activeSpan as { kind?: unknown }).kind === SpanKind.SERVER) {\n // A SERVER span produced by the user's own instrumentation is adopted:\n // no second span, and the request runs under the user's context.\n spanHandle.span = activeSpan;\n requestRecord.serverSpanId = activeSpan.spanContext().spanId;\n getActiveSpanPipeline()?.attachRequestRecord(requestRecord.serverSpanId, requestRecord);\n if (getActiveSpanPipeline()?.isRequestInFlight(requestRecord.serverSpanId) !== true) {\n requestRecord.dropReason = resolveUnavailableSpanDropReason();\n }\n requestContext = withRequestHolders(activeContext, spanHandle, requestRecord, consumerHolder);\n } else if (activeSpan && !activeSpan.isRecording() && !activeSpan.spanContext().isRemote) {\n requestRecord.dropReason = resolveUnavailableSpanDropReason();\n if (requestRecord.dropReason === \"sampled-out\") {\n warnAboutNonRecordingServerSpan();\n }\n requestContext = withRequestHolders(activeContext, spanHandle, requestRecord, consumerHolder);\n } else {\n requestContext = withRequestHolders(\n extractedContext,\n spanHandle,\n requestRecord,\n consumerHolder,\n );\n const ownSpan = trace\n .getTracer(tracerName)\n .startSpan(method, { kind: SpanKind.SERVER, attributes: startAttributes }, requestContext);\n if (!ownSpan.isRecording()) {\n requestRecord.dropReason = resolveUnavailableSpanDropReason();\n if (requestRecord.dropReason === \"sampled-out\") {\n warnAboutNonRecordingServerSpan();\n }\n } else {\n spanHandle.span = ownSpan;\n spanHandle.ownSpan = ownSpan;\n if (isApitallySpanProcessorDeclared() && requestRecord.serverSpanId === undefined) {\n requestRecord.dropReason = resolveUnavailableSpanDropReason();\n if (requestRecord.dropReason === \"sampled-out\") {\n warnAboutUnattachedSpanProcessor();\n }\n }\n }\n // A non-recording span still carries a valid span context, so user child\n // spans parent to it and parent-based samplers drop them consistently.\n requestContext = trace.setSpan(requestContext, ownSpan);\n }\n\n // Middleware-based span producers inspect OTel RPC metadata to demote duplicate\n // transport spans; completion adds the route.\n let rpcMetadata = getRPCMetadata(requestContext);\n if (!rpcMetadata && spanHandle.span) {\n rpcMetadata = { type: RPCType.HTTP, span: spanHandle.span };\n requestContext = setRPCMetadata(requestContext, rpcMetadata);\n }\n attachRequestRecordToRpcMetadata(rpcMetadata, requestRecord);\n if (requestRecord.dropReason !== undefined) {\n requestBodyCapture.stopBuffering();\n }\n return { requestRecord, requestContext, spanHandle, rpcMetadata };\n}\n\nexport interface RequestObservation {\n requestRecord: RequestRecord;\n spanHandle: SpanHandle;\n rpcMetadata?: RPCMetadata;\n method: string;\n startTimeMillis: number;\n}\n\nexport interface FinalizeRequestObservationOptions {\n observation: RequestObservation;\n completedAtMillis: number;\n statusCode: number;\n route?: string;\n clientAddress?: string;\n requestHeaders: Headers | Record<string, string | string[] | undefined>;\n responseHeaders: Headers | Record<string, string | number | string[] | undefined>;\n capturedRequestBody?: CapturedBody;\n capturedResponseBody?: CapturedBody;\n}\n\nexport function finalizeRequestObservation(options: FinalizeRequestObservationOptions): void {\n const { observation, statusCode, route } = options;\n const { requestRecord, spanHandle, rpcMetadata, method } = observation;\n requestRecord.durationSeconds = (options.completedAtMillis - observation.startTimeMillis) / 1000;\n const { span, ownSpan } = spanHandle;\n if (options.clientAddress !== undefined) {\n writeRequestAttribute(span, requestRecord, \"client.address\", options.clientAddress);\n }\n writeRequestAttribute(span, requestRecord, \"http.response.status_code\", statusCode);\n const requestBodySize = options.capturedRequestBody?.size;\n if (requestBodySize !== undefined) {\n writeRequestAttribute(span, requestRecord, \"http.request.body.size\", requestBodySize);\n }\n const responseBodySize = options.capturedResponseBody?.size;\n if (responseBodySize !== undefined) {\n writeRequestAttribute(span, requestRecord, \"http.response.body.size\", responseBodySize);\n }\n if (route !== undefined) {\n writeRequestAttribute(span, requestRecord, \"http.route\", route);\n if (rpcMetadata) {\n rpcMetadata.route = route;\n }\n if (ownSpan?.isRecording()) {\n ownSpan.updateName(`${method} ${route}`);\n }\n } else {\n // An empty route clears one set by the producing instrumentation; request\n // metrics omit empty routes.\n requestRecord.attributes[\"http.route\"] = \"\";\n }\n if (ownSpan && statusCode >= 500) {\n ownSpan.setStatus({ code: SpanStatusCode.ERROR });\n }\n // Validation and server errors are counted for every routed request,\n // including requests dropped from tracing.\n const consumer = requestRecord.attributes[\"apitally.consumer.identifier\"];\n const consumerIdentifier = typeof consumer === \"string\" ? consumer : undefined;\n if (requestRecord.validationErrors && isValidationResponseStatus(statusCode)) {\n addValidationErrors(consumerIdentifier, method, route ?? \"\", requestRecord.validationErrors);\n }\n if (statusCode === 500 && requestRecord.exception !== undefined) {\n const sentryEventId = requestRecord.attributes[\"apitally.exception.sentry_event_id\"];\n addServerError(\n consumerIdentifier,\n method,\n route ?? \"\",\n requestRecord.exception,\n typeof sentryEventId === \"string\" ? sentryEventId : undefined,\n );\n }\n // A dropped request's spans are never released, so a stash entry for it\n // would sit unconsumed until the cap evicts it.\n if (requestRecord.serverSpanId !== undefined && requestRecord.dropReason === undefined) {\n const config = getConfig();\n const stash: RequestStash = {};\n if (config.captureRequestHeaders) {\n stash.requestHeaders = normalizeHeaders(options.requestHeaders);\n }\n if (config.captureResponseHeaders) {\n stash.responseHeaders = normalizeHeaders(options.responseHeaders);\n }\n const requestBody = options.capturedRequestBody?.body;\n if (requestBody) {\n stash.requestBody = requestBody;\n }\n const responseBody = options.capturedResponseBody?.body;\n if (responseBody && config.captureResponseBody) {\n stash.responseBody = responseBody;\n }\n if (Object.keys(stash).length > 0) {\n getActiveSpanPipeline()?.updateStash(requestRecord.serverSpanId, stash);\n }\n }\n ownSpan?.end(options.completedAtMillis);\n getActiveSpanPipeline()?.handleTransportCompletion(requestRecord);\n}\n\nexport interface FinalizeRequestObservationWithErrorOptions {\n requestRecord: RequestRecord;\n spanHandle: SpanHandle;\n error: unknown;\n durationSeconds: number;\n}\n\nexport function finalizeRequestObservationWithError(\n options: FinalizeRequestObservationWithErrorOptions,\n): void {\n const { requestRecord, spanHandle, error, durationSeconds } = options;\n requestRecord.durationSeconds = durationSeconds;\n if (spanHandle.span?.isRecording()) {\n spanHandle.span.recordException(coerceToException(error));\n }\n if (spanHandle.ownSpan) {\n spanHandle.ownSpan.setStatus({ code: SpanStatusCode.ERROR });\n spanHandle.ownSpan.end();\n }\n getActiveSpanPipeline()?.handleTransportCompletion(requestRecord);\n}\n\n// Values remain raw so all redaction happens at the export boundary.\nfunction normalizeHeaders(\n headers: Headers | Record<string, string | number | string[] | undefined>,\n): Record<string, string | string[]> {\n const normalized: Record<string, string | string[]> = {};\n if (isWebHeaders(headers)) {\n // The Headers API combines repeated values except Set-Cookie.\n for (const [name, value] of headers) {\n const existing = normalized[name];\n if (existing === undefined) {\n normalized[name] = value;\n } else if (Array.isArray(existing)) {\n existing.push(value);\n } else {\n normalized[name] = [existing, value];\n }\n }\n return normalized;\n }\n for (const [name, value] of Object.entries(headers)) {\n if (value !== undefined) {\n normalized[name.toLowerCase()] = Array.isArray(value) ? value : String(value);\n }\n }\n return normalized;\n}\n\n// Duck-typed on iterability: a plain header record has no Symbol.iterator, and\n// the Headers instance may come from another realm's implementation.\nfunction isWebHeaders(headers: object): headers is Headers {\n return typeof (headers as Headers)[Symbol.iterator] === \"function\";\n}\n\nfunction warnAboutNonRecordingServerSpan(): void {\n logWarning(\n \"The OpenTelemetry sampler did not sample the SERVER span of a request. Only sampled requests are exported to Apitally as traces and request logs. Request metrics include all requests.\",\n );\n}\n\nfunction warnAboutUnattachedSpanProcessor(): void {\n logWarning(\n \"The recording OpenTelemetry SERVER span created for a request did not reach ApitallySpanProcessor. Traces and request logs are unavailable while request metrics continue. To resolve this, add the ApitallySpanProcessor instance to your tracer provider's spanProcessors constructor option or the NodeSDK spanProcessors option.\",\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Context, Attributes } from '@opentelemetry/api';
|
|
2
|
+
import { RPCMetadata } from '@opentelemetry/core';
|
|
3
|
+
import { CapturedBody, BodyCapture } from './bodyCapture.cjs';
|
|
4
|
+
import { RequestRecord, SpanHandle } from './context.cjs';
|
|
5
|
+
import './validationErrors.cjs';
|
|
6
|
+
import '@opentelemetry/api-logs';
|
|
7
|
+
|
|
8
|
+
interface StartRequestObservationOptions {
|
|
9
|
+
activeContext: Context;
|
|
10
|
+
extractedContext: Context;
|
|
11
|
+
tracerName: string;
|
|
12
|
+
method: string;
|
|
13
|
+
startAttributes: Attributes;
|
|
14
|
+
requestBodyCapture: BodyCapture;
|
|
15
|
+
}
|
|
16
|
+
interface StartedRequestObservation {
|
|
17
|
+
requestRecord: RequestRecord;
|
|
18
|
+
requestContext: Context;
|
|
19
|
+
spanHandle: SpanHandle;
|
|
20
|
+
rpcMetadata?: RPCMetadata;
|
|
21
|
+
}
|
|
22
|
+
interface HttpRequestStartAttributeInput {
|
|
23
|
+
method: string;
|
|
24
|
+
path?: string;
|
|
25
|
+
query?: string;
|
|
26
|
+
scheme?: string;
|
|
27
|
+
serverAddress?: string;
|
|
28
|
+
fullUrl?: string;
|
|
29
|
+
clientAddress?: string;
|
|
30
|
+
userAgent?: string;
|
|
31
|
+
requestBodySize?: number;
|
|
32
|
+
}
|
|
33
|
+
declare function resolveHttpRequestStartAttributes(input: HttpRequestStartAttributeInput): Attributes;
|
|
34
|
+
declare function startRequestObservation(options: StartRequestObservationOptions): StartedRequestObservation;
|
|
35
|
+
interface RequestObservation {
|
|
36
|
+
requestRecord: RequestRecord;
|
|
37
|
+
spanHandle: SpanHandle;
|
|
38
|
+
rpcMetadata?: RPCMetadata;
|
|
39
|
+
method: string;
|
|
40
|
+
startTimeMillis: number;
|
|
41
|
+
}
|
|
42
|
+
interface FinalizeRequestObservationOptions {
|
|
43
|
+
observation: RequestObservation;
|
|
44
|
+
completedAtMillis: number;
|
|
45
|
+
statusCode: number;
|
|
46
|
+
route?: string;
|
|
47
|
+
clientAddress?: string;
|
|
48
|
+
requestHeaders: Headers | Record<string, string | string[] | undefined>;
|
|
49
|
+
responseHeaders: Headers | Record<string, string | number | string[] | undefined>;
|
|
50
|
+
capturedRequestBody?: CapturedBody;
|
|
51
|
+
capturedResponseBody?: CapturedBody;
|
|
52
|
+
}
|
|
53
|
+
declare function finalizeRequestObservation(options: FinalizeRequestObservationOptions): void;
|
|
54
|
+
interface FinalizeRequestObservationWithErrorOptions {
|
|
55
|
+
requestRecord: RequestRecord;
|
|
56
|
+
spanHandle: SpanHandle;
|
|
57
|
+
error: unknown;
|
|
58
|
+
durationSeconds: number;
|
|
59
|
+
}
|
|
60
|
+
declare function finalizeRequestObservationWithError(options: FinalizeRequestObservationWithErrorOptions): void;
|
|
61
|
+
|
|
62
|
+
export { type FinalizeRequestObservationOptions, type FinalizeRequestObservationWithErrorOptions, type HttpRequestStartAttributeInput, type RequestObservation, type StartedRequestObservation, finalizeRequestObservation, finalizeRequestObservationWithError, resolveHttpRequestStartAttributes, startRequestObservation };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Context, Attributes } from '@opentelemetry/api';
|
|
2
|
+
import { RPCMetadata } from '@opentelemetry/core';
|
|
3
|
+
import { CapturedBody, BodyCapture } from './bodyCapture.js';
|
|
4
|
+
import { RequestRecord, SpanHandle } from './context.js';
|
|
5
|
+
import './validationErrors.js';
|
|
6
|
+
import '@opentelemetry/api-logs';
|
|
7
|
+
|
|
8
|
+
interface StartRequestObservationOptions {
|
|
9
|
+
activeContext: Context;
|
|
10
|
+
extractedContext: Context;
|
|
11
|
+
tracerName: string;
|
|
12
|
+
method: string;
|
|
13
|
+
startAttributes: Attributes;
|
|
14
|
+
requestBodyCapture: BodyCapture;
|
|
15
|
+
}
|
|
16
|
+
interface StartedRequestObservation {
|
|
17
|
+
requestRecord: RequestRecord;
|
|
18
|
+
requestContext: Context;
|
|
19
|
+
spanHandle: SpanHandle;
|
|
20
|
+
rpcMetadata?: RPCMetadata;
|
|
21
|
+
}
|
|
22
|
+
interface HttpRequestStartAttributeInput {
|
|
23
|
+
method: string;
|
|
24
|
+
path?: string;
|
|
25
|
+
query?: string;
|
|
26
|
+
scheme?: string;
|
|
27
|
+
serverAddress?: string;
|
|
28
|
+
fullUrl?: string;
|
|
29
|
+
clientAddress?: string;
|
|
30
|
+
userAgent?: string;
|
|
31
|
+
requestBodySize?: number;
|
|
32
|
+
}
|
|
33
|
+
declare function resolveHttpRequestStartAttributes(input: HttpRequestStartAttributeInput): Attributes;
|
|
34
|
+
declare function startRequestObservation(options: StartRequestObservationOptions): StartedRequestObservation;
|
|
35
|
+
interface RequestObservation {
|
|
36
|
+
requestRecord: RequestRecord;
|
|
37
|
+
spanHandle: SpanHandle;
|
|
38
|
+
rpcMetadata?: RPCMetadata;
|
|
39
|
+
method: string;
|
|
40
|
+
startTimeMillis: number;
|
|
41
|
+
}
|
|
42
|
+
interface FinalizeRequestObservationOptions {
|
|
43
|
+
observation: RequestObservation;
|
|
44
|
+
completedAtMillis: number;
|
|
45
|
+
statusCode: number;
|
|
46
|
+
route?: string;
|
|
47
|
+
clientAddress?: string;
|
|
48
|
+
requestHeaders: Headers | Record<string, string | string[] | undefined>;
|
|
49
|
+
responseHeaders: Headers | Record<string, string | number | string[] | undefined>;
|
|
50
|
+
capturedRequestBody?: CapturedBody;
|
|
51
|
+
capturedResponseBody?: CapturedBody;
|
|
52
|
+
}
|
|
53
|
+
declare function finalizeRequestObservation(options: FinalizeRequestObservationOptions): void;
|
|
54
|
+
interface FinalizeRequestObservationWithErrorOptions {
|
|
55
|
+
requestRecord: RequestRecord;
|
|
56
|
+
spanHandle: SpanHandle;
|
|
57
|
+
error: unknown;
|
|
58
|
+
durationSeconds: number;
|
|
59
|
+
}
|
|
60
|
+
declare function finalizeRequestObservationWithError(options: FinalizeRequestObservationWithErrorOptions): void;
|
|
61
|
+
|
|
62
|
+
export { type FinalizeRequestObservationOptions, type FinalizeRequestObservationWithErrorOptions, type HttpRequestStartAttributeInput, type RequestObservation, type StartedRequestObservation, finalizeRequestObservation, finalizeRequestObservationWithError, resolveHttpRequestStartAttributes, startRequestObservation };
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { SpanKind, SpanStatusCode, trace } from "@opentelemetry/api";
|
|
2
|
+
import { getRPCMetadata, RPCType, setRPCMetadata } from "@opentelemetry/core";
|
|
3
|
+
import { getConfig } from "./config.js";
|
|
4
|
+
import {
|
|
5
|
+
attachRequestRecordToRpcMetadata,
|
|
6
|
+
getConsumerHolder,
|
|
7
|
+
withRequestHolders
|
|
8
|
+
} from "./context.js";
|
|
9
|
+
import { coerceToException } from "./exceptions.js";
|
|
10
|
+
import { logWarning } from "./logger.js";
|
|
11
|
+
import { writeRequestAttribute } from "./requestAttributes.js";
|
|
12
|
+
import { addServerError } from "./serverErrors.js";
|
|
13
|
+
import {
|
|
14
|
+
getActiveSpanPipeline,
|
|
15
|
+
isApitallySpanProcessorDeclared
|
|
16
|
+
} from "./spanProcessor.js";
|
|
17
|
+
import { addValidationErrors, isValidationResponseStatus } from "./validationErrors.js";
|
|
18
|
+
function resolveHttpRequestStartAttributes(input) {
|
|
19
|
+
const attributes = { "http.request.method": input.method };
|
|
20
|
+
const optionalAttributes = [
|
|
21
|
+
["url.path", input.path],
|
|
22
|
+
["url.query", input.query],
|
|
23
|
+
["url.scheme", input.scheme],
|
|
24
|
+
["url.full", input.fullUrl],
|
|
25
|
+
["server.address", input.serverAddress],
|
|
26
|
+
["client.address", input.clientAddress],
|
|
27
|
+
["user_agent.original", input.userAgent],
|
|
28
|
+
["http.request.body.size", input.requestBodySize]
|
|
29
|
+
];
|
|
30
|
+
for (const [name, value] of optionalAttributes) {
|
|
31
|
+
if (value !== void 0) {
|
|
32
|
+
attributes[name] = value;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return attributes;
|
|
36
|
+
}
|
|
37
|
+
function startRequestObservation(options) {
|
|
38
|
+
const {
|
|
39
|
+
activeContext,
|
|
40
|
+
extractedContext,
|
|
41
|
+
tracerName,
|
|
42
|
+
method,
|
|
43
|
+
startAttributes,
|
|
44
|
+
requestBodyCapture
|
|
45
|
+
} = options;
|
|
46
|
+
const requestRecord = { attributes: {} };
|
|
47
|
+
const spanHandle = {};
|
|
48
|
+
const consumerHolder = getConsumerHolder(activeContext) ?? {};
|
|
49
|
+
Object.assign(requestRecord.attributes, startAttributes);
|
|
50
|
+
const activeSpan = trace.getSpan(activeContext);
|
|
51
|
+
const resolveUnavailableSpanDropReason = () => getActiveSpanPipeline()?.resolveRequestDropReasonBeforeSampling(startAttributes) ?? "sampled-out";
|
|
52
|
+
let requestContext;
|
|
53
|
+
if (activeSpan?.isRecording() && activeSpan.kind === SpanKind.SERVER) {
|
|
54
|
+
spanHandle.span = activeSpan;
|
|
55
|
+
requestRecord.serverSpanId = activeSpan.spanContext().spanId;
|
|
56
|
+
getActiveSpanPipeline()?.attachRequestRecord(requestRecord.serverSpanId, requestRecord);
|
|
57
|
+
if (getActiveSpanPipeline()?.isRequestInFlight(requestRecord.serverSpanId) !== true) {
|
|
58
|
+
requestRecord.dropReason = resolveUnavailableSpanDropReason();
|
|
59
|
+
}
|
|
60
|
+
requestContext = withRequestHolders(activeContext, spanHandle, requestRecord, consumerHolder);
|
|
61
|
+
} else if (activeSpan && !activeSpan.isRecording() && !activeSpan.spanContext().isRemote) {
|
|
62
|
+
requestRecord.dropReason = resolveUnavailableSpanDropReason();
|
|
63
|
+
if (requestRecord.dropReason === "sampled-out") {
|
|
64
|
+
warnAboutNonRecordingServerSpan();
|
|
65
|
+
}
|
|
66
|
+
requestContext = withRequestHolders(activeContext, spanHandle, requestRecord, consumerHolder);
|
|
67
|
+
} else {
|
|
68
|
+
requestContext = withRequestHolders(
|
|
69
|
+
extractedContext,
|
|
70
|
+
spanHandle,
|
|
71
|
+
requestRecord,
|
|
72
|
+
consumerHolder
|
|
73
|
+
);
|
|
74
|
+
const ownSpan = trace.getTracer(tracerName).startSpan(method, { kind: SpanKind.SERVER, attributes: startAttributes }, requestContext);
|
|
75
|
+
if (!ownSpan.isRecording()) {
|
|
76
|
+
requestRecord.dropReason = resolveUnavailableSpanDropReason();
|
|
77
|
+
if (requestRecord.dropReason === "sampled-out") {
|
|
78
|
+
warnAboutNonRecordingServerSpan();
|
|
79
|
+
}
|
|
80
|
+
} else {
|
|
81
|
+
spanHandle.span = ownSpan;
|
|
82
|
+
spanHandle.ownSpan = ownSpan;
|
|
83
|
+
if (isApitallySpanProcessorDeclared() && requestRecord.serverSpanId === void 0) {
|
|
84
|
+
requestRecord.dropReason = resolveUnavailableSpanDropReason();
|
|
85
|
+
if (requestRecord.dropReason === "sampled-out") {
|
|
86
|
+
warnAboutUnattachedSpanProcessor();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
requestContext = trace.setSpan(requestContext, ownSpan);
|
|
91
|
+
}
|
|
92
|
+
let rpcMetadata = getRPCMetadata(requestContext);
|
|
93
|
+
if (!rpcMetadata && spanHandle.span) {
|
|
94
|
+
rpcMetadata = { type: RPCType.HTTP, span: spanHandle.span };
|
|
95
|
+
requestContext = setRPCMetadata(requestContext, rpcMetadata);
|
|
96
|
+
}
|
|
97
|
+
attachRequestRecordToRpcMetadata(rpcMetadata, requestRecord);
|
|
98
|
+
if (requestRecord.dropReason !== void 0) {
|
|
99
|
+
requestBodyCapture.stopBuffering();
|
|
100
|
+
}
|
|
101
|
+
return { requestRecord, requestContext, spanHandle, rpcMetadata };
|
|
102
|
+
}
|
|
103
|
+
function finalizeRequestObservation(options) {
|
|
104
|
+
const { observation, statusCode, route } = options;
|
|
105
|
+
const { requestRecord, spanHandle, rpcMetadata, method } = observation;
|
|
106
|
+
requestRecord.durationSeconds = (options.completedAtMillis - observation.startTimeMillis) / 1e3;
|
|
107
|
+
const { span, ownSpan } = spanHandle;
|
|
108
|
+
if (options.clientAddress !== void 0) {
|
|
109
|
+
writeRequestAttribute(span, requestRecord, "client.address", options.clientAddress);
|
|
110
|
+
}
|
|
111
|
+
writeRequestAttribute(span, requestRecord, "http.response.status_code", statusCode);
|
|
112
|
+
const requestBodySize = options.capturedRequestBody?.size;
|
|
113
|
+
if (requestBodySize !== void 0) {
|
|
114
|
+
writeRequestAttribute(span, requestRecord, "http.request.body.size", requestBodySize);
|
|
115
|
+
}
|
|
116
|
+
const responseBodySize = options.capturedResponseBody?.size;
|
|
117
|
+
if (responseBodySize !== void 0) {
|
|
118
|
+
writeRequestAttribute(span, requestRecord, "http.response.body.size", responseBodySize);
|
|
119
|
+
}
|
|
120
|
+
if (route !== void 0) {
|
|
121
|
+
writeRequestAttribute(span, requestRecord, "http.route", route);
|
|
122
|
+
if (rpcMetadata) {
|
|
123
|
+
rpcMetadata.route = route;
|
|
124
|
+
}
|
|
125
|
+
if (ownSpan?.isRecording()) {
|
|
126
|
+
ownSpan.updateName(`${method} ${route}`);
|
|
127
|
+
}
|
|
128
|
+
} else {
|
|
129
|
+
requestRecord.attributes["http.route"] = "";
|
|
130
|
+
}
|
|
131
|
+
if (ownSpan && statusCode >= 500) {
|
|
132
|
+
ownSpan.setStatus({ code: SpanStatusCode.ERROR });
|
|
133
|
+
}
|
|
134
|
+
const consumer = requestRecord.attributes["apitally.consumer.identifier"];
|
|
135
|
+
const consumerIdentifier = typeof consumer === "string" ? consumer : void 0;
|
|
136
|
+
if (requestRecord.validationErrors && isValidationResponseStatus(statusCode)) {
|
|
137
|
+
addValidationErrors(consumerIdentifier, method, route ?? "", requestRecord.validationErrors);
|
|
138
|
+
}
|
|
139
|
+
if (statusCode === 500 && requestRecord.exception !== void 0) {
|
|
140
|
+
const sentryEventId = requestRecord.attributes["apitally.exception.sentry_event_id"];
|
|
141
|
+
addServerError(
|
|
142
|
+
consumerIdentifier,
|
|
143
|
+
method,
|
|
144
|
+
route ?? "",
|
|
145
|
+
requestRecord.exception,
|
|
146
|
+
typeof sentryEventId === "string" ? sentryEventId : void 0
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
if (requestRecord.serverSpanId !== void 0 && requestRecord.dropReason === void 0) {
|
|
150
|
+
const config = getConfig();
|
|
151
|
+
const stash = {};
|
|
152
|
+
if (config.captureRequestHeaders) {
|
|
153
|
+
stash.requestHeaders = normalizeHeaders(options.requestHeaders);
|
|
154
|
+
}
|
|
155
|
+
if (config.captureResponseHeaders) {
|
|
156
|
+
stash.responseHeaders = normalizeHeaders(options.responseHeaders);
|
|
157
|
+
}
|
|
158
|
+
const requestBody = options.capturedRequestBody?.body;
|
|
159
|
+
if (requestBody) {
|
|
160
|
+
stash.requestBody = requestBody;
|
|
161
|
+
}
|
|
162
|
+
const responseBody = options.capturedResponseBody?.body;
|
|
163
|
+
if (responseBody && config.captureResponseBody) {
|
|
164
|
+
stash.responseBody = responseBody;
|
|
165
|
+
}
|
|
166
|
+
if (Object.keys(stash).length > 0) {
|
|
167
|
+
getActiveSpanPipeline()?.updateStash(requestRecord.serverSpanId, stash);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
ownSpan?.end(options.completedAtMillis);
|
|
171
|
+
getActiveSpanPipeline()?.handleTransportCompletion(requestRecord);
|
|
172
|
+
}
|
|
173
|
+
function finalizeRequestObservationWithError(options) {
|
|
174
|
+
const { requestRecord, spanHandle, error, durationSeconds } = options;
|
|
175
|
+
requestRecord.durationSeconds = durationSeconds;
|
|
176
|
+
if (spanHandle.span?.isRecording()) {
|
|
177
|
+
spanHandle.span.recordException(coerceToException(error));
|
|
178
|
+
}
|
|
179
|
+
if (spanHandle.ownSpan) {
|
|
180
|
+
spanHandle.ownSpan.setStatus({ code: SpanStatusCode.ERROR });
|
|
181
|
+
spanHandle.ownSpan.end();
|
|
182
|
+
}
|
|
183
|
+
getActiveSpanPipeline()?.handleTransportCompletion(requestRecord);
|
|
184
|
+
}
|
|
185
|
+
function normalizeHeaders(headers) {
|
|
186
|
+
const normalized = {};
|
|
187
|
+
if (isWebHeaders(headers)) {
|
|
188
|
+
for (const [name, value] of headers) {
|
|
189
|
+
const existing = normalized[name];
|
|
190
|
+
if (existing === void 0) {
|
|
191
|
+
normalized[name] = value;
|
|
192
|
+
} else if (Array.isArray(existing)) {
|
|
193
|
+
existing.push(value);
|
|
194
|
+
} else {
|
|
195
|
+
normalized[name] = [existing, value];
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return normalized;
|
|
199
|
+
}
|
|
200
|
+
for (const [name, value] of Object.entries(headers)) {
|
|
201
|
+
if (value !== void 0) {
|
|
202
|
+
normalized[name.toLowerCase()] = Array.isArray(value) ? value : String(value);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return normalized;
|
|
206
|
+
}
|
|
207
|
+
function isWebHeaders(headers) {
|
|
208
|
+
return typeof headers[Symbol.iterator] === "function";
|
|
209
|
+
}
|
|
210
|
+
function warnAboutNonRecordingServerSpan() {
|
|
211
|
+
logWarning(
|
|
212
|
+
"The OpenTelemetry sampler did not sample the SERVER span of a request. Only sampled requests are exported to Apitally as traces and request logs. Request metrics include all requests."
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
function warnAboutUnattachedSpanProcessor() {
|
|
216
|
+
logWarning(
|
|
217
|
+
"The recording OpenTelemetry SERVER span created for a request did not reach ApitallySpanProcessor. Traces and request logs are unavailable while request metrics continue. To resolve this, add the ApitallySpanProcessor instance to your tracer provider's spanProcessors constructor option or the NodeSDK spanProcessors option."
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
export {
|
|
221
|
+
finalizeRequestObservation,
|
|
222
|
+
finalizeRequestObservationWithError,
|
|
223
|
+
resolveHttpRequestStartAttributes,
|
|
224
|
+
startRequestObservation
|
|
225
|
+
};
|
|
226
|
+
//# sourceMappingURL=requestObservation.js.map
|