Skip to content

Conversation

@k-fish
Copy link
Member

@k-fish k-fish commented Nov 10, 2025

Adds a metric sections to issue details, only shown when there are >0 metrics and there is a trace.

Also in this PR; modifying the providers to allow state based for it being embedded and searchable inside issue details with spamming url params.

Closes LOGS-369

@k-fish k-fish requested review from a team as code owners November 10, 2025 20:55
@github-actions github-actions bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Nov 10, 2025
@linear
Copy link

linear bot commented Nov 10, 2025

Comment on lines 82 to +99
traceIds={freeze?.traceIds ?? []}
tracePeriod={freeze?.tracePeriod}
>
<QueryParamsContextProvider
<QueryContextProvider
queryParams={queryParams}
setQueryParams={setWritableQueryParams}
isUsingDefaultFields
shouldManageFields={false}
>
{children}
</QueryParamsContextProvider>
</QueryContextProvider>
Copy link

Choose a reason for hiding this comment

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

Bug: QueryContextProvider is incorrectly instantiated with MetricsStateQueryParamsProvider due to incompatible prop signatures, causing a TypeScript compilation error.
Severity: CRITICAL | Confidence: 1.00

🔍 Detailed Analysis

The QueryContextProvider is incorrectly used with MetricsStateQueryParamsProvider when isStateBased=true. This leads to a TypeScript compilation error because MetricsStateQueryParamsProvider does not accept queryParams, setQueryParams, isUsingDefaultFields, and shouldManageFields props, which are expected by QueryContextProvider. This fundamental type mismatch prevents the code from compiling.

💡 Suggested Fix

Either MetricsStateQueryParamsProvider needs to accept frozenParams to receive parent state, or the caller must stop passing incompatible props like queryParams and setQueryParams when isStateBased is true.

🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: static/app/views/explore/metrics/metricsQueryParams.tsx#L82-L99

Potential issue: The `QueryContextProvider` is incorrectly used with
`MetricsStateQueryParamsProvider` when `isStateBased=true`. This leads to a TypeScript
compilation error because `MetricsStateQueryParamsProvider` does not accept
`queryParams`, `setQueryParams`, `isUsingDefaultFields`, and `shouldManageFields` props,
which are expected by `QueryContextProvider`. This fundamental type mismatch prevents
the code from compiling.

Did we get this right? 👍 / 👎 to inform future reviews.

