apitally 0.23.1 → 0.24.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 (49) hide show
  1. package/dist/common/client.cjs +2 -1
  2. package/dist/common/client.cjs.map +1 -1
  3. package/dist/common/client.js +2 -1
  4. package/dist/common/client.js.map +1 -1
  5. package/dist/common/instance.cjs +158 -0
  6. package/dist/common/instance.cjs.map +1 -0
  7. package/dist/common/instance.d.cts +4 -0
  8. package/dist/common/instance.d.ts +4 -0
  9. package/dist/common/instance.js +134 -0
  10. package/dist/common/instance.js.map +1 -0
  11. package/dist/common/requestLogger.cjs +12 -17
  12. package/dist/common/requestLogger.cjs.map +1 -1
  13. package/dist/common/requestLogger.js +12 -17
  14. package/dist/common/requestLogger.js.map +1 -1
  15. package/dist/common/response.cjs +2 -2
  16. package/dist/common/response.cjs.map +1 -1
  17. package/dist/common/response.js +2 -2
  18. package/dist/common/response.js.map +1 -1
  19. package/dist/common/serverErrorCounter.cjs +3 -0
  20. package/dist/common/serverErrorCounter.cjs.map +1 -1
  21. package/dist/common/serverErrorCounter.js +3 -0
  22. package/dist/common/serverErrorCounter.js.map +1 -1
  23. package/dist/common/tempGzipFile.cjs +25 -2
  24. package/dist/common/tempGzipFile.cjs.map +1 -1
  25. package/dist/common/tempGzipFile.d.cts +3 -2
  26. package/dist/common/tempGzipFile.d.ts +3 -2
  27. package/dist/common/tempGzipFile.js +22 -3
  28. package/dist/common/tempGzipFile.js.map +1 -1
  29. package/dist/elysia/plugin.cjs +7 -7
  30. package/dist/elysia/plugin.cjs.map +1 -1
  31. package/dist/elysia/plugin.js +7 -7
  32. package/dist/elysia/plugin.js.map +1 -1
  33. package/dist/fastify/plugin.cjs +2 -2
  34. package/dist/fastify/plugin.cjs.map +1 -1
  35. package/dist/fastify/plugin.js +2 -2
  36. package/dist/fastify/plugin.js.map +1 -1
  37. package/dist/h3/plugin.cjs +2 -2
  38. package/dist/h3/plugin.cjs.map +1 -1
  39. package/dist/h3/plugin.js +2 -2
  40. package/dist/h3/plugin.js.map +1 -1
  41. package/dist/hapi/plugin.cjs +6 -6
  42. package/dist/hapi/plugin.cjs.map +1 -1
  43. package/dist/hapi/plugin.js +6 -6
  44. package/dist/hapi/plugin.js.map +1 -1
  45. package/dist/loggers/pino.cjs +1 -1
  46. package/dist/loggers/pino.cjs.map +1 -1
  47. package/dist/loggers/pino.js +1 -1
  48. package/dist/loggers/pino.js.map +1 -1
  49. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/h3/plugin.ts"],"sourcesContent":["import type { H3Event, HTTPError } from \"h3\";\nimport { definePlugin, onError, onRequest, onResponse } from \"h3\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { performance } from \"node:perf_hooks\";\nimport type { ZodError } from \"zod\";\n\nimport { ApitallyClient } from \"../common/client.js\";\nimport { consumerFromStringOrObject } from \"../common/consumerRegistry.js\";\nimport { mergeHeaders, parseContentLength } from \"../common/headers.js\";\nimport type { LogRecord } from \"../common/requestLogger.js\";\nimport { convertHeaders } from \"../common/requestLogger.js\";\nimport { captureResponse } from \"../common/response.js\";\nimport { ApitallyConfig, ApitallyConsumer } from \"../common/types.js\";\nimport { patchConsole, patchWinston } from \"../loggers/index.js\";\nimport { getAppInfo } from \"./utils.js\";\n\nconst REQUEST_TIMESTAMP_SYMBOL = Symbol(\"apitally.requestTimestamp\");\nconst REQUEST_BODY_SYMBOL = Symbol(\"apitally.requestBody\");\n\ndeclare module \"h3\" {\n interface H3EventContext {\n apitallyConsumer?: ApitallyConsumer | string;\n\n [REQUEST_TIMESTAMP_SYMBOL]?: number;\n [REQUEST_BODY_SYMBOL]?: Buffer;\n }\n}\n\nconst jsonHeaders = new Headers({\n \"content-type\": \"application/json;charset=UTF-8\",\n});\n\nexport const apitallyPlugin = definePlugin<ApitallyConfig>((app, config) => {\n const client = new ApitallyClient(config);\n const logsContext = new AsyncLocalStorage<LogRecord[]>();\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 if (client.requestLogger.config.captureLogs) {\n patchConsole(logsContext);\n patchWinston(logsContext);\n }\n\n const handleResponse = async (\n event: H3Event,\n response?: Response,\n error?: HTTPError,\n ) => {\n if (event.req.method.toUpperCase() === \"OPTIONS\") {\n return response;\n }\n\n const startTime = event.context[REQUEST_TIMESTAMP_SYMBOL];\n const path = event.context.matchedRoute?.route;\n\n const consumer = getConsumer(event);\n client.consumerRegistry.addOrUpdateConsumer(consumer);\n\n if (!response) {\n response = new Response(null, {\n status: error?.status || 500,\n statusText: error?.statusText || \"Internal Server Error\",\n headers: error?.headers\n ? mergeHeaders(jsonHeaders, error.headers)\n : jsonHeaders,\n });\n }\n\n const [newResponse, responsePromise] = captureResponse(response, {\n captureBody:\n client.requestLogger.enabled &&\n client.requestLogger.config.logResponseBody,\n maxBodySize: client.requestLogger.maxBodySize,\n });\n\n responsePromise.then(async (capturedResponse) => {\n const responseTime = startTime ? performance.now() - startTime : 0;\n const responseSize = capturedResponse.completed\n ? capturedResponse.size\n : undefined;\n const requestSize = parseContentLength(\n event.req.headers.get(\"content-length\"),\n );\n\n if (path) {\n client.requestCounter.addRequest({\n consumer: consumer?.identifier,\n method: event.req.method,\n path,\n statusCode: response.status,\n responseTime,\n requestSize,\n responseSize,\n });\n }\n\n if (client.requestLogger.enabled) {\n const logs = logsContext.getStore();\n client.requestLogger.logRequest(\n {\n timestamp: (Date.now() - responseTime) / 1000,\n method: event.req.method,\n path,\n url: event.req.url,\n headers: convertHeaders(\n Object.fromEntries(event.req.headers.entries()),\n ),\n size: requestSize,\n consumer: consumer?.identifier,\n body: event.context[REQUEST_BODY_SYMBOL],\n },\n {\n statusCode: response.status,\n responseTime: responseTime / 1000,\n headers: convertHeaders(\n Object.fromEntries(response.headers.entries()),\n ),\n size: responseSize,\n body: capturedResponse.body,\n },\n error?.cause instanceof Error ? error.cause : undefined,\n logs,\n );\n }\n });\n\n if (\n path &&\n error?.status === 400 &&\n error.data &&\n (error.data as any).name === \"ZodError\"\n ) {\n const zodError = error.data as ZodError;\n zodError.issues?.forEach((issue) => {\n client.validationErrorCounter.addValidationError({\n consumer: consumer?.identifier,\n method: event.req.method,\n path,\n loc: issue.path.join(\".\"),\n msg: issue.message,\n type: issue.code,\n });\n });\n }\n\n if (path && error?.status === 500 && error.cause instanceof Error) {\n client.serverErrorCounter.addServerError({\n consumer: consumer?.identifier,\n method: event.req.method,\n path,\n type: error.cause.name,\n msg: error.cause.message,\n traceback: error.cause.stack || \"\",\n });\n }\n\n return newResponse;\n };\n\n app\n .use(\n onRequest(async (event) => {\n logsContext.enterWith([]);\n event.context[REQUEST_TIMESTAMP_SYMBOL] = performance.now();\n const requestContentType = event.req.headers.get(\"content-type\");\n const requestSize =\n parseContentLength(event.req.headers.get(\"content-length\")) ?? 0;\n\n if (\n client.requestLogger.enabled &&\n client.requestLogger.config.logRequestBody &&\n client.requestLogger.isSupportedContentType(requestContentType) &&\n requestSize <= client.requestLogger.maxBodySize\n ) {\n const clonedRequest = event.req.clone();\n const requestBody = Buffer.from(await clonedRequest.arrayBuffer());\n event.context[REQUEST_BODY_SYMBOL] = requestBody;\n }\n }),\n )\n .use(\n onResponse((response, event) => {\n if (client.isEnabled()) {\n return handleResponse(event, response, undefined);\n }\n }),\n )\n .use(\n onError((error, event) => {\n if (client.isEnabled()) {\n handleResponse(event, undefined, error);\n }\n }),\n );\n});\n\nexport function setConsumer(\n event: H3Event,\n consumer: ApitallyConsumer | string | null | undefined,\n) {\n event.context.apitallyConsumer = consumer || undefined;\n}\n\nfunction getConsumer(event: H3Event) {\n const consumer = event.context.apitallyConsumer;\n if (consumer) {\n return consumerFromStringOrObject(consumer);\n }\n return null;\n}\n"],"mappings":"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","names":["REQUEST_TIMESTAMP_SYMBOL","Symbol","REQUEST_BODY_SYMBOL","jsonHeaders","Headers","apitallyPlugin","definePlugin","app","config","client","ApitallyClient","logsContext","AsyncLocalStorage","setStartupData","attempt","appInfo","getAppInfo","appVersion","paths","length","startSync","setTimeout","requestLogger","captureLogs","patchConsole","patchWinston","handleResponse","event","response","error","req","method","toUpperCase","startTime","context","path","matchedRoute","route","consumer","getConsumer","consumerRegistry","addOrUpdateConsumer","Response","status","statusText","headers","mergeHeaders","newResponse","responsePromise","captureResponse","captureBody","enabled","logResponseBody","maxBodySize","then","capturedResponse","responseTime","performance","now","responseSize","completed","size","undefined","requestSize","parseContentLength","get","requestCounter","addRequest","identifier","statusCode","logs","getStore","logRequest","timestamp","Date","url","convertHeaders","Object","fromEntries","entries","body","cause","Error","data","name","zodError","issues","forEach","issue","validationErrorCounter","addValidationError","loc","join","msg","message","type","code","serverErrorCounter","addServerError","traceback","stack","use","onRequest","enterWith","requestContentType","logRequestBody","isSupportedContentType","clonedRequest","clone","requestBody","Buffer","from","arrayBuffer","onResponse","isEnabled","onError","setConsumer","apitallyConsumer","consumerFromStringOrObject"]}
