-
Notifications
You must be signed in to change notification settings - Fork 812
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Handle /api/v1/metadata in the queriers This commit handles the call to /api/v1/metadata from Prometheus. It looks for all metric metadata of a given metadata and exposes it as a map of slices. Signed-off-by: gotjosh <josue@grafana.com> * Add changelog entry Signed-off-by: gotjosh <josue@grafana.com> * Wordsmithing on comments Signed-off-by: gotjosh <josue@grafana.com> * Update CHANGELOG.md Signed-off-by: gotjosh <josue@grafana.com> * Add a note about this custom handler being temporary Signed-off-by: gotjosh <josue@grafana.com>
- Loading branch information
Showing
6 changed files
with
145 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package querier | ||
|
||
import ( | ||
"net/http" | ||
|
||
"github.com/cortexproject/cortex/pkg/util" | ||
) | ||
|
||
type metricMetadata struct { | ||
Type string `json:"type"` | ||
Help string `json:"help"` | ||
Unit string `json:"unit"` | ||
} | ||
|
||
const ( | ||
statusSuccess = "success" | ||
statusError = "error" | ||
) | ||
|
||
type metadataResult struct { | ||
Status string `json:"status"` | ||
Data map[string][]metricMetadata `json:"data,omitempty"` | ||
Error string `json:"error,omitempty"` | ||
} | ||
|
||
// MetadataHandler returns metric metadata held by Cortex for a given tenant. | ||
// It is kept and returned as a set. | ||
func MetadataHandler(d Distributor) http.Handler { | ||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
resp, err := d.MetricsMetadata(r.Context()) | ||
if err != nil { | ||
w.WriteHeader(http.StatusBadRequest) | ||
util.WriteJSONResponse(w, metadataResult{Status: statusError, Error: err.Error()}) | ||
return | ||
} | ||
|
||
// Put all the elements of the pseudo-set into a map of slices for marshalling. | ||
metrics := map[string][]metricMetadata{} | ||
for _, m := range resp { | ||
ms, ok := metrics[m.Metric] | ||
if !ok { | ||
// Most metrics will only hold 1 copy of the same metadata. | ||
ms = make([]metricMetadata, 0, 1) | ||
metrics[m.Metric] = ms | ||
} | ||
metrics[m.Metric] = append(ms, metricMetadata{Type: string(m.Type), Help: m.Help, Unit: m.Unit}) | ||
} | ||
|
||
util.WriteJSONResponse(w, metadataResult{Status: statusSuccess, Data: metrics}) | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package querier | ||
|
||
import ( | ||
"fmt" | ||
"io/ioutil" | ||
"net/http" | ||
"net/http/httptest" | ||
"testing" | ||
|
||
"github.com/prometheus/prometheus/scrape" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestMetadataHandler_Success(t *testing.T) { | ||
d := &mockDistributor{ | ||
metadata: []scrape.MetricMetadata{ | ||
{Metric: "alertmanager_dispatcher_aggregation_groups", Help: "Number of active aggregation groups", Type: "gauge", Unit: ""}, | ||
}, | ||
} | ||
|
||
handler := MetadataHandler(d) | ||
|
||
request, err := http.NewRequest("GET", "/metadata", nil) | ||
require.NoError(t, err) | ||
|
||
recorder := httptest.NewRecorder() | ||
handler.ServeHTTP(recorder, request) | ||
|
||
require.Equal(t, http.StatusOK, recorder.Result().StatusCode) | ||
responseBody, err := ioutil.ReadAll(recorder.Result().Body) | ||
require.NoError(t, err) | ||
|
||
expectedJSON := ` | ||
{ | ||
"status": "success", | ||
"data": { | ||
"alertmanager_dispatcher_aggregation_groups": [ | ||
{ | ||
"help": "Number of active aggregation groups", | ||
"type": "gauge", | ||
"unit": "" | ||
} | ||
] | ||
} | ||
} | ||
` | ||
|
||
require.JSONEq(t, expectedJSON, string(responseBody)) | ||
} | ||
|
||
func TestMetadataHandler_Error(t *testing.T) { | ||
d := &mockDistributor{ | ||
metadataError: fmt.Errorf("no user id"), | ||
} | ||
|
||
handler := MetadataHandler(d) | ||
|
||
request, err := http.NewRequest("GET", "/metadata", nil) | ||
require.NoError(t, err) | ||
|
||
recorder := httptest.NewRecorder() | ||
handler.ServeHTTP(recorder, request) | ||
|
||
require.Equal(t, http.StatusBadRequest, recorder.Result().StatusCode) | ||
responseBody, err := ioutil.ReadAll(recorder.Result().Body) | ||
require.NoError(t, err) | ||
|
||
expectedJSON := ` | ||
{ | ||
"status": "error", | ||
"error": "no user id" | ||
} | ||
` | ||
|
||
require.JSONEq(t, expectedJSON, string(responseBody)) | ||
} |