client: Add Option to provide limit query param for APIs that support it (#1544)
* client: Add Option to provide limit query param for APIs that support it Signed-off-by: Ivan Ryabov <abbyssoul@gmail.com> * Renamed formatOptions -> addOptionalURLParams and comment as per review feedback Signed-off-by: Ivan Ryabov <abbyssoul@gmail.com> --------- Signed-off-by: Ivan Ryabov <abbyssoul@gmail.com>
This commit is contained in:
parent
3631776ed8
commit
34e02e282d
|
@ -475,9 +475,9 @@ type API interface {
|
||||||
// Flags returns the flag values that Prometheus was launched with.
|
// Flags returns the flag values that Prometheus was launched with.
|
||||||
Flags(ctx context.Context) (FlagsResult, error)
|
Flags(ctx context.Context) (FlagsResult, error)
|
||||||
// LabelNames returns the unique label names present in the block in sorted order by given time range and matchers.
|
// LabelNames returns the unique label names present in the block in sorted order by given time range and matchers.
|
||||||
LabelNames(ctx context.Context, matches []string, startTime, endTime time.Time) ([]string, Warnings, error)
|
LabelNames(ctx context.Context, matches []string, startTime, endTime time.Time, opts ...Option) ([]string, Warnings, error)
|
||||||
// LabelValues performs a query for the values of the given label, time range and matchers.
|
// LabelValues performs a query for the values of the given label, time range and matchers.
|
||||||
LabelValues(ctx context.Context, label string, matches []string, startTime, endTime time.Time) (model.LabelValues, Warnings, error)
|
LabelValues(ctx context.Context, label string, matches []string, startTime, endTime time.Time, opts ...Option) (model.LabelValues, Warnings, error)
|
||||||
// Query performs a query for the given time.
|
// Query performs a query for the given time.
|
||||||
Query(ctx context.Context, query string, ts time.Time, opts ...Option) (model.Value, Warnings, error)
|
Query(ctx context.Context, query string, ts time.Time, opts ...Option) (model.Value, Warnings, error)
|
||||||
// QueryRange performs a query for the given range.
|
// QueryRange performs a query for the given range.
|
||||||
|
@ -489,7 +489,7 @@ type API interface {
|
||||||
// Runtimeinfo returns the various runtime information properties about the Prometheus server.
|
// Runtimeinfo returns the various runtime information properties about the Prometheus server.
|
||||||
Runtimeinfo(ctx context.Context) (RuntimeinfoResult, error)
|
Runtimeinfo(ctx context.Context) (RuntimeinfoResult, error)
|
||||||
// Series finds series by label matchers.
|
// Series finds series by label matchers.
|
||||||
Series(ctx context.Context, matches []string, startTime, endTime time.Time) ([]model.LabelSet, Warnings, error)
|
Series(ctx context.Context, matches []string, startTime, endTime time.Time, opts ...Option) ([]model.LabelSet, Warnings, error)
|
||||||
// Snapshot creates a snapshot of all current data into snapshots/<datetime>-<rand>
|
// Snapshot creates a snapshot of all current data into snapshots/<datetime>-<rand>
|
||||||
// under the TSDB's data directory and returns the directory as response.
|
// under the TSDB's data directory and returns the directory as response.
|
||||||
Snapshot(ctx context.Context, skipHead bool) (SnapshotResult, error)
|
Snapshot(ctx context.Context, skipHead bool) (SnapshotResult, error)
|
||||||
|
@ -502,7 +502,7 @@ type API interface {
|
||||||
// Metadata returns metadata about metrics currently scraped by the metric name.
|
// Metadata returns metadata about metrics currently scraped by the metric name.
|
||||||
Metadata(ctx context.Context, metric, limit string) (map[string][]Metadata, error)
|
Metadata(ctx context.Context, metric, limit string) (map[string][]Metadata, error)
|
||||||
// TSDB returns the cardinality statistics.
|
// TSDB returns the cardinality statistics.
|
||||||
TSDB(ctx context.Context) (TSDBResult, error)
|
TSDB(ctx context.Context, opts ...Option) (TSDBResult, error)
|
||||||
// WalReplay returns the current replay status of the wal.
|
// WalReplay returns the current replay status of the wal.
|
||||||
WalReplay(ctx context.Context) (WalReplayStatus, error)
|
WalReplay(ctx context.Context) (WalReplayStatus, error)
|
||||||
}
|
}
|
||||||
|
@ -1024,9 +1024,10 @@ func (h *httpAPI) Runtimeinfo(ctx context.Context) (RuntimeinfoResult, error) {
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *httpAPI) LabelNames(ctx context.Context, matches []string, startTime, endTime time.Time) ([]string, Warnings, error) {
|
func (h *httpAPI) LabelNames(ctx context.Context, matches []string, startTime, endTime time.Time, opts ...Option) ([]string, Warnings, error) {
|
||||||
u := h.client.URL(epLabels, nil)
|
u := h.client.URL(epLabels, nil)
|
||||||
q := u.Query()
|
q := addOptionalURLParams(u.Query(), opts)
|
||||||
|
|
||||||
if !startTime.IsZero() {
|
if !startTime.IsZero() {
|
||||||
q.Set("start", formatTime(startTime))
|
q.Set("start", formatTime(startTime))
|
||||||
}
|
}
|
||||||
|
@ -1046,9 +1047,10 @@ func (h *httpAPI) LabelNames(ctx context.Context, matches []string, startTime, e
|
||||||
return labelNames, w, err
|
return labelNames, w, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *httpAPI) LabelValues(ctx context.Context, label string, matches []string, startTime, endTime time.Time) (model.LabelValues, Warnings, error) {
|
func (h *httpAPI) LabelValues(ctx context.Context, label string, matches []string, startTime, endTime time.Time, opts ...Option) (model.LabelValues, Warnings, error) {
|
||||||
u := h.client.URL(epLabelValues, map[string]string{"name": label})
|
u := h.client.URL(epLabelValues, map[string]string{"name": label})
|
||||||
q := u.Query()
|
q := addOptionalURLParams(u.Query(), opts)
|
||||||
|
|
||||||
if !startTime.IsZero() {
|
if !startTime.IsZero() {
|
||||||
q.Set("start", formatTime(startTime))
|
q.Set("start", formatTime(startTime))
|
||||||
}
|
}
|
||||||
|
@ -1076,6 +1078,7 @@ func (h *httpAPI) LabelValues(ctx context.Context, label string, matches []strin
|
||||||
|
|
||||||
type apiOptions struct {
|
type apiOptions struct {
|
||||||
timeout time.Duration
|
timeout time.Duration
|
||||||
|
limit uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
type Option func(c *apiOptions)
|
type Option func(c *apiOptions)
|
||||||
|
@ -1088,20 +1091,35 @@ func WithTimeout(timeout time.Duration) Option {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *httpAPI) Query(ctx context.Context, query string, ts time.Time, opts ...Option) (model.Value, Warnings, error) {
|
// WithLimit provides an optional maximum number of returned entries for APIs that support limit parameter
|
||||||
u := h.client.URL(epQuery, nil)
|
// e.g. https://prometheus.io/docs/prometheus/latest/querying/api/#instant-querie:~:text=%3A%20End%20timestamp.-,limit%3D%3Cnumber%3E,-%3A%20Maximum%20number%20of
|
||||||
q := u.Query()
|
func WithLimit(limit uint64) Option {
|
||||||
|
return func(o *apiOptions) {
|
||||||
|
o.limit = limit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func addOptionalURLParams(q url.Values, opts []Option) url.Values {
|
||||||
opt := &apiOptions{}
|
opt := &apiOptions{}
|
||||||
for _, o := range opts {
|
for _, o := range opts {
|
||||||
o(opt)
|
o(opt)
|
||||||
}
|
}
|
||||||
|
|
||||||
d := opt.timeout
|
if opt.timeout > 0 {
|
||||||
if d > 0 {
|
q.Set("timeout", opt.timeout.String())
|
||||||
q.Set("timeout", d.String())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if opt.limit > 0 {
|
||||||
|
q.Set("limit", strconv.FormatUint(opt.limit, 10))
|
||||||
|
}
|
||||||
|
|
||||||
|
return q
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *httpAPI) Query(ctx context.Context, query string, ts time.Time, opts ...Option) (model.Value, Warnings, error) {
|
||||||
|
u := h.client.URL(epQuery, nil)
|
||||||
|
q := addOptionalURLParams(u.Query(), opts)
|
||||||
|
|
||||||
q.Set("query", query)
|
q.Set("query", query)
|
||||||
if !ts.IsZero() {
|
if !ts.IsZero() {
|
||||||
q.Set("time", formatTime(ts))
|
q.Set("time", formatTime(ts))
|
||||||
|
@ -1118,36 +1136,25 @@ func (h *httpAPI) Query(ctx context.Context, query string, ts time.Time, opts ..
|
||||||
|
|
||||||
func (h *httpAPI) QueryRange(ctx context.Context, query string, r Range, opts ...Option) (model.Value, Warnings, error) {
|
func (h *httpAPI) QueryRange(ctx context.Context, query string, r Range, opts ...Option) (model.Value, Warnings, error) {
|
||||||
u := h.client.URL(epQueryRange, nil)
|
u := h.client.URL(epQueryRange, nil)
|
||||||
q := u.Query()
|
q := addOptionalURLParams(u.Query(), opts)
|
||||||
|
|
||||||
q.Set("query", query)
|
q.Set("query", query)
|
||||||
q.Set("start", formatTime(r.Start))
|
q.Set("start", formatTime(r.Start))
|
||||||
q.Set("end", formatTime(r.End))
|
q.Set("end", formatTime(r.End))
|
||||||
q.Set("step", strconv.FormatFloat(r.Step.Seconds(), 'f', -1, 64))
|
q.Set("step", strconv.FormatFloat(r.Step.Seconds(), 'f', -1, 64))
|
||||||
|
|
||||||
opt := &apiOptions{}
|
|
||||||
for _, o := range opts {
|
|
||||||
o(opt)
|
|
||||||
}
|
|
||||||
|
|
||||||
d := opt.timeout
|
|
||||||
if d > 0 {
|
|
||||||
q.Set("timeout", d.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
_, body, warnings, err := h.client.DoGetFallback(ctx, u, q)
|
_, body, warnings, err := h.client.DoGetFallback(ctx, u, q)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, warnings, err
|
return nil, warnings, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var qres queryResult
|
var qres queryResult
|
||||||
|
|
||||||
return qres.v, warnings, json.Unmarshal(body, &qres)
|
return qres.v, warnings, json.Unmarshal(body, &qres)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *httpAPI) Series(ctx context.Context, matches []string, startTime, endTime time.Time) ([]model.LabelSet, Warnings, error) {
|
func (h *httpAPI) Series(ctx context.Context, matches []string, startTime, endTime time.Time, opts ...Option) ([]model.LabelSet, Warnings, error) {
|
||||||
u := h.client.URL(epSeries, nil)
|
u := h.client.URL(epSeries, nil)
|
||||||
q := u.Query()
|
q := addOptionalURLParams(u.Query(), opts)
|
||||||
|
|
||||||
for _, m := range matches {
|
for _, m := range matches {
|
||||||
q.Add("match[]", m)
|
q.Add("match[]", m)
|
||||||
|
@ -1166,8 +1173,7 @@ func (h *httpAPI) Series(ctx context.Context, matches []string, startTime, endTi
|
||||||
}
|
}
|
||||||
|
|
||||||
var mset []model.LabelSet
|
var mset []model.LabelSet
|
||||||
err = json.Unmarshal(body, &mset)
|
return mset, warnings, json.Unmarshal(body, &mset)
|
||||||
return mset, warnings, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *httpAPI) Snapshot(ctx context.Context, skipHead bool) (SnapshotResult, error) {
|
func (h *httpAPI) Snapshot(ctx context.Context, skipHead bool) (SnapshotResult, error) {
|
||||||
|
@ -1278,8 +1284,10 @@ func (h *httpAPI) Metadata(ctx context.Context, metric, limit string) (map[strin
|
||||||
return res, err
|
return res, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *httpAPI) TSDB(ctx context.Context) (TSDBResult, error) {
|
func (h *httpAPI) TSDB(ctx context.Context, opts ...Option) (TSDBResult, error) {
|
||||||
u := h.client.URL(epTSDB, nil)
|
u := h.client.URL(epTSDB, nil)
|
||||||
|
q := addOptionalURLParams(u.Query(), opts)
|
||||||
|
u.RawQuery = q.Encode()
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
|
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -154,15 +154,15 @@ func TestAPIs(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doLabelNames := func(matches []string, startTime, endTime time.Time) func() (interface{}, Warnings, error) {
|
doLabelNames := func(matches []string, startTime, endTime time.Time, opts ...Option) func() (interface{}, Warnings, error) {
|
||||||
return func() (interface{}, Warnings, error) {
|
return func() (interface{}, Warnings, error) {
|
||||||
return promAPI.LabelNames(context.Background(), matches, startTime, endTime)
|
return promAPI.LabelNames(context.Background(), matches, startTime, endTime, opts...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doLabelValues := func(matches []string, label string, startTime, endTime time.Time) func() (interface{}, Warnings, error) {
|
doLabelValues := func(matches []string, label string, startTime, endTime time.Time, opts ...Option) func() (interface{}, Warnings, error) {
|
||||||
return func() (interface{}, Warnings, error) {
|
return func() (interface{}, Warnings, error) {
|
||||||
return promAPI.LabelValues(context.Background(), label, matches, startTime, endTime)
|
return promAPI.LabelValues(context.Background(), label, matches, startTime, endTime, opts...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,9 +178,9 @@ func TestAPIs(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doSeries := func(matcher string, startTime, endTime time.Time) func() (interface{}, Warnings, error) {
|
doSeries := func(matcher string, startTime, endTime time.Time, opts ...Option) func() (interface{}, Warnings, error) {
|
||||||
return func() (interface{}, Warnings, error) {
|
return func() (interface{}, Warnings, error) {
|
||||||
return promAPI.Series(context.Background(), []string{matcher}, startTime, endTime)
|
return promAPI.Series(context.Background(), []string{matcher}, startTime, endTime, opts...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,9 +219,9 @@ func TestAPIs(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
doTSDB := func() func() (interface{}, Warnings, error) {
|
doTSDB := func(opts ...Option) func() (interface{}, Warnings, error) {
|
||||||
return func() (interface{}, Warnings, error) {
|
return func() (interface{}, Warnings, error) {
|
||||||
v, err := promAPI.TSDB(context.Background())
|
v, err := promAPI.TSDB(context.Background(), opts...)
|
||||||
return v, nil, err
|
return v, nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue