From 44a2b81bef1f73d6e2c24efc0f824f7b8edbea52 Mon Sep 17 00:00:00 2001 From: Livio Amstutz Date: Thu, 28 Apr 2022 14:44:13 +0200 Subject: [PATCH] feat: enable tracing (#3528) --- cmd/admin/start/config.go | 10 ++- internal/telemetry/tracing/config/config.go | 63 +++++-------------- .../telemetry/tracing/google/google_tracer.go | 27 ++++---- internal/telemetry/tracing/log/config.go | 22 ++++++- internal/telemetry/tracing/otel/config.go | 20 +++++- internal/telemetry/tracing/tracing.go | 4 -- 6 files changed, 76 insertions(+), 70 deletions(-) diff --git a/cmd/admin/start/config.go b/cmd/admin/start/config.go index 81d1bbcfc3..fa45ec2173 100644 --- a/cmd/admin/start/config.go +++ b/cmd/admin/start/config.go @@ -5,9 +5,6 @@ import ( "github.com/spf13/viper" "github.com/zitadel/logging" - "github.com/zitadel/zitadel/internal/command" - "github.com/zitadel/zitadel/internal/config/hook" - admin_es "github.com/zitadel/zitadel/internal/admin/repository/eventsourcing" internal_authz "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/api/http/middleware" @@ -16,12 +13,15 @@ import ( "github.com/zitadel/zitadel/internal/api/ui/login" auth_es "github.com/zitadel/zitadel/internal/auth/repository/eventsourcing" "github.com/zitadel/zitadel/internal/authz" + "github.com/zitadel/zitadel/internal/command" + "github.com/zitadel/zitadel/internal/config/hook" "github.com/zitadel/zitadel/internal/config/systemdefaults" "github.com/zitadel/zitadel/internal/crypto" "github.com/zitadel/zitadel/internal/database" "github.com/zitadel/zitadel/internal/notification" "github.com/zitadel/zitadel/internal/query/projection" static_config "github.com/zitadel/zitadel/internal/static/config" + tracing "github.com/zitadel/zitadel/internal/telemetry/tracing/config" ) type Config struct { @@ -34,6 +34,7 @@ type Config struct { HTTP1HostHeader string WebAuthNName string Database database.Config + Tracing tracing.Config Projections projection.Config AuthZ authz.Config Auth auth_es.Config @@ -64,6 +65,9 @@ func MustNewConfig(v *viper.Viper) *Config { err = config.Log.SetLogger() logging.OnError(err).Fatal("unable to set logger") + err = config.Tracing.NewTracer() + logging.OnError(err).Fatal("unable to set tracer") + return config } diff --git a/internal/telemetry/tracing/config/config.go b/internal/telemetry/tracing/config/config.go index 28921a1aea..4e1a415201 100644 --- a/internal/telemetry/tracing/config/config.go +++ b/internal/telemetry/tracing/config/config.go @@ -1,69 +1,34 @@ package config import ( - "encoding/json" - "github.com/zitadel/zitadel/internal/errors" - "github.com/zitadel/zitadel/internal/telemetry/tracing" "github.com/zitadel/zitadel/internal/telemetry/tracing/google" "github.com/zitadel/zitadel/internal/telemetry/tracing/log" "github.com/zitadel/zitadel/internal/telemetry/tracing/otel" ) -type TracingConfig struct { +type Config struct { Type string - Config tracing.Config + Config map[string]interface{} `mapstructure:",remain"` } -var tracer = map[string]func() tracing.Config{ - "otel": func() tracing.Config { return &otel.Config{} }, - "google": func() tracing.Config { return &google.Config{} }, - "log": func() tracing.Config { return &log.Config{} }, - "none": func() tracing.Config { return &NoTracing{} }, - "": func() tracing.Config { return &NoTracing{} }, -} - -func (c *TracingConfig) UnmarshalJSON(data []byte) error { - var rc struct { - Type string - Config json.RawMessage - } - - if err := json.Unmarshal(data, &rc); err != nil { - return errors.ThrowInternal(err, "TRACE-vmjS", "error parsing config") - } - - c.Type = rc.Type - - var err error - c.Config, err = newTracingConfig(c.Type, rc.Config) - if err != nil { - return err - } - - return c.Config.NewTracer() -} - -func newTracingConfig(tracerType string, configData []byte) (tracing.Config, error) { - t, ok := tracer[tracerType] +func (c *Config) NewTracer() error { + t, ok := tracer[c.Type] if !ok { - return nil, errors.ThrowInternalf(nil, "TRACE-HMEJ", "config type %s not supported", tracerType) + return errors.ThrowInternalf(nil, "TRACE-dsbjh", "config type %s not supported", c.Type) } - tracingConfig := t() - if len(configData) == 0 { - return tracingConfig, nil - } - - if err := json.Unmarshal(configData, tracingConfig); err != nil { - return nil, errors.ThrowInternal(err, "TRACE-1tSS", "Could not read config: %v") - } - - return tracingConfig, nil + return t(c.Config) } -type NoTracing struct{} +var tracer = map[string]func(map[string]interface{}) error{ + "otel": otel.NewTracerFromConfig, + "google": google.NewTracer, + "log": log.NewTracer, + "none": NoTracer, + "": NoTracer, +} -func (_ *NoTracing) NewTracer() error { +func NoTracer(_ map[string]interface{}) error { return nil } diff --git a/internal/telemetry/tracing/google/google_tracer.go b/internal/telemetry/tracing/google/google_tracer.go index 0643d2fe9f..5bf622b821 100644 --- a/internal/telemetry/tracing/google/google_tracer.go +++ b/internal/telemetry/tracing/google/google_tracer.go @@ -1,8 +1,7 @@ package google import ( - "os" - "strings" + "strconv" texporter "github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/trace" sdk_trace "go.opentelemetry.io/otel/sdk/trace" @@ -18,15 +17,26 @@ type Config struct { Fraction float64 } +func NewTracer(rawConfig map[string]interface{}) (err error) { + c := new(Config) + c.ProjectID, _ = rawConfig["projectid"].(string) + c.MetricPrefix, _ = rawConfig["metricprefix"].(string) + fraction, ok := rawConfig["fraction"].(string) + if ok { + c.Fraction, err = strconv.ParseFloat(fraction, 32) + if err != nil { + return errors.ThrowInternal(err, "GOOGLE-Dsag3", "could not map fraction") + } + } + + return c.NewTracer() +} + type Tracer struct { otel.Tracer } func (c *Config) NewTracer() error { - if !envIsSet() { - return errors.ThrowInvalidArgument(nil, "GOOGL-sdh3a", "env not properly set, GOOGLE_APPLICATION_CREDENTIALS is misconfigured or missing") - } - sampler := sdk_trace.ParentBased(sdk_trace.TraceIDRatioBased(c.Fraction)) exporter, err := texporter.New(texporter.WithProjectID(c.ProjectID)) if err != nil { @@ -37,8 +47,3 @@ func (c *Config) NewTracer() error { return nil } - -func envIsSet() bool { - gAuthCred := os.Getenv("GOOGLE_APPLICATION_CREDENTIALS") - return strings.Contains(gAuthCred, ".json") -} diff --git a/internal/telemetry/tracing/log/config.go b/internal/telemetry/tracing/log/config.go index e83b2ceb8e..19399744a3 100644 --- a/internal/telemetry/tracing/log/config.go +++ b/internal/telemetry/tracing/log/config.go @@ -1,10 +1,14 @@ package log import ( - "github.com/zitadel/zitadel/internal/telemetry/tracing" - "github.com/zitadel/zitadel/internal/telemetry/tracing/otel" + "strconv" + stdout "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" sdk_trace "go.opentelemetry.io/otel/sdk/trace" + + "github.com/zitadel/zitadel/internal/errors" + "github.com/zitadel/zitadel/internal/telemetry/tracing" + "github.com/zitadel/zitadel/internal/telemetry/tracing/otel" ) type Config struct { @@ -12,6 +16,20 @@ type Config struct { MetricPrefix string } +func NewTracer(rawConfig map[string]interface{}) (err error) { + c := new(Config) + c.MetricPrefix, _ = rawConfig["metricprefix"].(string) + fraction, ok := rawConfig["fraction"].(string) + if ok { + c.Fraction, err = strconv.ParseFloat(fraction, 32) + if err != nil { + return errors.ThrowInternal(err, "LOG-Dsag3", "could not map fraction") + } + } + + return c.NewTracer() +} + type Tracer struct { otel.Tracer } diff --git a/internal/telemetry/tracing/otel/config.go b/internal/telemetry/tracing/otel/config.go index fa35998211..4deb8d77e0 100644 --- a/internal/telemetry/tracing/otel/config.go +++ b/internal/telemetry/tracing/otel/config.go @@ -2,10 +2,13 @@ package otel import ( "context" + "strconv" - "github.com/zitadel/zitadel/internal/telemetry/tracing" otlpgrpc "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" sdk_trace "go.opentelemetry.io/otel/sdk/trace" + + "github.com/zitadel/zitadel/internal/errors" + "github.com/zitadel/zitadel/internal/telemetry/tracing" ) type Config struct { @@ -14,6 +17,21 @@ type Config struct { Endpoint string } +func NewTracerFromConfig(rawConfig map[string]interface{}) (err error) { + c := new(Config) + c.Endpoint, _ = rawConfig["endpoint"].(string) + c.MetricPrefix, _ = rawConfig["metricprefix"].(string) + fraction, ok := rawConfig["fraction"].(string) + if ok { + c.Fraction, err = strconv.ParseFloat(fraction, 32) + if err != nil { + return errors.ThrowInternal(err, "OTEL-Dd2s", "could not map fraction") + } + } + + return c.NewTracer() +} + func (c *Config) NewTracer() error { sampler := sdk_trace.ParentBased(sdk_trace.TraceIDRatioBased(c.Fraction)) exporter, err := otlpgrpc.New(context.Background(), otlpgrpc.WithEndpoint(c.Endpoint), otlpgrpc.WithInsecure()) diff --git a/internal/telemetry/tracing/tracing.go b/internal/telemetry/tracing/tracing.go index fc32b3ea10..31bbb050b0 100644 --- a/internal/telemetry/tracing/tracing.go +++ b/internal/telemetry/tracing/tracing.go @@ -18,10 +18,6 @@ type Tracer interface { Sampler() sdk_trace.Sampler } -type Config interface { - NewTracer() error -} - var T Tracer func Sampler() sdk_trace.Sampler {