mirror of
https://github.com/prometheus/prometheus.git
synced 2025-01-14 07:17:52 -08:00
Make time parameter optional in v1 query API
If no time paramter is provided, the current server timestamp is used.
This commit is contained in:
parent
a5461e1ad7
commit
50079a85a1
|
@ -54,15 +54,6 @@ type response struct {
|
||||||
Error string `json:"error,omitempty"`
|
Error string `json:"error,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// API can register a set of endpoints in a router and handle
|
|
||||||
// them using the provided storage and query engine.
|
|
||||||
type API struct {
|
|
||||||
Storage local.Storage
|
|
||||||
QueryEngine *promql.Engine
|
|
||||||
|
|
||||||
context func(r *http.Request) context.Context
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enables cross-site script calls.
|
// Enables cross-site script calls.
|
||||||
func setCORS(w http.ResponseWriter) {
|
func setCORS(w http.ResponseWriter) {
|
||||||
w.Header().Set("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type, Origin")
|
w.Header().Set("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type, Origin")
|
||||||
|
@ -73,12 +64,28 @@ func setCORS(w http.ResponseWriter) {
|
||||||
|
|
||||||
type apiFunc func(r *http.Request) (interface{}, *apiError)
|
type apiFunc func(r *http.Request) (interface{}, *apiError)
|
||||||
|
|
||||||
|
// API can register a set of endpoints in a router and handle
|
||||||
|
// them using the provided storage and query engine.
|
||||||
|
type API struct {
|
||||||
|
Storage local.Storage
|
||||||
|
QueryEngine *promql.Engine
|
||||||
|
|
||||||
|
context func(r *http.Request) context.Context
|
||||||
|
now func() model.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewAPI returns an initialized API type.
|
||||||
|
func NewAPI(qe *promql.Engine, st local.Storage) *API {
|
||||||
|
return &API{
|
||||||
|
QueryEngine: qe,
|
||||||
|
Storage: st,
|
||||||
|
context: route.Context,
|
||||||
|
now: model.Now,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Register the API's endpoints in the given router.
|
// Register the API's endpoints in the given router.
|
||||||
func (api *API) Register(r *route.Router) {
|
func (api *API) Register(r *route.Router) {
|
||||||
if api.context == nil {
|
|
||||||
api.context = route.Context
|
|
||||||
}
|
|
||||||
|
|
||||||
instr := func(name string, f apiFunc) http.HandlerFunc {
|
instr := func(name string, f apiFunc) http.HandlerFunc {
|
||||||
hf := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
hf := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
setCORS(w)
|
setCORS(w)
|
||||||
|
@ -108,10 +115,17 @@ type queryData struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *API) query(r *http.Request) (interface{}, *apiError) {
|
func (api *API) query(r *http.Request) (interface{}, *apiError) {
|
||||||
ts, err := parseTime(r.FormValue("time"))
|
var ts model.Time
|
||||||
if err != nil {
|
if t := r.FormValue("time"); t != "" {
|
||||||
return nil, &apiError{errorBadData, err}
|
var err error
|
||||||
|
ts, err = parseTime(t)
|
||||||
|
if err != nil {
|
||||||
|
return nil, &apiError{errorBadData, err}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ts = api.now()
|
||||||
}
|
}
|
||||||
|
|
||||||
qry, err := api.QueryEngine.NewInstantQuery(r.FormValue("query"), ts)
|
qry, err := api.QueryEngine.NewInstantQuery(r.FormValue("query"), ts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, &apiError{errorBadData, err}
|
return nil, &apiError{errorBadData, err}
|
||||||
|
|
|
@ -35,9 +35,11 @@ func TestEndpoints(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
now := model.Now()
|
||||||
api := &API{
|
api := &API{
|
||||||
Storage: suite.Storage(),
|
Storage: suite.Storage(),
|
||||||
QueryEngine: suite.QueryEngine(),
|
QueryEngine: suite.QueryEngine(),
|
||||||
|
now: func() model.Time { return now },
|
||||||
}
|
}
|
||||||
|
|
||||||
start := model.Time(0)
|
start := model.Time(0)
|
||||||
|
@ -90,6 +92,19 @@ func TestEndpoints(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
endpoint: api.query,
|
||||||
|
query: url.Values{
|
||||||
|
"query": []string{"0.333"},
|
||||||
|
},
|
||||||
|
response: &queryData{
|
||||||
|
ResultType: model.ValScalar,
|
||||||
|
Result: &model.Scalar{
|
||||||
|
Value: 0.333,
|
||||||
|
Timestamp: now,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
endpoint: api.queryRange,
|
endpoint: api.queryRange,
|
||||||
query: url.Values{
|
query: url.Values{
|
||||||
|
@ -140,14 +155,6 @@ func TestEndpoints(t *testing.T) {
|
||||||
},
|
},
|
||||||
errType: errorBadData,
|
errType: errorBadData,
|
||||||
},
|
},
|
||||||
// Missing evaluation time.
|
|
||||||
{
|
|
||||||
endpoint: api.query,
|
|
||||||
query: url.Values{
|
|
||||||
"query": []string{"0.333"},
|
|
||||||
},
|
|
||||||
errType: errorBadData,
|
|
||||||
},
|
|
||||||
// Bad query expression.
|
// Bad query expression.
|
||||||
{
|
{
|
||||||
endpoint: api.query,
|
endpoint: api.query,
|
||||||
|
|
|
@ -138,10 +138,7 @@ func New(st local.Storage, qe *promql.Engine, rm *rules.Manager, status *Prometh
|
||||||
queryEngine: qe,
|
queryEngine: qe,
|
||||||
storage: st,
|
storage: st,
|
||||||
|
|
||||||
apiV1: &v1.API{
|
apiV1: v1.NewAPI(qe, st),
|
||||||
QueryEngine: qe,
|
|
||||||
Storage: st,
|
|
||||||
},
|
|
||||||
apiLegacy: &legacy.API{
|
apiLegacy: &legacy.API{
|
||||||
QueryEngine: qe,
|
QueryEngine: qe,
|
||||||
Storage: st,
|
Storage: st,
|
||||||
|
|
Loading…
Reference in a new issue