apitally 0.23.1 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/dist/adonisjs/index.cjs +3 -0
  2. package/dist/adonisjs/index.cjs.map +1 -1
  3. package/dist/adonisjs/index.d.cts +2 -0
  4. package/dist/adonisjs/index.d.ts +2 -0
  5. package/dist/adonisjs/index.js +2 -0
  6. package/dist/adonisjs/index.js.map +1 -1
  7. package/dist/adonisjs/middleware.cjs +6 -2
  8. package/dist/adonisjs/middleware.cjs.map +1 -1
  9. package/dist/adonisjs/middleware.d.cts +2 -0
  10. package/dist/adonisjs/middleware.d.ts +2 -0
  11. package/dist/adonisjs/middleware.js +6 -2
  12. package/dist/adonisjs/middleware.js.map +1 -1
  13. package/dist/adonisjs/provider.d.cts +2 -0
  14. package/dist/adonisjs/provider.d.ts +2 -0
  15. package/dist/adonisjs/stubs/config/apitally.stub +1 -0
  16. package/dist/common/client.cjs +6 -1
  17. package/dist/common/client.cjs.map +1 -1
  18. package/dist/common/client.d.cts +3 -0
  19. package/dist/common/client.d.ts +3 -0
  20. package/dist/common/client.js +6 -1
  21. package/dist/common/client.js.map +1 -1
  22. package/dist/common/consumerRegistry.d.cts +2 -0
  23. package/dist/common/consumerRegistry.d.ts +2 -0
  24. package/dist/common/instance.cjs +158 -0
  25. package/dist/common/instance.cjs.map +1 -0
  26. package/dist/common/instance.d.cts +4 -0
  27. package/dist/common/instance.d.ts +4 -0
  28. package/dist/common/instance.js +134 -0
  29. package/dist/common/instance.js.map +1 -0
  30. package/dist/common/requestCounter.d.cts +2 -0
  31. package/dist/common/requestCounter.d.ts +2 -0
  32. package/dist/common/requestLogger.cjs +23 -19
  33. package/dist/common/requestLogger.cjs.map +1 -1
  34. package/dist/common/requestLogger.d.cts +6 -1
  35. package/dist/common/requestLogger.d.ts +6 -1
  36. package/dist/common/requestLogger.js +23 -19
  37. package/dist/common/requestLogger.js.map +1 -1
  38. package/dist/common/response.cjs +2 -2
  39. package/dist/common/response.cjs.map +1 -1
  40. package/dist/common/response.js +2 -2
  41. package/dist/common/response.js.map +1 -1
  42. package/dist/common/serverErrorCounter.cjs +3 -0
  43. package/dist/common/serverErrorCounter.cjs.map +1 -1
  44. package/dist/common/serverErrorCounter.d.cts +2 -0
  45. package/dist/common/serverErrorCounter.d.ts +2 -0
  46. package/dist/common/serverErrorCounter.js +3 -0
  47. package/dist/common/serverErrorCounter.js.map +1 -1
  48. package/dist/common/spanCollector.cjs +217 -0
  49. package/dist/common/spanCollector.cjs.map +1 -0
  50. package/dist/common/spanCollector.d.cts +50 -0
  51. package/dist/common/spanCollector.d.ts +50 -0
  52. package/dist/common/spanCollector.js +194 -0
  53. package/dist/common/spanCollector.js.map +1 -0
  54. package/dist/common/tempGzipFile.cjs +25 -2
  55. package/dist/common/tempGzipFile.cjs.map +1 -1
  56. package/dist/common/tempGzipFile.d.cts +3 -2
  57. package/dist/common/tempGzipFile.d.ts +3 -2
  58. package/dist/common/tempGzipFile.js +22 -3
  59. package/dist/common/tempGzipFile.js.map +1 -1
  60. package/dist/common/types.d.cts +2 -0
  61. package/dist/common/types.d.ts +2 -0
  62. package/dist/common/validationErrorCounter.d.cts +2 -0
  63. package/dist/common/validationErrorCounter.d.ts +2 -0
  64. package/dist/elysia/index.cjs +3 -0
  65. package/dist/elysia/index.cjs.map +1 -1
  66. package/dist/elysia/index.d.cts +2 -0
  67. package/dist/elysia/index.d.ts +2 -0
  68. package/dist/elysia/index.js +2 -0
  69. package/dist/elysia/index.js.map +1 -1
  70. package/dist/elysia/plugin.cjs +16 -8
  71. package/dist/elysia/plugin.cjs.map +1 -1
  72. package/dist/elysia/plugin.d.cts +4 -0
  73. package/dist/elysia/plugin.d.ts +4 -0
  74. package/dist/elysia/plugin.js +16 -8
  75. package/dist/elysia/plugin.js.map +1 -1
  76. package/dist/elysia/utils.d.cts +2 -0
  77. package/dist/elysia/utils.d.ts +2 -0
  78. package/dist/express/index.cjs +3 -0
  79. package/dist/express/index.cjs.map +1 -1
  80. package/dist/express/index.d.cts +2 -0
  81. package/dist/express/index.d.ts +2 -0
  82. package/dist/express/index.js +2 -0
  83. package/dist/express/index.js.map +1 -1
  84. package/dist/express/middleware.cjs +85 -77
  85. package/dist/express/middleware.cjs.map +1 -1
  86. package/dist/express/middleware.d.cts +2 -0
  87. package/dist/express/middleware.d.ts +2 -0
  88. package/dist/express/middleware.js +85 -77
  89. package/dist/express/middleware.js.map +1 -1
  90. package/dist/fastify/index.cjs +3 -0
  91. package/dist/fastify/index.cjs.map +1 -1
  92. package/dist/fastify/index.d.cts +2 -0
  93. package/dist/fastify/index.d.ts +2 -0
  94. package/dist/fastify/index.js +2 -0
  95. package/dist/fastify/index.js.map +1 -1
  96. package/dist/fastify/plugin.cjs +15 -6
  97. package/dist/fastify/plugin.cjs.map +1 -1
  98. package/dist/fastify/plugin.d.cts +4 -0
  99. package/dist/fastify/plugin.d.ts +4 -0
  100. package/dist/fastify/plugin.js +15 -6
  101. package/dist/fastify/plugin.js.map +1 -1
  102. package/dist/h3/index.cjs +3 -0
  103. package/dist/h3/index.cjs.map +1 -1
  104. package/dist/h3/index.d.cts +2 -0
  105. package/dist/h3/index.d.ts +2 -0
  106. package/dist/h3/index.js +2 -0
  107. package/dist/h3/index.js.map +1 -1
  108. package/dist/h3/plugin.cjs +15 -7
  109. package/dist/h3/plugin.cjs.map +1 -1
  110. package/dist/h3/plugin.d.cts +4 -0
  111. package/dist/h3/plugin.d.ts +4 -0
  112. package/dist/h3/plugin.js +15 -7
  113. package/dist/h3/plugin.js.map +1 -1
  114. package/dist/hapi/index.cjs +3 -0
  115. package/dist/hapi/index.cjs.map +1 -1
  116. package/dist/hapi/index.d.cts +2 -0
  117. package/dist/hapi/index.d.ts +2 -0
  118. package/dist/hapi/index.js +2 -0
  119. package/dist/hapi/index.js.map +1 -1
  120. package/dist/hapi/plugin.cjs +16 -9
  121. package/dist/hapi/plugin.cjs.map +1 -1
  122. package/dist/hapi/plugin.d.cts +4 -0
  123. package/dist/hapi/plugin.d.ts +4 -0
  124. package/dist/hapi/plugin.js +16 -9
  125. package/dist/hapi/plugin.js.map +1 -1
  126. package/dist/hapi/utils.d.cts +2 -0
  127. package/dist/hapi/utils.d.ts +2 -0
  128. package/dist/hono/index.cjs +3 -0
  129. package/dist/hono/index.cjs.map +1 -1
  130. package/dist/hono/index.d.cts +2 -0
  131. package/dist/hono/index.d.ts +2 -0
  132. package/dist/hono/index.js +2 -0
  133. package/dist/hono/index.js.map +1 -1
  134. package/dist/hono/middleware.cjs +6 -2
  135. package/dist/hono/middleware.cjs.map +1 -1
  136. package/dist/hono/middleware.d.cts +2 -0
  137. package/dist/hono/middleware.d.ts +2 -0
  138. package/dist/hono/middleware.js +6 -2
  139. package/dist/hono/middleware.js.map +1 -1
  140. package/dist/hono/utils.d.cts +2 -0
  141. package/dist/hono/utils.d.ts +2 -0
  142. package/dist/koa/index.cjs +3 -0
  143. package/dist/koa/index.cjs.map +1 -1
  144. package/dist/koa/index.d.cts +2 -0
  145. package/dist/koa/index.d.ts +2 -0
  146. package/dist/koa/index.js +2 -0
  147. package/dist/koa/index.js.map +1 -1
  148. package/dist/koa/middleware.cjs +8 -4
  149. package/dist/koa/middleware.cjs.map +1 -1
  150. package/dist/koa/middleware.d.cts +2 -0
  151. package/dist/koa/middleware.d.ts +2 -0
  152. package/dist/koa/middleware.js +8 -4
  153. package/dist/koa/middleware.js.map +1 -1
  154. package/dist/loggers/console.d.cts +4 -0
  155. package/dist/loggers/console.d.ts +4 -0
  156. package/dist/loggers/hapi.d.cts +4 -0
  157. package/dist/loggers/hapi.d.ts +4 -0
  158. package/dist/loggers/index.d.cts +4 -0
  159. package/dist/loggers/index.d.ts +4 -0
  160. package/dist/loggers/nestjs.d.cts +4 -0
  161. package/dist/loggers/nestjs.d.ts +4 -0
  162. package/dist/loggers/pino.cjs +1 -1
  163. package/dist/loggers/pino.cjs.map +1 -1
  164. package/dist/loggers/pino.d.cts +4 -0
  165. package/dist/loggers/pino.d.ts +4 -0
  166. package/dist/loggers/pino.js +1 -1
  167. package/dist/loggers/pino.js.map +1 -1
  168. package/dist/loggers/winston.d.cts +4 -0
  169. package/dist/loggers/winston.d.ts +4 -0
  170. package/dist/nestjs/index.cjs +3 -0
  171. package/dist/nestjs/index.cjs.map +1 -1
  172. package/dist/nestjs/index.d.cts +2 -0
  173. package/dist/nestjs/index.d.ts +2 -0
  174. package/dist/nestjs/index.js +2 -0
  175. package/dist/nestjs/index.js.map +1 -1
  176. package/package.json +6 -3
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/koa/middleware.ts"],"sourcesContent":["import Koa from \"koa\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n\nimport { ApitallyClient } from \"../common/client.js\";\nimport { consumerFromStringOrObject } from \"../common/consumerRegistry.js\";\nimport { getPackageVersion } from \"../common/packageVersions.js\";\nimport type { LogRecord } from \"../common/requestLogger.js\";\nimport { convertBody, convertHeaders } from \"../common/requestLogger.js\";\nimport {\n ApitallyConfig,\n ApitallyConsumer,\n PathInfo,\n StartupData,\n} from \"../common/types.js\";\nimport { patchConsole, patchWinston } from \"../loggers/index.js\";\n\nexport function useApitally(app: Koa, config: ApitallyConfig) {\n const client = new ApitallyClient(config);\n const middleware = getMiddleware(client);\n app.use(middleware);\n\n const setStartupData = (attempt: number = 1) => {\n const appInfo = getAppInfo(app, config.appVersion);\n if (appInfo.paths.length > 0 || attempt >= 10) {\n client.setStartupData(appInfo);\n client.startSync();\n } else {\n setTimeout(() => setStartupData(attempt + 1), 500);\n }\n };\n setTimeout(() => setStartupData(), 500);\n}\n\nfunction getMiddleware(client: ApitallyClient) {\n const logsContext = new AsyncLocalStorage<LogRecord[]>();\n\n if (client.requestLogger.config.captureLogs) {\n patchConsole(logsContext);\n patchWinston(logsContext);\n }\n\n return async (ctx: Koa.Context, next: Koa.Next) => {\n if (!client.isEnabled() || ctx.request.method.toUpperCase() === \"OPTIONS\") {\n await next();\n return;\n }\n\n await logsContext.run([], async () => {\n let path: string | undefined;\n let statusCode: number | undefined;\n let serverError: Error | undefined;\n const startTime = performance.now();\n try {\n await next();\n } catch (error: any) {\n path = getPath(ctx);\n statusCode = error.statusCode || error.status || 500;\n if (path && statusCode === 500 && error instanceof Error) {\n serverError = error;\n client.serverErrorCounter.addServerError({\n consumer: getConsumer(ctx)?.identifier,\n method: ctx.request.method,\n path,\n type: error.name,\n msg: error.message,\n traceback: error.stack || \"\",\n });\n }\n throw error;\n } finally {\n const responseTime = performance.now() - startTime;\n const consumer = getConsumer(ctx);\n client.consumerRegistry.addOrUpdateConsumer(consumer);\n if (!path) {\n path = getPath(ctx);\n }\n if (path) {\n try {\n client.requestCounter.addRequest({\n consumer: consumer?.identifier,\n method: ctx.request.method,\n path,\n statusCode: statusCode || ctx.response.status,\n responseTime,\n requestSize: ctx.request.length,\n responseSize: ctx.response.length,\n });\n } catch (error) {\n client.logger.error(\n \"Error while logging request in Apitally middleware.\",\n { context: ctx, error },\n );\n }\n }\n if (client.requestLogger.enabled) {\n const logs = logsContext.getStore();\n client.requestLogger.logRequest(\n {\n timestamp: Date.now() / 1000,\n method: ctx.request.method,\n path,\n url: ctx.request.href,\n headers: convertHeaders(ctx.request.headers),\n size: ctx.request.length,\n consumer: consumer?.identifier,\n body: convertBody(\n ctx.request.body,\n ctx.request.get(\"content-type\"),\n ),\n },\n {\n statusCode: statusCode || ctx.response.status,\n responseTime: responseTime / 1000,\n headers: convertHeaders(ctx.response.headers),\n size: ctx.response.length,\n body: convertBody(\n ctx.response.body,\n ctx.response.get(\"content-type\"),\n ),\n },\n serverError,\n logs,\n );\n }\n }\n });\n };\n}\n\nfunction getPath(ctx: Koa.Context) {\n return ctx._matchedRoute || ctx.routePath; // _matchedRoute is set by koa-router, routePath is set by koa-route\n}\n\nexport function setConsumer(\n ctx: Koa.Context,\n consumer: ApitallyConsumer | string | null | undefined,\n) {\n ctx.state.apitallyConsumer = consumer || undefined;\n}\n\nfunction getConsumer(ctx: Koa.Context) {\n if (ctx.state.apitallyConsumer) {\n return consumerFromStringOrObject(ctx.state.apitallyConsumer);\n } else if (ctx.state.consumerIdentifier) {\n // For backwards compatibility\n process.emitWarning(\n \"The consumerIdentifier property on the ctx.state object is deprecated. Use apitallyConsumer instead.\",\n \"DeprecationWarning\",\n );\n return consumerFromStringOrObject(ctx.state.consumerIdentifier);\n }\n return null;\n}\n\nfunction getAppInfo(app: Koa, appVersion?: string): StartupData {\n const versions: Array<[string, string]> = [\n [\"nodejs\", process.version.replace(/^v/, \"\")],\n ];\n const koaVersion = getPackageVersion(\"koa\");\n const apitallyVersion = getPackageVersion(\"../..\");\n if (koaVersion) {\n versions.push([\"koa\", koaVersion]);\n }\n if (apitallyVersion) {\n versions.push([\"apitally\", apitallyVersion]);\n }\n if (appVersion) {\n versions.push([\"app\", appVersion]);\n }\n return {\n paths: listEndpoints(app),\n versions: Object.fromEntries(versions),\n client: \"js:koa\",\n };\n}\n\nfunction isKoaRouterMiddleware(middleware: any) {\n return (\n typeof middleware === \"function\" &&\n middleware.router &&\n Array.isArray(middleware.router.stack)\n );\n}\n\nfunction listEndpoints(app: Koa) {\n const endpoints: Array<PathInfo> = [];\n app.middleware.forEach((middleware: any) => {\n if (isKoaRouterMiddleware(middleware)) {\n middleware.router.stack.forEach((layer: any) => {\n if (layer.methods && layer.methods.length > 0) {\n layer.methods.forEach((method: string) => {\n if (![\"HEAD\", \"OPTIONS\"].includes(method.toUpperCase())) {\n endpoints.push({\n method: method.toUpperCase(),\n path: layer.path,\n });\n }\n });\n }\n });\n }\n });\n return endpoints;\n}\n"],"mappings":"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","names":["AsyncLocalStorage","ApitallyClient","consumerFromStringOrObject","getPackageVersion","convertBody","convertHeaders","patchConsole","patchWinston","useApitally","app","config","client","middleware","getMiddleware","use","setStartupData","attempt","appInfo","getAppInfo","appVersion","paths","length","startSync","setTimeout","logsContext","requestLogger","captureLogs","ctx","next","isEnabled","request","method","toUpperCase","run","path","statusCode","serverError","startTime","performance","now","error","getPath","status","Error","serverErrorCounter","addServerError","consumer","getConsumer","identifier","type","name","msg","message","traceback","stack","responseTime","consumerRegistry","addOrUpdateConsumer","requestCounter","addRequest","response","requestSize","responseSize","logger","context","enabled","logs","getStore","logRequest","timestamp","Date","url","href","headers","size","body","get","_matchedRoute","routePath","setConsumer","state","apitallyConsumer","undefined","consumerIdentifier","process","emitWarning","versions","version","replace","koaVersion","apitallyVersion","push","listEndpoints","Object","fromEntries","isKoaRouterMiddleware","router","Array","isArray","endpoints","forEach","layer","methods","includes"]}
1
+ {"version":3,"sources":["../../src/koa/middleware.ts"],"sourcesContent":["import Koa from \"koa\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\n\nimport { ApitallyClient } from \"../common/client.js\";\nimport { consumerFromStringOrObject } from \"../common/consumerRegistry.js\";\nimport { getPackageVersion } from \"../common/packageVersions.js\";\nimport type { LogRecord } from \"../common/requestLogger.js\";\nimport { convertBody, convertHeaders } from \"../common/requestLogger.js\";\nimport {\n ApitallyConfig,\n ApitallyConsumer,\n PathInfo,\n StartupData,\n} from \"../common/types.js\";\nimport { patchConsole, patchWinston } from \"../loggers/index.js\";\n\nexport function useApitally(app: Koa, config: ApitallyConfig) {\n const client = new ApitallyClient(config);\n const middleware = getMiddleware(client);\n app.use(middleware);\n\n const setStartupData = (attempt: number = 1) => {\n const appInfo = getAppInfo(app, config.appVersion);\n if (appInfo.paths.length > 0 || attempt >= 10) {\n client.setStartupData(appInfo);\n client.startSync();\n } else {\n setTimeout(() => setStartupData(attempt + 1), 500);\n }\n };\n setTimeout(() => setStartupData(), 500);\n}\n\nfunction getMiddleware(client: ApitallyClient) {\n const logsContext = new AsyncLocalStorage<LogRecord[]>();\n\n if (client.requestLogger.config.captureLogs) {\n patchConsole(logsContext);\n patchWinston(logsContext);\n }\n\n return async (ctx: Koa.Context, next: Koa.Next) => {\n if (!client.isEnabled() || ctx.request.method.toUpperCase() === \"OPTIONS\") {\n await next();\n return;\n }\n\n await logsContext.run([], async () => {\n let path: string | undefined;\n let statusCode: number | undefined;\n let serverError: Error | undefined;\n const startTime = performance.now();\n const spanHandle = client.spanCollector.startSpan();\n try {\n await spanHandle.runInContext(next);\n } catch (error: any) {\n path = getPath(ctx);\n statusCode = error.statusCode || error.status || 500;\n if (path && statusCode === 500 && error instanceof Error) {\n serverError = error;\n client.serverErrorCounter.addServerError({\n consumer: getConsumer(ctx)?.identifier,\n method: ctx.request.method,\n path,\n type: error.name,\n msg: error.message,\n traceback: error.stack || \"\",\n });\n }\n throw error;\n } finally {\n const responseTime = performance.now() - startTime;\n\n if (!path) {\n path = getPath(ctx);\n }\n\n spanHandle.setName(`${ctx.request.method} ${path}`);\n const spans = spanHandle.end();\n const traceId = spanHandle.traceId;\n\n const consumer = getConsumer(ctx);\n client.consumerRegistry.addOrUpdateConsumer(consumer);\n\n if (path) {\n try {\n client.requestCounter.addRequest({\n consumer: consumer?.identifier,\n method: ctx.request.method,\n path,\n statusCode: statusCode || ctx.response.status,\n responseTime,\n requestSize: ctx.request.length,\n responseSize: ctx.response.length,\n });\n } catch (error) {\n client.logger.error(\n \"Error while logging request in Apitally middleware.\",\n { context: ctx, error },\n );\n }\n }\n\n if (client.requestLogger.enabled) {\n const logs = logsContext.getStore();\n client.requestLogger.logRequest(\n {\n timestamp: Date.now() / 1000,\n method: ctx.request.method,\n path,\n url: ctx.request.href,\n headers: convertHeaders(ctx.request.headers),\n size: ctx.request.length,\n consumer: consumer?.identifier,\n body: convertBody(\n ctx.request.body,\n ctx.request.get(\"content-type\"),\n ),\n },\n {\n statusCode: statusCode || ctx.response.status,\n responseTime: responseTime / 1000,\n headers: convertHeaders(ctx.response.headers),\n size: ctx.response.length,\n body: convertBody(\n ctx.response.body,\n ctx.response.get(\"content-type\"),\n ),\n },\n serverError,\n logs,\n spans,\n traceId,\n );\n }\n }\n });\n };\n}\n\nfunction getPath(ctx: Koa.Context) {\n return ctx._matchedRoute || ctx.routePath; // _matchedRoute is set by koa-router, routePath is set by koa-route\n}\n\nexport function setConsumer(\n ctx: Koa.Context,\n consumer: ApitallyConsumer | string | null | undefined,\n) {\n ctx.state.apitallyConsumer = consumer || undefined;\n}\n\nfunction getConsumer(ctx: Koa.Context) {\n if (ctx.state.apitallyConsumer) {\n return consumerFromStringOrObject(ctx.state.apitallyConsumer);\n } else if (ctx.state.consumerIdentifier) {\n // For backwards compatibility\n process.emitWarning(\n \"The consumerIdentifier property on the ctx.state object is deprecated. Use apitallyConsumer instead.\",\n \"DeprecationWarning\",\n );\n return consumerFromStringOrObject(ctx.state.consumerIdentifier);\n }\n return null;\n}\n\nfunction getAppInfo(app: Koa, appVersion?: string): StartupData {\n const versions: Array<[string, string]> = [\n [\"nodejs\", process.version.replace(/^v/, \"\")],\n ];\n const koaVersion = getPackageVersion(\"koa\");\n const apitallyVersion = getPackageVersion(\"../..\");\n if (koaVersion) {\n versions.push([\"koa\", koaVersion]);\n }\n if (apitallyVersion) {\n versions.push([\"apitally\", apitallyVersion]);\n }\n if (appVersion) {\n versions.push([\"app\", appVersion]);\n }\n return {\n paths: listEndpoints(app),\n versions: Object.fromEntries(versions),\n client: \"js:koa\",\n };\n}\n\nfunction isKoaRouterMiddleware(middleware: any) {\n return (\n typeof middleware === \"function\" &&\n middleware.router &&\n Array.isArray(middleware.router.stack)\n );\n}\n\nfunction listEndpoints(app: Koa) {\n const endpoints: Array<PathInfo> = [];\n app.middleware.forEach((middleware: any) => {\n if (isKoaRouterMiddleware(middleware)) {\n middleware.router.stack.forEach((layer: any) => {\n if (layer.methods && layer.methods.length > 0) {\n layer.methods.forEach((method: string) => {\n if (![\"HEAD\", \"OPTIONS\"].includes(method.toUpperCase())) {\n endpoints.push({\n method: method.toUpperCase(),\n path: layer.path,\n });\n }\n });\n }\n });\n }\n });\n return endpoints;\n}\n"],"mappings":";;AACA,SAASA,yBAAyB;AAElC,SAASC,sBAAsB;AAC/B,SAASC,kCAAkC;AAC3C,SAASC,yBAAyB;AAElC,SAASC,aAAaC,sBAAsB;AAO5C,SAASC,cAAcC,oBAAoB;AAEpC,SAASC,YAAYC,KAAUC,QAAsB;AAC1D,QAAMC,SAAS,IAAIV,eAAeS,MAAAA;AAClC,QAAME,aAAaC,cAAcF,MAAAA;AACjCF,MAAIK,IAAIF,UAAAA;AAER,QAAMG,iBAAiB,wBAACC,UAAkB,MAAC;AACzC,UAAMC,UAAUC,WAAWT,KAAKC,OAAOS,UAAU;AACjD,QAAIF,QAAQG,MAAMC,SAAS,KAAKL,WAAW,IAAI;AAC7CL,aAAOI,eAAeE,OAAAA;AACtBN,aAAOW,UAAS;IAClB,OAAO;AACLC,iBAAW,MAAMR,eAAeC,UAAU,CAAA,GAAI,GAAA;IAChD;EACF,GARuB;AASvBO,aAAW,MAAMR,eAAAA,GAAkB,GAAA;AACrC;AAfgBP;AAiBhB,SAASK,cAAcF,QAAsB;AAC3C,QAAMa,cAAc,IAAIxB,kBAAAA;AAExB,MAAIW,OAAOc,cAAcf,OAAOgB,aAAa;AAC3CpB,iBAAakB,WAAAA;AACbjB,iBAAaiB,WAAAA;EACf;AAEA,SAAO,OAAOG,KAAkBC,SAAAA;AAC9B,QAAI,CAACjB,OAAOkB,UAAS,KAAMF,IAAIG,QAAQC,OAAOC,YAAW,MAAO,WAAW;AACzE,YAAMJ,KAAAA;AACN;IACF;AAEA,UAAMJ,YAAYS,IAAI,CAAA,GAAI,YAAA;AA9C9B;AA+CM,UAAIC;AACJ,UAAIC;AACJ,UAAIC;AACJ,YAAMC,YAAYC,YAAYC,IAAG;AACjC,YAAMC,aAAa7B,OAAO8B,cAAcC,UAAS;AACjD,UAAI;AACF,cAAMF,WAAWG,aAAaf,IAAAA;MAChC,SAASgB,OAAY;AACnBV,eAAOW,QAAQlB,GAAAA;AACfQ,qBAAaS,MAAMT,cAAcS,MAAME,UAAU;AACjD,YAAIZ,QAAQC,eAAe,OAAOS,iBAAiBG,OAAO;AACxDX,wBAAcQ;AACdjC,iBAAOqC,mBAAmBC,eAAe;YACvCC,WAAUC,iBAAYxB,GAAAA,MAAZwB,mBAAkBC;YAC5BrB,QAAQJ,IAAIG,QAAQC;YACpBG;YACAmB,MAAMT,MAAMU;YACZC,KAAKX,MAAMY;YACXC,WAAWb,MAAMc,SAAS;UAC5B,CAAA;QACF;AACA,cAAMd;MACR,UAAA;AACE,cAAMe,eAAerB,YAAYC,IAAG,IAAKF;AAEzC,YAAI,CAACH,MAAM;AACTA,iBAAOW,QAAQlB,GAAAA;QACjB;AAEAa,mBAAWoB,QAAQ,GAAGjC,IAAIG,QAAQC,MAAM,IAAIG,IAAAA,EAAM;AAClD,cAAM2B,QAAQrB,WAAWsB,IAAG;AAC5B,cAAMC,UAAUvB,WAAWuB;AAE3B,cAAMb,WAAWC,YAAYxB,GAAAA;AAC7BhB,eAAOqD,iBAAiBC,oBAAoBf,QAAAA;AAE5C,YAAIhB,MAAM;AACR,cAAI;AACFvB,mBAAOuD,eAAeC,WAAW;cAC/BjB,UAAUA,qCAAUE;cACpBrB,QAAQJ,IAAIG,QAAQC;cACpBG;cACAC,YAAYA,cAAcR,IAAIyC,SAAStB;cACvCa;cACAU,aAAa1C,IAAIG,QAAQT;cACzBiD,cAAc3C,IAAIyC,SAAS/C;YAC7B,CAAA;UACF,SAASuB,OAAO;AACdjC,mBAAO4D,OAAO3B,MACZ,uDACA;cAAE4B,SAAS7C;cAAKiB;YAAM,CAAA;UAE1B;QACF;AAEA,YAAIjC,OAAOc,cAAcgD,SAAS;AAChC,gBAAMC,OAAOlD,YAAYmD,SAAQ;AACjChE,iBAAOc,cAAcmD,WACnB;YACEC,WAAWC,KAAKvC,IAAG,IAAK;YACxBR,QAAQJ,IAAIG,QAAQC;YACpBG;YACA6C,KAAKpD,IAAIG,QAAQkD;YACjBC,SAAS5E,eAAesB,IAAIG,QAAQmD,OAAO;YAC3CC,MAAMvD,IAAIG,QAAQT;YAClB6B,UAAUA,qCAAUE;YACpB+B,MAAM/E,YACJuB,IAAIG,QAAQqD,MACZxD,IAAIG,QAAQsD,IAAI,cAAA,CAAA;UAEpB,GACA;YACEjD,YAAYA,cAAcR,IAAIyC,SAAStB;YACvCa,cAAcA,eAAe;YAC7BsB,SAAS5E,eAAesB,IAAIyC,SAASa,OAAO;YAC5CC,MAAMvD,IAAIyC,SAAS/C;YACnB8D,MAAM/E,YACJuB,IAAIyC,SAASe,MACbxD,IAAIyC,SAASgB,IAAI,cAAA,CAAA;UAErB,GACAhD,aACAsC,MACAb,OACAE,OAAAA;QAEJ;MACF;IACF,CAAA;EACF;AACF;AAzGSlD;AA2GT,SAASgC,QAAQlB,KAAgB;AAC/B,SAAOA,IAAI0D,iBAAiB1D,IAAI2D;AAClC;AAFSzC;AAIF,SAAS0C,YACd5D,KACAuB,UAAsD;AAEtDvB,MAAI6D,MAAMC,mBAAmBvC,YAAYwC;AAC3C;AALgBH;AAOhB,SAASpC,YAAYxB,KAAgB;AACnC,MAAIA,IAAI6D,MAAMC,kBAAkB;AAC9B,WAAOvF,2BAA2ByB,IAAI6D,MAAMC,gBAAgB;EAC9D,WAAW9D,IAAI6D,MAAMG,oBAAoB;AAEvCC,YAAQC,YACN,wGACA,oBAAA;AAEF,WAAO3F,2BAA2ByB,IAAI6D,MAAMG,kBAAkB;EAChE;AACA,SAAO;AACT;AAZSxC;AAcT,SAASjC,WAAWT,KAAUU,YAAmB;AAC/C,QAAM2E,WAAoC;IACxC;MAAC;MAAUF,QAAQG,QAAQC,QAAQ,MAAM,EAAA;;;AAE3C,QAAMC,aAAa9F,kBAAkB,KAAA;AACrC,QAAM+F,kBAAkB/F,kBAAkB,OAAA;AAC1C,MAAI8F,YAAY;AACdH,aAASK,KAAK;MAAC;MAAOF;KAAW;EACnC;AACA,MAAIC,iBAAiB;AACnBJ,aAASK,KAAK;MAAC;MAAYD;KAAgB;EAC7C;AACA,MAAI/E,YAAY;AACd2E,aAASK,KAAK;MAAC;MAAOhF;KAAW;EACnC;AACA,SAAO;IACLC,OAAOgF,cAAc3F,GAAAA;IACrBqF,UAAUO,OAAOC,YAAYR,QAAAA;IAC7BnF,QAAQ;EACV;AACF;AApBSO;AAsBT,SAASqF,sBAAsB3F,YAAe;AAC5C,SACE,OAAOA,eAAe,cACtBA,WAAW4F,UACXC,MAAMC,QAAQ9F,WAAW4F,OAAO9C,KAAK;AAEzC;AANS6C;AAQT,SAASH,cAAc3F,KAAQ;AAC7B,QAAMkG,YAA6B,CAAA;AACnClG,MAAIG,WAAWgG,QAAQ,CAAChG,eAAAA;AACtB,QAAI2F,sBAAsB3F,UAAAA,GAAa;AACrCA,iBAAW4F,OAAO9C,MAAMkD,QAAQ,CAACC,UAAAA;AAC/B,YAAIA,MAAMC,WAAWD,MAAMC,QAAQzF,SAAS,GAAG;AAC7CwF,gBAAMC,QAAQF,QAAQ,CAAC7E,WAAAA;AACrB,gBAAI,CAAC;cAAC;cAAQ;cAAWgF,SAAShF,OAAOC,YAAW,CAAA,GAAK;AACvD2E,wBAAUR,KAAK;gBACbpE,QAAQA,OAAOC,YAAW;gBAC1BE,MAAM2E,MAAM3E;cACd,CAAA;YACF;UACF,CAAA;QACF;MACF,CAAA;IACF;EACF,CAAA;AACA,SAAOyE;AACT;AAnBSP;","names":["AsyncLocalStorage","ApitallyClient","consumerFromStringOrObject","getPackageVersion","convertBody","convertHeaders","patchConsole","patchWinston","useApitally","app","config","client","middleware","getMiddleware","use","setStartupData","attempt","appInfo","getAppInfo","appVersion","paths","length","startSync","setTimeout","logsContext","requestLogger","captureLogs","ctx","next","isEnabled","request","method","toUpperCase","run","path","statusCode","serverError","startTime","performance","now","spanHandle","spanCollector","startSpan","runInContext","error","getPath","status","Error","serverErrorCounter","addServerError","consumer","getConsumer","identifier","type","name","msg","message","traceback","stack","responseTime","setName","spans","end","traceId","consumerRegistry","addOrUpdateConsumer","requestCounter","addRequest","response","requestSize","responseSize","logger","context","enabled","logs","getStore","logRequest","timestamp","Date","url","href","headers","size","body","get","_matchedRoute","routePath","setConsumer","state","apitallyConsumer","undefined","consumerIdentifier","process","emitWarning","versions","version","replace","koaVersion","apitallyVersion","push","listEndpoints","Object","fromEntries","isKoaRouterMiddleware","router","Array","isArray","endpoints","forEach","layer","methods","includes"]}
@@ -2,6 +2,10 @@ import { AsyncLocalStorage } from 'node:async_hooks';
2
2
  import { LogRecord } from '../common/requestLogger.cjs';
3
3
  import 'node:buffer';
4
4
  import 'node:http';
5
+ import '../common/spanCollector.cjs';
6
+ import '@opentelemetry/sdk-trace-base';
7
+ import '../common/logging.cjs';
8
+ import 'winston';
5
9
  import '../common/tempGzipFile.cjs';
6
10
 
7
11
  declare function patchConsole(logsContext: AsyncLocalStorage<LogRecord[]>): void;
@@ -2,6 +2,10 @@ import { AsyncLocalStorage } from 'node:async_hooks';
2
2
  import { LogRecord } from '../common/requestLogger.js';
3
3
  import 'node:buffer';
4
4
  import 'node:http';
5
+ import '../common/spanCollector.js';
6
+ import '@opentelemetry/sdk-trace-base';
7
+ import '../common/logging.js';
8
+ import 'winston';
5
9
  import '../common/tempGzipFile.js';
6
10
 
7
11
  declare function patchConsole(logsContext: AsyncLocalStorage<LogRecord[]>): void;
@@ -3,6 +3,10 @@ import { AsyncLocalStorage } from 'node:async_hooks';
3
3
  import { LogRecord } from '../common/requestLogger.cjs';
4
4
  import 'node:buffer';
5
5
  import 'node:http';
6
+ import '../common/spanCollector.cjs';
7
+ import '@opentelemetry/sdk-trace-base';
8
+ import '../common/logging.cjs';
9
+ import 'winston';
6
10
  import '../common/tempGzipFile.cjs';