1
+ {"version":3,"sources":["../../src/h3/plugin.ts"],"sourcesContent":["import type { H3Event, HTTPError } from \"h3\";\nimport { definePlugin, onError, onRequest, onResponse } from \"h3\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { performance } from \"node:perf_hooks\";\nimport type { ZodError } from \"zod\";\n\nimport { ApitallyClient } from \"../common/client.js\";\nimport { consumerFromStringOrObject } from \"../common/consumerRegistry.js\";\nimport { mergeHeaders, parseContentLength } from \"../common/headers.js\";\nimport type { LogRecord } from \"../common/requestLogger.js\";\nimport { convertHeaders } from \"../common/requestLogger.js\";\nimport { captureResponse } from \"../common/response.js\";\nimport { ApitallyConfig, ApitallyConsumer } from \"../common/types.js\";\nimport { patchConsole, patchWinston } from \"../loggers/index.js\";\nimport { getAppInfo } from \"./utils.js\";\n\nconst REQUEST_TIMESTAMP_SYMBOL = Symbol(\"apitally.requestTimestamp\");\nconst REQUEST_BODY_SYMBOL = Symbol(\"apitally.requestBody\");\n\ndeclare module \"h3\" {\n interface H3EventContext {\n apitallyConsumer?: ApitallyConsumer | string;\n\n [REQUEST_TIMESTAMP_SYMBOL]?: number;\n [REQUEST_BODY_SYMBOL]?: Buffer;\n }\n}\n\nconst jsonHeaders = new Headers({\n \"content-type\": \"application/json;charset=UTF-8\",\n});\n\nexport const apitallyPlugin = definePlugin<ApitallyConfig>((app, config) => {\n const client = new ApitallyClient(config);\n const logsContext = new AsyncLocalStorage<LogRecord[]>();\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 if (client.requestLogger.config.captureLogs) {\n patchConsole(logsContext);\n patchWinston(logsContext);\n }\n\n const handleResponse = async (\n event: H3Event,\n response?: Response,\n error?: HTTPError,\n ) => {\n if (event.req.method.toUpperCase() === \"OPTIONS\") {\n return response;\n }\n\n const startTime = event.context[REQUEST_TIMESTAMP_SYMBOL];\n const path = event.context.matchedRoute?.route;\n\n const consumer = getConsumer(event);\n client.consumerRegistry.addOrUpdateConsumer(consumer);\n\n if (!response) {\n response = new Response(null, {\n status: error?.status || 500,\n statusText: error?.statusText || \"Internal Server Error\",\n headers: error?.headers\n ? mergeHeaders(jsonHeaders, error.headers)\n : jsonHeaders,\n });\n }\n\n const [newResponse, responsePromise] = captureResponse(response, {\n captureBody:\n client.requestLogger.enabled &&\n client.requestLogger.config.logResponseBody,\n maxBodySize: client.requestLogger.maxBodySize,\n });\n\n responsePromise.then(async (capturedResponse) => {\n const responseTime = startTime ? performance.now() - startTime : 0;\n const responseSize = capturedResponse.completed\n ? capturedResponse.size\n : undefined;\n const requestSize = parseContentLength(\n event.req.headers.get(\"content-length\"),\n );\n\n if (path) {\n client.requestCounter.addRequest({\n consumer: consumer?.identifier,\n method: event.req.method,\n path,\n statusCode: response.status,\n responseTime,\n requestSize,\n responseSize,\n });\n }\n\n if (client.requestLogger.enabled) {\n const logs = logsContext.getStore();\n client.requestLogger.logRequest(\n {\n timestamp: (Date.now() - responseTime) / 1000,\n method: event.req.method,\n path,\n url: event.req.url,\n headers: convertHeaders(\n Object.fromEntries(event.req.headers.entries()),\n ),\n size: requestSize,\n consumer: consumer?.identifier,\n body: event.context[REQUEST_BODY_SYMBOL],\n },\n {\n statusCode: response.status,\n responseTime: responseTime / 1000,\n headers: convertHeaders(\n Object.fromEntries(response.headers.entries()),\n ),\n size: responseSize,\n body: capturedResponse.body,\n },\n error?.cause instanceof Error ? error.cause : undefined,\n logs,\n );\n }\n });\n\n if (\n path &&\n error?.status === 400 &&\n error.data &&\n (error.data as any).name === \"ZodError\"\n ) {\n const zodError = error.data as ZodError;\n zodError.issues?.forEach((issue) => {\n client.validationErrorCounter.addValidationError({\n consumer: consumer?.identifier,\n method: event.req.method,\n path,\n loc: issue.path.join(\".\"),\n msg: issue.message,\n type: issue.code,\n });\n });\n }\n\n if (path && error?.status === 500 && error.cause instanceof Error) {\n client.serverErrorCounter.addServerError({\n consumer: consumer?.identifier,\n method: event.req.method,\n path,\n type: error.cause.name,\n msg: error.cause.message,\n traceback: error.cause.stack || \"\",\n });\n }\n\n return newResponse;\n };\n\n app\n .use(\n onRequest(async (event) => {\n logsContext.enterWith([]);\n event.context[REQUEST_TIMESTAMP_SYMBOL] = performance.now();\n const requestContentType = event.req.headers.get(\"content-type\");\n const requestSize =\n parseContentLength(event.req.headers.get(\"content-length\")) ?? 0;\n\n if (\n client.requestLogger.enabled &&\n client.requestLogger.config.logRequestBody &&\n client.requestLogger.isSupportedContentType(requestContentType) &&\n requestSize <= client.requestLogger.maxBodySize\n ) {\n const clonedRequest = event.req.clone();\n const requestBody = Buffer.from(await clonedRequest.arrayBuffer());\n event.context[REQUEST_BODY_SYMBOL] = requestBody;\n }\n }),\n )\n .use(\n onResponse((response, event) => {\n if (client.isEnabled()) {\n return handleResponse(event, response, undefined);\n }\n }),\n )\n .use(\n onError((error, event) => {\n if (client.isEnabled()) {\n handleResponse(event, undefined, error);\n }\n }),\n );\n});\n\nexport function setConsumer(\n event: H3Event,\n consumer: ApitallyConsumer | string | null | undefined,\n) {\n event.context.apitallyConsumer = consumer || undefined;\n}\n\nfunction getConsumer(event: H3Event) {\n const consumer = event.context.apitallyConsumer;\n if (consumer) {\n return consumerFromStringOrObject(consumer);\n }\n return null;\n}\n"],"mappings":"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","names":["REQUEST_TIMESTAMP_SYMBOL","Symbol","REQUEST_BODY_SYMBOL","jsonHeaders","Headers","apitallyPlugin","definePlugin","app","config","client","ApitallyClient","logsContext","AsyncLocalStorage","setStartupData","attempt","appInfo","getAppInfo","appVersion","paths","length","startSync","setTimeout","requestLogger","captureLogs","patchConsole","patchWinston","handleResponse","event","response","error","req","method","toUpperCase","startTime","context","path","matchedRoute","route","consumer","getConsumer","consumerRegistry","addOrUpdateConsumer","Response","status","statusText","headers","mergeHeaders","newResponse","responsePromise","captureResponse","captureBody","enabled","logResponseBody","maxBodySize","then","capturedResponse","responseTime","performance","now","responseSize","completed","size","undefined","requestSize","parseContentLength","get","requestCounter","addRequest","identifier","statusCode","logs","getStore","logRequest","timestamp","Date","url","convertHeaders","Object","fromEntries","entries","body","cause","Error","data","name","zodError","issues","forEach","issue","validationErrorCounter","addValidationError","loc","join","msg","message","type","code","serverErrorCounter","addServerError","traceback","stack","use","onRequest","enterWith","requestContentType","logRequestBody","isSupportedContentType","clonedRequest","clone","requestBody","Buffer","from","arrayBuffer","onResponse","isEnabled","onError","setConsumer","apitallyConsumer","consumerFromStringOrObject"]}
package/dist/h3/plugin.js CHANGED
@@ -10,8 +10,8 @@ import { convertHeaders } from "../common/requestLogger.js";
10
10
  import { captureResponse } from "../common/response.js";
11
11
  import { patchConsole, patchWinston } from "../loggers/index.js";
12
12
  import { getAppInfo } from "./utils.js";
13
- const REQUEST_TIMESTAMP_SYMBOL = Symbol("apitally.requestTimestamp");
14
- const REQUEST_BODY_SYMBOL = Symbol("apitally.requestBody");
13
+ const REQUEST_TIMESTAMP_SYMBOL = /* @__PURE__ */ Symbol("apitally.requestTimestamp");
14
+ const REQUEST_BODY_SYMBOL = /* @__PURE__ */ Symbol("apitally.requestBody");
15
15
  const jsonHeaders = new Headers({
16
16
  "content-type": "application/json;charset=UTF-8"
17
17
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/h3/plugin.ts"],"sourcesContent":["import type { H3Event, HTTPError } from \"h3\";\nimport { definePlugin, onError, onRequest, onResponse } from \"h3\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { performance } from \"node:perf_hooks\";\nimport type { ZodError } from \"zod\";\n\nimport { ApitallyClient } from \"../common/client.js\";\nimport { consumerFromStringOrObject } from \"../common/consumerRegistry.js\";\nimport { mergeHeaders, parseContentLength } from \"../common/headers.js\";\nimport type { LogRecord } from \"../common/requestLogger.js\";\nimport { convertHeaders } from \"../common/requestLogger.js\";\nimport { captureResponse } from \"../common/response.js\";\nimport { ApitallyConfig, ApitallyConsumer } from \"../common/types.js\";\nimport { patchConsole, patchWinston } from \"../loggers/index.js\";\nimport { getAppInfo } from \"./utils.js\";\n\nconst REQUEST_TIMESTAMP_SYMBOL = Symbol(\"apitally.requestTimestamp\");\nconst REQUEST_BODY_SYMBOL = Symbol(\"apitally.requestBody\");\n\ndeclare module \"h3\" {\n interface H3EventContext {\n apitallyConsumer?: ApitallyConsumer | string;\n\n [REQUEST_TIMESTAMP_SYMBOL]?: number;\n [REQUEST_BODY_SYMBOL]?: Buffer;\n }\n}\n\nconst jsonHeaders = new Headers({\n \"content-type\": \"application/json;charset=UTF-8\",\n});\n\nexport const apitallyPlugin = definePlugin<ApitallyConfig>((app, config) => {\n const client = new ApitallyClient(config);\n const logsContext = new AsyncLocalStorage<LogRecord[]>();\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 if (client.requestLogger.config.captureLogs) {\n patchConsole(logsContext);\n patchWinston(logsContext);\n }\n\n const handleResponse = async (\n event: H3Event,\n response?: Response,\n error?: HTTPError,\n ) => {\n if (event.req.method.toUpperCase() === \"OPTIONS\") {\n return response;\n }\n\n const startTime = event.context[REQUEST_TIMESTAMP_SYMBOL];\n const path = event.context.matchedRoute?.route;\n\n const consumer = getConsumer(event);\n client.consumerRegistry.addOrUpdateConsumer(consumer);\n\n if (!response) {\n response = new Response(null, {\n status: error?.status || 500,\n statusText: error?.statusText || \"Internal Server Error\",\n headers: error?.headers\n ? mergeHeaders(jsonHeaders, error.headers)\n : jsonHeaders,\n });\n }\n\n const [newResponse, responsePromise] = captureResponse(response, {\n captureBody:\n client.requestLogger.enabled &&\n client.requestLogger.config.logResponseBody,\n maxBodySize: client.requestLogger.maxBodySize,\n });\n\n responsePromise.then(async (capturedResponse) => {\n const responseTime = startTime ? performance.now() - startTime : 0;\n const responseSize = capturedResponse.completed\n ? capturedResponse.size\n : undefined;\n const requestSize = parseContentLength(\n event.req.headers.get(\"content-length\"),\n );\n\n if (path) {\n client.requestCounter.addRequest({\n consumer: consumer?.identifier,\n method: event.req.method,\n path,\n statusCode: response.status,\n responseTime,\n requestSize,\n responseSize,\n });\n }\n\n if (client.requestLogger.enabled) {\n const logs = logsContext.getStore();\n client.requestLogger.logRequest(\n {\n timestamp: (Date.now() - responseTime) / 1000,\n method: event.req.method,\n path,\n url: event.req.url,\n headers: convertHeaders(\n Object.fromEntries(event.req.headers.entries()),\n ),\n size: requestSize,\n consumer: consumer?.identifier,\n body: event.context[REQUEST_BODY_SYMBOL],\n },\n {\n statusCode: response.status,\n responseTime: responseTime / 1000,\n headers: convertHeaders(\n Object.fromEntries(response.headers.entries()),\n ),\n size: responseSize,\n body: capturedResponse.body,\n },\n error?.cause instanceof Error ? error.cause : undefined,\n logs,\n );\n }\n });\n\n if (\n path &&\n error?.status === 400 &&\n error.data &&\n (error.data as any).name === \"ZodError\"\n ) {\n const zodError = error.data as ZodError;\n zodError.issues?.forEach((issue) => {\n client.validationErrorCounter.addValidationError({\n consumer: consumer?.identifier,\n method: event.req.method,\n path,\n loc: issue.path.join(\".\"),\n msg: issue.message,\n type: issue.code,\n });\n });\n }\n\n if (path && error?.status === 500 && error.cause instanceof Error) {\n client.serverErrorCounter.addServerError({\n consumer: consumer?.identifier,\n method: event.req.method,\n path,\n type: error.cause.name,\n msg: error.cause.message,\n traceback: error.cause.stack || \"\",\n });\n }\n\n return newResponse;\n };\n\n app\n .use(\n onRequest(async (event) => {\n logsContext.enterWith([]);\n event.context[REQUEST_TIMESTAMP_SYMBOL] = performance.now();\n const requestContentType = event.req.headers.get(\"content-type\");\n const requestSize =\n parseContentLength(event.req.headers.get(\"content-length\")) ?? 0;\n\n if (\n client.requestLogger.enabled &&\n client.requestLogger.config.logRequestBody &&\n client.requestLogger.isSupportedContentType(requestContentType) &&\n requestSize <= client.requestLogger.maxBodySize\n ) {\n const clonedRequest = event.req.clone();\n const requestBody = Buffer.from(await clonedRequest.arrayBuffer());\n event.context[REQUEST_BODY_SYMBOL] = requestBody;\n }\n }),\n )\n .use(\n onResponse((response, event) => {\n if (client.isEnabled()) {\n return handleResponse(event, response, undefined);\n }\n }),\n )\n .use(\n onError((error, event) => {\n if (client.isEnabled()) {\n handleResponse(event, undefined, error);\n }\n }),\n );\n});\n\nexport function setConsumer(\n event: H3Event,\n consumer: ApitallyConsumer | string | null | undefined,\n) {\n event.context.apitallyConsumer = consumer || undefined;\n}\n\nfunction getConsumer(event: H3Event) {\n const consumer = event.context.apitallyConsumer;\n if (consumer) {\n return consumerFromStringOrObject(consumer);\n }\n return null;\n}\n"],"mappings":"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","names":["definePlugin","onError","onRequest","onResponse","AsyncLocalStorage","performance","ApitallyClient","consumerFromStringOrObject","mergeHeaders","parseContentLength","convertHeaders","captureResponse","patchConsole","patchWinston","getAppInfo","REQUEST_TIMESTAMP_SYMBOL","Symbol","REQUEST_BODY_SYMBOL","jsonHeaders","Headers","apitallyPlugin","app","config","client","logsContext","setStartupData","attempt","appInfo","appVersion","paths","length","startSync","setTimeout","requestLogger","captureLogs","handleResponse","event","response","error","req","method","toUpperCase","startTime","context","path","matchedRoute","route","consumer","getConsumer","consumerRegistry","addOrUpdateConsumer","Response","status","statusText","headers","newResponse","responsePromise","captureBody","enabled","logResponseBody","maxBodySize","then","capturedResponse","responseTime","now","responseSize","completed","size","undefined","requestSize","get","requestCounter","addRequest","identifier","statusCode","logs","getStore","logRequest","timestamp","Date","url","Object","fromEntries","entries","body","cause","Error","data","name","zodError","issues","forEach","issue","validationErrorCounter","addValidationError","loc","join","msg","message","type","code","serverErrorCounter","addServerError","traceback","stack","use","enterWith","requestContentType","logRequestBody","isSupportedContentType","clonedRequest","clone","requestBody","Buffer","from","arrayBuffer","isEnabled","setConsumer","apitallyConsumer"]}
1
+ {"version":3,"sources":["../../src/h3/plugin.ts"],"sourcesContent":["import type { H3Event, HTTPError } from \"h3\";\nimport { definePlugin, onError, onRequest, onResponse } from \"h3\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { performance } from \"node:perf_hooks\";\nimport type { ZodError } from \"zod\";\n\nimport { ApitallyClient } from \"../common/client.js\";\nimport { consumerFromStringOrObject } from \"../common/consumerRegistry.js\";\nimport { mergeHeaders, parseContentLength } from \"../common/headers.js\";\nimport type { LogRecord } from \"../common/requestLogger.js\";\nimport { convertHeaders } from \"../common/requestLogger.js\";\nimport { captureResponse } from \"../common/response.js\";\nimport { ApitallyConfig, ApitallyConsumer } from \"../common/types.js\";\nimport { patchConsole, patchWinston } from \"../loggers/index.js\";\nimport { getAppInfo } from \"./utils.js\";\n\nconst REQUEST_TIMESTAMP_SYMBOL = Symbol(\"apitally.requestTimestamp\");\nconst REQUEST_BODY_SYMBOL = Symbol(\"apitally.requestBody\");\n\ndeclare module \"h3\" {\n interface H3EventContext {\n apitallyConsumer?: ApitallyConsumer | string;\n\n [REQUEST_TIMESTAMP_SYMBOL]?: number;\n [REQUEST_BODY_SYMBOL]?: Buffer;\n }\n}\n\nconst jsonHeaders = new Headers({\n \"content-type\": \"application/json;charset=UTF-8\",\n});\n\nexport const apitallyPlugin = definePlugin<ApitallyConfig>((app, config) => {\n const client = new ApitallyClient(config);\n const logsContext = new AsyncLocalStorage<LogRecord[]>();\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 if (client.requestLogger.config.captureLogs) {\n patchConsole(logsContext);\n patchWinston(logsContext);\n }\n\n const handleResponse = async (\n event: H3Event,\n response?: Response,\n error?: HTTPError,\n ) => {\n if (event.req.method.toUpperCase() === \"OPTIONS\") {\n return response;\n }\n\n const startTime = event.context[REQUEST_TIMESTAMP_SYMBOL];\n const path = event.context.matchedRoute?.route;\n\n const consumer = getConsumer(event);\n client.consumerRegistry.addOrUpdateConsumer(consumer);\n\n if (!response) {\n response = new Response(null, {\n status: error?.status || 500,\n statusText: error?.statusText || \"Internal Server Error\",\n headers: error?.headers\n ? mergeHeaders(jsonHeaders, error.headers)\n : jsonHeaders,\n });\n }\n\n const [newResponse, responsePromise] = captureResponse(response, {\n captureBody:\n client.requestLogger.enabled &&\n client.requestLogger.config.logResponseBody,\n maxBodySize: client.requestLogger.maxBodySize,\n });\n\n responsePromise.then(async (capturedResponse) => {\n const responseTime = startTime ? performance.now() - startTime : 0;\n const responseSize = capturedResponse.completed\n ? capturedResponse.size\n : undefined;\n const requestSize = parseContentLength(\n event.req.headers.get(\"content-length\"),\n );\n\n if (path) {\n client.requestCounter.addRequest({\n consumer: consumer?.identifier,\n method: event.req.method,\n path,\n statusCode: response.status,\n responseTime,\n requestSize,\n responseSize,\n });\n }\n\n if (client.requestLogger.enabled) {\n const logs = logsContext.getStore();\n client.requestLogger.logRequest(\n {\n timestamp: (Date.now() - responseTime) / 1000,\n method: event.req.method,\n path,\n url: event.req.url,\n headers: convertHeaders(\n Object.fromEntries(event.req.headers.entries()),\n ),\n size: requestSize,\n consumer: consumer?.identifier,\n body: event.context[REQUEST_BODY_SYMBOL],\n },\n {\n statusCode: response.status,\n responseTime: responseTime / 1000,\n headers: convertHeaders(\n Object.fromEntries(response.headers.entries()),\n ),\n size: responseSize,\n body: capturedResponse.body,\n },\n error?.cause instanceof Error ? error.cause : undefined,\n logs,\n );\n }\n });\n\n if (\n path &&\n error?.status === 400 &&\n error.data &&\n (error.data as any).name === \"ZodError\"\n ) {\n const zodError = error.data as ZodError;\n zodError.issues?.forEach((issue) => {\n client.validationErrorCounter.addValidationError({\n consumer: consumer?.identifier,\n method: event.req.method,\n path,\n loc: issue.path.join(\".\"),\n msg: issue.message,\n type: issue.code,\n });\n });\n }\n\n if (path && error?.status === 500 && error.cause instanceof Error) {\n client.serverErrorCounter.addServerError({\n consumer: consumer?.identifier,\n method: event.req.method,\n path,\n type: error.cause.name,\n msg: error.cause.message,\n traceback: error.cause.stack || \"\",\n });\n }\n\n return newResponse;\n };\n\n app\n .use(\n onRequest(async (event) => {\n logsContext.enterWith([]);\n event.context[REQUEST_TIMESTAMP_SYMBOL] = performance.now();\n const requestContentType = event.req.headers.get(\"content-type\");\n const requestSize =\n parseContentLength(event.req.headers.get(\"content-length\")) ?? 0;\n\n if (\n client.requestLogger.enabled &&\n client.requestLogger.config.logRequestBody &&\n client.requestLogger.isSupportedContentType(requestContentType) &&\n requestSize <= client.requestLogger.maxBodySize\n ) {\n const clonedRequest = event.req.clone();\n const requestBody = Buffer.from(await clonedRequest.arrayBuffer());\n event.context[REQUEST_BODY_SYMBOL] = requestBody;\n }\n }),\n )\n .use(\n onResponse((response, event) => {\n if (client.isEnabled()) {\n return handleResponse(event, response, undefined);\n }\n }),\n )\n .use(\n onError((error, event) => {\n if (client.isEnabled()) {\n handleResponse(event, undefined, error);\n }\n }),\n );\n});\n\nexport function setConsumer(\n event: H3Event,\n consumer: ApitallyConsumer | string | null | undefined,\n) {\n event.context.apitallyConsumer = consumer || undefined;\n}\n\nfunction getConsumer(event: H3Event) {\n const consumer = event.context.apitallyConsumer;\n if (consumer) {\n return consumerFromStringOrObject(consumer);\n }\n return null;\n}\n"],"mappings":"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","names":["definePlugin","onError","onRequest","onResponse","AsyncLocalStorage","performance","ApitallyClient","consumerFromStringOrObject","mergeHeaders","parseContentLength","convertHeaders","captureResponse","patchConsole","patchWinston","getAppInfo","REQUEST_TIMESTAMP_SYMBOL","Symbol","REQUEST_BODY_SYMBOL","jsonHeaders","Headers","apitallyPlugin","app","config","client","logsContext","setStartupData","attempt","appInfo","appVersion","paths","length","startSync","setTimeout","requestLogger","captureLogs","handleResponse","event","response","error","req","method","toUpperCase","startTime","context","path","matchedRoute","route","consumer","getConsumer","consumerRegistry","addOrUpdateConsumer","Response","status","statusText","headers","newResponse","responsePromise","captureBody","enabled","logResponseBody","maxBodySize","then","capturedResponse","responseTime","now","responseSize","completed","size","undefined","requestSize","get","requestCounter","addRequest","identifier","statusCode","logs","getStore","logRequest","timestamp","Date","url","Object","fromEntries","entries","body","cause","Error","data","name","zodError","issues","forEach","issue","validationErrorCounter","addValidationError","loc","join","msg","message","type","code","serverErrorCounter","addServerError","traceback","stack","use","enterWith","requestContentType","logRequestBody","isSupportedContentType","clonedRequest","clone","requestBody","Buffer","from","arrayBuffer","isEnabled","setConsumer","apitallyConsumer"]}
@@ -30,12 +30,12 @@ var import_consumerRegistry = require("../common/consumerRegistry.js");
30
30
  var import_requestLogger = require("../common/requestLogger.js");
