Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
"@opentelemetry/core": "^2.6.1",
"@opentelemetry/instrumentation": "^0.214.0",
"@opentelemetry/sdk-trace-base": "^2.6.1",
"@opentelemetry/semantic-conventions": "^1.40.0",
"@sentry/conventions": "^0.12.0",
"@sentry/core": "10.58.0",
"@sentry/node-core": "10.58.0",
"@sentry/opentelemetry": "10.58.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* Original HTTP method sent by the client in the request line.
*/
export const ATTR_HTTP_REQUEST_METHOD_ORIGINAL = 'http.request.method_original' as const;

/**
* Duration of HTTP client requests.
*/
export const METRIC_HTTP_CLIENT_REQUEST_DURATION = 'http.client.request.duration' as const;
65 changes: 32 additions & 33 deletions packages/node/src/integrations/node-fetch/vendored/undici.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,21 @@ import {
trace,
ValueType,
} from '@opentelemetry/api';
import { ATTR_HTTP_REQUEST_METHOD_ORIGINAL, METRIC_HTTP_CLIENT_REQUEST_DURATION } from './semconv';
import {
ATTR_ERROR_TYPE,
ATTR_HTTP_REQUEST_METHOD,
ATTR_HTTP_REQUEST_METHOD_ORIGINAL,
ATTR_HTTP_RESPONSE_STATUS_CODE,
ATTR_NETWORK_PEER_ADDRESS,
ATTR_NETWORK_PEER_PORT,
ATTR_SERVER_ADDRESS,
ATTR_SERVER_PORT,
ATTR_URL_FULL,
ATTR_URL_PATH,
ATTR_URL_QUERY,
ATTR_URL_SCHEME,
ATTR_USER_AGENT_ORIGINAL,
METRIC_HTTP_CLIENT_REQUEST_DURATION,
} from '@opentelemetry/semantic-conventions';
ERROR_TYPE,
HTTP_REQUEST_METHOD,
HTTP_RESPONSE_STATUS_CODE,
NETWORK_PEER_ADDRESS,
NETWORK_PEER_PORT,
SERVER_ADDRESS,
SERVER_PORT,
URL_FULL,
URL_PATH,
URL_QUERY,
URL_SCHEME,
USER_AGENT_ORIGINAL,
} from '@sentry/conventions/attributes';

import type {
ListenerRecord,
Expand Down Expand Up @@ -225,21 +224,21 @@ export class UndiciInstrumentation extends InstrumentationBase<UndiciInstrumenta
const urlScheme = requestUrl.protocol.replace(':', '');
const requestMethod = this.getRequestMethod(request.method);
const attributes: Attributes = {
[ATTR_HTTP_REQUEST_METHOD]: requestMethod,
[HTTP_REQUEST_METHOD]: requestMethod,
[ATTR_HTTP_REQUEST_METHOD_ORIGINAL]: request.method,
[ATTR_URL_FULL]: requestUrl.toString(),
[ATTR_URL_PATH]: requestUrl.pathname,
[ATTR_URL_QUERY]: requestUrl.search,
[ATTR_URL_SCHEME]: urlScheme,
[URL_FULL]: requestUrl.toString(),
[URL_PATH]: requestUrl.pathname,
[URL_QUERY]: requestUrl.search,
[URL_SCHEME]: urlScheme,
};

const schemePorts: Record<string, string> = { https: '443', http: '80' };
const serverAddress = requestUrl.hostname;
const serverPort = requestUrl.port || schemePorts[urlScheme];

attributes[ATTR_SERVER_ADDRESS] = serverAddress;
attributes[SERVER_ADDRESS] = serverAddress;
if (serverPort && !isNaN(Number(serverPort))) {
attributes[ATTR_SERVER_PORT] = Number(serverPort);
attributes[SERVER_PORT] = Number(serverPort);
}

// Get user agent from headers
Expand All @@ -251,7 +250,7 @@ export class UndiciInstrumentation extends InstrumentationBase<UndiciInstrumenta
// we're going to take last one like `curl` does
// ref: https://curl.se/docs/manpage.html#-A
const userAgent = Array.isArray(userAgentValues) ? userAgentValues[userAgentValues.length - 1] : userAgentValues;
attributes[ATTR_USER_AGENT_ORIGINAL] = userAgent;
attributes[USER_AGENT_ORIGINAL] = userAgent;
}

// Get attributes from the hook if present
Expand Down Expand Up @@ -335,8 +334,8 @@ export class UndiciInstrumentation extends InstrumentationBase<UndiciInstrumenta
const { span } = record;
const { remoteAddress, remotePort } = socket;
const spanAttributes: Attributes = {
[ATTR_NETWORK_PEER_ADDRESS]: remoteAddress,
[ATTR_NETWORK_PEER_PORT]: remotePort,
[NETWORK_PEER_ADDRESS]: remoteAddress,
[NETWORK_PEER_PORT]: remotePort,
};

// After hooks have been processed (which may modify request headers)
Expand Down Expand Up @@ -368,7 +367,7 @@ export class UndiciInstrumentation extends InstrumentationBase<UndiciInstrumenta

const { span, attributes } = record;
const spanAttributes: Attributes = {
[ATTR_HTTP_RESPONSE_STATUS_CODE]: response.statusCode,
[HTTP_RESPONSE_STATUS_CODE]: response.statusCode,
};

const config = this.getConfig();
Expand Down Expand Up @@ -459,7 +458,7 @@ export class UndiciInstrumentation extends InstrumentationBase<UndiciInstrumenta
this._recordFromReq.delete(request);

// Record metrics (with the error)
attributes[ATTR_ERROR_TYPE] = error.message;
attributes[ERROR_TYPE] = error.message;
this.recordRequestDuration(attributes, startTime);
}

