{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.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 */\nimport {\n Context,\n createContextKey,\n diag,\n HrTime,\n Span,\n Attributes,\n AttributeValue,\n} from '@opentelemetry/api';\nimport {\n SEMATTRS_MESSAGING_PROTOCOL,\n SEMATTRS_MESSAGING_PROTOCOL_VERSION,\n SEMATTRS_MESSAGING_SYSTEM,\n SEMATTRS_MESSAGING_URL,\n SEMATTRS_NET_PEER_NAME,\n SEMATTRS_NET_PEER_PORT,\n} from '@opentelemetry/semantic-conventions';\nimport type * as amqp from 'amqplib';\n\nexport const MESSAGE_STORED_SPAN: unique symbol = Symbol(\n 'opentelemetry.amqplib.message.stored-span'\n);\nexport const CHANNEL_SPANS_NOT_ENDED: unique symbol = Symbol(\n 'opentelemetry.amqplib.channel.spans-not-ended'\n);\nexport const CHANNEL_CONSUME_TIMEOUT_TIMER: unique symbol = Symbol(\n 'opentelemetry.amqplib.channel.consumer-timeout-timer'\n);\nexport const CONNECTION_ATTRIBUTES: unique symbol = Symbol(\n 'opentelemetry.amqplib.connection.attributes'\n);\n\nexport type InstrumentationPublishChannel = (\n | amqp.Channel\n | amqp.ConfirmChannel\n) & { connection: { [CONNECTION_ATTRIBUTES]: Attributes } };\nexport type InstrumentationConsumeChannel = amqp.Channel & {\n connection: { [CONNECTION_ATTRIBUTES]: Attributes };\n [CHANNEL_SPANS_NOT_ENDED]?: {\n msg: amqp.ConsumeMessage;\n timeOfConsume: HrTime;\n }[];\n [CHANNEL_CONSUME_TIMEOUT_TIMER]?: NodeJS.Timeout;\n};\nexport type InstrumentationMessage = amqp.Message & {\n [MESSAGE_STORED_SPAN]?: Span;\n};\n\nconst IS_CONFIRM_CHANNEL_CONTEXT_KEY: symbol = createContextKey(\n 'opentelemetry.amqplib.channel.is-confirm-channel'\n);\n\nexport const normalizeExchange = (exchangeName: string) =>\n exchangeName !== '' ? exchangeName : '';\n\nconst censorPassword = (url: string): string => {\n return url.replace(/:[^:@/]*@/, ':***@');\n};\n\nconst getPort = (\n portFromUrl: number | undefined,\n resolvedProtocol: string\n): number => {\n // we are using the resolved protocol which is upper case\n // this code mimic the behavior of the amqplib which is used to set connection params\n return portFromUrl || (resolvedProtocol === 'AMQP' ? 5672 : 5671);\n};\n\nconst getProtocol = (protocolFromUrl: string | undefined): string => {\n const resolvedProtocol = protocolFromUrl || 'amqp';\n // the substring removed the ':' part of the protocol ('amqp:' -> 'amqp')\n const noEndingColon = resolvedProtocol.endsWith(':')\n ? resolvedProtocol.substring(0, resolvedProtocol.length - 1)\n : resolvedProtocol;\n // upper cases to match spec\n return noEndingColon.toUpperCase();\n};\n\nconst getHostname = (hostnameFromUrl: string | undefined): string => {\n // if user supplies empty hostname, it gets forwarded to 'net' package which default it to localhost.\n // https://nodejs.org/docs/latest-v12.x/api/net.html#net_socket_connect_options_connectlistener\n return hostnameFromUrl || 'localhost';\n};\n\nconst extractConnectionAttributeOrLog = (\n url: string | amqp.Options.Connect,\n attributeKey: string,\n attributeValue: AttributeValue,\n nameForLog: string\n): Attributes => {\n if (attributeValue) {\n return { [attributeKey]: attributeValue };\n } else {\n diag.error(\n `amqplib instrumentation: could not extract connection attribute ${nameForLog} from user supplied url`,\n {\n url,\n }\n );\n return {};\n }\n};\n\nexport const getConnectionAttributesFromServer = (\n conn: amqp.Connection['connection']\n): Attributes => {\n const product = conn.serverProperties.product?.toLowerCase?.();\n if (product) {\n return {\n [SEMATTRS_MESSAGING_SYSTEM]: product,\n };\n } else {\n return {};\n }\n};\n\nexport const getConnectionAttributesFromUrl = (\n url: string | amqp.Options.Connect\n): Attributes => {\n const attributes: Attributes = {\n [SEMATTRS_MESSAGING_PROTOCOL_VERSION]: '0.9.1', // this is the only protocol supported by the instrumented library\n };\n\n url = url || 'amqp://localhost';\n if (typeof url === 'object') {\n const connectOptions = url as amqp.Options.Connect;\n\n const protocol = getProtocol(connectOptions?.protocol);\n Object.assign(attributes, {\n ...extractConnectionAttributeOrLog(\n url,\n SEMATTRS_MESSAGING_PROTOCOL,\n protocol,\n 'protocol'\n ),\n });\n\n const hostname = getHostname(connectOptions?.hostname);\n Object.assign(attributes, {\n ...extractConnectionAttributeOrLog(\n url,\n SEMATTRS_NET_PEER_NAME,\n hostname,\n 'hostname'\n ),\n });\n\n const port = getPort(connectOptions.port, protocol);\n Object.assign(attributes, {\n ...extractConnectionAttributeOrLog(\n url,\n SEMATTRS_NET_PEER_PORT,\n port,\n 'port'\n ),\n });\n } else {\n const censoredUrl = censorPassword(url);\n attributes[SEMATTRS_MESSAGING_URL] = censoredUrl;\n try {\n const urlParts = new URL(censoredUrl);\n\n const protocol = getProtocol(urlParts.protocol);\n Object.assign(attributes, {\n ...extractConnectionAttributeOrLog(\n censoredUrl,\n SEMATTRS_MESSAGING_PROTOCOL,\n protocol,\n 'protocol'\n ),\n });\n\n const hostname = getHostname(urlParts.hostname);\n Object.assign(attributes, {\n ...extractConnectionAttributeOrLog(\n censoredUrl,\n SEMATTRS_NET_PEER_NAME,\n hostname,\n 'hostname'\n ),\n });\n\n const port = getPort(\n urlParts.port ? parseInt(urlParts.port) : undefined,\n protocol\n );\n Object.assign(attributes, {\n ...extractConnectionAttributeOrLog(\n censoredUrl,\n SEMATTRS_NET_PEER_PORT,\n port,\n 'port'\n ),\n });\n } catch (err) {\n diag.error(\n 'amqplib instrumentation: error while extracting connection details from connection url',\n {\n censoredUrl,\n err,\n }\n );\n }\n }\n return attributes;\n};\n\nexport const markConfirmChannelTracing = (context: Context) => {\n return context.setValue(IS_CONFIRM_CHANNEL_CONTEXT_KEY, true);\n};\n\nexport const unmarkConfirmChannelTracing = (context: Context) => {\n return context.deleteValue(IS_CONFIRM_CHANNEL_CONTEXT_KEY);\n};\n\nexport const isConfirmChannelTracing = (context: Context) => {\n return context.getValue(IS_CONFIRM_CHANNEL_CONTEXT_KEY) === true;\n};\n"]}