7
11
 
8
12
  declare function handleHapiRequestEvent(event: RequestEvent, logsContext: AsyncLocalStorage<LogRecord[]>): void;
@@ -3,6 +3,10 @@ import { AsyncLocalStorage } from 'node:async_hooks';
3
3
  import { LogRecord } from '../common/requestLogger.js';
4
4
  import 'node:buffer';
5
5
  import 'node:http';
6
+ import '../common/spanCollector.js';
7
+ import '@opentelemetry/sdk-trace-base';
8
+ import '../common/logging.js';
9
+ import 'winston';
6
10
  import '../common/tempGzipFile.js';
7
11
 
8
12
  declare function handleHapiRequestEvent(event: RequestEvent, logsContext: AsyncLocalStorage<LogRecord[]>): void;
@@ -7,5 +7,9 @@ import 'node:async_hooks';
7
7
  import '../common/requestLogger.cjs';
8
8
  import 'node:buffer';
9
9
  import 'node:http';
10
+ import '../common/spanCollector.cjs';
11
+ import '@opentelemetry/sdk-trace-base';
12
+ import '../common/logging.cjs';
13
+ import 'winston';
10
14
  import '../common/tempGzipFile.cjs';
11
15
  import '@hapi/hapi';
@@ -7,5 +7,9 @@ import 'node:async_hooks';
7
7
  import '../common/requestLogger.js';
8
8
  import 'node:buffer';
9
9
  import 'node:http';
10
+ import '../common/spanCollector.js';
11
+ import '@opentelemetry/sdk-trace-base';
12
+ import '../common/logging.js';
13
+ import 'winston';
10
14
  import '../common/tempGzipFile.js';
11
15
  import '@hapi/hapi';
@@ -2,6 +2,10 @@ import { AsyncLocalStorage } from 'node:async_hooks';
2
2
  import { LogRecord } from '../common/requestLogger.cjs';
3
3
  import 'node:buffer';
4
4
  import 'node:http';
5
+ import '../common/spanCollector.cjs';
6
+ import '@opentelemetry/sdk-trace-base';
7
+ import '../common/logging.cjs';
8
+ import 'winston';
5
9
  import '../common/tempGzipFile.cjs';
6
10
 
7
11
  declare function patchNestLogger(logsContext: AsyncLocalStorage<LogRecord[]>): Promise<void>;
@@ -2,6 +2,10 @@ import { AsyncLocalStorage } from 'node:async_hooks';
2
2
  import { LogRecord } from '../common/requestLogger.js';
3
3
  import 'node:buffer';
4
4
  import 'node:http';
5
+ import '../common/spanCollector.js';
6
+ import '@opentelemetry/sdk-trace-base';
7
+ import '../common/logging.js';
8
+ import 'winston';
5
9
  import '../common/tempGzipFile.js';
