Promtool: add evaluation time to instant query (#7829)

* Promtool: add evaluation time to instant query

Signed-off-by: Julien Pivotto <roidelapluie@inuits.eu>

* Apply suggestion

Signed-off-by: Julien Pivotto <roidelapluie@inuits.eu>
This commit is contained in:
Julien Pivotto 2020-08-25 12:32:25 +02:00 committed by GitHub
parent 5dcc21887b
commit 442b3364d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 36 deletions

View File

@ -70,9 +70,11 @@ func main() {
queryCmd := app.Command("query", "Run query against a Prometheus server.") queryCmd := app.Command("query", "Run query against a Prometheus server.")
queryCmdFmt := queryCmd.Flag("format", "Output format of the query.").Short('o').Default("promql").Enum("promql", "json") queryCmdFmt := queryCmd.Flag("format", "Output format of the query.").Short('o').Default("promql").Enum("promql", "json")
queryInstantCmd := queryCmd.Command("instant", "Run instant query.") queryInstantCmd := queryCmd.Command("instant", "Run instant query.")
queryServer := queryInstantCmd.Arg("server", "Prometheus server to query.").Required().String() queryInstantServer := queryInstantCmd.Arg("server", "Prometheus server to query.").Required().String()
queryExpr := queryInstantCmd.Arg("expr", "PromQL query expression.").Required().String() queryInstantExpr := queryInstantCmd.Arg("expr", "PromQL query expression.").Required().String()
queryInstantTime := queryInstantCmd.Flag("time", "Query evaluation time (RFC3339 or Unix timestamp).").String()
queryRangeCmd := queryCmd.Command("range", "Run range query.") queryRangeCmd := queryCmd.Command("range", "Run range query.")
queryRangeServer := queryRangeCmd.Arg("server", "Prometheus server to query.").Required().String() queryRangeServer := queryRangeCmd.Arg("server", "Prometheus server to query.").Required().String()
@ -153,7 +155,7 @@ func main() {
os.Exit(CheckMetrics()) os.Exit(CheckMetrics())
case queryInstantCmd.FullCommand(): case queryInstantCmd.FullCommand():
os.Exit(QueryInstant(*queryServer, *queryExpr, p)) os.Exit(QueryInstant(*queryInstantServer, *queryInstantExpr, *queryInstantTime, p))
case queryRangeCmd.FullCommand(): case queryRangeCmd.FullCommand():
os.Exit(QueryRange(*queryRangeServer, *queryRangeHeaders, *queryRangeExpr, *queryRangeBegin, *queryRangeEnd, *queryRangeStep, p)) os.Exit(QueryRange(*queryRangeServer, *queryRangeHeaders, *queryRangeExpr, *queryRangeBegin, *queryRangeEnd, *queryRangeStep, p))
@ -427,7 +429,7 @@ func CheckMetrics() int {
} }
// QueryInstant performs an instant query against a Prometheus server. // QueryInstant performs an instant query against a Prometheus server.
func QueryInstant(url, query string, p printer) int { func QueryInstant(url, query, evalTime string, p printer) int {
config := api.Config{ config := api.Config{
Address: url, Address: url,
} }
@ -439,11 +441,20 @@ func QueryInstant(url, query string, p printer) int {
return 1 return 1
} }
eTime := time.Now()
if evalTime != "" {
eTime, err = parseTime(evalTime)
if err != nil {
fmt.Fprintln(os.Stderr, "error parsing evaluation time:", err)
return 1
}
}
// Run query against client. // Run query against client.
api := v1.NewAPI(c) api := v1.NewAPI(c)
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute) ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
val, _, err := api.Query(ctx, query, time.Now()) // Ignoring warnings for now. val, _, err := api.Query(ctx, query, eTime) // Ignoring warnings for now.
cancel() cancel()
if err != nil { if err != nil {
fmt.Fprintln(os.Stderr, "query error:", err) fmt.Fprintln(os.Stderr, "query error:", err)

View File

@ -19,6 +19,8 @@ import (
"net/http/httptest" "net/http/httptest"
"testing" "testing"
"time" "time"
"github.com/prometheus/prometheus/util/testutil"
) )
func TestQueryRange(t *testing.T) { func TestQueryRange(t *testing.T) {
@ -27,41 +29,31 @@ func TestQueryRange(t *testing.T) {
p := &promqlPrinter{} p := &promqlPrinter{}
exitCode := QueryRange(s.URL, map[string]string{}, "up", "0", "300", 0, p) exitCode := QueryRange(s.URL, map[string]string{}, "up", "0", "300", 0, p)
expectedPath := "/api/v1/query_range" testutil.Equals(t, "/api/v1/query_range", getRequest().URL.Path)
gotPath := getRequest().URL.Path
if gotPath != expectedPath {
t.Errorf("unexpected URL path %s (wanted %s)", gotPath, expectedPath)
}
form := getRequest().Form form := getRequest().Form
actual := form.Get("query") testutil.Equals(t, "up", form.Get("query"))
if actual != "up" { testutil.Equals(t, "1", form.Get("step"))
t.Errorf("unexpected value %s for query", actual) testutil.Equals(t, 0, exitCode)
}
actual = form.Get("step")
if actual != "1" {
t.Errorf("unexpected value %s for step", actual)
}
if exitCode > 0 {
t.Error()
}
exitCode = QueryRange(s.URL, map[string]string{}, "up", "0", "300", 10*time.Millisecond, p) exitCode = QueryRange(s.URL, map[string]string{}, "up", "0", "300", 10*time.Millisecond, p)
gotPath = getRequest().URL.Path testutil.Equals(t, "/api/v1/query_range", getRequest().URL.Path)
if gotPath != expectedPath {
t.Errorf("unexpected URL path %s (wanted %s)", gotPath, expectedPath)
}
form = getRequest().Form form = getRequest().Form
actual = form.Get("query") testutil.Equals(t, "up", form.Get("query"))
if actual != "up" { testutil.Equals(t, "0.01", form.Get("step"))
t.Errorf("unexpected value %s for query", actual) testutil.Equals(t, 0, exitCode)
} }
actual = form.Get("step")
if actual != "0.01" { func TestQueryInstant(t *testing.T) {
t.Errorf("unexpected value %s for step", actual) s, getRequest := mockServer(200, `{"status": "success", "data": {"resultType": "vector", "result": []}}`)
} defer s.Close()
if exitCode > 0 {
t.Error() p := &promqlPrinter{}
} exitCode := QueryInstant(s.URL, "up", "300", p)
testutil.Equals(t, "/api/v1/query", getRequest().URL.Path)
form := getRequest().Form
testutil.Equals(t, "up", form.Get("query"))
testutil.Equals(t, "300", form.Get("time"))
testutil.Equals(t, 0, exitCode)
} }
func mockServer(code int, body string) (*httptest.Server, func() *http.Request) { func mockServer(code int, body string) (*httptest.Server, func() *http.Request) {