diff --git a/changelog/unreleased/trace-proxy-middlewares.md b/changelog/unreleased/trace-proxy-middlewares.md new file mode 100644 index 0000000000..ba30e24ced --- /dev/null +++ b/changelog/unreleased/trace-proxy-middlewares.md @@ -0,0 +1,5 @@ +Bugfix: trace proxy middlewares + +We moved trace initialization to an early middleware to also trace requests made by other proxy middlewares. + +https://github.com/owncloud/ocis/pull/6313 diff --git a/go.mod b/go.mod index 715d6a600d..7576498539 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,7 @@ require ( github.com/go-micro/plugins/v4/server/http v1.2.1 github.com/go-micro/plugins/v4/wrapper/breaker/gobreaker v1.2.0 github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus v1.2.0 - github.com/go-micro/plugins/v4/wrapper/trace/opencensus v1.1.0 + github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry v1.2.0 github.com/go-ozzo/ozzo-validation/v4 v4.3.0 github.com/gofrs/uuid v4.4.0+incompatible github.com/golang-jwt/jwt/v4 v4.5.0 @@ -80,12 +80,12 @@ require ( github.com/xhit/go-simple-mail/v2 v2.13.0 go-micro.dev/v4 v4.9.0 go.etcd.io/bbolt v1.3.7 - go.opencensus.io v0.24.0 - go.opentelemetry.io/otel v1.14.0 - go.opentelemetry.io/otel/exporters/jaeger v1.14.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0 - go.opentelemetry.io/otel/sdk v1.14.0 - go.opentelemetry.io/otel/trace v1.14.0 + go.opentelemetry.io/contrib/zpages v0.41.1 + go.opentelemetry.io/otel v1.15.1 + go.opentelemetry.io/otel/exporters/jaeger v1.15.1 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.15.1 + go.opentelemetry.io/otel/sdk v1.15.1 + go.opentelemetry.io/otel/trace v1.15.1 golang.org/x/crypto v0.9.0 golang.org/x/exp v0.0.0-20221026004748-78e5e7837ae6 golang.org/x/image v0.6.0 @@ -146,7 +146,7 @@ require ( github.com/bmizerany/pat v0.0.0-20210406213842-e4b6760bdd6f // indirect github.com/bombsimon/logrusr/v3 v3.1.0 // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect - github.com/cenkalti/backoff/v4 v4.2.0 // indirect + github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/ceph/go-ceph v0.18.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cevaris/ordered_map v0.0.0-20190319150403-3adeae072e73 // indirect @@ -306,9 +306,10 @@ require ( go.etcd.io/etcd/api/v3 v3.5.7 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.7 // indirect go.etcd.io/etcd/client/v3 v3.5.7 // indirect + go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.36.4 // indirect - go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.15.1 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.15.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 diff --git a/go.sum b/go.sum index f424880de9..44b7205dac 100644 --- a/go.sum +++ b/go.sum @@ -568,8 +568,8 @@ github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEe github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.1.0/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= -github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4= -github.com/cenkalti/backoff/v4 v4.2.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -803,8 +803,8 @@ github.com/go-micro/plugins/v4/wrapper/breaker/gobreaker v1.2.0 h1:EQj4l7fuOSz8u github.com/go-micro/plugins/v4/wrapper/breaker/gobreaker v1.2.0/go.mod h1:JR9Ox/iJIrcXm8nCWdAEBsyG7Q7lyMLzsTZPfXrqvwo= github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus v1.2.0 h1:UWBUYtMXCxQ9bIGOYcbLOjtPv8ovvCRjWWM6tHhB4S8= github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus v1.2.0/go.mod h1:8BYxs/wEE4ZJayHZQffw4A8s9rcPumyoNms0hYoNocM= -github.com/go-micro/plugins/v4/wrapper/trace/opencensus v1.1.0 h1:ITm1vEP8BPEccWFAu6/tMFHrxHfwYzE4GdkCy6PlF6A= -github.com/go-micro/plugins/v4/wrapper/trace/opencensus v1.1.0/go.mod h1:4izlDcwSo9tu8v2TcaBgpO3EmNqUkB4oMFSwxvSt438= +github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry v1.2.0 h1:e2hgtWMNqJ3DmbMt9ZxzmH/BkVAw9Xg23l6CHrXQfKw= +github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry v1.2.0/go.mod h1:BBqL7ckGNb7rFfk3vU2Yj/CILVsz/WF19CkAyveQl8A= github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= @@ -1675,20 +1675,22 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.36.4 h1:PRXhsszxTt5bbPriTjmaweWUsAnJYeWBhUMLRetUgBU= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.36.4/go.mod h1:05eWWy6ZWzmpeImD3UowLTB3VjDMU1yxQ+ENuVWDM3c= -go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM= -go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU= -go.opentelemetry.io/otel/exporters/jaeger v1.14.0 h1:CjbUNd4iN2hHmWekmOqZ+zSCU+dzZppG8XsV+A3oc8Q= -go.opentelemetry.io/otel/exporters/jaeger v1.14.0/go.mod h1:4Ay9kk5vELRrbg5z4cpP9EtmQRFap2Wb0woPG4lujZA= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 h1:/fXHZHGvro6MVqV34fJzDhi7sHGpX3Ej/Qjmfn003ho= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0/go.mod h1:UFG7EBMRdXyFstOwH028U0sVf+AvukSGhF0g8+dmNG8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0 h1:TKf2uAs2ueguzLaxOCBXNpHxfO/aC7PAdDsSH0IbeRQ= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0/go.mod h1:HrbCVv40OOLTABmOn1ZWty6CHXkU8DK/Urc43tHug70= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0 h1:ap+y8RXX3Mu9apKVtOkM6WSFESLM8K3wNQyOU8sWHcc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0/go.mod h1:5w41DY6S9gZrbjuq6Y+753e96WfPha5IcsOSZTtullM= -go.opentelemetry.io/otel/sdk v1.14.0 h1:PDCppFRDq8A1jL9v6KMI6dYesaq+DFcDZvjsoGvxGzY= -go.opentelemetry.io/otel/sdk v1.14.0/go.mod h1:bwIC5TjrNG6QDCHNWvW4HLHtUQ4I+VQDsnjhvyZCALM= -go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M= -go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8= +go.opentelemetry.io/contrib/zpages v0.41.1 h1:FReY8OWFNtYm4mWleTRxTUyD3r02uGcwS6ZeElahs00= +go.opentelemetry.io/contrib/zpages v0.41.1/go.mod h1:C3iy146ccMyv1+gEaxVDDHuoT7yXAKKmbg+twudDpeg= +go.opentelemetry.io/otel v1.15.1 h1:3Iwq3lfRByPaws0f6bU3naAqOR1n5IeDWd9390kWHa8= +go.opentelemetry.io/otel v1.15.1/go.mod h1:mHHGEHVDLal6YrKMmk9LqC4a3sF5g+fHfrttQIB1NTc= +go.opentelemetry.io/otel/exporters/jaeger v1.15.1 h1:x3SLvwli0OyAJapNcOIzf1xXBRBA+HD3elrMQmFfmXo= +go.opentelemetry.io/otel/exporters/jaeger v1.15.1/go.mod h1:0Ck9b5oLL/bFZvfAEEqtrb1U0jZXjm5fWXMCOCG3vvM= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.15.1 h1:XYDQtNzdb2T4uM1pku2m76eSMDJgqhJ+6KzkqgQBALc= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.15.1/go.mod h1:uOTV75+LOzV+ODmL8ahRLWkFA3eQcSC2aAsbxIu4duk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.15.1 h1:tyoeaUh8REKay72DVYsSEBYV18+fGONe+YYPaOxgLoE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.15.1/go.mod h1:HUSnrjQQ19KX9ECjpQxufsF+3ioD3zISPMlauTPZu2g= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.15.1 h1:pIfoG5IAZFzp9EUlJzdSkpUwpaUAAnD+Ru1nBLTACIQ= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.15.1/go.mod h1:poNKBqF5+nR/6ke2oGTDjHfksrsHDOHXAl2g4+9ONsY= +go.opentelemetry.io/otel/sdk v1.15.1 h1:5FKR+skgpzvhPQHIEfcwMYjCBr14LWzs3uSqKiQzETI= +go.opentelemetry.io/otel/sdk v1.15.1/go.mod h1:8rVtxQfrbmbHKfqzpQkT5EzZMcbMBwTzNAggbEAM0KA= +go.opentelemetry.io/otel/trace v1.15.1 h1:uXLo6iHJEzDfrNC0L0mNjItIp06SyaBQxu5t3xMlngY= +go.opentelemetry.io/otel/trace v1.15.1/go.mod h1:IWdQG/5N1x7f6YUlmdLeJvH9yxtuJAfc4VW5Agv9r/8= 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= diff --git a/ocis-pkg/service/debug/service.go b/ocis-pkg/service/debug/service.go index a0432b8652..0f806e5748 100644 --- a/ocis-pkg/service/debug/service.go +++ b/ocis-pkg/service/debug/service.go @@ -10,7 +10,7 @@ import ( "github.com/owncloud/ocis/v2/ocis-pkg/middleware" graphMiddleware "github.com/owncloud/ocis/v2/services/graph/pkg/middleware" "github.com/prometheus/client_golang/prometheus/promhttp" - "go.opencensus.io/zpages" + "go.opentelemetry.io/contrib/zpages" ) // NewService initializes a new debug service. @@ -42,7 +42,8 @@ func NewService(opts ...Option) *http.Server { } if dopts.Zpages { - zpages.Handle(mux, "/debug") + h := zpages.NewTracezHandler(zpages.NewSpanProcessor()) + mux.Handle("/debug", h) } return &http.Server{ diff --git a/ocis-pkg/service/grpc/client.go b/ocis-pkg/service/grpc/client.go index 528118237d..d3c4090089 100644 --- a/ocis-pkg/service/grpc/client.go +++ b/ocis-pkg/service/grpc/client.go @@ -9,9 +9,11 @@ import ( mgrpcc "github.com/go-micro/plugins/v4/client/grpc" mbreaker "github.com/go-micro/plugins/v4/wrapper/breaker/gobreaker" + mtracer "github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry" "github.com/owncloud/ocis/v2/ocis-pkg/registry" "github.com/owncloud/ocis/v2/ocis-pkg/shared" "go-micro.dev/v4/client" + "go.opentelemetry.io/otel/trace" ) var ( @@ -23,6 +25,7 @@ var ( type ClientOptions struct { tlsMode string caCert string + tp trace.TracerProvider } // Option is used to pass client options @@ -42,13 +45,19 @@ func WithTLSCACert(v string) ClientOption { } } +// WithTraceProvider allows to set the trace Provider for grpc clients +func WithTraceProvider(tp trace.TracerProvider) ClientOption { + return func(o *ClientOptions) { + o.tp = tp + } +} + // Configure configures the default oOCIS grpc client (e.g. TLS settings) func Configure(opts ...ClientOption) error { var options ClientOptions for _, opt := range opts { opt(&options) } - var outerr error once.Do(func() { reg := registry.GetRegistry() @@ -56,6 +65,9 @@ func Configure(opts ...ClientOption) error { cOpts := []client.Option{ client.Registry(reg), client.Wrap(mbreaker.NewClientWrapper()), + client.Wrap(mtracer.NewClientWrapper( + mtracer.WithTraceProvider(options.tp), + )), } switch options.tlsMode { case "insecure": @@ -74,12 +86,14 @@ func Configure(opts ...ClientOption) error { return } if !certs.AppendCertsFromPEM(pemData) { - outerr = errors.New("Error initializing LDAP Backend. Adding CA cert failed") + outerr = errors.New("could not initialize default client, adding CA cert failed") return } tlsConfig.RootCAs = certs } cOpts = append(cOpts, mgrpcc.AuthTLS(tlsConfig)) + //case "off": + //default: } defaultClient = mgrpcc.NewClient(cOpts...) @@ -99,3 +113,46 @@ func GetClientOptions(t *shared.GRPCClientTLS) []ClientOption { } return opts } + +func NewClient(opts ...ClientOption) (client.Client, error) { + var options ClientOptions + for _, opt := range opts { + opt(&options) + } + + reg := registry.GetRegistry() + var tlsConfig *tls.Config + cOpts := []client.Option{ + client.Registry(reg), + client.Wrap(mbreaker.NewClientWrapper()), + client.Wrap(mtracer.NewClientWrapper( + mtracer.WithTraceProvider(options.tp), + )), + } + switch options.tlsMode { + case "insecure": + tlsConfig = &tls.Config{ + InsecureSkipVerify: true, + } + cOpts = append(cOpts, mgrpcc.AuthTLS(tlsConfig)) + case "on": + tlsConfig = &tls.Config{} + // Note: If caCert is empty we use the system's default set of trusted CAs + if options.caCert != "" { + certs := x509.NewCertPool() + pemData, err := os.ReadFile(options.caCert) + if err != nil { + return nil, err + } + if !certs.AppendCertsFromPEM(pemData) { + return nil, errors.New("could not initialize client, adding CA cert failed") + } + tlsConfig.RootCAs = certs + } + cOpts = append(cOpts, mgrpcc.AuthTLS(tlsConfig)) + //case "off": + //default: + } + + return mgrpcc.NewClient(cOpts...), nil +} diff --git a/ocis-pkg/service/grpc/service.go b/ocis-pkg/service/grpc/service.go index 823ad5430a..d507213ef2 100644 --- a/ocis-pkg/service/grpc/service.go +++ b/ocis-pkg/service/grpc/service.go @@ -8,7 +8,7 @@ import ( mgrpcs "github.com/go-micro/plugins/v4/server/grpc" "github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus" - "github.com/go-micro/plugins/v4/wrapper/trace/opencensus" + mtracer "github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry" ociscrypto "github.com/owncloud/ocis/v2/ocis-pkg/crypto" "github.com/owncloud/ocis/v2/ocis-pkg/registry" "go-micro.dev/v4" @@ -62,9 +62,9 @@ func NewService(opts ...Option) (Service, error) { micro.RegisterTTL(time.Second * 30), micro.RegisterInterval(time.Second * 10), micro.WrapHandler(prometheus.NewHandlerWrapper()), - micro.WrapClient(opencensus.NewClientWrapper()), - micro.WrapHandler(opencensus.NewHandlerWrapper()), - micro.WrapSubscriber(opencensus.NewSubscriberWrapper()), + micro.WrapClient(mtracer.NewClientWrapper()), + micro.WrapHandler(mtracer.NewHandlerWrapper()), + micro.WrapSubscriber(mtracer.NewSubscriberWrapper()), } return Service{micro.NewService(mopts...)}, nil diff --git a/services/graph/pkg/server/http/server.go b/services/graph/pkg/server/http/server.go index fe9e34d75f..213cc7577f 100644 --- a/services/graph/pkg/server/http/server.go +++ b/services/graph/pkg/server/http/server.go @@ -18,7 +18,6 @@ import ( "github.com/owncloud/ocis/v2/ocis-pkg/keycloak" "github.com/owncloud/ocis/v2/ocis-pkg/middleware" "github.com/owncloud/ocis/v2/ocis-pkg/service/grpc" - ogrpc "github.com/owncloud/ocis/v2/ocis-pkg/service/grpc" "github.com/owncloud/ocis/v2/ocis-pkg/service/http" "github.com/owncloud/ocis/v2/ocis-pkg/version" ehsvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/eventhistory/v0" @@ -26,6 +25,7 @@ import ( settingssvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0" graphMiddleware "github.com/owncloud/ocis/v2/services/graph/pkg/middleware" svc "github.com/owncloud/ocis/v2/services/graph/pkg/service/v0" + "github.com/owncloud/ocis/v2/services/graph/pkg/tracing" "github.com/pkg/errors" "go-micro.dev/v4" "go-micro.dev/v4/events" @@ -115,13 +115,17 @@ func Server(opts ...Option) (http.Service, error) { var requireAdminMiddleware func(stdhttp.Handler) stdhttp.Handler var roleService svc.RoleService var gatewayClient gateway.GatewayAPIClient + grpcClient, err := grpc.NewClient(append(grpc.GetClientOptions(options.Config.GRPCClientTLS), grpc.WithTraceProvider(tracing.TraceProvider))...) + if err != nil { + return http.Service{}, err + } if options.Config.HTTP.APIToken == "" { middlewares = append(middlewares, graphMiddleware.Auth( account.Logger(options.Logger), account.JWTSecret(options.Config.TokenManager.JWTSecret), )) - roleService = settingssvc.NewRoleService("com.owncloud.api.settings", grpc.DefaultClient()) + roleService = settingssvc.NewRoleService("com.owncloud.api.settings", grpcClient) gatewayClient, err = pool.GetGatewayServiceClient(options.Config.Reva.Address, options.Config.Reva.GetRevaOptions()...) if err != nil { return http.Service{}, errors.Wrap(err, "could not initialize gateway client") @@ -145,7 +149,7 @@ func Server(opts ...Option) (http.Service, error) { keyCloakClient = keycloak.New(kcc.BasePath, kcc.ClientID, kcc.ClientSecret, kcc.ClientRealm, kcc.InsecureSkipVerify) } - hClient := ehsvc.NewEventHistoryService("com.owncloud.api.eventhistory", ogrpc.DefaultClient()) + hClient := ehsvc.NewEventHistoryService("com.owncloud.api.eventhistory", grpcClient) var handle svc.Service handle, err = svc.NewService( @@ -156,7 +160,7 @@ func Server(opts ...Option) (http.Service, error) { svc.WithRoleService(roleService), svc.WithRequireAdminMiddleware(requireAdminMiddleware), svc.WithGatewayClient(gatewayClient), - svc.WithSearchService(searchsvc.NewSearchProviderService("com.owncloud.api.search", grpc.DefaultClient())), + svc.WithSearchService(searchsvc.NewSearchProviderService("com.owncloud.api.search", grpcClient)), svc.KeycloakClient(keyCloakClient), svc.EventHistoryClient(hClient), ) diff --git a/services/graph/pkg/service/v0/drives.go b/services/graph/pkg/service/v0/drives.go index 75f53475a9..5cb2a46622 100644 --- a/services/graph/pkg/service/v0/drives.go +++ b/services/graph/pkg/service/v0/drives.go @@ -31,6 +31,7 @@ import ( v0 "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/settings/v0" settingssvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0" "github.com/owncloud/ocis/v2/services/graph/pkg/service/v0/errorcode" + gtracing "github.com/owncloud/ocis/v2/services/graph/pkg/tracing" settingsServiceExt "github.com/owncloud/ocis/v2/services/settings/pkg/store/defaults" "github.com/pkg/errors" merrors "go-micro.dev/v4/errors" @@ -582,13 +583,17 @@ func (g Graph) formatDrives(ctx context.Context, baseURL *url.URL, storageSpaces func (g Graph) ListStorageSpacesWithFilters(ctx context.Context, filters []*storageprovider.ListStorageSpacesRequest_Filter, unrestricted bool) (*storageprovider.ListStorageSpacesResponse, error) { client := g.GetGatewayClient() - permissions := make(map[string]struct{}, 1) - s := settingssvc.NewPermissionService("com.owncloud.api.settings", grpc.DefaultClient()) + grpcClient, err := grpc.NewClient(append(grpc.GetClientOptions(g.config.GRPCClientTLS), grpc.WithTraceProvider(gtracing.TraceProvider))...) + if err != nil { + return nil, err + } + s := settingssvc.NewPermissionService("com.owncloud.api.settings", grpcClient) - _, err := s.GetPermissionByID(ctx, &settingssvc.GetPermissionByIDRequest{ + _, err = s.GetPermissionByID(ctx, &settingssvc.GetPermissionByIDRequest{ PermissionId: settingsServiceExt.ListAllSpacesPermissionID, }) + permissions := make(map[string]struct{}, 1) // No error means the user has the permission if err == nil { permissions[settingsServiceExt.ListAllSpacesPermissionName] = struct{}{} diff --git a/services/graph/pkg/service/v0/password_test.go b/services/graph/pkg/service/v0/password_test.go index fea072f399..72bf4a07fc 100644 --- a/services/graph/pkg/service/v0/password_test.go +++ b/services/graph/pkg/service/v0/password_test.go @@ -18,6 +18,7 @@ import ( . "github.com/onsi/gomega" libregraph "github.com/owncloud/libre-graph-api-go" "github.com/owncloud/ocis/v2/ocis-pkg/log" + "github.com/owncloud/ocis/v2/ocis-pkg/shared" "github.com/owncloud/ocis/v2/services/graph/mocks" "github.com/owncloud/ocis/v2/services/graph/pkg/config" "github.com/owncloud/ocis/v2/services/graph/pkg/config/defaults" @@ -44,6 +45,7 @@ var _ = Describe("Users changing their own password", func() { ctx = context.Background() cfg = defaults.FullDefaultConfig() cfg.TokenManager.JWTSecret = "loremipsum" + cfg.GRPCClientTLS = &shared.GRPCClientTLS{} gatewayClient = &cs3mocks.GatewayAPIClient{} ldapClient = mockedLDAPClient() diff --git a/services/graph/pkg/service/v0/service.go b/services/graph/pkg/service/v0/service.go index 5c46f716e1..86fe823dd9 100644 --- a/services/graph/pkg/service/v0/service.go +++ b/services/graph/pkg/service/v0/service.go @@ -23,6 +23,7 @@ import ( "github.com/owncloud/ocis/v2/services/graph/pkg/identity" "github.com/owncloud/ocis/v2/services/graph/pkg/identity/ldap" graphm "github.com/owncloud/ocis/v2/services/graph/pkg/middleware" + gtracing "github.com/owncloud/ocis/v2/services/graph/pkg/tracing" microstore "go-micro.dev/v4/store" ) @@ -155,7 +156,11 @@ func NewService(opts ...Option) (Graph, error) { } if options.PermissionService == nil { - svc.permissionsService = settingssvc.NewPermissionService("com.owncloud.api.settings", grpc.DefaultClient()) + grpcClient, err := grpc.NewClient(append(grpc.GetClientOptions(options.Config.GRPCClientTLS), grpc.WithTraceProvider(gtracing.TraceProvider))...) + if err != nil { + return svc, err + } + svc.permissionsService = settingssvc.NewPermissionService("com.owncloud.api.settings", grpcClient) } else { svc.permissionsService = options.PermissionService } diff --git a/services/proxy/pkg/command/server.go b/services/proxy/pkg/command/server.go index 3476662b01..e49317c172 100644 --- a/services/proxy/pkg/command/server.go +++ b/services/proxy/pkg/command/server.go @@ -271,7 +271,11 @@ func (h *StaticRouteHandler) backchannelLogout(w http.ResponseWriter, r *http.Re } func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config, userInfoCache microstore.Store) alice.Chain { - rolesClient := settingssvc.NewRoleService("com.owncloud.api.settings", grpc.DefaultClient()) + grpcClient, err := grpc.NewClient(append(grpc.GetClientOptions(cfg.GRPCClientTLS), grpc.WithTraceProvider(tracing.TraceProvider))...) + if err != nil { + logger.Fatal().Err(err).Msg("Failed to get gateway client") + } + rolesClient := settingssvc.NewRoleService("com.owncloud.api.settings", grpcClient) revaClient, err := pool.GetGatewayServiceClient(cfg.Reva.Address, cfg.Reva.GetRevaOptions()...) if err != nil { logger.Fatal().Err(err).Msg("Failed to get gateway client") @@ -318,7 +322,7 @@ func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config, logger.Fatal().Msgf("Invalid role assignment driver '%s'", cfg.RoleAssignment.Driver) } - storeClient := storesvc.NewStoreService("com.owncloud.api.store", grpc.DefaultClient()) + storeClient := storesvc.NewStoreService("com.owncloud.api.store", grpcClient) if err != nil { logger.Error().Err(err). Str("gateway", cfg.Reva.Address). @@ -375,6 +379,7 @@ func loadMiddlewares(ctx context.Context, logger log.Logger, cfg *config.Config, return alice.New( // first make sure we log all requests and redirect to https if necessary + middleware.Tracer(), pkgmiddleware.TraceContext, chimiddleware.RealIP, chimiddleware.RequestID, diff --git a/services/proxy/pkg/middleware/tracing.go b/services/proxy/pkg/middleware/tracing.go new file mode 100644 index 0000000000..84760cba27 --- /dev/null +++ b/services/proxy/pkg/middleware/tracing.go @@ -0,0 +1,50 @@ +package middleware + +import ( + "fmt" + "net/http" + + chimiddleware "github.com/go-chi/chi/v5/middleware" + pkgtrace "github.com/owncloud/ocis/v2/ocis-pkg/tracing" + proxytracing "github.com/owncloud/ocis/v2/services/proxy/pkg/tracing" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/propagation" + "go.opentelemetry.io/otel/trace" +) + +// Tracer provides a middleware to start traces +func Tracer() func(next http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return &tracer{ + next: next, + } + } +} + +type tracer struct { + next http.Handler +} + +func (m tracer) ServeHTTP(w http.ResponseWriter, r *http.Request) { + var ( + ctx = r.Context() + span trace.Span + ) + + tracer := proxytracing.TraceProvider.Tracer("proxy") + spanOpts := []trace.SpanStartOption{ + trace.WithSpanKind(trace.SpanKindServer), + } + ctx, span = tracer.Start(ctx, fmt.Sprintf("%s %v", r.Method, r.URL.Path), spanOpts...) + defer span.End() + + span.SetAttributes( + attribute.KeyValue{ + Key: "x-request-id", + Value: attribute.StringValue(chimiddleware.GetReqID(r.Context())), + }) + + pkgtrace.Propagator.Inject(ctx, propagation.HeaderCarrier(r.Header)) + + m.next.ServeHTTP(w, r.WithContext(ctx)) +} diff --git a/services/proxy/pkg/proxy/proxy.go b/services/proxy/pkg/proxy/proxy.go index ab33dcc53a..0694f66197 100644 --- a/services/proxy/pkg/proxy/proxy.go +++ b/services/proxy/pkg/proxy/proxy.go @@ -4,25 +4,16 @@ import ( "crypto/tls" "crypto/x509" "errors" - "fmt" "net" "net/http" "net/http/httputil" "os" "time" - chimiddleware "github.com/go-chi/chi/v5/middleware" - - "go.opentelemetry.io/otel/attribute" - "github.com/owncloud/ocis/v2/ocis-pkg/log" - pkgtrace "github.com/owncloud/ocis/v2/ocis-pkg/tracing" "github.com/owncloud/ocis/v2/services/proxy/pkg/config" "github.com/owncloud/ocis/v2/services/proxy/pkg/proxy/policy" "github.com/owncloud/ocis/v2/services/proxy/pkg/router" - proxytracing "github.com/owncloud/ocis/v2/services/proxy/pkg/tracing" - "go.opentelemetry.io/otel/propagation" - "go.opentelemetry.io/otel/trace" ) // MultiHostReverseProxy extends "httputil" to support multiple hosts with different policies @@ -84,25 +75,5 @@ func NewMultiHostReverseProxy(opts ...Option) (*MultiHostReverseProxy, error) { } func (p *MultiHostReverseProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) { - var ( - ctx = r.Context() - span trace.Span - ) - - tracer := proxytracing.TraceProvider.Tracer("proxy") - spanOpts := []trace.SpanStartOption{ - trace.WithSpanKind(trace.SpanKindServer), - } - ctx, span = tracer.Start(ctx, fmt.Sprintf("%s %v", r.Method, r.URL.Path), spanOpts...) - defer span.End() - - span.SetAttributes( - attribute.KeyValue{ - Key: "x-request-id", - Value: attribute.StringValue(chimiddleware.GetReqID(r.Context())), - }) - - pkgtrace.Propagator.Inject(ctx, propagation.HeaderCarrier(r.Header)) - - p.ReverseProxy.ServeHTTP(w, r.WithContext(ctx)) + p.ReverseProxy.ServeHTTP(w, r) } diff --git a/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opencensus/README.md b/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opencensus/README.md deleted file mode 100644 index d18ebcef08..0000000000 --- a/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opencensus/README.md +++ /dev/null @@ -1,31 +0,0 @@ -# OpenCensus wrappers - -OpenCensus wrappers propagate traces (spans) accross services. - -## Usage - -```go -service := micro.NewService( - micro.Name("go.micro.srv.greeter"), - micro.WrapClient(opencensus.NewClientWrapper()), - micro.WrapHandler(opencensus.NewHandlerWrapper()), - micro.WrapSubscriber(opencensus.NewSubscriberWrapper()), -) -``` - -### Views - -The OpenCensus package exposes some convenience views. -Don't forget to register these views: - -```go -// Register to all RPC server views. -if err := view.Register(opencensus.DefaultServerViews...); err != nil { - log.Fatal(err) -} - -// Register to all RPC client views. -if err := view.Register(opencensus.DefaultClientViews...); err != nil { - log.Fatal(err) -} -``` diff --git a/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opencensus/opencensus.go b/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opencensus/opencensus.go deleted file mode 100644 index f427d030f3..0000000000 --- a/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opencensus/opencensus.go +++ /dev/null @@ -1,150 +0,0 @@ -// Package opencensus provides wrappers for OpenCensus tracing. -package opencensus - -import ( - "context" - "encoding/base64" - "fmt" - - "go-micro.dev/v4/client" - log "go-micro.dev/v4/logger" - "go-micro.dev/v4/metadata" - "go-micro.dev/v4/server" - "go.opencensus.io/trace" - "go.opencensus.io/trace/propagation" -) - -const ( - // TracePropagationField is the key for the tracing context - // that will be injected in go-micro's metadata. - TracePropagationField = "X-Trace-Context" -) - -// clientWrapper wraps an RPC client and adds tracing. -type clientWrapper struct { - client.Client -} - -func injectTraceIntoCtx(ctx context.Context, span *trace.Span) context.Context { - spanCtx := propagation.Binary(span.SpanContext()) - return metadata.Set(ctx, TracePropagationField, base64.RawStdEncoding.EncodeToString(spanCtx)) -} - -// Call implements client.Client.Call. -func (w *clientWrapper) Call( - ctx context.Context, - req client.Request, - rsp interface{}, - opts ...client.CallOption) (err error) { - t := newRequestTracker(req, ClientProfile) - ctx = t.start(ctx, true) - - defer func() { t.end(ctx, err) }() - - ctx = injectTraceIntoCtx(ctx, t.span) - - err = w.Client.Call(ctx, req, rsp, opts...) - return -} - -// Publish implements client.Client.Publish. -func (w *clientWrapper) Publish(ctx context.Context, p client.Message, opts ...client.PublishOption) (err error) { - t := newEventTracker(p, ClientProfile) - ctx = t.start(ctx, true) - - defer func() { t.end(ctx, err) }() - - ctx = injectTraceIntoCtx(ctx, t.span) - - err = w.Client.Publish(ctx, p, opts...) - return -} - -// NewClientWrapper returns a client.Wrapper -// that adds monitoring to outgoing requests. -func NewClientWrapper() client.Wrapper { - return func(c client.Client) client.Client { - return &clientWrapper{c} - } -} - -func getTraceFromCtx(ctx context.Context) *trace.SpanContext { - encodedTraceCtx, ok := metadata.Get(ctx, TracePropagationField) - if !ok { - return nil - } - - traceCtxBytes, err := base64.RawStdEncoding.DecodeString(encodedTraceCtx) - if err != nil { - log.Errorf("Could not decode trace context: %s", err.Error()) - return nil - } - - spanCtx, ok := propagation.FromBinary(traceCtxBytes) - if !ok { - log.Errorf("Could not decode trace context from binary") - return nil - } - - return &spanCtx -} - -// NewHandlerWrapper returns a server.HandlerWrapper -// that adds tracing to incoming requests. -func NewHandlerWrapper() server.HandlerWrapper { - return func(fn server.HandlerFunc) server.HandlerFunc { - return func(ctx context.Context, req server.Request, rsp interface{}) (err error) { - t := newRequestTracker(req, ServerProfile) - ctx = t.start(ctx, false) - - defer func() { t.end(ctx, err) }() - - spanCtx := getTraceFromCtx(ctx) - if spanCtx != nil { - ctx, t.span = trace.StartSpanWithRemoteParent( - ctx, - fmt.Sprintf("rpc/%s/%s/%s", ServerProfile.Role, req.Service(), req.Endpoint()), - *spanCtx, - ) - } else { - ctx, t.span = trace.StartSpan( - ctx, - fmt.Sprintf("rpc/%s/%s/%s", ServerProfile.Role, req.Service(), req.Endpoint()), - ) - } - - err = fn(ctx, req, rsp) - return - } - } -} - -// NewSubscriberWrapper returns a server.SubscriberWrapper -// that adds tracing to subscription requests. -func NewSubscriberWrapper() server.SubscriberWrapper { - return func(fn server.SubscriberFunc) server.SubscriberFunc { - return func(ctx context.Context, p server.Message) (err error) { - t := newEventTracker(p, ServerProfile) - ctx = t.start(ctx, false) - - defer func() { t.end(ctx, err) }() - - spanCtx := getTraceFromCtx(ctx) - if spanCtx != nil { - ctx, t.span = trace.StartSpanWithRemoteParent( - ctx, - fmt.Sprintf("rpc/%s/pubsub/%s", ServerProfile.Role, p.Topic()), - *spanCtx, - ) - } else { - ctx, t.span = trace.StartSpan( - ctx, - fmt.Sprintf("rpc/%s/pubsub/%s", ServerProfile.Role, p.Topic()), - ) - } - - err = fn(ctx, p) - return - } - } -} diff --git a/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opencensus/stats.go b/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opencensus/stats.go deleted file mode 100644 index 2fd7865f7d..0000000000 --- a/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opencensus/stats.go +++ /dev/null @@ -1,142 +0,0 @@ -package opencensus - -import ( - "go.opencensus.io/stats" - "go.opencensus.io/stats/view" - "go.opencensus.io/tag" -) - -// The following client RPC measures are supported for use in custom views. -var ( - ClientRequestCount = stats.Int64("opencensus.io/rpc/client/request_count", "Number of RPC requests started", stats.UnitNone) - ClientLatency = stats.Float64("opencensus.io/rpc/client/latency", "End-to-end latency", stats.UnitMilliseconds) -) - -// The following server RPC measures are supported for use in custom views. -var ( - ServerRequestCount = stats.Int64("opencensus.io/rpc/server/request_count", "Number of RPC requests received", stats.UnitNone) - ServerLatency = stats.Float64("opencensus.io/rpc/server/latency", "End-to-end latency", stats.UnitMilliseconds) -) - -// The following tags are applied to stats recorded by this package. -// Service and Method are applied to all measures. -// StatusCode is not applied to ClientRequestCount or ServerRequestCount, -// since it is recorded before the status is known. -var ( - // StatusCode is the RPC status code. - StatusCode, _ = tag.NewKey("rpc.status") - - // Service is the name of the micro-service. - Service, _ = tag.NewKey("rpc.service") - - // Method is the service method called. - Endpoint, _ = tag.NewKey("rpc.endpoint") -) - -// Default distributions used by views in this package. -var ( - DefaultLatencyDistribution = view.Distribution(0, 1, 2, 3, 4, 5, 6, 8, 10, 13, 16, 20, 25, 30, 40, 50, 65, 80, 100, 130, 160, 200, 250, 300, 400, 500, 650, 800, 1000, 2000, 5000, 10000, 20000, 50000, 100000) -) - -// This package provides some convenience views. -// You need to subscribe to the views for data to actually be collected. -var ( - ClientRequestCountView = &view.View{ - Name: "opencensus.io/rpc/client/request_count", - Description: "Count of RPC requests started", - Measure: ClientRequestCount, - Aggregation: view.Count(), - } - - ClientLatencyView = &view.View{ - Name: "opencensus.io/rpc/client/latency", - Description: "Latency distribution of RPC requests", - Measure: ClientLatency, - Aggregation: DefaultLatencyDistribution, - } - - ClientRequestCountByMethod = &view.View{ - Name: "opencensus.io/rpc/client/request_count_by_method", - Description: "Client request count by RPC method", - TagKeys: []tag.Key{Endpoint}, - Measure: ClientRequestCount, - Aggregation: view.Count(), - } - - ClientResponseCountByStatusCode = &view.View{ - Name: "opencensus.io/rpc/client/response_count_by_status_code", - Description: "Client response count by RPC status code", - TagKeys: []tag.Key{StatusCode}, - Measure: ClientLatency, - Aggregation: view.Count(), - } - - ServerRequestCountView = &view.View{ - Name: "opencensus.io/rpc/server/request_count", - Description: "Count of RPC requests received", - Measure: ServerRequestCount, - Aggregation: view.Count(), - } - - ServerLatencyView = &view.View{ - Name: "opencensus.io/rpc/server/latency", - Description: "Latency distribution of RPC requests", - Measure: ServerLatency, - Aggregation: DefaultLatencyDistribution, - } - - ServerRequestCountByMethod = &view.View{ - Name: "opencensus.io/rpc/server/request_count_by_method", - Description: "Server request count by RPC method", - TagKeys: []tag.Key{Endpoint}, - Measure: ServerRequestCount, - Aggregation: view.Count(), - } - - ServerResponseCountByStatusCode = &view.View{ - Name: "opencensus.io/rpc/server/response_count_by_status_code", - Description: "Server response count by RPC status code", - TagKeys: []tag.Key{StatusCode}, - Measure: ServerLatency, - Aggregation: view.Count(), - } -) - -// DefaultClientViews are the default client views provided by this package. -var DefaultClientViews = []*view.View{ - ClientRequestCountView, - ClientLatencyView, - ClientRequestCountByMethod, - ClientResponseCountByStatusCode, -} - -// DefaultServerViews are the default server views provided by this package. -var DefaultServerViews = []*view.View{ - ServerRequestCountView, - ServerLatencyView, - ServerRequestCountByMethod, - ServerResponseCountByStatusCode, -} - -// StatsProfile groups metrics-related data. -type StatsProfile struct { - Role string - CountMeasure *stats.Int64Measure - LatencyMeasure *stats.Float64Measure -} - -var ( - // ClientProfile is used for RPC clients. - ClientProfile = &StatsProfile{ - Role: "client", - CountMeasure: ClientRequestCount, - LatencyMeasure: ClientLatency, - } - - // ServerProfile is used for RPC servers. - ServerProfile = &StatsProfile{ - Role: "server", - CountMeasure: ServerRequestCount, - LatencyMeasure: ServerLatency, - } -) diff --git a/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opencensus/status.go b/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opencensus/status.go deleted file mode 100644 index bb7bdceb4d..0000000000 --- a/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opencensus/status.go +++ /dev/null @@ -1,45 +0,0 @@ -package opencensus - -import ( - "fmt" - - microerr "go-micro.dev/v4/errors" - - "go.opencensus.io/trace" - - "google.golang.org/genproto/googleapis/rpc/code" -) - -var microCodeToStatusCode = map[int32]code.Code{ - 400: code.Code_INVALID_ARGUMENT, - 401: code.Code_UNAUTHENTICATED, - 403: code.Code_PERMISSION_DENIED, - 404: code.Code_NOT_FOUND, - 409: code.Code_ABORTED, - 500: code.Code_INTERNAL, -} - -func getResponseStatus(err error) trace.Status { - if err != nil { - microErr, ok := err.(*microerr.Error) - if ok { - statusCode := microErr.Code - code, ok := microCodeToStatusCode[microErr.Code] - if ok { - statusCode = int32(code) - } - - return trace.Status{ - Code: statusCode, - Message: fmt.Sprintf("%s: %s", microErr.Id, microErr.Detail), - } - } - - return trace.Status{ - Code: int32(code.Code_UNKNOWN), - Message: err.Error(), - } - } - - return trace.Status{} -} diff --git a/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opencensus/tracker.go b/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opencensus/tracker.go deleted file mode 100644 index 9b1d4ee4db..0000000000 --- a/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opencensus/tracker.go +++ /dev/null @@ -1,81 +0,0 @@ -package opencensus - -import ( - "context" - "fmt" - "strconv" - "time" - - "go.opencensus.io/stats" - "go.opencensus.io/tag" - "go.opencensus.io/trace" -) - -type tracker struct { - startedAt time.Time - - profile *StatsProfile - span *trace.Span - - method string - service string -} - -type requestDescriptor interface { - Service() string - Endpoint() string -} - -type publicationDescriptor interface { - Topic() string -} - -// newRequestTracker creates a new tracker for an RPC request (client or server). -func newRequestTracker(req requestDescriptor, profile *StatsProfile) *tracker { - return &tracker{ - profile: profile, - method: req.Endpoint(), - service: req.Service(), - } -} - -// newEventTracker creates a new tracker for a publication (client or server). -func newEventTracker(pub publicationDescriptor, profile *StatsProfile) *tracker { - return &tracker{ - profile: profile, - method: pub.Topic(), - service: "pubsub", - } -} - -// start monitoring a request. You can choose to let this method -// start a span for the request or attach one later. -func (t *tracker) start(ctx context.Context, startSpan bool) context.Context { - t.startedAt = time.Now() - - ctx, _ = tag.New(ctx, tag.Upsert(Service, t.service), tag.Upsert(Endpoint, t.method)) - stats.Record(ctx, t.profile.CountMeasure.M(1)) - - if startSpan { - ctx, t.span = trace.StartSpan( - ctx, - fmt.Sprintf("rpc/%s/%s/%s", t.profile.Role, t.service, t.method), - ) - } - - return ctx -} - -// end a request's monitoring session. If there is a span ongoing, it will -// be ended and metrics will be recorded. -func (t *tracker) end(ctx context.Context, err error) { - status := getResponseStatus(err) - - ctx, _ = tag.New(ctx, tag.Upsert(StatusCode, strconv.Itoa(int(status.Code)))) - stats.Record(ctx, t.profile.LatencyMeasure.M(float64(time.Since(t.startedAt))/float64(time.Millisecond))) - - if t.span != nil { - t.span.SetStatus(status) - t.span.End() - } -} diff --git a/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opencensus/LICENSE b/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry/LICENSE similarity index 100% rename from vendor/github.com/go-micro/plugins/v4/wrapper/trace/opencensus/LICENSE rename to vendor/github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry/LICENSE diff --git a/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry/README.md b/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry/README.md new file mode 100644 index 0000000000..d1944d5bbb --- /dev/null +++ b/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry/README.md @@ -0,0 +1,14 @@ +# OpenTelemetry wrappers + +OpenTelemetry wrappers propagate traces (spans) accross services. + +## Usage + +```go +service := micro.NewService( + micro.Name("go.micro.srv.greeter"), + micro.WrapClient(opentelemetry.NewClientWrapper()), + micro.WrapHandler(open.NewHandlerWrapper()), + micro.WrapSubscriber(opentelemetry.NewSubscriberWrapper()), +) +``` \ No newline at end of file diff --git a/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry/opentelemetry.go b/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry/opentelemetry.go new file mode 100644 index 0000000000..8f9453921f --- /dev/null +++ b/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry/opentelemetry.go @@ -0,0 +1,55 @@ +package opentelemetry + +import ( + "context" + "strings" + + "go-micro.dev/v4/metadata" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/baggage" + "go.opentelemetry.io/otel/propagation" + "go.opentelemetry.io/otel/trace" +) + +const ( + instrumentationName = "github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry" +) + +// StartSpanFromContext returns a new span with the given operation name and options. If a span +// is found in the context, it will be used as the parent of the resulting span. +func StartSpanFromContext(ctx context.Context, tp trace.TracerProvider, name string, opts ...trace.SpanStartOption) (context.Context, trace.Span) { + md, ok := metadata.FromContext(ctx) + if !ok { + md = make(metadata.Metadata) + } + propagator, carrier := otel.GetTextMapPropagator(), make(propagation.MapCarrier) + for k, v := range md { + for _, f := range propagator.Fields() { + if strings.EqualFold(k, f) { + carrier[f] = v + } + } + } + ctx = propagator.Extract(ctx, carrier) + spanCtx := trace.SpanContextFromContext(ctx) + ctx = baggage.ContextWithBaggage(ctx, baggage.FromContext(ctx)) + + var tracer trace.Tracer + var span trace.Span + if tp != nil { + tracer = tp.Tracer(instrumentationName) + } else { + tracer = otel.Tracer(instrumentationName) + } + ctx, span = tracer.Start(trace.ContextWithRemoteSpanContext(ctx, spanCtx), name, opts...) + + carrier = make(propagation.MapCarrier) + propagator.Inject(ctx, carrier) + for k, v := range carrier { + //lint:ignore SA1019 no unicode punctution handle needed + md.Set(strings.Title(k), v) + } + ctx = metadata.NewContext(ctx, md) + + return ctx, span +} diff --git a/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry/options.go b/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry/options.go new file mode 100644 index 0000000000..fc36c7e208 --- /dev/null +++ b/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry/options.go @@ -0,0 +1,72 @@ +package opentelemetry + +import ( + "context" + + "go-micro.dev/v4/client" + "go-micro.dev/v4/server" + "go.opentelemetry.io/otel/trace" +) + +type Options struct { + TraceProvider trace.TracerProvider + + CallFilter CallFilter + StreamFilter StreamFilter + PublishFilter PublishFilter + SubscriberFilter SubscriberFilter + HandlerFilter HandlerFilter +} + +// CallFilter used to filter client.Call, return true to skip call trace. +type CallFilter func(context.Context, client.Request) bool + +// StreamFilter used to filter client.Stream, return true to skip stream trace. +type StreamFilter func(context.Context, client.Request) bool + +// PublishFilter used to filter client.Publish, return true to skip publish trace. +type PublishFilter func(context.Context, client.Message) bool + +// SubscriberFilter used to filter server.Subscribe, return true to skip subcribe trace. +type SubscriberFilter func(context.Context, server.Message) bool + +// HandlerFilter used to filter server.Handle, return true to skip handle trace. +type HandlerFilter func(context.Context, server.Request) bool + +type Option func(*Options) + +func WithTraceProvider(tp trace.TracerProvider) Option { + return func(o *Options) { + o.TraceProvider = tp + } +} + +func WithCallFilter(filter CallFilter) Option { + return func(o *Options) { + o.CallFilter = filter + } +} + +func WithStreamFilter(filter StreamFilter) Option { + return func(o *Options) { + o.StreamFilter = filter + } +} + +func WithPublishFilter(filter PublishFilter) Option { + return func(o *Options) { + o.PublishFilter = filter + } +} + +func WithSubscribeFilter(filter SubscriberFilter) Option { + return func(o *Options) { + o.SubscriberFilter = filter + } +} + +func WithHandleFilter(filter HandlerFilter) Option { + return func(o *Options) { + o.HandlerFilter = filter + } +} diff --git a/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry/wrapper.go b/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry/wrapper.go new file mode 100644 index 0000000000..da2649405a --- /dev/null +++ b/vendor/github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry/wrapper.go @@ -0,0 +1,175 @@ +package opentelemetry + +import ( + "context" + "fmt" + + "go-micro.dev/v4/client" + "go-micro.dev/v4/registry" + "go-micro.dev/v4/server" + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/trace" +) + +// NewCallWrapper accepts an opentracing Tracer and returns a Call Wrapper. +func NewCallWrapper(opts ...Option) client.CallWrapper { + options := Options{} + for _, o := range opts { + o(&options) + } + return func(cf client.CallFunc) client.CallFunc { + return func(ctx context.Context, node *registry.Node, req client.Request, rsp interface{}, opts client.CallOptions) error { + if options.CallFilter != nil && options.CallFilter(ctx, req) { + return cf(ctx, node, req, rsp, opts) + } + name := fmt.Sprintf("%s.%s", req.Service(), req.Endpoint()) + spanOpts := []trace.SpanStartOption{ + trace.WithSpanKind(trace.SpanKindClient), + } + ctx, span := StartSpanFromContext(ctx, options.TraceProvider, name, spanOpts...) + defer span.End() + if err := cf(ctx, node, req, rsp, opts); err != nil { + span.SetStatus(codes.Error, err.Error()) + span.RecordError(err) + return err + } + return nil + } + } +} + +// NewHandlerWrapper accepts an opentracing Tracer and returns a Handler Wrapper. +func NewHandlerWrapper(opts ...Option) server.HandlerWrapper { + options := Options{} + for _, o := range opts { + o(&options) + } + return func(h server.HandlerFunc) server.HandlerFunc { + return func(ctx context.Context, req server.Request, rsp interface{}) error { + if options.HandlerFilter != nil && options.HandlerFilter(ctx, req) { + return h(ctx, req, rsp) + } + name := fmt.Sprintf("%s.%s", req.Service(), req.Endpoint()) + spanOpts := []trace.SpanStartOption{ + trace.WithSpanKind(trace.SpanKindServer), + } + ctx, span := StartSpanFromContext(ctx, options.TraceProvider, name, spanOpts...) + defer span.End() + if err := h(ctx, req, rsp); err != nil { + span.SetStatus(codes.Error, err.Error()) + span.RecordError(err) + return err + } + return nil + } + } +} + +// NewSubscriberWrapper accepts an opentracing Tracer and returns a Subscriber Wrapper. +func NewSubscriberWrapper(opts ...Option) server.SubscriberWrapper { + options := Options{} + for _, o := range opts { + o(&options) + } + return func(next server.SubscriberFunc) server.SubscriberFunc { + return func(ctx context.Context, msg server.Message) error { + if options.SubscriberFilter != nil && options.SubscriberFilter(ctx, msg) { + return next(ctx, msg) + } + name := "Sub from " + msg.Topic() + spanOpts := []trace.SpanStartOption{ + trace.WithSpanKind(trace.SpanKindServer), + } + ctx, span := StartSpanFromContext(ctx, options.TraceProvider, name, spanOpts...) + defer span.End() + if err := next(ctx, msg); err != nil { + span.SetStatus(codes.Error, err.Error()) + span.RecordError(err) + return err + } + return nil + } + } +} + +// NewClientWrapper returns a client.Wrapper +// that adds monitoring to outgoing requests. +func NewClientWrapper(opts ...Option) client.Wrapper { + options := Options{} + for _, o := range opts { + o(&options) + } + return func(c client.Client) client.Client { + w := &clientWrapper{ + Client: c, + tp: options.TraceProvider, + callFilter: options.CallFilter, + streamFilter: options.StreamFilter, + publishFilter: options.PublishFilter, + } + return w + } +} + +type clientWrapper struct { + client.Client + + tp trace.TracerProvider + callFilter CallFilter + streamFilter StreamFilter + publishFilter PublishFilter +} + +func (w *clientWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error { + if w.callFilter != nil && w.callFilter(ctx, req) { + return w.Client.Call(ctx, req, rsp, opts...) + } + name := fmt.Sprintf("%s.%s", req.Service(), req.Endpoint()) + spanOpts := []trace.SpanStartOption{ + trace.WithSpanKind(trace.SpanKindClient), + } + ctx, span := StartSpanFromContext(ctx, w.tp, name, spanOpts...) + defer span.End() + if err := w.Client.Call(ctx, req, rsp, opts...); err != nil { + span.SetStatus(codes.Error, err.Error()) + span.RecordError(err) + return err + } + return nil +} + +func (w *clientWrapper) Stream(ctx context.Context, req client.Request, opts ...client.CallOption) (client.Stream, error) { + if w.streamFilter != nil && w.streamFilter(ctx, req) { + return w.Client.Stream(ctx, req, opts...) + } + name := fmt.Sprintf("%s.%s", req.Service(), req.Endpoint()) + spanOpts := []trace.SpanStartOption{ + trace.WithSpanKind(trace.SpanKindClient), + } + ctx, span := StartSpanFromContext(ctx, w.tp, name, spanOpts...) + defer span.End() + stream, err := w.Client.Stream(ctx, req, opts...) + if err != nil { + span.SetStatus(codes.Error, err.Error()) + span.RecordError(err) + } + return stream, err +} + +func (w *clientWrapper) Publish(ctx context.Context, p client.Message, opts ...client.PublishOption) error { + if w.publishFilter != nil && w.publishFilter(ctx, p) { + return w.Client.Publish(ctx, p, opts...) + } + name := fmt.Sprintf("Pub to %s", p.Topic()) + spanOpts := []trace.SpanStartOption{ + trace.WithSpanKind(trace.SpanKindClient), + } + ctx, span := StartSpanFromContext(ctx, w.tp, name, spanOpts...) + defer span.End() + if err := w.Client.Publish(ctx, p, opts...); err != nil { + span.SetStatus(codes.Error, err.Error()) + span.RecordError(err) + return err + } + return nil +} diff --git a/vendor/go.opencensus.io/plugin/ocgrpc/client.go b/vendor/go.opencensus.io/plugin/ocgrpc/client.go deleted file mode 100644 index 2063b6f76a..0000000000 --- a/vendor/go.opencensus.io/plugin/ocgrpc/client.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2018, OpenCensus Authors -// -// 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. - -package ocgrpc - -import ( - "context" - - "go.opencensus.io/trace" - "google.golang.org/grpc/stats" -) - -// ClientHandler implements a gRPC stats.Handler for recording OpenCensus stats and -// traces. Use with gRPC clients only. -type ClientHandler struct { - // StartOptions allows configuring the StartOptions used to create new spans. - // - // StartOptions.SpanKind will always be set to trace.SpanKindClient - // for spans started by this handler. - StartOptions trace.StartOptions -} - -// HandleConn exists to satisfy gRPC stats.Handler. -func (c *ClientHandler) HandleConn(ctx context.Context, cs stats.ConnStats) { - // no-op -} - -// TagConn exists to satisfy gRPC stats.Handler. -func (c *ClientHandler) TagConn(ctx context.Context, cti *stats.ConnTagInfo) context.Context { - // no-op - return ctx -} - -// HandleRPC implements per-RPC tracing and stats instrumentation. -func (c *ClientHandler) HandleRPC(ctx context.Context, rs stats.RPCStats) { - traceHandleRPC(ctx, rs) - statsHandleRPC(ctx, rs) -} - -// TagRPC implements per-RPC context management. -func (c *ClientHandler) TagRPC(ctx context.Context, rti *stats.RPCTagInfo) context.Context { - ctx = c.traceTagRPC(ctx, rti) - ctx = c.statsTagRPC(ctx, rti) - return ctx -} diff --git a/vendor/go.opencensus.io/plugin/ocgrpc/client_metrics.go b/vendor/go.opencensus.io/plugin/ocgrpc/client_metrics.go deleted file mode 100644 index fb3c19d6b6..0000000000 --- a/vendor/go.opencensus.io/plugin/ocgrpc/client_metrics.go +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright 2017, OpenCensus Authors -// -// 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. -// - -package ocgrpc - -import ( - "go.opencensus.io/stats" - "go.opencensus.io/stats/view" - "go.opencensus.io/tag" -) - -// The following variables are measures are recorded by ClientHandler: -var ( - ClientSentMessagesPerRPC = stats.Int64("grpc.io/client/sent_messages_per_rpc", "Number of messages sent in the RPC (always 1 for non-streaming RPCs).", stats.UnitDimensionless) - ClientSentBytesPerRPC = stats.Int64("grpc.io/client/sent_bytes_per_rpc", "Total bytes sent across all request messages per RPC.", stats.UnitBytes) - ClientReceivedMessagesPerRPC = stats.Int64("grpc.io/client/received_messages_per_rpc", "Number of response messages received per RPC (always 1 for non-streaming RPCs).", stats.UnitDimensionless) - ClientReceivedBytesPerRPC = stats.Int64("grpc.io/client/received_bytes_per_rpc", "Total bytes received across all response messages per RPC.", stats.UnitBytes) - ClientRoundtripLatency = stats.Float64("grpc.io/client/roundtrip_latency", "Time between first byte of request sent to last byte of response received, or terminal error.", stats.UnitMilliseconds) - ClientStartedRPCs = stats.Int64("grpc.io/client/started_rpcs", "Number of started client RPCs.", stats.UnitDimensionless) - ClientServerLatency = stats.Float64("grpc.io/client/server_latency", `Propagated from the server and should have the same value as "grpc.io/server/latency".`, stats.UnitMilliseconds) -) - -// Predefined views may be registered to collect data for the above measures. -// As always, you may also define your own custom views over measures collected by this -// package. These are declared as a convenience only; none are registered by -// default. -var ( - ClientSentBytesPerRPCView = &view.View{ - Measure: ClientSentBytesPerRPC, - Name: "grpc.io/client/sent_bytes_per_rpc", - Description: "Distribution of bytes sent per RPC, by method.", - TagKeys: []tag.Key{KeyClientMethod}, - Aggregation: DefaultBytesDistribution, - } - - ClientReceivedBytesPerRPCView = &view.View{ - Measure: ClientReceivedBytesPerRPC, - Name: "grpc.io/client/received_bytes_per_rpc", - Description: "Distribution of bytes received per RPC, by method.", - TagKeys: []tag.Key{KeyClientMethod}, - Aggregation: DefaultBytesDistribution, - } - - ClientRoundtripLatencyView = &view.View{ - Measure: ClientRoundtripLatency, - Name: "grpc.io/client/roundtrip_latency", - Description: "Distribution of round-trip latency, by method.", - TagKeys: []tag.Key{KeyClientMethod}, - Aggregation: DefaultMillisecondsDistribution, - } - - // Purposely reuses the count from `ClientRoundtripLatency`, tagging - // with method and status to result in ClientCompletedRpcs. - ClientCompletedRPCsView = &view.View{ - Measure: ClientRoundtripLatency, - Name: "grpc.io/client/completed_rpcs", - Description: "Count of RPCs by method and status.", - TagKeys: []tag.Key{KeyClientMethod, KeyClientStatus}, - Aggregation: view.Count(), - } - - ClientStartedRPCsView = &view.View{ - Measure: ClientStartedRPCs, - Name: "grpc.io/client/started_rpcs", - Description: "Number of started client RPCs.", - TagKeys: []tag.Key{KeyClientMethod}, - Aggregation: view.Count(), - } - - ClientSentMessagesPerRPCView = &view.View{ - Measure: ClientSentMessagesPerRPC, - Name: "grpc.io/client/sent_messages_per_rpc", - Description: "Distribution of sent messages count per RPC, by method.", - TagKeys: []tag.Key{KeyClientMethod}, - Aggregation: DefaultMessageCountDistribution, - } - - ClientReceivedMessagesPerRPCView = &view.View{ - Measure: ClientReceivedMessagesPerRPC, - Name: "grpc.io/client/received_messages_per_rpc", - Description: "Distribution of received messages count per RPC, by method.", - TagKeys: []tag.Key{KeyClientMethod}, - Aggregation: DefaultMessageCountDistribution, - } - - ClientServerLatencyView = &view.View{ - Measure: ClientServerLatency, - Name: "grpc.io/client/server_latency", - Description: "Distribution of server latency as viewed by client, by method.", - TagKeys: []tag.Key{KeyClientMethod}, - Aggregation: DefaultMillisecondsDistribution, - } -) - -// DefaultClientViews are the default client views provided by this package. -var DefaultClientViews = []*view.View{ - ClientSentBytesPerRPCView, - ClientReceivedBytesPerRPCView, - ClientRoundtripLatencyView, - ClientCompletedRPCsView, -} - -// TODO(jbd): Add roundtrip_latency, uncompressed_request_bytes, uncompressed_response_bytes, request_count, response_count. -// TODO(acetechnologist): This is temporary and will need to be replaced by a -// mechanism to load these defaults from a common repository/config shared by -// all supported languages. Likely a serialized protobuf of these defaults. diff --git a/vendor/go.opencensus.io/plugin/ocgrpc/client_stats_handler.go b/vendor/go.opencensus.io/plugin/ocgrpc/client_stats_handler.go deleted file mode 100644 index b36349820d..0000000000 --- a/vendor/go.opencensus.io/plugin/ocgrpc/client_stats_handler.go +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2017, OpenCensus Authors -// -// 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. -// - -package ocgrpc - -import ( - "context" - "time" - - "go.opencensus.io/tag" - "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/stats" -) - -// statsTagRPC gets the tag.Map populated by the application code, serializes -// its tags into the GRPC metadata in order to be sent to the server. -func (h *ClientHandler) statsTagRPC(ctx context.Context, info *stats.RPCTagInfo) context.Context { - startTime := time.Now() - if info == nil { - if grpclog.V(2) { - grpclog.Info("clientHandler.TagRPC called with nil info.") - } - return ctx - } - - d := &rpcData{ - startTime: startTime, - method: info.FullMethodName, - } - ts := tag.FromContext(ctx) - if ts != nil { - encoded := tag.Encode(ts) - ctx = stats.SetTags(ctx, encoded) - } - - return context.WithValue(ctx, rpcDataKey, d) -} diff --git a/vendor/go.opencensus.io/plugin/ocgrpc/server.go b/vendor/go.opencensus.io/plugin/ocgrpc/server.go deleted file mode 100644 index 8a53e09727..0000000000 --- a/vendor/go.opencensus.io/plugin/ocgrpc/server.go +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2018, OpenCensus Authors -// -// 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. - -package ocgrpc - -import ( - "context" - - "google.golang.org/grpc/stats" - - "go.opencensus.io/trace" -) - -// ServerHandler implements gRPC stats.Handler recording OpenCensus stats and -// traces. Use with gRPC servers. -// -// When installed (see Example), tracing metadata is read from inbound RPCs -// by default. If no tracing metadata is present, or if the tracing metadata is -// present but the SpanContext isn't sampled, then a new trace may be started -// (as determined by Sampler). -type ServerHandler struct { - // IsPublicEndpoint may be set to true to always start a new trace around - // each RPC. Any SpanContext in the RPC metadata will be added as a linked - // span instead of making it the parent of the span created around the - // server RPC. - // - // Be aware that if you leave this false (the default) on a public-facing - // server, callers will be able to send tracing metadata in gRPC headers - // and trigger traces in your backend. - IsPublicEndpoint bool - - // StartOptions to use for to spans started around RPCs handled by this server. - // - // These will apply even if there is tracing metadata already - // present on the inbound RPC but the SpanContext is not sampled. This - // ensures that each service has some opportunity to be traced. If you would - // like to not add any additional traces for this gRPC service, set: - // - // StartOptions.Sampler = trace.ProbabilitySampler(0.0) - // - // StartOptions.SpanKind will always be set to trace.SpanKindServer - // for spans started by this handler. - StartOptions trace.StartOptions -} - -var _ stats.Handler = (*ServerHandler)(nil) - -// HandleConn exists to satisfy gRPC stats.Handler. -func (s *ServerHandler) HandleConn(ctx context.Context, cs stats.ConnStats) { - // no-op -} - -// TagConn exists to satisfy gRPC stats.Handler. -func (s *ServerHandler) TagConn(ctx context.Context, cti *stats.ConnTagInfo) context.Context { - // no-op - return ctx -} - -// HandleRPC implements per-RPC tracing and stats instrumentation. -func (s *ServerHandler) HandleRPC(ctx context.Context, rs stats.RPCStats) { - traceHandleRPC(ctx, rs) - statsHandleRPC(ctx, rs) -} - -// TagRPC implements per-RPC context management. -func (s *ServerHandler) TagRPC(ctx context.Context, rti *stats.RPCTagInfo) context.Context { - ctx = s.traceTagRPC(ctx, rti) - ctx = s.statsTagRPC(ctx, rti) - return ctx -} diff --git a/vendor/go.opencensus.io/plugin/ocgrpc/server_metrics.go b/vendor/go.opencensus.io/plugin/ocgrpc/server_metrics.go deleted file mode 100644 index fe0e971086..0000000000 --- a/vendor/go.opencensus.io/plugin/ocgrpc/server_metrics.go +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2017, OpenCensus Authors -// -// 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. -// - -package ocgrpc - -import ( - "go.opencensus.io/stats" - "go.opencensus.io/stats/view" - "go.opencensus.io/tag" -) - -// The following variables are measures are recorded by ServerHandler: -var ( - ServerReceivedMessagesPerRPC = stats.Int64("grpc.io/server/received_messages_per_rpc", "Number of messages received in each RPC. Has value 1 for non-streaming RPCs.", stats.UnitDimensionless) - ServerReceivedBytesPerRPC = stats.Int64("grpc.io/server/received_bytes_per_rpc", "Total bytes received across all messages per RPC.", stats.UnitBytes) - ServerSentMessagesPerRPC = stats.Int64("grpc.io/server/sent_messages_per_rpc", "Number of messages sent in each RPC. Has value 1 for non-streaming RPCs.", stats.UnitDimensionless) - ServerSentBytesPerRPC = stats.Int64("grpc.io/server/sent_bytes_per_rpc", "Total bytes sent in across all response messages per RPC.", stats.UnitBytes) - ServerStartedRPCs = stats.Int64("grpc.io/server/started_rpcs", "Number of started server RPCs.", stats.UnitDimensionless) - ServerLatency = stats.Float64("grpc.io/server/server_latency", "Time between first byte of request received to last byte of response sent, or terminal error.", stats.UnitMilliseconds) -) - -// TODO(acetechnologist): This is temporary and will need to be replaced by a -// mechanism to load these defaults from a common repository/config shared by -// all supported languages. Likely a serialized protobuf of these defaults. - -// Predefined views may be registered to collect data for the above measures. -// As always, you may also define your own custom views over measures collected by this -// package. These are declared as a convenience only; none are registered by -// default. -var ( - ServerReceivedBytesPerRPCView = &view.View{ - Name: "grpc.io/server/received_bytes_per_rpc", - Description: "Distribution of received bytes per RPC, by method.", - Measure: ServerReceivedBytesPerRPC, - TagKeys: []tag.Key{KeyServerMethod}, - Aggregation: DefaultBytesDistribution, - } - - ServerSentBytesPerRPCView = &view.View{ - Name: "grpc.io/server/sent_bytes_per_rpc", - Description: "Distribution of total sent bytes per RPC, by method.", - Measure: ServerSentBytesPerRPC, - TagKeys: []tag.Key{KeyServerMethod}, - Aggregation: DefaultBytesDistribution, - } - - ServerLatencyView = &view.View{ - Name: "grpc.io/server/server_latency", - Description: "Distribution of server latency in milliseconds, by method.", - TagKeys: []tag.Key{KeyServerMethod}, - Measure: ServerLatency, - Aggregation: DefaultMillisecondsDistribution, - } - - // Purposely reuses the count from `ServerLatency`, tagging - // with method and status to result in ServerCompletedRpcs. - ServerCompletedRPCsView = &view.View{ - Name: "grpc.io/server/completed_rpcs", - Description: "Count of RPCs by method and status.", - TagKeys: []tag.Key{KeyServerMethod, KeyServerStatus}, - Measure: ServerLatency, - Aggregation: view.Count(), - } - - ServerStartedRPCsView = &view.View{ - Measure: ServerStartedRPCs, - Name: "grpc.io/server/started_rpcs", - Description: "Number of started server RPCs.", - TagKeys: []tag.Key{KeyServerMethod}, - Aggregation: view.Count(), - } - - ServerReceivedMessagesPerRPCView = &view.View{ - Name: "grpc.io/server/received_messages_per_rpc", - Description: "Distribution of messages received count per RPC, by method.", - TagKeys: []tag.Key{KeyServerMethod}, - Measure: ServerReceivedMessagesPerRPC, - Aggregation: DefaultMessageCountDistribution, - } - - ServerSentMessagesPerRPCView = &view.View{ - Name: "grpc.io/server/sent_messages_per_rpc", - Description: "Distribution of messages sent count per RPC, by method.", - TagKeys: []tag.Key{KeyServerMethod}, - Measure: ServerSentMessagesPerRPC, - Aggregation: DefaultMessageCountDistribution, - } -) - -// DefaultServerViews are the default server views provided by this package. -var DefaultServerViews = []*view.View{ - ServerReceivedBytesPerRPCView, - ServerSentBytesPerRPCView, - ServerLatencyView, - ServerCompletedRPCsView, -} diff --git a/vendor/go.opencensus.io/plugin/ocgrpc/server_stats_handler.go b/vendor/go.opencensus.io/plugin/ocgrpc/server_stats_handler.go deleted file mode 100644 index afcef023af..0000000000 --- a/vendor/go.opencensus.io/plugin/ocgrpc/server_stats_handler.go +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2017, OpenCensus Authors -// -// 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. -// - -package ocgrpc - -import ( - "time" - - "context" - - "go.opencensus.io/tag" - "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/stats" -) - -// statsTagRPC gets the metadata from gRPC context, extracts the encoded tags from -// it and creates a new tag.Map and puts them into the returned context. -func (h *ServerHandler) statsTagRPC(ctx context.Context, info *stats.RPCTagInfo) context.Context { - startTime := time.Now() - if info == nil { - if grpclog.V(2) { - grpclog.Infof("opencensus: TagRPC called with nil info.") - } - return ctx - } - d := &rpcData{ - startTime: startTime, - method: info.FullMethodName, - } - propagated := h.extractPropagatedTags(ctx) - ctx = tag.NewContext(ctx, propagated) - ctx, _ = tag.New(ctx, tag.Upsert(KeyServerMethod, methodName(info.FullMethodName))) - return context.WithValue(ctx, rpcDataKey, d) -} - -// extractPropagatedTags creates a new tag map containing the tags extracted from the -// gRPC metadata. -func (h *ServerHandler) extractPropagatedTags(ctx context.Context) *tag.Map { - buf := stats.Tags(ctx) - if buf == nil { - return nil - } - propagated, err := tag.Decode(buf) - if err != nil { - if grpclog.V(2) { - grpclog.Warningf("opencensus: Failed to decode tags from gRPC metadata failed to decode: %v", err) - } - return nil - } - return propagated -} diff --git a/vendor/go.opencensus.io/plugin/ocgrpc/stats_common.go b/vendor/go.opencensus.io/plugin/ocgrpc/stats_common.go deleted file mode 100644 index 9cb27320ca..0000000000 --- a/vendor/go.opencensus.io/plugin/ocgrpc/stats_common.go +++ /dev/null @@ -1,248 +0,0 @@ -// Copyright 2017, OpenCensus Authors -// -// 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. -// - -package ocgrpc - -import ( - "context" - "strconv" - "strings" - "sync/atomic" - "time" - - "go.opencensus.io/metric/metricdata" - ocstats "go.opencensus.io/stats" - "go.opencensus.io/stats/view" - "go.opencensus.io/tag" - "go.opencensus.io/trace" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/stats" - "google.golang.org/grpc/status" -) - -type grpcInstrumentationKey string - -// rpcData holds the instrumentation RPC data that is needed between the start -// and end of an call. It holds the info that this package needs to keep track -// of between the various GRPC events. -type rpcData struct { - // reqCount and respCount has to be the first words - // in order to be 64-aligned on 32-bit architectures. - sentCount, sentBytes, recvCount, recvBytes int64 // access atomically - - // startTime represents the time at which TagRPC was invoked at the - // beginning of an RPC. It is an appoximation of the time when the - // application code invoked GRPC code. - startTime time.Time - method string -} - -// The following variables define the default hard-coded auxiliary data used by -// both the default GRPC client and GRPC server metrics. -var ( - DefaultBytesDistribution = view.Distribution(1024, 2048, 4096, 16384, 65536, 262144, 1048576, 4194304, 16777216, 67108864, 268435456, 1073741824, 4294967296) - DefaultMillisecondsDistribution = view.Distribution(0.01, 0.05, 0.1, 0.3, 0.6, 0.8, 1, 2, 3, 4, 5, 6, 8, 10, 13, 16, 20, 25, 30, 40, 50, 65, 80, 100, 130, 160, 200, 250, 300, 400, 500, 650, 800, 1000, 2000, 5000, 10000, 20000, 50000, 100000) - DefaultMessageCountDistribution = view.Distribution(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536) -) - -// Server tags are applied to the context used to process each RPC, as well as -// the measures at the end of each RPC. -var ( - KeyServerMethod = tag.MustNewKey("grpc_server_method") - KeyServerStatus = tag.MustNewKey("grpc_server_status") -) - -// Client tags are applied to measures at the end of each RPC. -var ( - KeyClientMethod = tag.MustNewKey("grpc_client_method") - KeyClientStatus = tag.MustNewKey("grpc_client_status") -) - -var ( - rpcDataKey = grpcInstrumentationKey("opencensus-rpcData") -) - -func methodName(fullname string) string { - return strings.TrimLeft(fullname, "/") -} - -// statsHandleRPC processes the RPC events. -func statsHandleRPC(ctx context.Context, s stats.RPCStats) { - switch st := s.(type) { - case *stats.OutHeader, *stats.InHeader, *stats.InTrailer, *stats.OutTrailer: - // do nothing for client - case *stats.Begin: - handleRPCBegin(ctx, st) - case *stats.OutPayload: - handleRPCOutPayload(ctx, st) - case *stats.InPayload: - handleRPCInPayload(ctx, st) - case *stats.End: - handleRPCEnd(ctx, st) - default: - grpclog.Infof("unexpected stats: %T", st) - } -} - -func handleRPCBegin(ctx context.Context, s *stats.Begin) { - d, ok := ctx.Value(rpcDataKey).(*rpcData) - if !ok { - if grpclog.V(2) { - grpclog.Infoln("Failed to retrieve *rpcData from context.") - } - } - - if s.IsClient() { - ocstats.RecordWithOptions(ctx, - ocstats.WithTags(tag.Upsert(KeyClientMethod, methodName(d.method))), - ocstats.WithMeasurements(ClientStartedRPCs.M(1))) - } else { - ocstats.RecordWithOptions(ctx, - ocstats.WithTags(tag.Upsert(KeyClientMethod, methodName(d.method))), - ocstats.WithMeasurements(ServerStartedRPCs.M(1))) - } -} - -func handleRPCOutPayload(ctx context.Context, s *stats.OutPayload) { - d, ok := ctx.Value(rpcDataKey).(*rpcData) - if !ok { - if grpclog.V(2) { - grpclog.Infoln("Failed to retrieve *rpcData from context.") - } - return - } - - atomic.AddInt64(&d.sentBytes, int64(s.Length)) - atomic.AddInt64(&d.sentCount, 1) -} - -func handleRPCInPayload(ctx context.Context, s *stats.InPayload) { - d, ok := ctx.Value(rpcDataKey).(*rpcData) - if !ok { - if grpclog.V(2) { - grpclog.Infoln("Failed to retrieve *rpcData from context.") - } - return - } - - atomic.AddInt64(&d.recvBytes, int64(s.Length)) - atomic.AddInt64(&d.recvCount, 1) -} - -func handleRPCEnd(ctx context.Context, s *stats.End) { - d, ok := ctx.Value(rpcDataKey).(*rpcData) - if !ok { - if grpclog.V(2) { - grpclog.Infoln("Failed to retrieve *rpcData from context.") - } - return - } - - elapsedTime := time.Since(d.startTime) - - var st string - if s.Error != nil { - s, ok := status.FromError(s.Error) - if ok { - st = statusCodeToString(s) - } - } else { - st = "OK" - } - - latencyMillis := float64(elapsedTime) / float64(time.Millisecond) - attachments := getSpanCtxAttachment(ctx) - if s.Client { - ocstats.RecordWithOptions(ctx, - ocstats.WithTags( - tag.Upsert(KeyClientMethod, methodName(d.method)), - tag.Upsert(KeyClientStatus, st)), - ocstats.WithAttachments(attachments), - ocstats.WithMeasurements( - ClientSentBytesPerRPC.M(atomic.LoadInt64(&d.sentBytes)), - ClientSentMessagesPerRPC.M(atomic.LoadInt64(&d.sentCount)), - ClientReceivedMessagesPerRPC.M(atomic.LoadInt64(&d.recvCount)), - ClientReceivedBytesPerRPC.M(atomic.LoadInt64(&d.recvBytes)), - ClientRoundtripLatency.M(latencyMillis))) - } else { - ocstats.RecordWithOptions(ctx, - ocstats.WithTags( - tag.Upsert(KeyServerStatus, st), - ), - ocstats.WithAttachments(attachments), - ocstats.WithMeasurements( - ServerSentBytesPerRPC.M(atomic.LoadInt64(&d.sentBytes)), - ServerSentMessagesPerRPC.M(atomic.LoadInt64(&d.sentCount)), - ServerReceivedMessagesPerRPC.M(atomic.LoadInt64(&d.recvCount)), - ServerReceivedBytesPerRPC.M(atomic.LoadInt64(&d.recvBytes)), - ServerLatency.M(latencyMillis))) - } -} - -func statusCodeToString(s *status.Status) string { - // see https://github.com/grpc/grpc/blob/master/doc/statuscodes.md - switch c := s.Code(); c { - case codes.OK: - return "OK" - case codes.Canceled: - return "CANCELLED" - case codes.Unknown: - return "UNKNOWN" - case codes.InvalidArgument: - return "INVALID_ARGUMENT" - case codes.DeadlineExceeded: - return "DEADLINE_EXCEEDED" - case codes.NotFound: - return "NOT_FOUND" - case codes.AlreadyExists: - return "ALREADY_EXISTS" - case codes.PermissionDenied: - return "PERMISSION_DENIED" - case codes.ResourceExhausted: - return "RESOURCE_EXHAUSTED" - case codes.FailedPrecondition: - return "FAILED_PRECONDITION" - case codes.Aborted: - return "ABORTED" - case codes.OutOfRange: - return "OUT_OF_RANGE" - case codes.Unimplemented: - return "UNIMPLEMENTED" - case codes.Internal: - return "INTERNAL" - case codes.Unavailable: - return "UNAVAILABLE" - case codes.DataLoss: - return "DATA_LOSS" - case codes.Unauthenticated: - return "UNAUTHENTICATED" - default: - return "CODE_" + strconv.FormatInt(int64(c), 10) - } -} - -func getSpanCtxAttachment(ctx context.Context) metricdata.Attachments { - attachments := map[string]interface{}{} - span := trace.FromContext(ctx) - if span == nil { - return attachments - } - spanCtx := span.SpanContext() - if spanCtx.IsSampled() { - attachments[metricdata.AttachmentKeySpanContext] = spanCtx - } - return attachments -} diff --git a/vendor/go.opencensus.io/plugin/ocgrpc/trace_common.go b/vendor/go.opencensus.io/plugin/ocgrpc/trace_common.go deleted file mode 100644 index 61bc543d0a..0000000000 --- a/vendor/go.opencensus.io/plugin/ocgrpc/trace_common.go +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2017, OpenCensus Authors -// -// 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. - -package ocgrpc - -import ( - "context" - "strings" - - "google.golang.org/grpc/codes" - "google.golang.org/grpc/metadata" - "google.golang.org/grpc/stats" - "google.golang.org/grpc/status" - - "go.opencensus.io/trace" - "go.opencensus.io/trace/propagation" -) - -const traceContextKey = "grpc-trace-bin" - -// TagRPC creates a new trace span for the client side of the RPC. -// -// It returns ctx with the new trace span added and a serialization of the -// SpanContext added to the outgoing gRPC metadata. -func (c *ClientHandler) traceTagRPC(ctx context.Context, rti *stats.RPCTagInfo) context.Context { - name := strings.TrimPrefix(rti.FullMethodName, "/") - name = strings.Replace(name, "/", ".", -1) - ctx, span := trace.StartSpan(ctx, name, - trace.WithSampler(c.StartOptions.Sampler), - trace.WithSpanKind(trace.SpanKindClient)) // span is ended by traceHandleRPC - traceContextBinary := propagation.Binary(span.SpanContext()) - return metadata.AppendToOutgoingContext(ctx, traceContextKey, string(traceContextBinary)) -} - -// TagRPC creates a new trace span for the server side of the RPC. -// -// It checks the incoming gRPC metadata in ctx for a SpanContext, and if -// it finds one, uses that SpanContext as the parent context of the new span. -// -// It returns ctx, with the new trace span added. -func (s *ServerHandler) traceTagRPC(ctx context.Context, rti *stats.RPCTagInfo) context.Context { - md, _ := metadata.FromIncomingContext(ctx) - name := strings.TrimPrefix(rti.FullMethodName, "/") - name = strings.Replace(name, "/", ".", -1) - traceContext := md[traceContextKey] - var ( - parent trace.SpanContext - haveParent bool - ) - if len(traceContext) > 0 { - // Metadata with keys ending in -bin are actually binary. They are base64 - // encoded before being put on the wire, see: - // https://github.com/grpc/grpc-go/blob/08d6261/Documentation/grpc-metadata.md#storing-binary-data-in-metadata - traceContextBinary := []byte(traceContext[0]) - parent, haveParent = propagation.FromBinary(traceContextBinary) - if haveParent && !s.IsPublicEndpoint { - ctx, _ := trace.StartSpanWithRemoteParent(ctx, name, parent, - trace.WithSpanKind(trace.SpanKindServer), - trace.WithSampler(s.StartOptions.Sampler), - ) - return ctx - } - } - ctx, span := trace.StartSpan(ctx, name, - trace.WithSpanKind(trace.SpanKindServer), - trace.WithSampler(s.StartOptions.Sampler)) - if haveParent { - span.AddLink(trace.Link{TraceID: parent.TraceID, SpanID: parent.SpanID, Type: trace.LinkTypeChild}) - } - return ctx -} - -func traceHandleRPC(ctx context.Context, rs stats.RPCStats) { - span := trace.FromContext(ctx) - // TODO: compressed and uncompressed sizes are not populated in every message. - switch rs := rs.(type) { - case *stats.Begin: - span.AddAttributes( - trace.BoolAttribute("Client", rs.Client), - trace.BoolAttribute("FailFast", rs.FailFast)) - case *stats.InPayload: - span.AddMessageReceiveEvent(0 /* TODO: messageID */, int64(rs.Length), int64(rs.WireLength)) - case *stats.OutPayload: - span.AddMessageSendEvent(0, int64(rs.Length), int64(rs.WireLength)) - case *stats.End: - if rs.Error != nil { - s, ok := status.FromError(rs.Error) - if ok { - span.SetStatus(trace.Status{Code: int32(s.Code()), Message: s.Message()}) - } else { - span.SetStatus(trace.Status{Code: int32(codes.Internal), Message: rs.Error.Error()}) - } - } - span.End() - } -} diff --git a/vendor/go.opencensus.io/zpages/internal/resources.go b/vendor/go.opencensus.io/zpages/internal/resources.go deleted file mode 100644 index 5b7fc76b29..0000000000 --- a/vendor/go.opencensus.io/zpages/internal/resources.go +++ /dev/null @@ -1,284 +0,0 @@ -// Code generated by "esc -pkg resources -o resources.go public/ templates/"; DO NOT EDIT. - -package internal - -import ( - "bytes" - "compress/gzip" - "encoding/base64" - "io/ioutil" - "net/http" - "os" - "path" - "sync" - "time" -) - -type _escLocalFS struct{} - -var _escLocal _escLocalFS - -type _escStaticFS struct{} - -var _escStatic _escStaticFS - -type _escDirectory struct { - fs http.FileSystem - name string -} - -type _escFile struct { - compressed string - size int64 - modtime int64 - local string - isDir bool - - once sync.Once - data []byte - name string -} - -func (_escLocalFS) Open(name string) (http.File, error) { - f, present := _escData[path.Clean(name)] - if !present { - return nil, os.ErrNotExist - } - return os.Open(f.local) -} - -func (_escStaticFS) prepare(name string) (*_escFile, error) { - f, present := _escData[path.Clean(name)] - if !present { - return nil, os.ErrNotExist - } - var err error - f.once.Do(func() { - f.name = path.Base(name) - if f.size == 0 { - return - } - var gr *gzip.Reader - b64 := base64.NewDecoder(base64.StdEncoding, bytes.NewBufferString(f.compressed)) - gr, err = gzip.NewReader(b64) - if err != nil { - return - } - f.data, err = ioutil.ReadAll(gr) - }) - if err != nil { - return nil, err - } - return f, nil -} - -func (fs _escStaticFS) Open(name string) (http.File, error) { - f, err := fs.prepare(name) - if err != nil { - return nil, err - } - return f.File() -} - -func (dir _escDirectory) Open(name string) (http.File, error) { - return dir.fs.Open(dir.name + name) -} - -func (f *_escFile) File() (http.File, error) { - type httpFile struct { - *bytes.Reader - *_escFile - } - return &httpFile{ - Reader: bytes.NewReader(f.data), - _escFile: f, - }, nil -} - -func (f *_escFile) Close() error { - return nil -} - -func (f *_escFile) Readdir(count int) ([]os.FileInfo, error) { - return nil, nil -} - -func (f *_escFile) Stat() (os.FileInfo, error) { - return f, nil -} - -func (f *_escFile) Name() string { - return f.name -} - -func (f *_escFile) Size() int64 { - return f.size -} - -func (f *_escFile) Mode() os.FileMode { - return 0 -} - -func (f *_escFile) ModTime() time.Time { - return time.Unix(f.modtime, 0) -} - -func (f *_escFile) IsDir() bool { - return f.isDir -} - -func (f *_escFile) Sys() interface{} { - return f -} - -// FS returns a http.Filesystem for the embedded assets. If useLocal is true, -// the filesystem's contents are instead used. -func FS(useLocal bool) http.FileSystem { - if useLocal { - return _escLocal - } - return _escStatic -} - -// Dir returns a http.Filesystem for the embedded assets on a given prefix dir. -// If useLocal is true, the filesystem's contents are instead used. -func Dir(useLocal bool, name string) http.FileSystem { - if useLocal { - return _escDirectory{fs: _escLocal, name: name} - } - return _escDirectory{fs: _escStatic, name: name} -} - -// FSByte returns the named file from the embedded assets. If useLocal is -// true, the filesystem's contents are instead used. -func FSByte(useLocal bool, name string) ([]byte, error) { - if useLocal { - f, err := _escLocal.Open(name) - if err != nil { - return nil, err - } - b, err := ioutil.ReadAll(f) - _ = f.Close() - return b, err - } - f, err := _escStatic.prepare(name) - if err != nil { - return nil, err - } - return f.data, nil -} - -// FSMustByte is the same as FSByte, but panics if name is not present. -func FSMustByte(useLocal bool, name string) []byte { - b, err := FSByte(useLocal, name) - if err != nil { - panic(err) - } - return b -} - -// FSString is the string version of FSByte. -func FSString(useLocal bool, name string) (string, error) { - b, err := FSByte(useLocal, name) - return string(b), err -} - -// FSMustString is the string version of FSMustByte. -func FSMustString(useLocal bool, name string) string { - return string(FSMustByte(useLocal, name)) -} - -var _escData = map[string]*_escFile{ - - "/public/opencensus.css": { - local: "public/opencensus.css", - size: 0, - modtime: 1519153040, - compressed: ` -H4sIAAAAAAAC/wEAAP//AAAAAAAAAAA= -`, - }, - - "/templates/footer.html": { - local: "templates/footer.html", - size: 16, - modtime: 1519153248, - compressed: ` -H4sIAAAAAAAC/7LRT8pPqbTjstHPKMnNseMCBAAA//8ATCBFEAAAAA== -`, - }, - - "/templates/header.html": { - local: "templates/header.html", - size: 523, - modtime: 1519164535, - compressed: ` -H4sIAAAAAAAC/5TRv07rMBQG8D1P4ev1qvat7oKQEwZgYEAwdGF0nZP4UP+JfE6oqqrvjkyKBGIpky0f -+6fP+syfu6fbzcvzvfAcQ9eYuohg09hKSLIzHmzfNUIIYSKwFc7bQsCtnHlYXcnziJEDdMej2tTN6WT0 -crJMA6adKBBaST4XdjMLdDlJ4QsMrdR6v9+rPEFykGgmhVkP9q1eUeiy1D8ZPgQgD8CfxjRvAzr9BXFE -F730zBNdaz3kxKTGnMcAdkJSLkddM9wMNmI4tI+WoaANfx9cTiR/QbvcgxqBYx/q39bqv/qn45lTmHoc -82rCtFMR00fwM06u4MSihwGKoOIuJSvzSrIzehG6xuilSLPN/aHWvP7Wll93zXsAAAD//6iqQ1ULAgAA -`, - }, - - "/templates/rpcz.html": { - local: "templates/rpcz.html", - size: 2626, - modtime: 1519164559, - compressed: ` -H4sIAAAAAAAC/+yW3WrbMBTH7/0UwmUjYyxJU3o1W1C6sQ4WNrq+gCwdfzBFMtJx9+Hl3cex3DhNCrOz -XfbGxFZ+5/8D+Ry5bZ0wBbD5VxT4wdmm9tttlNQ8QZFpYFkhrbYuPQMAyHP2vVJYpufL5QueoGNCV4VJ -JRgExxNUPMmtQearX5C+XvG2nb+rHEisrNlukwUt8mRB/1ugowuF8GRR8+ggMD7L8/wSIGa5ExtIM/uD -SdDa10JWpkiX3V0tlKK7FY8ixhgjp6ECAFwqiHm3FJZLCi2DKnnsLzGphfdprM9jJi0lmfSCX9vG4FTo -6r5gWiAY+ZPNNv7VVP5WILCZq+ViOvvR1A2y2bfsBPZzg6fD752zzndU2Aza47H70r9KGnLka8DSql38 -S5P5+u3x9Vgr1HBVUSJfV2bel3i8cOOefn5ncf6c+Zz5XzKfaADyGLrlYn9UvlnxB52DERlFw4Q2oval -RRrQDyX3zBVPMhq4oXlo2mZHjXvcyqrXjzv/mAp0A29dmQbht6TfVGscdWMbN5W5syj0I2ik59V98SmM -2F5240elDlynO5kKwjtspO3tl2sa6r2qEwijYnusM50KBdE9aqRqd4DsySqBYnT2Du6UT0OD+AE7Uj6c -YKfaD/R0/YH9F/9wiE5uv4BN7L8A/a0BwxxqWzCKPg37b7bdgz8BAAD//6NjPmJCCgAA -`, - }, - - "/templates/summary.html": { - local: "templates/summary.html", - size: 1619, - modtime: 1519164559, - compressed: ` -H4sIAAAAAAAC/6yVPW/bMBCG9/yKg2p4qu2kW12JRQtkCzok3YoOlHSWBdMngaSc2iz/e8EP+Stqi8Re -DIo63t3zvjwr1TwXCEpvBWZJ3sgS5US1vKipmsNtwm4AAFItwyI8lFA0QrWcsjvgoq4oE7jQLM3ZU8sJ -vvE1prOcpTNdnhxjY8pV+yn8/j5+8KFDiZMCSaNMXPLHjqim6i2pB5v/OFDjgWukYgtPfN0KVFerNcRz -L2Ujhyuls17xv0t/pcbelsYYyalCmEbBvnbFCrVzXlmb6uU/wX8YM7X2Z0ReMmOQSmuviRIENGbEYZ7B -9LvkBap7KtumJm2teyNqWin/9sGt/GaAGsnmuaYSf733Sx/z2DyHkAmMiK/RbzreuFkvADdIh7NOBrkf -LF6sKtl0VM7hHSImjlko9EGBHyZRAUdvTMzdD8b/9IgtRKijVC/k57CUuMgSp421n3dOOgeUGePBrB3v -9LbF7NY1Of1S6HrjG+HsUMr1ft7wIXIfdUb1aoa9Ib0bGy66IH28d07ACxjvxjvV5X5pzCj65rhDpSPs -/o6e0J9Pge+G+dv98tClYlxs6IcDbPDW/wGpE8cGfB2Iiij9kHnIdOY/JezmTwAAAP//Dz6TJ1MGAAA= -`, - }, - - "/templates/traces.html": { - local: "templates/traces.html", - size: 420, - modtime: 1519164578, - compressed: ` -H4sIAAAAAAAC/4yQsU70MBCEez/FKtIv3RW/w6WgOIw7kGgoDiRqO14gwnGM1xEgs++OnKMA5Qq2ssYz -I82nolZW30UT4NaMuIdSZH0wg2qtVm3UQkVd1XlkhgO+zkiZvj8SavHwjAFO35U3kdDBhrDfiv9/PFFK -MuEJQR6mN2IuJaYh5Edo/nXn1MBmCA7fQV4P6B3B2ZYZfnh23dqzO3p+i12tlp85mR4HxyxKweCYVbvs -UjYt25UFyh8eL5t+8lPaWz/jRaPva+zGVUowogkEZMbo0UE6MpKiIlinTf9yMh6mvKpYMH8FAAD//yQs -JUakAQAA -`, - }, - - "/": { - isDir: true, - local: "", - }, - - "/public": { - isDir: true, - local: "public", - }, - - "/templates": { - isDir: true, - local: "templates", - }, -} diff --git a/vendor/go.opencensus.io/zpages/rpcz.go b/vendor/go.opencensus.io/zpages/rpcz.go deleted file mode 100644 index ef4dd15b32..0000000000 --- a/vendor/go.opencensus.io/zpages/rpcz.go +++ /dev/null @@ -1,333 +0,0 @@ -// Copyright 2017, OpenCensus Authors -// -// 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. -// - -package zpages - -import ( - "fmt" - "io" - "log" - "math" - "net/http" - "sort" - "sync" - "text/tabwriter" - "time" - - "go.opencensus.io/plugin/ocgrpc" - "go.opencensus.io/stats/view" -) - -const bytesPerKb = 1024 - -var ( - programStartTime = time.Now() - mu sync.Mutex // protects snaps - snaps = make(map[methodKey]*statSnapshot) - - // viewType lists the views we are interested in for RPC stats. - // A view's map value indicates whether that view contains data for received - // RPCs. - viewType = map[*view.View]bool{ - ocgrpc.ClientCompletedRPCsView: false, - ocgrpc.ClientSentBytesPerRPCView: false, - ocgrpc.ClientSentMessagesPerRPCView: false, - ocgrpc.ClientReceivedBytesPerRPCView: false, - ocgrpc.ClientReceivedMessagesPerRPCView: false, - ocgrpc.ClientRoundtripLatencyView: false, - ocgrpc.ServerCompletedRPCsView: true, - ocgrpc.ServerReceivedBytesPerRPCView: true, - ocgrpc.ServerReceivedMessagesPerRPCView: true, - ocgrpc.ServerSentBytesPerRPCView: true, - ocgrpc.ServerSentMessagesPerRPCView: true, - ocgrpc.ServerLatencyView: true, - } -) - -func registerRPCViews() { - views := make([]*view.View, 0, len(viewType)) - for v := range viewType { - views = append(views, v) - } - if err := view.Register(views...); err != nil { - log.Printf("error subscribing to views: %v", err) - } - view.RegisterExporter(snapExporter{}) -} - -func rpczHandler(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "text/html; charset=utf-8") - WriteHTMLRpczPage(w) -} - -// WriteHTMLRpczPage writes an HTML document to w containing per-method RPC stats. -func WriteHTMLRpczPage(w io.Writer) { - if err := headerTemplate.Execute(w, headerData{Title: "RPC Stats"}); err != nil { - log.Printf("zpages: executing template: %v", err) - } - WriteHTMLRpczSummary(w) - if err := footerTemplate.Execute(w, nil); err != nil { - log.Printf("zpages: executing template: %v", err) - } -} - -// WriteHTMLRpczSummary writes HTML to w containing per-method RPC stats. -// -// It includes neither a header nor footer, so you can embed this data in other pages. -func WriteHTMLRpczSummary(w io.Writer) { - mu.Lock() - if err := statsTemplate.Execute(w, getStatsPage()); err != nil { - log.Printf("zpages: executing template: %v", err) - } - mu.Unlock() -} - -// WriteTextRpczPage writes formatted text to w containing per-method RPC stats. -func WriteTextRpczPage(w io.Writer) { - mu.Lock() - defer mu.Unlock() - page := getStatsPage() - - for i, sg := range page.StatGroups { - switch i { - case 0: - fmt.Fprint(w, "Sent:\n") - case 1: - fmt.Fprint(w, "\nReceived:\n") - } - tw := tabwriter.NewWriter(w, 6, 8, 1, ' ', 0) - fmt.Fprint(tw, "Method\tCount\t\t\tAvgLat\t\t\tMaxLat\t\t\tRate\t\t\tIn (MiB/s)\t\t\tOut (MiB/s)\t\t\tErrors\t\t\n") - fmt.Fprint(tw, "\tMin\tHr\tTot\tMin\tHr\tTot\tMin\tHr\tTot\tMin\tHr\tTot\tMin\tHr\tTot\tMin\tHr\tTot\tMin\tHr\tTot\n") - for _, s := range sg.Snapshots { - fmt.Fprintf(tw, "%s\t%d\t%d\t%d\t%v\t%v\t%v\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%d\t%d\t%d\n", - s.Method, - s.CountMinute, - s.CountHour, - s.CountTotal, - s.AvgLatencyMinute, - s.AvgLatencyHour, - s.AvgLatencyTotal, - s.RPCRateMinute, - s.RPCRateHour, - s.RPCRateTotal, - s.InputRateMinute/bytesPerKb, - s.InputRateHour/bytesPerKb, - s.InputRateTotal/bytesPerKb, - s.OutputRateMinute/bytesPerKb, - s.OutputRateHour/bytesPerKb, - s.OutputRateTotal/bytesPerKb, - s.ErrorsMinute, - s.ErrorsHour, - s.ErrorsTotal) - } - tw.Flush() - } -} - -// headerData contains data for the header template. -type headerData struct { - Title string -} - -// statsPage aggregates stats on the page for 'sent' and 'received' categories -type statsPage struct { - StatGroups []*statGroup -} - -// statGroup aggregates snapshots for a directional category -type statGroup struct { - Direction string - Snapshots []*statSnapshot -} - -func (s *statGroup) Len() int { - return len(s.Snapshots) -} - -func (s *statGroup) Swap(i, j int) { - s.Snapshots[i], s.Snapshots[j] = s.Snapshots[j], s.Snapshots[i] -} - -func (s *statGroup) Less(i, j int) bool { - return s.Snapshots[i].Method < s.Snapshots[j].Method -} - -// statSnapshot holds the data items that are presented in a single row of RPC -// stat information. -type statSnapshot struct { - // TODO: compute hour/minute values from cumulative - Method string - Received bool - CountMinute uint64 - CountHour uint64 - CountTotal uint64 - AvgLatencyMinute time.Duration - AvgLatencyHour time.Duration - AvgLatencyTotal time.Duration - RPCRateMinute float64 - RPCRateHour float64 - RPCRateTotal float64 - InputRateMinute float64 - InputRateHour float64 - InputRateTotal float64 - OutputRateMinute float64 - OutputRateHour float64 - OutputRateTotal float64 - ErrorsMinute uint64 - ErrorsHour uint64 - ErrorsTotal uint64 -} - -type methodKey struct { - method string - received bool -} - -type snapExporter struct{} - -func (s snapExporter) ExportView(vd *view.Data) { - received, ok := viewType[vd.View] - if !ok { - return - } - if len(vd.Rows) == 0 { - return - } - ageSec := float64(time.Since(programStartTime)) / float64(time.Second) - - computeRate := func(maxSec, x float64) float64 { - dur := ageSec - if maxSec > 0 && dur > maxSec { - dur = maxSec - } - return x / dur - } - - convertTime := func(ms float64) time.Duration { - if math.IsInf(ms, 0) || math.IsNaN(ms) { - return 0 - } - return time.Duration(float64(time.Millisecond) * ms) - } - - haveResetErrors := make(map[string]struct{}) - - mu.Lock() - defer mu.Unlock() - for _, row := range vd.Rows { - var method string - for _, tag := range row.Tags { - if tag.Key == ocgrpc.KeyClientMethod || tag.Key == ocgrpc.KeyServerMethod { - method = tag.Value - break - } - } - - key := methodKey{method: method, received: received} - s := snaps[key] - if s == nil { - s = &statSnapshot{Method: method, Received: received} - snaps[key] = s - } - - var ( - sum float64 - count float64 - ) - switch v := row.Data.(type) { - case *view.CountData: - sum = float64(v.Value) - count = float64(v.Value) - case *view.DistributionData: - sum = v.Sum() - count = float64(v.Count) - case *view.SumData: - sum = v.Value - count = v.Value - } - - // Update field of s corresponding to the view. - switch vd.View { - case ocgrpc.ClientCompletedRPCsView: - if _, ok := haveResetErrors[method]; !ok { - haveResetErrors[method] = struct{}{} - s.ErrorsTotal = 0 - } - for _, tag := range row.Tags { - if tag.Key == ocgrpc.KeyClientStatus && tag.Value != "OK" { - s.ErrorsTotal += uint64(count) - } - } - - case ocgrpc.ClientRoundtripLatencyView: - s.AvgLatencyTotal = convertTime(sum / count) - - case ocgrpc.ClientSentBytesPerRPCView: - s.OutputRateTotal = computeRate(0, sum) - - case ocgrpc.ClientReceivedBytesPerRPCView: - s.InputRateTotal = computeRate(0, sum) - - case ocgrpc.ClientSentMessagesPerRPCView: - s.CountTotal = uint64(count) - s.RPCRateTotal = computeRate(0, count) - - case ocgrpc.ClientReceivedMessagesPerRPCView: - // currently unused - - case ocgrpc.ServerCompletedRPCsView: - if _, ok := haveResetErrors[method]; !ok { - haveResetErrors[method] = struct{}{} - s.ErrorsTotal = 0 - } - for _, tag := range row.Tags { - if tag.Key == ocgrpc.KeyServerStatus && tag.Value != "OK" { - s.ErrorsTotal += uint64(count) - } - } - - case ocgrpc.ServerLatencyView: - s.AvgLatencyTotal = convertTime(sum / count) - - case ocgrpc.ServerSentBytesPerRPCView: - s.OutputRateTotal = computeRate(0, sum) - - case ocgrpc.ServerReceivedMessagesPerRPCView: - s.CountTotal = uint64(count) - s.RPCRateTotal = computeRate(0, count) - - case ocgrpc.ServerSentMessagesPerRPCView: - // currently unused - } - } -} - -func getStatsPage() *statsPage { - sentStats := statGroup{Direction: "Sent"} - receivedStats := statGroup{Direction: "Received"} - for key, sg := range snaps { - if key.received { - receivedStats.Snapshots = append(receivedStats.Snapshots, sg) - } else { - sentStats.Snapshots = append(sentStats.Snapshots, sg) - } - } - sort.Sort(&sentStats) - sort.Sort(&receivedStats) - - return &statsPage{ - StatGroups: []*statGroup{&sentStats, &receivedStats}, - } -} diff --git a/vendor/go.opencensus.io/zpages/templates.go b/vendor/go.opencensus.io/zpages/templates.go deleted file mode 100644 index 6675b0ab08..0000000000 --- a/vendor/go.opencensus.io/zpages/templates.go +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2017, OpenCensus Authors -// -// 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. -// - -package zpages - -import ( - "fmt" - "html/template" - "io/ioutil" - "log" - "strconv" - "time" - - "go.opencensus.io/trace" - "go.opencensus.io/zpages/internal" -) - -var ( - fs = internal.FS(false) - templateFunctions = template.FuncMap{ - "count": countFormatter, - "ms": msFormatter, - "rate": rateFormatter, - "datarate": dataRateFormatter, - "even": even, - "traceid": traceIDFormatter, - } - headerTemplate = parseTemplate("header") - summaryTableTemplate = parseTemplate("summary") - statsTemplate = parseTemplate("rpcz") - tracesTableTemplate = parseTemplate("traces") - footerTemplate = parseTemplate("footer") -) - -func parseTemplate(name string) *template.Template { - f, err := fs.Open("/templates/" + name + ".html") - if err != nil { - log.Panicf("%v: %v", name, err) - } - defer f.Close() - text, err := ioutil.ReadAll(f) - if err != nil { - log.Panicf("%v: %v", name, err) - } - return template.Must(template.New(name).Funcs(templateFunctions).Parse(string(text))) -} - -func countFormatter(num uint64) string { - if num <= 0 { - return " " - } - var floatVal float64 - var suffix string - - if num >= 1e18 { - floatVal = float64(num) / 1e18 - suffix = " E " - } else if num >= 1e15 { - floatVal = float64(num) / 1e15 - suffix = " P " - } else if num >= 1e12 { - floatVal = float64(num) / 1e12 - suffix = " T " - } else if num >= 1e9 { - floatVal = float64(num) / 1e9 - suffix = " G " - } else if num >= 1e6 { - floatVal = float64(num) / 1e6 - suffix = " M " - } - - if floatVal != 0 { - return fmt.Sprintf("%1.3f%s", floatVal, suffix) - } - return fmt.Sprint(num) -} - -func msFormatter(d time.Duration) string { - if d == 0 { - return "0" - } - if d < 10*time.Millisecond { - return fmt.Sprintf("%.3f", float64(d)*1e-6) - } - return strconv.Itoa(int(d / time.Millisecond)) -} - -func rateFormatter(r float64) string { - return fmt.Sprintf("%.3f", r) -} - -func dataRateFormatter(b float64) string { - return fmt.Sprintf("%.3f", b/1e6) -} - -func traceIDFormatter(r traceRow) template.HTML { - sc := r.SpanContext - if sc == (trace.SpanContext{}) { - return "" - } - col := "black" - if sc.TraceOptions.IsSampled() { - col = "blue" - } - if r.ParentSpanID != (trace.SpanID{}) { - return template.HTML(fmt.Sprintf(`trace_id: %s span_id: %s parent_span_id: %s`, col, sc.TraceID, sc.SpanID, r.ParentSpanID)) - } - return template.HTML(fmt.Sprintf(`trace_id: %s span_id: %s`, col, sc.TraceID, sc.SpanID)) -} - -func even(x int) bool { - return x%2 == 0 -} diff --git a/vendor/go.opencensus.io/zpages/tracez.go b/vendor/go.opencensus.io/zpages/tracez.go deleted file mode 100644 index 330022c23e..0000000000 --- a/vendor/go.opencensus.io/zpages/tracez.go +++ /dev/null @@ -1,442 +0,0 @@ -// Copyright 2017, OpenCensus Authors -// -// 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. -// - -package zpages - -import ( - "fmt" - "io" - "log" - "net/http" - "sort" - "strconv" - "strings" - "text/tabwriter" - "time" - - "go.opencensus.io/internal" - "go.opencensus.io/trace" -) - -const ( - // spanNameQueryField is the header for span name. - spanNameQueryField = "zspanname" - // spanTypeQueryField is the header for type (running = 0, latency = 1, error = 2) to display. - spanTypeQueryField = "ztype" - // spanSubtypeQueryField is the header for sub-type: - // * for latency based samples [0, 8] representing the latency buckets, where 0 is the first one; - // * for error based samples, 0 means all, otherwise the error code; - spanSubtypeQueryField = "zsubtype" - // maxTraceMessageLength is the maximum length of a message in tracez output. - maxTraceMessageLength = 1024 -) - -var ( - defaultLatencies = [...]time.Duration{ - 10 * time.Microsecond, - 100 * time.Microsecond, - time.Millisecond, - 10 * time.Millisecond, - 100 * time.Millisecond, - time.Second, - 10 * time.Second, - 100 * time.Second, - } - canonicalCodes = [...]string{ - "OK", - "CANCELLED", - "UNKNOWN", - "INVALID_ARGUMENT", - "DEADLINE_EXCEEDED", - "NOT_FOUND", - "ALREADY_EXISTS", - "PERMISSION_DENIED", - "RESOURCE_EXHAUSTED", - "FAILED_PRECONDITION", - "ABORTED", - "OUT_OF_RANGE", - "UNIMPLEMENTED", - "INTERNAL", - "UNAVAILABLE", - "DATA_LOSS", - "UNAUTHENTICATED", - } -) - -func canonicalCodeString(code int32) string { - if code < 0 || int(code) >= len(canonicalCodes) { - return "error code " + strconv.FormatInt(int64(code), 10) - } - return canonicalCodes[code] -} - -func tracezHandler(w http.ResponseWriter, r *http.Request) { - r.ParseForm() - w.Header().Set("Content-Type", "text/html; charset=utf-8") - name := r.Form.Get(spanNameQueryField) - t, _ := strconv.Atoi(r.Form.Get(spanTypeQueryField)) - st, _ := strconv.Atoi(r.Form.Get(spanSubtypeQueryField)) - WriteHTMLTracezPage(w, name, t, st) -} - -// WriteHTMLTracezPage writes an HTML document to w containing locally-sampled trace spans. -func WriteHTMLTracezPage(w io.Writer, spanName string, spanType, spanSubtype int) { - if err := headerTemplate.Execute(w, headerData{Title: "Trace Spans"}); err != nil { - log.Printf("zpages: executing template: %v", err) - } - WriteHTMLTracezSummary(w) - WriteHTMLTracezSpans(w, spanName, spanType, spanSubtype) - if err := footerTemplate.Execute(w, nil); err != nil { - log.Printf("zpages: executing template: %v", err) - } -} - -// WriteHTMLTracezSummary writes HTML to w containing a summary of locally-sampled trace spans. -// -// It includes neither a header nor footer, so you can embed this data in other pages. -func WriteHTMLTracezSummary(w io.Writer) { - if err := summaryTableTemplate.Execute(w, getSummaryPageData()); err != nil { - log.Printf("zpages: executing template: %v", err) - } -} - -// WriteHTMLTracezSpans writes HTML to w containing locally-sampled trace spans. -// -// It includes neither a header nor footer, so you can embed this data in other pages. -func WriteHTMLTracezSpans(w io.Writer, spanName string, spanType, spanSubtype int) { - if spanName == "" { - return - } - if err := tracesTableTemplate.Execute(w, traceDataFromSpans(spanName, traceSpans(spanName, spanType, spanSubtype))); err != nil { - log.Printf("zpages: executing template: %v", err) - } -} - -// WriteTextTracezSpans writes formatted text to w containing locally-sampled trace spans. -func WriteTextTracezSpans(w io.Writer, spanName string, spanType, spanSubtype int) { - spans := traceSpans(spanName, spanType, spanSubtype) - data := traceDataFromSpans(spanName, spans) - writeTextTraces(w, data) -} - -// WriteTextTracezSummary writes formatted text to w containing a summary of locally-sampled trace spans. -func WriteTextTracezSummary(w io.Writer) { - w.Write([]byte("Locally sampled spans summary\n\n")) - - data := getSummaryPageData() - if len(data.Rows) == 0 { - return - } - - tw := tabwriter.NewWriter(w, 8, 8, 1, ' ', 0) - - for i, s := range data.Header { - if i != 0 { - tw.Write([]byte("\t")) - } - tw.Write([]byte(s)) - } - tw.Write([]byte("\n")) - - put := func(x int) { - if x == 0 { - tw.Write([]byte(".\t")) - return - } - fmt.Fprintf(tw, "%d\t", x) - } - for _, r := range data.Rows { - tw.Write([]byte(r.Name)) - tw.Write([]byte("\t")) - put(r.Active) - for _, l := range r.Latency { - put(l) - } - put(r.Errors) - tw.Write([]byte("\n")) - } - tw.Flush() -} - -// traceData contains data for the trace data template. -type traceData struct { - Name string - Num int - Rows []traceRow -} - -type traceRow struct { - Fields [3]string - trace.SpanContext - ParentSpanID trace.SpanID -} - -type events []interface{} - -func (e events) Len() int { return len(e) } -func (e events) Less(i, j int) bool { - var ti time.Time - switch x := e[i].(type) { - case *trace.Annotation: - ti = x.Time - case *trace.MessageEvent: - ti = x.Time - } - switch x := e[j].(type) { - case *trace.Annotation: - return ti.Before(x.Time) - case *trace.MessageEvent: - return ti.Before(x.Time) - } - return false -} - -func (e events) Swap(i, j int) { e[i], e[j] = e[j], e[i] } - -func traceRows(s *trace.SpanData) []traceRow { - start := s.StartTime - - lasty, lastm, lastd := start.Date() - wholeTime := func(t time.Time) string { - return t.Format("2006/01/02-15:04:05") + fmt.Sprintf(".%06d", t.Nanosecond()/1000) - } - formatTime := func(t time.Time) string { - y, m, d := t.Date() - if y == lasty && m == lastm && d == lastd { - return t.Format(" 15:04:05") + fmt.Sprintf(".%06d", t.Nanosecond()/1000) - } - lasty, lastm, lastd = y, m, d - return wholeTime(t) - } - - lastTime := start - formatElapsed := func(t time.Time) string { - d := t.Sub(lastTime) - lastTime = t - u := int64(d / 1000) - // There are five cases for duration printing: - // -1234567890s - // -1234.123456 - // .123456 - // 12345.123456 - // 12345678901s - switch { - case u < -9999999999: - return fmt.Sprintf("%11ds", u/1e6) - case u < 0: - sec := u / 1e6 - u -= sec * 1e6 - return fmt.Sprintf("%5d.%06d", sec, -u) - case u < 1e6: - return fmt.Sprintf(" .%6d", u) - case u <= 99999999999: - sec := u / 1e6 - u -= sec * 1e6 - return fmt.Sprintf("%5d.%06d", sec, u) - default: - return fmt.Sprintf("%11ds", u/1e6) - } - } - - firstRow := traceRow{Fields: [3]string{wholeTime(start), "", ""}, SpanContext: s.SpanContext, ParentSpanID: s.ParentSpanID} - if s.EndTime.IsZero() { - firstRow.Fields[1] = " " - } else { - firstRow.Fields[1] = formatElapsed(s.EndTime) - lastTime = start - } - out := []traceRow{firstRow} - - formatAttributes := func(a map[string]interface{}) string { - if len(a) == 0 { - return "" - } - var keys []string - for key := range a { - keys = append(keys, key) - } - sort.Strings(keys) - var s []string - for _, key := range keys { - val := a[key] - switch val.(type) { - case string: - s = append(s, fmt.Sprintf("%s=%q", key, val)) - default: - s = append(s, fmt.Sprintf("%s=%v", key, val)) - } - } - return "Attributes:{" + strings.Join(s, ", ") + "}" - } - - if s.Status != (trace.Status{}) { - msg := fmt.Sprintf("Status{canonicalCode=%s, description=%q}", - canonicalCodeString(s.Status.Code), s.Status.Message) - out = append(out, traceRow{Fields: [3]string{"", "", msg}}) - } - - if len(s.Attributes) != 0 { - out = append(out, traceRow{Fields: [3]string{"", "", formatAttributes(s.Attributes)}}) - } - - var es events - for i := range s.Annotations { - es = append(es, &s.Annotations[i]) - } - for i := range s.MessageEvents { - es = append(es, &s.MessageEvents[i]) - } - sort.Sort(es) - for _, e := range es { - switch e := e.(type) { - case *trace.Annotation: - msg := e.Message - if len(e.Attributes) != 0 { - msg = msg + " " + formatAttributes(e.Attributes) - } - row := traceRow{Fields: [3]string{ - formatTime(e.Time), - formatElapsed(e.Time), - msg, - }} - out = append(out, row) - case *trace.MessageEvent: - row := traceRow{Fields: [3]string{formatTime(e.Time), formatElapsed(e.Time)}} - switch e.EventType { - case trace.MessageEventTypeSent: - row.Fields[2] = fmt.Sprintf("sent message [%d bytes, %d compressed bytes]", e.UncompressedByteSize, e.CompressedByteSize) - case trace.MessageEventTypeRecv: - row.Fields[2] = fmt.Sprintf("received message [%d bytes, %d compressed bytes]", e.UncompressedByteSize, e.CompressedByteSize) - } - out = append(out, row) - } - } - for i := range out { - if len(out[i].Fields[2]) > maxTraceMessageLength { - out[i].Fields[2] = out[i].Fields[2][:maxTraceMessageLength] - } - } - return out -} - -func traceSpans(spanName string, spanType, spanSubtype int) []*trace.SpanData { - internalTrace := internal.Trace.(interface { - ReportActiveSpans(name string) []*trace.SpanData - ReportSpansByError(name string, code int32) []*trace.SpanData - ReportSpansByLatency(name string, minLatency, maxLatency time.Duration) []*trace.SpanData - }) - var spans []*trace.SpanData - switch spanType { - case 0: // active - spans = internalTrace.ReportActiveSpans(spanName) - case 1: // latency - var min, max time.Duration - n := len(defaultLatencies) - if spanSubtype == 0 { - max = defaultLatencies[0] - } else if spanSubtype == n { - min, max = defaultLatencies[spanSubtype-1], (1<<63)-1 - } else if 0 < spanSubtype && spanSubtype < n { - min, max = defaultLatencies[spanSubtype-1], defaultLatencies[spanSubtype] - } - spans = internalTrace.ReportSpansByLatency(spanName, min, max) - case 2: // error - spans = internalTrace.ReportSpansByError(spanName, 0) - } - return spans -} - -func traceDataFromSpans(name string, spans []*trace.SpanData) traceData { - data := traceData{ - Name: name, - Num: len(spans), - } - for _, s := range spans { - data.Rows = append(data.Rows, traceRows(s)...) - } - return data -} - -func writeTextTraces(w io.Writer, data traceData) { - tw := tabwriter.NewWriter(w, 1, 8, 1, ' ', 0) - fmt.Fprint(tw, "When\tElapsed(s)\tType\n") - for _, r := range data.Rows { - tw.Write([]byte(r.Fields[0])) - tw.Write([]byte("\t")) - tw.Write([]byte(r.Fields[1])) - tw.Write([]byte("\t")) - tw.Write([]byte(r.Fields[2])) - if sc := r.SpanContext; sc != (trace.SpanContext{}) { - fmt.Fprintf(tw, "trace_id: %s span_id: %s", sc.TraceID, sc.SpanID) - if r.ParentSpanID != (trace.SpanID{}) { - fmt.Fprintf(tw, " parent_span_id: %s", r.ParentSpanID) - } - } - tw.Write([]byte("\n")) - } - tw.Flush() -} - -type summaryPageData struct { - Header []string - LatencyBucketNames []string - Links bool - TracesEndpoint string - Rows []summaryPageRow -} - -type summaryPageRow struct { - Name string - Active int - Latency []int - Errors int -} - -func getSummaryPageData() summaryPageData { - data := summaryPageData{ - Links: true, - TracesEndpoint: "tracez", - } - internalTrace := internal.Trace.(interface { - ReportSpansPerMethod() map[string]internal.PerMethodSummary - }) - for name, s := range internalTrace.ReportSpansPerMethod() { - if len(data.Header) == 0 { - data.Header = []string{"Name", "Active"} - for _, b := range s.LatencyBuckets { - l := b.MinLatency - s := fmt.Sprintf(">%v", l) - if l == 100*time.Second { - s = ">100s" - } - data.Header = append(data.Header, s) - data.LatencyBucketNames = append(data.LatencyBucketNames, s) - } - data.Header = append(data.Header, "Errors") - } - row := summaryPageRow{Name: name, Active: s.Active} - for _, l := range s.LatencyBuckets { - row.Latency = append(row.Latency, l.Size) - } - for _, e := range s.ErrorBuckets { - row.Errors += e.Size - } - data.Rows = append(data.Rows, row) - } - sort.Slice(data.Rows, func(i, j int) bool { - return data.Rows[i].Name < data.Rows[j].Name - }) - return data -} diff --git a/vendor/go.opencensus.io/zpages/zpages.go b/vendor/go.opencensus.io/zpages/zpages.go deleted file mode 100644 index 7ee2c2e58e..0000000000 --- a/vendor/go.opencensus.io/zpages/zpages.go +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2017, OpenCensus Authors -// -// 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. -// - -// Package zpages implements a collection of HTML pages that display RPC stats -// and trace data, and also functions to write that same data in plain text to -// an io.Writer. -// -// Users can also embed the HTML for stats and traces in custom status pages. -// -// zpages are currrently work-in-process and cannot display minutely and -// hourly stats correctly. -// -// # Performance -// -// Installing the zpages has a performance overhead because additional traces -// and stats will be collected in-process. In most cases, we expect this -// overhead will not be significant but it depends on many factors, including -// how many spans your process creates and how richly annotated they are. -package zpages // import "go.opencensus.io/zpages" - -import ( - "net/http" - "path" - "sync" - - "go.opencensus.io/internal" -) - -// TODO(ramonza): Remove Handler to make initialization lazy. - -// Handler is deprecated: Use Handle. -var Handler http.Handler - -func init() { - mux := http.NewServeMux() - Handle(mux, "/") - Handler = mux -} - -// Handle adds the z-pages to the given ServeMux rooted at pathPrefix. -func Handle(mux *http.ServeMux, pathPrefix string) { - enable() - if mux == nil { - mux = http.DefaultServeMux - } - mux.HandleFunc(path.Join(pathPrefix, "rpcz"), rpczHandler) - mux.HandleFunc(path.Join(pathPrefix, "tracez"), tracezHandler) - mux.Handle(path.Join(pathPrefix, "public/"), http.FileServer(fs)) -} - -var enableOnce sync.Once - -func enable() { - enableOnce.Do(func() { - internal.LocalSpanStoreEnabled = true - registerRPCViews() - }) -} diff --git a/vendor/go.opentelemetry.io/contrib/zpages/LICENSE b/vendor/go.opentelemetry.io/contrib/zpages/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/vendor/go.opentelemetry.io/contrib/zpages/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/vendor/go.opentelemetry.io/contrib/zpages/boundaries.go b/vendor/go.opentelemetry.io/contrib/zpages/boundaries.go new file mode 100644 index 0000000000..3d437170a9 --- /dev/null +++ b/vendor/go.opentelemetry.io/contrib/zpages/boundaries.go @@ -0,0 +1,61 @@ +// Copyright The OpenTelemetry Authors +// +// 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. + +package zpages // import "go.opentelemetry.io/contrib/zpages" + +import ( + "sort" + "time" +) + +const zeroDuration = time.Duration(0) +const maxDuration = time.Duration(1<<63 - 1) + +var defaultBoundaries = newBoundaries([]time.Duration{ + 10 * time.Microsecond, + 100 * time.Microsecond, + time.Millisecond, + 10 * time.Millisecond, + 100 * time.Millisecond, + time.Second, + 10 * time.Second, + 100 * time.Second, +}) + +// boundaries represents the interval bounds for the latency based samples. +type boundaries struct { + durations []time.Duration +} + +// newBoundaries returns a new boundaries. +func newBoundaries(durations []time.Duration) *boundaries { + sort.Slice(durations, func(i, j int) bool { + return durations[i] < durations[j] + }) + return &boundaries{durations: durations} +} + +// numBuckets returns the number of buckets needed for these boundaries. +func (lb boundaries) numBuckets() int { + return len(lb.durations) + 1 +} + +// getBucketIndex returns the appropriate bucket index for a given latency. +func (lb boundaries) getBucketIndex(latency time.Duration) int { + i := 0 + for i < len(lb.durations) && latency >= lb.durations[i] { + i++ + } + return i +} diff --git a/vendor/go.opentelemetry.io/contrib/zpages/bucket.go b/vendor/go.opentelemetry.io/contrib/zpages/bucket.go new file mode 100644 index 0000000000..f88c73a341 --- /dev/null +++ b/vendor/go.opentelemetry.io/contrib/zpages/bucket.go @@ -0,0 +1,74 @@ +// Copyright The OpenTelemetry Authors +// Copyright 2017, OpenCensus Authors +// +// 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. + +package zpages // import "go.opentelemetry.io/contrib/zpages" + +import ( + "time" + + sdktrace "go.opentelemetry.io/otel/sdk/trace" +) + +const ( + // defaultBucketCapacity is the default capacity for every bucket (latency or error based). + defaultBucketCapacity = 10 + // samplePeriod is the minimum time between accepting spans in a single bucket. + samplePeriod = time.Second +) + +// bucket is a container for a set of spans for latency buckets or errored spans. +type bucket struct { + nextTime time.Time // next time we can accept a span + buffer []sdktrace.ReadOnlySpan // circular buffer of spans + nextIndex int // location next ReadOnlySpan should be placed in buffer + overflow bool // whether the circular buffer has wrapped around +} + +// newBucket returns a new bucket with the given capacity. +func newBucket(capacity uint) *bucket { + return &bucket{ + buffer: make([]sdktrace.ReadOnlySpan, capacity), + } +} + +// add adds a span to the bucket, if nextTime has been reached. +func (b *bucket) add(s sdktrace.ReadOnlySpan) { + if s.EndTime().Before(b.nextTime) { + return + } + if len(b.buffer) == 0 { + return + } + b.nextTime = s.EndTime().Add(samplePeriod) + b.buffer[b.nextIndex] = s + b.nextIndex++ + if b.nextIndex == len(b.buffer) { + b.nextIndex = 0 + b.overflow = true + } +} + +// len returns the number of spans in the bucket. +func (b *bucket) len() int { + if b.overflow { + return len(b.buffer) + } + return b.nextIndex +} + +// spans returns the spans in this bucket. +func (b *bucket) spans() []sdktrace.ReadOnlySpan { + return append([]sdktrace.ReadOnlySpan(nil), b.buffer[0:b.len()]...) +} diff --git a/vendor/go.opencensus.io/zpages/internal/gen.go b/vendor/go.opentelemetry.io/contrib/zpages/internal/gen.go similarity index 72% rename from vendor/go.opencensus.io/zpages/internal/gen.go rename to vendor/go.opentelemetry.io/contrib/zpages/internal/gen.go index 453e217544..5972035f82 100644 --- a/vendor/go.opencensus.io/zpages/internal/gen.go +++ b/vendor/go.opentelemetry.io/contrib/zpages/internal/gen.go @@ -1,4 +1,4 @@ -// Copyright 2018, OpenCensus Authors +// Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -11,9 +11,10 @@ // 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. -// -package internal // import "go.opencensus.io/zpages/internal" +package internal // import "go.opentelemetry.io/contrib/zpages/internal" -// go get https://github.com/mjibson/esc.git -//go:generate esc -pkg internal -o resources.go public/ templates/ +import "embed" + +//go:embed templates/* +var Templates embed.FS diff --git a/vendor/go.opentelemetry.io/contrib/zpages/internal/templates/footer.html b/vendor/go.opentelemetry.io/contrib/zpages/internal/templates/footer.html new file mode 100644 index 0000000000..308b1d01b6 --- /dev/null +++ b/vendor/go.opentelemetry.io/contrib/zpages/internal/templates/footer.html @@ -0,0 +1,2 @@ + + diff --git a/vendor/go.opentelemetry.io/contrib/zpages/internal/templates/header.html b/vendor/go.opentelemetry.io/contrib/zpages/internal/templates/header.html new file mode 100644 index 0000000000..cd92865e0c --- /dev/null +++ b/vendor/go.opentelemetry.io/contrib/zpages/internal/templates/header.html @@ -0,0 +1,11 @@ + + + + {{.Title}} + + + + + + +