6
10
 
7
11
  declare function patchNestLogger(logsContext: AsyncLocalStorage<LogRecord[]>): Promise<void>;
@@ -35,7 +35,7 @@ module.exports = __toCommonJS(pino_exports);
35
35
  var import_utils = require("./utils.js");
36
36
  var _a;
37
37
  const MAX_BUFFER_SIZE = 1e3;
38
- const originalStreamSym = Symbol.for("apitally.originalStream");
38
+ const originalStreamSym = /* @__PURE__ */ Symbol.for("apitally.originalStream");
39
39
  const logLevelMap = {
40
40
  10: "trace",
41
41
  20: "debug",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/loggers/pino.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\n\nimport type { LogRecord } from \"../common/requestLogger.js\";\nimport { formatMessage, removeKeys } from \"./utils.js\";\n\nconst MAX_BUFFER_SIZE = 1000;\n\nconst originalStreamSym = Symbol.for(\"apitally.originalStream\");\nconst logLevelMap: Record<number, string> = {\n 10: \"trace\",\n 20: \"debug\",\n 30: \"info\",\n 40: \"warn\",\n 50: \"error\",\n 60: \"fatal\",\n};\n\nexport async function patchPinoLogger(\n logger: any,\n logsContext: AsyncLocalStorage<LogRecord[]>,\n) {\n try {\n // Find stream and message key symbols on the logger and its prototype\n const symbols = [\n ...Object.getOwnPropertySymbols(logger),\n ...Object.getOwnPropertySymbols(Object.getPrototypeOf(logger)),\n ];\n const streamSym = symbols.find(\n (sym) => sym.toString() === \"Symbol(pino.stream)\",\n );\n const messageKeySym = symbols.find(\n (sym) => sym.toString() === \"Symbol(pino.messageKey)\",\n );\n if (!streamSym || !messageKeySym) {\n // not a pino logger\n return false;\n }\n\n if (!(originalStreamSym in logger)) {\n logger[originalStreamSym] = logger[streamSym];\n }\n\n const originalStream = logger[originalStreamSym];\n if (originalStream) {\n const pino = await import(/* webpackIgnore: true */ \"pino\");\n const captureStream = new ApitallyLogCaptureStream(\n logsContext,\n logger[messageKeySym],\n );\n logger[streamSym] = pino.default.multistream(\n [\n { level: 0, stream: originalStream },\n { level: 0, stream: captureStream },\n ],\n {\n levels: logger.levels,\n },\n );\n }\n return true;\n } catch {\n // ignore errors\n return false;\n }\n}\n\nfunction filterLogs(obj: any, messageKey: string) {\n return obj[messageKey] !== \"request completed\";\n}\n\nclass ApitallyLogCaptureStream {\n private logsContext: AsyncLocalStorage<LogRecord[]>;\n private messageKey: string;\n\n constructor(logsContext: AsyncLocalStorage<LogRecord[]>, messageKey: string) {\n this.logsContext = logsContext;\n this.messageKey = messageKey;\n }\n\n write(msg: string): void {\n const logs = this.logsContext.getStore();\n if (!logs || !msg || logs.length >= MAX_BUFFER_SIZE) {\n return;\n }\n\n let obj: any;\n try {\n obj = JSON.parse(msg);\n } catch (e) {\n return;\n }\n if (\n obj === null ||\n typeof obj !== \"object\" ||\n !filterLogs(obj, this.messageKey)\n ) {\n return;\n }\n\n try {\n let message = obj[this.messageKey];\n const ignoreKeys = [\n \"hostname\",\n \"level\",\n this.messageKey,\n \"pid\",\n \"time\",\n \"reqId\",\n \"req\",\n \"res\",\n ];\n if (!message && \"data\" in obj && \"tags\" in obj) {\n // hapi-pino uses data and tags instead of the message key\n message = obj.data;\n ignoreKeys.push(\"data\");\n ignoreKeys.push(\"tags\");\n }\n const rest = removeKeys(obj, ignoreKeys);\n const formattedMessage = formatMessage(message, rest);\n if (formattedMessage) {\n logs.push({\n timestamp: this.convertTime(obj.time),\n level: logLevelMap[obj.level] || \"info\",\n message: formattedMessage,\n });\n }\n } catch (e) {\n // ignore\n }\n }\n\n private convertTime(time: any): number {\n if (typeof time === \"number\" && !isNaN(time)) {\n return time / 1000; // Convert milliseconds to seconds\n }\n return Date.now() / 1000; // Fallback to current time\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA;;;;;AAAA,mBAA0C;AAA1C;AAEA,MAAMA,kBAAkB;AAExB,MAAMC,oBAAoBC,OAAOC,IAAI,yBAAA;AACrC,MAAMC,cAAsC;EAC1C,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;AACN;AAEA,eAAsBC,gBACpBC,QACAC,aAA2C;AAE3C,MAAI;AAEF,UAAMC,UAAU;SACXC,OAAOC,sBAAsBJ,MAAAA;SAC7BG,OAAOC,sBAAsBD,OAAOE,eAAeL,MAAAA,CAAAA;;AAExD,UAAMM,YAAYJ,QAAQK,KACxB,CAACC,QAAQA,IAAIC,SAAQ,MAAO,qBAAA;AAE9B,UAAMC,gBAAgBR,QAAQK,KAC5B,CAACC,QAAQA,IAAIC,SAAQ,MAAO,yBAAA;AAE9B,QAAI,CAACH,aAAa,CAACI,eAAe;AAEhC,aAAO;IACT;AAEA,QAAI,EAAEf,qBAAqBK,SAAS;AAClCA,aAAOL,iBAAAA,IAAqBK,OAAOM,SAAAA;IACrC;AAEA,UAAMK,iBAAiBX,OAAOL,iBAAAA;AAC9B,QAAIgB,gBAAgB;AAClB,YAAMC,OAAO,MAAM;;QAAiC;MAAA;AACpD,YAAMC,gBAAgB,IAAIC,yBACxBb,aACAD,OAAOU,aAAAA,CAAc;AAEvBV,aAAOM,SAAAA,IAAaM,KAAKG,QAAQC,YAC/B;QACE;UAAEC,OAAO;UAAGC,QAAQP;QAAe;QACnC;UAAEM,OAAO;UAAGC,QAAQL;QAAc;SAEpC;QACEM,QAAQnB,OAAOmB;MACjB,CAAA;IAEJ;AACA,WAAO;EACT,QAAQ;AAEN,WAAO;EACT;AACF;AA/CsBpB;AAiDtB,SAASqB,WAAWC,KAAUC,YAAkB;AAC9C,SAAOD,IAAIC,UAAAA,MAAgB;AAC7B;AAFSF;AAIT,IAAMN,4BAAN,WAAMA;EACIb;EACAqB;EAER,YAAYrB,aAA6CqB,YAAoB;AAC3E,SAAKrB,cAAcA;AACnB,SAAKqB,aAAaA;EACpB;EAEAC,MAAMC,KAAmB;AACvB,UAAMC,OAAO,KAAKxB,YAAYyB,SAAQ;AACtC,QAAI,CAACD,QAAQ,CAACD,OAAOC,KAAKE,UAAUjC,iBAAiB;AACnD;IACF;AAEA,QAAI2B;AACJ,QAAI;AACFA,YAAMO,KAAKC,MAAML,GAAAA;IACnB,SAASM,GAAG;AACV;IACF;AACA,QACET,QAAQ,QACR,OAAOA,QAAQ,YACf,CAACD,WAAWC,KAAK,KAAKC,UAAU,GAChC;AACA;IACF;AAEA,QAAI;AACF,UAAIS,UAAUV,IAAI,KAAKC,UAAU;AACjC,YAAMU,aAAa;QACjB;QACA;QACA,KAAKV;QACL;QACA;QACA;QACA;QACA;;AAEF,UAAI,CAACS,WAAW,UAAUV,OAAO,UAAUA,KAAK;AAE9CU,kBAAUV,IAAIY;AACdD,mBAAWE,KAAK,MAAA;AAChBF,mBAAWE,KAAK,MAAA;MAClB;AACA,YAAMC,WAAOC,yBAAWf,KAAKW,UAAAA;AAC7B,YAAMK,uBAAmBC,4BAAcP,SAASI,IAAAA;AAChD,UAAIE,kBAAkB;AACpBZ,aAAKS,KAAK;UACRK,WAAW,KAAKC,YAAYnB,IAAIoB,IAAI;UACpCxB,OAAOnB,YAAYuB,IAAIJ,KAAK,KAAK;UACjCc,SAASM;QACX,CAAA;MACF;IACF,SAASP,GAAG;IAEZ;EACF;EAEQU,YAAYC,MAAmB;AACrC,QAAI,OAAOA,SAAS,YAAY,CAACC,MAAMD,IAAAA,GAAO;AAC5C,aAAOA,OAAO;IAChB;AACA,WAAOE,KAAKC,IAAG,IAAK;EACtB;AACF,GAnEM9B,wCAAN;","names":["MAX_BUFFER_SIZE","originalStreamSym","Symbol","for","logLevelMap","patchPinoLogger","logger","logsContext","symbols","Object","getOwnPropertySymbols","getPrototypeOf","streamSym","find","sym","toString","messageKeySym","originalStream","pino","captureStream","ApitallyLogCaptureStream","default","multistream","level","stream","levels","filterLogs","obj","messageKey","write","msg","logs","getStore","length","JSON","parse","e","message","ignoreKeys","data","push","rest","removeKeys","formattedMessage","formatMessage","timestamp","convertTime","time","isNaN","Date","now"]}
