mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Prometheus: Add classic query option to variable query editor (#74060)
* add classic query to variable query editor * copy fixes * update test
This commit is contained in:
parent
0f552053e9
commit
951876b465
@ -31,13 +31,14 @@ You have the option to use several different variable types, but variables of th
|
||||
|
||||
Select a Prometheus data source query type and enter the required inputs:
|
||||
|
||||
| Query Type | Input(\* required) | Description | Used API endpoints |
|
||||
| -------------- | ------------------------- | ------------------------------------------------------------------------------------- | ---------------------------------------------- |
|
||||
| `Label names` | `metric` | Returns a list of all label names matching the specified `metric` regex. | /api/v1/labels |
|
||||
| `Label values` | `label`\*, `metric` | Returns a list of label values for the `label` in all metrics or the optional metric. | /api/v1/label/`label`/values or /api/v1/series |
|
||||
| `Metrics` | `metric` | Returns a list of metrics matching the specified `metric` regex. | /api/v1/label/\_\_name\_\_/values |
|
||||
| `Query result` | `query` | Returns a list of Prometheus query result for the `query`. | /api/v1/query |
|
||||
| `Series query` | `metric`, `label` or both | Returns a list of time series associated with the entered data. | /api/v1/series |
|
||||
| Query Type | Input(\* required) | Description | Used API endpoints |
|
||||
| --------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
|
||||
| `Label names` | `metric` | Returns a list of all label names matching the specified `metric` regex. | /api/v1/labels |
|
||||
| `Label values` | `label`\*, `metric` | Returns a list of label values for the `label` in all metrics or the optional metric. | /api/v1/label/`label`/values or /api/v1/series |
|
||||
| `Metrics` | `metric` | Returns a list of metrics matching the specified `metric` regex. | /api/v1/label/\_\_name\_\_/values |
|
||||
| `Query result` | `query` | Returns a list of Prometheus query result for the `query`. | /api/v1/query |
|
||||
| `Series query` | `metric`, `label` or both | Returns a list of time series associated with the entered data. | /api/v1/series |
|
||||
| `Classic query` | classic query string | Deprecated, classic version of variable query editor. Enter a string with the query type using a syntax like the following: `label_values(<metric>, <label>)` | all |
|
||||
|
||||
For details on _metric names_, _label names_, and _label values_, refer to the [Prometheus documentation](http://prometheus.io/docs/concepts/data_model/#metric-names-and-labels).
|
||||
|
||||
|
@ -149,6 +149,7 @@ describe('PromVariableQueryEditor', () => {
|
||||
await waitFor(() => expect(screen.getByText('Metrics')).toBeInTheDocument());
|
||||
await waitFor(() => expect(screen.getByText('Query result')).toBeInTheDocument());
|
||||
await waitFor(() => expect(screen.getByText('Series query')).toBeInTheDocument());
|
||||
await waitFor(() => expect(screen.getByText('Classic query')).toBeInTheDocument());
|
||||
});
|
||||
|
||||
test('Calls onChange for label_names(match) query', async () => {
|
||||
@ -167,10 +168,11 @@ describe('PromVariableQueryEditor', () => {
|
||||
expect(onChange).toHaveBeenCalledWith({
|
||||
query: 'label_names(that)',
|
||||
refId,
|
||||
qryType: 0,
|
||||
});
|
||||
});
|
||||
|
||||
test('Calls onChange for label_names, label_values, metrics, and query result queries', async () => {
|
||||
test('Calls onChange for label_names, label_values, metrics, query result and and classic query.', async () => {
|
||||
const onChange = jest.fn();
|
||||
|
||||
props.query = {
|
||||
@ -184,8 +186,9 @@ describe('PromVariableQueryEditor', () => {
|
||||
await selectOptionInTest(screen.getByLabelText('Query type'), 'Label values');
|
||||
await selectOptionInTest(screen.getByLabelText('Query type'), 'Metrics');
|
||||
await selectOptionInTest(screen.getByLabelText('Query type'), 'Query result');
|
||||
await selectOptionInTest(screen.getByLabelText('Query type'), 'Classic query');
|
||||
|
||||
expect(onChange).toHaveBeenCalledTimes(4);
|
||||
expect(onChange).toHaveBeenCalledTimes(5);
|
||||
});
|
||||
|
||||
test('Does not call onChange for series query', async () => {
|
||||
@ -220,6 +223,7 @@ describe('PromVariableQueryEditor', () => {
|
||||
expect(onChange).toHaveBeenCalledWith({
|
||||
query: 'metrics(a)',
|
||||
refId,
|
||||
qryType: 2,
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -230,6 +234,7 @@ describe('PromVariableQueryEditor', () => {
|
||||
props.query = {
|
||||
refId: 'test',
|
||||
query: 'label_names()',
|
||||
qryType: 0,
|
||||
};
|
||||
|
||||
render(<PromVariableQueryEditor {...props} onChange={onChange} />);
|
||||
@ -243,6 +248,7 @@ describe('PromVariableQueryEditor', () => {
|
||||
expect(onChange).toHaveBeenCalledWith({
|
||||
query: 'label_values(this)',
|
||||
refId,
|
||||
qryType: 1,
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -270,6 +276,7 @@ describe('PromVariableQueryEditor', () => {
|
||||
expect(onChange).toHaveBeenCalledWith({
|
||||
query: 'label_values(that,this)',
|
||||
refId,
|
||||
qryType: 1,
|
||||
})
|
||||
);
|
||||
});
|
||||
@ -292,6 +299,7 @@ describe('PromVariableQueryEditor', () => {
|
||||
expect(onChange).toHaveBeenCalledWith({
|
||||
query: 'query_result(a)',
|
||||
refId,
|
||||
qryType: 3,
|
||||
});
|
||||
});
|
||||
|
||||
@ -313,6 +321,30 @@ describe('PromVariableQueryEditor', () => {
|
||||
expect(onChange).toHaveBeenCalledWith({
|
||||
query: '{a: "example"}',
|
||||
refId,
|
||||
qryType: 4,
|
||||
});
|
||||
});
|
||||
|
||||
test('Calls onChange for classic query onBlur', async () => {
|
||||
const onChange = jest.fn();
|
||||
|
||||
props.query = {
|
||||
refId: 'test',
|
||||
qryType: 5,
|
||||
query: 'label_values(instance)',
|
||||
};
|
||||
|
||||
render(<PromVariableQueryEditor {...props} onChange={onChange} />);
|
||||
|
||||
const labelSelect = screen.getByLabelText('Classic Query');
|
||||
await userEvent.click(labelSelect);
|
||||
const functionSelect = screen.getByLabelText('Query type').parentElement!;
|
||||
await userEvent.click(functionSelect);
|
||||
|
||||
expect(onChange).toHaveBeenCalledWith({
|
||||
query: 'label_values(instance)',
|
||||
refId,
|
||||
qryType: 5,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -26,6 +26,7 @@ export const variableOptions = [
|
||||
{ label: 'Metrics', value: QueryType.MetricNames },
|
||||
{ label: 'Query result', value: QueryType.VarQueryResult },
|
||||
{ label: 'Series query', value: QueryType.SeriesQuery },
|
||||
{ label: 'Classic query', value: QueryType.ClassicQuery },
|
||||
];
|
||||
|
||||
export type Props = QueryEditorProps<PrometheusDatasource, PromQuery, PromOptions, PromVariableQuery>;
|
||||
@ -49,6 +50,9 @@ export const PromVariableQueryEditor = ({ onChange, query, datasource }: Props)
|
||||
// seriesQuery is only a whole
|
||||
const [seriesQuery, setSeriesQuery] = useState('');
|
||||
|
||||
// the original variable query implementation
|
||||
const [classicQuery, setClassicQuery] = useState('');
|
||||
|
||||
// list of label names for label_values(), /api/v1/labels, contains the same results as label_names() function
|
||||
const [labelOptions, setLabelOptions] = useState<Array<SelectableValue<string>>>([]);
|
||||
|
||||
@ -59,17 +63,24 @@ export const PromVariableQueryEditor = ({ onChange, query, datasource }: Props)
|
||||
if (!query) {
|
||||
return;
|
||||
}
|
||||
// 1. Changing from standard to custom variable editor changes the string attr from expr to query
|
||||
// 2. jsonnet grafana as code passes a variable as a string
|
||||
const variableQuery = variableMigration(query);
|
||||
|
||||
setLabelNamesMatch(variableQuery.match ?? '');
|
||||
setQryType(variableQuery.qryType);
|
||||
setLabel(variableQuery.label ?? '');
|
||||
setMetric(variableQuery.metric ?? '');
|
||||
setLabelFilters(variableQuery.labelFilters ?? []);
|
||||
setVarQuery(variableQuery.varQuery ?? '');
|
||||
setSeriesQuery(variableQuery.seriesQuery ?? '');
|
||||
if (query.qryType === QueryType.ClassicQuery) {
|
||||
setQryType(query.qryType);
|
||||
setClassicQuery(query.query ?? '');
|
||||
} else {
|
||||
// 1. Changing from standard to custom variable editor changes the string attr from expr to query
|
||||
// 2. jsonnet grafana as code passes a variable as a string
|
||||
const variableQuery = variableMigration(query);
|
||||
|
||||
setLabelNamesMatch(variableQuery.match ?? '');
|
||||
setQryType(variableQuery.qryType);
|
||||
setLabel(variableQuery.label ?? '');
|
||||
setMetric(variableQuery.metric ?? '');
|
||||
setLabelFilters(variableQuery.labelFilters ?? []);
|
||||
setVarQuery(variableQuery.varQuery ?? '');
|
||||
setSeriesQuery(variableQuery.seriesQuery ?? '');
|
||||
setClassicQuery(variableQuery.classicQuery ?? '');
|
||||
}
|
||||
}, [query]);
|
||||
|
||||
// set the label names options for the label values var query
|
||||
@ -116,6 +127,7 @@ export const PromVariableQueryEditor = ({ onChange, query, datasource }: Props)
|
||||
match: labelNamesMatch,
|
||||
varQuery,
|
||||
seriesQuery,
|
||||
classicQuery,
|
||||
refId: 'PrometheusVariableQueryEditor-VariableQuery',
|
||||
};
|
||||
|
||||
@ -128,6 +140,7 @@ export const PromVariableQueryEditor = ({ onChange, query, datasource }: Props)
|
||||
// setting query.query property allows for update of variable definition
|
||||
onChange({
|
||||
query: queryString,
|
||||
qryType: updatedVar.qryType,
|
||||
refId,
|
||||
});
|
||||
};
|
||||
@ -200,6 +213,10 @@ export const PromVariableQueryEditor = ({ onChange, query, datasource }: Props)
|
||||
setSeriesQuery(e.currentTarget.value);
|
||||
};
|
||||
|
||||
const onClassicQueryChange = (e: FormEvent<HTMLInputElement>) => {
|
||||
setClassicQuery(e.currentTarget.value);
|
||||
};
|
||||
|
||||
const promVisualQuery = useCallback(() => {
|
||||
return { metric: metric, labels: labelFilters, operations: [] };
|
||||
}, [metric, labelFilters]);
|
||||
@ -371,6 +388,35 @@ export const PromVariableQueryEditor = ({ onChange, query, datasource }: Props)
|
||||
</InlineField>
|
||||
</InlineFieldRow>
|
||||
)}
|
||||
|
||||
{qryType === QueryType.ClassicQuery && (
|
||||
<InlineFieldRow>
|
||||
<InlineField
|
||||
label="Classic Query"
|
||||
labelWidth={20}
|
||||
tooltip={
|
||||
<div>
|
||||
The original implemetation of the Prometheus variable query editor. Enter a string with the correct
|
||||
query type and parameters as described in these docs. For example, label_values(label, metric).
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<Input
|
||||
type="text"
|
||||
aria-label="Classic Query"
|
||||
placeholder="Classic Query"
|
||||
value={classicQuery}
|
||||
onChange={onClassicQueryChange}
|
||||
onBlur={() => {
|
||||
if (qryType === QueryType.ClassicQuery && classicQuery) {
|
||||
onChangeWithVariableString({ qryType });
|
||||
}
|
||||
}}
|
||||
width={100}
|
||||
/>
|
||||
</InlineField>
|
||||
</InlineFieldRow>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -123,7 +123,9 @@ export function migrateVariableEditorBackToVariableSupport(QueryVariable: PromVa
|
||||
const varQuery = removeLineBreaks(QueryVariable.varQuery);
|
||||
return `query_result(${varQuery})`;
|
||||
case QueryType.SeriesQuery:
|
||||
return '' + QueryVariable.seriesQuery;
|
||||
return QueryVariable.seriesQuery ?? '';
|
||||
case QueryType.ClassicQuery:
|
||||
return QueryVariable.classicQuery ?? '';
|
||||
}
|
||||
|
||||
return '';
|
||||
|
@ -183,6 +183,7 @@ export enum PromVariableQueryType {
|
||||
MetricNames,
|
||||
VarQueryResult,
|
||||
SeriesQuery,
|
||||
ClassicQuery,
|
||||
}
|
||||
|
||||
export interface PromVariableQuery extends DataQuery {
|
||||
@ -195,6 +196,7 @@ export interface PromVariableQuery extends DataQuery {
|
||||
seriesQuery?: string;
|
||||
labelFilters?: QueryBuilderLabelFilter[];
|
||||
match?: string;
|
||||
classicQuery?: string;
|
||||
}
|
||||
|
||||
export type StandardPromVariableQuery = {
|
||||
|
Loading…
Reference in New Issue
Block a user