{{.Title}}

diff --git a/vendor/go.opentelemetry.io/contrib/zpages/internal/templates/summary.html b/vendor/go.opentelemetry.io/contrib/zpages/internal/templates/summary.html new file mode 100644 index 0000000000..151c7d506d --- /dev/null +++ b/vendor/go.opentelemetry.io/contrib/zpages/internal/templates/summary.html @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + {{range .LatencyBucketNames}}{{end}} + + + +{{$a := .TracesEndpoint}} +{{$links := .Links}} +{{range $rowindex, $row := .Rows}} +{{- $name := .Name}} +{{- if even $rowindex}}{{else}}{{end -}} + +{{- if $links -}} + +{{- else -}} + +{{- end -}} + +{{- if $links -}} +{{range $index, $value := .Latency}}{{end}} +{{- else -}} +{{range .Latency}}{{end}} +{{- end -}} + +{{- if $links -}} + +{{- else -}} + +{{- end -}} + +{{end}}
Span Name  |  Running  |  Latency Samples  |  Error Samples
  |    |  [{{.}}]  |  
{{.Name}}  |  {{.Active}}{{.Active}}  |  {{$value}}{{.}}  |  {{.Errors}}{{.Errors}}
diff --git a/vendor/go.opentelemetry.io/contrib/zpages/internal/templates/traces.html b/vendor/go.opentelemetry.io/contrib/zpages/internal/templates/traces.html new file mode 100644 index 0000000000..7413608edd --- /dev/null +++ b/vendor/go.opentelemetry.io/contrib/zpages/internal/templates/traces.html @@ -0,0 +1,10 @@ +

Span Name: {{.Name}}

+

{{.Num}} Requests

+
+When                       Elapsed (sec)
+----------------------------------------
+{{range .Rows}}{{printf "%26s" (index .Fields 0)}} {{printf "%12s" (index .Fields 1)}} {{index .Fields 2}}{{.|spanRow}}
+{{end}}
+
+

TraceId means sampled request. + TraceId means not sampled request.

diff --git a/vendor/go.opentelemetry.io/contrib/zpages/spanprocessor.go b/vendor/go.opentelemetry.io/contrib/zpages/spanprocessor.go new file mode 100644 index 0000000000..189a04a746 --- /dev/null +++ b/vendor/go.opentelemetry.io/contrib/zpages/spanprocessor.go @@ -0,0 +1,224 @@ +// Copyright The OpenTelemetry Authors +// Copyright 2017, OpenCensus Authors +// +// 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. + +package zpages // import "go.opentelemetry.io/contrib/zpages" + +import ( + "context" + "sync" + + "go.opentelemetry.io/otel/codes" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + "go.opentelemetry.io/otel/trace" +) + +var _ sdktrace.SpanProcessor = (*SpanProcessor)(nil) + +// perMethodSummary is a summary of the spans stored for a single span name. +type perMethodSummary struct { + activeSpans int + latencySpans []int + errorSpans int +} + +// SpanProcessor is an sdktrace.SpanProcessor implementation that exposes zpages functionality for opentelemetry-go. +// +// It tracks all active spans, and stores samples of spans based on latency for non errored spans, +// and samples for errored spans. +type SpanProcessor struct { + // Cannot keep track of the active Spans per name because the Span interface, + // allows the name to be changed, and that will leak memory. + activeSpansStore sync.Map + spanSampleStores sync.Map +} + +// NewSpanProcessor returns a new SpanProcessor. +func NewSpanProcessor() *SpanProcessor { + return &SpanProcessor{} +} + +// OnStart adds span as active and reports it with zpages. +func (ssm *SpanProcessor) OnStart(_ context.Context, span sdktrace.ReadWriteSpan) { + sc := span.SpanContext() + if sc.IsValid() { + ssm.activeSpansStore.Store(spanKey(sc), span) + } +} + +// OnEnd processes all spans and reports them with zpages. +func (ssm *SpanProcessor) OnEnd(span sdktrace.ReadOnlySpan) { + sc := span.SpanContext() + if sc.IsValid() { + ssm.activeSpansStore.Delete(spanKey(sc)) + } + + name := span.Name() + value, ok := ssm.spanSampleStores.Load(name) + if !ok { + value, _ = ssm.spanSampleStores.LoadOrStore(name, newSampleStore(defaultBucketCapacity, defaultBucketCapacity)) + } + value.(*sampleStore).sampleSpan(span) +} + +// Shutdown does nothing. +func (ssm *SpanProcessor) Shutdown(context.Context) error { + // Do nothing + return nil +} + +// ForceFlush does nothing. +func (ssm *SpanProcessor) ForceFlush(context.Context) error { + // Do nothing + return nil +} + +// spanStoreForName returns the sampleStore for the given name. +// +// It returns nil if it doesn't exist. +func (ssm *SpanProcessor) spanStoreForName(name string) *sampleStore { + if value, ok := ssm.spanSampleStores.Load(name); ok { + return value.(*sampleStore) + } + return nil +} + +// spansPerMethod returns a summary of what spans are being stored for each span name. +func (ssm *SpanProcessor) spansPerMethod() map[string]*perMethodSummary { + out := make(map[string]*perMethodSummary) + ssm.spanSampleStores.Range(func(name, s interface{}) bool { + out[name.(string)] = s.(*sampleStore).perMethodSummary() + return true + }) + ssm.activeSpansStore.Range(func(_, sp interface{}) bool { + span := sp.(sdktrace.ReadOnlySpan) + if pms, ok := out[span.Name()]; ok { + pms.activeSpans++ + return true + } + out[span.Name()] = &perMethodSummary{activeSpans: 1} + return true + }) + return out +} + +// activeSpans returns the active spans for the given name. +func (ssm *SpanProcessor) activeSpans(name string) []sdktrace.ReadOnlySpan { + var out []sdktrace.ReadOnlySpan + ssm.activeSpansStore.Range(func(_, sp interface{}) bool { + span := sp.(sdktrace.ReadOnlySpan) + if span.Name() == name { + out = append(out, span) + } + return true + }) + return out +} + +// errorSpans returns a sample of error spans. +func (ssm *SpanProcessor) errorSpans(name string) []sdktrace.ReadOnlySpan { + s := ssm.spanStoreForName(name) + if s == nil { + return nil + } + return s.errorSpans() +} + +// spansByLatency returns a sample of successful spans. +// +// minLatency is the minimum latency of spans to be returned. +// maxDuration, if nonzero, is the maximum latency of spans to be returned. +func (ssm *SpanProcessor) spansByLatency(name string, latencyBucketIndex int) []sdktrace.ReadOnlySpan { + s := ssm.spanStoreForName(name) + if s == nil { + return nil + } + return s.spansByLatency(latencyBucketIndex) +} + +// sampleStore stores a sampled of spans for a particular span name. +// +// It contains sample of spans for error requests (status code is codes.Error); +// and a sample of spans for successful requests, bucketed by latency. +type sampleStore struct { + sync.Mutex // protects everything below. + latency []*bucket + errors *bucket +} + +// newSampleStore creates a sampleStore. +func newSampleStore(latencyBucketSize uint, errorBucketSize uint) *sampleStore { + s := &sampleStore{ + latency: make([]*bucket, defaultBoundaries.numBuckets()), + errors: newBucket(errorBucketSize), + } + for i := range s.latency { + s.latency[i] = newBucket(latencyBucketSize) + } + return s +} + +func (ss *sampleStore) perMethodSummary() *perMethodSummary { + ss.Lock() + defer ss.Unlock() + p := &perMethodSummary{} + p.errorSpans = ss.errors.len() + for _, b := range ss.latency { + p.latencySpans = append(p.latencySpans, b.len()) + } + return p +} + +func (ss *sampleStore) spansByLatency(latencyBucketIndex int) []sdktrace.ReadOnlySpan { + ss.Lock() + defer ss.Unlock() + if latencyBucketIndex < 0 || latencyBucketIndex >= len(ss.latency) { + return nil + } + return ss.latency[latencyBucketIndex].spans() +} + +func (ss *sampleStore) errorSpans() []sdktrace.ReadOnlySpan { + ss.Lock() + defer ss.Unlock() + return ss.errors.spans() +} + +// sampleSpan removes adds to the corresponding latency or error bucket. +func (ss *sampleStore) sampleSpan(span sdktrace.ReadOnlySpan) { + code := span.Status().Code + + ss.Lock() + defer ss.Unlock() + if code == codes.Error { + ss.errors.add(span) + return + } + + latency := span.EndTime().Sub(span.StartTime()) + // In case of time skew or wrong time, sample as 0 latency. + if latency < 0 { + latency = 0 + } + ss.latency[defaultBoundaries.getBucketIndex(latency)].add(span) +} + +func spanKey(sc trace.SpanContext) [24]byte { + var sk [24]byte + tid := sc.TraceID() + copy(sk[0:16], tid[:]) + sid := sc.SpanID() + copy(sk[16:24], sid[:]) + return sk +} diff --git a/vendor/go.opentelemetry.io/contrib/zpages/templates.go b/vendor/go.opentelemetry.io/contrib/zpages/templates.go new file mode 100644 index 0000000000..af2952fcaa --- /dev/null +++ b/vendor/go.opentelemetry.io/contrib/zpages/templates.go @@ -0,0 +1,77 @@ +// Copyright The OpenTelemetry Authors +// Copyright 2017, OpenCensus Authors +// +// 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. +// + +package zpages // import "go.opentelemetry.io/contrib/zpages" + +import ( + "fmt" + "html/template" + "io" + "log" + + "go.opentelemetry.io/contrib/zpages/internal" +) + +var ( + templateFunctions = template.FuncMap{ + "even": even, + "spanRow": spanRowFormatter, + } + headerTemplate = parseTemplate("header") + summaryTableTemplate = parseTemplate("summary") + tracesTableTemplate = parseTemplate("traces") + footerTemplate = parseTemplate("footer") +) + +// headerData contains data for the header template. +type headerData struct { + Title string +} + +func parseTemplate(name string) *template.Template { + f, err := internal.Templates.Open("templates/" + name + ".html") + if err != nil { + log.Panicf("%v: %v", name, err) // nolint: revive // Called during initialization. + } + defer func() { + if err = f.Close(); err != nil { + log.Panicf("%v: %v", name, err) // nolint: revive // Called during initialization. + } + }() + text, err := io.ReadAll(f) + if err != nil { + log.Panicf("%v: %v", name, err) // nolint: revive // Called during initialization. + } + return template.Must(template.New(name).Funcs(templateFunctions).Parse(string(text))) +} + +func spanRowFormatter(r spanRow) template.HTML { + if !r.SpanContext.IsValid() { + return "" + } + col := "black" + if r.SpanContext.IsSampled() { + col = "blue" + } + if r.ParentSpanContext.IsValid() { + return template.HTML(fmt.Sprintf(`trace_id: %s span_id: %s parent_span_id: %s`, col, r.SpanContext.TraceID(), r.SpanContext.SpanID(), r.ParentSpanContext.SpanID())) + } + return template.HTML(fmt.Sprintf(`trace_id: %s span_id: %s`, col, r.SpanContext.TraceID(), r.SpanContext.SpanID())) +} + +func even(x int) bool { + return x%2 == 0 +} diff --git a/vendor/go.opentelemetry.io/contrib/zpages/tracez.go b/vendor/go.opentelemetry.io/contrib/zpages/tracez.go new file mode 100644 index 0000000000..cb3325a039 --- /dev/null +++ b/vendor/go.opentelemetry.io/contrib/zpages/tracez.go @@ -0,0 +1,261 @@ +// Copyright The OpenTelemetry Authors +// Copyright 2017, OpenCensus Authors +// +// 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. + +package zpages // import "go.opentelemetry.io/contrib/zpages" + +import ( + "fmt" + "log" + "net/http" + "sort" + "strconv" + "strings" + "time" + + "go.opentelemetry.io/otel/attribute" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + "go.opentelemetry.io/otel/trace" +) + +const ( + // spanNameQueryField is the header for span name. + spanNameQueryField = "zspanname" + // spanTypeQueryField is the header for type (running = 0, latency = 1, error = 2) to display. + spanTypeQueryField = "ztype" + // spanLatencyBucketQueryField is the header for latency based samples. + // Default is [0, 8] representing the latency buckets, where 0 is the first one. + spanLatencyBucketQueryField = "zlatencybucket" + // maxTraceMessageLength is the maximum length of a message in tracez output. + maxTraceMessageLength = 1024 +) + +type summaryTableData struct { + Header []string + LatencyBucketNames []string + Links bool + TracesEndpoint string + Rows []summaryTableRowData +} + +type summaryTableRowData struct { + Name string + Active int + Latency []int + Errors int +} + +// traceTableData contains data for the trace data template. +type traceTableData struct { + Name string + Num int + Rows []spanRow +} + +var _ http.Handler = (*tracezHandler)(nil) + +type tracezHandler struct { + sp *SpanProcessor +} + +// NewTracezHandler returns an http.Handler that can be used to serve HTTP requests for trace zpages. +func NewTracezHandler(sp *SpanProcessor) http.Handler { + return &tracezHandler{sp: sp} +} + +// ServeHTTP implements the http.Handler and is capable of serving "tracez" HTTP requests. +func (th *tracezHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "text/html; charset=utf-8") + if err := r.ParseForm(); err != nil { + w.WriteHeader(http.StatusBadRequest) + return + } + spanName := r.Form.Get(spanNameQueryField) + spanType, _ := strconv.Atoi(r.Form.Get(spanTypeQueryField)) + spanSubtype, _ := strconv.Atoi(r.Form.Get(spanLatencyBucketQueryField)) + + if err := headerTemplate.Execute(w, headerData{Title: "Trace Spans"}); err != nil { + log.Printf("zpages: executing template: %v", err) + } + if err := summaryTableTemplate.Execute(w, th.getSummaryTableData()); err != nil { + log.Printf("zpages: executing template: %v", err) + } + if spanName != "" { + if err := tracesTableTemplate.Execute(w, th.getTraceTableData(spanName, spanType, spanSubtype)); err != nil { + log.Printf("zpages: executing template: %v", err) + } + } + if err := footerTemplate.Execute(w, nil); err != nil { + log.Printf("zpages: executing template: %v", err) + } +} + +func (th *tracezHandler) getTraceTableData(spanName string, spanType, latencyBucket int) traceTableData { + var spans []sdktrace.ReadOnlySpan + switch spanType { + case 0: // active + spans = th.sp.activeSpans(spanName) + case 1: // latency + spans = th.sp.spansByLatency(spanName, latencyBucket) + case 2: // error + spans = th.sp.errorSpans(spanName) + } + + data := traceTableData{ + Name: spanName, + Num: len(spans), + } + for _, s := range spans { + data.Rows = append(data.Rows, spanRows(s)...) + } + return data +} + +func (th *tracezHandler) getSummaryTableData() summaryTableData { + data := summaryTableData{ + Links: true, + TracesEndpoint: "tracez", + } + data.Header = []string{"Name", "active"} + // An implicit 0 lower bound latency bucket is always present. + latencyBuckets := append([]time.Duration{0}, defaultBoundaries.durations...) + for _, l := range latencyBuckets { + s := fmt.Sprintf(">%v", l) + data.Header = append(data.Header, s) + data.LatencyBucketNames = append(data.LatencyBucketNames, s) + } + data.Header = append(data.Header, "Errors") + for name, s := range th.sp.spansPerMethod() { + row := summaryTableRowData{Name: name, Active: s.activeSpans, Errors: s.errorSpans, Latency: s.latencySpans} + data.Rows = append(data.Rows, row) + } + sort.Slice(data.Rows, func(i, j int) bool { + return data.Rows[i].Name < data.Rows[j].Name + }) + return data +} + +type spanRow struct { + Fields [3]string + trace.SpanContext + ParentSpanContext trace.SpanContext +} + +type events []sdktrace.Event + +func (e events) Len() int { return len(e) } +func (e events) Less(i, j int) bool { + return e[i].Time.Before(e[j].Time) +} +func (e events) Swap(i, j int) { e[i], e[j] = e[j], e[i] } + +type attributes []attribute.KeyValue + +func (e attributes) Len() int { return len(e) } +func (e attributes) Less(i, j int) bool { + return string(e[i].Key) < string(e[j].Key) +} +func (e attributes) Swap(i, j int) { e[i], e[j] = e[j], e[i] } + +func spanRows(s sdktrace.ReadOnlySpan) []spanRow { + start := s.StartTime() + + lasty, lastm, lastd := start.Date() + wholeTime := func(t time.Time) string { + return t.Format("2006/01/02-15:04:05") + fmt.Sprintf(".%06d", t.Nanosecond()/1000) + } + formatTime := func(t time.Time) string { + y, m, d := t.Date() + if y == lasty && m == lastm && d == lastd { + return t.Format(" 15:04:05") + fmt.Sprintf(".%06d", t.Nanosecond()/1000) + } + lasty, lastm, lastd = y, m, d + return wholeTime(t) + } + + lastTime := start + formatElapsed := func(t time.Time) string { + d := t.Sub(lastTime) + lastTime = t + u := int64(d / 1000) + // There are five cases for duration printing: + // -1234567890s + // -1234.123456 + // .123456 + // 12345.123456 + // 12345678901s + switch { + case u < -9999999999: + return fmt.Sprintf("%11ds", u/1e6) + case u < 0: + sec := u / 1e6 + u -= sec * 1e6 + return fmt.Sprintf("%5d.%06d", sec, -u) + case u < 1e6: + return fmt.Sprintf(" .%6d", u) + case u <= 99999999999: + sec := u / 1e6 + u -= sec * 1e6 + return fmt.Sprintf("%5d.%06d", sec, u) + default: + return fmt.Sprintf("%11ds", u/1e6) + } + } + + firstRow := spanRow{Fields: [3]string{wholeTime(start), "", ""}, SpanContext: s.SpanContext(), ParentSpanContext: s.Parent()} + if s.EndTime().IsZero() { + firstRow.Fields[1] = " " + } else { + firstRow.Fields[1] = formatElapsed(s.EndTime()) + lastTime = start + } + out := []spanRow{firstRow} + + formatAttributes := func(a attributes) string { + sort.Sort(a) + var s []string + for i := range a { + s = append(s, fmt.Sprintf("%s=%v", a[i].Key, a[i].Value.Emit())) + } + return "Attributes:{" + strings.Join(s, ", ") + "}" + } + + msg := fmt.Sprintf("Status{Code=%s, description=%q}", s.Status().Code.String(), s.Status().Description) + out = append(out, spanRow{Fields: [3]string{"", "", msg}}) + + if len(s.Attributes()) != 0 { + out = append(out, spanRow{Fields: [3]string{"", "", formatAttributes(s.Attributes())}}) + } + + es := events(s.Events()) + sort.Sort(es) + for _, e := range es { + msg := e.Name + if len(e.Attributes) != 0 { + msg = msg + " " + formatAttributes(e.Attributes) + } + row := spanRow{Fields: [3]string{ + formatTime(e.Time), + formatElapsed(e.Time), + msg, + }} + out = append(out, row) + } + for i := range out { + if len(out[i].Fields[2]) > maxTraceMessageLength { + out[i].Fields[2] = out[i].Fields[2][:maxTraceMessageLength] + } + } + return out +} diff --git a/vendor/go.opentelemetry.io/contrib/zpages/version.go b/vendor/go.opentelemetry.io/contrib/zpages/version.go new file mode 100644 index 0000000000..a33fa16c85 --- /dev/null +++ b/vendor/go.opentelemetry.io/contrib/zpages/version.go @@ -0,0 +1,26 @@ +// Copyright The OpenTelemetry Authors +// +// 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. + +package zpages // import "go.opentelemetry.io/contrib/zpages" + +// Version is the current release version of the zpages span processor. +func Version() string { + return "0.41.1" + // This string is updated by the pre_release.sh script during release +} + +// SemVersion is the semantic version to be supplied to tracer/meter creation. +func SemVersion() string { + return "semver:" + Version() +} diff --git a/vendor/go.opentelemetry.io/otel/.gitignore b/vendor/go.opentelemetry.io/otel/.gitignore index 0b605b3d67..cf29d10a7c 100644 --- a/vendor/go.opentelemetry.io/otel/.gitignore +++ b/vendor/go.opentelemetry.io/otel/.gitignore @@ -7,6 +7,8 @@ Thumbs.db *.iml *.so coverage.* +go.work +go.work.sum gen/ diff --git a/vendor/go.opentelemetry.io/otel/.golangci.yml b/vendor/go.opentelemetry.io/otel/.golangci.yml index 0f099f5759..e28904f6ac 100644 --- a/vendor/go.opentelemetry.io/otel/.golangci.yml +++ b/vendor/go.opentelemetry.io/otel/.golangci.yml @@ -85,6 +85,8 @@ linters-settings: - "**/internal/matchers/*.go" godot: exclude: + # Exclude links. + - '^ *\[[^]]+\]:' # Exclude sentence fragments for lists. - '^[ ]*[-•]' # Exclude sentences prefixing a list. diff --git a/vendor/go.opentelemetry.io/otel/CHANGELOG.md b/vendor/go.opentelemetry.io/otel/CHANGELOG.md index 1d9726f60b..7630a4f33a 100644 --- a/vendor/go.opentelemetry.io/otel/CHANGELOG.md +++ b/vendor/go.opentelemetry.io/otel/CHANGELOG.md @@ -8,6 +8,147 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [Unreleased] +## [1.15.1/0.38.1] 2023-05-02 + +### Fixed + +- Remove unused imports from `sdk/resource/host_id_bsd.go` which caused build failures. (#4040, #4041) + +## [1.15.0/0.38.0] 2023-04-27 + +### Added + +- The `go.opentelemetry.io/otel/metric/embedded` package. (#3916) +- The `Version` function to `go.opentelemetry.io/otel/sdk` to return the SDK version. (#3949) +- Add a `WithNamespace` option to `go.opentelemetry.io/otel/exporters/prometheus` to allow users to prefix metrics with a namespace. (#3970) +- The following configuration types were added to `go.opentelemetry.io/otel/metric/instrument` to be used in the configuration of measurement methods. (#3971) + - The `AddConfig` used to hold configuration for addition measurements + - `NewAddConfig` used to create a new `AddConfig` + - `AddOption` used to configure an `AddConfig` + - The `RecordConfig` used to hold configuration for recorded measurements + - `NewRecordConfig` used to create a new `RecordConfig` + - `RecordOption` used to configure a `RecordConfig` + - The `ObserveConfig` used to hold configuration for observed measurements + - `NewObserveConfig` used to create a new `ObserveConfig` + - `ObserveOption` used to configure an `ObserveConfig` +- `WithAttributeSet` and `WithAttributes` are added to `go.opentelemetry.io/otel/metric/instrument`. + They return an option used during a measurement that defines the attribute Set associated with the measurement. (#3971) +- The `Version` function to `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` to return the OTLP metrics client version. (#3956) +- The `Version` function to `go.opentelemetry.io/otel/exporters/otlp/otlptrace` to return the OTLP trace client version. (#3956) + +### Changed + +- The `Extrema` in `go.opentelemetry.io/otel/sdk/metric/metricdata` is redefined with a generic argument of `[N int64 | float64]`. (#3870) +- Update all exported interfaces from `go.opentelemetry.io/otel/metric` to embed their corresponding interface from `go.opentelemetry.io/otel/metric/embedded`. + This adds an implementation requirement to set the interface default behavior for unimplemented methods. (#3916) +- Move No-Op implementation from `go.opentelemetry.io/otel/metric` into its own package `go.opentelemetry.io/otel/metric/noop`. (#3941) + - `metric.NewNoopMeterProvider` is replaced with `noop.NewMeterProvider` +- Add all the methods from `"go.opentelemetry.io/otel/trace".SpanContext` to `bridgeSpanContext` by embedding `otel.SpanContext` in `bridgeSpanContext`. (#3966) +- Wrap `UploadMetrics` error in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/` to improve error message when encountering generic grpc errors. (#3974) +- The measurement methods for all instruments in `go.opentelemetry.io/otel/metric/instrument` accept an option instead of the variadic `"go.opentelemetry.io/otel/attribute".KeyValue`. (#3971) + - The `Int64Counter.Add` method now accepts `...AddOption` + - The `Float64Counter.Add` method now accepts `...AddOption` + - The `Int64UpDownCounter.Add` method now accepts `...AddOption` + - The `Float64UpDownCounter.Add` method now accepts `...AddOption` + - The `Int64Histogram.Record` method now accepts `...RecordOption` + - The `Float64Histogram.Record` method now accepts `...RecordOption` + - The `Int64Observer.Observe` method now accepts `...ObserveOption` + - The `Float64Observer.Observe` method now accepts `...ObserveOption` +- The `Observer` methods in `go.opentelemetry.io/otel/metric` accept an option instead of the variadic `"go.opentelemetry.io/otel/attribute".KeyValue`. (#3971) + - The `Observer.ObserveInt64` method now accepts `...ObserveOption` + - The `Observer.ObserveFloat64` method now accepts `...ObserveOption` +- Move global metric back to `go.opentelemetry.io/otel/metric/global` from `go.opentelemetry.io/otel`. (#3986) + +### Fixed + +- `TracerProvider` allows calling `Tracer()` while it's shutting down. + It used to deadlock. (#3924) +- Use the SDK version for the Telemetry SDK resource detector in `go.opentelemetry.io/otel/sdk/resource`. (#3949) +- Fix a data race in `SpanProcessor` returned by `NewSimpleSpanProcessor` in `go.opentelemetry.io/otel/sdk/trace`. (#3951) +- Automatically figure out the default aggregation with `aggregation.Default`. (#3967) + +### Deprecated + +- The `go.opentelemetry.io/otel/metric/instrument` package is deprecated. + Use the equivalent types added to `go.opentelemetry.io/otel/metric` instead. (#4018) + +## [1.15.0-rc.2/0.38.0-rc.2] 2023-03-23 + +This is a release candidate for the v1.15.0/v0.38.0 release. +That release will include the `v1` release of the OpenTelemetry Go metric API and will provide stability guarantees of that API. +See our [versioning policy](VERSIONING.md) for more information about these stability guarantees. + +### Added + +- The `WithHostID` option to `go.opentelemetry.io/otel/sdk/resource`. (#3812) +- The `WithoutTimestamps` option to `go.opentelemetry.io/otel/exporters/stdout/stdoutmetric` to sets all timestamps to zero. (#3828) +- The new `Exemplar` type is added to `go.opentelemetry.io/otel/sdk/metric/metricdata`. + Both the `DataPoint` and `HistogramDataPoint` types from that package have a new field of `Exemplars` containing the sampled exemplars for their timeseries. (#3849) +- Configuration for each metric instrument in `go.opentelemetry.io/otel/sdk/metric/instrument`. (#3895) +- The internal logging introduces a warning level verbosity equal to `V(1)`. (#3900) +- Added a log message warning about usage of `SimpleSpanProcessor` in production environments. (#3854) + +### Changed + +- Optimize memory allocation when creation a new `Set` using `NewSet` or `NewSetWithFiltered` in `go.opentelemetry.io/otel/attribute`. (#3832) +- Optimize memory allocation when creation new metric instruments in `go.opentelemetry.io/otel/sdk/metric`. (#3832) +- Avoid creating new objects on all calls to `WithDeferredSetup` and `SkipContextSetup` in OpenTracing bridge. (#3833) +- The `New` and `Detect` functions from `go.opentelemetry.io/otel/sdk/resource` return errors that wrap underlying errors instead of just containing the underlying error strings. (#3844) +- Both the `Histogram` and `HistogramDataPoint` are redefined with a generic argument of `[N int64 | float64]` in `go.opentelemetry.io/otel/sdk/metric/metricdata`. (#3849) +- The metric `Export` interface from `go.opentelemetry.io/otel/sdk/metric` accepts a `*ResourceMetrics` instead of `ResourceMetrics`. (#3853) +- Rename `Asynchronous` to `Observable` in `go.opentelemetry.io/otel/metric/instrument`. (#3892) +- Rename `Int64ObserverOption` to `Int64ObservableOption` in `go.opentelemetry.io/otel/metric/instrument`. (#3895) +- Rename `Float64ObserverOption` to `Float64ObservableOption` in `go.opentelemetry.io/otel/metric/instrument`. (#3895) +- The internal logging changes the verbosity level of info to `V(4)`, the verbosity level of debug to `V(8)`. (#3900) + +### Fixed + +- `TracerProvider` consistently doesn't allow to register a `SpanProcessor` after shutdown. (#3845) + +### Removed + +- The deprecated `go.opentelemetry.io/otel/metric/global` package is removed. (#3829) +- The unneeded `Synchronous` interface in `go.opentelemetry.io/otel/metric/instrument` was removed. (#3892) +- The `Float64ObserverConfig` and `NewFloat64ObserverConfig` in `go.opentelemetry.io/otel/sdk/metric/instrument`. + Use the added `float64` instrument configuration instead. (#3895) +- The `Int64ObserverConfig` and `NewInt64ObserverConfig` in `go.opentelemetry.io/otel/sdk/metric/instrument`. + Use the added `int64` instrument configuration instead. (#3895) +- The `NewNoopMeter` function in `go.opentelemetry.io/otel/metric`, use `NewMeterProvider().Meter("")` instead. (#3893) + +## [1.15.0-rc.1/0.38.0-rc.1] 2023-03-01 + +This is a release candidate for the v1.15.0/v0.38.0 release. +That release will include the `v1` release of the OpenTelemetry Go metric API and will provide stability guarantees of that API. +See our [versioning policy](VERSIONING.md) for more information about these stability guarantees. + +This release drops the compatibility guarantee of [Go 1.18]. + +### Added + +- Support global `MeterProvider` in `go.opentelemetry.io/otel`. (#3818) + - Use `Meter` for a `metric.Meter` from the global `metric.MeterProvider`. + - Use `GetMeterProivder` for a global `metric.MeterProvider`. + - Use `SetMeterProivder` to set the global `metric.MeterProvider`. + +### Changed + +- Dropped compatibility testing for [Go 1.18]. + The project no longer guarantees support for this version of Go. (#3813) + +### Fixed + +- Handle empty environment variable as it they were not set. (#3764) +- Clarify the `httpconv` and `netconv` packages in `go.opentelemetry.io/otel/semconv/*` provide tracing semantic conventions. (#3823) + +### Deprecated + +- The `go.opentelemetry.io/otel/metric/global` package is deprecated. + Use `go.opentelemetry.io/otel` instead. (#3818) + +### Removed + +- The deprecated `go.opentelemetry.io/otel/metric/unit` package is removed. (#3814) + ## [1.14.0/0.37.0/0.0.4] 2023-02-27 This release is the last to support [Go 1.18]. @@ -121,7 +262,7 @@ The next release will require at least [Go 1.19]. - The `go.opentelemetry.io/otel/semconv/v1.16.0` package. The package contains semantic conventions from the `v1.16.0` version of the OpenTelemetry specification. (#3579) - Metric instruments to `go.opentelemetry.io/otel/metric/instrument`. - These instruments are use as replacements of the depreacted `go.opentelemetry.io/otel/metric/instrument/{asyncfloat64,asyncint64,syncfloat64,syncint64}` packages.(#3575, #3586) + These instruments are use as replacements of the deprecated `go.opentelemetry.io/otel/metric/instrument/{asyncfloat64,asyncint64,syncfloat64,syncint64}` packages.(#3575, #3586) - `Float64ObservableCounter` replaces the `asyncfloat64.Counter` - `Float64ObservableUpDownCounter` replaces the `asyncfloat64.UpDownCounter` - `Float64ObservableGauge` replaces the `asyncfloat64.Gauge` @@ -144,7 +285,7 @@ The next release will require at least [Go 1.19]. ### Changed - Jaeger and Zipkin exporter use `github.com/go-logr/logr` as the logging interface, and add the `WithLogr` option. (#3497, #3500) -- Instrument configuration in `go.opentelemetry.io/otel/metric/instrument` is split into specific options and confguration based on the instrument type. (#3507) +- Instrument configuration in `go.opentelemetry.io/otel/metric/instrument` is split into specific options and configuration based on the instrument type. (#3507) - Use the added `Int64Option` type to configure instruments from `go.opentelemetry.io/otel/metric/instrument/syncint64`. - Use the added `Float64Option` type to configure instruments from `go.opentelemetry.io/otel/metric/instrument/syncfloat64`. - Use the added `Int64ObserverOption` type to configure instruments from `go.opentelemetry.io/otel/metric/instrument/asyncint64`. @@ -157,7 +298,7 @@ The next release will require at least [Go 1.19]. - The `Shutdown` method of the `"go.opentelemetry.io/otel/sdk/trace".TracerProvider` releases all computational resources when called the first time. (#3551) - The `Sampler` returned from `TraceIDRatioBased` `go.opentelemetry.io/otel/sdk/trace` now uses the rightmost bits for sampling decisions. This fixes random sampling when using ID generators like `xray.IDGenerator` and increasing parity with other language implementations. (#3557) -- Errors from `go.opentelemetry.io/otel/exporters/otlp/otlptrace` exporters are wrapped in erros identifying their signal name. +- Errors from `go.opentelemetry.io/otel/exporters/otlp/otlptrace` exporters are wrapped in errors identifying their signal name. Existing users of the exporters attempting to identify specific errors will need to use `errors.Unwrap()` to get the underlying error. (#3516) - Exporters from `go.opentelemetry.io/otel/exporters/otlp` will print the final retryable error message when attempts to retry time out. (#3514) - The instrument kind names in `go.opentelemetry.io/otel/sdk/metric` are updated to match the API. (#3562) @@ -266,7 +407,7 @@ The next release will require at least [Go 1.19]. - Asynchronous counters (`Counter` and `UpDownCounter`) from the metric SDK now produce delta sums when configured with delta temporality. (#3398) - Exported `Status` codes in the `go.opentelemetry.io/otel/exporters/zipkin` exporter are now exported as all upper case values. (#3340) - `Aggregation`s from `go.opentelemetry.io/otel/sdk/metric` with no data are not exported. (#3394, #3436) -- Reenabled Attribute Filters in the Metric SDK. (#3396) +- Re-enabled Attribute Filters in the Metric SDK. (#3396) - Asynchronous callbacks are only called if they are registered with at least one instrument that does not use drop aggragation. (#3408) - Do not report empty partial-success responses in the `go.opentelemetry.io/otel/exporters/otlp` exporters. (#3438, #3432) - Handle partial success responses in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` exporters. (#3162, #3440) @@ -847,7 +988,7 @@ This release includes an API and SDK for the tracing signal that will comply wit - Setting the global `ErrorHandler` with `"go.opentelemetry.io/otel".SetErrorHandler` multiple times is now supported. (#2160, #2140) - The `"go.opentelemetry.io/otel/attribute".Any` function now supports `int32` values. (#2169) - Multiple calls to `"go.opentelemetry.io/otel/sdk/metric/controller/basic".WithResource()` are handled correctly, and when no resources are provided `"go.opentelemetry.io/otel/sdk/resource".Default()` is used. (#2120) -- The `WithoutTimestamps` option for the `go.opentelemetry.io/otel/exporters/stdout/stdouttrace` exporter causes the exporter to correctly ommit timestamps. (#2195) +- The `WithoutTimestamps` option for the `go.opentelemetry.io/otel/exporters/stdout/stdouttrace` exporter causes the exporter to correctly omit timestamps. (#2195) - Fixed typos in resources.go. (#2201) ## [1.0.0-RC2] - 2021-07-26 @@ -1293,7 +1434,7 @@ with major version 0. - `NewGRPCDriver` function returns a `ProtocolDriver` that maintains a single gRPC connection to the collector. (#1369) - Added documentation about the project's versioning policy. (#1388) - Added `NewSplitDriver` for OTLP exporter that allows sending traces and metrics to different endpoints. (#1418) -- Added codeql worfklow to GitHub Actions (#1428) +- Added codeql workflow to GitHub Actions (#1428) - Added Gosec workflow to GitHub Actions (#1429) - Add new HTTP driver for OTLP exporter in `exporters/otlp/otlphttp`. Currently it only supports the binary protobuf payloads. (#1420) - Add an OpenCensus exporter bridge. (#1444) @@ -2136,7 +2277,7 @@ There is still a possibility of breaking changes. ### Fixed -- Use stateful batcher on Prometheus exporter fixing regresion introduced in #395. (#428) +- Use stateful batcher on Prometheus exporter fixing regression introduced in #395. (#428) ## [0.2.1] - 2020-01-08 @@ -2302,7 +2443,11 @@ It contains api and sdk for trace and meter. - CircleCI build CI manifest files. - CODEOWNERS file to track owners of this project. -[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.14.0...HEAD +[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.15.1...HEAD +[1.15.1/0.38.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.15.1 +[1.15.0/0.38.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.15.0 +[1.15.0-rc.2/0.38.0-rc.2]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.15.0-rc.2 +[1.15.0-rc.1/0.38.0-rc.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.15.0-rc.1 [1.14.0/0.37.0/0.0.4]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.14.0 [1.13.0/0.36.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.13.0 [1.12.0/0.35.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.12.0 diff --git a/vendor/go.opentelemetry.io/otel/CODEOWNERS b/vendor/go.opentelemetry.io/otel/CODEOWNERS index c4012ed6ca..f6f6a313b5 100644 --- a/vendor/go.opentelemetry.io/otel/CODEOWNERS +++ b/vendor/go.opentelemetry.io/otel/CODEOWNERS @@ -12,6 +12,6 @@ # https://help.github.com/en/articles/about-code-owners # -* @jmacd @MrAlias @Aneurysm9 @evantorrie @XSAM @dashpole @MadVikingGod @pellared @hanyuancheung @dmathieu +* @MrAlias @Aneurysm9 @evantorrie @XSAM @dashpole @MadVikingGod @pellared @hanyuancheung @dmathieu CODEOWNERS @MrAlias @Aneurysm9 @MadVikingGod diff --git a/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md b/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md index a6928bfdff..f521d65431 100644 --- a/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md +++ b/vendor/go.opentelemetry.io/otel/CONTRIBUTING.md @@ -6,7 +6,7 @@ OpenTelemetry repo for information on this and other language SIGs. See the [public meeting -notes](https://docs.google.com/document/d/1A63zSWX0x2CyCK_LoNhmQC4rqhLpYXJzXbEPDUQ2n6w/edit#heading=h.9tngw7jdwd6b) +notes](https://docs.google.com/document/d/1E5e7Ld0NuU1iVvf-42tOBpu2VBBLYnh73GJuITGJTTU/edit) for a summary description of past meetings. To request edit access, join the meeting or get in touch on [Slack](https://cloud-native.slack.com/archives/C01NPAXACKT). @@ -94,30 +94,58 @@ request ID to the entry you added to `CHANGELOG.md`. ### How to Get PRs Merged -A PR is considered to be **ready to merge** when: +A PR is considered **ready to merge** when: -* It has received two approvals from Collaborators/Maintainers (at - different companies). This is not enforced through technical means - and a PR may be **ready to merge** with a single approval if the change - and its approach have been discussed and consensus reached. -* Feedback has been addressed. -* Any substantive changes to your PR will require that you clear any prior - Approval reviews, this includes changes resulting from other feedback. Unless - the approver explicitly stated that their approval will persist across - changes it should be assumed that the PR needs their review again. Other - project members (e.g. approvers, maintainers) can help with this if there are - any questions or if you forget to clear reviews. -* It has been open for review for at least one working day. This gives - people reasonable time to review. -* Trivial changes (typo, cosmetic, doc, etc.) do not have to wait for - one day and may be merged with a single Maintainer's approval. -* `CHANGELOG.md` has been updated to reflect what has been - added, changed, removed, or fixed. -* `README.md` has been updated if necessary. -* Urgent fix can take exception as long as it has been actively - communicated. +* It has received two qualified approvals[^1]. -Any Maintainer can merge the PR once it is **ready to merge**. + This is not enforced through automation, but needs to be validated by the + maintainer merging. + * The qualified approvals need to be from [Approver]s/[Maintainer]s + affiliated with different companies. Two qualified approvals from + [Approver]s or [Maintainer]s affiliated with the same company counts as a + single qualified approval. + * PRs introducing changes that have already been discussed and consensus + reached only need one qualified approval. The discussion and resolution + needs to be linked to the PR. + * Trivial changes[^2] only need one qualified approval. + +* All feedback has been addressed. + * All PR comments and suggestions are resolved. + * All GitHub Pull Request reviews with a status of "Request changes" have + been addressed. Another review by the objecting reviewer with a different + status can be submitted to clear the original review, or the review can be + dismissed by a [Maintainer] when the issues from the original review have + been addressed. + * Any comments or reviews that cannot be resolved between the PR author and + reviewers can be submitted to the community [Approver]s and [Maintainer]s + during the weekly SIG meeting. If consensus is reached among the + [Approver]s and [Maintainer]s during the SIG meeting the objections to the + PR may be dismissed or resolved or the PR closed by a [Maintainer]. + * Any substantive changes to the PR require existing Approval reviews be + cleared unless the approver explicitly states that their approval persists + across changes. This includes changes resulting from other feedback. + [Approver]s and [Maintainer]s can help in clearing reviews and they should + be consulted if there are any questions. + +* The PR branch is up to date with the base branch it is merging into. + * To ensure this does not block the PR, it should be configured to allow + maintainers to update it. + +* It has been open for review for at least one working day. This gives people + reasonable time to review. + * Trivial changes[^2] do not have to wait for one day and may be merged with + a single [Maintainer]'s approval. + +* All required GitHub workflows have succeeded. +* Urgent fix can take exception as long as it has been actively communicated + among [Maintainer]s. + +Any [Maintainer] can merge the PR once the above criteria have been met. + +[^1]: A qualified approval is a GitHub Pull Request review with "Approve" + status from an OpenTelemetry Go [Approver] or [Maintainer]. +[^2]: Trivial changes include: typo corrections, cosmetic non-substantive + changes, documentation corrections or updates, dependency updates, etc. ## Design Choices @@ -216,7 +244,7 @@ Meaning a `config` from one package should not be directly used by another. The one exception is the API packages. The configs from the base API, eg. `go.opentelemetry.io/otel/trace.TracerConfig` and `go.opentelemetry.io/otel/metric.InstrumentConfig`, are intended to be consumed -by the SDK therefor it is expected that these are exported. +by the SDK therefore it is expected that these are exported. When a config is exported we want to maintain forward and backward compatibility, to achieve this no fields should be exported but should @@ -234,12 +262,12 @@ func newConfig(options ...Option) config { for _, option := range options { config = option.apply(config) } - // Preform any validation here. + // Perform any validation here. return config } ``` -If validation of the `config` options is also preformed this can return an +If validation of the `config` options is also performed this can return an error as well that is expected to be handled by the instantiation function or propagated to the user. @@ -438,7 +466,7 @@ their parameters appropriately named. #### Interface Stability All exported stable interfaces that include the following warning in their -doumentation are allowed to be extended with additional methods. +documentation are allowed to be extended with additional methods. > Warning: methods may be added to this interface in minor releases. @@ -500,27 +528,30 @@ interface that defines the specific functionality should be preferred. ## Approvers and Maintainers -Approvers: +### Approvers - [Evan Torrie](https://github.com/evantorrie), Verizon Media -- [Josh MacDonald](https://github.com/jmacd), LightStep - [Sam Xie](https://github.com/XSAM), Cisco/AppDynamics - [David Ashpole](https://github.com/dashpole), Google - [Robert Pająk](https://github.com/pellared), Splunk - [Chester Cheung](https://github.com/hanyuancheung), Tencent - [Damien Mathieu](https://github.com/dmathieu), Elastic -Maintainers: +### Maintainers - [Aaron Clawson](https://github.com/MadVikingGod), LightStep - [Anthony Mirabella](https://github.com/Aneurysm9), AWS - [Tyler Yahn](https://github.com/MrAlias), Splunk -Emeritus: +### Emeritus - [Gustavo Silva Paiva](https://github.com/paivagustavo), LightStep +- [Josh MacDonald](https://github.com/jmacd), LightStep ### Become an Approver or a Maintainer See the [community membership document in OpenTelemetry community repo](https://github.com/open-telemetry/community/blob/main/community-membership.md). + +[Approver]: #approvers +[Maintainer]: #maintainers diff --git a/vendor/go.opentelemetry.io/otel/Makefile b/vendor/go.opentelemetry.io/otel/Makefile index 0e6ffa284e..91ead91b41 100644 --- a/vendor/go.opentelemetry.io/otel/Makefile +++ b/vendor/go.opentelemetry.io/otel/Makefile @@ -156,7 +156,7 @@ go-mod-tidy/%: DIR=$* go-mod-tidy/%: | crosslink @echo "$(GO) mod tidy in $(DIR)" \ && cd $(DIR) \ - && $(GO) mod tidy -compat=1.18 + && $(GO) mod tidy -compat=1.19 .PHONY: lint-modules lint-modules: go-mod-tidy diff --git a/vendor/go.opentelemetry.io/otel/README.md b/vendor/go.opentelemetry.io/otel/README.md index 878d87e58b..e138a8a07f 100644 --- a/vendor/go.opentelemetry.io/otel/README.md +++ b/vendor/go.opentelemetry.io/otel/README.md @@ -14,7 +14,7 @@ It provides a set of APIs to directly measure performance and behavior of your s | Signal | Status | Project | | ------- | ---------- | ------- | | Traces | Stable | N/A | -| Metrics | Alpha | N/A | +| Metrics | Beta | N/A | | Logs | Frozen [1] | N/A | - [1]: The Logs signal development is halted for this project while we develop both Traces and Metrics. @@ -52,19 +52,14 @@ Currently, this project supports the following environments. | ------- | ---------- | ------------ | | Ubuntu | 1.20 | amd64 | | Ubuntu | 1.19 | amd64 | -| Ubuntu | 1.18 | amd64 | | Ubuntu | 1.20 | 386 | | Ubuntu | 1.19 | 386 | -| Ubuntu | 1.18 | 386 | | MacOS | 1.20 | amd64 | | MacOS | 1.19 | amd64 | -| MacOS | 1.18 | amd64 | | Windows | 1.20 | amd64 | | Windows | 1.19 | amd64 | -| Windows | 1.18 | amd64 | | Windows | 1.20 | 386 | | Windows | 1.19 | 386 | -| Windows | 1.18 | 386 | While this project should work for other systems, no compatibility guarantees are made for those systems currently. diff --git a/vendor/go.opentelemetry.io/otel/attribute/set.go b/vendor/go.opentelemetry.io/otel/attribute/set.go index 26be598322..b976367e46 100644 --- a/vendor/go.opentelemetry.io/otel/attribute/set.go +++ b/vendor/go.opentelemetry.io/otel/attribute/set.go @@ -18,6 +18,7 @@ import ( "encoding/json" "reflect" "sort" + "sync" ) type ( @@ -62,6 +63,12 @@ var ( iface: [0]KeyValue{}, }, } + + // sortables is a pool of Sortables used to create Sets with a user does + // not provide one. + sortables = sync.Pool{ + New: func() interface{} { return new(Sortable) }, + } ) // EmptySet returns a reference to a Set with no elements. @@ -91,7 +98,7 @@ func (l *Set) Len() int { // Get returns the KeyValue at ordered position idx in this set. func (l *Set) Get(idx int) (KeyValue, bool) { - if l == nil { + if l == nil || !l.equivalent.Valid() { return KeyValue{}, false } value := l.equivalent.reflectValue() @@ -107,7 +114,7 @@ func (l *Set) Get(idx int) (KeyValue, bool) { // Value returns the value of a specified key in this set. func (l *Set) Value(k Key) (Value, bool) { - if l == nil { + if l == nil || !l.equivalent.Valid() { return Value{}, false } rValue := l.equivalent.reflectValue() @@ -191,7 +198,9 @@ func NewSet(kvs ...KeyValue) Set { if len(kvs) == 0 { return empty() } - s, _ := NewSetWithSortableFiltered(kvs, new(Sortable), nil) + srt := sortables.Get().(*Sortable) + s, _ := NewSetWithSortableFiltered(kvs, srt, nil) + sortables.Put(srt) return s } @@ -218,7 +227,10 @@ func NewSetWithFiltered(kvs []KeyValue, filter Filter) (Set, []KeyValue) { if len(kvs) == 0 { return empty(), nil } - return NewSetWithSortableFiltered(kvs, new(Sortable), filter) + srt := sortables.Get().(*Sortable) + s, filtered := NewSetWithSortableFiltered(kvs, srt, filter) + sortables.Put(srt) + return s, filtered } // NewSetWithSortableFiltered returns a new Set. diff --git a/vendor/go.opentelemetry.io/otel/exporters/jaeger/README.md b/vendor/go.opentelemetry.io/otel/exporters/jaeger/README.md index 598c569a51..9b9d370dd3 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/jaeger/README.md +++ b/vendor/go.opentelemetry.io/otel/exporters/jaeger/README.md @@ -47,4 +47,4 @@ When re-generating Thrift code in the future, please adapt import paths as neces - [Jaeger](https://www.jaegertracing.io/) - [OpenTelemetry to Jaeger Transformation](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk_exporters/jaeger.md) -- [OpenTelemetry Environment Variable Specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/sdk-environment-variables.md) +- [OpenTelemetry Environment Variable Specification](https://opentelemetry.io/docs/reference/specification/sdk-environment-variables/#general-sdk-configuration) diff --git a/vendor/go.opentelemetry.io/otel/exporters/jaeger/env.go b/vendor/go.opentelemetry.io/otel/exporters/jaeger/env.go index a7253e4831..460fb5e135 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/jaeger/env.go +++ b/vendor/go.opentelemetry.io/otel/exporters/jaeger/env.go @@ -37,7 +37,7 @@ const ( // envOr returns an env variable's value if it is exists or the default if not. func envOr(key, defaultValue string) string { - if v, ok := os.LookupEnv(key); ok && v != "" { + if v := os.Getenv(key); v != "" { return v } return defaultValue diff --git a/vendor/go.opentelemetry.io/otel/exporters/jaeger/internal/third_party/thrift/lib/go/thrift/exception.go b/vendor/go.opentelemetry.io/otel/exporters/jaeger/internal/third_party/thrift/lib/go/thrift/exception.go index 53bf862ea5..630b938f00 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/jaeger/internal/third_party/thrift/lib/go/thrift/exception.go +++ b/vendor/go.opentelemetry.io/otel/exporters/jaeger/internal/third_party/thrift/lib/go/thrift/exception.go @@ -77,7 +77,7 @@ const ( // WrapTException wraps an error into TException. // // If err is nil or already TException, it's returned as-is. -// Otherwise it will be wraped into TException with TExceptionType() returning +// Otherwise it will be wrapped into TException with TExceptionType() returning // TExceptionTypeUnknown, and Unwrap() returning the original error. func WrapTException(err error) TException { if err == nil { diff --git a/vendor/go.opentelemetry.io/otel/exporters/jaeger/internal/third_party/thrift/lib/go/thrift/transport.go b/vendor/go.opentelemetry.io/otel/exporters/jaeger/internal/third_party/thrift/lib/go/thrift/transport.go index ba2738a8df..d68d0b3179 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/jaeger/internal/third_party/thrift/lib/go/thrift/transport.go +++ b/vendor/go.opentelemetry.io/otel/exporters/jaeger/internal/third_party/thrift/lib/go/thrift/transport.go @@ -56,7 +56,7 @@ type stringWriter interface { WriteString(s string) (n int, err error) } -// This is "enchanced" transport with extra capabilities. You need to use one of these +// This is "enhanced" transport with extra capabilities. You need to use one of these // to construct protocol. // Notably, TSocket does not implement this interface, and it is always a mistake to use // TSocket directly in protocol. diff --git a/vendor/go.opentelemetry.io/otel/exporters/jaeger/internal/third_party/thrift/lib/go/thrift/type.go b/vendor/go.opentelemetry.io/otel/exporters/jaeger/internal/third_party/thrift/lib/go/thrift/type.go index 4292ffcadb..b24f1b05c4 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/jaeger/internal/third_party/thrift/lib/go/thrift/type.go +++ b/vendor/go.opentelemetry.io/otel/exporters/jaeger/internal/third_party/thrift/lib/go/thrift/type.go @@ -40,7 +40,7 @@ const ( LIST = 15 UTF8 = 16 UTF16 = 17 - //BINARY = 18 wrong and unusued + //BINARY = 18 wrong and unused ) var typeNames = map[int]string{ diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/internal/header.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/header.go similarity index 75% rename from vendor/go.opentelemetry.io/otel/exporters/otlp/internal/header.go rename to vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/header.go index 9aa62ed9e8..7fcd89a40f 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/internal/header.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/header.go @@ -12,13 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package internal contains common functionality for all OTLP exporters. -package internal // import "go.opentelemetry.io/otel/exporters/otlp/internal" +package internal // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal" -import "go.opentelemetry.io/otel" +import ( + "go.opentelemetry.io/otel/exporters/otlp/otlptrace" +) -// GetUserAgentHeader return an OTLP header value form "OTel OTLP Exporter Go/{{ .Version }}" +// GetUserAgentHeader returns an OTLP header value form "OTel OTLP Exporter Go/{{ .Version }}" // https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#user-agent func GetUserAgentHeader() string { - return "OTel OTLP Exporter Go/" + otel.Version() + return "OTel OTLP Exporter Go/" + otlptrace.Version() } diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig/options.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig/options.go index c48ffd5308..1a6bb423b3 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig/options.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig/options.go @@ -27,6 +27,7 @@ import ( "go.opentelemetry.io/otel/exporters/otlp/internal" "go.opentelemetry.io/otel/exporters/otlp/internal/retry" + otinternal "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal" ) const ( @@ -97,7 +98,7 @@ func NewGRPCConfig(opts ...GRPCOption) Config { Timeout: DefaultTimeout, }, RetryConfig: retry.DefaultConfig, - DialOptions: []grpc.DialOption{grpc.WithUserAgent(internal.GetUserAgentHeader())}, + DialOptions: []grpc.DialOption{grpc.WithUserAgent(otinternal.GetUserAgentHeader())}, } cfg = ApplyGRPCEnvConfigs(cfg) for _, opt := range opts { diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/client.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/client.go index fe23f8e376..2ab2a6e148 100644 --- a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/client.go +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/client.go @@ -130,13 +130,16 @@ var errAlreadyStopped = errors.New("the client is already stopped") // If the client has already stopped, an error will be returned describing // this. func (c *client) Stop(ctx context.Context) error { + // Make sure to return context error if the context is done when calling this method. + err := ctx.Err() + // Acquire the c.tscMu lock within the ctx lifetime. acquired := make(chan struct{}) go func() { c.tscMu.Lock() close(acquired) }() - var err error + select { case <-ctx.Done(): // The Stop timeout is reached. Kill any remaining exports to force diff --git a/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/version.go b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/version.go new file mode 100644 index 0000000000..851e8d1b06 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/exporters/otlp/otlptrace/version.go @@ -0,0 +1,20 @@ +// Copyright The OpenTelemetry Authors +// +// 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. + +package otlptrace // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace" + +// Version is the current release version of the OpenTelemetry OTLP trace exporter in use. +func Version() string { + return "1.15.1" +} diff --git a/vendor/go.opentelemetry.io/otel/handler.go b/vendor/go.opentelemetry.io/otel/handler.go index ecd363ab51..4115fe3bbb 100644 --- a/vendor/go.opentelemetry.io/otel/handler.go +++ b/vendor/go.opentelemetry.io/otel/handler.go @@ -15,58 +15,16 @@ package otel // import "go.opentelemetry.io/otel" import ( - "log" - "os" - "sync/atomic" - "unsafe" + "go.opentelemetry.io/otel/internal/global" ) var ( - // globalErrorHandler provides an ErrorHandler that can be used - // throughout an OpenTelemetry instrumented project. When a user - // specified ErrorHandler is registered (`SetErrorHandler`) all calls to - // `Handle` and will be delegated to the registered ErrorHandler. - globalErrorHandler = defaultErrorHandler() - - // Compile-time check that delegator implements ErrorHandler. - _ ErrorHandler = (*delegator)(nil) - // Compile-time check that errLogger implements ErrorHandler. - _ ErrorHandler = (*errLogger)(nil) + // Compile-time check global.ErrDelegator implements ErrorHandler. + _ ErrorHandler = (*global.ErrDelegator)(nil) + // Compile-time check global.ErrLogger implements ErrorHandler. + _ ErrorHandler = (*global.ErrLogger)(nil) ) -type delegator struct { - delegate unsafe.Pointer -} - -func (d *delegator) Handle(err error) { - d.getDelegate().Handle(err) -} - -func (d *delegator) getDelegate() ErrorHandler { - return *(*ErrorHandler)(atomic.LoadPointer(&d.delegate)) -} - -// setDelegate sets the ErrorHandler delegate. -func (d *delegator) setDelegate(eh ErrorHandler) { - atomic.StorePointer(&d.delegate, unsafe.Pointer(&eh)) -} - -func defaultErrorHandler() *delegator { - d := &delegator{} - d.setDelegate(&errLogger{l: log.New(os.Stderr, "", log.LstdFlags)}) - return d -} - -// errLogger logs errors if no delegate is set, otherwise they are delegated. -type errLogger struct { - l *log.Logger -} - -// Handle logs err if no delegate is set, otherwise it is delegated. -func (h *errLogger) Handle(err error) { - h.l.Print(err) -} - // GetErrorHandler returns the global ErrorHandler instance. // // The default ErrorHandler instance returned will log all errors to STDERR @@ -76,9 +34,7 @@ func (h *errLogger) Handle(err error) { // // Subsequent calls to SetErrorHandler after the first will not forward errors // to the new ErrorHandler for prior returned instances. -func GetErrorHandler() ErrorHandler { - return globalErrorHandler -} +func GetErrorHandler() ErrorHandler { return global.GetErrorHandler() } // SetErrorHandler sets the global ErrorHandler to h. // @@ -86,11 +42,7 @@ func GetErrorHandler() ErrorHandler { // GetErrorHandler will send errors to h instead of the default logging // ErrorHandler. Subsequent calls will set the global ErrorHandler, but not // delegate errors to h. -func SetErrorHandler(h ErrorHandler) { - globalErrorHandler.setDelegate(h) -} +func SetErrorHandler(h ErrorHandler) { global.SetErrorHandler(h) } // Handle is a convenience function for ErrorHandler().Handle(err). -func Handle(err error) { - GetErrorHandler().Handle(err) -} +func Handle(err error) { global.Handle(err) } diff --git a/vendor/go.opentelemetry.io/otel/internal/global/handler.go b/vendor/go.opentelemetry.io/otel/internal/global/handler.go new file mode 100644 index 0000000000..3dcd1caae6 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/internal/global/handler.go @@ -0,0 +1,103 @@ +// Copyright The OpenTelemetry Authors +// +// 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. + +package global // import "go.opentelemetry.io/otel/internal/global" + +import ( + "log" + "os" + "sync/atomic" + "unsafe" +) + +var ( + // GlobalErrorHandler provides an ErrorHandler that can be used + // throughout an OpenTelemetry instrumented project. When a user + // specified ErrorHandler is registered (`SetErrorHandler`) all calls to + // `Handle` and will be delegated to the registered ErrorHandler. + GlobalErrorHandler = defaultErrorHandler() + + // Compile-time check that delegator implements ErrorHandler. + _ ErrorHandler = (*ErrDelegator)(nil) + // Compile-time check that errLogger implements ErrorHandler. + _ ErrorHandler = (*ErrLogger)(nil) +) + +// ErrorHandler handles irremediable events. +type ErrorHandler interface { + // Handle handles any error deemed irremediable by an OpenTelemetry + // component. + Handle(error) +} + +type ErrDelegator struct { + delegate unsafe.Pointer +} + +func (d *ErrDelegator) Handle(err error) { + d.getDelegate().Handle(err) +} + +func (d *ErrDelegator) getDelegate() ErrorHandler { + return *(*ErrorHandler)(atomic.LoadPointer(&d.delegate)) +} + +// setDelegate sets the ErrorHandler delegate. +func (d *ErrDelegator) setDelegate(eh ErrorHandler) { + atomic.StorePointer(&d.delegate, unsafe.Pointer(&eh)) +} + +func defaultErrorHandler() *ErrDelegator { + d := &ErrDelegator{} + d.setDelegate(&ErrLogger{l: log.New(os.Stderr, "", log.LstdFlags)}) + return d +} + +// ErrLogger logs errors if no delegate is set, otherwise they are delegated. +type ErrLogger struct { + l *log.Logger +} + +// Handle logs err if no delegate is set, otherwise it is delegated. +func (h *ErrLogger) Handle(err error) { + h.l.Print(err) +} + +// GetErrorHandler returns the global ErrorHandler instance. +// +// The default ErrorHandler instance returned will log all errors to STDERR +// until an override ErrorHandler is set with SetErrorHandler. All +// ErrorHandler returned prior to this will automatically forward errors to +// the set instance instead of logging. +// +// Subsequent calls to SetErrorHandler after the first will not forward errors +// to the new ErrorHandler for prior returned instances. +func GetErrorHandler() ErrorHandler { + return GlobalErrorHandler +} + +// SetErrorHandler sets the global ErrorHandler to h. +// +// The first time this is called all ErrorHandler previously returned from +// GetErrorHandler will send errors to h instead of the default logging +// ErrorHandler. Subsequent calls will set the global ErrorHandler, but not +// delegate errors to h. +func SetErrorHandler(h ErrorHandler) { + GlobalErrorHandler.setDelegate(h) +} + +// Handle is a convenience function for ErrorHandler().Handle(err). +func Handle(err error) { + GetErrorHandler().Handle(err) +} diff --git a/vendor/go.opentelemetry.io/otel/internal/global/internal_logging.go b/vendor/go.opentelemetry.io/otel/internal/global/internal_logging.go index 293c08961f..5951fd06d4 100644 --- a/vendor/go.opentelemetry.io/otel/internal/global/internal_logging.go +++ b/vendor/go.opentelemetry.io/otel/internal/global/internal_logging.go @@ -24,7 +24,7 @@ import ( "github.com/go-logr/stdr" ) -// globalLogger is the logging interface used within the otel api and sdk provide deatails of the internals. +// globalLogger is the logging interface used within the otel api and sdk provide details of the internals. // // The default logger uses stdr which is backed by the standard `log.Logger` // interface. This logger will only show messages at the Error Level. @@ -36,8 +36,9 @@ func init() { // SetLogger overrides the globalLogger with l. // -// To see Info messages use a logger with `l.V(1).Enabled() == true` -// To see Debug messages use a logger with `l.V(5).Enabled() == true`. +// To see Warn messages use a logger with `l.V(1).Enabled() == true` +// To see Info messages use a logger with `l.V(4).Enabled() == true` +// To see Debug messages use a logger with `l.V(8).Enabled() == true`. func SetLogger(l logr.Logger) { atomic.StorePointer(&globalLogger, unsafe.Pointer(&l)) } @@ -47,9 +48,9 @@ func getLogger() logr.Logger { } // Info prints messages about the general state of the API or SDK. -// This should usually be less then 5 messages a minute. +// This should usually be less than 5 messages a minute. func Info(msg string, keysAndValues ...interface{}) { - getLogger().V(1).Info(msg, keysAndValues...) + getLogger().V(4).Info(msg, keysAndValues...) } // Error prints messages about exceptional states of the API or SDK. @@ -59,5 +60,11 @@ func Error(err error, msg string, keysAndValues ...interface{}) { // Debug prints messages about all internal changes in the API or SDK. func Debug(msg string, keysAndValues ...interface{}) { - getLogger().V(5).Info(msg, keysAndValues...) + getLogger().V(8).Info(msg, keysAndValues...) +} + +// Warn prints messages about warnings in the API or SDK. +// Not an error but is likely more important than an informational event. +func Warn(msg string, keysAndValues ...interface{}) { + getLogger().V(1).Info(msg, keysAndValues...) } diff --git a/vendor/go.opentelemetry.io/otel/sdk/internal/env/env.go b/vendor/go.opentelemetry.io/otel/sdk/internal/env/env.go index 5e94b8ae52..59dcfab250 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/internal/env/env.go +++ b/vendor/go.opentelemetry.io/otel/sdk/internal/env/env.go @@ -70,8 +70,8 @@ const ( // returned. func firstInt(defaultValue int, keys ...string) int { for _, key := range keys { - value, ok := os.LookupEnv(key) - if !ok { + value := os.Getenv(key) + if value == "" { continue } @@ -88,10 +88,10 @@ func firstInt(defaultValue int, keys ...string) int { } // IntEnvOr returns the int value of the environment variable with name key if -// it exists and the value is an int. Otherwise, defaultValue is returned. +// it exists, it is not empty, and the value is an int. Otherwise, defaultValue is returned. func IntEnvOr(key string, defaultValue int) int { - value, ok := os.LookupEnv(key) - if !ok { + value := os.Getenv(key) + if value == "" { return defaultValue } diff --git a/vendor/go.opentelemetry.io/otel/sdk/internal/internal.go b/vendor/go.opentelemetry.io/otel/sdk/internal/internal.go index 84a02306e6..dfeaaa8ca0 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/internal/internal.go +++ b/vendor/go.opentelemetry.io/otel/sdk/internal/internal.go @@ -14,16 +14,7 @@ package internal // import "go.opentelemetry.io/otel/sdk/internal" -import ( - "fmt" - "time" - - "go.opentelemetry.io/otel" -) - -// UserAgent is the user agent to be added to the outgoing -// requests from the exporters. -var UserAgent = fmt.Sprintf("opentelemetry-go/%s", otel.Version()) +import "time" // MonotonicEndTime returns the end time at present // but offset from start, monotonically. diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/auto.go b/vendor/go.opentelemetry.io/otel/sdk/resource/auto.go index c1d220408a..324dd4baf2 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/auto.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/auto.go @@ -18,6 +18,7 @@ import ( "context" "errors" "fmt" + "strings" ) var ( @@ -45,28 +46,65 @@ type Detector interface { // Detect calls all input detectors sequentially and merges each result with the previous one. // It returns the merged error too. func Detect(ctx context.Context, detectors ...Detector) (*Resource, error) { - var autoDetectedRes *Resource - var errInfo []string + r := new(Resource) + return r, detect(ctx, r, detectors) +} + +// detect runs all detectors using ctx and merges the result into res. This +// assumes res is allocated and not nil, it will panic otherwise. +func detect(ctx context.Context, res *Resource, detectors []Detector) error { + var ( + r *Resource + errs detectErrs + err error + ) + for _, detector := range detectors { if detector == nil { continue } - res, err := detector.Detect(ctx) + r, err = detector.Detect(ctx) if err != nil { - errInfo = append(errInfo, err.Error()) + errs = append(errs, err) if !errors.Is(err, ErrPartialResource) { continue } } - autoDetectedRes, err = Merge(autoDetectedRes, res) + r, err = Merge(res, r) if err != nil { - errInfo = append(errInfo, err.Error()) + errs = append(errs, err) } + *res = *r } - var aggregatedError error - if len(errInfo) > 0 { - aggregatedError = fmt.Errorf("detecting resources: %s", errInfo) + if len(errs) == 0 { + return nil } - return autoDetectedRes, aggregatedError + return errs +} + +type detectErrs []error + +func (e detectErrs) Error() string { + errStr := make([]string, len(e)) + for i, err := range e { + errStr[i] = fmt.Sprintf("* %s", err) + } + + format := "%d errors occurred detecting resource:\n\t%s" + return fmt.Sprintf(format, len(e), strings.Join(errStr, "\n\t")) +} + +func (e detectErrs) Unwrap() error { + switch len(e) { + case 0: + return nil + case 1: + return e[0] + } + return e[1:] +} + +func (e detectErrs) Is(target error) bool { + return len(e) != 0 && errors.Is(e[0], target) } diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/builtin.go b/vendor/go.opentelemetry.io/otel/sdk/resource/builtin.go index aa0f942f49..72320ca51f 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/builtin.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/builtin.go @@ -20,8 +20,8 @@ import ( "os" "path/filepath" - "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/sdk" semconv "go.opentelemetry.io/otel/semconv/v1.17.0" ) @@ -62,7 +62,7 @@ func (telemetrySDK) Detect(context.Context) (*Resource, error) { semconv.SchemaURL, semconv.TelemetrySDKName("opentelemetry"), semconv.TelemetrySDKLanguageGo, - semconv.TelemetrySDKVersion(otel.Version()), + semconv.TelemetrySDKVersion(sdk.Version()), ), nil } diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/config.go b/vendor/go.opentelemetry.io/otel/sdk/resource/config.go index f9a2a29990..f263919f6e 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/config.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/config.go @@ -71,6 +71,11 @@ func WithHost() Option { return WithDetectors(host{}) } +// WithHostID adds host ID information to the configured resource. +func WithHostID() Option { + return WithDetectors(hostIDDetector{}) +} + // WithTelemetrySDK adds TelemetrySDK version info to the configured resource. func WithTelemetrySDK() Option { return WithDetectors(telemetrySDK{}) diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id.go b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id.go new file mode 100644 index 0000000000..b8e934d4f8 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id.go @@ -0,0 +1,120 @@ +// Copyright The OpenTelemetry Authors +// +// 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. + +package resource // import "go.opentelemetry.io/otel/sdk/resource" + +import ( + "context" + "errors" + "strings" + + semconv "go.opentelemetry.io/otel/semconv/v1.17.0" +) + +type hostIDProvider func() (string, error) + +var defaultHostIDProvider hostIDProvider = platformHostIDReader.read + +var hostID = defaultHostIDProvider + +type hostIDReader interface { + read() (string, error) +} + +type fileReader func(string) (string, error) + +type commandExecutor func(string, ...string) (string, error) + +// hostIDReaderBSD implements hostIDReader. +type hostIDReaderBSD struct { + execCommand commandExecutor + readFile fileReader +} + +// read attempts to read the machine-id from /etc/hostid. If not found it will +// execute `kenv -q smbios.system.uuid`. If neither location yields an id an +// error will be returned. +func (r *hostIDReaderBSD) read() (string, error) { + if result, err := r.readFile("/etc/hostid"); err == nil { + return strings.TrimSpace(result), nil + } + + if result, err := r.execCommand("kenv", "-q", "smbios.system.uuid"); err == nil { + return strings.TrimSpace(result), nil + } + + return "", errors.New("host id not found in: /etc/hostid or kenv") +} + +// hostIDReaderDarwin implements hostIDReader. +type hostIDReaderDarwin struct { + execCommand commandExecutor +} + +// read executes `ioreg -rd1 -c "IOPlatformExpertDevice"` and parses host id +// from the IOPlatformUUID line. If the command fails or the uuid cannot be +// parsed an error will be returned. +func (r *hostIDReaderDarwin) read() (string, error) { + result, err := r.execCommand("ioreg", "-rd1", "-c", "IOPlatformExpertDevice") + if err != nil { + return "", err + } + + lines := strings.Split(result, "\n") + for _, line := range lines { + if strings.Contains(line, "IOPlatformUUID") { + parts := strings.Split(line, " = ") + if len(parts) == 2 { + return strings.Trim(parts[1], "\""), nil + } + break + } + } + + return "", errors.New("could not parse IOPlatformUUID") +} + +type hostIDReaderLinux struct { + readFile fileReader +} + +// read attempts to read the machine-id from /etc/machine-id followed by +// /var/lib/dbus/machine-id. If neither location yields an ID an error will +// be returned. +func (r *hostIDReaderLinux) read() (string, error) { + if result, err := r.readFile("/etc/machine-id"); err == nil { + return strings.TrimSpace(result), nil + } + + if result, err := r.readFile("/var/lib/dbus/machine-id"); err == nil { + return strings.TrimSpace(result), nil + } + + return "", errors.New("host id not found in: /etc/machine-id or /var/lib/dbus/machine-id") +} + +type hostIDDetector struct{} + +// Detect returns a *Resource containing the platform specific host id. +func (hostIDDetector) Detect(ctx context.Context) (*Resource, error) { + hostID, err := hostID() + if err != nil { + return nil, err + } + + return NewWithAttributes( + semconv.SchemaURL, + semconv.HostID(hostID), + ), nil +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_bsd.go b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_bsd.go new file mode 100644 index 0000000000..1778bbacf0 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_bsd.go @@ -0,0 +1,23 @@ +// Copyright The OpenTelemetry Authors +// +// 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. + +//go:build dragonfly || freebsd || netbsd || openbsd || solaris +// +build dragonfly freebsd netbsd openbsd solaris + +package resource // import "go.opentelemetry.io/otel/sdk/resource" + +var platformHostIDReader hostIDReader = &hostIDReaderBSD{ + execCommand: execCommand, + readFile: readFile, +} diff --git a/vendor/go.opencensus.io/plugin/ocgrpc/doc.go b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_darwin.go similarity index 69% rename from vendor/go.opencensus.io/plugin/ocgrpc/doc.go rename to vendor/go.opentelemetry.io/otel/sdk/resource/host_id_darwin.go index 1370323fb7..ba41409b23 100644 --- a/vendor/go.opencensus.io/plugin/ocgrpc/doc.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_darwin.go @@ -1,4 +1,4 @@ -// Copyright 2017, OpenCensus Authors +// Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package ocgrpc contains OpenCensus stats and trace -// integrations for gRPC. -// -// Use ServerHandler for servers and ClientHandler for clients. -package ocgrpc // import "go.opencensus.io/plugin/ocgrpc" +package resource // import "go.opentelemetry.io/otel/sdk/resource" + +var platformHostIDReader hostIDReader = &hostIDReaderDarwin{ + execCommand: execCommand, +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_exec.go b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_exec.go new file mode 100644 index 0000000000..0080fc6b69 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_exec.go @@ -0,0 +1,29 @@ +// Copyright The OpenTelemetry Authors +// +// 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. + +//go:build bsd || darwin + +package resource // import "go.opentelemetry.io/otel/sdk/resource" + +import "os/exec" + +func execCommand(name string, arg ...string) (string, error) { + cmd := exec.Command(name, arg...) + b, err := cmd.Output() + if err != nil { + return "", err + } + + return string(b), nil +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_linux.go b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_linux.go new file mode 100644 index 0000000000..410579b8fc --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_linux.go @@ -0,0 +1,22 @@ +// Copyright The OpenTelemetry Authors +// +// 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. + +//go:build linux +// +build linux + +package resource // import "go.opentelemetry.io/otel/sdk/resource" + +var platformHostIDReader hostIDReader = &hostIDReaderLinux{ + readFile: readFile, +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_readfile.go b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_readfile.go new file mode 100644 index 0000000000..df4dc92c19 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_readfile.go @@ -0,0 +1,28 @@ +// Copyright The OpenTelemetry Authors +// +// 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. + +//go:build bsd || linux + +package resource // import "go.opentelemetry.io/otel/sdk/resource" + +import "os" + +func readFile(filename string) (string, error) { + b, err := os.ReadFile(filename) + if err != nil { + return "", nil + } + + return string(b), nil +} diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_unsupported.go b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_unsupported.go new file mode 100644 index 0000000000..89df9d6882 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_unsupported.go @@ -0,0 +1,36 @@ +// Copyright The OpenTelemetry Authors +// +// 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. + +// +build !darwin +// +build !dragonfly +// +build !freebsd +// +build !linux +// +build !netbsd +// +build !openbsd +// +build !solaris +// +build !windows + +package resource // import "go.opentelemetry.io/otel/sdk/resource" + +// hostIDReaderUnsupported is a placeholder implementation for operating systems +// for which this project currently doesn't support host.id +// attribute detection. See build tags declaration early on this file +// for a list of unsupported OSes. +type hostIDReaderUnsupported struct{} + +func (*hostIDReaderUnsupported) read() (string, error) { + return "", nil +} + +var platformHostIDReader hostIDReader = &hostIDReaderUnsupported{} diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_windows.go b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_windows.go new file mode 100644 index 0000000000..5b431c6ee6 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/host_id_windows.go @@ -0,0 +1,48 @@ +// Copyright The OpenTelemetry Authors +// +// 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. + +//go:build windows +// +build windows + +package resource // import "go.opentelemetry.io/otel/sdk/resource" + +import ( + "golang.org/x/sys/windows/registry" +) + +// implements hostIDReader +type hostIDReaderWindows struct{} + +// read reads MachineGuid from the windows registry key: +// SOFTWARE\Microsoft\Cryptography +func (*hostIDReaderWindows) read() (string, error) { + k, err := registry.OpenKey( + registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Cryptography`, + registry.QUERY_VALUE|registry.WOW64_64KEY, + ) + + if err != nil { + return "", err + } + defer k.Close() + + guid, _, err := k.GetStringValue("MachineGuid") + if err != nil { + return "", err + } + + return guid, nil +} + +var platformHostIDReader hostIDReader = &hostIDReaderWindows{} diff --git a/vendor/go.opentelemetry.io/otel/sdk/resource/resource.go b/vendor/go.opentelemetry.io/otel/sdk/resource/resource.go index c425ff05db..49958a9a60 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/resource/resource.go +++ b/vendor/go.opentelemetry.io/otel/sdk/resource/resource.go @@ -17,7 +17,6 @@ package resource // import "go.opentelemetry.io/otel/sdk/resource" import ( "context" "errors" - "fmt" "sync" "go.opentelemetry.io/otel" @@ -51,17 +50,8 @@ func New(ctx context.Context, opts ...Option) (*Resource, error) { cfg = opt.apply(cfg) } - resource, err := Detect(ctx, cfg.detectors...) - - var err2 error - resource, err2 = Merge(resource, &Resource{schemaURL: cfg.schemaURL}) - if err == nil { - err = err2 - } else if err2 != nil { - err = fmt.Errorf("detecting resources: %s", []string{err.Error(), err2.Error()}) - } - - return resource, err + r := &Resource{schemaURL: cfg.schemaURL} + return r, detect(ctx, r, cfg.detectors) } // NewWithAttributes creates a resource from attrs and associates the resource with a diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/batch_span_processor.go b/vendor/go.opentelemetry.io/otel/sdk/trace/batch_span_processor.go index a2d7db4900..43d5b04230 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/batch_span_processor.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/batch_span_processor.go @@ -91,7 +91,7 @@ var _ SpanProcessor = (*batchSpanProcessor)(nil) // NewBatchSpanProcessor creates a new SpanProcessor that will send completed // span batches to the exporter with the supplied options. // -// If the exporter is nil, the span processor will preform no action. +// If the exporter is nil, the span processor will perform no action. func NewBatchSpanProcessor(exporter SpanExporter, options ...BatchSpanProcessorOption) SpanProcessor { maxQueueSize := env.BatchSpanProcessorMaxQueueSize(DefaultMaxQueueSize) maxExportBatchSize := env.BatchSpanProcessorMaxExportBatchSize(DefaultMaxExportBatchSize) diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/provider.go b/vendor/go.opentelemetry.io/otel/sdk/trace/provider.go index 201c178170..0a018c14de 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/provider.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/provider.go @@ -75,8 +75,9 @@ func (cfg tracerProviderConfig) MarshalLog() interface{} { type TracerProvider struct { mu sync.Mutex namedTracer map[instrumentation.Scope]*tracer - spanProcessors atomic.Value - isShutdown bool + spanProcessors atomic.Pointer[spanProcessorStates] + + isShutdown atomic.Bool // These fields are not protected by the lock mu. They are assumed to be // immutable after creation of the TracerProvider. @@ -119,11 +120,11 @@ func NewTracerProvider(opts ...TracerProviderOption) *TracerProvider { } global.Info("TracerProvider created", "config", o) - spss := spanProcessorStates{} + spss := make(spanProcessorStates, 0, len(o.processors)) for _, sp := range o.processors { spss = append(spss, newSpanProcessorState(sp)) } - tp.spanProcessors.Store(spss) + tp.spanProcessors.Store(&spss) return tp } @@ -136,10 +137,11 @@ func NewTracerProvider(opts ...TracerProviderOption) *TracerProvider { // // This method is safe to be called concurrently. func (p *TracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.Tracer { + // This check happens before the mutex is acquired to avoid deadlocking if Tracer() is called from within Shutdown(). + if p.isShutdown.Load() { + return trace.NewNoopTracerProvider().Tracer(name, opts...) + } c := trace.NewTracerConfig(opts...) - - p.mu.Lock() - defer p.mu.Unlock() if name == "" { name = defaultTracerName } @@ -148,44 +150,74 @@ func (p *TracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.T Version: c.InstrumentationVersion(), SchemaURL: c.SchemaURL(), } - t, ok := p.namedTracer[is] - if !ok { - t = &tracer{ - provider: p, - instrumentationScope: is, + + t, ok := func() (trace.Tracer, bool) { + p.mu.Lock() + defer p.mu.Unlock() + // Must check the flag after acquiring the mutex to avoid returning a valid tracer if Shutdown() ran + // after the first check above but before we acquired the mutex. + if p.isShutdown.Load() { + return trace.NewNoopTracerProvider().Tracer(name, opts...), true } - p.namedTracer[is] = t - global.Info("Tracer created", "name", name, "version", c.InstrumentationVersion(), "schemaURL", c.SchemaURL()) + t, ok := p.namedTracer[is] + if !ok { + t = &tracer{ + provider: p, + instrumentationScope: is, + } + p.namedTracer[is] = t + } + return t, ok + }() + if !ok { + // This code is outside the mutex to not hold the lock while calling third party logging code: + // - That code may do slow things like I/O, which would prolong the duration the lock is held, + // slowing down all tracing consumers. + // - Logging code may be instrumented with tracing and deadlock because it could try + // acquiring the same non-reentrant mutex. + global.Info("Tracer created", "name", name, "version", is.Version, "schemaURL", is.SchemaURL) } return t } // RegisterSpanProcessor adds the given SpanProcessor to the list of SpanProcessors. func (p *TracerProvider) RegisterSpanProcessor(sp SpanProcessor) { - p.mu.Lock() - defer p.mu.Unlock() - if p.isShutdown { + // This check prevents calls during a shutdown. + if p.isShutdown.Load() { return } - newSPS := spanProcessorStates{} - newSPS = append(newSPS, p.spanProcessors.Load().(spanProcessorStates)...) + p.mu.Lock() + defer p.mu.Unlock() + // This check prevents calls after a shutdown. + if p.isShutdown.Load() { + return + } + + current := p.getSpanProcessors() + newSPS := make(spanProcessorStates, 0, len(current)+1) + newSPS = append(newSPS, current...) newSPS = append(newSPS, newSpanProcessorState(sp)) - p.spanProcessors.Store(newSPS) + p.spanProcessors.Store(&newSPS) } // UnregisterSpanProcessor removes the given SpanProcessor from the list of SpanProcessors. func (p *TracerProvider) UnregisterSpanProcessor(sp SpanProcessor) { - p.mu.Lock() - defer p.mu.Unlock() - if p.isShutdown { + // This check prevents calls during a shutdown. + if p.isShutdown.Load() { return } - old := p.spanProcessors.Load().(spanProcessorStates) + p.mu.Lock() + defer p.mu.Unlock() + // This check prevents calls after a shutdown. + if p.isShutdown.Load() { + return + } + old := p.getSpanProcessors() if len(old) == 0 { return } - spss := spanProcessorStates{} - spss = append(spss, old...) + spss := make(spanProcessorStates, len(old)) + copy(spss, old) // stop the span processor if it is started and remove it from the list var stopOnce *spanProcessorState @@ -209,13 +241,13 @@ func (p *TracerProvider) UnregisterSpanProcessor(sp SpanProcessor) { spss[len(spss)-1] = nil spss = spss[:len(spss)-1] - p.spanProcessors.Store(spss) + p.spanProcessors.Store(&spss) } // ForceFlush immediately exports all spans that have not yet been exported for // all the registered span processors. func (p *TracerProvider) ForceFlush(ctx context.Context) error { - spss := p.spanProcessors.Load().(spanProcessorStates) + spss := p.getSpanProcessors() if len(spss) == 0 { return nil } @@ -236,18 +268,21 @@ func (p *TracerProvider) ForceFlush(ctx context.Context) error { // Shutdown shuts down TracerProvider. All registered span processors are shut down // in the order they were registered and any held computational resources are released. +// After Shutdown is called, all methods are no-ops. func (p *TracerProvider) Shutdown(ctx context.Context) error { - spss := p.spanProcessors.Load().(spanProcessorStates) - if len(spss) == 0 { + // This check prevents deadlocks in case of recursive shutdown. + if p.isShutdown.Load() { + return nil + } + p.mu.Lock() + defer p.mu.Unlock() + // This check prevents calls after a shutdown has already been done concurrently. + if !p.isShutdown.CompareAndSwap(false, true) { // did toggle? return nil } - p.mu.Lock() - defer p.mu.Unlock() - p.isShutdown = true - var retErr error - for _, sps := range spss { + for _, sps := range p.getSpanProcessors() { select { case <-ctx.Done(): return ctx.Err() @@ -267,10 +302,14 @@ func (p *TracerProvider) Shutdown(ctx context.Context) error { } } } - p.spanProcessors.Store(spanProcessorStates{}) + p.spanProcessors.Store(&spanProcessorStates{}) return retErr } +func (p *TracerProvider) getSpanProcessors() spanProcessorStates { + return *(p.spanProcessors.Load()) +} + // TracerProviderOption configures a TracerProvider. type TracerProviderOption interface { apply(tracerProviderConfig) tracerProviderConfig diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/simple_span_processor.go b/vendor/go.opentelemetry.io/otel/sdk/trace/simple_span_processor.go index e8530a9593..f8770fff79 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/simple_span_processor.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/simple_span_processor.go @@ -19,12 +19,13 @@ import ( "sync" "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/internal/global" ) // simpleSpanProcessor is a SpanProcessor that synchronously sends all // completed Spans to a trace.Exporter immediately. type simpleSpanProcessor struct { - exporterMu sync.RWMutex + exporterMu sync.Mutex exporter SpanExporter stopOnce sync.Once } @@ -43,6 +44,8 @@ func NewSimpleSpanProcessor(exporter SpanExporter) SpanProcessor { ssp := &simpleSpanProcessor{ exporter: exporter, } + global.Warn("SimpleSpanProcessor is not recommended for production use, consider using BatchSpanProcessor instead.") + return ssp } @@ -51,8 +54,8 @@ func (ssp *simpleSpanProcessor) OnStart(context.Context, ReadWriteSpan) {} // OnEnd immediately exports a ReadOnlySpan. func (ssp *simpleSpanProcessor) OnEnd(s ReadOnlySpan) { - ssp.exporterMu.RLock() - defer ssp.exporterMu.RUnlock() + ssp.exporterMu.Lock() + defer ssp.exporterMu.Unlock() if ssp.exporter != nil && s.SpanContext().TraceFlags().IsSampled() { if err := ssp.exporter.ExportSpans(context.Background(), []ReadOnlySpan{s}); err != nil { diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/span.go b/vendor/go.opentelemetry.io/otel/sdk/trace/span.go index 9fb483a99f..4fcca26e08 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/span.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/span.go @@ -302,7 +302,7 @@ func (s *recordingSpan) addOverCapAttrs(limit int, attrs []attribute.KeyValue) { // most a length of limit. Each string slice value is truncated in this fashion // (the slice length itself is unaffected). // -// No truncation is perfromed for a negative limit. +// No truncation is performed for a negative limit. func truncateAttr(limit int, attr attribute.KeyValue) attribute.KeyValue { if limit < 0 { return attr @@ -410,7 +410,7 @@ func (s *recordingSpan) End(options ...trace.SpanEndOption) { } s.mu.Unlock() - sps := s.tracer.provider.spanProcessors.Load().(spanProcessorStates) + sps := s.tracer.provider.getSpanProcessors() if len(sps) == 0 { return } diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/span_exporter.go b/vendor/go.opentelemetry.io/otel/sdk/trace/span_exporter.go index 9fb3d6eac3..c9bd52f7ad 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/span_exporter.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/span_exporter.go @@ -38,7 +38,7 @@ type SpanExporter interface { // must never be done outside of a new major release. // Shutdown notifies the exporter of a pending halt to operations. The - // exporter is expected to preform any cleanup or synchronization it + // exporter is expected to perform any cleanup or synchronization it // requires while honoring all timeouts and cancellations contained in // the passed context. Shutdown(ctx context.Context) error diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/span_processor.go b/vendor/go.opentelemetry.io/otel/sdk/trace/span_processor.go index e6ae193521..9c53657a71 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/span_processor.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/span_processor.go @@ -62,11 +62,11 @@ type SpanProcessor interface { type spanProcessorState struct { sp SpanProcessor - state *sync.Once + state sync.Once } func newSpanProcessorState(sp SpanProcessor) *spanProcessorState { - return &spanProcessorState{sp: sp, state: &sync.Once{}} + return &spanProcessorState{sp: sp} } type spanProcessorStates []*spanProcessorState diff --git a/vendor/go.opentelemetry.io/otel/sdk/trace/tracer.go b/vendor/go.opentelemetry.io/otel/sdk/trace/tracer.go index f17d924b89..85a71227f3 100644 --- a/vendor/go.opentelemetry.io/otel/sdk/trace/tracer.go +++ b/vendor/go.opentelemetry.io/otel/sdk/trace/tracer.go @@ -51,7 +51,7 @@ func (tr *tracer) Start(ctx context.Context, name string, options ...trace.SpanS s := tr.newSpan(ctx, name, &config) if rw, ok := s.(ReadWriteSpan); ok && s.IsRecording() { - sps := tr.provider.spanProcessors.Load().(spanProcessorStates) + sps := tr.provider.getSpanProcessors() for _, sp := range sps { sp.sp.OnStart(ctx, rw) } diff --git a/vendor/go.opentelemetry.io/otel/sdk/version.go b/vendor/go.opentelemetry.io/otel/sdk/version.go new file mode 100644 index 0000000000..2adddad860 --- /dev/null +++ b/vendor/go.opentelemetry.io/otel/sdk/version.go @@ -0,0 +1,20 @@ +// Copyright The OpenTelemetry Authors +// +// 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. + +package sdk // import "go.opentelemetry.io/otel/sdk" + +// Version is the current release version of the OpenTelemetry SDK in use. +func Version() string { + return "1.15.1" +} diff --git a/vendor/go.opentelemetry.io/otel/trace/noop.go b/vendor/go.opentelemetry.io/otel/trace/noop.go index 73950f2077..7cf6c7f3ef 100644 --- a/vendor/go.opentelemetry.io/otel/trace/noop.go +++ b/vendor/go.opentelemetry.io/otel/trace/noop.go @@ -37,7 +37,7 @@ func (p noopTracerProvider) Tracer(string, ...TracerOption) Tracer { return noopTracer{} } -// noopTracer is an implementation of Tracer that preforms no operations. +// noopTracer is an implementation of Tracer that performs no operations. type noopTracer struct{} var _ Tracer = noopTracer{} @@ -53,7 +53,7 @@ func (t noopTracer) Start(ctx context.Context, name string, _ ...SpanStartOption return ContextWithSpan(ctx, span), span } -// noopSpan is an implementation of Span that preforms no operations. +// noopSpan is an implementation of Span that performs no operations. type noopSpan struct{} var _ Span = noopSpan{} diff --git a/vendor/go.opentelemetry.io/otel/version.go b/vendor/go.opentelemetry.io/otel/version.go index 0e8e5e0232..6c7fe114bb 100644 --- a/vendor/go.opentelemetry.io/otel/version.go +++ b/vendor/go.opentelemetry.io/otel/version.go @@ -16,5 +16,5 @@ package otel // import "go.opentelemetry.io/otel" // Version is the current release version of OpenTelemetry in use. func Version() string { - return "1.14.0" + return "1.15.1" } diff --git a/vendor/go.opentelemetry.io/otel/versions.yaml b/vendor/go.opentelemetry.io/otel/versions.yaml index 40df1fae41..b49ec10296 100644 --- a/vendor/go.opentelemetry.io/otel/versions.yaml +++ b/vendor/go.opentelemetry.io/otel/versions.yaml @@ -14,7 +14,7 @@ module-sets: stable-v1: - version: v1.14.0 + version: v1.15.1 modules: - go.opentelemetry.io/otel - go.opentelemetry.io/otel/bridge/opentracing @@ -26,16 +26,16 @@ module-sets: - go.opentelemetry.io/otel/example/passthrough - go.opentelemetry.io/otel/example/zipkin - go.opentelemetry.io/otel/exporters/jaeger - - go.opentelemetry.io/otel/exporters/zipkin + - go.opentelemetry.io/otel/exporters/otlp/internal/retry - go.opentelemetry.io/otel/exporters/otlp/otlptrace - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp - - go.opentelemetry.io/otel/exporters/otlp/internal/retry - go.opentelemetry.io/otel/exporters/stdout/stdouttrace - - go.opentelemetry.io/otel/trace + - go.opentelemetry.io/otel/exporters/zipkin - go.opentelemetry.io/otel/sdk + - go.opentelemetry.io/otel/trace experimental-metrics: - version: v0.37.0 + version: v0.38.1 modules: - go.opentelemetry.io/otel/example/opencensus - go.opentelemetry.io/otel/example/prometheus diff --git a/vendor/google.golang.org/genproto/googleapis/rpc/code/code.pb.go b/vendor/google.golang.org/genproto/googleapis/rpc/code/code.pb.go deleted file mode 100644 index cc5d52fbcc..0000000000 --- a/vendor/google.golang.org/genproto/googleapis/rpc/code/code.pb.go +++ /dev/null @@ -1,336 +0,0 @@ -// Copyright 2022 Google LLC -// -// 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. - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.26.0 -// protoc v3.21.9 -// source: google/rpc/code.proto - -package code - -import ( - reflect "reflect" - sync "sync" - - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// The canonical error codes for gRPC APIs. -// -// Sometimes multiple error codes may apply. Services should return -// the most specific error code that applies. For example, prefer -// `OUT_OF_RANGE` over `FAILED_PRECONDITION` if both codes apply. -// Similarly prefer `NOT_FOUND` or `ALREADY_EXISTS` over `FAILED_PRECONDITION`. -type Code int32 - -const ( - // Not an error; returned on success. - // - // HTTP Mapping: 200 OK - Code_OK Code = 0 - // The operation was cancelled, typically by the caller. - // - // HTTP Mapping: 499 Client Closed Request - Code_CANCELLED Code = 1 - // Unknown error. For example, this error may be returned when - // a `Status` value received from another address space belongs to - // an error space that is not known in this address space. Also - // errors raised by APIs that do not return enough error information - // may be converted to this error. - // - // HTTP Mapping: 500 Internal Server Error - Code_UNKNOWN Code = 2 - // The client specified an invalid argument. Note that this differs - // from `FAILED_PRECONDITION`. `INVALID_ARGUMENT` indicates arguments - // that are problematic regardless of the state of the system - // (e.g., a malformed file name). - // - // HTTP Mapping: 400 Bad Request - Code_INVALID_ARGUMENT Code = 3 - // The deadline expired before the operation could complete. For operations - // that change the state of the system, this error may be returned - // even if the operation has completed successfully. For example, a - // successful response from a server could have been delayed long - // enough for the deadline to expire. - // - // HTTP Mapping: 504 Gateway Timeout - Code_DEADLINE_EXCEEDED Code = 4 - // Some requested entity (e.g., file or directory) was not found. - // - // Note to server developers: if a request is denied for an entire class - // of users, such as gradual feature rollout or undocumented allowlist, - // `NOT_FOUND` may be used. If a request is denied for some users within - // a class of users, such as user-based access control, `PERMISSION_DENIED` - // must be used. - // - // HTTP Mapping: 404 Not Found - Code_NOT_FOUND Code = 5 - // The entity that a client attempted to create (e.g., file or directory) - // already exists. - // - // HTTP Mapping: 409 Conflict - Code_ALREADY_EXISTS Code = 6 - // The caller does not have permission to execute the specified - // operation. `PERMISSION_DENIED` must not be used for rejections - // caused by exhausting some resource (use `RESOURCE_EXHAUSTED` - // instead for those errors). `PERMISSION_DENIED` must not be - // used if the caller can not be identified (use `UNAUTHENTICATED` - // instead for those errors). This error code does not imply the - // request is valid or the requested entity exists or satisfies - // other pre-conditions. - // - // HTTP Mapping: 403 Forbidden - Code_PERMISSION_DENIED Code = 7 - // The request does not have valid authentication credentials for the - // operation. - // - // HTTP Mapping: 401 Unauthorized - Code_UNAUTHENTICATED Code = 16 - // Some resource has been exhausted, perhaps a per-user quota, or - // perhaps the entire file system is out of space. - // - // HTTP Mapping: 429 Too Many Requests - Code_RESOURCE_EXHAUSTED Code = 8 - // The operation was rejected because the system is not in a state - // required for the operation's execution. For example, the directory - // to be deleted is non-empty, an rmdir operation is applied to - // a non-directory, etc. - // - // Service implementors can use the following guidelines to decide - // between `FAILED_PRECONDITION`, `ABORTED`, and `UNAVAILABLE`: - // - // (a) Use `UNAVAILABLE` if the client can retry just the failing call. - // (b) Use `ABORTED` if the client should retry at a higher level. For - // example, when a client-specified test-and-set fails, indicating the - // client should restart a read-modify-write sequence. - // (c) Use `FAILED_PRECONDITION` if the client should not retry until - // the system state has been explicitly fixed. For example, if an "rmdir" - // fails because the directory is non-empty, `FAILED_PRECONDITION` - // should be returned since the client should not retry unless - // the files are deleted from the directory. - // - // HTTP Mapping: 400 Bad Request - Code_FAILED_PRECONDITION Code = 9 - // The operation was aborted, typically due to a concurrency issue such as - // a sequencer check failure or transaction abort. - // - // See the guidelines above for deciding between `FAILED_PRECONDITION`, - // `ABORTED`, and `UNAVAILABLE`. - // - // HTTP Mapping: 409 Conflict - Code_ABORTED Code = 10 - // The operation was attempted past the valid range. E.g., seeking or - // reading past end-of-file. - // - // Unlike `INVALID_ARGUMENT`, this error indicates a problem that may - // be fixed if the system state changes. For example, a 32-bit file - // system will generate `INVALID_ARGUMENT` if asked to read at an - // offset that is not in the range [0,2^32-1], but it will generate - // `OUT_OF_RANGE` if asked to read from an offset past the current - // file size. - // - // There is a fair bit of overlap between `FAILED_PRECONDITION` and - // `OUT_OF_RANGE`. We recommend using `OUT_OF_RANGE` (the more specific - // error) when it applies so that callers who are iterating through - // a space can easily look for an `OUT_OF_RANGE` error to detect when - // they are done. - // - // HTTP Mapping: 400 Bad Request - Code_OUT_OF_RANGE Code = 11 - // The operation is not implemented or is not supported/enabled in this - // service. - // - // HTTP Mapping: 501 Not Implemented - Code_UNIMPLEMENTED Code = 12 - // Internal errors. This means that some invariants expected by the - // underlying system have been broken. This error code is reserved - // for serious errors. - // - // HTTP Mapping: 500 Internal Server Error - Code_INTERNAL Code = 13 - // The service is currently unavailable. This is most likely a - // transient condition, which can be corrected by retrying with - // a backoff. Note that it is not always safe to retry - // non-idempotent operations. - // - // See the guidelines above for deciding between `FAILED_PRECONDITION`, - // `ABORTED`, and `UNAVAILABLE`. - // - // HTTP Mapping: 503 Service Unavailable - Code_UNAVAILABLE Code = 14 - // Unrecoverable data loss or corruption. - // - // HTTP Mapping: 500 Internal Server Error - Code_DATA_LOSS Code = 15 -) - -// Enum value maps for Code. -var ( - Code_name = map[int32]string{ - 0: "OK", - 1: "CANCELLED", - 2: "UNKNOWN", - 3: "INVALID_ARGUMENT", - 4: "DEADLINE_EXCEEDED", - 5: "NOT_FOUND", - 6: "ALREADY_EXISTS", - 7: "PERMISSION_DENIED", - 16: "UNAUTHENTICATED", - 8: "RESOURCE_EXHAUSTED", - 9: "FAILED_PRECONDITION", - 10: "ABORTED", - 11: "OUT_OF_RANGE", - 12: "UNIMPLEMENTED", - 13: "INTERNAL", - 14: "UNAVAILABLE", - 15: "DATA_LOSS", - } - Code_value = map[string]int32{ - "OK": 0, - "CANCELLED": 1, - "UNKNOWN": 2, - "INVALID_ARGUMENT": 3, - "DEADLINE_EXCEEDED": 4, - "NOT_FOUND": 5, - "ALREADY_EXISTS": 6, - "PERMISSION_DENIED": 7, - "UNAUTHENTICATED": 16, - "RESOURCE_EXHAUSTED": 8, - "FAILED_PRECONDITION": 9, - "ABORTED": 10, - "OUT_OF_RANGE": 11, - "UNIMPLEMENTED": 12, - "INTERNAL": 13, - "UNAVAILABLE": 14, - "DATA_LOSS": 15, - } -) - -func (x Code) Enum() *Code { - p := new(Code) - *p = x - return p -} - -func (x Code) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (Code) Descriptor() protoreflect.EnumDescriptor { - return file_google_rpc_code_proto_enumTypes[0].Descriptor() -} - -func (Code) Type() protoreflect.EnumType { - return &file_google_rpc_code_proto_enumTypes[0] -} - -func (x Code) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use Code.Descriptor instead. -func (Code) EnumDescriptor() ([]byte, []int) { - return file_google_rpc_code_proto_rawDescGZIP(), []int{0} -} - -var File_google_rpc_code_proto protoreflect.FileDescriptor - -var file_google_rpc_code_proto_rawDesc = []byte{ - 0x0a, 0x15, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x63, 0x6f, 0x64, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0a, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x72, 0x70, 0x63, 0x2a, 0xb7, 0x02, 0x0a, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x06, 0x0a, 0x02, - 0x4f, 0x4b, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x4c, 0x45, - 0x44, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x02, - 0x12, 0x14, 0x0a, 0x10, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x41, 0x52, 0x47, 0x55, - 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x03, 0x12, 0x15, 0x0a, 0x11, 0x44, 0x45, 0x41, 0x44, 0x4c, 0x49, - 0x4e, 0x45, 0x5f, 0x45, 0x58, 0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10, 0x04, 0x12, 0x0d, 0x0a, - 0x09, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x05, 0x12, 0x12, 0x0a, 0x0e, - 0x41, 0x4c, 0x52, 0x45, 0x41, 0x44, 0x59, 0x5f, 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x10, 0x06, - 0x12, 0x15, 0x0a, 0x11, 0x50, 0x45, 0x52, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x44, - 0x45, 0x4e, 0x49, 0x45, 0x44, 0x10, 0x07, 0x12, 0x13, 0x0a, 0x0f, 0x55, 0x4e, 0x41, 0x55, 0x54, - 0x48, 0x45, 0x4e, 0x54, 0x49, 0x43, 0x41, 0x54, 0x45, 0x44, 0x10, 0x10, 0x12, 0x16, 0x0a, 0x12, - 0x52, 0x45, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x45, 0x58, 0x48, 0x41, 0x55, 0x53, 0x54, - 0x45, 0x44, 0x10, 0x08, 0x12, 0x17, 0x0a, 0x13, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x5f, 0x50, - 0x52, 0x45, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x09, 0x12, 0x0b, 0x0a, - 0x07, 0x41, 0x42, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x10, 0x0a, 0x12, 0x10, 0x0a, 0x0c, 0x4f, 0x55, - 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x0b, 0x12, 0x11, 0x0a, 0x0d, - 0x55, 0x4e, 0x49, 0x4d, 0x50, 0x4c, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x45, 0x44, 0x10, 0x0c, 0x12, - 0x0c, 0x0a, 0x08, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x10, 0x0d, 0x12, 0x0f, 0x0a, - 0x0b, 0x55, 0x4e, 0x41, 0x56, 0x41, 0x49, 0x4c, 0x41, 0x42, 0x4c, 0x45, 0x10, 0x0e, 0x12, 0x0d, - 0x0a, 0x09, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x4c, 0x4f, 0x53, 0x53, 0x10, 0x0f, 0x42, 0x58, 0x0a, - 0x0e, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x42, - 0x09, 0x43, 0x6f, 0x64, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x33, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, - 0x67, 0x65, 0x6e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x61, - 0x70, 0x69, 0x73, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x3b, 0x63, 0x6f, 0x64, - 0x65, 0xa2, 0x02, 0x03, 0x52, 0x50, 0x43, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_google_rpc_code_proto_rawDescOnce sync.Once - file_google_rpc_code_proto_rawDescData = file_google_rpc_code_proto_rawDesc -) - -func file_google_rpc_code_proto_rawDescGZIP() []byte { - file_google_rpc_code_proto_rawDescOnce.Do(func() { - file_google_rpc_code_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_rpc_code_proto_rawDescData) - }) - return file_google_rpc_code_proto_rawDescData -} - -var file_google_rpc_code_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_google_rpc_code_proto_goTypes = []interface{}{ - (Code)(0), // 0: google.rpc.Code -} -var file_google_rpc_code_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_google_rpc_code_proto_init() } -func file_google_rpc_code_proto_init() { - if File_google_rpc_code_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_google_rpc_code_proto_rawDesc, - NumEnums: 1, - NumMessages: 0, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_google_rpc_code_proto_goTypes, - DependencyIndexes: file_google_rpc_code_proto_depIdxs, - EnumInfos: file_google_rpc_code_proto_enumTypes, - }.Build() - File_google_rpc_code_proto = out.File - file_google_rpc_code_proto_rawDesc = nil - file_google_rpc_code_proto_goTypes = nil - file_google_rpc_code_proto_depIdxs = nil -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 072f98ca09..37da67e474 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -254,7 +254,7 @@ github.com/bombsimon/logrusr/v3 # github.com/cenkalti/backoff v2.2.1+incompatible ## explicit github.com/cenkalti/backoff -# github.com/cenkalti/backoff/v4 v4.2.0 +# github.com/cenkalti/backoff/v4 v4.2.1 ## explicit; go 1.18 github.com/cenkalti/backoff/v4 # github.com/ceph/go-ceph v0.18.0 @@ -926,9 +926,9 @@ github.com/go-micro/plugins/v4/wrapper/breaker/gobreaker # github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus v1.2.0 ## explicit; go 1.17 github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus -# github.com/go-micro/plugins/v4/wrapper/trace/opencensus v1.1.0 +# github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry v1.2.0 ## explicit; go 1.17 -github.com/go-micro/plugins/v4/wrapper/trace/opencensus +github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry # github.com/go-ozzo/ozzo-validation/v4 v4.3.0 ## explicit; go 1.13 github.com/go-ozzo/ozzo-validation/v4 @@ -1780,7 +1780,6 @@ go.opencensus.io/internal/tagencoding go.opencensus.io/metric/metricdata go.opencensus.io/metric/metricexport go.opencensus.io/metric/metricproducer -go.opencensus.io/plugin/ocgrpc go.opencensus.io/plugin/ochttp go.opencensus.io/plugin/ochttp/propagation/b3 go.opencensus.io/resource @@ -1792,14 +1791,16 @@ go.opencensus.io/trace go.opencensus.io/trace/internal go.opencensus.io/trace/propagation go.opencensus.io/trace/tracestate -go.opencensus.io/zpages -go.opencensus.io/zpages/internal # go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.36.4 ## explicit; go 1.18 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/internal -# go.opentelemetry.io/otel v1.14.0 -## explicit; go 1.18 +# go.opentelemetry.io/contrib/zpages v0.41.1 +## explicit; go 1.19 +go.opentelemetry.io/contrib/zpages +go.opentelemetry.io/contrib/zpages/internal +# go.opentelemetry.io/otel v1.15.1 +## explicit; go 1.19 go.opentelemetry.io/otel go.opentelemetry.io/otel/attribute go.opentelemetry.io/otel/baggage @@ -1816,33 +1817,35 @@ go.opentelemetry.io/otel/semconv/v1.10.0 go.opentelemetry.io/otel/semconv/v1.12.0 go.opentelemetry.io/otel/semconv/v1.17.0 go.opentelemetry.io/otel/semconv/v1.4.0 -# go.opentelemetry.io/otel/exporters/jaeger v1.14.0 -## explicit; go 1.18 +# go.opentelemetry.io/otel/exporters/jaeger v1.15.1 +## explicit; go 1.19 go.opentelemetry.io/otel/exporters/jaeger go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/agent go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/jaeger go.opentelemetry.io/otel/exporters/jaeger/internal/gen-go/zipkincore go.opentelemetry.io/otel/exporters/jaeger/internal/third_party/thrift/lib/go/thrift -# go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 -## explicit; go 1.18 +# go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.15.1 +## explicit; go 1.19 go.opentelemetry.io/otel/exporters/otlp/internal/retry -# go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0 -## explicit; go 1.18 +# go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.15.1 +## explicit; go 1.19 go.opentelemetry.io/otel/exporters/otlp/otlptrace +go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform -# go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0 -## explicit; go 1.18 +# go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.15.1 +## explicit; go 1.19 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc -# go.opentelemetry.io/otel/sdk v1.14.0 -## explicit; go 1.18 +# go.opentelemetry.io/otel/sdk v1.15.1 +## explicit; go 1.19 +go.opentelemetry.io/otel/sdk go.opentelemetry.io/otel/sdk/instrumentation go.opentelemetry.io/otel/sdk/internal go.opentelemetry.io/otel/sdk/internal/env go.opentelemetry.io/otel/sdk/resource go.opentelemetry.io/otel/sdk/trace -# go.opentelemetry.io/otel/trace v1.14.0 -## explicit; go 1.18 +# go.opentelemetry.io/otel/trace v1.15.1 +## explicit; go 1.19 go.opentelemetry.io/otel/trace # go.opentelemetry.io/proto/otlp v0.19.0 ## explicit; go 1.14 @@ -2019,7 +2022,6 @@ google.golang.org/appengine/urlfetch google.golang.org/genproto/googleapis/api google.golang.org/genproto/googleapis/api/annotations google.golang.org/genproto/googleapis/api/httpbody -google.golang.org/genproto/googleapis/rpc/code google.golang.org/genproto/googleapis/rpc/errdetails google.golang.org/genproto/googleapis/rpc/status google.golang.org/genproto/protobuf/field_mask