1
+ {"version":3,"sources":["../../src/loggers/pino.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\n\nimport type { LogRecord } from \"../common/requestLogger.js\";\nimport { formatMessage, removeKeys } from \"./utils.js\";\n\nconst MAX_BUFFER_SIZE = 1000;\n\nconst originalStreamSym = Symbol.for(\"apitally.originalStream\");\nconst logLevelMap: Record<number, string> = {\n 10: \"trace\",\n 20: \"debug\",\n 30: \"info\",\n 40: \"warn\",\n 50: \"error\",\n 60: \"fatal\",\n};\n\nexport async function patchPinoLogger(\n logger: any,\n logsContext: AsyncLocalStorage<LogRecord[]>,\n) {\n try {\n // Find stream and message key symbols on the logger and its prototype\n const symbols = [\n ...Object.getOwnPropertySymbols(logger),\n ...Object.getOwnPropertySymbols(Object.getPrototypeOf(logger)),\n ];\n const streamSym = symbols.find(\n (sym) => sym.toString() === \"Symbol(pino.stream)\",\n );\n const messageKeySym = symbols.find(\n (sym) => sym.toString() === \"Symbol(pino.messageKey)\",\n );\n if (!streamSym || !messageKeySym) {\n // not a pino logger\n return false;\n }\n\n if (!(originalStreamSym in logger)) {\n logger[originalStreamSym] = logger[streamSym];\n }\n\n const originalStream = logger[originalStreamSym];\n if (originalStream) {\n const pino = await import(/* webpackIgnore: true */ \"pino\");\n const captureStream = new ApitallyLogCaptureStream(\n logsContext,\n logger[messageKeySym],\n );\n logger[streamSym] = pino.default.multistream(\n [\n { level: 0, stream: originalStream },\n { level: 0, stream: captureStream },\n ],\n {\n levels: logger.levels,\n },\n );\n }\n return true;\n } catch {\n // ignore errors\n return false;\n }\n}\n\nfunction filterLogs(obj: any, messageKey: string) {\n return obj[messageKey] !== \"request completed\";\n}\n\nclass ApitallyLogCaptureStream {\n private logsContext: AsyncLocalStorage<LogRecord[]>;\n private messageKey: string;\n\n constructor(logsContext: AsyncLocalStorage<LogRecord[]>, messageKey: string) {\n this.logsContext = logsContext;\n this.messageKey = messageKey;\n }\n\n write(msg: string): void {\n const logs = this.logsContext.getStore();\n if (!logs || !msg || logs.length >= MAX_BUFFER_SIZE) {\n return;\n }\n\n let obj: any;\n try {\n obj = JSON.parse(msg);\n } catch (e) {\n return;\n }\n if (\n obj === null ||\n typeof obj !== \"object\" ||\n !filterLogs(obj, this.messageKey)\n ) {\n return;\n }\n\n try {\n let message = obj[this.messageKey];\n const ignoreKeys = [\n \"hostname\",\n \"level\",\n this.messageKey,\n \"pid\",\n \"time\",\n \"reqId\",\n \"req\",\n \"res\",\n ];\n if (!message && \"data\" in obj && \"tags\" in obj) {\n // hapi-pino uses data and tags instead of the message key\n message = obj.data;\n ignoreKeys.push(\"data\");\n ignoreKeys.push(\"tags\");\n }\n const rest = removeKeys(obj, ignoreKeys);\n const formattedMessage = formatMessage(message, rest);\n if (formattedMessage) {\n logs.push({\n timestamp: this.convertTime(obj.time),\n level: logLevelMap[obj.level] || \"info\",\n message: formattedMessage,\n });\n }\n } catch (e) {\n // ignore\n }\n }\n\n private convertTime(time: any): number {\n if (typeof time === \"number\" && !isNaN(time)) {\n return time / 1000; // Convert milliseconds to seconds\n }\n return Date.now() / 1000; // Fallback to current time\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA;;;;;AAAA,mBAA0C;AAA1C;AAEA,MAAMA,kBAAkB;AAExB,MAAMC,oBAAoBC,uBAAOC,IAAI,yBAAA;AACrC,MAAMC,cAAsC;EAC1C,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;AACN;AAEA,eAAsBC,gBACpBC,QACAC,aAA2C;AAE3C,MAAI;AAEF,UAAMC,UAAU;SACXC,OAAOC,sBAAsBJ,MAAAA;SAC7BG,OAAOC,sBAAsBD,OAAOE,eAAeL,MAAAA,CAAAA;;AAExD,UAAMM,YAAYJ,QAAQK,KACxB,CAACC,QAAQA,IAAIC,SAAQ,MAAO,qBAAA;AAE9B,UAAMC,gBAAgBR,QAAQK,KAC5B,CAACC,QAAQA,IAAIC,SAAQ,MAAO,yBAAA;AAE9B,QAAI,CAACH,aAAa,CAACI,eAAe;AAEhC,aAAO;IACT;AAEA,QAAI,EAAEf,qBAAqBK,SAAS;AAClCA,aAAOL,iBAAAA,IAAqBK,OAAOM,SAAAA;IACrC;AAEA,UAAMK,iBAAiBX,OAAOL,iBAAAA;AAC9B,QAAIgB,gBAAgB;AAClB,YAAMC,OAAO,MAAM;;QAAiC;MAAA;AACpD,YAAMC,gBAAgB,IAAIC,yBACxBb,aACAD,OAAOU,aAAAA,CAAc;AAEvBV,aAAOM,SAAAA,IAAaM,KAAKG,QAAQC,YAC/B;QACE;UAAEC,OAAO;UAAGC,QAAQP;QAAe;QACnC;UAAEM,OAAO;UAAGC,QAAQL;QAAc;SAEpC;QACEM,QAAQnB,OAAOmB;MACjB,CAAA;IAEJ;AACA,WAAO;EACT,QAAQ;AAEN,WAAO;EACT;AACF;AA/CsBpB;AAiDtB,SAASqB,WAAWC,KAAUC,YAAkB;AAC9C,SAAOD,IAAIC,UAAAA,MAAgB;AAC7B;AAFSF;AAIT,IAAMN,4BAAN,WAAMA;EACIb;EACAqB;EAER,YAAYrB,aAA6CqB,YAAoB;AAC3E,SAAKrB,cAAcA;AACnB,SAAKqB,aAAaA;EACpB;EAEAC,MAAMC,KAAmB;AACvB,UAAMC,OAAO,KAAKxB,YAAYyB,SAAQ;AACtC,QAAI,CAACD,QAAQ,CAACD,OAAOC,KAAKE,UAAUjC,iBAAiB;AACnD;IACF;AAEA,QAAI2B;AACJ,QAAI;AACFA,YAAMO,KAAKC,MAAML,GAAAA;IACnB,SAASM,GAAG;AACV;IACF;AACA,QACET,QAAQ,QACR,OAAOA,QAAQ,YACf,CAACD,WAAWC,KAAK,KAAKC,UAAU,GAChC;AACA;IACF;AAEA,QAAI;AACF,UAAIS,UAAUV,IAAI,KAAKC,UAAU;AACjC,YAAMU,aAAa;QACjB;QACA;QACA,KAAKV;QACL;QACA;QACA;QACA;QACA;;AAEF,UAAI,CAACS,WAAW,UAAUV,OAAO,UAAUA,KAAK;AAE9CU,kBAAUV,IAAIY;AACdD,mBAAWE,KAAK,MAAA;AAChBF,mBAAWE,KAAK,MAAA;MAClB;AACA,YAAMC,WAAOC,yBAAWf,KAAKW,UAAAA;AAC7B,YAAMK,uBAAmBC,4BAAcP,SAASI,IAAAA;AAChD,UAAIE,kBAAkB;AACpBZ,aAAKS,KAAK;UACRK,WAAW,KAAKC,YAAYnB,IAAIoB,IAAI;UACpCxB,OAAOnB,YAAYuB,IAAIJ,KAAK,KAAK;UACjCc,SAASM;QACX,CAAA;MACF;IACF,SAASP,GAAG;IAEZ;EACF;EAEQU,YAAYC,MAAmB;AACrC,QAAI,OAAOA,SAAS,YAAY,CAACC,MAAMD,IAAAA,GAAO;AAC5C,aAAOA,OAAO;IAChB;AACA,WAAOE,KAAKC,IAAG,IAAK;EACtB;AACF,GAnEM9B,wCAAN;","names":["MAX_BUFFER_SIZE","originalStreamSym","Symbol","for","logLevelMap","patchPinoLogger","logger","logsContext","symbols","Object","getOwnPropertySymbols","getPrototypeOf","streamSym","find","sym","toString","messageKeySym","originalStream","pino","captureStream","ApitallyLogCaptureStream","default","multistream","level","stream","levels","filterLogs","obj","messageKey","write","msg","logs","getStore","length","JSON","parse","e","message","ignoreKeys","data","push","rest","removeKeys","formattedMessage","formatMessage","timestamp","convertTime","time","isNaN","Date","now"]}
@@ -2,6 +2,10 @@ import { AsyncLocalStorage } from 'node:async_hooks';
2
2
  import { LogRecord } from '../common/requestLogger.cjs';
3
3
  import 'node:buffer';
4
4
  import 'node:http';
5
+ import '../common/spanCollector.cjs';
6
+ import '@opentelemetry/sdk-trace-base';
7
+ import '../common/logging.cjs';
8
+ import 'winston';
5
9
  import '../common/tempGzipFile.cjs';
6
10
 
7
11
  declare function patchPinoLogger(logger: any, logsContext: AsyncLocalStorage<LogRecord[]>): Promise<boolean>;
@@ -2,6 +2,10 @@ import { AsyncLocalStorage } from 'node:async_hooks';
2
2
  import { LogRecord } from '../common/requestLogger.js';
3
3
  import 'node:buffer';
4
4
  import 'node:http';
5
+ import '../common/spanCollector.js';
6
+ import '@opentelemetry/sdk-trace-base';
7
+ import '../common/logging.js';
8
+ import 'winston';
5
9
  import '../common/tempGzipFile.js';
6
10
 
7
11
  declare function patchPinoLogger(logger: any, logsContext: AsyncLocalStorage<LogRecord[]>): Promise<boolean>;
@@ -3,7 +3,7 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
3
3
  var _a;
4
4
  import { formatMessage, removeKeys } from "./utils.js";
5
5
  const MAX_BUFFER_SIZE = 1e3;
6
- const originalStreamSym = Symbol.for("apitally.originalStream");
6
+ const originalStreamSym = /* @__PURE__ */ Symbol.for("apitally.originalStream");
7
7
  const logLevelMap = {
8
8
  10: "trace",
9
9
  20: "debug",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/loggers/pino.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\n\nimport type { LogRecord } from \"../common/requestLogger.js\";\nimport { formatMessage, removeKeys } from \"./utils.js\";\n\nconst MAX_BUFFER_SIZE = 1000;\n\nconst originalStreamSym = Symbol.for(\"apitally.originalStream\");\nconst logLevelMap: Record<number, string> = {\n 10: \"trace\",\n 20: \"debug\",\n 30: \"info\",\n 40: \"warn\",\n 50: \"error\",\n 60: \"fatal\",\n};\n\nexport async function patchPinoLogger(\n logger: any,\n logsContext: AsyncLocalStorage<LogRecord[]>,\n) {\n try {\n // Find stream and message key symbols on the logger and its prototype\n const symbols = [\n ...Object.getOwnPropertySymbols(logger),\n ...Object.getOwnPropertySymbols(Object.getPrototypeOf(logger)),\n ];\n const streamSym = symbols.find(\n (sym) => sym.toString() === \"Symbol(pino.stream)\",\n );\n const messageKeySym = symbols.find(\n (sym) => sym.toString() === \"Symbol(pino.messageKey)\",\n );\n if (!streamSym || !messageKeySym) {\n // not a pino logger\n return false;\n }\n\n if (!(originalStreamSym in logger)) {\n logger[originalStreamSym] = logger[streamSym];\n }\n\n const originalStream = logger[originalStreamSym];\n if (originalStream) {\n const pino = await import(/* webpackIgnore: true */ \"pino\");\n const captureStream = new ApitallyLogCaptureStream(\n logsContext,\n logger[messageKeySym],\n );\n logger[streamSym] = pino.default.multistream(\n [\n { level: 0, stream: originalStream },\n { level: 0, stream: captureStream },\n ],\n {\n levels: logger.levels,\n },\n );\n }\n return true;\n } catch {\n // ignore errors\n return false;\n }\n}\n\nfunction filterLogs(obj: any, messageKey: string) {\n return obj[messageKey] !== \"request completed\";\n}\n\nclass ApitallyLogCaptureStream {\n private logsContext: AsyncLocalStorage<LogRecord[]>;\n private messageKey: string;\n\n constructor(logsContext: AsyncLocalStorage<LogRecord[]>, messageKey: string) {\n this.logsContext = logsContext;\n this.messageKey = messageKey;\n }\n\n write(msg: string): void {\n const logs = this.logsContext.getStore();\n if (!logs || !msg || logs.length >= MAX_BUFFER_SIZE) {\n return;\n }\n\n let obj: any;\n try {\n obj = JSON.parse(msg);\n } catch (e) {\n return;\n }\n if (\n obj === null ||\n typeof obj !== \"object\" ||\n !filterLogs(obj, this.messageKey)\n ) {\n return;\n }\n\n try {\n let message = obj[this.messageKey];\n const ignoreKeys = [\n \"hostname\",\n \"level\",\n this.messageKey,\n \"pid\",\n \"time\",\n \"reqId\",\n \"req\",\n \"res\",\n ];\n if (!message && \"data\" in obj && \"tags\" in obj) {\n // hapi-pino uses data and tags instead of the message key\n message = obj.data;\n ignoreKeys.push(\"data\");\n ignoreKeys.push(\"tags\");\n }\n const rest = removeKeys(obj, ignoreKeys);\n const formattedMessage = formatMessage(message, rest);\n if (formattedMessage) {\n logs.push({\n timestamp: this.convertTime(obj.time),\n level: logLevelMap[obj.level] || \"info\",\n message: formattedMessage,\n });\n }\n } catch (e) {\n // ignore\n }\n }\n\n private convertTime(time: any): number {\n if (typeof time === \"number\" && !isNaN(time)) {\n return time / 1000; // Convert milliseconds to seconds\n }\n return Date.now() / 1000; // Fallback to current time\n }\n}\n"],"mappings":";;AAGA;SAASA,eAAeC,kBAAkB;AAE1C,MAAMC,kBAAkB;AAExB,MAAMC,oBAAoBC,OAAOC,IAAI,yBAAA;AACrC,MAAMC,cAAsC;EAC1C,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;AACN;AAEA,eAAsBC,gBACpBC,QACAC,aAA2C;AAE3C,MAAI;AAEF,UAAMC,UAAU;SACXC,OAAOC,sBAAsBJ,MAAAA;SAC7BG,OAAOC,sBAAsBD,OAAOE,eAAeL,MAAAA,CAAAA;;AAExD,UAAMM,YAAYJ,QAAQK,KACxB,CAACC,QAAQA,IAAIC,SAAQ,MAAO,qBAAA;AAE9B,UAAMC,gBAAgBR,QAAQK,KAC5B,CAACC,QAAQA,IAAIC,SAAQ,MAAO,yBAAA;AAE9B,QAAI,CAACH,aAAa,CAACI,eAAe;AAEhC,aAAO;IACT;AAEA,QAAI,EAAEf,qBAAqBK,SAAS;AAClCA,aAAOL,iBAAAA,IAAqBK,OAAOM,SAAAA;IACrC;AAEA,UAAMK,iBAAiBX,OAAOL,iBAAAA;AAC9B,QAAIgB,gBAAgB;AAClB,YAAMC,OAAO,MAAM;;QAAiC;MAAA;AACpD,YAAMC,gBAAgB,IAAIC,yBACxBb,aACAD,OAAOU,aAAAA,CAAc;AAEvBV,aAAOM,SAAAA,IAAaM,KAAKG,QAAQC,YAC/B;QACE;UAAEC,OAAO;UAAGC,QAAQP;QAAe;QACnC;UAAEM,OAAO;UAAGC,QAAQL;QAAc;SAEpC;QACEM,QAAQnB,OAAOmB;MACjB,CAAA;IAEJ;AACA,WAAO;EACT,QAAQ;AAEN,WAAO;EACT;AACF;AA/CsBpB;AAiDtB,SAASqB,WAAWC,KAAUC,YAAkB;AAC9C,SAAOD,IAAIC,UAAAA,MAAgB;AAC7B;AAFSF;AAIT,IAAMN,4BAAN,WAAMA;EACIb;EACAqB;EAER,YAAYrB,aAA6CqB,YAAoB;AAC3E,SAAKrB,cAAcA;AACnB,SAAKqB,aAAaA;EACpB;EAEAC,MAAMC,KAAmB;AACvB,UAAMC,OAAO,KAAKxB,YAAYyB,SAAQ;AACtC,QAAI,CAACD,QAAQ,CAACD,OAAOC,KAAKE,UAAUjC,iBAAiB;AACnD;IACF;AAEA,QAAI2B;AACJ,QAAI;AACFA,YAAMO,KAAKC,MAAML,GAAAA;IACnB,SAASM,GAAG;AACV;IACF;AACA,QACET,QAAQ,QACR,OAAOA,QAAQ,YACf,CAACD,WAAWC,KAAK,KAAKC,UAAU,GAChC;AACA;IACF;AAEA,QAAI;AACF,UAAIS,UAAUV,IAAI,KAAKC,UAAU;AACjC,YAAMU,aAAa;QACjB;QACA;QACA,KAAKV;QACL;QACA;QACA;QACA;QACA;;AAEF,UAAI,CAACS,WAAW,UAAUV,OAAO,UAAUA,KAAK;AAE9CU,kBAAUV,IAAIY;AACdD,mBAAWE,KAAK,MAAA;AAChBF,mBAAWE,KAAK,MAAA;MAClB;AACA,YAAMC,OAAO1C,WAAW4B,KAAKW,UAAAA;AAC7B,YAAMI,mBAAmB5C,cAAcuC,SAASI,IAAAA;AAChD,UAAIC,kBAAkB;AACpBX,aAAKS,KAAK;UACRG,WAAW,KAAKC,YAAYjB,IAAIkB,IAAI;UACpCtB,OAAOnB,YAAYuB,IAAIJ,KAAK,KAAK;UACjCc,SAASK;QACX,CAAA;MACF;IACF,SAASN,GAAG;IAEZ;EACF;EAEQQ,YAAYC,MAAmB;AACrC,QAAI,OAAOA,SAAS,YAAY,CAACC,MAAMD,IAAAA,GAAO;AAC5C,aAAOA,OAAO;IAChB;AACA,WAAOE,KAAKC,IAAG,IAAK;EACtB;AACF,GAnEM5B,wCAAN;","names":["formatMessage","removeKeys","MAX_BUFFER_SIZE","originalStreamSym","Symbol","for","logLevelMap","patchPinoLogger","logger","logsContext","symbols","Object","getOwnPropertySymbols","getPrototypeOf","streamSym","find","sym","toString","messageKeySym","originalStream","pino","captureStream","ApitallyLogCaptureStream","default","multistream","level","stream","levels","filterLogs","obj","messageKey","write","msg","logs","getStore","length","JSON","parse","e","message","ignoreKeys","data","push","rest","formattedMessage","timestamp","convertTime","time","isNaN","Date","now"]}
