From d4aef935091b4ce92fd2436e37048b63394d5740 Mon Sep 17 00:00:00 2001 From: Kristof Kowalski Date: Tue, 2 Aug 2022 21:26:53 +1000 Subject: [PATCH] Adding header flag --- README.md | 21 ++++++++++++++++++- internal/cli/flags.go | 5 +++++ internal/cli/metrics_counter.go | 18 ++++++++++++++++ internal/cli/metrics_counter_observer.go | 18 ++++++++++++++++ .../cli/metrics_counter_observer_advanced.go | 18 ++++++++++++++++ internal/cli/metrics_counter_with_labels.go | 18 ++++++++++++++++ internal/cli/metrics_gauge_observer.go | 18 ++++++++++++++++ internal/cli/metrics_histogram.go | 18 ++++++++++++++++ internal/cli/metrics_up_down_counter.go | 18 ++++++++++++++++ .../cli/metrics_up_down_counter_observer.go | 18 ++++++++++++++++ internal/cli/traces.go | 19 ++++++++++++++--- 11 files changed, 185 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4489b8f..cf45795 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ USAGE: otelgen [global options] command [command options] [arguments...] VERSION: - v0.0.1 + v0.0.2 COMMANDS: metrics, m Generate metrics @@ -67,6 +67,7 @@ COMMANDS: GLOBAL OPTIONS: --duration value, -d value duration in seconds (default: 0) + --header value additional headers in 'key=value' format (accepts multiple inputs) --help, -h show help (default: false) --insecure, -i whether to enable client transport security (default: false) --log-level value log level used by the logger, one of: debug, info, warn, error (default: "info") @@ -110,6 +111,15 @@ $ otelgen --otel-exporter-otlp-endpoint otelcol.foo.bar:443 --duration 30 metric {"level":"info","ts":1658746751.791806,"caller":"cli/metrics_counter.go:79","msg":"stopping the exporter"} ``` +If you need to pass in additional HTTP headers to allow for authentication to vendor backends, simply utilise the `--header key=value` flag. The unit is a slice of headers so it accepts multiple headers during invocation. Such as: + +```sh +$ otelgen --otel-exporter-otlp-endpoint api.vendor.xyz:443 \ + --header 'x-auth=xxxxxx' \ + --header 'x-dataset=xxxxxx' \ + metrics counter +``` + ### Traces The `otelgen traces` command supports two types of traces, `single` and `multi`, the difference being, sometimes you just want to send a single trace to validate a configuration. **Multi** will allow you configure the `duration` and `rate`. @@ -155,6 +165,15 @@ $ otelgen --otel-exporter-otlp-endpoint otelcol.foo.bar:443 --duration 10 --rate ... ``` +If you need to pass in additional HTTP headers to allow for authentication to vendor backends, simply utilise the `--header key=value` flag. The unit is a slice of headers so it accepts multiple headers during invocation. Such as: + +```sh +$ otelgen --otel-exporter-otlp-endpoint api.vendor.xyz:443 \ + --header 'x-auth=xxxxxx' \ + --header 'x-dataset=xxxxxx' \ + traces single +``` + ## Acknowledgements This tool was developed in a short amount of time due to the awesome idea of the following sources: diff --git a/internal/cli/flags.go b/internal/cli/flags.go index 2873e95..64251d8 100644 --- a/internal/cli/flags.go +++ b/internal/cli/flags.go @@ -13,6 +13,11 @@ func getGlobalFlags() []cli.Flag { Usage: "duration in seconds", Value: 0, }), + altsrc.NewStringSliceFlag(&cli.StringSliceFlag{ + Name: "header", + // Aliases: []string{"h"}, + Usage: "additional headers in 'key=value' format", + }), altsrc.NewBoolFlag(&cli.BoolFlag{ Name: "insecure", Usage: "whether to enable client transport security", diff --git a/internal/cli/metrics_counter.go b/internal/cli/metrics_counter.go index ecec05b..da77c74 100644 --- a/internal/cli/metrics_counter.go +++ b/internal/cli/metrics_counter.go @@ -3,6 +3,8 @@ package cli import ( "context" "errors" + "fmt" + "strings" "time" grpcZap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap" @@ -62,6 +64,22 @@ func generateMetricsCounterAction(c *cli.Context) error { httpExpOpt = append(httpExpOpt, otlpmetrichttp.WithInsecure()) } + if len(c.StringSlice("header")) > 0 { + headers := make(map[string]string) + logger.Debug("Header count", zap.Int("headers", len(c.StringSlice("header")))) + for _, h := range c.StringSlice("header") { + kv := strings.SplitN(h, "=", 2) + if len(kv) != 2 { + return fmt.Errorf("value should be of the format key=value") + } + logger.Debug("key=value", zap.String(kv[0], kv[1])) + (headers)[kv[0]] = kv[1] + + } + grpcExpOpt = append(grpcExpOpt, otlpmetricgrpc.WithHeaders(headers)) + httpExpOpt = append(httpExpOpt, otlpmetrichttp.WithHeaders(headers)) + } + var exp *otlpmetric.Exporter if c.String("protocol") == "http" { logger.Info("starting HTTP exporter") diff --git a/internal/cli/metrics_counter_observer.go b/internal/cli/metrics_counter_observer.go index 830622e..ecda140 100644 --- a/internal/cli/metrics_counter_observer.go +++ b/internal/cli/metrics_counter_observer.go @@ -3,6 +3,8 @@ package cli import ( "context" "errors" + "fmt" + "strings" "time" grpcZap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap" @@ -63,6 +65,22 @@ func generateMetricsCounterObserverAction(c *cli.Context) error { httpExpOpt = append(httpExpOpt, otlpmetrichttp.WithInsecure()) } + if len(c.StringSlice("header")) > 0 { + headers := make(map[string]string) + logger.Debug("Header count", zap.Int("headers", len(c.StringSlice("header")))) + for _, h := range c.StringSlice("header") { + kv := strings.SplitN(h, "=", 2) + if len(kv) != 2 { + return fmt.Errorf("value should be of the format key=value") + } + logger.Debug("key=value", zap.String(kv[0], kv[1])) + (headers)[kv[0]] = kv[1] + + } + grpcExpOpt = append(grpcExpOpt, otlpmetricgrpc.WithHeaders(headers)) + httpExpOpt = append(httpExpOpt, otlpmetrichttp.WithHeaders(headers)) + } + var exp *otlpmetric.Exporter if c.String("protocol") == "http" { logger.Info("starting HTTP exporter") diff --git a/internal/cli/metrics_counter_observer_advanced.go b/internal/cli/metrics_counter_observer_advanced.go index 888929d..6692b4e 100644 --- a/internal/cli/metrics_counter_observer_advanced.go +++ b/internal/cli/metrics_counter_observer_advanced.go @@ -3,6 +3,8 @@ package cli import ( "context" "errors" + "fmt" + "strings" "time" grpcZap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap" @@ -62,6 +64,22 @@ func generateMetricsCounterObserverAdvancedAction(c *cli.Context) error { httpExpOpt = append(httpExpOpt, otlpmetrichttp.WithInsecure()) } + if len(c.StringSlice("header")) > 0 { + headers := make(map[string]string) + logger.Debug("Header count", zap.Int("headers", len(c.StringSlice("header")))) + for _, h := range c.StringSlice("header") { + kv := strings.SplitN(h, "=", 2) + if len(kv) != 2 { + return fmt.Errorf("value should be of the format key=value") + } + logger.Debug("key=value", zap.String(kv[0], kv[1])) + (headers)[kv[0]] = kv[1] + + } + grpcExpOpt = append(grpcExpOpt, otlpmetricgrpc.WithHeaders(headers)) + httpExpOpt = append(httpExpOpt, otlpmetrichttp.WithHeaders(headers)) + } + var exp *otlpmetric.Exporter if c.String("protocol") == "http" { logger.Info("starting HTTP exporter") diff --git a/internal/cli/metrics_counter_with_labels.go b/internal/cli/metrics_counter_with_labels.go index 0fbcf3f..2ddfc3e 100644 --- a/internal/cli/metrics_counter_with_labels.go +++ b/internal/cli/metrics_counter_with_labels.go @@ -3,6 +3,8 @@ package cli import ( "context" "errors" + "fmt" + "strings" "time" grpcZap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap" @@ -63,6 +65,22 @@ func generateMetricsCounterWithLabelsAction(c *cli.Context) error { httpExpOpt = append(httpExpOpt, otlpmetrichttp.WithInsecure()) } + if len(c.StringSlice("header")) > 0 { + headers := make(map[string]string) + logger.Debug("Header count", zap.Int("headers", len(c.StringSlice("header")))) + for _, h := range c.StringSlice("header") { + kv := strings.SplitN(h, "=", 2) + if len(kv) != 2 { + return fmt.Errorf("value should be of the format key=value") + } + logger.Debug("key=value", zap.String(kv[0], kv[1])) + (headers)[kv[0]] = kv[1] + + } + grpcExpOpt = append(grpcExpOpt, otlpmetricgrpc.WithHeaders(headers)) + httpExpOpt = append(httpExpOpt, otlpmetrichttp.WithHeaders(headers)) + } + var exp *otlpmetric.Exporter if c.String("protocol") == "http" { logger.Info("starting HTTP exporter") diff --git a/internal/cli/metrics_gauge_observer.go b/internal/cli/metrics_gauge_observer.go index 9fe013f..043203d 100644 --- a/internal/cli/metrics_gauge_observer.go +++ b/internal/cli/metrics_gauge_observer.go @@ -3,6 +3,8 @@ package cli import ( "context" "errors" + "fmt" + "strings" "time" grpcZap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap" @@ -63,6 +65,22 @@ func generateMetricsGaugeObserverAction(c *cli.Context) error { httpExpOpt = append(httpExpOpt, otlpmetrichttp.WithInsecure()) } + if len(c.StringSlice("header")) > 0 { + headers := make(map[string]string) + logger.Debug("Header count", zap.Int("headers", len(c.StringSlice("header")))) + for _, h := range c.StringSlice("header") { + kv := strings.SplitN(h, "=", 2) + if len(kv) != 2 { + return fmt.Errorf("value should be of the format key=value") + } + logger.Debug("key=value", zap.String(kv[0], kv[1])) + (headers)[kv[0]] = kv[1] + + } + grpcExpOpt = append(grpcExpOpt, otlpmetricgrpc.WithHeaders(headers)) + httpExpOpt = append(httpExpOpt, otlpmetrichttp.WithHeaders(headers)) + } + var exp *otlpmetric.Exporter if c.String("protocol") == "http" { logger.Info("starting HTTP exporter") diff --git a/internal/cli/metrics_histogram.go b/internal/cli/metrics_histogram.go index 4b93a11..d3f612e 100644 --- a/internal/cli/metrics_histogram.go +++ b/internal/cli/metrics_histogram.go @@ -3,6 +3,8 @@ package cli import ( "context" "errors" + "fmt" + "strings" "time" grpcZap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap" @@ -62,6 +64,22 @@ func generateMetricsHistogramAction(c *cli.Context) error { httpExpOpt = append(httpExpOpt, otlpmetrichttp.WithInsecure()) } + if len(c.StringSlice("header")) > 0 { + headers := make(map[string]string) + logger.Debug("Header count", zap.Int("headers", len(c.StringSlice("header")))) + for _, h := range c.StringSlice("header") { + kv := strings.SplitN(h, "=", 2) + if len(kv) != 2 { + return fmt.Errorf("value should be of the format key=value") + } + logger.Debug("key=value", zap.String(kv[0], kv[1])) + (headers)[kv[0]] = kv[1] + + } + grpcExpOpt = append(grpcExpOpt, otlpmetricgrpc.WithHeaders(headers)) + httpExpOpt = append(httpExpOpt, otlpmetrichttp.WithHeaders(headers)) + } + var exp *otlpmetric.Exporter if c.String("protocol") == "http" { logger.Info("starting HTTP exporter") diff --git a/internal/cli/metrics_up_down_counter.go b/internal/cli/metrics_up_down_counter.go index 2f43b35..fc539d6 100644 --- a/internal/cli/metrics_up_down_counter.go +++ b/internal/cli/metrics_up_down_counter.go @@ -3,6 +3,8 @@ package cli import ( "context" "errors" + "fmt" + "strings" "time" grpcZap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap" @@ -62,6 +64,22 @@ func generateMetricsUpDownCounterAction(c *cli.Context) error { httpExpOpt = append(httpExpOpt, otlpmetrichttp.WithInsecure()) } + if len(c.StringSlice("header")) > 0 { + headers := make(map[string]string) + logger.Debug("Header count", zap.Int("headers", len(c.StringSlice("header")))) + for _, h := range c.StringSlice("header") { + kv := strings.SplitN(h, "=", 2) + if len(kv) != 2 { + return fmt.Errorf("value should be of the format key=value") + } + logger.Debug("key=value", zap.String(kv[0], kv[1])) + (headers)[kv[0]] = kv[1] + + } + grpcExpOpt = append(grpcExpOpt, otlpmetricgrpc.WithHeaders(headers)) + httpExpOpt = append(httpExpOpt, otlpmetrichttp.WithHeaders(headers)) + } + var exp *otlpmetric.Exporter if c.String("protocol") == "http" { logger.Info("starting HTTP exporter") diff --git a/internal/cli/metrics_up_down_counter_observer.go b/internal/cli/metrics_up_down_counter_observer.go index 39734cf..f63aec5 100644 --- a/internal/cli/metrics_up_down_counter_observer.go +++ b/internal/cli/metrics_up_down_counter_observer.go @@ -3,6 +3,8 @@ package cli import ( "context" "errors" + "fmt" + "strings" "time" grpcZap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap" @@ -63,6 +65,22 @@ func generateMetricsUpDownCounterObserverAction(c *cli.Context) error { httpExpOpt = append(httpExpOpt, otlpmetrichttp.WithInsecure()) } + if len(c.StringSlice("header")) > 0 { + headers := make(map[string]string) + logger.Debug("Header count", zap.Int("headers", len(c.StringSlice("header")))) + for _, h := range c.StringSlice("header") { + kv := strings.SplitN(h, "=", 2) + if len(kv) != 2 { + return fmt.Errorf("value should be of the format key=value") + } + logger.Debug("key=value", zap.String(kv[0], kv[1])) + (headers)[kv[0]] = kv[1] + + } + grpcExpOpt = append(grpcExpOpt, otlpmetricgrpc.WithHeaders(headers)) + httpExpOpt = append(httpExpOpt, otlpmetrichttp.WithHeaders(headers)) + } + var exp *otlpmetric.Exporter if c.String("protocol") == "http" { logger.Info("starting HTTP exporter") diff --git a/internal/cli/traces.go b/internal/cli/traces.go index 425b84f..9509b03 100644 --- a/internal/cli/traces.go +++ b/internal/cli/traces.go @@ -3,6 +3,8 @@ package cli import ( "context" "errors" + "fmt" + "strings" "time" grpcZap "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap" @@ -76,9 +78,20 @@ func genTracesCommand() *cli.Command { httpExpOpt = append(httpExpOpt, otlptracehttp.WithInsecure()) } - if len(tracesCfg.Headers) > 0 { - grpcExpOpt = append(grpcExpOpt, otlptracegrpc.WithHeaders(tracesCfg.Headers)) - httpExpOpt = append(httpExpOpt, otlptracehttp.WithHeaders(tracesCfg.Headers)) + if len(c.StringSlice("header")) > 0 { + headers := make(map[string]string) + logger.Debug("Header count", zap.Int("headers", len(c.StringSlice("header")))) + for _, h := range c.StringSlice("header") { + kv := strings.SplitN(h, "=", 2) + if len(kv) != 2 { + return fmt.Errorf("value should be of the format key=value") + } + logger.Debug("key=value", zap.String(kv[0], kv[1])) + (headers)[kv[0]] = kv[1] + + } + grpcExpOpt = append(grpcExpOpt, otlptracegrpc.WithHeaders(headers)) + httpExpOpt = append(httpExpOpt, otlptracehttp.WithHeaders(headers)) } var exp *otlptrace.Exporter