{"version":3,"file":"instrumentation.js","sourceRoot":"","sources":["../../src/instrumentation.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { context, Attributes, SpanStatusCode, trace } from '@opentelemetry/api';\nimport { getRPCMetadata, RPCType } from '@opentelemetry/core';\nimport {\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n safeExecuteInTheMiddle,\n} from '@opentelemetry/instrumentation';\nimport { SEMATTRS_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';\nimport type {\n HookHandlerDoneFunction,\n FastifyInstance,\n FastifyRequest,\n FastifyReply,\n} from 'fastify';\nimport { hooksNamesToWrap } from './constants';\nimport {\n AttributeNames,\n FastifyNames,\n FastifyTypes,\n} from './enums/AttributeNames';\nimport type { HandlerOriginal, PluginFastifyReply } from './internal-types';\nimport type { FastifyInstrumentationConfig } from './types';\nimport {\n endSpan,\n safeExecuteInTheMiddleMaybePromise,\n startSpan,\n} from './utils';\n/** @knipignore */\nimport { PACKAGE_NAME, PACKAGE_VERSION } from './version';\n\nexport const ANONYMOUS_NAME = 'anonymous';\n\n/** Fastify instrumentation for OpenTelemetry */\nexport class FastifyInstrumentation extends InstrumentationBase {\n constructor(config: FastifyInstrumentationConfig = {}) {\n super(PACKAGE_NAME, PACKAGE_VERSION, config);\n }\n\n init() {\n return [\n new InstrumentationNodeModuleDefinition(\n 'fastify',\n ['>=3.0.0 <6'],\n moduleExports => {\n return this._patchConstructor(moduleExports);\n }\n ),\n ];\n }\n\n private _hookOnRequest() {\n const instrumentation = this;\n return function onRequest(\n request: FastifyRequest,\n reply: FastifyReply,\n done: HookHandlerDoneFunction\n ) {\n if (!instrumentation.isEnabled()) {\n return done();\n }\n instrumentation._wrap(reply, 'send', instrumentation._patchSend());\n\n const anyRequest = request as any;\n\n const rpcMetadata = getRPCMetadata(context.active());\n const routeName = anyRequest.routeOptions\n ? anyRequest.routeOptions.url // since fastify@4.10.0\n : request.routerPath;\n if (routeName && rpcMetadata?.type === RPCType.HTTP) {\n rpcMetadata.route = routeName;\n }\n done();\n };\n }\n\n private _wrapHandler(\n pluginName: string,\n hookName: string,\n original: (...args: unknown[]) => Promise,\n syncFunctionWithDone: boolean\n ): () => Promise {\n const instrumentation = this;\n this._diag.debug('Patching fastify route.handler function');\n\n return function (this: any, ...args: unknown[]): Promise {\n if (!instrumentation.isEnabled()) {\n return original.apply(this, args);\n }\n\n const name = original.name || pluginName || ANONYMOUS_NAME;\n const spanName = `${FastifyNames.MIDDLEWARE} - ${name}`;\n\n const reply = args[1] as PluginFastifyReply;\n\n const span = startSpan(reply, instrumentation.tracer, spanName, {\n [AttributeNames.FASTIFY_TYPE]: FastifyTypes.MIDDLEWARE,\n [AttributeNames.PLUGIN_NAME]: pluginName,\n [AttributeNames.HOOK_NAME]: hookName,\n });\n\n const origDone =\n syncFunctionWithDone &&\n (args[args.length - 1] as HookHandlerDoneFunction);\n if (origDone) {\n args[args.length - 1] = function (\n ...doneArgs: Parameters\n ) {\n endSpan(reply);\n origDone.apply(this, doneArgs);\n };\n }\n\n return context.with(trace.setSpan(context.active(), span), () => {\n return safeExecuteInTheMiddleMaybePromise(\n () => {\n return original.apply(this, args);\n },\n err => {\n if (err instanceof Error) {\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: err.message,\n });\n span.recordException(err);\n }\n // async hooks should end the span as soon as the promise is resolved\n if (!syncFunctionWithDone) {\n endSpan(reply);\n }\n }\n );\n });\n };\n }\n\n private _wrapAddHook(): (\n original: FastifyInstance['addHook']\n ) => () => FastifyInstance {\n const instrumentation = this;\n this._diag.debug('Patching fastify server.addHook function');\n\n return function (\n original: FastifyInstance['addHook']\n ): () => FastifyInstance {\n return function wrappedAddHook(this: any, ...args: any) {\n const name = args[0] as string;\n const handler = args[1] as HandlerOriginal;\n const pluginName = this.pluginName;\n if (!hooksNamesToWrap.has(name)) {\n return original.apply(this, args);\n }\n\n const syncFunctionWithDone =\n typeof args[args.length - 1] === 'function' &&\n handler.constructor.name !== 'AsyncFunction';\n\n return original.apply(this, [\n name,\n instrumentation._wrapHandler(\n pluginName,\n name,\n handler,\n syncFunctionWithDone\n ),\n ] as never);\n };\n };\n }\n\n private _patchConstructor(moduleExports: {\n fastify: () => FastifyInstance;\n }): () => FastifyInstance {\n const instrumentation = this;\n\n function fastify(this: FastifyInstance, ...args: any) {\n const app: FastifyInstance = moduleExports.fastify.apply(this, args);\n app.addHook('onRequest', instrumentation._hookOnRequest());\n app.addHook('preHandler', instrumentation._hookPreHandler());\n\n instrumentation._wrap(app, 'addHook', instrumentation._wrapAddHook());\n\n return app;\n }\n\n fastify.fastify = fastify;\n fastify.default = fastify;\n return fastify;\n }\n\n private _patchSend() {\n const instrumentation = this;\n this._diag.debug('Patching fastify reply.send function');\n\n return function patchSend(\n original: () => FastifyReply\n ): () => FastifyReply {\n return function send(this: FastifyReply, ...args: any) {\n const maybeError: any = args[0];\n\n if (!instrumentation.isEnabled()) {\n return original.apply(this, args);\n }\n\n return safeExecuteInTheMiddle(\n () => {\n return original.apply(this, args);\n },\n err => {\n if (!err && maybeError instanceof Error) {\n err = maybeError;\n }\n endSpan(this, err);\n }\n );\n };\n };\n }\n\n private _hookPreHandler() {\n const instrumentation = this;\n this._diag.debug('Patching fastify preHandler function');\n\n return function preHandler(\n this: any,\n request: FastifyRequest,\n reply: FastifyReply,\n done: HookHandlerDoneFunction\n ) {\n if (!instrumentation.isEnabled()) {\n return done();\n }\n const anyRequest = request as any;\n\n const handler =\n anyRequest.routeOptions?.handler || anyRequest.context?.handler;\n\n const handlerName = handler?.name.startsWith('bound ')\n ? handler.name.substr(6)\n : handler?.name;\n const spanName = `${FastifyNames.REQUEST_HANDLER} - ${\n handlerName || this.pluginName || ANONYMOUS_NAME\n }`;\n\n const spanAttributes: Attributes = {\n [AttributeNames.PLUGIN_NAME]: this.pluginName,\n [AttributeNames.FASTIFY_TYPE]: FastifyTypes.REQUEST_HANDLER,\n [SEMATTRS_HTTP_ROUTE]: anyRequest.routeOptions\n ? anyRequest.routeOptions.url // since fastify@4.10.0\n : request.routerPath,\n };\n if (handlerName) {\n spanAttributes[AttributeNames.FASTIFY_NAME] = handlerName;\n }\n const span = startSpan(\n reply,\n instrumentation.tracer,\n spanName,\n spanAttributes\n );\n\n const { requestHook } = instrumentation.getConfig();\n if (requestHook) {\n safeExecuteInTheMiddle(\n () => requestHook(span, { request }),\n e => {\n if (e) {\n instrumentation._diag.error('request hook failed', e);\n }\n },\n true\n );\n }\n\n return context.with(trace.setSpan(context.active(), span), () => {\n done();\n });\n };\n }\n}\n"]}