1
+ {"version":3,"sources":["../../src/loggers/pino.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\n\nimport type { LogRecord } from \"../common/requestLogger.js\";\nimport { formatMessage, removeKeys } from \"./utils.js\";\n\nconst MAX_BUFFER_SIZE = 1000;\n\nconst originalStreamSym = Symbol.for(\"apitally.originalStream\");\nconst logLevelMap: Record<number, string> = {\n 10: \"trace\",\n 20: \"debug\",\n 30: \"info\",\n 40: \"warn\",\n 50: \"error\",\n 60: \"fatal\",\n};\n\nexport async function patchPinoLogger(\n logger: any,\n logsContext: AsyncLocalStorage<LogRecord[]>,\n) {\n try {\n // Find stream and message key symbols on the logger and its prototype\n const symbols = [\n ...Object.getOwnPropertySymbols(logger),\n ...Object.getOwnPropertySymbols(Object.getPrototypeOf(logger)),\n ];\n const streamSym = symbols.find(\n (sym) => sym.toString() === \"Symbol(pino.stream)\",\n );\n const messageKeySym = symbols.find(\n (sym) => sym.toString() === \"Symbol(pino.messageKey)\",\n );\n if (!streamSym || !messageKeySym) {\n // not a pino logger\n return false;\n }\n\n if (!(originalStreamSym in logger)) {\n logger[originalStreamSym] = logger[streamSym];\n }\n\n const originalStream = logger[originalStreamSym];\n if (originalStream) {\n const pino = await import(/* webpackIgnore: true */ \"pino\");\n const captureStream = new ApitallyLogCaptureStream(\n logsContext,\n logger[messageKeySym],\n );\n logger[streamSym] = pino.default.multistream(\n [\n { level: 0, stream: originalStream },\n { level: 0, stream: captureStream },\n ],\n {\n levels: logger.levels,\n },\n );\n }\n return true;\n } catch {\n // ignore errors\n return false;\n }\n}\n\nfunction filterLogs(obj: any, messageKey: string) {\n return obj[messageKey] !== \"request completed\";\n}\n\nclass ApitallyLogCaptureStream {\n private logsContext: AsyncLocalStorage<LogRecord[]>;\n private messageKey: string;\n\n constructor(logsContext: AsyncLocalStorage<LogRecord[]>, messageKey: string) {\n this.logsContext = logsContext;\n this.messageKey = messageKey;\n }\n\n write(msg: string): void {\n const logs = this.logsContext.getStore();\n if (!logs || !msg || logs.length >= MAX_BUFFER_SIZE) {\n return;\n }\n\n let obj: any;\n try {\n obj = JSON.parse(msg);\n } catch (e) {\n return;\n }\n if (\n obj === null ||\n typeof obj !== \"object\" ||\n !filterLogs(obj, this.messageKey)\n ) {\n return;\n }\n\n try {\n let message = obj[this.messageKey];\n const ignoreKeys = [\n \"hostname\",\n \"level\",\n this.messageKey,\n \"pid\",\n \"time\",\n \"reqId\",\n \"req\",\n \"res\",\n ];\n if (!message && \"data\" in obj && \"tags\" in obj) {\n // hapi-pino uses data and tags instead of the message key\n message = obj.data;\n ignoreKeys.push(\"data\");\n ignoreKeys.push(\"tags\");\n }\n const rest = removeKeys(obj, ignoreKeys);\n const formattedMessage = formatMessage(message, rest);\n if (formattedMessage) {\n logs.push({\n timestamp: this.convertTime(obj.time),\n level: logLevelMap[obj.level] || \"info\",\n message: formattedMessage,\n });\n }\n } catch (e) {\n // ignore\n }\n }\n\n private convertTime(time: any): number {\n if (typeof time === \"number\" && !isNaN(time)) {\n return time / 1000; // Convert milliseconds to seconds\n }\n return Date.now() / 1000; // Fallback to current time\n }\n}\n"],"mappings":";;AAGA;SAASA,eAAeC,kBAAkB;AAE1C,MAAMC,kBAAkB;AAExB,MAAMC,oBAAoBC,uBAAOC,IAAI,yBAAA;AACrC,MAAMC,cAAsC;EAC1C,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;AACN;AAEA,eAAsBC,gBACpBC,QACAC,aAA2C;AAE3C,MAAI;AAEF,UAAMC,UAAU;SACXC,OAAOC,sBAAsBJ,MAAAA;SAC7BG,OAAOC,sBAAsBD,OAAOE,eAAeL,MAAAA,CAAAA;;AAExD,UAAMM,YAAYJ,QAAQK,KACxB,CAACC,QAAQA,IAAIC,SAAQ,MAAO,qBAAA;AAE9B,UAAMC,gBAAgBR,QAAQK,KAC5B,CAACC,QAAQA,IAAIC,SAAQ,MAAO,yBAAA;AAE9B,QAAI,CAACH,aAAa,CAACI,eAAe;AAEhC,aAAO;IACT;AAEA,QAAI,EAAEf,qBAAqBK,SAAS;AAClCA,aAAOL,iBAAAA,IAAqBK,OAAOM,SAAAA;IACrC;AAEA,UAAMK,iBAAiBX,OAAOL,iBAAAA;AAC9B,QAAIgB,gBAAgB;AAClB,YAAMC,OAAO,MAAM;;QAAiC;MAAA;AACpD,YAAMC,gBAAgB,IAAIC,yBACxBb,aACAD,OAAOU,aAAAA,CAAc;AAEvBV,aAAOM,SAAAA,IAAaM,KAAKG,QAAQC,YAC/B;QACE;UAAEC,OAAO;UAAGC,QAAQP;QAAe;QACnC;UAAEM,OAAO;UAAGC,QAAQL;QAAc;SAEpC;QACEM,QAAQnB,OAAOmB;MACjB,CAAA;IAEJ;AACA,WAAO;EACT,QAAQ;AAEN,WAAO;EACT;AACF;AA/CsBpB;AAiDtB,SAASqB,WAAWC,KAAUC,YAAkB;AAC9C,SAAOD,IAAIC,UAAAA,MAAgB;AAC7B;AAFSF;AAIT,IAAMN,4BAAN,WAAMA;EACIb;EACAqB;EAER,YAAYrB,aAA6CqB,YAAoB;AAC3E,SAAKrB,cAAcA;AACnB,SAAKqB,aAAaA;EACpB;EAEAC,MAAMC,KAAmB;AACvB,UAAMC,OAAO,KAAKxB,YAAYyB,SAAQ;AACtC,QAAI,CAACD,QAAQ,CAACD,OAAOC,KAAKE,UAAUjC,iBAAiB;AACnD;IACF;AAEA,QAAI2B;AACJ,QAAI;AACFA,YAAMO,KAAKC,MAAML,GAAAA;IACnB,SAASM,GAAG;AACV;IACF;AACA,QACET,QAAQ,QACR,OAAOA,QAAQ,YACf,CAACD,WAAWC,KAAK,KAAKC,UAAU,GAChC;AACA;IACF;AAEA,QAAI;AACF,UAAIS,UAAUV,IAAI,KAAKC,UAAU;AACjC,YAAMU,aAAa;QACjB;QACA;QACA,KAAKV;QACL;QACA;QACA;QACA;QACA;;AAEF,UAAI,CAACS,WAAW,UAAUV,OAAO,UAAUA,KAAK;AAE9CU,kBAAUV,IAAIY;AACdD,mBAAWE,KAAK,MAAA;AAChBF,mBAAWE,KAAK,MAAA;MAClB;AACA,YAAMC,OAAO1C,WAAW4B,KAAKW,UAAAA;AAC7B,YAAMI,mBAAmB5C,cAAcuC,SAASI,IAAAA;AAChD,UAAIC,kBAAkB;AACpBX,aAAKS,KAAK;UACRG,WAAW,KAAKC,YAAYjB,IAAIkB,IAAI;UACpCtB,OAAOnB,YAAYuB,IAAIJ,KAAK,KAAK;UACjCc,SAASK;QACX,CAAA;MACF;IACF,SAASN,GAAG;IAEZ;EACF;EAEQQ,YAAYC,MAAmB;AACrC,QAAI,OAAOA,SAAS,YAAY,CAACC,MAAMD,IAAAA,GAAO;AAC5C,aAAOA,OAAO;IAChB;AACA,WAAOE,KAAKC,IAAG,IAAK;EACtB;AACF,GAnEM5B,wCAAN;","names":["formatMessage","removeKeys","MAX_BUFFER_SIZE","originalStreamSym","Symbol","for","logLevelMap","patchPinoLogger","logger","logsContext","symbols","Object","getOwnPropertySymbols","getPrototypeOf","streamSym","find","sym","toString","messageKeySym","originalStream","pino","captureStream","ApitallyLogCaptureStream","default","multistream","level","stream","levels","filterLogs","obj","messageKey","write","msg","logs","getStore","length","JSON","parse","e","message","ignoreKeys","data","push","rest","formattedMessage","timestamp","convertTime","time","isNaN","Date","now"]}
@@ -2,6 +2,10 @@ import { AsyncLocalStorage } from 'node:async_hooks';
2
2
  import { LogRecord } from '../common/requestLogger.cjs';
3
3
  import 'node:buffer';
4
4
  import 'node:http';
5
+ import '../common/spanCollector.cjs';
6
+ import '@opentelemetry/sdk-trace-base';
7
+ import '../common/logging.cjs';
8
+ import 'winston';
5
9
  import '../common/tempGzipFile.cjs';
6
10
 
7
11
  declare function patchWinston(logsContext: AsyncLocalStorage<LogRecord[]>): Promise<void>;
@@ -2,6 +2,10 @@ import { AsyncLocalStorage } from 'node:async_hooks';
2
2
  import { LogRecord } from '../common/requestLogger.js';
3
3
  import 'node:buffer';
4
4
  import 'node:http';
5
+ import '../common/spanCollector.js';
6
+ import '@opentelemetry/sdk-trace-base';
7
+ import '../common/logging.js';
8
+ import 'winston';
5
9
  import '../common/tempGzipFile.js';
6
10
 
7
11
  declare function patchWinston(logsContext: AsyncLocalStorage<LogRecord[]>): Promise<void>;
@@ -29,12 +29,14 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
29
29
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
30
  var nestjs_exports = {};
