mirror of
https://github.com/grafana/grafana.git
synced 2024-11-26 02:40:26 -06:00
Prometheus: Support with aggregations without labels (#45160)
This commit is contained in:
parent
14c639fdb5
commit
68eb18c758
@ -80,6 +80,16 @@ describe('PromQueryModeller', () => {
|
||||
).toBe('avg(sum by(server, job) (metric))');
|
||||
});
|
||||
|
||||
it('Can use aggregation without label', () => {
|
||||
expect(
|
||||
modeller.renderQuery({
|
||||
metric: 'metric',
|
||||
labels: [],
|
||||
operations: [{ id: '__sum_without', params: ['server', 'job'] }],
|
||||
})
|
||||
).toBe('sum without(server, job) (metric)');
|
||||
});
|
||||
|
||||
it('Can render aggregations with parameters', () => {
|
||||
expect(
|
||||
modeller.renderQuery({
|
||||
|
@ -67,7 +67,28 @@ function createAggregationOperation(name: string): QueryBuilderOperationDef[] {
|
||||
renderer: getAggregationByRenderer(name),
|
||||
addOperationHandler: defaultAddOperationHandler,
|
||||
paramChangedHandler: getLastLabelRemovedHandler(name),
|
||||
explainHandler: getAggregationExplainer(name),
|
||||
explainHandler: getAggregationExplainer(name, 'by'),
|
||||
hideFromList: true,
|
||||
},
|
||||
{
|
||||
id: `__${name}_without`,
|
||||
name: `${getPromAndLokiOperationDisplayName(name)} without`,
|
||||
params: [
|
||||
{
|
||||
name: 'Label',
|
||||
type: 'string',
|
||||
restParam: true,
|
||||
optional: true,
|
||||
editor: LabelParamEditor,
|
||||
},
|
||||
],
|
||||
defaultParams: [''],
|
||||
alternativesKey: 'aggregations by',
|
||||
category: PromVisualQueryOperationCategory.Aggregations,
|
||||
renderer: getAggregationWithoutRenderer(name),
|
||||
addOperationHandler: defaultAddOperationHandler,
|
||||
paramChangedHandler: getLastLabelRemovedHandler(name),
|
||||
explainHandler: getAggregationExplainer(name, 'without'),
|
||||
hideFromList: true,
|
||||
},
|
||||
];
|
||||
@ -94,14 +115,24 @@ function getAggregationByRenderer(aggregation: string) {
|
||||
};
|
||||
}
|
||||
|
||||
function getAggregationWithoutRenderer(aggregation: string) {
|
||||
return function aggregationRenderer(model: QueryBuilderOperation, def: QueryBuilderOperationDef, innerExpr: string) {
|
||||
return `${aggregation} without(${model.params.join(', ')}) (${innerExpr})`;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Very simple poc implementation, needs to be modified to support all aggregation operators
|
||||
*/
|
||||
function getAggregationExplainer(aggregationName: string) {
|
||||
function getAggregationExplainer(aggregationName: string, mode: 'by' | 'without') {
|
||||
return function aggregationExplainer(model: QueryBuilderOperation) {
|
||||
const labels = model.params.map((label) => `\`${label}\``).join(' and ');
|
||||
const labelWord = pluralize('label', model.params.length);
|
||||
return `Calculates ${aggregationName} over dimensions while preserving ${labelWord} ${labels}.`;
|
||||
if (mode === 'by') {
|
||||
return `Calculates ${aggregationName} over dimensions while preserving ${labelWord} ${labels}.`;
|
||||
} else {
|
||||
return `Calculates ${aggregationName} over the dimensions ${labels}. All other labels are preserved.`;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -93,6 +93,31 @@ describe('buildVisualQueryFromString', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('parses query with aggregation without labels', () => {
|
||||
const visQuery = {
|
||||
metric: 'metric_name',
|
||||
labels: [
|
||||
{
|
||||
label: 'instance',
|
||||
op: '=',
|
||||
value: 'internal:3000',
|
||||
},
|
||||
],
|
||||
operations: [
|
||||
{
|
||||
id: '__sum_without',
|
||||
params: ['app', 'version'],
|
||||
},
|
||||
],
|
||||
};
|
||||
expect(buildVisualQueryFromString('sum(metric_name{instance="internal:3000"}) without (app, version)')).toEqual(
|
||||
noErrors(visQuery)
|
||||
);
|
||||
expect(buildVisualQueryFromString('sum without (app, version)(metric_name{instance="internal:3000"})')).toEqual(
|
||||
noErrors(visQuery)
|
||||
);
|
||||
});
|
||||
|
||||
it('parses aggregation with params', () => {
|
||||
expect(buildVisualQueryFromString('topk(5, http_requests_total)')).toEqual(
|
||||
noErrors({
|
||||
|
@ -233,12 +233,17 @@ function handleAggregation(expr: string, node: SyntaxNode, context: Context) {
|
||||
const modifier = node.getChild('AggregateModifier');
|
||||
const labels = [];
|
||||
|
||||
// TODO: support also Without modifier (but we don't support it in visual query yet)
|
||||
if (modifier) {
|
||||
const byModifier = modifier.getChild(`By`);
|
||||
if (byModifier && funcName) {
|
||||
funcName = `__${funcName}_by`;
|
||||
}
|
||||
|
||||
const withoutModifier = modifier.getChild(`Without`);
|
||||
if (withoutModifier) {
|
||||
funcName = `__${funcName}_without`;
|
||||
}
|
||||
|
||||
labels.push(...getAllByType(expr, modifier, 'GroupingLabel'));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user