Expand All @@ -468,12 +467,12 @@ export class UndiciInstrumentation extends InstrumentationBase<UndiciInstrumenta
const metricsAttributes: Attributes = {};
// Get the attribs already in span attributes
const keysToCopy = [
ATTR_HTTP_RESPONSE_STATUS_CODE,
ATTR_HTTP_REQUEST_METHOD,
ATTR_SERVER_ADDRESS,
ATTR_SERVER_PORT,
ATTR_URL_SCHEME,
ATTR_ERROR_TYPE,
HTTP_RESPONSE_STATUS_CODE,
HTTP_REQUEST_METHOD,
SERVER_ADDRESS,
SERVER_PORT,
URL_SCHEME,
ERROR_TYPE,
];
keysToCopy.forEach(key => {
if (key in attributes) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,6 @@
*/
/* eslint-disable */

/*
* This file contains constants for values that where replaced/removed from
* Semantic Conventions long enough ago that they do not have `ATTR_*`
* constants in the `@opentelemetry/semantic-conventions` package. Eventually
* it is expected that this instrumention will be updated to emit telemetry
* using modern Semantic Conventions, dropping the need for the constants in
* this file.
*/

/**
* The message destination name. This might be equal to the span name but is required nevertheless.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,15 @@
* @example create
* @example process
*
* @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
*
* @deprecated Replaced by `messaging.operation.type`.
*/
export const ATTR_MESSAGING_OPERATION = 'messaging.operation' as const;

/**
* The messaging system as identified by the client instrumentation.
*
* @note The actual messaging system may differ from the one known by the client. For example, when using Kafka client libraries to communicate with Azure Event Hubs, the `messaging.system` is set to `kafka` based on the instrumentation's best knowledge.
*
* @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
*/
export const ATTR_MESSAGING_SYSTEM = 'messaging.system' as const;

/**
* Deprecated, use `server.address` on client spans and `client.address` on server spans.
*
* @example example.com
*
* @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
*
* @deprecated Replaced by `server.address` on client spans and `client.address` on server spans.
*/
export const ATTR_NET_PEER_NAME = 'net.peer.name' as const;
Expand All @@ -52,8 +39,6 @@ export const ATTR_NET_PEER_NAME = 'net.peer.name' as const;
*
* @example 8080
*
* @experimental This attribute is experimental and is subject to breaking changes in minor releases of `@opentelemetry/semantic-conventions`.
*
* @deprecated Replaced by `server.port` on client spans and `client.port` on server spans.
*/
export const ATTR_NET_PEER_PORT = 'net.peer.port' as const;
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@

import { Context, createContextKey, diag, Span, Attributes, AttributeValue } from '@opentelemetry/api';
import { SemconvStability } from '@opentelemetry/instrumentation';
import { ATTR_SERVER_ADDRESS, ATTR_SERVER_PORT } from '@opentelemetry/semantic-conventions';
import { ATTR_MESSAGING_SYSTEM, ATTR_NET_PEER_NAME, ATTR_NET_PEER_PORT } from './semconv';
import { MESSAGING_SYSTEM, SERVER_ADDRESS, SERVER_PORT } from '@sentry/conventions/attributes';
import { ATTR_NET_PEER_NAME, ATTR_NET_PEER_PORT } from './semconv';
import { ATTR_MESSAGING_PROTOCOL, ATTR_MESSAGING_PROTOCOL_VERSION, ATTR_MESSAGING_URL } from './semconv-obsolete';
import type { Connection, Channel, ConfirmChannel, Options } from './amqplib-types';
import type { ConsumeMessage, Message } from './types';
Expand Down Expand Up @@ -95,7 +95,7 @@ export const getConnectionAttributesFromServer = (conn: Connection): Attributes
const product = conn.serverProperties.product?.toLowerCase?.();
if (product) {
return {
[ATTR_MESSAGING_SYSTEM]: product,
[MESSAGING_SYSTEM]: product,
};
} else {
return {};
Expand Down Expand Up @@ -127,7 +127,7 @@ export const getConnectionAttributesFromUrl = (
}
if (netSemconvStability & SemconvStability.STABLE) {
Object.assign(attributes, {
...extractConnectionAttributeOrLog(url, ATTR_SERVER_ADDRESS, hostname, 'hostname'),
...extractConnectionAttributeOrLog(url, SERVER_ADDRESS, hostname, 'hostname'),
});
}

Expand All @@ -136,7 +136,7 @@ export const getConnectionAttributesFromUrl = (
Object.assign(attributes, extractConnectionAttributeOrLog(url, ATTR_NET_PEER_PORT, port, 'port'));
}
if (netSemconvStability & SemconvStability.STABLE) {
Object.assign(attributes, extractConnectionAttributeOrLog(url, ATTR_SERVER_PORT, port, 'port'));
Object.assign(attributes, extractConnectionAttributeOrLog(url, SERVER_PORT, port, 'port'));
}
} else {
const censoredUrl = censorPassword(url);
Expand All @@ -157,7 +157,7 @@ export const getConnectionAttributesFromUrl = (
}
if (netSemconvStability & SemconvStability.STABLE) {
Object.assign(attributes, {
...extractConnectionAttributeOrLog(censoredUrl, ATTR_SERVER_ADDRESS, hostname, 'hostname'),
...extractConnectionAttributeOrLog(censoredUrl, SERVER_ADDRESS, hostname, 'hostname'),
});
}

Expand All @@ -166,7 +166,7 @@ export const getConnectionAttributesFromUrl = (
Object.assign(attributes, extractConnectionAttributeOrLog(censoredUrl, ATTR_NET_PEER_PORT, port, 'port'));
}
if (netSemconvStability & SemconvStability.STABLE) {
Object.assign(attributes, extractConnectionAttributeOrLog(censoredUrl, ATTR_SERVER_PORT, port, 'port'));
Object.assign(attributes, extractConnectionAttributeOrLog(censoredUrl, SERVER_PORT, port, 'port'));
}
} catch (err) {
diag.error('amqplib instrumentation: error while extracting connection details from connection url', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
import { setHttpServerSpanRouteAttribute } from '../../../../utils/setHttpServerSpanRouteAttribute';
import type { InstrumentationConfig } from '@opentelemetry/instrumentation';
import { InstrumentationBase, InstrumentationNodeModuleDefinition, isWrapped } from '@opentelemetry/instrumentation';
import { ATTR_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';
import { HTTP_ROUTE } from '@sentry/conventions/attributes';
import { replaceCurrentStackRoute, addNewStackLayer, generateRoute } from './utils';

const PACKAGE_NAME = '@sentry/instrumentation-connect';
Expand Down Expand Up @@ -82,7 +82,7 @@ export class ConnectInstrumentation extends InstrumentationBase {
op: `${connectType}.connect`,
attributes: {
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.otel.connect',
[ATTR_HTTP_ROUTE]: routeName.length > 0 ? routeName : '/',
[HTTP_ROUTE]: routeName.length > 0 ? routeName : '/',
[AttributeNames.CONNECT_TYPE]: connectType,
[AttributeNames.CONNECT_NAME]: connectName,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
InstrumentationNodeModuleDefinition,
safeExecuteInTheMiddle,
} from '@opentelemetry/instrumentation';
import { SEMATTRS_HTTP_ROUTE } from '@opentelemetry/semantic-conventions';
import { HTTP_ROUTE } from '@sentry/conventions/attributes';
import type { Span } from '@sentry/core';
import {
getClient,
Expand Down Expand Up @@ -265,8 +265,7 @@ export class FastifyInstrumentationV3 extends InstrumentationBase<FastifyInstrum
const spanAttributes: Attributes = {
[AttributeNames.PLUGIN_NAME]: this.pluginName,
[AttributeNames.FASTIFY_TYPE]: FastifyTypes.REQUEST_HANDLER,
// eslint-disable-next-line typescript/no-deprecated
[SEMATTRS_HTTP_ROUTE]: anyRequest.routeOptions
[HTTP_ROUTE]: anyRequest.routeOptions
? anyRequest.routeOptions.url // since fastify@4.10.0
: request.routerPath,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,7 @@

import * as dc from 'node:diagnostics_channel';
import { context, trace, SpanStatusCode, propagation, diag, type Span } from '@opentelemetry/api';
import {
ATTR_HTTP_ROUTE,
ATTR_HTTP_RESPONSE_STATUS_CODE,
ATTR_HTTP_REQUEST_METHOD,
ATTR_URL_PATH,
} from '@opentelemetry/semantic-conventions';
import { HTTP_REQUEST_METHOD, HTTP_RESPONSE_STATUS_CODE, HTTP_ROUTE, URL_PATH } from '@sentry/conventions/attributes';
import { InstrumentationBase, type InstrumentationConfig } from '@opentelemetry/instrumentation';
import { SDK_VERSION } from '@sentry/core';
import { setHttpServerSpanRouteAttribute } from '../../../../utils/setHttpServerSpanRouteAttribute';
Expand Down Expand Up @@ -173,7 +168,7 @@ export class FastifyOtelInstrumentation extends InstrumentationBase<FastifyOtelI
routeOptions[hook] = handlerWrapper(handlerLike, hook, {
[ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - route -> ${hook}`,
[ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.ROUTE,
[ATTR_HTTP_ROUTE]: routeOptions.url,
[HTTP_ROUTE]: routeOptions.url,
[ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:
handlerLike.name?.length > 0 ? handlerLike.name : ANONYMOUS_FUNCTION_NAME,
});
Expand All @@ -185,7 +180,7 @@ export class FastifyOtelInstrumentation extends InstrumentationBase<FastifyOtelI
handlerWrapper(handler, hook, {
[ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - route -> ${hook}`,
[ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.ROUTE,
[ATTR_HTTP_ROUTE]: routeOptions.url,
[HTTP_ROUTE]: routeOptions.url,
[ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:
handler.name?.length > 0 ? handler.name : ANONYMOUS_FUNCTION_NAME,
}),
Expand Down Expand Up @@ -216,7 +211,7 @@ export class FastifyOtelInstrumentation extends InstrumentationBase<FastifyOtelI
routeOptions.handler = handlerWrapper(routeOptions.handler, 'handler', {
[ATTRIBUTE_NAMES.HOOK_NAME]: `${this.pluginName} - route-handler`,
[ATTRIBUTE_NAMES.FASTIFY_TYPE]: HOOK_TYPES.HANDLER,
[ATTR_HTTP_ROUTE]: routeOptions.url,
[HTTP_ROUTE]: routeOptions.url,
[ATTRIBUTE_NAMES.HOOK_CALLBACK_NAME]:
routeOptions.handler.name.length > 0 ? routeOptions.handler.name : ANONYMOUS_FUNCTION_NAME,
});
Expand All @@ -241,12 +236,12 @@ export class FastifyOtelInstrumentation extends InstrumentationBase<FastifyOtelI

const attributes: Record<string, string> = {
[ATTRIBUTE_NAMES.ROOT]: PACKAGE_NAME,
[ATTR_HTTP_REQUEST_METHOD]: request.method,
[ATTR_URL_PATH]: request.url,
[HTTP_REQUEST_METHOD]: request.method,
[URL_PATH]: request.url,
};

if (request.routeOptions.url != null) {
attributes[ATTR_HTTP_ROUTE] = request.routeOptions.url;
attributes[HTTP_ROUTE] = request.routeOptions.url;
}

const span = this[kInstrumentation].tracer.startSpan('request', { attributes }, ctx);
Expand All @@ -271,7 +266,7 @@ export class FastifyOtelInstrumentation extends InstrumentationBase<FastifyOtelI

if (span != null) {
span.setAttributes({
[ATTR_HTTP_RESPONSE_STATUS_CODE]: reply.statusCode,
[HTTP_RESPONSE_STATUS_CODE]: reply.statusCode,
});
span.end();
}
Expand Down Expand Up @@ -300,7 +295,7 @@ export class FastifyOtelInstrumentation extends InstrumentationBase<FastifyOtelI
}

span.setAttributes({
[ATTR_HTTP_RESPONSE_STATUS_CODE]: reply.statusCode,
[HTTP_RESPONSE_STATUS_CODE]: reply.statusCode,
});
span.end();
}
Expand Down
Loading
Loading