mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Tempo: Filter available service graph filter values to most relevant options (#43728)
* Restrict service graph filter tag values to labels from service graph metrics
This commit is contained in:
parent
cb34c47123
commit
1a7567d8c7
@ -12,6 +12,9 @@ interface Props {
|
||||
addFilter: (filter: AdHocVariableFilter) => void;
|
||||
removeFilter: (index: number) => void;
|
||||
changeFilter: (index: number, newFilter: AdHocVariableFilter) => void;
|
||||
// Passes options to the datasources getTagKeys(options?: any) method
|
||||
// which is called to fetch the available filter key options in AdHocFilterKey.tsx
|
||||
getTagKeysOptions?: any;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -51,6 +54,7 @@ export class AdHocFilter extends PureComponent<Props> {
|
||||
datasource={this.props.datasource!}
|
||||
appendBefore={filters.length > 0 ? <ConditionSegment label="AND" /> : null}
|
||||
onCompleted={this.appendFilterToVariable}
|
||||
getTagKeysOptions={this.props.getTagKeysOptions}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
@ -75,6 +79,7 @@ export class AdHocFilter extends PureComponent<Props> {
|
||||
onKeyChange={this.onChange(index, 'key')}
|
||||
onOperatorChange={this.onChange(index, 'operator')}
|
||||
onValueChange={this.onChange(index, 'value')}
|
||||
getTagKeysOptions={this.props.getTagKeysOptions}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
|
@ -8,9 +8,10 @@ interface Props {
|
||||
datasource: DataSourceRef;
|
||||
onCompleted: (filter: AdHocVariableFilter) => void;
|
||||
appendBefore?: React.ReactNode;
|
||||
getTagKeysOptions?: any;
|
||||
}
|
||||
|
||||
export const AdHocFilterBuilder: FC<Props> = ({ datasource, appendBefore, onCompleted }) => {
|
||||
export const AdHocFilterBuilder: FC<Props> = ({ datasource, appendBefore, onCompleted, getTagKeysOptions }) => {
|
||||
const [key, setKey] = useState<string | null>(null);
|
||||
const [operator, setOperator] = useState<string>('=');
|
||||
|
||||
@ -44,7 +45,14 @@ export const AdHocFilterBuilder: FC<Props> = ({ datasource, appendBefore, onComp
|
||||
);
|
||||
|
||||
if (key === null) {
|
||||
return <AdHocFilterKey datasource={datasource} filterKey={key} onChange={onKeyChanged} />;
|
||||
return (
|
||||
<AdHocFilterKey
|
||||
datasource={datasource}
|
||||
filterKey={key}
|
||||
onChange={onKeyChanged}
|
||||
getTagKeysOptions={getTagKeysOptions}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
@ -57,6 +65,7 @@ export const AdHocFilterBuilder: FC<Props> = ({ datasource, appendBefore, onComp
|
||||
onKeyChange={onKeyChanged}
|
||||
onOperatorChange={onOperatorChanged}
|
||||
onValueChange={onValueChanged}
|
||||
getTagKeysOptions={getTagKeysOptions}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
|
@ -7,12 +7,13 @@ interface Props {
|
||||
datasource: DataSourceRef;
|
||||
filterKey: string | null;
|
||||
onChange: (item: SelectableValue<string | null>) => void;
|
||||
getTagKeysOptions?: any;
|
||||
}
|
||||
|
||||
const MIN_WIDTH = 90;
|
||||
export const AdHocFilterKey: FC<Props> = ({ datasource, onChange, filterKey }) => {
|
||||
const loadKeys = () => fetchFilterKeys(datasource);
|
||||
const loadKeysWithRemove = () => fetchFilterKeysWithRemove(datasource);
|
||||
export const AdHocFilterKey: FC<Props> = ({ datasource, onChange, filterKey, getTagKeysOptions }) => {
|
||||
const loadKeys = () => fetchFilterKeys(datasource, getTagKeysOptions);
|
||||
const loadKeysWithRemove = () => fetchFilterKeysWithRemove(datasource, getTagKeysOptions);
|
||||
|
||||
if (filterKey === null) {
|
||||
return (
|
||||
@ -51,18 +52,24 @@ const plusSegment: ReactElement = (
|
||||
</a>
|
||||
);
|
||||
|
||||
const fetchFilterKeys = async (datasource: DataSourceRef): Promise<Array<SelectableValue<string>>> => {
|
||||
const fetchFilterKeys = async (
|
||||
datasource: DataSourceRef,
|
||||
getTagKeysOptions?: any
|
||||
): Promise<Array<SelectableValue<string>>> => {
|
||||
const ds = await getDatasourceSrv().get(datasource);
|
||||
|
||||
if (!ds || !ds.getTagKeys) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const metrics = await ds.getTagKeys();
|
||||
const metrics = await ds.getTagKeys(getTagKeysOptions);
|
||||
return metrics.map((m) => ({ label: m.text, value: m.text }));
|
||||
};
|
||||
|
||||
const fetchFilterKeysWithRemove = async (datasource: DataSourceRef): Promise<Array<SelectableValue<string>>> => {
|
||||
const keys = await fetchFilterKeys(datasource);
|
||||
const fetchFilterKeysWithRemove = async (
|
||||
datasource: DataSourceRef,
|
||||
getTagKeysOptions?: any
|
||||
): Promise<Array<SelectableValue<string>>> => {
|
||||
const keys = await fetchFilterKeys(datasource, getTagKeysOptions);
|
||||
return [REMOVE_VALUE, ...keys];
|
||||
};
|
||||
|
@ -12,6 +12,7 @@ interface Props {
|
||||
onOperatorChange: (item: SelectableValue<string>) => void;
|
||||
onValueChange: (item: SelectableValue<string>) => void;
|
||||
placeHolder?: string;
|
||||
getTagKeysOptions?: any;
|
||||
}
|
||||
|
||||
export const AdHocFilterRenderer: FC<Props> = ({
|
||||
@ -21,10 +22,16 @@ export const AdHocFilterRenderer: FC<Props> = ({
|
||||
onOperatorChange,
|
||||
onValueChange,
|
||||
placeHolder,
|
||||
getTagKeysOptions,
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
<AdHocFilterKey datasource={datasource} filterKey={key} onChange={onKeyChange} />
|
||||
<AdHocFilterKey
|
||||
datasource={datasource}
|
||||
filterKey={key}
|
||||
onChange={onKeyChange}
|
||||
getTagKeysOptions={getTagKeysOptions}
|
||||
/>
|
||||
<div className="gf-form">
|
||||
<OperatorSegment value={operator} onChange={onOperatorChange} />
|
||||
</div>
|
||||
|
@ -790,10 +790,20 @@ export class PrometheusDatasource
|
||||
);
|
||||
}
|
||||
|
||||
async getTagKeys() {
|
||||
async getTagKeys(options?: any) {
|
||||
if (options?.series) {
|
||||
// Get tags for the provided series only
|
||||
const seriesLabels: Array<Record<string, string[]>> = await Promise.all(
|
||||
options.series.map((series: string) => this.languageProvider.fetchSeriesLabels(series))
|
||||
);
|
||||
const uniqueLabels = [...new Set(...seriesLabels.map((value) => Object.keys(value)))];
|
||||
return uniqueLabels.map((value: any) => ({ text: value }));
|
||||
} else {
|
||||
// Get all tags
|
||||
const result = await this.metadataRequest('/api/v1/labels');
|
||||
return result?.data?.data?.map((value: any) => ({ text: value })) ?? [];
|
||||
}
|
||||
}
|
||||
|
||||
async getTagValues(options: { key?: string } = {}) {
|
||||
const result = await this.metadataRequest(`/api/v1/label/${options.key}/values`);
|
||||
|
@ -44,6 +44,13 @@ export function ServiceGraphSection({
|
||||
<AdHocFilter
|
||||
datasource={{ uid: graphDatasourceUid }}
|
||||
filters={filters}
|
||||
getTagKeysOptions={{
|
||||
series: [
|
||||
'traces_service_graph_request_server_seconds_sum',
|
||||
'traces_service_graph_request_total',
|
||||
'traces_service_graph_request_failed_total',
|
||||
],
|
||||
}}
|
||||
addFilter={(filter: AdHocVariableFilter) => {
|
||||
onChange({
|
||||
...query,
|
||||
|
Loading…
Reference in New Issue
Block a user