소스 검색

Merge pull request #14104 from grafana/davkal/prometheus-rule-expansion

Prometheus: fix rules expansion
David 7 년 전
부모
커밋
c20c787b62

+ 3 - 5
public/app/plugins/datasource/prometheus/datasource.ts

@@ -10,6 +10,7 @@ import { BackendSrv } from 'app/core/services/backend_srv';
 
 import addLabelToQuery from './add_label_to_query';
 import { getQueryHints } from './query_hints';
+import { expandRecordingRules } from './language_utils';
 
 export function alignRange(start, end, step) {
   const alignedEnd = Math.ceil(end / step) * step;
@@ -468,11 +469,8 @@ export class PrometheusDatasource {
         return `sum(${query.trim()}) by ($1)`;
       }
       case 'EXPAND_RULES': {
-        const mapping = action.mapping;
-        if (mapping) {
-          const ruleNames = Object.keys(mapping);
-          const rulesRegex = new RegExp(`(\\s|^)(${ruleNames.join('|')})(\\s|$|\\()`, 'ig');
-          return query.replace(rulesRegex, (match, pre, name, post) => mapping[name]);
+        if (action.mapping) {
+          return expandRecordingRules(query, action.mapping);
         }
       }
       default:

+ 6 - 0
public/app/plugins/datasource/prometheus/language_utils.ts

@@ -83,3 +83,9 @@ export function parseSelector(query: string, cursorOffset = 1): { labelKeys: any
 
   return { labelKeys, selector: selectorString };
 }
+
+export function expandRecordingRules(query: string, mapping: { [name: string]: string }): string {
+  const ruleNames = Object.keys(mapping);
+  const rulesRegex = new RegExp(`(\\s|^)(${ruleNames.join('|')})(\\s|$|\\(|\\[|\\{)`, 'ig');
+  return query.replace(rulesRegex, (match, pre, name, post) => `${pre}${mapping[name]}${post}`);
+}

+ 23 - 1
public/app/plugins/datasource/prometheus/specs/language_utils.test.ts

@@ -1,4 +1,4 @@
-import { parseSelector } from '../language_utils';
+import { expandRecordingRules, parseSelector } from '../language_utils';
 
 describe('parseSelector()', () => {
   let parsed;
@@ -62,3 +62,25 @@ describe('parseSelector()', () => {
     expect(parsed.selector).toBe('{__name__="bar:metric:1m"}');
   });
 });
+
+describe('expandRecordingRules()', () => {
+  it('returns query w/o recording rules as is', () => {
+    expect(expandRecordingRules('metric', {})).toBe('metric');
+    expect(expandRecordingRules('metric + metric', {})).toBe('metric + metric');
+    expect(expandRecordingRules('metric{}', {})).toBe('metric{}');
+  });
+
+  it('does not modify recording rules name in label values', () => {
+    expect(expandRecordingRules('{__name__="metric"} + bar', { metric: 'foo', bar: 'super' })).toBe(
+      '{__name__="metric"} + super'
+    );
+  });
+
+  it('returns query with expanded recording rules', () => {
+    expect(expandRecordingRules('metric', { metric: 'foo' })).toBe('foo');
+    expect(expandRecordingRules('metric + metric', { metric: 'foo' })).toBe('foo + foo');
+    expect(expandRecordingRules('metric{}', { metric: 'foo' })).toBe('foo{}');
+    expect(expandRecordingRules('metric[]', { metric: 'foo' })).toBe('foo[]');
+    expect(expandRecordingRules('metric + foo', { metric: 'foo', foo: 'bar' })).toBe('foo + bar');
+  });
+});