mirror of https://github.com/docker/cli.git
Merge pull request #5279 from austinvazquez/vendor-golang.org-updates-to-25.0
[25.0 backport] vendor: golang.org/x/sys v0.18.0, golang.org/x/term v0.18.0, golang.org/x/crypto v0.21.0, golang.org/x/net v0.23.0
This commit is contained in:
commit
0e8f5236d1
22
vendor.mod
22
vendor.mod
|
@ -38,8 +38,8 @@ require (
|
|||
github.com/tonistiigi/go-rosetta v0.0.0-20200727161949-f79598599c5d
|
||||
github.com/xeipuuv/gojsonschema v1.2.0
|
||||
golang.org/x/sync v0.6.0
|
||||
golang.org/x/sys v0.16.0
|
||||
golang.org/x/term v0.15.0
|
||||
golang.org/x/sys v0.18.0
|
||||
golang.org/x/term v0.18.0
|
||||
golang.org/x/text v0.14.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gotest.tools/v3 v3.5.1
|
||||
|
@ -57,12 +57,13 @@ require (
|
|||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect
|
||||
github.com/docker/go-metrics v0.0.1 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/go-logr/logr v1.2.4 // indirect
|
||||
github.com/go-logr/logr v1.3.0 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/gorilla/mux v1.8.1 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/klauspost/compress v1.17.4 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/miekg/pkcs11 v1.1.1 // indirect
|
||||
github.com/moby/sys/symlink v0.2.0 // indirect
|
||||
|
@ -72,16 +73,19 @@ require (
|
|||
github.com/prometheus/common v0.42.0 // indirect
|
||||
github.com/prometheus/procfs v0.9.0 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/rogpeppe/go-internal v1.10.0 // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
go.etcd.io/etcd/raft/v3 v3.5.6 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect
|
||||
go.opentelemetry.io/otel v1.19.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.19.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.19.0 // indirect
|
||||
golang.org/x/crypto v0.17.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect
|
||||
go.opentelemetry.io/otel v1.21.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.21.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.21.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.21.0 // indirect
|
||||
golang.org/x/crypto v0.21.0 // indirect
|
||||
golang.org/x/mod v0.14.0 // indirect
|
||||
golang.org/x/net v0.19.0 // indirect
|
||||
golang.org/x/net v0.23.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
golang.org/x/tools v0.16.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect
|
||||
|
|
49
vendor.sum
49
vendor.sum
|
@ -84,8 +84,8 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2
|
|||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
||||
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
|
||||
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||
|
@ -143,8 +143,9 @@ github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW
|
|||
github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
|
@ -197,6 +198,7 @@ github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/
|
|||
github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8=
|
||||
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
|
@ -227,6 +229,9 @@ github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJf
|
|||
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
|
@ -273,17 +278,19 @@ github.com/zmap/zlint/v3 v3.1.0 h1:WjVytZo79m/L1+/Mlphl09WBob6YTGljN5IGWZFpAv0=
|
|||
go.etcd.io/etcd/client/pkg/v3 v3.5.6/go.mod h1:ggrwbk069qxpKPq8/FKkQ3Xq9y39kbFR4LnKszpRXeQ=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.6 h1:tOmx6Ym6rn2GpZOrvTGJZciJHek6RnC3U/zNInzIN50=
|
||||
go.etcd.io/etcd/raft/v3 v3.5.6/go.mod h1:wL8kkRGx1Hp8FmZUuHfL3K2/OaGIDaXGr1N7i2G07J0=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 h1:x8Z78aZx8cOF0+Kkazoc7lwUNMGy0LrzEMxTm4BbTxg=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0/go.mod h1:62CPTSry9QZtOaSsE3tOzhx6LzDhHnXJ6xHeMNNiM6Q=
|
||||
go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs=
|
||||
go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo=
|
||||
go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc=
|
||||
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg=
|
||||
go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE=
|
||||
go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8=
|
||||
go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o=
|
||||
go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg=
|
||||
go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo=
|
||||
go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4=
|
||||
go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM=
|
||||
go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8=
|
||||
go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
|
||||
go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc=
|
||||
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
|
||||
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
|
@ -295,8 +302,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
|||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
|
||||
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||
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.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
|
||||
|
@ -308,8 +315,8 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL
|
|||
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-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
|
||||
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
|
||||
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
|
||||
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -331,11 +338,11 @@ golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
|
||||
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
|
||||
golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
|
||||
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# A minimal logging API for Go
|
||||
|
||||
[![Go Reference](https://pkg.go.dev/badge/github.com/go-logr/logr.svg)](https://pkg.go.dev/github.com/go-logr/logr)
|
||||
[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/go-logr/logr/badge)](https://securityscorecards.dev/viewer/?platform=github.com&org=go-logr&repo=logr)
|
||||
|
||||
logr offers an(other) opinion on how Go programs and libraries can do logging
|
||||
without becoming coupled to a particular logging implementation. This is not
|
||||
|
@ -73,6 +74,29 @@ received:
|
|||
If the Go standard library had defined an interface for logging, this project
|
||||
probably would not be needed. Alas, here we are.
|
||||
|
||||
When the Go developers started developing such an interface with
|
||||
[slog](https://github.com/golang/go/issues/56345), they adopted some of the
|
||||
logr design but also left out some parts and changed others:
|
||||
|
||||
| Feature | logr | slog |
|
||||
|---------|------|------|
|
||||
| High-level API | `Logger` (passed by value) | `Logger` (passed by [pointer](https://github.com/golang/go/issues/59126)) |
|
||||
| Low-level API | `LogSink` | `Handler` |
|
||||
| Stack unwinding | done by `LogSink` | done by `Logger` |
|
||||
| Skipping helper functions | `WithCallDepth`, `WithCallStackHelper` | [not supported by Logger](https://github.com/golang/go/issues/59145) |
|
||||
| Generating a value for logging on demand | `Marshaler` | `LogValuer` |
|
||||
| Log levels | >= 0, higher meaning "less important" | positive and negative, with 0 for "info" and higher meaning "more important" |
|
||||
| Error log entries | always logged, don't have a verbosity level | normal log entries with level >= `LevelError` |
|
||||
| Passing logger via context | `NewContext`, `FromContext` | no API |
|
||||
| Adding a name to a logger | `WithName` | no API |
|
||||
| Modify verbosity of log entries in a call chain | `V` | no API |
|
||||
| Grouping of key/value pairs | not supported | `WithGroup`, `GroupValue` |
|
||||
|
||||
The high-level slog API is explicitly meant to be one of many different APIs
|
||||
that can be layered on top of a shared `slog.Handler`. logr is one such
|
||||
alternative API, with [interoperability](#slog-interoperability) provided by the [`slogr`](slogr)
|
||||
package.
|
||||
|
||||
### Inspiration
|
||||
|
||||
Before you consider this package, please read [this blog post by the
|
||||
|
@ -118,6 +142,91 @@ There are implementations for the following logging libraries:
|
|||
- **github.com/go-kit/log**: [gokitlogr](https://github.com/tonglil/gokitlogr) (also compatible with github.com/go-kit/kit/log since v0.12.0)
|
||||
- **bytes.Buffer** (writing to a buffer): [bufrlogr](https://github.com/tonglil/buflogr) (useful for ensuring values were logged, like during testing)
|
||||
|
||||
## slog interoperability
|
||||
|
||||
Interoperability goes both ways, using the `logr.Logger` API with a `slog.Handler`
|
||||
and using the `slog.Logger` API with a `logr.LogSink`. [slogr](./slogr) provides `NewLogr` and
|
||||
`NewSlogHandler` API calls to convert between a `logr.Logger` and a `slog.Handler`.
|
||||
As usual, `slog.New` can be used to wrap such a `slog.Handler` in the high-level
|
||||
slog API. `slogr` itself leaves that to the caller.
|
||||
|
||||
## Using a `logr.Sink` as backend for slog
|
||||
|
||||
Ideally, a logr sink implementation should support both logr and slog by
|
||||
implementing both the normal logr interface(s) and `slogr.SlogSink`. Because
|
||||
of a conflict in the parameters of the common `Enabled` method, it is [not
|
||||
possible to implement both slog.Handler and logr.Sink in the same
|
||||
type](https://github.com/golang/go/issues/59110).
|
||||
|
||||
If both are supported, log calls can go from the high-level APIs to the backend
|
||||
without the need to convert parameters. `NewLogr` and `NewSlogHandler` can
|
||||
convert back and forth without adding additional wrappers, with one exception:
|
||||
when `Logger.V` was used to adjust the verbosity for a `slog.Handler`, then
|
||||
`NewSlogHandler` has to use a wrapper which adjusts the verbosity for future
|
||||
log calls.
|
||||
|
||||
Such an implementation should also support values that implement specific
|
||||
interfaces from both packages for logging (`logr.Marshaler`, `slog.LogValuer`,
|
||||
`slog.GroupValue`). logr does not convert those.
|
||||
|
||||
Not supporting slog has several drawbacks:
|
||||
- Recording source code locations works correctly if the handler gets called
|
||||
through `slog.Logger`, but may be wrong in other cases. That's because a
|
||||
`logr.Sink` does its own stack unwinding instead of using the program counter
|
||||
provided by the high-level API.
|
||||
- slog levels <= 0 can be mapped to logr levels by negating the level without a
|
||||
loss of information. But all slog levels > 0 (e.g. `slog.LevelWarning` as
|
||||
used by `slog.Logger.Warn`) must be mapped to 0 before calling the sink
|
||||
because logr does not support "more important than info" levels.
|
||||
- The slog group concept is supported by prefixing each key in a key/value
|
||||
pair with the group names, separated by a dot. For structured output like
|
||||
JSON it would be better to group the key/value pairs inside an object.
|
||||
- Special slog values and interfaces don't work as expected.
|
||||
- The overhead is likely to be higher.
|
||||
|
||||
These drawbacks are severe enough that applications using a mixture of slog and
|
||||
logr should switch to a different backend.
|
||||
|
||||
## Using a `slog.Handler` as backend for logr
|
||||
|
||||
Using a plain `slog.Handler` without support for logr works better than the
|
||||
other direction:
|
||||
- All logr verbosity levels can be mapped 1:1 to their corresponding slog level
|
||||
by negating them.
|
||||
- Stack unwinding is done by the `slogr.SlogSink` and the resulting program
|
||||
counter is passed to the `slog.Handler`.
|
||||
- Names added via `Logger.WithName` are gathered and recorded in an additional
|
||||
attribute with `logger` as key and the names separated by slash as value.
|
||||
- `Logger.Error` is turned into a log record with `slog.LevelError` as level
|
||||
and an additional attribute with `err` as key, if an error was provided.
|
||||
|
||||
The main drawback is that `logr.Marshaler` will not be supported. Types should
|
||||
ideally support both `logr.Marshaler` and `slog.Valuer`. If compatibility
|
||||
with logr implementations without slog support is not important, then
|
||||
`slog.Valuer` is sufficient.
|
||||
|
||||
## Context support for slog
|
||||
|
||||
Storing a logger in a `context.Context` is not supported by
|
||||
slog. `logr.NewContext` and `logr.FromContext` can be used with slog like this
|
||||
to fill this gap:
|
||||
|
||||
func HandlerFromContext(ctx context.Context) slog.Handler {
|
||||
logger, err := logr.FromContext(ctx)
|
||||
if err == nil {
|
||||
return slogr.NewSlogHandler(logger)
|
||||
}
|
||||
return slog.Default().Handler()
|
||||
}
|
||||
|
||||
func ContextWithHandler(ctx context.Context, handler slog.Handler) context.Context {
|
||||
return logr.NewContext(ctx, slogr.NewLogr(handler))
|
||||
}
|
||||
|
||||
The downside is that storing and retrieving a `slog.Handler` needs more
|
||||
allocations compared to using a `logr.Logger`. Therefore the recommendation is
|
||||
to use the `logr.Logger` API in code which uses contextual logging.
|
||||
|
||||
## FAQ
|
||||
|
||||
### Conceptual
|
||||
|
@ -241,7 +350,9 @@ Otherwise, you can start out with `0` as "you always want to see this",
|
|||
|
||||
Then gradually choose levels in between as you need them, working your way
|
||||
down from 10 (for debug and trace style logs) and up from 1 (for chattier
|
||||
info-type logs.)
|
||||
info-type logs). For reference, slog pre-defines -4 for debug logs
|
||||
(corresponds to 4 in logr), which matches what is
|
||||
[recommended for Kubernetes](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/logging.md#what-method-to-use).
|
||||
|
||||
#### How do I choose my keys?
|
||||
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
# Security Policy
|
||||
|
||||
If you have discovered a security vulnerability in this project, please report it
|
||||
privately. **Do not disclose it as a public issue.** This gives us time to work with you
|
||||
to fix the issue before public exposure, reducing the chance that the exploit will be
|
||||
used before a patch is released.
|
||||
|
||||
You may submit the report in the following ways:
|
||||
|
||||
- send an email to go-logr-security@googlegroups.com
|
||||
- send us a [private vulnerability report](https://github.com/go-logr/logr/security/advisories/new)
|
||||
|
||||
Please provide the following information in your report:
|
||||
|
||||
- A description of the vulnerability and its impact
|
||||
- How to reproduce the issue
|
||||
|
||||
We ask that you give us 90 days to work on a fix before public exposure.
|
|
@ -116,17 +116,17 @@ type Options struct {
|
|||
// Equivalent hooks are offered for key-value pairs saved via
|
||||
// logr.Logger.WithValues or Formatter.AddValues (see RenderValuesHook) and
|
||||
// for user-provided pairs (see RenderArgsHook).
|
||||
RenderBuiltinsHook func(kvList []interface{}) []interface{}
|
||||
RenderBuiltinsHook func(kvList []any) []any
|
||||
|
||||
// RenderValuesHook is the same as RenderBuiltinsHook, except that it is
|
||||
// only called for key-value pairs saved via logr.Logger.WithValues. See
|
||||
// RenderBuiltinsHook for more details.
|
||||
RenderValuesHook func(kvList []interface{}) []interface{}
|
||||
RenderValuesHook func(kvList []any) []any
|
||||
|
||||
// RenderArgsHook is the same as RenderBuiltinsHook, except that it is only
|
||||
// called for key-value pairs passed directly to Info and Error. See
|
||||
// RenderBuiltinsHook for more details.
|
||||
RenderArgsHook func(kvList []interface{}) []interface{}
|
||||
RenderArgsHook func(kvList []any) []any
|
||||
|
||||
// MaxLogDepth tells funcr how many levels of nested fields (e.g. a struct
|
||||
// that contains a struct, etc.) it may log. Every time it finds a struct,
|
||||
|
@ -163,7 +163,7 @@ func (l fnlogger) WithName(name string) logr.LogSink {
|
|||
return &l
|
||||
}
|
||||
|
||||
func (l fnlogger) WithValues(kvList ...interface{}) logr.LogSink {
|
||||
func (l fnlogger) WithValues(kvList ...any) logr.LogSink {
|
||||
l.Formatter.AddValues(kvList)
|
||||
return &l
|
||||
}
|
||||
|
@ -173,12 +173,12 @@ func (l fnlogger) WithCallDepth(depth int) logr.LogSink {
|
|||
return &l
|
||||
}
|
||||
|
||||
func (l fnlogger) Info(level int, msg string, kvList ...interface{}) {
|
||||
func (l fnlogger) Info(level int, msg string, kvList ...any) {
|
||||
prefix, args := l.FormatInfo(level, msg, kvList)
|
||||
l.write(prefix, args)
|
||||
}
|
||||
|
||||
func (l fnlogger) Error(err error, msg string, kvList ...interface{}) {
|
||||
func (l fnlogger) Error(err error, msg string, kvList ...any) {
|
||||
prefix, args := l.FormatError(err, msg, kvList)
|
||||
l.write(prefix, args)
|
||||
}
|
||||
|
@ -229,7 +229,7 @@ func newFormatter(opts Options, outfmt outputFormat) Formatter {
|
|||
type Formatter struct {
|
||||
outputFormat outputFormat
|
||||
prefix string
|
||||
values []interface{}
|
||||
values []any
|
||||
valuesStr string
|
||||
depth int
|
||||
opts *Options
|
||||
|
@ -246,10 +246,10 @@ const (
|
|||
)
|
||||
|
||||
// PseudoStruct is a list of key-value pairs that gets logged as a struct.
|
||||
type PseudoStruct []interface{}
|
||||
type PseudoStruct []any
|
||||
|
||||
// render produces a log line, ready to use.
|
||||
func (f Formatter) render(builtins, args []interface{}) string {
|
||||
func (f Formatter) render(builtins, args []any) string {
|
||||
// Empirically bytes.Buffer is faster than strings.Builder for this.
|
||||
buf := bytes.NewBuffer(make([]byte, 0, 1024))
|
||||
if f.outputFormat == outputJSON {
|
||||
|
@ -292,7 +292,7 @@ func (f Formatter) render(builtins, args []interface{}) string {
|
|||
// This function returns a potentially modified version of kvList, which
|
||||
// ensures that there is a value for every key (adding a value if needed) and
|
||||
// that each key is a string (substituting a key if needed).
|
||||
func (f Formatter) flatten(buf *bytes.Buffer, kvList []interface{}, continuing bool, escapeKeys bool) []interface{} {
|
||||
func (f Formatter) flatten(buf *bytes.Buffer, kvList []any, continuing bool, escapeKeys bool) []any {
|
||||
// This logic overlaps with sanitize() but saves one type-cast per key,
|
||||
// which can be measurable.
|
||||
if len(kvList)%2 != 0 {
|
||||
|
@ -334,7 +334,7 @@ func (f Formatter) flatten(buf *bytes.Buffer, kvList []interface{}, continuing b
|
|||
return kvList
|
||||
}
|
||||
|
||||
func (f Formatter) pretty(value interface{}) string {
|
||||
func (f Formatter) pretty(value any) string {
|
||||
return f.prettyWithFlags(value, 0, 0)
|
||||
}
|
||||
|
||||
|
@ -343,7 +343,7 @@ const (
|
|||
)
|
||||
|
||||
// TODO: This is not fast. Most of the overhead goes here.
|
||||
func (f Formatter) prettyWithFlags(value interface{}, flags uint32, depth int) string {
|
||||
func (f Formatter) prettyWithFlags(value any, flags uint32, depth int) string {
|
||||
if depth > f.opts.MaxLogDepth {
|
||||
return `"<max-log-depth-exceeded>"`
|
||||
}
|
||||
|
@ -614,7 +614,7 @@ func isEmpty(v reflect.Value) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
func invokeMarshaler(m logr.Marshaler) (ret interface{}) {
|
||||
func invokeMarshaler(m logr.Marshaler) (ret any) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ret = fmt.Sprintf("<panic: %s>", r)
|
||||
|
@ -675,12 +675,12 @@ func (f Formatter) caller() Caller {
|
|||
|
||||
const noValue = "<no-value>"
|
||||
|
||||
func (f Formatter) nonStringKey(v interface{}) string {
|
||||
func (f Formatter) nonStringKey(v any) string {
|
||||
return fmt.Sprintf("<non-string-key: %s>", f.snippet(v))
|
||||
}
|
||||
|
||||
// snippet produces a short snippet string of an arbitrary value.
|
||||
func (f Formatter) snippet(v interface{}) string {
|
||||
func (f Formatter) snippet(v any) string {
|
||||
const snipLen = 16
|
||||
|
||||
snip := f.pretty(v)
|
||||
|
@ -693,7 +693,7 @@ func (f Formatter) snippet(v interface{}) string {
|
|||
// sanitize ensures that a list of key-value pairs has a value for every key
|
||||
// (adding a value if needed) and that each key is a string (substituting a key
|
||||
// if needed).
|
||||
func (f Formatter) sanitize(kvList []interface{}) []interface{} {
|
||||
func (f Formatter) sanitize(kvList []any) []any {
|
||||
if len(kvList)%2 != 0 {
|
||||
kvList = append(kvList, noValue)
|
||||
}
|
||||
|
@ -727,8 +727,8 @@ func (f Formatter) GetDepth() int {
|
|||
// FormatInfo renders an Info log message into strings. The prefix will be
|
||||
// empty when no names were set (via AddNames), or when the output is
|
||||
// configured for JSON.
|
||||
func (f Formatter) FormatInfo(level int, msg string, kvList []interface{}) (prefix, argsStr string) {
|
||||
args := make([]interface{}, 0, 64) // using a constant here impacts perf
|
||||
func (f Formatter) FormatInfo(level int, msg string, kvList []any) (prefix, argsStr string) {
|
||||
args := make([]any, 0, 64) // using a constant here impacts perf
|
||||
prefix = f.prefix
|
||||
if f.outputFormat == outputJSON {
|
||||
args = append(args, "logger", prefix)
|
||||
|
@ -745,10 +745,10 @@ func (f Formatter) FormatInfo(level int, msg string, kvList []interface{}) (pref
|
|||
}
|
||||
|
||||
// FormatError renders an Error log message into strings. The prefix will be
|
||||
// empty when no names were set (via AddNames), or when the output is
|
||||
// empty when no names were set (via AddNames), or when the output is
|
||||
// configured for JSON.
|
||||
func (f Formatter) FormatError(err error, msg string, kvList []interface{}) (prefix, argsStr string) {
|
||||
args := make([]interface{}, 0, 64) // using a constant here impacts perf
|
||||
func (f Formatter) FormatError(err error, msg string, kvList []any) (prefix, argsStr string) {
|
||||
args := make([]any, 0, 64) // using a constant here impacts perf
|
||||
prefix = f.prefix
|
||||
if f.outputFormat == outputJSON {
|
||||
args = append(args, "logger", prefix)
|
||||
|
@ -761,12 +761,12 @@ func (f Formatter) FormatError(err error, msg string, kvList []interface{}) (pre
|
|||
args = append(args, "caller", f.caller())
|
||||
}
|
||||
args = append(args, "msg", msg)
|
||||
var loggableErr interface{}
|
||||
var loggableErr any
|
||||
if err != nil {
|
||||
loggableErr = err.Error()
|
||||
}
|
||||
args = append(args, "error", loggableErr)
|
||||
return f.prefix, f.render(args, kvList)
|
||||
return prefix, f.render(args, kvList)
|
||||
}
|
||||
|
||||
// AddName appends the specified name. funcr uses '/' characters to separate
|
||||
|
@ -781,7 +781,7 @@ func (f *Formatter) AddName(name string) {
|
|||
|
||||
// AddValues adds key-value pairs to the set of saved values to be logged with
|
||||
// each log line.
|
||||
func (f *Formatter) AddValues(kvList []interface{}) {
|
||||
func (f *Formatter) AddValues(kvList []any) {
|
||||
// Three slice args forces a copy.
|
||||
n := len(f.values)
|
||||
f.values = append(f.values[:n:n], kvList...)
|
||||
|
|
|
@ -127,9 +127,9 @@ limitations under the License.
|
|||
// such a value can call its methods without having to check whether the
|
||||
// instance is ready for use.
|
||||
//
|
||||
// Calling methods with the null logger (Logger{}) as instance will crash
|
||||
// because it has no LogSink. Therefore this null logger should never be passed
|
||||
// around. For cases where passing a logger is optional, a pointer to Logger
|
||||
// The zero logger (= Logger{}) is identical to Discard() and discards all log
|
||||
// entries. Code that receives a Logger by value can simply call it, the methods
|
||||
// will never crash. For cases where passing a logger is optional, a pointer to Logger
|
||||
// should be used.
|
||||
//
|
||||
// # Key Naming Conventions
|
||||
|
@ -258,6 +258,12 @@ type Logger struct {
|
|||
// Enabled tests whether this Logger is enabled. For example, commandline
|
||||
// flags might be used to set the logging verbosity and disable some info logs.
|
||||
func (l Logger) Enabled() bool {
|
||||
// Some implementations of LogSink look at the caller in Enabled (e.g.
|
||||
// different verbosity levels per package or file), but we only pass one
|
||||
// CallDepth in (via Init). This means that all calls from Logger to the
|
||||
// LogSink's Enabled, Info, and Error methods must have the same number of
|
||||
// frames. In other words, Logger methods can't call other Logger methods
|
||||
// which call these LogSink methods unless we do it the same in all paths.
|
||||
return l.sink != nil && l.sink.Enabled(l.level)
|
||||
}
|
||||
|
||||
|
@ -267,11 +273,11 @@ func (l Logger) Enabled() bool {
|
|||
// line. The key/value pairs can then be used to add additional variable
|
||||
// information. The key/value pairs must alternate string keys and arbitrary
|
||||
// values.
|
||||
func (l Logger) Info(msg string, keysAndValues ...interface{}) {
|
||||
func (l Logger) Info(msg string, keysAndValues ...any) {
|
||||
if l.sink == nil {
|
||||
return
|
||||
}
|
||||
if l.Enabled() {
|
||||
if l.sink.Enabled(l.level) { // see comment in Enabled
|
||||
if withHelper, ok := l.sink.(CallStackHelperLogSink); ok {
|
||||
withHelper.GetCallStackHelper()()
|
||||
}
|
||||
|
@ -289,7 +295,7 @@ func (l Logger) Info(msg string, keysAndValues ...interface{}) {
|
|||
// while the err argument should be used to attach the actual error that
|
||||
// triggered this log line, if present. The err parameter is optional
|
||||
// and nil may be passed instead of an error instance.
|
||||
func (l Logger) Error(err error, msg string, keysAndValues ...interface{}) {
|
||||
func (l Logger) Error(err error, msg string, keysAndValues ...any) {
|
||||
if l.sink == nil {
|
||||
return
|
||||
}
|
||||
|
@ -314,9 +320,16 @@ func (l Logger) V(level int) Logger {
|
|||
return l
|
||||
}
|
||||
|
||||
// GetV returns the verbosity level of the logger. If the logger's LogSink is
|
||||
// nil as in the Discard logger, this will always return 0.
|
||||
func (l Logger) GetV() int {
|
||||
// 0 if l.sink nil because of the if check in V above.
|
||||
return l.level
|
||||
}
|
||||
|
||||
// WithValues returns a new Logger instance with additional key/value pairs.
|
||||
// See Info for documentation on how key/value pairs work.
|
||||
func (l Logger) WithValues(keysAndValues ...interface{}) Logger {
|
||||
func (l Logger) WithValues(keysAndValues ...any) Logger {
|
||||
if l.sink == nil {
|
||||
return l
|
||||
}
|
||||
|
@ -467,15 +480,15 @@ type LogSink interface {
|
|||
// The level argument is provided for optional logging. This method will
|
||||
// only be called when Enabled(level) is true. See Logger.Info for more
|
||||
// details.
|
||||
Info(level int, msg string, keysAndValues ...interface{})
|
||||
Info(level int, msg string, keysAndValues ...any)
|
||||
|
||||
// Error logs an error, with the given message and key/value pairs as
|
||||
// context. See Logger.Error for more details.
|
||||
Error(err error, msg string, keysAndValues ...interface{})
|
||||
Error(err error, msg string, keysAndValues ...any)
|
||||
|
||||
// WithValues returns a new LogSink with additional key/value pairs. See
|
||||
// Logger.WithValues for more details.
|
||||
WithValues(keysAndValues ...interface{}) LogSink
|
||||
WithValues(keysAndValues ...any) LogSink
|
||||
|
||||
// WithName returns a new LogSink with the specified name appended. See
|
||||
// Logger.WithName for more details.
|
||||
|
@ -546,5 +559,5 @@ type Marshaler interface {
|
|||
// with exported fields
|
||||
//
|
||||
// It may return any value of any type.
|
||||
MarshalLog() interface{}
|
||||
MarshalLog() any
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ const (
|
|||
RequestCount = "http.server.request_count" // Incoming request count total
|
||||
RequestContentLength = "http.server.request_content_length" // Incoming request bytes total
|
||||
ResponseContentLength = "http.server.response_content_length" // Incoming response bytes total
|
||||
ServerLatency = "http.server.duration" // Incoming end to end duration, microseconds
|
||||
ServerLatency = "http.server.duration" // Incoming end to end duration, milliseconds
|
||||
)
|
||||
|
||||
// Filter is a predicate used to determine whether a given http.request should
|
||||
|
@ -42,5 +42,5 @@ const (
|
|||
type Filter func(*http.Request) bool
|
||||
|
||||
func newTracer(tp trace.TracerProvider) trace.Tracer {
|
||||
return tp.Tracer(instrumentationName, trace.WithInstrumentationVersion(Version()))
|
||||
return tp.Tracer(ScopeName, trace.WithInstrumentationVersion(Version()))
|
||||
}
|
||||
|
|
|
@ -25,9 +25,8 @@ import (
|
|||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
const (
|
||||
instrumentationName = "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
)
|
||||
// ScopeName is the instrumentation scope name.
|
||||
const ScopeName = "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
|
||||
// config represents the configuration options available for the http.Handler
|
||||
// and http.Transport types.
|
||||
|
@ -76,7 +75,7 @@ func newConfig(opts ...Option) *config {
|
|||
}
|
||||
|
||||
c.Meter = c.MeterProvider.Meter(
|
||||
instrumentationName,
|
||||
ScopeName,
|
||||
metric.WithInstrumentationVersion(Version()),
|
||||
)
|
||||
|
||||
|
|
18
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go
generated
vendored
18
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/handler.go
generated
vendored
|
@ -107,13 +107,25 @@ func (h *middleware) createMeasures() {
|
|||
h.counters = make(map[string]metric.Int64Counter)
|
||||
h.valueRecorders = make(map[string]metric.Float64Histogram)
|
||||
|
||||
requestBytesCounter, err := h.meter.Int64Counter(RequestContentLength)
|
||||
requestBytesCounter, err := h.meter.Int64Counter(
|
||||
RequestContentLength,
|
||||
metric.WithUnit("By"),
|
||||
metric.WithDescription("Measures the size of HTTP request content length (uncompressed)"),
|
||||
)
|
||||
handleErr(err)
|
||||
|
||||
responseBytesCounter, err := h.meter.Int64Counter(ResponseContentLength)
|
||||
responseBytesCounter, err := h.meter.Int64Counter(
|
||||
ResponseContentLength,
|
||||
metric.WithUnit("By"),
|
||||
metric.WithDescription("Measures the size of HTTP response content length (uncompressed)"),
|
||||
)
|
||||
handleErr(err)
|
||||
|
||||
serverLatencyMeasure, err := h.meter.Float64Histogram(ServerLatency)
|
||||
serverLatencyMeasure, err := h.meter.Float64Histogram(
|
||||
ServerLatency,
|
||||
metric.WithUnit("ms"),
|
||||
metric.WithDescription("Measures the duration of HTTP request handling"),
|
||||
)
|
||||
handleErr(err)
|
||||
|
||||
h.counters[RequestContentLength] = requestBytesCounter
|
||||
|
|
2
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go
generated
vendored
2
vendor/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/version.go
generated
vendored
|
@ -16,7 +16,7 @@ package otelhttp // import "go.opentelemetry.io/contrib/instrumentation/net/http
|
|||
|
||||
// Version is the current release version of the otelhttp instrumentation.
|
||||
func Version() string {
|
||||
return "0.45.0"
|
||||
return "0.46.1"
|
||||
// This string is updated by the pre_release.sh script during release
|
||||
}
|
||||
|
||||
|
|
|
@ -14,12 +14,9 @@ go.work.sum
|
|||
gen/
|
||||
|
||||
/example/dice/dice
|
||||
/example/fib/fib
|
||||
/example/fib/traces.txt
|
||||
/example/jaeger/jaeger
|
||||
/example/namedtracer/namedtracer
|
||||
/example/otel-collector/otel-collector
|
||||
/example/opencensus/opencensus
|
||||
/example/passthrough/passthrough
|
||||
/example/prometheus/prometheus
|
||||
/example/zipkin/zipkin
|
||||
/example/otel-collector/otel-collector
|
||||
|
|
|
@ -12,8 +12,9 @@ linters:
|
|||
- depguard
|
||||
- errcheck
|
||||
- godot
|
||||
- gofmt
|
||||
- gofumpt
|
||||
- goimports
|
||||
- gosec
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
|
@ -53,6 +54,20 @@ issues:
|
|||
text: "calls to (.+) only in main[(][)] or init[(][)] functions"
|
||||
linters:
|
||||
- revive
|
||||
# It's okay to not run gosec in a test.
|
||||
- path: _test\.go
|
||||
linters:
|
||||
- gosec
|
||||
# Igonoring gosec G404: Use of weak random number generator (math/rand instead of crypto/rand)
|
||||
# as we commonly use it in tests and examples.
|
||||
- text: "G404:"
|
||||
linters:
|
||||
- gosec
|
||||
# Igonoring gosec G402: TLS MinVersion too low
|
||||
# as the https://pkg.go.dev/crypto/tls#Config handles MinVersion default well.
|
||||
- text: "G402: TLS MinVersion too low."
|
||||
linters:
|
||||
- gosec
|
||||
include:
|
||||
# revive exported should have comment or be unexported.
|
||||
- EXC0012
|
||||
|
|
|
@ -8,6 +8,85 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
## [1.21.0/0.44.0] 2023-11-16
|
||||
|
||||
### Removed
|
||||
|
||||
- Remove the deprecated `go.opentelemetry.io/otel/bridge/opencensus.NewTracer`. (#4706)
|
||||
- Remove the deprecated `go.opentelemetry.io/otel/exporters/otlp/otlpmetric` module. (#4707)
|
||||
- Remove the deprecated `go.opentelemetry.io/otel/example/view` module. (#4708)
|
||||
- Remove the deprecated `go.opentelemetry.io/otel/example/fib` module. (#4723)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Do not parse non-protobuf responses in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#4719)
|
||||
- Do not parse non-protobuf responses in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#4719)
|
||||
|
||||
## [1.20.0/0.43.0] 2023-11-10
|
||||
|
||||
This release brings a breaking change for custom trace API implementations. Some interfaces (`TracerProvider`, `Tracer`, `Span`) now embed the `go.opentelemetry.io/otel/trace/embedded` types. Implementors need to update their implementations based on what they want the default behavior to be. See the "API Implementations" section of the [trace API] package documentation for more information about how to accomplish this.
|
||||
|
||||
### Added
|
||||
|
||||
- Add `go.opentelemetry.io/otel/bridge/opencensus.InstallTraceBridge`, which installs the OpenCensus trace bridge, and replaces `opencensus.NewTracer`. (#4567)
|
||||
- Add scope version to trace and metric bridges in `go.opentelemetry.io/otel/bridge/opencensus`. (#4584)
|
||||
- Add the `go.opentelemetry.io/otel/trace/embedded` package to be embedded in the exported trace API interfaces. (#4620)
|
||||
- Add the `go.opentelemetry.io/otel/trace/noop` package as a default no-op implementation of the trace API. (#4620)
|
||||
- Add context propagation in `go.opentelemetry.io/otel/example/dice`. (#4644)
|
||||
- Add view configuration to `go.opentelemetry.io/otel/example/prometheus`. (#4649)
|
||||
- Add `go.opentelemetry.io/otel/metric.WithExplicitBucketBoundaries`, which allows defining default explicit bucket boundaries when creating histogram instruments. (#4603)
|
||||
- Add `Version` function in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. (#4660)
|
||||
- Add `Version` function in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#4660)
|
||||
- Add Summary, SummaryDataPoint, and QuantileValue to `go.opentelemetry.io/sdk/metric/metricdata`. (#4622)
|
||||
- `go.opentelemetry.io/otel/bridge/opencensus.NewMetricProducer` now supports exemplars from OpenCensus. (#4585)
|
||||
- Add support for `WithExplicitBucketBoundaries` in `go.opentelemetry.io/otel/sdk/metric`. (#4605)
|
||||
- Add support for Summary metrics in `go.opentelemetry.io/otel/bridge/opencensus`. (#4668)
|
||||
|
||||
### Deprecated
|
||||
|
||||
- Deprecate `go.opentelemetry.io/otel/bridge/opencensus.NewTracer` in favor of `opencensus.InstallTraceBridge`. (#4567)
|
||||
- Deprecate `go.opentelemetry.io/otel/example/fib` package is in favor of `go.opentelemetry.io/otel/example/dice`. (#4618)
|
||||
- Deprecate `go.opentelemetry.io/otel/trace.NewNoopTracerProvider`.
|
||||
Use the added `NewTracerProvider` function in `go.opentelemetry.io/otel/trace/noop` instead. (#4620)
|
||||
- Deprecate `go.opentelemetry.io/otel/example/view` package in favor of `go.opentelemetry.io/otel/example/prometheus`. (#4649)
|
||||
- Deprecate `go.opentelemetry.io/otel/exporters/otlp/otlpmetric`. (#4693)
|
||||
|
||||
### Changed
|
||||
|
||||
- `go.opentelemetry.io/otel/bridge/opencensus.NewMetricProducer` returns a `*MetricProducer` struct instead of the metric.Producer interface. (#4583)
|
||||
- The `TracerProvider` in `go.opentelemetry.io/otel/trace` now embeds the `go.opentelemetry.io/otel/trace/embedded.TracerProvider` type.
|
||||
This extends the `TracerProvider` interface and is is a breaking change for any existing implementation.
|
||||
Implementors need to update their implementations based on what they want the default behavior of the interface to be.
|
||||
See the "API Implementations" section of the `go.opentelemetry.io/otel/trace` package documentation for more information about how to accomplish this. (#4620)
|
||||
- The `Tracer` in `go.opentelemetry.io/otel/trace` now embeds the `go.opentelemetry.io/otel/trace/embedded.Tracer` type.
|
||||
This extends the `Tracer` interface and is is a breaking change for any existing implementation.
|
||||
Implementors need to update their implementations based on what they want the default behavior of the interface to be.
|
||||
See the "API Implementations" section of the `go.opentelemetry.io/otel/trace` package documentation for more information about how to accomplish this. (#4620)
|
||||
- The `Span` in `go.opentelemetry.io/otel/trace` now embeds the `go.opentelemetry.io/otel/trace/embedded.Span` type.
|
||||
This extends the `Span` interface and is is a breaking change for any existing implementation.
|
||||
Implementors need to update their implementations based on what they want the default behavior of the interface to be.
|
||||
See the "API Implementations" section of the `go.opentelemetry.io/otel/trace` package documentation for more information about how to accomplish this. (#4620)
|
||||
- `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` does no longer depend on `go.opentelemetry.io/otel/exporters/otlp/otlpmetric`. (#4660)
|
||||
- `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` does no longer depend on `go.opentelemetry.io/otel/exporters/otlp/otlpmetric`. (#4660)
|
||||
- Retry for `502 Bad Gateway` and `504 Gateway Timeout` HTTP statuses in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#4670)
|
||||
- Retry for `502 Bad Gateway` and `504 Gateway Timeout` HTTP statuses in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#4670)
|
||||
- Retry for `RESOURCE_EXHAUSTED` only if RetryInfo is returned in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. (#4669)
|
||||
- Retry for `RESOURCE_EXHAUSTED` only if RetryInfo is returned in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`. (#4669)
|
||||
- Retry temporary HTTP request failures in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp`. (#4679)
|
||||
- Retry temporary HTTP request failures in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp`. (#4679)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix improper parsing of characters such us `+`, `/` by `Parse` in `go.opentelemetry.io/otel/baggage` as they were rendered as a whitespace. (#4667)
|
||||
- Fix improper parsing of characters such us `+`, `/` passed via `OTEL_RESOURCE_ATTRIBUTES` in `go.opentelemetry.io/otel/sdk/resource` as they were rendered as a whitespace. (#4699)
|
||||
- Fix improper parsing of characters such us `+`, `/` passed via `OTEL_EXPORTER_OTLP_HEADERS` and `OTEL_EXPORTER_OTLP_METRICS_HEADERS` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` as they were rendered as a whitespace. (#4699)
|
||||
- Fix improper parsing of characters such us `+`, `/` passed via `OTEL_EXPORTER_OTLP_HEADERS` and `OTEL_EXPORTER_OTLP_METRICS_HEADERS` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp` as they were rendered as a whitespace. (#4699)
|
||||
- Fix improper parsing of characters such us `+`, `/` passed via `OTEL_EXPORTER_OTLP_HEADERS` and `OTEL_EXPORTER_OTLP_TRACES_HEADERS` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlptracegrpc` as they were rendered as a whitespace. (#4699)
|
||||
- Fix improper parsing of characters such us `+`, `/` passed via `OTEL_EXPORTER_OTLP_HEADERS` and `OTEL_EXPORTER_OTLP_TRACES_HEADERS` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlptracehttp` as they were rendered as a whitespace. (#4699)
|
||||
- In `go.opentelemetry.op/otel/exporters/prometheus`, the exporter no longer `Collect`s metrics after `Shutdown` is invoked. (#4648)
|
||||
- Fix documentation for `WithCompressor` in `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc`. (#4695)
|
||||
- Fix documentation for `WithCompressor` in `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc`. (#4695)
|
||||
|
||||
## [1.19.0/0.42.0/0.0.7] 2023-09-28
|
||||
|
||||
This release contains the first stable release of the OpenTelemetry Go [metric SDK].
|
||||
|
@ -2656,7 +2735,9 @@ It contains api and sdk for trace and meter.
|
|||
- CircleCI build CI manifest files.
|
||||
- CODEOWNERS file to track owners of this project.
|
||||
|
||||
[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.19.0...HEAD
|
||||
[Unreleased]: https://github.com/open-telemetry/opentelemetry-go/compare/v1.21.0...HEAD
|
||||
[1.21.0/0.44.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.21.0
|
||||
[1.20.0/0.43.0]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.20.0
|
||||
[1.19.0/0.42.0/0.0.7]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.19.0
|
||||
[1.19.0-rc.1/0.42.0-rc.1]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.19.0-rc.1
|
||||
[1.18.0/0.41.0/0.0.6]: https://github.com/open-telemetry/opentelemetry-go/releases/tag/v1.18.0
|
||||
|
@ -2731,7 +2812,7 @@ It contains api and sdk for trace and meter.
|
|||
[Go 1.20]: https://go.dev/doc/go1.20
|
||||
[Go 1.19]: https://go.dev/doc/go1.19
|
||||
[Go 1.18]: https://go.dev/doc/go1.18
|
||||
[Go 1.19]: https://go.dev/doc/go1.19
|
||||
|
||||
[metric API]:https://pkg.go.dev/go.opentelemetry.io/otel/metric
|
||||
[metric SDK]:https://pkg.go.dev/go.opentelemetry.io/otel/sdk/metric
|
||||
[trace API]:https://pkg.go.dev/go.opentelemetry.io/otel/trace
|
||||
|
|
|
@ -90,6 +90,10 @@ git push <YOUR_FORK> <YOUR_BRANCH_NAME>
|
|||
Open a pull request against the main `opentelemetry-go` repo. Be sure to add the pull
|
||||
request ID to the entry you added to `CHANGELOG.md`.
|
||||
|
||||
Avoid rebasing and force-pushing to your branch to facilitate reviewing the pull request.
|
||||
Rewriting Git history makes it difficult to keep track of iterations during code review.
|
||||
All pull requests are squashed to a single commit upon merge to `main`.
|
||||
|
||||
### How to Receive Comments
|
||||
|
||||
* If the PR is not ready for review, please put `[WIP]` in the title,
|
||||
|
|
|
@ -77,6 +77,9 @@ $(GOTMPL): PACKAGE=go.opentelemetry.io/build-tools/gotmpl
|
|||
GORELEASE = $(TOOLS)/gorelease
|
||||
$(GORELEASE): PACKAGE=golang.org/x/exp/cmd/gorelease
|
||||
|
||||
GOVULNCHECK = $(TOOLS)/govulncheck
|
||||
$(TOOLS)/govulncheck: PACKAGE=golang.org/x/vuln/cmd/govulncheck
|
||||
|
||||
.PHONY: tools
|
||||
tools: $(CROSSLINK) $(DBOTCONF) $(GOLANGCI_LINT) $(MISSPELL) $(GOCOVMERGE) $(STRINGER) $(PORTO) $(GOJQ) $(SEMCONVGEN) $(MULTIMOD) $(SEMCONVKIT) $(GOTMPL) $(GORELEASE)
|
||||
|
||||
|
@ -189,6 +192,18 @@ test-coverage: | $(GOCOVMERGE)
|
|||
done; \
|
||||
$(GOCOVMERGE) $$(find . -name coverage.out) > coverage.txt
|
||||
|
||||
# Adding a directory will include all benchmarks in that direcotry if a filter is not specified.
|
||||
BENCHMARK_TARGETS := sdk/trace
|
||||
.PHONY: benchmark
|
||||
benchmark: $(BENCHMARK_TARGETS:%=benchmark/%)
|
||||
BENCHMARK_FILTER = .
|
||||
# You can override the filter for a particular directory by adding a rule here.
|
||||
benchmark/sdk/trace: BENCHMARK_FILTER = SpanWithAttributes_8/AlwaysSample
|
||||
benchmark/%:
|
||||
@echo "$(GO) test -timeout $(TIMEOUT)s -run=xxxxxMatchNothingxxxxx -bench=$(BENCHMARK_FILTER) $*..." \
|
||||
&& cd $* \
|
||||
$(foreach filter, $(BENCHMARK_FILTER), && $(GO) test -timeout $(TIMEOUT)s -run=xxxxxMatchNothingxxxxx -bench=$(filter))
|
||||
|
||||
.PHONY: golangci-lint golangci-lint-fix
|
||||
golangci-lint-fix: ARGS=--fix
|
||||
golangci-lint-fix: golangci-lint
|
||||
|
@ -216,7 +231,7 @@ go-mod-tidy/%: | crosslink
|
|||
lint-modules: go-mod-tidy
|
||||
|
||||
.PHONY: lint
|
||||
lint: misspell lint-modules golangci-lint
|
||||
lint: misspell lint-modules golangci-lint govulncheck
|
||||
|
||||
.PHONY: vanity-import-check
|
||||
vanity-import-check: | $(PORTO)
|
||||
|
@ -226,6 +241,14 @@ vanity-import-check: | $(PORTO)
|
|||
misspell: | $(MISSPELL)
|
||||
@$(MISSPELL) -w $(ALL_DOCS)
|
||||
|
||||
.PHONY: govulncheck
|
||||
govulncheck: $(OTEL_GO_MOD_DIRS:%=govulncheck/%)
|
||||
govulncheck/%: DIR=$*
|
||||
govulncheck/%: | $(GOVULNCHECK)
|
||||
@echo "govulncheck ./... in $(DIR)" \
|
||||
&& cd $(DIR) \
|
||||
&& $(GOVULNCHECK) ./...
|
||||
|
||||
.PHONY: codespell
|
||||
codespell: | $(CODESPELL)
|
||||
@$(DOCKERPY) $(CODESPELL)
|
||||
|
@ -289,3 +312,7 @@ COMMIT ?= "HEAD"
|
|||
add-tags: | $(MULTIMOD)
|
||||
@[ "${MODSET}" ] || ( echo ">> env var MODSET is not set"; exit 1 )
|
||||
$(MULTIMOD) verify && $(MULTIMOD) tag -m ${MODSET} -c ${COMMIT}
|
||||
|
||||
.PHONY: lint-markdown
|
||||
lint-markdown:
|
||||
docker run -v "$(CURDIR):$(WORKDIR)" docker://avtodev/markdown-lint:v1 -c $(WORKDIR)/.markdownlint.yaml $(WORKDIR)/**/*.md
|
||||
|
|
|
@ -11,16 +11,13 @@ It provides a set of APIs to directly measure performance and behavior of your s
|
|||
|
||||
## Project Status
|
||||
|
||||
| Signal | Status | Project |
|
||||
|---------|------------|-----------------------|
|
||||
| Traces | Stable | N/A |
|
||||
| Metrics | Mixed [1] | [Go: Metric SDK (GA)] |
|
||||
| Logs | Frozen [2] | N/A |
|
||||
| Signal | Status |
|
||||
|---------|------------|
|
||||
| Traces | Stable |
|
||||
| Metrics | Stable |
|
||||
| Logs | Design [1] |
|
||||
|
||||
[Go: Metric SDK (GA)]: https://github.com/orgs/open-telemetry/projects/34
|
||||
|
||||
- [1]: [Metrics API](https://pkg.go.dev/go.opentelemetry.io/otel/metric) is Stable. [Metrics SDK](https://pkg.go.dev/go.opentelemetry.io/otel/sdk/metric) is Beta.
|
||||
- [2]: The Logs signal development is halted for this project while we stabilize the Metrics SDK.
|
||||
- [1]: Currently the logs signal development is in a design phase ([#4696](https://github.com/open-telemetry/opentelemetry-go/issues/4696)).
|
||||
No Logs Pull Requests are currently being accepted.
|
||||
|
||||
Progress and status specific to this repository is tracked in our
|
||||
|
|
|
@ -254,7 +254,7 @@ func NewMember(key, value string, props ...Property) (Member, error) {
|
|||
if err := m.validate(); err != nil {
|
||||
return newInvalidMember(), err
|
||||
}
|
||||
decodedValue, err := url.QueryUnescape(value)
|
||||
decodedValue, err := url.PathUnescape(value)
|
||||
if err != nil {
|
||||
return newInvalidMember(), fmt.Errorf("%w: %q", errInvalidValue, value)
|
||||
}
|
||||
|
@ -301,7 +301,7 @@ func parseMember(member string) (Member, error) {
|
|||
// when converting the header into a data structure."
|
||||
key = strings.TrimSpace(k)
|
||||
var err error
|
||||
value, err = url.QueryUnescape(strings.TrimSpace(v))
|
||||
value, err = url.PathUnescape(strings.TrimSpace(v))
|
||||
if err != nil {
|
||||
return newInvalidMember(), fmt.Errorf("%w: %q", err, value)
|
||||
}
|
||||
|
|
|
@ -34,11 +34,13 @@ type afCounter struct {
|
|||
name string
|
||||
opts []metric.Float64ObservableCounterOption
|
||||
|
||||
delegate atomic.Value //metric.Float64ObservableCounter
|
||||
delegate atomic.Value // metric.Float64ObservableCounter
|
||||
}
|
||||
|
||||
var _ unwrapper = (*afCounter)(nil)
|
||||
var _ metric.Float64ObservableCounter = (*afCounter)(nil)
|
||||
var (
|
||||
_ unwrapper = (*afCounter)(nil)
|
||||
_ metric.Float64ObservableCounter = (*afCounter)(nil)
|
||||
)
|
||||
|
||||
func (i *afCounter) setDelegate(m metric.Meter) {
|
||||
ctr, err := m.Float64ObservableCounter(i.name, i.opts...)
|
||||
|
@ -63,11 +65,13 @@ type afUpDownCounter struct {
|
|||
name string
|
||||
opts []metric.Float64ObservableUpDownCounterOption
|
||||
|
||||
delegate atomic.Value //metric.Float64ObservableUpDownCounter
|
||||
delegate atomic.Value // metric.Float64ObservableUpDownCounter
|
||||
}
|
||||
|
||||
var _ unwrapper = (*afUpDownCounter)(nil)
|
||||
var _ metric.Float64ObservableUpDownCounter = (*afUpDownCounter)(nil)
|
||||
var (
|
||||
_ unwrapper = (*afUpDownCounter)(nil)
|
||||
_ metric.Float64ObservableUpDownCounter = (*afUpDownCounter)(nil)
|
||||
)
|
||||
|
||||
func (i *afUpDownCounter) setDelegate(m metric.Meter) {
|
||||
ctr, err := m.Float64ObservableUpDownCounter(i.name, i.opts...)
|
||||
|
@ -92,11 +96,13 @@ type afGauge struct {
|
|||
name string
|
||||
opts []metric.Float64ObservableGaugeOption
|
||||
|
||||
delegate atomic.Value //metric.Float64ObservableGauge
|
||||
delegate atomic.Value // metric.Float64ObservableGauge
|
||||
}
|
||||
|
||||
var _ unwrapper = (*afGauge)(nil)
|
||||
var _ metric.Float64ObservableGauge = (*afGauge)(nil)
|
||||
var (
|
||||
_ unwrapper = (*afGauge)(nil)
|
||||
_ metric.Float64ObservableGauge = (*afGauge)(nil)
|
||||
)
|
||||
|
||||
func (i *afGauge) setDelegate(m metric.Meter) {
|
||||
ctr, err := m.Float64ObservableGauge(i.name, i.opts...)
|
||||
|
@ -121,11 +127,13 @@ type aiCounter struct {
|
|||
name string
|
||||
opts []metric.Int64ObservableCounterOption
|
||||
|
||||
delegate atomic.Value //metric.Int64ObservableCounter
|
||||
delegate atomic.Value // metric.Int64ObservableCounter
|
||||
}
|
||||
|
||||
var _ unwrapper = (*aiCounter)(nil)
|
||||
var _ metric.Int64ObservableCounter = (*aiCounter)(nil)
|
||||
var (
|
||||
_ unwrapper = (*aiCounter)(nil)
|
||||
_ metric.Int64ObservableCounter = (*aiCounter)(nil)
|
||||
)
|
||||
|
||||
func (i *aiCounter) setDelegate(m metric.Meter) {
|
||||
ctr, err := m.Int64ObservableCounter(i.name, i.opts...)
|
||||
|
@ -150,11 +158,13 @@ type aiUpDownCounter struct {
|
|||
name string
|
||||
opts []metric.Int64ObservableUpDownCounterOption
|
||||
|
||||
delegate atomic.Value //metric.Int64ObservableUpDownCounter
|
||||
delegate atomic.Value // metric.Int64ObservableUpDownCounter
|
||||
}
|
||||
|
||||
var _ unwrapper = (*aiUpDownCounter)(nil)
|
||||
var _ metric.Int64ObservableUpDownCounter = (*aiUpDownCounter)(nil)
|
||||
var (
|
||||
_ unwrapper = (*aiUpDownCounter)(nil)
|
||||
_ metric.Int64ObservableUpDownCounter = (*aiUpDownCounter)(nil)
|
||||
)
|
||||
|
||||
func (i *aiUpDownCounter) setDelegate(m metric.Meter) {
|
||||
ctr, err := m.Int64ObservableUpDownCounter(i.name, i.opts...)
|
||||
|
@ -179,11 +189,13 @@ type aiGauge struct {
|
|||
name string
|
||||
opts []metric.Int64ObservableGaugeOption
|
||||
|
||||
delegate atomic.Value //metric.Int64ObservableGauge
|
||||
delegate atomic.Value // metric.Int64ObservableGauge
|
||||
}
|
||||
|
||||
var _ unwrapper = (*aiGauge)(nil)
|
||||
var _ metric.Int64ObservableGauge = (*aiGauge)(nil)
|
||||
var (
|
||||
_ unwrapper = (*aiGauge)(nil)
|
||||
_ metric.Int64ObservableGauge = (*aiGauge)(nil)
|
||||
)
|
||||
|
||||
func (i *aiGauge) setDelegate(m metric.Meter) {
|
||||
ctr, err := m.Int64ObservableGauge(i.name, i.opts...)
|
||||
|
@ -208,7 +220,7 @@ type sfCounter struct {
|
|||
name string
|
||||
opts []metric.Float64CounterOption
|
||||
|
||||
delegate atomic.Value //metric.Float64Counter
|
||||
delegate atomic.Value // metric.Float64Counter
|
||||
}
|
||||
|
||||
var _ metric.Float64Counter = (*sfCounter)(nil)
|
||||
|
@ -234,7 +246,7 @@ type sfUpDownCounter struct {
|
|||
name string
|
||||
opts []metric.Float64UpDownCounterOption
|
||||
|
||||
delegate atomic.Value //metric.Float64UpDownCounter
|
||||
delegate atomic.Value // metric.Float64UpDownCounter
|
||||
}
|
||||
|
||||
var _ metric.Float64UpDownCounter = (*sfUpDownCounter)(nil)
|
||||
|
@ -260,7 +272,7 @@ type sfHistogram struct {
|
|||
name string
|
||||
opts []metric.Float64HistogramOption
|
||||
|
||||
delegate atomic.Value //metric.Float64Histogram
|
||||
delegate atomic.Value // metric.Float64Histogram
|
||||
}
|
||||
|
||||
var _ metric.Float64Histogram = (*sfHistogram)(nil)
|
||||
|
@ -286,7 +298,7 @@ type siCounter struct {
|
|||
name string
|
||||
opts []metric.Int64CounterOption
|
||||
|
||||
delegate atomic.Value //metric.Int64Counter
|
||||
delegate atomic.Value // metric.Int64Counter
|
||||
}
|
||||
|
||||
var _ metric.Int64Counter = (*siCounter)(nil)
|
||||
|
@ -312,7 +324,7 @@ type siUpDownCounter struct {
|
|||
name string
|
||||
opts []metric.Int64UpDownCounterOption
|
||||
|
||||
delegate atomic.Value //metric.Int64UpDownCounter
|
||||
delegate atomic.Value // metric.Int64UpDownCounter
|
||||
}
|
||||
|
||||
var _ metric.Int64UpDownCounter = (*siUpDownCounter)(nil)
|
||||
|
@ -338,7 +350,7 @@ type siHistogram struct {
|
|||
name string
|
||||
opts []metric.Int64HistogramOption
|
||||
|
||||
delegate atomic.Value //metric.Int64Histogram
|
||||
delegate atomic.Value // metric.Int64Histogram
|
||||
}
|
||||
|
||||
var _ metric.Int64Histogram = (*siHistogram)(nil)
|
||||
|
|
|
@ -39,6 +39,7 @@ import (
|
|||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"go.opentelemetry.io/otel/trace/embedded"
|
||||
)
|
||||
|
||||
// tracerProvider is a placeholder for a configured SDK TracerProvider.
|
||||
|
@ -46,6 +47,8 @@ import (
|
|||
// All TracerProvider functionality is forwarded to a delegate once
|
||||
// configured.
|
||||
type tracerProvider struct {
|
||||
embedded.TracerProvider
|
||||
|
||||
mtx sync.Mutex
|
||||
tracers map[il]*tracer
|
||||
delegate trace.TracerProvider
|
||||
|
@ -119,6 +122,8 @@ type il struct {
|
|||
// All Tracer functionality is forwarded to a delegate once configured.
|
||||
// Otherwise, all functionality is forwarded to a NoopTracer.
|
||||
type tracer struct {
|
||||
embedded.Tracer
|
||||
|
||||
name string
|
||||
opts []trace.TracerOption
|
||||
provider *tracerProvider
|
||||
|
@ -156,6 +161,8 @@ func (t *tracer) Start(ctx context.Context, name string, opts ...trace.SpanStart
|
|||
// SpanContext. It performs no operations other than to return the wrapped
|
||||
// SpanContext.
|
||||
type nonRecordingSpan struct {
|
||||
embedded.Span
|
||||
|
||||
sc trace.SpanContext
|
||||
tracer *tracer
|
||||
}
|
||||
|
|
|
@ -149,7 +149,7 @@ of [go.opentelemetry.io/otel/metric].
|
|||
|
||||
Finally, an author can embed another implementation in theirs. The embedded
|
||||
implementation will be used for methods not defined by the author. For example,
|
||||
an author who want to default to silently dropping the call can use
|
||||
an author who wants to default to silently dropping the call can use
|
||||
[go.opentelemetry.io/otel/metric/noop]:
|
||||
|
||||
import "go.opentelemetry.io/otel/metric/noop"
|
||||
|
|
|
@ -39,6 +39,12 @@ type InstrumentOption interface {
|
|||
Float64ObservableGaugeOption
|
||||
}
|
||||
|
||||
// HistogramOption applies options to histogram instruments.
|
||||
type HistogramOption interface {
|
||||
Int64HistogramOption
|
||||
Float64HistogramOption
|
||||
}
|
||||
|
||||
type descOpt string
|
||||
|
||||
func (o descOpt) applyFloat64Counter(c Float64CounterConfig) Float64CounterConfig {
|
||||
|
@ -171,6 +177,23 @@ func (o unitOpt) applyInt64ObservableGauge(c Int64ObservableGaugeConfig) Int64Ob
|
|||
// The unit u should be defined using the appropriate [UCUM](https://ucum.org) case-sensitive code.
|
||||
func WithUnit(u string) InstrumentOption { return unitOpt(u) }
|
||||
|
||||
// WithExplicitBucketBoundaries sets the instrument explicit bucket boundaries.
|
||||
//
|
||||
// This option is considered "advisory", and may be ignored by API implementations.
|
||||
func WithExplicitBucketBoundaries(bounds ...float64) HistogramOption { return bucketOpt(bounds) }
|
||||
|
||||
type bucketOpt []float64
|
||||
|
||||
func (o bucketOpt) applyFloat64Histogram(c Float64HistogramConfig) Float64HistogramConfig {
|
||||
c.explicitBucketBoundaries = o
|
||||
return c
|
||||
}
|
||||
|
||||
func (o bucketOpt) applyInt64Histogram(c Int64HistogramConfig) Int64HistogramConfig {
|
||||
c.explicitBucketBoundaries = o
|
||||
return c
|
||||
}
|
||||
|
||||
// AddOption applies options to an addition measurement. See
|
||||
// [MeasurementOption] for other options that can be used as an AddOption.
|
||||
type AddOption interface {
|
||||
|
|
|
@ -147,8 +147,9 @@ type Float64Histogram interface {
|
|||
// Float64HistogramConfig contains options for synchronous counter instruments
|
||||
// that record int64 values.
|
||||
type Float64HistogramConfig struct {
|
||||
description string
|
||||
unit string
|
||||
description string
|
||||
unit string
|
||||
explicitBucketBoundaries []float64
|
||||
}
|
||||
|
||||
// NewFloat64HistogramConfig returns a new [Float64HistogramConfig] with all
|
||||
|
@ -171,6 +172,11 @@ func (c Float64HistogramConfig) Unit() string {
|
|||
return c.unit
|
||||
}
|
||||
|
||||
// ExplicitBucketBoundaries returns the configured explicit bucket boundaries.
|
||||
func (c Float64HistogramConfig) ExplicitBucketBoundaries() []float64 {
|
||||
return c.explicitBucketBoundaries
|
||||
}
|
||||
|
||||
// Float64HistogramOption applies options to a [Float64HistogramConfig]. See
|
||||
// [InstrumentOption] for other options that can be used as a
|
||||
// Float64HistogramOption.
|
||||
|
|
|
@ -147,8 +147,9 @@ type Int64Histogram interface {
|
|||
// Int64HistogramConfig contains options for synchronous counter instruments
|
||||
// that record int64 values.
|
||||
type Int64HistogramConfig struct {
|
||||
description string
|
||||
unit string
|
||||
description string
|
||||
unit string
|
||||
explicitBucketBoundaries []float64
|
||||
}
|
||||
|
||||
// NewInt64HistogramConfig returns a new [Int64HistogramConfig] with all opts
|
||||
|
@ -171,6 +172,11 @@ func (c Int64HistogramConfig) Unit() string {
|
|||
return c.unit
|
||||
}
|
||||
|
||||
// ExplicitBucketBoundaries returns the configured explicit bucket boundaries.
|
||||
func (c Int64HistogramConfig) ExplicitBucketBoundaries() []float64 {
|
||||
return c.explicitBucketBoundaries
|
||||
}
|
||||
|
||||
// Int64HistogramOption applies options to a [Int64HistogramConfig]. See
|
||||
// [InstrumentOption] for other options that can be used as an
|
||||
// Int64HistogramOption.
|
||||
|
|
|
@ -40,8 +40,10 @@ const (
|
|||
// their proprietary information.
|
||||
type TraceContext struct{}
|
||||
|
||||
var _ TextMapPropagator = TraceContext{}
|
||||
var traceCtxRegExp = regexp.MustCompile("^(?P<version>[0-9a-f]{2})-(?P<traceID>[a-f0-9]{32})-(?P<spanID>[a-f0-9]{16})-(?P<traceFlags>[a-f0-9]{2})(?:-.*)?$")
|
||||
var (
|
||||
_ TextMapPropagator = TraceContext{}
|
||||
traceCtxRegExp = regexp.MustCompile("^(?P<version>[0-9a-f]{2})-(?P<traceID>[a-f0-9]{32})-(?P<spanID>[a-f0-9]{16})-(?P<traceFlags>[a-f0-9]{2})(?:-.*)?$")
|
||||
)
|
||||
|
||||
// Inject set tracecontext from the Context into the carrier.
|
||||
func (tc TraceContext) Inject(ctx context.Context, carrier TextMapCarrier) {
|
||||
|
|
|
@ -1 +1 @@
|
|||
codespell==2.2.5
|
||||
codespell==2.2.6
|
||||
|
|
|
@ -268,6 +268,7 @@ func (o stackTraceOption) applyEvent(c EventConfig) EventConfig {
|
|||
c.stackTrace = bool(o)
|
||||
return c
|
||||
}
|
||||
|
||||
func (o stackTraceOption) applySpan(c SpanConfig) SpanConfig {
|
||||
c.stackTrace = bool(o)
|
||||
return c
|
||||
|
|
|
@ -62,5 +62,69 @@ a default.
|
|||
defer span.End()
|
||||
// ...
|
||||
}
|
||||
|
||||
# API Implementations
|
||||
|
||||
This package does not conform to the standard Go versioning policy; all of its
|
||||
interfaces may have methods added to them without a package major version bump.
|
||||
This non-standard API evolution could surprise an uninformed implementation
|
||||
author. They could unknowingly build their implementation in a way that would
|
||||
result in a runtime panic for their users that update to the new API.
|
||||
|
||||
The API is designed to help inform an instrumentation author about this
|
||||
non-standard API evolution. It requires them to choose a default behavior for
|
||||
unimplemented interface methods. There are three behavior choices they can
|
||||
make:
|
||||
|
||||
- Compilation failure
|
||||
- Panic
|
||||
- Default to another implementation
|
||||
|
||||
All interfaces in this API embed a corresponding interface from
|
||||
[go.opentelemetry.io/otel/trace/embedded]. If an author wants the default
|
||||
behavior of their implementations to be a compilation failure, signaling to
|
||||
their users they need to update to the latest version of that implementation,
|
||||
they need to embed the corresponding interface from
|
||||
[go.opentelemetry.io/otel/trace/embedded] in their implementation. For
|
||||
example,
|
||||
|
||||
import "go.opentelemetry.io/otel/trace/embedded"
|
||||
|
||||
type TracerProvider struct {
|
||||
embedded.TracerProvider
|
||||
// ...
|
||||
}
|
||||
|
||||
If an author wants the default behavior of their implementations to panic, they
|
||||
can embed the API interface directly.
|
||||
|
||||
import "go.opentelemetry.io/otel/trace"
|
||||
|
||||
type TracerProvider struct {
|
||||
trace.TracerProvider
|
||||
// ...
|
||||
}
|
||||
|
||||
This option is not recommended. It will lead to publishing packages that
|
||||
contain runtime panics when users update to newer versions of
|
||||
[go.opentelemetry.io/otel/trace], which may be done with a trasitive
|
||||
dependency.
|
||||
|
||||
Finally, an author can embed another implementation in theirs. The embedded
|
||||
implementation will be used for methods not defined by the author. For example,
|
||||
an author who wants to default to silently dropping the call can use
|
||||
[go.opentelemetry.io/otel/trace/noop]:
|
||||
|
||||
import "go.opentelemetry.io/otel/trace/noop"
|
||||
|
||||
type TracerProvider struct {
|
||||
noop.TracerProvider
|
||||
// ...
|
||||
}
|
||||
|
||||
It is strongly recommended that authors only embed
|
||||
[go.opentelemetry.io/otel/trace/noop] if they choose this default behavior.
|
||||
That implementation is the only one OpenTelemetry authors can guarantee will
|
||||
fully implement all the API interfaces when a user updates their API.
|
||||
*/
|
||||
package trace // import "go.opentelemetry.io/otel/trace"
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
// 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 embedded provides interfaces embedded within the [OpenTelemetry
|
||||
// trace API].
|
||||
//
|
||||
// Implementers of the [OpenTelemetry trace API] can embed the relevant type
|
||||
// from this package into their implementation directly. Doing so will result
|
||||
// in a compilation error for users when the [OpenTelemetry trace API] is
|
||||
// extended (which is something that can happen without a major version bump of
|
||||
// the API package).
|
||||
//
|
||||
// [OpenTelemetry trace API]: https://pkg.go.dev/go.opentelemetry.io/otel/trace
|
||||
package embedded // import "go.opentelemetry.io/otel/trace/embedded"
|
||||
|
||||
// TracerProvider is embedded in
|
||||
// [go.opentelemetry.io/otel/trace.TracerProvider].
|
||||
//
|
||||
// Embed this interface in your implementation of the
|
||||
// [go.opentelemetry.io/otel/trace.TracerProvider] if you want users to
|
||||
// experience a compilation error, signaling they need to update to your latest
|
||||
// implementation, when the [go.opentelemetry.io/otel/trace.TracerProvider]
|
||||
// interface is extended (which is something that can happen without a major
|
||||
// version bump of the API package).
|
||||
type TracerProvider interface{ tracerProvider() }
|
||||
|
||||
// Tracer is embedded in [go.opentelemetry.io/otel/trace.Tracer].
|
||||
//
|
||||
// Embed this interface in your implementation of the
|
||||
// [go.opentelemetry.io/otel/trace.Tracer] if you want users to experience a
|
||||
// compilation error, signaling they need to update to your latest
|
||||
// implementation, when the [go.opentelemetry.io/otel/trace.Tracer] interface
|
||||
// is extended (which is something that can happen without a major version bump
|
||||
// of the API package).
|
||||
type Tracer interface{ tracer() }
|
||||
|
||||
// Span is embedded in [go.opentelemetry.io/otel/trace.Span].
|
||||
//
|
||||
// Embed this interface in your implementation of the
|
||||
// [go.opentelemetry.io/otel/trace.Span] if you want users to experience a
|
||||
// compilation error, signaling they need to update to your latest
|
||||
// implementation, when the [go.opentelemetry.io/otel/trace.Span] interface is
|
||||
// extended (which is something that can happen without a major version bump of
|
||||
// the API package).
|
||||
type Span interface{ span() }
|
|
@ -19,16 +19,20 @@ import (
|
|||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/trace/embedded"
|
||||
)
|
||||
|
||||
// NewNoopTracerProvider returns an implementation of TracerProvider that
|
||||
// performs no operations. The Tracer and Spans created from the returned
|
||||
// TracerProvider also perform no operations.
|
||||
//
|
||||
// Deprecated: Use [go.opentelemetry.io/otel/trace/noop.NewTracerProvider]
|
||||
// instead.
|
||||
func NewNoopTracerProvider() TracerProvider {
|
||||
return noopTracerProvider{}
|
||||
}
|
||||
|
||||
type noopTracerProvider struct{}
|
||||
type noopTracerProvider struct{ embedded.TracerProvider }
|
||||
|
||||
var _ TracerProvider = noopTracerProvider{}
|
||||
|
||||
|
@ -38,7 +42,7 @@ func (p noopTracerProvider) Tracer(string, ...TracerOption) Tracer {
|
|||
}
|
||||
|
||||
// noopTracer is an implementation of Tracer that performs no operations.
|
||||
type noopTracer struct{}
|
||||
type noopTracer struct{ embedded.Tracer }
|
||||
|
||||
var _ Tracer = noopTracer{}
|
||||
|
||||
|
@ -54,7 +58,7 @@ func (t noopTracer) Start(ctx context.Context, name string, _ ...SpanStartOption
|
|||
}
|
||||
|
||||
// noopSpan is an implementation of Span that performs no operations.
|
||||
type noopSpan struct{}
|
||||
type noopSpan struct{ embedded.Span }
|
||||
|
||||
var _ Span = noopSpan{}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/trace/embedded"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -48,8 +49,10 @@ func (e errorConst) Error() string {
|
|||
// nolint:revive // revive complains about stutter of `trace.TraceID`.
|
||||
type TraceID [16]byte
|
||||
|
||||
var nilTraceID TraceID
|
||||
var _ json.Marshaler = nilTraceID
|
||||
var (
|
||||
nilTraceID TraceID
|
||||
_ json.Marshaler = nilTraceID
|
||||
)
|
||||
|
||||
// IsValid checks whether the trace TraceID is valid. A valid trace ID does
|
||||
// not consist of zeros only.
|
||||
|
@ -71,8 +74,10 @@ func (t TraceID) String() string {
|
|||
// SpanID is a unique identity of a span in a trace.
|
||||
type SpanID [8]byte
|
||||
|
||||
var nilSpanID SpanID
|
||||
var _ json.Marshaler = nilSpanID
|
||||
var (
|
||||
nilSpanID SpanID
|
||||
_ json.Marshaler = nilSpanID
|
||||
)
|
||||
|
||||
// IsValid checks whether the SpanID is valid. A valid SpanID does not consist
|
||||
// of zeros only.
|
||||
|
@ -338,8 +343,15 @@ func (sc SpanContext) MarshalJSON() ([]byte, error) {
|
|||
// create a Span and it is then up to the operation the Span represents to
|
||||
// properly end the Span when the operation itself ends.
|
||||
//
|
||||
// Warning: methods may be added to this interface in minor releases.
|
||||
// Warning: Methods may be added to this interface in minor releases. See
|
||||
// package documentation on API implementation for information on how to set
|
||||
// default behavior for unimplemented methods.
|
||||
type Span interface {
|
||||
// Users of the interface can ignore this. This embedded type is only used
|
||||
// by implementations of this interface. See the "API Implementations"
|
||||
// section of the package documentation for more information.
|
||||
embedded.Span
|
||||
|
||||
// End completes the Span. The Span is considered complete and ready to be
|
||||
// delivered through the rest of the telemetry pipeline after this method
|
||||
// is called. Therefore, updates to the Span are not allowed after this
|
||||
|
@ -486,8 +498,15 @@ func (sk SpanKind) String() string {
|
|||
|
||||
// Tracer is the creator of Spans.
|
||||
//
|
||||
// Warning: methods may be added to this interface in minor releases.
|
||||
// Warning: Methods may be added to this interface in minor releases. See
|
||||
// package documentation on API implementation for information on how to set
|
||||
// default behavior for unimplemented methods.
|
||||
type Tracer interface {
|
||||
// Users of the interface can ignore this. This embedded type is only used
|
||||
// by implementations of this interface. See the "API Implementations"
|
||||
// section of the package documentation for more information.
|
||||
embedded.Tracer
|
||||
|
||||
// Start creates a span and a context.Context containing the newly-created span.
|
||||
//
|
||||
// If the context.Context provided in `ctx` contains a Span then the newly-created
|
||||
|
@ -518,8 +537,15 @@ type Tracer interface {
|
|||
// at runtime from its users or it can simply use the globally registered one
|
||||
// (see https://pkg.go.dev/go.opentelemetry.io/otel#GetTracerProvider).
|
||||
//
|
||||
// Warning: methods may be added to this interface in minor releases.
|
||||
// Warning: Methods may be added to this interface in minor releases. See
|
||||
// package documentation on API implementation for information on how to set
|
||||
// default behavior for unimplemented methods.
|
||||
type TracerProvider interface {
|
||||
// Users of the interface can ignore this. This embedded type is only used
|
||||
// by implementations of this interface. See the "API Implementations"
|
||||
// section of the package documentation for more information.
|
||||
embedded.TracerProvider
|
||||
|
||||
// Tracer returns a unique Tracer scoped to be used by instrumentation code
|
||||
// to trace computational workflows. The scope and identity of that
|
||||
// instrumentation code is uniquely defined by the name and options passed.
|
||||
|
|
|
@ -28,9 +28,9 @@ const (
|
|||
|
||||
// based on the W3C Trace Context specification, see
|
||||
// https://www.w3.org/TR/trace-context-1/#tracestate-header
|
||||
noTenantKeyFormat = `[a-z][_0-9a-z\-\*\/]{0,255}`
|
||||
withTenantKeyFormat = `[a-z0-9][_0-9a-z\-\*\/]{0,240}@[a-z][_0-9a-z\-\*\/]{0,13}`
|
||||
valueFormat = `[\x20-\x2b\x2d-\x3c\x3e-\x7e]{0,255}[\x21-\x2b\x2d-\x3c\x3e-\x7e]`
|
||||
noTenantKeyFormat = `[a-z][_0-9a-z\-\*\/]*`
|
||||
withTenantKeyFormat = `[a-z0-9][_0-9a-z\-\*\/]*@[a-z][_0-9a-z\-\*\/]*`
|
||||
valueFormat = `[\x20-\x2b\x2d-\x3c\x3e-\x7e]*[\x21-\x2b\x2d-\x3c\x3e-\x7e]`
|
||||
|
||||
errInvalidKey errorConst = "invalid tracestate key"
|
||||
errInvalidValue errorConst = "invalid tracestate value"
|
||||
|
@ -40,9 +40,10 @@ const (
|
|||
)
|
||||
|
||||
var (
|
||||
keyRe = regexp.MustCompile(`^((` + noTenantKeyFormat + `)|(` + withTenantKeyFormat + `))$`)
|
||||
valueRe = regexp.MustCompile(`^(` + valueFormat + `)$`)
|
||||
memberRe = regexp.MustCompile(`^\s*((` + noTenantKeyFormat + `)|(` + withTenantKeyFormat + `))=(` + valueFormat + `)\s*$`)
|
||||
noTenantKeyRe = regexp.MustCompile(`^` + noTenantKeyFormat + `$`)
|
||||
withTenantKeyRe = regexp.MustCompile(`^` + withTenantKeyFormat + `$`)
|
||||
valueRe = regexp.MustCompile(`^` + valueFormat + `$`)
|
||||
memberRe = regexp.MustCompile(`^\s*((?:` + noTenantKeyFormat + `)|(?:` + withTenantKeyFormat + `))=(` + valueFormat + `)\s*$`)
|
||||
)
|
||||
|
||||
type member struct {
|
||||
|
@ -51,10 +52,19 @@ type member struct {
|
|||
}
|
||||
|
||||
func newMember(key, value string) (member, error) {
|
||||
if !keyRe.MatchString(key) {
|
||||
if len(key) > 256 {
|
||||
return member{}, fmt.Errorf("%w: %s", errInvalidKey, key)
|
||||
}
|
||||
if !valueRe.MatchString(value) {
|
||||
if !noTenantKeyRe.MatchString(key) {
|
||||
if !withTenantKeyRe.MatchString(key) {
|
||||
return member{}, fmt.Errorf("%w: %s", errInvalidKey, key)
|
||||
}
|
||||
atIndex := strings.LastIndex(key, "@")
|
||||
if atIndex > 241 || len(key)-1-atIndex > 14 {
|
||||
return member{}, fmt.Errorf("%w: %s", errInvalidKey, key)
|
||||
}
|
||||
}
|
||||
if len(value) > 256 || !valueRe.MatchString(value) {
|
||||
return member{}, fmt.Errorf("%w: %s", errInvalidValue, value)
|
||||
}
|
||||
return member{Key: key, Value: value}, nil
|
||||
|
@ -62,14 +72,14 @@ func newMember(key, value string) (member, error) {
|
|||
|
||||
func parseMember(m string) (member, error) {
|
||||
matches := memberRe.FindStringSubmatch(m)
|
||||
if len(matches) != 5 {
|
||||
if len(matches) != 3 {
|
||||
return member{}, fmt.Errorf("%w: %s", errInvalidMember, m)
|
||||
}
|
||||
|
||||
return member{
|
||||
Key: matches[1],
|
||||
Value: matches[4],
|
||||
}, nil
|
||||
result, e := newMember(matches[1], matches[2])
|
||||
if e != nil {
|
||||
return member{}, fmt.Errorf("%w: %s", errInvalidMember, m)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// String encodes member into a string compliant with the W3C Trace Context
|
||||
|
|
|
@ -16,5 +16,5 @@ package otel // import "go.opentelemetry.io/otel"
|
|||
|
||||
// Version is the current release version of OpenTelemetry in use.
|
||||
func Version() string {
|
||||
return "1.19.0"
|
||||
return "1.21.0"
|
||||
}
|
||||
|
|
|
@ -14,13 +14,12 @@
|
|||
|
||||
module-sets:
|
||||
stable-v1:
|
||||
version: v1.19.0
|
||||
version: v1.21.0
|
||||
modules:
|
||||
- go.opentelemetry.io/otel
|
||||
- go.opentelemetry.io/otel/bridge/opentracing
|
||||
- go.opentelemetry.io/otel/bridge/opentracing/test
|
||||
- go.opentelemetry.io/otel/example/dice
|
||||
- go.opentelemetry.io/otel/example/fib
|
||||
- go.opentelemetry.io/otel/example/namedtracer
|
||||
- go.opentelemetry.io/otel/example/otel-collector
|
||||
- go.opentelemetry.io/otel/example/passthrough
|
||||
|
@ -35,14 +34,12 @@ module-sets:
|
|||
- go.opentelemetry.io/otel/sdk/metric
|
||||
- go.opentelemetry.io/otel/trace
|
||||
experimental-metrics:
|
||||
version: v0.42.0
|
||||
version: v0.44.0
|
||||
modules:
|
||||
- go.opentelemetry.io/otel/bridge/opencensus
|
||||
- go.opentelemetry.io/otel/bridge/opencensus/test
|
||||
- go.opentelemetry.io/otel/example/opencensus
|
||||
- go.opentelemetry.io/otel/example/prometheus
|
||||
- go.opentelemetry.io/otel/example/view
|
||||
- go.opentelemetry.io/otel/exporters/otlp/otlpmetric
|
||||
- go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc
|
||||
- go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp
|
||||
- go.opentelemetry.io/otel/exporters/prometheus
|
||||
|
|
|
@ -1510,13 +1510,12 @@ func (mh *MetaHeadersFrame) checkPseudos() error {
|
|||
}
|
||||
|
||||
func (fr *Framer) maxHeaderStringLen() int {
|
||||
v := fr.maxHeaderListSize()
|
||||
if uint32(int(v)) == v {
|
||||
return int(v)
|
||||
v := int(fr.maxHeaderListSize())
|
||||
if v < 0 {
|
||||
// If maxHeaderListSize overflows an int, use no limit (0).
|
||||
return 0
|
||||
}
|
||||
// They had a crazy big number for MaxHeaderBytes anyway,
|
||||
// so give them unlimited header lengths:
|
||||
return 0
|
||||
return v
|
||||
}
|
||||
|
||||
// readMetaFrame returns 0 or more CONTINUATION frames from fr and
|
||||
|
@ -1565,6 +1564,7 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) {
|
|||
if size > remainSize {
|
||||
hdec.SetEmitEnabled(false)
|
||||
mh.Truncated = true
|
||||
remainSize = 0
|
||||
return
|
||||
}
|
||||
remainSize -= size
|
||||
|
@ -1577,6 +1577,36 @@ func (fr *Framer) readMetaFrame(hf *HeadersFrame) (*MetaHeadersFrame, error) {
|
|||
var hc headersOrContinuation = hf
|
||||
for {
|
||||
frag := hc.HeaderBlockFragment()
|
||||
|
||||
// Avoid parsing large amounts of headers that we will then discard.
|
||||
// If the sender exceeds the max header list size by too much,
|
||||
// skip parsing the fragment and close the connection.
|
||||
//
|
||||
// "Too much" is either any CONTINUATION frame after we've already
|
||||
// exceeded the max header list size (in which case remainSize is 0),
|
||||
// or a frame whose encoded size is more than twice the remaining
|
||||
// header list bytes we're willing to accept.
|
||||
if int64(len(frag)) > int64(2*remainSize) {
|
||||
if VerboseLogs {
|
||||
log.Printf("http2: header list too large")
|
||||
}
|
||||
// It would be nice to send a RST_STREAM before sending the GOAWAY,
|
||||
// but the structure of the server's frame writer makes this difficult.
|
||||
return nil, ConnectionError(ErrCodeProtocol)
|
||||
}
|
||||
|
||||
// Also close the connection after any CONTINUATION frame following an
|
||||
// invalid header, since we stop tracking the size of the headers after
|
||||
// an invalid one.
|
||||
if invalid != nil {
|
||||
if VerboseLogs {
|
||||
log.Printf("http2: invalid header: %v", invalid)
|
||||
}
|
||||
// It would be nice to send a RST_STREAM before sending the GOAWAY,
|
||||
// but the structure of the server's frame writer makes this difficult.
|
||||
return nil, ConnectionError(ErrCodeProtocol)
|
||||
}
|
||||
|
||||
if _, err := hdec.Write(frag); err != nil {
|
||||
return nil, ConnectionError(ErrCodeCompression)
|
||||
}
|
||||
|
|
|
@ -77,7 +77,10 @@ func (p *pipe) Read(d []byte) (n int, err error) {
|
|||
}
|
||||
}
|
||||
|
||||
var errClosedPipeWrite = errors.New("write on closed buffer")
|
||||
var (
|
||||
errClosedPipeWrite = errors.New("write on closed buffer")
|
||||
errUninitializedPipeWrite = errors.New("write on uninitialized buffer")
|
||||
)
|
||||
|
||||
// Write copies bytes from p into the buffer and wakes a reader.
|
||||
// It is an error to write more data than the buffer can hold.
|
||||
|
@ -91,6 +94,12 @@ func (p *pipe) Write(d []byte) (n int, err error) {
|
|||
if p.err != nil || p.breakErr != nil {
|
||||
return 0, errClosedPipeWrite
|
||||
}
|
||||
// pipe.setBuffer is never invoked, leaving the buffer uninitialized.
|
||||
// We shouldn't try to write to an uninitialized pipe,
|
||||
// but returning an error is better than panicking.
|
||||
if p.b == nil {
|
||||
return 0, errUninitializedPipeWrite
|
||||
}
|
||||
return p.b.Write(d)
|
||||
}
|
||||
|
||||
|
|
|
@ -124,6 +124,7 @@ type Server struct {
|
|||
// IdleTimeout specifies how long until idle clients should be
|
||||
// closed with a GOAWAY frame. PING frames are not considered
|
||||
// activity for the purposes of IdleTimeout.
|
||||
// If zero or negative, there is no timeout.
|
||||
IdleTimeout time.Duration
|
||||
|
||||
// MaxUploadBufferPerConnection is the size of the initial flow
|
||||
|
@ -434,7 +435,7 @@ func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) {
|
|||
// passes the connection off to us with the deadline already set.
|
||||
// Write deadlines are set per stream in serverConn.newStream.
|
||||
// Disarm the net.Conn write deadline here.
|
||||
if sc.hs.WriteTimeout != 0 {
|
||||
if sc.hs.WriteTimeout > 0 {
|
||||
sc.conn.SetWriteDeadline(time.Time{})
|
||||
}
|
||||
|
||||
|
@ -924,7 +925,7 @@ func (sc *serverConn) serve() {
|
|||
sc.setConnState(http.StateActive)
|
||||
sc.setConnState(http.StateIdle)
|
||||
|
||||
if sc.srv.IdleTimeout != 0 {
|
||||
if sc.srv.IdleTimeout > 0 {
|
||||
sc.idleTimer = time.AfterFunc(sc.srv.IdleTimeout, sc.onIdleTimer)
|
||||
defer sc.idleTimer.Stop()
|
||||
}
|
||||
|
@ -1637,7 +1638,7 @@ func (sc *serverConn) closeStream(st *stream, err error) {
|
|||
delete(sc.streams, st.id)
|
||||
if len(sc.streams) == 0 {
|
||||
sc.setConnState(http.StateIdle)
|
||||
if sc.srv.IdleTimeout != 0 {
|
||||
if sc.srv.IdleTimeout > 0 {
|
||||
sc.idleTimer.Reset(sc.srv.IdleTimeout)
|
||||
}
|
||||
if h1ServerKeepAlivesDisabled(sc.hs) {
|
||||
|
@ -2017,7 +2018,7 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
|
|||
// similar to how the http1 server works. Here it's
|
||||
// technically more like the http1 Server's ReadHeaderTimeout
|
||||
// (in Go 1.8), though. That's a more sane option anyway.
|
||||
if sc.hs.ReadTimeout != 0 {
|
||||
if sc.hs.ReadTimeout > 0 {
|
||||
sc.conn.SetReadDeadline(time.Time{})
|
||||
st.readDeadline = time.AfterFunc(sc.hs.ReadTimeout, st.onReadTimeout)
|
||||
}
|
||||
|
@ -2038,7 +2039,7 @@ func (sc *serverConn) upgradeRequest(req *http.Request) {
|
|||
|
||||
// Disable any read deadline set by the net/http package
|
||||
// prior to the upgrade.
|
||||
if sc.hs.ReadTimeout != 0 {
|
||||
if sc.hs.ReadTimeout > 0 {
|
||||
sc.conn.SetReadDeadline(time.Time{})
|
||||
}
|
||||
|
||||
|
@ -2116,7 +2117,7 @@ func (sc *serverConn) newStream(id, pusherID uint32, state streamState) *stream
|
|||
st.flow.conn = &sc.flow // link to conn-level counter
|
||||
st.flow.add(sc.initialStreamSendWindowSize)
|
||||
st.inflow.init(sc.srv.initialStreamRecvWindowSize())
|
||||
if sc.hs.WriteTimeout != 0 {
|
||||
if sc.hs.WriteTimeout > 0 {
|
||||
st.writeDeadline = time.AfterFunc(sc.hs.WriteTimeout, st.onWriteTimeout)
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,331 @@
|
|||
// Copyright 2024 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
package http2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// testSyncHooks coordinates goroutines in tests.
|
||||
//
|
||||
// For example, a call to ClientConn.RoundTrip involves several goroutines, including:
|
||||
// - the goroutine running RoundTrip;
|
||||
// - the clientStream.doRequest goroutine, which writes the request; and
|
||||
// - the clientStream.readLoop goroutine, which reads the response.
|
||||
//
|
||||
// Using testSyncHooks, a test can start a RoundTrip and identify when all these goroutines
|
||||
// are blocked waiting for some condition such as reading the Request.Body or waiting for
|
||||
// flow control to become available.
|
||||
//
|
||||
// The testSyncHooks also manage timers and synthetic time in tests.
|
||||
// This permits us to, for example, start a request and cause it to time out waiting for
|
||||
// response headers without resorting to time.Sleep calls.
|
||||
type testSyncHooks struct {
|
||||
// active/inactive act as a mutex and condition variable.
|
||||
//
|
||||
// - neither chan contains a value: testSyncHooks is locked.
|
||||
// - active contains a value: unlocked, and at least one goroutine is not blocked
|
||||
// - inactive contains a value: unlocked, and all goroutines are blocked
|
||||
active chan struct{}
|
||||
inactive chan struct{}
|
||||
|
||||
// goroutine counts
|
||||
total int // total goroutines
|
||||
condwait map[*sync.Cond]int // blocked in sync.Cond.Wait
|
||||
blocked []*testBlockedGoroutine // otherwise blocked
|
||||
|
||||
// fake time
|
||||
now time.Time
|
||||
timers []*fakeTimer
|
||||
|
||||
// Transport testing: Report various events.
|
||||
newclientconn func(*ClientConn)
|
||||
newstream func(*clientStream)
|
||||
}
|
||||
|
||||
// testBlockedGoroutine is a blocked goroutine.
|
||||
type testBlockedGoroutine struct {
|
||||
f func() bool // blocked until f returns true
|
||||
ch chan struct{} // closed when unblocked
|
||||
}
|
||||
|
||||
func newTestSyncHooks() *testSyncHooks {
|
||||
h := &testSyncHooks{
|
||||
active: make(chan struct{}, 1),
|
||||
inactive: make(chan struct{}, 1),
|
||||
condwait: map[*sync.Cond]int{},
|
||||
}
|
||||
h.inactive <- struct{}{}
|
||||
h.now = time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||
return h
|
||||
}
|
||||
|
||||
// lock acquires the testSyncHooks mutex.
|
||||
func (h *testSyncHooks) lock() {
|
||||
select {
|
||||
case <-h.active:
|
||||
case <-h.inactive:
|
||||
}
|
||||
}
|
||||
|
||||
// waitInactive waits for all goroutines to become inactive.
|
||||
func (h *testSyncHooks) waitInactive() {
|
||||
for {
|
||||
<-h.inactive
|
||||
if !h.unlock() {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unlock releases the testSyncHooks mutex.
|
||||
// It reports whether any goroutines are active.
|
||||
func (h *testSyncHooks) unlock() (active bool) {
|
||||
// Look for a blocked goroutine which can be unblocked.
|
||||
blocked := h.blocked[:0]
|
||||
unblocked := false
|
||||
for _, b := range h.blocked {
|
||||
if !unblocked && b.f() {
|
||||
unblocked = true
|
||||
close(b.ch)
|
||||
} else {
|
||||
blocked = append(blocked, b)
|
||||
}
|
||||
}
|
||||
h.blocked = blocked
|
||||
|
||||
// Count goroutines blocked on condition variables.
|
||||
condwait := 0
|
||||
for _, count := range h.condwait {
|
||||
condwait += count
|
||||
}
|
||||
|
||||
if h.total > condwait+len(blocked) {
|
||||
h.active <- struct{}{}
|
||||
return true
|
||||
} else {
|
||||
h.inactive <- struct{}{}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// goRun starts a new goroutine.
|
||||
func (h *testSyncHooks) goRun(f func()) {
|
||||
h.lock()
|
||||
h.total++
|
||||
h.unlock()
|
||||
go func() {
|
||||
defer func() {
|
||||
h.lock()
|
||||
h.total--
|
||||
h.unlock()
|
||||
}()
|
||||
f()
|
||||
}()
|
||||
}
|
||||
|
||||
// blockUntil indicates that a goroutine is blocked waiting for some condition to become true.
|
||||
// It waits until f returns true before proceeding.
|
||||
//
|
||||
// Example usage:
|
||||
//
|
||||
// h.blockUntil(func() bool {
|
||||
// // Is the context done yet?
|
||||
// select {
|
||||
// case <-ctx.Done():
|
||||
// default:
|
||||
// return false
|
||||
// }
|
||||
// return true
|
||||
// })
|
||||
// // Wait for the context to become done.
|
||||
// <-ctx.Done()
|
||||
//
|
||||
// The function f passed to blockUntil must be non-blocking and idempotent.
|
||||
func (h *testSyncHooks) blockUntil(f func() bool) {
|
||||
if f() {
|
||||
return
|
||||
}
|
||||
ch := make(chan struct{})
|
||||
h.lock()
|
||||
h.blocked = append(h.blocked, &testBlockedGoroutine{
|
||||
f: f,
|
||||
ch: ch,
|
||||
})
|
||||
h.unlock()
|
||||
<-ch
|
||||
}
|
||||
|
||||
// broadcast is sync.Cond.Broadcast.
|
||||
func (h *testSyncHooks) condBroadcast(cond *sync.Cond) {
|
||||
h.lock()
|
||||
delete(h.condwait, cond)
|
||||
h.unlock()
|
||||
cond.Broadcast()
|
||||
}
|
||||
|
||||
// broadcast is sync.Cond.Wait.
|
||||
func (h *testSyncHooks) condWait(cond *sync.Cond) {
|
||||
h.lock()
|
||||
h.condwait[cond]++
|
||||
h.unlock()
|
||||
}
|
||||
|
||||
// newTimer creates a new fake timer.
|
||||
func (h *testSyncHooks) newTimer(d time.Duration) timer {
|
||||
h.lock()
|
||||
defer h.unlock()
|
||||
t := &fakeTimer{
|
||||
hooks: h,
|
||||
when: h.now.Add(d),
|
||||
c: make(chan time.Time),
|
||||
}
|
||||
h.timers = append(h.timers, t)
|
||||
return t
|
||||
}
|
||||
|
||||
// afterFunc creates a new fake AfterFunc timer.
|
||||
func (h *testSyncHooks) afterFunc(d time.Duration, f func()) timer {
|
||||
h.lock()
|
||||
defer h.unlock()
|
||||
t := &fakeTimer{
|
||||
hooks: h,
|
||||
when: h.now.Add(d),
|
||||
f: f,
|
||||
}
|
||||
h.timers = append(h.timers, t)
|
||||
return t
|
||||
}
|
||||
|
||||
func (h *testSyncHooks) contextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
t := h.afterFunc(d, cancel)
|
||||
return ctx, func() {
|
||||
t.Stop()
|
||||
cancel()
|
||||
}
|
||||
}
|
||||
|
||||
func (h *testSyncHooks) timeUntilEvent() time.Duration {
|
||||
h.lock()
|
||||
defer h.unlock()
|
||||
var next time.Time
|
||||
for _, t := range h.timers {
|
||||
if next.IsZero() || t.when.Before(next) {
|
||||
next = t.when
|
||||
}
|
||||
}
|
||||
if d := next.Sub(h.now); d > 0 {
|
||||
return d
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// advance advances time and causes synthetic timers to fire.
|
||||
func (h *testSyncHooks) advance(d time.Duration) {
|
||||
h.lock()
|
||||
defer h.unlock()
|
||||
h.now = h.now.Add(d)
|
||||
timers := h.timers[:0]
|
||||
for _, t := range h.timers {
|
||||
t := t // remove after go.mod depends on go1.22
|
||||
t.mu.Lock()
|
||||
switch {
|
||||
case t.when.After(h.now):
|
||||
timers = append(timers, t)
|
||||
case t.when.IsZero():
|
||||
// stopped timer
|
||||
default:
|
||||
t.when = time.Time{}
|
||||
if t.c != nil {
|
||||
close(t.c)
|
||||
}
|
||||
if t.f != nil {
|
||||
h.total++
|
||||
go func() {
|
||||
defer func() {
|
||||
h.lock()
|
||||
h.total--
|
||||
h.unlock()
|
||||
}()
|
||||
t.f()
|
||||
}()
|
||||
}
|
||||
}
|
||||
t.mu.Unlock()
|
||||
}
|
||||
h.timers = timers
|
||||
}
|
||||
|
||||
// A timer wraps a time.Timer, or a synthetic equivalent in tests.
|
||||
// Unlike time.Timer, timer is single-use: The timer channel is closed when the timer expires.
|
||||
type timer interface {
|
||||
C() <-chan time.Time
|
||||
Stop() bool
|
||||
Reset(d time.Duration) bool
|
||||
}
|
||||
|
||||
// timeTimer implements timer using real time.
|
||||
type timeTimer struct {
|
||||
t *time.Timer
|
||||
c chan time.Time
|
||||
}
|
||||
|
||||
// newTimeTimer creates a new timer using real time.
|
||||
func newTimeTimer(d time.Duration) timer {
|
||||
ch := make(chan time.Time)
|
||||
t := time.AfterFunc(d, func() {
|
||||
close(ch)
|
||||
})
|
||||
return &timeTimer{t, ch}
|
||||
}
|
||||
|
||||
// newTimeAfterFunc creates an AfterFunc timer using real time.
|
||||
func newTimeAfterFunc(d time.Duration, f func()) timer {
|
||||
return &timeTimer{
|
||||
t: time.AfterFunc(d, f),
|
||||
}
|
||||
}
|
||||
|
||||
func (t timeTimer) C() <-chan time.Time { return t.c }
|
||||
func (t timeTimer) Stop() bool { return t.t.Stop() }
|
||||
func (t timeTimer) Reset(d time.Duration) bool { return t.t.Reset(d) }
|
||||
|
||||
// fakeTimer implements timer using fake time.
|
||||
type fakeTimer struct {
|
||||
hooks *testSyncHooks
|
||||
|
||||
mu sync.Mutex
|
||||
when time.Time // when the timer will fire
|
||||
c chan time.Time // closed when the timer fires; mutually exclusive with f
|
||||
f func() // called when the timer fires; mutually exclusive with c
|
||||
}
|
||||
|
||||
func (t *fakeTimer) C() <-chan time.Time { return t.c }
|
||||
|
||||
func (t *fakeTimer) Stop() bool {
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
stopped := t.when.IsZero()
|
||||
t.when = time.Time{}
|
||||
return stopped
|
||||
}
|
||||
|
||||
func (t *fakeTimer) Reset(d time.Duration) bool {
|
||||
if t.c != nil || t.f == nil {
|
||||
panic("fakeTimer only supports Reset on AfterFunc timers")
|
||||
}
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
t.hooks.lock()
|
||||
defer t.hooks.unlock()
|
||||
active := !t.when.IsZero()
|
||||
t.when = t.hooks.now.Add(d)
|
||||
if !active {
|
||||
t.hooks.timers = append(t.hooks.timers, t)
|
||||
}
|
||||
return active
|
||||
}
|
|
@ -147,6 +147,12 @@ type Transport struct {
|
|||
// waiting for their turn.
|
||||
StrictMaxConcurrentStreams bool
|
||||
|
||||
// IdleConnTimeout is the maximum amount of time an idle
|
||||
// (keep-alive) connection will remain idle before closing
|
||||
// itself.
|
||||
// Zero means no limit.
|
||||
IdleConnTimeout time.Duration
|
||||
|
||||
// ReadIdleTimeout is the timeout after which a health check using ping
|
||||
// frame will be carried out if no frame is received on the connection.
|
||||
// Note that a ping response will is considered a received frame, so if
|
||||
|
@ -178,6 +184,8 @@ type Transport struct {
|
|||
|
||||
connPoolOnce sync.Once
|
||||
connPoolOrDef ClientConnPool // non-nil version of ConnPool
|
||||
|
||||
syncHooks *testSyncHooks
|
||||
}
|
||||
|
||||
func (t *Transport) maxHeaderListSize() uint32 {
|
||||
|
@ -302,7 +310,7 @@ type ClientConn struct {
|
|||
readerErr error // set before readerDone is closed
|
||||
|
||||
idleTimeout time.Duration // or 0 for never
|
||||
idleTimer *time.Timer
|
||||
idleTimer timer
|
||||
|
||||
mu sync.Mutex // guards following
|
||||
cond *sync.Cond // hold mu; broadcast on flow/closed changes
|
||||
|
@ -344,6 +352,60 @@ type ClientConn struct {
|
|||
werr error // first write error that has occurred
|
||||
hbuf bytes.Buffer // HPACK encoder writes into this
|
||||
henc *hpack.Encoder
|
||||
|
||||
syncHooks *testSyncHooks // can be nil
|
||||
}
|
||||
|
||||
// Hook points used for testing.
|
||||
// Outside of tests, cc.syncHooks is nil and these all have minimal implementations.
|
||||
// Inside tests, see the testSyncHooks function docs.
|
||||
|
||||
// goRun starts a new goroutine.
|
||||
func (cc *ClientConn) goRun(f func()) {
|
||||
if cc.syncHooks != nil {
|
||||
cc.syncHooks.goRun(f)
|
||||
return
|
||||
}
|
||||
go f()
|
||||
}
|
||||
|
||||
// condBroadcast is cc.cond.Broadcast.
|
||||
func (cc *ClientConn) condBroadcast() {
|
||||
if cc.syncHooks != nil {
|
||||
cc.syncHooks.condBroadcast(cc.cond)
|
||||
}
|
||||
cc.cond.Broadcast()
|
||||
}
|
||||
|
||||
// condWait is cc.cond.Wait.
|
||||
func (cc *ClientConn) condWait() {
|
||||
if cc.syncHooks != nil {
|
||||
cc.syncHooks.condWait(cc.cond)
|
||||
}
|
||||
cc.cond.Wait()
|
||||
}
|
||||
|
||||
// newTimer creates a new time.Timer, or a synthetic timer in tests.
|
||||
func (cc *ClientConn) newTimer(d time.Duration) timer {
|
||||
if cc.syncHooks != nil {
|
||||
return cc.syncHooks.newTimer(d)
|
||||
}
|
||||
return newTimeTimer(d)
|
||||
}
|
||||
|
||||
// afterFunc creates a new time.AfterFunc timer, or a synthetic timer in tests.
|
||||
func (cc *ClientConn) afterFunc(d time.Duration, f func()) timer {
|
||||
if cc.syncHooks != nil {
|
||||
return cc.syncHooks.afterFunc(d, f)
|
||||
}
|
||||
return newTimeAfterFunc(d, f)
|
||||
}
|
||||
|
||||
func (cc *ClientConn) contextWithTimeout(ctx context.Context, d time.Duration) (context.Context, context.CancelFunc) {
|
||||
if cc.syncHooks != nil {
|
||||
return cc.syncHooks.contextWithTimeout(ctx, d)
|
||||
}
|
||||
return context.WithTimeout(ctx, d)
|
||||
}
|
||||
|
||||
// clientStream is the state for a single HTTP/2 stream. One of these
|
||||
|
@ -425,7 +487,7 @@ func (cs *clientStream) abortStreamLocked(err error) {
|
|||
// TODO(dneil): Clean up tests where cs.cc.cond is nil.
|
||||
if cs.cc.cond != nil {
|
||||
// Wake up writeRequestBody if it is waiting on flow control.
|
||||
cs.cc.cond.Broadcast()
|
||||
cs.cc.condBroadcast()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -435,7 +497,7 @@ func (cs *clientStream) abortRequestBodyWrite() {
|
|||
defer cc.mu.Unlock()
|
||||
if cs.reqBody != nil && cs.reqBodyClosed == nil {
|
||||
cs.closeReqBodyLocked()
|
||||
cc.cond.Broadcast()
|
||||
cc.condBroadcast()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -445,10 +507,10 @@ func (cs *clientStream) closeReqBodyLocked() {
|
|||
}
|
||||
cs.reqBodyClosed = make(chan struct{})
|
||||
reqBodyClosed := cs.reqBodyClosed
|
||||
go func() {
|
||||
cs.cc.goRun(func() {
|
||||
cs.reqBody.Close()
|
||||
close(reqBodyClosed)
|
||||
}()
|
||||
})
|
||||
}
|
||||
|
||||
type stickyErrWriter struct {
|
||||
|
@ -537,15 +599,6 @@ func authorityAddr(scheme string, authority string) (addr string) {
|
|||
return net.JoinHostPort(host, port)
|
||||
}
|
||||
|
||||
var retryBackoffHook func(time.Duration) *time.Timer
|
||||
|
||||
func backoffNewTimer(d time.Duration) *time.Timer {
|
||||
if retryBackoffHook != nil {
|
||||
return retryBackoffHook(d)
|
||||
}
|
||||
return time.NewTimer(d)
|
||||
}
|
||||
|
||||
// RoundTripOpt is like RoundTrip, but takes options.
|
||||
func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) {
|
||||
if !(req.URL.Scheme == "https" || (req.URL.Scheme == "http" && t.AllowHTTP)) {
|
||||
|
@ -573,13 +626,27 @@ func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Res
|
|||
backoff := float64(uint(1) << (uint(retry) - 1))
|
||||
backoff += backoff * (0.1 * mathrand.Float64())
|
||||
d := time.Second * time.Duration(backoff)
|
||||
timer := backoffNewTimer(d)
|
||||
var tm timer
|
||||
if t.syncHooks != nil {
|
||||
tm = t.syncHooks.newTimer(d)
|
||||
t.syncHooks.blockUntil(func() bool {
|
||||
select {
|
||||
case <-tm.C():
|
||||
case <-req.Context().Done():
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
} else {
|
||||
tm = newTimeTimer(d)
|
||||
}
|
||||
select {
|
||||
case <-timer.C:
|
||||
case <-tm.C():
|
||||
t.vlogf("RoundTrip retrying after failure: %v", roundTripErr)
|
||||
continue
|
||||
case <-req.Context().Done():
|
||||
timer.Stop()
|
||||
tm.Stop()
|
||||
err = req.Context().Err()
|
||||
}
|
||||
}
|
||||
|
@ -658,6 +725,9 @@ func canRetryError(err error) bool {
|
|||
}
|
||||
|
||||
func (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse bool) (*ClientConn, error) {
|
||||
if t.syncHooks != nil {
|
||||
return t.newClientConn(nil, singleUse, t.syncHooks)
|
||||
}
|
||||
host, _, err := net.SplitHostPort(addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -666,7 +736,7 @@ func (t *Transport) dialClientConn(ctx context.Context, addr string, singleUse b
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return t.newClientConn(tconn, singleUse)
|
||||
return t.newClientConn(tconn, singleUse, nil)
|
||||
}
|
||||
|
||||
func (t *Transport) newTLSConfig(host string) *tls.Config {
|
||||
|
@ -732,10 +802,10 @@ func (t *Transport) maxEncoderHeaderTableSize() uint32 {
|
|||
}
|
||||
|
||||
func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) {
|
||||
return t.newClientConn(c, t.disableKeepAlives())
|
||||
return t.newClientConn(c, t.disableKeepAlives(), nil)
|
||||
}
|
||||
|
||||
func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, error) {
|
||||
func (t *Transport) newClientConn(c net.Conn, singleUse bool, hooks *testSyncHooks) (*ClientConn, error) {
|
||||
cc := &ClientConn{
|
||||
t: t,
|
||||
tconn: c,
|
||||
|
@ -750,10 +820,15 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro
|
|||
wantSettingsAck: true,
|
||||
pings: make(map[[8]byte]chan struct{}),
|
||||
reqHeaderMu: make(chan struct{}, 1),
|
||||
syncHooks: hooks,
|
||||
}
|
||||
if hooks != nil {
|
||||
hooks.newclientconn(cc)
|
||||
c = cc.tconn
|
||||
}
|
||||
if d := t.idleConnTimeout(); d != 0 {
|
||||
cc.idleTimeout = d
|
||||
cc.idleTimer = time.AfterFunc(d, cc.onIdleTimeout)
|
||||
cc.idleTimer = cc.afterFunc(d, cc.onIdleTimeout)
|
||||
}
|
||||
if VerboseLogs {
|
||||
t.vlogf("http2: Transport creating client conn %p to %v", cc, c.RemoteAddr())
|
||||
|
@ -818,7 +893,7 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro
|
|||
return nil, cc.werr
|
||||
}
|
||||
|
||||
go cc.readLoop()
|
||||
cc.goRun(cc.readLoop)
|
||||
return cc, nil
|
||||
}
|
||||
|
||||
|
@ -826,7 +901,7 @@ func (cc *ClientConn) healthCheck() {
|
|||
pingTimeout := cc.t.pingTimeout()
|
||||
// We don't need to periodically ping in the health check, because the readLoop of ClientConn will
|
||||
// trigger the healthCheck again if there is no frame received.
|
||||
ctx, cancel := context.WithTimeout(context.Background(), pingTimeout)
|
||||
ctx, cancel := cc.contextWithTimeout(context.Background(), pingTimeout)
|
||||
defer cancel()
|
||||
cc.vlogf("http2: Transport sending health check")
|
||||
err := cc.Ping(ctx)
|
||||
|
@ -1056,7 +1131,7 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error {
|
|||
// Wait for all in-flight streams to complete or connection to close
|
||||
done := make(chan struct{})
|
||||
cancelled := false // guarded by cc.mu
|
||||
go func() {
|
||||
cc.goRun(func() {
|
||||
cc.mu.Lock()
|
||||
defer cc.mu.Unlock()
|
||||
for {
|
||||
|
@ -1068,9 +1143,9 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error {
|
|||
if cancelled {
|
||||
break
|
||||
}
|
||||
cc.cond.Wait()
|
||||
cc.condWait()
|
||||
}
|
||||
}()
|
||||
})
|
||||
shutdownEnterWaitStateHook()
|
||||
select {
|
||||
case <-done:
|
||||
|
@ -1080,7 +1155,7 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error {
|
|||
cc.mu.Lock()
|
||||
// Free the goroutine above
|
||||
cancelled = true
|
||||
cc.cond.Broadcast()
|
||||
cc.condBroadcast()
|
||||
cc.mu.Unlock()
|
||||
return ctx.Err()
|
||||
}
|
||||
|
@ -1118,7 +1193,7 @@ func (cc *ClientConn) closeForError(err error) {
|
|||
for _, cs := range cc.streams {
|
||||
cs.abortStreamLocked(err)
|
||||
}
|
||||
cc.cond.Broadcast()
|
||||
cc.condBroadcast()
|
||||
cc.mu.Unlock()
|
||||
cc.closeConn()
|
||||
}
|
||||
|
@ -1215,6 +1290,10 @@ func (cc *ClientConn) decrStreamReservationsLocked() {
|
|||
}
|
||||
|
||||
func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
return cc.roundTrip(req, nil)
|
||||
}
|
||||
|
||||
func (cc *ClientConn) roundTrip(req *http.Request, streamf func(*clientStream)) (*http.Response, error) {
|
||||
ctx := req.Context()
|
||||
cs := &clientStream{
|
||||
cc: cc,
|
||||
|
@ -1229,9 +1308,23 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) {
|
|||
respHeaderRecv: make(chan struct{}),
|
||||
donec: make(chan struct{}),
|
||||
}
|
||||
go cs.doRequest(req)
|
||||
cc.goRun(func() {
|
||||
cs.doRequest(req)
|
||||
})
|
||||
|
||||
waitDone := func() error {
|
||||
if cc.syncHooks != nil {
|
||||
cc.syncHooks.blockUntil(func() bool {
|
||||
select {
|
||||
case <-cs.donec:
|
||||
case <-ctx.Done():
|
||||
case <-cs.reqCancel:
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
select {
|
||||
case <-cs.donec:
|
||||
return nil
|
||||
|
@ -1292,7 +1385,24 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) {
|
|||
return err
|
||||
}
|
||||
|
||||
if streamf != nil {
|
||||
streamf(cs)
|
||||
}
|
||||
|
||||
for {
|
||||
if cc.syncHooks != nil {
|
||||
cc.syncHooks.blockUntil(func() bool {
|
||||
select {
|
||||
case <-cs.respHeaderRecv:
|
||||
case <-cs.abort:
|
||||
case <-ctx.Done():
|
||||
case <-cs.reqCancel:
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
select {
|
||||
case <-cs.respHeaderRecv:
|
||||
return handleResponseHeaders()
|
||||
|
@ -1348,6 +1458,21 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) {
|
|||
if cc.reqHeaderMu == nil {
|
||||
panic("RoundTrip on uninitialized ClientConn") // for tests
|
||||
}
|
||||
var newStreamHook func(*clientStream)
|
||||
if cc.syncHooks != nil {
|
||||
newStreamHook = cc.syncHooks.newstream
|
||||
cc.syncHooks.blockUntil(func() bool {
|
||||
select {
|
||||
case cc.reqHeaderMu <- struct{}{}:
|
||||
<-cc.reqHeaderMu
|
||||
case <-cs.reqCancel:
|
||||
case <-ctx.Done():
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
select {
|
||||
case cc.reqHeaderMu <- struct{}{}:
|
||||
case <-cs.reqCancel:
|
||||
|
@ -1372,6 +1497,10 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) {
|
|||
}
|
||||
cc.mu.Unlock()
|
||||
|
||||
if newStreamHook != nil {
|
||||
newStreamHook(cs)
|
||||
}
|
||||
|
||||
// TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere?
|
||||
if !cc.t.disableCompression() &&
|
||||
req.Header.Get("Accept-Encoding") == "" &&
|
||||
|
@ -1452,15 +1581,30 @@ func (cs *clientStream) writeRequest(req *http.Request) (err error) {
|
|||
var respHeaderTimer <-chan time.Time
|
||||
var respHeaderRecv chan struct{}
|
||||
if d := cc.responseHeaderTimeout(); d != 0 {
|
||||
timer := time.NewTimer(d)
|
||||
timer := cc.newTimer(d)
|
||||
defer timer.Stop()
|
||||
respHeaderTimer = timer.C
|
||||
respHeaderTimer = timer.C()
|
||||
respHeaderRecv = cs.respHeaderRecv
|
||||
}
|
||||
// Wait until the peer half-closes its end of the stream,
|
||||
// or until the request is aborted (via context, error, or otherwise),
|
||||
// whichever comes first.
|
||||
for {
|
||||
if cc.syncHooks != nil {
|
||||
cc.syncHooks.blockUntil(func() bool {
|
||||
select {
|
||||
case <-cs.peerClosed:
|
||||
case <-respHeaderTimer:
|
||||
case <-respHeaderRecv:
|
||||
case <-cs.abort:
|
||||
case <-ctx.Done():
|
||||
case <-cs.reqCancel:
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
select {
|
||||
case <-cs.peerClosed:
|
||||
return nil
|
||||
|
@ -1609,7 +1753,7 @@ func (cc *ClientConn) awaitOpenSlotForStreamLocked(cs *clientStream) error {
|
|||
return nil
|
||||
}
|
||||
cc.pendingRequests++
|
||||
cc.cond.Wait()
|
||||
cc.condWait()
|
||||
cc.pendingRequests--
|
||||
select {
|
||||
case <-cs.abort:
|
||||
|
@ -1871,10 +2015,26 @@ func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error)
|
|||
cs.flow.take(take)
|
||||
return take, nil
|
||||
}
|
||||
cc.cond.Wait()
|
||||
cc.condWait()
|
||||
}
|
||||
}
|
||||
|
||||
func validateHeaders(hdrs http.Header) string {
|
||||
for k, vv := range hdrs {
|
||||
if !httpguts.ValidHeaderFieldName(k) {
|
||||
return fmt.Sprintf("name %q", k)
|
||||
}
|
||||
for _, v := range vv {
|
||||
if !httpguts.ValidHeaderFieldValue(v) {
|
||||
// Don't include the value in the error,
|
||||
// because it may be sensitive.
|
||||
return fmt.Sprintf("value for header %q", k)
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var errNilRequestURL = errors.New("http2: Request.URI is nil")
|
||||
|
||||
// requires cc.wmu be held.
|
||||
|
@ -1912,19 +2072,14 @@ func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trail
|
|||
}
|
||||
}
|
||||
|
||||
// Check for any invalid headers and return an error before we
|
||||
// Check for any invalid headers+trailers and return an error before we
|
||||
// potentially pollute our hpack state. (We want to be able to
|
||||
// continue to reuse the hpack encoder for future requests)
|
||||
for k, vv := range req.Header {
|
||||
if !httpguts.ValidHeaderFieldName(k) {
|
||||
return nil, fmt.Errorf("invalid HTTP header name %q", k)
|
||||
}
|
||||
for _, v := range vv {
|
||||
if !httpguts.ValidHeaderFieldValue(v) {
|
||||
// Don't include the value in the error, because it may be sensitive.
|
||||
return nil, fmt.Errorf("invalid HTTP header value for header %q", k)
|
||||
}
|
||||
}
|
||||
if err := validateHeaders(req.Header); err != "" {
|
||||
return nil, fmt.Errorf("invalid HTTP header %s", err)
|
||||
}
|
||||
if err := validateHeaders(req.Trailer); err != "" {
|
||||
return nil, fmt.Errorf("invalid HTTP trailer %s", err)
|
||||
}
|
||||
|
||||
enumerateHeaders := func(f func(name, value string)) {
|
||||
|
@ -2143,7 +2298,7 @@ func (cc *ClientConn) forgetStreamID(id uint32) {
|
|||
}
|
||||
// Wake up writeRequestBody via clientStream.awaitFlowControl and
|
||||
// wake up RoundTrip if there is a pending request.
|
||||
cc.cond.Broadcast()
|
||||
cc.condBroadcast()
|
||||
|
||||
closeOnIdle := cc.singleUse || cc.doNotReuse || cc.t.disableKeepAlives() || cc.goAway != nil
|
||||
if closeOnIdle && cc.streamsReserved == 0 && len(cc.streams) == 0 {
|
||||
|
@ -2231,7 +2386,7 @@ func (rl *clientConnReadLoop) cleanup() {
|
|||
cs.abortStreamLocked(err)
|
||||
}
|
||||
}
|
||||
cc.cond.Broadcast()
|
||||
cc.condBroadcast()
|
||||
cc.mu.Unlock()
|
||||
}
|
||||
|
||||
|
@ -2266,10 +2421,9 @@ func (rl *clientConnReadLoop) run() error {
|
|||
cc := rl.cc
|
||||
gotSettings := false
|
||||
readIdleTimeout := cc.t.ReadIdleTimeout
|
||||
var t *time.Timer
|
||||
var t timer
|
||||
if readIdleTimeout != 0 {
|
||||
t = time.AfterFunc(readIdleTimeout, cc.healthCheck)
|
||||
defer t.Stop()
|
||||
t = cc.afterFunc(readIdleTimeout, cc.healthCheck)
|
||||
}
|
||||
for {
|
||||
f, err := cc.fr.ReadFrame()
|
||||
|
@ -2684,7 +2838,7 @@ func (rl *clientConnReadLoop) processData(f *DataFrame) error {
|
|||
})
|
||||
return nil
|
||||
}
|
||||
if !cs.firstByte {
|
||||
if !cs.pastHeaders {
|
||||
cc.logf("protocol error: received DATA before a HEADERS frame")
|
||||
rl.endStreamError(cs, StreamError{
|
||||
StreamID: f.StreamID,
|
||||
|
@ -2867,7 +3021,7 @@ func (rl *clientConnReadLoop) processSettingsNoWrite(f *SettingsFrame) error {
|
|||
for _, cs := range cc.streams {
|
||||
cs.flow.add(delta)
|
||||
}
|
||||
cc.cond.Broadcast()
|
||||
cc.condBroadcast()
|
||||
|
||||
cc.initialWindowSize = s.Val
|
||||
case SettingHeaderTableSize:
|
||||
|
@ -2911,9 +3065,18 @@ func (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error {
|
|||
fl = &cs.flow
|
||||
}
|
||||
if !fl.add(int32(f.Increment)) {
|
||||
// For stream, the sender sends RST_STREAM with an error code of FLOW_CONTROL_ERROR
|
||||
if cs != nil {
|
||||
rl.endStreamError(cs, StreamError{
|
||||
StreamID: f.StreamID,
|
||||
Code: ErrCodeFlowControl,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
return ConnectionError(ErrCodeFlowControl)
|
||||
}
|
||||
cc.cond.Broadcast()
|
||||
cc.condBroadcast()
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -2955,24 +3118,38 @@ func (cc *ClientConn) Ping(ctx context.Context) error {
|
|||
}
|
||||
cc.mu.Unlock()
|
||||
}
|
||||
errc := make(chan error, 1)
|
||||
go func() {
|
||||
var pingError error
|
||||
errc := make(chan struct{})
|
||||
cc.goRun(func() {
|
||||
cc.wmu.Lock()
|
||||
defer cc.wmu.Unlock()
|
||||
if err := cc.fr.WritePing(false, p); err != nil {
|
||||
errc <- err
|
||||
if pingError = cc.fr.WritePing(false, p); pingError != nil {
|
||||
close(errc)
|
||||
return
|
||||
}
|
||||
if err := cc.bw.Flush(); err != nil {
|
||||
errc <- err
|
||||
if pingError = cc.bw.Flush(); pingError != nil {
|
||||
close(errc)
|
||||
return
|
||||
}
|
||||
}()
|
||||
})
|
||||
if cc.syncHooks != nil {
|
||||
cc.syncHooks.blockUntil(func() bool {
|
||||
select {
|
||||
case <-c:
|
||||
case <-errc:
|
||||
case <-ctx.Done():
|
||||
case <-cc.readerDone:
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
select {
|
||||
case <-c:
|
||||
return nil
|
||||
case err := <-errc:
|
||||
return err
|
||||
case <-errc:
|
||||
return pingError
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case <-cc.readerDone:
|
||||
|
@ -3141,9 +3318,17 @@ func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, err
|
|||
}
|
||||
|
||||
func (t *Transport) idleConnTimeout() time.Duration {
|
||||
// to keep things backwards compatible, we use non-zero values of
|
||||
// IdleConnTimeout, followed by using the IdleConnTimeout on the underlying
|
||||
// http1 transport, followed by 0
|
||||
if t.IdleConnTimeout != 0 {
|
||||
return t.IdleConnTimeout
|
||||
}
|
||||
|
||||
if t.t1 != nil {
|
||||
return t.t1.IdleConnTimeout
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos) && go1.9
|
||||
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos
|
||||
|
||||
package unix
|
||||
|
||||
|
|
|
@ -584,7 +584,7 @@ ccflags="$@"
|
|||
$2 ~ /^KEY_(SPEC|REQKEY_DEFL)_/ ||
|
||||
$2 ~ /^KEYCTL_/ ||
|
||||
$2 ~ /^PERF_/ ||
|
||||
$2 ~ /^SECCOMP_MODE_/ ||
|
||||
$2 ~ /^SECCOMP_/ ||
|
||||
$2 ~ /^SEEK_/ ||
|
||||
$2 ~ /^SCHED_/ ||
|
||||
$2 ~ /^SPLICE_/ ||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build darwin && go1.12
|
||||
//go:build darwin
|
||||
|
||||
package unix
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
package unix
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
"unsafe"
|
||||
)
|
||||
|
@ -169,25 +170,26 @@ func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
|
|||
func Uname(uname *Utsname) error {
|
||||
mib := []_C_int{CTL_KERN, KERN_OSTYPE}
|
||||
n := unsafe.Sizeof(uname.Sysname)
|
||||
if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil {
|
||||
// Suppress ENOMEM errors to be compatible with the C library __xuname() implementation.
|
||||
if err := sysctl(mib, &uname.Sysname[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {
|
||||
return err
|
||||
}
|
||||
|
||||
mib = []_C_int{CTL_KERN, KERN_HOSTNAME}
|
||||
n = unsafe.Sizeof(uname.Nodename)
|
||||
if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil {
|
||||
if err := sysctl(mib, &uname.Nodename[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {
|
||||
return err
|
||||
}
|
||||
|
||||
mib = []_C_int{CTL_KERN, KERN_OSRELEASE}
|
||||
n = unsafe.Sizeof(uname.Release)
|
||||
if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil {
|
||||
if err := sysctl(mib, &uname.Release[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {
|
||||
return err
|
||||
}
|
||||
|
||||
mib = []_C_int{CTL_KERN, KERN_VERSION}
|
||||
n = unsafe.Sizeof(uname.Version)
|
||||
if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil {
|
||||
if err := sysctl(mib, &uname.Version[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -205,7 +207,7 @@ func Uname(uname *Utsname) error {
|
|||
|
||||
mib = []_C_int{CTL_HW, HW_MACHINE}
|
||||
n = unsafe.Sizeof(uname.Machine)
|
||||
if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil {
|
||||
if err := sysctl(mib, &uname.Machine[0], &n, nil, 0); err != nil && !errors.Is(err, ENOMEM) {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -1849,6 +1849,105 @@ func Dup2(oldfd, newfd int) error {
|
|||
//sys Fsmount(fd int, flags int, mountAttrs int) (fsfd int, err error)
|
||||
//sys Fsopen(fsName string, flags int) (fd int, err error)
|
||||
//sys Fspick(dirfd int, pathName string, flags int) (fd int, err error)
|
||||
|
||||
//sys fsconfig(fd int, cmd uint, key *byte, value *byte, aux int) (err error)
|
||||
|
||||
func fsconfigCommon(fd int, cmd uint, key string, value *byte, aux int) (err error) {
|
||||
var keyp *byte
|
||||
if keyp, err = BytePtrFromString(key); err != nil {
|
||||
return
|
||||
}
|
||||
return fsconfig(fd, cmd, keyp, value, aux)
|
||||
}
|
||||
|
||||
// FsconfigSetFlag is equivalent to fsconfig(2) called
|
||||
// with cmd == FSCONFIG_SET_FLAG.
|
||||
//
|
||||
// fd is the filesystem context to act upon.
|
||||
// key the parameter key to set.
|
||||
func FsconfigSetFlag(fd int, key string) (err error) {
|
||||
return fsconfigCommon(fd, FSCONFIG_SET_FLAG, key, nil, 0)
|
||||
}
|
||||
|
||||
// FsconfigSetString is equivalent to fsconfig(2) called
|
||||
// with cmd == FSCONFIG_SET_STRING.
|
||||
//
|
||||
// fd is the filesystem context to act upon.
|
||||
// key the parameter key to set.
|
||||
// value is the parameter value to set.
|
||||
func FsconfigSetString(fd int, key string, value string) (err error) {
|
||||
var valuep *byte
|
||||
if valuep, err = BytePtrFromString(value); err != nil {
|
||||
return
|
||||
}
|
||||
return fsconfigCommon(fd, FSCONFIG_SET_STRING, key, valuep, 0)
|
||||
}
|
||||
|
||||
// FsconfigSetBinary is equivalent to fsconfig(2) called
|
||||
// with cmd == FSCONFIG_SET_BINARY.
|
||||
//
|
||||
// fd is the filesystem context to act upon.
|
||||
// key the parameter key to set.
|
||||
// value is the parameter value to set.
|
||||
func FsconfigSetBinary(fd int, key string, value []byte) (err error) {
|
||||
if len(value) == 0 {
|
||||
return EINVAL
|
||||
}
|
||||
return fsconfigCommon(fd, FSCONFIG_SET_BINARY, key, &value[0], len(value))
|
||||
}
|
||||
|
||||
// FsconfigSetPath is equivalent to fsconfig(2) called
|
||||
// with cmd == FSCONFIG_SET_PATH.
|
||||
//
|
||||
// fd is the filesystem context to act upon.
|
||||
// key the parameter key to set.
|
||||
// path is a non-empty path for specified key.
|
||||
// atfd is a file descriptor at which to start lookup from or AT_FDCWD.
|
||||
func FsconfigSetPath(fd int, key string, path string, atfd int) (err error) {
|
||||
var valuep *byte
|
||||
if valuep, err = BytePtrFromString(path); err != nil {
|
||||
return
|
||||
}
|
||||
return fsconfigCommon(fd, FSCONFIG_SET_PATH, key, valuep, atfd)
|
||||
}
|
||||
|
||||
// FsconfigSetPathEmpty is equivalent to fsconfig(2) called
|
||||
// with cmd == FSCONFIG_SET_PATH_EMPTY. The same as
|
||||
// FconfigSetPath but with AT_PATH_EMPTY implied.
|
||||
func FsconfigSetPathEmpty(fd int, key string, path string, atfd int) (err error) {
|
||||
var valuep *byte
|
||||
if valuep, err = BytePtrFromString(path); err != nil {
|
||||
return
|
||||
}
|
||||
return fsconfigCommon(fd, FSCONFIG_SET_PATH_EMPTY, key, valuep, atfd)
|
||||
}
|
||||
|
||||
// FsconfigSetFd is equivalent to fsconfig(2) called
|
||||
// with cmd == FSCONFIG_SET_FD.
|
||||
//
|
||||
// fd is the filesystem context to act upon.
|
||||
// key the parameter key to set.
|
||||
// value is a file descriptor to be assigned to specified key.
|
||||
func FsconfigSetFd(fd int, key string, value int) (err error) {
|
||||
return fsconfigCommon(fd, FSCONFIG_SET_FD, key, nil, value)
|
||||
}
|
||||
|
||||
// FsconfigCreate is equivalent to fsconfig(2) called
|
||||
// with cmd == FSCONFIG_CMD_CREATE.
|
||||
//
|
||||
// fd is the filesystem context to act upon.
|
||||
func FsconfigCreate(fd int) (err error) {
|
||||
return fsconfig(fd, FSCONFIG_CMD_CREATE, nil, nil, 0)
|
||||
}
|
||||
|
||||
// FsconfigReconfigure is equivalent to fsconfig(2) called
|
||||
// with cmd == FSCONFIG_CMD_RECONFIGURE.
|
||||
//
|
||||
// fd is the filesystem context to act upon.
|
||||
func FsconfigReconfigure(fd int) (err error) {
|
||||
return fsconfig(fd, FSCONFIG_CMD_RECONFIGURE, nil, nil, 0)
|
||||
}
|
||||
|
||||
//sys Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64
|
||||
//sysnb Getpgid(pid int) (pgid int, err error)
|
||||
|
||||
|
|
|
@ -1785,6 +1785,8 @@ const (
|
|||
LANDLOCK_ACCESS_FS_REMOVE_FILE = 0x20
|
||||
LANDLOCK_ACCESS_FS_TRUNCATE = 0x4000
|
||||
LANDLOCK_ACCESS_FS_WRITE_FILE = 0x2
|
||||
LANDLOCK_ACCESS_NET_BIND_TCP = 0x1
|
||||
LANDLOCK_ACCESS_NET_CONNECT_TCP = 0x2
|
||||
LANDLOCK_CREATE_RULESET_VERSION = 0x1
|
||||
LINUX_REBOOT_CMD_CAD_OFF = 0x0
|
||||
LINUX_REBOOT_CMD_CAD_ON = 0x89abcdef
|
||||
|
@ -2465,6 +2467,7 @@ const (
|
|||
PR_MCE_KILL_GET = 0x22
|
||||
PR_MCE_KILL_LATE = 0x0
|
||||
PR_MCE_KILL_SET = 0x1
|
||||
PR_MDWE_NO_INHERIT = 0x2
|
||||
PR_MDWE_REFUSE_EXEC_GAIN = 0x1
|
||||
PR_MPX_DISABLE_MANAGEMENT = 0x2c
|
||||
PR_MPX_ENABLE_MANAGEMENT = 0x2b
|
||||
|
@ -2669,8 +2672,9 @@ const (
|
|||
RTAX_FEATURES = 0xc
|
||||
RTAX_FEATURE_ALLFRAG = 0x8
|
||||
RTAX_FEATURE_ECN = 0x1
|
||||
RTAX_FEATURE_MASK = 0xf
|
||||
RTAX_FEATURE_MASK = 0x1f
|
||||
RTAX_FEATURE_SACK = 0x2
|
||||
RTAX_FEATURE_TCP_USEC_TS = 0x10
|
||||
RTAX_FEATURE_TIMESTAMP = 0x4
|
||||
RTAX_HOPLIMIT = 0xa
|
||||
RTAX_INITCWND = 0xb
|
||||
|
@ -2913,9 +2917,38 @@ const (
|
|||
SCM_RIGHTS = 0x1
|
||||
SCM_TIMESTAMP = 0x1d
|
||||
SC_LOG_FLUSH = 0x100000
|
||||
SECCOMP_ADDFD_FLAG_SEND = 0x2
|
||||
SECCOMP_ADDFD_FLAG_SETFD = 0x1
|
||||
SECCOMP_FILTER_FLAG_LOG = 0x2
|
||||
SECCOMP_FILTER_FLAG_NEW_LISTENER = 0x8
|
||||
SECCOMP_FILTER_FLAG_SPEC_ALLOW = 0x4
|
||||
SECCOMP_FILTER_FLAG_TSYNC = 0x1
|
||||
SECCOMP_FILTER_FLAG_TSYNC_ESRCH = 0x10
|
||||
SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV = 0x20
|
||||
SECCOMP_GET_ACTION_AVAIL = 0x2
|
||||
SECCOMP_GET_NOTIF_SIZES = 0x3
|
||||
SECCOMP_IOCTL_NOTIF_RECV = 0xc0502100
|
||||
SECCOMP_IOCTL_NOTIF_SEND = 0xc0182101
|
||||
SECCOMP_IOC_MAGIC = '!'
|
||||
SECCOMP_MODE_DISABLED = 0x0
|
||||
SECCOMP_MODE_FILTER = 0x2
|
||||
SECCOMP_MODE_STRICT = 0x1
|
||||
SECCOMP_RET_ACTION = 0x7fff0000
|
||||
SECCOMP_RET_ACTION_FULL = 0xffff0000
|
||||
SECCOMP_RET_ALLOW = 0x7fff0000
|
||||
SECCOMP_RET_DATA = 0xffff
|
||||
SECCOMP_RET_ERRNO = 0x50000
|
||||
SECCOMP_RET_KILL = 0x0
|
||||
SECCOMP_RET_KILL_PROCESS = 0x80000000
|
||||
SECCOMP_RET_KILL_THREAD = 0x0
|
||||
SECCOMP_RET_LOG = 0x7ffc0000
|
||||
SECCOMP_RET_TRACE = 0x7ff00000
|
||||
SECCOMP_RET_TRAP = 0x30000
|
||||
SECCOMP_RET_USER_NOTIF = 0x7fc00000
|
||||
SECCOMP_SET_MODE_FILTER = 0x1
|
||||
SECCOMP_SET_MODE_STRICT = 0x0
|
||||
SECCOMP_USER_NOTIF_FD_SYNC_WAKE_UP = 0x1
|
||||
SECCOMP_USER_NOTIF_FLAG_CONTINUE = 0x1
|
||||
SECRETMEM_MAGIC = 0x5345434d
|
||||
SECURITYFS_MAGIC = 0x73636673
|
||||
SEEK_CUR = 0x1
|
||||
|
@ -3075,6 +3108,7 @@ const (
|
|||
SOL_TIPC = 0x10f
|
||||
SOL_TLS = 0x11a
|
||||
SOL_UDP = 0x11
|
||||
SOL_VSOCK = 0x11f
|
||||
SOL_X25 = 0x106
|
||||
SOL_XDP = 0x11b
|
||||
SOMAXCONN = 0x1000
|
||||
|
|
|
@ -281,6 +281,9 @@ const (
|
|||
SCM_TIMESTAMPNS = 0x23
|
||||
SCM_TXTIME = 0x3d
|
||||
SCM_WIFI_STATUS = 0x29
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102
|
||||
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
|
||||
SFD_CLOEXEC = 0x80000
|
||||
SFD_NONBLOCK = 0x800
|
||||
SIOCATMARK = 0x8905
|
||||
|
|
|
@ -282,6 +282,9 @@ const (
|
|||
SCM_TIMESTAMPNS = 0x23
|
||||
SCM_TXTIME = 0x3d
|
||||
SCM_WIFI_STATUS = 0x29
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102
|
||||
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
|
||||
SFD_CLOEXEC = 0x80000
|
||||
SFD_NONBLOCK = 0x800
|
||||
SIOCATMARK = 0x8905
|
||||
|
|
|
@ -288,6 +288,9 @@ const (
|
|||
SCM_TIMESTAMPNS = 0x23
|
||||
SCM_TXTIME = 0x3d
|
||||
SCM_WIFI_STATUS = 0x29
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102
|
||||
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
|
||||
SFD_CLOEXEC = 0x80000
|
||||
SFD_NONBLOCK = 0x800
|
||||
SIOCATMARK = 0x8905
|
||||
|
|
|
@ -278,6 +278,9 @@ const (
|
|||
SCM_TIMESTAMPNS = 0x23
|
||||
SCM_TXTIME = 0x3d
|
||||
SCM_WIFI_STATUS = 0x29
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102
|
||||
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
|
||||
SFD_CLOEXEC = 0x80000
|
||||
SFD_NONBLOCK = 0x800
|
||||
SIOCATMARK = 0x8905
|
||||
|
|
|
@ -275,6 +275,9 @@ const (
|
|||
SCM_TIMESTAMPNS = 0x23
|
||||
SCM_TXTIME = 0x3d
|
||||
SCM_WIFI_STATUS = 0x29
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102
|
||||
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
|
||||
SFD_CLOEXEC = 0x80000
|
||||
SFD_NONBLOCK = 0x800
|
||||
SIOCATMARK = 0x8905
|
||||
|
|
|
@ -281,6 +281,9 @@ const (
|
|||
SCM_TIMESTAMPNS = 0x23
|
||||
SCM_TXTIME = 0x3d
|
||||
SCM_WIFI_STATUS = 0x29
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
|
||||
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
|
||||
SFD_CLOEXEC = 0x80000
|
||||
SFD_NONBLOCK = 0x80
|
||||
SIOCATMARK = 0x40047307
|
||||
|
|
|
@ -281,6 +281,9 @@ const (
|
|||
SCM_TIMESTAMPNS = 0x23
|
||||
SCM_TXTIME = 0x3d
|
||||
SCM_WIFI_STATUS = 0x29
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
|
||||
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
|
||||
SFD_CLOEXEC = 0x80000
|
||||
SFD_NONBLOCK = 0x80
|
||||
SIOCATMARK = 0x40047307
|
||||
|
|
|
@ -281,6 +281,9 @@ const (
|
|||
SCM_TIMESTAMPNS = 0x23
|
||||
SCM_TXTIME = 0x3d
|
||||
SCM_WIFI_STATUS = 0x29
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
|
||||
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
|
||||
SFD_CLOEXEC = 0x80000
|
||||
SFD_NONBLOCK = 0x80
|
||||
SIOCATMARK = 0x40047307
|
||||
|
|
|
@ -281,6 +281,9 @@ const (
|
|||
SCM_TIMESTAMPNS = 0x23
|
||||
SCM_TXTIME = 0x3d
|
||||
SCM_WIFI_STATUS = 0x29
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
|
||||
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
|
||||
SFD_CLOEXEC = 0x80000
|
||||
SFD_NONBLOCK = 0x80
|
||||
SIOCATMARK = 0x40047307
|
||||
|
|
|
@ -336,6 +336,9 @@ const (
|
|||
SCM_TIMESTAMPNS = 0x23
|
||||
SCM_TXTIME = 0x3d
|
||||
SCM_WIFI_STATUS = 0x29
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
|
||||
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
|
||||
SFD_CLOEXEC = 0x80000
|
||||
SFD_NONBLOCK = 0x800
|
||||
SIOCATMARK = 0x8905
|
||||
|
|
|
@ -340,6 +340,9 @@ const (
|
|||
SCM_TIMESTAMPNS = 0x23
|
||||
SCM_TXTIME = 0x3d
|
||||
SCM_WIFI_STATUS = 0x29
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
|
||||
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
|
||||
SFD_CLOEXEC = 0x80000
|
||||
SFD_NONBLOCK = 0x800
|
||||
SIOCATMARK = 0x8905
|
||||
|
|
|
@ -340,6 +340,9 @@ const (
|
|||
SCM_TIMESTAMPNS = 0x23
|
||||
SCM_TXTIME = 0x3d
|
||||
SCM_WIFI_STATUS = 0x29
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
|
||||
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
|
||||
SFD_CLOEXEC = 0x80000
|
||||
SFD_NONBLOCK = 0x800
|
||||
SIOCATMARK = 0x8905
|
||||
|
|
|
@ -272,6 +272,9 @@ const (
|
|||
SCM_TIMESTAMPNS = 0x23
|
||||
SCM_TXTIME = 0x3d
|
||||
SCM_WIFI_STATUS = 0x29
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102
|
||||
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
|
||||
SFD_CLOEXEC = 0x80000
|
||||
SFD_NONBLOCK = 0x800
|
||||
SIOCATMARK = 0x8905
|
||||
|
|
|
@ -344,6 +344,9 @@ const (
|
|||
SCM_TIMESTAMPNS = 0x23
|
||||
SCM_TXTIME = 0x3d
|
||||
SCM_WIFI_STATUS = 0x29
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102
|
||||
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
|
||||
SFD_CLOEXEC = 0x80000
|
||||
SFD_NONBLOCK = 0x800
|
||||
SIOCATMARK = 0x8905
|
||||
|
|
|
@ -335,6 +335,9 @@ const (
|
|||
SCM_TIMESTAMPNS = 0x21
|
||||
SCM_TXTIME = 0x3f
|
||||
SCM_WIFI_STATUS = 0x25
|
||||
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
|
||||
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
|
||||
SFD_CLOEXEC = 0x400000
|
||||
SFD_NONBLOCK = 0x4000
|
||||
SF_FP = 0x38
|
||||
|
|
|
@ -906,6 +906,16 @@ func Fspick(dirfd int, pathName string, flags int) (fd int, err error) {
|
|||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func fsconfig(fd int, cmd uint, key *byte, value *byte, aux int) (err error) {
|
||||
_, _, e1 := Syscall6(SYS_FSCONFIG, uintptr(fd), uintptr(cmd), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(value)), uintptr(aux), 0)
|
||||
if e1 != 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func Getdents(fd int, buf []byte) (n int, err error) {
|
||||
var _p0 unsafe.Pointer
|
||||
if len(buf) > 0 {
|
||||
|
|
|
@ -448,4 +448,8 @@ const (
|
|||
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
||||
SYS_CACHESTAT = 451
|
||||
SYS_FCHMODAT2 = 452
|
||||
SYS_MAP_SHADOW_STACK = 453
|
||||
SYS_FUTEX_WAKE = 454
|
||||
SYS_FUTEX_WAIT = 455
|
||||
SYS_FUTEX_REQUEUE = 456
|
||||
)
|
||||
|
|
|
@ -371,4 +371,7 @@ const (
|
|||
SYS_CACHESTAT = 451
|
||||
SYS_FCHMODAT2 = 452
|
||||
SYS_MAP_SHADOW_STACK = 453
|
||||
SYS_FUTEX_WAKE = 454
|
||||
SYS_FUTEX_WAIT = 455
|
||||
SYS_FUTEX_REQUEUE = 456
|
||||
)
|
||||
|
|
|
@ -412,4 +412,8 @@ const (
|
|||
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
||||
SYS_CACHESTAT = 451
|
||||
SYS_FCHMODAT2 = 452
|
||||
SYS_MAP_SHADOW_STACK = 453
|
||||
SYS_FUTEX_WAKE = 454
|
||||
SYS_FUTEX_WAIT = 455
|
||||
SYS_FUTEX_REQUEUE = 456
|
||||
)
|
||||
|
|
|
@ -315,4 +315,8 @@ const (
|
|||
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
||||
SYS_CACHESTAT = 451
|
||||
SYS_FCHMODAT2 = 452
|
||||
SYS_MAP_SHADOW_STACK = 453
|
||||
SYS_FUTEX_WAKE = 454
|
||||
SYS_FUTEX_WAIT = 455
|
||||
SYS_FUTEX_REQUEUE = 456
|
||||
)
|
||||
|
|
|
@ -309,4 +309,8 @@ const (
|
|||
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
||||
SYS_CACHESTAT = 451
|
||||
SYS_FCHMODAT2 = 452
|
||||
SYS_MAP_SHADOW_STACK = 453
|
||||
SYS_FUTEX_WAKE = 454
|
||||
SYS_FUTEX_WAIT = 455
|
||||
SYS_FUTEX_REQUEUE = 456
|
||||
)
|
||||
|
|
|
@ -432,4 +432,8 @@ const (
|
|||
SYS_SET_MEMPOLICY_HOME_NODE = 4450
|
||||
SYS_CACHESTAT = 4451
|
||||
SYS_FCHMODAT2 = 4452
|
||||
SYS_MAP_SHADOW_STACK = 4453
|
||||
SYS_FUTEX_WAKE = 4454
|
||||
SYS_FUTEX_WAIT = 4455
|
||||
SYS_FUTEX_REQUEUE = 4456
|
||||
)
|
||||
|
|
|
@ -362,4 +362,8 @@ const (
|
|||
SYS_SET_MEMPOLICY_HOME_NODE = 5450
|
||||
SYS_CACHESTAT = 5451
|
||||
SYS_FCHMODAT2 = 5452
|
||||
SYS_MAP_SHADOW_STACK = 5453
|
||||
SYS_FUTEX_WAKE = 5454
|
||||
SYS_FUTEX_WAIT = 5455
|
||||
SYS_FUTEX_REQUEUE = 5456
|
||||
)
|
||||
|
|
|
@ -362,4 +362,8 @@ const (
|
|||
SYS_SET_MEMPOLICY_HOME_NODE = 5450
|
||||
SYS_CACHESTAT = 5451
|
||||
SYS_FCHMODAT2 = 5452
|
||||
SYS_MAP_SHADOW_STACK = 5453
|
||||
SYS_FUTEX_WAKE = 5454
|
||||
SYS_FUTEX_WAIT = 5455
|
||||
SYS_FUTEX_REQUEUE = 5456
|
||||
)
|
||||
|
|
|
@ -432,4 +432,8 @@ const (
|
|||
SYS_SET_MEMPOLICY_HOME_NODE = 4450
|
||||
SYS_CACHESTAT = 4451
|
||||
SYS_FCHMODAT2 = 4452
|
||||
SYS_MAP_SHADOW_STACK = 4453
|
||||
SYS_FUTEX_WAKE = 4454
|
||||
SYS_FUTEX_WAIT = 4455
|
||||
SYS_FUTEX_REQUEUE = 4456
|
||||
)
|
||||
|
|
|
@ -439,4 +439,8 @@ const (
|
|||
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
||||
SYS_CACHESTAT = 451
|
||||
SYS_FCHMODAT2 = 452
|
||||
SYS_MAP_SHADOW_STACK = 453
|
||||
SYS_FUTEX_WAKE = 454
|
||||
SYS_FUTEX_WAIT = 455
|
||||
SYS_FUTEX_REQUEUE = 456
|
||||
)
|
||||
|
|
|
@ -411,4 +411,8 @@ const (
|
|||
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
||||
SYS_CACHESTAT = 451
|
||||
SYS_FCHMODAT2 = 452
|
||||
SYS_MAP_SHADOW_STACK = 453
|
||||
SYS_FUTEX_WAKE = 454
|
||||
SYS_FUTEX_WAIT = 455
|
||||
SYS_FUTEX_REQUEUE = 456
|
||||
)
|
||||
|
|
|
@ -411,4 +411,8 @@ const (
|
|||
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
||||
SYS_CACHESTAT = 451
|
||||
SYS_FCHMODAT2 = 452
|
||||
SYS_MAP_SHADOW_STACK = 453
|
||||
SYS_FUTEX_WAKE = 454
|
||||
SYS_FUTEX_WAIT = 455
|
||||
SYS_FUTEX_REQUEUE = 456
|
||||
)
|
||||
|
|
|
@ -316,4 +316,8 @@ const (
|
|||
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
||||
SYS_CACHESTAT = 451
|
||||
SYS_FCHMODAT2 = 452
|
||||
SYS_MAP_SHADOW_STACK = 453
|
||||
SYS_FUTEX_WAKE = 454
|
||||
SYS_FUTEX_WAIT = 455
|
||||
SYS_FUTEX_REQUEUE = 456
|
||||
)
|
||||
|
|
|
@ -377,4 +377,8 @@ const (
|
|||
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
||||
SYS_CACHESTAT = 451
|
||||
SYS_FCHMODAT2 = 452
|
||||
SYS_MAP_SHADOW_STACK = 453
|
||||
SYS_FUTEX_WAKE = 454
|
||||
SYS_FUTEX_WAIT = 455
|
||||
SYS_FUTEX_REQUEUE = 456
|
||||
)
|
||||
|
|
|
@ -390,4 +390,8 @@ const (
|
|||
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
||||
SYS_CACHESTAT = 451
|
||||
SYS_FCHMODAT2 = 452
|
||||
SYS_MAP_SHADOW_STACK = 453
|
||||
SYS_FUTEX_WAKE = 454
|
||||
SYS_FUTEX_WAIT = 455
|
||||
SYS_FUTEX_REQUEUE = 456
|
||||
)
|
||||
|
|
|
@ -174,7 +174,8 @@ type FscryptPolicyV2 struct {
|
|||
Contents_encryption_mode uint8
|
||||
Filenames_encryption_mode uint8
|
||||
Flags uint8
|
||||
_ [4]uint8
|
||||
Log2_data_unit_size uint8
|
||||
_ [3]uint8
|
||||
Master_key_identifier [16]uint8
|
||||
}
|
||||
|
||||
|
@ -455,60 +456,63 @@ type Ucred struct {
|
|||
}
|
||||
|
||||
type TCPInfo struct {
|
||||
State uint8
|
||||
Ca_state uint8
|
||||
Retransmits uint8
|
||||
Probes uint8
|
||||
Backoff uint8
|
||||
Options uint8
|
||||
Rto uint32
|
||||
Ato uint32
|
||||
Snd_mss uint32
|
||||
Rcv_mss uint32
|
||||
Unacked uint32
|
||||
Sacked uint32
|
||||
Lost uint32
|
||||
Retrans uint32
|
||||
Fackets uint32
|
||||
Last_data_sent uint32
|
||||
Last_ack_sent uint32
|
||||
Last_data_recv uint32
|
||||
Last_ack_recv uint32
|
||||
Pmtu uint32
|
||||
Rcv_ssthresh uint32
|
||||
Rtt uint32
|
||||
Rttvar uint32
|
||||
Snd_ssthresh uint32
|
||||
Snd_cwnd uint32
|
||||
Advmss uint32
|
||||
Reordering uint32
|
||||
Rcv_rtt uint32
|
||||
Rcv_space uint32
|
||||
Total_retrans uint32
|
||||
Pacing_rate uint64
|
||||
Max_pacing_rate uint64
|
||||
Bytes_acked uint64
|
||||
Bytes_received uint64
|
||||
Segs_out uint32
|
||||
Segs_in uint32
|
||||
Notsent_bytes uint32
|
||||
Min_rtt uint32
|
||||
Data_segs_in uint32
|
||||
Data_segs_out uint32
|
||||
Delivery_rate uint64
|
||||
Busy_time uint64
|
||||
Rwnd_limited uint64
|
||||
Sndbuf_limited uint64
|
||||
Delivered uint32
|
||||
Delivered_ce uint32
|
||||
Bytes_sent uint64
|
||||
Bytes_retrans uint64
|
||||
Dsack_dups uint32
|
||||
Reord_seen uint32
|
||||
Rcv_ooopack uint32
|
||||
Snd_wnd uint32
|
||||
Rcv_wnd uint32
|
||||
Rehash uint32
|
||||
State uint8
|
||||
Ca_state uint8
|
||||
Retransmits uint8
|
||||
Probes uint8
|
||||
Backoff uint8
|
||||
Options uint8
|
||||
Rto uint32
|
||||
Ato uint32
|
||||
Snd_mss uint32
|
||||
Rcv_mss uint32
|
||||
Unacked uint32
|
||||
Sacked uint32
|
||||
Lost uint32
|
||||
Retrans uint32
|
||||
Fackets uint32
|
||||
Last_data_sent uint32
|
||||
Last_ack_sent uint32
|
||||
Last_data_recv uint32
|
||||
Last_ack_recv uint32
|
||||
Pmtu uint32
|
||||
Rcv_ssthresh uint32
|
||||
Rtt uint32
|
||||
Rttvar uint32
|
||||
Snd_ssthresh uint32
|
||||
Snd_cwnd uint32
|
||||
Advmss uint32
|
||||
Reordering uint32
|
||||
Rcv_rtt uint32
|
||||
Rcv_space uint32
|
||||
Total_retrans uint32
|
||||
Pacing_rate uint64
|
||||
Max_pacing_rate uint64
|
||||
Bytes_acked uint64
|
||||
Bytes_received uint64
|
||||
Segs_out uint32
|
||||
Segs_in uint32
|
||||
Notsent_bytes uint32
|
||||
Min_rtt uint32
|
||||
Data_segs_in uint32
|
||||
Data_segs_out uint32
|
||||
Delivery_rate uint64
|
||||
Busy_time uint64
|
||||
Rwnd_limited uint64
|
||||
Sndbuf_limited uint64
|
||||
Delivered uint32
|
||||
Delivered_ce uint32
|
||||
Bytes_sent uint64
|
||||
Bytes_retrans uint64
|
||||
Dsack_dups uint32
|
||||
Reord_seen uint32
|
||||
Rcv_ooopack uint32
|
||||
Snd_wnd uint32
|
||||
Rcv_wnd uint32
|
||||
Rehash uint32
|
||||
Total_rto uint16
|
||||
Total_rto_recoveries uint16
|
||||
Total_rto_time uint32
|
||||
}
|
||||
|
||||
type CanFilter struct {
|
||||
|
@ -551,7 +555,7 @@ const (
|
|||
SizeofIPv6MTUInfo = 0x20
|
||||
SizeofICMPv6Filter = 0x20
|
||||
SizeofUcred = 0xc
|
||||
SizeofTCPInfo = 0xf0
|
||||
SizeofTCPInfo = 0xf8
|
||||
SizeofCanFilter = 0x8
|
||||
SizeofTCPRepairOpt = 0x8
|
||||
)
|
||||
|
@ -832,6 +836,15 @@ const (
|
|||
FSPICK_EMPTY_PATH = 0x8
|
||||
|
||||
FSMOUNT_CLOEXEC = 0x1
|
||||
|
||||
FSCONFIG_SET_FLAG = 0x0
|
||||
FSCONFIG_SET_STRING = 0x1
|
||||
FSCONFIG_SET_BINARY = 0x2
|
||||
FSCONFIG_SET_PATH = 0x3
|
||||
FSCONFIG_SET_PATH_EMPTY = 0x4
|
||||
FSCONFIG_SET_FD = 0x5
|
||||
FSCONFIG_CMD_CREATE = 0x6
|
||||
FSCONFIG_CMD_RECONFIGURE = 0x7
|
||||
)
|
||||
|
||||
type OpenHow struct {
|
||||
|
@ -1546,6 +1559,7 @@ const (
|
|||
IFLA_DEVLINK_PORT = 0x3e
|
||||
IFLA_GSO_IPV4_MAX_SIZE = 0x3f
|
||||
IFLA_GRO_IPV4_MAX_SIZE = 0x40
|
||||
IFLA_DPLL_PIN = 0x41
|
||||
IFLA_PROTO_DOWN_REASON_UNSPEC = 0x0
|
||||
IFLA_PROTO_DOWN_REASON_MASK = 0x1
|
||||
IFLA_PROTO_DOWN_REASON_VALUE = 0x2
|
||||
|
@ -1561,6 +1575,7 @@ const (
|
|||
IFLA_INET6_ICMP6STATS = 0x6
|
||||
IFLA_INET6_TOKEN = 0x7
|
||||
IFLA_INET6_ADDR_GEN_MODE = 0x8
|
||||
IFLA_INET6_RA_MTU = 0x9
|
||||
IFLA_BR_UNSPEC = 0x0
|
||||
IFLA_BR_FORWARD_DELAY = 0x1
|
||||
IFLA_BR_HELLO_TIME = 0x2
|
||||
|
@ -1608,6 +1623,9 @@ const (
|
|||
IFLA_BR_MCAST_MLD_VERSION = 0x2c
|
||||
IFLA_BR_VLAN_STATS_PER_PORT = 0x2d
|
||||
IFLA_BR_MULTI_BOOLOPT = 0x2e
|
||||
IFLA_BR_MCAST_QUERIER_STATE = 0x2f
|
||||
IFLA_BR_FDB_N_LEARNED = 0x30
|
||||
IFLA_BR_FDB_MAX_LEARNED = 0x31
|
||||
IFLA_BRPORT_UNSPEC = 0x0
|
||||
IFLA_BRPORT_STATE = 0x1
|
||||
IFLA_BRPORT_PRIORITY = 0x2
|
||||
|
@ -1645,6 +1663,14 @@ const (
|
|||
IFLA_BRPORT_BACKUP_PORT = 0x22
|
||||
IFLA_BRPORT_MRP_RING_OPEN = 0x23
|
||||
IFLA_BRPORT_MRP_IN_OPEN = 0x24
|
||||
IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT = 0x25
|
||||
IFLA_BRPORT_MCAST_EHT_HOSTS_CNT = 0x26
|
||||
IFLA_BRPORT_LOCKED = 0x27
|
||||
IFLA_BRPORT_MAB = 0x28
|
||||
IFLA_BRPORT_MCAST_N_GROUPS = 0x29
|
||||
IFLA_BRPORT_MCAST_MAX_GROUPS = 0x2a
|
||||
IFLA_BRPORT_NEIGH_VLAN_SUPPRESS = 0x2b
|
||||
IFLA_BRPORT_BACKUP_NHID = 0x2c
|
||||
IFLA_INFO_UNSPEC = 0x0
|
||||
IFLA_INFO_KIND = 0x1
|
||||
IFLA_INFO_DATA = 0x2
|
||||
|
@ -1666,6 +1692,9 @@ const (
|
|||
IFLA_MACVLAN_MACADDR = 0x4
|
||||
IFLA_MACVLAN_MACADDR_DATA = 0x5
|
||||
IFLA_MACVLAN_MACADDR_COUNT = 0x6
|
||||
IFLA_MACVLAN_BC_QUEUE_LEN = 0x7
|
||||
IFLA_MACVLAN_BC_QUEUE_LEN_USED = 0x8
|
||||
IFLA_MACVLAN_BC_CUTOFF = 0x9
|
||||
IFLA_VRF_UNSPEC = 0x0
|
||||
IFLA_VRF_TABLE = 0x1
|
||||
IFLA_VRF_PORT_UNSPEC = 0x0
|
||||
|
@ -1689,9 +1718,22 @@ const (
|
|||
IFLA_XFRM_UNSPEC = 0x0
|
||||
IFLA_XFRM_LINK = 0x1
|
||||
IFLA_XFRM_IF_ID = 0x2
|
||||
IFLA_XFRM_COLLECT_METADATA = 0x3
|
||||
IFLA_IPVLAN_UNSPEC = 0x0
|
||||
IFLA_IPVLAN_MODE = 0x1
|
||||
IFLA_IPVLAN_FLAGS = 0x2
|
||||
NETKIT_NEXT = -0x1
|
||||
NETKIT_PASS = 0x0
|
||||
NETKIT_DROP = 0x2
|
||||
NETKIT_REDIRECT = 0x7
|
||||
NETKIT_L2 = 0x0
|
||||
NETKIT_L3 = 0x1
|
||||
IFLA_NETKIT_UNSPEC = 0x0
|
||||
IFLA_NETKIT_PEER_INFO = 0x1
|
||||
IFLA_NETKIT_PRIMARY = 0x2
|
||||
IFLA_NETKIT_POLICY = 0x3
|
||||
IFLA_NETKIT_PEER_POLICY = 0x4
|
||||
IFLA_NETKIT_MODE = 0x5
|
||||
IFLA_VXLAN_UNSPEC = 0x0
|
||||
IFLA_VXLAN_ID = 0x1
|
||||
IFLA_VXLAN_GROUP = 0x2
|
||||
|
@ -1722,6 +1764,8 @@ const (
|
|||
IFLA_VXLAN_GPE = 0x1b
|
||||
IFLA_VXLAN_TTL_INHERIT = 0x1c
|
||||
IFLA_VXLAN_DF = 0x1d
|
||||
IFLA_VXLAN_VNIFILTER = 0x1e
|
||||
IFLA_VXLAN_LOCALBYPASS = 0x1f
|
||||
IFLA_GENEVE_UNSPEC = 0x0
|
||||
IFLA_GENEVE_ID = 0x1
|
||||
IFLA_GENEVE_REMOTE = 0x2
|
||||
|
@ -1736,6 +1780,7 @@ const (
|
|||
IFLA_GENEVE_LABEL = 0xb
|
||||
IFLA_GENEVE_TTL_INHERIT = 0xc
|
||||
IFLA_GENEVE_DF = 0xd
|
||||
IFLA_GENEVE_INNER_PROTO_INHERIT = 0xe
|
||||
IFLA_BAREUDP_UNSPEC = 0x0
|
||||
IFLA_BAREUDP_PORT = 0x1
|
||||
IFLA_BAREUDP_ETHERTYPE = 0x2
|
||||
|
@ -1748,6 +1793,8 @@ const (
|
|||
IFLA_GTP_FD1 = 0x2
|
||||
IFLA_GTP_PDP_HASHSIZE = 0x3
|
||||
IFLA_GTP_ROLE = 0x4
|
||||
IFLA_GTP_CREATE_SOCKETS = 0x5
|
||||
IFLA_GTP_RESTART_COUNT = 0x6
|
||||
IFLA_BOND_UNSPEC = 0x0
|
||||
IFLA_BOND_MODE = 0x1
|
||||
IFLA_BOND_ACTIVE_SLAVE = 0x2
|
||||
|
@ -1777,6 +1824,9 @@ const (
|
|||
IFLA_BOND_AD_ACTOR_SYSTEM = 0x1a
|
||||
IFLA_BOND_TLB_DYNAMIC_LB = 0x1b
|
||||
IFLA_BOND_PEER_NOTIF_DELAY = 0x1c
|
||||
IFLA_BOND_AD_LACP_ACTIVE = 0x1d
|
||||
IFLA_BOND_MISSED_MAX = 0x1e
|
||||
IFLA_BOND_NS_IP6_TARGET = 0x1f
|
||||
IFLA_BOND_AD_INFO_UNSPEC = 0x0
|
||||
IFLA_BOND_AD_INFO_AGGREGATOR = 0x1
|
||||
IFLA_BOND_AD_INFO_NUM_PORTS = 0x2
|
||||
|
@ -1792,6 +1842,7 @@ const (
|
|||
IFLA_BOND_SLAVE_AD_AGGREGATOR_ID = 0x6
|
||||
IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE = 0x7
|
||||
IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE = 0x8
|
||||
IFLA_BOND_SLAVE_PRIO = 0x9
|
||||
IFLA_VF_INFO_UNSPEC = 0x0
|
||||
IFLA_VF_INFO = 0x1
|
||||
IFLA_VF_UNSPEC = 0x0
|
||||
|
@ -1850,8 +1901,16 @@ const (
|
|||
IFLA_STATS_LINK_XSTATS_SLAVE = 0x3
|
||||
IFLA_STATS_LINK_OFFLOAD_XSTATS = 0x4
|
||||
IFLA_STATS_AF_SPEC = 0x5
|
||||
IFLA_STATS_GETSET_UNSPEC = 0x0
|
||||
IFLA_STATS_GET_FILTERS = 0x1
|
||||
IFLA_STATS_SET_OFFLOAD_XSTATS_L3_STATS = 0x2
|
||||
IFLA_OFFLOAD_XSTATS_UNSPEC = 0x0
|
||||
IFLA_OFFLOAD_XSTATS_CPU_HIT = 0x1
|
||||
IFLA_OFFLOAD_XSTATS_HW_S_INFO = 0x2
|
||||
IFLA_OFFLOAD_XSTATS_L3_STATS = 0x3
|
||||
IFLA_OFFLOAD_XSTATS_HW_S_INFO_UNSPEC = 0x0
|
||||
IFLA_OFFLOAD_XSTATS_HW_S_INFO_REQUEST = 0x1
|
||||
IFLA_OFFLOAD_XSTATS_HW_S_INFO_USED = 0x2
|
||||
IFLA_XDP_UNSPEC = 0x0
|
||||
IFLA_XDP_FD = 0x1
|
||||
IFLA_XDP_ATTACHED = 0x2
|
||||
|
@ -1881,6 +1940,11 @@ const (
|
|||
IFLA_RMNET_UNSPEC = 0x0
|
||||
IFLA_RMNET_MUX_ID = 0x1
|
||||
IFLA_RMNET_FLAGS = 0x2
|
||||
IFLA_MCTP_UNSPEC = 0x0
|
||||
IFLA_MCTP_NET = 0x1
|
||||
IFLA_DSA_UNSPEC = 0x0
|
||||
IFLA_DSA_CONDUIT = 0x1
|
||||
IFLA_DSA_MASTER = 0x1
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -3399,7 +3463,7 @@ const (
|
|||
DEVLINK_PORT_FN_ATTR_STATE = 0x2
|
||||
DEVLINK_PORT_FN_ATTR_OPSTATE = 0x3
|
||||
DEVLINK_PORT_FN_ATTR_CAPS = 0x4
|
||||
DEVLINK_PORT_FUNCTION_ATTR_MAX = 0x4
|
||||
DEVLINK_PORT_FUNCTION_ATTR_MAX = 0x5
|
||||
)
|
||||
|
||||
type FsverityDigest struct {
|
||||
|
@ -4183,7 +4247,8 @@ const (
|
|||
)
|
||||
|
||||
type LandlockRulesetAttr struct {
|
||||
Access_fs uint64
|
||||
Access_fs uint64
|
||||
Access_net uint64
|
||||
}
|
||||
|
||||
type LandlockPathBeneathAttr struct {
|
||||
|
@ -5134,7 +5199,7 @@ const (
|
|||
NL80211_FREQUENCY_ATTR_GO_CONCURRENT = 0xf
|
||||
NL80211_FREQUENCY_ATTR_INDOOR_ONLY = 0xe
|
||||
NL80211_FREQUENCY_ATTR_IR_CONCURRENT = 0xf
|
||||
NL80211_FREQUENCY_ATTR_MAX = 0x1b
|
||||
NL80211_FREQUENCY_ATTR_MAX = 0x1c
|
||||
NL80211_FREQUENCY_ATTR_MAX_TX_POWER = 0x6
|
||||
NL80211_FREQUENCY_ATTR_NO_10MHZ = 0x11
|
||||
NL80211_FREQUENCY_ATTR_NO_160MHZ = 0xc
|
||||
|
@ -5547,7 +5612,7 @@ const (
|
|||
NL80211_REGDOM_TYPE_CUSTOM_WORLD = 0x2
|
||||
NL80211_REGDOM_TYPE_INTERSECTION = 0x3
|
||||
NL80211_REGDOM_TYPE_WORLD = 0x1
|
||||
NL80211_REG_RULE_ATTR_MAX = 0x7
|
||||
NL80211_REG_RULE_ATTR_MAX = 0x8
|
||||
NL80211_REKEY_DATA_AKM = 0x4
|
||||
NL80211_REKEY_DATA_KCK = 0x2
|
||||
NL80211_REKEY_DATA_KEK = 0x1
|
||||
|
|
|
@ -37,14 +37,17 @@ func (token Token) Environ(inheritExisting bool) (env []string, err error) {
|
|||
return nil, err
|
||||
}
|
||||
defer DestroyEnvironmentBlock(block)
|
||||
blockp := unsafe.Pointer(block)
|
||||
for {
|
||||
entry := UTF16PtrToString((*uint16)(blockp))
|
||||
if len(entry) == 0 {
|
||||
break
|
||||
size := unsafe.Sizeof(*block)
|
||||
for *block != 0 {
|
||||
// find NUL terminator
|
||||
end := unsafe.Pointer(block)
|
||||
for *(*uint16)(end) != 0 {
|
||||
end = unsafe.Add(end, size)
|
||||
}
|
||||
env = append(env, entry)
|
||||
blockp = unsafe.Add(blockp, 2*(len(entry)+1))
|
||||
|
||||
entry := unsafe.Slice(block, (uintptr(end)-uintptr(unsafe.Pointer(block)))/size)
|
||||
env = append(env, UTF16ToString(entry))
|
||||
block = (*uint16)(unsafe.Add(end, size))
|
||||
}
|
||||
return env, nil
|
||||
}
|
||||
|
|
|
@ -125,8 +125,7 @@ func UTF16PtrToString(p *uint16) string {
|
|||
for ptr := unsafe.Pointer(p); *(*uint16)(ptr) != 0; n++ {
|
||||
ptr = unsafe.Pointer(uintptr(ptr) + unsafe.Sizeof(*p))
|
||||
}
|
||||
|
||||
return string(utf16.Decode(unsafe.Slice(p, n)))
|
||||
return UTF16ToString(unsafe.Slice(p, n))
|
||||
}
|
||||
|
||||
func Getpagesize() int { return 4096 }
|
||||
|
|
|
@ -120,8 +120,8 @@ github.com/felixge/httpsnoop
|
|||
# github.com/fvbommel/sortorder v1.0.2
|
||||
## explicit; go 1.13
|
||||
github.com/fvbommel/sortorder
|
||||
# github.com/go-logr/logr v1.2.4
|
||||
## explicit; go 1.16
|
||||
# github.com/go-logr/logr v1.3.0
|
||||
## explicit; go 1.18
|
||||
github.com/go-logr/logr
|
||||
github.com/go-logr/logr/funcr
|
||||
# github.com/go-logr/stdr v1.2.2
|
||||
|
@ -168,6 +168,8 @@ github.com/klauspost/compress/internal/cpuinfo
|
|||
github.com/klauspost/compress/internal/snapref
|
||||
github.com/klauspost/compress/zstd
|
||||
github.com/klauspost/compress/zstd/internal/xxhash
|
||||
# github.com/kr/pretty v0.3.1
|
||||
## explicit; go 1.12
|
||||
# github.com/mattn/go-runewidth v0.0.15
|
||||
## explicit; go 1.9
|
||||
github.com/mattn/go-runewidth
|
||||
|
@ -242,6 +244,8 @@ github.com/prometheus/procfs/internal/util
|
|||
# github.com/rivo/uniseg v0.2.0
|
||||
## explicit; go 1.12
|
||||
github.com/rivo/uniseg
|
||||
# github.com/rogpeppe/go-internal v1.10.0
|
||||
## explicit; go 1.19
|
||||
# github.com/sirupsen/logrus v1.9.3
|
||||
## explicit; go 1.13
|
||||
github.com/sirupsen/logrus
|
||||
|
@ -282,11 +286,11 @@ github.com/xeipuuv/gojsonschema
|
|||
# go.etcd.io/etcd/raft/v3 v3.5.6
|
||||
## explicit; go 1.16
|
||||
go.etcd.io/etcd/raft/v3/raftpb
|
||||
# go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0
|
||||
## explicit; go 1.19
|
||||
# go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1
|
||||
## explicit; go 1.20
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconvutil
|
||||
# go.opentelemetry.io/otel v1.19.0
|
||||
# go.opentelemetry.io/otel v1.21.0
|
||||
## explicit; go 1.20
|
||||
go.opentelemetry.io/otel
|
||||
go.opentelemetry.io/otel/attribute
|
||||
|
@ -298,21 +302,26 @@ go.opentelemetry.io/otel/internal/baggage
|
|||
go.opentelemetry.io/otel/internal/global
|
||||
go.opentelemetry.io/otel/propagation
|
||||
go.opentelemetry.io/otel/semconv/v1.17.0
|
||||
# go.opentelemetry.io/otel/metric v1.19.0
|
||||
# go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0
|
||||
## explicit; go 1.20
|
||||
# go.opentelemetry.io/otel/metric v1.21.0
|
||||
## explicit; go 1.20
|
||||
go.opentelemetry.io/otel/metric
|
||||
go.opentelemetry.io/otel/metric/embedded
|
||||
# go.opentelemetry.io/otel/trace v1.19.0
|
||||
# go.opentelemetry.io/otel/sdk v1.21.0
|
||||
## explicit; go 1.20
|
||||
# go.opentelemetry.io/otel/trace v1.21.0
|
||||
## explicit; go 1.20
|
||||
go.opentelemetry.io/otel/trace
|
||||
# golang.org/x/crypto v0.17.0
|
||||
go.opentelemetry.io/otel/trace/embedded
|
||||
# golang.org/x/crypto v0.21.0
|
||||
## explicit; go 1.18
|
||||
golang.org/x/crypto/ed25519
|
||||
golang.org/x/crypto/pbkdf2
|
||||
# golang.org/x/mod v0.14.0
|
||||
## explicit; go 1.18
|
||||
golang.org/x/mod/semver
|
||||
# golang.org/x/net v0.19.0
|
||||
# golang.org/x/net v0.23.0
|
||||
## explicit; go 1.18
|
||||
golang.org/x/net/http/httpguts
|
||||
golang.org/x/net/http2
|
||||
|
@ -323,12 +332,12 @@ golang.org/x/net/trace
|
|||
# golang.org/x/sync v0.6.0
|
||||
## explicit; go 1.18
|
||||
golang.org/x/sync/errgroup
|
||||
# golang.org/x/sys v0.16.0
|
||||
# golang.org/x/sys v0.18.0
|
||||
## explicit; go 1.18
|
||||
golang.org/x/sys/plan9
|
||||
golang.org/x/sys/unix
|
||||
golang.org/x/sys/windows
|
||||
# golang.org/x/term v0.15.0
|
||||
# golang.org/x/term v0.18.0
|
||||
## explicit; go 1.18
|
||||
golang.org/x/term
|
||||
# golang.org/x/text v0.14.0
|
||||
|
|
Loading…
Reference in New Issue