From 4ab15850da1f7f08c3e368d3bff96f5381f38fd8 Mon Sep 17 00:00:00 2001 From: Martin Sonnberger Date: Tue, 27 Oct 2026 15:53:26 +0100 Subject: [PATCH] refactor(core): Use convention constants for attribute keys Co-Authored-By: GPT-6 --- packages/core/src/integrations/consola.ts | 3 +- .../http/get-outgoing-span-data.ts | 3 +- .../integrations/http/server-subscription.ts | 6 ++-- packages/core/src/integrations/requestdata.ts | 13 ++++++-- packages/core/src/logs/internal.ts | 33 +++++++++++++------ packages/core/src/logs/utils.ts | 3 +- packages/core/src/metrics/internal.ts | 26 ++++++++++----- packages/core/src/server-runtime-client.ts | 3 +- .../tracing/spans/scopeContextAttributes.ts | 29 +++++++++++----- packages/core/src/tracing/spanstatus.ts | 3 +- packages/core/src/utils/timestampSequence.ts | 4 +-- 11 files changed, 87 insertions(+), 39 deletions(-) diff --git a/packages/core/src/integrations/consola.ts b/packages/core/src/integrations/consola.ts index 6385d330ec37..2c57c9e44360 100644 --- a/packages/core/src/integrations/consola.ts +++ b/packages/core/src/integrations/consola.ts @@ -1,3 +1,4 @@ +import { SENTRY_ORIGIN } from '@sentry/conventions/attributes'; import type { Client } from '../client'; import { getClient } from '../currentScopes'; import { _INTERNAL_captureLog } from '../logs/internal'; @@ -253,7 +254,7 @@ export function createConsolaReporter(options: ConsolaReporterOptions = {}): Con attributes[key] = normalize(value, normalizeDepth, normalizeMaxBreadth); } - attributes['sentry.origin'] = 'auto.log.consola'; + attributes[SENTRY_ORIGIN] = 'auto.log.consola'; if (tag) { attributes['consola.tag'] = tag; diff --git a/packages/core/src/integrations/http/get-outgoing-span-data.ts b/packages/core/src/integrations/http/get-outgoing-span-data.ts index 71ca886eb486..8f04fd161bbe 100644 --- a/packages/core/src/integrations/http/get-outgoing-span-data.ts +++ b/packages/core/src/integrations/http/get-outgoing-span-data.ts @@ -24,6 +24,7 @@ import { SERVER_PORT, URL_FULL, USER_AGENT_ORIGINAL, + HTTP_RESPONSE_STATUS_TEXT, } from '@sentry/conventions/attributes'; import { HTTP_CLIENT } from '@sentry/conventions/op'; @@ -77,7 +78,7 @@ export function setIncomingResponseSpanData(response: HttpIncomingMessage, span: [NETWORK_PROTOCOL_NAME]: 'http', [NETWORK_PROTOCOL_VERSION]: httpVersion, [NETWORK_TRANSPORT]: transport, - 'http.response.status_text': statusMessage?.toUpperCase(), + [HTTP_RESPONSE_STATUS_TEXT]: statusMessage?.toUpperCase(), [HTTP_RESPONSE_BODY_SIZE]: getContentLengthFromHeaders(response.headers), ...getSocketAttrs(socket), }); diff --git a/packages/core/src/integrations/http/server-subscription.ts b/packages/core/src/integrations/http/server-subscription.ts index d75bd2b10703..af5826fb6c86 100644 --- a/packages/core/src/integrations/http/server-subscription.ts +++ b/packages/core/src/integrations/http/server-subscription.ts @@ -67,6 +67,8 @@ import { URL_SCHEME, USER_AGENT_ORIGINAL, SENTRY_ORIGIN, + HTTP_REQUEST_BODY_SIZE, + HTTP_RESPONSE_STATUS_TEXT, } from '@sentry/conventions/attributes'; import { HTTP_SERVER } from '@sentry/conventions/op'; import { filterCollectedUrl, filterCollectedUrlQuery } from '../../utils/data-collection/filterCollectedUrl'; @@ -357,7 +359,7 @@ function buildServerSpanWrap( [USER_AGENT_ORIGINAL]: userAgent, [URL_SCHEME]: scheme, [NETWORK_TRANSPORT]: httpVersion?.toUpperCase() === 'QUIC' ? 'udp' : 'tcp', - 'http.request.body.size': getContentLengthFromHeaders(request.headers), + [HTTP_REQUEST_BODY_SIZE]: getContentLengthFromHeaders(request.headers), ...httpHeadersToSpanAttributes(normalizedRequest.headers || {}, dataCollectionOptions), }, }, @@ -379,7 +381,7 @@ function buildServerSpanWrap( isEnded = true; // set attributes that come from the response span.setAttributes({ - 'http.response.status_text': response.statusMessage?.toUpperCase(), + [HTTP_RESPONSE_STATUS_TEXT]: response.statusMessage?.toUpperCase(), [HTTP_RESPONSE_STATUS_CODE]: response.statusCode, ...httpHeadersToSpanAttributes(headersToDict(response.headers), dataCollectionOptions, 'response'), }); diff --git a/packages/core/src/integrations/requestdata.ts b/packages/core/src/integrations/requestdata.ts index 12d9d99d433c..04913990440a 100644 --- a/packages/core/src/integrations/requestdata.ts +++ b/packages/core/src/integrations/requestdata.ts @@ -18,7 +18,14 @@ import { getUrlQuery } from '../utils/url'; import { getClientIPAddress } from '../utils/clientIPAddress'; import { ipHeaderNames } from '../vendor/getIpAddress'; import { safeSetSpanJSONAttributes } from '../tracing/spans/captureSpan'; -import { SENTRY_IS_LOCALHOST, URL_FULL, URL_QUERY, USER_IP_ADDRESS } from '@sentry/conventions/attributes'; +import { + SENTRY_IS_LOCALHOST, + URL_FULL, + URL_QUERY, + USER_IP_ADDRESS, + HTTP_REQUEST_BODY_DATA, + HTTP_REQUEST_METHOD, +} from '@sentry/conventions/attributes'; type RequestDataIncludeOptions = { cookies?: boolean; @@ -219,7 +226,7 @@ function addNormalizedRequestDataToSpan( } if (requestData.method) { - attributes['http.request.method'] = requestData.method; + attributes[HTTP_REQUEST_METHOD] = requestData.method; } if (requestData.query_string) { @@ -254,7 +261,7 @@ function addNormalizedRequestDataToSpan( if (requestData.data != null) { const serialized = typeof requestData.data === 'string' ? requestData.data : JSON.stringify(requestData.data); if (serialized) { - safeSetSpanJSONAttributes(span, { 'http.request.body.data': serialized }); + safeSetSpanJSONAttributes(span, { [HTTP_REQUEST_BODY_DATA]: serialized }); } } diff --git a/packages/core/src/logs/internal.ts b/packages/core/src/logs/internal.ts index 64bbabad80e6..652212746a5c 100644 --- a/packages/core/src/logs/internal.ts +++ b/packages/core/src/logs/internal.ts @@ -1,3 +1,15 @@ +import { + SENTRY_ENVIRONMENT, + SENTRY_MESSAGE_TEMPLATE, + SENTRY_RELEASE, + SENTRY_REPLAY_ID, + SENTRY_SDK_NAME, + SENTRY_SDK_VERSION, + SENTRY_TRACE_PARENT_SPAN_ID, + USER_EMAIL, + USER_ID, + USER_NAME, +} from '@sentry/conventions/attributes'; import type { Attributes } from '../attributes'; import { serializeAttributes } from '../attributes'; import { getGlobalSingleton } from '../carrier'; @@ -98,16 +110,16 @@ export function _INTERNAL_captureLog( attributes: scopeAttributes, } = getCombinedScopeData(getIsolationScope(), currentScope); - setLogAttribute(processedLogAttributes, 'user.id', id, false); - setLogAttribute(processedLogAttributes, 'user.email', email, false); - setLogAttribute(processedLogAttributes, 'user.name', username, false); + setLogAttribute(processedLogAttributes, USER_ID, id, false); + setLogAttribute(processedLogAttributes, USER_EMAIL, email, false); + setLogAttribute(processedLogAttributes, USER_NAME, username, false); - setLogAttribute(processedLogAttributes, 'sentry.release', release); - setLogAttribute(processedLogAttributes, 'sentry.environment', environment); + setLogAttribute(processedLogAttributes, SENTRY_RELEASE, release); + setLogAttribute(processedLogAttributes, SENTRY_ENVIRONMENT, environment); const { name, version } = client.getSdkMetadata()?.sdk ?? {}; - setLogAttribute(processedLogAttributes, 'sentry.sdk.name', name); - setLogAttribute(processedLogAttributes, 'sentry.sdk.version', version); + setLogAttribute(processedLogAttributes, SENTRY_SDK_NAME, name); + setLogAttribute(processedLogAttributes, SENTRY_SDK_VERSION, version); const replay = client.getIntegrationByName< Integration & { @@ -117,7 +129,7 @@ export function _INTERNAL_captureLog( >('Replay'); const replayId = replay?.getReplayId(true); - setLogAttribute(processedLogAttributes, 'sentry.replay_id', replayId); + setLogAttribute(processedLogAttributes, SENTRY_REPLAY_ID, replayId); if (replayId && replay?.getRecordingMode() === 'buffer') { // We send this so we can identify cases where the replayId is attached but the replay itself might not have been sent to Sentry @@ -128,7 +140,7 @@ export function _INTERNAL_captureLog( if (isParameterizedString(beforeLogMessage)) { const { __sentry_template_string__, __sentry_template_values__ = [] } = beforeLogMessage; if (__sentry_template_values__?.length) { - processedLogAttributes['sentry.message.template'] = __sentry_template_string__; + processedLogAttributes[SENTRY_MESSAGE_TEMPLATE] = __sentry_template_string__; } __sentry_template_values__.forEach((param, index) => { processedLogAttributes[`sentry.message.parameter.${index}`] = param; @@ -137,7 +149,8 @@ export function _INTERNAL_captureLog( const span = getActiveSpan(currentScope); // Add the parent span ID to the log attributes for trace context - setLogAttribute(processedLogAttributes, 'sentry.trace.parent_span_id', span?.spanContext().spanId); + // oxlint-disable-next-line typescript/no-deprecated -- Preserve the existing attribute name. + setLogAttribute(processedLogAttributes, SENTRY_TRACE_PARENT_SPAN_ID, span?.spanContext().spanId); const processedLog = { ...beforeLog, attributes: processedLogAttributes }; diff --git a/packages/core/src/logs/utils.ts b/packages/core/src/logs/utils.ts index 5f95e0db3aad..af4a1ba71e74 100644 --- a/packages/core/src/logs/utils.ts +++ b/packages/core/src/logs/utils.ts @@ -1,3 +1,4 @@ +import { SENTRY_MESSAGE_TEMPLATE } from '@sentry/conventions/attributes'; import { isPrimitive } from '../utils/is'; import { normalize } from '../utils/normalize'; import { GLOBAL_OBJ } from '../utils/worldwide'; @@ -60,7 +61,7 @@ export function createConsoleTemplateAttributes(firstArg: unknown, followingArgs // Create template with placeholders for each argument const template = new Array(followingArgs.length).fill('{}').join(' '); - attributes['sentry.message.template'] = `${firstArg} ${template}`; + attributes[SENTRY_MESSAGE_TEMPLATE] = `${firstArg} ${template}`; // Add each argument as a parameter followingArgs.forEach((arg, index) => { diff --git a/packages/core/src/metrics/internal.ts b/packages/core/src/metrics/internal.ts index 830fb279303d..4d0635522bd6 100644 --- a/packages/core/src/metrics/internal.ts +++ b/packages/core/src/metrics/internal.ts @@ -1,3 +1,13 @@ +import { + SENTRY_ENVIRONMENT, + SENTRY_RELEASE, + SENTRY_REPLAY_ID, + SENTRY_SDK_NAME, + SENTRY_SDK_VERSION, + USER_EMAIL, + USER_ID, + USER_NAME, +} from '@sentry/conventions/attributes'; import { type RawAttributes, serializeAttributes } from '../attributes'; import { getGlobalSingleton } from '../carrier'; import type { Client } from '../client'; @@ -88,18 +98,18 @@ function _enrichMetricAttributes(beforeMetric: Metric, client: Client, user: Use }; // Add user attributes - setMetricAttribute(processedMetricAttributes, 'user.id', user.id, false); - setMetricAttribute(processedMetricAttributes, 'user.email', user.email, false); - setMetricAttribute(processedMetricAttributes, 'user.name', user.username, false); + setMetricAttribute(processedMetricAttributes, USER_ID, user.id, false); + setMetricAttribute(processedMetricAttributes, USER_EMAIL, user.email, false); + setMetricAttribute(processedMetricAttributes, USER_NAME, user.username, false); // Add Sentry metadata - setMetricAttribute(processedMetricAttributes, 'sentry.release', release); - setMetricAttribute(processedMetricAttributes, 'sentry.environment', environment); + setMetricAttribute(processedMetricAttributes, SENTRY_RELEASE, release); + setMetricAttribute(processedMetricAttributes, SENTRY_ENVIRONMENT, environment); // Add SDK metadata const { name, version } = client.getSdkMetadata()?.sdk ?? {}; - setMetricAttribute(processedMetricAttributes, 'sentry.sdk.name', name); - setMetricAttribute(processedMetricAttributes, 'sentry.sdk.version', version); + setMetricAttribute(processedMetricAttributes, SENTRY_SDK_NAME, name); + setMetricAttribute(processedMetricAttributes, SENTRY_SDK_VERSION, version); // Add replay metadata const replay = client.getIntegrationByName< @@ -110,7 +120,7 @@ function _enrichMetricAttributes(beforeMetric: Metric, client: Client, user: Use >('Replay'); const replayId = replay?.getReplayId(true); - setMetricAttribute(processedMetricAttributes, 'sentry.replay_id', replayId); + setMetricAttribute(processedMetricAttributes, SENTRY_REPLAY_ID, replayId); if (replayId && replay?.getRecordingMode() === 'buffer') { setMetricAttribute(processedMetricAttributes, 'sentry._internal.replay_is_buffering', true); diff --git a/packages/core/src/server-runtime-client.ts b/packages/core/src/server-runtime-client.ts index 9dcc4512bea4..ab9729f60732 100644 --- a/packages/core/src/server-runtime-client.ts +++ b/packages/core/src/server-runtime-client.ts @@ -1,3 +1,4 @@ +import { SERVER_ADDRESS } from '@sentry/conventions/attributes'; import { createCheckInEnvelope } from './checkin'; import { Client } from './client'; import { getIsolationScope } from './currentScopes'; @@ -248,7 +249,7 @@ export class ServerRuntimeClient< this.on('processMetric', metric => { if (this._options.serverName) { metric.attributes = { - 'server.address': this._options.serverName, + [SERVER_ADDRESS]: this._options.serverName, ...metric.attributes, }; } diff --git a/packages/core/src/tracing/spans/scopeContextAttributes.ts b/packages/core/src/tracing/spans/scopeContextAttributes.ts index 63b468fea922..a0bc65e4cc90 100644 --- a/packages/core/src/tracing/spans/scopeContextAttributes.ts +++ b/packages/core/src/tracing/spans/scopeContextAttributes.ts @@ -1,3 +1,14 @@ +import { + ANGULAR_VERSION, + CULTURE_LOCALE, + CULTURE_TIMEZONE, + HTTP_RESPONSE_BODY_SIZE, + HTTP_RESPONSE_STATUS_CODE, + REACT_VERSION, + SENTRY_PROFILER_ID, + SENTRY_PROFILE_ID, + STATE_TYPE, +} from '@sentry/conventions/attributes'; import type { Contexts } from '../../types/context'; /** @@ -13,19 +24,19 @@ export function scopeContextsToSpanAttributes(contexts: Contexts): Record