[promtool] Support writing output as json (#4848)
* Support writing output as json Oftentimes I'll want to execute something based on the output from promtool, and supporting json makes it easy to pull out values with a supporting tool such as jq. Signed-off-by: stuart nelson <stuartnelson3@gmail.com>
This commit is contained in:
parent
b82f930238
commit
6a69471bc2
|
@ -15,6 +15,7 @@ package main
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"net/url"
|
||||
|
@ -29,6 +30,7 @@ import (
|
|||
"github.com/prometheus/client_golang/api"
|
||||
"github.com/prometheus/client_golang/api/prometheus/v1"
|
||||
config_util "github.com/prometheus/common/config"
|
||||
"github.com/prometheus/common/model"
|
||||
"github.com/prometheus/common/version"
|
||||
"github.com/prometheus/prometheus/config"
|
||||
"github.com/prometheus/prometheus/pkg/rulefmt"
|
||||
|
@ -57,6 +59,7 @@ func main() {
|
|||
checkMetricsCmd := checkCmd.Command("metrics", checkMetricsUsage)
|
||||
|
||||
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")
|
||||
queryInstantCmd := queryCmd.Command("instant", "Run instant query.")
|
||||
queryServer := queryInstantCmd.Arg("server", "Prometheus server to query.").Required().String()
|
||||
queryExpr := queryInstantCmd.Arg("expr", "PromQL query expression.").Required().String()
|
||||
|
@ -93,7 +96,17 @@ func main() {
|
|||
"The unit test file.",
|
||||
).Required().ExistingFiles()
|
||||
|
||||
switch kingpin.MustParse(app.Parse(os.Args[1:])) {
|
||||
parsedCmd := kingpin.MustParse(app.Parse(os.Args[1:]))
|
||||
|
||||
var p printer
|
||||
switch *queryCmdFmt {
|
||||
case "json":
|
||||
p = &jsonPrinter{}
|
||||
case "promql":
|
||||
p = &promqlPrinter{}
|
||||
}
|
||||
|
||||
switch parsedCmd {
|
||||
case checkConfigCmd.FullCommand():
|
||||
os.Exit(CheckConfig(*configFiles...))
|
||||
|
||||
|
@ -104,13 +117,13 @@ func main() {
|
|||
os.Exit(CheckMetrics())
|
||||
|
||||
case queryInstantCmd.FullCommand():
|
||||
os.Exit(QueryInstant(*queryServer, *queryExpr))
|
||||
os.Exit(QueryInstant(*queryServer, *queryExpr, p))
|
||||
|
||||
case queryRangeCmd.FullCommand():
|
||||
os.Exit(QueryRange(*queryRangeServer, *queryRangeExpr, *queryRangeBegin, *queryRangeEnd, *queryRangeStep))
|
||||
os.Exit(QueryRange(*queryRangeServer, *queryRangeExpr, *queryRangeBegin, *queryRangeEnd, *queryRangeStep, p))
|
||||
|
||||
case querySeriesCmd.FullCommand():
|
||||
os.Exit(QuerySeries(*querySeriesServer, *querySeriesMatch, *querySeriesBegin, *querySeriesEnd))
|
||||
os.Exit(QuerySeries(*querySeriesServer, *querySeriesMatch, *querySeriesBegin, *querySeriesEnd, p))
|
||||
|
||||
case debugPprofCmd.FullCommand():
|
||||
os.Exit(debugPprof(*debugPprofServer))
|
||||
|
@ -122,7 +135,7 @@ func main() {
|
|||
os.Exit(debugAll(*debugAllServer))
|
||||
|
||||
case queryLabelsCmd.FullCommand():
|
||||
os.Exit(QueryLabels(*queryLabelsServer, *queryLabelsName))
|
||||
os.Exit(QueryLabels(*queryLabelsServer, *queryLabelsName, p))
|
||||
|
||||
case testRulesCmd.FullCommand():
|
||||
os.Exit(RulesUnitTest(*testRulesFiles...))
|
||||
|
@ -316,7 +329,7 @@ func CheckMetrics() int {
|
|||
}
|
||||
|
||||
// QueryInstant performs an instant query against a Prometheus server.
|
||||
func QueryInstant(url string, query string) int {
|
||||
func QueryInstant(url, query string, p printer) int {
|
||||
config := api.Config{
|
||||
Address: url,
|
||||
}
|
||||
|
@ -339,13 +352,13 @@ func QueryInstant(url string, query string) int {
|
|||
return 1
|
||||
}
|
||||
|
||||
fmt.Println(val.String())
|
||||
p.printValue(val)
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
// QueryRange performs a range query against a Prometheus server.
|
||||
func QueryRange(url, query, start, end string, step time.Duration) int {
|
||||
func QueryRange(url, query, start, end string, step time.Duration, p printer) int {
|
||||
config := api.Config{
|
||||
Address: url,
|
||||
}
|
||||
|
@ -400,12 +413,12 @@ func QueryRange(url, query, start, end string, step time.Duration) int {
|
|||
return 1
|
||||
}
|
||||
|
||||
fmt.Println(val.String())
|
||||
p.printValue(val)
|
||||
return 0
|
||||
}
|
||||
|
||||
// QuerySeries queries for a series against a Prometheus server.
|
||||
func QuerySeries(url *url.URL, matchers []string, start string, end string) int {
|
||||
func QuerySeries(url *url.URL, matchers []string, start, end string, p printer) int {
|
||||
config := api.Config{
|
||||
Address: url.String(),
|
||||
}
|
||||
|
@ -454,14 +467,12 @@ func QuerySeries(url *url.URL, matchers []string, start string, end string) int
|
|||
return 1
|
||||
}
|
||||
|
||||
for _, v := range val {
|
||||
fmt.Println(v)
|
||||
}
|
||||
p.printSeries(val)
|
||||
return 0
|
||||
}
|
||||
|
||||
// QueryLabels queries for label values against a Prometheus server.
|
||||
func QueryLabels(url *url.URL, name string) int {
|
||||
func QueryLabels(url *url.URL, name string, p printer) int {
|
||||
config := api.Config{
|
||||
Address: url.String(),
|
||||
}
|
||||
|
@ -484,9 +495,7 @@ func QueryLabels(url *url.URL, name string) int {
|
|||
return 1
|
||||
}
|
||||
|
||||
for _, v := range val {
|
||||
fmt.Println(v)
|
||||
}
|
||||
p.printLabelValues(val)
|
||||
return 0
|
||||
}
|
||||
|
||||
|
@ -557,3 +566,37 @@ func debugAll(url string) int {
|
|||
}
|
||||
return w.Write()
|
||||
}
|
||||
|
||||
type printer interface {
|
||||
printValue(v model.Value)
|
||||
printSeries(v []model.LabelSet)
|
||||
printLabelValues(v model.LabelValues)
|
||||
}
|
||||
|
||||
type promqlPrinter struct{}
|
||||
|
||||
func (p *promqlPrinter) printValue(v model.Value) {
|
||||
fmt.Println(v)
|
||||
}
|
||||
func (p *promqlPrinter) printSeries(val []model.LabelSet) {
|
||||
for _, v := range val {
|
||||
fmt.Println(v)
|
||||
}
|
||||
}
|
||||
func (j *promqlPrinter) printLabelValues(val model.LabelValues) {
|
||||
for _, v := range val {
|
||||
fmt.Println(v)
|
||||
}
|
||||
}
|
||||
|
||||
type jsonPrinter struct{}
|
||||
|
||||
func (j *jsonPrinter) printValue(v model.Value) {
|
||||
json.NewEncoder(os.Stdout).Encode(v)
|
||||
}
|
||||
func (j *jsonPrinter) printSeries(v []model.LabelSet) {
|
||||
json.NewEncoder(os.Stdout).Encode(v)
|
||||
}
|
||||
func (j *jsonPrinter) printLabelValues(v model.LabelValues) {
|
||||
json.NewEncoder(os.Stdout).Encode(v)
|
||||
}
|
||||
|
|
|
@ -26,7 +26,8 @@ func TestQueryRange(t *testing.T) {
|
|||
s, getURL := mockServer(200, `{"status": "success", "data": {"resultType": "matrix", "result": []}}`)
|
||||
defer s.Close()
|
||||
|
||||
exitCode := QueryRange(s.URL, "up", "0", "300", 0)
|
||||
p := &promqlPrinter{}
|
||||
exitCode := QueryRange(s.URL, "up", "0", "300", 0, p)
|
||||
expectedPath := "/api/v1/query_range"
|
||||
if getURL().Path != expectedPath {
|
||||
t.Errorf("unexpected URL path %s (wanted %s)", getURL().Path, expectedPath)
|
||||
|
@ -43,7 +44,7 @@ func TestQueryRange(t *testing.T) {
|
|||
t.Error()
|
||||
}
|
||||
|
||||
exitCode = QueryRange(s.URL, "up", "0", "300", 10*time.Millisecond)
|
||||
exitCode = QueryRange(s.URL, "up", "0", "300", 10*time.Millisecond, p)
|
||||
if getURL().Path != expectedPath {
|
||||
t.Errorf("unexpected URL path %s (wanted %s)", getURL().Path, expectedPath)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue