mirror of
https://github.com/prometheus/prometheus.git
synced 2024-12-24 21:24:05 -08:00
Merge pull request #6442 from gotjosh/single-metric-api
api: provide metadata for a specified metric
This commit is contained in:
commit
af2257b100
|
@ -668,6 +668,7 @@ GET /api/v1/metadata
|
|||
URL query parameters:
|
||||
|
||||
- `limit=<number>`: Maximum number of metrics to return.
|
||||
- `metric=<string>`: A metric name to filter metadata for. All metric metadata is retrieved if left empty.
|
||||
|
||||
The `data` section of the query result consists of an object where each key is a metric name and each value is a list of unique metadata objects, as exposed for that metric name across all targets.
|
||||
|
||||
|
@ -702,6 +703,30 @@ curl -G http://localhost:9090/api/v1/metadata?limit=2
|
|||
}
|
||||
```
|
||||
|
||||
The following example returns metadata only for the metric `http_requests_total`.
|
||||
|
||||
```json
|
||||
curl -G http://localhost:9090/api/v1/metadata?metric=http_requests_total
|
||||
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"http_requests_total": [
|
||||
{
|
||||
"type": "counter",
|
||||
"help": "Number of HTTP requests",
|
||||
"unit": ""
|
||||
},
|
||||
{
|
||||
"type": "counter",
|
||||
"help": "Amount of HTTP requests",
|
||||
"unit": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Alertmanagers
|
||||
|
||||
The following endpoint returns an overview of the current state of the
|
||||
|
|
|
@ -822,22 +822,39 @@ func (api *API) metricMetadata(r *http.Request) apiFuncResult {
|
|||
}
|
||||
}
|
||||
|
||||
metric := r.FormValue("metric")
|
||||
|
||||
for _, tt := range api.targetRetriever.TargetsActive() {
|
||||
for _, t := range tt {
|
||||
for _, mm := range t.MetadataList() {
|
||||
m := metadata{Type: mm.Type, Help: mm.Help, Unit: mm.Unit}
|
||||
ms, ok := metrics[mm.Metric]
|
||||
|
||||
if metric == "" {
|
||||
for _, mm := range t.MetadataList() {
|
||||
m := metadata{Type: mm.Type, Help: mm.Help, Unit: mm.Unit}
|
||||
ms, ok := metrics[mm.Metric]
|
||||
|
||||
if !ok {
|
||||
ms = map[metadata]struct{}{}
|
||||
metrics[mm.Metric] = ms
|
||||
}
|
||||
ms[m] = struct{}{}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if md, ok := t.Metadata(metric); ok {
|
||||
m := metadata{Type: md.Type, Help: md.Help, Unit: md.Unit}
|
||||
ms, ok := metrics[md.Metric]
|
||||
|
||||
if !ok {
|
||||
ms = map[metadata]struct{}{}
|
||||
metrics[mm.Metric] = ms
|
||||
metrics[md.Metric] = ms
|
||||
}
|
||||
|
||||
ms[m] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Put the elements from the pseudo-set into a slice for marshaling.
|
||||
res := map[string][]metadata{}
|
||||
|
||||
for name, set := range metrics {
|
||||
|
@ -846,11 +863,9 @@ func (api *API) metricMetadata(r *http.Request) apiFuncResult {
|
|||
}
|
||||
|
||||
s := []metadata{}
|
||||
|
||||
for metadata := range set {
|
||||
s = append(s, metadata)
|
||||
}
|
||||
|
||||
res[name] = s
|
||||
}
|
||||
|
||||
|
|
|
@ -1182,7 +1182,7 @@ func testEndpoints(t *testing.T, api *API, tr *testTargetRetriever, testLabelAPI
|
|||
})
|
||||
},
|
||||
},
|
||||
// With a limit for the number of metrics returned
|
||||
// With a limit for the number of metrics returned.
|
||||
{
|
||||
endpoint: api.metricMetadata,
|
||||
query: url.Values{
|
||||
|
@ -1220,7 +1220,74 @@ func testEndpoints(t *testing.T, api *API, tr *testTargetRetriever, testLabelAPI
|
|||
},
|
||||
responseLen: 2,
|
||||
},
|
||||
// With no available metadata
|
||||
// When requesting a specific metric that is present.
|
||||
{
|
||||
endpoint: api.metricMetadata,
|
||||
query: url.Values{"metric": []string{"go_threads"}},
|
||||
metadata: []targetMetadata{
|
||||
{
|
||||
identifier: "test",
|
||||
metadata: []scrape.MetricMetadata{
|
||||
{
|
||||
Metric: "go_threads",
|
||||
Type: textparse.MetricTypeGauge,
|
||||
Help: "Number of OS threads created",
|
||||
Unit: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
identifier: "blackbox",
|
||||
metadata: []scrape.MetricMetadata{
|
||||
{
|
||||
Metric: "go_gc_duration_seconds",
|
||||
Type: textparse.MetricTypeSummary,
|
||||
Help: "A summary of the GC invocation durations.",
|
||||
Unit: "",
|
||||
},
|
||||
{
|
||||
Metric: "go_threads",
|
||||
Type: textparse.MetricTypeGauge,
|
||||
Help: "Number of OS threads that were created.",
|
||||
Unit: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
response: map[string][]metadata{
|
||||
"go_threads": []metadata{
|
||||
{textparse.MetricTypeGauge, "Number of OS threads created", ""},
|
||||
{textparse.MetricTypeGauge, "Number of OS threads that were created.", ""},
|
||||
},
|
||||
},
|
||||
sorter: func(m interface{}) {
|
||||
v := m.(map[string][]metadata)["go_threads"]
|
||||
|
||||
sort.Slice(v, func(i, j int) bool {
|
||||
return v[i].Help < v[j].Help
|
||||
})
|
||||
},
|
||||
},
|
||||
// With a specific metric that is not present.
|
||||
{
|
||||
endpoint: api.metricMetadata,
|
||||
query: url.Values{"metric": []string{"go_gc_duration_seconds"}},
|
||||
metadata: []targetMetadata{
|
||||
{
|
||||
identifier: "test",
|
||||
metadata: []scrape.MetricMetadata{
|
||||
{
|
||||
Metric: "go_threads",
|
||||
Type: textparse.MetricTypeGauge,
|
||||
Help: "Number of OS threads created",
|
||||
Unit: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
response: map[string][]metadata{},
|
||||
},
|
||||
// With no available metadata.
|
||||
{
|
||||
endpoint: api.metricMetadata,
|
||||
response: map[string][]metadata{},
|
||||
|
|
Loading…
Reference in a new issue