31
31
  var import_loggers = require("../loggers/index.js");
32
32
  var import_utils = require("./utils.js");
33
- const START_TIME_SYMBOL = Symbol("apitally.startTime");
34
- const REQUEST_BODY_SYMBOL = Symbol("apitally.requestBody");
35
- const REQUEST_SIZE_SYMBOL = Symbol("apitally.requestSize");
36
- const RESPONSE_BODY_SYMBOL = Symbol("apitally.responseBody");
37
- const RESPONSE_SIZE_SYMBOL = Symbol("apitally.responseSize");
38
- const LOGS_SYMBOL = Symbol("apitally.logs");
33
+ const START_TIME_SYMBOL = /* @__PURE__ */ Symbol("apitally.startTime");
34
+ const REQUEST_BODY_SYMBOL = /* @__PURE__ */ Symbol("apitally.requestBody");
35
+ const REQUEST_SIZE_SYMBOL = /* @__PURE__ */ Symbol("apitally.requestSize");
36
+ const RESPONSE_BODY_SYMBOL = /* @__PURE__ */ Symbol("apitally.responseBody");
37
+ const RESPONSE_SIZE_SYMBOL = /* @__PURE__ */ Symbol("apitally.responseSize");
38
+ const LOGS_SYMBOL = /* @__PURE__ */ Symbol("apitally.logs");
39
39
  function apitallyPlugin(config) {
40
40
  const client = new import_client.ApitallyClient(config);
41
41
  const logsContext = new import_node_async_hooks.AsyncLocalStorage();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hapi/plugin.ts"],"sourcesContent":["import type { Request, Server } from \"@hapi/hapi\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { performance } from \"node:perf_hooks\";\n\nimport { ApitallyClient } from \"../common/client.js\";\nimport { consumerFromStringOrObject } from \"../common/consumerRegistry.js\";\nimport type { LogRecord } from \"../common/requestLogger.js\";\nimport { convertHeaders } from \"../common/requestLogger.js\";\nimport { ApitallyConfig, ApitallyConsumer } from \"../common/types.js\";\nimport {\n handleHapiRequestEvent,\n patchConsole,\n patchPinoLogger,\n patchWinston,\n} from \"../loggers/index.js\";\nimport { getAppInfo, isBoom } from \"./utils.js\";\n\nconst START_TIME_SYMBOL = Symbol(\"apitally.startTime\");\nconst REQUEST_BODY_SYMBOL = Symbol(\"apitally.requestBody\");\nconst REQUEST_SIZE_SYMBOL = Symbol(\"apitally.requestSize\");\nconst RESPONSE_BODY_SYMBOL = Symbol(\"apitally.responseBody\");\nconst RESPONSE_SIZE_SYMBOL = Symbol(\"apitally.responseSize\");\nconst LOGS_SYMBOL = Symbol(\"apitally.logs\");\n\ndeclare module \"@hapi/hapi\" {\n interface Request {\n [START_TIME_SYMBOL]?: number;\n [REQUEST_BODY_SYMBOL]?: Buffer;\n [REQUEST_SIZE_SYMBOL]?: number;\n [RESPONSE_BODY_SYMBOL]?: Buffer;\n [RESPONSE_SIZE_SYMBOL]?: number;\n [LOGS_SYMBOL]?: LogRecord[];\n apitallyConsumer?: ApitallyConsumer | string;\n }\n\n interface ResponseObject {\n readonly contentType: string | null; // Missing in Hapi types\n }\n}\n\nexport default function apitallyPlugin(config: ApitallyConfig) {\n const client = new ApitallyClient(config);\n const logsContext = new AsyncLocalStorage<LogRecord[]>();\n let pinoLoggerPatched = false;\n\n if (client.requestLogger.enabled && client.requestLogger.config.captureLogs) {\n patchConsole(logsContext);\n patchWinston(logsContext);\n }\n\n return {\n name: \"apitally\",\n register: async function (server: Server) {\n server.ext(\"onPostStart\", async () => {\n if (\n \"logger\" in server &&\n client.requestLogger.enabled &&\n client.requestLogger.config.captureLogs\n ) {\n pinoLoggerPatched = await patchPinoLogger(\n (server as any).logger,\n logsContext,\n );\n }\n });\n\n server.ext(\"onPostStart\", () => {\n const appInfo = getAppInfo(server, config.appVersion);\n client.setStartupData(appInfo);\n client.startSync();\n });\n\n server.ext(\"onPreStop\", async () => {\n await client.handleShutdown();\n });\n\n server.events.on(\"request\", (_, event) => {\n if (\n !pinoLoggerPatched &&\n client.requestLogger.enabled &&\n client.requestLogger.config.captureLogs &&\n event.channel === \"app\"\n ) {\n handleHapiRequestEvent(event, logsContext);\n }\n });\n\n server.ext(\"onRequest\", async (request, h) => {\n if (!client.isEnabled() || request.method.toUpperCase() === \"OPTIONS\") {\n return h.continue;\n }\n\n request[START_TIME_SYMBOL] = performance.now();\n\n // Patch the lifecycle function to run with the logs context\n const lifecycle = (request as any)._lifecycle.bind(request);\n const logs: LogRecord[] = [];\n request[LOGS_SYMBOL] = logs;\n (request as any)._lifecycle = () => logsContext.run(logs, lifecycle);\n\n const captureRequestBody =\n client.requestLogger.enabled &&\n client.requestLogger.config.logRequestBody &&\n client.requestLogger.isSupportedContentType(\n request.headers[\"content-type\"],\n );\n const chunks: Buffer[] = [];\n let size = 0;\n request.events.on(\"peek\", (chunk: string, encoding: string) => {\n if (captureRequestBody) {\n chunks.push(Buffer.from(chunk, encoding as BufferEncoding));\n }\n size += Buffer.byteLength(chunk, encoding as BufferEncoding);\n });\n request.events.once(\"finish\", () => {\n if (chunks.length > 0) {\n request[REQUEST_BODY_SYMBOL] = Buffer.concat(chunks);\n }\n request[REQUEST_SIZE_SYMBOL] = size;\n });\n\n return h.continue;\n });\n\n server.ext(\"onPreResponse\", async (request, h) => {\n if (\n !client.isEnabled() ||\n request.method.toUpperCase() === \"OPTIONS\" ||\n isBoom(request.response)\n ) {\n return h.continue;\n }\n\n const captureResponseBody =\n client.requestLogger.enabled &&\n client.requestLogger.config.logResponseBody &&\n client.requestLogger.isSupportedContentType(\n request.response.contentType,\n );\n const chunks: Buffer[] = [];\n let size = 0;\n request.response.events.on(\n \"peek\",\n (chunk: string, encoding: string) => {\n if (captureResponseBody) {\n chunks.push(Buffer.from(chunk, encoding as BufferEncoding));\n }\n size += Buffer.byteLength(chunk, encoding as BufferEncoding);\n },\n );\n request.response.events.once(\"finish\", () => {\n if (chunks.length > 0) {\n request[RESPONSE_BODY_SYMBOL] = Buffer.concat(chunks);\n }\n request[RESPONSE_SIZE_SYMBOL] = size;\n });\n\n return h.continue;\n });\n\n server.ext(\"onPostResponse\", async (request, h) => {\n if (!client.isEnabled() || request.method.toUpperCase() === \"OPTIONS\") {\n return h.continue;\n }\n\n const startTime = request[START_TIME_SYMBOL];\n const responseTime = startTime ? performance.now() - startTime : 0;\n const timestamp = (Date.now() - responseTime) / 1000;\n const requestBody = request[REQUEST_BODY_SYMBOL];\n const requestSize = request[REQUEST_SIZE_SYMBOL];\n const response = request.response;\n let statusCode: number;\n let responseHeaders: Record<string, any>;\n let responseBody = request[RESPONSE_BODY_SYMBOL];\n let responseSize = request[RESPONSE_SIZE_SYMBOL];\n const error =\n (response as any)._error instanceof Error\n ? (response as any)._error\n : undefined;\n\n if (isBoom(response)) {\n // Handle Boom error object\n statusCode = response.output?.statusCode ?? 500;\n responseHeaders = response.output?.headers ?? {};\n } else {\n // Handle normal ResponseObject\n statusCode = response.statusCode ?? 200;\n responseHeaders = response.headers ?? {};\n }\n\n if (\n !responseBody &&\n (response as any)._payload &&\n client.requestLogger.enabled &&\n client.requestLogger.config.logResponseBody &&\n (isBoom(response) ||\n client.requestLogger.isSupportedContentType(response.contentType))\n ) {\n const responsePayload = (response as any)._payload;\n if (\n responsePayload &&\n responsePayload._data &&\n responsePayload._encoding &&\n typeof responsePayload._data === \"string\" &&\n typeof responsePayload._encoding === \"string\"\n ) {\n responseBody = Buffer.from(\n responsePayload._data,\n responsePayload._encoding as BufferEncoding,\n );\n }\n }\n\n if (!responseSize && responseBody) {\n responseSize = responseBody.length;\n }\n\n const consumer = request.apitallyConsumer\n ? consumerFromStringOrObject(request.apitallyConsumer)\n : null;\n client.consumerRegistry.addOrUpdateConsumer(consumer);\n\n if (request.route.path) {\n client.requestCounter.addRequest({\n consumer: consumer?.identifier,\n method: request.method,\n path: request.route.path,\n statusCode,\n responseTime,\n requestSize,\n responseSize,\n });\n\n if (statusCode === 500 && error) {\n client.serverErrorCounter.addServerError({\n consumer: consumer?.identifier,\n method: request.method,\n path: request.route.path,\n type: error.name,\n msg: error.message,\n traceback: error.stack || \"\",\n });\n }\n }\n\n if (client.requestLogger.enabled) {\n const logs = request[LOGS_SYMBOL];\n client.requestLogger.logRequest(\n {\n timestamp,\n consumer: consumer?.identifier,\n method: request.method,\n path: request.route.path,\n url: request.url?.href || \"\",\n headers: convertHeaders(request.headers),\n size: requestSize,\n body: requestBody,\n },\n {\n statusCode,\n responseTime: responseTime / 1000,\n headers: convertHeaders(responseHeaders),\n size: responseSize,\n body: responseBody,\n },\n error,\n logs,\n );\n }\n\n return h.continue;\n });\n },\n };\n}\n\nexport function setConsumer(\n request: Request,\n consumer: ApitallyConsumer | string | null | undefined,\n) {\n request.apitallyConsumer = consumer || undefined;\n}\n"],"mappings":"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","names":["START_TIME_SYMBOL","Symbol","REQUEST_BODY_SYMBOL","REQUEST_SIZE_SYMBOL","RESPONSE_BODY_SYMBOL","RESPONSE_SIZE_SYMBOL","LOGS_SYMBOL","config","client","ApitallyClient","logsContext","AsyncLocalStorage","pinoLoggerPatched","requestLogger","enabled","captureLogs","patchConsole","patchWinston","name","register","server","ext","patchPinoLogger","logger","appInfo","getAppInfo","appVersion","setStartupData","startSync","handleShutdown","events","on","_","event","channel","handleHapiRequestEvent","request","h","isEnabled","method","toUpperCase","continue","performance","now","lifecycle","_lifecycle","bind","logs","run","captureRequestBody","logRequestBody","isSupportedContentType","headers","chunks","size","chunk","encoding","push","Buffer","from","byteLength","once","length","concat","isBoom","response","captureResponseBody","logResponseBody","contentType","startTime","responseTime","timestamp","Date","requestBody","requestSize","statusCode","responseHeaders","responseBody","responseSize","error","_error","Error","undefined","output","_payload","responsePayload","_data","_encoding","consumer","apitallyConsumer","consumerFromStringOrObject","consumerRegistry","addOrUpdateConsumer","route","path","requestCounter","addRequest","identifier","serverErrorCounter","addServerError","type","msg","message","traceback","stack","logRequest","url","href","convertHeaders","body","apitallyPlugin","setConsumer"]}
