diff --git a/cmd/root.go b/cmd/root.go index 19a42fb0..5e4c274a 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -336,6 +336,12 @@ func initFlags() { "", "Prometheus pushgateway auth password", ) + rootCmd.Flags().StringVar( + flags.PushGateway.Format, + "push-gtwy-format", + "", + "Prometheus pushgateway format", + ) } // ---------------------------------------------------------------------------- diff --git a/pkg/config/flags.go b/pkg/config/flags.go index 7fbabfc5..d67381ee 100644 --- a/pkg/config/flags.go +++ b/pkg/config/flags.go @@ -6,6 +6,7 @@ package config import ( "errors" "fmt" + "slices" "strings" "k8s.io/cli-runtime/pkg/genericclioptions" @@ -86,6 +87,13 @@ func (f *Flags) Validate() error { return errors.New("you must set --push-gtwy-url when prometheus report is enabled") } } + if IsStrSet(f.PushGateway.URL) && IsStrSet(f.PushGateway.Format) { + validFormats := []string{"protocompact", "protodelim", "prototext", "textplain", "openmetrics"} + + if !slices.Contains(validFormats, *f.PushGateway.Format) { + return fmt.Errorf("'--push-gtwy-format' must be one of: %s", strings.Join(validFormats, ", ")) + } + } return nil } diff --git a/pkg/config/prom.go b/pkg/config/prom.go index d5bbd602..2fc9e4a6 100644 --- a/pkg/config/prom.go +++ b/pkg/config/prom.go @@ -20,11 +20,13 @@ func newBasicAuth() BasicAuth { type PushGateway struct { URL *string BasicAuth BasicAuth + Format *string } func newPushGateway() *PushGateway { return &PushGateway{ URL: strPtr(""), BasicAuth: newBasicAuth(), + Format: strPtr("textplain"), } } diff --git a/pkg/popeye.go b/pkg/popeye.go index 9190b2eb..52252af8 100644 --- a/pkg/popeye.go +++ b/pkg/popeye.go @@ -11,9 +11,12 @@ import ( "errors" "fmt" "io" + "maps" "net/http" "os" "path/filepath" + "slices" + "strings" "time" "github.com/derailed/popeye/internal" @@ -408,6 +411,27 @@ func (p *Popeye) dumpPrometheus(ctx context.Context, asset string, persist bool) instance += "-" + *p.flags.InClusterName } + validFormats := map[string]expfmt.Format{ + "protocompact": expfmt.NewFormat(expfmt.TypeProtoCompact), + "protodelim": expfmt.NewFormat(expfmt.TypeProtoDelim), + "prototext": expfmt.NewFormat(expfmt.TypeProtoText), + "textplain": expfmt.NewFormat(expfmt.TypeTextPlain), + "openmetrics": expfmt.NewFormat(expfmt.TypeOpenMetrics), + } + + format := validFormats["textplain"] + if config.IsStrSet(p.flags.PushGateway.Format) { + if f, exists := validFormats[*p.flags.PushGateway.Format]; exists { + format = f + } else { + validFormatsList := slices.Collect(maps.Keys(validFormats)) + return fmt.Errorf( + "'--push-gtwy-format' must be one of: %s", + strings.Join(validFormatsList, ", "), + ) + } + } + pusher := p.builder.ToPrometheus( p.flags.PushGateway, instance, @@ -415,10 +439,13 @@ func (p *Popeye) dumpPrometheus(ctx context.Context, asset string, persist bool) asset, p.codes.Glossary, ) - // Enable saving to file + + pusher = pusher.Format(format) + // Persist is used when prometheus output format is selected... + // ...custom p.Do func intercepts push output and prints it... + // ...to stdout, while replying to pusher with stub HTTP 200 if persist { pusher = pusher.Client(p) - pusher = pusher.Format(expfmt.NewFormat(expfmt.TypeTextPlain)) } return pusher.AddContext(ctx)