31
31
  __export(nestjs_exports, {
32
+ ApitallySpanProcessor: () => import_spanCollector.ApitallySpanProcessor,
32
33
  setConsumer: () => setConsumer,
33
34
  useApitally: () => useApitally
34
35
  });
35
36
  module.exports = __toCommonJS(nestjs_exports);
36
37
  var import_common = require("@nestjs/common");
37
38
  var import_rxjs = require("rxjs");
39
+ var import_spanCollector = require("../common/spanCollector.js");
38
40
  var _a;
39
41
  function _ts_decorate(decorators, target, key, desc) {
40
42
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -99,6 +101,7 @@ ApitallyInterceptor = _ts_decorate([
99
101
  ], ApitallyInterceptor);
100
102
  // Annotate the CommonJS export names for ESM import in node:
101
103
  0 && (module.exports = {
104
+ ApitallySpanProcessor,
102
105
  setConsumer,
103
106
  useApitally
104
107
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/nestjs/index.ts"],"sourcesContent":["import {\n CallHandler,\n ExecutionContext,\n INestApplication,\n Injectable,\n NestInterceptor,\n} from \"@nestjs/common\";\nimport { catchError, throwError } from \"rxjs\";\n\nimport type { ApitallyConfig, ApitallyConsumer } from \"../common/types.js\";\nexport type { ApitallyConfig, ApitallyConsumer } from \"../common/types.js\";\n\nlet setConsumerFn:\n | ((\n request: any,\n consumer: ApitallyConsumer | string | null | undefined,\n ) => void)\n | null = null;\n\nexport async function useApitally(\n app: INestApplication,\n config: ApitallyConfig,\n) {\n const httpAdapter = app.getHttpAdapter();\n const instance = httpAdapter.getInstance();\n const platform = httpAdapter.constructor.name\n .toLowerCase()\n .includes(\"fastify\")\n ? \"fastify\"\n : \"express\";\n\n if (platform === \"express\") {\n const { useApitally, setConsumer } = await import(\"../express/index.js\");\n setConsumerFn = setConsumer;\n useApitally(instance, config);\n } else if (platform === \"fastify\") {\n const { apitallyPlugin, setConsumer } = await import(\"../fastify/index.js\");\n setConsumerFn = setConsumer;\n await instance.register(apitallyPlugin, config);\n }\n\n app.useGlobalInterceptors(new ApitallyInterceptor(platform));\n}\n\nexport function setConsumer(\n request: any,\n consumer: ApitallyConsumer | string | null | undefined,\n) {\n if (setConsumerFn) {\n setConsumerFn(request, consumer);\n }\n}\n\n@Injectable()\nclass ApitallyInterceptor implements NestInterceptor {\n constructor(private readonly platform: \"express\" | \"fastify\") {}\n\n intercept(context: ExecutionContext, next: CallHandler) {\n return next.handle().pipe(\n catchError((exception) => {\n if (context.getType() === \"http\") {\n const ctx = context.switchToHttp();\n const res = ctx.getResponse();\n\n if (this.platform === \"express\" && res.locals) {\n res.locals.serverError = exception;\n } else if (\n this.platform === \"fastify\" &&\n (!exception.statusCode || exception.statusCode === 500)\n ) {\n res.serverError = exception;\n }\n }\n return throwError(() => exception);\n }),\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,oBAMO;AACP,kBAAuC;;;;;;;;;;;;;AAKvC,IAAIA,gBAKO;AAEX,eAAsBC,YACpBC,KACAC,QAAsB;AAEtB,QAAMC,cAAcF,IAAIG,eAAc;AACtC,QAAMC,WAAWF,YAAYG,YAAW;AACxC,QAAMC,WAAWJ,YAAY,YAAYK,KACtCC,YAAW,EACXC,SAAS,SAAA,IACR,YACA;AAEJ,MAAIH,aAAa,WAAW;AAC1B,UAAM,EAAEP,aAAAA,cAAaW,aAAAA,aAAW,IAAK,MAAM,OAAO,qBAAA;AAClDZ,oBAAgBY;AAChBX,IAAAA,aAAYK,UAAUH,MAAAA;EACxB,WAAWK,aAAa,WAAW;AACjC,UAAM,EAAEK,gBAAgBD,aAAAA,aAAW,IAAK,MAAM,OAAO,qBAAA;AACrDZ,oBAAgBY;AAChB,UAAMN,SAASQ,SAASD,gBAAgBV,MAAAA;EAC1C;AAEAD,MAAIa,sBAAsB,IAAIC,oBAAoBR,QAAAA,CAAAA;AACpD;AAvBsBP;AAyBf,SAASW,YACdK,SACAC,UAAsD;AAEtD,MAAIlB,eAAe;AACjBA,kBAAciB,SAASC,QAAAA;EACzB;AACF;AAPgBN;AAShB,IACMI,uBADN,WACMA;;EACJ,YAA6BR,UAAiC;SAAjCA,WAAAA;EAAkC;EAE/DW,UAAUC,SAA2BC,MAAmB;AACtD,WAAOA,KAAKC,OAAM,EAAGC,SACnBC,wBAAW,CAACC,cAAAA;AACV,UAAIL,QAAQM,QAAO,MAAO,QAAQ;AAChC,cAAMC,MAAMP,QAAQQ,aAAY;AAChC,cAAMC,MAAMF,IAAIG,YAAW;AAE3B,YAAI,KAAKtB,aAAa,aAAaqB,IAAIE,QAAQ;AAC7CF,cAAIE,OAAOC,cAAcP;QAC3B,WACE,KAAKjB,aAAa,cACjB,CAACiB,UAAUQ,cAAcR,UAAUQ,eAAe,MACnD;AACAJ,cAAIG,cAAcP;QACpB;MACF;AACA,iBAAOS,wBAAW,MAAMT,SAAAA;IAC1B,CAAA,CAAA;EAEJ;AACF,GAvBMT,mCADN;;;;;;;;","names":["setConsumerFn","useApitally","app","config","httpAdapter","getHttpAdapter","instance","getInstance","platform","name","toLowerCase","includes","setConsumer","apitallyPlugin","register","useGlobalInterceptors","ApitallyInterceptor","request","consumer","intercept","context","next","handle","pipe","catchError","exception","getType","ctx","switchToHttp","res","getResponse","locals","serverError","statusCode","throwError"]}
1
+ {"version":3,"sources":["../../src/nestjs/index.ts"],"sourcesContent":["import {\n CallHandler,\n ExecutionContext,\n INestApplication,\n Injectable,\n NestInterceptor,\n} from \"@nestjs/common\";\nimport { catchError, throwError } from \"rxjs\";\n\nimport type { ApitallyConfig, ApitallyConsumer } from \"../common/types.js\";\nexport { ApitallySpanProcessor } from \"../common/spanCollector.js\";\nexport type { ApitallyConfig, ApitallyConsumer } from \"../common/types.js\";\n\nlet setConsumerFn:\n | ((\n request: any,\n consumer: ApitallyConsumer | string | null | undefined,\n ) => void)\n | null = null;\n\nexport async function useApitally(\n app: INestApplication,\n config: ApitallyConfig,\n) {\n const httpAdapter = app.getHttpAdapter();\n const instance = httpAdapter.getInstance();\n const platform = httpAdapter.constructor.name\n .toLowerCase()\n .includes(\"fastify\")\n ? \"fastify\"\n : \"express\";\n\n if (platform === \"express\") {\n const { useApitally, setConsumer } = await import(\"../express/index.js\");\n setConsumerFn = setConsumer;\n useApitally(instance, config);\n } else if (platform === \"fastify\") {\n const { apitallyPlugin, setConsumer } = await import(\"../fastify/index.js\");\n setConsumerFn = setConsumer;\n await instance.register(apitallyPlugin, config);\n }\n\n app.useGlobalInterceptors(new ApitallyInterceptor(platform));\n}\n\nexport function setConsumer(\n request: any,\n consumer: ApitallyConsumer | string | null | undefined,\n) {\n if (setConsumerFn) {\n setConsumerFn(request, consumer);\n }\n}\n\n@Injectable()\nclass ApitallyInterceptor implements NestInterceptor {\n constructor(private readonly platform: \"express\" | \"fastify\") {}\n\n intercept(context: ExecutionContext, next: CallHandler) {\n return next.handle().pipe(\n catchError((exception) => {\n if (context.getType() === \"http\") {\n const ctx = context.switchToHttp();\n const res = ctx.getResponse();\n\n if (this.platform === \"express\" && res.locals) {\n res.locals.serverError = exception;\n } else if (\n this.platform === \"fastify\" &&\n (!exception.statusCode || exception.statusCode === 500)\n ) {\n res.serverError = exception;\n }\n }\n return throwError(() => exception);\n }),\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,oBAMO;AACP,kBAAuC;AAGvC,2BAAsC;;;;;;;;;;;;;AAGtC,IAAIA,gBAKO;AAEX,eAAsBC,YACpBC,KACAC,QAAsB;AAEtB,QAAMC,cAAcF,IAAIG,eAAc;AACtC,QAAMC,WAAWF,YAAYG,YAAW;AACxC,QAAMC,WAAWJ,YAAY,YAAYK,KACtCC,YAAW,EACXC,SAAS,SAAA,IACR,YACA;AAEJ,MAAIH,aAAa,WAAW;AAC1B,UAAM,EAAEP,aAAAA,cAAaW,aAAAA,aAAW,IAAK,MAAM,OAAO,qBAAA;AAClDZ,oBAAgBY;AAChBX,IAAAA,aAAYK,UAAUH,MAAAA;EACxB,WAAWK,aAAa,WAAW;AACjC,UAAM,EAAEK,gBAAgBD,aAAAA,aAAW,IAAK,MAAM,OAAO,qBAAA;AACrDZ,oBAAgBY;AAChB,UAAMN,SAASQ,SAASD,gBAAgBV,MAAAA;EAC1C;AAEAD,MAAIa,sBAAsB,IAAIC,oBAAoBR,QAAAA,CAAAA;AACpD;AAvBsBP;AAyBf,SAASW,YACdK,SACAC,UAAsD;AAEtD,MAAIlB,eAAe;AACjBA,kBAAciB,SAASC,QAAAA;EACzB;AACF;AAPgBN;AAShB,IACMI,uBADN,WACMA;;EACJ,YAA6BR,UAAiC;SAAjCA,WAAAA;EAAkC;EAE/DW,UAAUC,SAA2BC,MAAmB;AACtD,WAAOA,KAAKC,OAAM,EAAGC,SACnBC,wBAAW,CAACC,cAAAA;AACV,UAAIL,QAAQM,QAAO,MAAO,QAAQ;AAChC,cAAMC,MAAMP,QAAQQ,aAAY;AAChC,cAAMC,MAAMF,IAAIG,YAAW;AAE3B,YAAI,KAAKtB,aAAa,aAAaqB,IAAIE,QAAQ;AAC7CF,cAAIE,OAAOC,cAAcP;QAC3B,WACE,KAAKjB,aAAa,cACjB,CAACiB,UAAUQ,cAAcR,UAAUQ,eAAe,MACnD;AACAJ,cAAIG,cAAcP;QACpB;MACF;AACA,iBAAOS,wBAAW,MAAMT,SAAAA;IAC1B,CAAA,CAAA;EAEJ;AACF,GAvBMT,mCADN;;;;;;;;","names":["setConsumerFn","useApitally","app","config","httpAdapter","getHttpAdapter","instance","getInstance","platform","name","toLowerCase","includes","setConsumer","apitallyPlugin","register","useGlobalInterceptors","ApitallyInterceptor","request","consumer","intercept","context","next","handle","pipe","catchError","exception","getType","ctx","switchToHttp","res","getResponse","locals","serverError","statusCode","throwError"]}
@@ -1,11 +1,13 @@
1
1
  import { INestApplication } from '@nestjs/common';
2
2
  import { ApitallyConfig, ApitallyConsumer } from '../common/types.cjs';
3
+ export { ApitallySpanProcessor } from '../common/spanCollector.cjs';
3
4
  import '../common/logging.cjs';
4
5
  import 'winston';
5
6
  import '../common/requestLogger.cjs';
6
7
  import 'node:buffer';
7
8
  import 'node:http';
8
9
  import '../common/tempGzipFile.cjs';
10
+ import '@opentelemetry/sdk-trace-base';
9
11
 
10
12
  declare function useApitally(app: INestApplication, config: ApitallyConfig): Promise<void>;
11
13
  declare function setConsumer(request: any, consumer: ApitallyConsumer | string | null | undefined): void;
@@ -1,11 +1,13 @@
1
1
  import { INestApplication } from '@nestjs/common';
2
2
  import { ApitallyConfig, ApitallyConsumer } from '../common/types.js';
3
+ export { ApitallySpanProcessor } from '../common/spanCollector.js';
3
4
  import '../common/logging.js';
4
5
  import 'winston';
5
6
  import '../common/requestLogger.js';
6
7
  import 'node:buffer';
7
8
  import 'node:http';
8
9
  import '../common/tempGzipFile.js';
10
+ import '@opentelemetry/sdk-trace-base';
9
11
 
10
12
  declare function useApitally(app: INestApplication, config: ApitallyConfig): Promise<void>;
11
13
  declare function setConsumer(request: any, consumer: ApitallyConsumer | string | null | undefined): void;
@@ -14,6 +14,7 @@ function _ts_metadata(k, v) {
14
14
  __name(_ts_metadata, "_ts_metadata");
15
15
  import { Injectable } from "@nestjs/common";
16
16
  import { catchError, throwError } from "rxjs";
17
+ import { ApitallySpanProcessor } from "../common/spanCollector.js";
17
18
  let setConsumerFn = null;
18
19
  async function useApitally(app, config) {
19
20
  const httpAdapter = app.getHttpAdapter();
@@ -65,6 +66,7 @@ ApitallyInterceptor = _ts_decorate([
65
66
  ])
66
67
  ], ApitallyInterceptor);
67
68
  export {
69
+ ApitallySpanProcessor,
68
70
  setConsumer,
69
71
  useApitally
70
72
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/nestjs/index.ts"],"sourcesContent":["import {\n CallHandler,\n ExecutionContext,\n INestApplication,\n Injectable,\n NestInterceptor,\n} from \"@nestjs/common\";\nimport { catchError, throwError } from \"rxjs\";\n\nimport type { ApitallyConfig, ApitallyConsumer } from \"../common/types.js\";\nexport type { ApitallyConfig, ApitallyConsumer } from \"../common/types.js\";\n\nlet setConsumerFn:\n | ((\n request: any,\n consumer: ApitallyConsumer | string | null | undefined,\n ) => void)\n | null = null;\n\nexport async function useApitally(\n app: INestApplication,\n config: ApitallyConfig,\n) {\n const httpAdapter = app.getHttpAdapter();\n const instance = httpAdapter.getInstance();\n const platform = httpAdapter.constructor.name\n .toLowerCase()\n .includes(\"fastify\")\n ? \"fastify\"\n : \"express\";\n\n if (platform === \"express\") {\n const { useApitally, setConsumer } = await import(\"../express/index.js\");\n setConsumerFn = setConsumer;\n useApitally(instance, config);\n } else if (platform === \"fastify\") {\n const { apitallyPlugin, setConsumer } = await import(\"../fastify/index.js\");\n setConsumerFn = setConsumer;\n await instance.register(apitallyPlugin, config);\n }\n\n app.useGlobalInterceptors(new ApitallyInterceptor(platform));\n}\n\nexport function setConsumer(\n request: any,\n consumer: ApitallyConsumer | string | null | undefined,\n) {\n if (setConsumerFn) {\n setConsumerFn(request, consumer);\n }\n}\n\n@Injectable()\nclass ApitallyInterceptor implements NestInterceptor {\n constructor(private readonly platform: \"express\" | \"fastify\") {}\n\n intercept(context: ExecutionContext, next: CallHandler) {\n return next.handle().pipe(\n catchError((exception) => {\n if (context.getType() === \"http\") {\n const ctx = context.switchToHttp();\n const res = ctx.getResponse();\n\n if (this.platform === \"express\" && res.locals) {\n res.locals.serverError = exception;\n } else if (\n this.platform === \"fastify\" &&\n (!exception.statusCode || exception.statusCode === 500)\n ) {\n res.serverError = exception;\n }\n }\n return throwError(() => exception);\n }),\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;AAAA,SAIEA,kBAEK;AACP,SAASC,YAAYC,kBAAkB;AAKvC,IAAIC,gBAKO;AAEX,eAAsBC,YACpBC,KACAC,QAAsB;AAEtB,QAAMC,cAAcF,IAAIG,eAAc;AACtC,QAAMC,WAAWF,YAAYG,YAAW;AACxC,QAAMC,WAAWJ,YAAY,YAAYK,KACtCC,YAAW,EACXC,SAAS,SAAA,IACR,YACA;AAEJ,MAAIH,aAAa,WAAW;AAC1B,UAAM,EAAEP,aAAAA,cAAaW,aAAAA,aAAW,IAAK,MAAM,OAAO,qBAAA;AAClDZ,oBAAgBY;AAChBX,IAAAA,aAAYK,UAAUH,MAAAA;EACxB,WAAWK,aAAa,WAAW;AACjC,UAAM,EAAEK,gBAAgBD,aAAAA,aAAW,IAAK,MAAM,OAAO,qBAAA;AACrDZ,oBAAgBY;AAChB,UAAMN,SAASQ,SAASD,gBAAgBV,MAAAA;EAC1C;AAEAD,MAAIa,sBAAsB,IAAIC,oBAAoBR,QAAAA,CAAAA;AACpD;AAvBsBP;AAyBf,SAASW,YACdK,SACAC,UAAsD;AAEtD,MAAIlB,eAAe;AACjBA,kBAAciB,SAASC,QAAAA;EACzB;AACF;AAPgBN;AAShB,IACMI,uBADN,WACMA;;EACJ,YAA6BR,UAAiC;SAAjCA,WAAAA;EAAkC;EAE/DW,UAAUC,SAA2BC,MAAmB;AACtD,WAAOA,KAAKC,OAAM,EAAGC,KACnBzB,WAAW,CAAC0B,cAAAA;AACV,UAAIJ,QAAQK,QAAO,MAAO,QAAQ;AAChC,cAAMC,MAAMN,QAAQO,aAAY;AAChC,cAAMC,MAAMF,IAAIG,YAAW;AAE3B,YAAI,KAAKrB,aAAa,aAAaoB,IAAIE,QAAQ;AAC7CF,cAAIE,OAAOC,cAAcP;QAC3B,WACE,KAAKhB,aAAa,cACjB,CAACgB,UAAUQ,cAAcR,UAAUQ,eAAe,MACnD;AACAJ,cAAIG,cAAcP;QACpB;MACF;AACA,aAAOzB,WAAW,MAAMyB,SAAAA;IAC1B,CAAA,CAAA;EAEJ;AACF,GAvBMR,mCADN;;;;;;;;","names":["Injectable","catchError","throwError","setConsumerFn","useApitally","app","config","httpAdapter","getHttpAdapter","instance","getInstance","platform","name","toLowerCase","includes","setConsumer","apitallyPlugin","register","useGlobalInterceptors","ApitallyInterceptor","request","consumer","intercept","context","next","handle","pipe","exception","getType","ctx","switchToHttp","res","getResponse","locals","serverError","statusCode"]}
1
+ {"version":3,"sources":["../../src/nestjs/index.ts"],"sourcesContent":["import {\n CallHandler,\n ExecutionContext,\n INestApplication,\n Injectable,\n NestInterceptor,\n} from \"@nestjs/common\";\nimport { catchError, throwError } from \"rxjs\";\n\nimport type { ApitallyConfig, ApitallyConsumer } from \"../common/types.js\";\nexport { ApitallySpanProcessor } from \"../common/spanCollector.js\";\nexport type { ApitallyConfig, ApitallyConsumer } from \"../common/types.js\";\n\nlet setConsumerFn:\n | ((\n request: any,\n consumer: ApitallyConsumer | string | null | undefined,\n ) => void)\n | null = null;\n\nexport async function useApitally(\n app: INestApplication,\n config: ApitallyConfig,\n) {\n const httpAdapter = app.getHttpAdapter();\n const instance = httpAdapter.getInstance();\n const platform = httpAdapter.constructor.name\n .toLowerCase()\n .includes(\"fastify\")\n ? \"fastify\"\n : \"express\";\n\n if (platform === \"express\") {\n const { useApitally, setConsumer } = await import(\"../express/index.js\");\n setConsumerFn = setConsumer;\n useApitally(instance, config);\n } else if (platform === \"fastify\") {\n const { apitallyPlugin, setConsumer } = await import(\"../fastify/index.js\");\n setConsumerFn = setConsumer;\n await instance.register(apitallyPlugin, config);\n }\n\n app.useGlobalInterceptors(new ApitallyInterceptor(platform));\n}\n\nexport function setConsumer(\n request: any,\n consumer: ApitallyConsumer | string | null | undefined,\n) {\n if (setConsumerFn) {\n setConsumerFn(request, consumer);\n }\n}\n\n@Injectable()\nclass ApitallyInterceptor implements NestInterceptor {\n constructor(private readonly platform: \"express\" | \"fastify\") {}\n\n intercept(context: ExecutionContext, next: CallHandler) {\n return next.handle().pipe(\n catchError((exception) => {\n if (context.getType() === \"http\") {\n const ctx = context.switchToHttp();\n const res = ctx.getResponse();\n\n if (this.platform === \"express\" && res.locals) {\n res.locals.serverError = exception;\n } else if (\n this.platform === \"fastify\" &&\n (!exception.statusCode || exception.statusCode === 500)\n ) {\n res.serverError = exception;\n }\n }\n return throwError(() => exception);\n }),\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;AAAA,SAIEA,kBAEK;AACP,SAASC,YAAYC,kBAAkB;AAGvC,SAASC,6BAA6B;AAGtC,IAAIC,gBAKO;AAEX,eAAsBC,YACpBC,KACAC,QAAsB;AAEtB,QAAMC,cAAcF,IAAIG,eAAc;AACtC,QAAMC,WAAWF,YAAYG,YAAW;AACxC,QAAMC,WAAWJ,YAAY,YAAYK,KACtCC,YAAW,EACXC,SAAS,SAAA,IACR,YACA;AAEJ,MAAIH,aAAa,WAAW;AAC1B,UAAM,EAAEP,aAAAA,cAAaW,aAAAA,aAAW,IAAK,MAAM,OAAO,qBAAA;AAClDZ,oBAAgBY;AAChBX,IAAAA,aAAYK,UAAUH,MAAAA;EACxB,WAAWK,aAAa,WAAW;AACjC,UAAM,EAAEK,gBAAgBD,aAAAA,aAAW,IAAK,MAAM,OAAO,qBAAA;AACrDZ,oBAAgBY;AAChB,UAAMN,SAASQ,SAASD,gBAAgBV,MAAAA;EAC1C;AAEAD,MAAIa,sBAAsB,IAAIC,oBAAoBR,QAAAA,CAAAA;AACpD;AAvBsBP;AAyBf,SAASW,YACdK,SACAC,UAAsD;AAEtD,MAAIlB,eAAe;AACjBA,kBAAciB,SAASC,QAAAA;EACzB;AACF;AAPgBN;AAShB,IACMI,uBADN,WACMA;;EACJ,YAA6BR,UAAiC;SAAjCA,WAAAA;EAAkC;EAE/DW,UAAUC,SAA2BC,MAAmB;AACtD,WAAOA,KAAKC,OAAM,EAAGC,KACnB1B,WAAW,CAAC2B,cAAAA;AACV,UAAIJ,QAAQK,QAAO,MAAO,QAAQ;AAChC,cAAMC,MAAMN,QAAQO,aAAY;AAChC,cAAMC,MAAMF,IAAIG,YAAW;AAE3B,YAAI,KAAKrB,aAAa,aAAaoB,IAAIE,QAAQ;AAC7CF,cAAIE,OAAOC,cAAcP;QAC3B,WACE,KAAKhB,aAAa,cACjB,CAACgB,UAAUQ,cAAcR,UAAUQ,eAAe,MACnD;AACAJ,cAAIG,cAAcP;QACpB;MACF;AACA,aAAO1B,WAAW,MAAM0B,SAAAA;IAC1B,CAAA,CAAA;EAEJ;AACF,GAvBMR,mCADN;;;;;;;;","names":["Injectable","catchError","throwError","ApitallySpanProcessor","setConsumerFn","useApitally","app","config","httpAdapter","getHttpAdapter","instance","getInstance","platform","name","toLowerCase","includes","setConsumer","apitallyPlugin","register","useGlobalInterceptors","ApitallyInterceptor","request","consumer","intercept","context","next","handle","pipe","exception","getType","ctx","switchToHttp","res","getResponse","locals","serverError","statusCode"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apitally",
3
- "version": "0.23.1",
3
+ "version": "0.25.0",
4
4
  "description": "Simple API monitoring & analytics for REST APIs built with Express, Fastify, NestJS, AdonisJS, Hono, H3, Elysia, Hapi, and Koa.",
5
5
  "author": "Apitally <hello@apitally.io>",
6
6
  "license": "MIT",
@@ -203,6 +203,9 @@
203
203
  "printWidth": 80
204
204
  },
205
205
  "dependencies": {
206
+ "@opentelemetry/api": "^1.9.0",
207
+ "@opentelemetry/context-async-hooks": "^2.0.0",
208
+ "@opentelemetry/sdk-trace-base": "^2.0.0",
206
209
  "async-lock": "^1",
207
210
  "fetch-retry": "^6",
208
211
  "winston": "^3"
@@ -305,8 +308,8 @@
305
308
  "express-validator": "^7.2.1",
306
309
  "fastify": "^5.0.0",
307
310
  "fastify-plugin": "^5.0.1",
308
- "globals": "^16.2.0",
309
- "h3": "2.0.1-rc.5",
311
+ "globals": "^17.0.0",
312
+ "h3": "2.0.1-rc.8",
310
313
  "hono": "^4.6.5",
311
314
  "koa": "^3.0.0",
312
315
  "koa-bodyparser": "^4.4.1",