From 05358e535e378cf2c49cab05c39fe9cc2d4a6de3 Mon Sep 17 00:00:00 2001 From: David Allen Date: Mon, 6 Jul 2026 18:38:20 -0600 Subject: [PATCH 1/3] fix(security): bump grpc to v1.79.3 and otel/sdk to v1.44.0 Closes the two reachable vulnerabilities from the security review: - GO-2026-4762: grpc-go authorization bypass via missing leading slash in :path - GO-2026-4394: otel SDK code execution via PATH-resolved binary in resource detection govulncheck now reports 0 vulnerabilities affecting our code. Co-Authored-By: Claude Fable 5 --- go.mod | 30 ++++++++++++++--------------- go.sum | 60 +++++++++++++++++++++++++++++----------------------------- 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/go.mod b/go.mod index d013f8b..227615b 100644 --- a/go.mod +++ b/go.mod @@ -11,13 +11,15 @@ require ( github.com/redis/go-redis/v9 v9.14.0 github.com/rs/zerolog v1.34.0 github.com/sony/gobreaker v1.0.0 - go.opentelemetry.io/otel v1.38.0 + go.opentelemetry.io/otel v1.44.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 - go.opentelemetry.io/otel/metric v1.38.0 - go.opentelemetry.io/otel/sdk v1.38.0 - go.opentelemetry.io/otel/sdk/metric v1.38.0 - go.opentelemetry.io/otel/trace v1.38.0 - google.golang.org/grpc v1.75.1 + go.opentelemetry.io/otel/exporters/prometheus v0.60.0 + go.opentelemetry.io/otel/metric v1.44.0 + go.opentelemetry.io/otel/sdk v1.44.0 + go.opentelemetry.io/otel/sdk/metric v1.44.0 + go.opentelemetry.io/otel/trace v1.44.0 + google.golang.org/grpc v1.79.3 gopkg.in/yaml.v3 v3.0.1 ) @@ -38,16 +40,14 @@ require ( github.com/prometheus/common v0.66.1 // indirect github.com/prometheus/otlptranslator v0.0.2 // indirect github.com/prometheus/procfs v0.17.0 // indirect - go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/prometheus v0.60.0 // indirect go.opentelemetry.io/proto/otlp v1.7.1 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/net v0.43.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/text v0.28.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect - google.golang.org/protobuf v1.36.8 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/sys v0.45.0 // indirect + golang.org/x/text v0.32.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/protobuf v1.36.10 // indirect ) diff --git a/go.sum b/go.sum index c24f3d9..d96ed42 100644 --- a/go.sum +++ b/go.sum @@ -64,14 +64,12 @@ github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9Z github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= github.com/prometheus/otlptranslator v0.0.2 h1:+1CdeLVrRQ6Psmhnobldo0kTp96Rj80DRXRd5OSnMEQ= github.com/prometheus/otlptranslator v0.0.2/go.mod h1:P8AwMgdD7XEr6QRUJ2QWLpiAZTgTE2UYgjlu3svompI= -github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= -github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0= github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= github.com/redis/go-redis/v9 v9.14.0 h1:u4tNCjXOyzfgeLN+vAZaW1xUooqWDqVEsZN0U01jfAE= github.com/redis/go-redis/v9 v9.14.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw= -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/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= @@ -81,10 +79,10 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -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.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= +go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 h1:vl9obrcoWVKp/lwl8tRE33853I8Xru9HFbw/skNeLs8= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0/go.mod h1:GAXRxmLJcVM3u22IjTg74zWBrRCKq8BnOqUVLodpcpw= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= @@ -93,39 +91,41 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4D go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= go.opentelemetry.io/otel/exporters/prometheus v0.60.0 h1:cGtQxGvZbnrWdC2GyjZi0PDKVSLWP/Jocix3QWfXtbo= go.opentelemetry.io/otel/exporters/prometheus v0.60.0/go.mod h1:hkd1EekxNo69PTV4OWFGZcKQiIqg0RfuWExcPKFvepk= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= +go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/metric/x v0.66.0 h1:YkCrx1zLOChi9ZcZ6euupOcsgzbVlec7D/xoEU1+cTA= +go.opentelemetry.io/otel/metric/x v0.66.0/go.mod h1:d1+BDj9t96do0/1LoU1ayfCv79ZgNE41qbhBvnMOBZk= +go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= +go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= +go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= +go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= +golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY= -google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= -google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI= -google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= -google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= -google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= From 2203357fd8b816f0ff85699a5af6507d270b5f57 Mon Sep 17 00:00:00 2001 From: David Allen Date: Mon, 6 Jul 2026 18:47:22 -0600 Subject: [PATCH 2/3] fix(security): address HIGH/MEDIUM/LOW findings from security review JWT bundle: - add StreamServerInterceptor so streaming RPCs are authenticated (shared auth helper with unary); was a silent auth gap (#2) - RequireHTTPS no longer trusts X-Forwarded-Proto unless TrustedProxyHeader opt-in is set (#10) httpclient bundle: - strip Authorization + API-key header on cross-host redirects (#5) - sanitize URL in error-log path, matching success path (#12) - opt-in AllowedHosts SSRF guard on request and RawRequest paths (#14) framework + health: - redact raw dependency error strings from public health endpoint bodies; full detail stays in logs (#4) - opt-in basic auth for /metrics with constant-time comparison; warn when unauthenticated in production (#6) - block pprof outside development (was leaking in staging; old branch warned but never returned) (#7) - add Vary: Origin when reflecting a CORS origin (#13) config + configloader + redis: - gRPC reflection now requires explicit EnableReflection, not implicit in dev (#8) - redact connection-string values (DATABASE_URL/REDIS_URL) by name and URL-userinfo parsing (#9) - unique rate-limiter ZSET members to prevent same-nanosecond undercount (#11) govulncheck: 0 vulnerabilities affecting our code. Co-Authored-By: Claude Fable 5 --- bundles/configloader/bundle.go | 20 +++ bundles/configloader/bundle_test.go | 94 +++++++++++ bundles/httpclient/bundle.go | 77 ++++++++- bundles/httpclient/bundle_test.go | 166 ++++++++++++++++++++ bundles/jwt/bundle.go | 105 +++++++++++-- bundles/jwt/bundle_test.go | 197 +++++++++++++++++++++++ bundles/redis/bundle.go | 23 ++- bundles/redis/bundle_test.go | 117 ++++++++++++++ config/base.go | 9 +- config/base_test.go | 2 +- framework/app.go | 6 +- framework/app_http_test.go | 61 ++++++++ framework/http.go | 64 ++++++-- framework/http_test.go | 235 ++++++++++++++++++++++++++++ health/check.go | 12 ++ health/check_test.go | 41 +++++ health/status.go | 19 +++ health/status_test.go | 43 +++++ 18 files changed, 1247 insertions(+), 44 deletions(-) diff --git a/bundles/configloader/bundle.go b/bundles/configloader/bundle.go index 91c4ac1..401233a 100644 --- a/bundles/configloader/bundle.go +++ b/bundles/configloader/bundle.go @@ -86,6 +86,7 @@ import ( stderrors "errors" "fmt" "io" + "net/url" "os" "path/filepath" "reflect" @@ -621,6 +622,7 @@ func (l *Loader) containsSensitiveKeyword(text string) bool { "auth", "cert", "private", "jwt", "oauth", "api_key", "access_key", "secret_key", "private_key", "client_secret", "session", "cookie", "tls", "ssl", "pgp", "gpg", + "dsn", "database", "redis", "conn", "connection", } for _, keyword := range sensitiveKeywords { @@ -628,6 +630,15 @@ func (l *Loader) containsSensitiveKeyword(text string) bool { return true } } + + // Connection-string-style values (e.g. DATABASE_URL, REDIS_URL, + // ServiceURL) are commonly named with a "url"/"uri" suffix rather than + // containing an obviously sensitive keyword, but frequently embed + // credentials. Match the suffix rather than "contains" to avoid + // flagging every field that merely mentions a URL in passing. + if strings.HasSuffix(text, "url") || strings.HasSuffix(text, "uri") { + return true + } return false } @@ -637,6 +648,15 @@ func (l *Loader) looksLikeSensitiveData(value string) bool { return false } + // Connection-string-style URLs with embedded credentials (e.g. + // postgres://user:pass@host:5432/db, redis://:pass@host:6379/0) leak a + // password regardless of the field/env var name. + if u, err := url.Parse(value); err == nil && u.User != nil { + if _, hasPassword := u.User.Password(); hasPassword { + return true + } + } + // Base64-encoded data (likely sensitive) if len(value) > 20 && len(value)%4 == 0 { // Check if it's base64 diff --git a/bundles/configloader/bundle_test.go b/bundles/configloader/bundle_test.go index 9eecbed..d7d090e 100644 --- a/bundles/configloader/bundle_test.go +++ b/bundles/configloader/bundle_test.go @@ -5,6 +5,7 @@ import ( "os" "path/filepath" "reflect" + "strings" "testing" ) @@ -182,6 +183,44 @@ func TestLoaderLoad_EnvVarOverride(t *testing.T) { } } +// TestLoaderLoad_RedactsConnectionStringSecrets verifies that DATABASE_URL / +// REDIS_URL style values, which embed credentials but whose field/env names +// don't contain an obviously sensitive keyword like "password" or "secret", +// are redacted in LoadResult.EnvVarsUsed rather than logged in cleartext. +func TestLoaderLoad_RedactsConnectionStringSecrets(t *testing.T) { + type TestCfg struct { + DatabaseURL string `env:"TEST_DATABASE_URL_CONFIGLOADER"` + RedisURL string `env:"TEST_REDIS_URL_CONFIGLOADER"` + } + + const dbPassword = "sup3rSecretPW" + t.Setenv("TEST_DATABASE_URL_CONFIGLOADER", "postgres://user:"+dbPassword+"@dbhost:5432/mydb") + t.Setenv("TEST_REDIS_URL_CONFIGLOADER", "redis://:"+dbPassword+"@redishost:6379/0") + + l := loaderWithConfig(Config{ + ConfigPaths: []string{"./nonexistent.yaml"}, + RequireConfigFile: false, + ValidateOnLoad: false, + MaxFileSize: 1024 * 1024, + SecureLogging: true, + }) + + var cfg TestCfg + result, err := l.Load(&cfg) + if err != nil { + t.Fatalf("Load failed: %v", err) + } + + if len(result.EnvVarsUsed) == 0 { + t.Fatal("expected EnvVarsUsed to be populated") + } + for _, entry := range result.EnvVarsUsed { + if strings.Contains(entry, dbPassword) { + t.Errorf("expected password to be redacted from EnvVarsUsed, got %q", entry) + } + } +} + // TestLoaderLoad_NilDest tests that Load rejects nil destination. func TestLoaderLoad_NilDest(t *testing.T) { l := loaderWithConfig(DefaultConfig()) @@ -688,6 +727,61 @@ func TestLoadFromFile_RelativePath(t *testing.T) { } } +// TestLooksLikeSensitiveData_ConnectionStringPassword verifies that URL-shaped +// values with embedded userinfo credentials are flagged regardless of the +// field/env name that carries them (defense-in-depth alongside the +// name-based keyword check). +func TestLooksLikeSensitiveData_ConnectionStringPassword(t *testing.T) { + l := loaderWithConfig(DefaultConfig()) + + cases := []struct { + name string + value string + expected bool + }{ + {"postgres with password", "postgres://user:pass@dbhost:5432/mydb", true}, + {"redis with password only", "redis://:pass@redishost:6379/0", true}, + {"http url without credentials", "http://example.com/path", false}, + {"url with user but no password", "postgres://user@dbhost:5432/mydb", false}, + {"plain non-url string", "hello", false}, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + if got := l.looksLikeSensitiveData(tc.value); got != tc.expected { + t.Errorf("looksLikeSensitiveData(%q) = %v, want %v", tc.value, got, tc.expected) + } + }) + } +} + +// TestContainsSensitiveKeyword_URLSuffix verifies the url/dsn/uri suffix +// matching added for connection-string-style field names, and that it +// doesn't over-match names that merely contain "url" as an infix. +func TestContainsSensitiveKeyword_URLSuffix(t *testing.T) { + l := loaderWithConfig(DefaultConfig()) + + cases := []struct { + name string + text string + expected bool + }{ + {"database_url env tag", "database_url", true}, + {"redis_url env tag", "redis_url", true}, + {"DatabaseURL field name lowered", "databaseurl", true}, + {"dsn suffix", "connectiondsn", true}, + {"plain normal field", "normal", false}, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + if got := l.containsSensitiveKeyword(tc.text); got != tc.expected { + t.Errorf("containsSensitiveKeyword(%q) = %v, want %v", tc.text, got, tc.expected) + } + }) + } +} + func TestMustLoadConfig_Panics(t *testing.T) { defer func() { if r := recover(); r == nil { diff --git a/bundles/httpclient/bundle.go b/bundles/httpclient/bundle.go index aabb794..ef55d21 100644 --- a/bundles/httpclient/bundle.go +++ b/bundles/httpclient/bundle.go @@ -151,6 +151,13 @@ type Config struct { // Secure credential provider (replaces plain text APIKey) CredentialProvider CredentialProvider // Provider for secure credential access + // AllowedHosts optionally restricts requests (including RawRequest and + // resolved BaseURL+path lookups) to this set of hosts. This is opt-in + // defense-in-depth against SSRF for services that pass user-influenced + // URLs or paths through the client. Empty/nil (default) preserves the + // existing unrestricted behavior. + AllowedHosts []string + // Retry configuration RetryConfig RetryConfig @@ -370,8 +377,9 @@ func (b *Bundle) Initialize(app *framework.App) error { // Create HTTP client httpClient := &http.Client{ - Transport: transport, - Timeout: b.config.Timeout, + Transport: transport, + Timeout: b.config.Timeout, + CheckRedirect: redirectHeaderStripper(b.config.APIKeyHeader), } // Create enhanced client wrapper @@ -411,6 +419,34 @@ func (b *Bundle) Close() error { return b.Stop(ctx) } +// maxRedirects matches the net/http default redirect limit. +const maxRedirects = 10 + +// redirectHeaderStripper returns an http.Client CheckRedirect function that +// removes credential headers whenever a redirect crosses to a different host. +// Go's default redirect handling already strips "Authorization" on cross-host +// redirects but forwards custom headers like the configured API-key header +// unchanged, allowing a malicious or compromised upstream to harvest +// credentials via a 302 to an attacker-controlled host. Same-host redirects +// are unaffected and continue to carry auth headers as before. +func redirectHeaderStripper(apiKeyHeader string) func(*http.Request, []*http.Request) error { + return func(req *http.Request, via []*http.Request) error { + if len(via) >= maxRedirects { + return fmt.Errorf("stopped after %d redirects", maxRedirects) + } + + prev := via[len(via)-1] + if prev.URL.Host != req.URL.Host { + req.Header.Del("Authorization") + if apiKeyHeader != "" { + req.Header.Del(apiKeyHeader) + } + } + + return nil + } +} + // createBackoffStrategy creates the configured backoff strategy. func (b *Bundle) createBackoffStrategy() backoff.BackOff { exponentialBackoff := backoff.NewExponentialBackOff() @@ -475,6 +511,7 @@ func (e *HTTPError) IsRetryableError() bool { var ( ErrCircuitBreakerOpen = stderrors.New("circuit breaker is open") ErrMaxRetriesExceeded = stderrors.New("maximum retries exceeded") + ErrHostNotAllowed = stderrors.New("host not allowed") ) // Get performs a GET request and unmarshals the response into dest. @@ -505,6 +542,10 @@ func (c *Client) request(ctx context.Context, method, path string, body interfac return fmt.Errorf("failed to build URL: %w", err) } + if err := c.checkHostAllowed(fullURL); err != nil { + return err + } + // Execute request with circuit breaker protection _, err = c.circuitBreaker.Execute(func() (interface{}, error) { return nil, c.executeWithRetry(ctx, method, fullURL, body, dest) @@ -722,7 +763,7 @@ func (c *Client) sanitizeURLForLogging(rawURL string) string { func (c *Client) logRequestError(method, url string, duration time.Duration, err error) { c.logger.Error(). Str("method", method). - Str("url", url). + Str("url", c.sanitizeURLForLogging(url)). Dur("duration", duration). Err(err). Msg("HTTP Request Error") @@ -747,6 +788,32 @@ func (c *Client) buildURL(path string) (string, error) { return baseURL.ResolveReference(pathURL).String(), nil } +// checkHostAllowed validates rawURL's host against config.AllowedHosts. It is +// an opt-in SSRF safeguard: when AllowedHosts is empty (the default), every +// host is permitted, preserving existing behavior. When non-empty, requests +// to any other host are rejected with ErrHostNotAllowed. This covers both the +// shared request path (buildURL results, which may be overridden by an +// absolute path) and RawRequest, where the caller supplies the URL directly. +func (c *Client) checkHostAllowed(rawURL string) error { + if len(c.config.AllowedHosts) == 0 { + return nil + } + + parsedURL, err := url.Parse(rawURL) + if err != nil { + return fmt.Errorf("invalid URL: %w", err) + } + + host := parsedURL.Hostname() + for _, allowed := range c.config.AllowedHosts { + if host == allowed { + return nil + } + } + + return fmt.Errorf("%w: %s", ErrHostNotAllowed, host) +} + // addAuthHeaders adds authentication headers to the request. func (c *Client) addAuthHeaders(ctx context.Context, req *http.Request) error { // Add API key if credential provider is configured @@ -823,6 +890,10 @@ func (b *Bundle) EnableJWTIntegration(jwtBundle interface{}) error { // RawRequest performs a raw HTTP request with full control over request/response. func (c *Client) RawRequest(ctx context.Context, method, url string, headers map[string]string, body io.Reader) (*http.Response, error) { + if err := c.checkHostAllowed(url); err != nil { + return nil, err + } + req, err := http.NewRequestWithContext(ctx, method, url, body) if err != nil { return nil, fmt.Errorf("failed to create HTTP request: %w", err) diff --git a/bundles/httpclient/bundle_test.go b/bundles/httpclient/bundle_test.go index b93dd73..173e455 100644 --- a/bundles/httpclient/bundle_test.go +++ b/bundles/httpclient/bundle_test.go @@ -5,6 +5,7 @@ import ( "errors" "net/http" "net/http/httptest" + "strings" "testing" "time" ) @@ -661,6 +662,171 @@ func TestExecuteWithRetry_ContextDeadlineExceeded(t *testing.T) { } } +// --- Cross-host redirect header stripping (Finding #5) --- + +func TestClient_CrossHostRedirect_StripsAuthHeaders(t *testing.T) { + var capturedAuth, capturedAPIKey string + target := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + capturedAuth = r.Header.Get("Authorization") + capturedAPIKey = r.Header.Get("X-API-Key") + w.WriteHeader(http.StatusOK) + })) + defer target.Close() + + redirector := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, target.URL+"/dest", http.StatusFound) + })) + defer redirector.Close() + + cfg := DefaultConfig() + cfg.BaseURL = redirector.URL + cfg.RetryConfig.MaxRetries = 0 + cfg.CircuitBreakerConfig.Name = "test-cross-host-redirect" + cfg.CredentialProvider = NewStaticCredentialProvider("secret-api-key", "header.payload.signature") + cfg.EnableJWTAuth = true + + b := NewBundle(cfg) + if err := b.Initialize(nil); err != nil { + t.Fatalf("failed to initialize bundle: %v", err) + } + + if err := b.Client().Get(context.Background(), "/start", nil); err != nil { + t.Fatalf("unexpected error: %v", err) + } + + if capturedAuth != "" { + t.Errorf("expected Authorization header to be stripped on cross-host redirect, got %q", capturedAuth) + } + if capturedAPIKey != "" { + t.Errorf("expected API key header to be stripped on cross-host redirect, got %q", capturedAPIKey) + } +} + +func TestClient_SameHostRedirect_KeepsAuthHeaders(t *testing.T) { + var capturedAuth, capturedAPIKey string + mux := http.NewServeMux() + mux.HandleFunc("/start", func(w http.ResponseWriter, r *http.Request) { + http.Redirect(w, r, "/dest", http.StatusFound) + }) + mux.HandleFunc("/dest", func(w http.ResponseWriter, r *http.Request) { + capturedAuth = r.Header.Get("Authorization") + capturedAPIKey = r.Header.Get("X-API-Key") + w.WriteHeader(http.StatusOK) + }) + server := httptest.NewServer(mux) + defer server.Close() + + cfg := DefaultConfig() + cfg.BaseURL = server.URL + cfg.RetryConfig.MaxRetries = 0 + cfg.CircuitBreakerConfig.Name = "test-same-host-redirect" + cfg.CredentialProvider = NewStaticCredentialProvider("secret-api-key", "header.payload.signature") + cfg.EnableJWTAuth = true + + b := NewBundle(cfg) + if err := b.Initialize(nil); err != nil { + t.Fatalf("failed to initialize bundle: %v", err) + } + + if err := b.Client().Get(context.Background(), "/start", nil); err != nil { + t.Fatalf("unexpected error: %v", err) + } + + if capturedAuth != "Bearer header.payload.signature" { + t.Errorf("expected Authorization header to be preserved on same-host redirect, got %q", capturedAuth) + } + if capturedAPIKey != "secret-api-key" { + t.Errorf("expected API key header to be preserved on same-host redirect, got %q", capturedAPIKey) + } +} + +// --- logRequestError URL sanitization (Finding #12) --- + +func TestClient_LogRequestError_SanitizesURL(t *testing.T) { + client := newTestClient(t, "") + + rawURL := "http://example.com/path?token=super-secret&other=1" + sanitized := client.sanitizeURLForLogging(rawURL) + if strings.Contains(sanitized, "super-secret") { + t.Fatalf("sanitizeURLForLogging did not redact token, got %q", sanitized) + } + + // logRequestError must route the URL through the same sanitizer used by + // logRequest; exercise it directly to ensure it does not panic and + // completes (the logger is a no-op in tests, so we assert indirectly via + // sanitizeURLForLogging above and simply confirm the call is safe). + client.logRequestError(http.MethodGet, rawURL, time.Millisecond, errors.New("boom")) +} + +// --- AllowedHosts SSRF allowlist (Finding #14) --- + +func TestClient_AllowedHosts_NilAllowsAnyHost(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + })) + defer server.Close() + + client := newTestClient(t, "") + if err := client.checkHostAllowed(server.URL); err != nil { + t.Errorf("expected nil AllowedHosts to permit any host, got: %v", err) + } +} + +func TestClient_AllowedHosts_BlocksDisallowedHost(t *testing.T) { + client := newTestClient(t, "") + client.config.AllowedHosts = []string{"api.example.com"} + + err := client.checkHostAllowed("https://evil.example.org/steal") + if !errors.Is(err, ErrHostNotAllowed) { + t.Fatalf("expected errors.Is(err, ErrHostNotAllowed), got %v", err) + } +} + +func TestClient_AllowedHosts_AllowsListedHost(t *testing.T) { + client := newTestClient(t, "") + client.config.AllowedHosts = []string{"api.example.com"} + + if err := client.checkHostAllowed("https://api.example.com/resource"); err != nil { + t.Errorf("expected listed host to be allowed, got: %v", err) + } +} + +func TestClient_AllowedHosts_BlocksRawRequestToDisallowedHost(t *testing.T) { + target := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + })) + defer target.Close() + + client := newTestClient(t, "") + client.config.AllowedHosts = []string{"some-other-host.invalid"} + + _, err := client.RawRequest(context.Background(), http.MethodGet, target.URL, nil, nil) + if !errors.Is(err, ErrHostNotAllowed) { + t.Fatalf("expected errors.Is(err, ErrHostNotAllowed), got %v", err) + } +} + +func TestClient_AllowedHosts_PermitsRequestToAllowedHost(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte(`{"ok":true}`)) + })) + defer server.Close() + + serverHostname := strings.Split(strings.TrimPrefix(strings.TrimPrefix(server.URL, "http://"), "https://"), ":")[0] + + client := newTestClient(t, server.URL) + client.config.AllowedHosts = []string{serverHostname} + + var result map[string]bool + if err := client.Get(context.Background(), "/ok", &result); err != nil { + t.Fatalf("unexpected error for allowed host: %v", err) + } + if !result["ok"] { + t.Error("expected ok=true") + } +} + func TestRequest_CircuitBreakerOpen(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusInternalServerError) diff --git a/bundles/jwt/bundle.go b/bundles/jwt/bundle.go index a06acfb..5739222 100644 --- a/bundles/jwt/bundle.go +++ b/bundles/jwt/bundle.go @@ -38,9 +38,15 @@ // // // Server side (automatic token validation) // app, err := framework.New( -// framework.WithGRPCInterceptor(jwtBundle.UnaryServerInterceptor()), +// framework.WithUnaryInterceptor(jwtBundle.UnaryServerInterceptor()), +// framework.WithStreamInterceptor(jwtBundle.StreamServerInterceptor()), // ) // +// The framework maintains separate interceptor chains for unary and streaming +// RPCs. Registering only UnaryServerInterceptor leaves server-streaming and +// bidirectional-streaming methods completely unauthenticated — always register +// both interceptors together. +// // # HTTP Authentication // // Secure HTTP endpoints with JWT middleware: @@ -115,6 +121,14 @@ type Config struct { // RequireHTTPS enforces HTTPS for HTTP authentication (recommended for production). RequireHTTPS bool + // TrustedProxyHeader controls whether the X-Forwarded-Proto header is + // trusted to satisfy RequireHTTPS. It defaults to false: by default only + // the actual connection (req.TLS != nil) is consulted, since any client + // can forge X-Forwarded-Proto. Set this to true only when the service + // sits behind a trusted, terminating reverse proxy that overwrites (never + // merely appends to) this header before requests reach the service. + TrustedProxyHeader bool + // SkipPaths are HTTP paths that don't require authentication. SkipPaths []string } @@ -300,23 +314,36 @@ func (b *Bundle) validateClaims(claims *ServiceClaims) error { return nil } +// authenticateContext extracts and validates a JWT token from gRPC metadata +// on ctx, returning the resulting claims. Both UnaryServerInterceptor and +// StreamServerInterceptor call this so their authentication logic cannot +// drift apart. +func (b *Bundle) authenticateContext(ctx context.Context) (*ServiceClaims, error) { + // Extract token from gRPC metadata + token, err := b.extractTokenFromMetadata(ctx) + if err != nil { + // Log detailed error for debugging, return generic error to client + // TODO: Add proper logging when logger is available + return nil, status.Errorf(codes.Unauthenticated, "authentication required") + } + + // Validate token + claims, err := b.ValidateToken(token) + if err != nil { + // Log detailed error for debugging, return generic error to client + // TODO: Add proper logging when logger is available + return nil, status.Errorf(codes.Unauthenticated, "invalid credentials") + } + + return claims, nil +} + // UnaryServerInterceptor returns a gRPC server interceptor for JWT authentication. func (b *Bundle) UnaryServerInterceptor() grpc.UnaryServerInterceptor { return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { - // Extract token from gRPC metadata - token, err := b.extractTokenFromMetadata(ctx) + claims, err := b.authenticateContext(ctx) if err != nil { - // Log detailed error for debugging, return generic error to client - // TODO: Add proper logging when logger is available - return nil, status.Errorf(codes.Unauthenticated, "authentication required") - } - - // Validate token - claims, err := b.ValidateToken(token) - if err != nil { - // Log detailed error for debugging, return generic error to client - // TODO: Add proper logging when logger is available - return nil, status.Errorf(codes.Unauthenticated, "invalid credentials") + return nil, err } // Add claims to context @@ -326,6 +353,39 @@ func (b *Bundle) UnaryServerInterceptor() grpc.UnaryServerInterceptor { } } +// StreamServerInterceptor returns a gRPC stream server interceptor for JWT +// authentication. It performs the same token extraction and validation as +// UnaryServerInterceptor, but reads the token from the stream's context +// (grpc.ServerStream.Context()) and injects claims into a wrapped stream so +// handlers can retrieve them via ClaimsFromContext. +func (b *Bundle) StreamServerInterceptor() grpc.StreamServerInterceptor { + return func(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error { + claims, err := b.authenticateContext(ss.Context()) + if err != nil { + return err + } + + wrapped := &wrappedServerStream{ + ServerStream: ss, + ctx: b.contextWithClaims(ss.Context(), claims), + } + + return handler(srv, wrapped) + } +} + +// wrappedServerStream wraps a grpc.ServerStream to override its Context(), +// allowing authenticated claims to be injected for stream handlers. +type wrappedServerStream struct { + grpc.ServerStream + ctx context.Context +} + +// Context returns the wrapped context carrying authenticated claims. +func (w *wrappedServerStream) Context() context.Context { + return w.ctx +} + // UnaryClientInterceptor returns a gRPC client interceptor for JWT token injection. func (b *Bundle) UnaryClientInterceptor() grpc.UnaryClientInterceptor { return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { @@ -363,8 +423,10 @@ func (b *Bundle) HTTPMiddleware(next http.Handler) http.Handler { return } - // Enforce HTTPS in production if configured - if b.config.RequireHTTPS && r.TLS == nil && r.Header.Get("X-Forwarded-Proto") != "https" { + // Enforce HTTPS in production if configured. Only consult + // X-Forwarded-Proto when TrustedProxyHeader is set — otherwise a + // client could forge the header to bypass this check. + if b.config.RequireHTTPS && !b.isRequestHTTPS(r) { http.Error(w, "HTTPS required", http.StatusBadRequest) return } @@ -469,6 +531,17 @@ func (b *Bundle) shouldSkipPath(path string) bool { return false } +// isRequestHTTPS reports whether the request should be treated as HTTPS for +// RequireHTTPS enforcement. It trusts the X-Forwarded-Proto header only when +// TrustedProxyHeader is enabled; otherwise it relies solely on the actual +// connection state, since the header can be forged by any client. +func (b *Bundle) isRequestHTTPS(r *http.Request) bool { + if r.TLS != nil { + return true + } + return b.config.TrustedProxyHeader && r.Header.Get("X-Forwarded-Proto") == "https" +} + // contextWithClaims adds JWT claims to the context. func (b *Bundle) contextWithClaims(ctx context.Context, claims *ServiceClaims) context.Context { return context.WithValue(ctx, claimsContextKeyType{}, claims) diff --git a/bundles/jwt/bundle_test.go b/bundles/jwt/bundle_test.go index 093d5ac..bb31be4 100644 --- a/bundles/jwt/bundle_test.go +++ b/bundles/jwt/bundle_test.go @@ -6,6 +6,11 @@ import ( "testing" "time" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + "github.com/datariot/forge/errors" ) @@ -642,3 +647,195 @@ func TestValidateServiceIdentifier_InvalidChars(t *testing.T) { t.Error("expected error for identifier with invalid characters") } } + +// fakeServerStream is a minimal grpc.ServerStream whose Context() is +// controllable, used to drive StreamServerInterceptor in tests. +type fakeServerStream struct { + grpc.ServerStream + ctx context.Context +} + +func (f *fakeServerStream) Context() context.Context { return f.ctx } + +// TestBundle_StreamServerInterceptor_RejectsMissingToken returns +// Unauthenticated when the stream context carries no metadata. +func TestBundle_StreamServerInterceptor_RejectsMissingToken(t *testing.T) { + b := newValidBundle() + interceptor := b.StreamServerInterceptor() + + stream := &fakeServerStream{ctx: context.Background()} + handlerCalled := false + handler := func(srv interface{}, ss grpc.ServerStream) error { + handlerCalled = true + return nil + } + + err := interceptor(nil, stream, &grpc.StreamServerInfo{}, handler) + if err == nil { + t.Fatal("expected error for missing token") + } + if status.Code(err) != codes.Unauthenticated { + t.Errorf("expected Unauthenticated, got %v", status.Code(err)) + } + if handlerCalled { + t.Error("expected handler not to be called") + } +} + +// TestBundle_StreamServerInterceptor_RejectsInvalidToken returns +// Unauthenticated when the token fails validation. +func TestBundle_StreamServerInterceptor_RejectsInvalidToken(t *testing.T) { + b := newValidBundle() + interceptor := b.StreamServerInterceptor() + + md := metadata.Pairs("authorization", "Bearer not-a-real-token") + ctx := metadata.NewIncomingContext(context.Background(), md) + stream := &fakeServerStream{ctx: ctx} + handlerCalled := false + handler := func(srv interface{}, ss grpc.ServerStream) error { + handlerCalled = true + return nil + } + + err := interceptor(nil, stream, &grpc.StreamServerInfo{}, handler) + if err == nil { + t.Fatal("expected error for invalid token") + } + if status.Code(err) != codes.Unauthenticated { + t.Errorf("expected Unauthenticated, got %v", status.Code(err)) + } + if handlerCalled { + t.Error("expected handler not to be called") + } +} + +// TestBundle_StreamServerInterceptor_AcceptsValidToken calls the handler with +// a wrapped stream whose Context() carries the authenticated claims. +func TestBundle_StreamServerInterceptor_AcceptsValidToken(t *testing.T) { + b := newValidBundle() + interceptor := b.StreamServerInterceptor() + + token, err := b.GenerateToken("svc-123", "test-service", []string{"read"}) + if err != nil { + t.Fatalf("generate: %v", err) + } + + md := metadata.Pairs("authorization", "Bearer "+token) + ctx := metadata.NewIncomingContext(context.Background(), md) + stream := &fakeServerStream{ctx: ctx} + + var gotClaims *ServiceClaims + handler := func(srv interface{}, ss grpc.ServerStream) error { + gotClaims = ClaimsFromContext(ss.Context()) + return nil + } + + if err := interceptor(nil, stream, &grpc.StreamServerInfo{}, handler); err != nil { + t.Fatalf("expected no error, got: %v", err) + } + if gotClaims == nil { + t.Fatal("expected claims to be present in wrapped stream context") + } + if gotClaims.ServiceID != "svc-123" { + t.Errorf("expected ServiceID='svc-123', got %q", gotClaims.ServiceID) + } +} + +// TestBundle_RequireHTTPS_UntrustedProxyHeader_ForgedHeaderIgnored verifies +// that a forged X-Forwarded-Proto header does not satisfy RequireHTTPS when +// TrustedProxyHeader is left at its default (false). +func TestBundle_RequireHTTPS_UntrustedProxyHeader_ForgedHeaderIgnored(t *testing.T) { + cfg := DefaultConfig() + cfg.SecretKey = []byte("this-is-a-32-byte-secret-key!!!!") + cfg.ServiceName = "test-service" + cfg.Issuer = "test-issuer" + cfg.Audience = "test-audience" + cfg.RequireHTTPS = true + // TrustedProxyHeader defaults to false. + b := NewBundle(cfg) + + handlerCalled := false + inner := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + handlerCalled = true + w.WriteHeader(http.StatusOK) + }) + handler := b.HTTPMiddleware(inner) + + req, _ := http.NewRequest(http.MethodGet, "/api/data", nil) + req.Header.Set("X-Forwarded-Proto", "https") // forged by an untrusted client + w := newResponseRecorder() + handler.ServeHTTP(w, req) + + if w.Code != http.StatusBadRequest { + t.Errorf("expected 400 (HTTPS required), got %d", w.Code) + } + if handlerCalled { + t.Error("expected handler not to be called when forged header is ignored") + } +} + +// TestBundle_RequireHTTPS_TrustedProxyHeader_HonorsForwardedProto verifies +// that setting TrustedProxyHeader=true honors X-Forwarded-Proto, preserving +// existing behavior for operators behind a trusted terminating proxy. +func TestBundle_RequireHTTPS_TrustedProxyHeader_HonorsForwardedProto(t *testing.T) { + cfg := DefaultConfig() + cfg.SecretKey = []byte("this-is-a-32-byte-secret-key!!!!") + cfg.ServiceName = "test-service" + cfg.Issuer = "test-issuer" + cfg.Audience = "test-audience" + cfg.RequireHTTPS = true + cfg.TrustedProxyHeader = true + b := NewBundle(cfg) + + token, err := b.GenerateToken("svc-123", "test-service", nil) + if err != nil { + t.Fatalf("generate: %v", err) + } + + handlerCalled := false + inner := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + handlerCalled = true + w.WriteHeader(http.StatusOK) + }) + handler := b.HTTPMiddleware(inner) + + req, _ := http.NewRequest(http.MethodGet, "/api/data", nil) + req.Header.Set("X-Forwarded-Proto", "https") + req.Header.Set("Authorization", "Bearer "+token) + w := newResponseRecorder() + handler.ServeHTTP(w, req) + + if w.Code != http.StatusOK { + t.Errorf("expected 200, got %d", w.Code) + } + if !handlerCalled { + t.Error("expected handler to be called when trusted proxy header indicates https") + } +} + +// TestBundle_RequireHTTPS_TrustedProxyHeader_StillRejectsPlainHTTP verifies +// that enabling TrustedProxyHeader doesn't disable enforcement outright. +func TestBundle_RequireHTTPS_TrustedProxyHeader_StillRejectsPlainHTTP(t *testing.T) { + cfg := DefaultConfig() + cfg.SecretKey = []byte("this-is-a-32-byte-secret-key!!!!") + cfg.ServiceName = "test-service" + cfg.Issuer = "test-issuer" + cfg.Audience = "test-audience" + cfg.RequireHTTPS = true + cfg.TrustedProxyHeader = true + b := NewBundle(cfg) + + inner := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + }) + handler := b.HTTPMiddleware(inner) + + req, _ := http.NewRequest(http.MethodGet, "/api/data", nil) + // No X-Forwarded-Proto and no TLS. + w := newResponseRecorder() + handler.ServeHTTP(w, req) + + if w.Code != http.StatusBadRequest { + t.Errorf("expected 400 (HTTPS required), got %d", w.Code) + } +} diff --git a/bundles/redis/bundle.go b/bundles/redis/bundle.go index f18f173..e425165 100644 --- a/bundles/redis/bundle.go +++ b/bundles/redis/bundle.go @@ -80,6 +80,7 @@ import ( "fmt" "net/url" "os" + "sync/atomic" "time" "github.com/redis/go-redis/v9" @@ -597,6 +598,7 @@ func (l *DistributedLock) Unlock(ctx context.Context) error { type RateLimiter struct { client redis.UniversalClient prefix string + seq atomic.Uint64 } // NewRateLimiter creates a new Redis-based rate limiter. @@ -607,11 +609,26 @@ func (b *Bundle) NewRateLimiter(prefix string) *RateLimiter { } } +// rateLimitMember builds a unique ZSET member for a rate-limit request whose +// score is the request timestamp. The timestamp alone is not safe to use as +// the member: ZADD treats the member as the entry's identity, so two calls +// that land on the same timestamp (routine under concurrent load, since +// UnixNano has finite resolution) would collapse into a single ZSET entry +// and silently undercount requests. Appending the process id and a +// monotonically increasing per-process sequence number keeps every call's +// member distinct, both within this process and across replicas, while the +// score (now) still drives ZREMRANGEBYSCORE window trimming and ZCARD +// counting. +func rateLimitMember(now time.Time, pid int, seq uint64) string { + return fmt.Sprintf("%d-%d-%d", now.UnixNano(), pid, seq) +} + // Allow checks if a request is allowed under the rate limit using atomic Lua script. func (r *RateLimiter) Allow(ctx context.Context, key string, limit int, window time.Duration) (bool, error) { now := time.Now() windowStart := now.Add(-window) fullKey := fmt.Sprintf("%s:%s", r.prefix, key) + member := rateLimitMember(now, os.Getpid(), r.seq.Add(1)) // Atomic rate limiting with Lua script script := ` @@ -620,6 +637,7 @@ func (r *RateLimiter) Allow(ctx context.Context, key string, limit int, window t local window_start = tonumber(ARGV[2]) local limit = tonumber(ARGV[3]) local window_seconds = tonumber(ARGV[4]) + local member = ARGV[5] -- Remove expired entries redis.call('ZREMRANGEBYSCORE', key, 0, window_start) @@ -630,8 +648,8 @@ func (r *RateLimiter) Allow(ctx context.Context, key string, limit int, window t return 0 -- Denied end - -- Add current request and set expiry - redis.call('ZADD', key, now, now) + -- Add current request (unique member, score = timestamp) and set expiry + redis.call('ZADD', key, now, member) redis.call('EXPIRE', key, math.ceil(window_seconds)) return 1 -- Allowed @@ -642,6 +660,7 @@ func (r *RateLimiter) Allow(ctx context.Context, key string, limit int, window t windowStart.UnixNano(), limit, window.Seconds(), + member, ).Result() if err != nil { diff --git a/bundles/redis/bundle_test.go b/bundles/redis/bundle_test.go index a9098d1..08746dc 100644 --- a/bundles/redis/bundle_test.go +++ b/bundles/redis/bundle_test.go @@ -4,6 +4,8 @@ import ( "context" stderrors "errors" "fmt" + "sync" + "sync/atomic" "testing" "time" @@ -409,3 +411,118 @@ func TestRedisHealthCheck_Readiness_Success(t *testing.T) { t.Errorf("expected Readiness to succeed, got: %v", err) } } + +// --- RateLimiter --- + +// TestRateLimitMember_UniqueForSameTimestamp is the deterministic regression +// test for the undercounting bug: Allow() itself calls time.Now() internally +// (it has no injectable clock), so two calls landing on the exact same +// nanosecond can't be reliably reproduced through Allow() in a unit test. +// Instead this exercises rateLimitMember directly with a fixed timestamp, +// which is exactly the scenario that used to collapse two ZADD entries into +// one: with the old `ZADD key now now` scheme, member == score, so two calls +// sharing a timestamp shared a member too. +func TestRateLimitMember_UniqueForSameTimestamp(t *testing.T) { + now := time.Unix(0, 1_700_000_000_000_000_000) + + m1 := rateLimitMember(now, 1234, 1) + m2 := rateLimitMember(now, 1234, 2) + + if m1 == m2 { + t.Fatalf("expected distinct members for the same timestamp, got %q twice", m1) + } + + // Different processes (e.g. two service replicas) must also stay distinct + // even if their sequence counters happen to line up. + m3 := rateLimitMember(now, 5678, 1) + if m3 == m1 { + t.Fatalf("expected distinct members across pids, got %q twice", m1) + } +} + +// TestRateLimiter_Allow_EnforcesLimit is a live-Redis regression test +// confirming that Allow() still enforces the configured limit (i.e. the +// member-uniqueness fix didn't break ZCARD-based counting, which keys off +// score/window trimming rather than the member value). +func TestRateLimiter_Allow_EnforcesLimit(t *testing.T) { + client := newLiveTestClient(t) + ctx := context.Background() + + limiter := &RateLimiter{ + client: client, + prefix: fmt.Sprintf("test:ratelimit:%d", time.Now().UnixNano()), + } + key := "user-1" + fullKey := fmt.Sprintf("%s:%s", limiter.prefix, key) + defer client.Del(ctx, fullKey) + + const limit = 3 + for i := 0; i < limit; i++ { + allowed, err := limiter.Allow(ctx, key, limit, time.Minute) + if err != nil { + t.Fatalf("unexpected error on request %d: %v", i, err) + } + if !allowed { + t.Fatalf("expected request %d to be allowed", i) + } + } + + allowed, err := limiter.Allow(ctx, key, limit, time.Minute) + if err != nil { + t.Fatalf("unexpected error on over-limit request: %v", err) + } + if allowed { + t.Fatal("expected request beyond the limit to be denied") + } +} + +// TestRateLimiter_Allow_ConcurrentDistinctMembers fires many concurrent Allow +// calls at a high limit and verifies the underlying ZSET ends up with one +// member per accepted call. Under the old `ZADD key now now` scheme, +// concurrent calls landing on the same nanosecond would silently collapse +// into fewer ZSET members than calls made, undercounting usage. +func TestRateLimiter_Allow_ConcurrentDistinctMembers(t *testing.T) { + client := newLiveTestClient(t) + ctx := context.Background() + + limiter := &RateLimiter{ + client: client, + prefix: fmt.Sprintf("test:ratelimit-concurrent:%d", time.Now().UnixNano()), + } + key := "burst" + fullKey := fmt.Sprintf("%s:%s", limiter.prefix, key) + defer client.Del(ctx, fullKey) + + const calls = 50 + const limit = calls * 2 // generous limit: every call should be allowed + + var wg sync.WaitGroup + var allowedCount int64 + for i := 0; i < calls; i++ { + wg.Add(1) + go func() { + defer wg.Done() + allowed, err := limiter.Allow(ctx, key, limit, time.Minute) + if err != nil { + t.Errorf("unexpected error: %v", err) + return + } + if allowed { + atomic.AddInt64(&allowedCount, 1) + } + }() + } + wg.Wait() + + if allowedCount != calls { + t.Fatalf("expected all %d calls to be allowed, got %d", calls, allowedCount) + } + + card, err := client.ZCard(ctx, fullKey).Result() + if err != nil { + t.Fatalf("ZCard failed: %v", err) + } + if card != calls { + t.Errorf("expected %d distinct ZSET members (one per allowed call), got %d — members collapsed under concurrent load", calls, card) + } +} diff --git a/config/base.go b/config/base.go index fb56eaa..0dc225f 100644 --- a/config/base.go +++ b/config/base.go @@ -282,12 +282,11 @@ func (c *BaseConfig) IsProduction() bool { } // ShouldEnableReflection returns true if gRPC reflection should be enabled. -// By default, reflection is enabled in development unless explicitly disabled. +// Reflection exposes the full service schema and must be explicitly opted +// into via EnableReflection (env ENABLE_REFLECTION) — it is never enabled +// implicitly by environment, including in development. func (c *BaseConfig) ShouldEnableReflection() bool { - if c.EnableReflection { - return true - } - return c.IsDevelopment() + return c.EnableReflection } // Validator is an interface for configuration structs that can validate themselves. diff --git a/config/base_test.go b/config/base_test.go index f9f5e4d..8c1a47b 100644 --- a/config/base_test.go +++ b/config/base_test.go @@ -183,7 +183,7 @@ func TestBaseConfig_ShouldEnableReflection(t *testing.T) { explicitEnable bool expectedEnabled bool }{ - {"development implicit", "development", false, true}, + {"development implicit", "development", false, false}, {"production implicit", "production", false, false}, {"production explicit", "production", true, true}, {"development explicit", "development", true, true}, diff --git a/framework/app.go b/framework/app.go index 5d3668e..89db954 100644 --- a/framework/app.go +++ b/framework/app.go @@ -858,7 +858,7 @@ func (a *App) startHTTPServer(ctx context.Context) error { // handleHealth handles the /health endpoint. func (a *App) handleHealth(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - status := a.healthRegistry.CheckHealth(ctx) + status := a.healthRegistry.CheckHealth(ctx).Redacted() w.Header().Set("Content-Type", "application/json") w.WriteHeader(status.HTTPStatus()) @@ -873,7 +873,7 @@ func (a *App) handleHealth(w http.ResponseWriter, r *http.Request) { // handleReady handles the /health/ready endpoint. func (a *App) handleReady(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - status := a.healthRegistry.CheckReadiness(ctx) + status := a.healthRegistry.CheckReadiness(ctx).Redacted() w.Header().Set("Content-Type", "application/json") w.WriteHeader(status.HTTPStatus()) @@ -888,7 +888,7 @@ func (a *App) handleReady(w http.ResponseWriter, r *http.Request) { // handleLive handles the /health/live endpoint. func (a *App) handleLive(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - status := a.healthRegistry.CheckLiveness(ctx) + status := a.healthRegistry.CheckLiveness(ctx).Redacted() w.Header().Set("Content-Type", "application/json") w.WriteHeader(status.HTTPStatus()) diff --git a/framework/app_http_test.go b/framework/app_http_test.go index d6cfaf5..1774f2c 100644 --- a/framework/app_http_test.go +++ b/framework/app_http_test.go @@ -3,14 +3,17 @@ package framework import ( "context" "encoding/json" + "errors" "net/http" "net/http/httptest" + "strings" "testing" "time" "google.golang.org/grpc" "github.com/datariot/forge/config" + forgeHealth "github.com/datariot/forge/health" ) // TestApp_HandleReady_NotReady tests readiness when service not marked ready @@ -52,6 +55,64 @@ func TestApp_HandleReady_NotReady(t *testing.T) { } } +// TestApp_HealthEndpoints_RedactErrorDetail verifies that a failing +// dependency check's raw error (which can embed internal hostnames, IPs, +// and ports) never reaches the unauthenticated /health and /health/ready +// HTTP responses, while the overall unhealthy verdict is still reported. +func TestApp_HealthEndpoints_RedactErrorDetail(t *testing.T) { + cfg := config.DefaultBaseConfig() + cfg.ServiceName = "redact-test" + cfg.GRPCAddr = ":0" + cfg.HTTPAddr = ":0" + + app, err := New(WithConfig(&cfg)) + if err != nil { + t.Fatalf("failed to create app: %v", err) + } + + const leakyErr = "dial tcp 10.0.1.5:5432: connect: connection refused" + leaky := forgeHealth.NewAlwaysUnhealthyCheck("postgres", errors.New(leakyErr)) + if err := app.healthRegistry.Register(leaky, forgeHealth.DefaultCheckConfig("postgres")); err != nil { + t.Fatalf("failed to register health check: %v", err) + } + + cases := []struct { + name string + path string + handler func(http.ResponseWriter, *http.Request) + }{ + {"health", "/health", app.handleHealth}, + {"ready", "/health/ready", app.handleReady}, + {"live", "/health/live", app.handleLive}, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + req := httptest.NewRequest(http.MethodGet, tc.path, nil) + w := httptest.NewRecorder() + tc.handler(w, req) + + resp := w.Result() + if resp.StatusCode != http.StatusServiceUnavailable { + t.Errorf("expected 503 for unhealthy required check, got %d", resp.StatusCode) + } + + body := w.Body.String() + if strings.Contains(body, "10.0.1.5:5432") { + t.Errorf("expected response body to not leak raw dependency error, got: %s", body) + } + + var parsed map[string]interface{} + if err := json.Unmarshal(w.Body.Bytes(), &parsed); err != nil { + t.Fatalf("failed to parse JSON response: %v", err) + } + if parsed["status"] == "healthy" { + t.Error("expected overall status to reflect the unhealthy required check") + } + }) + } +} + // TestApp_GetterMethods tests Config(), Logger(), HealthRegistry() getters func TestApp_GetterMethods(t *testing.T) { cfg := config.DefaultBaseConfig() diff --git a/framework/http.go b/framework/http.go index afb1b2a..7334b15 100644 --- a/framework/http.go +++ b/framework/http.go @@ -13,6 +13,7 @@ package framework import ( + "crypto/subtle" "fmt" "net/http" "net/http/pprof" @@ -38,6 +39,12 @@ type HTTPServerConfig struct { MetricsPath string `yaml:"metrics_path" env:"METRICS_PATH"` HealthPathPrefix string `yaml:"health_path_prefix" env:"HEALTH_PATH_PREFIX"` + // MetricsBasicAuthUser and MetricsBasicAuthPass, when both set, gate the + // metrics endpoint behind HTTP Basic Auth. Left empty (the default) the + // endpoint is unauthenticated, matching prior behavior. + MetricsBasicAuthUser string `yaml:"metrics_basic_auth_user" env:"METRICS_BASIC_AUTH_USER"` + MetricsBasicAuthPass string `yaml:"metrics_basic_auth_pass" env:"METRICS_BASIC_AUTH_PASS"` + // Request logging EnableRequestLogging bool `yaml:"enable_request_logging" env:"ENABLE_REQUEST_LOGGING"` } @@ -201,15 +208,26 @@ func (b *HTTPServerBuilder) registerMetricsEndpoint() { }, ) + authEnabled := b.config.MetricsBasicAuthUser != "" && b.config.MetricsBasicAuthPass != "" + if authEnabled { + handler = b.basicAuthMiddleware(handler, b.config.MetricsBasicAuthUser, b.config.MetricsBasicAuthPass) + } + b.mux.Handle(path, handler) // Security consideration logging - if b.app.config.IsProduction() { + switch { + case authEnabled: + b.logger.Info(). + Str("path", path). + Str("environment", b.app.config.AppEnv). + Msg("Metrics endpoint registered with basic auth") + case b.app.config.IsProduction(): b.logger.Warn(). Str("path", path). Str("environment", b.app.config.AppEnv). - Msg("Metrics endpoint registered in production - ensure proper network security and access controls") - } else { + Msg("Metrics endpoint registered in production without authentication - isolate it at the network layer or set MetricsBasicAuthUser/MetricsBasicAuthPass") + default: b.logger.Info(). Str("path", path). Str("environment", b.app.config.AppEnv). @@ -217,21 +235,37 @@ func (b *HTTPServerBuilder) registerMetricsEndpoint() { } } +// basicAuthMiddleware guards next behind HTTP Basic Auth, comparing +// credentials in constant time to avoid leaking their length or contents +// via timing. +func (b *HTTPServerBuilder) basicAuthMiddleware(next http.Handler, user, pass string) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + suppliedUser, suppliedPass, ok := r.BasicAuth() + if !ok || !constantTimeEqual(suppliedUser, user) || !constantTimeEqual(suppliedPass, pass) { + w.Header().Set("WWW-Authenticate", `Basic realm="metrics"`) + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } + next.ServeHTTP(w, r) + }) +} + +// constantTimeEqual reports whether a and b are equal without leaking +// timing information about where they first differ. +func constantTimeEqual(a, b string) bool { + return subtle.ConstantTimeCompare([]byte(a), []byte(b)) == 1 +} + // registerPprofEndpoints registers debug/pprof endpoints when enabled. func (b *HTTPServerBuilder) registerPprofEndpoints() { - // SECURITY: Never enable pprof in production - if b.app.config.IsProduction() { - b.logger.Error(). - Str("environment", b.app.config.AppEnv). - Msg("SECURITY ERROR: Pprof endpoints cannot be enabled in production environment") - return - } - - // Additional warning for non-development environments + // SECURITY: Pprof is only ever served in development, regardless of the + // EnablePprof toggle - staging and production are both blocked since + // pprof exposes memory contents, goroutine stacks, and other internals. if !b.app.config.IsDevelopment() { b.logger.Warn(). Str("environment", b.app.config.AppEnv). - Msg("WARNING: Pprof endpoints enabled in non-development environment - ensure network security") + Msg("EnablePprof is set but ignored - pprof endpoints are only served in the development environment") + return } b.mux.HandleFunc("/debug/pprof/", pprof.Index) @@ -336,8 +370,10 @@ func (b *HTTPServerBuilder) corsMiddleware(next http.Handler) http.Handler { // Safe to use wildcard only when credentials are disabled w.Header().Set("Access-Control-Allow-Origin", "*") } else { - // Use specific origin when credentials are enabled or specific origins are configured + // Use specific origin when credentials are enabled or specific origins are configured. + // The response varies by the reflected Origin, so caches must key on it too. w.Header().Set("Access-Control-Allow-Origin", origin) + w.Header().Add("Vary", "Origin") } } diff --git a/framework/http_test.go b/framework/http_test.go index c2dfae1..9513b0b 100644 --- a/framework/http_test.go +++ b/framework/http_test.go @@ -4,6 +4,8 @@ import ( "net/http" "net/http/httptest" "testing" + + "github.com/datariot/forge/config" ) // --- HTTPServerConfig.Validate tests --- @@ -303,6 +305,239 @@ func TestCORSMiddleware_NoOriginHeader(t *testing.T) { } } +func TestCORSMiddleware_ReflectedOrigin_SetsVaryOrigin(t *testing.T) { + builder := &HTTPServerBuilder{ + config: HTTPServerConfig{ + EnableCORS: true, + CORSOrigins: []string{"https://example.com"}, + CORSMethods: []string{"GET"}, + CORSHeaders: []string{"Content-Type"}, + CORSCredentials: false, + }, + } + + inner := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + }) + handler := builder.corsMiddleware(inner) + + req := httptest.NewRequest(http.MethodGet, "/api", nil) + req.Header.Set("Origin", "https://example.com") + w := httptest.NewRecorder() + handler.ServeHTTP(w, req) + + if !containsValue(w.Header().Values("Vary"), "Origin") { + t.Errorf("expected Vary header to include Origin, got %v", w.Header().Values("Vary")) + } +} + +func TestCORSMiddleware_ReflectedOrigin_AppendsToExistingVary(t *testing.T) { + builder := &HTTPServerBuilder{ + config: HTTPServerConfig{ + EnableCORS: true, + CORSOrigins: []string{"https://example.com"}, + CORSMethods: []string{"GET"}, + CORSHeaders: []string{"Content-Type"}, + CORSCredentials: false, + }, + } + + inner := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Add("Vary", "Accept-Encoding") + w.WriteHeader(http.StatusOK) + }) + handler := builder.corsMiddleware(inner) + + req := httptest.NewRequest(http.MethodGet, "/api", nil) + req.Header.Set("Origin", "https://example.com") + w := httptest.NewRecorder() + handler.ServeHTTP(w, req) + + vary := w.Header().Values("Vary") + if !containsValue(vary, "Origin") || !containsValue(vary, "Accept-Encoding") { + t.Errorf("expected Vary to contain both Origin and Accept-Encoding, got %v", vary) + } +} + +func TestCORSMiddleware_WildcardOrigin_NoVaryHeader(t *testing.T) { + builder := &HTTPServerBuilder{ + config: HTTPServerConfig{ + EnableCORS: true, + CORSOrigins: []string{"*"}, + CORSMethods: []string{"GET"}, + CORSHeaders: []string{"Content-Type"}, + CORSCredentials: false, + }, + } + + inner := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + }) + handler := builder.corsMiddleware(inner) + + req := httptest.NewRequest(http.MethodGet, "/api", nil) + req.Header.Set("Origin", "https://any.example.com") + w := httptest.NewRecorder() + handler.ServeHTTP(w, req) + + if vary := w.Header().Get("Vary"); vary != "" { + t.Errorf("expected no Vary header for wildcard origin, got %q", vary) + } +} + +func containsValue(values []string, target string) bool { + for _, v := range values { + if v == target { + return true + } + } + return false +} + +// --- Metrics basic auth tests --- + +func newTestBuilder(t *testing.T, env string, httpCfg HTTPServerConfig) *HTTPServerBuilder { + t.Helper() + cfg := config.DefaultBaseConfig() + cfg.ServiceName = "http-test" + cfg.AppEnv = env + + app, err := New(WithConfig(&cfg)) + if err != nil { + t.Fatalf("failed to create app: %v", err) + } + + return NewHTTPServerBuilder(app, httpCfg) +} + +func TestRegisterMetricsEndpoint_OpenWhenAuthUnset(t *testing.T) { + builder := newTestBuilder(t, "development", DefaultHTTPServerConfig()) + builder.registerMetricsEndpoint() + + req := httptest.NewRequest(http.MethodGet, "/metrics", nil) + w := httptest.NewRecorder() + builder.mux.ServeHTTP(w, req) + + if w.Code != http.StatusOK { + t.Errorf("expected metrics endpoint to be open when credentials are unset, got %d", w.Code) + } +} + +func TestRegisterMetricsEndpoint_RejectsWrongCredentials(t *testing.T) { + httpCfg := DefaultHTTPServerConfig() + httpCfg.MetricsBasicAuthUser = "prom" + httpCfg.MetricsBasicAuthPass = "s3cret" + + builder := newTestBuilder(t, "development", httpCfg) + builder.registerMetricsEndpoint() + + req := httptest.NewRequest(http.MethodGet, "/metrics", nil) + req.SetBasicAuth("prom", "wrong-password") + w := httptest.NewRecorder() + builder.mux.ServeHTTP(w, req) + + if w.Code != http.StatusUnauthorized { + t.Errorf("expected 401 for wrong credentials, got %d", w.Code) + } +} + +func TestRegisterMetricsEndpoint_RejectsMissingCredentials(t *testing.T) { + httpCfg := DefaultHTTPServerConfig() + httpCfg.MetricsBasicAuthUser = "prom" + httpCfg.MetricsBasicAuthPass = "s3cret" + + builder := newTestBuilder(t, "development", httpCfg) + builder.registerMetricsEndpoint() + + req := httptest.NewRequest(http.MethodGet, "/metrics", nil) + w := httptest.NewRecorder() + builder.mux.ServeHTTP(w, req) + + if w.Code != http.StatusUnauthorized { + t.Errorf("expected 401 with no credentials, got %d", w.Code) + } +} + +func TestRegisterMetricsEndpoint_AcceptsCorrectCredentials(t *testing.T) { + httpCfg := DefaultHTTPServerConfig() + httpCfg.MetricsBasicAuthUser = "prom" + httpCfg.MetricsBasicAuthPass = "s3cret" + + builder := newTestBuilder(t, "development", httpCfg) + builder.registerMetricsEndpoint() + + req := httptest.NewRequest(http.MethodGet, "/metrics", nil) + req.SetBasicAuth("prom", "s3cret") + w := httptest.NewRecorder() + builder.mux.ServeHTTP(w, req) + + if w.Code != http.StatusOK { + t.Errorf("expected 200 for correct credentials, got %d", w.Code) + } +} + +func TestConstantTimeEqual(t *testing.T) { + if !constantTimeEqual("secret", "secret") { + t.Error("expected equal strings to compare equal") + } + if constantTimeEqual("secret", "different") { + t.Error("expected different strings to compare unequal") + } + if constantTimeEqual("secret", "secretlonger") { + t.Error("expected different-length strings to compare unequal") + } +} + +// --- Pprof environment gating tests --- + +func TestRegisterPprofEndpoints_BlockedInStaging(t *testing.T) { + httpCfg := DefaultHTTPServerConfig() + builder := newTestBuilder(t, "staging", httpCfg) + builder.app.config.EnablePprof = true + + builder.registerPprofEndpoints() + + req := httptest.NewRequest(http.MethodGet, "/debug/pprof/", nil) + w := httptest.NewRecorder() + builder.mux.ServeHTTP(w, req) + + if w.Code == http.StatusOK { + t.Error("expected pprof endpoints to be blocked in staging even with EnablePprof=true") + } +} + +func TestRegisterPprofEndpoints_BlockedInProduction(t *testing.T) { + httpCfg := DefaultHTTPServerConfig() + builder := newTestBuilder(t, "production", httpCfg) + builder.app.config.EnablePprof = true + + builder.registerPprofEndpoints() + + req := httptest.NewRequest(http.MethodGet, "/debug/pprof/", nil) + w := httptest.NewRecorder() + builder.mux.ServeHTTP(w, req) + + if w.Code == http.StatusOK { + t.Error("expected pprof endpoints to be blocked in production even with EnablePprof=true") + } +} + +func TestRegisterPprofEndpoints_AllowedInDevelopment(t *testing.T) { + httpCfg := DefaultHTTPServerConfig() + builder := newTestBuilder(t, "development", httpCfg) + builder.app.config.EnablePprof = true + + builder.registerPprofEndpoints() + + req := httptest.NewRequest(http.MethodGet, "/debug/pprof/", nil) + w := httptest.NewRecorder() + builder.mux.ServeHTTP(w, req) + + if w.Code != http.StatusOK { + t.Errorf("expected pprof endpoints reachable in development, got %d", w.Code) + } +} + // --- promLogAdapter tests --- func TestPromLogAdapter_Println(t *testing.T) { diff --git a/health/check.go b/health/check.go index d82d9e4..ee8163b 100644 --- a/health/check.go +++ b/health/check.go @@ -176,6 +176,18 @@ func (r CheckResult) IsHealthy() bool { return r.Status == StatusHealthy } +// Redacted returns a copy of the CheckResult with the raw Error detail +// removed. Error strings from dependency checks (e.g. database or cache +// connectivity failures) can embed internal topology such as hostnames, +// IPs, and ports, so they must not be exposed over unauthenticated +// interfaces like the public HTTP health endpoints. The check name and +// Status remain, which is all an external caller needs; the full detail +// is still available internally (e.g. to the background runner's logs). +func (r CheckResult) Redacted() CheckResult { + r.Error = "" + return r +} + // BasicCheck provides a simple implementation of Check interface. type BasicCheck struct { config CheckConfig diff --git a/health/check_test.go b/health/check_test.go index c86c53c..4f636de 100644 --- a/health/check_test.go +++ b/health/check_test.go @@ -184,6 +184,47 @@ func TestNewCheckResult_Unhealthy(t *testing.T) { } } +// --- CheckResult.Redacted tests --- + +func TestCheckResult_Redacted_StripsError(t *testing.T) { + result := NewCheckResult("postgres", true, 10*time.Millisecond, errors.New("dial tcp 10.0.1.5:5432: connect: connection refused")) + + redacted := result.Redacted() + + if redacted.Error != "" { + t.Errorf("expected redacted Error to be empty, got %q", redacted.Error) + } + if redacted.Name != result.Name { + t.Errorf("expected Name to be preserved, got %q", redacted.Name) + } + if redacted.Status != result.Status { + t.Errorf("expected Status to be preserved, got %q", redacted.Status) + } + if redacted.Required != result.Required { + t.Error("expected Required to be preserved") + } + if redacted.Duration != result.Duration { + t.Errorf("expected Duration to be preserved, got %q", redacted.Duration) + } + // Original result must be unaffected. + if result.Error == "" { + t.Error("expected original CheckResult.Error to remain populated") + } +} + +func TestCheckResult_Redacted_HealthyUnaffected(t *testing.T) { + result := NewCheckResult("db", true, time.Millisecond, nil) + + redacted := result.Redacted() + + if redacted.Message != "OK" { + t.Errorf("expected message 'OK' preserved, got %q", redacted.Message) + } + if !redacted.IsHealthy() { + t.Error("expected redacted healthy result to remain healthy") + } +} + // --- DefaultCheckConfig tests --- func TestDefaultCheckConfig(t *testing.T) { diff --git a/health/status.go b/health/status.go index 58f5285..dc1dc56 100644 --- a/health/status.go +++ b/health/status.go @@ -62,6 +62,25 @@ func (h HealthStatus) String() string { return string(data) } +// Redacted returns a copy of the HealthStatus safe for exposure over +// unauthenticated interfaces such as the public HTTP health endpoints. +// Every entry in Details has its raw error detail stripped via +// CheckResult.Redacted, while the overall Status, Message, and per-check +// name/status/duration/required metadata are preserved. +func (h HealthStatus) Redacted() HealthStatus { + if len(h.Details) == 0 { + return h + } + + redacted := make(map[string]CheckResult, len(h.Details)) + for name, result := range h.Details { + redacted[name] = result.Redacted() + } + h.Details = redacted + + return h +} + // FailedChecks returns a slice of check results that failed. func (h HealthStatus) FailedChecks() []CheckResult { var failed []CheckResult diff --git a/health/status_test.go b/health/status_test.go index 7c17905..4b25717 100644 --- a/health/status_test.go +++ b/health/status_test.go @@ -1,6 +1,7 @@ package health import ( + "errors" "strings" "testing" "time" @@ -249,3 +250,45 @@ func TestStatusResponse_Creation(t *testing.T) { t.Errorf("Expected message 'test message', got %s", resp.Message) } } + +// --- HealthStatus.Redacted tests --- + +func TestHealthStatus_Redacted_StripsCheckErrors(t *testing.T) { + status := HealthStatus{ + Status: StatusUnhealthy, + Message: "One or more checks failed", + Details: map[string]CheckResult{ + "postgres": NewCheckResult("postgres", true, time.Millisecond, errors.New("dial tcp 10.0.1.5:5432: connect: connection refused")), + "cache": NewCheckResult("cache", false, time.Millisecond, nil), + }, + } + + redacted := status.Redacted() + + if redacted.Status != status.Status { + t.Errorf("expected overall Status preserved, got %q", redacted.Status) + } + if redacted.Message != status.Message { + t.Errorf("expected overall Message preserved, got %q", redacted.Message) + } + + for name, result := range redacted.Details { + if result.Error != "" { + t.Errorf("expected redacted Details[%q].Error to be empty, got %q", name, result.Error) + } + } + + if status.Details["postgres"].Error == "" { + t.Error("expected original status Details to remain unaffected") + } +} + +func TestHealthStatus_Redacted_NoDetails(t *testing.T) { + status := NewHealthyStatus("") + + redacted := status.Redacted() + + if len(redacted.Details) != 0 { + t.Errorf("expected no details, got %d", len(redacted.Details)) + } +} From 52985ca5cdbdc60a44092265bb9e67ad84f655fa Mon Sep 17 00:00:00 2001 From: David Allen Date: Mon, 6 Jul 2026 18:48:04 -0600 Subject: [PATCH 3/3] chore: go mod tidy examples for bumped grpc/otel deps Co-Authored-By: Claude Fable 5 --- examples/config-service/go.mod | 26 +++++++------- examples/config-service/go.sum | 58 +++++++++++++++--------------- examples/httpclient-service/go.mod | 26 +++++++------- examples/httpclient-service/go.sum | 58 +++++++++++++++--------------- examples/jwt-service/go.mod | 26 +++++++------- examples/jwt-service/go.sum | 58 +++++++++++++++--------------- examples/postgresql-service/go.mod | 26 +++++++------- examples/postgresql-service/go.sum | 58 +++++++++++++++--------------- examples/prometheus-service/go.mod | 26 +++++++------- examples/prometheus-service/go.sum | 58 +++++++++++++++--------------- examples/redis-service/go.mod | 26 +++++++------- examples/redis-service/go.sum | 58 +++++++++++++++--------------- examples/simple-service/go.mod | 26 +++++++------- examples/simple-service/go.sum | 58 +++++++++++++++--------------- 14 files changed, 301 insertions(+), 287 deletions(-) diff --git a/examples/config-service/go.mod b/examples/config-service/go.mod index 450766e..6cffc67 100644 --- a/examples/config-service/go.mod +++ b/examples/config-service/go.mod @@ -25,24 +25,24 @@ require ( github.com/prometheus/otlptranslator v0.0.2 // indirect github.com/prometheus/procfs v0.17.0 // indirect github.com/rs/zerolog v1.34.0 // indirect - go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/otel v1.44.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect go.opentelemetry.io/otel/exporters/prometheus v0.60.0 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/sdk v1.38.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.44.0 // indirect + go.opentelemetry.io/otel/sdk v1.44.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.44.0 // indirect + go.opentelemetry.io/otel/trace v1.44.0 // indirect go.opentelemetry.io/proto/otlp v1.7.1 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/net v0.43.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/text v0.28.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect - google.golang.org/grpc v1.75.1 // indirect - google.golang.org/protobuf v1.36.8 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/sys v0.45.0 // indirect + golang.org/x/text v0.32.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.10 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/examples/config-service/go.sum b/examples/config-service/go.sum index 2d87ce3..0b24e81 100644 --- a/examples/config-service/go.sum +++ b/examples/config-service/go.sum @@ -53,17 +53,17 @@ github.com/prometheus/otlptranslator v0.0.2 h1:+1CdeLVrRQ6Psmhnobldo0kTp96Rj80DR github.com/prometheus/otlptranslator v0.0.2/go.mod h1:P8AwMgdD7XEr6QRUJ2QWLpiAZTgTE2UYgjlu3svompI= github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0= github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= -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/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -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.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= +go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 h1:vl9obrcoWVKp/lwl8tRE33853I8Xru9HFbw/skNeLs8= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0/go.mod h1:GAXRxmLJcVM3u22IjTg74zWBrRCKq8BnOqUVLodpcpw= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= @@ -72,39 +72,41 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4D go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= go.opentelemetry.io/otel/exporters/prometheus v0.60.0 h1:cGtQxGvZbnrWdC2GyjZi0PDKVSLWP/Jocix3QWfXtbo= go.opentelemetry.io/otel/exporters/prometheus v0.60.0/go.mod h1:hkd1EekxNo69PTV4OWFGZcKQiIqg0RfuWExcPKFvepk= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= +go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/metric/x v0.66.0 h1:YkCrx1zLOChi9ZcZ6euupOcsgzbVlec7D/xoEU1+cTA= +go.opentelemetry.io/otel/metric/x v0.66.0/go.mod h1:d1+BDj9t96do0/1LoU1ayfCv79ZgNE41qbhBvnMOBZk= +go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= +go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= +go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= +go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= +golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY= -google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= -google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI= -google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= -google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= -google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/examples/httpclient-service/go.mod b/examples/httpclient-service/go.mod index fe8f77b..334b043 100644 --- a/examples/httpclient-service/go.mod +++ b/examples/httpclient-service/go.mod @@ -27,23 +27,23 @@ require ( github.com/prometheus/otlptranslator v0.0.2 // indirect github.com/prometheus/procfs v0.17.0 // indirect github.com/rs/zerolog v1.34.0 // indirect - go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/otel v1.44.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect go.opentelemetry.io/otel/exporters/prometheus v0.60.0 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/sdk v1.38.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.44.0 // indirect + go.opentelemetry.io/otel/sdk v1.44.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.44.0 // indirect + go.opentelemetry.io/otel/trace v1.44.0 // indirect go.opentelemetry.io/proto/otlp v1.7.1 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/net v0.43.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/text v0.28.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect - google.golang.org/grpc v1.75.1 // indirect - google.golang.org/protobuf v1.36.8 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/sys v0.45.0 // indirect + golang.org/x/text v0.32.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.10 // indirect ) diff --git a/examples/httpclient-service/go.sum b/examples/httpclient-service/go.sum index 04c466a..df4c13c 100644 --- a/examples/httpclient-service/go.sum +++ b/examples/httpclient-service/go.sum @@ -54,8 +54,8 @@ github.com/prometheus/otlptranslator v0.0.2 h1:+1CdeLVrRQ6Psmhnobldo0kTp96Rj80DR github.com/prometheus/otlptranslator v0.0.2/go.mod h1:P8AwMgdD7XEr6QRUJ2QWLpiAZTgTE2UYgjlu3svompI= github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0= github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= -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/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= @@ -65,10 +65,10 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -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.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= +go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 h1:vl9obrcoWVKp/lwl8tRE33853I8Xru9HFbw/skNeLs8= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0/go.mod h1:GAXRxmLJcVM3u22IjTg74zWBrRCKq8BnOqUVLodpcpw= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= @@ -77,39 +77,41 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4D go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= go.opentelemetry.io/otel/exporters/prometheus v0.60.0 h1:cGtQxGvZbnrWdC2GyjZi0PDKVSLWP/Jocix3QWfXtbo= go.opentelemetry.io/otel/exporters/prometheus v0.60.0/go.mod h1:hkd1EekxNo69PTV4OWFGZcKQiIqg0RfuWExcPKFvepk= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= +go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/metric/x v0.66.0 h1:YkCrx1zLOChi9ZcZ6euupOcsgzbVlec7D/xoEU1+cTA= +go.opentelemetry.io/otel/metric/x v0.66.0/go.mod h1:d1+BDj9t96do0/1LoU1ayfCv79ZgNE41qbhBvnMOBZk= +go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= +go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= +go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= +go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= +golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY= -google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= -google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI= -google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= -google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= -google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/examples/jwt-service/go.mod b/examples/jwt-service/go.mod index 414219c..0aeab62 100644 --- a/examples/jwt-service/go.mod +++ b/examples/jwt-service/go.mod @@ -25,23 +25,23 @@ require ( github.com/prometheus/otlptranslator v0.0.2 // indirect github.com/prometheus/procfs v0.17.0 // indirect github.com/rs/zerolog v1.34.0 // indirect - go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/otel v1.44.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect go.opentelemetry.io/otel/exporters/prometheus v0.60.0 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/sdk v1.38.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.44.0 // indirect + go.opentelemetry.io/otel/sdk v1.44.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.44.0 // indirect + go.opentelemetry.io/otel/trace v1.44.0 // indirect go.opentelemetry.io/proto/otlp v1.7.1 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/net v0.43.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/text v0.28.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect - google.golang.org/grpc v1.75.1 // indirect - google.golang.org/protobuf v1.36.8 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/sys v0.45.0 // indirect + golang.org/x/text v0.32.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.10 // indirect ) diff --git a/examples/jwt-service/go.sum b/examples/jwt-service/go.sum index 3849009..f086e79 100644 --- a/examples/jwt-service/go.sum +++ b/examples/jwt-service/go.sum @@ -53,17 +53,17 @@ github.com/prometheus/otlptranslator v0.0.2 h1:+1CdeLVrRQ6Psmhnobldo0kTp96Rj80DR github.com/prometheus/otlptranslator v0.0.2/go.mod h1:P8AwMgdD7XEr6QRUJ2QWLpiAZTgTE2UYgjlu3svompI= github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0= github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= -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/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -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.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= +go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 h1:vl9obrcoWVKp/lwl8tRE33853I8Xru9HFbw/skNeLs8= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0/go.mod h1:GAXRxmLJcVM3u22IjTg74zWBrRCKq8BnOqUVLodpcpw= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= @@ -72,39 +72,41 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4D go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= go.opentelemetry.io/otel/exporters/prometheus v0.60.0 h1:cGtQxGvZbnrWdC2GyjZi0PDKVSLWP/Jocix3QWfXtbo= go.opentelemetry.io/otel/exporters/prometheus v0.60.0/go.mod h1:hkd1EekxNo69PTV4OWFGZcKQiIqg0RfuWExcPKFvepk= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= +go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/metric/x v0.66.0 h1:YkCrx1zLOChi9ZcZ6euupOcsgzbVlec7D/xoEU1+cTA= +go.opentelemetry.io/otel/metric/x v0.66.0/go.mod h1:d1+BDj9t96do0/1LoU1ayfCv79ZgNE41qbhBvnMOBZk= +go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= +go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= +go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= +go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= +golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY= -google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= -google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI= -google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= -google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= -google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/examples/postgresql-service/go.mod b/examples/postgresql-service/go.mod index afd87ff..8ee0c2f 100644 --- a/examples/postgresql-service/go.mod +++ b/examples/postgresql-service/go.mod @@ -25,23 +25,23 @@ require ( github.com/prometheus/otlptranslator v0.0.2 // indirect github.com/prometheus/procfs v0.17.0 // indirect github.com/rs/zerolog v1.34.0 // indirect - go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/otel v1.44.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect go.opentelemetry.io/otel/exporters/prometheus v0.60.0 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/sdk v1.38.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.44.0 // indirect + go.opentelemetry.io/otel/sdk v1.44.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.44.0 // indirect + go.opentelemetry.io/otel/trace v1.44.0 // indirect go.opentelemetry.io/proto/otlp v1.7.1 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/net v0.43.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/text v0.28.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect - google.golang.org/grpc v1.75.1 // indirect - google.golang.org/protobuf v1.36.8 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/sys v0.45.0 // indirect + golang.org/x/text v0.32.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.10 // indirect ) diff --git a/examples/postgresql-service/go.sum b/examples/postgresql-service/go.sum index 162e999..ae15668 100644 --- a/examples/postgresql-service/go.sum +++ b/examples/postgresql-service/go.sum @@ -53,17 +53,17 @@ github.com/prometheus/otlptranslator v0.0.2 h1:+1CdeLVrRQ6Psmhnobldo0kTp96Rj80DR github.com/prometheus/otlptranslator v0.0.2/go.mod h1:P8AwMgdD7XEr6QRUJ2QWLpiAZTgTE2UYgjlu3svompI= github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0= github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= -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/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -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.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= +go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 h1:vl9obrcoWVKp/lwl8tRE33853I8Xru9HFbw/skNeLs8= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0/go.mod h1:GAXRxmLJcVM3u22IjTg74zWBrRCKq8BnOqUVLodpcpw= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= @@ -72,39 +72,41 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4D go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= go.opentelemetry.io/otel/exporters/prometheus v0.60.0 h1:cGtQxGvZbnrWdC2GyjZi0PDKVSLWP/Jocix3QWfXtbo= go.opentelemetry.io/otel/exporters/prometheus v0.60.0/go.mod h1:hkd1EekxNo69PTV4OWFGZcKQiIqg0RfuWExcPKFvepk= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= +go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/metric/x v0.66.0 h1:YkCrx1zLOChi9ZcZ6euupOcsgzbVlec7D/xoEU1+cTA= +go.opentelemetry.io/otel/metric/x v0.66.0/go.mod h1:d1+BDj9t96do0/1LoU1ayfCv79ZgNE41qbhBvnMOBZk= +go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= +go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= +go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= +go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= +golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY= -google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= -google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI= -google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= -google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= -google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/examples/prometheus-service/go.mod b/examples/prometheus-service/go.mod index 669cdce..db1ecb0 100644 --- a/examples/prometheus-service/go.mod +++ b/examples/prometheus-service/go.mod @@ -26,23 +26,23 @@ require ( github.com/prometheus/otlptranslator v0.0.2 // indirect github.com/prometheus/procfs v0.17.0 // indirect github.com/rs/zerolog v1.34.0 // indirect - go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/otel v1.44.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect go.opentelemetry.io/otel/exporters/prometheus v0.60.0 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/sdk v1.38.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.44.0 // indirect + go.opentelemetry.io/otel/sdk v1.44.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.44.0 // indirect + go.opentelemetry.io/otel/trace v1.44.0 // indirect go.opentelemetry.io/proto/otlp v1.7.1 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/net v0.43.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/text v0.28.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect - google.golang.org/grpc v1.75.1 // indirect - google.golang.org/protobuf v1.36.8 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/sys v0.45.0 // indirect + golang.org/x/text v0.32.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.10 // indirect ) diff --git a/examples/prometheus-service/go.sum b/examples/prometheus-service/go.sum index 42e8e23..60cb864 100644 --- a/examples/prometheus-service/go.sum +++ b/examples/prometheus-service/go.sum @@ -51,17 +51,17 @@ github.com/prometheus/otlptranslator v0.0.2 h1:+1CdeLVrRQ6Psmhnobldo0kTp96Rj80DR github.com/prometheus/otlptranslator v0.0.2/go.mod h1:P8AwMgdD7XEr6QRUJ2QWLpiAZTgTE2UYgjlu3svompI= github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0= github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= -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/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -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.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= +go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 h1:vl9obrcoWVKp/lwl8tRE33853I8Xru9HFbw/skNeLs8= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0/go.mod h1:GAXRxmLJcVM3u22IjTg74zWBrRCKq8BnOqUVLodpcpw= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= @@ -70,39 +70,41 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4D go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= go.opentelemetry.io/otel/exporters/prometheus v0.60.0 h1:cGtQxGvZbnrWdC2GyjZi0PDKVSLWP/Jocix3QWfXtbo= go.opentelemetry.io/otel/exporters/prometheus v0.60.0/go.mod h1:hkd1EekxNo69PTV4OWFGZcKQiIqg0RfuWExcPKFvepk= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= +go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/metric/x v0.66.0 h1:YkCrx1zLOChi9ZcZ6euupOcsgzbVlec7D/xoEU1+cTA= +go.opentelemetry.io/otel/metric/x v0.66.0/go.mod h1:d1+BDj9t96do0/1LoU1ayfCv79ZgNE41qbhBvnMOBZk= +go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= +go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= +go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= +go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= +golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY= -google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= -google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI= -google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= -google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= -google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/examples/redis-service/go.mod b/examples/redis-service/go.mod index abcff88..c9d3d24 100644 --- a/examples/redis-service/go.mod +++ b/examples/redis-service/go.mod @@ -26,23 +26,23 @@ require ( github.com/prometheus/procfs v0.17.0 // indirect github.com/redis/go-redis/v9 v9.14.0 // indirect github.com/rs/zerolog v1.34.0 // indirect - go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/otel v1.44.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect go.opentelemetry.io/otel/exporters/prometheus v0.60.0 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/sdk v1.38.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.44.0 // indirect + go.opentelemetry.io/otel/sdk v1.44.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.44.0 // indirect + go.opentelemetry.io/otel/trace v1.44.0 // indirect go.opentelemetry.io/proto/otlp v1.7.1 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/net v0.43.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/text v0.28.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect - google.golang.org/grpc v1.75.1 // indirect - google.golang.org/protobuf v1.36.8 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/sys v0.45.0 // indirect + golang.org/x/text v0.32.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.10 // indirect ) diff --git a/examples/redis-service/go.sum b/examples/redis-service/go.sum index c512da0..c5091e9 100644 --- a/examples/redis-service/go.sum +++ b/examples/redis-service/go.sum @@ -59,17 +59,17 @@ github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7D github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= github.com/redis/go-redis/v9 v9.14.0 h1:u4tNCjXOyzfgeLN+vAZaW1xUooqWDqVEsZN0U01jfAE= github.com/redis/go-redis/v9 v9.14.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw= -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/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -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.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= +go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 h1:vl9obrcoWVKp/lwl8tRE33853I8Xru9HFbw/skNeLs8= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0/go.mod h1:GAXRxmLJcVM3u22IjTg74zWBrRCKq8BnOqUVLodpcpw= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= @@ -78,39 +78,41 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4D go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= go.opentelemetry.io/otel/exporters/prometheus v0.60.0 h1:cGtQxGvZbnrWdC2GyjZi0PDKVSLWP/Jocix3QWfXtbo= go.opentelemetry.io/otel/exporters/prometheus v0.60.0/go.mod h1:hkd1EekxNo69PTV4OWFGZcKQiIqg0RfuWExcPKFvepk= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= +go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/metric/x v0.66.0 h1:YkCrx1zLOChi9ZcZ6euupOcsgzbVlec7D/xoEU1+cTA= +go.opentelemetry.io/otel/metric/x v0.66.0/go.mod h1:d1+BDj9t96do0/1LoU1ayfCv79ZgNE41qbhBvnMOBZk= +go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= +go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= +go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= +go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= +golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY= -google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= -google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI= -google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= -google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= -google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/examples/simple-service/go.mod b/examples/simple-service/go.mod index 4ff8200..765eb4d 100644 --- a/examples/simple-service/go.mod +++ b/examples/simple-service/go.mod @@ -24,23 +24,23 @@ require ( github.com/prometheus/otlptranslator v0.0.2 // indirect github.com/prometheus/procfs v0.17.0 // indirect github.com/rs/zerolog v1.34.0 // indirect - go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/otel v1.38.0 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/otel v1.44.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 // indirect go.opentelemetry.io/otel/exporters/prometheus v0.60.0 // indirect - go.opentelemetry.io/otel/metric v1.38.0 // indirect - go.opentelemetry.io/otel/sdk v1.38.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect - go.opentelemetry.io/otel/trace v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.44.0 // indirect + go.opentelemetry.io/otel/sdk v1.44.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.44.0 // indirect + go.opentelemetry.io/otel/trace v1.44.0 // indirect go.opentelemetry.io/proto/otlp v1.7.1 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/net v0.43.0 // indirect - golang.org/x/sys v0.35.0 // indirect - golang.org/x/text v0.28.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect - google.golang.org/grpc v1.75.1 // indirect - google.golang.org/protobuf v1.36.8 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/sys v0.45.0 // indirect + golang.org/x/text v0.32.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect + google.golang.org/grpc v1.79.3 // indirect + google.golang.org/protobuf v1.36.10 // indirect ) diff --git a/examples/simple-service/go.sum b/examples/simple-service/go.sum index 42e8e23..60cb864 100644 --- a/examples/simple-service/go.sum +++ b/examples/simple-service/go.sum @@ -51,17 +51,17 @@ github.com/prometheus/otlptranslator v0.0.2 h1:+1CdeLVrRQ6Psmhnobldo0kTp96Rj80DR github.com/prometheus/otlptranslator v0.0.2/go.mod h1:P8AwMgdD7XEr6QRUJ2QWLpiAZTgTE2UYgjlu3svompI= github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0= github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= -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/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -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.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= -go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= +go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 h1:vl9obrcoWVKp/lwl8tRE33853I8Xru9HFbw/skNeLs8= go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0/go.mod h1:GAXRxmLJcVM3u22IjTg74zWBrRCKq8BnOqUVLodpcpw= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 h1:GqRJVj7UmLjCVyVJ3ZFLdPRmhDUp2zFmQe3RHIOsw24= @@ -70,39 +70,41 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0 h1:lwI4D go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.38.0/go.mod h1:Kz/oCE7z5wuyhPxsXDuaPteSWqjSBD5YaSdbxZYGbGk= go.opentelemetry.io/otel/exporters/prometheus v0.60.0 h1:cGtQxGvZbnrWdC2GyjZi0PDKVSLWP/Jocix3QWfXtbo= go.opentelemetry.io/otel/exporters/prometheus v0.60.0/go.mod h1:hkd1EekxNo69PTV4OWFGZcKQiIqg0RfuWExcPKFvepk= -go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= -go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= -go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= -go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= -go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= -go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= -go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= -go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= +go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/metric/x v0.66.0 h1:YkCrx1zLOChi9ZcZ6euupOcsgzbVlec7D/xoEU1+cTA= +go.opentelemetry.io/otel/metric/x v0.66.0/go.mod h1:d1+BDj9t96do0/1LoU1ayfCv79ZgNE41qbhBvnMOBZk= +go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= +go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= +go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= +go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4= go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= -golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= -golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= -golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= -golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= +golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 h1:BIRfGDEjiHRrk0QKZe3Xv2ieMhtgRGeLcZQ0mIVn4EY= -google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5/go.mod h1:j3QtIyytwqGr1JUDtYXwtMXWPKsEa5LtzIFN1Wn5WvE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 h1:eaY8u2EuxbRv7c3NiGK0/NedzVsCcV6hDuU5qPX5EGE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5/go.mod h1:M4/wBTSeyLxupu3W3tJtOgB14jILAS/XWPSSa3TAlJc= -google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI= -google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= -google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= -google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls= +google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= +google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= +google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=