From 4d7055b5eedc9a6662f6b23d09f2272f9709d7cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Fri, 25 Nov 2022 08:35:57 +0000 Subject: [PATCH 1/5] introduce otel tracing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jörn Friedrich Dreyer introduce otlp tracing Signed-off-by: Jörn Friedrich Dreyer --- changelog/unreleased/otlp-tracing.md | 5 ++ cmd/revad/runtime/runtime.go | 5 +- go.mod | 6 ++ go.sum | 16 +++- .../owncloud/ocdav/propfind/propfind.go | 4 + pkg/micro/ocdav/option.go | 8 +- pkg/micro/ocdav/service.go | 2 +- pkg/trace/trace.go | 80 +++++++++++++++++-- 8 files changed, 111 insertions(+), 15 deletions(-) create mode 100644 changelog/unreleased/otlp-tracing.md diff --git a/changelog/unreleased/otlp-tracing.md b/changelog/unreleased/otlp-tracing.md new file mode 100644 index 0000000000..58b6665400 --- /dev/null +++ b/changelog/unreleased/otlp-tracing.md @@ -0,0 +1,5 @@ +Enhancement: add otlp tracing exporter + +We can now use `tracing_exporter=otlp` to send traces using the otlp exporter. + +https://github.com/cs3org/reva/pull/3496 diff --git a/cmd/revad/runtime/runtime.go b/cmd/revad/runtime/runtime.go index 9f467a84f6..75ed887764 100644 --- a/cmd/revad/runtime/runtime.go +++ b/cmd/revad/runtime/runtime.go @@ -76,6 +76,7 @@ func RunWithOptions(mainConf map[string]interface{}, pidFile string, opts ...Opt type coreConf struct { MaxCPUs string `mapstructure:"max_cpus"` TracingEnabled bool `mapstructure:"tracing_enabled"` + TracingExporter string `mapstructure:"tracing_exporter"` TracingEndpoint string `mapstructure:"tracing_endpoint"` TracingCollector string `mapstructure:"tracing_collector"` TracingServiceName string `mapstructure:"tracing_service_name"` @@ -149,9 +150,9 @@ func initServers(mainConf map[string]interface{}, log *zerolog.Logger, tp trace. func initTracing(conf *coreConf) trace.TracerProvider { if conf.TracingEnabled { - rtrace.InitDefaultTracerProvider(conf.TracingCollector, conf.TracingEndpoint) + rtrace.InitDefaultTracerProvider(conf.TracingExporter, conf.TracingCollector, conf.TracingEndpoint) } - return rtrace.GetTracerProvider(conf.TracingEnabled, conf.TracingCollector, conf.TracingEndpoint, conf.TracingServiceName) + return rtrace.GetTracerProvider(conf.TracingEnabled, conf.TracingExporter, conf.TracingCollector, conf.TracingEndpoint, conf.TracingServiceName) } func initCPUCount(conf *coreConf, log *zerolog.Logger) { diff --git a/go.mod b/go.mod index 99cb980d8d..5a2fdf0033 100644 --- a/go.mod +++ b/go.mod @@ -78,6 +78,8 @@ require ( go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.36.4 go.opentelemetry.io/otel v1.11.1 go.opentelemetry.io/otel/exporters/jaeger v1.11.1 + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.11.1 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.11.1 go.opentelemetry.io/otel/sdk v1.11.1 go.opentelemetry.io/otel/trace v1.11.1 golang.org/x/crypto v0.1.0 @@ -104,6 +106,7 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/bitly/go-simplejson v0.5.0 // indirect github.com/bmizerany/pat v0.0.0-20210406213842-e4b6760bdd6f // indirect + github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cloudflare/circl v1.2.0 // indirect github.com/coreos/go-semver v0.3.0 // indirect @@ -135,6 +138,7 @@ require ( github.com/golang/glog v1.0.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/google/go-querystring v1.1.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 // indirect github.com/hashicorp/consul/api v1.15.2 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect @@ -197,6 +201,8 @@ require ( go.etcd.io/etcd/api/v3 v3.5.5 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.5 // indirect go.mongodb.org/mongo-driver v1.10.3 // indirect + go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.1 // indirect + go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.8.0 // indirect go.uber.org/zap v1.23.0 // indirect diff --git a/go.sum b/go.sum index 4544e1ee1e..6e0c5670ce 100644 --- a/go.sum +++ b/go.sum @@ -208,6 +208,8 @@ github.com/c-bata/go-prompt v0.2.6/go.mod h1:/LMAke8wD2FsNu9EXNdHxNLbd9MedkPnCdf github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= +github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/ceph/go-ceph v0.18.0 h1:4WM6yAq/iqBDaeeADDiPKLqKiP0iZ4fffdgCr1lnOL4= github.com/ceph/go-ceph v0.18.0/go.mod h1:cflETVTBNAQM6jdr7hpNHHFHKYiJiWWcAeRDrRx/1ng= @@ -527,6 +529,9 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaW github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 h1:lLT7ZLSzGLI08vc9cpd+tYmNWjdKDqyr/2L+f6U12Fk= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= github.com/hashicorp/consul/api v1.15.2 h1:3Q/pDqvJ7udgt/60QOOW/p/PeKioQN+ncYzzCdN2av0= github.com/hashicorp/consul/api v1.15.2/go.mod h1:v6nvB10borjOuIwNRZYPZiHKrTM/AyrGtd0WVVodKM8= @@ -954,18 +959,26 @@ go.opentelemetry.io/otel v1.11.1 h1:4WLLAmcfkmDk2ukNXJyq3/kiz/3UzCaYq6PskJsaou4= go.opentelemetry.io/otel v1.11.1/go.mod h1:1nNhXBbWSD0nsL38H6btgnFN2k4i0sNLHNNMZMSbUGE= go.opentelemetry.io/otel/exporters/jaeger v1.11.1 h1:F9Io8lqWdGyIbY3/SOGki34LX/l+7OL0gXNxjqwcbuQ= go.opentelemetry.io/otel/exporters/jaeger v1.11.1/go.mod h1:lRa2w3bQ4R4QN6zYsDgy7tEezgoKEu7Ow2g35Y75+KI= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.1 h1:X2GndnMCsUPh6CiY2a+frAbNsXaPLbB0soHRYhAZ5Ig= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.1/go.mod h1:i8vjiSzbiUC7wOQplijSXMYUpNM93DtlS5CbUT+C6oQ= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.11.1 h1:MEQNafcNCB0uQIti/oHgU7CZpUMYQ7qigBwMVKycHvc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.11.1/go.mod h1:19O5I2U5iys38SsmT2uDJja/300woyzE1KPIQxEUBUc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.11.1 h1:LYyG/f1W/jzAix16jbksJfMQFpOH/Ma6T639pVPMgfI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.11.1/go.mod h1:QrRRQiY3kzAoYPNLP0W/Ikg0gR6V3LMc+ODSxr7yyvg= go.opentelemetry.io/otel/sdk v1.11.1 h1:F7KmQgoHljhUuJyA+9BiU+EkJfyX5nVVF4wyzWZpKxs= go.opentelemetry.io/otel/sdk v1.11.1/go.mod h1:/l3FE4SupHJ12TduVjUkZtlfFqDCQJlOlithYrdktys= go.opentelemetry.io/otel/trace v1.11.1 h1:ofxdnzsNrGBYXbP7t7zpUK281+go5rF7dvdIZXF8gdQ= go.opentelemetry.io/otel/trace v1.11.1/go.mod h1:f/Q9G7vzk5u91PhbmKbg1Qn0rzH1LJ4vbPHFGkTPtOk= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= +go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= +go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= @@ -1515,6 +1528,7 @@ google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnD google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= +google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= diff --git a/internal/http/services/owncloud/ocdav/propfind/propfind.go b/internal/http/services/owncloud/ocdav/propfind/propfind.go index 918a28cf08..ad4c671a29 100644 --- a/internal/http/services/owncloud/ocdav/propfind/propfind.go +++ b/internal/http/services/owncloud/ocdav/propfind/propfind.go @@ -53,6 +53,7 @@ import ( "github.com/rs/zerolog" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" + semconv "go.opentelemetry.io/otel/semconv/v1.4.0" "golang.org/x/sync/errgroup" "google.golang.org/protobuf/types/known/fieldmaskpb" ) @@ -234,6 +235,9 @@ func (p *Handler) HandleSpacesPropfind(w http.ResponseWriter, r *http.Request, s depth, err := net.ParseDepth(dh) if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, "Invalid Depth header value") + span.SetAttributes(semconv.HTTPStatusCodeKey.Int(http.StatusBadRequest)) sublog.Debug().Str("depth", dh).Msg(err.Error()) w.WriteHeader(http.StatusBadRequest) m := fmt.Sprintf("Invalid Depth header value: %v", dh) diff --git a/pkg/micro/ocdav/option.go b/pkg/micro/ocdav/option.go index 85f847a004..679f931fcb 100644 --- a/pkg/micro/ocdav/option.go +++ b/pkg/micro/ocdav/option.go @@ -48,6 +48,7 @@ type Options struct { GatewayClient gateway.GatewayAPIClient TracingEnabled bool + TracingExporter string TracingCollector string TracingEndpoint string @@ -209,11 +210,12 @@ func LockSystem(val ocdav.LockSystem) Option { } // Tracing enables tracing -func Tracing(trEndpoint string, trCollector string) Option { +func Tracing(exporter, endpoint, collector string) Option { return func(o *Options) { o.TracingEnabled = true - o.TracingEndpoint = trEndpoint - o.TracingCollector = trCollector + o.TracingExporter = exporter + o.TracingEndpoint = endpoint + o.TracingCollector = collector } } diff --git a/pkg/micro/ocdav/service.go b/pkg/micro/ocdav/service.go index 5ad140c5dd..bbb563cc4b 100644 --- a/pkg/micro/ocdav/service.go +++ b/pkg/micro/ocdav/service.go @@ -68,7 +68,7 @@ func Service(opts ...Option) (micro.Service, error) { server.Version(sopts.config.VersionString), ) - tp := rtrace.GetTracerProvider(sopts.TracingEnabled, sopts.TracingCollector, sopts.TracingEndpoint, sopts.Name) + tp := rtrace.GetTracerProvider(sopts.TracingEnabled, sopts.TracingExporter, sopts.TracingCollector, sopts.TracingEndpoint, sopts.Name) revaService, err := ocdav.NewWith(&sopts.config, sopts.FavoriteManager, sopts.lockSystem, &sopts.Logger, tp, sopts.GatewayClient) if err != nil { return nil, err diff --git a/pkg/trace/trace.go b/pkg/trace/trace.go index 9aab17679d..3a7ca2dee0 100644 --- a/pkg/trace/trace.go +++ b/pkg/trace/trace.go @@ -26,11 +26,15 @@ import ( "strings" "sync" + "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/exporters/jaeger" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" "go.opentelemetry.io/otel/propagation" "go.opentelemetry.io/otel/sdk/resource" sdktrace "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.4.0" + "go.opentelemetry.io/otel/trace" ) @@ -71,15 +75,30 @@ func ContextGetTracerProvider(ctx context.Context) trace.TracerProvider { } // InitDefaultTracerProvider initializes a global default TracerProvider at a package level. -func InitDefaultTracerProvider(collectorEndpoint string, agentEndpoint string) { +func InitDefaultTracerProvider(exporter, collector, endpoint string) { defaultProvider.mutex.Lock() defer defaultProvider.mutex.Unlock() if !defaultProvider.initialized { - defaultProvider.provider = GetTracerProvider(true, collectorEndpoint, agentEndpoint, "reva default provider") + switch exporter { + case "otlp": + defaultProvider.provider = getOtlpTracerProvider(true, endpoint, "reva default otlp provider") + default: + defaultProvider.provider = getJaegerTracerProvider(true, collector, endpoint, "reva default jaeger provider") + } } defaultProvider.initialized = true } +// GetTracerProvider returns a new TracerProvider, configure for the specified service +func GetTracerProvider(enabled bool, exporter, collector, endpoint, serviceName string) trace.TracerProvider { + switch exporter { + case "otlp": + return getOtlpTracerProvider(enabled, endpoint, serviceName) + default: + return getJaegerTracerProvider(enabled, collector, endpoint, serviceName) + } +} + // DefaultProvider returns the "global" default TracerProvider func DefaultProvider() trace.TracerProvider { defaultProvider.mutex.RLock() @@ -87,8 +106,8 @@ func DefaultProvider() trace.TracerProvider { return defaultProvider.provider } -// GetTracerProvider returns a new TracerProvider, configure for the specified service -func GetTracerProvider(enabled bool, collectorEndpoint string, agentEndpoint, serviceName string) trace.TracerProvider { +// getJaegerTracerProvider returns a new TracerProvider, configure for the specified service +func getJaegerTracerProvider(enabled bool, collector, endpoint, serviceName string) trace.TracerProvider { if !enabled { return trace.NewNoopTracerProvider() } @@ -101,11 +120,11 @@ func GetTracerProvider(enabled bool, collectorEndpoint string, agentEndpoint, se var exp *jaeger.Exporter var err error - if agentEndpoint != "" { + if endpoint != "" { var agentHost string var agentPort string - agentHost, agentPort, err = parseAgentConfig(agentEndpoint) + agentHost, agentPort, err = parseAgentConfig(endpoint) if err != nil { panic(err) } @@ -121,8 +140,8 @@ func GetTracerProvider(enabled bool, collectorEndpoint string, agentEndpoint, se } } - if collectorEndpoint != "" { - exp, err = jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(collectorEndpoint))) + if collector != "" { + exp, err = jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(collector))) if err != nil { panic(err) } @@ -166,3 +185,48 @@ func parseAgentConfig(ae string) (string, string, error) { } return p[0], p[1], nil } + +// getOtelTracerProvider returns a new TracerProvider, configure for the specified service +func getOtlpTracerProvider(enabled bool, endpoint string, serviceName string) trace.TracerProvider { + if !enabled { + return trace.NewNoopTracerProvider() + } + + // default to 'reva' as service name if not set + if serviceName == "" { + serviceName = "reva" + } + + //secureOption := otlptracegrpc.WithTLSCredentials(credentials.NewClientTLSFromCert(nil, "")) + //if len(insecure) > 0 { + secureOption := otlptracegrpc.WithInsecure() + //} + + exporter, err := otlptrace.New( + context.Background(), + otlptracegrpc.NewClient( + secureOption, + otlptracegrpc.WithEndpoint(endpoint), + ), + ) + + if err != nil { + panic(err) + } + resources, err := resource.New( + context.Background(), + resource.WithAttributes( + attribute.String("service.name", serviceName), + attribute.String("library.language", "go"), + ), + ) + if err != nil { + panic(err) + } + + return sdktrace.NewTracerProvider( + sdktrace.WithSampler(sdktrace.AlwaysSample()), + sdktrace.WithBatcher(exporter), + sdktrace.WithResource(resources), + ) +} From b287a014ba88386b47ea6ee9ee2fdaeac6e6f94a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Fri, 2 Dec 2022 22:36:28 +0000 Subject: [PATCH 2/5] introduce options to reva tracer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jörn Friedrich Dreyer --- cmd/revad/runtime/runtime.go | 19 ++- .../storageprovider/storageprovider.go | 3 +- internal/http/services/owncloud/ocdav/copy.go | 4 +- .../http/services/owncloud/ocdav/delete.go | 7 +- internal/http/services/owncloud/ocdav/get.go | 4 +- internal/http/services/owncloud/ocdav/head.go | 4 +- .../http/services/owncloud/ocdav/locks.go | 6 +- .../http/services/owncloud/ocdav/mkcol.go | 4 +- internal/http/services/owncloud/ocdav/move.go | 4 +- .../http/services/owncloud/ocdav/ocdav.go | 6 +- .../owncloud/ocdav/ocdav_blackbox_test.go | 3 +- .../http/services/owncloud/ocdav/proppatch.go | 4 +- .../services/owncloud/ocdav/publicfile.go | 2 +- internal/http/services/owncloud/ocdav/put.go | 4 +- .../http/services/owncloud/ocdav/trashbin.go | 6 +- internal/http/services/owncloud/ocdav/tus.go | 4 +- .../http/services/owncloud/ocdav/versions.go | 4 +- pkg/micro/ocdav/option.go | 18 ++- pkg/micro/ocdav/service.go | 17 ++- pkg/rgrpc/todo/pool/pool.go | 18 ++- pkg/trace/context.go | 47 +++++++ pkg/trace/options.go | 59 +++++++++ pkg/trace/trace.go | 124 +++++++++--------- 23 files changed, 259 insertions(+), 112 deletions(-) create mode 100644 pkg/trace/context.go create mode 100644 pkg/trace/options.go diff --git a/cmd/revad/runtime/runtime.go b/cmd/revad/runtime/runtime.go index 75ed887764..d161a23b4b 100644 --- a/cmd/revad/runtime/runtime.go +++ b/cmd/revad/runtime/runtime.go @@ -76,6 +76,7 @@ func RunWithOptions(mainConf map[string]interface{}, pidFile string, opts ...Opt type coreConf struct { MaxCPUs string `mapstructure:"max_cpus"` TracingEnabled bool `mapstructure:"tracing_enabled"` + TracingInsecure bool `mapstructure:"tracing_insecure"` TracingExporter string `mapstructure:"tracing_exporter"` TracingEndpoint string `mapstructure:"tracing_endpoint"` TracingCollector string `mapstructure:"tracing_collector"` @@ -150,9 +151,23 @@ func initServers(mainConf map[string]interface{}, log *zerolog.Logger, tp trace. func initTracing(conf *coreConf) trace.TracerProvider { if conf.TracingEnabled { - rtrace.InitDefaultTracerProvider(conf.TracingExporter, conf.TracingCollector, conf.TracingEndpoint) + opts := []rtrace.Option{ + rtrace.WithExporter(conf.TracingExporter), + rtrace.WithEndpoint(conf.TracingEndpoint), + rtrace.WithCollector(conf.TracingCollector), + rtrace.WithServiceName(conf.TracingServiceName), + } + if conf.TracingEnabled { + opts = append(opts, rtrace.WithEnabled()) + } + if conf.TracingInsecure { + opts = append(opts, rtrace.WithInsecure()) + } + tp := rtrace.NewTracerProvider(opts...) + rtrace.SetDefaultTracerProvider(tp) + return tp } - return rtrace.GetTracerProvider(conf.TracingEnabled, conf.TracingExporter, conf.TracingCollector, conf.TracingEndpoint, conf.TracingServiceName) + return rtrace.DefaultProvider() } func initCPUCount(conf *coreConf, log *zerolog.Logger) { diff --git a/internal/grpc/services/storageprovider/storageprovider.go b/internal/grpc/services/storageprovider/storageprovider.go index b3fc565f7f..9748db5cc6 100644 --- a/internal/grpc/services/storageprovider/storageprovider.go +++ b/internal/grpc/services/storageprovider/storageprovider.go @@ -48,7 +48,6 @@ import ( "github.com/cs3org/reva/v2/pkg/storage" "github.com/cs3org/reva/v2/pkg/storage/fs/registry" "github.com/cs3org/reva/v2/pkg/storagespace" - rtrace "github.com/cs3org/reva/v2/pkg/trace" "github.com/cs3org/reva/v2/pkg/utils" "github.com/go-micro/plugins/v4/events/natsjs" "github.com/mitchellh/mapstructure" @@ -722,7 +721,7 @@ func (s *service) Move(ctx context.Context, req *provider.MoveRequest) (*provide } func (s *service) Stat(ctx context.Context, req *provider.StatRequest) (*provider.StatResponse, error) { - ctx, span := rtrace.DefaultProvider().Tracer(tracerName).Start(ctx, "stat") + ctx, span := appctx.GetTracerProvider(ctx).Tracer(tracerName).Start(ctx, "stat") defer span.End() span.SetAttributes(attribute.KeyValue{ diff --git a/internal/http/services/owncloud/ocdav/copy.go b/internal/http/services/owncloud/ocdav/copy.go index 4dc25f6bb8..1aa89ac6e4 100644 --- a/internal/http/services/owncloud/ocdav/copy.go +++ b/internal/http/services/owncloud/ocdav/copy.go @@ -52,7 +52,7 @@ type copy struct { } func (s *svc) handlePathCopy(w http.ResponseWriter, r *http.Request, ns string) { - ctx, span := s.tracerProvider.Tracer(tracerName).Start(r.Context(), "copy") + ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(r.Context(), "copy") defer span.End() if r.Body != http.NoBody { @@ -315,7 +315,7 @@ func (s *svc) executePathCopy(ctx context.Context, client gateway.GatewayAPIClie } func (s *svc) handleSpacesCopy(w http.ResponseWriter, r *http.Request, spaceID string) { - ctx, span := s.tracerProvider.Tracer(tracerName).Start(r.Context(), "spaces_copy") + ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(r.Context(), "spaces_copy") defer span.End() if r.Body != http.NoBody { diff --git a/internal/http/services/owncloud/ocdav/delete.go b/internal/http/services/owncloud/ocdav/delete.go index efc4e7f6d7..c091000376 100644 --- a/internal/http/services/owncloud/ocdav/delete.go +++ b/internal/http/services/owncloud/ocdav/delete.go @@ -28,6 +28,7 @@ import ( provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" "github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/net" "github.com/cs3org/reva/v2/internal/http/services/owncloud/ocdav/spacelookup" + "github.com/cs3org/reva/v2/pkg/appctx" "github.com/cs3org/reva/v2/pkg/errtypes" rstatus "github.com/cs3org/reva/v2/pkg/rgrpc/status" "github.com/cs3org/reva/v2/pkg/utils" @@ -35,7 +36,7 @@ import ( func (s *svc) handlePathDelete(w http.ResponseWriter, r *http.Request, ns string) (status int, err error) { ctx := r.Context() - ctx, span := s.tracerProvider.Tracer(tracerName).Start(ctx, "path_delete") + ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(ctx, "path_delete") defer span.End() if r.Body != http.NoBody { @@ -57,7 +58,7 @@ func (s *svc) handlePathDelete(w http.ResponseWriter, r *http.Request, ns string } func (s *svc) handleDelete(ctx context.Context, w http.ResponseWriter, r *http.Request, ref *provider.Reference) (status int, err error) { - ctx, span := s.tracerProvider.Tracer(tracerName).Start(ctx, "delete") + ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(ctx, "delete") defer span.End() req := &provider.DeleteRequest{Ref: ref} @@ -114,7 +115,7 @@ func (s *svc) handleDelete(ctx context.Context, w http.ResponseWriter, r *http.R func (s *svc) handleSpacesDelete(w http.ResponseWriter, r *http.Request, spaceID string) (status int, err error) { ctx := r.Context() - ctx, span := s.tracerProvider.Tracer(tracerName).Start(ctx, "spaces_delete") + ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(ctx, "spaces_delete") defer span.End() if r.Body != http.NoBody { diff --git a/internal/http/services/owncloud/ocdav/get.go b/internal/http/services/owncloud/ocdav/get.go index 1be7021851..21b10ff7a7 100644 --- a/internal/http/services/owncloud/ocdav/get.go +++ b/internal/http/services/owncloud/ocdav/get.go @@ -38,7 +38,7 @@ import ( ) func (s *svc) handlePathGet(w http.ResponseWriter, r *http.Request, ns string) { - ctx, span := s.tracerProvider.Tracer(tracerName).Start(r.Context(), "get") + ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(r.Context(), "get") defer span.End() fn := path.Join(ns, r.URL.Path) @@ -159,7 +159,7 @@ func copyHeader(dst, src http.Header) { } func (s *svc) handleSpacesGet(w http.ResponseWriter, r *http.Request, spaceID string) { - ctx, span := s.tracerProvider.Tracer(tracerName).Start(r.Context(), "spaces_get") + ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(r.Context(), "spaces_get") defer span.End() sublog := appctx.GetLogger(ctx).With().Str("path", r.URL.Path).Str("spaceid", spaceID).Str("handler", "get").Logger() diff --git a/internal/http/services/owncloud/ocdav/head.go b/internal/http/services/owncloud/ocdav/head.go index 607a83d8e2..702193b392 100644 --- a/internal/http/services/owncloud/ocdav/head.go +++ b/internal/http/services/owncloud/ocdav/head.go @@ -41,7 +41,7 @@ import ( ) func (s *svc) handlePathHead(w http.ResponseWriter, r *http.Request, ns string) { - ctx, span := s.tracerProvider.Tracer(tracerName).Start(r.Context(), "head") + ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(r.Context(), "head") defer span.End() fn := path.Join(ns, r.URL.Path) @@ -100,7 +100,7 @@ func (s *svc) handleHead(ctx context.Context, w http.ResponseWriter, r *http.Req } func (s *svc) handleSpacesHead(w http.ResponseWriter, r *http.Request, spaceID string) { - ctx, span := s.tracerProvider.Tracer(tracerName).Start(r.Context(), "spaces_head") + ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(r.Context(), "spaces_head") defer span.End() sublog := appctx.GetLogger(ctx).With().Str("spaceid", spaceID).Str("path", r.URL.Path).Logger() diff --git a/internal/http/services/owncloud/ocdav/locks.go b/internal/http/services/owncloud/ocdav/locks.go index 02ddafe9f2..d822b10556 100644 --- a/internal/http/services/owncloud/ocdav/locks.go +++ b/internal/http/services/owncloud/ocdav/locks.go @@ -380,7 +380,7 @@ The LockManager also defaults to exclusive locks: } */ func (s *svc) handleLock(w http.ResponseWriter, r *http.Request, ns string) (retStatus int, retErr error) { - ctx, span := s.tracerProvider.Tracer(tracerName).Start(r.Context(), fmt.Sprintf("%s %v", r.Method, r.URL.Path)) + ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(r.Context(), fmt.Sprintf("%s %v", r.Method, r.URL.Path)) defer span.End() span.SetAttributes(attribute.String("component", "ocdav")) @@ -400,7 +400,7 @@ func (s *svc) handleLock(w http.ResponseWriter, r *http.Request, ns string) (ret } func (s *svc) handleSpacesLock(w http.ResponseWriter, r *http.Request, spaceID string) (retStatus int, retErr error) { - ctx, span := s.tracerProvider.Tracer(tracerName).Start(r.Context(), fmt.Sprintf("%s %v", r.Method, r.URL.Path)) + ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(r.Context(), fmt.Sprintf("%s %v", r.Method, r.URL.Path)) defer span.End() span.SetAttributes(attribute.String("component", "ocdav")) @@ -558,7 +558,7 @@ func writeLockInfo(w io.Writer, token string, ld LockDetails) (int, error) { } func (s *svc) handleUnlock(w http.ResponseWriter, r *http.Request, ns string) (status int, err error) { - ctx, span := s.tracerProvider.Tracer(tracerName).Start(r.Context(), fmt.Sprintf("%s %v", r.Method, r.URL.Path)) + ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(r.Context(), fmt.Sprintf("%s %v", r.Method, r.URL.Path)) defer span.End() span.SetAttributes(attribute.String("component", "ocdav")) diff --git a/internal/http/services/owncloud/ocdav/mkcol.go b/internal/http/services/owncloud/ocdav/mkcol.go index 9861fc672e..0636052b0e 100644 --- a/internal/http/services/owncloud/ocdav/mkcol.go +++ b/internal/http/services/owncloud/ocdav/mkcol.go @@ -36,7 +36,7 @@ import ( ) func (s *svc) handlePathMkcol(w http.ResponseWriter, r *http.Request, ns string) (status int, err error) { - ctx, span := s.tracerProvider.Tracer(tracerName).Start(r.Context(), "mkcol") + ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(r.Context(), "mkcol") defer span.End() fn := path.Join(ns, r.URL.Path) @@ -87,7 +87,7 @@ func (s *svc) handlePathMkcol(w http.ResponseWriter, r *http.Request, ns string) } func (s *svc) handleSpacesMkCol(w http.ResponseWriter, r *http.Request, spaceID string) (status int, err error) { - ctx, span := s.tracerProvider.Tracer(tracerName).Start(r.Context(), "spaces_mkcol") + ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(r.Context(), "spaces_mkcol") defer span.End() sublog := appctx.GetLogger(ctx).With().Str("path", r.URL.Path).Str("spaceid", spaceID).Str("handler", "mkcol").Logger() diff --git a/internal/http/services/owncloud/ocdav/move.go b/internal/http/services/owncloud/ocdav/move.go index 34d20b8547..793eaa9d8d 100644 --- a/internal/http/services/owncloud/ocdav/move.go +++ b/internal/http/services/owncloud/ocdav/move.go @@ -39,7 +39,7 @@ import ( ) func (s *svc) handlePathMove(w http.ResponseWriter, r *http.Request, ns string) { - ctx, span := s.tracerProvider.Tracer(tracerName).Start(r.Context(), "move") + ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(r.Context(), "move") defer span.End() if r.Body != http.NoBody { @@ -103,7 +103,7 @@ func (s *svc) handlePathMove(w http.ResponseWriter, r *http.Request, ns string) } func (s *svc) handleSpacesMove(w http.ResponseWriter, r *http.Request, srcSpaceID string) { - ctx, span := s.tracerProvider.Tracer(tracerName).Start(r.Context(), "spaces_move") + ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(r.Context(), "spaces_move") defer span.End() if r.Body != http.NoBody { diff --git a/internal/http/services/owncloud/ocdav/ocdav.go b/internal/http/services/owncloud/ocdav/ocdav.go index 998cd56187..bd6aff1f4d 100644 --- a/internal/http/services/owncloud/ocdav/ocdav.go +++ b/internal/http/services/owncloud/ocdav/ocdav.go @@ -41,7 +41,6 @@ import ( "github.com/cs3org/reva/v2/pkg/storage/favorite" "github.com/cs3org/reva/v2/pkg/storage/favorite/registry" "github.com/cs3org/reva/v2/pkg/storage/utils/templates" - rtrace "github.com/cs3org/reva/v2/pkg/trace" "github.com/cs3org/reva/v2/pkg/utils" "github.com/jellydator/ttlcache/v2" "github.com/mitchellh/mapstructure" @@ -191,11 +190,11 @@ func New(m map[string]interface{}, log *zerolog.Logger) (global.Service, error) return nil, err } - return NewWith(conf, fm, ls, log, rtrace.DefaultProvider(), nil) + return NewWith(conf, fm, ls, log, nil) } // NewWith returns a new ocdav service -func NewWith(conf *Config, fm favorite.Manager, ls LockSystem, _ *zerolog.Logger, tp trace.TracerProvider, gwc gateway.GatewayAPIClient) (global.Service, error) { +func NewWith(conf *Config, fm favorite.Manager, ls LockSystem, _ *zerolog.Logger, gwc gateway.GatewayAPIClient) (global.Service, error) { // be safe - init the conf again conf.init() @@ -211,7 +210,6 @@ func NewWith(conf *Config, fm favorite.Manager, ls LockSystem, _ *zerolog.Logger favoritesManager: fm, LockSystem: ls, userIdentifierCache: ttlcache.NewCache(), - tracerProvider: tp, nameValidators: ValidatorsFromConfig(conf), } _ = s.userIdentifierCache.SetTTL(60 * time.Second) diff --git a/internal/http/services/owncloud/ocdav/ocdav_blackbox_test.go b/internal/http/services/owncloud/ocdav/ocdav_blackbox_test.go index a06d0e1602..c1929fbc77 100644 --- a/internal/http/services/owncloud/ocdav/ocdav_blackbox_test.go +++ b/internal/http/services/owncloud/ocdav/ocdav_blackbox_test.go @@ -40,7 +40,6 @@ import ( "github.com/cs3org/reva/v2/pkg/utils" "github.com/cs3org/reva/v2/tests/cs3mocks/mocks" "github.com/stretchr/testify/mock" - "go.opentelemetry.io/otel/trace" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -145,7 +144,7 @@ var _ = Describe("ocdav", func() { InvalidChars: []string{"\f", "\r", "\n", "\\"}, }, } - handler, err = ocdav.NewWith(cfg, nil, ocdav.NewCS3LS(client), nil, trace.NewNoopTracerProvider(), client) + handler, err = ocdav.NewWith(cfg, nil, ocdav.NewCS3LS(client), nil, client) Expect(err).ToNot(HaveOccurred()) userspace = &cs3storageprovider.StorageSpace{ diff --git a/internal/http/services/owncloud/ocdav/proppatch.go b/internal/http/services/owncloud/ocdav/proppatch.go index bfc5e16cd1..9358e6b8cd 100644 --- a/internal/http/services/owncloud/ocdav/proppatch.go +++ b/internal/http/services/owncloud/ocdav/proppatch.go @@ -43,7 +43,7 @@ import ( ) func (s *svc) handlePathProppatch(w http.ResponseWriter, r *http.Request, ns string) (status int, err error) { - ctx, span := s.tracerProvider.Tracer(tracerName).Start(r.Context(), "proppatch") + ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(r.Context(), "proppatch") defer span.End() fn := path.Join(ns, r.URL.Path) @@ -93,7 +93,7 @@ func (s *svc) handlePathProppatch(w http.ResponseWriter, r *http.Request, ns str } func (s *svc) handleSpacesProppatch(w http.ResponseWriter, r *http.Request, spaceID string) (status int, err error) { - ctx, span := s.tracerProvider.Tracer(tracerName).Start(r.Context(), "spaces_proppatch") + ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(r.Context(), "spaces_proppatch") defer span.End() sublog := appctx.GetLogger(ctx).With().Str("path", r.URL.Path).Str("spaceid", spaceID).Logger() diff --git a/internal/http/services/owncloud/ocdav/publicfile.go b/internal/http/services/owncloud/ocdav/publicfile.go index 44e28a2779..7b918268cd 100644 --- a/internal/http/services/owncloud/ocdav/publicfile.go +++ b/internal/http/services/owncloud/ocdav/publicfile.go @@ -89,7 +89,7 @@ func (h *PublicFileHandler) Handler(s *svc) http.Handler { // ns is the namespace that is prefixed to the path in the cs3 namespace func (s *svc) handlePropfindOnToken(w http.ResponseWriter, r *http.Request, ns string, onContainer bool) { - ctx, span := s.tracerProvider.Tracer(tracerName).Start(r.Context(), "token_propfind") + ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(r.Context(), "token_propfind") defer span.End() tokenStatInfo := ctx.Value(tokenStatInfoKey{}).(*provider.ResourceInfo) diff --git a/internal/http/services/owncloud/ocdav/put.go b/internal/http/services/owncloud/ocdav/put.go index 36b151de25..f90b0d7b3e 100644 --- a/internal/http/services/owncloud/ocdav/put.go +++ b/internal/http/services/owncloud/ocdav/put.go @@ -108,7 +108,7 @@ func isContentRange(r *http.Request) bool { } func (s *svc) handlePathPut(w http.ResponseWriter, r *http.Request, ns string) { - ctx, span := s.tracerProvider.Tracer(tracerName).Start(r.Context(), "put") + ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(r.Context(), "put") defer span.End() fn := path.Join(ns, r.URL.Path) @@ -357,7 +357,7 @@ func (s *svc) handlePut(ctx context.Context, w http.ResponseWriter, r *http.Requ } func (s *svc) handleSpacesPut(w http.ResponseWriter, r *http.Request, spaceID string) { - ctx, span := s.tracerProvider.Tracer(tracerName).Start(r.Context(), "spaces_put") + ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(r.Context(), "spaces_put") defer span.End() sublog := appctx.GetLogger(ctx).With().Str("spaceid", spaceID).Str("path", r.URL.Path).Logger() diff --git a/internal/http/services/owncloud/ocdav/trashbin.go b/internal/http/services/owncloud/ocdav/trashbin.go index 763a229f7c..3944546a03 100644 --- a/internal/http/services/owncloud/ocdav/trashbin.go +++ b/internal/http/services/owncloud/ocdav/trashbin.go @@ -177,7 +177,7 @@ func (h *TrashbinHandler) Handler(s *svc) http.Handler { } func (h *TrashbinHandler) listTrashbin(w http.ResponseWriter, r *http.Request, s *svc, ref *provider.Reference, refBase, key, itemPath string) { - ctx, span := s.tracerProvider.Tracer(tracerName).Start(r.Context(), "list_trashbin") + ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(r.Context(), "list_trashbin") defer span.End() sublog := appctx.GetLogger(ctx).With().Logger() @@ -452,7 +452,7 @@ func (h *TrashbinHandler) itemToPropResponse(ctx context.Context, s *svc, spaceI } func (h *TrashbinHandler) restore(w http.ResponseWriter, r *http.Request, s *svc, ref, dst *provider.Reference, key, itemPath string) { - ctx, span := s.tracerProvider.Tracer(tracerName).Start(r.Context(), "restore") + ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(r.Context(), "restore") defer span.End() sublog := appctx.GetLogger(ctx).With().Logger() @@ -573,7 +573,7 @@ func (h *TrashbinHandler) restore(w http.ResponseWriter, r *http.Request, s *svc // delete has only a key func (h *TrashbinHandler) delete(w http.ResponseWriter, r *http.Request, s *svc, ref *provider.Reference, key, itemPath string) { - ctx, span := s.tracerProvider.Tracer(tracerName).Start(r.Context(), "erase") + ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(r.Context(), "erase") defer span.End() sublog := appctx.GetLogger(ctx).With().Interface("reference", ref).Str("key", key).Str("item_path", itemPath).Logger() diff --git a/internal/http/services/owncloud/ocdav/tus.go b/internal/http/services/owncloud/ocdav/tus.go index 780cb6b0d7..7e9148d068 100644 --- a/internal/http/services/owncloud/ocdav/tus.go +++ b/internal/http/services/owncloud/ocdav/tus.go @@ -45,7 +45,7 @@ import ( ) func (s *svc) handlePathTusPost(w http.ResponseWriter, r *http.Request, ns string) { - ctx, span := s.tracerProvider.Tracer(tracerName).Start(r.Context(), "tus-post") + ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(r.Context(), "tus-post") defer span.End() // read filename from metadata @@ -69,7 +69,7 @@ func (s *svc) handlePathTusPost(w http.ResponseWriter, r *http.Request, ns strin } func (s *svc) handleSpacesTusPost(w http.ResponseWriter, r *http.Request, spaceID string) { - ctx, span := s.tracerProvider.Tracer(tracerName).Start(r.Context(), "spaces-tus-post") + ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(r.Context(), "spaces-tus-post") defer span.End() // read filename from metadata diff --git a/internal/http/services/owncloud/ocdav/versions.go b/internal/http/services/owncloud/ocdav/versions.go index 0eec232c07..36831f0cf2 100644 --- a/internal/http/services/owncloud/ocdav/versions.go +++ b/internal/http/services/owncloud/ocdav/versions.go @@ -110,7 +110,7 @@ func (h *VersionsHandler) Handler(s *svc, rid *provider.ResourceId) http.Handler } func (h *VersionsHandler) doListVersions(w http.ResponseWriter, r *http.Request, s *svc, rid *provider.ResourceId) { - ctx, span := s.tracerProvider.Tracer(tracerName).Start(r.Context(), "listVersions") + ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(r.Context(), "listVersions") defer span.End() sublog := appctx.GetLogger(ctx).With().Interface("resourceid", rid).Logger() @@ -215,7 +215,7 @@ func (h *VersionsHandler) doListVersions(w http.ResponseWriter, r *http.Request, } func (h *VersionsHandler) doRestore(w http.ResponseWriter, r *http.Request, s *svc, rid *provider.ResourceId, key string) { - ctx, span := s.tracerProvider.Tracer(tracerName).Start(r.Context(), "restore") + ctx, span := appctx.GetTracerProvider(r.Context()).Tracer(tracerName).Start(r.Context(), "restore") defer span.End() sublog := appctx.GetLogger(ctx).With().Interface("resourceid", rid).Str("key", key).Logger() diff --git a/pkg/micro/ocdav/option.go b/pkg/micro/ocdav/option.go index 679f931fcb..762cbb8e91 100644 --- a/pkg/micro/ocdav/option.go +++ b/pkg/micro/ocdav/option.go @@ -48,6 +48,7 @@ type Options struct { GatewayClient gateway.GatewayAPIClient TracingEnabled bool + TracingInsecure bool TracingExporter string TracingCollector string TracingEndpoint string @@ -210,15 +211,28 @@ func LockSystem(val ocdav.LockSystem) Option { } // Tracing enables tracing -func Tracing(exporter, endpoint, collector string) Option { +func Tracing(endpoint, collector string) Option { return func(o *Options) { o.TracingEnabled = true - o.TracingExporter = exporter o.TracingEndpoint = endpoint o.TracingCollector = collector } } +// WithTracingInsecure option +func WithTracingInsecure() Option { + return func(o *Options) { + o.TracingInsecure = true + } +} + +// WithTracingExporter option +func WithTracingExporter(exporter string) Option { + return func(o *Options) { + o.TracingExporter = exporter + } +} + // Version provides a function to set the Version config option. func Version(val string) Option { return func(o *Options) { diff --git a/pkg/micro/ocdav/service.go b/pkg/micro/ocdav/service.go index bbb563cc4b..5e384e3a6f 100644 --- a/pkg/micro/ocdav/service.go +++ b/pkg/micro/ocdav/service.go @@ -68,8 +68,7 @@ func Service(opts ...Option) (micro.Service, error) { server.Version(sopts.config.VersionString), ) - tp := rtrace.GetTracerProvider(sopts.TracingEnabled, sopts.TracingExporter, sopts.TracingCollector, sopts.TracingEndpoint, sopts.Name) - revaService, err := ocdav.NewWith(&sopts.config, sopts.FavoriteManager, sopts.lockSystem, &sopts.Logger, tp, sopts.GatewayClient) + revaService, err := ocdav.NewWith(&sopts.config, sopts.FavoriteManager, sopts.lockSystem, &sopts.Logger, sopts.GatewayClient) if err != nil { return nil, err } @@ -86,7 +85,19 @@ func Service(opts ...Option) (micro.Service, error) { // chi.RegisterMethod(ocdav.MethodMkcol) // chi.RegisterMethod(ocdav.MethodReport) r := chi.NewRouter() - + topts := []rtrace.Option{ + rtrace.WithExporter(sopts.TracingExporter), + rtrace.WithEndpoint(sopts.TracingEndpoint), + rtrace.WithCollector(sopts.TracingCollector), + rtrace.WithServiceName(sopts.Name), + } + if sopts.TracingEnabled { + topts = append(topts, rtrace.WithEnabled()) + } + if sopts.TracingInsecure { + topts = append(topts, rtrace.WithInsecure()) + } + tp := rtrace.NewTracerProvider(topts...) if err := useMiddlewares(r, &sopts, revaService, tp); err != nil { return nil, err } diff --git a/pkg/rgrpc/todo/pool/pool.go b/pkg/rgrpc/todo/pool/pool.go index d065953b05..cd506bf9d6 100644 --- a/pkg/rgrpc/todo/pool/pool.go +++ b/pkg/rgrpc/todo/pool/pool.go @@ -45,6 +45,7 @@ import ( "github.com/cs3org/reva/v2/pkg/sharedconf" rtrace "github.com/cs3org/reva/v2/pkg/trace" "go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc" + "go.opentelemetry.io/otel/trace" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/insecure" @@ -77,8 +78,9 @@ const ( // ClientOptions represent additional options (e.g. tls settings) for the grpc clients type ClientOptions struct { - tlsMode TLSMode - caCert string + tlsMode TLSMode + caCert string + tracerProvider trace.TracerProvider } // Option is used to pass client options @@ -132,6 +134,7 @@ func (o *ClientOptions) init() error { return err } o.caCert = sharedOpt.CACertFile + o.tracerProvider = rtrace.DefaultProvider() return nil } @@ -149,6 +152,13 @@ func WithTLSCACert(v string) Option { } } +// WithTracerProvider allows to set the opentelemetry tracer provider for grpc clients +func WithTracerProvider(v trace.TracerProvider) Option { + return func(o *ClientOptions) { + o.tracerProvider = v + } +} + // NewConn creates a new connection to a grpc server // with open census tracing support. // TODO(labkode): make grpc tls configurable. @@ -194,7 +204,7 @@ func NewConn(endpoint string, opts ...Option) (*grpc.ClientConn, error) { ), grpc.WithStreamInterceptor(otelgrpc.StreamClientInterceptor( otelgrpc.WithTracerProvider( - rtrace.DefaultProvider(), + options.tracerProvider, ), otelgrpc.WithPropagators( rtrace.Propagator, @@ -203,7 +213,7 @@ func NewConn(endpoint string, opts ...Option) (*grpc.ClientConn, error) { grpc.WithUnaryInterceptor( otelgrpc.UnaryClientInterceptor( otelgrpc.WithTracerProvider( - rtrace.DefaultProvider(), + options.tracerProvider, ), otelgrpc.WithPropagators( rtrace.Propagator, diff --git a/pkg/trace/context.go b/pkg/trace/context.go new file mode 100644 index 0000000000..c1dcaba132 --- /dev/null +++ b/pkg/trace/context.go @@ -0,0 +1,47 @@ +// Copyright 2018-2021 CERN +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// In applying this license, CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +package trace + +import ( + "context" + + "go.opentelemetry.io/otel/trace" +) + +type ctxKey struct{} + +// ContextSetTracerProvider returns a copy of ctx with p associated. +func ContextSetTracerProvider(ctx context.Context, p trace.TracerProvider) context.Context { + if tp, ok := ctx.Value(ctxKey{}).(trace.TracerProvider); ok { + if tp == p { + return ctx + } + } + return context.WithValue(ctx, ctxKey{}, p) +} + +// ContextGetTracerProvider returns the TracerProvider associated with the ctx. +// If no TracerProvider is associated is associated, the global default TracerProvider +// is returned +func ContextGetTracerProvider(ctx context.Context) trace.TracerProvider { + if p, ok := ctx.Value(ctxKey{}).(trace.TracerProvider); ok { + return p + } + return trace.NewNoopTracerProvider() +} diff --git a/pkg/trace/options.go b/pkg/trace/options.go new file mode 100644 index 0000000000..7d0646f0f8 --- /dev/null +++ b/pkg/trace/options.go @@ -0,0 +1,59 @@ +package trace + +import "google.golang.org/grpc/credentials" + +// Options for trace +type Options struct { + Enabled bool + Insecure bool + Exporter string + Collector string + Endpoint string + ServiceName string + TransportCredentials credentials.TransportCredentials +} + +// Option for trace +type Option func(o *Options) + +// WithEnabled option +func WithEnabled() Option { + return func(o *Options) { + o.Enabled = true + } +} + +// WithExporter option +func WithExporter(v string) Option { + return func(o *Options) { + o.Exporter = v + } +} + +// WithInsecure option +func WithInsecure() Option { + return func(o *Options) { + o.Insecure = true + } +} + +// WithCollector option +func WithCollector(v string) Option { + return func(o *Options) { + o.Collector = v + } +} + +// WithEndpoint option +func WithEndpoint(v string) Option { + return func(o *Options) { + o.Endpoint = v + } +} + +// WithServiceName option +func WithServiceName(v string) Option { + return func(o *Options) { + o.ServiceName = v + } +} diff --git a/pkg/trace/trace.go b/pkg/trace/trace.go index 3a7ca2dee0..d78fdcc10a 100644 --- a/pkg/trace/trace.go +++ b/pkg/trace/trace.go @@ -34,6 +34,7 @@ import ( "go.opentelemetry.io/otel/sdk/resource" sdktrace "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.4.0" + "google.golang.org/grpc/credentials" "go.opentelemetry.io/otel/trace" ) @@ -52,54 +53,62 @@ type revaDefaultTracerProvider struct { provider trace.TracerProvider } -type ctxKey struct{} +// NewTracerProvider returns a new TracerProvider, configure for the specified service +func NewTracerProvider(opts ...Option) trace.TracerProvider { + options := Options{} -// ContextSetTracerProvider returns a copy of ctx with p associated. -func ContextSetTracerProvider(ctx context.Context, p trace.TracerProvider) context.Context { - if tp, ok := ctx.Value(ctxKey{}).(trace.TracerProvider); ok { - if tp == p { - return ctx - } + for _, o := range opts { + o(&options) + } + + if options.TransportCredentials == nil { + options.TransportCredentials = credentials.NewClientTLSFromCert(nil, "") + } + + if !options.Enabled { + return trace.NewNoopTracerProvider() + } + + // default to 'reva' as service name if not set + if options.ServiceName == "" { + options.ServiceName = "reva" } - return context.WithValue(ctx, ctxKey{}, p) -} -// ContextGetTracerProvider returns the TracerProvider associated with the ctx. -// If no TracerProvider is associated is associated, the global default TracerProvider -// is returned -func ContextGetTracerProvider(ctx context.Context) trace.TracerProvider { - if p, ok := ctx.Value(ctxKey{}).(trace.TracerProvider); ok { - return p + switch options.Exporter { + case "otlp": + return getOtlpTracerProvider(options) + default: + return getJaegerTracerProvider(options) } - return DefaultProvider() } -// InitDefaultTracerProvider initializes a global default TracerProvider at a package level. -func InitDefaultTracerProvider(exporter, collector, endpoint string) { +// SetDefaultTracerProvider sets the default trace provider +func SetDefaultTracerProvider(tp trace.TracerProvider) { defaultProvider.mutex.Lock() defer defaultProvider.mutex.Unlock() - if !defaultProvider.initialized { - switch exporter { - case "otlp": - defaultProvider.provider = getOtlpTracerProvider(true, endpoint, "reva default otlp provider") - default: - defaultProvider.provider = getJaegerTracerProvider(true, collector, endpoint, "reva default jaeger provider") - } - } + defaultProvider.provider = tp defaultProvider.initialized = true } -// GetTracerProvider returns a new TracerProvider, configure for the specified service -func GetTracerProvider(enabled bool, exporter, collector, endpoint, serviceName string) trace.TracerProvider { - switch exporter { - case "otlp": - return getOtlpTracerProvider(enabled, endpoint, serviceName) - default: - return getJaegerTracerProvider(enabled, collector, endpoint, serviceName) +// InitDefaultTracerProvider initializes a global default jaeger TracerProvider at a package level. +// +// Deprecated: Use NewTracerProvider and SetDefaultTracerProvider to properly initialize a tracer provider with options +func InitDefaultTracerProvider(collector, endpoint string) { + defaultProvider.mutex.Lock() + defer defaultProvider.mutex.Unlock() + if !defaultProvider.initialized { + defaultProvider.provider = getJaegerTracerProvider(Options{ + Enabled: true, + Collector: collector, + Endpoint: endpoint, + ServiceName: "reva default jaeger provider", + }) } + defaultProvider.initialized = true } // DefaultProvider returns the "global" default TracerProvider +// Currently used by the pool to get the global tracer func DefaultProvider() trace.TracerProvider { defaultProvider.mutex.RLock() defer defaultProvider.mutex.RUnlock() @@ -107,24 +116,15 @@ func DefaultProvider() trace.TracerProvider { } // getJaegerTracerProvider returns a new TracerProvider, configure for the specified service -func getJaegerTracerProvider(enabled bool, collector, endpoint, serviceName string) trace.TracerProvider { - if !enabled { - return trace.NewNoopTracerProvider() - } - - // default to 'reva' as service name if not set - if serviceName == "" { - serviceName = "reva" - } - +func getJaegerTracerProvider(options Options) trace.TracerProvider { var exp *jaeger.Exporter var err error - if endpoint != "" { + if options.Endpoint != "" { var agentHost string var agentPort string - agentHost, agentPort, err = parseAgentConfig(endpoint) + agentHost, agentPort, err = parseAgentConfig(options.Endpoint) if err != nil { panic(err) } @@ -140,8 +140,8 @@ func getJaegerTracerProvider(enabled bool, collector, endpoint, serviceName stri } } - if collector != "" { - exp, err = jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(collector))) + if options.Collector != "" { + exp, err = jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(options.Collector))) if err != nil { panic(err) } @@ -156,7 +156,7 @@ func getJaegerTracerProvider(enabled bool, collector, endpoint, serviceName stri sdktrace.WithBatcher(exp), sdktrace.WithResource(resource.NewWithAttributes( semconv.SchemaURL, - semconv.ServiceNameKey.String(serviceName), + semconv.ServiceNameKey.String(options.ServiceName), semconv.HostNameKey.String(hostname), )), ) @@ -187,27 +187,21 @@ func parseAgentConfig(ae string) (string, string, error) { } // getOtelTracerProvider returns a new TracerProvider, configure for the specified service -func getOtlpTracerProvider(enabled bool, endpoint string, serviceName string) trace.TracerProvider { - if !enabled { - return trace.NewNoopTracerProvider() - } +func getOtlpTracerProvider(options Options) trace.TracerProvider { - // default to 'reva' as service name if not set - if serviceName == "" { - serviceName = "reva" + opts := []otlptracegrpc.Option{ + otlptracegrpc.WithEndpoint(options.Endpoint), + } + if options.TransportCredentials != nil { + opts = append(opts, otlptracegrpc.WithTLSCredentials(options.TransportCredentials)) + } + if options.Insecure { + opts = append(opts, otlptracegrpc.WithInsecure()) } - - //secureOption := otlptracegrpc.WithTLSCredentials(credentials.NewClientTLSFromCert(nil, "")) - //if len(insecure) > 0 { - secureOption := otlptracegrpc.WithInsecure() - //} exporter, err := otlptrace.New( context.Background(), - otlptracegrpc.NewClient( - secureOption, - otlptracegrpc.WithEndpoint(endpoint), - ), + otlptracegrpc.NewClient(opts...), ) if err != nil { @@ -216,7 +210,7 @@ func getOtlpTracerProvider(enabled bool, endpoint string, serviceName string) tr resources, err := resource.New( context.Background(), resource.WithAttributes( - attribute.String("service.name", serviceName), + attribute.String("service.name", options.ServiceName), attribute.String("library.language", "go"), ), ) From ad01e123068a9aa3bf4d371bbb50403173b082be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Fri, 19 May 2023 11:28:38 +0200 Subject: [PATCH 3/5] for now use insecure connection to send traces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jörn Friedrich Dreyer --- pkg/trace/trace.go | 46 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/pkg/trace/trace.go b/pkg/trace/trace.go index d78fdcc10a..40a69d4a55 100644 --- a/pkg/trace/trace.go +++ b/pkg/trace/trace.go @@ -25,16 +25,18 @@ import ( "os" "strings" "sync" + "time" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/exporters/jaeger" - "go.opentelemetry.io/otel/exporters/otlp/otlptrace" "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" "go.opentelemetry.io/otel/propagation" "go.opentelemetry.io/otel/sdk/resource" sdktrace "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.4.0" + "google.golang.org/grpc" "google.golang.org/grpc/credentials" + "google.golang.org/grpc/credentials/insecure" "go.opentelemetry.io/otel/trace" ) @@ -189,24 +191,44 @@ func parseAgentConfig(ae string) (string, string, error) { // getOtelTracerProvider returns a new TracerProvider, configure for the specified service func getOtlpTracerProvider(options Options) trace.TracerProvider { - opts := []otlptracegrpc.Option{ - otlptracegrpc.WithEndpoint(options.Endpoint), - } - if options.TransportCredentials != nil { - opts = append(opts, otlptracegrpc.WithTLSCredentials(options.TransportCredentials)) - } - if options.Insecure { - opts = append(opts, otlptracegrpc.WithInsecure()) + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + conn, err := grpc.DialContext(ctx, options.Endpoint, + // Note the use of insecure transport here. TLS is recommended in production. + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithBlock(), + ) + if err != nil { + panic(fmt.Errorf("failed to create gRPC connection to collector: %w", err)) } - - exporter, err := otlptrace.New( + exporter, err := otlptracegrpc.New( context.Background(), - otlptracegrpc.NewClient(opts...), + otlptracegrpc.WithGRPCConn(conn), ) if err != nil { panic(err) } + /* + opts := []otlptracegrpc.Option{ + otlptracegrpc.WithEndpoint(options.Endpoint), + } + if options.TransportCredentials != nil { + opts = append(opts, otlptracegrpc.WithTLSCredentials(options.TransportCredentials)) + } + if options.Insecure { + opts = append(opts, otlptracegrpc.WithInsecure()) + } + + exporter, err := otlptrace.New( + context.Background(), + otlptracegrpc.NewClient(opts...), + ) + + if err != nil { + panic(err) + } + */ resources, err := resource.New( context.Background(), resource.WithAttributes( From a387f6c092d0992a80b25e822cbe610e2d319a58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Duffeck?= Date: Thu, 25 May 2023 14:17:19 +0200 Subject: [PATCH 4/5] Remove commented code --- pkg/trace/trace.go | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/pkg/trace/trace.go b/pkg/trace/trace.go index 40a69d4a55..f8f2355e74 100644 --- a/pkg/trace/trace.go +++ b/pkg/trace/trace.go @@ -209,26 +209,7 @@ func getOtlpTracerProvider(options Options) trace.TracerProvider { if err != nil { panic(err) } - /* - opts := []otlptracegrpc.Option{ - otlptracegrpc.WithEndpoint(options.Endpoint), - } - if options.TransportCredentials != nil { - opts = append(opts, otlptracegrpc.WithTLSCredentials(options.TransportCredentials)) - } - if options.Insecure { - opts = append(opts, otlptracegrpc.WithInsecure()) - } - - exporter, err := otlptrace.New( - context.Background(), - otlptracegrpc.NewClient(opts...), - ) - if err != nil { - panic(err) - } - */ resources, err := resource.New( context.Background(), resource.WithAttributes( From ea243ad51a6f547e80c2c6ab0cd54fd977988140 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Duffeck?= Date: Thu, 25 May 2023 14:34:50 +0200 Subject: [PATCH 5/5] Remove unused field --- internal/http/services/owncloud/ocdav/ocdav.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/internal/http/services/owncloud/ocdav/ocdav.go b/internal/http/services/owncloud/ocdav/ocdav.go index bd6aff1f4d..db25c5d7ae 100644 --- a/internal/http/services/owncloud/ocdav/ocdav.go +++ b/internal/http/services/owncloud/ocdav/ocdav.go @@ -45,7 +45,6 @@ import ( "github.com/jellydator/ttlcache/v2" "github.com/mitchellh/mapstructure" "github.com/rs/zerolog" - "go.opentelemetry.io/otel/trace" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" @@ -149,7 +148,6 @@ type svc struct { // LockSystem is the lock management system. LockSystem LockSystem userIdentifierCache *ttlcache.Cache - tracerProvider trace.TracerProvider nameValidators []Validator }