浏览代码

Merge pull request #15290 from mtanda/prometheus_label_names_query

(prometheus) support /api/v1/labels
Daniel Lee 6 年之前
父节点
当前提交
fe1c204d4a

+ 1 - 0
docs/sources/features/datasources/prometheus.md

@@ -68,6 +68,7 @@ provides the following functions you can use in the `Query` input field.
 
 
 Name | Description
 Name | Description
 ---- | --------
 ---- | --------
+*label_names()* | Returns a list of label names.
 *label_values(label)* | Returns a list of label values for the `label` in every metric.
 *label_values(label)* | Returns a list of label values for the `label` in every metric.
 *label_values(metric, label)* | Returns a list of label values for the `label` in the specified metric.
 *label_values(metric, label)* | Returns a list of label values for the `label` in the specified metric.
 *metrics(metric)* | Returns a list of metrics matching the specified `metric` regex.
 *metrics(metric)* | Returns a list of metrics matching the specified `metric` regex.

+ 18 - 0
public/app/plugins/datasource/prometheus/datasource.ts

@@ -379,6 +379,24 @@ export class PrometheusDatasource implements DataSourceApi<PromQuery> {
     });
     });
   }
   }
 
 
+  getTagKeys(options) {
+    const url = '/api/v1/labels';
+    return this.metadataRequest(url).then(result => {
+      return _.map(result.data.data, value => {
+        return { text: value };
+      });
+    });
+  }
+
+  getTagValues(options) {
+    const url = '/api/v1/label/' + options.key + '/values';
+    return this.metadataRequest(url).then(result => {
+      return _.map(result.data.data, value => {
+        return { text: value };
+      });
+    });
+  }
+
   testDatasource() {
   testDatasource() {
     const now = new Date().getTime();
     const now = new Date().getTime();
     return this.performInstantQuery({ expr: '1+1' }, now / 1000).then(response => {
     return this.performInstantQuery({ expr: '1+1' }, now / 1000).then(response => {

+ 15 - 0
public/app/plugins/datasource/prometheus/metric_find_query.ts

@@ -12,10 +12,16 @@ export default class PrometheusMetricFindQuery {
   }
   }
 
 
   process() {
   process() {
+    const labelNamesRegex = /^label_names\(\)\s*$/;
     const labelValuesRegex = /^label_values\((?:(.+),\s*)?([a-zA-Z_][a-zA-Z0-9_]*)\)\s*$/;
     const labelValuesRegex = /^label_values\((?:(.+),\s*)?([a-zA-Z_][a-zA-Z0-9_]*)\)\s*$/;
     const metricNamesRegex = /^metrics\((.+)\)\s*$/;
     const metricNamesRegex = /^metrics\((.+)\)\s*$/;
     const queryResultRegex = /^query_result\((.+)\)\s*$/;
     const queryResultRegex = /^query_result\((.+)\)\s*$/;
 
 
+    const labelNamesQuery = this.query.match(labelNamesRegex);
+    if (labelNamesQuery) {
+      return this.labelNamesQuery();
+    }
+
     const labelValuesQuery = this.query.match(labelValuesRegex);
     const labelValuesQuery = this.query.match(labelValuesRegex);
     if (labelValuesQuery) {
     if (labelValuesQuery) {
       if (labelValuesQuery[1]) {
       if (labelValuesQuery[1]) {
@@ -39,6 +45,15 @@ export default class PrometheusMetricFindQuery {
     return this.metricNameAndLabelsQuery(this.query);
     return this.metricNameAndLabelsQuery(this.query);
   }
   }
 
 
+  labelNamesQuery() {
+    const url = '/api/v1/labels';
+    return this.datasource.metadataRequest(url).then(result => {
+      return _.map(result.data.data, value => {
+        return { text: value };
+      });
+    });
+  }
+
   labelValuesQuery(label, metric) {
   labelValuesQuery(label, metric) {
     let url;
     let url;
 
 

+ 18 - 0
public/app/plugins/datasource/prometheus/specs/metric_find_query.test.ts

@@ -42,6 +42,24 @@ describe('PrometheusMetricFindQuery', () => {
   });
   });
 
 
   describe('When performing metricFindQuery', () => {
   describe('When performing metricFindQuery', () => {
+    it('label_names() should generate label name search query', async () => {
+      const query = ctx.setupMetricFindQuery({
+        query: 'label_names()',
+        response: {
+          data: ['name1', 'name2', 'name3'],
+        },
+      });
+      const results = await query.process();
+
+      expect(results).toHaveLength(3);
+      expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledTimes(1);
+      expect(ctx.backendSrvMock.datasourceRequest).toHaveBeenCalledWith({
+        method: 'GET',
+        url: 'proxied/api/v1/labels',
+        silent: true,
+      });
+    });
+
     it('label_values(resource) should generate label search query', async () => {
     it('label_values(resource) should generate label search query', async () => {
       const query = ctx.setupMetricFindQuery({
       const query = ctx.setupMetricFindQuery({
         query: 'label_values(resource)',
         query: 'label_values(resource)',