diff --git a/api/prometheus/v1/api.go b/api/prometheus/v1/api.go index 13b36464d..9b4fc5725 100644 --- a/api/prometheus/v1/api.go +++ b/api/prometheus/v1/api.go @@ -138,6 +138,7 @@ const ( epConfig = apiPrefix + "/status/config" epFlags = apiPrefix + "/status/flags" epRuntimeinfo = apiPrefix + "/status/runtimeinfo" + epTSDB = apiPrefix + "/status/tsdb" ) // AlertState models the state of an alert. @@ -254,6 +255,8 @@ type API interface { TargetsMetadata(ctx context.Context, matchTarget string, metric string, limit string) ([]MetricMetadata, error) // Metadata returns metadata about metrics currently scraped by the metric name. Metadata(ctx context.Context, metric string, limit string) (map[string][]Metadata, error) + // TSDB returns the cardinality statistics. + TSDB(ctx context.Context) (TSDBResult, error) } // AlertsResult contains the result from querying the alerts endpoint. @@ -404,6 +407,20 @@ type queryResult struct { v model.Value } +// TSDBResult contains the result from querying the tsdb endpoint. +type TSDBResult struct { + SeriesCountByMetricName []Stat `json:"seriesCountByMetricName"` + LabelValueCountByLabelName []Stat `json:"labelValueCountByLabelName"` + MemoryInBytesByLabelName []Stat `json:"memoryInBytesByLabelName"` + SeriesCountByLabelValuePair []Stat `json:"seriesCountByLabelValuePair"` +} + +// Stat models information about statistic value. +type Stat struct { + Name string `json:"name"` + Value uint64 `json:"value"` +} + func (rg *RuleGroup) UnmarshalJSON(b []byte) error { v := struct { Name string `json:"name"` @@ -883,6 +900,24 @@ func (h *httpAPI) Metadata(ctx context.Context, metric string, limit string) (ma return res, json.Unmarshal(body, &res) } +func (h *httpAPI) TSDB(ctx context.Context) (TSDBResult, error) { + u := h.client.URL(epTSDB, nil) + + req, err := http.NewRequest(http.MethodGet, u.String(), nil) + if err != nil { + return TSDBResult{}, err + } + + _, body, _, err := h.client.Do(ctx, req) + if err != nil { + return TSDBResult{}, err + } + + var res TSDBResult + return res, json.Unmarshal(body, &res) + +} + // Warnings is an array of non critical errors type Warnings []string diff --git a/api/prometheus/v1/api_test.go b/api/prometheus/v1/api_test.go index 4bc4d53f5..1cc6d2007 100644 --- a/api/prometheus/v1/api_test.go +++ b/api/prometheus/v1/api_test.go @@ -216,6 +216,13 @@ func TestAPIs(t *testing.T) { } } + doTSDB := func() func() (interface{}, Warnings, error) { + return func() (interface{}, Warnings, error) { + v, err := promAPI.TSDB(context.Background()) + return v, nil, err + } + } + queryTests := []apiTest{ { do: doQuery("2", testTime), @@ -953,6 +960,72 @@ func TestAPIs(t *testing.T) { }, err: fmt.Errorf("some error"), }, + + { + do: doTSDB(), + reqMethod: "GET", + reqPath: "/api/v1/status/tsdb", + inErr: fmt.Errorf("some error"), + err: fmt.Errorf("some error"), + }, + + { + do: doTSDB(), + reqMethod: "GET", + reqPath: "/api/v1/status/tsdb", + inRes: map[string]interface{}{ + "seriesCountByMetricName": []interface{}{ + map[string]interface{}{ + "name": "kubelet_http_requests_duration_seconds_bucket", + "value": 1000, + }, + }, + "labelValueCountByLabelName": []interface{}{ + map[string]interface{}{ + "name": "__name__", + "value": 200, + }, + }, + "memoryInBytesByLabelName": []interface{}{ + map[string]interface{}{ + "name": "id", + "value": 4096, + }, + }, + "seriesCountByLabelValuePair": []interface{}{ + map[string]interface{}{ + "name": "job=kubelet", + "value": 30000, + }, + }, + }, + res: TSDBResult{ + SeriesCountByMetricName: []Stat{ + { + Name: "kubelet_http_requests_duration_seconds_bucket", + Value: 1000, + }, + }, + LabelValueCountByLabelName: []Stat{ + { + Name: "__name__", + Value: 200, + }, + }, + MemoryInBytesByLabelName: []Stat{ + { + Name: "id", + Value: 4096, + }, + }, + SeriesCountByLabelValuePair: []Stat{ + { + Name: "job=kubelet", + Value: 30000, + }, + }, + }, + }, } var tests []apiTest