1
+ {"version":3,"sources":["../../src/hapi/plugin.ts"],"sourcesContent":["import type { Request, Server } from \"@hapi/hapi\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { performance } from \"node:perf_hooks\";\n\nimport { ApitallyClient } from \"../common/client.js\";\nimport { consumerFromStringOrObject } from \"../common/consumerRegistry.js\";\nimport type { LogRecord } from \"../common/requestLogger.js\";\nimport { convertHeaders } from \"../common/requestLogger.js\";\nimport { ApitallyConfig, ApitallyConsumer } from \"../common/types.js\";\nimport {\n handleHapiRequestEvent,\n patchConsole,\n patchPinoLogger,\n patchWinston,\n} from \"../loggers/index.js\";\nimport { getAppInfo, isBoom } from \"./utils.js\";\n\nconst START_TIME_SYMBOL = Symbol(\"apitally.startTime\");\nconst REQUEST_BODY_SYMBOL = Symbol(\"apitally.requestBody\");\nconst REQUEST_SIZE_SYMBOL = Symbol(\"apitally.requestSize\");\nconst RESPONSE_BODY_SYMBOL = Symbol(\"apitally.responseBody\");\nconst RESPONSE_SIZE_SYMBOL = Symbol(\"apitally.responseSize\");\nconst LOGS_SYMBOL = Symbol(\"apitally.logs\");\n\ndeclare module \"@hapi/hapi\" {\n interface Request {\n [START_TIME_SYMBOL]?: number;\n [REQUEST_BODY_SYMBOL]?: Buffer;\n [REQUEST_SIZE_SYMBOL]?: number;\n [RESPONSE_BODY_SYMBOL]?: Buffer;\n [RESPONSE_SIZE_SYMBOL]?: number;\n [LOGS_SYMBOL]?: LogRecord[];\n apitallyConsumer?: ApitallyConsumer | string;\n }\n\n interface ResponseObject {\n readonly contentType: string | null; // Missing in Hapi types\n }\n}\n\nexport default function apitallyPlugin(config: ApitallyConfig) {\n const client = new ApitallyClient(config);\n const logsContext = new AsyncLocalStorage<LogRecord[]>();\n let pinoLoggerPatched = false;\n\n if (client.requestLogger.enabled && client.requestLogger.config.captureLogs) {\n patchConsole(logsContext);\n patchWinston(logsContext);\n }\n\n return {\n name: \"apitally\",\n register: async function (server: Server) {\n server.ext(\"onPostStart\", async () => {\n if (\n \"logger\" in server &&\n client.requestLogger.enabled &&\n client.requestLogger.config.captureLogs\n ) {\n pinoLoggerPatched = await patchPinoLogger(\n (server as any).logger,\n logsContext,\n );\n }\n });\n\n server.ext(\"onPostStart\", () => {\n const appInfo = getAppInfo(server, config.appVersion);\n client.setStartupData(appInfo);\n client.startSync();\n });\n\n server.ext(\"onPreStop\", async () => {\n await client.handleShutdown();\n });\n\n server.events.on(\"request\", (_, event) => {\n if (\n !pinoLoggerPatched &&\n client.requestLogger.enabled &&\n client.requestLogger.config.captureLogs &&\n event.channel === \"app\"\n ) {\n handleHapiRequestEvent(event, logsContext);\n }\n });\n\n server.ext(\"onRequest\", async (request, h) => {\n if (!client.isEnabled() || request.method.toUpperCase() === \"OPTIONS\") {\n return h.continue;\n }\n\n request[START_TIME_SYMBOL] = performance.now();\n\n // Patch the lifecycle function to run with the logs context\n const lifecycle = (request as any)._lifecycle.bind(request);\n const logs: LogRecord[] = [];\n request[LOGS_SYMBOL] = logs;\n (request as any)._lifecycle = () => logsContext.run(logs, lifecycle);\n\n const captureRequestBody =\n client.requestLogger.enabled &&\n client.requestLogger.config.logRequestBody &&\n client.requestLogger.isSupportedContentType(\n request.headers[\"content-type\"],\n );\n const chunks: Buffer[] = [];\n let size = 0;\n request.events.on(\"peek\", (chunk: string, encoding: string) => {\n if (captureRequestBody) {\n chunks.push(Buffer.from(chunk, encoding as BufferEncoding));\n }\n size += Buffer.byteLength(chunk, encoding as BufferEncoding);\n });\n request.events.once(\"finish\", () => {\n if (chunks.length > 0) {\n request[REQUEST_BODY_SYMBOL] = Buffer.concat(chunks);\n }\n request[REQUEST_SIZE_SYMBOL] = size;\n });\n\n return h.continue;\n });\n\n server.ext(\"onPreResponse\", async (request, h) => {\n if (\n !client.isEnabled() ||\n request.method.toUpperCase() === \"OPTIONS\" ||\n isBoom(request.response)\n ) {\n return h.continue;\n }\n\n const captureResponseBody =\n client.requestLogger.enabled &&\n client.requestLogger.config.logResponseBody &&\n client.requestLogger.isSupportedContentType(\n request.response.contentType,\n );\n const chunks: Buffer[] = [];\n let size = 0;\n request.response.events.on(\n \"peek\",\n (chunk: string, encoding: string) => {\n if (captureResponseBody) {\n chunks.push(Buffer.from(chunk, encoding as BufferEncoding));\n }\n size += Buffer.byteLength(chunk, encoding as BufferEncoding);\n },\n );\n request.response.events.once(\"finish\", () => {\n if (chunks.length > 0) {\n request[RESPONSE_BODY_SYMBOL] = Buffer.concat(chunks);\n }\n request[RESPONSE_SIZE_SYMBOL] = size;\n });\n\n return h.continue;\n });\n\n server.ext(\"onPostResponse\", async (request, h) => {\n if (!client.isEnabled() || request.method.toUpperCase() === \"OPTIONS\") {\n return h.continue;\n }\n\n const startTime = request[START_TIME_SYMBOL];\n const responseTime = startTime ? performance.now() - startTime : 0;\n const timestamp = (Date.now() - responseTime) / 1000;\n const requestBody = request[REQUEST_BODY_SYMBOL];\n const requestSize = request[REQUEST_SIZE_SYMBOL];\n const response = request.response;\n let statusCode: number;\n let responseHeaders: Record<string, any>;\n let responseBody = request[RESPONSE_BODY_SYMBOL];\n let responseSize = request[RESPONSE_SIZE_SYMBOL];\n const error =\n (response as any)._error instanceof Error\n ? (response as any)._error\n : undefined;\n\n if (isBoom(response)) {\n // Handle Boom error object\n statusCode = response.output?.statusCode ?? 500;\n responseHeaders = response.output?.headers ?? {};\n } else {\n // Handle normal ResponseObject\n statusCode = response.statusCode ?? 200;\n responseHeaders = response.headers ?? {};\n }\n\n if (\n !responseBody &&\n (response as any)._payload &&\n client.requestLogger.enabled &&\n client.requestLogger.config.logResponseBody &&\n (isBoom(response) ||\n client.requestLogger.isSupportedContentType(response.contentType))\n ) {\n const responsePayload = (response as any)._payload;\n if (\n responsePayload &&\n responsePayload._data &&\n responsePayload._encoding &&\n typeof responsePayload._data === \"string\" &&\n typeof responsePayload._encoding === \"string\"\n ) {\n responseBody = Buffer.from(\n responsePayload._data,\n responsePayload._encoding as BufferEncoding,\n );\n }\n }\n\n if (!responseSize && responseBody) {\n responseSize = responseBody.length;\n }\n\n const consumer = request.apitallyConsumer\n ? consumerFromStringOrObject(request.apitallyConsumer)\n : null;\n client.consumerRegistry.addOrUpdateConsumer(consumer);\n\n if (request.route.path) {\n client.requestCounter.addRequest({\n consumer: consumer?.identifier,\n method: request.method,\n path: request.route.path,\n statusCode,\n responseTime,\n requestSize,\n responseSize,\n });\n\n if (statusCode === 500 && error) {\n client.serverErrorCounter.addServerError({\n consumer: consumer?.identifier,\n method: request.method,\n path: request.route.path,\n type: error.name,\n msg: error.message,\n traceback: error.stack || \"\",\n });\n }\n }\n\n if (client.requestLogger.enabled) {\n const logs = request[LOGS_SYMBOL];\n client.requestLogger.logRequest(\n {\n timestamp,\n consumer: consumer?.identifier,\n method: request.method,\n path: request.route.path,\n url: request.url?.href || \"\",\n headers: convertHeaders(request.headers),\n size: requestSize,\n body: requestBody,\n },\n {\n statusCode,\n responseTime: responseTime / 1000,\n headers: convertHeaders(responseHeaders),\n size: responseSize,\n body: responseBody,\n },\n error,\n logs,\n );\n }\n\n return h.continue;\n });\n },\n };\n}\n\nexport function setConsumer(\n request: Request,\n consumer: ApitallyConsumer | string | null | undefined,\n) {\n request.apitallyConsumer = consumer || undefined;\n}\n"],"mappings":"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","names":["START_TIME_SYMBOL","Symbol","REQUEST_BODY_SYMBOL","REQUEST_SIZE_SYMBOL","RESPONSE_BODY_SYMBOL","RESPONSE_SIZE_SYMBOL","LOGS_SYMBOL","config","client","ApitallyClient","logsContext","AsyncLocalStorage","pinoLoggerPatched","requestLogger","enabled","captureLogs","patchConsole","patchWinston","name","register","server","ext","patchPinoLogger","logger","appInfo","getAppInfo","appVersion","setStartupData","startSync","handleShutdown","events","on","_","event","channel","handleHapiRequestEvent","request","h","isEnabled","method","toUpperCase","continue","performance","now","lifecycle","_lifecycle","bind","logs","run","captureRequestBody","logRequestBody","isSupportedContentType","headers","chunks","size","chunk","encoding","push","Buffer","from","byteLength","once","length","concat","isBoom","response","captureResponseBody","logResponseBody","contentType","startTime","responseTime","timestamp","Date","requestBody","requestSize","statusCode","responseHeaders","responseBody","responseSize","error","_error","Error","undefined","output","_payload","responsePayload","_data","_encoding","consumer","apitallyConsumer","consumerFromStringOrObject","consumerRegistry","addOrUpdateConsumer","route","path","requestCounter","addRequest","identifier","serverErrorCounter","addServerError","type","msg","message","traceback","stack","logRequest","url","href","convertHeaders","body","apitallyPlugin","setConsumer"]}
@@ -7,12 +7,12 @@ import { consumerFromStringOrObject } from "../common/consumerRegistry.js";
7
7
  import { convertHeaders } from "../common/requestLogger.js";
8
8
  import { handleHapiRequestEvent, patchConsole, patchPinoLogger, patchWinston } from "../loggers/index.js";
9
9
  import { getAppInfo, isBoom } from "./utils.js";
10
- const START_TIME_SYMBOL = Symbol("apitally.startTime");
11
- const REQUEST_BODY_SYMBOL = Symbol("apitally.requestBody");
12
- const REQUEST_SIZE_SYMBOL = Symbol("apitally.requestSize");
13
- const RESPONSE_BODY_SYMBOL = Symbol("apitally.responseBody");
14
- const RESPONSE_SIZE_SYMBOL = Symbol("apitally.responseSize");
15
- const LOGS_SYMBOL = Symbol("apitally.logs");
10
+ const START_TIME_SYMBOL = /* @__PURE__ */ Symbol("apitally.startTime");
11
+ const REQUEST_BODY_SYMBOL = /* @__PURE__ */ Symbol("apitally.requestBody");
12
+ const REQUEST_SIZE_SYMBOL = /* @__PURE__ */ Symbol("apitally.requestSize");
13
+ const RESPONSE_BODY_SYMBOL = /* @__PURE__ */ Symbol("apitally.responseBody");
14
+ const RESPONSE_SIZE_SYMBOL = /* @__PURE__ */ Symbol("apitally.responseSize");
15
+ const LOGS_SYMBOL = /* @__PURE__ */ Symbol("apitally.logs");
16
16
  function apitallyPlugin(config) {
17
17
  const client = new ApitallyClient(config);
18
18
  const logsContext = new AsyncLocalStorage();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hapi/plugin.ts"],"sourcesContent":["import type { Request, Server } from \"@hapi/hapi\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { performance } from \"node:perf_hooks\";\n\nimport { ApitallyClient } from \"../common/client.js\";\nimport { consumerFromStringOrObject } from \"../common/consumerRegistry.js\";\nimport type { LogRecord } from \"../common/requestLogger.js\";\nimport { convertHeaders } from \"../common/requestLogger.js\";\nimport { ApitallyConfig, ApitallyConsumer } from \"../common/types.js\";\nimport {\n handleHapiRequestEvent,\n patchConsole,\n patchPinoLogger,\n patchWinston,\n} from \"../loggers/index.js\";\nimport { getAppInfo, isBoom } from \"./utils.js\";\n\nconst START_TIME_SYMBOL = Symbol(\"apitally.startTime\");\nconst REQUEST_BODY_SYMBOL = Symbol(\"apitally.requestBody\");\nconst REQUEST_SIZE_SYMBOL = Symbol(\"apitally.requestSize\");\nconst RESPONSE_BODY_SYMBOL = Symbol(\"apitally.responseBody\");\nconst RESPONSE_SIZE_SYMBOL = Symbol(\"apitally.responseSize\");\nconst LOGS_SYMBOL = Symbol(\"apitally.logs\");\n\ndeclare module \"@hapi/hapi\" {\n interface Request {\n [START_TIME_SYMBOL]?: number;\n [REQUEST_BODY_SYMBOL]?: Buffer;\n [REQUEST_SIZE_SYMBOL]?: number;\n [RESPONSE_BODY_SYMBOL]?: Buffer;\n [RESPONSE_SIZE_SYMBOL]?: number;\n [LOGS_SYMBOL]?: LogRecord[];\n apitallyConsumer?: ApitallyConsumer | string;\n }\n\n interface ResponseObject {\n readonly contentType: string | null; // Missing in Hapi types\n }\n}\n\nexport default function apitallyPlugin(config: ApitallyConfig) {\n const client = new ApitallyClient(config);\n const logsContext = new AsyncLocalStorage<LogRecord[]>();\n let pinoLoggerPatched = false;\n\n if (client.requestLogger.enabled && client.requestLogger.config.captureLogs) {\n patchConsole(logsContext);\n patchWinston(logsContext);\n }\n\n return {\n name: \"apitally\",\n register: async function (server: Server) {\n server.ext(\"onPostStart\", async () => {\n if (\n \"logger\" in server &&\n client.requestLogger.enabled &&\n client.requestLogger.config.captureLogs\n ) {\n pinoLoggerPatched = await patchPinoLogger(\n (server as any).logger,\n logsContext,\n );\n }\n });\n\n server.ext(\"onPostStart\", () => {\n const appInfo = getAppInfo(server, config.appVersion);\n client.setStartupData(appInfo);\n client.startSync();\n });\n\n server.ext(\"onPreStop\", async () => {\n await client.handleShutdown();\n });\n\n server.events.on(\"request\", (_, event) => {\n if (\n !pinoLoggerPatched &&\n client.requestLogger.enabled &&\n client.requestLogger.config.captureLogs &&\n event.channel === \"app\"\n ) {\n handleHapiRequestEvent(event, logsContext);\n }\n });\n\n server.ext(\"onRequest\", async (request, h) => {\n if (!client.isEnabled() || request.method.toUpperCase() === \"OPTIONS\") {\n return h.continue;\n }\n\n request[START_TIME_SYMBOL] = performance.now();\n\n // Patch the lifecycle function to run with the logs context\n const lifecycle = (request as any)._lifecycle.bind(request);\n const logs: LogRecord[] = [];\n request[LOGS_SYMBOL] = logs;\n (request as any)._lifecycle = () => logsContext.run(logs, lifecycle);\n\n const captureRequestBody =\n client.requestLogger.enabled &&\n client.requestLogger.config.logRequestBody &&\n client.requestLogger.isSupportedContentType(\n request.headers[\"content-type\"],\n );\n const chunks: Buffer[] = [];\n let size = 0;\n request.events.on(\"peek\", (chunk: string, encoding: string) => {\n if (captureRequestBody) {\n chunks.push(Buffer.from(chunk, encoding as BufferEncoding));\n }\n size += Buffer.byteLength(chunk, encoding as BufferEncoding);\n });\n request.events.once(\"finish\", () => {\n if (chunks.length > 0) {\n request[REQUEST_BODY_SYMBOL] = Buffer.concat(chunks);\n }\n request[REQUEST_SIZE_SYMBOL] = size;\n });\n\n return h.continue;\n });\n\n server.ext(\"onPreResponse\", async (request, h) => {\n if (\n !client.isEnabled() ||\n request.method.toUpperCase() === \"OPTIONS\" ||\n isBoom(request.response)\n ) {\n return h.continue;\n }\n\n const captureResponseBody =\n client.requestLogger.enabled &&\n client.requestLogger.config.logResponseBody &&\n client.requestLogger.isSupportedContentType(\n request.response.contentType,\n );\n const chunks: Buffer[] = [];\n let size = 0;\n request.response.events.on(\n \"peek\",\n (chunk: string, encoding: string) => {\n if (captureResponseBody) {\n chunks.push(Buffer.from(chunk, encoding as BufferEncoding));\n }\n size += Buffer.byteLength(chunk, encoding as BufferEncoding);\n },\n );\n request.response.events.once(\"finish\", () => {\n if (chunks.length > 0) {\n request[RESPONSE_BODY_SYMBOL] = Buffer.concat(chunks);\n }\n request[RESPONSE_SIZE_SYMBOL] = size;\n });\n\n return h.continue;\n });\n\n server.ext(\"onPostResponse\", async (request, h) => {\n if (!client.isEnabled() || request.method.toUpperCase() === \"OPTIONS\") {\n return h.continue;\n }\n\n const startTime = request[START_TIME_SYMBOL];\n const responseTime = startTime ? performance.now() - startTime : 0;\n const timestamp = (Date.now() - responseTime) / 1000;\n const requestBody = request[REQUEST_BODY_SYMBOL];\n const requestSize = request[REQUEST_SIZE_SYMBOL];\n const response = request.response;\n let statusCode: number;\n let responseHeaders: Record<string, any>;\n let responseBody = request[RESPONSE_BODY_SYMBOL];\n let responseSize = request[RESPONSE_SIZE_SYMBOL];\n const error =\n (response as any)._error instanceof Error\n ? (response as any)._error\n : undefined;\n\n if (isBoom(response)) {\n // Handle Boom error object\n statusCode = response.output?.statusCode ?? 500;\n responseHeaders = response.output?.headers ?? {};\n } else {\n // Handle normal ResponseObject\n statusCode = response.statusCode ?? 200;\n responseHeaders = response.headers ?? {};\n }\n\n if (\n !responseBody &&\n (response as any)._payload &&\n client.requestLogger.enabled &&\n client.requestLogger.config.logResponseBody &&\n (isBoom(response) ||\n client.requestLogger.isSupportedContentType(response.contentType))\n ) {\n const responsePayload = (response as any)._payload;\n if (\n responsePayload &&\n responsePayload._data &&\n responsePayload._encoding &&\n typeof responsePayload._data === \"string\" &&\n typeof responsePayload._encoding === \"string\"\n ) {\n responseBody = Buffer.from(\n responsePayload._data,\n responsePayload._encoding as BufferEncoding,\n );\n }\n }\n\n if (!responseSize && responseBody) {\n responseSize = responseBody.length;\n }\n\n const consumer = request.apitallyConsumer\n ? consumerFromStringOrObject(request.apitallyConsumer)\n : null;\n client.consumerRegistry.addOrUpdateConsumer(consumer);\n\n if (request.route.path) {\n client.requestCounter.addRequest({\n consumer: consumer?.identifier,\n method: request.method,\n path: request.route.path,\n statusCode,\n responseTime,\n requestSize,\n responseSize,\n });\n\n if (statusCode === 500 && error) {\n client.serverErrorCounter.addServerError({\n consumer: consumer?.identifier,\n method: request.method,\n path: request.route.path,\n type: error.name,\n msg: error.message,\n traceback: error.stack || \"\",\n });\n }\n }\n\n if (client.requestLogger.enabled) {\n const logs = request[LOGS_SYMBOL];\n client.requestLogger.logRequest(\n {\n timestamp,\n consumer: consumer?.identifier,\n method: request.method,\n path: request.route.path,\n url: request.url?.href || \"\",\n headers: convertHeaders(request.headers),\n size: requestSize,\n body: requestBody,\n },\n {\n statusCode,\n responseTime: responseTime / 1000,\n headers: convertHeaders(responseHeaders),\n size: responseSize,\n body: responseBody,\n },\n error,\n logs,\n );\n }\n\n return h.continue;\n });\n },\n };\n}\n\nexport function setConsumer(\n request: Request,\n consumer: ApitallyConsumer | string | null | undefined,\n) {\n request.apitallyConsumer = consumer || undefined;\n}\n"],"mappings":"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","names":["AsyncLocalStorage","performance","ApitallyClient","consumerFromStringOrObject","convertHeaders","handleHapiRequestEvent","patchConsole","patchPinoLogger","patchWinston","getAppInfo","isBoom","START_TIME_SYMBOL","Symbol","REQUEST_BODY_SYMBOL","REQUEST_SIZE_SYMBOL","RESPONSE_BODY_SYMBOL","RESPONSE_SIZE_SYMBOL","LOGS_SYMBOL","config","client","logsContext","pinoLoggerPatched","requestLogger","enabled","captureLogs","name","register","server","ext","logger","appInfo","appVersion","setStartupData","startSync","handleShutdown","events","on","_","event","channel","request","h","isEnabled","method","toUpperCase","continue","now","lifecycle","_lifecycle","bind","logs","run","captureRequestBody","logRequestBody","isSupportedContentType","headers","chunks","size","chunk","encoding","push","Buffer","from","byteLength","once","length","concat","response","captureResponseBody","logResponseBody","contentType","startTime","responseTime","timestamp","Date","requestBody","requestSize","statusCode","responseHeaders","responseBody","responseSize","error","_error","Error","undefined","output","_payload","responsePayload","_data","_encoding","consumer","apitallyConsumer","consumerRegistry","addOrUpdateConsumer","route","path","requestCounter","addRequest","identifier","serverErrorCounter","addServerError","type","msg","message","traceback","stack","logRequest","url","href","body","apitallyPlugin","setConsumer"]}
