mirror of
https://github.com/prometheus/prometheus.git
synced 2025-03-05 20:59:13 -08:00
Merge 9eaa7cda7a
into 677efa4678
This commit is contained in:
commit
9dd0c5f683
|
@ -34,6 +34,7 @@ import (
|
||||||
"github.com/alecthomas/kingpin/v2"
|
"github.com/alecthomas/kingpin/v2"
|
||||||
"github.com/google/pprof/profile"
|
"github.com/google/pprof/profile"
|
||||||
"github.com/prometheus/client_golang/api"
|
"github.com/prometheus/client_golang/api"
|
||||||
|
v1 "github.com/prometheus/client_golang/api/prometheus/v1"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/prometheus/client_golang/prometheus/testutil/promlint"
|
"github.com/prometheus/client_golang/prometheus/testutil/promlint"
|
||||||
"github.com/prometheus/common/expfmt"
|
"github.com/prometheus/common/expfmt"
|
||||||
|
@ -162,7 +163,7 @@ func main() {
|
||||||
agentMode := checkConfigCmd.Flag("agent", "Check config file for Prometheus in Agent mode.").Bool()
|
agentMode := checkConfigCmd.Flag("agent", "Check config file for Prometheus in Agent mode.").Bool()
|
||||||
|
|
||||||
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: promql, json, unittest. Unittest output is experimental.").Short('o').Default("promql").Enum("promql", "json", "unittest")
|
||||||
queryCmd.Flag("http.config.file", "HTTP client configuration file for promtool to connect to Prometheus.").PlaceHolder("<filename>").ExistingFileVar(&httpConfigFilePath)
|
queryCmd.Flag("http.config.file", "HTTP client configuration file for promtool to connect to Prometheus.").PlaceHolder("<filename>").ExistingFileVar(&httpConfigFilePath)
|
||||||
|
|
||||||
queryInstantCmd := queryCmd.Command("instant", "Run instant query.")
|
queryInstantCmd := queryCmd.Command("instant", "Run instant query.")
|
||||||
|
@ -310,12 +311,31 @@ func main() {
|
||||||
|
|
||||||
parsedCmd := kingpin.MustParse(app.Parse(os.Args[1:]))
|
parsedCmd := kingpin.MustParse(app.Parse(os.Args[1:]))
|
||||||
|
|
||||||
|
queryRange := v1.Range{}
|
||||||
|
var err error
|
||||||
|
|
||||||
|
switch parsedCmd {
|
||||||
|
case queryInstantCmd.FullCommand():
|
||||||
|
queryRange, err = newQueryRange(*queryInstantTime, "", time.Second)
|
||||||
|
case queryRangeCmd.FullCommand():
|
||||||
|
queryRange, err = newQueryRange(*queryRangeBegin, *queryRangeEnd, *queryRangeStep)
|
||||||
|
case querySeriesCmd.FullCommand():
|
||||||
|
queryRange, err = newQueryRange(*querySeriesBegin, *querySeriesEnd, 0)
|
||||||
|
case queryLabelsCmd.FullCommand():
|
||||||
|
queryRange, err = newQueryRange(*queryLabelsBegin, *queryLabelsEnd, 0)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
kingpin.Fatalf("Failed to parse query range: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
var p printer
|
var p printer
|
||||||
switch *queryCmdFmt {
|
switch *queryCmdFmt {
|
||||||
case "json":
|
case "json":
|
||||||
p = &jsonPrinter{}
|
p = &jsonPrinter{}
|
||||||
case "promql":
|
case "promql":
|
||||||
p = &promqlPrinter{}
|
p = &promqlPrinter{}
|
||||||
|
case "unittest":
|
||||||
|
p = &unittestPrinter{Step: model.Duration(queryRange.Step)}
|
||||||
}
|
}
|
||||||
|
|
||||||
if httpConfigFilePath != "" {
|
if httpConfigFilePath != "" {
|
||||||
|
@ -372,13 +392,13 @@ func main() {
|
||||||
os.Exit(PushMetrics(remoteWriteURL, httpRoundTripper, *pushMetricsHeaders, *pushMetricsTimeout, *pushMetricsLabels, *metricFiles...))
|
os.Exit(PushMetrics(remoteWriteURL, httpRoundTripper, *pushMetricsHeaders, *pushMetricsTimeout, *pushMetricsLabels, *metricFiles...))
|
||||||
|
|
||||||
case queryInstantCmd.FullCommand():
|
case queryInstantCmd.FullCommand():
|
||||||
os.Exit(QueryInstant(serverURL, httpRoundTripper, *queryInstantExpr, *queryInstantTime, p))
|
os.Exit(QueryInstant(serverURL, httpRoundTripper, *queryInstantExpr, queryRange, p))
|
||||||
|
|
||||||
case queryRangeCmd.FullCommand():
|
case queryRangeCmd.FullCommand():
|
||||||
os.Exit(QueryRange(serverURL, httpRoundTripper, *queryRangeHeaders, *queryRangeExpr, *queryRangeBegin, *queryRangeEnd, *queryRangeStep, p))
|
os.Exit(QueryRange(serverURL, httpRoundTripper, *queryRangeHeaders, *queryRangeExpr, queryRange, p))
|
||||||
|
|
||||||
case querySeriesCmd.FullCommand():
|
case querySeriesCmd.FullCommand():
|
||||||
os.Exit(QuerySeries(serverURL, httpRoundTripper, *querySeriesMatch, *querySeriesBegin, *querySeriesEnd, p))
|
os.Exit(QuerySeries(serverURL, httpRoundTripper, *querySeriesMatch, queryRange, p))
|
||||||
|
|
||||||
case debugPprofCmd.FullCommand():
|
case debugPprofCmd.FullCommand():
|
||||||
os.Exit(debugPprof(*debugPprofServer))
|
os.Exit(debugPprof(*debugPprofServer))
|
||||||
|
@ -390,7 +410,7 @@ func main() {
|
||||||
os.Exit(debugAll(*debugAllServer))
|
os.Exit(debugAll(*debugAllServer))
|
||||||
|
|
||||||
case queryLabelsCmd.FullCommand():
|
case queryLabelsCmd.FullCommand():
|
||||||
os.Exit(QueryLabels(serverURL, httpRoundTripper, *queryLabelsMatch, *queryLabelsName, *queryLabelsBegin, *queryLabelsEnd, p))
|
os.Exit(QueryLabels(serverURL, httpRoundTripper, *queryLabelsMatch, *queryLabelsName, queryRange, p))
|
||||||
|
|
||||||
case testRulesCmd.FullCommand():
|
case testRulesCmd.FullCommand():
|
||||||
results := io.Discard
|
results := io.Discard
|
||||||
|
@ -1214,6 +1234,64 @@ func (j *jsonPrinter) printLabelValues(v model.LabelValues) {
|
||||||
json.NewEncoder(os.Stdout).Encode(v)
|
json.NewEncoder(os.Stdout).Encode(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type unittestPrinter struct {
|
||||||
|
Step model.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *unittestPrinter) printValue(v model.Value) {
|
||||||
|
samples := make(map[string][]string)
|
||||||
|
|
||||||
|
switch modelType := v.(type) {
|
||||||
|
case model.Vector:
|
||||||
|
|
||||||
|
for _, samplePair := range modelType {
|
||||||
|
metricName := samplePair.Metric.String()
|
||||||
|
|
||||||
|
if _, ok := samples[metricName]; !ok {
|
||||||
|
samples[metricName] = []string{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if samplePair.Histogram != nil {
|
||||||
|
panic("histograms are not supported")
|
||||||
|
}
|
||||||
|
|
||||||
|
samples[metricName] = append(samples[metricName], strconv.FormatFloat(float64(samplePair.Value), 'f', -1, 64))
|
||||||
|
}
|
||||||
|
|
||||||
|
case model.Matrix:
|
||||||
|
for _, stream := range modelType {
|
||||||
|
metricName := stream.Metric.String()
|
||||||
|
|
||||||
|
if _, ok := samples[metricName]; !ok {
|
||||||
|
samples[metricName] = []string{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(stream.Histograms) > 0 {
|
||||||
|
panic("histograms are not supported")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, samplePair := range stream.Values {
|
||||||
|
samples[metricName] = append(samples[metricName], strconv.FormatFloat(float64(samplePair.Value), 'f', -1, 64))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inputSeries := make([]series, 0, len(samples))
|
||||||
|
|
||||||
|
for metric, value := range samples {
|
||||||
|
inputSeries = append(inputSeries, series{Series: metric, Values: strings.Join(value, " ")})
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := yaml.NewEncoder(os.Stdout).Encode(unitTestFile{Tests: []testGroup{{Interval: u.Step, InputSeries: inputSeries}}}); err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, err)
|
||||||
|
os.Exit(failureExitCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *unittestPrinter) printSeries(v []model.LabelSet) {}
|
||||||
|
|
||||||
|
func (u *unittestPrinter) printLabelValues(v model.LabelValues) {}
|
||||||
|
|
||||||
// importRules backfills recording rules from the files provided. The output are blocks of data
|
// importRules backfills recording rules from the files provided. The output are blocks of data
|
||||||
// at the outputDir location.
|
// at the outputDir location.
|
||||||
func importRules(url *url.URL, roundTripper http.RoundTripper, start, end, outputDir string, evalInterval, maxBlockDuration time.Duration, files ...string) error {
|
func importRules(url *url.URL, roundTripper http.RoundTripper, start, end, outputDir string, evalInterval, maxBlockDuration time.Duration, files ...string) error {
|
||||||
|
|
|
@ -68,14 +68,17 @@ func TestQueryRange(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
p := &promqlPrinter{}
|
p := &promqlPrinter{}
|
||||||
exitCode := QueryRange(urlObject, http.DefaultTransport, map[string]string{}, "up", "0", "300", 0, p)
|
qr, err := newQueryRange("0", "300", 0)
|
||||||
|
require.NoError(t, err)
|
||||||
|
exitCode := QueryRange(urlObject, http.DefaultTransport, map[string]string{}, "up", qr, p)
|
||||||
require.Equal(t, "/api/v1/query_range", getRequest().URL.Path)
|
require.Equal(t, "/api/v1/query_range", getRequest().URL.Path)
|
||||||
form := getRequest().Form
|
form := getRequest().Form
|
||||||
require.Equal(t, "up", form.Get("query"))
|
require.Equal(t, "up", form.Get("query"))
|
||||||
require.Equal(t, "1", form.Get("step"))
|
require.Equal(t, "1", form.Get("step"))
|
||||||
require.Equal(t, 0, exitCode)
|
require.Equal(t, 0, exitCode)
|
||||||
|
|
||||||
exitCode = QueryRange(urlObject, http.DefaultTransport, map[string]string{}, "up", "0", "300", 10*time.Millisecond, p)
|
qr, err = newQueryRange("0", "300", 10*time.Millisecond)
|
||||||
|
exitCode = QueryRange(urlObject, http.DefaultTransport, map[string]string{}, "up", qr, p)
|
||||||
require.Equal(t, "/api/v1/query_range", getRequest().URL.Path)
|
require.Equal(t, "/api/v1/query_range", getRequest().URL.Path)
|
||||||
form = getRequest().Form
|
form = getRequest().Form
|
||||||
require.Equal(t, "up", form.Get("query"))
|
require.Equal(t, "up", form.Get("query"))
|
||||||
|
@ -92,7 +95,9 @@ func TestQueryInstant(t *testing.T) {
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
p := &promqlPrinter{}
|
p := &promqlPrinter{}
|
||||||
exitCode := QueryInstant(urlObject, http.DefaultTransport, "up", "300", p)
|
qr, err := newQueryRange("300", "", time.Second)
|
||||||
|
require.NoError(t, err)
|
||||||
|
exitCode := QueryInstant(urlObject, http.DefaultTransport, "up", qr, p)
|
||||||
require.Equal(t, "/api/v1/query", getRequest().URL.Path)
|
require.Equal(t, "/api/v1/query", getRequest().URL.Path)
|
||||||
form := getRequest().Form
|
form := getRequest().Form
|
||||||
require.Equal(t, "up", form.Get("query"))
|
require.Equal(t, "up", form.Get("query"))
|
||||||
|
|
|
@ -61,25 +61,20 @@ func newAPI(url *url.URL, roundTripper http.RoundTripper, headers map[string]str
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryInstant performs an instant query against a Prometheus server.
|
// QueryInstant performs an instant query against a Prometheus server.
|
||||||
func QueryInstant(url *url.URL, roundTripper http.RoundTripper, query, evalTime string, p printer) int {
|
func QueryInstant(url *url.URL, roundTripper http.RoundTripper, query string, qr v1.Range, p printer) int {
|
||||||
api, err := newAPI(url, roundTripper, nil)
|
api, err := newAPI(url, roundTripper, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "error creating API client:", err)
|
fmt.Fprintln(os.Stderr, "error creating API client:", err)
|
||||||
return failureExitCode
|
return failureExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
eTime := time.Now()
|
if qr.Start.Equal(minTime) {
|
||||||
if evalTime != "" {
|
qr.Start = time.Now()
|
||||||
eTime, err = parseTime(evalTime)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, "error parsing evaluation time:", err)
|
|
||||||
return failureExitCode
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run query against client.
|
// Run query against client.
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||||
val, _, err := api.Query(ctx, query, eTime) // Ignoring warnings for now.
|
val, _, err := api.Query(ctx, query, qr.Start) // Ignoring warnings for now.
|
||||||
cancel()
|
cancel()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return handleAPIError(err)
|
return handleAPIError(err)
|
||||||
|
@ -91,50 +86,24 @@ func QueryInstant(url *url.URL, roundTripper http.RoundTripper, query, evalTime
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryRange performs a range query against a Prometheus server.
|
// QueryRange performs a range query against a Prometheus server.
|
||||||
func QueryRange(url *url.URL, roundTripper http.RoundTripper, 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 string, qr v1.Range, p printer) int {
|
||||||
api, err := newAPI(url, roundTripper, headers)
|
api, err := newAPI(url, roundTripper, headers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "error creating API client:", err)
|
fmt.Fprintln(os.Stderr, "error creating API client:", err)
|
||||||
return failureExitCode
|
return failureExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
var stime, etime time.Time
|
if qr.End.Equal(maxTime) {
|
||||||
|
qr.End = time.Now()
|
||||||
if end == "" {
|
|
||||||
etime = time.Now()
|
|
||||||
} else {
|
|
||||||
etime, err = parseTime(end)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, "error parsing end time:", err)
|
|
||||||
return failureExitCode
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if start == "" {
|
if qr.Start.Equal(minTime) {
|
||||||
stime = etime.Add(-5 * time.Minute)
|
qr.Start = qr.End.Add(-5 * time.Minute)
|
||||||
} else {
|
|
||||||
stime, err = parseTime(start)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, "error parsing start time:", err)
|
|
||||||
return failureExitCode
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !stime.Before(etime) {
|
|
||||||
fmt.Fprintln(os.Stderr, "start time is not before end time")
|
|
||||||
return failureExitCode
|
|
||||||
}
|
|
||||||
|
|
||||||
if step == 0 {
|
|
||||||
resolution := math.Max(math.Floor(etime.Sub(stime).Seconds()/250), 1)
|
|
||||||
// Convert seconds to nanoseconds such that time.Duration parses correctly.
|
|
||||||
step = time.Duration(resolution) * time.Second
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run query against client.
|
// Run query against client.
|
||||||
r := v1.Range{Start: stime, End: etime, Step: step}
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||||
val, _, err := api.QueryRange(ctx, query, r) // Ignoring warnings for now.
|
val, _, err := api.QueryRange(ctx, query, qr) // Ignoring warnings for now.
|
||||||
cancel()
|
cancel()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -146,22 +115,16 @@ func QueryRange(url *url.URL, roundTripper http.RoundTripper, headers map[string
|
||||||
}
|
}
|
||||||
|
|
||||||
// QuerySeries queries for a series against a Prometheus server.
|
// QuerySeries queries for a series against a Prometheus server.
|
||||||
func QuerySeries(url *url.URL, roundTripper http.RoundTripper, matchers []string, start, end string, p printer) int {
|
func QuerySeries(url *url.URL, roundTripper http.RoundTripper, matchers []string, qr v1.Range, p printer) int {
|
||||||
api, err := newAPI(url, roundTripper, nil)
|
api, err := newAPI(url, roundTripper, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "error creating API client:", err)
|
fmt.Fprintln(os.Stderr, "error creating API client:", err)
|
||||||
return failureExitCode
|
return failureExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
stime, etime, err := parseStartTimeAndEndTime(start, end)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
return failureExitCode
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run query against client.
|
// Run query against client.
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||||
val, _, err := api.Series(ctx, matchers, stime, etime) // Ignoring warnings for now.
|
val, _, err := api.Series(ctx, matchers, qr.Start, qr.End) // Ignoring warnings for now.
|
||||||
cancel()
|
cancel()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -173,22 +136,16 @@ func QuerySeries(url *url.URL, roundTripper http.RoundTripper, matchers []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryLabels queries for label values against a Prometheus server.
|
// QueryLabels queries for label values against a Prometheus server.
|
||||||
func QueryLabels(url *url.URL, roundTripper http.RoundTripper, matchers []string, name, start, end string, p printer) int {
|
func QueryLabels(url *url.URL, roundTripper http.RoundTripper, matchers []string, name string, qr v1.Range, p printer) int {
|
||||||
api, err := newAPI(url, roundTripper, nil)
|
api, err := newAPI(url, roundTripper, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, "error creating API client:", err)
|
fmt.Fprintln(os.Stderr, "error creating API client:", err)
|
||||||
return failureExitCode
|
return failureExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
stime, etime, err := parseStartTimeAndEndTime(start, end)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
return failureExitCode
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run query against client.
|
// Run query against client.
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
|
||||||
val, warn, err := api.LabelValues(ctx, name, matchers, stime, etime)
|
val, warn, err := api.LabelValues(ctx, name, matchers, qr.Start, qr.End)
|
||||||
cancel()
|
cancel()
|
||||||
|
|
||||||
for _, v := range warn {
|
for _, v := range warn {
|
||||||
|
@ -213,12 +170,31 @@ func handleAPIError(err error) int {
|
||||||
return failureExitCode
|
return failureExitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newQueryRange(start, end string, step time.Duration) (v1.Range, error) {
|
||||||
|
qr := v1.Range{}
|
||||||
|
var err error
|
||||||
|
qr.Start, qr.End, err = parseStartTimeAndEndTime(start, end)
|
||||||
|
|
||||||
|
if !qr.Start.Before(qr.End) {
|
||||||
|
return qr, errors.New("start time is not before end time")
|
||||||
|
}
|
||||||
|
|
||||||
|
if step == 0 {
|
||||||
|
resolution := math.Max(math.Floor(qr.End.Sub(qr.Start).Seconds()/250), 1)
|
||||||
|
// Convert seconds to nanoseconds such that time.Duration parses correctly.
|
||||||
|
step = time.Duration(resolution) * time.Second
|
||||||
|
}
|
||||||
|
|
||||||
|
qr.Step = step
|
||||||
|
|
||||||
|
return qr, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var minTime = time.Now().Add(-9999 * time.Hour)
|
||||||
|
var maxTime = time.Now().Add(9999 * time.Hour)
|
||||||
|
|
||||||
func parseStartTimeAndEndTime(start, end string) (time.Time, time.Time, error) {
|
func parseStartTimeAndEndTime(start, end string) (time.Time, time.Time, error) {
|
||||||
var (
|
var err error
|
||||||
minTime = time.Now().Add(-9999 * time.Hour)
|
|
||||||
maxTime = time.Now().Add(9999 * time.Hour)
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
|
|
||||||
stime := minTime
|
stime := minTime
|
||||||
etime := maxTime
|
etime := maxTime
|
||||||
|
|
|
@ -215,7 +215,7 @@ Run query against a Prometheus server.
|
||||||
|
|
||||||
| Flag | Description | Default |
|
| Flag | Description | Default |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| <code class="text-nowrap">-o</code>, <code class="text-nowrap">--format</code> | Output format of the query. | `promql` |
|
| <code class="text-nowrap">-o</code>, <code class="text-nowrap">--format</code> | Output format of the query: promql, json, unittest. Unittest output is experimental. | `promql` |
|
||||||
| <code class="text-nowrap">--http.config.file</code> | HTTP client configuration file for promtool to connect to Prometheus. | |
|
| <code class="text-nowrap">--http.config.file</code> | HTTP client configuration file for promtool to connect to Prometheus. | |
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue