Skip to content

Commit e22ecb2

Browse files
authored
fix(ourlogs): Fix title and link for ourlog queries (#97519)
### Summary Link in the explore secondary nav and the title were both still referencing traces instead of logs
1 parent 977d932 commit e22ecb2

File tree

8 files changed

+160
-71
lines changed

8 files changed

+160
-71
lines changed

static/app/views/explore/components/breadcrumb.tsx

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,25 @@ import type {Crumb} from 'sentry/components/breadcrumbs';
22
import Breadcrumbs from 'sentry/components/breadcrumbs';
33
import {t} from 'sentry/locale';
44
import useOrganization from 'sentry/utils/useOrganization';
5+
import {makeLogsPathname} from 'sentry/views/explore/logs/utils';
6+
import {TraceItemDataset} from 'sentry/views/explore/types';
57
import {makeTracesPathname} from 'sentry/views/traces/pathnames';
68

7-
function ExploreBreadcrumb() {
9+
function ExploreBreadcrumb({traceItemDataset}: {traceItemDataset: TraceItemDataset}) {
810
const organization = useOrganization();
911
const crumbs: Crumb[] = [];
10-
crumbs.push({
11-
to: makeTracesPathname({organization, path: '/'}),
12-
label: t('Traces'),
13-
});
12+
if (traceItemDataset === TraceItemDataset.SPANS) {
13+
crumbs.push({
14+
to: makeTracesPathname({organization, path: '/'}),
15+
label: t('Traces'),
16+
});
17+
}
18+
if (traceItemDataset === TraceItemDataset.LOGS) {
19+
crumbs.push({
20+
to: makeLogsPathname({organization, path: '/'}),
21+
label: t('Logs'),
22+
});
23+
}
1424
crumbs.push({
1525
label: t('Saved Query'),
1626
});

static/app/views/explore/contexts/logs/logsPageParams.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ export function LogsPageParamsProvider({
168168
}
169169
}
170170

171+
const title = getLogTitleFromLocation(location);
172+
const id = getLogIdFromLocation(location);
171173
const fields = isTableFrozen ? defaultLogFields() : getLogFieldsFromLocation(location);
172174
const sortBys = isTableFrozen
173175
? [logsTimestampDescendingSortBy]
@@ -211,6 +213,8 @@ export function LogsPageParamsProvider({
211213
search,
212214
setSearchForFrozenPages,
213215
sortBys,
216+
title,
217+
id,
214218
cursor,
215219
setCursorForFrozenPages,
216220
isTableFrozen,
@@ -430,6 +434,16 @@ export function useLogsFields() {
430434
return fields;
431435
}
432436

437+
export function useLogsId() {
438+
const {id} = useLogsPageParams();
439+
return id;
440+
}
441+
442+
export function useLogsTitle() {
443+
const {title} = useLogsPageParams();
444+
return title;
445+
}
446+
433447
export function useLogsProjectIds() {
434448
const {projectIds} = useLogsPageParams();
435449
return projectIds;
@@ -499,6 +513,14 @@ export function useLogsAnalyticsPageSource() {
499513
return analyticsPageSource;
500514
}
501515

516+
function getLogTitleFromLocation(location: Location): string {
517+
return decodeScalar(location.query.title, '');
518+
}
519+
520+
function getLogIdFromLocation(location: Location): string {
521+
return decodeScalar(location.query.id, '');
522+
}
523+
502524
function getLogCursorFromLocation(location: Location): string {
503525
if (!location.query?.[LOGS_CURSOR_KEY]) {
504526
return '';

static/app/views/explore/logs/content.tsx

Lines changed: 66 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,18 @@ import PageFiltersContainer from 'sentry/components/organizations/pageFilters/co
77
import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
88
import {IconMegaphone, IconOpen} from 'sentry/icons';
99
import {t} from 'sentry/locale';
10+
import {defined} from 'sentry/utils';
1011
import {trackAnalytics} from 'sentry/utils/analytics';
1112
import {LogsAnalyticsPageSource} from 'sentry/utils/analytics/logsAnalyticsEvent';
1213
import {useFeedbackForm} from 'sentry/utils/useFeedbackForm';
1314
import useOrganization from 'sentry/utils/useOrganization';
15+
import ExploreBreadcrumb from 'sentry/views/explore/components/breadcrumb';
1416
import {LogsPageDataProvider} from 'sentry/views/explore/contexts/logs/logsPageData';
15-
import {LogsPageParamsProvider} from 'sentry/views/explore/contexts/logs/logsPageParams';
17+
import {
18+
LogsPageParamsProvider,
19+
useLogsId,
20+
useLogsTitle,
21+
} from 'sentry/views/explore/contexts/logs/logsPageParams';
1622
import {TraceItemAttributeProvider} from 'sentry/views/explore/contexts/traceItemAttributeContext';
1723
import {LOGS_INSTRUCTIONS_URL} from 'sentry/views/explore/logs/constants';
1824
import {LogsQueryParamsProvider} from 'sentry/views/explore/logs/logsQueryParamsProvider';
@@ -52,8 +58,6 @@ export default function LogsContent() {
5258
const {defaultPeriod, maxPickableDays, relativeOptions} =
5359
logsPickableDays(organization);
5460

55-
const prefersStackedNav = usePrefersStackedNav();
56-
5761
return (
5862
<SentryDocumentTitle title={t('Logs')} orgSlug={organization?.slug}>
5963
<PageFiltersContainer
@@ -67,59 +71,73 @@ export default function LogsContent() {
6771
},
6872
}}
6973
>
70-
<Layout.Page>
71-
<Layout.Header unified={prefersStackedNav}>
72-
<Layout.HeaderContent unified={prefersStackedNav}>
73-
<Layout.Title>
74-
{t('Logs')}
75-
<FeatureBadge
76-
type="beta"
77-
tooltipProps={{
78-
title: t(
79-
"This feature is currently in beta and we're actively working on it"
80-
),
81-
isHoverable: true,
82-
}}
83-
/>
84-
</Layout.Title>
85-
</Layout.HeaderContent>
86-
<Layout.HeaderActions>
87-
<ButtonBar>
88-
<FeedbackButton />
89-
<LinkButton
90-
icon={<IconOpen />}
91-
priority="primary"
92-
href={LOGS_INSTRUCTIONS_URL}
93-
external
94-
size="xs"
95-
onMouseDown={() => {
96-
trackAnalytics('logs.doc_link.clicked', {
97-
organization,
98-
});
99-
}}
100-
>
101-
{t('Set Up Logs')}
102-
</LinkButton>
103-
</ButtonBar>
104-
</Layout.HeaderActions>
105-
</Layout.Header>
106-
<TraceItemAttributeProvider traceItemType={TraceItemDataset.LOGS} enabled>
107-
<LogsQueryParamsProvider source="location">
108-
<LogsPageParamsProvider
109-
analyticsPageSource={LogsAnalyticsPageSource.EXPLORE_LOGS}
110-
>
74+
<LogsQueryParamsProvider source="location">
75+
<LogsPageParamsProvider
76+
analyticsPageSource={LogsAnalyticsPageSource.EXPLORE_LOGS}
77+
>
78+
<Layout.Page>
79+
<LogsHeader />
80+
<TraceItemAttributeProvider traceItemType={TraceItemDataset.LOGS} enabled>
11181
<LogsPageDataProvider>
11282
<LogsTabContent
11383
defaultPeriod={defaultPeriod}
11484
maxPickableDays={maxPickableDays}
11585
relativeOptions={relativeOptions}
11686
/>
11787
</LogsPageDataProvider>
118-
</LogsPageParamsProvider>
119-
</LogsQueryParamsProvider>
120-
</TraceItemAttributeProvider>
121-
</Layout.Page>
88+
</TraceItemAttributeProvider>
89+
</Layout.Page>
90+
</LogsPageParamsProvider>
91+
</LogsQueryParamsProvider>
12292
</PageFiltersContainer>
12393
</SentryDocumentTitle>
12494
);
12595
}
96+
97+
function LogsHeader() {
98+
const organization = useOrganization();
99+
const prefersStackedNav = usePrefersStackedNav();
100+
101+
const pageId = useLogsId();
102+
const title = useLogsTitle();
103+
return (
104+
<Layout.Header unified={prefersStackedNav}>
105+
<Layout.HeaderContent unified={prefersStackedNav}>
106+
<Layout.Title>
107+
{title && defined(pageId) ? (
108+
<ExploreBreadcrumb traceItemDataset={TraceItemDataset.LOGS} />
109+
) : null}
110+
{title ? title : t('Logs')}
111+
<FeatureBadge
112+
type="beta"
113+
tooltipProps={{
114+
title: t(
115+
"This feature is currently in beta and we're actively working on it"
116+
),
117+
isHoverable: true,
118+
}}
119+
/>
120+
</Layout.Title>
121+
</Layout.HeaderContent>
122+
<Layout.HeaderActions>
123+
<ButtonBar>
124+
<FeedbackButton />
125+
<LinkButton
126+
icon={<IconOpen />}
127+
priority="primary"
128+
href={LOGS_INSTRUCTIONS_URL}
129+
external
130+
size="xs"
131+
onMouseDown={() => {
132+
trackAnalytics('logs.doc_link.clicked', {
133+
organization,
134+
});
135+
}}
136+
>
137+
{t('Set Up Logs')}
138+
</LinkButton>
139+
</ButtonBar>
140+
</Layout.HeaderActions>
141+
</Layout.Header>
142+
);
143+
}

static/app/views/explore/logs/utils.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ export function getLogsUrl({
399399
);
400400
}
401401

402-
function makeLogsPathname({
402+
export function makeLogsPathname({
403403
organization,
404404
path,
405405
}: {
@@ -409,10 +409,13 @@ function makeLogsPathname({
409409
return normalizeUrl(`/organizations/${organization.slug}/explore/logs${path}`);
410410
}
411411

412-
export function getLogsUrlFromSavedQueryUrl(
413-
savedQuery: SavedQuery,
414-
organization: Organization
415-
) {
412+
export function getLogsUrlFromSavedQueryUrl({
413+
savedQuery,
414+
organization,
415+
}: {
416+
organization: Organization;
417+
savedQuery: SavedQuery;
418+
}) {
416419
const firstQuery = savedQuery.query[0];
417420
const visualize = firstQuery.visualize?.[0]?.yAxes?.[0];
418421
const aggregateFn = visualize ? visualize.split('(')[0] : undefined;

static/app/views/explore/savedQueries/savedQueriesTable.tsx

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,11 @@ import {
3030
} from 'sentry/views/explore/hooks/useGetSavedQueries';
3131
import {useFromSavedQuery} from 'sentry/views/explore/hooks/useSaveQuery';
3232
import {useStarQuery} from 'sentry/views/explore/hooks/useStarQuery';
33-
import {getLogsUrlFromSavedQueryUrl} from 'sentry/views/explore/logs/utils';
3433
import {ExploreParams} from 'sentry/views/explore/savedQueries/exploreParams';
3534
import {TraceItemDataset} from 'sentry/views/explore/types';
3635
import {
3736
confirmDeleteSavedQuery,
38-
getExploreUrlFromSavedQueryUrl,
37+
getSavedQueryTraceItemUrl,
3938
} from 'sentry/views/explore/utils';
4039

4140
type Props = {
@@ -228,11 +227,7 @@ export function SavedQueriesTable({
228227
</SavedEntityTable.Cell>
229228
<SavedEntityTable.Cell data-column="name">
230229
<SavedEntityTable.CellName
231-
to={
232-
query.dataset === 'logs'
233-
? getLogsUrlFromSavedQueryUrl(query, organization)
234-
: getExploreUrlFromSavedQueryUrl({savedQuery: query, organization})
235-
}
230+
to={getSavedQueryTraceItemUrl({savedQuery: query, organization})}
236231
>
237232
{query.name}
238233
</SavedEntityTable.CellName>

static/app/views/explore/spans/content.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,9 @@ function SpansTabHeader({organization}: SpansTabHeaderProps) {
135135
return (
136136
<Layout.Header unified={prefersStackedNav}>
137137
<Layout.HeaderContent unified={prefersStackedNav}>
138-
{title && defined(id) ? <ExploreBreadcrumb /> : null}
138+
{title && defined(id) ? (
139+
<ExploreBreadcrumb traceItemDataset={TraceItemDataset.SPANS} />
140+
) : null}
139141
<Layout.Title>
140142
{title ? title : t('Traces')}
141143
<PageHeadingQuestionTooltip

static/app/views/explore/utils.tsx

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type {ReactNode} from 'react';
22
import styled from '@emotion/styled';
3+
import * as Sentry from '@sentry/react';
34
import type {Location} from 'history';
45
import * as qs from 'query-string';
56

@@ -40,8 +41,13 @@ import type {
4041
RawVisualize,
4142
SavedQuery,
4243
} from 'sentry/views/explore/hooks/useGetSavedQueries';
43-
import {isRawVisualize} from 'sentry/views/explore/hooks/useGetSavedQueries';
44+
import {
45+
getSavedQueryTraceItemDataset,
46+
isRawVisualize,
47+
} from 'sentry/views/explore/hooks/useGetSavedQueries';
48+
import {getLogsUrlFromSavedQueryUrl} from 'sentry/views/explore/logs/utils';
4449
import type {ReadableExploreQueryParts} from 'sentry/views/explore/multiQueryMode/locationUtils';
50+
import {TraceItemDataset} from 'sentry/views/explore/types';
4551
import type {ChartType} from 'sentry/views/insights/common/components/chart';
4652
import {isChartType} from 'sentry/views/insights/common/components/chart';
4753
import type {useSortedTimeSeries} from 'sentry/views/insights/common/queries/useSortedTimeSeries';
@@ -106,7 +112,7 @@ export function getExploreUrl({
106112
);
107113
}
108114

109-
export function getExploreUrlFromSavedQueryUrl({
115+
function getExploreUrlFromSavedQueryUrl({
110116
savedQuery,
111117
organization,
112118
}: {
@@ -656,3 +662,36 @@ export const onlyShowKeys = (tagCollection: Tag[], keys: string[]): Tag[] => {
656662
});
657663
return result;
658664
};
665+
666+
export function getSavedQueryTraceItemUrl({
667+
savedQuery,
668+
organization,
669+
}: {
670+
organization: Organization;
671+
savedQuery: SavedQuery;
672+
}) {
673+
const traceItemDataset = getSavedQueryTraceItemDataset(savedQuery.dataset);
674+
const urlFunction = TRACE_ITEM_TO_URL_FUNCTION[traceItemDataset];
675+
if (urlFunction) {
676+
return urlFunction({savedQuery, organization});
677+
}
678+
// Invariant, only spans and logs are currently supported.
679+
Sentry.captureMessage(
680+
`Saved query ${savedQuery.id} has an invalid dataset: ${savedQuery.dataset}`
681+
);
682+
return getExploreUrlFromSavedQueryUrl({savedQuery, organization});
683+
}
684+
685+
const TRACE_ITEM_TO_URL_FUNCTION: Record<
686+
TraceItemDataset,
687+
({
688+
savedQuery,
689+
organization,
690+
}: {
691+
organization: Organization;
692+
savedQuery: SavedQuery;
693+
}) => string
694+
> = {
695+
[TraceItemDataset.LOGS]: getLogsUrlFromSavedQueryUrl,
696+
[TraceItemDataset.SPANS]: getExploreUrlFromSavedQueryUrl,
697+
};

static/app/views/nav/secondary/sections/explore/exploreSavedQueryNavItems.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ import {useLocation} from 'sentry/utils/useLocation';
1111
import useOrganization from 'sentry/utils/useOrganization';
1212
import useProjects from 'sentry/utils/useProjects';
1313
import {getIdFromLocation} from 'sentry/views/explore/contexts/pageParamsContext/id';
14-
import type {SavedQuery} from 'sentry/views/explore/hooks/useGetSavedQueries';
14+
import {type SavedQuery} from 'sentry/views/explore/hooks/useGetSavedQueries';
1515
import {useReorderStarredSavedQueries} from 'sentry/views/explore/hooks/useReorderStarredSavedQueries';
16-
import {getExploreUrlFromSavedQueryUrl} from 'sentry/views/explore/utils';
16+
import {getSavedQueryTraceItemUrl} from 'sentry/views/explore/utils';
1717
import ProjectIcon from 'sentry/views/nav/projectIcon';
1818
import {SecondaryNav} from 'sentry/views/nav/secondary/secondary';
1919

@@ -111,7 +111,7 @@ export function ExploreSavedQueryNavItems({queries}: Props) {
111111
</LeadingItemsWrapper>
112112
}
113113
key={query.id}
114-
to={getExploreUrlFromSavedQueryUrl({savedQuery: query, organization})}
114+
to={getSavedQueryTraceItemUrl({savedQuery: query, organization})}
115115
analyticsItemName="explore_starred_item"
116116
isActive={id === query.id.toString()}
117117
>

0 commit comments

Comments
 (0)