1
+ {"version":3,"sources":["../../src/hapi/plugin.ts"],"sourcesContent":["import type { Request, Server } from \"@hapi/hapi\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { performance } from \"node:perf_hooks\";\n\nimport { ApitallyClient } from \"../common/client.js\";\nimport { consumerFromStringOrObject } from \"../common/consumerRegistry.js\";\nimport type { LogRecord } from \"../common/requestLogger.js\";\nimport { convertHeaders } from \"../common/requestLogger.js\";\nimport { ApitallyConfig, ApitallyConsumer } from \"../common/types.js\";\nimport {\n handleHapiRequestEvent,\n patchConsole,\n patchPinoLogger,\n patchWinston,\n} from \"../loggers/index.js\";\nimport { getAppInfo, isBoom } from \"./utils.js\";\n\nconst START_TIME_SYMBOL = Symbol(\"apitally.startTime\");\nconst REQUEST_BODY_SYMBOL = Symbol(\"apitally.requestBody\");\nconst REQUEST_SIZE_SYMBOL = Symbol(\"apitally.requestSize\");\nconst RESPONSE_BODY_SYMBOL = Symbol(\"apitally.responseBody\");\nconst RESPONSE_SIZE_SYMBOL = Symbol(\"apitally.responseSize\");\nconst LOGS_SYMBOL = Symbol(\"apitally.logs\");\n\ndeclare module \"@hapi/hapi\" {\n interface Request {\n [START_TIME_SYMBOL]?: number;\n [REQUEST_BODY_SYMBOL]?: Buffer;\n [REQUEST_SIZE_SYMBOL]?: number;\n [RESPONSE_BODY_SYMBOL]?: Buffer;\n [RESPONSE_SIZE_SYMBOL]?: number;\n [LOGS_SYMBOL]?: LogRecord[];\n apitallyConsumer?: ApitallyConsumer | string;\n }\n\n interface ResponseObject {\n readonly contentType: string | null; // Missing in Hapi types\n }\n}\n\nexport default function apitallyPlugin(config: ApitallyConfig) {\n const client = new ApitallyClient(config);\n const logsContext = new AsyncLocalStorage<LogRecord[]>();\n let pinoLoggerPatched = false;\n\n if (client.requestLogger.enabled && client.requestLogger.config.captureLogs) {\n patchConsole(logsContext);\n patchWinston(logsContext);\n }\n\n return {\n name: \"apitally\",\n register: async function (server: Server) {\n server.ext(\"onPostStart\", async () => {\n if (\n \"logger\" in server &&\n client.requestLogger.enabled &&\n client.requestLogger.config.captureLogs\n ) {\n pinoLoggerPatched = await patchPinoLogger(\n (server as any).logger,\n logsContext,\n );\n }\n });\n\n server.ext(\"onPostStart\", () => {\n const appInfo = getAppInfo(server, config.appVersion);\n client.setStartupData(appInfo);\n client.startSync();\n });\n\n server.ext(\"onPreStop\", async () => {\n await client.handleShutdown();\n });\n\n server.events.on(\"request\", (_, event) => {\n if (\n !pinoLoggerPatched &&\n client.requestLogger.enabled &&\n client.requestLogger.config.captureLogs &&\n event.channel === \"app\"\n ) {\n handleHapiRequestEvent(event, logsContext);\n }\n });\n\n server.ext(\"onRequest\", async (request, h) => {\n if (!client.isEnabled() || request.method.toUpperCase() === \"OPTIONS\") {\n return h.continue;\n }\n\n request[START_TIME_SYMBOL] = performance.now();\n\n // Patch the lifecycle function to run with the logs context\n const lifecycle = (request as any)._lifecycle.bind(request);\n const logs: LogRecord[] = [];\n request[LOGS_SYMBOL] = logs;\n (request as any)._lifecycle = () => logsContext.run(logs, lifecycle);\n\n const captureRequestBody =\n client.requestLogger.enabled &&\n client.requestLogger.config.logRequestBody &&\n client.requestLogger.isSupportedContentType(\n request.headers[\"content-type\"],\n );\n const chunks: Buffer[] = [];\n let size = 0;\n request.events.on(\"peek\", (chunk: string, encoding: string) => {\n if (captureRequestBody) {\n chunks.push(Buffer.from(chunk, encoding as BufferEncoding));\n }\n size += Buffer.byteLength(chunk, encoding as BufferEncoding);\n });\n request.events.once(\"finish\", () => {\n if (chunks.length > 0) {\n request[REQUEST_BODY_SYMBOL] = Buffer.concat(chunks);\n }\n request[REQUEST_SIZE_SYMBOL] = size;\n });\n\n return h.continue;\n });\n\n server.ext(\"onPreResponse\", async (request, h) => {\n if (\n !client.isEnabled() ||\n request.method.toUpperCase() === \"OPTIONS\" ||\n isBoom(request.response)\n ) {\n return h.continue;\n }\n\n const captureResponseBody =\n client.requestLogger.enabled &&\n client.requestLogger.config.logResponseBody &&\n client.requestLogger.isSupportedContentType(\n request.response.contentType,\n );\n const chunks: Buffer[] = [];\n let size = 0;\n request.response.events.on(\n \"peek\",\n (chunk: string, encoding: string) => {\n if (captureResponseBody) {\n chunks.push(Buffer.from(chunk, encoding as BufferEncoding));\n }\n size += Buffer.byteLength(chunk, encoding as BufferEncoding);\n },\n );\n request.response.events.once(\"finish\", () => {\n if (chunks.length > 0) {\n request[RESPONSE_BODY_SYMBOL] = Buffer.concat(chunks);\n }\n request[RESPONSE_SIZE_SYMBOL] = size;\n });\n\n return h.continue;\n });\n\n server.ext(\"onPostResponse\", async (request, h) => {\n if (!client.isEnabled() || request.method.toUpperCase() === \"OPTIONS\") {\n return h.continue;\n }\n\n const startTime = request[START_TIME_SYMBOL];\n const responseTime = startTime ? performance.now() - startTime : 0;\n const timestamp = (Date.now() - responseTime) / 1000;\n const requestBody = request[REQUEST_BODY_SYMBOL];\n const requestSize = request[REQUEST_SIZE_SYMBOL];\n const response = request.response;\n let statusCode: number;\n let responseHeaders: Record<string, any>;\n let responseBody = request[RESPONSE_BODY_SYMBOL];\n let responseSize = request[RESPONSE_SIZE_SYMBOL];\n const error =\n (response as any)._error instanceof Error\n ? (response as any)._error\n : undefined;\n\n if (isBoom(response)) {\n // Handle Boom error object\n statusCode = response.output?.statusCode ?? 500;\n responseHeaders = response.output?.headers ?? {};\n } else {\n // Handle normal ResponseObject\n statusCode = response.statusCode ?? 200;\n responseHeaders = response.headers ?? {};\n }\n\n if (\n !responseBody &&\n (response as any)._payload &&\n client.requestLogger.enabled &&\n client.requestLogger.config.logResponseBody &&\n (isBoom(response) ||\n client.requestLogger.isSupportedContentType(response.contentType))\n ) {\n const responsePayload = (response as any)._payload;\n if (\n responsePayload &&\n responsePayload._data &&\n responsePayload._encoding &&\n typeof responsePayload._data === \"string\" &&\n typeof responsePayload._encoding === \"string\"\n ) {\n responseBody = Buffer.from(\n responsePayload._data,\n responsePayload._encoding as BufferEncoding,\n );\n }\n }\n\n if (!responseSize && responseBody) {\n responseSize = responseBody.length;\n }\n\n const consumer = request.apitallyConsumer\n ? consumerFromStringOrObject(request.apitallyConsumer)\n : null;\n client.consumerRegistry.addOrUpdateConsumer(consumer);\n\n if (request.route.path) {\n client.requestCounter.addRequest({\n consumer: consumer?.identifier,\n method: request.method,\n path: request.route.path,\n statusCode,\n responseTime,\n requestSize,\n responseSize,\n });\n\n if (statusCode === 500 && error) {\n client.serverErrorCounter.addServerError({\n consumer: consumer?.identifier,\n method: request.method,\n path: request.route.path,\n type: error.name,\n msg: error.message,\n traceback: error.stack || \"\",\n });\n }\n }\n\n if (client.requestLogger.enabled) {\n const logs = request[LOGS_SYMBOL];\n client.requestLogger.logRequest(\n {\n timestamp,\n consumer: consumer?.identifier,\n method: request.method,\n path: request.route.path,\n url: request.url?.href || \"\",\n headers: convertHeaders(request.headers),\n size: requestSize,\n body: requestBody,\n },\n {\n statusCode,\n responseTime: responseTime / 1000,\n headers: convertHeaders(responseHeaders),\n size: responseSize,\n body: responseBody,\n },\n error,\n logs,\n );\n }\n\n return h.continue;\n });\n },\n };\n}\n\nexport function setConsumer(\n request: Request,\n consumer: ApitallyConsumer | string | null | undefined,\n) {\n request.apitallyConsumer = consumer || undefined;\n}\n"],"mappings":"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","names":["AsyncLocalStorage","performance","ApitallyClient","consumerFromStringOrObject","convertHeaders","handleHapiRequestEvent","patchConsole","patchPinoLogger","patchWinston","getAppInfo","isBoom","START_TIME_SYMBOL","Symbol","REQUEST_BODY_SYMBOL","REQUEST_SIZE_SYMBOL","RESPONSE_BODY_SYMBOL","RESPONSE_SIZE_SYMBOL","LOGS_SYMBOL","config","client","logsContext","pinoLoggerPatched","requestLogger","enabled","captureLogs","name","register","server","ext","logger","appInfo","appVersion","setStartupData","startSync","handleShutdown","events","on","_","event","channel","request","h","isEnabled","method","toUpperCase","continue","now","lifecycle","_lifecycle","bind","logs","run","captureRequestBody","logRequestBody","isSupportedContentType","headers","chunks","size","chunk","encoding","push","Buffer","from","byteLength","once","length","concat","response","captureResponseBody","logResponseBody","contentType","startTime","responseTime","timestamp","Date","requestBody","requestSize","statusCode","responseHeaders","responseBody","responseSize","error","_error","Error","undefined","output","_payload","responsePayload","_data","_encoding","consumer","apitallyConsumer","consumerRegistry","addOrUpdateConsumer","route","path","requestCounter","addRequest","identifier","serverErrorCounter","addServerError","type","msg","message","traceback","stack","logRequest","url","href","body","apitallyPlugin","setConsumer"]}
@@ -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"]}
@@ -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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apitally",
3
- "version": "0.23.1",
3
+ "version": "0.24.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",
@@ -305,8 +305,8 @@
305
305
  "express-validator": "^7.2.1",
306
306
  "fastify": "^5.0.0",
307
307
  "fastify-plugin": "^5.0.1",
308
- "globals": "^16.2.0",
309
- "h3": "2.0.1-rc.5",
308
+ "globals": "^17.0.0",
309
+ "h3": "2.0.1-rc.6",
310
310
  "hono": "^4.6.5",
311
311
  "koa": "^3.0.0",
312
312
  "koa-bodyparser": "^4.4.1",