Skip to content

Commit

Permalink
feat: add promtool http config support
Browse files Browse the repository at this point in the history
Signed-off-by: Martin Chodur <m.chodur@seznam.cz>
  • Loading branch information
FUSAKLA committed Jan 9, 2023
1 parent 48bccc5 commit 8721e8f
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 20 deletions.
62 changes: 45 additions & 17 deletions cmd/promtool/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,11 @@ import (
"gopkg.in/yaml.v2"

dto "github.com/prometheus/client_model/go"
promconfig "github.com/prometheus/common/config"
"github.com/prometheus/common/expfmt"

amconfig "github.com/prometheus/alertmanager/cli/config"

"github.com/prometheus/prometheus/config"
"github.com/prometheus/prometheus/discovery"
"github.com/prometheus/prometheus/discovery/file"
Expand Down Expand Up @@ -74,6 +77,8 @@ const (
var lintOptions = []string{lintOptionAll, lintOptionDuplicateRules, lintOptionNone}

func main() {
var queryCmdServer *url.URL

app := kingpin.New(filepath.Base(os.Args[0]), "Tooling for the Prometheus monitoring system.").UsageWriter(os.Stdout)
app.Version(version.Print("promtool"))
app.HelpFlag.Short('h')
Expand Down Expand Up @@ -124,22 +129,23 @@ func main() {

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")
queryCmdHTTPConfigFile := queryCmd.Flag("http.config.file", "HTTP client configuration file for promtool to connect to Prometheus.").PlaceHolder("<filename>").ExistingFile()

queryInstantCmd := queryCmd.Command("instant", "Run instant query.")
queryInstantServer := queryInstantCmd.Arg("server", "Prometheus server to query.").Required().URL()
queryInstantCmd.Arg("server", "Prometheus server to query.").Required().URLVar(&queryCmdServer)
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.")
queryRangeServer := queryRangeCmd.Arg("server", "Prometheus server to query.").Required().URL()
queryRangeCmd.Arg("server", "Prometheus server to query.").Required().URLVar(&queryCmdServer)
queryRangeExpr := queryRangeCmd.Arg("expr", "PromQL query expression.").Required().String()
queryRangeHeaders := queryRangeCmd.Flag("header", "Extra headers to send to server.").StringMap()
queryRangeBegin := queryRangeCmd.Flag("start", "Query range start time (RFC3339 or Unix timestamp).").String()
queryRangeEnd := queryRangeCmd.Flag("end", "Query range end time (RFC3339 or Unix timestamp).").String()
queryRangeStep := queryRangeCmd.Flag("step", "Query step size (duration).").Duration()

querySeriesCmd := queryCmd.Command("series", "Run series query.")
querySeriesServer := querySeriesCmd.Arg("server", "Prometheus server to query.").Required().URL()
querySeriesCmd.Arg("server", "Prometheus server to query.").Required().URLVar(&queryCmdServer)
querySeriesMatch := querySeriesCmd.Flag("match", "Series selector. Can be specified multiple times.").Required().Strings()
querySeriesBegin := querySeriesCmd.Flag("start", "Start time (RFC3339 or Unix timestamp).").String()
querySeriesEnd := querySeriesCmd.Flag("end", "End time (RFC3339 or Unix timestamp).").String()
Expand All @@ -153,7 +159,7 @@ func main() {
debugAllServer := debugAllCmd.Arg("server", "Prometheus server to get all debug information from.").Required().String()

queryLabelsCmd := queryCmd.Command("labels", "Run labels query.")
queryLabelsServer := queryLabelsCmd.Arg("server", "Prometheus server to query.").Required().URL()
queryLabelsCmd.Arg("server", "Prometheus server to query.").Required().URLVar(&queryCmdServer)
queryLabelsName := queryLabelsCmd.Arg("name", "Label name to provide label values for.").Required().String()
queryLabelsBegin := queryLabelsCmd.Flag("start", "Start time (RFC3339 or Unix timestamp).").String()
queryLabelsEnd := queryLabelsCmd.Flag("end", "End time (RFC3339 or Unix timestamp).").String()
Expand Down Expand Up @@ -223,6 +229,24 @@ func main() {
p = &promqlPrinter{}
}

httpRoundTripper := api.DefaultRoundTripper

if *queryCmdHTTPConfigFile != "" {
if queryCmdServer.User.Username() != "" {
kingpin.Fatalf("Cannot set base auth in the server URL and use a http.config.file at the same time")
}
var err error
httpConfig, err := amconfig.LoadHTTPConfigFile(*queryCmdHTTPConfigFile)
if err != nil {
kingpin.Fatalf("Failed to load HTTP config file: %v", err)
}

httpRoundTripper, err = promconfig.NewRoundTripperFromConfig(*httpConfig, "promtool", config_util.WithUserAgent("promtool/"+version.Version))
if err != nil {
kingpin.Fatalf("Failed to create a new HTTP round tripper: %v", err)
}
}

var noDefaultScrapePort bool
for _, f := range *featureList {
opts := strings.Split(f, ",")
Expand Down Expand Up @@ -257,13 +281,13 @@ func main() {
os.Exit(CheckMetrics(*checkMetricsExtended))

case queryInstantCmd.FullCommand():
os.Exit(QueryInstant(*queryInstantServer, *queryInstantExpr, *queryInstantTime, p))
os.Exit(QueryInstant(queryCmdServer, httpRoundTripper, *queryInstantExpr, *queryInstantTime, p))

case queryRangeCmd.FullCommand():
os.Exit(QueryRange(*queryRangeServer, *queryRangeHeaders, *queryRangeExpr, *queryRangeBegin, *queryRangeEnd, *queryRangeStep, p))
os.Exit(QueryRange(queryCmdServer, httpRoundTripper, *queryRangeHeaders, *queryRangeExpr, *queryRangeBegin, *queryRangeEnd, *queryRangeStep, p))

case querySeriesCmd.FullCommand():
os.Exit(QuerySeries(*querySeriesServer, *querySeriesMatch, *querySeriesBegin, *querySeriesEnd, p))
os.Exit(QuerySeries(queryCmdServer, httpRoundTripper, *querySeriesMatch, *querySeriesBegin, *querySeriesEnd, p))

case debugPprofCmd.FullCommand():
os.Exit(debugPprof(*debugPprofServer))
Expand All @@ -275,7 +299,7 @@ func main() {
os.Exit(debugAll(*debugAllServer))

case queryLabelsCmd.FullCommand():
os.Exit(QueryLabels(*queryLabelsServer, *queryLabelsMatch, *queryLabelsName, *queryLabelsBegin, *queryLabelsEnd, p))
os.Exit(QueryLabels(queryCmdServer, httpRoundTripper, *queryLabelsMatch, *queryLabelsName, *queryLabelsBegin, *queryLabelsEnd, p))

case testRulesCmd.FullCommand():
os.Exit(RulesUnitTest(
Expand Down Expand Up @@ -794,12 +818,13 @@ func checkMetricsExtended(r io.Reader) ([]metricStat, int, error) {
}

// QueryInstant performs an instant query against a Prometheus server.
func QueryInstant(url *url.URL, query, evalTime string, p printer) int {
func QueryInstant(url *url.URL, roundTripper http.RoundTripper, query, evalTime string, p printer) int {
if url.Scheme == "" {
url.Scheme = "http"
}
config := api.Config{
Address: url.String(),
Address: url.String(),
RoundTripper: roundTripper,
}

// Create new client.
Expand Down Expand Up @@ -834,20 +859,21 @@ func QueryInstant(url *url.URL, query, evalTime string, p printer) int {
}

// QueryRange performs a range query against a Prometheus server.
func QueryRange(url *url.URL, headers map[string]string, query, start, end string, step time.Duration, p printer) int {
func QueryRange(url *url.URL, roundTripper http.RoundTripper, headers map[string]string, query, start, end string, step time.Duration, p printer) int {
if url.Scheme == "" {
url.Scheme = "http"
}
config := api.Config{
Address: url.String(),
Address: url.String(),
RoundTripper: roundTripper,
}

if len(headers) > 0 {
config.RoundTripper = promhttp.RoundTripperFunc(func(req *http.Request) (*http.Response, error) {
for key, value := range headers {
req.Header.Add(key, value)
}
return http.DefaultTransport.RoundTrip(req)
return roundTripper.RoundTrip(req)
})
}

Expand Down Expand Up @@ -907,12 +933,13 @@ func QueryRange(url *url.URL, headers map[string]string, query, start, end strin
}

// QuerySeries queries for a series against a Prometheus server.
func QuerySeries(url *url.URL, matchers []string, start, end string, p printer) int {
func QuerySeries(url *url.URL, roundTripper http.RoundTripper, matchers []string, start, end string, p printer) int {
if url.Scheme == "" {
url.Scheme = "http"
}
config := api.Config{
Address: url.String(),
Address: url.String(),
RoundTripper: roundTripper,
}

// Create new client.
Expand Down Expand Up @@ -943,12 +970,13 @@ func QuerySeries(url *url.URL, matchers []string, start, end string, p printer)
}

// QueryLabels queries for label values against a Prometheus server.
func QueryLabels(url *url.URL, matchers []string, name, start, end string, p printer) int {
func QueryLabels(url *url.URL, roundTripper http.RoundTripper, matchers []string, name, start, end string, p printer) int {
if url.Scheme == "" {
url.Scheme = "http"
}
config := api.Config{
Address: url.String(),
Address: url.String(),
RoundTripper: roundTripper,
}

// Create new client.
Expand Down
6 changes: 3 additions & 3 deletions cmd/promtool/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@ func TestQueryRange(t *testing.T) {
require.Equal(t, nil, err)

p := &promqlPrinter{}
exitCode := QueryRange(urlObject, map[string]string{}, "up", "0", "300", 0, p)
exitCode := QueryRange(urlObject, http.DefaultTransport, map[string]string{}, "up", "0", "300", 0, p)
require.Equal(t, "/api/v1/query_range", getRequest().URL.Path)
form := getRequest().Form
require.Equal(t, "up", form.Get("query"))
require.Equal(t, "1", form.Get("step"))
require.Equal(t, 0, exitCode)

exitCode = QueryRange(urlObject, map[string]string{}, "up", "0", "300", 10*time.Millisecond, p)
exitCode = QueryRange(urlObject, http.DefaultTransport, map[string]string{}, "up", "0", "300", 10*time.Millisecond, p)
require.Equal(t, "/api/v1/query_range", getRequest().URL.Path)
form = getRequest().Form
require.Equal(t, "up", form.Get("query"))
Expand All @@ -79,7 +79,7 @@ func TestQueryInstant(t *testing.T) {
require.Equal(t, nil, err)

p := &promqlPrinter{}
exitCode := QueryInstant(urlObject, "up", "300", p)
exitCode := QueryInstant(urlObject, http.DefaultTransport, "up", "300", p)
require.Equal(t, "/api/v1/query", getRequest().URL.Path)
form := getRequest().Form
require.Equal(t, "up", form.Get("query"))
Expand Down

0 comments on commit 8721e8f

Please sign in to comment.