diff --git a/go.mod b/go.mod index be3bf744ba..005709ed7c 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,6 @@ require ( github.com/klauspost/compress v1.17.9 github.com/onsi/ginkgo v1.16.5 github.com/onsi/gomega v1.35.1 - github.com/opentracing/opentracing-go v1.2.0 github.com/pierrec/lz4/v4 v4.1.22 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.20.5 @@ -24,16 +23,19 @@ require ( github.com/spaolacci/murmur3 v1.1.0 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.10.0 - github.com/testcontainers/testcontainers-go v0.35.0 + github.com/testcontainers/testcontainers-go v0.37.0 + go.opentelemetry.io/otel v1.37.0 + go.opentelemetry.io/otel/sdk v1.37.0 + go.opentelemetry.io/otel/trace v1.37.0 go.uber.org/atomic v1.11.0 - golang.org/x/mod v0.20.0 + golang.org/x/mod v0.25.0 golang.org/x/oauth2 v0.28.0 golang.org/x/time v0.10.0 - google.golang.org/protobuf v1.36.5 + google.golang.org/protobuf v1.36.6 ) require ( - dario.cat/mergo v1.0.0 // indirect + dario.cat/mergo v1.0.1 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect @@ -41,21 +43,21 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/containerd/containerd v1.7.27 // indirect github.com/containerd/log v0.1.0 // indirect github.com/containerd/platforms v0.2.1 // indirect github.com/cpuguy83/dockercfg v0.3.2 // indirect github.com/danieljoos/wincred v1.1.2 // indirect github.com/distribution/reference v0.6.0 // indirect - github.com/docker/docker v27.1.1+incompatible // indirect + github.com/docker/docker v28.0.1+incompatible // indirect github.com/docker/go-connections v0.5.0 // indirect github.com/docker/go-units v0.5.0 // indirect - github.com/dvsekhvalnov/jose2go v1.6.0 // indirect + github.com/dvsekhvalnov/jose2go v1.5.0 // indirect + github.com/ebitengine/purego v0.8.2 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-jose/go-jose/v4 v4.0.5 // indirect - github.com/go-logr/logr v1.4.2 // 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.6 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect @@ -67,12 +69,12 @@ require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect - github.com/magiconair/properties v1.8.7 // indirect + github.com/magiconair/properties v1.8.10 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/patternmatcher v0.6.0 // indirect github.com/moby/sys/sequential v0.5.0 // indirect - github.com/moby/sys/user v0.3.0 // indirect + github.com/moby/sys/user v0.1.0 // indirect github.com/moby/sys/userns v0.1.0 // indirect github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -82,30 +84,29 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/nxadm/tail v1.4.8 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0 // indirect + github.com/opencontainers/image-spec v1.1.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect - github.com/shirou/gopsutil/v3 v3.23.12 // indirect - github.com/shoenig/go-m1cpu v0.1.6 // indirect + github.com/shirou/gopsutil/v4 v4.25.1 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect github.com/x448/float16 v0.8.4 // indirect - github.com/yusufpapurcu/wmi v1.2.3 // indirect + github.com/yusufpapurcu/wmi v1.2.4 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 // indirect - go.opentelemetry.io/otel v1.34.0 // indirect - go.opentelemetry.io/otel/metric v1.34.0 // indirect - go.opentelemetry.io/otel/trace v1.34.0 // indirect - golang.org/x/crypto v0.36.0 // indirect - golang.org/x/net v0.38.0 // indirect - golang.org/x/sys v0.31.0 // indirect - golang.org/x/term v0.30.0 // indirect - golang.org/x/text v0.23.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect + go.opentelemetry.io/otel/metric v1.37.0 // indirect + go.opentelemetry.io/proto/otlp v1.7.0 // indirect + golang.org/x/crypto v0.38.0 // indirect + golang.org/x/net v0.40.0 // indirect + golang.org/x/sys v0.33.0 // indirect + golang.org/x/term v0.32.0 // indirect + golang.org/x/text v0.25.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index e150c46c92..b639263d96 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= -dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= +dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= github.com/99designs/keyring v1.2.1 h1:tYLp1ULvO7i3fI5vE21ReQuj99QFSs7lGm0xWyJo87o= @@ -26,8 +26,6 @@ github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqy github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/containerd/containerd v1.7.27 h1:yFyEyojddO3MIGVER2xJLWoCIn+Up4GaHFquP7hsFII= -github.com/containerd/containerd v1.7.27/go.mod h1:xZmPnl75Vc+BLGt4MIfu6bp+fy03gdHAn9bz+FreFR0= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A= @@ -47,14 +45,16 @@ github.com/dimfeld/httptreemux v5.0.1+incompatible h1:Qj3gVcDNoOthBAqftuD596rm4w github.com/dimfeld/httptreemux v5.0.1+incompatible/go.mod h1:rbUlSV+CCpv/SuqUTP/8Bk2O3LyUV436/yaRGkhP6Z0= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/docker v27.1.1+incompatible h1:hO/M4MtV36kzKldqnA37IWhebRA+LnqqcqDja6kVaKY= -github.com/docker/docker v27.1.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v28.0.1+incompatible h1:FCHjSRdXhNRFjlHMTv4jUNlIBbTeRjrWfeFuJp7jpo0= +github.com/docker/docker v28.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/dvsekhvalnov/jose2go v1.6.0 h1:Y9gnSnP4qEI0+/uQkHvFXeD2PLPJeXEL+ySMEA2EjTY= -github.com/dvsekhvalnov/jose2go v1.6.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= +github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= +github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= +github.com/ebitengine/purego v0.8.2 h1:jPPGWs2sZ1UgOSgD2bClL0MJIqu58nOmIcBuXr62z1I= +github.com/ebitengine/purego v0.8.2/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -66,8 +66,8 @@ github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXE github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE= github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +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.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= @@ -96,7 +96,6 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/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.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -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.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -108,8 +107,8 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaU github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= 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/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= github.com/hamba/avro/v2 v2.26.0 h1:IaT5l6W3zh7K67sMrT2+RreJyDTllBGVJm4+Hedk9qE= @@ -133,8 +132,8 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= -github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE= +github.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= @@ -143,8 +142,8 @@ github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkV github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= -github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo= -github.com/moby/sys/user v0.3.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= +github.com/moby/sys/user v0.1.0 h1:WmZ93f5Ux6het5iituh9x2zAG7NFY9Aqi49jjE1PaQg= +github.com/moby/sys/user v0.1.0/go.mod h1:fKJhFOnsCN6xZ5gSfbM6zaHGgDJMrqt9/reuj4T7MmU= github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g= github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= @@ -176,10 +175,8 @@ github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4= github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= -github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= -github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= -github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= +github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -200,12 +197,8 @@ github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoG 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/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/shirou/gopsutil/v3 v3.23.12 h1:z90NtUkp3bMtmICZKpC4+WaknU1eXtp5vtbQ11DgpE4= -github.com/shirou/gopsutil/v3 v3.23.12/go.mod h1:1FrWgea594Jp7qmjHUUPlJDTPgcsb9mGnXDxavtikzM= -github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= -github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= -github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= -github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= +github.com/shirou/gopsutil/v4 v4.25.1 h1:QSWkTc+fu9LTAWfkZwZ6j8MSUk4A2LV7rbH0ZqmLjXs= +github.com/shirou/gopsutil/v4 v4.25.1/go.mod h1:RoUCUpndaJFtT+2zsZzzmhvbfGoDCJ7nFXKJf8GqJbI= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= @@ -215,20 +208,15 @@ github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3k github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 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/testcontainers/testcontainers-go v0.35.0 h1:uADsZpTKFAtp8SLK+hMwSaa+X+JiERHtd4sQAFmXeMo= -github.com/testcontainers/testcontainers-go v0.35.0/go.mod h1:oEVBj5zrfJTrgjwONs1SsRbnBtH9OKl+IGl3UMcr2B4= +github.com/testcontainers/testcontainers-go v0.37.0 h1:L2Qc0vkTw2EHWQ08djon0D2uw7Z/PtHS/QzZZ5Ra/hg= +github.com/testcontainers/testcontainers-go v0.37.0/go.mod h1:QPzbxZhQ6Bclip9igjLFj6z0hs01bU8lrl2dHQmgFGM= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= @@ -237,45 +225,47 @@ github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= -github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= +github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= 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/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I= -go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= -go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE= +go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= +go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU= -go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= -go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= -go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= -go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= -go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= -go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= -go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= +go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= +go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= +go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= +go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= +go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= +go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= +go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os= +go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= -golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= +golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w= +golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= -golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= +golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc= golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -298,15 +288,14 @@ golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= -golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= -golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= +golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= +golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg= +golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= +golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4= golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -321,20 +310,20 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb h1:ITgPrl429bc6+2ZraNSzMDk3I95nmQln2fuPstKwFDE= -google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950= -google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250227231956-55c901821b1e h1:YA5lmSs3zc/5w+xsRcHqpETkaYyK63ivEPzNTcUUlSA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250227231956-55c901821b1e/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= -google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg= -google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= +google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a h1:SGktgSolFCo75dnHJF2yMvnns6jCmHFJ0vE4Vn2JKvQ= +google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a/go.mod h1:a77HrdMjoeKbnd2jmgcWdaS++ZLZAEq3orIOAEIKiVw= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/grpc v1.72.2 h1:TdbGzwb82ty4OusHWepvFWGLgIbNo1/SUynEN0ssqv8= +google.golang.org/grpc v1.72.2/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= -google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/pulsar/internal/pulsartracing/consumer_interceptor_test.go b/pulsar/internal/pulsartracing/consumer_interceptor_test.go deleted file mode 100644 index e7712356f5..0000000000 --- a/pulsar/internal/pulsartracing/consumer_interceptor_test.go +++ /dev/null @@ -1,121 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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 pulsartracing - -import ( - "context" - "testing" - "time" - - "github.com/apache/pulsar-client-go/pulsar" - "github.com/opentracing/opentracing-go" - "github.com/opentracing/opentracing-go/mocktracer" - "github.com/stretchr/testify/assert" -) - -func TestConsumerBuildAndInjectChildSpan(t *testing.T) { - tracer := mocktracer.New() - - opentracing.SetGlobalTracer(tracer) - - message := pulsar.ConsumerMessage{ - Consumer: &mockConsumer{}, - Message: &mockConsumerMessage{ - properties: map[string]string{}, - }, - } - - span := buildAndInjectChildSpan(message) - assert.NotNil(t, span) - assert.True(t, len(message.Properties()) > 0) -} - -type mockConsumer struct { -} - -func (c *mockConsumer) Subscription() string { - return "" -} - -func (c *mockConsumer) AckWithTxn(_ pulsar.Message, _ pulsar.Transaction) error { - return nil -} - -func (c *mockConsumer) Unsubscribe() error { - return nil -} -func (c *mockConsumer) UnsubscribeForce() error { - return nil -} - -func (c *mockConsumer) Receive(_ context.Context) (message pulsar.Message, err error) { - return nil, nil -} - -func (c *mockConsumer) Chan() <-chan pulsar.ConsumerMessage { - return nil -} - -func (c *mockConsumer) Ack(_ pulsar.Message) error { - return nil -} - -func (c *mockConsumer) AckID(_ pulsar.MessageID) error { - return nil -} - -func (c *mockConsumer) AckIDList(_ []pulsar.MessageID) error { - return nil -} - -func (c *mockConsumer) AckCumulative(_ pulsar.Message) error { - return nil -} - -func (c *mockConsumer) AckIDCumulative(_ pulsar.MessageID) error { - return nil -} - -func (c *mockConsumer) ReconsumeLater(_ pulsar.Message, _ time.Duration) {} - -func (c *mockConsumer) ReconsumeLaterWithCustomProperties(_ pulsar.Message, _ map[string]string, - _ time.Duration) { -} - -func (c *mockConsumer) Nack(_ pulsar.Message) {} - -func (c *mockConsumer) NackID(_ pulsar.MessageID) {} - -func (c *mockConsumer) Close() {} - -func (c *mockConsumer) Seek(_ pulsar.MessageID) error { - return nil -} - -func (c *mockConsumer) SeekByTime(_ time.Time) error { - return nil -} - -func (c *mockConsumer) Name() string { - return "" -} - -func (c *mockConsumer) GetLastMessageIDs() ([]pulsar.TopicMessageID, error) { - ids := make([]pulsar.TopicMessageID, 0) - return ids, nil -} diff --git a/pulsar/internal/pulsartracing/message_carrier_adaptors.go b/pulsar/internal/pulsartracing/message_carrier_adaptors.go deleted file mode 100644 index 8fcfa17ef9..0000000000 --- a/pulsar/internal/pulsartracing/message_carrier_adaptors.go +++ /dev/null @@ -1,84 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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 pulsartracing - -import ( - "errors" - - "github.com/apache/pulsar-client-go/pulsar" -) - -// ProducerMessageExtractAdapter Implements TextMap Interface -type ProducerMessageExtractAdapter struct { - message *pulsar.ProducerMessage -} - -func (a *ProducerMessageExtractAdapter) ForeachKey(handler func(key, val string) error) error { - for k, v := range (*a.message).Properties { - if err := handler(k, v); err != nil { - return err - } - } - - return nil -} - -func (a *ProducerMessageExtractAdapter) Set(_, _ string) {} - -// ProducerMessageInjectAdapter Implements TextMap Interface -type ProducerMessageInjectAdapter struct { - message *pulsar.ProducerMessage -} - -func (a *ProducerMessageInjectAdapter) ForeachKey(_ func(_, _ string) error) error { - return errors.New("iterator should never be used with Tracer.inject()") -} - -func (a *ProducerMessageInjectAdapter) Set(key, val string) { - a.message.Properties[key] = val -} - -// ConsumerMessageExtractAdapter Implements TextMap Interface -type ConsumerMessageExtractAdapter struct { - message pulsar.ConsumerMessage -} - -func (a *ConsumerMessageExtractAdapter) ForeachKey(handler func(key, val string) error) error { - for k, v := range a.message.Properties() { - if err := handler(k, v); err != nil { - return err - } - } - - return nil -} - -func (a *ConsumerMessageExtractAdapter) Set(_, _ string) {} - -// ConsumerMessageInjectAdapter Implements TextMap Interface -type ConsumerMessageInjectAdapter struct { - message pulsar.ConsumerMessage -} - -func (a *ConsumerMessageInjectAdapter) ForeachKey(_ func(_, _ string) error) error { - return errors.New("iterator should never be used with tracer.inject()") -} - -func (a *ConsumerMessageInjectAdapter) Set(key, val string) { - a.message.Properties()[key] = val -} diff --git a/pulsar/internal/pulsartracing/message_carrier_util.go b/pulsar/internal/pulsartracing/message_carrier_util.go deleted file mode 100644 index d1fd0ddb96..0000000000 --- a/pulsar/internal/pulsartracing/message_carrier_util.go +++ /dev/null @@ -1,89 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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 pulsartracing - -import ( - "context" - - "github.com/apache/pulsar-client-go/pulsar" - "github.com/opentracing/opentracing-go" - log "github.com/sirupsen/logrus" -) - -func InjectProducerMessageSpanContext(ctx context.Context, message *pulsar.ProducerMessage) { - injectAdapter := &ProducerMessageInjectAdapter{message} - - span := opentracing.SpanFromContext(ctx) - - err := opentracing.GlobalTracer().Inject(span.Context(), opentracing.TextMap, injectAdapter) - - if err != nil { - log.Error("could not inject span context into pulsar message", err) - } -} - -func ExtractSpanContextFromProducerMessage(message *pulsar.ProducerMessage) opentracing.SpanContext { - extractAdapter := &ProducerMessageExtractAdapter{message} - - spanContext, err := opentracing.GlobalTracer().Extract(opentracing.TextMap, extractAdapter) - - if err != nil { - log.Error("could not extract span context from pulsar message", err) - } - - return spanContext -} - -func ExtractSpanContextFromConsumerMessage(message pulsar.ConsumerMessage) opentracing.SpanContext { - extractAdapter := &ConsumerMessageExtractAdapter{message} - - spanContext, err := opentracing.GlobalTracer().Extract(opentracing.TextMap, extractAdapter) - - if err != nil { - log.Error("could not extract span context from pulsar message", err) - } - - return spanContext -} - -func InjectConsumerMessageSpanContext(ctx context.Context, message pulsar.ConsumerMessage) { - injectAdapter := &ConsumerMessageInjectAdapter{message} - span := opentracing.SpanFromContext(ctx) - - if span == nil { - log.Warn("no span could be extracted from context, nothing will be injected into the message properties") - return - } - - err := opentracing.GlobalTracer().Inject(span.Context(), opentracing.TextMap, injectAdapter) - - if err != nil { - log.Error("could not inject span context into pulsar message", err) - } -} - -func CreateSpanFromMessage(cm *pulsar.ConsumerMessage, tracer opentracing.Tracer, label string) opentracing.Span { - parentSpan := ExtractSpanContextFromConsumerMessage(*cm) - var span opentracing.Span - if parentSpan != nil { - span = tracer.StartSpan(label, opentracing.ChildOf(parentSpan)) - } else { - span = tracer.StartSpan(label) - } - return span -} diff --git a/pulsar/internal/pulsartracing/message_carrier_util_test.go b/pulsar/internal/pulsartracing/message_carrier_util_test.go deleted file mode 100644 index 90658c1abc..0000000000 --- a/pulsar/internal/pulsartracing/message_carrier_util_test.go +++ /dev/null @@ -1,136 +0,0 @@ -// Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file -// distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file -// to you 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 pulsartracing - -import ( - "context" - "testing" - "time" - - "github.com/apache/pulsar-client-go/pulsar" - "github.com/opentracing/opentracing-go" - "github.com/opentracing/opentracing-go/mocktracer" - "github.com/stretchr/testify/assert" -) - -func TestProducerMessageInjectAndExtract(t *testing.T) { - message := &pulsar.ProducerMessage{ - Properties: map[string]string{}, - } - - tracer := mocktracer.New() - - opentracing.SetGlobalTracer(tracer) - - span := tracer.StartSpan("test") - - InjectProducerMessageSpanContext(opentracing.ContextWithSpan(context.Background(), span), message) - assert.True(t, len(message.Properties) > 0) - extractedSpanContext := ExtractSpanContextFromProducerMessage(message) - assert.Equal(t, span.Context(), extractedSpanContext) -} - -func TestConsumerMessageInjectAndExtract(t *testing.T) { - message := pulsar.ConsumerMessage{ - Message: &mockConsumerMessage{ - properties: map[string]string{}, - }, - } - - tracer := mocktracer.New() - - opentracing.SetGlobalTracer(tracer) - - span := tracer.StartSpan("test") - - InjectConsumerMessageSpanContext(opentracing.ContextWithSpan(context.Background(), span), message) - assert.True(t, len(message.Properties()) > 0) - extractedSpanContext := ExtractSpanContextFromConsumerMessage(message) - assert.Equal(t, span.Context(), extractedSpanContext) -} - -type mockConsumerMessage struct { - properties map[string]string -} - -func (msg *mockConsumerMessage) Topic() string { - return "" -} - -func (msg *mockConsumerMessage) Properties() map[string]string { - return msg.properties -} - -func (msg *mockConsumerMessage) Payload() []byte { - return nil -} - -func (msg *mockConsumerMessage) ID() pulsar.MessageID { - return nil -} - -func (msg *mockConsumerMessage) PublishTime() time.Time { - return time.Time{} -} - -func (msg *mockConsumerMessage) EventTime() time.Time { - return time.Time{} -} - -func (msg *mockConsumerMessage) Key() string { - return "" -} - -func (msg *mockConsumerMessage) OrderingKey() string { - return "" -} - -func (msg *mockConsumerMessage) RedeliveryCount() uint32 { - return 0 -} - -func (msg *mockConsumerMessage) IsReplicated() bool { - return false -} - -func (msg *mockConsumerMessage) GetReplicatedFrom() string { - return "" -} - -func (msg *mockConsumerMessage) GetSchemaValue(_ interface{}) error { - return nil -} - -func (msg *mockConsumerMessage) ProducerName() string { - return "" -} - -func (msg *mockConsumerMessage) SchemaVersion() []byte { - return nil -} -func (msg *mockConsumerMessage) GetEncryptionContext() *pulsar.EncryptionContext { - return &pulsar.EncryptionContext{} -} - -func (msg *mockConsumerMessage) Index() *uint64 { - return nil -} - -func (msg *mockConsumerMessage) BrokerPublishTime() *time.Time { - return nil -} diff --git a/pulsar/internal/pulsartracing/readme.md b/pulsar/internal/pulsartracing/readme.md deleted file mode 100644 index 24f40976c9..0000000000 --- a/pulsar/internal/pulsartracing/readme.md +++ /dev/null @@ -1,40 +0,0 @@ -### Usage - -#### Interceptors based solution - -```go -// create new tracer -// register tracer with GlobalTracer -opentracing.SetGlobalTracer(tracer) -``` - -**Producer** - -```go -tracingInterceptor := &pulsartracing.ProducerInterceptor{} - -options := pulsar.ProducerOptions{ -Topic: topicName, -Interceptors: pulsar.ProducerInterceptors{tracingInterceptor}, -} -``` - -**Consumer** -```go -tracingInterceptor := &pulsartracing.ConsumerInterceptor{} - -options := pulsar.ConsumerOptions{ -Topics: topicName, -SubscriptionName: subscriptionName, -Type: pulsar.Shared, -Interceptors: pulsar.ConsumerInterceptors{tracingInterceptor}, -} - - -// to create span with message as parent span -span := pulsartracing.CreateSpanFromMessage(message, tracer, "child_span") -``` - -## License - -[Apache 2.0 License](./../../../LICENSE). \ No newline at end of file diff --git a/pulsar/internal/pulsartracing/consumer_interceptor.go b/pulsar/tracing/consumer_interceptor.go similarity index 58% rename from pulsar/internal/pulsartracing/consumer_interceptor.go rename to pulsar/tracing/consumer_interceptor.go index 3b91e7cbb4..5a4e8dd82d 100644 --- a/pulsar/internal/pulsartracing/consumer_interceptor.go +++ b/pulsar/tracing/consumer_interceptor.go @@ -15,44 +15,28 @@ // specific language governing permissions and limitations // under the License. -package pulsartracing +package tracing import ( "context" "github.com/apache/pulsar-client-go/pulsar" - "github.com/opentracing/opentracing-go" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/trace" ) const fromPrefix = "From__" -type ConsumerInterceptor struct { -} +type ConsumerInterceptor struct{} func (t *ConsumerInterceptor) BeforeConsume(message pulsar.ConsumerMessage) { - buildAndInjectChildSpan(message).Finish() -} - -func (t *ConsumerInterceptor) OnAcknowledge(_ pulsar.Consumer, _ pulsar.MessageID) {} - -func (t *ConsumerInterceptor) OnNegativeAcksSend(_ pulsar.Consumer, _ []pulsar.MessageID) { -} - -func buildAndInjectChildSpan(message pulsar.ConsumerMessage) opentracing.Span { - tracer := opentracing.GlobalTracer() - parentContext := ExtractSpanContextFromConsumerMessage(message) - - var span opentracing.Span - - var startSpanOptions []opentracing.StartSpanOption - if parentContext != nil { - startSpanOptions = []opentracing.StartSpanOption{opentracing.FollowsFrom(parentContext)} - } - - span = tracer.StartSpan(fromPrefix+message.Topic()+"__"+message.Subscription(), startSpanOptions...) - + ctx := ExtractSpanContextFromConsumerMessage(context.Background(), message) + tracer := otel.Tracer(componentName) + ctx, span := tracer.Start(ctx, fromPrefix+message.Topic()+"__"+message.Subscription(), trace.WithSpanKind(trace.SpanKindConsumer)) enrichConsumerSpan(&message, span) - InjectConsumerMessageSpanContext(opentracing.ContextWithSpan(context.Background(), span), message) - - return span + InjectConsumerMessageSpanContext(ctx, message) + span.End() } + +func (t *ConsumerInterceptor) OnAcknowledge(_ pulsar.Consumer, _ pulsar.MessageID) {} +func (t *ConsumerInterceptor) OnNegativeAcksSend(_ pulsar.Consumer, _ []pulsar.MessageID) {} diff --git a/pulsar/tracing/consumer_interceptor_test.go b/pulsar/tracing/consumer_interceptor_test.go new file mode 100644 index 0000000000..8173b07cff --- /dev/null +++ b/pulsar/tracing/consumer_interceptor_test.go @@ -0,0 +1,81 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 tracing + +import ( + "context" + "testing" + "time" + + "github.com/apache/pulsar-client-go/pulsar" + "github.com/stretchr/testify/assert" + "go.opentelemetry.io/otel" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + "go.opentelemetry.io/otel/sdk/trace/tracetest" +) + +func TestConsumerBuildAndInjectChildSpan(t *testing.T) { + exporter := tracetest.NewInMemoryExporter() + provider := sdktrace.NewTracerProvider( + sdktrace.WithSyncer(exporter), + ) + otel.SetTracerProvider(provider) + + message := pulsar.ConsumerMessage{ + Consumer: &mockConsumer{}, + Message: &mockConsumerMessage{ + properties: map[string]string{}, + }, + } + + interceptor := &ConsumerInterceptor{} + interceptor.BeforeConsume(message) + + spans := exporter.GetSpans() + assert.NotEmpty(t, spans) + span := spans[0] + assert.Contains(t, span.Name, "From__") +} + +type mockConsumer struct{} + +func (c *mockConsumer) Subscription() string { return "test-sub" } +func (c *mockConsumer) AckWithTxn(_ pulsar.Message, _ pulsar.Transaction) error { return nil } +func (c *mockConsumer) Unsubscribe() error { return nil } +func (c *mockConsumer) UnsubscribeForce() error { return nil } +func (c *mockConsumer) Receive(_ context.Context) (message pulsar.Message, err error) { + return nil, nil +} +func (c *mockConsumer) Chan() <-chan pulsar.ConsumerMessage { return nil } +func (c *mockConsumer) Ack(_ pulsar.Message) error { return nil } +func (c *mockConsumer) AckID(_ pulsar.MessageID) error { return nil } +func (c *mockConsumer) AckIDList(_ []pulsar.MessageID) error { return nil } +func (c *mockConsumer) AckCumulative(_ pulsar.Message) error { return nil } +func (c *mockConsumer) AckIDCumulative(_ pulsar.MessageID) error { return nil } +func (c *mockConsumer) ReconsumeLater(_ pulsar.Message, _ time.Duration) {} +func (c *mockConsumer) ReconsumeLaterWithCustomProperties(_ pulsar.Message, _ map[string]string, _ time.Duration) { +} +func (c *mockConsumer) Nack(_ pulsar.Message) {} +func (c *mockConsumer) NackID(_ pulsar.MessageID) {} +func (c *mockConsumer) Close() {} +func (c *mockConsumer) Seek(_ pulsar.MessageID) error { return nil } +func (c *mockConsumer) SeekByTime(_ time.Time) error { return nil } +func (c *mockConsumer) Name() string { return "" } +func (c *mockConsumer) GetLastMessageIDs() ([]pulsar.TopicMessageID, error) { + return []pulsar.TopicMessageID{}, nil +} diff --git a/pulsar/tracing/message_carrier_adaptors.go b/pulsar/tracing/message_carrier_adaptors.go new file mode 100644 index 0000000000..e9b0a39bfa --- /dev/null +++ b/pulsar/tracing/message_carrier_adaptors.go @@ -0,0 +1,76 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 tracing + +import ( + "github.com/apache/pulsar-client-go/pulsar" +) + +// ProducerMessageCarrier carrier adapters for Pulsar messages +type ProducerMessageCarrier struct { + msg *pulsar.ProducerMessage +} + +func (c ProducerMessageCarrier) Get(key string) string { + if len(c.msg.Properties) == 0 { + c.msg.Properties = make(map[string]string) + } + return c.msg.Properties[key] +} + +func (c ProducerMessageCarrier) Set(key, value string) { + if len(c.msg.Properties) == 0 { + c.msg.Properties = make(map[string]string) + } + c.msg.Properties[key] = value +} + +func (c ProducerMessageCarrier) Keys() []string { + if len(c.msg.Properties) == 0 { + return nil + } + keys := make([]string, 0, len(c.msg.Properties)) + for k := range c.msg.Properties { + keys = append(keys, k) + } + return keys +} + +type ConsumerMessageCarrier struct { + msg pulsar.ConsumerMessage +} + +func (c ConsumerMessageCarrier) Get(key string) string { + if len(c.msg.Message.Properties()) == 0 { + return "" + } + return c.msg.Properties()[key] +} + +func (c ConsumerMessageCarrier) Set(key, value string) { + c.msg.Properties()[key] = value +} + +func (c ConsumerMessageCarrier) Keys() []string { + props := c.msg.Properties() + keys := make([]string, 0, len(props)) + for k := range props { + keys = append(keys, k) + } + return keys +} diff --git a/pulsar/tracing/message_carrier_util.go b/pulsar/tracing/message_carrier_util.go new file mode 100644 index 0000000000..670ccbde65 --- /dev/null +++ b/pulsar/tracing/message_carrier_util.go @@ -0,0 +1,53 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 tracing + +import ( + "context" + + "github.com/apache/pulsar-client-go/pulsar" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/trace" +) + +func InjectProducerMessageSpanContext(ctx context.Context, message *pulsar.ProducerMessage) { + carrier := ProducerMessageCarrier{message} + otel.GetTextMapPropagator().Inject(ctx, carrier) +} + +func ExtractSpanContextFromProducerMessage(ctx context.Context, message *pulsar.ProducerMessage) context.Context { + carrier := ProducerMessageCarrier{message} + return otel.GetTextMapPropagator().Extract(ctx, carrier) +} + +func InjectConsumerMessageSpanContext(ctx context.Context, message pulsar.ConsumerMessage) { + carrier := ConsumerMessageCarrier{message} + otel.GetTextMapPropagator().Inject(ctx, carrier) +} + +func ExtractSpanContextFromConsumerMessage(ctx context.Context, message pulsar.ConsumerMessage) context.Context { + carrier := ConsumerMessageCarrier{message} + return otel.GetTextMapPropagator().Extract(ctx, carrier) +} + +// CreateSpanFromMessage create a span from a consumer message, using extracted context as parent +func CreateSpanFromMessage(cm *pulsar.ConsumerMessage, tracerName, label string) (context.Context, trace.Span) { + ctx := ExtractSpanContextFromConsumerMessage(context.Background(), *cm) + tracer := otel.Tracer(tracerName) + return tracer.Start(ctx, label) +} diff --git a/pulsar/tracing/message_carrier_util_test.go b/pulsar/tracing/message_carrier_util_test.go new file mode 100644 index 0000000000..0d3dd4958d --- /dev/null +++ b/pulsar/tracing/message_carrier_util_test.go @@ -0,0 +1,99 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 tracing + +import ( + "context" + "testing" + "time" + + "github.com/apache/pulsar-client-go/pulsar" + "github.com/stretchr/testify/assert" + "go.opentelemetry.io/otel" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + "go.opentelemetry.io/otel/sdk/trace/tracetest" + "go.opentelemetry.io/otel/trace" +) + +func TestProducerMessageInjectAndExtract(t *testing.T) { + exporter := tracetest.NewInMemoryExporter() + provider := sdktrace.NewTracerProvider( + sdktrace.WithSyncer(exporter), + ) + otel.SetTracerProvider(provider) + + message := &pulsar.ProducerMessage{ + Properties: map[string]string{}, + } + + tracer := otel.Tracer("test") + ctx, span := tracer.Start(context.Background(), "test-span") + InjectProducerMessageSpanContext(ctx, message) + assert.NotNil(t, span) + + ctx2 := ExtractSpanContextFromProducerMessage(context.Background(), message) + span2 := trace.SpanFromContext(ctx2) + assert.NotNil(t, span2) +} + +func TestConsumerMessageInjectAndExtract(t *testing.T) { + exporter := tracetest.NewInMemoryExporter() + provider := sdktrace.NewTracerProvider( + sdktrace.WithSyncer(exporter), + ) + otel.SetTracerProvider(provider) + + message := pulsar.ConsumerMessage{ + Message: &mockConsumerMessage{ + properties: map[string]string{}, + }, + } + + tracer := otel.Tracer("test") + ctx, span := tracer.Start(context.Background(), "test-span") + InjectConsumerMessageSpanContext(ctx, message) + assert.NotNil(t, span) + + ctx2 := ExtractSpanContextFromConsumerMessage(context.Background(), message) + span2 := trace.SpanFromContext(ctx2) + assert.NotNil(t, span2) +} + +type mockConsumerMessage struct { + properties map[string]string +} + +func (msg *mockConsumerMessage) Topic() string { return "test-topic" } +func (msg *mockConsumerMessage) Properties() map[string]string { return msg.properties } +func (msg *mockConsumerMessage) Payload() []byte { return nil } +func (msg *mockConsumerMessage) ID() pulsar.MessageID { return pulsar.NewMessageID(-1, -1, -1, 0) } +func (msg *mockConsumerMessage) PublishTime() time.Time { return time.Time{} } +func (msg *mockConsumerMessage) EventTime() time.Time { return time.Time{} } +func (msg *mockConsumerMessage) Key() string { return "" } +func (msg *mockConsumerMessage) OrderingKey() string { return "" } +func (msg *mockConsumerMessage) RedeliveryCount() uint32 { return 0 } +func (msg *mockConsumerMessage) IsReplicated() bool { return false } +func (msg *mockConsumerMessage) GetReplicatedFrom() string { return "" } +func (msg *mockConsumerMessage) GetSchemaValue(_ interface{}) error { return nil } +func (msg *mockConsumerMessage) ProducerName() string { return "" } +func (msg *mockConsumerMessage) SchemaVersion() []byte { return nil } +func (msg *mockConsumerMessage) GetEncryptionContext() *pulsar.EncryptionContext { + return &pulsar.EncryptionContext{} +} +func (msg *mockConsumerMessage) Index() *uint64 { return nil } +func (msg *mockConsumerMessage) BrokerPublishTime() *time.Time { return nil } diff --git a/pulsar/internal/pulsartracing/producer_interceptor.go b/pulsar/tracing/producer_interceptor.go similarity index 58% rename from pulsar/internal/pulsartracing/producer_interceptor.go rename to pulsar/tracing/producer_interceptor.go index 77cb8bf94d..820e9fb164 100644 --- a/pulsar/internal/pulsartracing/producer_interceptor.go +++ b/pulsar/tracing/producer_interceptor.go @@ -15,45 +15,28 @@ // specific language governing permissions and limitations // under the License. -package pulsartracing +package tracing import ( "context" "github.com/apache/pulsar-client-go/pulsar" - "github.com/opentracing/opentracing-go" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/trace" ) const toPrefix = "To__" -type ProducerInterceptor struct { -} +type ProducerInterceptor struct{} func (t *ProducerInterceptor) BeforeSend(producer pulsar.Producer, message *pulsar.ProducerMessage) { - buildAndInjectSpan(message, producer).Finish() -} - -func (t *ProducerInterceptor) OnSendAcknowledgement(_ pulsar.Producer, - _ *pulsar.ProducerMessage, - _ pulsar.MessageID) { -} - -func buildAndInjectSpan(message *pulsar.ProducerMessage, producer pulsar.Producer) opentracing.Span { - tracer := opentracing.GlobalTracer() - spanContext := ExtractSpanContextFromProducerMessage(message) - - var span opentracing.Span - - var startSpanOptions []opentracing.StartSpanOption - if spanContext != nil { - startSpanOptions = []opentracing.StartSpanOption{opentracing.FollowsFrom(spanContext)} - } - - span = tracer.StartSpan(toPrefix+producer.Topic(), startSpanOptions...) - + ctx := ExtractSpanContextFromProducerMessage(context.Background(), message) + tracer := otel.Tracer(componentName) + ctx, span := tracer.Start(ctx, toPrefix+producer.Topic(), trace.WithSpanKind(trace.SpanKindProducer)) enrichProducerSpan(message, producer, span) + InjectProducerMessageSpanContext(ctx, message) + span.End() +} - InjectProducerMessageSpanContext(opentracing.ContextWithSpan(context.Background(), span), message) - - return span +func (t *ProducerInterceptor) OnSendAcknowledgement(_ pulsar.Producer, _ *pulsar.ProducerMessage, _ pulsar.MessageID) { } diff --git a/pulsar/internal/pulsartracing/producer_interceptor_test.go b/pulsar/tracing/producer_interceptor_test.go similarity index 54% rename from pulsar/internal/pulsartracing/producer_interceptor_test.go rename to pulsar/tracing/producer_interceptor_test.go index 74890f7371..f5f9c930f3 100644 --- a/pulsar/internal/pulsartracing/producer_interceptor_test.go +++ b/pulsar/tracing/producer_interceptor_test.go @@ -15,60 +15,50 @@ // specific language governing permissions and limitations // under the License. -package pulsartracing +package tracing import ( "context" "testing" "github.com/apache/pulsar-client-go/pulsar" - "github.com/opentracing/opentracing-go" - "github.com/opentracing/opentracing-go/mocktracer" "github.com/stretchr/testify/assert" + "go.opentelemetry.io/otel" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + "go.opentelemetry.io/otel/sdk/trace/tracetest" ) func TestProducerBuildAndInjectSpan(t *testing.T) { - tracer := mocktracer.New() - opentracing.SetGlobalTracer(tracer) + exporter := tracetest.NewInMemoryExporter() + provider := sdktrace.NewTracerProvider( + sdktrace.WithSyncer(exporter), + ) + otel.SetTracerProvider(provider) message := &pulsar.ProducerMessage{ Properties: map[string]string{}, } - span := buildAndInjectSpan(message, &mockProducer{}) - assert.NotNil(t, span) - assert.True(t, len(message.Properties) > 0) -} - -type mockProducer struct { -} + producer := &mockProducer{} + interceptor := &ProducerInterceptor{} + interceptor.BeforeSend(producer, message) -func (p *mockProducer) Topic() string { - return "" + spans := exporter.GetSpans() + assert.NotEmpty(t, spans) + span := spans[0] + assert.Contains(t, span.Name, "To__") } -func (p *mockProducer) Name() string { - return "" -} +type mockProducer struct{} +func (p *mockProducer) Topic() string { return "test-topic" } +func (p *mockProducer) Name() string { return "" } func (p *mockProducer) Send(context.Context, *pulsar.ProducerMessage) (pulsar.MessageID, error) { return nil, nil } - -func (p *mockProducer) SendAsync(context.Context, *pulsar.ProducerMessage, - func(pulsar.MessageID, *pulsar.ProducerMessage, error)) { -} - -func (p *mockProducer) LastSequenceID() int64 { - return 0 -} - -func (p *mockProducer) Flush() error { - return nil +func (p *mockProducer) SendAsync(context.Context, *pulsar.ProducerMessage, func(pulsar.MessageID, *pulsar.ProducerMessage, error)) { } - -func (p *mockProducer) FlushWithCtx(_ context.Context) error { - return nil -} - -func (p *mockProducer) Close() {} +func (p *mockProducer) LastSequenceID() int64 { return 0 } +func (p *mockProducer) Flush() error { return nil } +func (p *mockProducer) FlushWithCtx(_ context.Context) error { return nil } +func (p *mockProducer) Close() {} diff --git a/pulsar/tracing/readme.md b/pulsar/tracing/readme.md new file mode 100644 index 0000000000..2b02adb74b --- /dev/null +++ b/pulsar/tracing/readme.md @@ -0,0 +1,89 @@ +# Pulsar Client Go Tracing (OpenTelemetry) + +This package provides distributed tracing support for [pulsar-client-go](https://github.com/apache/pulsar-client-go) using [OpenTelemetry (otel)](https://opentelemetry.io/). It enables you to trace message production and consumption across Pulsar topics, propagating context via message properties. + +**Note:** This package is fully based on OpenTelemetry. + +## Features +- Producer and Consumer interceptors for automatic span creation +- Context propagation using OpenTelemetry's W3C Trace Context +- Utilities for extracting/injecting context and creating child spans from messages + +## Usage + +### 1. Set up OpenTelemetry globally + +Before using the interceptors, set up your OpenTelemetry tracer provider and propagator: + +```go +import ( + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/propagation" + "go.opentelemetry.io/otel/sdk/trace" +) + +// Set up your exporter and tracer provider (example uses stdout) +provider := trace.NewTracerProvider(/* ...options... */) +otel.SetTracerProvider(provider) + +// Set the global propagator (W3C TraceContext is default) +otel.SetTextMapPropagator(propagation.TraceContext{}) +``` + +### 2. Producer Interceptor + +```go +import "github.com/apache/pulsar-client-go/pulsar/tracing" + +tracingInterceptor := &tracing.ProducerInterceptor{} + +producerOptions := pulsar.ProducerOptions{ + Topic: "your-topic", + Interceptors: pulsar.ProducerInterceptors{tracingInterceptor}, +} +producer, err := client.CreateProducer(producerOptions) +``` + +### 3. Consumer Interceptor + +```go +import "github.com/apache/pulsar-client-go/pulsar/tracing" + +tracingInterceptor := &tracing.ConsumerInterceptor{} + +consumerOptions := pulsar.ConsumerOptions{ + Topics: []string{"your-topic"}, + SubscriptionName: "your-subscription", + Type: pulsar.Shared, + Interceptors: pulsar.ConsumerInterceptors{tracingInterceptor}, +} +consumer, err := client.Subscribe(consumerOptions) +``` + +### 4. Creating a child span from a message + +If you want to create a span that is a child of the context propagated in a Pulsar message: + +```go +import "github.com/apache/pulsar-client-go/pulsar/tracing" + +ctx, span := tracing.CreateSpanFromMessage(&msg, "your-tracer-name", "operation-name") +defer span.End() +// ... do work with ctx ... +``` + +### 5. Manual context propagation + +You can manually inject or extract context using: + +```go +tracing.InjectProducerMessageSpanContext(ctx, producerMessage) +ctx = tracing.ExtractSpanContextFromProducerMessage(ctx, producerMessage) + +tracing.InjectConsumerMessageSpanContext(ctx, consumerMessage) +ctx = tracing.ExtractSpanContextFromConsumerMessage(ctx, consumerMessage) +``` + +## License + +[Apache 2.0 License](../../LICENSE) \ No newline at end of file diff --git a/pulsar/internal/pulsartracing/span-enrichment.go b/pulsar/tracing/span-enrichment.go similarity index 53% rename from pulsar/internal/pulsartracing/span-enrichment.go rename to pulsar/tracing/span-enrichment.go index e75c398813..4efee20915 100644 --- a/pulsar/internal/pulsartracing/span-enrichment.go +++ b/pulsar/tracing/span-enrichment.go @@ -15,36 +15,42 @@ // specific language governing permissions and limitations // under the License. -package pulsartracing +package tracing import ( "github.com/apache/pulsar-client-go/pulsar" - "github.com/opentracing/opentracing-go" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/trace" ) -func enrichConsumerSpan(message *pulsar.ConsumerMessage, span opentracing.Span) { - spanCommonTags(span) +const componentName = "pulsar-client-go" +func enrichConsumerSpan(message *pulsar.ConsumerMessage, span trace.Span) { + spanCommonAttributes(span) for k, v := range message.Properties() { - span.SetTag(k, v) + span.SetAttributes(attribute.String(k, v)) } - span.SetTag("message_bus.destination", message.Topic()) - span.SetTag("messageId", message.ID()) - span.SetTag("subscription", message.Subscription()) + span.SetAttributes( + attribute.String("topic", message.Topic()), + attribute.String("messageId", message.ID().String()), + attribute.String("subscription", message.Subscription()), + ) } -func enrichProducerSpan(message *pulsar.ProducerMessage, producer pulsar.Producer, span opentracing.Span) { - spanCommonTags(span) - +func enrichProducerSpan(message *pulsar.ProducerMessage, producer pulsar.Producer, span trace.Span) { + spanCommonAttributes(span) for k, v := range message.Properties { - span.SetTag(k, v) + span.SetAttributes(attribute.String(k, v)) } - span.SetTag("span.kind", "producer") - span.SetTag("message_bus.destination", producer.Topic()) - span.SetTag("sequenceId", producer.LastSequenceID()) + span.SetAttributes( + attribute.String("topic", producer.Topic()), + attribute.Int64("sequenceId", producer.LastSequenceID()), + ) } -func spanCommonTags(span opentracing.Span) { - span.SetTag("component", "pulsar-client-go") - span.SetTag("peer.service", "pulsar-broker") +func spanCommonAttributes(span trace.Span) { + span.SetAttributes( + attribute.String("component", "pulsar-client-go"), + attribute.String("peer.service", "pulsar-broker"), + ) }