Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for tsdb endpoint #773

Merged
merged 1 commit into from Jun 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
35 changes: 35 additions & 0 deletions api/prometheus/v1/api.go
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -404,6 +407,20 @@ type queryResult struct {
v model.Value
}

// TSDBResult contains the result from querying the tsdb endpoint.
type TSDBResult struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am maybe bias, but I wish we could just import https://github.com/prometheus/prometheus/blob/master/web/api/v1/api.go#L1172

This is fine though I guess - to avoid importing prometheus.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might to avoid cyclic dependencies? In any case, I would stick to what already is standard practice here but we could open issue for this to discuss?

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"`
Expand Down Expand Up @@ -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

Expand Down
73 changes: 73 additions & 0 deletions api/prometheus/v1/api_test.go
Expand Up @@ -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),
Expand Down Expand Up @@ -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
Expand Down