UNPKG

apitally

Version:

Simple API monitoring & analytics for REST APIs built with Express, Fastify, NestJS, AdonisJS, Hono, H3, Elysia, Hapi, and Koa.

1 lines 19 kB
{"version":3,"sources":["../../src/fastify/plugin.ts"],"sourcesContent":["import type {\n FastifyError,\n FastifyPluginAsync,\n FastifyReply,\n FastifyRequest,\n} from \"fastify\";\nimport fp from \"fastify-plugin\";\nimport { AsyncLocalStorage, AsyncResource } from \"node:async_hooks\";\n\nimport { ApitallyClient } from \"../common/client.js\";\nimport { consumerFromStringOrObject } from \"../common/consumerRegistry.js\";\nimport { parseContentLength } from \"../common/headers.js\";\nimport { getPackageVersion } from \"../common/packageVersions.js\";\nimport type { LogRecord } from \"../common/requestLogger.js\";\nimport { convertBody, convertHeaders } from \"../common/requestLogger.js\";\nimport type { SpanHandle } from \"../common/spanCollector.js\";\nimport {\n ApitallyConfig,\n ApitallyConsumer,\n PathInfo,\n ValidationError,\n} from \"../common/types.js\";\nimport {\n patchConsole,\n patchNestLogger,\n patchPinoLogger,\n patchWinston,\n} from \"../loggers/index.js\";\n\nconst LOGS_SYMBOL = Symbol(\"apitally.logs\");\nconst ASYNC_RESOURCE_SYMBOL = Symbol(\"apitally.asyncResource\");\nconst SPAN_HANDLE_SYMBOL = Symbol(\"apitally.spanHandle\");\n\ndeclare module \"fastify\" {\n interface FastifyReply {\n payload: any;\n serverError?: FastifyError;\n }\n\n interface FastifyRequest {\n apitallyConsumer?: ApitallyConsumer | string | null;\n consumerIdentifier?: ApitallyConsumer | string | null; // For backwards compatibility\n\n [LOGS_SYMBOL]?: LogRecord[];\n [ASYNC_RESOURCE_SYMBOL]?: AsyncResource;\n [SPAN_HANDLE_SYMBOL]?: SpanHandle;\n }\n}\n\nconst apitallyPlugin: FastifyPluginAsync<ApitallyConfig> = async (\n fastify,\n config,\n) => {\n const client = new ApitallyClient(config);\n const routes: PathInfo[] = [];\n const logsContext = new AsyncLocalStorage<LogRecord[]>();\n\n if (client.requestLogger.config.captureLogs) {\n patchConsole(logsContext);\n patchWinston(logsContext);\n patchPinoLogger(fastify.log, logsContext);\n patchNestLogger(logsContext);\n }\n\n fastify.decorateRequest(\"apitallyConsumer\", null);\n fastify.decorateRequest(\"consumerIdentifier\", null); // For backwards compatibility\n fastify.decorateReply(\"payload\", null);\n\n fastify.addHook(\"onRoute\", (routeOptions) => {\n const methods = Array.isArray(routeOptions.method)\n ? routeOptions.method\n : [routeOptions.method];\n methods.forEach((method) => {\n if (![\"HEAD\", \"OPTIONS\"].includes(method.toUpperCase())) {\n routes.push({\n method: method.toUpperCase(),\n path: routeOptions.url,\n });\n }\n });\n });\n\n fastify.addHook(\"onReady\", () => {\n client.setStartupData(getAppInfo(routes, config.appVersion));\n client.startSync();\n });\n\n fastify.addHook(\"onClose\", async () => {\n await client.handleShutdown();\n });\n\n // Establish logs context and start span for each request\n fastify.addHook(\"onRequest\", (request, reply, done) => {\n if (client.isEnabled()) {\n const logs: LogRecord[] = [];\n request[LOGS_SYMBOL] = logs;\n logsContext.run(logs, () => {\n const spanHandle = client.spanCollector.startSpan();\n request[SPAN_HANDLE_SYMBOL] = spanHandle;\n spanHandle.runInContext(() => {\n const asyncResource = new AsyncResource(\"ApitallyContext\");\n request[ASYNC_RESOURCE_SYMBOL] = asyncResource;\n asyncResource.runInAsyncScope(done, request.raw);\n });\n });\n } else {\n done();\n }\n });\n\n // Restore async context for later hooks and route handlers\n fastify.addHook(\"preValidation\", (request, reply, done) => {\n if (client.isEnabled() && request[ASYNC_RESOURCE_SYMBOL]) {\n const asyncResource = request[ASYNC_RESOURCE_SYMBOL];\n asyncResource.runInAsyncScope(done, request.raw);\n } else {\n done();\n }\n });\n\n fastify.addHook(\"onSend\", (request, reply, payload: any, done) => {\n const contentType = reply.getHeader(\"content-type\") as string | undefined;\n if (client.requestLogger.isSupportedContentType(contentType)) {\n reply.payload = payload;\n }\n done();\n });\n\n fastify.addHook(\"onError\", (request, reply, error, done) => {\n if (!error.statusCode || error.statusCode === 500) {\n reply.serverError = error;\n }\n done();\n });\n\n fastify.addHook(\"onResponse\", (request, reply, done) => {\n if (client.isEnabled() && request.method.toUpperCase() !== \"OPTIONS\") {\n // Get path from routeOptions if available (from v4), otherwise fallback to deprecated routerPath\n const consumer = getConsumer(request);\n const path =\n \"routeOptions\" in request\n ? (request as any).routeOptions.url\n : (request as any).routerPath;\n const requestSize = parseContentLength(request.headers[\"content-length\"]);\n const responseSize = parseContentLength(\n reply.getHeader(\"content-length\"),\n );\n const responseTime = getResponseTime(reply);\n client.consumerRegistry.addOrUpdateConsumer(consumer);\n client.requestCounter.addRequest({\n consumer: consumer?.identifier,\n method: request.method,\n path,\n statusCode: reply.statusCode,\n responseTime,\n requestSize,\n responseSize,\n });\n\n if (\n (reply.statusCode === 400 || reply.statusCode === 422) &&\n reply.payload\n ) {\n try {\n const parsedPayload = JSON.parse(reply.payload);\n const validationErrors: ValidationError[] = [];\n\n if (\n (!parsedPayload.code ||\n parsedPayload.code === \"FST_ERR_VALIDATION\") &&\n typeof parsedPayload.message === \"string\"\n ) {\n validationErrors.push(...extractAjvErrors(parsedPayload.message));\n } else if (Array.isArray(parsedPayload.message)) {\n validationErrors.push(\n ...extractNestValidationErrors(parsedPayload.message),\n );\n }\n\n validationErrors.forEach((error) => {\n client.validationErrorCounter.addValidationError({\n consumer: consumer?.identifier,\n method: request.method,\n path: path,\n ...error,\n });\n });\n } catch (error) {} // eslint-disable-line no-empty\n }\n\n if (reply.statusCode === 500 && reply.serverError) {\n client.serverErrorCounter.addServerError({\n consumer: consumer?.identifier,\n method: request.method,\n path: path,\n type: reply.serverError.name,\n msg: reply.serverError.message,\n traceback: reply.serverError.stack || \"\",\n });\n }\n\n const spanHandle = request[SPAN_HANDLE_SYMBOL];\n spanHandle?.setName(`${request.method} ${path}`);\n const spans = spanHandle?.end();\n const traceId = spanHandle?.traceId;\n\n if (client.requestLogger.enabled) {\n const logs = request[LOGS_SYMBOL];\n client.requestLogger.logRequest(\n {\n timestamp: Date.now() / 1000,\n method: request.method,\n path,\n url: `${request.protocol}://${request.host ?? request.hostname}${request.originalUrl ?? request.url}`,\n headers: convertHeaders(request.headers),\n size: requestSize,\n consumer: consumer?.identifier,\n body: convertBody(request.body, request.headers[\"content-type\"]),\n },\n {\n statusCode: reply.statusCode,\n responseTime: responseTime / 1000,\n headers: convertHeaders(reply.getHeaders()),\n size: responseSize,\n body: convertBody(\n reply.payload,\n reply.getHeader(\"content-type\")?.toString(),\n ),\n },\n reply.serverError,\n logs,\n spans,\n traceId,\n );\n }\n }\n\n done();\n });\n};\n\nfunction getAppInfo(routes: PathInfo[], appVersion?: string) {\n const versions = [[\"nodejs\", process.version.replace(/^v/, \"\")]];\n const fastifyVersion = getPackageVersion(\"fastify\");\n const pinoVersion = getPackageVersion(\"pino\");\n const nestjsVersion = getPackageVersion(\"@nestjs/core\");\n const apitallyVersion = getPackageVersion(\"../..\");\n if (fastifyVersion) {\n versions.push([\"fastify\", fastifyVersion]);\n }\n if (pinoVersion) {\n versions.push([\"pino\", pinoVersion]);\n }\n if (nestjsVersion) {\n versions.push([\"nestjs\", nestjsVersion]);\n }\n if (apitallyVersion) {\n versions.push([\"apitally\", apitallyVersion]);\n }\n if (appVersion) {\n versions.push([\"app\", appVersion]);\n }\n return {\n paths: routes,\n versions: Object.fromEntries(versions),\n client: \"js:fastify\",\n };\n}\n\nexport function setConsumer(\n request: FastifyRequest,\n consumer: ApitallyConsumer | string | null | undefined,\n) {\n request.apitallyConsumer = consumer || undefined;\n}\n\nfunction getConsumer(request: FastifyRequest) {\n if (request.apitallyConsumer) {\n return consumerFromStringOrObject(request.apitallyConsumer);\n } else if (request.consumerIdentifier) {\n // For backwards compatibility\n process.emitWarning(\n \"The consumerIdentifier property on the request object is deprecated. Use apitallyConsumer instead.\",\n \"DeprecationWarning\",\n );\n return consumerFromStringOrObject(request.consumerIdentifier);\n }\n return null;\n}\n\nfunction getResponseTime(reply: FastifyReply) {\n if (reply.elapsedTime !== undefined) {\n return reply.elapsedTime;\n } else if ((reply as any).getResponseTime !== undefined) {\n return (reply as any).getResponseTime();\n }\n return 0;\n}\n\nfunction extractAjvErrors(message: string): ValidationError[] {\n try {\n const regex =\n /(?<=^|, )((?:headers|params|query|querystring|body)[/.][^ ]+)(?= )/g;\n const matches: { match: string; index: number }[] = [];\n let match: RegExpExecArray | null;\n while ((match = regex.exec(message)) !== null) {\n matches.push({ match: match[0], index: match.index });\n }\n\n return matches.map((m, i) => {\n const endIndex =\n i + 1 < matches.length ? matches[i + 1].index - 2 : message.length;\n const matchSplit = m.match.split(/[/.]/);\n if (matchSplit[0] === \"querystring\") {\n matchSplit[0] = \"query\";\n }\n return {\n loc: matchSplit.join(\".\"),\n msg: message.substring(m.index, endIndex),\n type: \"\",\n };\n });\n } catch (error) {\n return [];\n }\n}\n\nfunction extractNestValidationErrors(message: any[]): ValidationError[] {\n try {\n return message\n .filter((msg: any) => typeof msg === \"string\")\n .map((msg: any) => ({\n loc: \"\",\n msg,\n type: \"\",\n }));\n } catch (error) {\n return [];\n }\n}\n\nexport { apitallyPlugin };\n\nexport default fp(apitallyPlugin, {\n name: \"apitally\",\n});\n"],"mappings":"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","names":["LOGS_SYMBOL","Symbol","ASYNC_RESOURCE_SYMBOL","SPAN_HANDLE_SYMBOL","apitallyPlugin","fastify","config","client","ApitallyClient","routes","logsContext","AsyncLocalStorage","requestLogger","captureLogs","patchConsole","patchWinston","patchPinoLogger","log","patchNestLogger","decorateRequest","decorateReply","addHook","routeOptions","methods","Array","isArray","method","forEach","includes","toUpperCase","push","path","url","setStartupData","getAppInfo","appVersion","startSync","handleShutdown","request","reply","done","isEnabled","logs","run","spanHandle","spanCollector","startSpan","runInContext","asyncResource","AsyncResource","runInAsyncScope","raw","payload","contentType","getHeader","isSupportedContentType","error","statusCode","serverError","consumer","getConsumer","routerPath","requestSize","parseContentLength","headers","responseSize","responseTime","getResponseTime","consumerRegistry","addOrUpdateConsumer","requestCounter","addRequest","identifier","parsedPayload","JSON","parse","validationErrors","code","message","extractAjvErrors","extractNestValidationErrors","validationErrorCounter","addValidationError","serverErrorCounter","addServerError","type","name","msg","traceback","stack","setName","spans","end","traceId","enabled","logRequest","timestamp","Date","now","protocol","host","hostname","originalUrl","convertHeaders","size","body","convertBody","getHeaders","toString","versions","process","version","replace","fastifyVersion","getPackageVersion","pinoVersion","nestjsVersion","apitallyVersion","paths","Object","fromEntries","setConsumer","apitallyConsumer","undefined","consumerFromStringOrObject","consumerIdentifier","emitWarning","elapsedTime","regex","matches","match","exec","index","map","m","i","endIndex","length","matchSplit","split","loc","join","substring","filter","fp"]}