diff --git a/packages/core/src/transports/base.ts b/packages/core/src/transports/base.ts index 68e4522267db..ffeeb7fad396 100644 --- a/packages/core/src/transports/base.ts +++ b/packages/core/src/transports/base.ts @@ -49,10 +49,10 @@ export function createTransport( // Drop rate limited items from envelope forEachEnvelopeItem(envelope, (item, type) => { - const envelopeItemDataCategory = envelopeItemTypeToDataCategory(type); - if (isRateLimited(rateLimits, envelopeItemDataCategory)) { + const dataCategory = envelopeItemTypeToDataCategory(type); + if (isRateLimited(rateLimits, dataCategory)) { const event: Event | undefined = getEventForEnvelopeItem(item, type); - options.recordDroppedEvent('ratelimit_backoff', envelopeItemDataCategory, event); + options.recordDroppedEvent('ratelimit_backoff', dataCategory, event); } else { filteredEnvelopeItems.push(item); } diff --git a/packages/types/src/datacategory.ts b/packages/types/src/datacategory.ts index de482bc3d7cc..bd1c0b693e4d 100644 --- a/packages/types/src/datacategory.ts +++ b/packages/types/src/datacategory.ts @@ -1,7 +1,7 @@ // This type is used in various places like Client Reports and Rate Limit Categories // See: // - https://develop.sentry.dev/sdk/rate-limiting/#definitions -// - https://github.com/getsentry/relay/blob/c3b339e151c1e548ede489a01c65db82472c8751/relay-common/src/constants.rs#L139-L152 +// - https://github.com/getsentry/relay/blob/ec791fed9c2260688f25ea6a6d53ab913927e9a5/relay-base-schema/src/data_category.rs#L91 // - https://develop.sentry.dev/sdk/client-reports/#envelope-item-payload under `discarded_events` export type DataCategory = // Reserved and only used in edgecases, unlikely to be ever actually used @@ -26,8 +26,8 @@ export type DataCategory = | 'monitor' // Feedback type event (v2) | 'feedback' - // Statsd type event for metrics - | 'statsd' + // Metrics sent via the statsd or metrics envelope items + | 'metric_bucket' // Span | 'span' // Unknown data category diff --git a/packages/types/src/envelope.ts b/packages/types/src/envelope.ts index 5db39eb65f3e..c7e7c128264d 100644 --- a/packages/types/src/envelope.ts +++ b/packages/types/src/envelope.ts @@ -30,6 +30,8 @@ export type DynamicSamplingContext = { sampled?: string; }; +// https://github.com/getsentry/relay/blob/311b237cd4471042352fa45e7a0824b8995f216f/relay-server/src/envelope.rs#L154 +// https://develop.sentry.dev/sdk/envelopes/#data-model export type EnvelopeItemType = | 'client_report' | 'user_report' diff --git a/packages/utils/src/envelope.ts b/packages/utils/src/envelope.ts index 8d1ec735ca02..93e38fd92280 100644 --- a/packages/utils/src/envelope.ts +++ b/packages/utils/src/envelope.ts @@ -210,7 +210,7 @@ const ITEM_TYPE_TO_DATA_CATEGORY_MAP: Record = { check_in: 'monitor', feedback: 'feedback', span: 'span', - statsd: 'statsd', + statsd: 'metric_bucket', }; /** @@ -220,7 +220,7 @@ export function envelopeItemTypeToDataCategory(type: EnvelopeItemType): DataCate return ITEM_TYPE_TO_DATA_CATEGORY_MAP[type]; } -/** Extracts the minimal SDK info from from the metadata or an events */ +/** Extracts the minimal SDK info from the metadata or an events */ export function getSdkMetadataForEnvelopeHeader(metadataOrEvent?: SdkMetadata | Event): SdkInfo | undefined { if (!metadataOrEvent || !metadataOrEvent.sdk) { return; diff --git a/packages/utils/src/ratelimit.ts b/packages/utils/src/ratelimit.ts index c3353c8034a6..eda9375a9de6 100644 --- a/packages/utils/src/ratelimit.ts +++ b/packages/utils/src/ratelimit.ts @@ -1,4 +1,4 @@ -import type { TransportMakeRequestResponse } from '@sentry/types'; +import type { DataCategory, TransportMakeRequestResponse } from '@sentry/types'; // Intentionally keeping the key broad, as we don't know for sure what rate limit headers get returned from backend export type RateLimits = Record; @@ -32,15 +32,15 @@ export function parseRetryAfterHeader(header: string, now: number = Date.now()): * * @return the time in ms that the category is disabled until or 0 if there's no active rate limit. */ -export function disabledUntil(limits: RateLimits, category: string): number { - return limits[category] || limits.all || 0; +export function disabledUntil(limits: RateLimits, dataCategory: DataCategory): number { + return limits[dataCategory] || limits.all || 0; } /** * Checks if a category is rate limited */ -export function isRateLimited(limits: RateLimits, category: string, now: number = Date.now()): boolean { - return disabledUntil(limits, category) > now; +export function isRateLimited(limits: RateLimits, dataCategory: DataCategory, now: number = Date.now()): boolean { + return disabledUntil(limits, dataCategory) > now; } /** @@ -74,6 +74,8 @@ export function updateRateLimits( * ;;... * is what's being limited (org, project, or key) - ignored by SDK * is an arbitrary string like "org_quota" - ignored by SDK + * Semicolon-separated list of metric namespace identifiers. Defines which namespace(s) will be affected. + * Only present if rate limit applies to the metric_bucket data category. */ for (const limit of rateLimitHeader.trim().split(',')) { const [retryAfter, categories] = limit.split(':', 2);