You've already forked opentelemetry-go
mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-09-16 09:26:25 +02:00
Merge remote-tracking branch 'upstream/main' into internal_logging
This commit is contained in:
12
.github/workflows/ci.yml
vendored
12
.github/workflows/ci.yml
vendored
@@ -24,14 +24,14 @@ jobs:
|
||||
echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV
|
||||
echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
|
||||
- name: Module cache
|
||||
uses: actions/cache@v2.1.6
|
||||
uses: actions/cache@v2.1.7
|
||||
env:
|
||||
cache-name: go-mod-cache
|
||||
with:
|
||||
path: ~/go/pkg/mod
|
||||
key: ${{ runner.os }}-${{ env.cache-name }}-${{ hashFiles('**/go.sum') }}
|
||||
- name: Tools cache
|
||||
uses: actions/cache@v2.1.6
|
||||
uses: actions/cache@v2.1.7
|
||||
env:
|
||||
cache-name: go-tools-cache
|
||||
with:
|
||||
@@ -58,7 +58,7 @@ jobs:
|
||||
echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV
|
||||
echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
|
||||
- name: Module cache
|
||||
uses: actions/cache@v2.1.6
|
||||
uses: actions/cache@v2.1.7
|
||||
env:
|
||||
cache-name: go-mod-cache
|
||||
with:
|
||||
@@ -81,7 +81,7 @@ jobs:
|
||||
echo "GOPATH=$(go env GOPATH)" >> $GITHUB_ENV
|
||||
echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
|
||||
- name: Module cache
|
||||
uses: actions/cache@v2.1.6
|
||||
uses: actions/cache@v2.1.7
|
||||
env:
|
||||
cache-name: go-mod-cache
|
||||
with:
|
||||
@@ -109,7 +109,7 @@ jobs:
|
||||
compatibility-test:
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.17, 1.16, 1.15]
|
||||
go-version: [1.17, 1.16]
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
# GitHub Actions does not support arm* architectures on default
|
||||
# runners. It is possible to acomplish this with a self-hosted runner
|
||||
@@ -134,7 +134,7 @@ jobs:
|
||||
echo "$(go env GOPATH)/bin" >> $GITHUB_PATH
|
||||
shell: bash
|
||||
- name: Module cache
|
||||
uses: actions/cache@v2.1.6
|
||||
uses: actions/cache@v2.1.7
|
||||
env:
|
||||
cache-name: go-mod-cache
|
||||
with:
|
||||
|
2
.github/workflows/dependabot.yml
vendored
2
.github/workflows/dependabot.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
ref: ${{ github.head_ref }}
|
||||
- uses: actions/setup-go@v2.1.4
|
||||
with:
|
||||
go-version: '^1.15.0'
|
||||
go-version: '^1.16.0'
|
||||
- uses: evantorrie/mott-the-tidier@v1-beta
|
||||
id: modtidy
|
||||
with:
|
||||
|
@@ -14,6 +14,11 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
||||
This can be used by the SDK and API to provide users with feedback of the internal state.
|
||||
To enable verbose logs configure the logger which will print V(1) logs. For debugging information configure to print V(5) logs. (#2343)
|
||||
|
||||
### Changed
|
||||
|
||||
- The `"go.opentelemetry.io/otel/exporter/otel/otlptrace/otlptracegrpc".Client` now uses the underlying gRPC `ClientConn` to handle name resolution, TCP connection establishment (with retries and backoff) and TLS handshakes, and handling errors on established connections by re-resolving the name and reconnecting. (#2329)
|
||||
- Changed the project minimum supported Go version from 1.15 to 1.16. (#2412)
|
||||
|
||||
### Removed
|
||||
|
||||
- Remove the metric Processor's ability to convert cumulative to delta aggregation temporality. (#2350)
|
||||
@@ -29,6 +34,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
||||
- The following interface types simply moved from `metric` to `metric/sdkapi`: `Descriptor`, `MeterImpl`, `InstrumentImpl`, `SyncImpl`, `BoundSyncImpl`, `AsyncImpl`, `AsyncRunner`, `AsyncSingleRunner`, and `AsyncBatchRunner`
|
||||
- The following struct types moved and are replaced with type aliases, since they are exposed to the user: `Observation`, `Measurement`.
|
||||
- The No-op implementations of sync and async instruments are no longer exported, new functions `sdkapi.NewNoopAsyncInstrument()` and `sdkapi.NewNoopSyncInstrument()` are provided instead. (#2271)
|
||||
- Add `SpanStatusFromHTTPStatusCodeAndSpanKind` to all `semconv` packages to return a span status code similar to `SpanStatusFromHTTPStatusCode`, but exclude `4XX` HTTP errors as span errors if the span is of server kind. (#2296)
|
||||
- Update the SDK `BatchSpanProcessor` to export all queued spans when `ForceFlush` is called. (#2080, #2335)
|
||||
- Change `resource.Default` to be evaluated the first time it is called, rather than on import. This allows the caller the option to update `OTEL_RESOURCE_ATTRIBUTES` first, such as with `os.Setenv`. (#2371)
|
||||
|
||||
|
@@ -14,4 +14,4 @@
|
||||
|
||||
* @jmacd @MrAlias @Aneurysm9 @evantorrie @XSAM @dashpole @paivagustavo @MadVikingGod @pellared
|
||||
|
||||
CODEOWNERS @MrAlias @Aneurysm9
|
||||
CODEOWNERS @MrAlias @Aneurysm9 @MadVikingGod
|
||||
|
@@ -481,11 +481,11 @@ Approvers:
|
||||
- [Sam Xie](https://github.com/XSAM)
|
||||
- [David Ashpole](https://github.com/dashpole), Google
|
||||
- [Gustavo Silva Paiva](https://github.com/paivagustavo), LightStep
|
||||
- [Aaron Clawson](https://github.com/MadVikingGod)
|
||||
- [Robert Pająk](https://github.com/pellared), Splunk
|
||||
|
||||
Maintainers:
|
||||
|
||||
- [Aaron Clawson](https://github.com/MadVikingGod), LightStep
|
||||
- [Anthony Mirabella](https://github.com/Aneurysm9), AWS
|
||||
- [Tyler Yahn](https://github.com/MrAlias), Splunk
|
||||
|
||||
|
12
README.md
12
README.md
@@ -30,25 +30,27 @@ Project versioning information and stability guarantees can be found in the
|
||||
|
||||
### Compatibility
|
||||
|
||||
OpenTelemetry-Go attempts to track the current supported versions of the
|
||||
[Go language](https://golang.org/doc/devel/release#policy). The release
|
||||
schedule after a new minor version of go is as follows:
|
||||
|
||||
- The first release or one month, which ever is sooner, will add build steps for the new go version.
|
||||
- The first release after three months will remove support for the oldest go version.
|
||||
|
||||
This project is tested on the following systems.
|
||||
|
||||
| OS | Go Version | Architecture |
|
||||
| ------- | ---------- | ------------ |
|
||||
| Ubuntu | 1.17 | amd64 |
|
||||
| Ubuntu | 1.16 | amd64 |
|
||||
| Ubuntu | 1.15 | amd64 |
|
||||
| Ubuntu | 1.17 | 386 |
|
||||
| Ubuntu | 1.16 | 386 |
|
||||
| Ubuntu | 1.15 | 386 |
|
||||
| MacOS | 1.17 | amd64 |
|
||||
| MacOS | 1.16 | amd64 |
|
||||
| MacOS | 1.15 | amd64 |
|
||||
| Windows | 1.17 | amd64 |
|
||||
| Windows | 1.16 | amd64 |
|
||||
| Windows | 1.15 | amd64 |
|
||||
| Windows | 1.17 | 386 |
|
||||
| Windows | 1.16 | 386 |
|
||||
| Windows | 1.15 | 386 |
|
||||
|
||||
While this project should work for other systems, no compatibility guarantees
|
||||
are made for those systems currently.
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/bridge/opencensus
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
go.opencensus.io v0.22.6-0.20201102222123-380f4078db9f
|
||||
|
@@ -1,7 +1,7 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/benbjohnson/clock v1.2.0 h1:9Re3G2TWxkE06LdMWMpcY6KV81GLXMGiYpPYUPkFAws=
|
||||
github.com/benbjohnson/clock v1.2.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
|
||||
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -51,7 +51,6 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
@@ -59,7 +58,6 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/bridge/opencensus/test
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
go.opencensus.io v0.23.0
|
||||
|
@@ -1,7 +1,7 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/benbjohnson/clock v1.2.0 h1:9Re3G2TWxkE06LdMWMpcY6KV81GLXMGiYpPYUPkFAws=
|
||||
github.com/benbjohnson/clock v1.2.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
|
||||
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
@@ -82,7 +82,6 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
@@ -105,7 +104,6 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/bridge/opentracing
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
replace go.opentelemetry.io/otel => ../..
|
||||
|
||||
|
@@ -14,9 +14,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/example/fib
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
go.opentelemetry.io/otel v1.2.0
|
||||
|
@@ -13,9 +13,7 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/example/jaeger
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
replace (
|
||||
go.opentelemetry.io/otel => ../..
|
||||
|
@@ -14,9 +14,7 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/example/namedtracer
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
replace (
|
||||
go.opentelemetry.io/otel => ../..
|
||||
|
@@ -13,9 +13,7 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/example/opencensus
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
replace (
|
||||
go.opentelemetry.io/otel => ../..
|
||||
|
@@ -1,7 +1,7 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/benbjohnson/clock v1.2.0 h1:9Re3G2TWxkE06LdMWMpcY6KV81GLXMGiYpPYUPkFAws=
|
||||
github.com/benbjohnson/clock v1.2.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
|
||||
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -59,7 +59,6 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/example/otel-collector
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
replace (
|
||||
go.opentelemetry.io/otel => ../..
|
||||
|
@@ -53,6 +53,9 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
@@ -61,41 +64,60 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
go.opentelemetry.io/proto/otlp v0.11.0 h1:cLDgIBTf4lLOlztkhzAEdQsJ4Lj+i5Wc9k6Nn0K1VyU=
|
||||
go.opentelemetry.io/proto/otlp v0.11.0/go.mod h1:QpEjXPrNQzrFDZgoTo49dgHR9RYRSrg3NAKnUGl9YpQ=
|
||||
go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA=
|
||||
go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-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=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -127,8 +149,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
|
@@ -53,13 +53,11 @@ func initProvider() func() {
|
||||
// `localhost:30080` endpoint. Otherwise, replace `localhost` with the
|
||||
// endpoint of your cluster. If you run the app inside k8s, then you can
|
||||
// probably connect directly to the service through dns
|
||||
conn, err := grpc.DialContext(ctx, "localhost:30080", grpc.WithInsecure(), grpc.WithBlock())
|
||||
handleErr(err, "failed to create gRPC connection to collector")
|
||||
|
||||
// Set up a trace exporter
|
||||
traceExporter, err := otlptracegrpc.New(ctx,
|
||||
otlptracegrpc.WithInsecure(),
|
||||
otlptracegrpc.WithEndpoint("localhost:30080"),
|
||||
otlptracegrpc.WithDialOption(grpc.WithBlock()),
|
||||
)
|
||||
traceExporter, err := otlptracegrpc.New(ctx, otlptracegrpc.WithGRPCConn(conn))
|
||||
handleErr(err, "failed to create trace exporter")
|
||||
|
||||
// Register the trace exporter with a TracerProvider, using a batch
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/example/passthrough
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
go.opentelemetry.io/otel v1.2.0
|
||||
|
@@ -13,9 +13,7 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/example/prometheus
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
replace (
|
||||
go.opentelemetry.io/otel => ../..
|
||||
|
@@ -4,8 +4,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/benbjohnson/clock v1.2.0 h1:9Re3G2TWxkE06LdMWMpcY6KV81GLXMGiYpPYUPkFAws=
|
||||
github.com/benbjohnson/clock v1.2.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
|
||||
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
@@ -55,10 +55,8 @@ github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/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/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
@@ -144,7 +142,6 @@ google.golang.org/protobuf v1.26.0-rc.1 h1:7QnIQpGRHE5RnLKnESfDoxm2dTapTZua5a0kS
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/example/zipkin
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
replace (
|
||||
go.opentelemetry.io/otel => ../..
|
||||
|
@@ -73,11 +73,9 @@ github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxy
|
||||
github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc=
|
||||
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
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=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
@@ -177,7 +175,6 @@ golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4f
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
@@ -205,7 +202,6 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/exporters/jaeger
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/google/go-cmp v0.5.6
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/exporters/otlp/otlpmetric
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/cenkalti/backoff/v4 v4.1.2
|
||||
|
@@ -2,8 +2,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/benbjohnson/clock v1.2.0 h1:9Re3G2TWxkE06LdMWMpcY6KV81GLXMGiYpPYUPkFAws=
|
||||
github.com/benbjohnson/clock v1.2.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
|
||||
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo=
|
||||
github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/stretchr/testify v1.7.0
|
||||
|
@@ -2,8 +2,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/benbjohnson/clock v1.2.0 h1:9Re3G2TWxkE06LdMWMpcY6KV81GLXMGiYpPYUPkFAws=
|
||||
github.com/benbjohnson/clock v1.2.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
|
||||
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo=
|
||||
github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/stretchr/testify v1.7.0
|
||||
|
@@ -2,8 +2,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/benbjohnson/clock v1.2.0 h1:9Re3G2TWxkE06LdMWMpcY6KV81GLXMGiYpPYUPkFAws=
|
||||
github.com/benbjohnson/clock v1.2.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
|
||||
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/exporters/otlp/otlptrace
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/cenkalti/backoff/v4 v4.1.2
|
||||
@@ -10,7 +10,6 @@ require (
|
||||
go.opentelemetry.io/otel/sdk v1.2.0
|
||||
go.opentelemetry.io/otel/trace v1.2.0
|
||||
go.opentelemetry.io/proto/otlp v0.11.0
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013
|
||||
google.golang.org/grpc v1.42.0
|
||||
google.golang.org/protobuf v1.27.1
|
||||
)
|
||||
|
@@ -1,38 +0,0 @@
|
||||
// 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 connection
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
"unsafe"
|
||||
|
||||
ottest "go.opentelemetry.io/otel/internal/internaltest"
|
||||
)
|
||||
|
||||
// Ensure struct alignment prior to running tests.
|
||||
func TestMain(m *testing.M) {
|
||||
fields := []ottest.FieldOffset{
|
||||
{
|
||||
Name: "Connection.lastConnectErrPtr",
|
||||
Offset: unsafe.Offsetof(Connection{}.lastConnectErrPtr),
|
||||
},
|
||||
}
|
||||
if !ottest.Aligned8Byte(fields, os.Stderr) {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
os.Exit(m.Run())
|
||||
}
|
@@ -1,334 +0,0 @@
|
||||
// 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 connection // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/connection"
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/rand"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"google.golang.org/genproto/googleapis/rpc/errdetails"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/encoding/gzip"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/retry"
|
||||
)
|
||||
|
||||
type Connection struct {
|
||||
// Ensure pointer is 64-bit aligned for atomic operations on both 32 and 64 bit machines.
|
||||
lastConnectErrPtr unsafe.Pointer
|
||||
|
||||
// mu protects the Connection as it is accessed by the
|
||||
// exporter goroutines and background Connection goroutine
|
||||
mu sync.Mutex
|
||||
cc *grpc.ClientConn
|
||||
|
||||
// these fields are read-only after constructor is finished
|
||||
cfg otlpconfig.Config
|
||||
SCfg otlpconfig.SignalConfig
|
||||
requestFunc retry.RequestFunc
|
||||
metadata metadata.MD
|
||||
newConnectionHandler func(cc *grpc.ClientConn)
|
||||
|
||||
// these channels are created once
|
||||
disconnectedCh chan bool
|
||||
backgroundConnectionDoneCh chan struct{}
|
||||
stopCh chan struct{}
|
||||
|
||||
// this is for tests, so they can replace the closing
|
||||
// routine without a worry of modifying some global variable
|
||||
// or changing it back to original after the test is done
|
||||
closeBackgroundConnectionDoneCh func(ch chan struct{})
|
||||
}
|
||||
|
||||
func NewConnection(cfg otlpconfig.Config, sCfg otlpconfig.SignalConfig, handler func(cc *grpc.ClientConn)) *Connection {
|
||||
c := new(Connection)
|
||||
c.newConnectionHandler = handler
|
||||
c.cfg = cfg
|
||||
c.requestFunc = cfg.RetryConfig.RequestFunc(evaluate)
|
||||
c.SCfg = sCfg
|
||||
if len(c.SCfg.Headers) > 0 {
|
||||
c.metadata = metadata.New(c.SCfg.Headers)
|
||||
}
|
||||
c.closeBackgroundConnectionDoneCh = func(ch chan struct{}) {
|
||||
close(ch)
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *Connection) StartConnection(ctx context.Context) error {
|
||||
c.stopCh = make(chan struct{})
|
||||
c.disconnectedCh = make(chan bool, 1)
|
||||
c.backgroundConnectionDoneCh = make(chan struct{})
|
||||
|
||||
if err := c.connect(ctx); err == nil {
|
||||
c.setStateConnected()
|
||||
} else {
|
||||
c.SetStateDisconnected(err)
|
||||
}
|
||||
go c.indefiniteBackgroundConnection()
|
||||
|
||||
// TODO: proper error handling when initializing connections.
|
||||
// We can report permanent errors, e.g., invalid settings.
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Connection) LastConnectError() error {
|
||||
errPtr := (*error)(atomic.LoadPointer(&c.lastConnectErrPtr))
|
||||
if errPtr == nil {
|
||||
return nil
|
||||
}
|
||||
return *errPtr
|
||||
}
|
||||
|
||||
func (c *Connection) saveLastConnectError(err error) {
|
||||
var errPtr *error
|
||||
if err != nil {
|
||||
errPtr = &err
|
||||
}
|
||||
atomic.StorePointer(&c.lastConnectErrPtr, unsafe.Pointer(errPtr))
|
||||
}
|
||||
|
||||
func (c *Connection) SetStateDisconnected(err error) {
|
||||
c.saveLastConnectError(err)
|
||||
select {
|
||||
case c.disconnectedCh <- true:
|
||||
default:
|
||||
}
|
||||
c.newConnectionHandler(nil)
|
||||
}
|
||||
|
||||
func (c *Connection) setStateConnected() {
|
||||
c.saveLastConnectError(nil)
|
||||
}
|
||||
|
||||
func (c *Connection) Connected() bool {
|
||||
return c.LastConnectError() == nil
|
||||
}
|
||||
|
||||
const defaultConnReattemptPeriod = 10 * time.Second
|
||||
|
||||
func (c *Connection) indefiniteBackgroundConnection() {
|
||||
defer func() {
|
||||
c.closeBackgroundConnectionDoneCh(c.backgroundConnectionDoneCh)
|
||||
}()
|
||||
|
||||
connReattemptPeriod := c.cfg.ReconnectionPeriod
|
||||
if connReattemptPeriod <= 0 {
|
||||
connReattemptPeriod = defaultConnReattemptPeriod
|
||||
}
|
||||
|
||||
// No strong seeding required, nano time can
|
||||
// already help with pseudo uniqueness.
|
||||
rng := rand.New(rand.NewSource(time.Now().UnixNano() + rand.Int63n(1024)))
|
||||
|
||||
// maxJitterNanos: 70% of the connectionReattemptPeriod
|
||||
maxJitterNanos := int64(0.7 * float64(connReattemptPeriod))
|
||||
|
||||
for {
|
||||
// Otherwise these will be the normal scenarios to enable
|
||||
// reconnection if we trip out.
|
||||
// 1. If we've stopped, return entirely
|
||||
// 2. Otherwise block until we are disconnected, and
|
||||
// then retry connecting
|
||||
select {
|
||||
case <-c.stopCh:
|
||||
return
|
||||
|
||||
case <-c.disconnectedCh:
|
||||
// Quickly check if we haven't stopped at the
|
||||
// same time.
|
||||
select {
|
||||
case <-c.stopCh:
|
||||
return
|
||||
|
||||
default:
|
||||
}
|
||||
|
||||
// Normal scenario that we'll wait for
|
||||
}
|
||||
|
||||
if err := c.connect(context.Background()); err == nil {
|
||||
c.setStateConnected()
|
||||
} else {
|
||||
// this code is unreachable in most cases
|
||||
// c.connect does not establish Connection
|
||||
c.SetStateDisconnected(err)
|
||||
}
|
||||
|
||||
// Apply some jitter to avoid lockstep retrials of other
|
||||
// collector-exporters. Lockstep retrials could result in an
|
||||
// innocent DDOS, by clogging the machine's resources and network.
|
||||
jitter := time.Duration(rng.Int63n(maxJitterNanos))
|
||||
select {
|
||||
case <-c.stopCh:
|
||||
return
|
||||
case <-time.After(connReattemptPeriod + jitter):
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Connection) connect(ctx context.Context) error {
|
||||
cc, err := c.dialToCollector(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.setConnection(cc)
|
||||
c.newConnectionHandler(cc)
|
||||
return nil
|
||||
}
|
||||
|
||||
// setConnection sets cc as the client Connection and returns true if
|
||||
// the Connection state changed.
|
||||
func (c *Connection) setConnection(cc *grpc.ClientConn) bool {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
// If previous clientConn is same as the current then just return.
|
||||
// This doesn't happen right now as this func is only called with new ClientConn.
|
||||
// It is more about future-proofing.
|
||||
if c.cc == cc {
|
||||
return false
|
||||
}
|
||||
|
||||
// If the previous clientConn was non-nil, close it
|
||||
if c.cc != nil {
|
||||
_ = c.cc.Close()
|
||||
}
|
||||
c.cc = cc
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *Connection) dialToCollector(ctx context.Context) (*grpc.ClientConn, error) {
|
||||
if c.cfg.GRPCConn != nil {
|
||||
return c.cfg.GRPCConn, nil
|
||||
}
|
||||
|
||||
dialOpts := []grpc.DialOption{}
|
||||
if c.cfg.ServiceConfig != "" {
|
||||
dialOpts = append(dialOpts, grpc.WithDefaultServiceConfig(c.cfg.ServiceConfig))
|
||||
}
|
||||
if c.SCfg.GRPCCredentials != nil {
|
||||
dialOpts = append(dialOpts, grpc.WithTransportCredentials(c.SCfg.GRPCCredentials))
|
||||
} else if c.SCfg.Insecure {
|
||||
dialOpts = append(dialOpts, grpc.WithInsecure())
|
||||
}
|
||||
if c.SCfg.Compression == otlpconfig.GzipCompression {
|
||||
dialOpts = append(dialOpts, grpc.WithDefaultCallOptions(grpc.UseCompressor(gzip.Name)))
|
||||
}
|
||||
if len(c.cfg.DialOptions) != 0 {
|
||||
dialOpts = append(dialOpts, c.cfg.DialOptions...)
|
||||
}
|
||||
|
||||
ctx, cancel := c.ContextWithStop(ctx)
|
||||
defer cancel()
|
||||
ctx = c.ContextWithMetadata(ctx)
|
||||
return grpc.DialContext(ctx, c.SCfg.Endpoint, dialOpts...)
|
||||
}
|
||||
|
||||
func (c *Connection) ContextWithMetadata(ctx context.Context) context.Context {
|
||||
if c.metadata.Len() > 0 {
|
||||
return metadata.NewOutgoingContext(ctx, c.metadata)
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (c *Connection) Shutdown(ctx context.Context) error {
|
||||
close(c.stopCh)
|
||||
// Ensure that the backgroundConnector returns
|
||||
select {
|
||||
case <-c.backgroundConnectionDoneCh:
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
|
||||
c.mu.Lock()
|
||||
cc := c.cc
|
||||
c.cc = nil
|
||||
c.mu.Unlock()
|
||||
|
||||
if cc != nil {
|
||||
return cc.Close()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Connection) ContextWithStop(ctx context.Context) (context.Context, context.CancelFunc) {
|
||||
// Unify the parent context Done signal with the Connection's
|
||||
// stop channel.
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
go func(ctx context.Context, cancel context.CancelFunc) {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
// Nothing to do, either cancelled or deadline
|
||||
// happened.
|
||||
case <-c.stopCh:
|
||||
cancel()
|
||||
}
|
||||
}(ctx, cancel)
|
||||
return ctx, cancel
|
||||
}
|
||||
|
||||
func (c *Connection) DoRequest(ctx context.Context, fn func(context.Context) error) error {
|
||||
ctx, cancel := c.ContextWithStop(ctx)
|
||||
defer cancel()
|
||||
return c.requestFunc(ctx, func(ctx context.Context) error {
|
||||
err := fn(ctx)
|
||||
// nil is converted to OK.
|
||||
if status.Code(err) == codes.OK {
|
||||
// Success.
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
// evaluate returns if err is retry-able and a duration to wait for if an
|
||||
// explicit throttle time is included in err.
|
||||
func evaluate(err error) (bool, time.Duration) {
|
||||
s := status.Convert(err)
|
||||
switch s.Code() {
|
||||
case codes.Canceled,
|
||||
codes.DeadlineExceeded,
|
||||
codes.ResourceExhausted,
|
||||
codes.Aborted,
|
||||
codes.OutOfRange,
|
||||
codes.Unavailable,
|
||||
codes.DataLoss:
|
||||
return true, throttleDelay(s)
|
||||
}
|
||||
|
||||
// Not a retry-able error.
|
||||
return false, 0
|
||||
}
|
||||
|
||||
// throttleDelay returns a duration to wait for if an explicit throttle time
|
||||
// is included in the response status.
|
||||
func throttleDelay(status *status.Status) time.Duration {
|
||||
for _, detail := range status.Details() {
|
||||
if t, ok := detail.(*errdetails.RetryInfo); ok {
|
||||
return t.RetryDelay.AsDuration()
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
@@ -20,7 +20,9 @@ import (
|
||||
"time"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/backoff"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/encoding/gzip"
|
||||
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/retry"
|
||||
)
|
||||
@@ -76,6 +78,40 @@ func NewDefaultConfig() Config {
|
||||
return c
|
||||
}
|
||||
|
||||
// NewGRPCConfig returns a new Config with all settings applied from opts and
|
||||
// any unset setting using the default gRPC config values.
|
||||
func NewGRPCConfig(opts ...GRPCOption) Config {
|
||||
cfg := NewDefaultConfig()
|
||||
ApplyGRPCEnvConfigs(&cfg)
|
||||
for _, opt := range opts {
|
||||
opt.ApplyGRPCOption(&cfg)
|
||||
}
|
||||
|
||||
if cfg.ServiceConfig != "" {
|
||||
cfg.DialOptions = append(cfg.DialOptions, grpc.WithDefaultServiceConfig(cfg.ServiceConfig))
|
||||
}
|
||||
if cfg.Traces.GRPCCredentials != nil {
|
||||
cfg.DialOptions = append(cfg.DialOptions, grpc.WithTransportCredentials(cfg.Traces.GRPCCredentials))
|
||||
} else if cfg.Traces.Insecure {
|
||||
cfg.DialOptions = append(cfg.DialOptions, grpc.WithInsecure())
|
||||
}
|
||||
if cfg.Traces.Compression == GzipCompression {
|
||||
cfg.DialOptions = append(cfg.DialOptions, grpc.WithDefaultCallOptions(grpc.UseCompressor(gzip.Name)))
|
||||
}
|
||||
if len(cfg.DialOptions) != 0 {
|
||||
cfg.DialOptions = append(cfg.DialOptions, cfg.DialOptions...)
|
||||
}
|
||||
if cfg.ReconnectionPeriod != 0 {
|
||||
p := grpc.ConnectParams{
|
||||
Backoff: backoff.DefaultConfig,
|
||||
MinConnectTimeout: cfg.ReconnectionPeriod,
|
||||
}
|
||||
cfg.DialOptions = append(cfg.DialOptions, grpc.WithConnectParams(p))
|
||||
}
|
||||
|
||||
return cfg
|
||||
}
|
||||
|
||||
type (
|
||||
// GenericOption applies an option to the HTTP or gRPC driver.
|
||||
GenericOption interface {
|
||||
|
@@ -55,44 +55,60 @@ func initializeExporter(t *testing.T, client otlptrace.Client) *otlptrace.Export
|
||||
}
|
||||
|
||||
func testClientStopHonorsTimeout(t *testing.T, client otlptrace.Client) {
|
||||
t.Cleanup(func() {
|
||||
// The test is looking for a failed shut down. Call Stop a second time
|
||||
// with an un-expired context to give the client a second chance at
|
||||
// cleaning up. There is not guarantee from the Client interface this
|
||||
// will succeed, therefore, no need to check the error (just give it a
|
||||
// best try).
|
||||
_ = client.Stop(context.Background())
|
||||
})
|
||||
e := initializeExporter(t, client)
|
||||
|
||||
innerCtx, innerCancel := context.WithTimeout(context.Background(), time.Microsecond)
|
||||
<-innerCtx.Done()
|
||||
if err := e.Shutdown(innerCtx); err == nil {
|
||||
t.Error("expected context DeadlineExceeded error, got nil")
|
||||
} else if !errors.Is(err, context.DeadlineExceeded) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Nanosecond)
|
||||
defer cancel()
|
||||
<-ctx.Done()
|
||||
|
||||
if err := e.Shutdown(ctx); !errors.Is(err, context.DeadlineExceeded) {
|
||||
t.Errorf("expected context DeadlineExceeded error, got %v", err)
|
||||
}
|
||||
innerCancel()
|
||||
}
|
||||
|
||||
func testClientStopHonorsCancel(t *testing.T, client otlptrace.Client) {
|
||||
t.Cleanup(func() {
|
||||
// The test is looking for a failed shut down. Call Stop a second time
|
||||
// with an un-expired context to give the client a second chance at
|
||||
// cleaning up. There is not guarantee from the Client interface this
|
||||
// will succeed, therefore, no need to check the error (just give it a
|
||||
// best try).
|
||||
_ = client.Stop(context.Background())
|
||||
})
|
||||
e := initializeExporter(t, client)
|
||||
|
||||
ctx, innerCancel := context.WithCancel(context.Background())
|
||||
innerCancel()
|
||||
if err := e.Shutdown(ctx); err == nil {
|
||||
t.Error("expected context canceled error, got nil")
|
||||
} else if !errors.Is(err, context.Canceled) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
cancel()
|
||||
|
||||
if err := e.Shutdown(ctx); !errors.Is(err, context.Canceled) {
|
||||
t.Errorf("expected context canceled error, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func testClientStopNoError(t *testing.T, client otlptrace.Client) {
|
||||
e := initializeExporter(t, client)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
e := initializeExporter(t, client)
|
||||
if err := e.Shutdown(ctx); err != nil {
|
||||
t.Errorf("shutdown errored: expected nil, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func testClientStopManyTimes(t *testing.T, client otlptrace.Client) {
|
||||
e := initializeExporter(t, client)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute)
|
||||
defer cancel()
|
||||
e := initializeExporter(t, client)
|
||||
|
||||
ch := make(chan struct{})
|
||||
wg := sync.WaitGroup{}
|
||||
@@ -110,7 +126,8 @@ func testClientStopManyTimes(t *testing.T, client otlptrace.Client) {
|
||||
wg.Wait()
|
||||
for _, err := range errs {
|
||||
if err != nil {
|
||||
t.Fatalf("failed to shutdown exporter: %v", err)
|
||||
t.Errorf("failed to shutdown exporter: %v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -87,7 +87,9 @@ func RunEndToEndTest(ctx context.Context, t *testing.T, exp *otlptrace.Exporter,
|
||||
|
||||
// Shutdown the collector too so that we can begin
|
||||
// verification checks of expected data back.
|
||||
_ = tracesCollector.Stop()
|
||||
if err := tracesCollector.Stop(); err != nil {
|
||||
t.Fatalf("failed to stop the mock collector: %v", err)
|
||||
}
|
||||
|
||||
// Now verify that we only got two resources
|
||||
rss := tracesCollector.GetResourceSpans()
|
||||
|
@@ -17,92 +17,259 @@ package otlptracegrpc // import "go.opentelemetry.io/otel/exporters/otlp/otlptra
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"google.golang.org/genproto/googleapis/rpc/errdetails"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlptrace"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/connection"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig"
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/retry"
|
||||
coltracepb "go.opentelemetry.io/proto/otlp/collector/trace/v1"
|
||||
tracepb "go.opentelemetry.io/proto/otlp/trace/v1"
|
||||
)
|
||||
|
||||
type client struct {
|
||||
connection *connection.Connection
|
||||
endpoint string
|
||||
dialOpts []grpc.DialOption
|
||||
metadata metadata.MD
|
||||
exportTimeout time.Duration
|
||||
requestFunc retry.RequestFunc
|
||||
|
||||
lock sync.Mutex
|
||||
tracesClient coltracepb.TraceServiceClient
|
||||
// stopCtx is used as a parent context for all exports. Therefore, when it
|
||||
// is canceled with the stopFunc all exports are canceled.
|
||||
stopCtx context.Context
|
||||
// stopFunc cancels stopCtx, stopping any active exports.
|
||||
stopFunc context.CancelFunc
|
||||
|
||||
// ourConn keeps track of where conn was created: true if created here on
|
||||
// Start, or false if passed with an option. This is important on Shutdown
|
||||
// as the conn should only be closed if created here on start. Otherwise,
|
||||
// it is up to the processes that passed the conn to close it.
|
||||
ourConn bool
|
||||
conn *grpc.ClientConn
|
||||
tscMu sync.RWMutex
|
||||
tsc coltracepb.TraceServiceClient
|
||||
}
|
||||
|
||||
// Compile time check *client implements otlptrace.Client.
|
||||
var _ otlptrace.Client = (*client)(nil)
|
||||
|
||||
var (
|
||||
errNoClient = errors.New("no client")
|
||||
)
|
||||
|
||||
// NewClient creates a new gRPC trace client.
|
||||
func NewClient(opts ...Option) otlptrace.Client {
|
||||
cfg := otlpconfig.NewDefaultConfig()
|
||||
otlpconfig.ApplyGRPCEnvConfigs(&cfg)
|
||||
for _, opt := range opts {
|
||||
opt.applyGRPCOption(&cfg)
|
||||
return newClient(opts...)
|
||||
}
|
||||
|
||||
func newClient(opts ...Option) *client {
|
||||
cfg := otlpconfig.NewGRPCConfig(asGRPCOptions(opts)...)
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
c := &client{
|
||||
endpoint: cfg.Traces.Endpoint,
|
||||
exportTimeout: cfg.Traces.Timeout,
|
||||
requestFunc: cfg.RetryConfig.RequestFunc(retryable),
|
||||
dialOpts: cfg.DialOptions,
|
||||
stopCtx: ctx,
|
||||
stopFunc: cancel,
|
||||
conn: cfg.GRPCConn,
|
||||
}
|
||||
|
||||
c := &client{}
|
||||
c.connection = connection.NewConnection(cfg, cfg.Traces, c.handleNewConnection)
|
||||
if len(cfg.Traces.Headers) > 0 {
|
||||
c.metadata = metadata.New(cfg.Traces.Headers)
|
||||
}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func (c *client) handleNewConnection(cc *grpc.ClientConn) {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
if cc != nil {
|
||||
c.tracesClient = coltracepb.NewTraceServiceClient(cc)
|
||||
} else {
|
||||
c.tracesClient = nil
|
||||
}
|
||||
}
|
||||
|
||||
// Start establishes a connection to the collector.
|
||||
// Start establishes a gRPC connection to the collector.
|
||||
func (c *client) Start(ctx context.Context) error {
|
||||
return c.connection.StartConnection(ctx)
|
||||
}
|
||||
|
||||
// Stop shuts down the connection to the collector.
|
||||
func (c *client) Stop(ctx context.Context) error {
|
||||
return c.connection.Shutdown(ctx)
|
||||
}
|
||||
|
||||
// UploadTraces sends a batch of spans to the collector.
|
||||
func (c *client) UploadTraces(ctx context.Context, protoSpans []*tracepb.ResourceSpans) error {
|
||||
if !c.connection.Connected() {
|
||||
return fmt.Errorf("traces exporter is disconnected from the server %s: %w", c.connection.SCfg.Endpoint, c.connection.LastConnectError())
|
||||
if c.conn == nil {
|
||||
// If the caller did not provide a ClientConn when the client was
|
||||
// created, create one using the configuration they did provide.
|
||||
conn, err := grpc.DialContext(ctx, c.endpoint, c.dialOpts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Keep track that we own the lifecycle of this conn and need to close
|
||||
// it on Shutdown.
|
||||
c.ourConn = true
|
||||
c.conn = conn
|
||||
}
|
||||
|
||||
ctx, cancel := c.connection.ContextWithStop(ctx)
|
||||
defer cancel()
|
||||
ctx, tCancel := context.WithTimeout(ctx, c.connection.SCfg.Timeout)
|
||||
defer tCancel()
|
||||
// The otlptrace.Client interface states this method is called just once,
|
||||
// so no need to check if already started.
|
||||
c.tscMu.Lock()
|
||||
c.tsc = coltracepb.NewTraceServiceClient(c.conn)
|
||||
c.tscMu.Unlock()
|
||||
|
||||
ctx = c.connection.ContextWithMetadata(ctx)
|
||||
err := func() error {
|
||||
c.lock.Lock()
|
||||
defer c.lock.Unlock()
|
||||
if c.tracesClient == nil {
|
||||
return errNoClient
|
||||
}
|
||||
return c.connection.DoRequest(ctx, func(ctx context.Context) error {
|
||||
_, err := c.tracesClient.Export(ctx, &coltracepb.ExportTraceServiceRequest{
|
||||
ResourceSpans: protoSpans,
|
||||
})
|
||||
return err
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
var errAlreadyStopped = errors.New("the client is already stopped")
|
||||
|
||||
// Stop shuts down the client.
|
||||
//
|
||||
// Any active connections to a remote endpoint are closed if they were created
|
||||
// by the client. Any gRPC connection passed during creation using
|
||||
// WithGRPCConn will not be closed. It is the caller's responsibility to
|
||||
// handle cleanup of that resource.
|
||||
//
|
||||
// This method synchronizes with the UploadTraces method of the client. It
|
||||
// will wait for any active calls to that method to complete unimpeded, or it
|
||||
// will cancel any active calls if ctx expires. If ctx expires, the context
|
||||
// error will be forwarded as the returned error. All client held resources
|
||||
// will still be released in this situation.
|
||||
//
|
||||
// If the client has already stopped, an error will be returned describing
|
||||
// this.
|
||||
func (c *client) Stop(ctx context.Context) error {
|
||||
// Acquire the c.tscMu lock within the ctx lifetime.
|
||||
acquired := make(chan struct{})
|
||||
go func() {
|
||||
c.tscMu.Lock()
|
||||
close(acquired)
|
||||
}()
|
||||
if err != nil {
|
||||
c.connection.SetStateDisconnected(err)
|
||||
var err error
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
// The Stop timeout is reached. Kill any remaining exports to force
|
||||
// the clear of the lock and save the timeout error to return and
|
||||
// signal the shutdown timed out before cleanly stopping.
|
||||
c.stopFunc()
|
||||
err = ctx.Err()
|
||||
|
||||
// To ensure the client is not left in a dirty state c.tsc needs to be
|
||||
// set to nil. To avoid the race condition when doing this, ensure
|
||||
// that all the exports are killed (initiated by c.stopFunc).
|
||||
<-acquired
|
||||
case <-acquired:
|
||||
}
|
||||
// Hold the tscMu lock for the rest of the function to ensure no new
|
||||
// exports are started.
|
||||
defer c.tscMu.Unlock()
|
||||
|
||||
// The otlptrace.Client interface states this method is called only
|
||||
// once, but there is no guarantee it is called after Start. Ensure the
|
||||
// client is started before doing anything and let the called know if they
|
||||
// made a mistake.
|
||||
if c.tsc == nil {
|
||||
return errAlreadyStopped
|
||||
}
|
||||
|
||||
// Clear c.tsc to signal the client is stopped.
|
||||
c.tsc = nil
|
||||
|
||||
if c.ourConn {
|
||||
closeErr := c.conn.Close()
|
||||
// A context timeout error takes precedence over this error.
|
||||
if err == nil && closeErr != nil {
|
||||
err = closeErr
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
var errShutdown = errors.New("the client is shutdown")
|
||||
|
||||
// UploadTraces sends a batch of spans.
|
||||
//
|
||||
// Retryable errors from the server will be handled according to any
|
||||
// RetryConfig the client was created with.
|
||||
func (c *client) UploadTraces(ctx context.Context, protoSpans []*tracepb.ResourceSpans) error {
|
||||
// Hold a read lock to ensure a shut down initiated after this starts does
|
||||
// not abandon the export. This read lock acquire has less priority than a
|
||||
// write lock acquire (i.e. Stop), meaning if the client is shutting down
|
||||
// this will come after the shut down.
|
||||
c.tscMu.RLock()
|
||||
defer c.tscMu.RUnlock()
|
||||
|
||||
if c.tsc == nil {
|
||||
return errShutdown
|
||||
}
|
||||
|
||||
ctx, cancel := c.exportContext(ctx)
|
||||
defer cancel()
|
||||
|
||||
return c.requestFunc(ctx, func(iCtx context.Context) error {
|
||||
_, err := c.tsc.Export(iCtx, &coltracepb.ExportTraceServiceRequest{
|
||||
ResourceSpans: protoSpans,
|
||||
})
|
||||
// nil is converted to OK.
|
||||
if status.Code(err) == codes.OK {
|
||||
// Success.
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
// exportContext returns a copy of parent with an appropriate deadline and
|
||||
// cancellation function.
|
||||
//
|
||||
// It is the callers responsibility to cancel the returned context once its
|
||||
// use is complete, via the parent or directly with the returned CancelFunc, to
|
||||
// ensure all resources are correctly released.
|
||||
func (c *client) exportContext(parent context.Context) (context.Context, context.CancelFunc) {
|
||||
var (
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
)
|
||||
|
||||
if c.exportTimeout > 0 {
|
||||
ctx, cancel = context.WithTimeout(parent, c.exportTimeout)
|
||||
} else {
|
||||
ctx, cancel = context.WithCancel(parent)
|
||||
}
|
||||
|
||||
if c.metadata.Len() > 0 {
|
||||
ctx = metadata.NewOutgoingContext(ctx, c.metadata)
|
||||
}
|
||||
|
||||
// Unify the client stopCtx with the parent.
|
||||
go func() {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
case <-c.stopCtx.Done():
|
||||
// Cancel the export as the shutdown has timed out.
|
||||
cancel()
|
||||
}
|
||||
}()
|
||||
|
||||
return ctx, cancel
|
||||
}
|
||||
|
||||
// retryable returns if err identifies a request that can be retried and a
|
||||
// duration to wait for if an explicit throttle time is included in err.
|
||||
func retryable(err error) (bool, time.Duration) {
|
||||
//func retryable(err error) (bool, time.Duration) {
|
||||
s := status.Convert(err)
|
||||
switch s.Code() {
|
||||
case codes.Canceled,
|
||||
codes.DeadlineExceeded,
|
||||
codes.ResourceExhausted,
|
||||
codes.Aborted,
|
||||
codes.OutOfRange,
|
||||
codes.Unavailable,
|
||||
codes.DataLoss:
|
||||
return true, throttleDelay(s)
|
||||
}
|
||||
|
||||
// Not a retry-able error.
|
||||
return false, 0
|
||||
}
|
||||
|
||||
// throttleDelay returns a duration to wait for if an explicit throttle time
|
||||
// is included in the response status.
|
||||
func throttleDelay(status *status.Status) time.Duration {
|
||||
for _, detail := range status.Details() {
|
||||
if t, ok := detail.(*errdetails.RetryInfo); ok {
|
||||
return t.RetryDelay.AsDuration()
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/goleak"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/encoding/gzip"
|
||||
@@ -37,8 +38,26 @@ import (
|
||||
commonpb "go.opentelemetry.io/proto/otlp/common/v1"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
goleak.VerifyTestMain(m)
|
||||
}
|
||||
|
||||
var roSpans = tracetest.SpanStubs{{Name: "Span 0"}}.Snapshots()
|
||||
|
||||
func contextWithTimeout(parent context.Context, t *testing.T, timeout time.Duration) (context.Context, context.CancelFunc) {
|
||||
d, ok := t.Deadline()
|
||||
if !ok {
|
||||
d = time.Now().Add(timeout)
|
||||
} else {
|
||||
d = d.Add(-1 * time.Millisecond)
|
||||
now := time.Now()
|
||||
if d.Sub(now) > timeout {
|
||||
d = now.Add(timeout)
|
||||
}
|
||||
}
|
||||
return context.WithDeadline(parent, d)
|
||||
}
|
||||
|
||||
func TestNew_endToEnd(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -91,56 +110,44 @@ func newGRPCExporter(t *testing.T, ctx context.Context, endpoint string, additio
|
||||
}
|
||||
|
||||
func newExporterEndToEndTest(t *testing.T, additionalOpts []otlptracegrpc.Option) {
|
||||
mc := runMockCollectorAtEndpoint(t, "localhost:56561")
|
||||
|
||||
defer func() {
|
||||
_ = mc.stop()
|
||||
}()
|
||||
mc := runMockCollector(t)
|
||||
|
||||
<-time.After(5 * time.Millisecond)
|
||||
|
||||
ctx := context.Background()
|
||||
exp := newGRPCExporter(t, ctx, mc.endpoint, additionalOpts...)
|
||||
defer func() {
|
||||
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
t.Cleanup(func() {
|
||||
ctx, cancel := contextWithTimeout(ctx, t, 10*time.Second)
|
||||
defer cancel()
|
||||
if err := exp.Shutdown(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
require.NoError(t, exp.Shutdown(ctx))
|
||||
})
|
||||
|
||||
// RunEndToEndTest closes mc.
|
||||
otlptracetest.RunEndToEndTest(ctx, t, exp, mc)
|
||||
}
|
||||
|
||||
func TestExporterShutdown(t *testing.T) {
|
||||
mc := runMockCollectorAtEndpoint(t, "localhost:56561")
|
||||
defer func() {
|
||||
_ = mc.stop()
|
||||
}()
|
||||
mc := runMockCollectorAtEndpoint(t, "localhost:0")
|
||||
t.Cleanup(func() { require.NoError(t, mc.stop()) })
|
||||
|
||||
<-time.After(5 * time.Millisecond)
|
||||
|
||||
otlptracetest.RunExporterShutdownTest(t, func() otlptrace.Client {
|
||||
factory := func() otlptrace.Client {
|
||||
return otlptracegrpc.NewClient(
|
||||
otlptracegrpc.WithInsecure(),
|
||||
otlptracegrpc.WithEndpoint(mc.endpoint),
|
||||
otlptracegrpc.WithReconnectionPeriod(50*time.Millisecond))
|
||||
})
|
||||
otlptracegrpc.WithInsecure(),
|
||||
otlptracegrpc.WithDialOption(grpc.WithBlock()),
|
||||
)
|
||||
}
|
||||
otlptracetest.RunExporterShutdownTest(t, factory)
|
||||
}
|
||||
|
||||
func TestNew_invokeStartThenStopManyTimes(t *testing.T) {
|
||||
mc := runMockCollector(t)
|
||||
defer func() {
|
||||
_ = mc.stop()
|
||||
}()
|
||||
t.Cleanup(func() { require.NoError(t, mc.stop()) })
|
||||
|
||||
ctx := context.Background()
|
||||
exp := newGRPCExporter(t, ctx, mc.endpoint)
|
||||
defer func() {
|
||||
if err := exp.Shutdown(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
t.Cleanup(func() { require.NoError(t, exp.Shutdown(ctx)) })
|
||||
|
||||
// Invoke Start numerous times, should return errAlreadyStarted
|
||||
for i := 0; i < 10; i++ {
|
||||
@@ -160,120 +167,6 @@ func TestNew_invokeStartThenStopManyTimes(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestNew_collectorConnectionDiesThenReconnectsWhenInRestMode(t *testing.T) {
|
||||
// TODO: Fix this test #1527
|
||||
t.Skip("This test is flaky and needs to be rewritten")
|
||||
mc := runMockCollector(t)
|
||||
|
||||
reconnectionPeriod := 20 * time.Millisecond
|
||||
ctx := context.Background()
|
||||
exp := newGRPCExporter(t, ctx, mc.endpoint,
|
||||
otlptracegrpc.WithRetry(otlptracegrpc.RetryConfig{Enabled: false}),
|
||||
otlptracegrpc.WithReconnectionPeriod(reconnectionPeriod))
|
||||
defer func() { require.NoError(t, exp.Shutdown(ctx)) }()
|
||||
|
||||
// Wait for a connection.
|
||||
mc.ln.WaitForConn()
|
||||
|
||||
// We'll now stop the collector right away to simulate a connection
|
||||
// dying in the midst of communication or even not existing before.
|
||||
require.NoError(t, mc.stop())
|
||||
|
||||
// first export, it will send disconnected message to the channel on export failure,
|
||||
// trigger almost immediate reconnection
|
||||
require.Error(t, exp.ExportSpans(ctx, roSpans))
|
||||
|
||||
// second export, it will detect connection issue, change state of exporter to disconnected and
|
||||
// send message to disconnected channel but this time reconnection gouroutine will be in (rest mode, not listening to the disconnected channel)
|
||||
require.Error(t, exp.ExportSpans(ctx, roSpans))
|
||||
|
||||
// as a result we have exporter in disconnected state waiting for disconnection message to reconnect
|
||||
|
||||
// resurrect collector
|
||||
nmc := runMockCollectorAtEndpoint(t, mc.endpoint)
|
||||
|
||||
// make sure reconnection loop hits beginning and goes back to waiting mode
|
||||
// after hitting beginning of the loop it should reconnect
|
||||
nmc.ln.WaitForConn()
|
||||
|
||||
n := 10
|
||||
for i := 0; i < n; i++ {
|
||||
// when disconnected exp.ExportSpans doesnt send disconnected messages again
|
||||
// it just quits and return last connection error
|
||||
require.NoError(t, exp.ExportSpans(ctx, roSpans))
|
||||
}
|
||||
|
||||
nmaSpans := nmc.getSpans()
|
||||
|
||||
// Expecting 10 spans that were sampled, given that
|
||||
if g, w := len(nmaSpans), n; g != w {
|
||||
t.Fatalf("Connected collector: spans: got %d want %d", g, w)
|
||||
}
|
||||
|
||||
dSpans := mc.getSpans()
|
||||
// Expecting 0 spans to have been received by the original but now dead collector
|
||||
if g, w := len(dSpans), 0; g != w {
|
||||
t.Fatalf("Disconnected collector: spans: got %d want %d", g, w)
|
||||
}
|
||||
|
||||
require.NoError(t, nmc.Stop())
|
||||
}
|
||||
|
||||
func TestNew_collectorConnectionDiesThenReconnects(t *testing.T) {
|
||||
// TODO: Fix this test #1527
|
||||
t.Skip("This test is flaky and needs to be rewritten")
|
||||
mc := runMockCollector(t)
|
||||
|
||||
reconnectionPeriod := 50 * time.Millisecond
|
||||
ctx := context.Background()
|
||||
exp := newGRPCExporter(t, ctx, mc.endpoint,
|
||||
otlptracegrpc.WithRetry(otlptracegrpc.RetryConfig{Enabled: false}),
|
||||
otlptracegrpc.WithReconnectionPeriod(reconnectionPeriod))
|
||||
defer func() { require.NoError(t, exp.Shutdown(ctx)) }()
|
||||
|
||||
mc.ln.WaitForConn()
|
||||
|
||||
// We'll now stop the collector right away to simulate a connection
|
||||
// dying in the midst of communication or even not existing before.
|
||||
require.NoError(t, mc.stop())
|
||||
|
||||
// In the test below, we'll stop the collector many times,
|
||||
// while exporting traces and test to ensure that we can
|
||||
// reconnect.
|
||||
for j := 0; j < 3; j++ {
|
||||
|
||||
// No endpoint up.
|
||||
require.Error(t, exp.ExportSpans(ctx, roSpans))
|
||||
|
||||
// Now resurrect the collector by making a new one but reusing the
|
||||
// old endpoint, and the collector should reconnect automatically.
|
||||
nmc := runMockCollectorAtEndpoint(t, mc.endpoint)
|
||||
|
||||
// Give the exporter sometime to reconnect
|
||||
nmc.ln.WaitForConn()
|
||||
|
||||
n := 10
|
||||
for i := 0; i < n; i++ {
|
||||
require.NoError(t, exp.ExportSpans(ctx, roSpans))
|
||||
}
|
||||
|
||||
nmaSpans := nmc.getSpans()
|
||||
// Expecting 10 spans that were sampled, given that
|
||||
if g, w := len(nmaSpans), n; g != w {
|
||||
t.Fatalf("Round #%d: Connected collector: spans: got %d want %d", j, g, w)
|
||||
}
|
||||
|
||||
dSpans := mc.getSpans()
|
||||
// Expecting 0 spans to have been received by the original but now dead collector
|
||||
if g, w := len(dSpans), 0; g != w {
|
||||
t.Fatalf("Round #%d: Disconnected collector: spans: got %d want %d", j, g, w)
|
||||
}
|
||||
|
||||
// Disconnect for the next try.
|
||||
require.NoError(t, nmc.stop())
|
||||
}
|
||||
}
|
||||
|
||||
// This test takes a long time to run: to skip it, run tests using: -short
|
||||
func TestNew_collectorOnBadConnection(t *testing.T) {
|
||||
if testing.Short() {
|
||||
@@ -298,9 +191,7 @@ func TestNew_collectorOnBadConnection(t *testing.T) {
|
||||
|
||||
func TestNew_withEndpoint(t *testing.T) {
|
||||
mc := runMockCollector(t)
|
||||
defer func() {
|
||||
_ = mc.stop()
|
||||
}()
|
||||
t.Cleanup(func() { require.NoError(t, mc.stop()) })
|
||||
|
||||
ctx := context.Background()
|
||||
exp := newGRPCExporter(t, ctx, mc.endpoint)
|
||||
@@ -309,127 +200,64 @@ func TestNew_withEndpoint(t *testing.T) {
|
||||
|
||||
func TestNew_withHeaders(t *testing.T) {
|
||||
mc := runMockCollector(t)
|
||||
defer func() {
|
||||
_ = mc.stop()
|
||||
}()
|
||||
t.Cleanup(func() { require.NoError(t, mc.stop()) })
|
||||
|
||||
ctx := context.Background()
|
||||
exp := newGRPCExporter(t, ctx, mc.endpoint,
|
||||
otlptracegrpc.WithHeaders(map[string]string{"header1": "value1"}))
|
||||
t.Cleanup(func() { require.NoError(t, exp.Shutdown(ctx)) })
|
||||
require.NoError(t, exp.ExportSpans(ctx, roSpans))
|
||||
|
||||
defer func() {
|
||||
_ = exp.Shutdown(ctx)
|
||||
}()
|
||||
|
||||
headers := mc.getHeaders()
|
||||
require.Len(t, headers.Get("header1"), 1)
|
||||
assert.Equal(t, "value1", headers.Get("header1")[0])
|
||||
}
|
||||
|
||||
func TestNew_WithTimeout(t *testing.T) {
|
||||
tts := []struct {
|
||||
name string
|
||||
fn func(exp *otlptrace.Exporter) error
|
||||
timeout time.Duration
|
||||
spans int
|
||||
code codes.Code
|
||||
delay bool
|
||||
}{
|
||||
{
|
||||
name: "Timeout Spans",
|
||||
fn: func(exp *otlptrace.Exporter) error {
|
||||
return exp.ExportSpans(context.Background(), roSpans)
|
||||
},
|
||||
timeout: time.Millisecond * 100,
|
||||
code: codes.DeadlineExceeded,
|
||||
delay: true,
|
||||
},
|
||||
func TestExportSpansTimeoutHonored(t *testing.T) {
|
||||
ctx, cancel := contextWithTimeout(context.Background(), t, 1*time.Minute)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
{
|
||||
name: "No Timeout Spans",
|
||||
fn: func(exp *otlptrace.Exporter) error {
|
||||
return exp.ExportSpans(context.Background(), roSpans)
|
||||
},
|
||||
timeout: time.Minute,
|
||||
spans: 1,
|
||||
code: codes.OK,
|
||||
},
|
||||
}
|
||||
mc := runMockCollector(t)
|
||||
exportBlock := make(chan struct{})
|
||||
mc.traceSvc.exportBlock = exportBlock
|
||||
t.Cleanup(func() { require.NoError(t, mc.stop()) })
|
||||
|
||||
for _, tt := range tts {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
exp := newGRPCExporter(
|
||||
t,
|
||||
ctx,
|
||||
mc.endpoint,
|
||||
otlptracegrpc.WithTimeout(1*time.Nanosecond),
|
||||
otlptracegrpc.WithRetry(otlptracegrpc.RetryConfig{Enabled: false}),
|
||||
)
|
||||
t.Cleanup(func() { require.NoError(t, exp.Shutdown(ctx)) })
|
||||
|
||||
mc := runMockCollector(t)
|
||||
if tt.delay {
|
||||
mc.traceSvc.delay = time.Second * 10
|
||||
}
|
||||
defer func() {
|
||||
_ = mc.stop()
|
||||
}()
|
||||
err := exp.ExportSpans(ctx, roSpans)
|
||||
// Release the export so everything is cleaned up on shutdown.
|
||||
close(exportBlock)
|
||||
|
||||
ctx := context.Background()
|
||||
exp := newGRPCExporter(t, ctx, mc.endpoint, otlptracegrpc.WithTimeout(tt.timeout), otlptracegrpc.WithRetry(otlptracegrpc.RetryConfig{Enabled: false}))
|
||||
defer func() {
|
||||
_ = exp.Shutdown(ctx)
|
||||
}()
|
||||
|
||||
err := tt.fn(exp)
|
||||
|
||||
if tt.code == codes.OK {
|
||||
require.NoError(t, err)
|
||||
} else {
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
s := status.Convert(err)
|
||||
require.Equal(t, tt.code, s.Code())
|
||||
|
||||
require.Len(t, mc.getSpans(), tt.spans)
|
||||
})
|
||||
}
|
||||
require.Equal(t, codes.DeadlineExceeded, status.Convert(err).Code())
|
||||
}
|
||||
|
||||
func TestNew_withInvalidSecurityConfiguration(t *testing.T) {
|
||||
func TestStartErrorInvalidSecurityConfiguration(t *testing.T) {
|
||||
mc := runMockCollector(t)
|
||||
defer func() {
|
||||
_ = mc.stop()
|
||||
}()
|
||||
t.Cleanup(func() { require.NoError(t, mc.stop()) })
|
||||
|
||||
ctx := context.Background()
|
||||
driver := otlptracegrpc.NewClient(otlptracegrpc.WithEndpoint(mc.endpoint))
|
||||
exp, err := otlptrace.New(ctx, driver)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create a new collector exporter: %v", err)
|
||||
}
|
||||
|
||||
err = exp.ExportSpans(ctx, roSpans)
|
||||
|
||||
expectedErr := fmt.Sprintf("traces exporter is disconnected from the server %s: grpc: no transport security set (use grpc.WithInsecure() explicitly or set credentials)", mc.endpoint)
|
||||
|
||||
require.Error(t, err)
|
||||
require.Equal(t, expectedErr, err.Error())
|
||||
|
||||
defer func() {
|
||||
_ = exp.Shutdown(ctx)
|
||||
}()
|
||||
client := otlptracegrpc.NewClient(otlptracegrpc.WithEndpoint(mc.endpoint))
|
||||
err := client.Start(context.Background())
|
||||
// https://github.com/grpc/grpc-go/blob/a671967dfbaab779d37fd7e597d9248f13806087/clientconn.go#L82
|
||||
assert.EqualError(t, err, "grpc: no transport security set (use grpc.WithInsecure() explicitly or set credentials)")
|
||||
}
|
||||
|
||||
func TestNew_withMultipleAttributeTypes(t *testing.T) {
|
||||
mc := runMockCollector(t)
|
||||
|
||||
defer func() {
|
||||
_ = mc.stop()
|
||||
}()
|
||||
|
||||
<-time.After(5 * time.Millisecond)
|
||||
|
||||
ctx := context.Background()
|
||||
exp := newGRPCExporter(t, ctx, mc.endpoint)
|
||||
ctx, cancel := contextWithTimeout(context.Background(), t, 10*time.Second)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
defer func() {
|
||||
_ = exp.Shutdown(ctx)
|
||||
}()
|
||||
exp := newGRPCExporter(t, ctx, mc.endpoint)
|
||||
t.Cleanup(func() { require.NoError(t, exp.Shutdown(ctx)) })
|
||||
|
||||
tp := sdktrace.NewTracerProvider(
|
||||
sdktrace.WithSampler(sdktrace.AlwaysSample()),
|
||||
@@ -440,7 +268,7 @@ func TestNew_withMultipleAttributeTypes(t *testing.T) {
|
||||
sdktrace.WithMaxExportBatchSize(10),
|
||||
),
|
||||
)
|
||||
defer func() { _ = tp.Shutdown(ctx) }()
|
||||
t.Cleanup(func() { require.NoError(t, tp.Shutdown(ctx)) })
|
||||
|
||||
tr := tp.Tracer("test-tracer")
|
||||
testKvs := []attribute.KeyValue{
|
||||
@@ -456,26 +284,20 @@ func TestNew_withMultipleAttributeTypes(t *testing.T) {
|
||||
|
||||
// Flush and close.
|
||||
func() {
|
||||
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
ctx, cancel := contextWithTimeout(ctx, t, 10*time.Second)
|
||||
defer cancel()
|
||||
if err := tp.Shutdown(ctx); err != nil {
|
||||
t.Fatalf("failed to shut down a tracer provider: %v", err)
|
||||
}
|
||||
require.NoError(t, tp.Shutdown(ctx))
|
||||
}()
|
||||
|
||||
// Wait >2 cycles.
|
||||
<-time.After(40 * time.Millisecond)
|
||||
|
||||
// Now shutdown the exporter
|
||||
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||
defer cancel()
|
||||
if err := exp.Shutdown(ctx); err != nil {
|
||||
t.Fatalf("failed to stop the exporter: %v", err)
|
||||
}
|
||||
require.NoError(t, exp.Shutdown(ctx))
|
||||
|
||||
// Shutdown the collector too so that we can begin
|
||||
// verification checks of expected data back.
|
||||
_ = mc.stop()
|
||||
require.NoError(t, mc.stop())
|
||||
|
||||
// Now verify that we only got one span
|
||||
rss := mc.getSpans()
|
||||
@@ -546,39 +368,30 @@ func TestNew_withMultipleAttributeTypes(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDisconnected(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
// The endpoint is whatever, we want to be disconnected. But we
|
||||
// setting a blocking connection, so dialing to the invalid
|
||||
// endpoint actually fails.
|
||||
exp := newGRPCExporter(t, ctx, "invalid",
|
||||
otlptracegrpc.WithReconnectionPeriod(time.Hour),
|
||||
func TestStartErrorInvalidAddress(t *testing.T) {
|
||||
client := otlptracegrpc.NewClient(
|
||||
otlptracegrpc.WithInsecure(),
|
||||
// Validate the connection in Start (which should return the error).
|
||||
otlptracegrpc.WithDialOption(
|
||||
grpc.WithBlock(),
|
||||
grpc.FailOnNonTempDialError(true),
|
||||
),
|
||||
otlptracegrpc.WithEndpoint("invalid"),
|
||||
otlptracegrpc.WithReconnectionPeriod(time.Hour),
|
||||
)
|
||||
defer func() {
|
||||
assert.NoError(t, exp.Shutdown(ctx))
|
||||
}()
|
||||
|
||||
assert.Error(t, exp.ExportSpans(ctx, otlptracetest.SingleReadOnlySpan()))
|
||||
err := client.Start(context.Background())
|
||||
assert.EqualError(t, err, `connection error: desc = "transport: error while dialing: dial tcp: address invalid: missing port in address"`)
|
||||
}
|
||||
|
||||
func TestEmptyData(t *testing.T) {
|
||||
mc := runMockCollectorAtEndpoint(t, "localhost:56561")
|
||||
|
||||
defer func() {
|
||||
_ = mc.stop()
|
||||
}()
|
||||
t.Cleanup(func() { require.NoError(t, mc.stop()) })
|
||||
|
||||
<-time.After(5 * time.Millisecond)
|
||||
|
||||
ctx := context.Background()
|
||||
exp := newGRPCExporter(t, ctx, mc.endpoint)
|
||||
defer func() {
|
||||
assert.NoError(t, exp.Shutdown(ctx))
|
||||
}()
|
||||
t.Cleanup(func() { require.NoError(t, exp.Shutdown(ctx)) })
|
||||
|
||||
assert.NoError(t, exp.ExportSpans(ctx, nil))
|
||||
}
|
||||
|
@@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package connection
|
||||
package otlptracegrpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -25,8 +25,6 @@ import (
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
|
||||
"go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/retry"
|
||||
)
|
||||
|
||||
func TestThrottleDuration(t *testing.T) {
|
||||
@@ -98,8 +96,8 @@ func TestThrottleDuration(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestEvaluate(t *testing.T) {
|
||||
retryable := map[codes.Code]bool{
|
||||
func TestRetryable(t *testing.T) {
|
||||
retryableCodes := map[codes.Code]bool{
|
||||
codes.OK: false,
|
||||
codes.Canceled: true,
|
||||
codes.Unknown: false,
|
||||
@@ -119,27 +117,77 @@ func TestEvaluate(t *testing.T) {
|
||||
codes.Unauthenticated: false,
|
||||
}
|
||||
|
||||
for c, want := range retryable {
|
||||
got, _ := evaluate(status.Error(c, ""))
|
||||
for c, want := range retryableCodes {
|
||||
got, _ := retryable(status.Error(c, ""))
|
||||
assert.Equalf(t, want, got, "evaluate(%s)", c)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDoRequest(t *testing.T) {
|
||||
ev := func(error) (bool, time.Duration) { return false, 0 }
|
||||
|
||||
c := new(Connection)
|
||||
c.requestFunc = retry.Config{}.RequestFunc(ev)
|
||||
c.stopCh = make(chan struct{})
|
||||
|
||||
ctx := context.Background()
|
||||
assert.NoError(t, c.DoRequest(ctx, func(ctx context.Context) error {
|
||||
return nil
|
||||
}))
|
||||
assert.NoError(t, c.DoRequest(ctx, func(ctx context.Context) error {
|
||||
return status.Error(codes.OK, "")
|
||||
}))
|
||||
assert.ErrorIs(t, c.DoRequest(ctx, func(ctx context.Context) error {
|
||||
return assert.AnError
|
||||
}), assert.AnError)
|
||||
func TestUnstartedStop(t *testing.T) {
|
||||
client := NewClient()
|
||||
assert.ErrorIs(t, client.Stop(context.Background()), errAlreadyStopped)
|
||||
}
|
||||
|
||||
func TestUnstartedUploadTrace(t *testing.T) {
|
||||
client := NewClient()
|
||||
assert.ErrorIs(t, client.UploadTraces(context.Background(), nil), errShutdown)
|
||||
}
|
||||
|
||||
func TestExportContextHonorsParentDeadline(t *testing.T) {
|
||||
now := time.Now()
|
||||
ctx, cancel := context.WithDeadline(context.Background(), now)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
// Without a client timeout, the parent deadline should be used.
|
||||
client := newClient(WithTimeout(0))
|
||||
eCtx, eCancel := client.exportContext(ctx)
|
||||
t.Cleanup(eCancel)
|
||||
|
||||
deadline, ok := eCtx.Deadline()
|
||||
assert.True(t, ok, "deadline not propagated to child context")
|
||||
assert.Equal(t, now, deadline)
|
||||
}
|
||||
|
||||
func TestExportContextHonorsClientTimeout(t *testing.T) {
|
||||
// Setting a timeout should ensure a deadline is set on the context.
|
||||
client := newClient(WithTimeout(1 * time.Second))
|
||||
ctx, cancel := client.exportContext(context.Background())
|
||||
t.Cleanup(cancel)
|
||||
|
||||
_, ok := ctx.Deadline()
|
||||
assert.True(t, ok, "timeout not set as deadline for child context")
|
||||
}
|
||||
|
||||
func TestExportContextLinksStopSignal(t *testing.T) {
|
||||
rootCtx := context.Background()
|
||||
|
||||
client := newClient(WithInsecure())
|
||||
t.Cleanup(func() { require.NoError(t, client.Stop(rootCtx)) })
|
||||
require.NoError(t, client.Start(rootCtx))
|
||||
|
||||
ctx, cancel := client.exportContext(rootCtx)
|
||||
t.Cleanup(cancel)
|
||||
|
||||
require.False(t, func() bool {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return true
|
||||
default:
|
||||
}
|
||||
return false
|
||||
}(), "context should not be done prior to canceling it")
|
||||
|
||||
// The client.stopFunc cancels the client.stopCtx. This should have been
|
||||
// setup as a parent of ctx. Therefore, it should cancel ctx as well.
|
||||
client.stopFunc()
|
||||
|
||||
// Assert this with Eventually to account for goroutine scheduler timing.
|
||||
assert.Eventually(t, func() bool {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return true
|
||||
default:
|
||||
}
|
||||
return false
|
||||
}, 10*time.Second, time.Microsecond)
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/stretchr/testify v1.7.0
|
||||
@@ -8,7 +8,10 @@ require (
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.2.0
|
||||
go.opentelemetry.io/otel/sdk v1.2.0
|
||||
go.opentelemetry.io/proto/otlp v0.11.0
|
||||
go.uber.org/goleak v1.1.12
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013
|
||||
google.golang.org/grpc v1.42.0
|
||||
google.golang.org/protobuf v1.27.1
|
||||
)
|
||||
|
||||
replace go.opentelemetry.io/otel => ../../../..
|
||||
|
@@ -53,6 +53,11 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
@@ -61,41 +66,62 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
go.opentelemetry.io/proto/otlp v0.11.0 h1:cLDgIBTf4lLOlztkhzAEdQsJ4Lj+i5Wc9k6Nn0K1VyU=
|
||||
go.opentelemetry.io/proto/otlp v0.11.0/go.mod h1:QpEjXPrNQzrFDZgoTo49dgHR9RYRSrg3NAKnUGl9YpQ=
|
||||
go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA=
|
||||
go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/sync v0.0.0-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=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -127,8 +153,9 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
|
@@ -18,8 +18,6 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -45,12 +43,12 @@ func makeMockCollector(t *testing.T, mockConfig *mockConfig) *mockCollector {
|
||||
type mockTraceService struct {
|
||||
collectortracepb.UnimplementedTraceServiceServer
|
||||
|
||||
errors []error
|
||||
requests int
|
||||
mu sync.RWMutex
|
||||
storage otlptracetest.SpansStorage
|
||||
headers metadata.MD
|
||||
delay time.Duration
|
||||
errors []error
|
||||
requests int
|
||||
mu sync.RWMutex
|
||||
storage otlptracetest.SpansStorage
|
||||
headers metadata.MD
|
||||
exportBlock chan struct{}
|
||||
}
|
||||
|
||||
func (mts *mockTraceService) getHeaders() metadata.MD {
|
||||
@@ -72,16 +70,18 @@ func (mts *mockTraceService) getResourceSpans() []*tracepb.ResourceSpans {
|
||||
}
|
||||
|
||||
func (mts *mockTraceService) Export(ctx context.Context, exp *collectortracepb.ExportTraceServiceRequest) (*collectortracepb.ExportTraceServiceResponse, error) {
|
||||
if mts.delay > 0 {
|
||||
time.Sleep(mts.delay)
|
||||
}
|
||||
|
||||
mts.mu.Lock()
|
||||
defer func() {
|
||||
mts.requests++
|
||||
mts.mu.Unlock()
|
||||
}()
|
||||
|
||||
if mts.exportBlock != nil {
|
||||
// Do this with the lock held so the mockCollector.Stop does not
|
||||
// abandon cleaning up resources.
|
||||
<-mts.exportBlock
|
||||
}
|
||||
|
||||
reply := &collectortracepb.ExportTraceServiceResponse{}
|
||||
if mts.requests < len(mts.errors) {
|
||||
idx := mts.requests
|
||||
@@ -99,7 +99,6 @@ type mockCollector struct {
|
||||
traceSvc *mockTraceService
|
||||
|
||||
endpoint string
|
||||
ln *listener
|
||||
stopFunc func()
|
||||
stopOnce sync.Once
|
||||
}
|
||||
@@ -169,70 +168,12 @@ func runMockCollectorWithConfig(t *testing.T, mockConfig *mockConfig) *mockColle
|
||||
srv := grpc.NewServer()
|
||||
mc := makeMockCollector(t, mockConfig)
|
||||
collectortracepb.RegisterTraceServiceServer(srv, mc.traceSvc)
|
||||
mc.ln = newListener(ln)
|
||||
go func() {
|
||||
_ = srv.Serve((net.Listener)(mc.ln))
|
||||
_ = srv.Serve(ln)
|
||||
}()
|
||||
|
||||
mc.endpoint = ln.Addr().String()
|
||||
// srv.Stop calls Close on mc.ln.
|
||||
mc.stopFunc = srv.Stop
|
||||
|
||||
return mc
|
||||
}
|
||||
|
||||
type listener struct {
|
||||
closeOnce sync.Once
|
||||
wrapped net.Listener
|
||||
C chan struct{}
|
||||
}
|
||||
|
||||
func newListener(wrapped net.Listener) *listener {
|
||||
return &listener{
|
||||
wrapped: wrapped,
|
||||
C: make(chan struct{}, 1),
|
||||
}
|
||||
}
|
||||
|
||||
func (l *listener) Close() error { return l.wrapped.Close() }
|
||||
|
||||
func (l *listener) Addr() net.Addr { return l.wrapped.Addr() }
|
||||
|
||||
// Accept waits for and returns the next connection to the listener. It will
|
||||
// send a signal on l.C that a connection has been made before returning.
|
||||
func (l *listener) Accept() (net.Conn, error) {
|
||||
conn, err := l.wrapped.Accept()
|
||||
if err != nil {
|
||||
// Go 1.16 exported net.ErrClosed that could clean up this check, but to
|
||||
// remain backwards compatible with previous versions of Go that we
|
||||
// support the following string evaluation is used instead to keep in line
|
||||
// with the previously recommended way to check this:
|
||||
// https://github.com/golang/go/issues/4373#issuecomment-353076799
|
||||
if strings.Contains(err.Error(), "use of closed network connection") {
|
||||
// If the listener has been closed, do not allow callers of
|
||||
// WaitForConn to wait for a connection that will never come.
|
||||
l.closeOnce.Do(func() { close(l.C) })
|
||||
}
|
||||
return conn, err
|
||||
}
|
||||
|
||||
select {
|
||||
case l.C <- struct{}{}:
|
||||
default:
|
||||
// If C is full, assume nobody is listening and move on.
|
||||
}
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
// WaitForConn will wait indefintely for a connection to be estabilished with
|
||||
// the listener before returning.
|
||||
func (l *listener) WaitForConn() {
|
||||
for {
|
||||
select {
|
||||
case <-l.C:
|
||||
return
|
||||
default:
|
||||
runtime.Gosched()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -31,8 +31,19 @@ type Option interface {
|
||||
applyGRPCOption(*otlpconfig.Config)
|
||||
}
|
||||
|
||||
// RetryConfig defines configuration for retrying batches in case of export
|
||||
// failure using an exponential backoff.
|
||||
func asGRPCOptions(opts []Option) []otlpconfig.GRPCOption {
|
||||
converted := make([]otlpconfig.GRPCOption, len(opts))
|
||||
for i, o := range opts {
|
||||
converted[i] = otlpconfig.NewGRPCOption(o.applyGRPCOption)
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
// RetryConfig defines configuration for retrying export of span batches that
|
||||
// failed to be received by the target endpoint.
|
||||
//
|
||||
// This configuration does not define any network retry strategy. That is
|
||||
// entirely handled by the gRPC ClientConn.
|
||||
type RetryConfig retry.Config
|
||||
|
||||
type wrappedOption struct {
|
||||
@@ -43,22 +54,28 @@ func (w wrappedOption) applyGRPCOption(cfg *otlpconfig.Config) {
|
||||
w.ApplyGRPCOption(cfg)
|
||||
}
|
||||
|
||||
// WithInsecure disables client transport security for the exporter's gRPC connection
|
||||
// just like grpc.WithInsecure() https://pkg.go.dev/google.golang.org/grpc#WithInsecure
|
||||
// does. Note, by default, client security is required unless WithInsecure is used.
|
||||
// WithInsecure disables client transport security for the exporter's gRPC
|
||||
// connection just like grpc.WithInsecure()
|
||||
// (https://pkg.go.dev/google.golang.org/grpc#WithInsecure) does. Note, by
|
||||
// default, client security is required unless WithInsecure is used.
|
||||
//
|
||||
// This option has no effect if WithGRPCConn is used.
|
||||
func WithInsecure() Option {
|
||||
return wrappedOption{otlpconfig.WithInsecure()}
|
||||
}
|
||||
|
||||
// WithEndpoint allows one to set the endpoint that the exporter will
|
||||
// connect to the collector on. If unset, it will instead try to use
|
||||
// connect to DefaultCollectorHost:DefaultCollectorPort.
|
||||
// WithEndpoint sets the target endpoint the exporter will connect to. If
|
||||
// unset, localhost:4317 will be used as a default.
|
||||
//
|
||||
// This option has no effect if WithGRPCConn is used.
|
||||
func WithEndpoint(endpoint string) Option {
|
||||
return wrappedOption{otlpconfig.WithEndpoint(endpoint)}
|
||||
}
|
||||
|
||||
// WithReconnectionPeriod allows one to set the delay between next connection attempt
|
||||
// after failing to connect with the collector.
|
||||
// WithReconnectionPeriod set the minimum amount of time between connection
|
||||
// attempts to the target endpoint.
|
||||
//
|
||||
// This option has no effect if WithGRPCConn is used.
|
||||
func WithReconnectionPeriod(rp time.Duration) Option {
|
||||
return wrappedOption{otlpconfig.NewGRPCOption(func(cfg *otlpconfig.Config) {
|
||||
cfg.ReconnectionPeriod = rp
|
||||
@@ -75,25 +92,30 @@ func compressorToCompression(compressor string) otlpconfig.Compression {
|
||||
return otlpconfig.NoCompression
|
||||
}
|
||||
|
||||
// WithCompressor will set the compressor for the gRPC client to use when sending requests.
|
||||
// It is the responsibility of the caller to ensure that the compressor set has been registered
|
||||
// with google.golang.org/grpc/encoding. This can be done by encoding.RegisterCompressor. Some
|
||||
// compressors auto-register on import, such as gzip, which can be registered by calling
|
||||
// WithCompressor sets the compressor for the gRPC client to use when sending
|
||||
// requests. It is the responsibility of the caller to ensure that the
|
||||
// compressor set has been registered with google.golang.org/grpc/encoding.
|
||||
// This can be done by encoding.RegisterCompressor. Some compressors
|
||||
// auto-register on import, such as gzip, which can be registered by calling
|
||||
// `import _ "google.golang.org/grpc/encoding/gzip"`.
|
||||
//
|
||||
// This option has no effect if WithGRPCConn is used.
|
||||
func WithCompressor(compressor string) Option {
|
||||
return wrappedOption{otlpconfig.WithCompression(compressorToCompression(compressor))}
|
||||
}
|
||||
|
||||
// WithHeaders will send the provided headers with gRPC requests.
|
||||
// WithHeaders will send the provided headers with each gRPC requests.
|
||||
func WithHeaders(headers map[string]string) Option {
|
||||
return wrappedOption{otlpconfig.WithHeaders(headers)}
|
||||
}
|
||||
|
||||
// WithTLSCredentials allows the connection to use TLS credentials
|
||||
// when talking to the server. It takes in grpc.TransportCredentials instead
|
||||
// of say a Certificate file or a tls.Certificate, because the retrieving of
|
||||
// these credentials can be done in many ways e.g. plain file, in code tls.Config
|
||||
// or by certificate rotation, so it is up to the caller to decide what to use.
|
||||
// WithTLSCredentials allows the connection to use TLS credentials when
|
||||
// talking to the server. It takes in grpc.TransportCredentials instead of say
|
||||
// a Certificate file or a tls.Certificate, because the retrieving of these
|
||||
// credentials can be done in many ways e.g. plain file, in code tls.Config or
|
||||
// by certificate rotation, so it is up to the caller to decide what to use.
|
||||
//
|
||||
// This option has no effect if WithGRPCConn is used.
|
||||
func WithTLSCredentials(creds credentials.TransportCredentials) Option {
|
||||
return wrappedOption{otlpconfig.NewGRPCOption(func(cfg *otlpconfig.Config) {
|
||||
cfg.Traces.GRPCCredentials = creds
|
||||
@@ -101,40 +123,63 @@ func WithTLSCredentials(creds credentials.TransportCredentials) Option {
|
||||
}
|
||||
|
||||
// WithServiceConfig defines the default gRPC service config used.
|
||||
//
|
||||
// This option has no effect if WithGRPCConn is used.
|
||||
func WithServiceConfig(serviceConfig string) Option {
|
||||
return wrappedOption{otlpconfig.NewGRPCOption(func(cfg *otlpconfig.Config) {
|
||||
cfg.ServiceConfig = serviceConfig
|
||||
})}
|
||||
}
|
||||
|
||||
// WithDialOption opens support to any grpc.DialOption to be used. If it conflicts
|
||||
// with some other configuration the GRPC specified via the collector the ones here will
|
||||
// take preference since they are set last.
|
||||
// WithDialOption sets explicit grpc.DialOptions to use when making a
|
||||
// connection. The options here are appended to the internal grpc.DialOptions
|
||||
// used so they will take precedence over any other internal grpc.DialOptions
|
||||
// they might conflict with.
|
||||
//
|
||||
// This option has no effect if WithGRPCConn is used.
|
||||
func WithDialOption(opts ...grpc.DialOption) Option {
|
||||
return wrappedOption{otlpconfig.NewGRPCOption(func(cfg *otlpconfig.Config) {
|
||||
cfg.DialOptions = opts
|
||||
})}
|
||||
}
|
||||
|
||||
// WithGRPCConn allows reusing existing gRPC connection when it has already been
|
||||
// established for other services. When set, other dial options will be ignored.
|
||||
// WithGRPCConn sets conn as the gRPC ClientConn used for all communication.
|
||||
//
|
||||
// This option takes precedence over any other option that relates to
|
||||
// establishing or persisting a gRPC connection to a target endpoint. Any
|
||||
// other option of those types passed will be ignored.
|
||||
//
|
||||
// It is the callers responsibility to close the passed conn. The client
|
||||
// Shutdown method will not close this connection.
|
||||
func WithGRPCConn(conn *grpc.ClientConn) Option {
|
||||
return wrappedOption{otlpconfig.NewGRPCOption(func(cfg *otlpconfig.Config) {
|
||||
cfg.GRPCConn = conn
|
||||
})}
|
||||
}
|
||||
|
||||
// WithTimeout tells the driver the max waiting time for the backend to process
|
||||
// each spans batch. If unset, the default will be 10 seconds.
|
||||
// WithTimeout sets the max amount of time a client will attempt to export a
|
||||
// batch of spans. This takes precedence over any retry settings defined with
|
||||
// WithRetry, once this time limit has been reached the export is abandoned
|
||||
// and the batch of spans is dropped.
|
||||
//
|
||||
// If unset, the default timeout will be set to 10 seconds.
|
||||
func WithTimeout(duration time.Duration) Option {
|
||||
return wrappedOption{otlpconfig.WithTimeout(duration)}
|
||||
}
|
||||
|
||||
// WithRetry configures the retry policy for transient errors that may occurs
|
||||
// when exporting traces. An exponential back-off algorithm is used to ensure
|
||||
// endpoints are not overwhelmed with retries. If unset, the default retry
|
||||
// policy will retry after 5 seconds and increase exponentially after each
|
||||
// error for a total of 1 minute.
|
||||
// WithRetry sets the retry policy for transient retryable errors that may be
|
||||
// returned by the target endpoint when exporting a batch of spans.
|
||||
//
|
||||
// If the target endpoint responds with not only a retryable error, but
|
||||
// explicitly returns a backoff time in the response. That time will take
|
||||
// precedence over these settings.
|
||||
//
|
||||
// These settings do not define any network retry strategy. That is entirely
|
||||
// handled by the gRPC ClientConn.
|
||||
//
|
||||
// If unset, the default retry policy will be used. It will retry the export
|
||||
// 5 seconds after receiving a retryable error and increase exponentially
|
||||
// after each error for no more than a total time of 1 minute.
|
||||
func WithRetry(settings RetryConfig) Option {
|
||||
return wrappedOption{otlpconfig.WithRetry(retry.Config(settings))}
|
||||
}
|
||||
|
@@ -71,6 +71,7 @@ type client struct {
|
||||
requestFunc retry.RequestFunc
|
||||
client *http.Client
|
||||
stopCh chan struct{}
|
||||
stopOnce sync.Once
|
||||
}
|
||||
|
||||
var _ otlptrace.Client = (*client)(nil)
|
||||
@@ -132,7 +133,9 @@ func (d *client) Start(ctx context.Context) error {
|
||||
|
||||
// Stop shuts down the client and interrupt any in-flight request.
|
||||
func (d *client) Stop(ctx context.Context) error {
|
||||
close(d.stopCh)
|
||||
d.stopOnce.Do(func() {
|
||||
close(d.stopCh)
|
||||
})
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/stretchr/testify v1.7.0
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/exporters/prometheus
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/prometheus/client_golang v1.11.0
|
||||
|
@@ -4,8 +4,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/benbjohnson/clock v1.2.0 h1:9Re3G2TWxkE06LdMWMpcY6KV81GLXMGiYpPYUPkFAws=
|
||||
github.com/benbjohnson/clock v1.2.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
|
||||
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/exporters/stdout/stdoutmetric
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
replace (
|
||||
go.opentelemetry.io/otel => ../../..
|
||||
|
@@ -1,5 +1,5 @@
|
||||
github.com/benbjohnson/clock v1.2.0 h1:9Re3G2TWxkE06LdMWMpcY6KV81GLXMGiYpPYUPkFAws=
|
||||
github.com/benbjohnson/clock v1.2.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
|
||||
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/go-logr/logr v1.2.0 h1:QK40JKJyMdUDz+h+xvCsru/bJhvG0UxvePV0ufL/AcE=
|
||||
@@ -15,7 +15,6 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/exporters/stdout/stdouttrace
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
replace (
|
||||
go.opentelemetry.io/otel => ../../..
|
||||
|
@@ -13,7 +13,6 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/exporters/zipkin
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/google/go-cmp v0.5.6
|
||||
|
2
go.mod
2
go.mod
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/go-logr/logr v1.2.0
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/internal/metric
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/stretchr/testify v1.7.0
|
||||
|
@@ -11,7 +11,6 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/internal/tools
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/client9/misspell v0.3.4
|
||||
|
@@ -186,7 +186,6 @@ github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4=
|
||||
github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
@@ -458,7 +457,6 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfC
|
||||
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
|
||||
github.com/josharian/txtarfs v0.0.0-20210218200122-0702f000015a h1:8NZHLa6Gp0hW6xJ0c3F1Kse7dJw30fOcDzHuF9sLbnE=
|
||||
github.com/josharian/txtarfs v0.0.0-20210218200122-0702f000015a/go.mod h1:izVPOvVRsHiKkeGCT6tYBNWyDVuzj9wAaBb5R9qamfw=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
@@ -620,10 +618,8 @@ github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFSt
|
||||
github.com/otiai10/copy v1.2.0 h1:HvG945u96iNadPoG2/Ja2+AUJeW5YuFQMixq9yirC+k=
|
||||
github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw=
|
||||
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
|
||||
github.com/otiai10/curr v1.0.0 h1:TJIWdbX0B+kpNagQrjgq8bCMrbhiuX73M2XwgtDMoOI=
|
||||
github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
|
||||
github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
|
||||
github.com/otiai10/mint v1.3.1 h1:BCmzIS3n71sGfHB5NMNDB3lHYPz8fWSkCAErHed//qc=
|
||||
github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/metric
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
replace go.opentelemetry.io/otel => ../
|
||||
|
||||
|
@@ -25,7 +25,7 @@ const baggageHeader = "baggage"
|
||||
// Baggage is a propagator that supports the W3C Baggage format.
|
||||
//
|
||||
// This propagates user-defined baggage associated with a trace. The complete
|
||||
// specification is defined at https://w3c.github.io/baggage/.
|
||||
// specification is defined at https://www.w3.org/TR/baggage/.
|
||||
type Baggage struct{}
|
||||
|
||||
var _ TextMapPropagator = Baggage{}
|
||||
|
@@ -19,6 +19,6 @@ OpenTelemetry propagators are used to extract and inject context data from and
|
||||
into messages exchanged by applications. The propagator supported by this
|
||||
package is the W3C Trace Context encoding
|
||||
(https://www.w3.org/TR/trace-context/), and W3C Baggage
|
||||
(https://w3c.github.io/baggage/).
|
||||
(https://www.w3.org/TR/baggage/).
|
||||
*/
|
||||
package propagation // import "go.opentelemetry.io/otel/propagation"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/schema
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/Masterminds/semver/v3 v3.1.1
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/sdk/export/metric
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
replace go.opentelemetry.io/otel => ../../..
|
||||
|
||||
|
@@ -13,7 +13,6 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/sdk
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
replace go.opentelemetry.io/otel => ../
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/sdk/metric
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
replace go.opentelemetry.io/otel => ../..
|
||||
|
||||
@@ -41,7 +41,7 @@ replace go.opentelemetry.io/otel/sdk/metric => ./
|
||||
replace go.opentelemetry.io/otel/trace => ../../trace
|
||||
|
||||
require (
|
||||
github.com/benbjohnson/clock v1.2.0 // do not upgrade to v1.1.x because it would require Go >= 1.15
|
||||
github.com/benbjohnson/clock v1.3.0
|
||||
github.com/stretchr/testify v1.7.0
|
||||
go.opentelemetry.io/otel v1.2.0
|
||||
go.opentelemetry.io/otel/internal/metric v0.25.0
|
||||
|
@@ -1,5 +1,5 @@
|
||||
github.com/benbjohnson/clock v1.2.0 h1:9Re3G2TWxkE06LdMWMpcY6KV81GLXMGiYpPYUPkFAws=
|
||||
github.com/benbjohnson/clock v1.2.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
|
||||
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/go-logr/logr v1.2.0 h1:QK40JKJyMdUDz+h+xvCsru/bJhvG0UxvePV0ufL/AcE=
|
||||
@@ -15,7 +15,6 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
@@ -17,6 +17,7 @@ package trace_test
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
||||
@@ -44,6 +45,7 @@ func BenchmarkSpanWithAttributes_4(b *testing.B) {
|
||||
span.SetAttributes(
|
||||
attribute.Bool("key1", false),
|
||||
attribute.String("key2", "hello"),
|
||||
attribute.Int64("key3", 123),
|
||||
attribute.Float64("key4", 123.456),
|
||||
)
|
||||
span.End()
|
||||
@@ -61,9 +63,11 @@ func BenchmarkSpanWithAttributes_8(b *testing.B) {
|
||||
span.SetAttributes(
|
||||
attribute.Bool("key1", false),
|
||||
attribute.String("key2", "hello"),
|
||||
attribute.Int64("key3", 123),
|
||||
attribute.Float64("key4", 123.456),
|
||||
attribute.Bool("key21", false),
|
||||
attribute.String("key22", "hello"),
|
||||
attribute.Int64("key23", 123),
|
||||
attribute.Float64("key24", 123.456),
|
||||
)
|
||||
span.End()
|
||||
@@ -114,6 +118,67 @@ func BenchmarkSpanWithAttributes_all_2x(b *testing.B) {
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkSpanWithEvents_4(b *testing.B) {
|
||||
traceBenchmark(b, "Benchmark Start With 4 Events", func(b *testing.B, t trace.Tracer) {
|
||||
ctx := context.Background()
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, span := t.Start(ctx, "/foo")
|
||||
span.AddEvent("event1")
|
||||
span.AddEvent("event2")
|
||||
span.AddEvent("event3")
|
||||
span.AddEvent("event4")
|
||||
span.End()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkSpanWithEvents_8(b *testing.B) {
|
||||
traceBenchmark(b, "Benchmark Start With 4 Events", func(b *testing.B, t trace.Tracer) {
|
||||
ctx := context.Background()
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, span := t.Start(ctx, "/foo")
|
||||
span.AddEvent("event1")
|
||||
span.AddEvent("event2")
|
||||
span.AddEvent("event3")
|
||||
span.AddEvent("event4")
|
||||
span.AddEvent("event5")
|
||||
span.AddEvent("event6")
|
||||
span.AddEvent("event7")
|
||||
span.AddEvent("event8")
|
||||
span.End()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkSpanWithEvents_WithStackTrace(b *testing.B) {
|
||||
traceBenchmark(b, "Benchmark Start With 4 Attributes", func(b *testing.B, t trace.Tracer) {
|
||||
ctx := context.Background()
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, span := t.Start(ctx, "/foo")
|
||||
span.AddEvent("event1", trace.WithStackTrace(true))
|
||||
span.End()
|
||||
}
|
||||
})
|
||||
}
|
||||
func BenchmarkSpanWithEvents_WithTimestamp(b *testing.B) {
|
||||
traceBenchmark(b, "Benchmark Start With 4 Attributes", func(b *testing.B, t trace.Tracer) {
|
||||
ctx := context.Background()
|
||||
b.ResetTimer()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
_, span := t.Start(ctx, "/foo")
|
||||
span.AddEvent("event1", trace.WithTimestamp(time.Unix(0, 0)))
|
||||
span.End()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkTraceID_DotString(b *testing.B) {
|
||||
t, _ := trace.TraceIDFromHex("0000000000000001000000000000002a")
|
||||
sc := trace.NewSpanContext(trace.SpanContextConfig{TraceID: t})
|
||||
|
@@ -23,6 +23,7 @@ import (
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
// HTTP scheme attributes.
|
||||
@@ -269,6 +270,21 @@ func SpanStatusFromHTTPStatusCode(code int) (codes.Code, string) {
|
||||
return spanCode, ""
|
||||
}
|
||||
|
||||
// SpanStatusFromHTTPStatusCodeAndSpanKind generates a status code and a message
|
||||
// as specified by the OpenTelemetry specification for a span.
|
||||
// Exclude 4xx for SERVER to set the appropriate status.
|
||||
func SpanStatusFromHTTPStatusCodeAndSpanKind(code int, spanKind trace.SpanKind) (codes.Code, string) {
|
||||
spanCode, valid := validateHTTPStatusCode(code)
|
||||
if !valid {
|
||||
return spanCode, fmt.Sprintf("Invalid HTTP status code %d", code)
|
||||
}
|
||||
category := code / 100
|
||||
if spanKind == trace.SpanKindServer && category == 4 {
|
||||
return codes.Unset, ""
|
||||
}
|
||||
return spanCode, ""
|
||||
}
|
||||
|
||||
// Validates the HTTP status code and returns corresponding span status code.
|
||||
// If the `code` is not a valid HTTP status code, returns span status Error
|
||||
// and false.
|
||||
|
@@ -20,6 +20,8 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
@@ -854,7 +856,7 @@ func TestHTTPAttributesFromHTTPStatusCode(t *testing.T) {
|
||||
|
||||
func TestSpanStatusFromHTTPStatusCode(t *testing.T) {
|
||||
for code := 0; code < 1000; code++ {
|
||||
expected := getExpectedCodeForHTTPCode(code)
|
||||
expected := getExpectedCodeForHTTPCode(code, trace.SpanKindClient)
|
||||
got, msg := SpanStatusFromHTTPStatusCode(code)
|
||||
assert.Equalf(t, expected, got, "%s vs %s", expected, got)
|
||||
|
||||
@@ -867,7 +869,24 @@ func TestSpanStatusFromHTTPStatusCode(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func getExpectedCodeForHTTPCode(code int) codes.Code {
|
||||
func TestSpanStatusFromHTTPStatusCodeAndSpanKind(t *testing.T) {
|
||||
for code := 0; code < 1000; code++ {
|
||||
expected := getExpectedCodeForHTTPCode(code, trace.SpanKindClient)
|
||||
got, msg := SpanStatusFromHTTPStatusCodeAndSpanKind(code, trace.SpanKindClient)
|
||||
assert.Equalf(t, expected, got, "%s vs %s", expected, got)
|
||||
|
||||
_, valid := validateHTTPStatusCode(code)
|
||||
if !valid {
|
||||
assert.NotEmpty(t, msg, "message should be set if error cannot be inferred from code")
|
||||
} else {
|
||||
assert.Empty(t, msg, "message should not be set if error can be inferred from code")
|
||||
}
|
||||
}
|
||||
code, _ := SpanStatusFromHTTPStatusCodeAndSpanKind(400, trace.SpanKindServer)
|
||||
assert.Equalf(t, codes.Unset, code, "message should be set if error cannot be inferred from code")
|
||||
}
|
||||
|
||||
func getExpectedCodeForHTTPCode(code int, spanKind trace.SpanKind) codes.Code {
|
||||
if http.StatusText(code) == "" {
|
||||
return codes.Error
|
||||
}
|
||||
@@ -886,6 +905,9 @@ func getExpectedCodeForHTTPCode(code int) codes.Code {
|
||||
if category > 0 && category < 4 {
|
||||
return codes.Unset
|
||||
}
|
||||
if spanKind == trace.SpanKindServer && category == 4 {
|
||||
return codes.Unset
|
||||
}
|
||||
return codes.Error
|
||||
}
|
||||
|
||||
|
@@ -23,6 +23,7 @@ import (
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
// HTTP scheme attributes.
|
||||
@@ -269,6 +270,21 @@ func SpanStatusFromHTTPStatusCode(code int) (codes.Code, string) {
|
||||
return spanCode, ""
|
||||
}
|
||||
|
||||
// SpanStatusFromHTTPStatusCodeAndSpanKind generates a status code and a message
|
||||
// as specified by the OpenTelemetry specification for a span.
|
||||
// Exclude 4xx for SERVER to set the appropriate status.
|
||||
func SpanStatusFromHTTPStatusCodeAndSpanKind(code int, spanKind trace.SpanKind) (codes.Code, string) {
|
||||
spanCode, valid := validateHTTPStatusCode(code)
|
||||
if !valid {
|
||||
return spanCode, fmt.Sprintf("Invalid HTTP status code %d", code)
|
||||
}
|
||||
category := code / 100
|
||||
if spanKind == trace.SpanKindServer && category == 4 {
|
||||
return codes.Unset, ""
|
||||
}
|
||||
return spanCode, ""
|
||||
}
|
||||
|
||||
// Validates the HTTP status code and returns corresponding span status code.
|
||||
// If the `code` is not a valid HTTP status code, returns span status Error
|
||||
// and false.
|
||||
|
@@ -23,6 +23,8 @@ import (
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
)
|
||||
@@ -854,7 +856,7 @@ func TestHTTPAttributesFromHTTPStatusCode(t *testing.T) {
|
||||
|
||||
func TestSpanStatusFromHTTPStatusCode(t *testing.T) {
|
||||
for code := 0; code < 1000; code++ {
|
||||
expected := getExpectedCodeForHTTPCode(code)
|
||||
expected := getExpectedCodeForHTTPCode(code, trace.SpanKindClient)
|
||||
got, msg := SpanStatusFromHTTPStatusCode(code)
|
||||
assert.Equalf(t, expected, got, "%s vs %s", expected, got)
|
||||
|
||||
@@ -867,7 +869,24 @@ func TestSpanStatusFromHTTPStatusCode(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func getExpectedCodeForHTTPCode(code int) codes.Code {
|
||||
func TestSpanStatusFromHTTPStatusCodeAndSpanKind(t *testing.T) {
|
||||
for code := 0; code < 1000; code++ {
|
||||
expected := getExpectedCodeForHTTPCode(code, trace.SpanKindClient)
|
||||
got, msg := SpanStatusFromHTTPStatusCodeAndSpanKind(code, trace.SpanKindClient)
|
||||
assert.Equalf(t, expected, got, "%s vs %s", expected, got)
|
||||
|
||||
_, valid := validateHTTPStatusCode(code)
|
||||
if !valid {
|
||||
assert.NotEmpty(t, msg, "message should be set if error cannot be inferred from code")
|
||||
} else {
|
||||
assert.Empty(t, msg, "message should not be set if error can be inferred from code")
|
||||
}
|
||||
}
|
||||
code, _ := SpanStatusFromHTTPStatusCodeAndSpanKind(400, trace.SpanKindServer)
|
||||
assert.Equalf(t, codes.Unset, code, "message should be set if error cannot be inferred from code")
|
||||
}
|
||||
|
||||
func getExpectedCodeForHTTPCode(code int, spanKind trace.SpanKind) codes.Code {
|
||||
if http.StatusText(code) == "" {
|
||||
return codes.Error
|
||||
}
|
||||
@@ -886,6 +905,9 @@ func getExpectedCodeForHTTPCode(code int) codes.Code {
|
||||
if category > 0 && category < 4 {
|
||||
return codes.Unset
|
||||
}
|
||||
if spanKind == trace.SpanKindServer && category == 4 {
|
||||
return codes.Unset
|
||||
}
|
||||
return codes.Error
|
||||
}
|
||||
|
||||
|
@@ -23,6 +23,7 @@ import (
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
// HTTP scheme attributes.
|
||||
@@ -269,6 +270,21 @@ func SpanStatusFromHTTPStatusCode(code int) (codes.Code, string) {
|
||||
return spanCode, ""
|
||||
}
|
||||
|
||||
// SpanStatusFromHTTPStatusCodeAndSpanKind generates a status code and a message
|
||||
// as specified by the OpenTelemetry specification for a span.
|
||||
// Exclude 4xx for SERVER to set the appropriate status.
|
||||
func SpanStatusFromHTTPStatusCodeAndSpanKind(code int, spanKind trace.SpanKind) (codes.Code, string) {
|
||||
spanCode, valid := validateHTTPStatusCode(code)
|
||||
if !valid {
|
||||
return spanCode, fmt.Sprintf("Invalid HTTP status code %d", code)
|
||||
}
|
||||
category := code / 100
|
||||
if spanKind == trace.SpanKindServer && category == 4 {
|
||||
return codes.Unset, ""
|
||||
}
|
||||
return spanCode, ""
|
||||
}
|
||||
|
||||
// Validates the HTTP status code and returns corresponding span status code.
|
||||
// If the `code` is not a valid HTTP status code, returns span status Error
|
||||
// and false.
|
||||
|
@@ -25,6 +25,7 @@ import (
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
)
|
||||
|
||||
type tlsOption int
|
||||
@@ -854,7 +855,7 @@ func TestHTTPAttributesFromHTTPStatusCode(t *testing.T) {
|
||||
|
||||
func TestSpanStatusFromHTTPStatusCode(t *testing.T) {
|
||||
for code := 0; code < 1000; code++ {
|
||||
expected := getExpectedCodeForHTTPCode(code)
|
||||
expected := getExpectedCodeForHTTPCode(code, trace.SpanKindClient)
|
||||
got, msg := SpanStatusFromHTTPStatusCode(code)
|
||||
assert.Equalf(t, expected, got, "%s vs %s", expected, got)
|
||||
|
||||
@@ -867,7 +868,24 @@ func TestSpanStatusFromHTTPStatusCode(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func getExpectedCodeForHTTPCode(code int) codes.Code {
|
||||
func TestSpanStatusFromHTTPStatusCodeAndSpanKind(t *testing.T) {
|
||||
for code := 0; code < 1000; code++ {
|
||||
expected := getExpectedCodeForHTTPCode(code, trace.SpanKindClient)
|
||||
got, msg := SpanStatusFromHTTPStatusCodeAndSpanKind(code, trace.SpanKindClient)
|
||||
assert.Equalf(t, expected, got, "%s vs %s", expected, got)
|
||||
|
||||
_, valid := validateHTTPStatusCode(code)
|
||||
if !valid {
|
||||
assert.NotEmpty(t, msg, "message should be set if error cannot be inferred from code")
|
||||
} else {
|
||||
assert.Empty(t, msg, "message should not be set if error can be inferred from code")
|
||||
}
|
||||
}
|
||||
code, _ := SpanStatusFromHTTPStatusCodeAndSpanKind(400, trace.SpanKindServer)
|
||||
assert.Equalf(t, codes.Unset, code, "message should be set if error cannot be inferred from code")
|
||||
}
|
||||
|
||||
func getExpectedCodeForHTTPCode(code int, spanKind trace.SpanKind) codes.Code {
|
||||
if http.StatusText(code) == "" {
|
||||
return codes.Error
|
||||
}
|
||||
@@ -886,6 +904,9 @@ func getExpectedCodeForHTTPCode(code int) codes.Code {
|
||||
if category > 0 && category < 4 {
|
||||
return codes.Unset
|
||||
}
|
||||
if spanKind == trace.SpanKindServer && category == 4 {
|
||||
return codes.Unset
|
||||
}
|
||||
return codes.Error
|
||||
}
|
||||
|
||||
|
@@ -21,6 +21,8 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/codes"
|
||||
)
|
||||
@@ -269,6 +271,21 @@ func SpanStatusFromHTTPStatusCode(code int) (codes.Code, string) {
|
||||
return spanCode, ""
|
||||
}
|
||||
|
||||
// SpanStatusFromHTTPStatusCodeAndSpanKind generates a status code and a message
|
||||
// as specified by the OpenTelemetry specification for a span.
|
||||
// Exclude 4xx for SERVER to set the appropriate status.
|
||||
func SpanStatusFromHTTPStatusCodeAndSpanKind(code int, spanKind trace.SpanKind) (codes.Code, string) {
|
||||
spanCode, valid := validateHTTPStatusCode(code)
|
||||
if !valid {
|
||||
return spanCode, fmt.Sprintf("Invalid HTTP status code %d", code)
|
||||
}
|
||||
category := code / 100
|
||||
if spanKind == trace.SpanKindServer && category == 4 {
|
||||
return codes.Unset, ""
|
||||
}
|
||||
return spanCode, ""
|
||||
}
|
||||
|
||||
// Validates the HTTP status code and returns corresponding span status code.
|
||||
// If the `code` is not a valid HTTP status code, returns span status Error
|
||||
// and false.
|
||||
|
@@ -20,6 +20,8 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
@@ -854,7 +856,7 @@ func TestHTTPAttributesFromHTTPStatusCode(t *testing.T) {
|
||||
|
||||
func TestSpanStatusFromHTTPStatusCode(t *testing.T) {
|
||||
for code := 0; code < 1000; code++ {
|
||||
expected := getExpectedCodeForHTTPCode(code)
|
||||
expected := getExpectedCodeForHTTPCode(code, trace.SpanKindClient)
|
||||
got, msg := SpanStatusFromHTTPStatusCode(code)
|
||||
assert.Equalf(t, expected, got, "%s vs %s", expected, got)
|
||||
|
||||
@@ -867,7 +869,24 @@ func TestSpanStatusFromHTTPStatusCode(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func getExpectedCodeForHTTPCode(code int) codes.Code {
|
||||
func TestSpanStatusFromHTTPStatusCodeAndSpanKind(t *testing.T) {
|
||||
for code := 0; code < 1000; code++ {
|
||||
expected := getExpectedCodeForHTTPCode(code, trace.SpanKindClient)
|
||||
got, msg := SpanStatusFromHTTPStatusCodeAndSpanKind(code, trace.SpanKindClient)
|
||||
assert.Equalf(t, expected, got, "%s vs %s", expected, got)
|
||||
|
||||
_, valid := validateHTTPStatusCode(code)
|
||||
if !valid {
|
||||
assert.NotEmpty(t, msg, "message should be set if error cannot be inferred from code")
|
||||
} else {
|
||||
assert.Empty(t, msg, "message should not be set if error can be inferred from code")
|
||||
}
|
||||
}
|
||||
code, _ := SpanStatusFromHTTPStatusCodeAndSpanKind(400, trace.SpanKindServer)
|
||||
assert.Equalf(t, codes.Unset, code, "message should be set if error cannot be inferred from code")
|
||||
}
|
||||
|
||||
func getExpectedCodeForHTTPCode(code int, spanKind trace.SpanKind) codes.Code {
|
||||
if http.StatusText(code) == "" {
|
||||
return codes.Error
|
||||
}
|
||||
@@ -886,6 +905,9 @@ func getExpectedCodeForHTTPCode(code int) codes.Code {
|
||||
if category > 0 && category < 4 {
|
||||
return codes.Unset
|
||||
}
|
||||
if spanKind == trace.SpanKindServer && category == 4 {
|
||||
return codes.Unset
|
||||
}
|
||||
return codes.Error
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
module go.opentelemetry.io/otel/trace
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
replace go.opentelemetry.io/otel => ../
|
||||
|
||||
|
@@ -3,7 +3,7 @@ title: "Getting Started"
|
||||
weight: 2
|
||||
---
|
||||
|
||||
Welcome to the OpenTelemetry for Go getting started guide! This guide will walk you through the basic steps in installing, instrumenting with, configuring, and exporting data from OpenTelemetry. Before you get started, be sure to have Go 1.15 or newer installed.
|
||||
Welcome to the OpenTelemetry for Go getting started guide! This guide will walk you through the basic steps in installing, instrumenting with, configuring, and exporting data from OpenTelemetry. Before you get started, be sure to have Go 1.16 or newer installed.
|
||||
|
||||
Understand how a system is functioning when it is failing or having issues is critical to resolving those issues. One strategy to understand this is with tracing. This guide shows how the OpenTelemetry Go project can be used to trace an example application. You will start with an application that computes Fibonacci numbers for users, and from there you will add instrumentation to produce tracing telemetry with OpenTelemetry Go.
|
||||
|
||||
|
Reference in New Issue
Block a user