UNPKG

@sentry/node

Version:

Sentry Node SDK using OpenTelemetry for performance instrumentation

137 lines (134 loc) 4.99 kB
import { getActiveSpan, SPAN_STATUS_ERROR, startInactiveSpan, SPAN_KIND, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core'; import { AttributeNames } from './enums/AttributeNames.js'; import { SpanNames } from './enums/SpanNames.js'; import { DB_SYSTEM_VALUE_POSTGRESQL, ATTR_DB_CONNECTION_STRING } from './semconv.js'; import { NET_PEER_PORT, NET_PEER_NAME, DB_USER, DB_NAME, DB_SYSTEM, DB_STATEMENT } from '@sentry/conventions/attributes'; const ORIGIN = "auto.db.otel.postgres"; function getQuerySpanName(dbName, queryConfig) { if (!queryConfig) return SpanNames.QUERY_PREFIX; const command = typeof queryConfig.name === "string" && queryConfig.name ? queryConfig.name : parseNormalizedOperationName(queryConfig.text); return `${SpanNames.QUERY_PREFIX}:${command}${dbName ? ` ${dbName}` : ""}`; } function parseNormalizedOperationName(queryText) { const trimmedQuery = queryText.trim(); const indexOfFirstSpace = trimmedQuery.indexOf(" "); let sqlCommand = indexOfFirstSpace === -1 ? trimmedQuery : trimmedQuery.slice(0, indexOfFirstSpace); sqlCommand = sqlCommand.toUpperCase(); return sqlCommand.endsWith(";") ? sqlCommand.slice(0, -1) : sqlCommand; } function parseAndMaskConnectionString(connectionString) { try { const url = new URL(connectionString); url.username = ""; url.password = ""; return url.toString(); } catch { return "postgresql://localhost:5432/"; } } function getConnectionString(params) { if ("connectionString" in params && params.connectionString) { return parseAndMaskConnectionString(params.connectionString); } const host = params.host || "localhost"; const port = params.port || 5432; const database = params.database || ""; return `postgresql://${host}:${port}/${database}`; } function getPort(port) { if (Number.isInteger(port)) { return port; } return void 0; } function getSemanticAttributesFromConnection(params) { return { [DB_SYSTEM]: DB_SYSTEM_VALUE_POSTGRESQL, [DB_NAME]: params.database, [ATTR_DB_CONNECTION_STRING]: getConnectionString(params), [DB_USER]: params.user, [NET_PEER_NAME]: params.host, // required [NET_PEER_PORT]: getPort(params.port) }; } function getSemanticAttributesFromPoolConnection(params) { let url; try { url = params.connectionString ? new URL(params.connectionString) : void 0; } catch { url = void 0; } return { [AttributeNames.IDLE_TIMEOUT_MILLIS]: params.idleTimeoutMillis, [AttributeNames.MAX_CLIENT]: params.maxClient, [DB_SYSTEM]: DB_SYSTEM_VALUE_POSTGRESQL, [DB_NAME]: url?.pathname.slice(1) ?? params.database, [ATTR_DB_CONNECTION_STRING]: getConnectionString(params), [NET_PEER_NAME]: url?.hostname ?? params.host, [NET_PEER_PORT]: Number(url?.port) || getPort(params.port), [DB_USER]: url?.username ?? params.user }; } function shouldSkipInstrumentation() { return getActiveSpan() === void 0; } function handleConfigQuery(queryConfig) { const { connectionParameters } = this; const dbName = connectionParameters.database; const spanName = getQuerySpanName(dbName, queryConfig); const span = startInactiveSpan({ name: spanName, kind: SPAN_KIND.CLIENT, attributes: { ...getSemanticAttributesFromConnection(connectionParameters), [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: ORIGIN } }); if (!queryConfig) { return span; } if (queryConfig.text) { span.setAttribute(DB_STATEMENT, queryConfig.text); } if (typeof queryConfig.name === "string") { span.setAttribute(AttributeNames.PG_PLAN, queryConfig.name); } return span; } function patchCallback(span, cb) { return function patchedCallback(err, res) { if (err) { span.setStatus({ code: SPAN_STATUS_ERROR, message: err.message }); } span.end(); cb.call(this, err, res); }; } function patchCallbackPGPool(span, cb) { return function patchedCallback(err, res, done) { if (err) { span.setStatus({ code: SPAN_STATUS_ERROR, message: err.message }); } span.end(); cb.call(this, err, res, done); }; } function patchClientConnectCallback(span, cb) { return function patchedClientConnectCallback(...args) { const err = args[0]; if (err instanceof Error) { span.setStatus({ code: SPAN_STATUS_ERROR, message: err.message }); } span.end(); cb.apply(this, args); }; } function getErrorMessage(e) { return typeof e === "object" && e !== null && "message" in e ? String(e.message) : void 0; } function isObjectWithTextString(it) { return typeof it === "object" && typeof it?.text === "string"; } export { ORIGIN, getConnectionString, getErrorMessage, getQuerySpanName, getSemanticAttributesFromConnection, getSemanticAttributesFromPoolConnection, handleConfigQuery, isObjectWithTextString, parseAndMaskConnectionString, parseNormalizedOperationName, patchCallback, patchCallbackPGPool, patchClientConnectCallback, shouldSkipInstrumentation }; //# sourceMappingURL=utils.js.map