diff --git a/.gitignore b/.gitignore index 1f65182bb50a5d2be62535b5ac93356c0d44ed3d..0c1a268460f9e55cc5ac6d7003a0dcc62310efa1 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ gl-code-quality-report.json .env router node_modules +.idea diff --git a/go.mod b/go.mod index 080630c10c6bf0d3b37699c7681c31f74b5388ff..238e1e3b04a2c93d4390a866e81a4bf977c79331 100644 --- a/go.mod +++ b/go.mod @@ -15,10 +15,15 @@ require ( github.com/prometheus/client_model v0.6.1 github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a github.com/sirupsen/logrus v1.9.3 - github.com/stretchr/testify v1.9.0 - github.com/uber/jaeger-client-go v2.29.1+incompatible + github.com/stretchr/testify v1.10.0 + github.com/uber/jaeger-client-go v2.30.0+incompatible gitlab.com/gitlab-org/go/reopen v1.0.0 go.opencensus.io v0.23.0 + go.opentelemetry.io/otel v1.36.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.0.0 + go.opentelemetry.io/otel/sdk v1.36.0 golang.org/x/crypto v0.41.0 google.golang.org/api v0.54.0 google.golang.org/grpc v1.40.0 @@ -35,18 +40,22 @@ require ( github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect github.com/aws/aws-sdk-go v1.37.0 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/cenkalti/backoff/v4 v4.1.1 // indirect github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect github.com/certifi/gocertifi v0.0.0-20210507211836-431795d63e8d // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.4 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect - github.com/golang/protobuf v1.5.2 // indirect - github.com/google/go-cmp v0.6.0 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/go-cmp v0.7.0 // indirect github.com/google/pprof v0.0.0-20210804190019-f964ff605595 // indirect - github.com/google/uuid v1.1.2 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/googleapis/gax-go/v2 v2.0.5 // indirect + github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/klauspost/compress v1.17.9 // indirect github.com/kylelemons/godebug v1.1.0 // indirect @@ -64,16 +73,20 @@ require ( github.com/tklauser/go-sysconf v0.3.4 // indirect github.com/tklauser/numcpus v0.2.1 // indirect github.com/uber/jaeger-lib v2.4.1+incompatible // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/otel/metric v1.36.0 // indirect + go.opentelemetry.io/otel/trace v1.36.0 // indirect + go.opentelemetry.io/proto/otlp v0.9.0 // indirect go.uber.org/atomic v1.4.0 // indirect - golang.org/x/net v0.42.0 // indirect - golang.org/x/oauth2 v0.23.0 // indirect + golang.org/x/net v0.43.0 // indirect + golang.org/x/oauth2 v0.30.0 // indirect golang.org/x/sync v0.16.0 // indirect golang.org/x/sys v0.35.0 // indirect golang.org/x/text v0.28.0 // indirect golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20210813162853-db860fec028c // indirect - google.golang.org/protobuf v1.34.2 // indirect + google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83 // indirect + google.golang.org/protobuf v1.36.8 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 8c933563a5c63672095614ee08653bb326801198..ea3bd3a18b0a3bd28d5aab9fd5516c8c3460255a 100644 --- a/go.sum +++ b/go.sum @@ -70,6 +70,8 @@ github.com/aws/aws-sdk-go v1.37.0 h1:GzFnhOIsrGyQ69s7VgqtrG2BG8v7X7vwB3Xpbd/DBBk github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ= +github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -112,6 +114,11 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= @@ -149,8 +156,9 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -166,8 +174,8 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -193,13 +201,15 @@ github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210804190019-f964ff605595 h1:uNrRgpnKjTfxu4qHaZAAs3eKTYV1EzGF3dAykpnxgDE= github.com/google/pprof v0.0.0-20210804190019-f964ff605595/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -270,8 +280,8 @@ github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0leargg github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a h1:iLcLb5Fwwz7g/DLK89F+uQBDeAhHhwdzB5fSlVdhGcM= github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a/go.mod h1:wozgYq9WEBQBaIJe4YZ0qTSFAMxmcwBhQH0fO0R34Z0= github.com/shirou/gopsutil/v3 v3.21.2 h1:fIOk3hyqV1oGKogfGNjUZa0lUbtlkx3+ZT0IoJth2uM= @@ -291,16 +301,16 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tinylib/msgp v1.1.2 h1:gWmO7n0Ys2RBEb7GPYB9Ujq8Mk5p2U08lRnmMcGy6BQ= github.com/tinylib/msgp v1.1.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tklauser/go-sysconf v0.3.4 h1:HT8SVixZd3IzLdfs/xlpq0jeSfTX57g1v6wB1EuzV7M= github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek= github.com/tklauser/numcpus v0.2.1 h1:ct88eFm+Q7m2ZfXJdan1xYoXKlmwsfP+k88q05KvlZc= github.com/tklauser/numcpus v0.2.1/go.mod h1:9aU+wOc6WjUIZEwWMP62PL/41d65P+iks1gBkr4QyP8= -github.com/uber/jaeger-client-go v2.29.1+incompatible h1:R9ec3zO3sGpzs0abd43Y+fBZRJ9uiH6lXyR/+u6brW4= -github.com/uber/jaeger-client-go v2.29.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= +github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -319,9 +329,32 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.22.6/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/otel v1.0.0/go.mod h1:AjRVh9A5/5DE7S+mZtTR6t8vpKKryam+0lREnfmS4cg= +go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg= +go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.0 h1:Vv4wbLEjheCTPV07jEav7fyUpJkyftQK7Ss2G7qgdSo= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.0/go.mod h1:3VqVbIbjAycfL1C7sIu/Uh/kACIUPWHztt8ODYwR3oM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.0 h1:B9VtEB1u41Ohnl8U6rMCh1jjedu8HwFh4D0QeB+1N+0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.0/go.mod h1:zhEt6O5GGJ3NCAICr4hlCPoDb2GQuh4Obb4gZBgkoQQ= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.0.0 h1:JU4DYtRg3V83juRZfdUUtHLBlUPEnvcq/a30OOyUZGQ= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.0.0/go.mod h1:neVwLpom2R8BZm8pORLiKj7mLUqwsPZ2x1CqPf7VQLI= +go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE= +go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs= +go.opentelemetry.io/otel/sdk v1.0.0/go.mod h1:PCrDHlSy5x1kjezSdL37PhbFUMjrsLRshJ2zCzeXwbM= +go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs= +go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY= +go.opentelemetry.io/otel/trace v1.0.0/go.mod h1:PXTWqayeFUlJV1YDNhsJYB184+IvAH814St6o6ajzIs= +go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w= +go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v0.9.0 h1:C0g6TWmQYvjKRnljRULLWUVJGy8Uvu0NEL/5frY2/t4= +go.opentelemetry.io/proto/otlp v0.9.0/go.mod h1:1vKfU9rv61e9EVGthD1zNvUbiwPcimSsOPU9brfSHJg= go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -407,8 +440,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs= -golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= +golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= +golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -424,8 +457,8 @@ golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= -golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= +golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -481,6 +514,7 @@ golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -662,8 +696,9 @@ google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c h1:iLQakcwWG3k/++1q/46apVb1sUQ3IqIdn9yUE6eh/xA= google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83 h1:3V2dxSZpz4zozWWUq36vUxXEKnSYitEH2LdsAx+RUmg= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -705,8 +740,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= gopkg.in/DataDog/dd-trace-go.v1 v1.32.0 h1:DkD0plWEVUB8v/Ru6kRBW30Hy/fRNBC8hPdcExuBZMc= gopkg.in/DataDog/dd-trace-go.v1 v1.32.0/go.mod h1:wRKMf/tRASHwH/UOfPQ3IQmVFhTz2/1a1/mpXoIjF54= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/tracing/connstr/connection_string_parser.go b/tracing/connstr/connection_string_parser.go index 65e146172d9f3d7d0821bf7ff7d0215c3fdec7c5..a72f5b3d88bc89ee43fb0e0816dd2ed1f5f6efc1 100644 --- a/tracing/connstr/connection_string_parser.go +++ b/tracing/connstr/connection_string_parser.go @@ -24,7 +24,7 @@ func Parse(connectionString string) (driverName string, options map[string]strin return "", nil, errInvalidConnection } - if URL.Scheme != "opentracing" { + if URL.Scheme != "opentracing" && URL.Scheme != "otel" { return "", nil, errInvalidConnection } diff --git a/tracing/impl/datadog_tracer.go b/tracing/impl/datadog_tracer.go index 7f298485f1c27f4aa3415dcafe481f4de2787ddc..685b9a5cbe222b45cb63986035141c97ab2f6fd4 100644 --- a/tracing/impl/datadog_tracer.go +++ b/tracing/impl/datadog_tracer.go @@ -10,13 +10,15 @@ import ( "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer" ) -func tracerFactory(config map[string]string) (opentracing.Tracer, io.Closer, error) { +func tracerFactory(config map[string]string) (io.Closer, error) { opts := []tracer.StartOption{} if config["service_name"] != "" { opts = append(opts, tracer.WithServiceName(config["service_name"])) } - return opentracer.New(opts...), nil, nil + tracer := opentracer.New(opts...) + opentracing.SetGlobalTracer(tracer) + return nil, nil } func init() { // nolint:gochecknoinits diff --git a/tracing/impl/jaeger_tracer.go b/tracing/impl/jaeger_tracer.go index 585a2d626f3829ac4fb649c1e35d7d0dac14cb18..d0930dac593f0633ba1d7131a8a77c4c7e20cda9 100644 --- a/tracing/impl/jaeger_tracer.go +++ b/tracing/impl/jaeger_tracer.go @@ -59,10 +59,10 @@ var configMapper = map[string]traceConfigMapper{ }, } -func jaegerTracerFactory(config map[string]string) (opentracing.Tracer, io.Closer, error) { +func jaegerTracerFactory(config map[string]string) (io.Closer, error) { traceCfg, err := jaegercfg.FromEnv() if err != nil { - return nil, nil, err + return nil, err } options := []jaegercfg.Option{} @@ -76,19 +76,40 @@ func jaegerTracerFactory(config map[string]string) (opentracing.Tracer, io.Close if mapper != nil { o, err := mapper(traceCfg, v) if err != nil { - return nil, nil, err + return nil, err } options = append(options, o...) } else { if config[keyStrictConnectionParsing] != "" { - return nil, nil, fmt.Errorf("jaeger tracer: invalid option: %s: %w", k, ErrConfiguration) + return nil, fmt.Errorf("jaeger tracer: invalid option: %s: %w", k, ErrConfiguration) } log.Printf("jaeger tracer: warning: ignoring unknown configuration option: %s", k) } } - return traceCfg.NewTracer(options...) + tracer, closer, err := traceCfg.NewTracer(options...) + if err != nil { + return nil, err + } + + opentracing.SetGlobalTracer(tracer) + return &jaegerTracerCloser{ + closer: closer, + tracer: tracer, + }, err +} + +// jaegerTracerCloser is closer for the Jaeger tracer while at the +// same time being a wrapper around a Jaeger tracer in order to access +// the tracer during testing. +type jaegerTracerCloser struct { + closer io.Closer + tracer opentracing.Tracer +} + +func (c *jaegerTracerCloser) Close() error { + return c.closer.Close() } func init() { // nolint:gochecknoinits diff --git a/tracing/impl/jaeger_tracer_test.go b/tracing/impl/jaeger_tracer_test.go index 1cf6a027234d0c063df73834a60b8b92b549759f..d3ef7cddd38103da7791fb82ce2d7c1321d6dad4 100644 --- a/tracing/impl/jaeger_tracer_test.go +++ b/tracing/impl/jaeger_tracer_test.go @@ -75,7 +75,7 @@ func TestTracerFactory(t *testing.T) { options["service_name"] = "test" - gotTracer, gotCloser, err := jaegerTracerFactory(options) + gotCloser, err := jaegerTracerFactory(options) if (err != nil) != tt.wantErr { t.Errorf("TracerFactory() error = %v, wantErr %v", err, tt.wantErr) @@ -83,9 +83,6 @@ func TestTracerFactory(t *testing.T) { } if !tt.wantErr { - if gotTracer == nil { - t.Errorf("TracerFactory() expected a tracer, got nil") - } if gotCloser == nil { t.Errorf("TracerFactory() expected a closed, got nil") } @@ -95,8 +92,6 @@ func TestTracerFactory(t *testing.T) { } func TestIsSampled_jaeger(t *testing.T) { - t.Parallel() - for _, tc := range []struct { desc string connection string @@ -118,9 +113,10 @@ func TestIsSampled_jaeger(t *testing.T) { require.NoError(t, err) options["service_name"] = "test" - jaegerTracer, closer, err := jaegerTracerFactory(options) + closer, err := jaegerTracerFactory(options) require.NoError(t, err) + jaegerTracer := closer.(*jaegerTracerCloser).tracer span := jaegerTracer.StartSpan("rootSpan") for i := range 10 { require.Equal(t, tc.sampled, IsSampled(span)) diff --git a/tracing/impl/lightstep_tracer.go b/tracing/impl/lightstep_tracer.go index dd4bbce90dc13f1ea1098aa799b125b4067a1b0f..8dff6cef4f7b19133d88426d71594928587dd3ed 100644 --- a/tracing/impl/lightstep_tracer.go +++ b/tracing/impl/lightstep_tracer.go @@ -8,7 +8,7 @@ import ( "io" lightstep "github.com/lightstep/lightstep-tracer-go" - opentracing "github.com/opentracing/opentracing-go" + "github.com/opentracing/opentracing-go" log "github.com/sirupsen/logrus" ) @@ -32,7 +32,7 @@ var lightstepConfigMapper = map[string]func(traceCfg *lightstep.Options, value s }, } -func lightstepTracerFactory(config map[string]string) (opentracing.Tracer, io.Closer, error) { +func lightstepTracerFactory(config map[string]string) (io.Closer, error) { options := lightstep.Options{ Tags: map[string]interface{}{}, } @@ -47,11 +47,11 @@ func lightstepTracerFactory(config map[string]string) (opentracing.Tracer, io.Cl if mapper != nil { err := mapper(&options, v) if err != nil { - return nil, nil, err + return nil, err } } else { if config[keyStrictConnectionParsing] != "" { - return nil, nil, fmt.Errorf("lightstep tracer: invalid option: %s: %w", k, ErrConfiguration) + return nil, fmt.Errorf("lightstep tracer: invalid option: %s: %w", k, ErrConfiguration) } log.Printf("lightstep tracer: warning: ignoring unknown configuration option: %s", k) @@ -59,15 +59,16 @@ func lightstepTracerFactory(config map[string]string) (opentracing.Tracer, io.Cl } if options.AccessToken == "" { - return nil, nil, fmt.Errorf("failed to parse access_token from config: %q: %w", config, ErrConfiguration) + return nil, fmt.Errorf("failed to parse access_token from config: %q: %w", config, ErrConfiguration) } tracer := lightstep.NewTracer(options) if tracer == nil { - return nil, nil, fmt.Errorf("lightstep tracer: unable to create tracer, review log messages: %w", ErrConfiguration) + return nil, fmt.Errorf("lightstep tracer: unable to create tracer, review log messages: %w", ErrConfiguration) } - return tracer, &lightstepCloser{tracer}, nil + opentracing.SetGlobalTracer(tracer) + return &lightstepCloser{tracer}, nil } func init() { // nolint:gochecknoinits diff --git a/tracing/impl/lightstep_tracer_test.go b/tracing/impl/lightstep_tracer_test.go index 1b84b9b0bf947bd89988250b59d068227bc08a6c..d5b0611d4c408ba064778bc0f8d590bb7b6865b8 100644 --- a/tracing/impl/lightstep_tracer_test.go +++ b/tracing/impl/lightstep_tracer_test.go @@ -51,7 +51,7 @@ func Test_lightstepTracerFactory(t *testing.T) { options["service_name"] = "test" - gotTracer, gotCloser, err := lightstepTracerFactory(options) + gotCloser, err := lightstepTracerFactory(options) if (err != nil) != tt.wantErr { t.Errorf("TracerFactory() error = %v, wantErr %v", err, tt.wantErr) @@ -59,9 +59,6 @@ func Test_lightstepTracerFactory(t *testing.T) { } if !tt.wantErr { - if gotTracer == nil { - t.Errorf("TracerFactory() expected a tracer, got nil") - } if gotCloser == nil { t.Errorf("TracerFactory() expected a closed, got nil") } @@ -71,18 +68,11 @@ func Test_lightstepTracerFactory(t *testing.T) { } func TestIsSampled_lightstep(t *testing.T) { - t.Parallel() - for _, tc := range []struct { desc string connection string sampled bool }{ - { - desc: "lightstep sampled", - connection: "opentracing://lightstep?access_token=12345&relaxed", - sampled: true, - }, { desc: "lightstep not sampled", connection: "opentracing://lightstep?access_token=12345&relaxed", @@ -94,7 +84,7 @@ func TestIsSampled_lightstep(t *testing.T) { require.NoError(t, err) options["service_name"] = "test" - lightstepTracer, closer, err := lightstepTracerFactory(options) + closer, err := lightstepTracerFactory(options) require.NoError(t, err) var opt opentracing.StartSpanOption @@ -104,6 +94,8 @@ func TestIsSampled_lightstep(t *testing.T) { opt = lightstep.SetSampled("false") } + lightstepTracer := closer.(*lightstepCloser).tracer + span := lightstepTracer.StartSpan("rootSpan", lightstep.SetTraceID(1), opt) for i := range 10 { require.Equal(t, tc.sampled, IsSampled(span)) diff --git a/tracing/impl/null_tracer.go b/tracing/impl/null_tracer.go index ecaf5e4c89b838d03813e274ac1933b7144a0b23..0ef465109e4aa04ef21a5b0a4c0be0edd5b9e80f 100644 --- a/tracing/impl/null_tracer.go +++ b/tracing/impl/null_tracer.go @@ -5,11 +5,10 @@ package impl import ( "fmt" "io" - - opentracing "github.com/opentracing/opentracing-go" ) -// New will instantiate a new instance of the tracer, given the driver and configuration. -func New(driverName string, config map[string]string) (opentracing.Tracer, io.Closer, error) { - return nil, nil, fmt.Errorf("tracer: binary compiled without tracer support: cannot load driver %s", driverName) +// SetTracer will instantiate a new instance of the tracer, given the driver and configuration, and +// set it as the global tracer. +func SetTracer(driverName string, _ map[string]string) (io.Closer, error) { + return nil, fmt.Errorf("tracer: binary compiled without tracer support: cannot load driver %s", driverName) } diff --git a/tracing/impl/otel_tracer.go b/tracing/impl/otel_tracer.go new file mode 100644 index 0000000000000000000000000000000000000000..7a99c3c58159511bb02e93ca0bda1b1f0565ce1e --- /dev/null +++ b/tracing/impl/otel_tracer.go @@ -0,0 +1,184 @@ +//go:build tracer_static && tracer_static_otel + +package impl + +import ( + "context" + "errors" + "fmt" + "io" + "strconv" + "strings" + "time" + + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "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/propagation" + "go.opentelemetry.io/otel/sdk/resource" + oteltracingsdk "go.opentelemetry.io/otel/sdk/trace" +) + +const ( + optOtelGrpcEndpoint = "grpc_endpoint" + optOtelHttpEndpoint = "http_endpoint" + optOtelServiceName = "service_name" + optOtelSamplerParameter = "sampler_param" + optOtelTimeOut = "timeout_seconds" + + optOtelHeaderPrefix = "header^" +) + +// ErrOtelOptions is used when the options specified by the user in the connection string are invalid +var ErrOtelOptions = errors.New("otel tracer: options error") + +type otelTracerOptions struct { + grpcEndpoint string + httpEndpoint string + serviceName string + sampleParam float64 + timeout time.Duration + headers map[string]string +} + +func otelTracerFactory(config map[string]string) (io.Closer, error) { + ctx := context.Background() + + if config == nil { + return nil, fmt.Errorf("otel tracer: empty config options: %q", config) + } + + options, err := parseOtelOptions(config) + if err != nil { + return nil, err + } + + // Propagators are objects responsible to propagate tracing data. + // The TraceContext propagator propagates trace IDs across process boundaries + // The Baggage propagator propagates baggage across process boundaries. + // Note: contrary to OpenTracing, OpenTelemetry propagates baggage within contexts, not within spans + defaultPropagator := propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}) + otel.SetTextMapPropagator(defaultPropagator) + + // Create a resource to provide additional context to spans + serviceResource, err := resource.New( + ctx, + resource.WithFromEnv(), + resource.WithTelemetrySDK(), + resource.WithProcess(), + resource.WithOS(), + resource.WithContainer(), + resource.WithHost(), + resource.WithAttributes(attribute.String("service.name", options.serviceName)), + ) + + // Create the exporter client, either gRPC or HTTP (TLS not yet supported) + var client otlptrace.Client + if options.grpcEndpoint != "" { + client = configureGrpcOtelClient(options.grpcEndpoint, options) //"127.0.0.1:4317" + } else { + client = configureHttpOtelClient(options.httpEndpoint, options) + } + + // Create the exporter using the client + exporter, err := otlptrace.New(ctx, client) + if err != nil { + return nil, err + } + + // Create a new tracer provider with the exporter configured above + tp := oteltracingsdk.NewTracerProvider( + oteltracingsdk.WithBatcher(exporter), + oteltracingsdk.WithResource(serviceResource), + oteltracingsdk.WithSampler(oteltracingsdk.TraceIDRatioBased(options.sampleParam)), + ) + + otel.SetTracerProvider(tp) + + return newOtelTracerProviderCloser(ctx, tp), nil +} + +func configureHttpOtelClient(endpoint string, opts otelTracerOptions) otlptrace.Client { + return otlptracehttp.NewClient( + otlptracehttp.WithEndpoint(endpoint), + otlptracehttp.WithInsecure(), + otlptracehttp.WithTimeout(opts.timeout), + ) +} + +func configureGrpcOtelClient(endpoint string, opts otelTracerOptions) otlptrace.Client { + return otlptracegrpc.NewClient( + otlptracegrpc.WithEndpoint(endpoint), + otlptracegrpc.WithInsecure(), + otlptracegrpc.WithTimeout(opts.timeout), + ) +} + +func parseOtelOptions(opts map[string]string) (otelTracerOptions, error) { + samplerFloatValue := 1.0 + // If the option is not defined, we assume default value, which is 1.0 + if !strings.EqualFold(opts[optOtelSamplerParameter], "") { + if f, err := strconv.ParseFloat(opts[optOtelSamplerParameter], 64); err != nil { + return otelTracerOptions{}, + fmt.Errorf("%w: %s is (%s); must be a float", ErrOtelOptions, optOtelSamplerParameter, opts[optOtelSamplerParameter]) + } else { + samplerFloatValue = f + } + } + + timeoutSecondsValue := 10 + // If the option is not defined, we assume default value, which is 10 seconds + if !strings.EqualFold(opts[optOtelTimeOut], "") { + if i, err := strconv.Atoi(opts[optOtelTimeOut]); err != nil { + return otelTracerOptions{}, + fmt.Errorf("%w: %s is (%s); must be an integer", ErrOtelOptions, optOtelTimeOut, opts[optOtelTimeOut]) + } else { + timeoutSecondsValue = i + } + } + + if opts[optOtelGrpcEndpoint] == "" && opts[optOtelHttpEndpoint] == "" { + return otelTracerOptions{}, + fmt.Errorf("%w: one of '%s' or '%s' must be defined", ErrOtelOptions, optOtelGrpcEndpoint, optOtelHttpEndpoint) + } + + if opts[optOtelGrpcEndpoint] != "" && opts[optOtelHttpEndpoint] != "" { + return otelTracerOptions{}, + fmt.Errorf("%w: both '%s' and '%s' are defined; pick one only", ErrOtelOptions, optOtelGrpcEndpoint, optOtelHttpEndpoint) + } + + headers := make(map[string]string) + for k, v := range opts { + if header, ok := strings.CutPrefix(k, optOtelHeaderPrefix); ok { + headers[header] = v + } + } + + return otelTracerOptions{ + grpcEndpoint: opts[optOtelGrpcEndpoint], + httpEndpoint: opts[optOtelHttpEndpoint], + serviceName: opts[optOtelServiceName], + sampleParam: samplerFloatValue, + timeout: time.Duration(timeoutSecondsValue) * time.Second, + headers: headers, + }, nil +} + +type otelTracerProviderCloser struct { + ctx context.Context + tp *oteltracingsdk.TracerProvider +} + +func newOtelTracerProviderCloser(ctx context.Context, tp *oteltracingsdk.TracerProvider) *otelTracerProviderCloser { + return &otelTracerProviderCloser{ctx: ctx, tp: tp} +} + +func (c *otelTracerProviderCloser) Close() error { + return c.tp.Shutdown(c.ctx) +} + +func init() { // nolint:gochecknoinits + registerTracer("otel", otelTracerFactory) +} diff --git a/tracing/impl/otel_tracer_test.go b/tracing/impl/otel_tracer_test.go new file mode 100644 index 0000000000000000000000000000000000000000..bd98509bcab1afe0acc3c752f70792d2223e563a --- /dev/null +++ b/tracing/impl/otel_tracer_test.go @@ -0,0 +1,72 @@ +//go:build tracer_static && tracer_static_otel + +package impl + +import ( + "testing" + + "gitlab.com/gitlab-org/labkit/tracing/connstr" +) + +func Test_otelTracerFactory(t *testing.T) { + tests := []struct { + connectionString string + wantErr bool + }{ + { + connectionString: "otel://otel", + wantErr: true, + }, + { + connectionString: "otel://otel?grpc_endpoint=localhost:4337", + wantErr: false, + }, + { + connectionString: "otel://otel?http_endpoint=localhost:1234", + wantErr: false, + }, + { + connectionString: "otel://otel?http_endpoint=localhost:1234&grpc_endpoint=localhost:4337", + wantErr: true, + }, + { + connectionString: "otel://otel?http_endpoint=localhost:1234&sampler_param=0.76", + wantErr: false, + }, + { + connectionString: "otel://otel?http_endpoint=localhost:1234&sampler_param=hello", + wantErr: true, + }, + { + connectionString: "otel://otel?http_endpoint=localhost:1234&timeout_seconds=15", + wantErr: false, + }, + { + connectionString: "otel://otel?http_endpoint=localhost:1234&timeout_seconds=hello", + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.connectionString, func(t *testing.T) { + _, options, err := connstr.Parse(tt.connectionString) + if err != nil { + t.Errorf("TracerFactory() error = unable to parse connection string: %v", err) + } + + options["service_name"] = "test" + + gotCloser, err := otelTracerFactory(options) + + if (err != nil) != tt.wantErr { + t.Errorf("TracerFactory() error = %v, wantErr %v", err, tt.wantErr) + return + } + + if !tt.wantErr { + if gotCloser == nil { + t.Errorf("TracerFactory() expected a closed, got nil") + } + } + }) + } +} diff --git a/tracing/impl/stackdriver_tracer.go b/tracing/impl/stackdriver_tracer.go index b5266fc1735d5bbf018d7f88d2aa381b51758f45..3df3fb436337e37472f48ca22bcfb53cf7f5e156 100644 --- a/tracing/impl/stackdriver_tracer.go +++ b/tracing/impl/stackdriver_tracer.go @@ -336,7 +336,7 @@ var stackdriverConfigMapper = map[string]func(traceCfg *stackdriverConfig, value }, } -func stackdriverTracerFactory(config map[string]string) (opentracing.Tracer, io.Closer, error) { +func stackdriverTracerFactory(config map[string]string) (io.Closer, error) { stackdriverCfg := &stackdriverConfig{ options: &stackdriver.Options{}, sampler: trace.NeverSample(), @@ -347,7 +347,7 @@ func stackdriverTracerFactory(config map[string]string) (opentracing.Tracer, io. if mapper != nil { err := mapper(stackdriverCfg, v) if err != nil { - return nil, nil, err + return nil, err } } else { log.Printf("stackdriver tracer: warning: ignoring unknown configuration option: %s", k) @@ -356,13 +356,14 @@ func stackdriverTracerFactory(config map[string]string) (opentracing.Tracer, io. exporter, err := stackdriver.NewExporter(*stackdriverCfg.options) if err != nil { - return nil, nil, err + return nil, err } trace.RegisterExporter(exporter) trace.ApplyConfig(trace.Config{DefaultSampler: stackdriverCfg.sampler}) - return &adapterTracer{exporter}, &stackdriverCloser{exporter}, nil + opentracing.SetGlobalTracer(&adapterTracer{exporter}) + return &stackdriverCloser{exporter}, nil } func init() { diff --git a/tracing/impl/static_tracer.go b/tracing/impl/static_tracer.go index 84dbe6b2a0dc6f5447bdf09df9f88e413d0ed304..a6203458de873f365b734cff676b913a72926e04 100644 --- a/tracing/impl/static_tracer.go +++ b/tracing/impl/static_tracer.go @@ -5,15 +5,14 @@ package impl import ( "fmt" "io" - - opentracing "github.com/opentracing/opentracing-go" ) -// New will instantiate a new instance of the tracer, given the driver and configuration. -func New(driverName string, config map[string]string) (opentracing.Tracer, io.Closer, error) { +// SetTracer will instantiate a new instance of the tracer, given the driver and configuration, and +// set it as the global tracer. +func SetTracer(driverName string, config map[string]string) (io.Closer, error) { factory := registry[driverName] if factory == nil { - return nil, nil, fmt.Errorf("tracer: unable to load driver %s: %w", driverName, ErrConfiguration) + return nil, fmt.Errorf("tracer: unable to load driver %s: %w", driverName, ErrConfiguration) } return factory(config) diff --git a/tracing/impl/tracer_registry.go b/tracing/impl/tracer_registry.go index 2506469c82557ca18a0942f87789baecf38c1dd2..98cad41fec1a6daa6f835bfdc07ca0bd70f84e45 100644 --- a/tracing/impl/tracer_registry.go +++ b/tracing/impl/tracer_registry.go @@ -2,11 +2,9 @@ package impl import ( "io" - - opentracing "github.com/opentracing/opentracing-go" ) -type tracerFactoryFunc func(config map[string]string) (opentracing.Tracer, io.Closer, error) +type tracerFactoryFunc func(config map[string]string) (io.Closer, error) var registry = map[string]tracerFactoryFunc{} diff --git a/tracing/initialization.go b/tracing/initialization.go index b6e89cfc3d26812c887615d6b16a2f3fae06b92d..211dfa98c0a2a5c9e43208259f5e579bd1c5d9cf 100644 --- a/tracing/initialization.go +++ b/tracing/initialization.go @@ -3,7 +3,6 @@ package tracing import ( "io" - opentracing "github.com/opentracing/opentracing-go" log "github.com/sirupsen/logrus" "gitlab.com/gitlab-org/labkit/tracing/connstr" "gitlab.com/gitlab-org/labkit/tracing/impl" @@ -34,19 +33,12 @@ func Initialize(opts ...InitializationOption) io.Closer { options["service_name"] = config.serviceName } - tracer, closer, err := impl.New(driverName, options) + closer, err := impl.SetTracer(driverName, options) if err != nil { log.WithError(err).Warn("skipping tracing configuration step") return &nopCloser{} } - if tracer == nil { - log.Warn("no tracer provided, tracing will be disabled") - } else { - log.Info("Tracing enabled") - opentracing.SetGlobalTracer(tracer) - } - if closer == nil { return &nopCloser{} }