Skip to content

Commit eef3e43

Browse files
k-fishlzhao-sentry
authored andcommitted
fix(ourlogs): Fix logs widget viewer link (#98126)
### Summary Should say 'open in explore' and link to the correct logs page #### Screenshots <img width="1145" height="555" alt="Screenshot 2025-08-22 at 12 03 12 PM" src="https://github.com/user-attachments/assets/1750a00f-7022-4dcc-ba25-115958958776" />
1 parent 6634032 commit eef3e43

File tree

2 files changed

+92
-5
lines changed

2 files changed

+92
-5
lines changed

static/app/components/modals/widgetViewerModal.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,6 +914,10 @@ function OpenButton({
914914
openLabel = t('Open in Explore');
915915
path = getWidgetExploreUrl(widget, dashboardFilters, selection, organization);
916916
break;
917+
case WidgetType.LOGS:
918+
openLabel = t('Open in Explore');
919+
path = getWidgetExploreUrl(widget, dashboardFilters, selection, organization);
920+
break;
917921
case WidgetType.DISCOVER:
918922
default:
919923
openLabel = t('Open in Discover');

static/app/views/dashboards/utils/getWidgetExploreUrl.tsx

Lines changed: 88 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import * as Sentry from '@sentry/react';
12
import trimStart from 'lodash/trimStart';
23

34
import type {PageFilters} from 'sentry/types/core';
@@ -14,7 +15,7 @@ import {decodeBoolean, decodeScalar, decodeSorts} from 'sentry/utils/queryString
1415
import {MutableSearch} from 'sentry/utils/tokenizeSearch';
1516
import normalizeUrl from 'sentry/utils/url/normalizeUrl';
1617
import type {DashboardFilters, Widget} from 'sentry/views/dashboards/types';
17-
import {DisplayType} from 'sentry/views/dashboards/types';
18+
import {DisplayType, WidgetType} from 'sentry/views/dashboards/types';
1819
import {
1920
applyDashboardFilters,
2021
eventViewFromWidget,
@@ -29,9 +30,58 @@ import {
2930
LOGS_QUERY_KEY,
3031
} from 'sentry/views/explore/contexts/logs/logsPageParams';
3132
import {Mode} from 'sentry/views/explore/contexts/pageParamsContext/mode';
33+
import {getLogsUrl} from 'sentry/views/explore/logs/utils';
34+
import {TraceItemDataset} from 'sentry/views/explore/types';
3235
import {getExploreMultiQueryUrl, getExploreUrl} from 'sentry/views/explore/utils';
3336
import {ChartType} from 'sentry/views/insights/common/components/chart';
3437

38+
function getTraceItemDatasetFromWidgetType(widgetType?: WidgetType): TraceItemDataset {
39+
switch (widgetType) {
40+
case WidgetType.LOGS:
41+
return TraceItemDataset.LOGS;
42+
case WidgetType.SPANS:
43+
return TraceItemDataset.SPANS;
44+
default:
45+
return TraceItemDataset.SPANS; // Default to spans for backwards compatibility
46+
}
47+
}
48+
49+
function getWidgetExploreUrlWithDataset(traceItemDataset: TraceItemDataset) {
50+
return (
51+
widget: Widget,
52+
dashboardFilters: DashboardFilters | undefined,
53+
selection: PageFilters,
54+
organization: Organization,
55+
preferMode?: Mode
56+
) => {
57+
return _getWidgetExploreUrl(
58+
widget,
59+
dashboardFilters,
60+
selection,
61+
organization,
62+
preferMode,
63+
undefined,
64+
traceItemDataset
65+
);
66+
};
67+
}
68+
69+
const WIDGET_TRACE_ITEM_TO_URL_FUNCTION: Record<
70+
TraceItemDataset,
71+
| ((
72+
widget: Widget,
73+
dashboardFilters: DashboardFilters | undefined,
74+
selection: PageFilters,
75+
organization: Organization,
76+
preferMode?: Mode
77+
) => string)
78+
| undefined
79+
> = {
80+
[TraceItemDataset.LOGS]: getWidgetExploreUrlWithDataset(TraceItemDataset.LOGS),
81+
[TraceItemDataset.SPANS]: getWidgetExploreUrlWithDataset(TraceItemDataset.SPANS),
82+
[TraceItemDataset.UPTIME_RESULTS]: undefined,
83+
};
84+
3585
export function getWidgetLogURL(
3686
widget: Widget,
3787
dashboardFilters: DashboardFilters | undefined,
@@ -105,21 +155,39 @@ export function getWidgetExploreUrl(
105155
organization: Organization,
106156
preferMode?: Mode
107157
) {
158+
const traceItemDataset = getTraceItemDatasetFromWidgetType(widget.widgetType);
159+
108160
if (widget.queries.length > 1) {
161+
if (traceItemDataset === TraceItemDataset.LOGS) {
162+
Sentry.captureException(
163+
new Error(
164+
`getWidgetExploreUrl: multiple queries for logs is unsupported, widget_id: ${widget.id}, organization_id: ${organization.id}, dashboard_id: ${widget.dashboardId}`
165+
)
166+
);
167+
}
109168
return _getWidgetExploreUrlForMultipleQueries(
110169
widget,
111170
dashboardFilters,
112171
selection,
113-
organization
172+
organization,
173+
traceItemDataset
114174
);
115175
}
116176

177+
const urlFunction = WIDGET_TRACE_ITEM_TO_URL_FUNCTION[traceItemDataset];
178+
179+
if (urlFunction) {
180+
return urlFunction(widget, dashboardFilters, selection, organization, preferMode);
181+
}
182+
117183
return _getWidgetExploreUrl(
118184
widget,
119185
dashboardFilters,
120186
selection,
121187
organization,
122-
preferMode
188+
preferMode,
189+
undefined,
190+
traceItemDataset
123191
);
124192
}
125193

@@ -165,7 +233,8 @@ function _getWidgetExploreUrl(
165233
selection: PageFilters,
166234
organization: Organization,
167235
preferMode?: Mode,
168-
overrideQuery?: MutableSearch
236+
overrideQuery?: MutableSearch,
237+
traceItemDataset?: TraceItemDataset
169238
) {
170239
const eventView = eventViewFromWidget(widget.title, widget.queries[0]!, selection);
171240
const locationQueryParams = eventView.generateQueryStringObject();
@@ -287,6 +356,19 @@ function _getWidgetExploreUrl(
287356
getWidgetInterval(widget, selection.datetime),
288357
};
289358

359+
if (traceItemDataset === TraceItemDataset.LOGS) {
360+
return getLogsUrl({
361+
organization: queryParams.organization,
362+
selection: queryParams.selection,
363+
query: queryParams.query,
364+
field: queryParams.field,
365+
groupBy: queryParams.groupBy,
366+
aggregateFields: queryParams.visualize,
367+
interval: queryParams.interval,
368+
mode: queryParams.mode,
369+
});
370+
}
371+
290372
return getExploreUrl(queryParams);
291373
}
292374

@@ -299,7 +381,8 @@ function _getWidgetExploreUrlForMultipleQueries(
299381
widget: Widget,
300382
dashboardFilters: DashboardFilters | undefined,
301383
selection: PageFilters,
302-
organization: Organization
384+
organization: Organization,
385+
_traceItemDataset: TraceItemDataset
303386
): string {
304387
const eventView = eventViewFromWidget(widget.title, widget.queries[0]!, selection);
305388
const locationQueryParams = eventView.generateQueryStringObject();

0 commit comments

Comments
 (0)