Skip to content

[Due for payment 2026-04-02] Group telemetry tag keys so child-span propagation is automatic #86219

@rlinoz

Description

@rlinoz

Hi, can you review one small proposal?

Proposal: Group telemetry tag keys so child-span propagation is automatic

Background: The app instruments performance using Sentry spans and transactions. Each transaction can carry tags — indexed key/value pairs that make it filterable and queryable in Sentry. A middleware (copyTagsToChildSpans) runs on every Sentry event and copies a set of tags from the root transaction down to all child spans, so engineers can filter on those dimensions at any level of the trace. The tag key strings themselves are defined as constants in CONST.TELEMETRY — a flat object that currently holds ~18 tag keys (prefixed TAG_), ~20 span name strings (prefixed SPAN_), ~15 attribute name strings (prefixed ATTRIBUTE_), breadcrumb categories, event names, value enums, and config — all at the same level.

Problem: When a developer adds a new tag key to CONST.TELEMETRY, if they ship without also updating the TAGS_TO_COPY array in copyTagsToChildSpans.ts, the new tag silently appears only on the root transaction and not on any child spans, making it invisible in the most granular Sentry data with no compiler error, no lint warning, and no test failure to signal the omission.

Solution: Move all tag key constants out of the flat CONST.TELEMETRY namespace into a dedicated sub-object CONST.TELEMETRY.TAGS, and replace the manual TAGS_TO_COPY array with Object.values(CONST.TELEMETRY.TAGS).

Concretely:

In src/CONST/index.ts, replace the 18 flat TAG_* entries with a TAGS sub-object:

  TAGS: {
    ACTIVE_POLICY: 'active_policy_id',
    POLICIES_COUNT: 'policies_count',
    REPORTS_COUNT: 'reports_count',
    PERSONAL_DETAILS_COUNT: 'personal_details_count',
    USER_ROLE: 'user_role',
    NUDGE_MIGRATION_COHORT: 'nudge_migration_cohort',
    AUTHENTICATION_FUNCTION: 'authentication_function',
    AUTHENTICATION_ERROR_TYPE: 'authentication_error_type',
    AUTHENTICATION_JSON_CODE: 'authentication_json_code',
    EXPENSE_ERROR_TYPE: 'expense_error_type',
    EXPENSE_ERROR_SOURCE: 'expense_error_source',
    EXPENSE_IS_REQUEST_PENDING: 'expense_is_request_pending',
    EXPENSE_HAS_RECEIPT: 'expense_has_receipt',
    EXPENSE_COMMAND: 'expense_command',
    EXPENSE_JSON_CODE: 'expense_json_code',
    MFA_SCENARIO: 'mfa_scenario',
    MFA_ERROR_REASON: 'mfa_error_reason',
    BUILD_TYPE: 'build_type',
  },

All other keys (SPAN_, ATTRIBUTE_, BREADCRUMB_*, etc.) remain flat and unchanged in this PR.
In copyTagsToChildSpans.ts, replace the manual array:

  // before
  const TAGS_TO_COPY = [
   CONST.TELEMETRY.TAG_POLICIES_COUNT,
   // ...5 more entries, manually maintained
  ] as const;
  
  // after
  const TAGS_TO_COPY = Object.values(CONST.TELEMETRY.TAGS);

Tags that carry no value on the root transaction are undefined and already skipped by the existing guard in the middleware, so including all tags is safe.
Update all call sites of CONST.TELEMETRY.TAG_FOO → CONST.TELEMETRY.TAGS.FOO. TypeScript will catch any missed references at compile time, so the migration is verifiable.

With this in place, adding a tag to CONST.TELEMETRY.TAGS automatically propagates it to child spans — the omission is structurally impossible.

Issue OwnerCurrent Issue Owner: @sosek108

Metadata

Metadata

Labels

Awaiting PaymentAuto-added when associated PR is deployed to productionWeeklyKSv2

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions