Skip to content

feat: add listAttributeKeys telemetry endpoint#1712

Merged
tgmendes merged 6 commits intomainfrom
tiago/age-1429-feat-list-distinct-attribute-keys-for-telemetry-filter
Feb 27, 2026
Merged

feat: add listAttributeKeys telemetry endpoint#1712
tgmendes merged 6 commits intomainfrom
tiago/age-1429-feat-list-distinct-attribute-keys-for-telemetry-filter

Conversation

@tgmendes
Copy link
Contributor

@tgmendes tgmendes commented Feb 27, 2026

Summary

  • Adds POST /rpc/telemetry.listAttributeKeys endpoint that returns all distinct attribute paths from telemetry_logs for a project + time range
  • Uses ClickHouse JSONAllPaths() to discover paths, translates app.*@-prefixed user keys, returns system keys bare
  • Includes 7 tests (empty, disabled, system+user keys, dedup, sorting, time range, project scoping)
  • Regenerated SDK artifacts

Closes AGE-1429

Example

Request:

POST /rpc/telemetry.listAttributeKeys
Gram-Key: gram_local_...
Gram-Project: ecommerce-api
Content-Type: application/json

{
  "from": "2025-01-01T00:00:00Z",
  "to": "2026-12-31T23:59:59Z"
}

Response:

{
  "keys": [
    "@error.code",
    "@order.total",
    "@user.id",
    "@user.region",
    "@user.tier",
    "gen_ai.conversation.id",
    "gen_ai.response.model",
    "gen_ai.usage.input_tokens",
    "gram.tool.urn",
    "http.request.method",
    "http.response.status_code",
    "http.route",
    "..."
  ]
}

User attributes (app.*) are returned with @ prefix. System attributes are returned bare. Results are sorted alphabetically and deduplicated.

Test plan

  • mise build:server passes
  • mise lint:server passes
  • 7 new tests in list_attribute_keys_test.go pass
  • Existing telemetry tests unaffected
  • Manual test against local server confirmed correct response

@tgmendes tgmendes requested a review from a team as a code owner February 27, 2026 10:25
@linear
Copy link

linear bot commented Feb 27, 2026

@changeset-bot
Copy link

changeset-bot bot commented Feb 27, 2026

🦋 Changeset detected

Latest commit: 25e38f1

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@gram/client Minor
server Minor
dashboard Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link

vercel bot commented Feb 27, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
gram-docs-redirect Ready Ready Preview, Comment Feb 27, 2026 10:50am

Request Review

Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 4 additional findings.

Open in Devin Review

Copy link
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 new potential issue.

View 5 additional findings in Devin Review.

Open in Devin Review

Comment on lines +47 to +52
return {
queryKey: queryKeyListAttributeKeys({
gramKey: request.gramKey,
gramSession: request.gramSession,
gramProject: request.gramProject,
}),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 React Query cache key omits from/to body parameters, causing stale data across different time ranges

The queryKeyListAttributeKeys function only includes header parameters (gramKey, gramSession, gramProject) but excludes the request body's from and to time-range fields. This means TanStack Query treats requests with different time ranges as identical, serving stale cached data.

Root Cause and Impact

At client/sdk/src/react-query/listAttributeKeys.core.ts:47-52, the query key is built using only header params:

queryKey: queryKeyListAttributeKeys({
  gramKey: request.gramKey,
  gramSession: request.gramSession,
  gramProject: request.gramProject,
}),

The request object also contains getProjectMetricsSummaryPayload (which holds from and to), but these are not included in the cache key at client/sdk/src/react-query/listAttributeKeys.core.ts:77-85.

Scenario:

  1. Component calls useListAttributeKeys with from: "2025-01-01", to: "2025-06-01" → fetches and caches result under key ["@gram/client", "telemetry", "listAttributeKeys", {gramProject: "x"}]
  2. User changes time range to from: "2025-06-01", to: "2025-12-01" → TanStack Query finds a cache hit on the same key and returns the old result without refetching.

Impact: Users see incorrect/stale attribute keys when changing the time range filter in the UI.

Prompt for agents
In client/sdk/src/react-query/listAttributeKeys.core.ts, the queryKeyListAttributeKeys function at lines 77-85 and the call site at lines 47-52 need to include the request body parameters (from/to) in the cache key. Since the request body is typed as getProjectMetricsSummaryPayload (containing from and to fields), these should be included in the parameters object passed to queryKeyListAttributeKeys. Similarly, update the queryKeyBase type in client/sdk/src/react-query/listAttributeKeys.ts for setListAttributeKeysData and invalidateListAttributeKeys. Note: since this is generated code (Speakeasy), the fix may need to be applied at the OpenAPI spec or Speakeasy configuration level to ensure the code generator includes request body fields in the query key.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@tgmendes tgmendes merged commit f364cc0 into main Feb 27, 2026
31 checks passed
@tgmendes tgmendes deleted the tiago/age-1429-feat-list-distinct-attribute-keys-for-telemetry-filter branch February 27, 2026 13:53
@github-actions github-actions bot locked and limited conversation to collaborators Feb 27, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants