Skip to content

recordAnalytics: support arbitrary key/value dimensions #565

Description

@kriszyp

server.recordAnalytics currently accepts only three fixed positional dimensions (path, method, type), which forces consumers to encode unrelated dimensions into those slots or split a metric into multiple metrics. The PXG team has asked for a custom-dimensions API.

Desired API

Additive to the current signature (existing 3-positional form remains supported for back-compat):

recordAnalytics(value: number | boolean, metric: string, dimensions?: Record<string, string | number | boolean>): void;

Example:

recordAnalytics(1000, 'response_time', { device_type: 'mobile', status_code: 200 });

Implementation notes

  • Current impl (resources/analytics/write.ts:729) builds the aggregation key by concatenating metric-path-method-type. With variable dimensions, the key needs a stable canonicalization (sorted keys, joined). Cardinality of the dimension set affects memory in activeActions.
  • Downstream consumers (the analytics report payload, listeners via addAnalyticsListener, and storage in the analytics table) need to surface custom dimensions — likely as a nested object rather than the current flat fields.
  • Existing path / method / type callers and dashboards should continue to work unchanged.

Acceptance criteria

  • New dimensions-object form is supported alongside the positional form.
  • Aggregation correctly groups records sharing the same (metric, dimensions) tuple.
  • Reported analytics include custom dimensions in a structured way that the metrics exporter / Grafana plugin can consume.
  • Document the new signature; deprecate the positional form in docs (without removing).

Open design questions (keeps this Not Ready)

  • Cardinality guardrails — recommend bounded values (status code, device type) and warn against unbounded ones (user IDs). Should we enforce a per-metric dimension allowlist or a cardinality cap at recording time? Without guardrails, customer misuse could blow up memory in activeActions and storage size.
  • How should custom dimensions surface in the existing Prometheus exporter and Grafana plugin? Mapping a variable-cardinality record onto Prometheus labels requires a registration step.
  • Naming / collision rules with the reserved path / method / type keys.

Tracked in Jira: CORE-3075

🤖 Filed by Claude on behalf of Kris.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:metricsMetrics, analytics, and observabilityenhancementNew feature or requestfrom-jiraMigrated or originated from a Jira ticket

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions