go.mod: update opentelemetry modules to v1.0.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2021-09-16 13:06:18 +02:00
parent 483e23bdcd
commit 483d2e947f
No known key found for this signature in database
GPG Key ID: 76698F39D527CE8C
100 changed files with 2835 additions and 1545 deletions

View File

@ -8,7 +8,7 @@ require (
github.com/gogo/googleapis v1.4.0 github.com/gogo/googleapis v1.4.0
github.com/gogo/protobuf v1.3.2 github.com/gogo/protobuf v1.3.2
github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/go-digest v1.0.0
google.golang.org/grpc v1.38.0 google.golang.org/grpc v1.40.0
) )
replace ( replace (

View File

@ -1,8 +1,14 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/containerd/ttrpc v1.0.2 h1:2/O3oTZN36q2xRolk0a2WWGgh7/Vf/liElg5hFYLX9U= github.com/containerd/ttrpc v1.0.2 h1:2/O3oTZN36q2xRolk0a2WWGgh7/Vf/liElg5hFYLX9U=
github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y=
github.com/containerd/typeurl v1.0.2 h1:Chlt8zIieDbzQFzXzAeBEF92KhExuE4p9p92/QmY7aY= github.com/containerd/typeurl v1.0.2 h1:Chlt8zIieDbzQFzXzAeBEF92KhExuE4p9p92/QmY7aY=
@ -12,8 +18,11 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gogo/googleapis v1.3.2 h1:kX1es4djPJrsDhY7aZKJy7aZasdcB5oSOEphMjSB53c= github.com/gogo/googleapis v1.3.2 h1:kX1es4djPJrsDhY7aZKJy7aZasdcB5oSOEphMjSB53c=
github.com/gogo/googleapis v1.3.2/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= github.com/gogo/googleapis v1.3.2/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
@ -30,8 +39,9 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@ -39,6 +49,7 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
@ -54,8 +65,10 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1 h1:Lo6mRUjdS99f3zxYOUalftWHUoOGaDRqFk1+j0Q57/I= github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1 h1:Lo6mRUjdS99f3zxYOUalftWHUoOGaDRqFk1+j0Q57/I=
github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
@ -63,19 +76,24 @@ github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -85,6 +103,7 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -103,14 +122,17 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63 h1:YzfoEYWbODU5Fbt37+h7X16BWQbad7Q4S6gclTKFXM8= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63 h1:YzfoEYWbODU5Fbt37+h7X16BWQbad7Q4S6gclTKFXM8=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q=
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -121,6 +143,7 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3 h1:fvjTMHxHEw/mxHbtzPi3JCcKXQRAnQTBRo6YCJSVHKI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

12
go.mod
View File

@ -56,15 +56,15 @@ require (
github.com/urfave/cli v1.22.2 github.com/urfave/cli v1.22.2
go.etcd.io/bbolt v1.3.6 go.etcd.io/bbolt v1.3.6
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.21.0 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.21.0
go.opentelemetry.io/otel v1.0.0-RC1 go.opentelemetry.io/otel v1.0.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.0-RC1 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.0
go.opentelemetry.io/otel/sdk v1.0.0-RC1 go.opentelemetry.io/otel/sdk v1.0.0
go.opentelemetry.io/otel/trace v1.0.0-RC1 go.opentelemetry.io/otel/trace v1.0.0
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023 golang.org/x/net v0.0.0-20210520170846-37e1c6afe023
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c
google.golang.org/grpc v1.38.0 google.golang.org/grpc v1.40.0
google.golang.org/protobuf v1.26.0 google.golang.org/protobuf v1.27.1
gotest.tools/v3 v3.0.3 gotest.tools/v3 v3.0.3
k8s.io/api v0.22.0 k8s.io/api v0.22.0
k8s.io/apimachinery v0.22.0 k8s.io/apimachinery v0.22.0

27
go.sum
View File

@ -97,6 +97,7 @@ github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJ
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo=
github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA=
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
@ -186,6 +187,7 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
@ -576,26 +578,28 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.2
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.21.0/go.mod h1:Vm5u/mtkj1OMhtao0v+BGo2LUoLCgHYXvRmj0jWITlE= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.21.0/go.mod h1:Vm5u/mtkj1OMhtao0v+BGo2LUoLCgHYXvRmj0jWITlE=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4=
go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo=
go.opentelemetry.io/otel v1.0.0-RC1 h1:4CeoX93DNTWt8awGK9JmNXzF9j7TyOu9upscEdtcdXc=
go.opentelemetry.io/otel v1.0.0-RC1/go.mod h1:x9tRa9HK4hSSq7jf2TKbqFbtt58/TGk0f9XiEYISI1I= go.opentelemetry.io/otel v1.0.0-RC1/go.mod h1:x9tRa9HK4hSSq7jf2TKbqFbtt58/TGk0f9XiEYISI1I=
go.opentelemetry.io/otel v1.0.0 h1:qTTn6x71GVBvoafHK/yaRUmFzI4LcONZD0/kXxl5PHI=
go.opentelemetry.io/otel v1.0.0/go.mod h1:AjRVh9A5/5DE7S+mZtTR6t8vpKKryam+0lREnfmS4cg=
go.opentelemetry.io/otel/exporters/otlp v0.20.0 h1:PTNgq9MRmQqqJY0REVbZFvwkYOA85vbdQU/nVfxDyqg= go.opentelemetry.io/otel/exporters/otlp v0.20.0 h1:PTNgq9MRmQqqJY0REVbZFvwkYOA85vbdQU/nVfxDyqg=
go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.0-RC1 h1:GHKxjc4EDldz8ScMDpiNwX4BAub6wGFUUo5Axm2BimU= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.0 h1:Vv4wbLEjheCTPV07jEav7fyUpJkyftQK7Ss2G7qgdSo=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.0-RC1/go.mod h1:FliQjImlo7emZVjixV8nbDMAa4iAkcWTE9zzSEOiEPw= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.0/go.mod h1:3VqVbIbjAycfL1C7sIu/Uh/kACIUPWHztt8ODYwR3oM=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.0-RC1 h1:ZOQXuxKJ9evGspu3LvbZxx3KOOQvKAPBJVMOfGf1cOM= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.0 h1:B9VtEB1u41Ohnl8U6rMCh1jjedu8HwFh4D0QeB+1N+0=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.0-RC1/go.mod h1:cDwRc2Jrh5Gku1peGK8p9rRuX/Uq2OtVmLicjlw2WYU= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.0/go.mod h1:zhEt6O5GGJ3NCAICr4hlCPoDb2GQuh4Obb4gZBgkoQQ=
go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU=
go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw=
go.opentelemetry.io/otel/oteltest v1.0.0-RC1 h1:G685iP3XiskCwk/z0eIabL55XUl2gk0cljhGk9sB0Yk= go.opentelemetry.io/otel/oteltest v1.0.0-RC1 h1:G685iP3XiskCwk/z0eIabL55XUl2gk0cljhGk9sB0Yk=
go.opentelemetry.io/otel/oteltest v1.0.0-RC1/go.mod h1:+eoIG0gdEOaPNftuy1YScLr1Gb4mL/9lpDkZ0JjMRq4= go.opentelemetry.io/otel/oteltest v1.0.0-RC1/go.mod h1:+eoIG0gdEOaPNftuy1YScLr1Gb4mL/9lpDkZ0JjMRq4=
go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc=
go.opentelemetry.io/otel/sdk v1.0.0-RC1 h1:Sy2VLOOg24bipyC29PhuMXYNJrLsxkie8hyI7kUlG9Q= go.opentelemetry.io/otel/sdk v1.0.0 h1:BNPMYUONPNbLneMttKSjQhOTlFLOD9U22HNG1KrIN2Y=
go.opentelemetry.io/otel/sdk v1.0.0-RC1/go.mod h1:kj6yPn7Pgt5ByRuwesbaWcRLA+V7BSDg3Hf8xRvsvf8= go.opentelemetry.io/otel/sdk v1.0.0/go.mod h1:PCrDHlSy5x1kjezSdL37PhbFUMjrsLRshJ2zCzeXwbM=
go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE= go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE=
go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE= go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE=
go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw=
go.opentelemetry.io/otel/trace v1.0.0-RC1 h1:jrjqKJZEibFrDz+umEASeU3LvdVyWKlnTh7XEfwrT58=
go.opentelemetry.io/otel/trace v1.0.0-RC1/go.mod h1:86UHmyHWFEtWjfWPSbu0+d0Pf9Q6e1U+3ViBOc+NXAg= go.opentelemetry.io/otel/trace v1.0.0-RC1/go.mod h1:86UHmyHWFEtWjfWPSbu0+d0Pf9Q6e1U+3ViBOc+NXAg=
go.opentelemetry.io/otel/trace v1.0.0 h1:TSBr8GTEtKevYMG/2d21M989r5WJYVimhTHBKVEZuh4=
go.opentelemetry.io/otel/trace v1.0.0/go.mod h1:PXTWqayeFUlJV1YDNhsJYB184+IvAH814St6o6ajzIs=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.opentelemetry.io/proto/otlp v0.9.0 h1:C0g6TWmQYvjKRnljRULLWUVJGy8Uvu0NEL/5frY2/t4= go.opentelemetry.io/proto/otlp v0.9.0 h1:C0g6TWmQYvjKRnljRULLWUVJGy8Uvu0NEL/5frY2/t4=
go.opentelemetry.io/proto/otlp v0.9.0/go.mod h1:1vKfU9rv61e9EVGthD1zNvUbiwPcimSsOPU9brfSHJg= go.opentelemetry.io/proto/otlp v0.9.0/go.mod h1:1vKfU9rv61e9EVGthD1zNvUbiwPcimSsOPU9brfSHJg=
@ -756,6 +760,7 @@ golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -854,8 +859,9 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q=
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -865,8 +871,9 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@ -94,6 +94,7 @@ github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJ
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo=
github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA=
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
@ -174,6 +175,7 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
@ -533,18 +535,20 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.2
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4=
go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo=
go.opentelemetry.io/otel v1.0.0-RC1/go.mod h1:x9tRa9HK4hSSq7jf2TKbqFbtt58/TGk0f9XiEYISI1I= go.opentelemetry.io/otel v1.0.0-RC1/go.mod h1:x9tRa9HK4hSSq7jf2TKbqFbtt58/TGk0f9XiEYISI1I=
go.opentelemetry.io/otel v1.0.0/go.mod h1:AjRVh9A5/5DE7S+mZtTR6t8vpKKryam+0lREnfmS4cg=
go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.0-RC1/go.mod h1:FliQjImlo7emZVjixV8nbDMAa4iAkcWTE9zzSEOiEPw= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.0/go.mod h1:3VqVbIbjAycfL1C7sIu/Uh/kACIUPWHztt8ODYwR3oM=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.0-RC1/go.mod h1:cDwRc2Jrh5Gku1peGK8p9rRuX/Uq2OtVmLicjlw2WYU= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.0/go.mod h1:zhEt6O5GGJ3NCAICr4hlCPoDb2GQuh4Obb4gZBgkoQQ=
go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU=
go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw=
go.opentelemetry.io/otel/oteltest v1.0.0-RC1/go.mod h1:+eoIG0gdEOaPNftuy1YScLr1Gb4mL/9lpDkZ0JjMRq4= go.opentelemetry.io/otel/oteltest v1.0.0-RC1/go.mod h1:+eoIG0gdEOaPNftuy1YScLr1Gb4mL/9lpDkZ0JjMRq4=
go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc=
go.opentelemetry.io/otel/sdk v1.0.0-RC1/go.mod h1:kj6yPn7Pgt5ByRuwesbaWcRLA+V7BSDg3Hf8xRvsvf8= go.opentelemetry.io/otel/sdk v1.0.0/go.mod h1:PCrDHlSy5x1kjezSdL37PhbFUMjrsLRshJ2zCzeXwbM=
go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE= go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE=
go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE= go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE=
go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw=
go.opentelemetry.io/otel/trace v1.0.0-RC1/go.mod h1:86UHmyHWFEtWjfWPSbu0+d0Pf9Q6e1U+3ViBOc+NXAg= go.opentelemetry.io/otel/trace v1.0.0-RC1/go.mod h1:86UHmyHWFEtWjfWPSbu0+d0Pf9Q6e1U+3ViBOc+NXAg=
go.opentelemetry.io/otel/trace v1.0.0/go.mod h1:PXTWqayeFUlJV1YDNhsJYB184+IvAH814St6o6ajzIs=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.opentelemetry.io/proto/otlp v0.9.0/go.mod h1:1vKfU9rv61e9EVGthD1zNvUbiwPcimSsOPU9brfSHJg= go.opentelemetry.io/proto/otlp v0.9.0/go.mod h1:1vKfU9rv61e9EVGthD1zNvUbiwPcimSsOPU9brfSHJg=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
@ -702,6 +706,7 @@ golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -798,8 +803,9 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q=
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -809,8 +815,9 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@ -10,6 +10,7 @@ coverage.*
gen/ gen/
/example/fib/fib
/example/jaeger/jaeger /example/jaeger/jaeger
/example/namedtracer/namedtracer /example/namedtracer/namedtracer
/example/opencensus/opencensus /example/opencensus/opencensus

View File

@ -8,17 +8,141 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
## [Unreleased] ## [Unreleased]
### Added
### Changed ### Changed
### Deprecated - NoopMeterProvider is now private and NewNoopMeterProvider must be used to obtain a noopMeterProvider. (#2237)
### Removed ## [1.0.0] - 2021-09-20
This is the first stable release for the project.
This release includes an API and SDK for the tracing signal that will comply with the stability guarantees defined by the projects [versioning policy](./VERSIONING.md).
### Added
- OTLP trace exporter now sets the `SchemaURL` field in the exported telemetry if the Tracer has `WithSchemaURL` option. (#2242)
### Fixed ### Fixed
### Security - Slice-valued attributes can correctly be used as map keys. (#2223)
### Removed
- Removed the `"go.opentelemetry.io/otel/exporters/zipkin".WithSDKOptions` function. (#2248)
- Removed the deprecated package `go.opentelemetry.io/otel/oteltest`. (#2234)
- Removed the deprecated package `go.opentelemetry.io/otel/bridge/opencensus/utils`. (#2233)
- Removed deprecated functions, types, and methods from `go.opentelemetry.io/otel/attribute` package.
Use the typed functions and methods added to the package instead. (#2235)
- The `Key.Array` method is removed.
- The `Array` function is removed.
- The `Any` function is removed.
- The `ArrayValue` function is removed.
- The `AsArray` function is removed.
## [1.0.0-RC3] - 2021-09-02
### Added
- Added `ErrorHandlerFunc` to use a function as an `"go.opentelemetry.io/otel".ErrorHandler`. (#2149)
- Added `"go.opentelemetry.io/otel/trace".WithStackTrace` option to add a stack trace when using `span.RecordError` or when panic is handled in `span.End`. (#2163)
- Added typed slice attribute types and functionality to the `go.opentelemetry.io/otel/attribute` package to replace the existing array type and functions. (#2162)
- `BoolSlice`, `IntSlice`, `Int64Slice`, `Float64Slice`, and `StringSlice` replace the use of the `Array` function in the package.
- Added the `go.opentelemetry.io/otel/example/fib` example package.
Included is an example application that computes Fibonacci numbers. (#2203)
### Changed
- Metric instruments have been renamed to match the (feature-frozen) metric API specification:
- ValueRecorder becomes Histogram
- ValueObserver becomes Gauge
- SumObserver becomes CounterObserver
- UpDownSumObserver becomes UpDownCounterObserver
The API exported from this project is still considered experimental. (#2202)
- Metric SDK/API implementation type `InstrumentKind` moves into `sdkapi` sub-package. (#2091)
- The Metrics SDK export record no longer contains a Resource pointer, the SDK `"go.opentelemetry.io/otel/sdk/trace/export/metric".Exporter.Export()` function for push-based exporters now takes a single Resource argument, pull-based exporters use `"go.opentelemetry.io/otel/sdk/metric/controller/basic".Controller.Resource()`. (#2120)
- The JSON output of the `go.opentelemetry.io/otel/exporters/stdout/stdouttrace` is harmonized now such that the output is "plain" JSON objects after each other of the form `{ ... } { ... } { ... }`. Earlier the JSON objects describing a span were wrapped in a slice for each `Exporter.ExportSpans` call, like `[ { ... } ][ { ... } { ... } ]`. Outputting JSON object directly after each other is consistent with JSON loggers, and a bit easier to parse and read. (#2196)
- Update the `NewTracerConfig`, `NewSpanStartConfig`, `NewSpanEndConfig`, and `NewEventConfig` function in the `go.opentelemetry.io/otel/trace` package to return their respective configurations as structs instead of pointers to the struct. (#2212)
### Deprecated
- The `go.opentelemetry.io/otel/bridge/opencensus/utils` package is deprecated.
All functionality from this package now exists in the `go.opentelemetry.io/otel/bridge/opencensus` package.
The functions from that package should be used instead. (#2166)
- The `"go.opentelemetry.io/otel/attribute".Array` function and the related `ARRAY` value type is deprecated.
Use the typed `*Slice` functions and types added to the package instead. (#2162)
- The `"go.opentelemetry.io/otel/attribute".Any` function is deprecated.
Use the typed functions instead. (#2181)
- The `go.opentelemetry.io/otel/oteltest` package is deprecated.
The `"go.opentelemetry.io/otel/sdk/trace/tracetest".SpanRecorder` can be registered with the default SDK (`go.opentelemetry.io/otel/sdk/trace`) as a `SpanProcessor` and used as a replacement for this deprecated package. (#2188)
### Removed
- Removed metrics test package `go.opentelemetry.io/otel/sdk/export/metric/metrictest`. (#2105)
### Fixed
- The `fromEnv` detector no longer throws an error when `OTEL_RESOURCE_ATTRIBUTES` environment variable is not set or empty. (#2138)
- Setting the global `ErrorHandler` with `"go.opentelemetry.io/otel".SetErrorHandler` multiple times is now supported. (#2160, #2140)
- The `"go.opentelemetry.io/otel/attribute".Any` function now supports `int32` values. (#2169)
- Multiple calls to `"go.opentelemetry.io/otel/sdk/metric/controller/basic".WithResource()` are handled correctly, and when no resources are provided `"go.opentelemetry.io/otel/sdk/resource".Default()` is used. (#2120)
- The `WithoutTimestamps` option for the `go.opentelemetry.io/otel/exporters/stdout/stdouttrace` exporter causes the exporter to correctly ommit timestamps. (#2195)
- Fixed typos in resources.go. (#2201)
## [1.0.0-RC2] - 2021-07-26
### Added
- Added `WithOSDescription` resource configuration option to set OS (Operating System) description resource attribute (`os.description`). (#1840)
- Added `WithOS` resource configuration option to set all OS (Operating System) resource attributes at once. (#1840)
- Added the `WithRetry` option to the `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` package.
This option is a replacement for the removed `WithMaxAttempts` and `WithBackoff` options. (#2095)
- Added API `LinkFromContext` to return Link which encapsulates SpanContext from provided context and also encapsulates attributes. (#2115)
- Added a new `Link` type under the SDK `otel/sdk/trace` package that counts the number of attributes that were dropped for surpassing the `AttributePerLinkCountLimit` configured in the Span's `SpanLimits`.
This new type replaces the equal-named API `Link` type found in the `otel/trace` package for most usages within the SDK.
For example, instances of this type are now returned by the `Links()` function of `ReadOnlySpan`s provided in places like the `OnEnd` function of `SpanProcessor` implementations. (#2118)
- Added the `SpanRecorder` type to the `go.opentelemetry.io/otel/skd/trace/tracetest` package.
This type can be used with the default SDK as a `SpanProcessor` during testing. (#2132)
### Changed
- The `SpanModels` function is now exported from the `go.opentelemetry.io/otel/exporters/zipkin` package to convert OpenTelemetry spans into Zipkin model spans. (#2027)
- Rename the `"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc".RetrySettings` to `RetryConfig`. (#2095)
### Deprecated
- The `TextMapCarrier` and `TextMapPropagator` from the `go.opentelemetry.io/otel/oteltest` package and their associated creation functions (`TextMapCarrier`, `NewTextMapPropagator`) are deprecated. (#2114)
- The `Harness` type from the `go.opentelemetry.io/otel/oteltest` package and its associated creation function, `NewHarness` are deprecated and will be removed in the next release. (#2123)
- The `TraceStateFromKeyValues` function from the `go.opentelemetry.io/otel/oteltest` package is deprecated.
Use the `trace.ParseTraceState` function instead. (#2122)
### Removed
- Removed the deprecated package `go.opentelemetry.io/otel/exporters/trace/jaeger`. (#2020)
- Removed the deprecated package `go.opentelemetry.io/otel/exporters/trace/zipkin`. (#2020)
- Removed the `"go.opentelemetry.io/otel/sdk/resource".WithBuiltinDetectors` function.
The explicit `With*` options for every built-in detector should be used instead. (#2026 #2097)
- Removed the `WithMaxAttempts` and `WithBackoff` options from the `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp` package.
The retry logic of the package has been updated to match the `otlptracegrpc` package and accordingly a `WithRetry` option is added that should be used instead. (#2095)
- Removed `DroppedAttributeCount` field from `otel/trace.Link` struct. (#2118)
### Fixed
- When using WithNewRoot, don't use the parent context for making sampling decisions. (#2032)
- `oteltest.Tracer` now creates a valid `SpanContext` when using `WithNewRoot`. (#2073)
- OS type detector now sets the correct `dragonflybsd` value for DragonFly BSD. (#2092)
- The OTel span status is correctly transformed into the OTLP status in the `go.opentelemetry.io/otel/exporters/otlp/otlptrace` package.
This fix will by default set the status to `Unset` if it is not explicitly set to `Ok` or `Error`. (#2099 #2102)
- The `Inject` method for the `"go.opentelemetry.io/otel/propagation".TraceContext` type no longer injects empty `tracestate` values. (#2108)
- Use `6831` as default Jaeger agent port instead of `6832`. (#2131)
## [Experimental Metrics v0.22.0] - 2021-07-19
### Added
- Adds HTTP support for OTLP metrics exporter. (#2022)
### Removed
- Removed the deprecated package `go.opentelemetry.io/otel/exporters/metric/prometheus`. (#2020)
## [1.0.0-RC1] / 0.21.0 - 2021-06-18 ## [1.0.0-RC1] / 0.21.0 - 2021-06-18
@ -1415,7 +1539,11 @@ It contains api and sdk for trace and meter.
- CircleCI build CI manifest files. - CircleCI build CI manifest files.
- CODEOWNERS file to track owners of this project. - CODEOWNERS file to track owners of this project.
[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.0.0-RC1...HEAD [Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.0.0...HEAD
[1.0.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.0.0
[1.0.0-RC3]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.0.0-RC3
[1.0.0-RC2]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.0.0-RC2
[Experimental Metrics v0.22.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/metric/v0.22.0
[1.0.0-RC1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.0.0-RC1 [1.0.0-RC1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.0.0-RC1
[0.20.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.20.0 [0.20.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.20.0
[0.19.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.19.0 [0.19.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v0.19.0

View File

@ -12,6 +12,6 @@
# https://help.github.com/en/articles/about-code-owners # https://help.github.com/en/articles/about-code-owners
# #
* @jmacd @MrAlias @Aneurysm9 @evantorrie @XSAM @dashpole @paivagustavo @MadVikingGod * @jmacd @MrAlias @Aneurysm9 @evantorrie @XSAM @dashpole @paivagustavo @MadVikingGod @pellared
CODEOWNERS @MrAlias @Aneurysm9 CODEOWNERS @MrAlias @Aneurysm9

View File

@ -113,6 +113,7 @@ A PR is considered to be **ready to merge** when:
one day and may be merged with a single Maintainer's approval. one day and may be merged with a single Maintainer's approval.
* `CHANGELOG.md` has been updated to reflect what has been * `CHANGELOG.md` has been updated to reflect what has been
added, changed, removed, or fixed. added, changed, removed, or fixed.
* `README.md` has been updated if necessary.
* Urgent fix can take exception as long as it has been actively * Urgent fix can take exception as long as it has been actively
communicated. communicated.
@ -143,6 +144,26 @@ patterns in the spec.
For a deeper discussion, see For a deeper discussion, see
[this](https://github.com/open-telemetry/opentelemetry-specification/issues/165). [this](https://github.com/open-telemetry/opentelemetry-specification/issues/165).
## Documentation
Each non-example Go Module should have its own `README.md` containing:
- A pkg.go.dev badge which can be generated [here](https://pkg.go.dev/badge/).
- Brief description.
- Installation instructions (and requirements if applicable).
- Hyperlink to an example. Depending on the component the example can be:
- An `example_test.go` like [here](exporters/stdout/stdouttrace/example_test.go).
- A sample Go application with its own `README.md`, like [here](example/zipkin).
- Additional documentation sections such us:
- Configuration,
- Contributing,
- References.
[Here](exporters/jaeger/README.md) is an example of a concise `README.md`.
Moreover, it should be possible to navigate to any `README.md` from the
root `README.md`.
## Style Guide ## Style Guide
One of the primary goals of this project is that it is actually used by One of the primary goals of this project is that it is actually used by
@ -461,6 +482,7 @@ Approvers:
- [David Ashpole](https://github.com/dashpole), Google - [David Ashpole](https://github.com/dashpole), Google
- [Gustavo Silva Paiva](https://github.com/paivagustavo), LightStep - [Gustavo Silva Paiva](https://github.com/paivagustavo), LightStep
- [Aaron Clawson](https://github.com/MadVikingGod) - [Aaron Clawson](https://github.com/MadVikingGod)
- [Robert Pająk](https://github.com/pellared), Splunk
Maintainers: Maintainers:

View File

@ -40,8 +40,8 @@ $(TOOLS)/%: | $(TOOLS)
cd $(TOOLS_MOD_DIR) && \ cd $(TOOLS_MOD_DIR) && \
$(GO) build -o $@ $(PACKAGE) $(GO) build -o $@ $(PACKAGE)
SEMCONVGEN = $(TOOLS)/semconv-gen SEMCONVGEN = $(TOOLS)/semconvgen
$(TOOLS)/semconv-gen: PACKAGE=go.opentelemetry.io/otel/$(TOOLS_MOD_DIR)/semconv-gen $(TOOLS)/semconvgen: PACKAGE=go.opentelemetry.io/build-tools/semconvgen
CROSSLINK = $(TOOLS)/crosslink CROSSLINK = $(TOOLS)/crosslink
$(TOOLS)/crosslink: PACKAGE=go.opentelemetry.io/otel/$(TOOLS_MOD_DIR)/crosslink $(TOOLS)/crosslink: PACKAGE=go.opentelemetry.io/otel/$(TOOLS_MOD_DIR)/crosslink
@ -52,13 +52,16 @@ $(TOOLS)/golangci-lint: PACKAGE=github.com/golangci/golangci-lint/cmd/golangci-l
MISSPELL = $(TOOLS)/misspell MISSPELL = $(TOOLS)/misspell
$(TOOLS)/misspell: PACKAGE= github.com/client9/misspell/cmd/misspell $(TOOLS)/misspell: PACKAGE= github.com/client9/misspell/cmd/misspell
GOCOVMERGE = $(TOOLS)/gocovmerge
$(TOOLS)/gocovmerge: PACKAGE= github.com/wadey/gocovmerge
STRINGER = $(TOOLS)/stringer STRINGER = $(TOOLS)/stringer
$(TOOLS)/stringer: PACKAGE=golang.org/x/tools/cmd/stringer $(TOOLS)/stringer: PACKAGE=golang.org/x/tools/cmd/stringer
$(TOOLS)/gojq: PACKAGE=github.com/itchyny/gojq/cmd/gojq $(TOOLS)/gojq: PACKAGE=github.com/itchyny/gojq/cmd/gojq
.PHONY: tools .PHONY: tools
tools: $(CROSSLINK) $(GOLANGCI_LINT) $(MISSPELL) $(STRINGER) $(TOOLS)/gojq $(SEMCONVGEN) tools: $(CROSSLINK) $(GOLANGCI_LINT) $(MISSPELL) $(GOCOVMERGE) $(STRINGER) $(TOOLS)/gojq $(SEMCONVGEN)
# Build # Build
@ -111,19 +114,18 @@ test:
COVERAGE_MODE = atomic COVERAGE_MODE = atomic
COVERAGE_PROFILE = coverage.out COVERAGE_PROFILE = coverage.out
.PHONY: test-coverage .PHONY: test-coverage
test-coverage: test-coverage: | $(GOCOVMERGE)
@set -e; \ @set -e; \
printf "" > coverage.txt; \ printf "" > coverage.txt; \
for dir in $(ALL_COVERAGE_MOD_DIRS); do \ for dir in $(ALL_COVERAGE_MOD_DIRS); do \
echo "$(GO) test -coverpkg=./... -covermode=$(COVERAGE_MODE) -coverprofile="$(COVERAGE_PROFILE)" $${dir}/..."; \ echo "$(GO) test -coverpkg=go.opentelemetry.io/otel/... -covermode=$(COVERAGE_MODE) -coverprofile="$(COVERAGE_PROFILE)" $${dir}/..."; \
(cd "$${dir}" && \ (cd "$${dir}" && \
$(GO) list ./... \ $(GO) list ./... \
| grep -v third_party \ | grep -v third_party \
| xargs $(GO) test -coverpkg=./... -covermode=$(COVERAGE_MODE) -coverprofile="$(COVERAGE_PROFILE)" && \ | xargs $(GO) test -coverpkg=./... -covermode=$(COVERAGE_MODE) -coverprofile="$(COVERAGE_PROFILE)" && \
$(GO) tool cover -html=coverage.out -o coverage.html); \ $(GO) tool cover -html=coverage.out -o coverage.html); \
[ -f "$${dir}/coverage.out" ] && cat "$${dir}/coverage.out" >> coverage.txt; \
done; \ done; \
sed -i.bak -e '2,$$ { /^mode: /d; }' coverage.txt $(GOCOVMERGE) $$(find . -name coverage.out) > coverage.txt
.PHONY: lint .PHONY: lint
lint: misspell lint-modules | $(GOLANGCI_LINT) lint: misspell lint-modules | $(GOLANGCI_LINT)

View File

@ -11,14 +11,14 @@ It provides a set of APIs to directly measure performance and behavior of your s
## Project Status ## Project Status
**Warning**: this project is currently in a pre-GA phase. Backwards | Signal | Status | Project |
incompatible changes may be introduced in subsequent minor version releases as | ------- | ---------- | ------- |
we work to track the evolving OpenTelemetry specification and user feedback. | Traces | Stable | N/A |
| Metrics | Alpha | N/A |
| Logs | Frozen [1] | N/A |
Our progress towards a GA release candidate is tracked in [this project - [1]: The Logs signal development is halted for this project while we develop both Traces and Metrics.
board](https://github.com/orgs/open-telemetry/projects/5). This release No Logs Pull Requests are currently being accepted.
candidate will follow semantic versioning and will be released with a major
version greater than zero.
Progress and status specific to this repository is tracked in our local Progress and status specific to this repository is tracked in our local
[project boards](https://github.com/open-telemetry/opentelemetry-go/projects) [project boards](https://github.com/open-telemetry/opentelemetry-go/projects)
@ -28,17 +28,6 @@ and
Project versioning information and stability guarantees can be found in the Project versioning information and stability guarantees can be found in the
[versioning documentation](./VERSIONING.md). [versioning documentation](./VERSIONING.md).
| Signal | Status |
| --- | --- |
| Traces | Stable [release](https://github.com/orgs/open-telemetry/projects/5) is primary focus |
| Metrics | Development paused [1] |
| Logs | Frozen [2] |
- [1]: The development of the metrics API and SDK has paused due to limited development resources, prioritization of a stable Traces release, and instability of the official overall design from the OpenTelemetry specification.
Pull Requests for metrics related issues are not being accepted currently outside of security vulnerability mitigations.
- [2]: The Logs signal development is halted for this project while we develop both Traces and Metrics.
No Logs Pull Requests are currently being accepted.
### Compatibility ### Compatibility
This project is tested on the following systems. This project is tested on the following systems.

View File

@ -3,8 +3,8 @@
## Semantic Convention Generation ## Semantic Convention Generation
If a new version of the OpenTelemetry Specification has been released it will be necessary to generate a new If a new version of the OpenTelemetry Specification has been released it will be necessary to generate a new
semantic convention package from the YAML definitions in the specification repository. There is a utility in semantic convention package from the YAML definitions in the specification repository. There is a `semconvgen` utility
`internal/tools/semconv-gen` that can be used to generate the a package with the name matching the specification installed by `make tools` that can be used to generate the a package with the name matching the specification
version number under the `semconv` package. This will ideally be done soon after the specification release is version number under the `semconv` package. This will ideally be done soon after the specification release is
tagged. Make sure that the specification repo contains a checkout of the the latest tagged release so that the tagged. Make sure that the specification repo contains a checkout of the the latest tagged release so that the
generated files match the released semantic conventions. generated files match the released semantic conventions.
@ -12,9 +12,8 @@ generated files match the released semantic conventions.
There are currently two categories of semantic conventions that must be generated, `resource` and `trace`. There are currently two categories of semantic conventions that must be generated, `resource` and `trace`.
``` ```
cd internal/tools/semconv-gen .tools/semconvgen -i /path/to/specification/repo/semantic_conventions/resource -t semconv/template.j2
go run generator.go -i /path/to/specification/repo/semantic_conventions/resource .tools/semconvgen -i /path/to/specification/repo/semantic_conventions/trace -t semconv/template.j2
go run generator.go -i /path/to/specification/repo/semantic_conventions/trace
``` ```
Using default values for all options other than `input` will result in using the `template.j2` template to Using default values for all options other than `input` will result in using the `template.j2` template to

View File

@ -150,10 +150,10 @@ The `otel` package is refactored to remove its dependencies on `otel/metric` so
it can be released as stable as well. With that done the following release it can be released as stable as well. With that done the following release
candidates are made: candidates are made:
* `otel`: `v1.0.0-rc.1` * `otel`: `v1.0.0-RC1`
* `otel/trace`: `v1.0.0-rc.1` * `otel/trace`: `v1.0.0-RC1`
* `otel/baggage`: `v1.0.0-rc.1` * `otel/baggage`: `v1.0.0-RC1`
* `otel/sdk/trace`: `v1.0.0-rc.1` * `otel/sdk/trace`: `v1.0.0-RC1`
The `otel/metric` and `otel/sdk/metric` modules remain at `v0.14.0`. The `otel/metric` and `otel/sdk/metric` modules remain at `v0.14.0`.
@ -161,10 +161,10 @@ A few minor issues are discovered in the `otel/trace` package. These issues are
resolved with some minor, but backwards incompatible, changes and are released resolved with some minor, but backwards incompatible, changes and are released
as a second release candidate: as a second release candidate:
* `otel`: `v1.0.0-rc.2` * `otel`: `v1.0.0-RC2`
* `otel/trace`: `v1.0.0-rc.2` * `otel/trace`: `v1.0.0-RC2`
* `otel/baggage`: `v1.0.0-rc.2` * `otel/baggage`: `v1.0.0-RC2`
* `otel/sdk/trace`: `v1.0.0-rc.2` * `otel/sdk/trace`: `v1.0.0-RC2`
Notice that all module version numbers are incremented to adhere to our Notice that all module version numbers are incremented to adhere to our
versioning policy. versioning policy.
@ -205,12 +205,12 @@ As we progress, the `otel/metric` and `otel/sdk/metric` packages have reached a
point where they should be evaluated for stability. The `otel` module is point where they should be evaluated for stability. The `otel` module is
reintegrated with the `otel/metric` package and the following release is made: reintegrated with the `otel/metric` package and the following release is made:
* `otel`: `v1.1.0-rc.1` * `otel`: `v1.1.0-RC1`
* `otel/trace`: `v1.1.0-rc.1` * `otel/trace`: `v1.1.0-RC1`
* `otel/metric`: `v1.1.0-rc.1` * `otel/metric`: `v1.1.0-RC1`
* `otel/baggage`: `v1.1.0-rc.1` * `otel/baggage`: `v1.1.0-RC1`
* `otel/sdk/trace`: `v1.1.0-rc.1` * `otel/sdk/trace`: `v1.1.0-RC1`
* `otel/sdk/metric`: `v1.1.0-rc.1` * `otel/sdk/metric`: `v1.1.0-RC1`
All the modules are evaluated and determined to a viable stable release. They All the modules are evaluated and determined to a viable stable release. They
are then released as version `v1.1.0` (the minor version is incremented to are then released as version `v1.1.0` (the minor version is incremented to

View File

@ -12,8 +12,5 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// package attribute provides key and value attributes. // Package attribute provides key and value attributes.
//
// This package is currently in a Release Candidate phase. Backwards incompatible changes
// may be introduced prior to v1.0.0, but we believe the current API is ready to stabilize.
package attribute // import "go.opentelemetry.io/otel/attribute" package attribute // import "go.opentelemetry.io/otel/attribute"

View File

@ -20,10 +20,8 @@ type Key string
// Bool creates a KeyValue instance with a BOOL Value. // Bool creates a KeyValue instance with a BOOL Value.
// //
// If creating both key and a bool value at the same time, then // If creating both a key and value at the same time, use the provided
// instead of calling Key(name).Bool(value) consider using a // convenience function instead -- Bool(name, value).
// convenience function provided by the api/key package -
// key.Bool(name, value).
func (k Key) Bool(v bool) KeyValue { func (k Key) Bool(v bool) KeyValue {
return KeyValue{ return KeyValue{
Key: k, Key: k,
@ -31,51 +29,21 @@ func (k Key) Bool(v bool) KeyValue {
} }
} }
// Int64 creates a KeyValue instance with an INT64 Value. // BoolSlice creates a KeyValue instance with a BOOLSLICE Value.
// //
// If creating both key and an int64 value at the same time, then // If creating both a key and value at the same time, use the provided
// instead of calling Key(name).Int64(value) consider using a // convenience function instead -- BoolSlice(name, value).
// convenience function provided by the api/key package - func (k Key) BoolSlice(v []bool) KeyValue {
// key.Int64(name, value).
func (k Key) Int64(v int64) KeyValue {
return KeyValue{ return KeyValue{
Key: k, Key: k,
Value: Int64Value(v), Value: BoolSliceValue(v),
}
}
// Float64 creates a KeyValue instance with a FLOAT64 Value.
//
// If creating both key and a float64 value at the same time, then
// instead of calling Key(name).Float64(value) consider using a
// convenience function provided by the api/key package -
// key.Float64(name, value).
func (k Key) Float64(v float64) KeyValue {
return KeyValue{
Key: k,
Value: Float64Value(v),
}
}
// String creates a KeyValue instance with a STRING Value.
//
// If creating both key and a string value at the same time, then
// instead of calling Key(name).String(value) consider using a
// convenience function provided by the api/key package -
// key.String(name, value).
func (k Key) String(v string) KeyValue {
return KeyValue{
Key: k,
Value: StringValue(v),
} }
} }
// Int creates a KeyValue instance with an INT64 Value. // Int creates a KeyValue instance with an INT64 Value.
// //
// If creating both key and an int value at the same time, then // If creating both a key and value at the same time, use the provided
// instead of calling Key(name).Int(value) consider using a // convenience function instead -- Int(name, value).
// convenience function provided by the api/key package -
// key.Int(name, value).
func (k Key) Int(v int) KeyValue { func (k Key) Int(v int) KeyValue {
return KeyValue{ return KeyValue{
Key: k, Key: k,
@ -83,20 +51,84 @@ func (k Key) Int(v int) KeyValue {
} }
} }
// IntSlice creates a KeyValue instance with an INT64SLICE Value.
//
// If creating both a key and value at the same time, use the provided
// convenience function instead -- IntSlice(name, value).
func (k Key) IntSlice(v []int) KeyValue {
return KeyValue{
Key: k,
Value: IntSliceValue(v),
}
}
// Int64 creates a KeyValue instance with an INT64 Value.
//
// If creating both a key and value at the same time, use the provided
// convenience function instead -- Int64(name, value).
func (k Key) Int64(v int64) KeyValue {
return KeyValue{
Key: k,
Value: Int64Value(v),
}
}
// Int64Slice creates a KeyValue instance with an INT64SLICE Value.
//
// If creating both a key and value at the same time, use the provided
// convenience function instead -- Int64Slice(name, value).
func (k Key) Int64Slice(v []int64) KeyValue {
return KeyValue{
Key: k,
Value: Int64SliceValue(v),
}
}
// Float64 creates a KeyValue instance with a FLOAT64 Value.
//
// If creating both a key and value at the same time, use the provided
// convenience function instead -- Float64(name, value).
func (k Key) Float64(v float64) KeyValue {
return KeyValue{
Key: k,
Value: Float64Value(v),
}
}
// Float64Slice creates a KeyValue instance with a FLOAT64SLICE Value.
//
// If creating both a key and value at the same time, use the provided
// convenience function instead -- Float64(name, value).
func (k Key) Float64Slice(v []float64) KeyValue {
return KeyValue{
Key: k,
Value: Float64SliceValue(v),
}
}
// String creates a KeyValue instance with a STRING Value.
//
// If creating both a key and value at the same time, use the provided
// convenience function instead -- String(name, value).
func (k Key) String(v string) KeyValue {
return KeyValue{
Key: k,
Value: StringValue(v),
}
}
// StringSlice creates a KeyValue instance with a STRINGSLICE Value.
//
// If creating both a key and value at the same time, use the provided
// convenience function instead -- StringSlice(name, value).
func (k Key) StringSlice(v []string) KeyValue {
return KeyValue{
Key: k,
Value: StringSliceValue(v),
}
}
// Defined returns true for non-empty keys. // Defined returns true for non-empty keys.
func (k Key) Defined() bool { func (k Key) Defined() bool {
return len(k) != 0 return len(k) != 0
} }
// Array creates a KeyValue instance with a ARRAY Value.
//
// If creating both key and a array value at the same time, then
// instead of calling Key(name).String(value) consider using a
// convenience function provided by the api/key package -
// key.Array(name, value).
func (k Key) Array(v interface{}) KeyValue {
return KeyValue{
Key: k,
Value: ArrayValue(v),
}
}

View File

@ -15,9 +15,7 @@
package attribute // import "go.opentelemetry.io/otel/attribute" package attribute // import "go.opentelemetry.io/otel/attribute"
import ( import (
"encoding/json"
"fmt" "fmt"
"reflect"
) )
// KeyValue holds a key and value pair. // KeyValue holds a key and value pair.
@ -31,78 +29,58 @@ func (kv KeyValue) Valid() bool {
return kv.Key != "" && kv.Value.Type() != INVALID return kv.Key != "" && kv.Value.Type() != INVALID
} }
// Bool creates a new key-value pair with a passed name and a bool // Bool creates a KeyValue with a BOOL Value type.
// value.
func Bool(k string, v bool) KeyValue { func Bool(k string, v bool) KeyValue {
return Key(k).Bool(v) return Key(k).Bool(v)
} }
// Int64 creates a new key-value pair with a passed name and an int64 // BoolSlice creates a KeyValue with a BOOLSLICE Value type.
// value. func BoolSlice(k string, v []bool) KeyValue {
return Key(k).BoolSlice(v)
}
// Int creates a KeyValue with an INT64 Value type.
func Int(k string, v int) KeyValue {
return Key(k).Int(v)
}
// IntSlice creates a KeyValue with an INT64SLICE Value type.
func IntSlice(k string, v []int) KeyValue {
return Key(k).IntSlice(v)
}
// Int64 creates a KeyValue with an INT64 Value type.
func Int64(k string, v int64) KeyValue { func Int64(k string, v int64) KeyValue {
return Key(k).Int64(v) return Key(k).Int64(v)
} }
// Float64 creates a new key-value pair with a passed name and a float64 // Int64Slice creates a KeyValue with an INT64SLICE Value type.
// value. func Int64Slice(k string, v []int64) KeyValue {
return Key(k).Int64Slice(v)
}
// Float64 creates a KeyValue with a FLOAT64 Value type.
func Float64(k string, v float64) KeyValue { func Float64(k string, v float64) KeyValue {
return Key(k).Float64(v) return Key(k).Float64(v)
} }
// String creates a new key-value pair with a passed name and a string // Float64Slice creates a KeyValue with a FLOAT64SLICE Value type.
// value. func Float64Slice(k string, v []float64) KeyValue {
return Key(k).Float64Slice(v)
}
// String creates a KeyValue with a STRING Value type.
func String(k, v string) KeyValue { func String(k, v string) KeyValue {
return Key(k).String(v) return Key(k).String(v)
} }
// StringSlice creates a KeyValue with a STRINGSLICE Value type.
func StringSlice(k string, v []string) KeyValue {
return Key(k).StringSlice(v)
}
// Stringer creates a new key-value pair with a passed name and a string // Stringer creates a new key-value pair with a passed name and a string
// value generated by the passed Stringer interface. // value generated by the passed Stringer interface.
func Stringer(k string, v fmt.Stringer) KeyValue { func Stringer(k string, v fmt.Stringer) KeyValue {
return Key(k).String(v.String()) return Key(k).String(v.String())
} }
// Int creates a new key-value pair instance with a passed name and
// either an int32 or an int64 value, depending on whether the int
// type is 32 or 64 bits wide.
func Int(k string, v int) KeyValue {
return Key(k).Int(v)
}
// Array creates a new key-value pair with a passed name and a array.
// Only arrays of primitive type are supported.
func Array(k string, v interface{}) KeyValue {
return Key(k).Array(v)
}
// Any creates a new key-value pair instance with a passed name and
// automatic type inference. This is slower, and not type-safe.
func Any(k string, value interface{}) KeyValue {
if value == nil {
return String(k, "<nil>")
}
if stringer, ok := value.(fmt.Stringer); ok {
return String(k, stringer.String())
}
rv := reflect.ValueOf(value)
switch rv.Kind() {
case reflect.Array, reflect.Slice:
return Array(k, value)
case reflect.Bool:
return Bool(k, rv.Bool())
case reflect.Int, reflect.Int8, reflect.Int16:
return Int(k, int(rv.Int()))
case reflect.Int64:
return Int64(k, rv.Int())
case reflect.Float64:
return Float64(k, rv.Float())
case reflect.String:
return String(k, rv.String())
}
if b, err := json.Marshal(value); b != nil && err == nil {
return String(k, string(b))
}
return String(k, fmt.Sprint(value))
}

View File

@ -13,12 +13,15 @@ func _() {
_ = x[INT64-2] _ = x[INT64-2]
_ = x[FLOAT64-3] _ = x[FLOAT64-3]
_ = x[STRING-4] _ = x[STRING-4]
_ = x[ARRAY-5] _ = x[BOOLSLICE-5]
_ = x[INT64SLICE-6]
_ = x[FLOAT64SLICE-7]
_ = x[STRINGSLICE-8]
} }
const _Type_name = "INVALIDBOOLINT64FLOAT64STRINGARRAY" const _Type_name = "INVALIDBOOLINT64FLOAT64STRINGBOOLSLICEINT64SLICEFLOAT64SLICESTRINGSLICE"
var _Type_index = [...]uint8{0, 7, 11, 16, 23, 29, 34} var _Type_index = [...]uint8{0, 7, 11, 16, 23, 29, 38, 48, 60, 71}
func (i Type) String() string { func (i Type) String() string {
if i < 0 || i >= Type(len(_Type_index)-1) { if i < 0 || i >= Type(len(_Type_index)-1) {

View File

@ -17,7 +17,6 @@ package attribute // import "go.opentelemetry.io/otel/attribute"
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"reflect"
"strconv" "strconv"
"go.opentelemetry.io/otel/internal" "go.opentelemetry.io/otel/internal"
@ -33,9 +32,7 @@ type Value struct {
vtype Type vtype Type
numeric uint64 numeric uint64
stringly string stringly string
// TODO Lazy value type? slice interface{}
array interface{}
} }
const ( const (
@ -49,10 +46,14 @@ const (
FLOAT64 FLOAT64
// STRING is a string Type Value. // STRING is a string Type Value.
STRING STRING
// ARRAY is an array Type Value used to store 1-dimensional slices or // BOOLSLICE is a slice of booleans Type Value.
// arrays of bool, int, int32, int64, uint, uint32, uint64, float, BOOLSLICE
// float32, float64, or string types. // INT64SLICE is a slice of 64-bit signed integral numbers Type Value.
ARRAY INT64SLICE
// FLOAT64SLICE is a slice of 64-bit floating point numbers Type Value.
FLOAT64SLICE
// STRINGSLICE is a slice of strings Type Value.
STRINGSLICE
) )
// BoolValue creates a BOOL Value. // BoolValue creates a BOOL Value.
@ -63,6 +64,33 @@ func BoolValue(v bool) Value {
} }
} }
// BoolSliceValue creates a BOOLSLICE Value.
func BoolSliceValue(v []bool) Value {
cp := make([]bool, len(v))
copy(cp, v)
return Value{
vtype: BOOLSLICE,
slice: &cp,
}
}
// IntValue creates an INT64 Value.
func IntValue(v int) Value {
return Int64Value(int64(v))
}
// IntSliceValue creates an INTSLICE Value.
func IntSliceValue(v []int) Value {
cp := make([]int64, 0, len(v))
for _, i := range v {
cp = append(cp, int64(i))
}
return Value{
vtype: INT64SLICE,
slice: &cp,
}
}
// Int64Value creates an INT64 Value. // Int64Value creates an INT64 Value.
func Int64Value(v int64) Value { func Int64Value(v int64) Value {
return Value{ return Value{
@ -71,6 +99,16 @@ func Int64Value(v int64) Value {
} }
} }
// Int64SliceValue creates an INT64SLICE Value.
func Int64SliceValue(v []int64) Value {
cp := make([]int64, len(v))
copy(cp, v)
return Value{
vtype: INT64SLICE,
slice: &cp,
}
}
// Float64Value creates a FLOAT64 Value. // Float64Value creates a FLOAT64 Value.
func Float64Value(v float64) Value { func Float64Value(v float64) Value {
return Value{ return Value{
@ -79,6 +117,16 @@ func Float64Value(v float64) Value {
} }
} }
// Float64SliceValue creates a FLOAT64SLICE Value.
func Float64SliceValue(v []float64) Value {
cp := make([]float64, len(v))
copy(cp, v)
return Value{
vtype: FLOAT64SLICE,
slice: &cp,
}
}
// StringValue creates a STRING Value. // StringValue creates a STRING Value.
func StringValue(v string) Value { func StringValue(v string) Value {
return Value{ return Value{
@ -87,38 +135,14 @@ func StringValue(v string) Value {
} }
} }
// IntValue creates an INT64 Value. // StringSliceValue creates a STRINGSLICE Value.
func IntValue(v int) Value { func StringSliceValue(v []string) Value {
return Int64Value(int64(v)) cp := make([]string, len(v))
} copy(cp, v)
// ArrayValue creates an ARRAY value from an array or slice.
// Only arrays or slices of bool, int, int64, float, float64, or string types are allowed.
// Specifically, arrays and slices can not contain other arrays, slices, structs, or non-standard
// types. If the passed value is not an array or slice of these types an
// INVALID value is returned.
func ArrayValue(v interface{}) Value {
switch reflect.TypeOf(v).Kind() {
case reflect.Array, reflect.Slice:
// get array type regardless of dimensions
typ := reflect.TypeOf(v).Elem()
kind := typ.Kind()
switch kind {
case reflect.Bool, reflect.Int, reflect.Int64,
reflect.Float64, reflect.String:
val := reflect.ValueOf(v)
length := val.Len()
frozen := reflect.Indirect(reflect.New(reflect.ArrayOf(length, typ)))
reflect.Copy(frozen, val)
return Value{ return Value{
vtype: ARRAY, vtype: STRINGSLICE,
array: frozen.Interface(), slice: &cp,
} }
default:
return Value{vtype: INVALID}
}
}
return Value{vtype: INVALID}
} }
// Type returns a type of the Value. // Type returns a type of the Value.
@ -132,27 +156,58 @@ func (v Value) AsBool() bool {
return internal.RawToBool(v.numeric) return internal.RawToBool(v.numeric)
} }
// AsBoolSlice returns the []bool value. Make sure that the Value's type is
// BOOLSLICE.
func (v Value) AsBoolSlice() []bool {
if s, ok := v.slice.(*[]bool); ok {
return *s
}
return nil
}
// AsInt64 returns the int64 value. Make sure that the Value's type is // AsInt64 returns the int64 value. Make sure that the Value's type is
// INT64. // INT64.
func (v Value) AsInt64() int64 { func (v Value) AsInt64() int64 {
return internal.RawToInt64(v.numeric) return internal.RawToInt64(v.numeric)
} }
// AsInt64Slice returns the []int64 value. Make sure that the Value's type is
// INT64SLICE.
func (v Value) AsInt64Slice() []int64 {
if s, ok := v.slice.(*[]int64); ok {
return *s
}
return nil
}
// AsFloat64 returns the float64 value. Make sure that the Value's // AsFloat64 returns the float64 value. Make sure that the Value's
// type is FLOAT64. // type is FLOAT64.
func (v Value) AsFloat64() float64 { func (v Value) AsFloat64() float64 {
return internal.RawToFloat64(v.numeric) return internal.RawToFloat64(v.numeric)
} }
// AsFloat64Slice returns the []float64 value. Make sure that the Value's type is
// INT64SLICE.
func (v Value) AsFloat64Slice() []float64 {
if s, ok := v.slice.(*[]float64); ok {
return *s
}
return nil
}
// AsString returns the string value. Make sure that the Value's type // AsString returns the string value. Make sure that the Value's type
// is STRING. // is STRING.
func (v Value) AsString() string { func (v Value) AsString() string {
return v.stringly return v.stringly
} }
// AsArray returns the array Value as an interface{}. // AsStringSlice returns the []string value. Make sure that the Value's type is
func (v Value) AsArray() interface{} { // INT64SLICE.
return v.array func (v Value) AsStringSlice() []string {
if s, ok := v.slice.(*[]string); ok {
return *s
}
return nil
} }
type unknownValueType struct{} type unknownValueType struct{}
@ -160,16 +215,22 @@ type unknownValueType struct{}
// AsInterface returns Value's data as interface{}. // AsInterface returns Value's data as interface{}.
func (v Value) AsInterface() interface{} { func (v Value) AsInterface() interface{} {
switch v.Type() { switch v.Type() {
case ARRAY:
return v.AsArray()
case BOOL: case BOOL:
return v.AsBool() return v.AsBool()
case BOOLSLICE:
return v.AsBoolSlice()
case INT64: case INT64:
return v.AsInt64() return v.AsInt64()
case INT64SLICE:
return v.AsInt64Slice()
case FLOAT64: case FLOAT64:
return v.AsFloat64() return v.AsFloat64()
case FLOAT64SLICE:
return v.AsFloat64Slice()
case STRING: case STRING:
return v.stringly return v.stringly
case STRINGSLICE:
return v.AsStringSlice()
} }
return unknownValueType{} return unknownValueType{}
} }
@ -177,14 +238,20 @@ func (v Value) AsInterface() interface{} {
// Emit returns a string representation of Value's data. // Emit returns a string representation of Value's data.
func (v Value) Emit() string { func (v Value) Emit() string {
switch v.Type() { switch v.Type() {
case ARRAY: case BOOLSLICE:
return fmt.Sprint(v.array) return fmt.Sprint(*(v.slice.(*[]bool)))
case BOOL: case BOOL:
return strconv.FormatBool(v.AsBool()) return strconv.FormatBool(v.AsBool())
case INT64SLICE:
return fmt.Sprint(*(v.slice.(*[]int64)))
case INT64: case INT64:
return strconv.FormatInt(v.AsInt64(), 10) return strconv.FormatInt(v.AsInt64(), 10)
case FLOAT64SLICE:
return fmt.Sprint(*(v.slice.(*[]float64)))
case FLOAT64: case FLOAT64:
return fmt.Sprint(v.AsFloat64()) return fmt.Sprint(v.AsFloat64())
case STRINGSLICE:
return fmt.Sprint(*(v.slice.(*[]string)))
case STRING: case STRING:
return v.stringly return v.stringly
default: default:

View File

@ -16,8 +16,5 @@
Package baggage provides functionality for storing and retrieving Package baggage provides functionality for storing and retrieving
baggage items in Go context. For propagating the baggage, see the baggage items in Go context. For propagating the baggage, see the
go.opentelemetry.io/otel/propagation package. go.opentelemetry.io/otel/propagation package.
This package is currently in a Release Candidate phase. Backwards incompatible changes
may be introduced prior to v1.0.0, but we believe the current API is ready to stabilize.
*/ */
package baggage // import "go.opentelemetry.io/otel/baggage" package baggage // import "go.opentelemetry.io/otel/baggage"

View File

@ -15,9 +15,6 @@
/* /*
Package codes defines the canonical error codes used by OpenTelemetry. Package codes defines the canonical error codes used by OpenTelemetry.
This package is currently in a Release Candidate phase. Backwards incompatible changes
may be introduced prior to v1.0.0, but we believe the current API is ready to stabilize.
It conforms to [the OpenTelemetry It conforms to [the OpenTelemetry
specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#statuscanonicalcode). specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/api.md#statuscanonicalcode).
*/ */

View File

@ -16,9 +16,6 @@
Package otel provides global access to the OpenTelemetry API. The subpackages of Package otel provides global access to the OpenTelemetry API. The subpackages of
the otel package provide an implementation of the OpenTelemetry API. the otel package provide an implementation of the OpenTelemetry API.
This package is currently in a Release Candidate phase. Backwards incompatible changes
may be introduced prior to v1.0.0, but we believe the current API is ready to stabilize.
The provided API is used to instrument code and measure data about that code's The provided API is used to instrument code and measure data about that code's
performance and operation. The measured data, by default, is not processed or performance and operation. The measured data, by default, is not processed or
transmitted anywhere. An implementation of the OpenTelemetry SDK, like the transmitted anywhere. An implementation of the OpenTelemetry SDK, like the

View File

@ -25,3 +25,14 @@ type ErrorHandler interface {
// DO NOT CHANGE: any modification will not be backwards compatible and // DO NOT CHANGE: any modification will not be backwards compatible and
// must never be done outside of a new major release. // must never be done outside of a new major release.
} }
// ErrorHandlerFunc is a convenience adapter to allow the use of a function
// as an ErrorHandler.
type ErrorHandlerFunc func(error)
var _ ErrorHandler = ErrorHandlerFunc(nil)
// Handle handles the irremediable error by calling the ErrorHandlerFunc itself.
func (f ErrorHandlerFunc) Handle(err error) {
f(err)
}

View File

@ -0,0 +1,47 @@
# OpenTelemetry-Go OTLP Span Exporter
[![Go Reference](https://pkg.go.dev/badge/go.opentelemetry.io/otel/exporters/otlp/otlptrace.svg)](https://pkg.go.dev/go.opentelemetry.io/otel/exporters/otlp/otlptrace)
[OpenTelemetry Protocol Exporter](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.5.0/specification/protocol/exporter.md) implementation.
## Installation
```
go get -u go.opentelemetry.io/otel/exporters/otlp/otlptrace
```
## Examples
- [Exporter setup and examples](./otlptracehttp/example_test.go)
- [Full example sending telemetry to a local collector](../../../example/otel-collector)
## [`otlptrace`](https://pkg.go.dev/go.opentelemetry.io/otel/exporters/otlp/otlptrace)
The `otlptrace` package provides an exporter implementing the OTel span exporter interface.
This exporter is configured using a client satisfying the `otlptrace.Client` interface.
This client handles the transformation of data into wire format and the transmission of that data to the collector.
## [`otlptracegrpc`](https://pkg.go.dev/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc)
The `otlptracegrpc` package implements a client for the span exporter that sends trace telemetry data to the collector using gRPC with protobuf-encoded payloads.
## [`otlptracehttp`](https://pkg.go.dev/go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp)
The `otlptracehttp` package implements a client for the span exporter that sends trace telemetry data to the collector using HTTP with protobuf-encoded payloads.
## Configuration
### Environment Variables
The following environment variables can be used
(instead of options objects) to override the default configuration.
| Environment variable | Option | Default value |
| ------------------------------------------------------------------------ |------------------------------ | ----------------------------------- |
| `OTEL_EXPORTER_OTLP_ENDPOINT` `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | `WithEndpoint` `WithInsecure` | `https://localhost:4317` |
| `OTEL_EXPORTER_OTLP_CERTIFICATE` `OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE` | `WithTLSClientConfig` | |
| `OTEL_EXPORTER_OTLP_HEADERS` `OTEL_EXPORTER_OTLP_TRACES_HEADERS` | `WithHeaders` | |
| `OTEL_EXPORTER_OTLP_COMPRESSION` `OTEL_EXPORTER_OTLP_TRACES_COMPRESSION` | `WithCompression` | |
| `OTEL_EXPORTER_OTLP_TIMEOUT` `OTEL_EXPORTER_OTLP_TRACES_TIMEOUT` | `WithTimeout` | `10s` |
Configuration using options have precedence over the environment variables.

View File

@ -6,14 +6,13 @@ require (
github.com/cenkalti/backoff/v4 v4.1.1 github.com/cenkalti/backoff/v4 v4.1.1
github.com/google/go-cmp v0.5.6 github.com/google/go-cmp v0.5.6
github.com/stretchr/testify v1.7.0 github.com/stretchr/testify v1.7.0
go.opentelemetry.io/otel v1.0.0-RC1 go.opentelemetry.io/otel v1.0.0
go.opentelemetry.io/otel/oteltest v1.0.0-RC1 go.opentelemetry.io/otel/sdk v1.0.0
go.opentelemetry.io/otel/sdk v1.0.0-RC1 go.opentelemetry.io/otel/trace v1.0.0
go.opentelemetry.io/otel/trace v1.0.0-RC1
go.opentelemetry.io/proto/otlp v0.9.0 go.opentelemetry.io/proto/otlp v0.9.0
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013
google.golang.org/grpc v1.38.0 google.golang.org/grpc v1.40.0
google.golang.org/protobuf v1.26.0 google.golang.org/protobuf v1.27.1
) )
replace go.opentelemetry.io/otel => ../../.. replace go.opentelemetry.io/otel => ../../..
@ -22,8 +21,6 @@ replace go.opentelemetry.io/otel/sdk => ../../../sdk
replace go.opentelemetry.io/otel/metric => ../../../metric replace go.opentelemetry.io/otel/metric => ../../../metric
replace go.opentelemetry.io/otel/oteltest => ../../../oteltest
replace go.opentelemetry.io/otel/trace => ../../../trace replace go.opentelemetry.io/otel/trace => ../../../trace
replace go.opentelemetry.io/otel/bridge/opencensus => ../../../bridge/opencensus replace go.opentelemetry.io/otel/bridge/opencensus => ../../../bridge/opencensus
@ -66,12 +63,6 @@ replace go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp => ./otl
replace go.opentelemetry.io/otel/internal/metric => ../../../internal/metric replace go.opentelemetry.io/otel/internal/metric => ../../../internal/metric
replace go.opentelemetry.io/otel/exporters/metric/prometheus => ../../metric/prometheus
replace go.opentelemetry.io/otel/exporters/trace/jaeger => ../../trace/jaeger
replace go.opentelemetry.io/otel/exporters/trace/zipkin => ../../trace/zipkin
replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric => ../otlpmetric replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric => ../otlpmetric
replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc => ../otlpmetric/otlpmetricgrpc replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc => ../otlpmetric/otlpmetricgrpc
@ -79,3 +70,9 @@ replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc => ../
replace go.opentelemetry.io/otel/exporters/stdout/stdoutmetric => ../../stdout/stdoutmetric replace go.opentelemetry.io/otel/exporters/stdout/stdoutmetric => ../../stdout/stdoutmetric
replace go.opentelemetry.io/otel/exporters/stdout/stdouttrace => ../../stdout/stdouttrace replace go.opentelemetry.io/otel/exporters/stdout/stdouttrace => ../../stdout/stdouttrace
replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp => ../otlpmetric/otlpmetrichttp
replace go.opentelemetry.io/otel/bridge/opencensus/test => ../../../bridge/opencensus/test
replace go.opentelemetry.io/otel/example/fib => ../../../example/fib

View File

@ -1,19 +1,24 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ= github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ=
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@ -28,6 +33,7 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
@ -46,10 +52,12 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.opentelemetry.io/proto/otlp v0.9.0 h1:C0g6TWmQYvjKRnljRULLWUVJGy8Uvu0NEL/5frY2/t4= go.opentelemetry.io/proto/otlp v0.9.0 h1:C0g6TWmQYvjKRnljRULLWUVJGy8Uvu0NEL/5frY2/t4=
go.opentelemetry.io/proto/otlp v0.9.0/go.mod h1:1vKfU9rv61e9EVGthD1zNvUbiwPcimSsOPU9brfSHJg= go.opentelemetry.io/proto/otlp v0.9.0/go.mod h1:1vKfU9rv61e9EVGthD1zNvUbiwPcimSsOPU9brfSHJg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@ -75,8 +83,9 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw=
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@ -98,9 +107,10 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0= google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -111,8 +121,9 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@ -16,14 +16,12 @@ package connection
import ( import (
"context" "context"
"fmt"
"math/rand" "math/rand"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time" "time"
"unsafe" "unsafe"
"github.com/cenkalti/backoff/v4"
"google.golang.org/genproto/googleapis/rpc/errdetails" "google.golang.org/genproto/googleapis/rpc/errdetails"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
@ -31,6 +29,7 @@ import (
"google.golang.org/grpc/encoding/gzip" "google.golang.org/grpc/encoding/gzip"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig" "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/retry"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/metadata" "google.golang.org/grpc/metadata"
@ -48,6 +47,7 @@ type Connection struct {
// these fields are read-only after constructor is finished // these fields are read-only after constructor is finished
cfg otlpconfig.Config cfg otlpconfig.Config
SCfg otlpconfig.SignalConfig SCfg otlpconfig.SignalConfig
requestFunc retry.RequestFunc
metadata metadata.MD metadata metadata.MD
newConnectionHandler func(cc *grpc.ClientConn) newConnectionHandler func(cc *grpc.ClientConn)
@ -66,6 +66,7 @@ func NewConnection(cfg otlpconfig.Config, sCfg otlpconfig.SignalConfig, handler
c := new(Connection) c := new(Connection)
c.newConnectionHandler = handler c.newConnectionHandler = handler
c.cfg = cfg c.cfg = cfg
c.requestFunc = cfg.RetryConfig.RequestFunc(evaluate)
c.SCfg = sCfg c.SCfg = sCfg
if len(c.SCfg.Headers) > 0 { if len(c.SCfg.Headers) > 0 {
c.metadata = metadata.New(c.SCfg.Headers) c.metadata = metadata.New(c.SCfg.Headers)
@ -287,88 +288,24 @@ func (c *Connection) ContextWithStop(ctx context.Context) (context.Context, cont
} }
func (c *Connection) DoRequest(ctx context.Context, fn func(context.Context) error) error { func (c *Connection) DoRequest(ctx context.Context, fn func(context.Context) error) error {
expBackoff := newExponentialBackoff(c.cfg.RetrySettings) ctx, cancel := c.ContextWithStop(ctx)
defer cancel()
for { return c.requestFunc(ctx, func(ctx context.Context) error {
err := fn(ctx) err := fn(ctx)
if err == nil { // nil is converted to OK.
// request succeeded. if status.Code(err) == codes.OK {
// Success.
return nil return nil
} }
if !c.cfg.RetrySettings.Enabled {
return err return err
} })
// We have an error, check gRPC status code.
st := status.Convert(err)
if st.Code() == codes.OK {
// Not really an error, still success.
return nil
}
// Now, this is this a real error.
if !shouldRetry(st.Code()) {
// It is not a retryable error, we should not retry.
return err
}
// Need to retry.
throttle := getThrottleDuration(st)
backoffDelay := expBackoff.NextBackOff()
if backoffDelay == backoff.Stop {
// throw away the batch
err = fmt.Errorf("max elapsed time expired: %w", err)
return err
}
var delay time.Duration
if backoffDelay > throttle {
delay = backoffDelay
} else {
if expBackoff.GetElapsedTime()+throttle > expBackoff.MaxElapsedTime {
err = fmt.Errorf("max elapsed time expired when respecting server throttle: %w", err)
return err
}
// Respect server throttling.
delay = throttle
}
// back-off, but get interrupted when shutting down or request is cancelled or timed out.
err = func() error {
dt := time.NewTimer(delay)
defer dt.Stop()
select {
case <-ctx.Done():
return ctx.Err()
case <-c.stopCh:
return fmt.Errorf("interrupted due to shutdown: %w", err)
case <-dt.C:
}
return nil
}()
if err != nil {
return err
}
}
} }
func shouldRetry(code codes.Code) bool { // evaluate returns if err is retry-able and a duration to wait for if an
switch code { // explicit throttle time is included in err.
case codes.OK: func evaluate(err error) (bool, time.Duration) {
// Success. This function should not be called for this code, the best we s := status.Convert(err)
// can do is tell the caller not to retry. switch s.Code() {
return false
case codes.Canceled, case codes.Canceled,
codes.DeadlineExceeded, codes.DeadlineExceeded,
codes.ResourceExhausted, codes.ResourceExhausted,
@ -376,54 +313,20 @@ func shouldRetry(code codes.Code) bool {
codes.OutOfRange, codes.OutOfRange,
codes.Unavailable, codes.Unavailable,
codes.DataLoss: codes.DataLoss:
// These are retryable errors. return true, throttleDelay(s)
return true
case codes.Unknown,
codes.InvalidArgument,
codes.Unauthenticated,
codes.PermissionDenied,
codes.NotFound,
codes.AlreadyExists,
codes.FailedPrecondition,
codes.Unimplemented,
codes.Internal:
// These are fatal errors, don't retry.
return false
default:
// Don't retry on unknown codes.
return false
} }
// Not a retry-able error.
return false, 0
} }
func getThrottleDuration(status *status.Status) time.Duration { // throttleDelay returns a duration to wait for if an explicit throttle time
// See if throttling information is available. // is included in the response status.
func throttleDelay(status *status.Status) time.Duration {
for _, detail := range status.Details() { for _, detail := range status.Details() {
if t, ok := detail.(*errdetails.RetryInfo); ok { if t, ok := detail.(*errdetails.RetryInfo); ok {
if t.RetryDelay.Seconds > 0 || t.RetryDelay.Nanos > 0 { return t.RetryDelay.AsDuration()
// We are throttled. Wait before retrying as requested by the server.
return time.Duration(t.RetryDelay.Seconds)*time.Second + time.Duration(t.RetryDelay.Nanos)*time.Nanosecond
}
return 0
} }
} }
return 0 return 0
} }
func newExponentialBackoff(rs otlpconfig.RetrySettings) *backoff.ExponentialBackOff {
// Do not use NewExponentialBackOff since it calls Reset and the code here must
// call Reset after changing the InitialInterval (this saves an unnecessary call to Now).
expBackoff := &backoff.ExponentialBackOff{
InitialInterval: rs.InitialInterval,
RandomizationFactor: backoff.DefaultRandomizationFactor,
Multiplier: backoff.DefaultMultiplier,
MaxInterval: rs.MaxInterval,
MaxElapsedTime: rs.MaxElapsedTime,
Stop: backoff.Stop,
Clock: backoff.SystemClock,
}
expBackoff.Reset()
return expBackoff
}

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package otlpconfig // import "go.opentelemetry.io/otel/exporters/otlp/internal/otlpconfig" package otlpconfig // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig"
import ( import (
"crypto/tls" "crypto/tls"
@ -21,34 +21,19 @@ import (
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/retry"
) )
const ( const (
// DefaultMaxAttempts describes how many times the driver
// should retry the sending of the payload in case of a
// retryable error.
DefaultMaxAttempts int = 5
// DefaultTracesPath is a default URL path for endpoint that // DefaultTracesPath is a default URL path for endpoint that
// receives spans. // receives spans.
DefaultTracesPath string = "/v1/traces" DefaultTracesPath string = "/v1/traces"
// DefaultBackoff is a default base backoff time used in the
// exponential backoff strategy.
DefaultBackoff time.Duration = 300 * time.Millisecond
// DefaultTimeout is a default max waiting time for the backend to process // DefaultTimeout is a default max waiting time for the backend to process
// each span batch. // each span batch.
DefaultTimeout time.Duration = 10 * time.Second DefaultTimeout time.Duration = 10 * time.Second
) )
var (
// defaultRetrySettings is a default settings for the retry policy.
defaultRetrySettings = RetrySettings{
Enabled: true,
InitialInterval: 5 * time.Second,
MaxInterval: 30 * time.Second,
MaxElapsedTime: time.Minute,
}
)
type ( type (
SignalConfig struct { SignalConfig struct {
Endpoint string Endpoint string
@ -67,15 +52,12 @@ type (
// Signal specific configurations // Signal specific configurations
Traces SignalConfig Traces SignalConfig
// HTTP configurations RetryConfig retry.Config
MaxAttempts int
Backoff time.Duration
// gRPC configurations // gRPC configurations
ReconnectionPeriod time.Duration ReconnectionPeriod time.Duration
ServiceConfig string ServiceConfig string
DialOptions []grpc.DialOption DialOptions []grpc.DialOption
RetrySettings RetrySettings
} }
) )
@ -87,9 +69,7 @@ func NewDefaultConfig() Config {
Compression: NoCompression, Compression: NoCompression,
Timeout: DefaultTimeout, Timeout: DefaultTimeout,
}, },
MaxAttempts: DefaultMaxAttempts, RetryConfig: retry.DefaultConfig,
Backoff: DefaultBackoff,
RetrySettings: defaultRetrySettings,
} }
return c return c
@ -219,9 +199,9 @@ func WithURLPath(urlPath string) GenericOption {
}) })
} }
func WithRetry(settings RetrySettings) GenericOption { func WithRetry(rc retry.Config) GenericOption {
return newGenericOption(func(cfg *Config) { return newGenericOption(func(cfg *Config) {
cfg.RetrySettings = settings cfg.RetryConfig = rc
}) })
} }
@ -256,15 +236,3 @@ func WithTimeout(duration time.Duration) GenericOption {
cfg.Traces.Timeout = duration cfg.Traces.Timeout = duration
}) })
} }
func WithMaxAttempts(maxAttempts int) GenericOption {
return newGenericOption(func(cfg *Config) {
cfg.MaxAttempts = maxAttempts
})
}
func WithBackoff(duration time.Duration) GenericOption {
return newGenericOption(func(cfg *Config) {
cfg.Backoff = duration
})
}

View File

@ -14,8 +14,6 @@
package otlpconfig // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig" package otlpconfig // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig"
import "time"
const ( const (
// DefaultCollectorPort is the port the Exporter will attempt connect to // DefaultCollectorPort is the port the Exporter will attempt connect to
// if no collector port is provided. // if no collector port is provided.
@ -47,18 +45,3 @@ const (
// MarshalJSON tells the driver to send using json format. // MarshalJSON tells the driver to send using json format.
MarshalJSON MarshalJSON
) )
// RetrySettings defines configuration for retrying batches in case of export failure
// using an exponential backoff.
type RetrySettings struct {
// Enabled indicates whether to not retry sending batches in case of export failure.
Enabled bool
// InitialInterval the time to wait after the first failure before retrying.
InitialInterval time.Duration
// MaxInterval is the upper bound on backoff interval. Once this value is reached the delay between
// consecutive retries will always be `MaxInterval`.
MaxInterval time.Duration
// MaxElapsedTime is the maximum amount of time (including retries) spent trying to send a request/batch.
// Once this value is reached, the data is discarded.
MaxElapsedTime time.Duration
}

View File

@ -0,0 +1,130 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package retry
import (
"context"
"fmt"
"time"
"github.com/cenkalti/backoff/v4"
)
// DefaultConfig are the recommended defaults to use.
var DefaultConfig = Config{
Enabled: true,
InitialInterval: 5 * time.Second,
MaxInterval: 30 * time.Second,
MaxElapsedTime: time.Minute,
}
// Config defines configuration for retrying batches in case of export failure
// using an exponential backoff.
type Config struct {
// Enabled indicates whether to not retry sending batches in case of
// export failure.
Enabled bool
// InitialInterval the time to wait after the first failure before
// retrying.
InitialInterval time.Duration
// MaxInterval is the upper bound on backoff interval. Once this value is
// reached the delay between consecutive retries will always be
// `MaxInterval`.
MaxInterval time.Duration
// MaxElapsedTime is the maximum amount of time (including retries) spent
// trying to send a request/batch. Once this value is reached, the data
// is discarded.
MaxElapsedTime time.Duration
}
// RequestFunc wraps a request with retry logic.
type RequestFunc func(context.Context, func(context.Context) error) error
// EvaluateFunc returns if an error is retry-able and if an explicit throttle
// duration should be honored that was included in the error.
type EvaluateFunc func(error) (bool, time.Duration)
func (c Config) RequestFunc(evaluate EvaluateFunc) RequestFunc {
if !c.Enabled {
return func(ctx context.Context, fn func(context.Context) error) error {
return fn(ctx)
}
}
// Do not use NewExponentialBackOff since it calls Reset and the code here
// must call Reset after changing the InitialInterval (this saves an
// unnecessary call to Now).
b := &backoff.ExponentialBackOff{
InitialInterval: c.InitialInterval,
RandomizationFactor: backoff.DefaultRandomizationFactor,
Multiplier: backoff.DefaultMultiplier,
MaxInterval: c.MaxInterval,
MaxElapsedTime: c.MaxElapsedTime,
Stop: backoff.Stop,
Clock: backoff.SystemClock,
}
b.Reset()
return func(ctx context.Context, fn func(context.Context) error) error {
for {
err := fn(ctx)
if err == nil {
return nil
}
retryable, throttle := evaluate(err)
if !retryable {
return err
}
bOff := b.NextBackOff()
if bOff == backoff.Stop {
return fmt.Errorf("max retry time elapsed: %w", err)
}
// Wait for the greater of the backoff or throttle delay.
var delay time.Duration
if bOff > throttle {
delay = bOff
} else {
elapsed := b.GetElapsedTime()
if b.MaxElapsedTime != 0 && elapsed+throttle > b.MaxElapsedTime {
return fmt.Errorf("max retry time would elapse: %w", err)
}
delay = throttle
}
if err := waitFunc(ctx, delay); err != nil {
return err
}
}
}
}
// Allow override for testing.
var waitFunc = wait
func wait(ctx context.Context, delay time.Duration) error {
timer := time.NewTimer(delay)
defer timer.Stop()
select {
case <-ctx.Done():
return ctx.Err()
case <-timer.C:
}
return nil
}

View File

@ -15,127 +15,145 @@
package tracetransform package tracetransform
import ( import (
"reflect"
"go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/attribute"
commonpb "go.opentelemetry.io/proto/otlp/common/v1" commonpb "go.opentelemetry.io/proto/otlp/common/v1"
"go.opentelemetry.io/otel/sdk/resource" "go.opentelemetry.io/otel/sdk/resource"
) )
// Attributes transforms a slice of KeyValues into a slice of OTLP attribute key-values. // KeyValues transforms a slice of attribute KeyValues into OTLP key-values.
func Attributes(attrs []attribute.KeyValue) []*commonpb.KeyValue { func KeyValues(attrs []attribute.KeyValue) []*commonpb.KeyValue {
if len(attrs) == 0 { if len(attrs) == 0 {
return nil return nil
} }
out := make([]*commonpb.KeyValue, 0, len(attrs)) out := make([]*commonpb.KeyValue, 0, len(attrs))
for _, kv := range attrs { for _, kv := range attrs {
out = append(out, toAttribute(kv)) out = append(out, KeyValue(kv))
} }
return out return out
} }
// ResourceAttributes transforms a Resource into a slice of OTLP attribute key-values. // Iterator transforms an attribute iterator into OTLP key-values.
func ResourceAttributes(resource *resource.Resource) []*commonpb.KeyValue { func Iterator(iter attribute.Iterator) []*commonpb.KeyValue {
if resource.Len() == 0 { l := iter.Len()
if l == 0 {
return nil return nil
} }
out := make([]*commonpb.KeyValue, 0, resource.Len()) out := make([]*commonpb.KeyValue, 0, l)
for iter := resource.Iter(); iter.Next(); { for iter.Next() {
out = append(out, toAttribute(iter.Attribute())) out = append(out, KeyValue(iter.Attribute()))
} }
return out return out
} }
func toAttribute(v attribute.KeyValue) *commonpb.KeyValue { // ResourceAttributes transforms a Resource OTLP key-values.
result := &commonpb.KeyValue{ func ResourceAttributes(resource *resource.Resource) []*commonpb.KeyValue {
Key: string(v.Key), return Iterator(resource.Iter())
Value: new(commonpb.AnyValue), }
}
switch v.Value.Type() { // KeyValue transforms an attribute KeyValue into an OTLP key-value.
func KeyValue(kv attribute.KeyValue) *commonpb.KeyValue {
return &commonpb.KeyValue{Key: string(kv.Key), Value: Value(kv.Value)}
}
// Value transforms an attribute Value into an OTLP AnyValue.
func Value(v attribute.Value) *commonpb.AnyValue {
av := new(commonpb.AnyValue)
switch v.Type() {
case attribute.BOOL: case attribute.BOOL:
result.Value.Value = &commonpb.AnyValue_BoolValue{ av.Value = &commonpb.AnyValue_BoolValue{
BoolValue: v.Value.AsBool(), BoolValue: v.AsBool(),
}
case attribute.BOOLSLICE:
av.Value = &commonpb.AnyValue_ArrayValue{
ArrayValue: &commonpb.ArrayValue{
Values: boolSliceValues(v.AsBoolSlice()),
},
} }
case attribute.INT64: case attribute.INT64:
result.Value.Value = &commonpb.AnyValue_IntValue{ av.Value = &commonpb.AnyValue_IntValue{
IntValue: v.Value.AsInt64(), IntValue: v.AsInt64(),
}
case attribute.INT64SLICE:
av.Value = &commonpb.AnyValue_ArrayValue{
ArrayValue: &commonpb.ArrayValue{
Values: int64SliceValues(v.AsInt64Slice()),
},
} }
case attribute.FLOAT64: case attribute.FLOAT64:
result.Value.Value = &commonpb.AnyValue_DoubleValue{ av.Value = &commonpb.AnyValue_DoubleValue{
DoubleValue: v.Value.AsFloat64(), DoubleValue: v.AsFloat64(),
}
case attribute.FLOAT64SLICE:
av.Value = &commonpb.AnyValue_ArrayValue{
ArrayValue: &commonpb.ArrayValue{
Values: float64SliceValues(v.AsFloat64Slice()),
},
} }
case attribute.STRING: case attribute.STRING:
result.Value.Value = &commonpb.AnyValue_StringValue{ av.Value = &commonpb.AnyValue_StringValue{
StringValue: v.Value.AsString(), StringValue: v.AsString(),
} }
case attribute.ARRAY: case attribute.STRINGSLICE:
result.Value.Value = &commonpb.AnyValue_ArrayValue{ av.Value = &commonpb.AnyValue_ArrayValue{
ArrayValue: &commonpb.ArrayValue{ ArrayValue: &commonpb.ArrayValue{
Values: arrayValues(v), Values: stringSliceValues(v.AsStringSlice()),
}, },
} }
default: default:
result.Value.Value = &commonpb.AnyValue_StringValue{ av.Value = &commonpb.AnyValue_StringValue{
StringValue: "INVALID", StringValue: "INVALID",
} }
} }
return result return av
} }
func arrayValues(kv attribute.KeyValue) []*commonpb.AnyValue { func boolSliceValues(vals []bool) []*commonpb.AnyValue {
a := kv.Value.AsArray() converted := make([]*commonpb.AnyValue, len(vals))
aType := reflect.TypeOf(a) for i, v := range vals {
var valueFunc func(reflect.Value) *commonpb.AnyValue converted[i] = &commonpb.AnyValue{
switch aType.Elem().Kind() {
case reflect.Bool:
valueFunc = func(v reflect.Value) *commonpb.AnyValue {
return &commonpb.AnyValue{
Value: &commonpb.AnyValue_BoolValue{ Value: &commonpb.AnyValue_BoolValue{
BoolValue: v.Bool(), BoolValue: v,
}, },
} }
} }
case reflect.Int, reflect.Int64: return converted
valueFunc = func(v reflect.Value) *commonpb.AnyValue { }
return &commonpb.AnyValue{
Value: &commonpb.AnyValue_IntValue{ func int64SliceValues(vals []int64) []*commonpb.AnyValue {
IntValue: v.Int(), converted := make([]*commonpb.AnyValue, len(vals))
}, for i, v := range vals {
} converted[i] = &commonpb.AnyValue{
} Value: &commonpb.AnyValue_IntValue{
case reflect.Uintptr: IntValue: v,
valueFunc = func(v reflect.Value) *commonpb.AnyValue { },
return &commonpb.AnyValue{ }
Value: &commonpb.AnyValue_IntValue{ }
IntValue: int64(v.Uint()), return converted
}, }
}
} func float64SliceValues(vals []float64) []*commonpb.AnyValue {
case reflect.Float64: converted := make([]*commonpb.AnyValue, len(vals))
valueFunc = func(v reflect.Value) *commonpb.AnyValue { for i, v := range vals {
return &commonpb.AnyValue{ converted[i] = &commonpb.AnyValue{
Value: &commonpb.AnyValue_DoubleValue{ Value: &commonpb.AnyValue_DoubleValue{
DoubleValue: v.Float(), DoubleValue: v,
}, },
} }
} }
case reflect.String: return converted
valueFunc = func(v reflect.Value) *commonpb.AnyValue { }
return &commonpb.AnyValue{
Value: &commonpb.AnyValue_StringValue{ func stringSliceValues(vals []string) []*commonpb.AnyValue {
StringValue: v.String(), converted := make([]*commonpb.AnyValue, len(vals))
}, for i, v := range vals {
} converted[i] = &commonpb.AnyValue{
} Value: &commonpb.AnyValue_StringValue{
} StringValue: v,
},
results := make([]*commonpb.AnyValue, aType.Len()) }
for i, aValue := 0, reflect.ValueOf(a); i < aValue.Len(); i++ { }
results[i] = valueFunc(aValue.Index(i)) return converted
}
return results
} }

View File

@ -60,6 +60,7 @@ func Spans(sdl []tracesdk.ReadOnlySpan) []*tracepb.ResourceSpans {
ils = &tracepb.InstrumentationLibrarySpans{ ils = &tracepb.InstrumentationLibrarySpans{
InstrumentationLibrary: InstrumentationLibrary(sd.InstrumentationLibrary()), InstrumentationLibrary: InstrumentationLibrary(sd.InstrumentationLibrary()),
Spans: []*tracepb.Span{}, Spans: []*tracepb.Span{},
SchemaUrl: sd.InstrumentationLibrary().SchemaURL,
} }
} }
ils.Spans = append(ils.Spans, span(sd)) ils.Spans = append(ils.Spans, span(sd))
@ -72,6 +73,7 @@ func Spans(sdl []tracesdk.ReadOnlySpan) []*tracepb.ResourceSpans {
rs = &tracepb.ResourceSpans{ rs = &tracepb.ResourceSpans{
Resource: Resource(sd.Resource()), Resource: Resource(sd.Resource()),
InstrumentationLibrarySpans: []*tracepb.InstrumentationLibrarySpans{ils}, InstrumentationLibrarySpans: []*tracepb.InstrumentationLibrarySpans{ils},
SchemaUrl: sd.Resource().SchemaURL(),
} }
rsm[rKey] = rs rsm[rKey] = rs
continue continue
@ -114,7 +116,7 @@ func span(sd tracesdk.ReadOnlySpan) *tracepb.Span {
Links: links(sd.Links()), Links: links(sd.Links()),
Kind: spanKind(sd.SpanKind()), Kind: spanKind(sd.SpanKind()),
Name: sd.Name(), Name: sd.Name(),
Attributes: Attributes(sd.Attributes()), Attributes: KeyValues(sd.Attributes()),
Events: spanEvents(sd.Events()), Events: spanEvents(sd.Events()),
DroppedAttributesCount: uint32(sd.DroppedAttributes()), DroppedAttributesCount: uint32(sd.DroppedAttributes()),
DroppedEventsCount: uint32(sd.DroppedEvents()), DroppedEventsCount: uint32(sd.DroppedEvents()),
@ -132,10 +134,12 @@ func span(sd tracesdk.ReadOnlySpan) *tracepb.Span {
func status(status codes.Code, message string) *tracepb.Status { func status(status codes.Code, message string) *tracepb.Status {
var c tracepb.Status_StatusCode var c tracepb.Status_StatusCode
switch status { switch status {
case codes.Ok:
c = tracepb.Status_STATUS_CODE_OK
case codes.Error: case codes.Error:
c = tracepb.Status_STATUS_CODE_ERROR c = tracepb.Status_STATUS_CODE_ERROR
default: default:
c = tracepb.Status_STATUS_CODE_OK c = tracepb.Status_STATUS_CODE_UNSET
} }
return &tracepb.Status{ return &tracepb.Status{
Code: c, Code: c,
@ -144,7 +148,7 @@ func status(status codes.Code, message string) *tracepb.Status {
} }
// links transforms span Links to OTLP span links. // links transforms span Links to OTLP span links.
func links(links []trace.Link) []*tracepb.Span_Link { func links(links []tracesdk.Link) []*tracepb.Span_Link {
if len(links) == 0 { if len(links) == 0 {
return nil return nil
} }
@ -161,7 +165,7 @@ func links(links []trace.Link) []*tracepb.Span_Link {
sl = append(sl, &tracepb.Span_Link{ sl = append(sl, &tracepb.Span_Link{
TraceId: tid[:], TraceId: tid[:],
SpanId: sid[:], SpanId: sid[:],
Attributes: Attributes(otLink.Attributes), Attributes: KeyValues(otLink.Attributes),
}) })
} }
return sl return sl
@ -190,7 +194,7 @@ func spanEvents(es []tracesdk.Event) []*tracepb.Span_Event {
&tracepb.Span_Event{ &tracepb.Span_Event{
Name: e.Name, Name: e.Name,
TimeUnixNano: uint64(e.Time.UnixNano()), TimeUnixNano: uint64(e.Time.UnixNano()),
Attributes: Attributes(e.Attributes), Attributes: KeyValues(e.Attributes),
// TODO (rghetia) : Add Drop Counts when supported. // TODO (rghetia) : Add Drop Counts when supported.
}, },
) )

View File

@ -4,13 +4,11 @@ go 1.15
require ( require (
github.com/stretchr/testify v1.7.0 github.com/stretchr/testify v1.7.0
go.opentelemetry.io/otel v1.0.0-RC1 go.opentelemetry.io/otel v1.0.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.0-RC1 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.0
go.opentelemetry.io/otel/sdk v1.0.0-RC1 go.opentelemetry.io/otel/sdk v1.0.0
go.opentelemetry.io/proto/otlp v0.9.0 go.opentelemetry.io/proto/otlp v0.9.0
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 google.golang.org/grpc v1.40.0
google.golang.org/grpc v1.38.0
google.golang.org/protobuf v1.26.0
) )
replace go.opentelemetry.io/otel => ../../../.. replace go.opentelemetry.io/otel => ../../../..
@ -21,8 +19,6 @@ replace go.opentelemetry.io/otel/exporters/otlp/otlptrace => ../
replace go.opentelemetry.io/otel/metric => ../../../../metric replace go.opentelemetry.io/otel/metric => ../../../../metric
replace go.opentelemetry.io/otel/oteltest => ../../../../oteltest
replace go.opentelemetry.io/otel/trace => ../../../../trace replace go.opentelemetry.io/otel/trace => ../../../../trace
replace go.opentelemetry.io/otel/bridge/opencensus => ../../../../bridge/opencensus replace go.opentelemetry.io/otel/bridge/opencensus => ../../../../bridge/opencensus
@ -63,12 +59,6 @@ replace go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp => ../ot
replace go.opentelemetry.io/otel/internal/metric => ../../../../internal/metric replace go.opentelemetry.io/otel/internal/metric => ../../../../internal/metric
replace go.opentelemetry.io/otel/exporters/metric/prometheus => ../../../metric/prometheus
replace go.opentelemetry.io/otel/exporters/trace/jaeger => ../../../trace/jaeger
replace go.opentelemetry.io/otel/exporters/trace/zipkin => ../../../trace/zipkin
replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric => ../../otlpmetric replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric => ../../otlpmetric
replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc => ../../otlpmetric/otlpmetricgrpc replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc => ../../otlpmetric/otlpmetricgrpc
@ -76,3 +66,9 @@ replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc => ../
replace go.opentelemetry.io/otel/exporters/stdout/stdoutmetric => ../../../stdout/stdoutmetric replace go.opentelemetry.io/otel/exporters/stdout/stdoutmetric => ../../../stdout/stdoutmetric
replace go.opentelemetry.io/otel/exporters/stdout/stdouttrace => ../../../stdout/stdouttrace replace go.opentelemetry.io/otel/exporters/stdout/stdouttrace => ../../../stdout/stdouttrace
replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp => ../../otlpmetric/otlpmetrichttp
replace go.opentelemetry.io/otel/bridge/opencensus/test => ../../../../bridge/opencensus/test
replace go.opentelemetry.io/otel/example/fib => ../../../../example/fib

View File

@ -1,19 +1,24 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ= github.com/cenkalti/backoff/v4 v4.1.1 h1:G2HAfAmvm/GcKan2oOQpBXOd2tT2G57ZnZGWa1PxPBQ=
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@ -28,6 +33,7 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
@ -46,10 +52,12 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.opentelemetry.io/proto/otlp v0.9.0 h1:C0g6TWmQYvjKRnljRULLWUVJGy8Uvu0NEL/5frY2/t4= go.opentelemetry.io/proto/otlp v0.9.0 h1:C0g6TWmQYvjKRnljRULLWUVJGy8Uvu0NEL/5frY2/t4=
go.opentelemetry.io/proto/otlp v0.9.0/go.mod h1:1vKfU9rv61e9EVGthD1zNvUbiwPcimSsOPU9brfSHJg= go.opentelemetry.io/proto/otlp v0.9.0/go.mod h1:1vKfU9rv61e9EVGthD1zNvUbiwPcimSsOPU9brfSHJg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@ -75,8 +83,9 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw=
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@ -98,9 +107,10 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0= google.golang.org/grpc v1.40.0 h1:AGJ0Ih4mHjSeibYkFGh1dD9KJ/eOtZ93I6hoHhukQ5Q=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -111,8 +121,9 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@ -20,6 +20,7 @@ import (
"go.opentelemetry.io/otel" "go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig" "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig"
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/retry"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials"
@ -30,9 +31,9 @@ type Option interface {
applyGRPCOption(*otlpconfig.Config) applyGRPCOption(*otlpconfig.Config)
} }
// RetrySettings defines configuration for retrying batches in case of export failure // RetryConfig defines configuration for retrying batches in case of export
// using an exponential backoff. // failure using an exponential backoff.
type RetrySettings otlpconfig.RetrySettings type RetryConfig retry.Config
type wrappedOption struct { type wrappedOption struct {
otlpconfig.GRPCOption otlpconfig.GRPCOption
@ -121,12 +122,11 @@ func WithTimeout(duration time.Duration) Option {
return wrappedOption{otlpconfig.WithTimeout(duration)} return wrappedOption{otlpconfig.WithTimeout(duration)}
} }
// WithRetry configures the retry policy for transient errors that may occurs when // WithRetry configures the retry policy for transient errors that may occurs
// exporting traces. An exponential back-off algorithm is used to // when exporting traces. An exponential back-off algorithm is used to ensure
// ensure endpoints are not overwhelmed with retries. If unset, the default // endpoints are not overwhelmed with retries. If unset, the default retry
// ensure endpoints are not overwhelmed with retries. If unset, the default // policy will retry after 5 seconds and increase exponentially after each
// retry policy will retry after 5 seconds and increase exponentially after each
// error for a total of 1 minute. // error for a total of 1 minute.
func WithRetry(settings RetrySettings) Option { func WithRetry(settings RetryConfig) Option {
return wrappedOption{otlpconfig.WithRetry(otlpconfig.RetrySettings(settings))} return wrappedOption{otlpconfig.WithRetry(retry.Config(settings))}
} }

View File

@ -5,8 +5,7 @@ go 1.15
require ( require (
github.com/google/go-cmp v0.5.6 github.com/google/go-cmp v0.5.6
github.com/stretchr/testify v1.7.0 github.com/stretchr/testify v1.7.0
go.opentelemetry.io/otel/oteltest v1.0.0-RC1 go.opentelemetry.io/otel/trace v1.0.0
go.opentelemetry.io/otel/trace v1.0.0-RC1
) )
replace go.opentelemetry.io/otel => ./ replace go.opentelemetry.io/otel => ./
@ -43,8 +42,6 @@ replace go.opentelemetry.io/otel/internal/metric => ./internal/metric
replace go.opentelemetry.io/otel/metric => ./metric replace go.opentelemetry.io/otel/metric => ./metric
replace go.opentelemetry.io/otel/oteltest => ./oteltest
replace go.opentelemetry.io/otel/sdk/export/metric => ./sdk/export/metric replace go.opentelemetry.io/otel/sdk/export/metric => ./sdk/export/metric
replace go.opentelemetry.io/otel/sdk/metric => ./sdk/metric replace go.opentelemetry.io/otel/sdk/metric => ./sdk/metric
@ -59,12 +56,6 @@ replace go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc => ./exp
replace go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp => ./exporters/otlp/otlptrace/otlptracehttp replace go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp => ./exporters/otlp/otlptrace/otlptracehttp
replace go.opentelemetry.io/otel/exporters/metric/prometheus => ./exporters/metric/prometheus
replace go.opentelemetry.io/otel/exporters/trace/jaeger => ./exporters/trace/jaeger
replace go.opentelemetry.io/otel/exporters/trace/zipkin => ./exporters/trace/zipkin
replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric => ./exporters/otlp/otlpmetric replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric => ./exporters/otlp/otlpmetric
replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc => ./exporters/otlp/otlpmetric/otlpmetricgrpc replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc => ./exporters/otlp/otlpmetric/otlpmetricgrpc
@ -72,3 +63,9 @@ replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc => ./e
replace go.opentelemetry.io/otel/exporters/stdout/stdoutmetric => ./exporters/stdout/stdoutmetric replace go.opentelemetry.io/otel/exporters/stdout/stdoutmetric => ./exporters/stdout/stdoutmetric
replace go.opentelemetry.io/otel/exporters/stdout/stdouttrace => ./exporters/stdout/stdouttrace replace go.opentelemetry.io/otel/exporters/stdout/stdouttrace => ./exporters/stdout/stdouttrace
replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp => ./exporters/otlp/otlpmetric/otlpmetrichttp
replace go.opentelemetry.io/otel/bridge/opencensus/test => ./bridge/opencensus/test
replace go.opentelemetry.io/otel/example/fib => ./example/fib

View File

@ -26,36 +26,42 @@ var (
// throughout an OpenTelemetry instrumented project. When a user // throughout an OpenTelemetry instrumented project. When a user
// specified ErrorHandler is registered (`SetErrorHandler`) all calls to // specified ErrorHandler is registered (`SetErrorHandler`) all calls to
// `Handle` and will be delegated to the registered ErrorHandler. // `Handle` and will be delegated to the registered ErrorHandler.
globalErrorHandler = &loggingErrorHandler{ globalErrorHandler = defaultErrorHandler()
l: log.New(os.Stderr, "", log.LstdFlags),
}
// delegateErrorHandlerOnce ensures that a user provided ErrorHandler is // delegateErrorHandlerOnce ensures that a user provided ErrorHandler is
// only ever registered once. // only ever registered once.
delegateErrorHandlerOnce sync.Once delegateErrorHandlerOnce sync.Once
// Comiple time check that loggingErrorHandler implements ErrorHandler. // Compile-time check that delegator implements ErrorHandler.
_ ErrorHandler = (*loggingErrorHandler)(nil) _ ErrorHandler = (*delegator)(nil)
) )
// loggingErrorHandler logs all errors to STDERR. type holder struct {
type loggingErrorHandler struct { eh ErrorHandler
}
func defaultErrorHandler() *atomic.Value {
v := &atomic.Value{}
v.Store(holder{eh: &delegator{l: log.New(os.Stderr, "", log.LstdFlags)}})
return v
}
// delegator logs errors if no delegate is set, otherwise they are delegated.
type delegator struct {
delegate atomic.Value delegate atomic.Value
l *log.Logger l *log.Logger
} }
// setDelegate sets the ErrorHandler delegate if one is not already set. // setDelegate sets the ErrorHandler delegate.
func (h *loggingErrorHandler) setDelegate(d ErrorHandler) { func (h *delegator) setDelegate(d ErrorHandler) {
if h.delegate.Load() != nil { // It is critical this is guarded with delegateErrorHandlerOnce, if it is
// Delegate already registered // called again with a different concrete type it will panic.
return
}
h.delegate.Store(d) h.delegate.Store(d)
} }
// Handle implements ErrorHandler. // Handle logs err if no delegate is set, otherwise it is delegated.
func (h *loggingErrorHandler) Handle(err error) { func (h *delegator) Handle(err error) {
if d := h.delegate.Load(); d != nil { if d := h.delegate.Load(); d != nil {
d.(ErrorHandler).Handle(err) d.(ErrorHandler).Handle(err)
return return
@ -63,27 +69,39 @@ func (h *loggingErrorHandler) Handle(err error) {
h.l.Print(err) h.l.Print(err)
} }
// GetErrorHandler returns the global ErrorHandler instance. If no ErrorHandler // GetErrorHandler returns the global ErrorHandler instance.
// instance has been set (`SetErrorHandler`), the default ErrorHandler which //
// logs errors to STDERR is returned. // The default ErrorHandler instance returned will log all errors to STDERR
// until an override ErrorHandler is set with SetErrorHandler. All
// ErrorHandler returned prior to this will automatically forward errors to
// the set instance instead of logging.
//
// Subsequent calls to SetErrorHandler after the first will not forward errors
// to the new ErrorHandler for prior returned instances.
func GetErrorHandler() ErrorHandler { func GetErrorHandler() ErrorHandler {
return globalErrorHandler return globalErrorHandler.Load().(holder).eh
} }
// SetErrorHandler sets the global ErrorHandler to be h. // SetErrorHandler sets the global ErrorHandler to h.
//
// The first time this is called all ErrorHandler previously returned from
// GetErrorHandler will send errors to h instead of the default logging
// ErrorHandler. Subsequent calls will set the global ErrorHandler, but not
// delegate errors to h.
func SetErrorHandler(h ErrorHandler) { func SetErrorHandler(h ErrorHandler) {
delegateErrorHandlerOnce.Do(func() { delegateErrorHandlerOnce.Do(func() {
current := GetErrorHandler() current := GetErrorHandler()
if current == h { if current == h {
return return
} }
if internalHandler, ok := current.(*loggingErrorHandler); ok { if internalHandler, ok := current.(*delegator); ok {
internalHandler.setDelegate(h) internalHandler.setDelegate(h)
} }
}) })
globalErrorHandler.Store(holder{eh: h})
} }
// Handle is a convience function for ErrorHandler().Handle(err) // Handle is a convenience function for ErrorHandler().Handle(err)
func Handle(err error) { func Handle(err error) {
GetErrorHandler().Handle(err) GetErrorHandler().Handle(err)
} }

View File

@ -90,9 +90,10 @@ func (p *tracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.T
// At this moment it is guaranteed that no sdk is installed, save the tracer in the tracers map. // At this moment it is guaranteed that no sdk is installed, save the tracer in the tracers map.
c := trace.NewTracerConfig(opts...)
key := il{ key := il{
name: name, name: name,
version: trace.NewTracerConfig(opts...).InstrumentationVersion(), version: c.InstrumentationVersion(),
} }
if p.tracers == nil { if p.tracers == nil {

View File

@ -15,9 +15,6 @@
/* /*
Package propagation contains OpenTelemetry context propagators. Package propagation contains OpenTelemetry context propagators.
This package is currently in a Release Candidate phase. Backwards incompatible changes
may be introduced prior to v1.0.0, but we believe the current API is ready to stabilize.
OpenTelemetry propagators are used to extract and inject context data from and OpenTelemetry propagators are used to extract and inject context data from and
into messages exchanged by applications. The propagator supported by this into messages exchanged by applications. The propagator supported by this
package is the W3C Trace Context encoding package is the W3C Trace Context encoding

View File

@ -78,7 +78,7 @@ type TextMapPropagator interface {
// DO NOT CHANGE: any modification will not be backwards compatible and // DO NOT CHANGE: any modification will not be backwards compatible and
// must never be done outside of a new major release. // must never be done outside of a new major release.
// Fields returns the keys who's values are set with Inject. // Fields returns the keys whose values are set with Inject.
Fields() []string Fields() []string
// DO NOT CHANGE: any modification will not be backwards compatible and // DO NOT CHANGE: any modification will not be backwards compatible and
// must never be done outside of a new major release. // must never be done outside of a new major release.

View File

@ -50,7 +50,9 @@ func (tc TraceContext) Inject(ctx context.Context, carrier TextMapCarrier) {
return return
} }
carrier.Set(tracestateHeader, sc.TraceState().String()) if ts := sc.TraceState().String(); ts != "" {
carrier.Set(tracestateHeader, ts)
}
// Clear all flags other than the trace-context supported sampling bit. // Clear all flags other than the trace-context supported sampling bit.
flags := sc.TraceFlags() & trace.FlagsSampled flags := sc.TraceFlags() & trace.FlagsSampled

View File

@ -16,9 +16,6 @@
Package instrumentation provides an instrumentation library structure to be Package instrumentation provides an instrumentation library structure to be
passed to both the OpenTelemetry Tracer and Meter components. passed to both the OpenTelemetry Tracer and Meter components.
This package is currently in a Release Candidate phase. Backwards incompatible changes
may be introduced prior to v1.0.0, but we believe the current API is ready to stabilize.
For more information see For more information see
[this](https://github.com/open-telemetry/oteps/blob/main/text/0083-component.md). [this](https://github.com/open-telemetry/oteps/blob/main/text/0083-component.md).
*/ */

View File

@ -78,7 +78,8 @@ func StringDetector(schemaURL string, k attribute.Key, f func() (string, error))
return stringDetector{schemaURL: schemaURL, K: k, F: f} return stringDetector{schemaURL: schemaURL, K: k, F: f}
} }
// Detect implements Detector. // Detect returns a *Resource that describes the string as a value
// corresponding to attribute.Key as well as the specific schemaURL.
func (sd stringDetector) Detect(ctx context.Context) (*Resource, error) { func (sd stringDetector) Detect(ctx context.Context) (*Resource, error) {
value, err := sd.F() value, err := sd.F()
if err != nil { if err != nil {

View File

@ -60,13 +60,6 @@ func (o detectorsOption) apply(cfg *config) {
cfg.detectors = append(cfg.detectors, o.detectors...) cfg.detectors = append(cfg.detectors, o.detectors...)
} }
// WithBuiltinDetectors adds the built detectors to the configured resource.
func WithBuiltinDetectors() Option {
return WithDetectors(telemetrySDK{},
host{},
fromEnv{})
}
// WithFromEnv adds attributes from environment variables to the configured resource. // WithFromEnv adds attributes from environment variables to the configured resource.
func WithFromEnv() Option { func WithFromEnv() Option {
return WithDetectors(fromEnv{}) return WithDetectors(fromEnv{})
@ -92,3 +85,87 @@ type schemaURLOption string
func (o schemaURLOption) apply(cfg *config) { func (o schemaURLOption) apply(cfg *config) {
cfg.schemaURL = string(o) cfg.schemaURL = string(o)
} }
// WithOS adds all the OS attributes to the configured Resource.
// See individual WithOS* functions to configure specific attributes.
func WithOS() Option {
return WithDetectors(
osTypeDetector{},
osDescriptionDetector{},
)
}
// WithOSType adds an attribute with the operating system type to the configured Resource.
func WithOSType() Option {
return WithDetectors(osTypeDetector{})
}
// WithOSDescription adds an attribute with the operating system description to the
// configured Resource. The formatted string is equivalent to the output of the
// `uname -snrvm` command.
func WithOSDescription() Option {
return WithDetectors(osDescriptionDetector{})
}
// WithProcess adds all the Process attributes to the configured Resource.
// See individual WithProcess* functions to configure specific attributes.
func WithProcess() Option {
return WithDetectors(
processPIDDetector{},
processExecutableNameDetector{},
processExecutablePathDetector{},
processCommandArgsDetector{},
processOwnerDetector{},
processRuntimeNameDetector{},
processRuntimeVersionDetector{},
processRuntimeDescriptionDetector{},
)
}
// WithProcessPID adds an attribute with the process identifier (PID) to the
// configured Resource.
func WithProcessPID() Option {
return WithDetectors(processPIDDetector{})
}
// WithProcessExecutableName adds an attribute with the name of the process
// executable to the configured Resource.
func WithProcessExecutableName() Option {
return WithDetectors(processExecutableNameDetector{})
}
// WithProcessExecutablePath adds an attribute with the full path to the process
// executable to the configured Resource.
func WithProcessExecutablePath() Option {
return WithDetectors(processExecutablePathDetector{})
}
// WithProcessCommandArgs adds an attribute with all the command arguments (including
// the command/executable itself) as received by the process the configured Resource.
func WithProcessCommandArgs() Option {
return WithDetectors(processCommandArgsDetector{})
}
// WithProcessOwner adds an attribute with the username of the user that owns the process
// to the configured Resource.
func WithProcessOwner() Option {
return WithDetectors(processOwnerDetector{})
}
// WithProcessRuntimeName adds an attribute with the name of the runtime of this
// process to the configured Resource.
func WithProcessRuntimeName() Option {
return WithDetectors(processRuntimeNameDetector{})
}
// WithProcessRuntimeVersion adds an attribute with the version of the runtime of
// this process to the configured Resource.
func WithProcessRuntimeVersion() Option {
return WithDetectors(processRuntimeVersionDetector{})
}
// WithProcessRuntimeDescription adds an attribute with an additional description
// about the runtime of the process to the configured Resource.
func WithProcessRuntimeDescription() Option {
return WithDetectors(processRuntimeDescriptionDetector{})
}

View File

@ -14,9 +14,6 @@
// Package resource provides detecting and representing resources. // Package resource provides detecting and representing resources.
// //
// This package is currently in a Release Candidate phase. Backwards incompatible changes
// may be introduced prior to v1.0.0, but we believe the current API is ready to stabilize.
//
// The fundamental struct is a Resource which holds identifying information // The fundamental struct is a Resource which holds identifying information
// about the entities for which telemetry is exported. // about the entities for which telemetry is exported.
// //

View File

@ -76,6 +76,9 @@ func (fromEnv) Detect(context.Context) (*Resource, error) {
} }
func constructOTResources(s string) (*Resource, error) { func constructOTResources(s string) (*Resource, error) {
if s == "" {
return Empty(), nil
}
pairs := strings.Split(s, ",") pairs := strings.Split(s, ",")
attrs := []attribute.KeyValue{} attrs := []attribute.KeyValue{}
var invalid []string var invalid []string

View File

@ -18,23 +18,80 @@ import (
"context" "context"
"strings" "strings"
"go.opentelemetry.io/otel/attribute"
semconv "go.opentelemetry.io/otel/semconv/v1.4.0" semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
) )
type osDescriptionProvider func() (string, error)
var defaultOSDescriptionProvider osDescriptionProvider = platformOSDescription
var osDescription = defaultOSDescriptionProvider
func setDefaultOSDescriptionProvider() {
setOSDescriptionProvider(defaultOSDescriptionProvider)
}
func setOSDescriptionProvider(osDescriptionProvider osDescriptionProvider) {
osDescription = osDescriptionProvider
}
type osTypeDetector struct{} type osTypeDetector struct{}
type osDescriptionDetector struct{}
// Detect returns a *Resource that describes the operating system type the // Detect returns a *Resource that describes the operating system type the
// service is running on. // service is running on.
func (osTypeDetector) Detect(ctx context.Context) (*Resource, error) { func (osTypeDetector) Detect(ctx context.Context) (*Resource, error) {
osType := runtimeOS() osType := runtimeOS()
osTypeAttribute := mapRuntimeOSToSemconvOSType(osType)
return NewWithAttributes( return NewWithAttributes(
semconv.SchemaURL, semconv.SchemaURL,
semconv.OSTypeKey.String(strings.ToLower(osType)), osTypeAttribute,
), nil ), nil
} }
// WithOSType adds an attribute with the operating system type to the configured Resource. // Detect returns a *Resource that describes the operating system the
func WithOSType() Option { // service is running on.
return WithDetectors(osTypeDetector{}) func (osDescriptionDetector) Detect(ctx context.Context) (*Resource, error) {
description, err := osDescription()
if err != nil {
return nil, err
}
return NewWithAttributes(
semconv.SchemaURL,
semconv.OSDescriptionKey.String(description),
), nil
}
// mapRuntimeOSToSemconvOSType translates the OS name as provided by the Go runtime
// into an OS type attribute with the corresponding value defined by the semantic
// conventions. In case the provided OS name isn't mapped, it's transformed to lowercase
// and used as the value for the returned OS type attribute.
func mapRuntimeOSToSemconvOSType(osType string) attribute.KeyValue {
// the elements in this map are the intersection between
// available GOOS values and defined semconv OS types
osTypeAttributeMap := map[string]attribute.KeyValue{
"darwin": semconv.OSTypeDarwin,
"dragonfly": semconv.OSTypeDragonflyBSD,
"freebsd": semconv.OSTypeFreeBSD,
"linux": semconv.OSTypeLinux,
"netbsd": semconv.OSTypeNetBSD,
"openbsd": semconv.OSTypeOpenBSD,
"solaris": semconv.OSTypeSolaris,
"windows": semconv.OSTypeWindows,
}
var osTypeAttribute attribute.KeyValue
if attr, ok := osTypeAttributeMap[osType]; ok {
osTypeAttribute = attr
} else {
osTypeAttribute = semconv.OSTypeKey.String(strings.ToLower(osType))
}
return osTypeAttribute
} }

View File

@ -0,0 +1,102 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package resource // import "go.opentelemetry.io/otel/sdk/resource"
import (
"encoding/xml"
"fmt"
"io"
"os"
)
type plist struct {
XMLName xml.Name `xml:"plist"`
Dict dict `xml:"dict"`
}
type dict struct {
Key []string `xml:"key"`
String []string `xml:"string"`
}
// osRelease builds a string describing the operating system release based on the
// contents of the property list (.plist) system files. If no .plist files are found,
// or if the required properties to build the release description string are missing,
// an empty string is returned instead. The generated string resembles the output of
// the `sw_vers` commandline program, but in a single-line string. For more information
// about the `sw_vers` program, see: https://www.unix.com/man-page/osx/1/SW_VERS.
func osRelease() string {
file, err := getPlistFile()
if err != nil {
return ""
}
defer file.Close()
values, err := parsePlistFile(file)
if err != nil {
return ""
}
return buildOSRelease(values)
}
// getPlistFile returns a *os.File pointing to one of the well-known .plist files
// available on macOS. If no file can be opened, it returns an error.
func getPlistFile() (*os.File, error) {
return getFirstAvailableFile([]string{
"/System/Library/CoreServices/SystemVersion.plist",
"/System/Library/CoreServices/ServerVersion.plist",
})
}
// parsePlistFile process the file pointed by `file` as a .plist file and returns
// a map with the key-values for each pair of correlated <key> and <string> elements
// contained in it.
func parsePlistFile(file io.Reader) (map[string]string, error) {
var v plist
err := xml.NewDecoder(file).Decode(&v)
if err != nil {
return nil, err
}
if len(v.Dict.Key) != len(v.Dict.String) {
return nil, fmt.Errorf("the number of <key> and <string> elements doesn't match")
}
properties := make(map[string]string, len(v.Dict.Key))
for i, key := range v.Dict.Key {
properties[key] = v.Dict.String[i]
}
return properties, nil
}
// buildOSRelease builds a string describing the OS release based on the properties
// available on the provided map. It tries to find the `ProductName`, `ProductVersion`
// and `ProductBuildVersion` properties. If some of these properties are not found,
// it returns an empty string.
func buildOSRelease(properties map[string]string) string {
productName := properties["ProductName"]
productVersion := properties["ProductVersion"]
productBuildVersion := properties["ProductBuildVersion"]
if productName == "" || productVersion == "" || productBuildVersion == "" {
return ""
}
return fmt.Sprintf("%s %s (%s)", productName, productVersion, productBuildVersion)
}

View File

@ -0,0 +1,153 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// +build aix dragonfly freebsd linux netbsd openbsd solaris zos
package resource // import "go.opentelemetry.io/otel/sdk/resource"
import (
"bufio"
"fmt"
"io"
"os"
"strings"
)
// osRelease builds a string describing the operating system release based on the
// properties of the os-release file. If no os-release file is found, or if the
// required properties to build the release description string are missing, an empty
// string is returned instead. For more information about os-release files, see:
// https://www.freedesktop.org/software/systemd/man/os-release.html
func osRelease() string {
file, err := getOSReleaseFile()
if err != nil {
return ""
}
defer file.Close()
values := parseOSReleaseFile(file)
return buildOSRelease(values)
}
// getOSReleaseFile returns a *os.File pointing to one of the well-known os-release
// files, according to their order of preference. If no file can be opened, it
// returns an error.
func getOSReleaseFile() (*os.File, error) {
return getFirstAvailableFile([]string{"/etc/os-release", "/usr/lib/os-release"})
}
// parseOSReleaseFile process the file pointed by `file` as an os-release file and
// returns a map with the key-values contained in it. Empty lines or lines starting
// with a '#' character are ignored, as well as lines with the missing key=value
// separator. Values are unquoted and unescaped.
func parseOSReleaseFile(file io.Reader) map[string]string {
values := make(map[string]string)
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
if skip(line) {
continue
}
key, value, ok := parse(line)
if ok {
values[key] = value
}
}
return values
}
// skip returns true if the line is blank or starts with a '#' character, and
// therefore should be skipped from processing.
func skip(line string) bool {
line = strings.TrimSpace(line)
return len(line) == 0 || strings.HasPrefix(line, "#")
}
// parse attempts to split the provided line on the first '=' character, and then
// sanitize each side of the split before returning them as a key-value pair.
func parse(line string) (string, string, bool) {
parts := strings.SplitN(line, "=", 2)
if len(parts) != 2 || len(parts[0]) == 0 {
return "", "", false
}
key := strings.TrimSpace(parts[0])
value := unescape(unquote(strings.TrimSpace(parts[1])))
return key, value, true
}
// unquote checks whether the string `s` is quoted with double or single quotes
// and, if so, returns a version of the string without them. Otherwise it returns
// the provided string unchanged.
func unquote(s string) string {
if len(s) < 2 {
return s
}
if (s[0] == '"' || s[0] == '\'') && s[0] == s[len(s)-1] {
return s[1 : len(s)-1]
}
return s
}
// unescape removes the `\` prefix from some characters that are expected
// to have it added in front of them for escaping purposes.
func unescape(s string) string {
return strings.NewReplacer(
`\$`, `$`,
`\"`, `"`,
`\'`, `'`,
`\\`, `\`,
"\\`", "`",
).Replace(s)
}
// buildOSRelease builds a string describing the OS release based on the properties
// available on the provided map. It favors a combination of the `NAME` and `VERSION`
// properties as first option (falling back to `VERSION_ID` if `VERSION` isn't
// found), and using `PRETTY_NAME` alone if some of the previous are not present. If
// none of these properties are found, it returns an empty string.
//
// The rationale behind not using `PRETTY_NAME` as first choice was that, for some
// Linux distributions, it doesn't include the same detail that can be found on the
// individual `NAME` and `VERSION` properties, and combining `PRETTY_NAME` with
// other properties can produce "pretty" redundant strings in some cases.
func buildOSRelease(values map[string]string) string {
var osRelease string
name := values["NAME"]
version := values["VERSION"]
if version == "" {
version = values["VERSION_ID"]
}
if name != "" && version != "" {
osRelease = fmt.Sprintf("%s %s", name, version)
} else {
osRelease = values["PRETTY_NAME"]
}
return osRelease
}

View File

@ -0,0 +1,99 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris zos
package resource // import "go.opentelemetry.io/otel/sdk/resource"
import (
"bytes"
"fmt"
"os"
"golang.org/x/sys/unix"
)
type unameProvider func(buf *unix.Utsname) (err error)
var defaultUnameProvider unameProvider = unix.Uname
var currentUnameProvider = defaultUnameProvider
func setDefaultUnameProvider() {
setUnameProvider(defaultUnameProvider)
}
func setUnameProvider(unameProvider unameProvider) {
currentUnameProvider = unameProvider
}
// platformOSDescription returns a human readable OS version information string.
// The final string combines OS release information (where available) and the
// result of the `uname` system call.
func platformOSDescription() (string, error) {
uname, err := uname()
if err != nil {
return "", err
}
osRelease := osRelease()
if osRelease != "" {
return fmt.Sprintf("%s (%s)", osRelease, uname), nil
}
return uname, nil
}
// uname issues a uname(2) system call (or equivalent on systems which doesn't
// have one) and formats the output in a single string, similar to the output
// of the `uname` commandline program. The final string resembles the one
// obtained with a call to `uname -snrvm`.
func uname() (string, error) {
var utsName unix.Utsname
err := currentUnameProvider(&utsName)
if err != nil {
return "", err
}
return fmt.Sprintf("%s %s %s %s %s",
charsToString(utsName.Sysname[:]),
charsToString(utsName.Nodename[:]),
charsToString(utsName.Release[:]),
charsToString(utsName.Version[:]),
charsToString(utsName.Machine[:]),
), nil
}
// charsToString converts a C-like null-terminated char array to a Go string.
func charsToString(charArray []byte) string {
if i := bytes.IndexByte(charArray, 0); i >= 0 {
charArray = charArray[:i]
}
return string(charArray)
}
// getFirstAvailableFile returns an *os.File of the first available
// file from a list of candidate file paths.
func getFirstAvailableFile(candidates []string) (*os.File, error) {
for _, c := range candidates {
file, err := os.Open(c)
if err == nil {
return file, nil
}
}
return nil, fmt.Errorf("no candidate file available: %v", candidates)
}

View File

@ -0,0 +1,34 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// +build !aix
// +build !darwin
// +build !dragonfly
// +build !freebsd
// +build !linux
// +build !netbsd
// +build !openbsd
// +build !solaris
// +build !windows
// +build !zos
package resource // import "go.opentelemetry.io/otel/sdk/resource"
// platformOSDescription is a placeholder implementation for OSes
// for which this project currently doesn't support os.description
// attribute detection. See build tags declaration early on this file
// for a list of unsupported OSes.
func platformOSDescription() (string, error) {
return "<unknown>", nil
}

View File

@ -0,0 +1,101 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package resource // import "go.opentelemetry.io/otel/sdk/resource"
import (
"fmt"
"strconv"
"golang.org/x/sys/windows/registry"
)
// platformOSDescription returns a human readable OS version information string.
// It does so by querying registry values under the
// `SOFTWARE\Microsoft\Windows NT\CurrentVersion` key. The final string
// resembles the one displayed by the Version Reporter Applet (winver.exe).
func platformOSDescription() (string, error) {
k, err := registry.OpenKey(
registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
if err != nil {
return "", err
}
defer k.Close()
var (
productName = readProductName(k)
displayVersion = readDisplayVersion(k)
releaseID = readReleaseID(k)
currentMajorVersionNumber = readCurrentMajorVersionNumber(k)
currentMinorVersionNumber = readCurrentMinorVersionNumber(k)
currentBuildNumber = readCurrentBuildNumber(k)
ubr = readUBR(k)
)
if displayVersion != "" {
displayVersion += " "
}
return fmt.Sprintf("%s %s(%s) [Version %s.%s.%s.%s]",
productName,
displayVersion,
releaseID,
currentMajorVersionNumber,
currentMinorVersionNumber,
currentBuildNumber,
ubr,
), nil
}
func getStringValue(name string, k registry.Key) string {
value, _, _ := k.GetStringValue(name)
return value
}
func getIntegerValue(name string, k registry.Key) uint64 {
value, _, _ := k.GetIntegerValue(name)
return value
}
func readProductName(k registry.Key) string {
return getStringValue("ProductName", k)
}
func readDisplayVersion(k registry.Key) string {
return getStringValue("DisplayVersion", k)
}
func readReleaseID(k registry.Key) string {
return getStringValue("ReleaseID", k)
}
func readCurrentMajorVersionNumber(k registry.Key) string {
return strconv.FormatUint(getIntegerValue("CurrentMajorVersionNumber", k), 10)
}
func readCurrentMinorVersionNumber(k registry.Key) string {
return strconv.FormatUint(getIntegerValue("CurrentMinorVersionNumber", k), 10)
}
func readCurrentBuildNumber(k registry.Key) string {
return getStringValue("CurrentBuildNumber", k)
}
func readUBR(k registry.Key) string {
return strconv.FormatUint(getIntegerValue("UBR", k), 10)
}

View File

@ -138,7 +138,7 @@ func (processExecutablePathDetector) Detect(ctx context.Context) (*Resource, err
// Detect returns a *Resource that describes all the command arguments as received // Detect returns a *Resource that describes all the command arguments as received
// by the process. // by the process.
func (processCommandArgsDetector) Detect(ctx context.Context) (*Resource, error) { func (processCommandArgsDetector) Detect(ctx context.Context) (*Resource, error) {
return NewWithAttributes(semconv.SchemaURL, semconv.ProcessCommandArgsKey.Array(commandArgs())), nil return NewWithAttributes(semconv.SchemaURL, semconv.ProcessCommandArgsKey.StringSlice(commandArgs())), nil
} }
// Detect returns a *Resource that describes the username of the user that owns the // Detect returns a *Resource that describes the username of the user that owns the
@ -173,66 +173,3 @@ func (processRuntimeDescriptionDetector) Detect(ctx context.Context) (*Resource,
semconv.ProcessRuntimeDescriptionKey.String(runtimeDescription), semconv.ProcessRuntimeDescriptionKey.String(runtimeDescription),
), nil ), nil
} }
// WithProcessPID adds an attribute with the process identifier (PID) to the
// configured Resource.
func WithProcessPID() Option {
return WithDetectors(processPIDDetector{})
}
// WithProcessExecutableName adds an attribute with the name of the process
// executable to the configured Resource.
func WithProcessExecutableName() Option {
return WithDetectors(processExecutableNameDetector{})
}
// WithProcessExecutablePath adds an attribute with the full path to the process
// executable to the configured Resource.
func WithProcessExecutablePath() Option {
return WithDetectors(processExecutablePathDetector{})
}
// WithProcessCommandArgs adds an attribute with all the command arguments (including
// the command/executable itself) as received by the process the configured Resource.
func WithProcessCommandArgs() Option {
return WithDetectors(processCommandArgsDetector{})
}
// WithProcessOwner adds an attribute with the username of the user that owns the process
// to the configured Resource.
func WithProcessOwner() Option {
return WithDetectors(processOwnerDetector{})
}
// WithProcessRuntimeName adds an attribute with the name of the runtime of this
// process to the configured Resource.
func WithProcessRuntimeName() Option {
return WithDetectors(processRuntimeNameDetector{})
}
// WithProcessRuntimeVersion adds an attribute with the version of the runtime of
// this process to the configured Resource.
func WithProcessRuntimeVersion() Option {
return WithDetectors(processRuntimeVersionDetector{})
}
// WithProcessRuntimeDescription adds an attribute with an additional description
// about the runtime of the process to the configured Resource.
func WithProcessRuntimeDescription() Option {
return WithDetectors(processRuntimeDescriptionDetector{})
}
// WithProcess adds all the Process attributes to the configured Resource.
// See individual WithProcess* functions to configure specific attributes.
func WithProcess() Option {
return WithDetectors(
processPIDDetector{},
processExecutableNameDetector{},
processExecutablePathDetector{},
processCommandArgsDetector{},
processOwnerDetector{},
processRuntimeNameDetector{},
processRuntimeVersionDetector{},
processRuntimeDescriptionDetector{},
)
}

View File

@ -43,7 +43,14 @@ var (
otel.Handle(err) otel.Handle(err)
} }
return r return r
}(Detect(context.Background(), defaultServiceNameDetector{}, fromEnv{}, telemetrySDK{})) }(
Detect(
context.Background(),
defaultServiceNameDetector{},
fromEnv{},
telemetrySDK{},
),
)
) )
var ( var (
@ -125,10 +132,13 @@ func (r *Resource) Attributes() []attribute.KeyValue {
} }
func (r *Resource) SchemaURL() string { func (r *Resource) SchemaURL() string {
if r == nil {
return ""
}
return r.schemaURL return r.schemaURL
} }
// Iter returns an interator of the Resource attributes. // Iter returns an iterator of the Resource attributes.
// This is ideal to use if you do not want a copy of the attributes. // This is ideal to use if you do not want a copy of the attributes.
func (r *Resource) Iter() attribute.Iterator { func (r *Resource) Iter() attribute.Iterator {
if r == nil { if r == nil {
@ -199,7 +209,7 @@ func Empty() *Resource {
} }
// Default returns an instance of Resource with a default // Default returns an instance of Resource with a default
// "service.name" and OpenTelemetrySDK attributes // "service.name" and OpenTelemetrySDK attributes.
func Default() *Resource { func Default() *Resource {
return defaultResource return defaultResource
} }
@ -222,7 +232,7 @@ func (r *Resource) Equivalent() attribute.Distinct {
return r.Set().Equivalent() return r.Set().Equivalent()
} }
// Set returns the equivalent *attribute.Set of this resources attributes. // Set returns the equivalent *attribute.Set of this resource's attributes.
func (r *Resource) Set() *attribute.Set { func (r *Resource) Set() *attribute.Set {
if r == nil { if r == nil {
r = Empty() r = Empty()

View File

@ -15,9 +15,6 @@
/* /*
Package trace contains support for OpenTelemetry distributed tracing. Package trace contains support for OpenTelemetry distributed tracing.
This package is currently in a Release Candidate phase. Backwards incompatible changes
may be introduced prior to v1.0.0, but we believe the current API is ready to stabilize.
The following assumes a basic familiarity with OpenTelemetry concepts. The following assumes a basic familiarity with OpenTelemetry concepts.
See https://opentelemetry.io. See https://opentelemetry.io.
*/ */

34
vendor/go.opentelemetry.io/otel/sdk/trace/link.go generated vendored Normal file
View File

@ -0,0 +1,34 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package trace // import "go.opentelemetry.io/otel/sdk/trace"
import (
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
)
// Link is the relationship between two Spans. The relationship can be within
// the same Trace or across different Traces.
type Link struct {
// SpanContext of the linked Span.
SpanContext trace.SpanContext
// Attributes describe the aspects of the link.
Attributes []attribute.KeyValue
// DroppedAttributeCount is the number of attributes that were not
// recorded due to configured limits being reached.
DroppedAttributeCount int
}

View File

@ -34,7 +34,7 @@ type snapshot struct {
endTime time.Time endTime time.Time
attributes []attribute.KeyValue attributes []attribute.KeyValue
events []Event events []Event
links []trace.Link links []Link
status Status status Status
childSpanCount int childSpanCount int
droppedAttributeCount int droppedAttributeCount int
@ -87,7 +87,7 @@ func (s snapshot) Attributes() []attribute.KeyValue {
} }
// Links returns all the links the span has to other spans. // Links returns all the links the span has to other spans.
func (s snapshot) Links() []trace.Link { func (s snapshot) Links() []Link {
return s.links return s.links
} }

View File

@ -18,6 +18,8 @@ import (
"context" "context"
"fmt" "fmt"
"reflect" "reflect"
"runtime"
rt "runtime/trace"
"sync" "sync"
"time" "time"
@ -55,7 +57,7 @@ type ReadOnlySpan interface {
// Attributes returns the defining attributes of the span. // Attributes returns the defining attributes of the span.
Attributes() []attribute.KeyValue Attributes() []attribute.KeyValue
// Links returns all the links the span has to other spans. // Links returns all the links the span has to other spans.
Links() []trace.Link Links() []Link
// Events returns all the events that occurred within in the spans // Events returns all the events that occurred within in the spans
// lifetime. // lifetime.
Events() []Event Events() []Event
@ -97,9 +99,9 @@ type ReadWriteSpan interface {
ReadOnlySpan ReadOnlySpan
} }
// span is an implementation of the OpenTelemetry Span API representing the // recordingSpan is an implementation of the OpenTelemetry Span API
// individual component of a trace. // representing the individual component of a trace that is sampled.
type span struct { type recordingSpan struct {
// mu protects the contents of this span. // mu protects the contents of this span.
mu sync.Mutex mu sync.Mutex
@ -156,10 +158,11 @@ type span struct {
spanLimits SpanLimits spanLimits SpanLimits
} }
var _ trace.Span = &span{} var _ ReadWriteSpan = (*recordingSpan)(nil)
var _ runtimeTracer = (*recordingSpan)(nil)
// SpanContext returns the SpanContext of this span. // SpanContext returns the SpanContext of this span.
func (s *span) SpanContext() trace.SpanContext { func (s *recordingSpan) SpanContext() trace.SpanContext {
if s == nil { if s == nil {
return trace.SpanContext{} return trace.SpanContext{}
} }
@ -168,21 +171,21 @@ func (s *span) SpanContext() trace.SpanContext {
// IsRecording returns if this span is being recorded. If this span has ended // IsRecording returns if this span is being recorded. If this span has ended
// this will return false. // this will return false.
func (s *span) IsRecording() bool { func (s *recordingSpan) IsRecording() bool {
if s == nil { if s == nil {
return false return false
} }
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
return !s.startTime.IsZero() && s.endTime.IsZero() return s.endTime.IsZero()
} }
// SetStatus sets the status of the Span in the form of a code and a // SetStatus sets the status of the Span in the form of a code and a
// description, overriding previous values set. The description is only // description, overriding previous values set. The description is only
// included in the set status when the code is for an error. If this span is // included in the set status when the code is for an error. If this span is
// not being recorded than this method does nothing. // not being recorded than this method does nothing.
func (s *span) SetStatus(code codes.Code, description string) { func (s *recordingSpan) SetStatus(code codes.Code, description string) {
if !s.IsRecording() { if !s.IsRecording() {
return return
} }
@ -203,7 +206,7 @@ func (s *span) SetStatus(code codes.Code, description string) {
// will be overwritten with the value contained in attributes. // will be overwritten with the value contained in attributes.
// //
// If this span is not being recorded than this method does nothing. // If this span is not being recorded than this method does nothing.
func (s *span) SetAttributes(attributes ...attribute.KeyValue) { func (s *recordingSpan) SetAttributes(attributes ...attribute.KeyValue) {
if !s.IsRecording() { if !s.IsRecording() {
return return
} }
@ -218,7 +221,7 @@ func (s *span) SetAttributes(attributes ...attribute.KeyValue) {
// //
// If this method is called while panicking an error event is added to the // If this method is called while panicking an error event is added to the
// Span before ending it and the panic is continued. // Span before ending it and the panic is continued.
func (s *span) End(options ...trace.SpanEndOption) { func (s *recordingSpan) End(options ...trace.SpanEndOption) {
// Do not start by checking if the span is being recorded which requires // Do not start by checking if the span is being recorded which requires
// acquiring a lock. Make a minimal check that the span is not nil. // acquiring a lock. Make a minimal check that the span is not nil.
if s == nil { if s == nil {
@ -235,24 +238,30 @@ func (s *span) End(options ...trace.SpanEndOption) {
return return
} }
config := trace.NewSpanEndConfig(options...)
if recovered := recover(); recovered != nil { if recovered := recover(); recovered != nil {
// Record but don't stop the panic. // Record but don't stop the panic.
defer panic(recovered) defer panic(recovered)
s.addEvent( opts := []trace.EventOption{
semconv.ExceptionEventName,
trace.WithAttributes( trace.WithAttributes(
semconv.ExceptionTypeKey.String(typeStr(recovered)), semconv.ExceptionTypeKey.String(typeStr(recovered)),
semconv.ExceptionMessageKey.String(fmt.Sprint(recovered)), semconv.ExceptionMessageKey.String(fmt.Sprint(recovered)),
), ),
) }
if config.StackTrace() {
opts = append(opts, trace.WithAttributes(
semconv.ExceptionStacktraceKey.String(recordStackTrace()),
))
}
s.addEvent(semconv.ExceptionEventName, opts...)
} }
if s.executionTracerTaskEnd != nil { if s.executionTracerTaskEnd != nil {
s.executionTracerTaskEnd() s.executionTracerTaskEnd()
} }
config := trace.NewSpanEndConfig(options...)
s.mu.Lock() s.mu.Lock()
// Setting endTime to non-zero marks the span as ended and not recording. // Setting endTime to non-zero marks the span as ended and not recording.
if config.Timestamp().IsZero() { if config.Timestamp().IsZero() {
@ -262,11 +271,13 @@ func (s *span) End(options ...trace.SpanEndOption) {
} }
s.mu.Unlock() s.mu.Unlock()
sps, ok := s.tracer.provider.spanProcessors.Load().(spanProcessorStates) if sps, ok := s.tracer.provider.spanProcessors.Load().(spanProcessorStates); ok {
mustExportOrProcess := ok && len(sps) > 0 if len(sps) == 0 {
if mustExportOrProcess { return
}
snap := s.snapshot()
for _, sp := range sps { for _, sp := range sps {
sp.sp.OnEnd(s.snapshot()) sp.sp.OnEnd(snap)
} }
} }
} }
@ -275,7 +286,7 @@ func (s *span) End(options ...trace.SpanEndOption) {
// SetStatus is required if the Status of the Span should be set to Error, this method // SetStatus is required if the Status of the Span should be set to Error, this method
// does not change the Span status. If this span is not being recorded or err is nil // does not change the Span status. If this span is not being recorded or err is nil
// than this method does nothing. // than this method does nothing.
func (s *span) RecordError(err error, opts ...trace.EventOption) { func (s *recordingSpan) RecordError(err error, opts ...trace.EventOption) {
if s == nil || err == nil || !s.IsRecording() { if s == nil || err == nil || !s.IsRecording() {
return return
} }
@ -284,6 +295,14 @@ func (s *span) RecordError(err error, opts ...trace.EventOption) {
semconv.ExceptionTypeKey.String(typeStr(err)), semconv.ExceptionTypeKey.String(typeStr(err)),
semconv.ExceptionMessageKey.String(err.Error()), semconv.ExceptionMessageKey.String(err.Error()),
)) ))
c := trace.NewEventConfig(opts...)
if c.StackTrace() {
opts = append(opts, trace.WithAttributes(
semconv.ExceptionStacktraceKey.String(recordStackTrace()),
))
}
s.addEvent(semconv.ExceptionEventName, opts...) s.addEvent(semconv.ExceptionEventName, opts...)
} }
@ -296,16 +315,23 @@ func typeStr(i interface{}) string {
return fmt.Sprintf("%s.%s", t.PkgPath(), t.Name()) return fmt.Sprintf("%s.%s", t.PkgPath(), t.Name())
} }
func recordStackTrace() string {
stackTrace := make([]byte, 2048)
n := runtime.Stack(stackTrace, false)
return string(stackTrace[0:n])
}
// AddEvent adds an event with the provided name and options. If this span is // AddEvent adds an event with the provided name and options. If this span is
// not being recorded than this method does nothing. // not being recorded than this method does nothing.
func (s *span) AddEvent(name string, o ...trace.EventOption) { func (s *recordingSpan) AddEvent(name string, o ...trace.EventOption) {
if !s.IsRecording() { if !s.IsRecording() {
return return
} }
s.addEvent(name, o...) s.addEvent(name, o...)
} }
func (s *span) addEvent(name string, o ...trace.EventOption) { func (s *recordingSpan) addEvent(name string, o ...trace.EventOption) {
c := trace.NewEventConfig(o...) c := trace.NewEventConfig(o...)
// Discard over limited attributes // Discard over limited attributes
@ -327,7 +353,7 @@ func (s *span) addEvent(name string, o ...trace.EventOption) {
// SetName sets the name of this span. If this span is not being recorded than // SetName sets the name of this span. If this span is not being recorded than
// this method does nothing. // this method does nothing.
func (s *span) SetName(name string) { func (s *recordingSpan) SetName(name string) {
if !s.IsRecording() { if !s.IsRecording() {
return return
} }
@ -338,28 +364,28 @@ func (s *span) SetName(name string) {
} }
// Name returns the name of this span. // Name returns the name of this span.
func (s *span) Name() string { func (s *recordingSpan) Name() string {
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
return s.name return s.name
} }
// Name returns the SpanContext of this span's parent span. // Name returns the SpanContext of this span's parent span.
func (s *span) Parent() trace.SpanContext { func (s *recordingSpan) Parent() trace.SpanContext {
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
return s.parent return s.parent
} }
// SpanKind returns the SpanKind of this span. // SpanKind returns the SpanKind of this span.
func (s *span) SpanKind() trace.SpanKind { func (s *recordingSpan) SpanKind() trace.SpanKind {
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
return s.spanKind return s.spanKind
} }
// StartTime returns the time this span started. // StartTime returns the time this span started.
func (s *span) StartTime() time.Time { func (s *recordingSpan) StartTime() time.Time {
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
return s.startTime return s.startTime
@ -367,14 +393,14 @@ func (s *span) StartTime() time.Time {
// EndTime returns the time this span ended. For spans that have not yet // EndTime returns the time this span ended. For spans that have not yet
// ended, the returned value will be the zero value of time.Time. // ended, the returned value will be the zero value of time.Time.
func (s *span) EndTime() time.Time { func (s *recordingSpan) EndTime() time.Time {
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
return s.endTime return s.endTime
} }
// Attributes returns the attributes of this span. // Attributes returns the attributes of this span.
func (s *span) Attributes() []attribute.KeyValue { func (s *recordingSpan) Attributes() []attribute.KeyValue {
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
if s.attributes.evictList.Len() == 0 { if s.attributes.evictList.Len() == 0 {
@ -384,17 +410,17 @@ func (s *span) Attributes() []attribute.KeyValue {
} }
// Links returns the links of this span. // Links returns the links of this span.
func (s *span) Links() []trace.Link { func (s *recordingSpan) Links() []Link {
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
if len(s.links.queue) == 0 { if len(s.links.queue) == 0 {
return []trace.Link{} return []Link{}
} }
return s.interfaceArrayToLinksArray() return s.interfaceArrayToLinksArray()
} }
// Events returns the events of this span. // Events returns the events of this span.
func (s *span) Events() []Event { func (s *recordingSpan) Events() []Event {
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
if len(s.events.queue) == 0 { if len(s.events.queue) == 0 {
@ -404,7 +430,7 @@ func (s *span) Events() []Event {
} }
// Status returns the status of this span. // Status returns the status of this span.
func (s *span) Status() Status { func (s *recordingSpan) Status() Status {
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
return s.status return s.status
@ -412,7 +438,7 @@ func (s *span) Status() Status {
// InstrumentationLibrary returns the instrumentation.Library associated with // InstrumentationLibrary returns the instrumentation.Library associated with
// the Tracer that created this span. // the Tracer that created this span.
func (s *span) InstrumentationLibrary() instrumentation.Library { func (s *recordingSpan) InstrumentationLibrary() instrumentation.Library {
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
return s.instrumentationLibrary return s.instrumentationLibrary
@ -420,31 +446,33 @@ func (s *span) InstrumentationLibrary() instrumentation.Library {
// Resource returns the Resource associated with the Tracer that created this // Resource returns the Resource associated with the Tracer that created this
// span. // span.
func (s *span) Resource() *resource.Resource { func (s *recordingSpan) Resource() *resource.Resource {
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
return s.resource return s.resource
} }
func (s *span) addLink(link trace.Link) { func (s *recordingSpan) addLink(link trace.Link) {
if !s.IsRecording() { if !s.IsRecording() {
return return
} }
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
var droppedAttributeCount int
// Discard over limited attributes // Discard over limited attributes
if len(link.Attributes) > s.spanLimits.AttributePerLinkCountLimit { if len(link.Attributes) > s.spanLimits.AttributePerLinkCountLimit {
link.DroppedAttributeCount = len(link.Attributes) - s.spanLimits.AttributePerLinkCountLimit droppedAttributeCount = len(link.Attributes) - s.spanLimits.AttributePerLinkCountLimit
link.Attributes = link.Attributes[:s.spanLimits.AttributePerLinkCountLimit] link.Attributes = link.Attributes[:s.spanLimits.AttributePerLinkCountLimit]
} }
s.links.add(link) s.links.add(Link{link.SpanContext, link.Attributes, droppedAttributeCount})
} }
// DroppedAttributes returns the number of attributes dropped by the span // DroppedAttributes returns the number of attributes dropped by the span
// due to limits being reached. // due to limits being reached.
func (s *span) DroppedAttributes() int { func (s *recordingSpan) DroppedAttributes() int {
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
return s.attributes.droppedCount return s.attributes.droppedCount
@ -452,7 +480,7 @@ func (s *span) DroppedAttributes() int {
// DroppedLinks returns the number of links dropped by the span due to limits // DroppedLinks returns the number of links dropped by the span due to limits
// being reached. // being reached.
func (s *span) DroppedLinks() int { func (s *recordingSpan) DroppedLinks() int {
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
return s.links.droppedCount return s.links.droppedCount
@ -460,7 +488,7 @@ func (s *span) DroppedLinks() int {
// DroppedEvents returns the number of events dropped by the span due to // DroppedEvents returns the number of events dropped by the span due to
// limits being reached. // limits being reached.
func (s *span) DroppedEvents() int { func (s *recordingSpan) DroppedEvents() int {
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
return s.events.droppedCount return s.events.droppedCount
@ -468,7 +496,7 @@ func (s *span) DroppedEvents() int {
// ChildSpanCount returns the count of spans that consider the span a // ChildSpanCount returns the count of spans that consider the span a
// direct parent. // direct parent.
func (s *span) ChildSpanCount() int { func (s *recordingSpan) ChildSpanCount() int {
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
return s.childSpanCount return s.childSpanCount
@ -476,12 +504,12 @@ func (s *span) ChildSpanCount() int {
// TracerProvider returns a trace.TracerProvider that can be used to generate // TracerProvider returns a trace.TracerProvider that can be used to generate
// additional Spans on the same telemetry pipeline as the current Span. // additional Spans on the same telemetry pipeline as the current Span.
func (s *span) TracerProvider() trace.TracerProvider { func (s *recordingSpan) TracerProvider() trace.TracerProvider {
return s.tracer.provider return s.tracer.provider
} }
// snapshot creates a read-only copy of the current state of the span. // snapshot creates a read-only copy of the current state of the span.
func (s *span) snapshot() ReadOnlySpan { func (s *recordingSpan) snapshot() ReadOnlySpan {
var sd snapshot var sd snapshot
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
@ -512,15 +540,15 @@ func (s *span) snapshot() ReadOnlySpan {
return &sd return &sd
} }
func (s *span) interfaceArrayToLinksArray() []trace.Link { func (s *recordingSpan) interfaceArrayToLinksArray() []Link {
linkArr := make([]trace.Link, 0) linkArr := make([]Link, 0)
for _, value := range s.links.queue { for _, value := range s.links.queue {
linkArr = append(linkArr, value.(trace.Link)) linkArr = append(linkArr, value.(Link))
} }
return linkArr return linkArr
} }
func (s *span) interfaceArrayToEventArray() []Event { func (s *recordingSpan) interfaceArrayToEventArray() []Event {
eventArr := make([]Event, 0) eventArr := make([]Event, 0)
for _, value := range s.events.queue { for _, value := range s.events.queue {
eventArr = append(eventArr, value.(Event)) eventArr = append(eventArr, value.(Event))
@ -528,7 +556,7 @@ func (s *span) interfaceArrayToEventArray() []Event {
return eventArr return eventArr
} }
func (s *span) copyToCappedAttributes(attributes ...attribute.KeyValue) { func (s *recordingSpan) copyToCappedAttributes(attributes ...attribute.KeyValue) {
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
for _, a := range attributes { for _, a := range attributes {
@ -540,7 +568,7 @@ func (s *span) copyToCappedAttributes(attributes ...attribute.KeyValue) {
} }
} }
func (s *span) addChild() { func (s *recordingSpan) addChild() {
if !s.IsRecording() { if !s.IsRecording() {
return return
} }
@ -549,80 +577,66 @@ func (s *span) addChild() {
s.mu.Unlock() s.mu.Unlock()
} }
func (*span) private() {} func (*recordingSpan) private() {}
func startSpanInternal(ctx context.Context, tr *tracer, name string, o *trace.SpanConfig) *span { // runtimeTrace starts a "runtime/trace".Task for the span and returns a
span := &span{} // context containing the task.
func (s *recordingSpan) runtimeTrace(ctx context.Context) context.Context {
provider := tr.provider if !rt.IsEnabled() {
// Avoid additional overhead if runtime/trace is not enabled.
// If told explicitly to make this a new root use a zero value SpanContext return ctx
// as a parent which contains an invalid trace ID and is not remote.
var psc trace.SpanContext
if !o.NewRoot() {
psc = trace.SpanContextFromContext(ctx)
} }
nctx, task := rt.NewTask(ctx, s.name)
// If there is a valid parent trace ID, use it to ensure the continuity of s.mu.Lock()
// the trace. Always generate a new span ID so other components can rely s.executionTracerTaskEnd = task.End
// on a unique span ID, even if the Span is non-recording. s.mu.Unlock()
var tid trace.TraceID
var sid trace.SpanID
if !psc.TraceID().IsValid() {
tid, sid = provider.idGenerator.NewIDs(ctx)
} else {
tid = psc.TraceID()
sid = provider.idGenerator.NewSpanID(ctx, tid)
}
spanLimits := provider.spanLimits return nctx
span.attributes = newAttributesMap(spanLimits.AttributeCountLimit)
span.events = newEvictedQueue(spanLimits.EventCountLimit)
span.links = newEvictedQueue(spanLimits.LinkCountLimit)
span.spanLimits = spanLimits
samplingResult := provider.sampler.ShouldSample(SamplingParameters{
ParentContext: ctx,
TraceID: tid,
Name: name,
Kind: o.SpanKind(),
Attributes: o.Attributes(),
Links: o.Links(),
})
scc := trace.SpanContextConfig{
TraceID: tid,
SpanID: sid,
TraceState: samplingResult.Tracestate,
}
if isSampled(samplingResult) {
scc.TraceFlags = psc.TraceFlags() | trace.FlagsSampled
} else {
scc.TraceFlags = psc.TraceFlags() &^ trace.FlagsSampled
}
span.spanContext = trace.NewSpanContext(scc)
if !isRecording(samplingResult) {
return span
}
startTime := o.Timestamp()
if startTime.IsZero() {
startTime = time.Now()
}
span.startTime = startTime
span.spanKind = trace.ValidateSpanKind(o.SpanKind())
span.name = name
span.parent = psc
span.resource = provider.resource
span.instrumentationLibrary = tr.instrumentationLibrary
span.SetAttributes(samplingResult.Attributes...)
return span
} }
// nonRecordingSpan is a minimal implementation of the OpenTelemetry Span API
// that wraps a SpanContext. It performs no operations other than to return
// the wrapped SpanContext or TracerProvider that created it.
type nonRecordingSpan struct {
// tracer is the SDK tracer that created this span.
tracer *tracer
sc trace.SpanContext
}
var _ trace.Span = nonRecordingSpan{}
// SpanContext returns the wrapped SpanContext.
func (s nonRecordingSpan) SpanContext() trace.SpanContext { return s.sc }
// IsRecording always returns false.
func (nonRecordingSpan) IsRecording() bool { return false }
// SetStatus does nothing.
func (nonRecordingSpan) SetStatus(codes.Code, string) {}
// SetError does nothing.
func (nonRecordingSpan) SetError(bool) {}
// SetAttributes does nothing.
func (nonRecordingSpan) SetAttributes(...attribute.KeyValue) {}
// End does nothing.
func (nonRecordingSpan) End(...trace.SpanEndOption) {}
// RecordError does nothing.
func (nonRecordingSpan) RecordError(error, ...trace.EventOption) {}
// AddEvent does nothing.
func (nonRecordingSpan) AddEvent(string, ...trace.EventOption) {}
// SetName does nothing.
func (nonRecordingSpan) SetName(string) {}
// TracerProvider returns the trace.TracerProvider that provided the Tracer
// that created this span.
func (s nonRecordingSpan) TracerProvider() trace.TracerProvider { return s.tracer.provider }
func isRecording(s SamplingResult) bool { func isRecording(s SamplingResult) bool {
return s.Decision == RecordOnly || s.Decision == RecordAndSample return s.Decision == RecordOnly || s.Decision == RecordAndSample
} }
@ -635,7 +649,7 @@ func isSampled(s SamplingResult) bool {
type Status struct { type Status struct {
// Code is an identifier of a Spans state classification. // Code is an identifier of a Spans state classification.
Code codes.Code Code codes.Code
// Message is a user hint about why that status was set. It is only // Description is a user hint about why that status was set. It is only
// applicable when Code is Error. // applicable when Code is Error.
Description string Description string
} }

View File

@ -16,7 +16,7 @@ package trace // import "go.opentelemetry.io/otel/sdk/trace"
import ( import (
"context" "context"
rt "runtime/trace" "time"
"go.opentelemetry.io/otel/trace" "go.opentelemetry.io/otel/trace"
@ -34,42 +34,120 @@ var _ trace.Tracer = &tracer{}
// //
// The Span is created with the provided name and as a child of any existing // The Span is created with the provided name and as a child of any existing
// span context found in the passed context. The created Span will be // span context found in the passed context. The created Span will be
// configured appropriately by any SpanOption passed. Any Timestamp option // configured appropriately by any SpanOption passed.
// passed will be used as the start time of the Span's life-cycle.
func (tr *tracer) Start(ctx context.Context, name string, options ...trace.SpanStartOption) (context.Context, trace.Span) { func (tr *tracer) Start(ctx context.Context, name string, options ...trace.SpanStartOption) (context.Context, trace.Span) {
config := trace.NewSpanStartConfig(options...) config := trace.NewSpanStartConfig(options...)
// For local spans created by this SDK, track child span count. // For local spans created by this SDK, track child span count.
if p := trace.SpanFromContext(ctx); p != nil { if p := trace.SpanFromContext(ctx); p != nil {
if sdkSpan, ok := p.(*span); ok { if sdkSpan, ok := p.(*recordingSpan); ok {
sdkSpan.addChild() sdkSpan.addChild()
} }
} }
span := startSpanInternal(ctx, tr, name, config) s := tr.newSpan(ctx, name, &config)
for _, l := range config.Links() { if rw, ok := s.(ReadWriteSpan); ok && s.IsRecording() {
span.addLink(l)
}
span.SetAttributes(config.Attributes()...)
span.tracer = tr
if span.IsRecording() {
sps, _ := tr.provider.spanProcessors.Load().(spanProcessorStates) sps, _ := tr.provider.spanProcessors.Load().(spanProcessorStates)
for _, sp := range sps { for _, sp := range sps {
sp.sp.OnStart(ctx, span) sp.sp.OnStart(ctx, rw)
} }
} }
if rtt, ok := s.(runtimeTracer); ok {
ctx = rtt.runtimeTrace(ctx)
}
ctx, span.executionTracerTaskEnd = func(ctx context.Context) (context.Context, func()) { return trace.ContextWithSpan(ctx, s), s
if !rt.IsEnabled() { }
// Avoid additional overhead if
// runtime/trace is not enabled. type runtimeTracer interface {
return ctx, func() {} // runtimeTrace starts a "runtime/trace".Task for the span and
} // returns a context containing the task.
nctx, task := rt.NewTask(ctx, name) runtimeTrace(ctx context.Context) context.Context
return nctx, task.End }
}(ctx)
// newSpan returns a new configured span.
return trace.ContextWithSpan(ctx, span), span func (tr *tracer) newSpan(ctx context.Context, name string, config *trace.SpanConfig) trace.Span {
// If told explicitly to make this a new root use a zero value SpanContext
// as a parent which contains an invalid trace ID and is not remote.
var psc trace.SpanContext
if config.NewRoot() {
ctx = trace.ContextWithSpanContext(ctx, psc)
} else {
psc = trace.SpanContextFromContext(ctx)
}
// If there is a valid parent trace ID, use it to ensure the continuity of
// the trace. Always generate a new span ID so other components can rely
// on a unique span ID, even if the Span is non-recording.
var tid trace.TraceID
var sid trace.SpanID
if !psc.TraceID().IsValid() {
tid, sid = tr.provider.idGenerator.NewIDs(ctx)
} else {
tid = psc.TraceID()
sid = tr.provider.idGenerator.NewSpanID(ctx, tid)
}
samplingResult := tr.provider.sampler.ShouldSample(SamplingParameters{
ParentContext: ctx,
TraceID: tid,
Name: name,
Kind: config.SpanKind(),
Attributes: config.Attributes(),
Links: config.Links(),
})
scc := trace.SpanContextConfig{
TraceID: tid,
SpanID: sid,
TraceState: samplingResult.Tracestate,
}
if isSampled(samplingResult) {
scc.TraceFlags = psc.TraceFlags() | trace.FlagsSampled
} else {
scc.TraceFlags = psc.TraceFlags() &^ trace.FlagsSampled
}
sc := trace.NewSpanContext(scc)
if !isRecording(samplingResult) {
return tr.newNonRecordingSpan(sc)
}
return tr.newRecordingSpan(psc, sc, name, samplingResult, config)
}
// newRecordingSpan returns a new configured recordingSpan.
func (tr *tracer) newRecordingSpan(psc, sc trace.SpanContext, name string, sr SamplingResult, config *trace.SpanConfig) *recordingSpan {
startTime := config.Timestamp()
if startTime.IsZero() {
startTime = time.Now()
}
s := &recordingSpan{
parent: psc,
spanContext: sc,
spanKind: trace.ValidateSpanKind(config.SpanKind()),
name: name,
startTime: startTime,
attributes: newAttributesMap(tr.provider.spanLimits.AttributeCountLimit),
events: newEvictedQueue(tr.provider.spanLimits.EventCountLimit),
links: newEvictedQueue(tr.provider.spanLimits.LinkCountLimit),
tracer: tr,
spanLimits: tr.provider.spanLimits,
resource: tr.provider.resource,
instrumentationLibrary: tr.instrumentationLibrary,
}
for _, l := range config.Links() {
s.addLink(l)
}
s.SetAttributes(sr.Attributes...)
s.SetAttributes(config.Attributes()...)
return s
}
// newNonRecordingSpan returns a new configured nonRecordingSpan.
func (tr *tracer) newNonRecordingSpan(sc trace.SpanContext) nonRecordingSpan {
return nonRecordingSpan{tracer: tr, sc: sc}
} }

View File

@ -14,9 +14,6 @@
// Package semconv implements OpenTelemetry semantic conventions. // Package semconv implements OpenTelemetry semantic conventions.
// //
// This package is currently in a Release Candidate phase. Backwards incompatible changes
// may be introduced prior to v1.0.0, but we believe the current API is ready to stabilize.
//
// OpenTelemetry semantic conventions are agreed standardized naming // OpenTelemetry semantic conventions are agreed standardized naming
// patterns for OpenTelemetry things. This package represents the conventions // patterns for OpenTelemetry things. This package represents the conventions
// as of the v1.4.0 version of the OpenTelemetry specification. // as of the v1.4.0 version of the OpenTelemetry specification.

View File

@ -24,12 +24,14 @@ const (
// //
// Type: Enum // Type: Enum
// Required: No // Required: No
// Stability: stable
// Examples: 'gcp' // Examples: 'gcp'
CloudProviderKey = attribute.Key("cloud.provider") CloudProviderKey = attribute.Key("cloud.provider")
// The cloud account ID the resource is assigned to. // The cloud account ID the resource is assigned to.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '111111111111', 'opentelemetry' // Examples: '111111111111', 'opentelemetry'
CloudAccountIDKey = attribute.Key("cloud.account.id") CloudAccountIDKey = attribute.Key("cloud.account.id")
// The geographical region the resource is running. Refer to your provider's docs // The geographical region the resource is running. Refer to your provider's docs
@ -41,6 +43,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'us-central1', 'us-east-1' // Examples: 'us-central1', 'us-east-1'
CloudRegionKey = attribute.Key("cloud.region") CloudRegionKey = attribute.Key("cloud.region")
// Cloud regions often have multiple, isolated locations known as zones to // Cloud regions often have multiple, isolated locations known as zones to
@ -49,6 +52,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'us-east-1c' // Examples: 'us-east-1c'
// Note: Availability zones are called "zones" on Google Cloud. // Note: Availability zones are called "zones" on Google Cloud.
CloudAvailabilityZoneKey = attribute.Key("cloud.availability_zone") CloudAvailabilityZoneKey = attribute.Key("cloud.availability_zone")
@ -56,6 +60,7 @@ const (
// //
// Type: Enum // Type: Enum
// Required: No // Required: No
// Stability: stable
// Examples: 'aws_ec2', 'azure_vm', 'gcp_compute_engine' // Examples: 'aws_ec2', 'azure_vm', 'gcp_compute_engine'
// Note: The prefix of the service SHOULD match the one specified in // Note: The prefix of the service SHOULD match the one specified in
// `cloud.provider`. // `cloud.provider`.
@ -111,6 +116,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'arn:aws:ecs:us- // Examples: 'arn:aws:ecs:us-
// west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9' // west-1:123456789123:container/32624152-9086-4f0e-acae-1a75b14fe4d9'
AWSECSContainerARNKey = attribute.Key("aws.ecs.container.arn") AWSECSContainerARNKey = attribute.Key("aws.ecs.container.arn")
@ -119,6 +125,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster' // Examples: 'arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster'
AWSECSClusterARNKey = attribute.Key("aws.ecs.cluster.arn") AWSECSClusterARNKey = attribute.Key("aws.ecs.cluster.arn")
// The [launch type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/l // The [launch type](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/l
@ -126,6 +133,7 @@ const (
// //
// Type: Enum // Type: Enum
// Required: No // Required: No
// Stability: stable
// Examples: 'ec2', 'fargate' // Examples: 'ec2', 'fargate'
AWSECSLaunchtypeKey = attribute.Key("aws.ecs.launchtype") AWSECSLaunchtypeKey = attribute.Key("aws.ecs.launchtype")
// The ARN of an [ECS task definition](https://docs.aws.amazon.com/AmazonECS/lates // The ARN of an [ECS task definition](https://docs.aws.amazon.com/AmazonECS/lates
@ -133,6 +141,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'arn:aws:ecs:us- // Examples: 'arn:aws:ecs:us-
// west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b' // west-1:123456789123:task/10838bed-421f-43ef-870a-f43feacbbb5b'
AWSECSTaskARNKey = attribute.Key("aws.ecs.task.arn") AWSECSTaskARNKey = attribute.Key("aws.ecs.task.arn")
@ -140,12 +149,14 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'opentelemetry-family' // Examples: 'opentelemetry-family'
AWSECSTaskFamilyKey = attribute.Key("aws.ecs.task.family") AWSECSTaskFamilyKey = attribute.Key("aws.ecs.task.family")
// The revision for this task definition. // The revision for this task definition.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '8', '26' // Examples: '8', '26'
AWSECSTaskRevisionKey = attribute.Key("aws.ecs.task.revision") AWSECSTaskRevisionKey = attribute.Key("aws.ecs.task.revision")
) )
@ -163,6 +174,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster' // Examples: 'arn:aws:ecs:us-west-2:123456789123:cluster/my-cluster'
AWSEKSClusterARNKey = attribute.Key("aws.eks.cluster.arn") AWSEKSClusterARNKey = attribute.Key("aws.eks.cluster.arn")
) )
@ -173,6 +185,7 @@ const (
// //
// Type: string[] // Type: string[]
// Required: No // Required: No
// Stability: stable
// Examples: '/aws/lambda/my-function', 'opentelemetry-service' // Examples: '/aws/lambda/my-function', 'opentelemetry-service'
// Note: Multiple log groups must be supported for cases like multi-container // Note: Multiple log groups must be supported for cases like multi-container
// applications, where a single application has sidecar containers, and each write // applications, where a single application has sidecar containers, and each write
@ -182,6 +195,7 @@ const (
// //
// Type: string[] // Type: string[]
// Required: No // Required: No
// Stability: stable
// Examples: 'arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*' // Examples: 'arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:*'
// Note: See the [log group ARN format // Note: See the [log group ARN format
// documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam- // documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/iam-
@ -191,12 +205,14 @@ const (
// //
// Type: string[] // Type: string[]
// Required: No // Required: No
// Stability: stable
// Examples: 'logs/main/10838bed-421f-43ef-870a-f43feacbbb5b' // Examples: 'logs/main/10838bed-421f-43ef-870a-f43feacbbb5b'
AWSLogStreamNamesKey = attribute.Key("aws.log.stream.names") AWSLogStreamNamesKey = attribute.Key("aws.log.stream.names")
// The ARN(s) of the AWS log stream(s). // The ARN(s) of the AWS log stream(s).
// //
// Type: string[] // Type: string[]
// Required: No // Required: No
// Stability: stable
// Examples: 'arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log- // Examples: 'arn:aws:logs:us-west-1:123456789012:log-group:/aws/my/group:log-
// stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b' // stream:logs/main/10838bed-421f-43ef-870a-f43feacbbb5b'
// Note: See the [log stream ARN format // Note: See the [log stream ARN format
@ -213,6 +229,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'opentelemetry-autoconf' // Examples: 'opentelemetry-autoconf'
ContainerNameKey = attribute.Key("container.name") ContainerNameKey = attribute.Key("container.name")
// Container ID. Usually a UUID, as for example used to [identify Docker // Container ID. Usually a UUID, as for example used to [identify Docker
@ -221,24 +238,28 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'a3bf90e006b2' // Examples: 'a3bf90e006b2'
ContainerIDKey = attribute.Key("container.id") ContainerIDKey = attribute.Key("container.id")
// The container runtime managing this container. // The container runtime managing this container.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'docker', 'containerd', 'rkt' // Examples: 'docker', 'containerd', 'rkt'
ContainerRuntimeKey = attribute.Key("container.runtime") ContainerRuntimeKey = attribute.Key("container.runtime")
// Name of the image the container was built on. // Name of the image the container was built on.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'gcr.io/opentelemetry/operator' // Examples: 'gcr.io/opentelemetry/operator'
ContainerImageNameKey = attribute.Key("container.image.name") ContainerImageNameKey = attribute.Key("container.image.name")
// Container image tag. // Container image tag.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '0.1' // Examples: '0.1'
ContainerImageTagKey = attribute.Key("container.image.tag") ContainerImageTagKey = attribute.Key("container.image.tag")
) )
@ -251,6 +272,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'staging', 'production' // Examples: 'staging', 'production'
DeploymentEnvironmentKey = attribute.Key("deployment.environment") DeploymentEnvironmentKey = attribute.Key("deployment.environment")
) )
@ -261,6 +283,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '2ab2916d-a51f-4ac8-80ee-45ac31a28092' // Examples: '2ab2916d-a51f-4ac8-80ee-45ac31a28092'
// Note: The device identifier MUST only be defined using the values outlined // Note: The device identifier MUST only be defined using the values outlined
// below. This value is not an advertising identifier and MUST NOT be used as // below. This value is not an advertising identifier and MUST NOT be used as
@ -278,6 +301,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'iPhone3,4', 'SM-G920F' // Examples: 'iPhone3,4', 'SM-G920F'
// Note: It's recommended this value represents a machine readable version of the // Note: It's recommended this value represents a machine readable version of the
// model identifier rather than the market or consumer-friendly name of the // model identifier rather than the market or consumer-friendly name of the
@ -287,6 +311,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'iPhone 6s Plus', 'Samsung Galaxy S6' // Examples: 'iPhone 6s Plus', 'Samsung Galaxy S6'
// Note: It's recommended this value represents a human readable version of the // Note: It's recommended this value represents a human readable version of the
// device model rather than a machine readable alternative. // device model rather than a machine readable alternative.
@ -299,12 +324,14 @@ const (
// //
// Type: string // Type: string
// Required: Always // Required: Always
// Stability: stable
// Examples: 'my-function' // Examples: 'my-function'
FaaSNameKey = attribute.Key("faas.name") FaaSNameKey = attribute.Key("faas.name")
// The unique ID of the function being executed. // The unique ID of the function being executed.
// //
// Type: string // Type: string
// Required: Always // Required: Always
// Stability: stable
// Examples: 'arn:aws:lambda:us-west-2:123456789012:function:my-function' // Examples: 'arn:aws:lambda:us-west-2:123456789012:function:my-function'
// Note: For example, in AWS Lambda this field corresponds to the // Note: For example, in AWS Lambda this field corresponds to the
// [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and- // [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-
@ -317,18 +344,21 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '2.0.0' // Examples: '2.0.0'
FaaSVersionKey = attribute.Key("faas.version") FaaSVersionKey = attribute.Key("faas.version")
// The execution environment ID as a string. // The execution environment ID as a string.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'my-function:instance-0001' // Examples: 'my-function:instance-0001'
FaaSInstanceKey = attribute.Key("faas.instance") FaaSInstanceKey = attribute.Key("faas.instance")
// The amount of memory available to the serverless function in MiB. // The amount of memory available to the serverless function in MiB.
// //
// Type: int // Type: int
// Required: No // Required: No
// Stability: stable
// Examples: 128 // Examples: 128
// Note: It's recommended to set this attribute since e.g. too little memory can // Note: It's recommended to set this attribute since e.g. too little memory can
// easily stop a Java AWS Lambda function from working correctly. On AWS Lambda, // easily stop a Java AWS Lambda function from working correctly. On AWS Lambda,
@ -344,6 +374,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'opentelemetry-test' // Examples: 'opentelemetry-test'
HostIDKey = attribute.Key("host.id") HostIDKey = attribute.Key("host.id")
// Name of the host. On Unix systems, it may contain what the hostname command // Name of the host. On Unix systems, it may contain what the hostname command
@ -352,29 +383,34 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'opentelemetry-test' // Examples: 'opentelemetry-test'
HostNameKey = attribute.Key("host.name") HostNameKey = attribute.Key("host.name")
// Type of host. For Cloud, this must be the machine type. // Type of host. For Cloud, this must be the machine type.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'n1-standard-1' // Examples: 'n1-standard-1'
HostTypeKey = attribute.Key("host.type") HostTypeKey = attribute.Key("host.type")
// The CPU architecture the host system is running on. // The CPU architecture the host system is running on.
// //
// Type: Enum // Type: Enum
// Required: No // Required: No
// Stability: stable
HostArchKey = attribute.Key("host.arch") HostArchKey = attribute.Key("host.arch")
// Name of the VM image or OS install the host was instantiated from. // Name of the VM image or OS install the host was instantiated from.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'infra-ami-eks-worker-node-7d4ec78312', 'CentOS-8-x86_64-1905' // Examples: 'infra-ami-eks-worker-node-7d4ec78312', 'CentOS-8-x86_64-1905'
HostImageNameKey = attribute.Key("host.image.name") HostImageNameKey = attribute.Key("host.image.name")
// VM image ID. For Cloud, this value is from the provider. // VM image ID. For Cloud, this value is from the provider.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'ami-07b06b442921831e5' // Examples: 'ami-07b06b442921831e5'
HostImageIDKey = attribute.Key("host.image.id") HostImageIDKey = attribute.Key("host.image.id")
// The version string of the VM image as defined in [Version // The version string of the VM image as defined in [Version
@ -382,6 +418,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '0.1' // Examples: '0.1'
HostImageVersionKey = attribute.Key("host.image.version") HostImageVersionKey = attribute.Key("host.image.version")
) )
@ -409,6 +446,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'opentelemetry-cluster' // Examples: 'opentelemetry-cluster'
K8SClusterNameKey = attribute.Key("k8s.cluster.name") K8SClusterNameKey = attribute.Key("k8s.cluster.name")
) )
@ -419,12 +457,14 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'node-1' // Examples: 'node-1'
K8SNodeNameKey = attribute.Key("k8s.node.name") K8SNodeNameKey = attribute.Key("k8s.node.name")
// The UID of the Node. // The UID of the Node.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2' // Examples: '1eb3a0c6-0477-4080-a9cb-0cb7db65c6a2'
K8SNodeUIDKey = attribute.Key("k8s.node.uid") K8SNodeUIDKey = attribute.Key("k8s.node.uid")
) )
@ -435,6 +475,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'default' // Examples: 'default'
K8SNamespaceNameKey = attribute.Key("k8s.namespace.name") K8SNamespaceNameKey = attribute.Key("k8s.namespace.name")
) )
@ -445,12 +486,14 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff' // Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
K8SPodUIDKey = attribute.Key("k8s.pod.uid") K8SPodUIDKey = attribute.Key("k8s.pod.uid")
// The name of the Pod. // The name of the Pod.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'opentelemetry-pod-autoconf' // Examples: 'opentelemetry-pod-autoconf'
K8SPodNameKey = attribute.Key("k8s.pod.name") K8SPodNameKey = attribute.Key("k8s.pod.name")
) )
@ -461,6 +504,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'redis' // Examples: 'redis'
K8SContainerNameKey = attribute.Key("k8s.container.name") K8SContainerNameKey = attribute.Key("k8s.container.name")
) )
@ -471,12 +515,14 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff' // Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
K8SReplicasetUIDKey = attribute.Key("k8s.replicaset.uid") K8SReplicasetUIDKey = attribute.Key("k8s.replicaset.uid")
// The name of the ReplicaSet. // The name of the ReplicaSet.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'opentelemetry' // Examples: 'opentelemetry'
K8SReplicasetNameKey = attribute.Key("k8s.replicaset.name") K8SReplicasetNameKey = attribute.Key("k8s.replicaset.name")
) )
@ -487,12 +533,14 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff' // Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
K8SDeploymentUIDKey = attribute.Key("k8s.deployment.uid") K8SDeploymentUIDKey = attribute.Key("k8s.deployment.uid")
// The name of the Deployment. // The name of the Deployment.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'opentelemetry' // Examples: 'opentelemetry'
K8SDeploymentNameKey = attribute.Key("k8s.deployment.name") K8SDeploymentNameKey = attribute.Key("k8s.deployment.name")
) )
@ -503,12 +551,14 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff' // Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
K8SStatefulsetUIDKey = attribute.Key("k8s.statefulset.uid") K8SStatefulsetUIDKey = attribute.Key("k8s.statefulset.uid")
// The name of the StatefulSet. // The name of the StatefulSet.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'opentelemetry' // Examples: 'opentelemetry'
K8SStatefulsetNameKey = attribute.Key("k8s.statefulset.name") K8SStatefulsetNameKey = attribute.Key("k8s.statefulset.name")
) )
@ -519,12 +569,14 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff' // Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
K8SDaemonsetUIDKey = attribute.Key("k8s.daemonset.uid") K8SDaemonsetUIDKey = attribute.Key("k8s.daemonset.uid")
// The name of the DaemonSet. // The name of the DaemonSet.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'opentelemetry' // Examples: 'opentelemetry'
K8SDaemonsetNameKey = attribute.Key("k8s.daemonset.name") K8SDaemonsetNameKey = attribute.Key("k8s.daemonset.name")
) )
@ -535,12 +587,14 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff' // Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
K8SJobUIDKey = attribute.Key("k8s.job.uid") K8SJobUIDKey = attribute.Key("k8s.job.uid")
// The name of the Job. // The name of the Job.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'opentelemetry' // Examples: 'opentelemetry'
K8SJobNameKey = attribute.Key("k8s.job.name") K8SJobNameKey = attribute.Key("k8s.job.name")
) )
@ -551,12 +605,14 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff' // Examples: '275ecb36-5aa8-4c2a-9c47-d8bb681b9aff'
K8SCronJobUIDKey = attribute.Key("k8s.cronjob.uid") K8SCronJobUIDKey = attribute.Key("k8s.cronjob.uid")
// The name of the CronJob. // The name of the CronJob.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'opentelemetry' // Examples: 'opentelemetry'
K8SCronJobNameKey = attribute.Key("k8s.cronjob.name") K8SCronJobNameKey = attribute.Key("k8s.cronjob.name")
) )
@ -567,18 +623,21 @@ const (
// //
// Type: Enum // Type: Enum
// Required: Always // Required: Always
// Stability: stable
OSTypeKey = attribute.Key("os.type") OSTypeKey = attribute.Key("os.type")
// Human readable (not intended to be parsed) OS version information, like e.g. // Human readable (not intended to be parsed) OS version information, like e.g.
// reported by `ver` or `lsb_release -a` commands. // reported by `ver` or `lsb_release -a` commands.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'Microsoft Windows [Version 10.0.18363.778]', 'Ubuntu 18.04.1 LTS' // Examples: 'Microsoft Windows [Version 10.0.18363.778]', 'Ubuntu 18.04.1 LTS'
OSDescriptionKey = attribute.Key("os.description") OSDescriptionKey = attribute.Key("os.description")
// Human readable operating system name. // Human readable operating system name.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'iOS', 'Android', 'Ubuntu' // Examples: 'iOS', 'Android', 'Ubuntu'
OSNameKey = attribute.Key("os.name") OSNameKey = attribute.Key("os.name")
// The version string of the operating system as defined in [Version // The version string of the operating system as defined in [Version
@ -586,6 +645,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '14.2.1', '18.04.1' // Examples: '14.2.1', '18.04.1'
OSVersionKey = attribute.Key("os.version") OSVersionKey = attribute.Key("os.version")
) )
@ -621,6 +681,7 @@ const (
// //
// Type: int // Type: int
// Required: No // Required: No
// Stability: stable
// Examples: 1234 // Examples: 1234
ProcessPIDKey = attribute.Key("process.pid") ProcessPIDKey = attribute.Key("process.pid")
// The name of the process executable. On Linux based systems, can be set to the // The name of the process executable. On Linux based systems, can be set to the
@ -629,6 +690,7 @@ const (
// //
// Type: string // Type: string
// Required: See below // Required: See below
// Stability: stable
// Examples: 'otelcol' // Examples: 'otelcol'
ProcessExecutableNameKey = attribute.Key("process.executable.name") ProcessExecutableNameKey = attribute.Key("process.executable.name")
// The full path to the process executable. On Linux based systems, can be set to // The full path to the process executable. On Linux based systems, can be set to
@ -637,6 +699,7 @@ const (
// //
// Type: string // Type: string
// Required: See below // Required: See below
// Stability: stable
// Examples: '/usr/bin/cmd/otelcol' // Examples: '/usr/bin/cmd/otelcol'
ProcessExecutablePathKey = attribute.Key("process.executable.path") ProcessExecutablePathKey = attribute.Key("process.executable.path")
// The command used to launch the process (i.e. the command name). On Linux based // The command used to launch the process (i.e. the command name). On Linux based
@ -645,6 +708,7 @@ const (
// //
// Type: string // Type: string
// Required: See below // Required: See below
// Stability: stable
// Examples: 'cmd/otelcol' // Examples: 'cmd/otelcol'
ProcessCommandKey = attribute.Key("process.command") ProcessCommandKey = attribute.Key("process.command")
// The full command used to launch the process as a single string representing the // The full command used to launch the process as a single string representing the
@ -654,6 +718,7 @@ const (
// //
// Type: string // Type: string
// Required: See below // Required: See below
// Stability: stable
// Examples: 'C:\\cmd\\otecol --config="my directory\\config.yaml"' // Examples: 'C:\\cmd\\otecol --config="my directory\\config.yaml"'
ProcessCommandLineKey = attribute.Key("process.command_line") ProcessCommandLineKey = attribute.Key("process.command_line")
// All the command arguments (including the command/executable itself) as received // All the command arguments (including the command/executable itself) as received
@ -664,12 +729,14 @@ const (
// //
// Type: string[] // Type: string[]
// Required: See below // Required: See below
// Stability: stable
// Examples: 'cmd/otecol', '--config=config.yaml' // Examples: 'cmd/otecol', '--config=config.yaml'
ProcessCommandArgsKey = attribute.Key("process.command_args") ProcessCommandArgsKey = attribute.Key("process.command_args")
// The username of the user that owns the process. // The username of the user that owns the process.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'root' // Examples: 'root'
ProcessOwnerKey = attribute.Key("process.owner") ProcessOwnerKey = attribute.Key("process.owner")
) )
@ -681,6 +748,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'OpenJDK Runtime Environment' // Examples: 'OpenJDK Runtime Environment'
ProcessRuntimeNameKey = attribute.Key("process.runtime.name") ProcessRuntimeNameKey = attribute.Key("process.runtime.name")
// The version of the runtime of this process, as returned by the runtime without // The version of the runtime of this process, as returned by the runtime without
@ -688,6 +756,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '14.0.2' // Examples: '14.0.2'
ProcessRuntimeVersionKey = attribute.Key("process.runtime.version") ProcessRuntimeVersionKey = attribute.Key("process.runtime.version")
// An additional description about the runtime of the process, for example a // An additional description about the runtime of the process, for example a
@ -695,6 +764,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0' // Examples: 'Eclipse OpenJ9 Eclipse OpenJ9 VM openj9-0.21.0'
ProcessRuntimeDescriptionKey = attribute.Key("process.runtime.description") ProcessRuntimeDescriptionKey = attribute.Key("process.runtime.description")
) )
@ -705,6 +775,7 @@ const (
// //
// Type: string // Type: string
// Required: Always // Required: Always
// Stability: stable
// Examples: 'shoppingcart' // Examples: 'shoppingcart'
// Note: MUST be the same for all instances of horizontally scaled services. If // Note: MUST be the same for all instances of horizontally scaled services. If
// the value was not specified, SDKs MUST fallback to `unknown_service:` // the value was not specified, SDKs MUST fallback to `unknown_service:`
@ -716,6 +787,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'Shop' // Examples: 'Shop'
// Note: A string value having a meaning that helps to distinguish a group of // Note: A string value having a meaning that helps to distinguish a group of
// services, for example the team name that owns a group of services. // services, for example the team name that owns a group of services.
@ -729,6 +801,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '627cc493-f310-47de-96bd-71410b7dec09' // Examples: '627cc493-f310-47de-96bd-71410b7dec09'
// Note: MUST be unique for each instance of the same // Note: MUST be unique for each instance of the same
// `service.namespace,service.name` pair (in other words // `service.namespace,service.name` pair (in other words
@ -747,6 +820,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '2.0.0' // Examples: '2.0.0'
ServiceVersionKey = attribute.Key("service.version") ServiceVersionKey = attribute.Key("service.version")
) )
@ -757,30 +831,34 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'opentelemetry' // Examples: 'opentelemetry'
TelemetrySDKNameKey = attribute.Key("telemetry.sdk.name") TelemetrySDKNameKey = attribute.Key("telemetry.sdk.name")
// The language of the telemetry SDK. // The language of the telemetry SDK.
// //
// Type: Enum // Type: Enum
// Required: No // Required: No
// Stability: stable
TelemetrySDKLanguageKey = attribute.Key("telemetry.sdk.language") TelemetrySDKLanguageKey = attribute.Key("telemetry.sdk.language")
// The version string of the telemetry SDK. // The version string of the telemetry SDK.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '1.2.3' // Examples: '1.2.3'
TelemetrySDKVersionKey = attribute.Key("telemetry.sdk.version") TelemetrySDKVersionKey = attribute.Key("telemetry.sdk.version")
// The version string of the auto instrumentation agent, if used. // The version string of the auto instrumentation agent, if used.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '1.2.3' // Examples: '1.2.3'
TelemetryAutoVersionKey = attribute.Key("telemetry.auto.version") TelemetryAutoVersionKey = attribute.Key("telemetry.auto.version")
) )
var ( var (
// cpp // cpp
TelemetrySDKLanguageCpp = TelemetrySDKLanguageKey.String("cpp") TelemetrySDKLanguageCPP = TelemetrySDKLanguageKey.String("cpp")
// dotnet // dotnet
TelemetrySDKLanguageDotnet = TelemetrySDKLanguageKey.String("dotnet") TelemetrySDKLanguageDotnet = TelemetrySDKLanguageKey.String("dotnet")
// erlang // erlang
@ -807,12 +885,14 @@ const (
// //
// Type: string // Type: string
// Required: Always // Required: Always
// Stability: stable
// Examples: 'WildFly' // Examples: 'WildFly'
WebEngineNameKey = attribute.Key("webengine.name") WebEngineNameKey = attribute.Key("webengine.name")
// The version of the web engine. // The version of the web engine.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '21.0.0' // Examples: '21.0.0'
WebEngineVersionKey = attribute.Key("webengine.version") WebEngineVersionKey = attribute.Key("webengine.version")
// Additional description of the web engine (e.g. detailed version and edition // Additional description of the web engine (e.g. detailed version and edition
@ -820,6 +900,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) - 2.2.2.Final' // Examples: 'WildFly Full 21.0.0.Final (WildFly Core 13.0.1.Final) - 2.2.2.Final'
WebEngineDescriptionKey = attribute.Key("webengine.description") WebEngineDescriptionKey = attribute.Key("webengine.description")
) )

View File

@ -25,18 +25,21 @@ const (
// //
// Type: Enum // Type: Enum
// Required: Always // Required: Always
// Stability: stable
DBSystemKey = attribute.Key("db.system") DBSystemKey = attribute.Key("db.system")
// The connection string used to connect to the database. It is recommended to // The connection string used to connect to the database. It is recommended to
// remove embedded credentials. // remove embedded credentials.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'Server=(localdb)\\v11.0;Integrated Security=true;' // Examples: 'Server=(localdb)\\v11.0;Integrated Security=true;'
DBConnectionStringKey = attribute.Key("db.connection_string") DBConnectionStringKey = attribute.Key("db.connection_string")
// Username for accessing the database. // Username for accessing the database.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'readonly_user', 'reporting_user' // Examples: 'readonly_user', 'reporting_user'
DBUserKey = attribute.Key("db.user") DBUserKey = attribute.Key("db.user")
// The fully-qualified class name of the [Java Database Connectivity // The fully-qualified class name of the [Java Database Connectivity
@ -45,6 +48,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'org.postgresql.Driver', // Examples: 'org.postgresql.Driver',
// 'com.microsoft.sqlserver.jdbc.SQLServerDriver' // 'com.microsoft.sqlserver.jdbc.SQLServerDriver'
DBJDBCDriverClassnameKey = attribute.Key("db.jdbc.driver_classname") DBJDBCDriverClassnameKey = attribute.Key("db.jdbc.driver_classname")
@ -55,6 +59,7 @@ const (
// //
// Type: string // Type: string
// Required: Required, if applicable and no more-specific attribute is defined. // Required: Required, if applicable and no more-specific attribute is defined.
// Stability: stable
// Examples: 'customers', 'main' // Examples: 'customers', 'main'
// Note: In some SQL databases, the database name to be used is called "schema // Note: In some SQL databases, the database name to be used is called "schema
// name". // name".
@ -64,6 +69,7 @@ const (
// Type: string // Type: string
// Required: Required if applicable and not explicitly disabled via // Required: Required if applicable and not explicitly disabled via
// instrumentation configuration. // instrumentation configuration.
// Stability: stable
// Examples: 'SELECT * FROM wuser_table', 'SET mykey "WuValue"' // Examples: 'SELECT * FROM wuser_table', 'SET mykey "WuValue"'
// Note: The value may be sanitized to exclude sensitive information. // Note: The value may be sanitized to exclude sensitive information.
DBStatementKey = attribute.Key("db.statement") DBStatementKey = attribute.Key("db.statement")
@ -73,6 +79,7 @@ const (
// //
// Type: string // Type: string
// Required: Required, if `db.statement` is not applicable. // Required: Required, if `db.statement` is not applicable.
// Stability: stable
// Examples: 'findAndModify', 'HMSET', 'SELECT' // Examples: 'findAndModify', 'HMSET', 'SELECT'
// Note: When setting this to an SQL keyword, it is not recommended to attempt any // Note: When setting this to an SQL keyword, it is not recommended to attempt any
// client-side parsing of `db.statement` just to get this property, but it should // client-side parsing of `db.statement` just to get this property, but it should
@ -187,6 +194,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'MSSQLSERVER' // Examples: 'MSSQLSERVER'
// Note: If setting a `db.mssql.instance_name`, `net.peer.port` is no longer // Note: If setting a `db.mssql.instance_name`, `net.peer.port` is no longer
// required (but still recommended if non-standard). // required (but still recommended if non-standard).
@ -200,12 +208,14 @@ const (
// //
// Type: string // Type: string
// Required: Always // Required: Always
// Stability: stable
// Examples: 'mykeyspace' // Examples: 'mykeyspace'
DBCassandraKeyspaceKey = attribute.Key("db.cassandra.keyspace") DBCassandraKeyspaceKey = attribute.Key("db.cassandra.keyspace")
// The fetch size used for paging, i.e. how many rows will be returned at once. // The fetch size used for paging, i.e. how many rows will be returned at once.
// //
// Type: int // Type: int
// Required: No // Required: No
// Stability: stable
// Examples: 5000 // Examples: 5000
DBCassandraPageSizeKey = attribute.Key("db.cassandra.page_size") DBCassandraPageSizeKey = attribute.Key("db.cassandra.page_size")
// The consistency level of the query. Based on consistency values from // The consistency level of the query. Based on consistency values from
@ -214,12 +224,14 @@ const (
// //
// Type: Enum // Type: Enum
// Required: No // Required: No
// Stability: stable
DBCassandraConsistencyLevelKey = attribute.Key("db.cassandra.consistency_level") DBCassandraConsistencyLevelKey = attribute.Key("db.cassandra.consistency_level")
// The name of the primary table that the operation is acting upon, including the // The name of the primary table that the operation is acting upon, including the
// schema name (if applicable). // schema name (if applicable).
// //
// Type: string // Type: string
// Required: Recommended if available. // Required: Recommended if available.
// Stability: stable
// Examples: 'mytable' // Examples: 'mytable'
// Note: This mirrors the db.sql.table attribute but references cassandra rather // Note: This mirrors the db.sql.table attribute but references cassandra rather
// than sql. It is not recommended to attempt any client-side parsing of // than sql. It is not recommended to attempt any client-side parsing of
@ -231,24 +243,28 @@ const (
// //
// Type: boolean // Type: boolean
// Required: No // Required: No
// Stability: stable
DBCassandraIdempotenceKey = attribute.Key("db.cassandra.idempotence") DBCassandraIdempotenceKey = attribute.Key("db.cassandra.idempotence")
// The number of times a query was speculatively executed. Not set or `0` if the // The number of times a query was speculatively executed. Not set or `0` if the
// query was not executed speculatively. // query was not executed speculatively.
// //
// Type: int // Type: int
// Required: No // Required: No
// Stability: stable
// Examples: 0, 2 // Examples: 0, 2
DBCassandraSpeculativeExecutionCountKey = attribute.Key("db.cassandra.speculative_execution_count") DBCassandraSpeculativeExecutionCountKey = attribute.Key("db.cassandra.speculative_execution_count")
// The ID of the coordinating node for a query. // The ID of the coordinating node for a query.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'be13faa2-8574-4d71-926d-27f16cf8a7af' // Examples: 'be13faa2-8574-4d71-926d-27f16cf8a7af'
DBCassandraCoordinatorIDKey = attribute.Key("db.cassandra.coordinator.id") DBCassandraCoordinatorIDKey = attribute.Key("db.cassandra.coordinator.id")
// The data center of the coordinating node for a query. // The data center of the coordinating node for a query.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'us-west-2' // Examples: 'us-west-2'
DBCassandraCoordinatorDCKey = attribute.Key("db.cassandra.coordinator.dc") DBCassandraCoordinatorDCKey = attribute.Key("db.cassandra.coordinator.dc")
) )
@ -285,6 +301,7 @@ const (
// //
// Type: string // Type: string
// Required: Always // Required: Always
// Stability: stable
// Examples: 'default' // Examples: 'default'
DBHBaseNamespaceKey = attribute.Key("db.hbase.namespace") DBHBaseNamespaceKey = attribute.Key("db.hbase.namespace")
) )
@ -297,6 +314,7 @@ const (
// //
// Type: int // Type: int
// Required: Required, if other than the default database (`0`). // Required: Required, if other than the default database (`0`).
// Stability: stable
// Examples: 0, 1, 15 // Examples: 0, 1, 15
DBRedisDBIndexKey = attribute.Key("db.redis.database_index") DBRedisDBIndexKey = attribute.Key("db.redis.database_index")
) )
@ -307,6 +325,7 @@ const (
// //
// Type: string // Type: string
// Required: Always // Required: Always
// Stability: stable
// Examples: 'customers', 'products' // Examples: 'customers', 'products'
DBMongoDBCollectionKey = attribute.Key("db.mongodb.collection") DBMongoDBCollectionKey = attribute.Key("db.mongodb.collection")
) )
@ -318,6 +337,7 @@ const (
// //
// Type: string // Type: string
// Required: Recommended if available. // Required: Recommended if available.
// Stability: stable
// Examples: 'public.users', 'customers' // Examples: 'public.users', 'customers'
// Note: It is not recommended to attempt any client-side parsing of // Note: It is not recommended to attempt any client-side parsing of
// `db.statement` just to get this property, but it should be set if it is // `db.statement` just to get this property, but it should be set if it is
@ -334,12 +354,14 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'java.net.ConnectException', 'OSError' // Examples: 'java.net.ConnectException', 'OSError'
ExceptionTypeKey = attribute.Key("exception.type") ExceptionTypeKey = attribute.Key("exception.type")
// The exception message. // The exception message.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'Division by zero', "Can't convert 'int' object to str implicitly" // Examples: 'Division by zero', "Can't convert 'int' object to str implicitly"
ExceptionMessageKey = attribute.Key("exception.message") ExceptionMessageKey = attribute.Key("exception.message")
// A stacktrace as a string in the natural representation for the language // A stacktrace as a string in the natural representation for the language
@ -348,6 +370,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'Exception in thread "main" java.lang.RuntimeException: Test // Examples: 'Exception in thread "main" java.lang.RuntimeException: Test
// exception\\n at ' // exception\\n at '
// 'com.example.GenerateTrace.methodB(GenerateTrace.java:13)\\n at ' // 'com.example.GenerateTrace.methodB(GenerateTrace.java:13)\\n at '
@ -359,6 +382,7 @@ const (
// //
// Type: boolean // Type: boolean
// Required: No // Required: No
// Stability: stable
// Note: An exception is considered to have escaped (or left) the scope of a span, // Note: An exception is considered to have escaped (or left) the scope of a span,
// if that span is ended while the exception is still logically "in flight". // if that span is ended while the exception is still logically "in flight".
// This may be actually "in flight" in some languages (e.g. if the exception // This may be actually "in flight" in some languages (e.g. if the exception
@ -389,11 +413,13 @@ const (
// invocations, if it is known to the client. This is, for example, not the case, // invocations, if it is known to the client. This is, for example, not the case,
// when the transport layer is abstracted in a FaaS client framework without // when the transport layer is abstracted in a FaaS client framework without
// access to its configuration. // access to its configuration.
// Stability: stable
FaaSTriggerKey = attribute.Key("faas.trigger") FaaSTriggerKey = attribute.Key("faas.trigger")
// The execution ID of the current function execution. // The execution ID of the current function execution.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'af9d5aa4-a685-4c5f-a22b-444f80b3cc28' // Examples: 'af9d5aa4-a685-4c5f-a22b-444f80b3cc28'
FaaSExecutionKey = attribute.Key("faas.execution") FaaSExecutionKey = attribute.Key("faas.execution")
) )
@ -419,12 +445,14 @@ const (
// //
// Type: string // Type: string
// Required: Always // Required: Always
// Stability: stable
// Examples: 'myBucketName', 'myDBName' // Examples: 'myBucketName', 'myDBName'
FaaSDocumentCollectionKey = attribute.Key("faas.document.collection") FaaSDocumentCollectionKey = attribute.Key("faas.document.collection")
// Describes the type of the operation that was performed on the data. // Describes the type of the operation that was performed on the data.
// //
// Type: Enum // Type: Enum
// Required: Always // Required: Always
// Stability: stable
FaaSDocumentOperationKey = attribute.Key("faas.document.operation") FaaSDocumentOperationKey = attribute.Key("faas.document.operation")
// A string containing the time when the data was accessed in the [ISO // A string containing the time when the data was accessed in the [ISO
// 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed // 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format expressed
@ -432,6 +460,7 @@ const (
// //
// Type: string // Type: string
// Required: Always // Required: Always
// Stability: stable
// Examples: '2020-01-23T13:47:06Z' // Examples: '2020-01-23T13:47:06Z'
FaaSDocumentTimeKey = attribute.Key("faas.document.time") FaaSDocumentTimeKey = attribute.Key("faas.document.time")
// The document name/table subjected to the operation. For example, in Cloud // The document name/table subjected to the operation. For example, in Cloud
@ -439,6 +468,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'myFile.txt', 'myTableName' // Examples: 'myFile.txt', 'myTableName'
FaaSDocumentNameKey = attribute.Key("faas.document.name") FaaSDocumentNameKey = attribute.Key("faas.document.name")
) )
@ -460,6 +490,7 @@ const (
// //
// Type: string // Type: string
// Required: Always // Required: Always
// Stability: stable
// Examples: '2020-01-23T13:47:06Z' // Examples: '2020-01-23T13:47:06Z'
FaaSTimeKey = attribute.Key("faas.time") FaaSTimeKey = attribute.Key("faas.time")
// A string containing the schedule period as [Cron Expression](https://docs.oracl // A string containing the schedule period as [Cron Expression](https://docs.oracl
@ -467,6 +498,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '0/5 * * * ? *' // Examples: '0/5 * * * ? *'
FaaSCronKey = attribute.Key("faas.cron") FaaSCronKey = attribute.Key("faas.cron")
) )
@ -478,6 +510,7 @@ const (
// //
// Type: boolean // Type: boolean
// Required: No // Required: No
// Stability: stable
FaaSColdstartKey = attribute.Key("faas.coldstart") FaaSColdstartKey = attribute.Key("faas.coldstart")
) )
@ -487,6 +520,7 @@ const (
// //
// Type: string // Type: string
// Required: Always // Required: Always
// Stability: stable
// Examples: 'my-function' // Examples: 'my-function'
// Note: SHOULD be equal to the `faas.name` resource attribute of the invoked // Note: SHOULD be equal to the `faas.name` resource attribute of the invoked
// function. // function.
@ -495,6 +529,7 @@ const (
// //
// Type: Enum // Type: Enum
// Required: Always // Required: Always
// Stability: stable
// Examples: 'aws' // Examples: 'aws'
// Note: SHOULD be equal to the `cloud.provider` resource attribute of the invoked // Note: SHOULD be equal to the `cloud.provider` resource attribute of the invoked
// function. // function.
@ -508,6 +543,7 @@ const (
// always known to clients. In these cases, `faas.invoked_region` MUST be set // always known to clients. In these cases, `faas.invoked_region` MUST be set
// accordingly. If the region is unknown to the client or not required for // accordingly. If the region is unknown to the client or not required for
// identifying the invoked function, setting `faas.invoked_region` is optional. // identifying the invoked function, setting `faas.invoked_region` is optional.
// Stability: stable
// Examples: 'eu-central-1' // Examples: 'eu-central-1'
// Note: SHOULD be equal to the `cloud.region` resource attribute of the invoked // Note: SHOULD be equal to the `cloud.region` resource attribute of the invoked
// function. // function.
@ -529,6 +565,7 @@ const (
// //
// Type: Enum // Type: Enum
// Required: No // Required: No
// Stability: stable
// Examples: 'ip_tcp' // Examples: 'ip_tcp'
NetTransportKey = attribute.Key("net.transport") NetTransportKey = attribute.Key("net.transport")
// Remote address of the peer (dotted decimal for IPv4 or // Remote address of the peer (dotted decimal for IPv4 or
@ -536,36 +573,42 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '127.0.0.1' // Examples: '127.0.0.1'
NetPeerIPKey = attribute.Key("net.peer.ip") NetPeerIPKey = attribute.Key("net.peer.ip")
// Remote port number. // Remote port number.
// //
// Type: int // Type: int
// Required: No // Required: No
// Stability: stable
// Examples: 80, 8080, 443 // Examples: 80, 8080, 443
NetPeerPortKey = attribute.Key("net.peer.port") NetPeerPortKey = attribute.Key("net.peer.port")
// Remote hostname or similar, see note below. // Remote hostname or similar, see note below.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'example.com' // Examples: 'example.com'
NetPeerNameKey = attribute.Key("net.peer.name") NetPeerNameKey = attribute.Key("net.peer.name")
// Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host. // Like `net.peer.ip` but for the host IP. Useful in case of a multi-IP host.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '192.168.0.1' // Examples: '192.168.0.1'
NetHostIPKey = attribute.Key("net.host.ip") NetHostIPKey = attribute.Key("net.host.ip")
// Like `net.peer.port` but for the host port. // Like `net.peer.port` but for the host port.
// //
// Type: int // Type: int
// Required: No // Required: No
// Stability: stable
// Examples: 35555 // Examples: 35555
NetHostPortKey = attribute.Key("net.host.port") NetHostPortKey = attribute.Key("net.host.port")
// Local hostname or similar, see note below. // Local hostname or similar, see note below.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'localhost' // Examples: 'localhost'
NetHostNameKey = attribute.Key("net.host.name") NetHostNameKey = attribute.Key("net.host.name")
) )
@ -595,6 +638,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'AuthTokenCache' // Examples: 'AuthTokenCache'
PeerServiceKey = attribute.Key("peer.service") PeerServiceKey = attribute.Key("peer.service")
) )
@ -607,6 +651,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'username' // Examples: 'username'
EnduserIDKey = attribute.Key("enduser.id") EnduserIDKey = attribute.Key("enduser.id")
// Actual/assumed role the client is making the request under extracted from token // Actual/assumed role the client is making the request under extracted from token
@ -614,6 +659,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'admin' // Examples: 'admin'
EnduserRoleKey = attribute.Key("enduser.role") EnduserRoleKey = attribute.Key("enduser.role")
// Scopes or granted authorities the client currently possesses extracted from // Scopes or granted authorities the client currently possesses extracted from
@ -625,6 +671,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'read:message, write:files' // Examples: 'read:message, write:files'
EnduserScopeKey = attribute.Key("enduser.scope") EnduserScopeKey = attribute.Key("enduser.scope")
) )
@ -635,12 +682,14 @@ const (
// //
// Type: int // Type: int
// Required: No // Required: No
// Stability: stable
// Examples: 42 // Examples: 42
ThreadIDKey = attribute.Key("thread.id") ThreadIDKey = attribute.Key("thread.id")
// Current thread name. // Current thread name.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'main' // Examples: 'main'
ThreadNameKey = attribute.Key("thread.name") ThreadNameKey = attribute.Key("thread.name")
) )
@ -652,6 +701,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'serveRequest' // Examples: 'serveRequest'
CodeFunctionKey = attribute.Key("code.function") CodeFunctionKey = attribute.Key("code.function")
// The "namespace" within which `code.function` is defined. Usually the qualified // The "namespace" within which `code.function` is defined. Usually the qualified
@ -660,6 +710,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'com.example.MyHTTPService' // Examples: 'com.example.MyHTTPService'
CodeNamespaceKey = attribute.Key("code.namespace") CodeNamespaceKey = attribute.Key("code.namespace")
// The source code file name that identifies the code unit as uniquely as possible // The source code file name that identifies the code unit as uniquely as possible
@ -667,6 +718,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '/usr/local/MyApplication/content_root/app/index.php' // Examples: '/usr/local/MyApplication/content_root/app/index.php'
CodeFilepathKey = attribute.Key("code.filepath") CodeFilepathKey = attribute.Key("code.filepath")
// The line number in `code.filepath` best representing the operation. It SHOULD // The line number in `code.filepath` best representing the operation. It SHOULD
@ -674,6 +726,7 @@ const (
// //
// Type: int // Type: int
// Required: No // Required: No
// Stability: stable
// Examples: 42 // Examples: 42
CodeLineNumberKey = attribute.Key("code.lineno") CodeLineNumberKey = attribute.Key("code.lineno")
) )
@ -684,6 +737,7 @@ const (
// //
// Type: string // Type: string
// Required: Always // Required: Always
// Stability: stable
// Examples: 'GET', 'POST', 'HEAD' // Examples: 'GET', 'POST', 'HEAD'
HTTPMethodKey = attribute.Key("http.method") HTTPMethodKey = attribute.Key("http.method")
// Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`. // Full HTTP request URL in the form `scheme://host[:port]/path?query[#fragment]`.
@ -692,6 +746,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'https://www.foo.bar/search?q=OpenTelemetry#SemConv' // Examples: 'https://www.foo.bar/search?q=OpenTelemetry#SemConv'
// Note: `http.url` MUST NOT contain credentials passed via URL in form of // Note: `http.url` MUST NOT contain credentials passed via URL in form of
// `https://username:password@www.example.com/`. In such case the attribute's // `https://username:password@www.example.com/`. In such case the attribute's
@ -701,6 +756,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '/path/12314/?q=ddds#123' // Examples: '/path/12314/?q=ddds#123'
HTTPTargetKey = attribute.Key("http.target") HTTPTargetKey = attribute.Key("http.target")
// The value of the [HTTP host // The value of the [HTTP host
@ -709,24 +765,28 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'www.example.org' // Examples: 'www.example.org'
HTTPHostKey = attribute.Key("http.host") HTTPHostKey = attribute.Key("http.host")
// The URI scheme identifying the used protocol. // The URI scheme identifying the used protocol.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'http', 'https' // Examples: 'http', 'https'
HTTPSchemeKey = attribute.Key("http.scheme") HTTPSchemeKey = attribute.Key("http.scheme")
// [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6). // [HTTP response status code](https://tools.ietf.org/html/rfc7231#section-6).
// //
// Type: int // Type: int
// Required: If and only if one was received/sent. // Required: If and only if one was received/sent.
// Stability: stable
// Examples: 200 // Examples: 200
HTTPStatusCodeKey = attribute.Key("http.status_code") HTTPStatusCodeKey = attribute.Key("http.status_code")
// Kind of HTTP protocol used. // Kind of HTTP protocol used.
// //
// Type: Enum // Type: Enum
// Required: No // Required: No
// Stability: stable
// Examples: '1.0' // Examples: '1.0'
// Note: If `net.transport` is not specified, it can be assumed to be `IP.TCP` // Note: If `net.transport` is not specified, it can be assumed to be `IP.TCP`
// except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed. // except if `http.flavor` is `QUIC`, in which case `IP.UDP` is assumed.
@ -737,6 +797,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'CERN-LineMode/2.15 libwww/2.17b3' // Examples: 'CERN-LineMode/2.15 libwww/2.17b3'
HTTPUserAgentKey = attribute.Key("http.user_agent") HTTPUserAgentKey = attribute.Key("http.user_agent")
// The size of the request payload body in bytes. This is the number of bytes // The size of the request payload body in bytes. This is the number of bytes
@ -746,6 +807,7 @@ const (
// //
// Type: int // Type: int
// Required: No // Required: No
// Stability: stable
// Examples: 3495 // Examples: 3495
HTTPRequestContentLengthKey = attribute.Key("http.request_content_length") HTTPRequestContentLengthKey = attribute.Key("http.request_content_length")
// The size of the uncompressed request payload body after transport decoding. Not // The size of the uncompressed request payload body after transport decoding. Not
@ -753,6 +815,7 @@ const (
// //
// Type: int // Type: int
// Required: No // Required: No
// Stability: stable
// Examples: 5493 // Examples: 5493
HTTPRequestContentLengthUncompressedKey = attribute.Key("http.request_content_length_uncompressed") HTTPRequestContentLengthUncompressedKey = attribute.Key("http.request_content_length_uncompressed")
// The size of the response payload body in bytes. This is the number of bytes // The size of the response payload body in bytes. This is the number of bytes
@ -762,6 +825,7 @@ const (
// //
// Type: int // Type: int
// Required: No // Required: No
// Stability: stable
// Examples: 3495 // Examples: 3495
HTTPResponseContentLengthKey = attribute.Key("http.response_content_length") HTTPResponseContentLengthKey = attribute.Key("http.response_content_length")
// The size of the uncompressed response payload body after transport decoding. // The size of the uncompressed response payload body after transport decoding.
@ -769,6 +833,7 @@ const (
// //
// Type: int // Type: int
// Required: No // Required: No
// Stability: stable
// Examples: 5493 // Examples: 5493
HTTPResponseContentLengthUncompressedKey = attribute.Key("http.response_content_length_uncompressed") HTTPResponseContentLengthUncompressedKey = attribute.Key("http.response_content_length_uncompressed")
) )
@ -794,6 +859,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'example.com' // Examples: 'example.com'
// Note: `http.url` is usually not readily available on the server side but would // Note: `http.url` is usually not readily available on the server side but would
// have to be assembled in a cumbersome and sometimes lossy process from other // have to be assembled in a cumbersome and sometimes lossy process from other
@ -804,6 +870,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '/users/:userID?' // Examples: '/users/:userID?'
HTTPRouteKey = attribute.Key("http.route") HTTPRouteKey = attribute.Key("http.route")
// The IP address of the original client behind all proxies, if known (e.g. from // The IP address of the original client behind all proxies, if known (e.g. from
@ -812,6 +879,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '83.164.160.102' // Examples: '83.164.160.102'
// Note: This is not necessarily the same as `net.peer.ip`, which would identify // Note: This is not necessarily the same as `net.peer.ip`, which would identify
// the network-level peer, which may be a proxy. // the network-level peer, which may be a proxy.
@ -824,6 +892,7 @@ const (
// //
// Type: string[] // Type: string[]
// Required: No // Required: No
// Stability: stable
// Examples: 'Users', 'Cats' // Examples: 'Users', 'Cats'
AWSDynamoDBTableNamesKey = attribute.Key("aws.dynamodb.table_names") AWSDynamoDBTableNamesKey = attribute.Key("aws.dynamodb.table_names")
// The JSON-serialized value of each item in the `ConsumedCapacity` response // The JSON-serialized value of each item in the `ConsumedCapacity` response
@ -831,6 +900,7 @@ const (
// //
// Type: string[] // Type: string[]
// Required: No // Required: No
// Stability: stable
// Examples: '{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : { // Examples: '{ "CapacityUnits": number, "GlobalSecondaryIndexes": { "string" : {
// "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits": // "CapacityUnits": number, "ReadCapacityUnits": number, "WriteCapacityUnits":
// number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number, // number } }, "LocalSecondaryIndexes": { "string" : { "CapacityUnits": number,
@ -843,6 +913,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob, // Examples: '{ "string" : [ { "ItemCollectionKey": { "string" : { "B": blob,
// "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" : // "BOOL": boolean, "BS": [ blob ], "L": [ "AttributeValue" ], "M": { "string" :
// "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S": // "AttributeValue" }, "N": "string", "NS": [ "string" ], "NULL": boolean, "S":
@ -852,23 +923,27 @@ const (
// //
// Type: double // Type: double
// Required: No // Required: No
// Stability: stable
// Examples: 1.0, 2.0 // Examples: 1.0, 2.0
AWSDynamoDBProvisionedReadCapacityKey = attribute.Key("aws.dynamodb.provisioned_read_capacity") AWSDynamoDBProvisionedReadCapacityKey = attribute.Key("aws.dynamodb.provisioned_read_capacity")
// The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter. // The value of the `ProvisionedThroughput.WriteCapacityUnits` request parameter.
// //
// Type: double // Type: double
// Required: No // Required: No
// Stability: stable
// Examples: 1.0, 2.0 // Examples: 1.0, 2.0
AWSDynamoDBProvisionedWriteCapacityKey = attribute.Key("aws.dynamodb.provisioned_write_capacity") AWSDynamoDBProvisionedWriteCapacityKey = attribute.Key("aws.dynamodb.provisioned_write_capacity")
// The value of the `ConsistentRead` request parameter. // The value of the `ConsistentRead` request parameter.
// //
// Type: boolean // Type: boolean
// Required: No // Required: No
// Stability: stable
AWSDynamoDBConsistentReadKey = attribute.Key("aws.dynamodb.consistent_read") AWSDynamoDBConsistentReadKey = attribute.Key("aws.dynamodb.consistent_read")
// The value of the `ProjectionExpression` request parameter. // The value of the `ProjectionExpression` request parameter.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'Title', 'Title, Price, Color', 'Title, Description, RelatedItems, // Examples: 'Title', 'Title, Price, Color', 'Title, Description, RelatedItems,
// ProductReviews' // ProductReviews'
AWSDynamoDBProjectionKey = attribute.Key("aws.dynamodb.projection") AWSDynamoDBProjectionKey = attribute.Key("aws.dynamodb.projection")
@ -876,24 +951,28 @@ const (
// //
// Type: int // Type: int
// Required: No // Required: No
// Stability: stable
// Examples: 10 // Examples: 10
AWSDynamoDBLimitKey = attribute.Key("aws.dynamodb.limit") AWSDynamoDBLimitKey = attribute.Key("aws.dynamodb.limit")
// The value of the `AttributesToGet` request parameter. // The value of the `AttributesToGet` request parameter.
// //
// Type: string[] // Type: string[]
// Required: No // Required: No
// Stability: stable
// Examples: 'lives', 'id' // Examples: 'lives', 'id'
AWSDynamoDBAttributesToGetKey = attribute.Key("aws.dynamodb.attributes_to_get") AWSDynamoDBAttributesToGetKey = attribute.Key("aws.dynamodb.attributes_to_get")
// The value of the `IndexName` request parameter. // The value of the `IndexName` request parameter.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'name_to_group' // Examples: 'name_to_group'
AWSDynamoDBIndexNameKey = attribute.Key("aws.dynamodb.index_name") AWSDynamoDBIndexNameKey = attribute.Key("aws.dynamodb.index_name")
// The value of the `Select` request parameter. // The value of the `Select` request parameter.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'ALL_ATTRIBUTES', 'COUNT' // Examples: 'ALL_ATTRIBUTES', 'COUNT'
AWSDynamoDBSelectKey = attribute.Key("aws.dynamodb.select") AWSDynamoDBSelectKey = attribute.Key("aws.dynamodb.select")
) )
@ -905,6 +984,7 @@ const (
// //
// Type: string[] // Type: string[]
// Required: No // Required: No
// Stability: stable
// Examples: '{ "IndexName": "string", "KeySchema": [ { "AttributeName": "string", // Examples: '{ "IndexName": "string", "KeySchema": [ { "AttributeName": "string",
// "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], // "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ],
// "ProjectionType": "string" }, "ProvisionedThroughput": { "ReadCapacityUnits": // "ProjectionType": "string" }, "ProvisionedThroughput": { "ReadCapacityUnits":
@ -915,7 +995,8 @@ const (
// //
// Type: string[] // Type: string[]
// Required: No // Required: No
// Examples: '{ "IndexArn": "string", "IndexName": "string", "IndexSizeBytes": // Stability: stable
// Examples: '{ "IndexARN": "string", "IndexName": "string", "IndexSizeBytes":
// number, "ItemCount": number, "KeySchema": [ { "AttributeName": "string", // number, "ItemCount": number, "KeySchema": [ { "AttributeName": "string",
// "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ], // "KeyType": "string" } ], "Projection": { "NonKeyAttributes": [ "string" ],
// "ProjectionType": "string" } }' // "ProjectionType": "string" } }'
@ -928,12 +1009,14 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'Users', 'CatsTable' // Examples: 'Users', 'CatsTable'
AWSDynamoDBExclusiveStartTableKey = attribute.Key("aws.dynamodb.exclusive_start_table") AWSDynamoDBExclusiveStartTableKey = attribute.Key("aws.dynamodb.exclusive_start_table")
// The the number of items in the `TableNames` response parameter. // The the number of items in the `TableNames` response parameter.
// //
// Type: int // Type: int
// Required: No // Required: No
// Stability: stable
// Examples: 20 // Examples: 20
AWSDynamoDBTableCountKey = attribute.Key("aws.dynamodb.table_count") AWSDynamoDBTableCountKey = attribute.Key("aws.dynamodb.table_count")
) )
@ -944,6 +1027,7 @@ const (
// //
// Type: boolean // Type: boolean
// Required: No // Required: No
// Stability: stable
AWSDynamoDBScanForwardKey = attribute.Key("aws.dynamodb.scan_forward") AWSDynamoDBScanForwardKey = attribute.Key("aws.dynamodb.scan_forward")
) )
@ -953,24 +1037,28 @@ const (
// //
// Type: int // Type: int
// Required: No // Required: No
// Stability: stable
// Examples: 10 // Examples: 10
AWSDynamoDBSegmentKey = attribute.Key("aws.dynamodb.segment") AWSDynamoDBSegmentKey = attribute.Key("aws.dynamodb.segment")
// The value of the `TotalSegments` request parameter. // The value of the `TotalSegments` request parameter.
// //
// Type: int // Type: int
// Required: No // Required: No
// Stability: stable
// Examples: 100 // Examples: 100
AWSDynamoDBTotalSegmentsKey = attribute.Key("aws.dynamodb.total_segments") AWSDynamoDBTotalSegmentsKey = attribute.Key("aws.dynamodb.total_segments")
// The value of the `Count` response parameter. // The value of the `Count` response parameter.
// //
// Type: int // Type: int
// Required: No // Required: No
// Stability: stable
// Examples: 10 // Examples: 10
AWSDynamoDBCountKey = attribute.Key("aws.dynamodb.count") AWSDynamoDBCountKey = attribute.Key("aws.dynamodb.count")
// The value of the `ScannedCount` response parameter. // The value of the `ScannedCount` response parameter.
// //
// Type: int // Type: int
// Required: No // Required: No
// Stability: stable
// Examples: 50 // Examples: 50
AWSDynamoDBScannedCountKey = attribute.Key("aws.dynamodb.scanned_count") AWSDynamoDBScannedCountKey = attribute.Key("aws.dynamodb.scanned_count")
) )
@ -982,6 +1070,7 @@ const (
// //
// Type: string[] // Type: string[]
// Required: No // Required: No
// Stability: stable
// Examples: '{ "AttributeName": "string", "AttributeType": "string" }' // Examples: '{ "AttributeName": "string", "AttributeType": "string" }'
AWSDynamoDBAttributeDefinitionsKey = attribute.Key("aws.dynamodb.attribute_definitions") AWSDynamoDBAttributeDefinitionsKey = attribute.Key("aws.dynamodb.attribute_definitions")
// The JSON-serialized value of each item in the the `GlobalSecondaryIndexUpdates` // The JSON-serialized value of each item in the the `GlobalSecondaryIndexUpdates`
@ -989,6 +1078,7 @@ const (
// //
// Type: string[] // Type: string[]
// Required: No // Required: No
// Stability: stable
// Examples: '{ "Create": { "IndexName": "string", "KeySchema": [ { // Examples: '{ "Create": { "IndexName": "string", "KeySchema": [ {
// "AttributeName": "string", "KeyType": "string" } ], "Projection": { // "AttributeName": "string", "KeyType": "string" } ], "Projection": {
// "NonKeyAttributes": [ "string" ], "ProjectionType": "string" }, // "NonKeyAttributes": [ "string" ], "ProjectionType": "string" },
@ -1003,6 +1093,7 @@ const (
// //
// Type: string // Type: string
// Required: Always // Required: Always
// Stability: stable
// Examples: 'kafka', 'rabbitmq', 'activemq', 'AmazonSQS' // Examples: 'kafka', 'rabbitmq', 'activemq', 'AmazonSQS'
MessagingSystemKey = attribute.Key("messaging.system") MessagingSystemKey = attribute.Key("messaging.system")
// The message destination name. This might be equal to the span name but is // The message destination name. This might be equal to the span name but is
@ -1010,6 +1101,7 @@ const (
// //
// Type: string // Type: string
// Required: Always // Required: Always
// Stability: stable
// Examples: 'MyQueue', 'MyTopic' // Examples: 'MyQueue', 'MyTopic'
MessagingDestinationKey = attribute.Key("messaging.destination") MessagingDestinationKey = attribute.Key("messaging.destination")
// The kind of message destination // The kind of message destination
@ -1017,28 +1109,33 @@ const (
// Type: Enum // Type: Enum
// Required: Required only if the message destination is either a `queue` or // Required: Required only if the message destination is either a `queue` or
// `topic`. // `topic`.
// Stability: stable
MessagingDestinationKindKey = attribute.Key("messaging.destination_kind") MessagingDestinationKindKey = attribute.Key("messaging.destination_kind")
// A boolean that is true if the message destination is temporary. // A boolean that is true if the message destination is temporary.
// //
// Type: boolean // Type: boolean
// Required: If missing, it is assumed to be false. // Required: If missing, it is assumed to be false.
// Stability: stable
MessagingTempDestinationKey = attribute.Key("messaging.temp_destination") MessagingTempDestinationKey = attribute.Key("messaging.temp_destination")
// The name of the transport protocol. // The name of the transport protocol.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'AMQP', 'MQTT' // Examples: 'AMQP', 'MQTT'
MessagingProtocolKey = attribute.Key("messaging.protocol") MessagingProtocolKey = attribute.Key("messaging.protocol")
// The version of the transport protocol. // The version of the transport protocol.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '0.9.1' // Examples: '0.9.1'
MessagingProtocolVersionKey = attribute.Key("messaging.protocol_version") MessagingProtocolVersionKey = attribute.Key("messaging.protocol_version")
// Connection string. // Connection string.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'tibjmsnaming://localhost:7222', // Examples: 'tibjmsnaming://localhost:7222',
// 'https://queue.amazonaws.com/80398EXAMPLE/MyQueue' // 'https://queue.amazonaws.com/80398EXAMPLE/MyQueue'
MessagingURLKey = attribute.Key("messaging.url") MessagingURLKey = attribute.Key("messaging.url")
@ -1047,6 +1144,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '452a7c7c7c7048c2f887f61572b18fc2' // Examples: '452a7c7c7c7048c2f887f61572b18fc2'
MessagingMessageIDKey = attribute.Key("messaging.message_id") MessagingMessageIDKey = attribute.Key("messaging.message_id")
// The [conversation ID](#conversations) identifying the conversation to which the // The [conversation ID](#conversations) identifying the conversation to which the
@ -1054,7 +1152,8 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Examples: 'MyConversationId' // Stability: stable
// Examples: 'MyConversationID'
MessagingConversationIDKey = attribute.Key("messaging.conversation_id") MessagingConversationIDKey = attribute.Key("messaging.conversation_id")
// The (uncompressed) size of the message payload in bytes. Also use this // The (uncompressed) size of the message payload in bytes. Also use this
// attribute if it is unknown whether the compressed or uncompressed payload size // attribute if it is unknown whether the compressed or uncompressed payload size
@ -1062,12 +1161,14 @@ const (
// //
// Type: int // Type: int
// Required: No // Required: No
// Stability: stable
// Examples: 2738 // Examples: 2738
MessagingMessagePayloadSizeBytesKey = attribute.Key("messaging.message_payload_size_bytes") MessagingMessagePayloadSizeBytesKey = attribute.Key("messaging.message_payload_size_bytes")
// The compressed size of the message payload in bytes. // The compressed size of the message payload in bytes.
// //
// Type: int // Type: int
// Required: No // Required: No
// Stability: stable
// Examples: 2048 // Examples: 2048
MessagingMessagePayloadCompressedSizeBytesKey = attribute.Key("messaging.message_payload_compressed_size_bytes") MessagingMessagePayloadCompressedSizeBytesKey = attribute.Key("messaging.message_payload_compressed_size_bytes")
) )
@ -1088,6 +1189,7 @@ const (
// //
// Type: Enum // Type: Enum
// Required: No // Required: No
// Stability: stable
MessagingOperationKey = attribute.Key("messaging.operation") MessagingOperationKey = attribute.Key("messaging.operation")
) )
@ -1104,6 +1206,7 @@ const (
// //
// Type: string // Type: string
// Required: Unless it is empty. // Required: Unless it is empty.
// Stability: stable
// Examples: 'myKey' // Examples: 'myKey'
MessagingRabbitmqRoutingKeyKey = attribute.Key("messaging.rabbitmq.routing_key") MessagingRabbitmqRoutingKeyKey = attribute.Key("messaging.rabbitmq.routing_key")
) )
@ -1116,6 +1219,7 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'myKey' // Examples: 'myKey'
// Note: If the key type is not string, it's string representation has to be // Note: If the key type is not string, it's string representation has to be
// supplied for the attribute. If the key has no unambiguous, canonical string // supplied for the attribute. If the key has no unambiguous, canonical string
@ -1126,24 +1230,28 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'my-group' // Examples: 'my-group'
MessagingKafkaConsumerGroupKey = attribute.Key("messaging.kafka.consumer_group") MessagingKafkaConsumerGroupKey = attribute.Key("messaging.kafka.consumer_group")
// Client ID for the Consumer or Producer that is handling the message. // Client ID for the Consumer or Producer that is handling the message.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'client-5' // Examples: 'client-5'
MessagingKafkaClientIDKey = attribute.Key("messaging.kafka.client_id") MessagingKafkaClientIDKey = attribute.Key("messaging.kafka.client_id")
// Partition the message is sent to. // Partition the message is sent to.
// //
// Type: int // Type: int
// Required: No // Required: No
// Stability: stable
// Examples: 2 // Examples: 2
MessagingKafkaPartitionKey = attribute.Key("messaging.kafka.partition") MessagingKafkaPartitionKey = attribute.Key("messaging.kafka.partition")
// A boolean that is true if the message is a tombstone. // A boolean that is true if the message is a tombstone.
// //
// Type: boolean // Type: boolean
// Required: If missing, it is assumed to be false. // Required: If missing, it is assumed to be false.
// Stability: stable
MessagingKafkaTombstoneKey = attribute.Key("messaging.kafka.tombstone") MessagingKafkaTombstoneKey = attribute.Key("messaging.kafka.tombstone")
) )
@ -1153,6 +1261,7 @@ const (
// //
// Type: string // Type: string
// Required: Always // Required: Always
// Stability: stable
// Examples: 'grpc', 'java_rmi', 'wcf' // Examples: 'grpc', 'java_rmi', 'wcf'
RPCSystemKey = attribute.Key("rpc.system") RPCSystemKey = attribute.Key("rpc.system")
// The full name of the service being called, including its package name, if // The full name of the service being called, including its package name, if
@ -1160,6 +1269,7 @@ const (
// //
// Type: string // Type: string
// Required: No, but recommended // Required: No, but recommended
// Stability: stable
// Examples: 'myservice.EchoService' // Examples: 'myservice.EchoService'
RPCServiceKey = attribute.Key("rpc.service") RPCServiceKey = attribute.Key("rpc.service")
// The name of the method being called, must be equal to the $method part in the // The name of the method being called, must be equal to the $method part in the
@ -1167,6 +1277,7 @@ const (
// //
// Type: string // Type: string
// Required: No, but recommended // Required: No, but recommended
// Stability: stable
// Examples: 'exampleMethod' // Examples: 'exampleMethod'
RPCMethodKey = attribute.Key("rpc.method") RPCMethodKey = attribute.Key("rpc.method")
) )
@ -1179,6 +1290,7 @@ const (
// //
// Type: Enum // Type: Enum
// Required: Always // Required: Always
// Stability: stable
// Examples: 0, 1, 16 // Examples: 0, 1, 16
RPCGRPCStatusCodeKey = attribute.Key("rpc.grpc.status_code") RPCGRPCStatusCodeKey = attribute.Key("rpc.grpc.status_code")
) )
@ -1227,6 +1339,7 @@ const (
// //
// Type: string // Type: string
// Required: If missing, it is assumed to be "1.0". // Required: If missing, it is assumed to be "1.0".
// Stability: stable
// Examples: '2.0', '1.0' // Examples: '2.0', '1.0'
RPCJsonrpcVersionKey = attribute.Key("rpc.jsonrpc.version") RPCJsonrpcVersionKey = attribute.Key("rpc.jsonrpc.version")
// `method` property from request. Unlike `rpc.method`, this may not relate to the // `method` property from request. Unlike `rpc.method`, this may not relate to the
@ -1235,6 +1348,7 @@ const (
// //
// Type: string // Type: string
// Required: Always // Required: Always
// Stability: stable
// Examples: 'users.create', 'get_users' // Examples: 'users.create', 'get_users'
RPCJsonrpcMethodKey = attribute.Key("rpc.jsonrpc.method") RPCJsonrpcMethodKey = attribute.Key("rpc.jsonrpc.method")
// `id` property of request or response. Since protocol allows id to be int, // `id` property of request or response. Since protocol allows id to be int,
@ -1244,18 +1358,21 @@ const (
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: '10', 'request-7', '' // Examples: '10', 'request-7', ''
RPCJsonrpcRequestIDKey = attribute.Key("rpc.jsonrpc.request_id") RPCJsonrpcRequestIDKey = attribute.Key("rpc.jsonrpc.request_id")
// `error.code` property of response if it is an error response. // `error.code` property of response if it is an error response.
// //
// Type: int // Type: int
// Required: If missing, response is assumed to be successful. // Required: If missing, response is assumed to be successful.
// Stability: stable
// Examples: -32700, 100 // Examples: -32700, 100
RPCJsonrpcErrorCodeKey = attribute.Key("rpc.jsonrpc.error_code") RPCJsonrpcErrorCodeKey = attribute.Key("rpc.jsonrpc.error_code")
// `error.message` property of response if it is an error response. // `error.message` property of response if it is an error response.
// //
// Type: string // Type: string
// Required: No // Required: No
// Stability: stable
// Examples: 'Parse error', 'User already exists' // Examples: 'Parse error', 'User already exists'
RPCJsonrpcErrorMessageKey = attribute.Key("rpc.jsonrpc.error_message") RPCJsonrpcErrorMessageKey = attribute.Key("rpc.jsonrpc.error_message")
) )

View File

@ -31,9 +31,9 @@ func Tracer(name string, opts ...trace.TracerOption) trace.Tracer {
// If none is registered then an instance of NoopTracerProvider is returned. // If none is registered then an instance of NoopTracerProvider is returned.
// //
// Use the trace provider to create a named tracer. E.g. // Use the trace provider to create a named tracer. E.g.
// tracer := global.GetTracerProvider().Tracer("example.com/foo") // tracer := otel.GetTracerProvider().Tracer("example.com/foo")
// or // or
// tracer := global.Tracer("example.com/foo") // tracer := otel.Tracer("example.com/foo")
func GetTracerProvider() trace.TracerProvider { func GetTracerProvider() trace.TracerProvider {
return global.TracerProvider() return global.TracerProvider()
} }

View File

@ -38,10 +38,10 @@ func (t *TracerConfig) SchemaURL() string {
} }
// NewTracerConfig applies all the options to a returned TracerConfig. // NewTracerConfig applies all the options to a returned TracerConfig.
func NewTracerConfig(options ...TracerOption) *TracerConfig { func NewTracerConfig(options ...TracerOption) TracerConfig {
config := new(TracerConfig) var config TracerConfig
for _, option := range options { for _, option := range options {
option.apply(config) option.apply(&config)
} }
return config return config
} }
@ -64,6 +64,7 @@ type SpanConfig struct {
links []Link links []Link
newRoot bool newRoot bool
spanKind SpanKind spanKind SpanKind
stackTrace bool
} }
// Attributes describe the associated qualities of a Span. // Attributes describe the associated qualities of a Span.
@ -76,6 +77,11 @@ func (cfg *SpanConfig) Timestamp() time.Time {
return cfg.timestamp return cfg.timestamp
} }
// StackTrace checks whether stack trace capturing is enabled.
func (cfg *SpanConfig) StackTrace() bool {
return cfg.stackTrace
}
// Links are the associations a Span has with other Spans. // Links are the associations a Span has with other Spans.
func (cfg *SpanConfig) Links() []Link { func (cfg *SpanConfig) Links() []Link {
return cfg.links return cfg.links
@ -97,10 +103,10 @@ func (cfg *SpanConfig) SpanKind() SpanKind {
// No validation is performed on the returned SpanConfig (e.g. no uniqueness // No validation is performed on the returned SpanConfig (e.g. no uniqueness
// checking or bounding of data), it is left to the SDK to perform this // checking or bounding of data), it is left to the SDK to perform this
// action. // action.
func NewSpanStartConfig(options ...SpanStartOption) *SpanConfig { func NewSpanStartConfig(options ...SpanStartOption) SpanConfig {
c := new(SpanConfig) var c SpanConfig
for _, option := range options { for _, option := range options {
option.applySpanStart(c) option.applySpanStart(&c)
} }
return c return c
} }
@ -109,10 +115,10 @@ func NewSpanStartConfig(options ...SpanStartOption) *SpanConfig {
// No validation is performed on the returned SpanConfig (e.g. no uniqueness // No validation is performed on the returned SpanConfig (e.g. no uniqueness
// checking or bounding of data), it is left to the SDK to perform this // checking or bounding of data), it is left to the SDK to perform this
// action. // action.
func NewSpanEndConfig(options ...SpanEndOption) *SpanConfig { func NewSpanEndConfig(options ...SpanEndOption) SpanConfig {
c := new(SpanConfig) var c SpanConfig
for _, option := range options { for _, option := range options {
option.applySpanEnd(c) option.applySpanEnd(&c)
} }
return c return c
} }
@ -139,6 +145,7 @@ type SpanEndOption interface {
type EventConfig struct { type EventConfig struct {
attributes []attribute.KeyValue attributes []attribute.KeyValue
timestamp time.Time timestamp time.Time
stackTrace bool
} }
// Attributes describe the associated qualities of an Event. // Attributes describe the associated qualities of an Event.
@ -151,14 +158,19 @@ func (cfg *EventConfig) Timestamp() time.Time {
return cfg.timestamp return cfg.timestamp
} }
// NewEventConfig applies all the EventOptions to a returned SpanConfig. If no // StackTrace checks whether stack trace capturing is enabled.
// timestamp option is passed, the returned SpanConfig will have a Timestamp func (cfg *EventConfig) StackTrace() bool {
return cfg.stackTrace
}
// NewEventConfig applies all the EventOptions to a returned EventConfig. If no
// timestamp option is passed, the returned EventConfig will have a Timestamp
// set to the call time, otherwise no validation is performed on the returned // set to the call time, otherwise no validation is performed on the returned
// SpanConfig. // EventConfig.
func NewEventConfig(options ...EventOption) *EventConfig { func NewEventConfig(options ...EventOption) EventConfig {
c := new(EventConfig) var c EventConfig
for _, option := range options { for _, option := range options {
option.applyEvent(c) option.applyEvent(&c)
} }
if c.timestamp.IsZero() { if c.timestamp.IsZero() {
c.timestamp = time.Now() c.timestamp = time.Now()
@ -183,6 +195,12 @@ type SpanStartEventOption interface {
EventOption EventOption
} }
// SpanEndEventOption are options that can be used at the end of a span, or with an event.
type SpanEndEventOption interface {
SpanEndOption
EventOption
}
type attributeOption []attribute.KeyValue type attributeOption []attribute.KeyValue
func (o attributeOption) applySpan(c *SpanConfig) { func (o attributeOption) applySpan(c *SpanConfig) {
@ -229,6 +247,17 @@ func WithTimestamp(t time.Time) SpanEventOption {
return timestampOption(t) return timestampOption(t)
} }
type stackTraceOption bool
func (o stackTraceOption) applyEvent(c *EventConfig) { c.stackTrace = bool(o) }
func (o stackTraceOption) applySpan(c *SpanConfig) { c.stackTrace = bool(o) }
func (o stackTraceOption) applySpanEnd(c *SpanConfig) { o.applySpan(c) }
// WithStackTrace sets the flag to capture the error with stack trace (e.g. true, false).
func WithStackTrace(b bool) SpanEndEventOption {
return stackTraceOption(b)
}
// WithLinks adds links to a Span. The links are added to the existing Span // WithLinks adds links to a Span. The links are added to the existing Span
// links, i.e. this does not overwrite. // links, i.e. this does not overwrite.
func WithLinks(links ...Link) SpanStartOption { func WithLinks(links ...Link) SpanStartOption {

View File

@ -16,9 +16,6 @@
Package trace provides an implementation of the tracing part of the Package trace provides an implementation of the tracing part of the
OpenTelemetry API. OpenTelemetry API.
This package is currently in a Release Candidate phase. Backwards incompatible changes
may be introduced prior to v1.0.0, but we believe the current API is ready to stabilize.
To participate in distributed traces a Span needs to be created for the To participate in distributed traces a Span needs to be created for the
operation being performed as part of a traced workflow. It its simplest form: operation being performed as part of a traced workflow. It its simplest form:

View File

@ -32,8 +32,6 @@ replace go.opentelemetry.io/otel/internal/tools => ../internal/tools
replace go.opentelemetry.io/otel/metric => ../metric replace go.opentelemetry.io/otel/metric => ../metric
replace go.opentelemetry.io/otel/oteltest => ../oteltest
replace go.opentelemetry.io/otel/sdk => ../sdk replace go.opentelemetry.io/otel/sdk => ../sdk
replace go.opentelemetry.io/otel/sdk/export/metric => ../sdk/export/metric replace go.opentelemetry.io/otel/sdk/export/metric => ../sdk/export/metric
@ -45,7 +43,7 @@ replace go.opentelemetry.io/otel/trace => ./
require ( require (
github.com/google/go-cmp v0.5.6 github.com/google/go-cmp v0.5.6
github.com/stretchr/testify v1.7.0 github.com/stretchr/testify v1.7.0
go.opentelemetry.io/otel v1.0.0-RC1 go.opentelemetry.io/otel v1.0.0
) )
replace go.opentelemetry.io/otel/example/passthrough => ../example/passthrough replace go.opentelemetry.io/otel/example/passthrough => ../example/passthrough
@ -58,12 +56,6 @@ replace go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp => ../ex
replace go.opentelemetry.io/otel/internal/metric => ../internal/metric replace go.opentelemetry.io/otel/internal/metric => ../internal/metric
replace go.opentelemetry.io/otel/exporters/metric/prometheus => ../exporters/metric/prometheus
replace go.opentelemetry.io/otel/exporters/trace/jaeger => ../exporters/trace/jaeger
replace go.opentelemetry.io/otel/exporters/trace/zipkin => ../exporters/trace/zipkin
replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric => ../exporters/otlp/otlpmetric replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric => ../exporters/otlp/otlpmetric
replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc => ../exporters/otlp/otlpmetric/otlpmetricgrpc replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc => ../exporters/otlp/otlpmetric/otlpmetricgrpc
@ -71,3 +63,9 @@ replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc => ../
replace go.opentelemetry.io/otel/exporters/stdout/stdoutmetric => ../exporters/stdout/stdoutmetric replace go.opentelemetry.io/otel/exporters/stdout/stdoutmetric => ../exporters/stdout/stdoutmetric
replace go.opentelemetry.io/otel/exporters/stdout/stdouttrace => ../exporters/stdout/stdouttrace replace go.opentelemetry.io/otel/exporters/stdout/stdouttrace => ../exporters/stdout/stdouttrace
replace go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp => ../exporters/otlp/otlpmetric/otlpmetrichttp
replace go.opentelemetry.io/otel/bridge/opencensus/test => ../bridge/opencensus/test
replace go.opentelemetry.io/otel/example/fib => ../example/fib

View File

@ -402,10 +402,14 @@ type Link struct {
// Attributes describe the aspects of the link. // Attributes describe the aspects of the link.
Attributes []attribute.KeyValue Attributes []attribute.KeyValue
}
// DroppedAttributeCount is the number of attributes that were not // LinkFromContext returns a link encapsulating the SpanContext in the provided ctx.
// recorded due to configured limits being reached. func LinkFromContext(ctx context.Context, attrs ...attribute.KeyValue) Link {
DroppedAttributeCount int return Link{
SpanContext: SpanContextFromContext(ctx),
Attributes: attrs,
}
} }
// SpanKind is the role a Span plays in a Trace. // SpanKind is the role a Span plays in a Trace.

View File

@ -16,5 +16,5 @@ package otel // import "go.opentelemetry.io/otel"
// Version is the current release version of OpenTelemetry in use. // Version is the current release version of OpenTelemetry in use.
func Version() string { func Version() string {
return "1.0.0-RC1" return "1.0.0"
} }

View File

@ -14,9 +14,11 @@
module-sets: module-sets:
stable-v1: stable-v1:
version: v1.0.0-RC1 version: v1.0.0
modules: modules:
- go.opentelemetry.io/otel - go.opentelemetry.io/otel
- go.opentelemetry.io/otel/bridge/opentracing
- go.opentelemetry.io/otel/example/fib
- go.opentelemetry.io/otel/example/jaeger - go.opentelemetry.io/otel/example/jaeger
- go.opentelemetry.io/otel/example/namedtracer - go.opentelemetry.io/otel/example/namedtracer
- go.opentelemetry.io/otel/example/otel-collector - go.opentelemetry.io/otel/example/otel-collector
@ -28,18 +30,15 @@ module-sets:
- go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc
- go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp
- go.opentelemetry.io/otel/exporters/stdout/stdouttrace - go.opentelemetry.io/otel/exporters/stdout/stdouttrace
- go.opentelemetry.io/otel/exporters/trace/jaeger
- go.opentelemetry.io/otel/exporters/trace/zipkin
- go.opentelemetry.io/otel/oteltest
- go.opentelemetry.io/otel/trace - go.opentelemetry.io/otel/trace
- go.opentelemetry.io/otel/sdk - go.opentelemetry.io/otel/sdk
experimental-metrics: experimental-metrics:
version: v0.21.0 version: v0.23.0
modules: modules:
- go.opentelemetry.io/otel/example/prometheus - go.opentelemetry.io/otel/example/prometheus
- go.opentelemetry.io/otel/exporters/metric/prometheus
- go.opentelemetry.io/otel/exporters/otlp/otlpmetric - go.opentelemetry.io/otel/exporters/otlp/otlpmetric
- go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc
- go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp
- go.opentelemetry.io/otel/exporters/prometheus - go.opentelemetry.io/otel/exporters/prometheus
- go.opentelemetry.io/otel/exporters/stdout/stdoutmetric - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric
- go.opentelemetry.io/otel/internal/metric - go.opentelemetry.io/otel/internal/metric
@ -47,10 +46,10 @@ module-sets:
- go.opentelemetry.io/otel/sdk/export/metric - go.opentelemetry.io/otel/sdk/export/metric
- go.opentelemetry.io/otel/sdk/metric - go.opentelemetry.io/otel/sdk/metric
bridge: bridge:
version: v0.21.0 version: v0.23.0
modules: modules:
- go.opentelemetry.io/otel/bridge/opencensus - go.opentelemetry.io/otel/bridge/opencensus
- go.opentelemetry.io/otel/bridge/opentracing - go.opentelemetry.io/otel/bridge/opencensus/test
- go.opentelemetry.io/otel/example/opencensus - go.opentelemetry.io/otel/example/opencensus
excluded-modules: excluded-modules:
- go.opentelemetry.io/otel/internal/tools - go.opentelemetry.io/otel/internal/tools

View File

@ -1,42 +0,0 @@
language: go
matrix:
include:
- go: 1.14.x
env: VET=1 GO111MODULE=on
- go: 1.14.x
env: RACE=1 GO111MODULE=on
- go: 1.14.x
env: RUN386=1
- go: 1.14.x
env: GRPC_GO_RETRY=on
- go: 1.14.x
env: TESTEXTRAS=1
- go: 1.13.x
env: GO111MODULE=on
- go: 1.12.x
env: GO111MODULE=on
- go: 1.11.x # Keep until interop tests no longer require Go1.11
env: GO111MODULE=on
go_import_path: google.golang.org/grpc
before_install:
- if [[ "${GO111MODULE}" = "on" ]]; then mkdir "${HOME}/go"; export GOPATH="${HOME}/go"; fi
- if [[ -n "${RUN386}" ]]; then export GOARCH=386; fi
- if [[ "${TRAVIS_EVENT_TYPE}" = "cron" && -z "${RUN386}" ]]; then RACE=1; fi
- if [[ "${TRAVIS_EVENT_TYPE}" != "cron" ]]; then export VET_SKIP_PROTO=1; fi
install:
- try3() { eval "$*" || eval "$*" || eval "$*"; }
- try3 'if [[ "${GO111MODULE}" = "on" ]]; then go mod download; else make testdeps; fi'
- if [[ -n "${GAE}" ]]; then source ./install_gae.sh; make testappenginedeps; fi
- if [[ -n "${VET}" ]]; then ./vet.sh -install; fi
script:
- set -e
- if [[ -n "${TESTEXTRAS}" ]]; then examples/examples_test.sh; security/advancedtls/examples/examples_test.sh; interop/interop_test.sh; make testsubmodule; exit 0; fi
- if [[ -n "${VET}" ]]; then ./vet.sh; fi
- if [[ -n "${GAE}" ]]; then make testappengine; exit 0; fi
- if [[ -n "${RACE}" ]]; then make testrace; exit 0; fi
- make test

View File

@ -136,6 +136,6 @@ errors.
[Go module]: https://github.com/golang/go/wiki/Modules [Go module]: https://github.com/golang/go/wiki/Modules
[gRPC]: https://grpc.io [gRPC]: https://grpc.io
[Go gRPC docs]: https://grpc.io/docs/languages/go [Go gRPC docs]: https://grpc.io/docs/languages/go
[Performance benchmark]: https://performance-dot-grpc-testing.appspot.com/explore?dashboard=5652536396611584&widget=490377658&container=1286539696 [Performance benchmark]: https://performance-dot-grpc-testing.appspot.com/explore?dashboard=5180705743044608
[quick start]: https://grpc.io/docs/languages/go/quickstart [quick start]: https://grpc.io/docs/languages/go/quickstart
[go-releases]: https://golang.org/doc/devel/release.html [go-releases]: https://golang.org/doc/devel/release.html

View File

@ -43,7 +43,8 @@ type ccBalancerWrapper struct {
cc *ClientConn cc *ClientConn
balancerMu sync.Mutex // synchronizes calls to the balancer balancerMu sync.Mutex // synchronizes calls to the balancer
balancer balancer.Balancer balancer balancer.Balancer
scBuffer *buffer.Unbounded updateCh *buffer.Unbounded
closed *grpcsync.Event
done *grpcsync.Event done *grpcsync.Event
mu sync.Mutex mu sync.Mutex
@ -53,7 +54,8 @@ type ccBalancerWrapper struct {
func newCCBalancerWrapper(cc *ClientConn, b balancer.Builder, bopts balancer.BuildOptions) *ccBalancerWrapper { func newCCBalancerWrapper(cc *ClientConn, b balancer.Builder, bopts balancer.BuildOptions) *ccBalancerWrapper {
ccb := &ccBalancerWrapper{ ccb := &ccBalancerWrapper{
cc: cc, cc: cc,
scBuffer: buffer.NewUnbounded(), updateCh: buffer.NewUnbounded(),
closed: grpcsync.NewEvent(),
done: grpcsync.NewEvent(), done: grpcsync.NewEvent(),
subConns: make(map[*acBalancerWrapper]struct{}), subConns: make(map[*acBalancerWrapper]struct{}),
} }
@ -67,35 +69,53 @@ func newCCBalancerWrapper(cc *ClientConn, b balancer.Builder, bopts balancer.Bui
func (ccb *ccBalancerWrapper) watcher() { func (ccb *ccBalancerWrapper) watcher() {
for { for {
select { select {
case t := <-ccb.scBuffer.Get(): case t := <-ccb.updateCh.Get():
ccb.scBuffer.Load() ccb.updateCh.Load()
if ccb.done.HasFired() { if ccb.closed.HasFired() {
break break
} }
switch u := t.(type) {
case *scStateUpdate:
ccb.balancerMu.Lock() ccb.balancerMu.Lock()
su := t.(*scStateUpdate) ccb.balancer.UpdateSubConnState(u.sc, balancer.SubConnState{ConnectivityState: u.state, ConnectionError: u.err})
ccb.balancer.UpdateSubConnState(su.sc, balancer.SubConnState{ConnectivityState: su.state, ConnectionError: su.err})
ccb.balancerMu.Unlock() ccb.balancerMu.Unlock()
case <-ccb.done.Done(): case *acBalancerWrapper:
ccb.mu.Lock()
if ccb.subConns != nil {
delete(ccb.subConns, u)
ccb.cc.removeAddrConn(u.getAddrConn(), errConnDrain)
}
ccb.mu.Unlock()
default:
logger.Errorf("ccBalancerWrapper.watcher: unknown update %+v, type %T", t, t)
}
case <-ccb.closed.Done():
} }
if ccb.done.HasFired() { if ccb.closed.HasFired() {
ccb.balancerMu.Lock()
ccb.balancer.Close() ccb.balancer.Close()
ccb.balancerMu.Unlock()
ccb.mu.Lock() ccb.mu.Lock()
scs := ccb.subConns scs := ccb.subConns
ccb.subConns = nil ccb.subConns = nil
ccb.mu.Unlock() ccb.mu.Unlock()
ccb.UpdateState(balancer.State{ConnectivityState: connectivity.Connecting, Picker: nil})
ccb.done.Fire()
// Fire done before removing the addr conns. We can safely unblock
// ccb.close and allow the removeAddrConns to happen
// asynchronously.
for acbw := range scs { for acbw := range scs {
ccb.cc.removeAddrConn(acbw.getAddrConn(), errConnDrain) ccb.cc.removeAddrConn(acbw.getAddrConn(), errConnDrain)
} }
ccb.UpdateState(balancer.State{ConnectivityState: connectivity.Connecting, Picker: nil})
return return
} }
} }
} }
func (ccb *ccBalancerWrapper) close() { func (ccb *ccBalancerWrapper) close() {
ccb.done.Fire() ccb.closed.Fire()
<-ccb.done.Done()
} }
func (ccb *ccBalancerWrapper) handleSubConnStateChange(sc balancer.SubConn, s connectivity.State, err error) { func (ccb *ccBalancerWrapper) handleSubConnStateChange(sc balancer.SubConn, s connectivity.State, err error) {
@ -109,7 +129,7 @@ func (ccb *ccBalancerWrapper) handleSubConnStateChange(sc balancer.SubConn, s co
if sc == nil { if sc == nil {
return return
} }
ccb.scBuffer.Put(&scStateUpdate{ ccb.updateCh.Put(&scStateUpdate{
sc: sc, sc: sc,
state: s, state: s,
err: err, err: err,
@ -150,17 +170,10 @@ func (ccb *ccBalancerWrapper) NewSubConn(addrs []resolver.Address, opts balancer
} }
func (ccb *ccBalancerWrapper) RemoveSubConn(sc balancer.SubConn) { func (ccb *ccBalancerWrapper) RemoveSubConn(sc balancer.SubConn) {
acbw, ok := sc.(*acBalancerWrapper) // The RemoveSubConn() is handled in the run() goroutine, to avoid deadlock
if !ok { // during switchBalancer() if the old balancer calls RemoveSubConn() in its
return // Close().
} ccb.updateCh.Put(sc)
ccb.mu.Lock()
defer ccb.mu.Unlock()
if ccb.subConns == nil {
return
}
delete(ccb.subConns, acbw)
ccb.cc.removeAddrConn(acbw.getAddrConn(), errConnDrain)
} }
func (ccb *ccBalancerWrapper) UpdateAddresses(sc balancer.SubConn, addrs []resolver.Address) { func (ccb *ccBalancerWrapper) UpdateAddresses(sc balancer.SubConn, addrs []resolver.Address) {

View File

@ -711,7 +711,12 @@ func (cc *ClientConn) switchBalancer(name string) {
return return
} }
if cc.balancerWrapper != nil { if cc.balancerWrapper != nil {
// Don't hold cc.mu while closing the balancers. The balancers may call
// methods that require cc.mu (e.g. cc.NewSubConn()). Holding the mutex
// would cause a deadlock in that case.
cc.mu.Unlock()
cc.balancerWrapper.close() cc.balancerWrapper.close()
cc.mu.Lock()
} }
builder := balancer.Get(name) builder := balancer.Get(name)
@ -1046,12 +1051,12 @@ func (cc *ClientConn) Close() error {
cc.blockingpicker.close() cc.blockingpicker.close()
if rWrapper != nil {
rWrapper.close()
}
if bWrapper != nil { if bWrapper != nil {
bWrapper.close() bWrapper.close()
} }
if rWrapper != nil {
rWrapper.close()
}
for ac := range conns { for ac := range conns {
ac.tearDown(ErrClientConnClosing) ac.tearDown(ErrClientConnClosing)
@ -1424,26 +1429,14 @@ func (ac *addrConn) resetConnectBackoff() {
ac.mu.Unlock() ac.mu.Unlock()
} }
// getReadyTransport returns the transport if ac's state is READY. // getReadyTransport returns the transport if ac's state is READY or nil if not.
// Otherwise it returns nil, false. func (ac *addrConn) getReadyTransport() transport.ClientTransport {
// If ac's state is IDLE, it will trigger ac to connect.
func (ac *addrConn) getReadyTransport() (transport.ClientTransport, bool) {
ac.mu.Lock() ac.mu.Lock()
if ac.state == connectivity.Ready && ac.transport != nil { defer ac.mu.Unlock()
t := ac.transport if ac.state == connectivity.Ready {
ac.mu.Unlock() return ac.transport
return t, true
} }
var idle bool return nil
if ac.state == connectivity.Idle {
idle = true
}
ac.mu.Unlock()
// Trigger idle ac to connect.
if idle {
ac.connect()
}
return nil, false
} }
// tearDown starts to tear down the addrConn. // tearDown starts to tear down the addrConn.

11
vendor/google.golang.org/grpc/go.mod generated vendored
View File

@ -3,15 +3,16 @@ module google.golang.org/grpc
go 1.11 go 1.11
require ( require (
github.com/cespare/xxhash v1.1.0
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403 github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
github.com/golang/protobuf v1.4.2 github.com/golang/protobuf v1.4.3
github.com/google/go-cmp v0.5.0 github.com/google/go-cmp v0.5.0
github.com/google/uuid v1.1.2 github.com/google/uuid v1.1.2
golang.org/x/net v0.0.0-20190311183353-d8887717615a golang.org/x/net v0.0.0-20200822124328-c89045814202
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013
google.golang.org/protobuf v1.25.0 google.golang.org/protobuf v1.25.0
) )

50
vendor/google.golang.org/grpc/go.sum generated vendored
View File

@ -1,32 +1,46 @@
cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0 h1:eOI3/cP2VTU6uZLDYAoic+eyzzB9YyGmJ7eIjl8rOPg=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403 h1:cqQfy1jclcSy/FwLjemeg3SR1yaINm74aQyupQ0Bl8M= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403 h1:cqQfy1jclcSy/FwLjemeg3SR1yaINm74aQyupQ0Bl8M=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed h1:OZmjad4L3H8ncOIR8rnb5MREYqG8ixi5+WbeUsquF0c=
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d h1:QyzYnTnPE15SQyUeqU6qLbWxMkwyAyu+vGksa0b7j00= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0 h1:dulLQAYQFYtG5MTplgNGHWuV2D+OBD+Z8lmDBmbLg+s=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@ -35,49 +49,66 @@ github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -90,7 +121,8 @@ google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3 h1:fvjTMHxHEw/mxHbtzPi3JCcKXQRAnQTBRo6YCJSVHKI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View File

@ -69,7 +69,8 @@ type writerSink struct {
func (ws *writerSink) Write(e *pb.GrpcLogEntry) error { func (ws *writerSink) Write(e *pb.GrpcLogEntry) error {
b, err := proto.Marshal(e) b, err := proto.Marshal(e)
if err != nil { if err != nil {
grpclogLogger.Infof("binary logging: failed to marshal proto message: %v", err) grpclogLogger.Errorf("binary logging: failed to marshal proto message: %v", err)
return err
} }
hdr := make([]byte, 4) hdr := make([]byte, 4)
binary.BigEndian.PutUint32(hdr, uint32(len(b))) binary.BigEndian.PutUint32(hdr, uint32(len(b)))
@ -89,20 +90,23 @@ type bufferedSink struct {
closer io.Closer closer io.Closer
out Sink // out is built on buf. out Sink // out is built on buf.
buf *bufio.Writer // buf is kept for flush. buf *bufio.Writer // buf is kept for flush.
flusherStarted bool
writeStartOnce sync.Once
writeTicker *time.Ticker writeTicker *time.Ticker
done chan struct{}
} }
func (fs *bufferedSink) Write(e *pb.GrpcLogEntry) error { func (fs *bufferedSink) Write(e *pb.GrpcLogEntry) error {
// Start the write loop when Write is called.
fs.writeStartOnce.Do(fs.startFlushGoroutine)
fs.mu.Lock() fs.mu.Lock()
defer fs.mu.Unlock()
if !fs.flusherStarted {
// Start the write loop when Write is called.
fs.startFlushGoroutine()
fs.flusherStarted = true
}
if err := fs.out.Write(e); err != nil { if err := fs.out.Write(e); err != nil {
fs.mu.Unlock()
return err return err
} }
fs.mu.Unlock()
return nil return nil
} }
@ -113,7 +117,12 @@ const (
func (fs *bufferedSink) startFlushGoroutine() { func (fs *bufferedSink) startFlushGoroutine() {
fs.writeTicker = time.NewTicker(bufFlushDuration) fs.writeTicker = time.NewTicker(bufFlushDuration)
go func() { go func() {
for range fs.writeTicker.C { for {
select {
case <-fs.done:
return
case <-fs.writeTicker.C:
}
fs.mu.Lock() fs.mu.Lock()
if err := fs.buf.Flush(); err != nil { if err := fs.buf.Flush(); err != nil {
grpclogLogger.Warningf("failed to flush to Sink: %v", err) grpclogLogger.Warningf("failed to flush to Sink: %v", err)
@ -124,10 +133,12 @@ func (fs *bufferedSink) startFlushGoroutine() {
} }
func (fs *bufferedSink) Close() error { func (fs *bufferedSink) Close() error {
fs.mu.Lock()
defer fs.mu.Unlock()
if fs.writeTicker != nil { if fs.writeTicker != nil {
fs.writeTicker.Stop() fs.writeTicker.Stop()
} }
fs.mu.Lock() close(fs.done)
if err := fs.buf.Flush(); err != nil { if err := fs.buf.Flush(); err != nil {
grpclogLogger.Warningf("failed to flush to Sink: %v", err) grpclogLogger.Warningf("failed to flush to Sink: %v", err)
} }
@ -137,7 +148,6 @@ func (fs *bufferedSink) Close() error {
if err := fs.out.Close(); err != nil { if err := fs.out.Close(); err != nil {
grpclogLogger.Warningf("failed to close the Sink: %v", err) grpclogLogger.Warningf("failed to close the Sink: %v", err)
} }
fs.mu.Unlock()
return nil return nil
} }
@ -155,5 +165,6 @@ func NewBufferedSink(o io.WriteCloser) Sink {
closer: o, closer: o,
out: newWriterSink(bufW), out: newWriterSink(bufW),
buf: bufW, buf: bufW,
done: make(chan struct{}),
} }
} }

View File

@ -31,26 +31,37 @@ var (
mu sync.Mutex mu sync.Mutex
) )
// Int implements rand.Int on the grpcrand global source.
func Int() int {
mu.Lock()
defer mu.Unlock()
return r.Int()
}
// Int63n implements rand.Int63n on the grpcrand global source. // Int63n implements rand.Int63n on the grpcrand global source.
func Int63n(n int64) int64 { func Int63n(n int64) int64 {
mu.Lock() mu.Lock()
res := r.Int63n(n) defer mu.Unlock()
mu.Unlock() return r.Int63n(n)
return res
} }
// Intn implements rand.Intn on the grpcrand global source. // Intn implements rand.Intn on the grpcrand global source.
func Intn(n int) int { func Intn(n int) int {
mu.Lock() mu.Lock()
res := r.Intn(n) defer mu.Unlock()
mu.Unlock() return r.Intn(n)
return res
} }
// Float64 implements rand.Float64 on the grpcrand global source. // Float64 implements rand.Float64 on the grpcrand global source.
func Float64() float64 { func Float64() float64 {
mu.Lock() mu.Lock()
res := r.Float64() defer mu.Unlock()
mu.Unlock() return r.Float64()
return res }
// Uint64 implements rand.Uint64 on the grpcrand global source.
func Uint64() uint64 {
mu.Lock()
defer mu.Unlock()
return r.Uint64()
} }

View File

@ -97,7 +97,7 @@ func (s *Status) Err() error {
if s.Code() == codes.OK { if s.Code() == codes.OK {
return nil return nil
} }
return &Error{e: s.Proto()} return &Error{s: s}
} }
// WithDetails returns a new status with the provided details messages appended to the status. // WithDetails returns a new status with the provided details messages appended to the status.
@ -136,19 +136,23 @@ func (s *Status) Details() []interface{} {
return details return details
} }
func (s *Status) String() string {
return fmt.Sprintf("rpc error: code = %s desc = %s", s.Code(), s.Message())
}
// Error wraps a pointer of a status proto. It implements error and Status, // Error wraps a pointer of a status proto. It implements error and Status,
// and a nil *Error should never be returned by this package. // and a nil *Error should never be returned by this package.
type Error struct { type Error struct {
e *spb.Status s *Status
} }
func (e *Error) Error() string { func (e *Error) Error() string {
return fmt.Sprintf("rpc error: code = %s desc = %s", codes.Code(e.e.GetCode()), e.e.GetMessage()) return e.s.String()
} }
// GRPCStatus returns the Status represented by se. // GRPCStatus returns the Status represented by se.
func (e *Error) GRPCStatus() *Status { func (e *Error) GRPCStatus() *Status {
return FromProto(e.e) return e.s
} }
// Is implements future error.Is functionality. // Is implements future error.Is functionality.
@ -158,5 +162,5 @@ func (e *Error) Is(target error) bool {
if !ok { if !ok {
return false return false
} }
return proto.Equal(e.e, tse.e) return proto.Equal(e.s.s, tse.s.s)
} }

View File

@ -296,7 +296,7 @@ type controlBuffer struct {
// closed and nilled when transportResponseFrames drops below the // closed and nilled when transportResponseFrames drops below the
// threshold. Both fields are protected by mu. // threshold. Both fields are protected by mu.
transportResponseFrames int transportResponseFrames int
trfChan atomic.Value // *chan struct{} trfChan atomic.Value // chan struct{}
} }
func newControlBuffer(done <-chan struct{}) *controlBuffer { func newControlBuffer(done <-chan struct{}) *controlBuffer {
@ -310,10 +310,10 @@ func newControlBuffer(done <-chan struct{}) *controlBuffer {
// throttle blocks if there are too many incomingSettings/cleanupStreams in the // throttle blocks if there are too many incomingSettings/cleanupStreams in the
// controlbuf. // controlbuf.
func (c *controlBuffer) throttle() { func (c *controlBuffer) throttle() {
ch, _ := c.trfChan.Load().(*chan struct{}) ch, _ := c.trfChan.Load().(chan struct{})
if ch != nil { if ch != nil {
select { select {
case <-*ch: case <-ch:
case <-c.done: case <-c.done:
} }
} }
@ -347,8 +347,7 @@ func (c *controlBuffer) executeAndPut(f func(it interface{}) bool, it cbItem) (b
if c.transportResponseFrames == maxQueuedTransportResponseFrames { if c.transportResponseFrames == maxQueuedTransportResponseFrames {
// We are adding the frame that puts us over the threshold; create // We are adding the frame that puts us over the threshold; create
// a throttling channel. // a throttling channel.
ch := make(chan struct{}) c.trfChan.Store(make(chan struct{}))
c.trfChan.Store(&ch)
} }
} }
c.mu.Unlock() c.mu.Unlock()
@ -389,9 +388,9 @@ func (c *controlBuffer) get(block bool) (interface{}, error) {
if c.transportResponseFrames == maxQueuedTransportResponseFrames { if c.transportResponseFrames == maxQueuedTransportResponseFrames {
// We are removing the frame that put us over the // We are removing the frame that put us over the
// threshold; close and clear the throttling channel. // threshold; close and clear the throttling channel.
ch := c.trfChan.Load().(*chan struct{}) ch := c.trfChan.Load().(chan struct{})
close(*ch) close(ch)
c.trfChan.Store((*chan struct{})(nil)) c.trfChan.Store((chan struct{})(nil))
} }
c.transportResponseFrames-- c.transportResponseFrames--
} }
@ -407,7 +406,6 @@ func (c *controlBuffer) get(block bool) (interface{}, error) {
select { select {
case <-c.ch: case <-c.ch:
case <-c.done: case <-c.done:
c.finish()
return nil, ErrConnClosing return nil, ErrConnClosing
} }
} }
@ -432,6 +430,14 @@ func (c *controlBuffer) finish() {
hdr.onOrphaned(ErrConnClosing) hdr.onOrphaned(ErrConnClosing)
} }
} }
// In case throttle() is currently in flight, it needs to be unblocked.
// Otherwise, the transport may not close, since the transport is closed by
// the reader encountering the connection error.
ch, _ := c.trfChan.Load().(chan struct{})
if ch != nil {
close(ch)
}
c.trfChan.Store((chan struct{})(nil))
c.mu.Unlock() c.mu.Unlock()
} }

View File

@ -141,9 +141,8 @@ type serverHandlerTransport struct {
stats stats.Handler stats stats.Handler
} }
func (ht *serverHandlerTransport) Close() error { func (ht *serverHandlerTransport) Close() {
ht.closeOnce.Do(ht.closeCloseChanOnce) ht.closeOnce.Do(ht.closeCloseChanOnce)
return nil
} }
func (ht *serverHandlerTransport) closeCloseChanOnce() { close(ht.closedCh) } func (ht *serverHandlerTransport) closeCloseChanOnce() { close(ht.closedCh) }

View File

@ -24,6 +24,7 @@ import (
"io" "io"
"math" "math"
"net" "net"
"net/http"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -241,7 +242,15 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts
// and passed to the credential handshaker. This makes it possible for // and passed to the credential handshaker. This makes it possible for
// address specific arbitrary data to reach the credential handshaker. // address specific arbitrary data to reach the credential handshaker.
connectCtx = icredentials.NewClientHandshakeInfoContext(connectCtx, credentials.ClientHandshakeInfo{Attributes: addr.Attributes}) connectCtx = icredentials.NewClientHandshakeInfoContext(connectCtx, credentials.ClientHandshakeInfo{Attributes: addr.Attributes})
conn, authInfo, err = transportCreds.ClientHandshake(connectCtx, addr.ServerName, conn) rawConn := conn
// Pull the deadline from the connectCtx, which will be used for
// timeouts in the authentication protocol handshake. Can ignore the
// boolean as the deadline will return the zero value, which will make
// the conn not timeout on I/O operations.
deadline, _ := connectCtx.Deadline()
rawConn.SetDeadline(deadline)
conn, authInfo, err = transportCreds.ClientHandshake(connectCtx, addr.ServerName, rawConn)
rawConn.SetDeadline(time.Time{})
if err != nil { if err != nil {
return nil, connectionErrorf(isTemporary(err), err, "transport: authentication handshake failed: %v", err) return nil, connectionErrorf(isTemporary(err), err, "transport: authentication handshake failed: %v", err)
} }
@ -399,11 +408,10 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts
logger.Errorf("transport: loopyWriter.run returning. Err: %v", err) logger.Errorf("transport: loopyWriter.run returning. Err: %v", err)
} }
} }
// If it's a connection error, let reader goroutine handle it // Do not close the transport. Let reader goroutine handle it since
// since there might be data in the buffers. // there might be data in the buffers.
if _, ok := err.(net.Error); !ok {
t.conn.Close() t.conn.Close()
} t.controlBuf.finish()
close(t.writerDone) close(t.writerDone)
}() }()
return t, nil return t, nil
@ -608,26 +616,39 @@ func (t *http2Client) getCallAuthData(ctx context.Context, audience string, call
return callAuthData, nil return callAuthData, nil
} }
// PerformedIOError wraps an error to indicate IO may have been performed // NewStreamError wraps an error and reports additional information.
// before the error occurred. type NewStreamError struct {
type PerformedIOError struct {
Err error Err error
DoNotRetry bool
PerformedIO bool
} }
// Error implements error. func (e NewStreamError) Error() string {
func (p PerformedIOError) Error() string { return e.Err.Error()
return p.Err.Error()
} }
// NewStream creates a stream and registers it into the transport as "active" // NewStream creates a stream and registers it into the transport as "active"
// streams. // streams. All non-nil errors returned will be *NewStreamError.
func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Stream, err error) { func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Stream, err error) {
defer func() {
if err != nil {
nse, ok := err.(*NewStreamError)
if !ok {
nse = &NewStreamError{Err: err}
}
if len(t.perRPCCreds) > 0 || callHdr.Creds != nil {
// We may have performed I/O in the per-RPC creds callback, so do not
// allow transparent retry.
nse.PerformedIO = true
}
err = nse
}
}()
ctx = peer.NewContext(ctx, t.getPeer()) ctx = peer.NewContext(ctx, t.getPeer())
headerFields, err := t.createHeaderFields(ctx, callHdr) headerFields, err := t.createHeaderFields(ctx, callHdr)
if err != nil { if err != nil {
// We may have performed I/O in the per-RPC creds callback, so do not return nil, err
// allow transparent retry.
return nil, PerformedIOError{err}
} }
s := t.newStream(ctx, callHdr) s := t.newStream(ctx, callHdr)
cleanup := func(err error) { cleanup := func(err error) {
@ -733,7 +754,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
break break
} }
if hdrListSizeErr != nil { if hdrListSizeErr != nil {
return nil, hdrListSizeErr return nil, &NewStreamError{Err: hdrListSizeErr, DoNotRetry: true}
} }
firstTry = false firstTry = false
select { select {
@ -878,12 +899,18 @@ func (t *http2Client) Close(err error) {
// Append info about previous goaways if there were any, since this may be important // Append info about previous goaways if there were any, since this may be important
// for understanding the root cause for this connection to be closed. // for understanding the root cause for this connection to be closed.
_, goAwayDebugMessage := t.GetGoAwayReason() _, goAwayDebugMessage := t.GetGoAwayReason()
var st *status.Status
if len(goAwayDebugMessage) > 0 { if len(goAwayDebugMessage) > 0 {
err = fmt.Errorf("closing transport due to: %v, received prior goaway: %v", err, goAwayDebugMessage) st = status.Newf(codes.Unavailable, "closing transport due to: %v, received prior goaway: %v", err, goAwayDebugMessage)
err = st.Err()
} else {
st = status.New(codes.Unavailable, err.Error())
} }
// Notify all active streams. // Notify all active streams.
for _, s := range streams { for _, s := range streams {
t.closeStream(s, err, false, http2.ErrCodeNo, status.New(codes.Unavailable, err.Error()), nil, false) t.closeStream(s, err, false, http2.ErrCodeNo, st, nil, false)
} }
if t.statsHandler != nil { if t.statsHandler != nil {
connEnd := &stats.ConnEnd{ connEnd := &stats.ConnEnd{
@ -1221,7 +1248,11 @@ func (t *http2Client) setGoAwayReason(f *http2.GoAwayFrame) {
t.goAwayReason = GoAwayTooManyPings t.goAwayReason = GoAwayTooManyPings
} }
} }
t.goAwayDebugMessage = fmt.Sprintf("code: %s, debug data: %v", f.ErrCode, string(f.DebugData())) if len(f.DebugData()) == 0 {
t.goAwayDebugMessage = fmt.Sprintf("code: %s", f.ErrCode)
} else {
t.goAwayDebugMessage = fmt.Sprintf("code: %s, debug data: %q", f.ErrCode, string(f.DebugData()))
}
} }
func (t *http2Client) GetGoAwayReason() (GoAwayReason, string) { func (t *http2Client) GetGoAwayReason() (GoAwayReason, string) {
@ -1254,11 +1285,124 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) {
return return
} }
state := &decodeState{} // frame.Truncated is set to true when framer detects that the current header
// Initialize isGRPC value to be !initialHeader, since if a gRPC Response-Headers has already been received, then it means that the peer is speaking gRPC and we are in gRPC mode. // list size hits MaxHeaderListSize limit.
state.data.isGRPC = !initialHeader if frame.Truncated {
if h2code, err := state.decodeHeader(frame); err != nil { se := status.New(codes.Internal, "peer header list size exceeded limit")
t.closeStream(s, err, true, h2code, status.Convert(err), nil, endStream) t.closeStream(s, se.Err(), true, http2.ErrCodeFrameSize, se, nil, endStream)
return
}
var (
// If a gRPC Response-Headers has already been received, then it means
// that the peer is speaking gRPC and we are in gRPC mode.
isGRPC = !initialHeader
mdata = make(map[string][]string)
contentTypeErr = "malformed header: missing HTTP content-type"
grpcMessage string
statusGen *status.Status
recvCompress string
httpStatusCode *int
httpStatusErr string
rawStatusCode = codes.Unknown
// headerError is set if an error is encountered while parsing the headers
headerError string
)
if initialHeader {
httpStatusErr = "malformed header: missing HTTP status"
}
for _, hf := range frame.Fields {
switch hf.Name {
case "content-type":
if _, validContentType := grpcutil.ContentSubtype(hf.Value); !validContentType {
contentTypeErr = fmt.Sprintf("transport: received unexpected content-type %q", hf.Value)
break
}
contentTypeErr = ""
mdata[hf.Name] = append(mdata[hf.Name], hf.Value)
isGRPC = true
case "grpc-encoding":
recvCompress = hf.Value
case "grpc-status":
code, err := strconv.ParseInt(hf.Value, 10, 32)
if err != nil {
se := status.New(codes.Internal, fmt.Sprintf("transport: malformed grpc-status: %v", err))
t.closeStream(s, se.Err(), true, http2.ErrCodeProtocol, se, nil, endStream)
return
}
rawStatusCode = codes.Code(uint32(code))
case "grpc-message":
grpcMessage = decodeGrpcMessage(hf.Value)
case "grpc-status-details-bin":
var err error
statusGen, err = decodeGRPCStatusDetails(hf.Value)
if err != nil {
headerError = fmt.Sprintf("transport: malformed grpc-status-details-bin: %v", err)
}
case ":status":
if hf.Value == "200" {
httpStatusErr = ""
statusCode := 200
httpStatusCode = &statusCode
break
}
c, err := strconv.ParseInt(hf.Value, 10, 32)
if err != nil {
se := status.New(codes.Internal, fmt.Sprintf("transport: malformed http-status: %v", err))
t.closeStream(s, se.Err(), true, http2.ErrCodeProtocol, se, nil, endStream)
return
}
statusCode := int(c)
httpStatusCode = &statusCode
httpStatusErr = fmt.Sprintf(
"unexpected HTTP status code received from server: %d (%s)",
statusCode,
http.StatusText(statusCode),
)
default:
if isReservedHeader(hf.Name) && !isWhitelistedHeader(hf.Name) {
break
}
v, err := decodeMetadataHeader(hf.Name, hf.Value)
if err != nil {
headerError = fmt.Sprintf("transport: malformed %s: %v", hf.Name, err)
logger.Warningf("Failed to decode metadata header (%q, %q): %v", hf.Name, hf.Value, err)
break
}
mdata[hf.Name] = append(mdata[hf.Name], v)
}
}
if !isGRPC || httpStatusErr != "" {
var code = codes.Internal // when header does not include HTTP status, return INTERNAL
if httpStatusCode != nil {
var ok bool
code, ok = HTTPStatusConvTab[*httpStatusCode]
if !ok {
code = codes.Unknown
}
}
var errs []string
if httpStatusErr != "" {
errs = append(errs, httpStatusErr)
}
if contentTypeErr != "" {
errs = append(errs, contentTypeErr)
}
// Verify the HTTP response is a 200.
se := status.New(code, strings.Join(errs, "; "))
t.closeStream(s, se.Err(), true, http2.ErrCodeProtocol, se, nil, endStream)
return
}
if headerError != "" {
se := status.New(codes.Internal, headerError)
t.closeStream(s, se.Err(), true, http2.ErrCodeProtocol, se, nil, endStream)
return return
} }
@ -1293,9 +1437,9 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) {
// These values can be set without any synchronization because // These values can be set without any synchronization because
// stream goroutine will read it only after seeing a closed // stream goroutine will read it only after seeing a closed
// headerChan which we'll close after setting this. // headerChan which we'll close after setting this.
s.recvCompress = state.data.encoding s.recvCompress = recvCompress
if len(state.data.mdata) > 0 { if len(mdata) > 0 {
s.header = state.data.mdata s.header = mdata
} }
} else { } else {
// HEADERS frame block carries a Trailers-Only. // HEADERS frame block carries a Trailers-Only.
@ -1308,9 +1452,13 @@ func (t *http2Client) operateHeaders(frame *http2.MetaHeadersFrame) {
return return
} }
if statusGen == nil {
statusGen = status.New(rawStatusCode, grpcMessage)
}
// if client received END_STREAM from server while stream was still active, send RST_STREAM // if client received END_STREAM from server while stream was still active, send RST_STREAM
rst := s.getState() == streamActive rst := s.getState() == streamActive
t.closeStream(s, io.EOF, rst, http2.ErrCodeNo, state.status(), state.data.mdata, true) t.closeStream(s, io.EOF, rst, http2.ErrCodeNo, statusGen, mdata, true)
} }
// reader runs as a separate goroutine in charge of reading data from network // reader runs as a separate goroutine in charge of reading data from network

View File

@ -102,11 +102,11 @@ type http2Server struct {
mu sync.Mutex // guard the following mu sync.Mutex // guard the following
// drainChan is initialized when drain(...) is called the first time. // drainChan is initialized when Drain() is called the first time.
// After which the server writes out the first GoAway(with ID 2^31-1) frame. // After which the server writes out the first GoAway(with ID 2^31-1) frame.
// Then an independent goroutine will be launched to later send the second GoAway. // Then an independent goroutine will be launched to later send the second GoAway.
// During this time we don't want to write another first GoAway(with ID 2^31 -1) frame. // During this time we don't want to write another first GoAway(with ID 2^31 -1) frame.
// Thus call to drain(...) will be a no-op if drainChan is already initialized since draining is // Thus call to Drain() will be a no-op if drainChan is already initialized since draining is
// already underway. // already underway.
drainChan chan struct{} drainChan chan struct{}
state transportState state transportState
@ -125,9 +125,14 @@ type http2Server struct {
connectionID uint64 connectionID uint64
} }
// newHTTP2Server constructs a ServerTransport based on HTTP2. ConnectionError is // NewServerTransport creates a http2 transport with conn and configuration
// returned if something goes wrong. // options from config.
func newHTTP2Server(conn net.Conn, config *ServerConfig) (_ ServerTransport, err error) { //
// It returns a non-nil transport and a nil error on success. On failure, it
// returns a non-nil transport and a nil-error. For a special case where the
// underlying conn gets closed before the client preface could be read, it
// returns a nil transport and a nil error.
func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, err error) {
writeBufSize := config.WriteBufferSize writeBufSize := config.WriteBufferSize
readBufSize := config.ReadBufferSize readBufSize := config.ReadBufferSize
maxHeaderListSize := defaultServerMaxHeaderListSize maxHeaderListSize := defaultServerMaxHeaderListSize
@ -266,6 +271,13 @@ func newHTTP2Server(conn net.Conn, config *ServerConfig) (_ ServerTransport, err
// Check the validity of client preface. // Check the validity of client preface.
preface := make([]byte, len(clientPreface)) preface := make([]byte, len(clientPreface))
if _, err := io.ReadFull(t.conn, preface); err != nil { if _, err := io.ReadFull(t.conn, preface); err != nil {
// In deployments where a gRPC server runs behind a cloud load balancer
// which performs regular TCP level health checks, the connection is
// closed immediately by the latter. Skipping the error here will help
// reduce log clutter.
if err == io.EOF {
return nil, nil
}
return nil, connectionErrorf(false, err, "transport: http2Server.HandleStreams failed to receive the preface from client: %v", err) return nil, connectionErrorf(false, err, "transport: http2Server.HandleStreams failed to receive the preface from client: %v", err)
} }
if !bytes.Equal(preface, clientPreface) { if !bytes.Equal(preface, clientPreface) {
@ -295,6 +307,7 @@ func newHTTP2Server(conn net.Conn, config *ServerConfig) (_ ServerTransport, err
} }
} }
t.conn.Close() t.conn.Close()
t.controlBuf.finish()
close(t.writerDone) close(t.writerDone)
}() }()
go t.keepalive() go t.keepalive()
@ -304,18 +317,16 @@ func newHTTP2Server(conn net.Conn, config *ServerConfig) (_ ServerTransport, err
// operateHeader takes action on the decoded headers. // operateHeader takes action on the decoded headers.
func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(*Stream), traceCtx func(context.Context, string) context.Context) (fatal bool) { func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(*Stream), traceCtx func(context.Context, string) context.Context) (fatal bool) {
streamID := frame.Header().StreamID streamID := frame.Header().StreamID
state := &decodeState{
serverSide: true, // frame.Truncated is set to true when framer detects that the current header
} // list size hits MaxHeaderListSize limit.
if h2code, err := state.decodeHeader(frame); err != nil { if frame.Truncated {
if _, ok := status.FromError(err); ok {
t.controlBuf.put(&cleanupStream{ t.controlBuf.put(&cleanupStream{
streamID: streamID, streamID: streamID,
rst: true, rst: true,
rstCode: h2code, rstCode: http2.ErrCodeFrameSize,
onWrite: func() {}, onWrite: func() {},
}) })
}
return false return false
} }
@ -325,16 +336,73 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
st: t, st: t,
buf: buf, buf: buf,
fc: &inFlow{limit: uint32(t.initialWindowSize)}, fc: &inFlow{limit: uint32(t.initialWindowSize)},
recvCompress: state.data.encoding,
method: state.data.method,
contentSubtype: state.data.contentSubtype,
} }
var (
// If a gRPC Response-Headers has already been received, then it means
// that the peer is speaking gRPC and we are in gRPC mode.
isGRPC = false
mdata = make(map[string][]string)
httpMethod string
// headerError is set if an error is encountered while parsing the headers
headerError bool
timeoutSet bool
timeout time.Duration
)
for _, hf := range frame.Fields {
switch hf.Name {
case "content-type":
contentSubtype, validContentType := grpcutil.ContentSubtype(hf.Value)
if !validContentType {
break
}
mdata[hf.Name] = append(mdata[hf.Name], hf.Value)
s.contentSubtype = contentSubtype
isGRPC = true
case "grpc-encoding":
s.recvCompress = hf.Value
case ":method":
httpMethod = hf.Value
case ":path":
s.method = hf.Value
case "grpc-timeout":
timeoutSet = true
var err error
if timeout, err = decodeTimeout(hf.Value); err != nil {
headerError = true
}
default:
if isReservedHeader(hf.Name) && !isWhitelistedHeader(hf.Name) {
break
}
v, err := decodeMetadataHeader(hf.Name, hf.Value)
if err != nil {
headerError = true
logger.Warningf("Failed to decode metadata header (%q, %q): %v", hf.Name, hf.Value, err)
break
}
mdata[hf.Name] = append(mdata[hf.Name], v)
}
}
if !isGRPC || headerError {
t.controlBuf.put(&cleanupStream{
streamID: streamID,
rst: true,
rstCode: http2.ErrCodeProtocol,
onWrite: func() {},
})
return false
}
if frame.StreamEnded() { if frame.StreamEnded() {
// s is just created by the caller. No lock needed. // s is just created by the caller. No lock needed.
s.state = streamReadDone s.state = streamReadDone
} }
if state.data.timeoutSet { if timeoutSet {
s.ctx, s.cancel = context.WithTimeout(t.ctx, state.data.timeout) s.ctx, s.cancel = context.WithTimeout(t.ctx, timeout)
} else { } else {
s.ctx, s.cancel = context.WithCancel(t.ctx) s.ctx, s.cancel = context.WithCancel(t.ctx)
} }
@ -347,14 +415,14 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
} }
s.ctx = peer.NewContext(s.ctx, pr) s.ctx = peer.NewContext(s.ctx, pr)
// Attach the received metadata to the context. // Attach the received metadata to the context.
if len(state.data.mdata) > 0 { if len(mdata) > 0 {
s.ctx = metadata.NewIncomingContext(s.ctx, state.data.mdata) s.ctx = metadata.NewIncomingContext(s.ctx, mdata)
if statsTags := mdata["grpc-tags-bin"]; len(statsTags) > 0 {
s.ctx = stats.SetIncomingTags(s.ctx, []byte(statsTags[len(statsTags)-1]))
} }
if state.data.statsTags != nil { if statsTrace := mdata["grpc-trace-bin"]; len(statsTrace) > 0 {
s.ctx = stats.SetIncomingTags(s.ctx, state.data.statsTags) s.ctx = stats.SetIncomingTrace(s.ctx, []byte(statsTrace[len(statsTrace)-1]))
} }
if state.data.statsTrace != nil {
s.ctx = stats.SetIncomingTrace(s.ctx, state.data.statsTrace)
} }
t.mu.Lock() t.mu.Lock()
if t.state != reachable { if t.state != reachable {
@ -383,10 +451,10 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
return true return true
} }
t.maxStreamID = streamID t.maxStreamID = streamID
if state.data.httpMethod != http.MethodPost { if httpMethod != http.MethodPost {
t.mu.Unlock() t.mu.Unlock()
if logger.V(logLevel) { if logger.V(logLevel) {
logger.Warningf("transport: http2Server.operateHeaders parsed a :method field: %v which should be POST", state.data.httpMethod) logger.Infof("transport: http2Server.operateHeaders parsed a :method field: %v which should be POST", httpMethod)
} }
t.controlBuf.put(&cleanupStream{ t.controlBuf.put(&cleanupStream{
streamID: streamID, streamID: streamID,
@ -399,7 +467,7 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
} }
if t.inTapHandle != nil { if t.inTapHandle != nil {
var err error var err error
if s.ctx, err = t.inTapHandle(s.ctx, &tap.Info{FullMethodName: state.data.method}); err != nil { if s.ctx, err = t.inTapHandle(s.ctx, &tap.Info{FullMethodName: s.method}); err != nil {
t.mu.Unlock() t.mu.Unlock()
if logger.V(logLevel) { if logger.V(logLevel) {
logger.Infof("transport: http2Server.operateHeaders got an error from InTapHandle: %v", err) logger.Infof("transport: http2Server.operateHeaders got an error from InTapHandle: %v", err)
@ -437,7 +505,7 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
LocalAddr: t.localAddr, LocalAddr: t.localAddr,
Compression: s.recvCompress, Compression: s.recvCompress,
WireLength: int(frame.Header().Length), WireLength: int(frame.Header().Length),
Header: metadata.MD(state.data.mdata).Copy(), Header: metadata.MD(mdata).Copy(),
} }
t.stats.HandleRPC(s.ctx, inHeader) t.stats.HandleRPC(s.ctx, inHeader)
} }
@ -1004,12 +1072,12 @@ func (t *http2Server) keepalive() {
if val <= 0 { if val <= 0 {
// The connection has been idle for a duration of keepalive.MaxConnectionIdle or more. // The connection has been idle for a duration of keepalive.MaxConnectionIdle or more.
// Gracefully close the connection. // Gracefully close the connection.
t.drain(http2.ErrCodeNo, []byte{}) t.Drain()
return return
} }
idleTimer.Reset(val) idleTimer.Reset(val)
case <-ageTimer.C: case <-ageTimer.C:
t.drain(http2.ErrCodeNo, []byte{}) t.Drain()
ageTimer.Reset(t.kp.MaxConnectionAgeGrace) ageTimer.Reset(t.kp.MaxConnectionAgeGrace)
select { select {
case <-ageTimer.C: case <-ageTimer.C:
@ -1063,11 +1131,11 @@ func (t *http2Server) keepalive() {
// Close starts shutting down the http2Server transport. // Close starts shutting down the http2Server transport.
// TODO(zhaoq): Now the destruction is not blocked on any pending streams. This // TODO(zhaoq): Now the destruction is not blocked on any pending streams. This
// could cause some resource issue. Revisit this later. // could cause some resource issue. Revisit this later.
func (t *http2Server) Close() error { func (t *http2Server) Close() {
t.mu.Lock() t.mu.Lock()
if t.state == closing { if t.state == closing {
t.mu.Unlock() t.mu.Unlock()
return errors.New("transport: Close() was already called") return
} }
t.state = closing t.state = closing
streams := t.activeStreams streams := t.activeStreams
@ -1075,7 +1143,9 @@ func (t *http2Server) Close() error {
t.mu.Unlock() t.mu.Unlock()
t.controlBuf.finish() t.controlBuf.finish()
close(t.done) close(t.done)
err := t.conn.Close() if err := t.conn.Close(); err != nil && logger.V(logLevel) {
logger.Infof("transport: error closing conn during Close: %v", err)
}
if channelz.IsOn() { if channelz.IsOn() {
channelz.RemoveEntry(t.channelzID) channelz.RemoveEntry(t.channelzID)
} }
@ -1087,7 +1157,6 @@ func (t *http2Server) Close() error {
connEnd := &stats.ConnEnd{} connEnd := &stats.ConnEnd{}
t.stats.HandleConn(t.ctx, connEnd) t.stats.HandleConn(t.ctx, connEnd)
} }
return err
} }
// deleteStream deletes the stream s from transport's active streams. // deleteStream deletes the stream s from transport's active streams.
@ -1152,17 +1221,13 @@ func (t *http2Server) RemoteAddr() net.Addr {
} }
func (t *http2Server) Drain() { func (t *http2Server) Drain() {
t.drain(http2.ErrCodeNo, []byte{})
}
func (t *http2Server) drain(code http2.ErrCode, debugData []byte) {
t.mu.Lock() t.mu.Lock()
defer t.mu.Unlock() defer t.mu.Unlock()
if t.drainChan != nil { if t.drainChan != nil {
return return
} }
t.drainChan = make(chan struct{}) t.drainChan = make(chan struct{})
t.controlBuf.put(&goAway{code: code, debugData: debugData, headsUp: true}) t.controlBuf.put(&goAway{code: http2.ErrCodeNo, debugData: []byte{}, headsUp: true})
} }
var goAwayPing = &ping{data: [8]byte{1, 6, 1, 8, 0, 3, 3, 9}} var goAwayPing = &ping{data: [8]byte{1, 6, 1, 8, 0, 3, 3, 9}}

View File

@ -39,7 +39,6 @@ import (
spb "google.golang.org/genproto/googleapis/rpc/status" spb "google.golang.org/genproto/googleapis/rpc/status"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog" "google.golang.org/grpc/grpclog"
"google.golang.org/grpc/internal/grpcutil"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
) )
@ -96,53 +95,6 @@ var (
logger = grpclog.Component("transport") logger = grpclog.Component("transport")
) )
type parsedHeaderData struct {
encoding string
// statusGen caches the stream status received from the trailer the server
// sent. Client side only. Do not access directly. After all trailers are
// parsed, use the status method to retrieve the status.
statusGen *status.Status
// rawStatusCode and rawStatusMsg are set from the raw trailer fields and are not
// intended for direct access outside of parsing.
rawStatusCode *int
rawStatusMsg string
httpStatus *int
// Server side only fields.
timeoutSet bool
timeout time.Duration
method string
httpMethod string
// key-value metadata map from the peer.
mdata map[string][]string
statsTags []byte
statsTrace []byte
contentSubtype string
// isGRPC field indicates whether the peer is speaking gRPC (otherwise HTTP).
//
// We are in gRPC mode (peer speaking gRPC) if:
// * We are client side and have already received a HEADER frame that indicates gRPC peer.
// * The header contains valid a content-type, i.e. a string starts with "application/grpc"
// And we should handle error specific to gRPC.
//
// Otherwise (i.e. a content-type string starts without "application/grpc", or does not exist), we
// are in HTTP fallback mode, and should handle error specific to HTTP.
isGRPC bool
grpcErr error
httpErr error
contentTypeErr string
}
// decodeState configures decoding criteria and records the decoded data.
type decodeState struct {
// whether decoding on server side or not
serverSide bool
// Records the states during HPACK decoding. It will be filled with info parsed from HTTP HEADERS
// frame once decodeHeader function has been invoked and returned.
data parsedHeaderData
}
// isReservedHeader checks whether hdr belongs to HTTP2 headers // isReservedHeader checks whether hdr belongs to HTTP2 headers
// reserved by gRPC protocol. Any other headers are classified as the // reserved by gRPC protocol. Any other headers are classified as the
// user-specified metadata. // user-specified metadata.
@ -180,14 +132,6 @@ func isWhitelistedHeader(hdr string) bool {
} }
} }
func (d *decodeState) status() *status.Status {
if d.data.statusGen == nil {
// No status-details were provided; generate status using code/msg.
d.data.statusGen = status.New(codes.Code(int32(*(d.data.rawStatusCode))), d.data.rawStatusMsg)
}
return d.data.statusGen
}
const binHdrSuffix = "-bin" const binHdrSuffix = "-bin"
func encodeBinHeader(v []byte) string { func encodeBinHeader(v []byte) string {
@ -217,168 +161,16 @@ func decodeMetadataHeader(k, v string) (string, error) {
return v, nil return v, nil
} }
func (d *decodeState) decodeHeader(frame *http2.MetaHeadersFrame) (http2.ErrCode, error) { func decodeGRPCStatusDetails(rawDetails string) (*status.Status, error) {
// frame.Truncated is set to true when framer detects that the current header v, err := decodeBinHeader(rawDetails)
// list size hits MaxHeaderListSize limit.
if frame.Truncated {
return http2.ErrCodeFrameSize, status.Error(codes.Internal, "peer header list size exceeded limit")
}
for _, hf := range frame.Fields {
d.processHeaderField(hf)
}
if d.data.isGRPC {
if d.data.grpcErr != nil {
return http2.ErrCodeProtocol, d.data.grpcErr
}
if d.serverSide {
return http2.ErrCodeNo, nil
}
if d.data.rawStatusCode == nil && d.data.statusGen == nil {
// gRPC status doesn't exist.
// Set rawStatusCode to be unknown and return nil error.
// So that, if the stream has ended this Unknown status
// will be propagated to the user.
// Otherwise, it will be ignored. In which case, status from
// a later trailer, that has StreamEnded flag set, is propagated.
code := int(codes.Unknown)
d.data.rawStatusCode = &code
}
return http2.ErrCodeNo, nil
}
// HTTP fallback mode
if d.data.httpErr != nil {
return http2.ErrCodeProtocol, d.data.httpErr
}
var (
code = codes.Internal // when header does not include HTTP status, return INTERNAL
ok bool
)
if d.data.httpStatus != nil {
code, ok = HTTPStatusConvTab[*(d.data.httpStatus)]
if !ok {
code = codes.Unknown
}
}
return http2.ErrCodeProtocol, status.Error(code, d.constructHTTPErrMsg())
}
// constructErrMsg constructs error message to be returned in HTTP fallback mode.
// Format: HTTP status code and its corresponding message + content-type error message.
func (d *decodeState) constructHTTPErrMsg() string {
var errMsgs []string
if d.data.httpStatus == nil {
errMsgs = append(errMsgs, "malformed header: missing HTTP status")
} else {
errMsgs = append(errMsgs, fmt.Sprintf("%s: HTTP status code %d", http.StatusText(*(d.data.httpStatus)), *d.data.httpStatus))
}
if d.data.contentTypeErr == "" {
errMsgs = append(errMsgs, "transport: missing content-type field")
} else {
errMsgs = append(errMsgs, d.data.contentTypeErr)
}
return strings.Join(errMsgs, "; ")
}
func (d *decodeState) addMetadata(k, v string) {
if d.data.mdata == nil {
d.data.mdata = make(map[string][]string)
}
d.data.mdata[k] = append(d.data.mdata[k], v)
}
func (d *decodeState) processHeaderField(f hpack.HeaderField) {
switch f.Name {
case "content-type":
contentSubtype, validContentType := grpcutil.ContentSubtype(f.Value)
if !validContentType {
d.data.contentTypeErr = fmt.Sprintf("transport: received the unexpected content-type %q", f.Value)
return
}
d.data.contentSubtype = contentSubtype
// TODO: do we want to propagate the whole content-type in the metadata,
// or come up with a way to just propagate the content-subtype if it was set?
// ie {"content-type": "application/grpc+proto"} or {"content-subtype": "proto"}
// in the metadata?
d.addMetadata(f.Name, f.Value)
d.data.isGRPC = true
case "grpc-encoding":
d.data.encoding = f.Value
case "grpc-status":
code, err := strconv.Atoi(f.Value)
if err != nil { if err != nil {
d.data.grpcErr = status.Errorf(codes.Internal, "transport: malformed grpc-status: %v", err) return nil, err
return
} }
d.data.rawStatusCode = &code st := &spb.Status{}
case "grpc-message": if err = proto.Unmarshal(v, st); err != nil {
d.data.rawStatusMsg = decodeGrpcMessage(f.Value) return nil, err
case "grpc-status-details-bin":
v, err := decodeBinHeader(f.Value)
if err != nil {
d.data.grpcErr = status.Errorf(codes.Internal, "transport: malformed grpc-status-details-bin: %v", err)
return
}
s := &spb.Status{}
if err := proto.Unmarshal(v, s); err != nil {
d.data.grpcErr = status.Errorf(codes.Internal, "transport: malformed grpc-status-details-bin: %v", err)
return
}
d.data.statusGen = status.FromProto(s)
case "grpc-timeout":
d.data.timeoutSet = true
var err error
if d.data.timeout, err = decodeTimeout(f.Value); err != nil {
d.data.grpcErr = status.Errorf(codes.Internal, "transport: malformed time-out: %v", err)
}
case ":path":
d.data.method = f.Value
case ":status":
code, err := strconv.Atoi(f.Value)
if err != nil {
d.data.httpErr = status.Errorf(codes.Internal, "transport: malformed http-status: %v", err)
return
}
d.data.httpStatus = &code
case "grpc-tags-bin":
v, err := decodeBinHeader(f.Value)
if err != nil {
d.data.grpcErr = status.Errorf(codes.Internal, "transport: malformed grpc-tags-bin: %v", err)
return
}
d.data.statsTags = v
d.addMetadata(f.Name, string(v))
case "grpc-trace-bin":
v, err := decodeBinHeader(f.Value)
if err != nil {
d.data.grpcErr = status.Errorf(codes.Internal, "transport: malformed grpc-trace-bin: %v", err)
return
}
d.data.statsTrace = v
d.addMetadata(f.Name, string(v))
case ":method":
d.data.httpMethod = f.Value
default:
if isReservedHeader(f.Name) && !isWhitelistedHeader(f.Name) {
break
}
v, err := decodeMetadataHeader(f.Name, f.Value)
if err != nil {
if logger.V(logLevel) {
logger.Errorf("Failed to decode metadata header (%q, %q): %v", f.Name, f.Value, err)
}
return
}
d.addMetadata(f.Name, v)
} }
return status.FromProto(st), nil
} }
type timeoutUnit uint8 type timeoutUnit uint8

View File

@ -17,7 +17,7 @@
*/ */
// Package networktype declares the network type to be used in the default // Package networktype declares the network type to be used in the default
// dailer. Attribute of a resolver.Address. // dialer. Attribute of a resolver.Address.
package networktype package networktype
import ( import (

View File

@ -532,12 +532,6 @@ type ServerConfig struct {
HeaderTableSize *uint32 HeaderTableSize *uint32
} }
// NewServerTransport creates a ServerTransport with conn or non-nil error
// if it fails.
func NewServerTransport(protocol string, conn net.Conn, config *ServerConfig) (ServerTransport, error) {
return newHTTP2Server(conn, config)
}
// ConnectOptions covers all relevant options for communicating with the server. // ConnectOptions covers all relevant options for communicating with the server.
type ConnectOptions struct { type ConnectOptions struct {
// UserAgent is the application user agent. // UserAgent is the application user agent.
@ -694,7 +688,7 @@ type ServerTransport interface {
// Close tears down the transport. Once it is called, the transport // Close tears down the transport. Once it is called, the transport
// should not be accessed any more. All the pending streams and their // should not be accessed any more. All the pending streams and their
// handlers will be terminated asynchronously. // handlers will be terminated asynchronously.
Close() error Close()
// RemoteAddr returns the remote network address. // RemoteAddr returns the remote network address.
RemoteAddr() net.Addr RemoteAddr() net.Addr

View File

@ -93,12 +93,16 @@ func (md MD) Copy() MD {
} }
// Get obtains the values for a given key. // Get obtains the values for a given key.
//
// k is converted to lowercase before searching in md.
func (md MD) Get(k string) []string { func (md MD) Get(k string) []string {
k = strings.ToLower(k) k = strings.ToLower(k)
return md[k] return md[k]
} }
// Set sets the value of a given key with a slice of values. // Set sets the value of a given key with a slice of values.
//
// k is converted to lowercase before storing in md.
func (md MD) Set(k string, vals ...string) { func (md MD) Set(k string, vals ...string) {
if len(vals) == 0 { if len(vals) == 0 {
return return
@ -107,7 +111,10 @@ func (md MD) Set(k string, vals ...string) {
md[k] = vals md[k] = vals
} }
// Append adds the values to key k, not overwriting what was already stored at that key. // Append adds the values to key k, not overwriting what was already stored at
// that key.
//
// k is converted to lowercase before storing in md.
func (md MD) Append(k string, vals ...string) { func (md MD) Append(k string, vals ...string) {
if len(vals) == 0 { if len(vals) == 0 {
return return
@ -116,9 +123,17 @@ func (md MD) Append(k string, vals ...string) {
md[k] = append(md[k], vals...) md[k] = append(md[k], vals...)
} }
// Delete removes the values for a given key k which is converted to lowercase
// before removing it from md.
func (md MD) Delete(k string) {
k = strings.ToLower(k)
delete(md, k)
}
// Join joins any number of mds into a single MD. // Join joins any number of mds into a single MD.
// The order of values for each key is determined by the order in which //
// the mds containing those values are presented to Join. // The order of values for each key is determined by the order in which the mds
// containing those values are presented to Join.
func Join(mds ...MD) MD { func Join(mds ...MD) MD {
out := MD{} out := MD{}
for _, md := range mds { for _, md := range mds {
@ -145,8 +160,8 @@ func NewOutgoingContext(ctx context.Context, md MD) context.Context {
} }
// AppendToOutgoingContext returns a new context with the provided kv merged // AppendToOutgoingContext returns a new context with the provided kv merged
// with any existing metadata in the context. Please refer to the // with any existing metadata in the context. Please refer to the documentation
// documentation of Pairs for a description of kv. // of Pairs for a description of kv.
func AppendToOutgoingContext(ctx context.Context, kv ...string) context.Context { func AppendToOutgoingContext(ctx context.Context, kv ...string) context.Context {
if len(kv)%2 == 1 { if len(kv)%2 == 1 {
panic(fmt.Sprintf("metadata: AppendToOutgoingContext got an odd number of input pairs for metadata: %d", len(kv))) panic(fmt.Sprintf("metadata: AppendToOutgoingContext got an odd number of input pairs for metadata: %d", len(kv)))
@ -159,20 +174,34 @@ func AppendToOutgoingContext(ctx context.Context, kv ...string) context.Context
return context.WithValue(ctx, mdOutgoingKey{}, rawMD{md: md.md, added: added}) return context.WithValue(ctx, mdOutgoingKey{}, rawMD{md: md.md, added: added})
} }
// FromIncomingContext returns the incoming metadata in ctx if it exists. The // FromIncomingContext returns the incoming metadata in ctx if it exists.
// returned MD should not be modified. Writing to it may cause races. //
// Modification should be made to copies of the returned MD. // All keys in the returned MD are lowercase.
func FromIncomingContext(ctx context.Context) (md MD, ok bool) { func FromIncomingContext(ctx context.Context) (MD, bool) {
md, ok = ctx.Value(mdIncomingKey{}).(MD) md, ok := ctx.Value(mdIncomingKey{}).(MD)
return if !ok {
return nil, false
}
out := MD{}
for k, v := range md {
// We need to manually convert all keys to lower case, because MD is a
// map, and there's no guarantee that the MD attached to the context is
// created using our helper functions.
key := strings.ToLower(k)
out[key] = v
}
return out, true
} }
// FromOutgoingContextRaw returns the un-merged, intermediary contents // FromOutgoingContextRaw returns the un-merged, intermediary contents of rawMD.
// of rawMD. Remember to perform strings.ToLower on the keys. The returned
// MD should not be modified. Writing to it may cause races. Modification
// should be made to copies of the returned MD.
// //
// This is intended for gRPC-internal use ONLY. // Remember to perform strings.ToLower on the keys, for both the returned MD (MD
// is a map, there's no guarantee it's created using our helper functions) and
// the extra kv pairs (AppendToOutgoingContext doesn't turn them into
// lowercase).
//
// This is intended for gRPC-internal use ONLY. Users should use
// FromOutgoingContext instead.
func FromOutgoingContextRaw(ctx context.Context) (MD, [][]string, bool) { func FromOutgoingContextRaw(ctx context.Context) (MD, [][]string, bool) {
raw, ok := ctx.Value(mdOutgoingKey{}).(rawMD) raw, ok := ctx.Value(mdOutgoingKey{}).(rawMD)
if !ok { if !ok {
@ -182,16 +211,23 @@ func FromOutgoingContextRaw(ctx context.Context) (MD, [][]string, bool) {
return raw.md, raw.added, true return raw.md, raw.added, true
} }
// FromOutgoingContext returns the outgoing metadata in ctx if it exists. The // FromOutgoingContext returns the outgoing metadata in ctx if it exists.
// returned MD should not be modified. Writing to it may cause races. //
// Modification should be made to copies of the returned MD. // All keys in the returned MD are lowercase.
func FromOutgoingContext(ctx context.Context) (MD, bool) { func FromOutgoingContext(ctx context.Context) (MD, bool) {
raw, ok := ctx.Value(mdOutgoingKey{}).(rawMD) raw, ok := ctx.Value(mdOutgoingKey{}).(rawMD)
if !ok { if !ok {
return nil, false return nil, false
} }
out := raw.md.Copy() out := MD{}
for k, v := range raw.md {
// We need to manually convert all keys to lower case, because MD is a
// map, and there's no guarantee that the MD attached to the context is
// created using our helper functions.
key := strings.ToLower(k)
out[key] = v
}
for _, added := range raw.added { for _, added := range raw.added {
if len(added)%2 == 1 { if len(added)%2 == 1 {
panic(fmt.Sprintf("metadata: FromOutgoingContext got an odd number of input pairs for metadata: %d", len(added))) panic(fmt.Sprintf("metadata: FromOutgoingContext got an odd number of input pairs for metadata: %d", len(added)))

View File

@ -147,7 +147,7 @@ func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer.
logger.Error("subconn returned from pick is not *acBalancerWrapper") logger.Error("subconn returned from pick is not *acBalancerWrapper")
continue continue
} }
if t, ok := acw.getAddrConn().getReadyTransport(); ok { if t := acw.getAddrConn().getReadyTransport(); t != nil {
if channelz.IsOn() { if channelz.IsOn() {
return t, doneChannelzWrapper(acw, pickResult.Done), nil return t, doneChannelzWrapper(acw, pickResult.Done), nil
} }

View File

@ -39,6 +39,8 @@ type ccResolverWrapper struct {
resolver resolver.Resolver resolver resolver.Resolver
done *grpcsync.Event done *grpcsync.Event
curState resolver.State curState resolver.State
incomingMu sync.Mutex // Synchronizes all the incoming calls.
} }
// newCCResolverWrapper uses the resolver.Builder to build a Resolver and // newCCResolverWrapper uses the resolver.Builder to build a Resolver and
@ -90,6 +92,8 @@ func (ccr *ccResolverWrapper) close() {
} }
func (ccr *ccResolverWrapper) UpdateState(s resolver.State) error { func (ccr *ccResolverWrapper) UpdateState(s resolver.State) error {
ccr.incomingMu.Lock()
defer ccr.incomingMu.Unlock()
if ccr.done.HasFired() { if ccr.done.HasFired() {
return nil return nil
} }
@ -105,6 +109,8 @@ func (ccr *ccResolverWrapper) UpdateState(s resolver.State) error {
} }
func (ccr *ccResolverWrapper) ReportError(err error) { func (ccr *ccResolverWrapper) ReportError(err error) {
ccr.incomingMu.Lock()
defer ccr.incomingMu.Unlock()
if ccr.done.HasFired() { if ccr.done.HasFired() {
return return
} }
@ -114,6 +120,8 @@ func (ccr *ccResolverWrapper) ReportError(err error) {
// NewAddress is called by the resolver implementation to send addresses to gRPC. // NewAddress is called by the resolver implementation to send addresses to gRPC.
func (ccr *ccResolverWrapper) NewAddress(addrs []resolver.Address) { func (ccr *ccResolverWrapper) NewAddress(addrs []resolver.Address) {
ccr.incomingMu.Lock()
defer ccr.incomingMu.Unlock()
if ccr.done.HasFired() { if ccr.done.HasFired() {
return return
} }
@ -128,6 +136,8 @@ func (ccr *ccResolverWrapper) NewAddress(addrs []resolver.Address) {
// NewServiceConfig is called by the resolver implementation to send service // NewServiceConfig is called by the resolver implementation to send service
// configs to gRPC. // configs to gRPC.
func (ccr *ccResolverWrapper) NewServiceConfig(sc string) { func (ccr *ccResolverWrapper) NewServiceConfig(sc string) {
ccr.incomingMu.Lock()
defer ccr.incomingMu.Unlock()
if ccr.done.HasFired() { if ccr.done.HasFired() {
return return
} }

View File

@ -258,7 +258,8 @@ func (o PeerCallOption) after(c *callInfo, attempt *csAttempt) {
} }
// WaitForReady configures the action to take when an RPC is attempted on broken // WaitForReady configures the action to take when an RPC is attempted on broken
// connections or unreachable servers. If waitForReady is false, the RPC will fail // connections or unreachable servers. If waitForReady is false and the
// connection is in the TRANSIENT_FAILURE state, the RPC will fail
// immediately. Otherwise, the RPC client will block the call until a // immediately. Otherwise, the RPC client will block the call until a
// connection is available (or the call is canceled or times out) and will // connection is available (or the call is canceled or times out) and will
// retry the call if it fails due to a transient error. gRPC will not retry if // retry the call if it fails due to a transient error. gRPC will not retry if
@ -828,26 +829,28 @@ func Errorf(c codes.Code, format string, a ...interface{}) error {
// toRPCErr converts an error into an error from the status package. // toRPCErr converts an error into an error from the status package.
func toRPCErr(err error) error { func toRPCErr(err error) error {
if err == nil || err == io.EOF {
return err
}
if err == io.ErrUnexpectedEOF {
return status.Error(codes.Internal, err.Error())
}
if _, ok := status.FromError(err); ok {
return err
}
switch e := err.(type) {
case transport.ConnectionError:
return status.Error(codes.Unavailable, e.Desc)
default:
switch err { switch err {
case nil, io.EOF:
return err
case context.DeadlineExceeded: case context.DeadlineExceeded:
return status.Error(codes.DeadlineExceeded, err.Error()) return status.Error(codes.DeadlineExceeded, err.Error())
case context.Canceled: case context.Canceled:
return status.Error(codes.Canceled, err.Error()) return status.Error(codes.Canceled, err.Error())
case io.ErrUnexpectedEOF:
return status.Error(codes.Internal, err.Error())
} }
switch e := err.(type) {
case transport.ConnectionError:
return status.Error(codes.Unavailable, e.Desc)
case *transport.NewStreamError:
return toRPCErr(e.Err)
} }
if _, ok := status.FromError(err); ok {
return err
}
return status.Error(codes.Unknown, err.Error()) return status.Error(codes.Unknown, err.Error())
} }

View File

@ -844,10 +844,16 @@ func (s *Server) handleRawConn(lisAddr string, rawConn net.Conn) {
// ErrConnDispatched means that the connection was dispatched away from // ErrConnDispatched means that the connection was dispatched away from
// gRPC; those connections should be left open. // gRPC; those connections should be left open.
if err != credentials.ErrConnDispatched { if err != credentials.ErrConnDispatched {
// In deployments where a gRPC server runs behind a cloud load
// balancer which performs regular TCP level health checks, the
// connection is closed immediately by the latter. Skipping the
// error here will help reduce log clutter.
if err != io.EOF {
s.mu.Lock() s.mu.Lock()
s.errorf("ServerHandshake(%q) failed: %v", rawConn.RemoteAddr(), err) s.errorf("ServerHandshake(%q) failed: %v", rawConn.RemoteAddr(), err)
s.mu.Unlock() s.mu.Unlock()
channelz.Warningf(logger, s.channelzID, "grpc: Server.Serve failed to complete security handshake from %q: %v", rawConn.RemoteAddr(), err) channelz.Warningf(logger, s.channelzID, "grpc: Server.Serve failed to complete security handshake from %q: %v", rawConn.RemoteAddr(), err)
}
rawConn.Close() rawConn.Close()
} }
rawConn.SetDeadline(time.Time{}) rawConn.SetDeadline(time.Time{})
@ -857,6 +863,7 @@ func (s *Server) handleRawConn(lisAddr string, rawConn net.Conn) {
// Finish handshaking (HTTP2) // Finish handshaking (HTTP2)
st := s.newHTTP2Transport(conn, authInfo) st := s.newHTTP2Transport(conn, authInfo)
if st == nil { if st == nil {
conn.Close()
return return
} }
@ -897,7 +904,7 @@ func (s *Server) newHTTP2Transport(c net.Conn, authInfo credentials.AuthInfo) tr
MaxHeaderListSize: s.opts.maxHeaderListSize, MaxHeaderListSize: s.opts.maxHeaderListSize,
HeaderTableSize: s.opts.headerTableSize, HeaderTableSize: s.opts.headerTableSize,
} }
st, err := transport.NewServerTransport("http2", c, config) st, err := transport.NewServerTransport(c, config)
if err != nil { if err != nil {
s.mu.Lock() s.mu.Lock()
s.errorf("NewServerTransport(%q) failed: %v", c.RemoteAddr(), err) s.errorf("NewServerTransport(%q) failed: %v", c.RemoteAddr(), err)
@ -1109,22 +1116,24 @@ func chainUnaryServerInterceptors(s *Server) {
} else if len(interceptors) == 1 { } else if len(interceptors) == 1 {
chainedInt = interceptors[0] chainedInt = interceptors[0]
} else { } else {
chainedInt = func(ctx context.Context, req interface{}, info *UnaryServerInfo, handler UnaryHandler) (interface{}, error) { chainedInt = chainUnaryInterceptors(interceptors)
return interceptors[0](ctx, req, info, getChainUnaryHandler(interceptors, 0, info, handler))
}
} }
s.opts.unaryInt = chainedInt s.opts.unaryInt = chainedInt
} }
// getChainUnaryHandler recursively generate the chained UnaryHandler func chainUnaryInterceptors(interceptors []UnaryServerInterceptor) UnaryServerInterceptor {
func getChainUnaryHandler(interceptors []UnaryServerInterceptor, curr int, info *UnaryServerInfo, finalHandler UnaryHandler) UnaryHandler { return func(ctx context.Context, req interface{}, info *UnaryServerInfo, handler UnaryHandler) (interface{}, error) {
if curr == len(interceptors)-1 { var i int
return finalHandler var next UnaryHandler
next = func(ctx context.Context, req interface{}) (interface{}, error) {
if i == len(interceptors)-1 {
return interceptors[i](ctx, req, info, handler)
} }
i++
return func(ctx context.Context, req interface{}) (interface{}, error) { return interceptors[i-1](ctx, req, info, next)
return interceptors[curr+1](ctx, req, info, getChainUnaryHandler(interceptors, curr+1, info, finalHandler)) }
return next(ctx, req)
} }
} }
@ -1139,6 +1148,8 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
beginTime := time.Now() beginTime := time.Now()
statsBegin = &stats.Begin{ statsBegin = &stats.Begin{
BeginTime: beginTime, BeginTime: beginTime,
IsClientStream: false,
IsServerStream: false,
} }
sh.HandleRPC(stream.Context(), statsBegin) sh.HandleRPC(stream.Context(), statsBegin)
} }
@ -1390,22 +1401,24 @@ func chainStreamServerInterceptors(s *Server) {
} else if len(interceptors) == 1 { } else if len(interceptors) == 1 {
chainedInt = interceptors[0] chainedInt = interceptors[0]
} else { } else {
chainedInt = func(srv interface{}, ss ServerStream, info *StreamServerInfo, handler StreamHandler) error { chainedInt = chainStreamInterceptors(interceptors)
return interceptors[0](srv, ss, info, getChainStreamHandler(interceptors, 0, info, handler))
}
} }
s.opts.streamInt = chainedInt s.opts.streamInt = chainedInt
} }
// getChainStreamHandler recursively generate the chained StreamHandler func chainStreamInterceptors(interceptors []StreamServerInterceptor) StreamServerInterceptor {
func getChainStreamHandler(interceptors []StreamServerInterceptor, curr int, info *StreamServerInfo, finalHandler StreamHandler) StreamHandler { return func(srv interface{}, ss ServerStream, info *StreamServerInfo, handler StreamHandler) error {
if curr == len(interceptors)-1 { var i int
return finalHandler var next StreamHandler
next = func(srv interface{}, ss ServerStream) error {
if i == len(interceptors)-1 {
return interceptors[i](srv, ss, info, handler)
} }
i++
return func(srv interface{}, ss ServerStream) error { return interceptors[i-1](srv, ss, info, next)
return interceptors[curr+1](srv, ss, info, getChainStreamHandler(interceptors, curr+1, info, finalHandler)) }
return next(srv, ss)
} }
} }
@ -1419,6 +1432,8 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp
beginTime := time.Now() beginTime := time.Now()
statsBegin = &stats.Begin{ statsBegin = &stats.Begin{
BeginTime: beginTime, BeginTime: beginTime,
IsClientStream: sd.ClientStreams,
IsServerStream: sd.ServerStreams,
} }
sh.HandleRPC(stream.Context(), statsBegin) sh.HandleRPC(stream.Context(), statsBegin)
} }
@ -1521,6 +1536,8 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp
} }
} }
ss.ctx = newContextWithRPCInfo(ss.ctx, false, ss.codec, ss.cp, ss.comp)
if trInfo != nil { if trInfo != nil {
trInfo.tr.LazyLog(&trInfo.firstLine, false) trInfo.tr.LazyLog(&trInfo.firstLine, false)
} }
@ -1588,7 +1605,7 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str
trInfo.tr.SetError() trInfo.tr.SetError()
} }
errDesc := fmt.Sprintf("malformed method name: %q", stream.Method()) errDesc := fmt.Sprintf("malformed method name: %q", stream.Method())
if err := t.WriteStatus(stream, status.New(codes.ResourceExhausted, errDesc)); err != nil { if err := t.WriteStatus(stream, status.New(codes.Unimplemented, errDesc)); err != nil {
if trInfo != nil { if trInfo != nil {
trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true) trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true)
trInfo.tr.SetError() trInfo.tr.SetError()

View File

@ -45,6 +45,10 @@ type Begin struct {
BeginTime time.Time BeginTime time.Time
// FailFast indicates if this RPC is failfast. // FailFast indicates if this RPC is failfast.
FailFast bool FailFast bool
// IsClientStream indicates whether the RPC is a client streaming RPC.
IsClientStream bool
// IsServerStream indicates whether the RPC is a server streaming RPC.
IsServerStream bool
} }
// IsClient indicates if the stats information is from client side. // IsClient indicates if the stats information is from client side.

View File

@ -298,6 +298,8 @@ func newClientStreamWithParams(ctx context.Context, desc *StreamDesc, cc *Client
Client: true, Client: true,
BeginTime: beginTime, BeginTime: beginTime,
FailFast: c.failFast, FailFast: c.failFast,
IsClientStream: desc.ClientStreams,
IsServerStream: desc.ServerStreams,
} }
sh.HandleRPC(ctx, begin) sh.HandleRPC(ctx, begin)
} }
@ -419,13 +421,10 @@ func (a *csAttempt) newStream() error {
cs.callHdr.PreviousAttempts = cs.numRetries cs.callHdr.PreviousAttempts = cs.numRetries
s, err := a.t.NewStream(cs.ctx, cs.callHdr) s, err := a.t.NewStream(cs.ctx, cs.callHdr)
if err != nil { if err != nil {
if _, ok := err.(transport.PerformedIOError); ok {
// Return without converting to an RPC error so retry code can // Return without converting to an RPC error so retry code can
// inspect. // inspect.
return err return err
} }
return toRPCErr(err)
}
cs.attempt.s = s cs.attempt.s = s
cs.attempt.p = &parser{r: s} cs.attempt.p = &parser{r: s}
return nil return nil
@ -523,19 +522,28 @@ func (cs *clientStream) commitAttempt() {
// shouldRetry returns nil if the RPC should be retried; otherwise it returns // shouldRetry returns nil if the RPC should be retried; otherwise it returns
// the error that should be returned by the operation. // the error that should be returned by the operation.
func (cs *clientStream) shouldRetry(err error) error { func (cs *clientStream) shouldRetry(err error) error {
unprocessed := false
if cs.attempt.s == nil { if cs.attempt.s == nil {
pioErr, ok := err.(transport.PerformedIOError) // Error from NewClientStream.
if ok { nse, ok := err.(*transport.NewStreamError)
// Unwrap error. if !ok {
err = toRPCErr(pioErr.Err) // Unexpected, but assume no I/O was performed and the RPC is not
} else { // fatal, so retry indefinitely.
unprocessed = true return nil
} }
if !ok && !cs.callInfo.failFast {
// In the event of a non-IO operation error from NewStream, we // Unwrap and convert error.
// never attempted to write anything to the wire, so we can retry err = toRPCErr(nse.Err)
// indefinitely for non-fail-fast RPCs.
// Never retry DoNotRetry errors, which indicate the RPC should not be
// retried due to max header list size violation, etc.
if nse.DoNotRetry {
return err
}
// In the event of a non-IO operation error from NewStream, we never
// attempted to write anything to the wire, so we can retry
// indefinitely.
if !nse.PerformedIO {
return nil return nil
} }
} }
@ -544,6 +552,7 @@ func (cs *clientStream) shouldRetry(err error) error {
return err return err
} }
// Wait for the trailers. // Wait for the trailers.
unprocessed := false
if cs.attempt.s != nil { if cs.attempt.s != nil {
<-cs.attempt.s.Done() <-cs.attempt.s.Done()
unprocessed = cs.attempt.s.Unprocessed() unprocessed = cs.attempt.s.Unprocessed()
@ -632,7 +641,7 @@ func (cs *clientStream) shouldRetry(err error) error {
// Returns nil if a retry was performed and succeeded; error otherwise. // Returns nil if a retry was performed and succeeded; error otherwise.
func (cs *clientStream) retryLocked(lastErr error) error { func (cs *clientStream) retryLocked(lastErr error) error {
for { for {
cs.attempt.finish(lastErr) cs.attempt.finish(toRPCErr(lastErr))
if err := cs.shouldRetry(lastErr); err != nil { if err := cs.shouldRetry(lastErr); err != nil {
cs.commitAttemptLocked() cs.commitAttemptLocked()
return err return err
@ -659,7 +668,11 @@ func (cs *clientStream) withRetry(op func(a *csAttempt) error, onSuccess func())
for { for {
if cs.committed { if cs.committed {
cs.mu.Unlock() cs.mu.Unlock()
return op(cs.attempt) // toRPCErr is used in case the error from the attempt comes from
// NewClientStream, which intentionally doesn't return a status
// error to allow for further inspection; all other errors should
// already be status errors.
return toRPCErr(op(cs.attempt))
} }
a := cs.attempt a := cs.attempt
cs.mu.Unlock() cs.mu.Unlock()

View File

@ -19,4 +19,4 @@
package grpc package grpc
// Version is the current grpc version. // Version is the current grpc version.
const Version = "1.38.0" const Version = "1.40.0"

12
vendor/google.golang.org/grpc/vet.sh generated vendored
View File

@ -32,8 +32,6 @@ PATH="${HOME}/go/bin:${GOROOT}/bin:${PATH}"
go version go version
if [[ "$1" = "-install" ]]; then if [[ "$1" = "-install" ]]; then
# Check for module support
if go help mod >& /dev/null; then
# Install the pinned versions as defined in module tools. # Install the pinned versions as defined in module tools.
pushd ./test/tools pushd ./test/tools
go install \ go install \
@ -42,16 +40,6 @@ if [[ "$1" = "-install" ]]; then
honnef.co/go/tools/cmd/staticcheck \ honnef.co/go/tools/cmd/staticcheck \
github.com/client9/misspell/cmd/misspell github.com/client9/misspell/cmd/misspell
popd popd
else
# Ye olde `go get` incantation.
# Note: this gets the latest version of all tools (vs. the pinned versions
# with Go modules).
go get -u \
golang.org/x/lint/golint \
golang.org/x/tools/cmd/goimports \
honnef.co/go/tools/cmd/staticcheck \
github.com/client9/misspell/cmd/misspell
fi
if [[ -z "${VET_SKIP_PROTO}" ]]; then if [[ -z "${VET_SKIP_PROTO}" ]]; then
if [[ "${TRAVIS}" = "true" ]]; then if [[ "${TRAVIS}" = "true" ]]; then
PROTOBUF_VERSION=3.14.0 PROTOBUF_VERSION=3.14.0

View File

@ -744,9 +744,6 @@ func (d decoder) skipValue() error {
// Skip items. This will not validate whether skipped values are // Skip items. This will not validate whether skipped values are
// of the same type or not, same behavior as C++ // of the same type or not, same behavior as C++
// TextFormat::Parser::AllowUnknownField(true) version 3.8.0. // TextFormat::Parser::AllowUnknownField(true) version 3.8.0.
if err := d.skipValue(); err != nil {
return err
}
} }
} }
} }

View File

@ -263,3 +263,8 @@ func (e *Encoder) Snapshot() encoderState {
func (e *Encoder) Reset(es encoderState) { func (e *Encoder) Reset(es encoderState) {
e.encoderState = es e.encoderState = es
} }
// AppendString appends the escaped form of the input string to b.
func AppendString(b []byte, s string) []byte {
return appendString(b, s, false)
}

View File

@ -440,6 +440,13 @@ func legacyMerge(in piface.MergeInput) piface.MergeOutput {
if !ok { if !ok {
return piface.MergeOutput{} return piface.MergeOutput{}
} }
if !in.Source.IsValid() {
// Legacy Marshal methods may not function on nil messages.
// Check for a typed nil source only after we confirm that
// legacy Marshal/Unmarshal methods are present, for
// consistency.
return piface.MergeOutput{Flags: piface.MergeComplete}
}
b, err := marshaler.Marshal() b, err := marshaler.Marshal()
if err != nil { if err != nil {
return piface.MergeOutput{} return piface.MergeOutput{}

View File

@ -52,8 +52,8 @@ import (
// 10. Send out the CL for review and submit it. // 10. Send out the CL for review and submit it.
const ( const (
Major = 1 Major = 1
Minor = 26 Minor = 27
Patch = 0 Patch = 1
PreRelease = "" PreRelease = ""
) )

View File

@ -94,7 +94,8 @@ type Files struct {
// Note that enum values are in the top-level since that are in the same // Note that enum values are in the top-level since that are in the same
// scope as the parent enum. // scope as the parent enum.
descsByName map[protoreflect.FullName]interface{} descsByName map[protoreflect.FullName]interface{}
filesByPath map[string]protoreflect.FileDescriptor filesByPath map[string][]protoreflect.FileDescriptor
numFiles int
} }
type packageDescriptor struct { type packageDescriptor struct {
@ -117,18 +118,17 @@ func (r *Files) RegisterFile(file protoreflect.FileDescriptor) error {
r.descsByName = map[protoreflect.FullName]interface{}{ r.descsByName = map[protoreflect.FullName]interface{}{
"": &packageDescriptor{}, "": &packageDescriptor{},
} }
r.filesByPath = make(map[string]protoreflect.FileDescriptor) r.filesByPath = make(map[string][]protoreflect.FileDescriptor)
} }
path := file.Path() path := file.Path()
if prev := r.filesByPath[path]; prev != nil { if prev := r.filesByPath[path]; len(prev) > 0 {
r.checkGenProtoConflict(path) r.checkGenProtoConflict(path)
err := errors.New("file %q is already registered", file.Path()) err := errors.New("file %q is already registered", file.Path())
err = amendErrorWithCaller(err, prev, file) err = amendErrorWithCaller(err, prev[0], file)
if r == GlobalFiles && ignoreConflict(file, err) { if !(r == GlobalFiles && ignoreConflict(file, err)) {
err = nil
}
return err return err
} }
}
for name := file.Package(); name != ""; name = name.Parent() { for name := file.Package(); name != ""; name = name.Parent() {
switch prev := r.descsByName[name]; prev.(type) { switch prev := r.descsByName[name]; prev.(type) {
@ -168,7 +168,8 @@ func (r *Files) RegisterFile(file protoreflect.FileDescriptor) error {
rangeTopLevelDescriptors(file, func(d protoreflect.Descriptor) { rangeTopLevelDescriptors(file, func(d protoreflect.Descriptor) {
r.descsByName[d.FullName()] = d r.descsByName[d.FullName()] = d
}) })
r.filesByPath[path] = file r.filesByPath[path] = append(r.filesByPath[path], file)
r.numFiles++
return nil return nil
} }
@ -308,6 +309,7 @@ func (s *nameSuffix) Pop() (name protoreflect.Name) {
// FindFileByPath looks up a file by the path. // FindFileByPath looks up a file by the path.
// //
// This returns (nil, NotFound) if not found. // This returns (nil, NotFound) if not found.
// This returns an error if multiple files have the same path.
func (r *Files) FindFileByPath(path string) (protoreflect.FileDescriptor, error) { func (r *Files) FindFileByPath(path string) (protoreflect.FileDescriptor, error) {
if r == nil { if r == nil {
return nil, NotFound return nil, NotFound
@ -316,13 +318,19 @@ func (r *Files) FindFileByPath(path string) (protoreflect.FileDescriptor, error)
globalMutex.RLock() globalMutex.RLock()
defer globalMutex.RUnlock() defer globalMutex.RUnlock()
} }
if fd, ok := r.filesByPath[path]; ok { fds := r.filesByPath[path]
return fd, nil switch len(fds) {
} case 0:
return nil, NotFound return nil, NotFound
case 1:
return fds[0], nil
default:
return nil, errors.New("multiple files named %q", path)
}
} }
// NumFiles reports the number of registered files. // NumFiles reports the number of registered files,
// including duplicate files with the same name.
func (r *Files) NumFiles() int { func (r *Files) NumFiles() int {
if r == nil { if r == nil {
return 0 return 0
@ -331,10 +339,11 @@ func (r *Files) NumFiles() int {
globalMutex.RLock() globalMutex.RLock()
defer globalMutex.RUnlock() defer globalMutex.RUnlock()
} }
return len(r.filesByPath) return r.numFiles
} }
// RangeFiles iterates over all registered files while f returns true. // RangeFiles iterates over all registered files while f returns true.
// If multiple files have the same name, RangeFiles iterates over all of them.
// The iteration order is undefined. // The iteration order is undefined.
func (r *Files) RangeFiles(f func(protoreflect.FileDescriptor) bool) { func (r *Files) RangeFiles(f func(protoreflect.FileDescriptor) bool) {
if r == nil { if r == nil {
@ -344,11 +353,13 @@ func (r *Files) RangeFiles(f func(protoreflect.FileDescriptor) bool) {
globalMutex.RLock() globalMutex.RLock()
defer globalMutex.RUnlock() defer globalMutex.RUnlock()
} }
for _, file := range r.filesByPath { for _, files := range r.filesByPath {
for _, file := range files {
if !f(file) { if !f(file) {
return return
} }
} }
}
} }
// NumFilesByPackage reports the number of registered files in a proto package. // NumFilesByPackage reports the number of registered files in a proto package.

View File

@ -43,7 +43,6 @@ package descriptorpb
import ( import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoiface "google.golang.org/protobuf/runtime/protoiface"
protoimpl "google.golang.org/protobuf/runtime/protoimpl" protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect" reflect "reflect"
sync "sync" sync "sync"
@ -829,15 +828,6 @@ func (*ExtensionRangeOptions) Descriptor() ([]byte, []int) {
return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{3} return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{3}
} }
var extRange_ExtensionRangeOptions = []protoiface.ExtensionRangeV1{
{Start: 1000, End: 536870911},
}
// Deprecated: Use ExtensionRangeOptions.ProtoReflect.Descriptor.ExtensionRanges instead.
func (*ExtensionRangeOptions) ExtensionRangeArray() []protoiface.ExtensionRangeV1 {
return extRange_ExtensionRangeOptions
}
func (x *ExtensionRangeOptions) GetUninterpretedOption() []*UninterpretedOption { func (x *ExtensionRangeOptions) GetUninterpretedOption() []*UninterpretedOption {
if x != nil { if x != nil {
return x.UninterpretedOption return x.UninterpretedOption
@ -1520,15 +1510,6 @@ func (*FileOptions) Descriptor() ([]byte, []int) {
return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{10} return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{10}
} }
var extRange_FileOptions = []protoiface.ExtensionRangeV1{
{Start: 1000, End: 536870911},
}
// Deprecated: Use FileOptions.ProtoReflect.Descriptor.ExtensionRanges instead.
func (*FileOptions) ExtensionRangeArray() []protoiface.ExtensionRangeV1 {
return extRange_FileOptions
}
func (x *FileOptions) GetJavaPackage() string { func (x *FileOptions) GetJavaPackage() string {
if x != nil && x.JavaPackage != nil { if x != nil && x.JavaPackage != nil {
return *x.JavaPackage return *x.JavaPackage
@ -1776,15 +1757,6 @@ func (*MessageOptions) Descriptor() ([]byte, []int) {
return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{11} return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{11}
} }
var extRange_MessageOptions = []protoiface.ExtensionRangeV1{
{Start: 1000, End: 536870911},
}
// Deprecated: Use MessageOptions.ProtoReflect.Descriptor.ExtensionRanges instead.
func (*MessageOptions) ExtensionRangeArray() []protoiface.ExtensionRangeV1 {
return extRange_MessageOptions
}
func (x *MessageOptions) GetMessageSetWireFormat() bool { func (x *MessageOptions) GetMessageSetWireFormat() bool {
if x != nil && x.MessageSetWireFormat != nil { if x != nil && x.MessageSetWireFormat != nil {
return *x.MessageSetWireFormat return *x.MessageSetWireFormat
@ -1930,15 +1902,6 @@ func (*FieldOptions) Descriptor() ([]byte, []int) {
return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{12} return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{12}
} }
var extRange_FieldOptions = []protoiface.ExtensionRangeV1{
{Start: 1000, End: 536870911},
}
// Deprecated: Use FieldOptions.ProtoReflect.Descriptor.ExtensionRanges instead.
func (*FieldOptions) ExtensionRangeArray() []protoiface.ExtensionRangeV1 {
return extRange_FieldOptions
}
func (x *FieldOptions) GetCtype() FieldOptions_CType { func (x *FieldOptions) GetCtype() FieldOptions_CType {
if x != nil && x.Ctype != nil { if x != nil && x.Ctype != nil {
return *x.Ctype return *x.Ctype
@ -2030,15 +1993,6 @@ func (*OneofOptions) Descriptor() ([]byte, []int) {
return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{13} return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{13}
} }
var extRange_OneofOptions = []protoiface.ExtensionRangeV1{
{Start: 1000, End: 536870911},
}
// Deprecated: Use OneofOptions.ProtoReflect.Descriptor.ExtensionRanges instead.
func (*OneofOptions) ExtensionRangeArray() []protoiface.ExtensionRangeV1 {
return extRange_OneofOptions
}
func (x *OneofOptions) GetUninterpretedOption() []*UninterpretedOption { func (x *OneofOptions) GetUninterpretedOption() []*UninterpretedOption {
if x != nil { if x != nil {
return x.UninterpretedOption return x.UninterpretedOption
@ -2101,15 +2055,6 @@ func (*EnumOptions) Descriptor() ([]byte, []int) {
return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{14} return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{14}
} }
var extRange_EnumOptions = []protoiface.ExtensionRangeV1{
{Start: 1000, End: 536870911},
}
// Deprecated: Use EnumOptions.ProtoReflect.Descriptor.ExtensionRanges instead.
func (*EnumOptions) ExtensionRangeArray() []protoiface.ExtensionRangeV1 {
return extRange_EnumOptions
}
func (x *EnumOptions) GetAllowAlias() bool { func (x *EnumOptions) GetAllowAlias() bool {
if x != nil && x.AllowAlias != nil { if x != nil && x.AllowAlias != nil {
return *x.AllowAlias return *x.AllowAlias
@ -2183,15 +2128,6 @@ func (*EnumValueOptions) Descriptor() ([]byte, []int) {
return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{15} return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{15}
} }
var extRange_EnumValueOptions = []protoiface.ExtensionRangeV1{
{Start: 1000, End: 536870911},
}
// Deprecated: Use EnumValueOptions.ProtoReflect.Descriptor.ExtensionRanges instead.
func (*EnumValueOptions) ExtensionRangeArray() []protoiface.ExtensionRangeV1 {
return extRange_EnumValueOptions
}
func (x *EnumValueOptions) GetDeprecated() bool { func (x *EnumValueOptions) GetDeprecated() bool {
if x != nil && x.Deprecated != nil { if x != nil && x.Deprecated != nil {
return *x.Deprecated return *x.Deprecated
@ -2258,15 +2194,6 @@ func (*ServiceOptions) Descriptor() ([]byte, []int) {
return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{16} return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{16}
} }
var extRange_ServiceOptions = []protoiface.ExtensionRangeV1{
{Start: 1000, End: 536870911},
}
// Deprecated: Use ServiceOptions.ProtoReflect.Descriptor.ExtensionRanges instead.
func (*ServiceOptions) ExtensionRangeArray() []protoiface.ExtensionRangeV1 {
return extRange_ServiceOptions
}
func (x *ServiceOptions) GetDeprecated() bool { func (x *ServiceOptions) GetDeprecated() bool {
if x != nil && x.Deprecated != nil { if x != nil && x.Deprecated != nil {
return *x.Deprecated return *x.Deprecated
@ -2335,15 +2262,6 @@ func (*MethodOptions) Descriptor() ([]byte, []int) {
return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{17} return file_google_protobuf_descriptor_proto_rawDescGZIP(), []int{17}
} }
var extRange_MethodOptions = []protoiface.ExtensionRangeV1{
{Start: 1000, End: 536870911},
}
// Deprecated: Use MethodOptions.ProtoReflect.Descriptor.ExtensionRanges instead.
func (*MethodOptions) ExtensionRangeArray() []protoiface.ExtensionRangeV1 {
return extRange_MethodOptions
}
func (x *MethodOptions) GetDeprecated() bool { func (x *MethodOptions) GetDeprecated() bool {
if x != nil && x.Deprecated != nil { if x != nil && x.Deprecated != nil {
return *x.Deprecated return *x.Deprecated

15
vendor/modules.txt vendored
View File

@ -380,7 +380,7 @@ go.opentelemetry.io/contrib
# go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.21.0 # go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.21.0
## explicit ## explicit
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc
# go.opentelemetry.io/otel v1.0.0-RC1 # go.opentelemetry.io/otel v1.0.0
## explicit ## explicit
go.opentelemetry.io/otel go.opentelemetry.io/otel
go.opentelemetry.io/otel/attribute go.opentelemetry.io/otel/attribute
@ -391,21 +391,22 @@ go.opentelemetry.io/otel/internal/baggage
go.opentelemetry.io/otel/internal/global go.opentelemetry.io/otel/internal/global
go.opentelemetry.io/otel/propagation go.opentelemetry.io/otel/propagation
go.opentelemetry.io/otel/semconv/v1.4.0 go.opentelemetry.io/otel/semconv/v1.4.0
# go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.0-RC1 # go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace go.opentelemetry.io/otel/exporters/otlp/otlptrace
go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/connection go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/connection
go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig
go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/retry
go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform
# go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.0-RC1 # go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.0
## explicit ## explicit
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc
# go.opentelemetry.io/otel/sdk v1.0.0-RC1 # go.opentelemetry.io/otel/sdk v1.0.0
## explicit ## explicit
go.opentelemetry.io/otel/sdk/instrumentation go.opentelemetry.io/otel/sdk/instrumentation
go.opentelemetry.io/otel/sdk/internal go.opentelemetry.io/otel/sdk/internal
go.opentelemetry.io/otel/sdk/resource go.opentelemetry.io/otel/sdk/resource
go.opentelemetry.io/otel/sdk/trace go.opentelemetry.io/otel/sdk/trace
# go.opentelemetry.io/otel/trace v1.0.0-RC1 # go.opentelemetry.io/otel/trace v1.0.0
## explicit ## explicit
go.opentelemetry.io/otel/trace go.opentelemetry.io/otel/trace
# go.opentelemetry.io/proto/otlp v0.9.0 # go.opentelemetry.io/proto/otlp v0.9.0
@ -478,7 +479,7 @@ google.golang.org/genproto/googleapis/api/httpbody
google.golang.org/genproto/googleapis/rpc/errdetails google.golang.org/genproto/googleapis/rpc/errdetails
google.golang.org/genproto/googleapis/rpc/status google.golang.org/genproto/googleapis/rpc/status
google.golang.org/genproto/protobuf/field_mask google.golang.org/genproto/protobuf/field_mask
# google.golang.org/grpc v1.38.0 # google.golang.org/grpc v1.40.0
## explicit ## explicit
google.golang.org/grpc google.golang.org/grpc
google.golang.org/grpc/attributes google.golang.org/grpc/attributes
@ -527,7 +528,7 @@ google.golang.org/grpc/serviceconfig
google.golang.org/grpc/stats google.golang.org/grpc/stats
google.golang.org/grpc/status google.golang.org/grpc/status
google.golang.org/grpc/tap google.golang.org/grpc/tap
# google.golang.org/protobuf v1.26.0 # google.golang.org/protobuf v1.27.1
## explicit ## explicit
google.golang.org/protobuf/encoding/protojson google.golang.org/protobuf/encoding/protojson
google.golang.org/protobuf/encoding/prototext google.golang.org/protobuf/encoding/prototext