Comment on lines 135 to 137
export function defaultSortBys(fields: string[]): Sort[] {
// TODO: Handle compound sort-by.
return [{field: fields[0]!, kind: 'desc'}];
Copy link

Choose a reason for hiding this comment

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

Bug: defaultSortBys in metrics module sorts by id instead of prioritizing timestamp, deviating from established codebase patterns.
Severity: HIGH | Confidence: 0.90

🔍 Detailed Analysis

The defaultSortBys function in the new metrics module sorts by fields[0] (which is 'id' when called with ['id', 'timestamp']), instead of prioritizing 'timestamp'. This deviates from the established pattern in logsQueryParams.tsx, spansQueryParams.tsx, and the shared sortBys.tsx, all of which prioritize 'timestamp' for sorting. Consequently, metrics samples will sort by 'id' descending, altering user experience and violating a standard UX pattern.

💡 Suggested Fix

Modify the defaultSortBys function in the metrics module to prioritize 'timestamp' when available, consistent with other modules and shared utilities.

🤖 Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: static/app/views/explore/metrics/metricQuery.tsx#L135-L137

Potential issue: The `defaultSortBys` function in the new metrics module sorts by
`fields[0]` (which is 'id' when called with `['id', 'timestamp']`), instead of
prioritizing 'timestamp'. This deviates from the established pattern in
`logsQueryParams.tsx`, `spansQueryParams.tsx`, and the shared `sortBys.tsx`, all of
which prioritize 'timestamp' for sorting. Consequently, metrics samples will sort by
'id' descending, altering user experience and violating a standard UX pattern.

Did we get this right? 👍 / 👎 to inform future reviews.

@codecov
Copy link

codecov bot commented Nov 10, 2025

❌ 2 Tests Failed:

Tests completed Failed Passed Skipped
12415 2 12413 10
View the top 2 failed test(s) by shortest run time
useMetricSamplesTable simple usage
Stack Traces | 0.029s run time
Error: expect(jest.fn()).toHaveBeenCalledWith(...expected)

Expected: "....../organizations/org-slug/events/", ObjectContaining {"query": ObjectContaining {"caseInsensitive": undefined, "dataset": "tracemetrics", "disableAggregateExtrapolation": undefined, "environment": ["prod"], "field": ["id", "project.id", "trace", "span_id", "sentry.span_id", "metric.type", "metric.name", "timestamp"], "metricName": "test.metric", "metricType": "counter", "orderby": ["-timestamp"], "per_page": 50, "project": ["1", "2"], "query": "", "referrer": "api.explore.metric-samples-table", "sampling": "NORMAL", "sort": "-timestamp"}}
Received: "....../organizations/org-slug/events/", {"data": undefined, "error": [Function error], "headers": undefined, "host": undefined, "method": "GET", "query": {"caseInsensitive": undefined, "dataset": "tracemetrics", "disableAggregateExtrapolation": undefined, "end": "2017-10-17T02:41:20.000", "environment": ["prod"], "field": ["id", "project.id", "trace", "span_id", "sentry.span_id", "metric.type", "metric.name", "timestamp"], "metricName": "test.metric", "metricType": "counter", "orderby": ["-id"], "per_page": 50, "project": ["1", "2"], "query": "", "referrer": "api.explore.metric-samples-table", "sampling": "NORMAL", "sort": "-id", "start": "2017-10-16T02:41:20.000"}, "success": [Function success]}

Number of calls: 1
    at Object.toHaveBeenCalledWith (.../metrics/hooks/useMetricSamplesTable.spec.tsx:128:25)
MultiMetricsQueryParamsProvider sets defaults
Stack Traces | 0.031s run time
Error: expect(received).toEqual(expected) // deep equality

- Expected  - 1
+ Received  + 1

@@ -40,11 +40,11 @@
        "search": MutableSearch {
          "tokens": Array [],
        },
        "sortBys": Array [
          Object {
-           "field": "timestamp",
+           "field": "id",
            "kind": "desc",
          },
        ],
        "title": undefined,
        "visualizes": Array [
    at Object.toEqual (.../explore/metrics/multiMetricsQueryParams.spec.tsx:23:28)
    at Promise.finally.completed (.../sentry/node_modules/.pnpm/[email protected][email protected]..../jest-circus/build/jestAdapterInit.js:1559:28)
    at new Promise (<anonymous>)
    at callAsyncCircusFn (.../sentry/node_modules/.pnpm/[email protected][email protected]..../jest-circus/build/jestAdapterInit.js:1499:10)
    at _callCircusTest (.../sentry/node_modules/.pnpm/[email protected][email protected]..../jest-circus/build/jestAdapterInit.js:1009:40)
    at processTicksAndRejections (node:internal/process/task_queues:105:5)
    at _runTest (.../sentry/node_modules/.pnpm/[email protected][email protected]..../jest-circus/build/jestAdapterInit.js:949:3)
    at _runTestsForDescribeBlock (.../sentry/node_modules/.pnpm/[email protected][email protected]..../jest-circus/build/jestAdapterInit.js:839:13)
    at _runTestsForDescribeBlock (.../sentry/node_modules/.pnpm/[email protected][email protected]..../jest-circus/build/jestAdapterInit.js:829:11)
    at run (.../sentry/node_modules/.pnpm/[email protected][email protected]..../jest-circus/build/jestAdapterInit.js:757:3)
    at runAndTransformResultsToJestFormat (.../sentry/node_modules/.pnpm/[email protected][email protected]..../jest-circus/build/jestAdapterInit.js:1920:21)
    at jestAdapter (.../sentry/node_modules/.pnpm/[email protected][email protected]..../jest-circus/build/runner.js:101:19)
    at runTestInternal (.../sentry/node_modules/.pnpm/[email protected]..../jest-runner/build/testWorker.js:272:16)
    at runTest (.../sentry/node_modules/.pnpm/[email protected]..../jest-runner/build/testWorker.js:340:7)
    at Object.worker (.../sentry/node_modules/.pnpm/[email protected]..../jest-runner/build/testWorker.js:494:12)

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

disabled: embedded
? false
: !traceMetric?.name || isMetricOptionsEmpty || !!overrideTableData,
limit: embedded ? EMBEDDED_RESULT_LIMIT : RESULT_LIMIT,
Copy link
Contributor

Choose a reason for hiding this comment

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

Bug: Optimize API: Disable Unused Queries

When embedded=true and overrideTableData is provided, the query is not disabled but the fetched data is never used since overrideTableData takes precedence in rendering. This causes unnecessary API requests. The disabled condition should account for overrideTableData even when embedded.

Fix in Cursor Fix in Web

>
<Flex direction="column" gap="xl">
<MetricsSamplesTable embedded overrideTableData={abbreviatedTableData} />
{result.data && result.data.length > 5 ? (
Copy link
Member

Choose a reason for hiding this comment

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

Can we put this 5 into a const somewhere?

Comment on lines +76 to +79
setQueryParams={() => {}}
traceMetric={{name: '', type: ''}}
setTraceMetric={() => {}}
removeMetric={() => {}}
Copy link
Member

Choose a reason for hiding this comment

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

The signature is a little odd here as it forces you to pass these empty values but this is fine for now I guess.

Comment on lines +99 to +106
if (!feature) {
return null;
}

if (!traceId) {
// If there isn't a traceId, we shouldn't show metrics since they are trace specific
return null;
}
Copy link
Member

Choose a reason for hiding this comment

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

Should these be moved to the wrapper component?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants