promtool: add command for querying series
@@ -74,6 +74,12 @@ func main() {
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()
+ querySeriesCmd := queryCmd.Command("series", "Run series query.")
+ querySeriesServer := querySeriesCmd.Arg("server", "Prometheus server to query.").Required().URL()
+ 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()
+
debugCmd := app.Command("debug", "Fetch debug information.")
debugPprofCmd := debugCmd.Command("pprof", "Fetch profiling debug information.")
debugPprofServer := debugPprofCmd.Arg("server", "Prometheus server to get pprof files from.").Required().String()
@@ -101,6 +107,9 @@ func main() {
case queryRangeCmd.FullCommand():
os.Exit(QueryRange(*queryRangeServer, *queryRangeExpr, *queryRangeBegin, *queryRangeEnd))
+ case querySeriesCmd.FullCommand():
+ os.Exit(QuerySeries(*querySeriesServer, *querySeriesMatch, *querySeriesBegin, *querySeriesEnd))
+
case debugPprofCmd.FullCommand():
os.Exit(debugPprof(*debugPprofServer))
@@ -453,6 +462,62 @@ func QueryRange(url string, query string, start string, end string) int {
return 0
}
+// QuerySeries queries for a series against a Prometheus server.
+func QuerySeries(url *url.URL, matchers []string, start string, end string) int {
+ config := api.Config{
+ Address: url.String(),
+ }
+
+ // Create new client.
+ c, err := api.NewClient(config)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, "error creating API client:", err)
+ return 1
+ }
+
+ // TODO: clean up timestamps
+ var (
+ minTime = time.Now().Add(-9999 * time.Hour)
+ maxTime = time.Now().Add(9999 * time.Hour)
+ )
+
+ var stime, etime time.Time
+
+ if start == "" {
+ stime = minTime
+ } else {
+ stime, err = parseTime(start)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, "error parsing start time:", err)
+ }
+ }
+
+ if end == "" {
+ etime = maxTime
+ } else {
+ etime, err = parseTime(end)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, "error parsing end time:", err)
+ }
+ }
+
+ // Run query against client.
+ api := v1.NewAPI(c)
+ ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
+ val, err := api.Series(ctx, matchers, stime, etime)
+ cancel()
+
+ if err != nil {
+ fmt.Fprintln(os.Stderr, "query error:", err)
+ return 1
+ }
+
+ for _, v := range val {
+ fmt.Println(v)
+ }
+ return 0
+}
+
func parseTime(s string) (time.Time, error) {
if t, err := strconv.ParseFloat(s, 64); err == nil {
s, ns := math.Modf(t)
