Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions web/src/hooks/useTagValues.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,10 @@ export function useTagValues(
.sort((a, b) => a.value.localeCompare(b.value));
},
staleTime: 60 * 1000, // cache tag value response for 1m
// Keep the previous query result during loading.
// Without this setting, the select boxes in the filter bar flicker on every selection,
// because the select box data goes from list of values -> undefined (during loading state) -> list of values.
// The select box values are refreshed because the absolute time range changes.
keepPreviousData: true,
});
}
17 changes: 9 additions & 8 deletions web/src/pages/TracesPage/QueryBrowser.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useCallback, useEffect } from 'react';
import React, { useCallback, useEffect, useRef } from 'react';
import { Divider, PageSection, Split, SplitItem, Stack, Title } from '@patternfly/react-core';
import { useTranslation } from 'react-i18next';
import { TimeRangeSelect } from '../../components/TimeRangeSelect';
Expand Down Expand Up @@ -31,11 +31,18 @@ export function QueryBrowserBody() {
const [query, setQuery] = useQueryParam('q', withDefault(StringParam, '{}'));
const [limit, setLimit] = useQueryParam('limit', withDefault(NumberParam, DEFAULT_LIMIT));
const { refresh } = useTimeRange();
const isInitialRender = useRef(true);

// Refresh query if Tempo instance or tenant changes.
// The Perses data source is selected via a mock DatasourceApiImpl implementation in <PersesWrapper>,
// therefore Perses doesn't refresh automatically if the Tempo instance changes.
useEffect(() => {
// Only call refresh() if the Tempo instance changed, not on the initial render of this component.
if (isInitialRender.current) {
isInitialRender.current = false;
return;
}

refresh();
}, [tempo, refresh]);

Expand All @@ -61,13 +68,7 @@ export function QueryBrowserBody() {
</PageSection>
<PageSection className="mui-pf-theme">
<Stack hasGutter>
<FilterToolbar
tempo={tempo}
setTempo={setTempo}
query={query}
setQuery={setQuery}
runQuery={runQuery}
/>
<FilterToolbar tempo={tempo} setTempo={setTempo} query={query} runQuery={runQuery} />
<PersesTempoDatasourceWrapper
tempo={tempo}
queries={[{ kind: 'TempoTraceQuery', spec: { query, limit } }]}
Expand Down
26 changes: 12 additions & 14 deletions web/src/pages/TracesPage/Toolbar/AttributeFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import { DurationField, Filter, splitByUnquotedWhitespace } from './Filter/filte
import { useTagValues } from '../../../hooks/useTagValues';
import { Link } from 'react-router-dom-v5-compat';
import { useTimeRange } from '@perses-dev/plugin-system';
import { isAbsoluteTimeRange, toAbsoluteTimeRange } from '@perses-dev/core';
import { getUnixTimeRange } from '@perses-dev/tempo-plugin';

const k8sAttributesProcessorLink =
'https://docs.redhat.com/en/documentation/openshift_container_platform/latest/html/red_hat_build_of_opentelemetry/configuring-the-collector#kubernetes-attributes-processor_otel-collector-processors';
Expand All @@ -48,7 +48,7 @@ const attributeFilterOptions = [
interface AttributeFiltersProps {
tempo: TempoInstance | undefined;
query: string;
setQuery: (query: string) => void;
runQuery: (query: string) => void;
}

const statusOptions = [
Expand All @@ -59,44 +59,42 @@ const statusOptions = [

export function AttributeFilters(props: AttributeFiltersProps) {
const { t } = useTranslation('plugin__distributed-tracing-console-plugin');
const { tempo, query, setQuery } = props;
const { tempo, query, runQuery } = props;
const [activeFilter, setActiveFilter] = useState<string | undefined>(
attributeFilterOptions[0].value,
);

const filter = traceQLToFilter(query);
const setFilter = (filter: Filter) => {
setQuery(filterToTraceQL(filter));
runQuery(filterToTraceQL(filter));
};

const { timeRange } = useTimeRange();
const absTimeRange = !isAbsoluteTimeRange(timeRange) ? toAbsoluteTimeRange(timeRange) : timeRange;
const startTime = Math.round(absTimeRange.start.getTime() / 1000);
const endTime = Math.round(absTimeRange.end.getTime() / 1000);
const { absoluteTimeRange } = useTimeRange();
const { start, end } = getUnixTimeRange(absoluteTimeRange);

const { data: serviceNameOptions } = useTagValues(
tempo,
'resource.service.name',
filterToTraceQL({ ...filter, serviceName: [] }),
activeFilter === serviceNameFilter.value,
startTime,
endTime,
start,
end,
);
const { data: spanNameOptions } = useTagValues(
tempo,
'name',
filterToTraceQL({ ...filter, spanName: [] }),
activeFilter === spanNameFilter.value,
startTime,
endTime,
start,
end,
);
const { data: namespaceOptions } = useTagValues(
tempo,
'resource.k8s.namespace.name',
filterToTraceQL({ ...filter, namespace: [] }),
activeFilter === namespaceFilter.value,
startTime,
endTime,
start,
end,
);

return (
Expand Down
6 changes: 2 additions & 4 deletions web/src/pages/TracesPage/Toolbar/FilterToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,13 @@ interface FilterToolbarProps {
tempo: TempoInstance | undefined;
setTempo: (tempo?: TempoInstance) => void;
query: string;
/** Update the query. Fetches the search results only if the query changed. */
setQuery: (query: string) => void;
/** Update and execute the query. Always fetches the search results. */
runQuery: (query: string) => void;
}

export function FilterToolbar(props: FilterToolbarProps) {
const { t } = useTranslation('plugin__distributed-tracing-console-plugin');
const { tempo, setTempo, query, setQuery, runQuery } = props;
const { tempo, setTempo, query, runQuery } = props;
const [showAttributeFilters, setShowAttributeFilters] = useState(isSimpleTraceQLQuery(query));

return (
Expand All @@ -39,7 +37,7 @@ export function FilterToolbar(props: FilterToolbarProps) {
<TempoInstanceDropdown tempo={tempo} setTempo={setTempo} />
<ToolbarToggleGroup toggleIcon={<FilterIcon />} breakpoint="xl">
{showAttributeFilters ? (
<AttributeFilters tempo={tempo} query={query} setQuery={setQuery} />
<AttributeFilters tempo={tempo} query={query} runQuery={runQuery} />
) : (
<TraceQLFilter tempo={tempo} query={query} runQuery={runQuery} />
)}
Expand Down