diff --git a/example/basic/go.sum b/example/basic/go.sum index cc3ccc8b96f..fa2e4687b09 100644 --- a/example/basic/go.sum +++ b/example/basic/go.sum @@ -13,7 +13,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= diff --git a/example/grpc/go.sum b/example/grpc/go.sum index e4f46d18497..66c206c15ec 100644 --- a/example/grpc/go.sum +++ b/example/grpc/go.sum @@ -13,7 +13,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= diff --git a/example/http/Dockerfile b/example/http/Dockerfile deleted file mode 100644 index 23f88befd73..00000000000 --- a/example/http/Dockerfile +++ /dev/null @@ -1,24 +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. -FROM golang:1.14-alpine AS base -COPY . /go/src/github.com/open-telemetry/opentelemetry-go/ -WORKDIR /go/src/github.com/open-telemetry/opentelemetry-go/example/http/ - -FROM base AS example-http-server -RUN go install ./server/server.go -CMD ["/go/bin/server"] - -FROM base AS example-http-client -RUN go install ./client/client.go -CMD ["/go/bin/client"] diff --git a/example/http/README.md b/example/http/README.md deleted file mode 100644 index 9da9e2dc813..00000000000 --- a/example/http/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# HTTP Client-Server Example - -An HTTP client connects to an HTTP server. They both generate span information to `stdout`. -These instructions expect you have [docker-compose](https://docs.docker.com/compose/) installed. - -Bring up the `http-server` and `http-client` services to run the example: -```sh -docker-compose up --detach http-server http-client -``` - -The `http-client` service sends just one HTTP request to `http-server` and then exits. View the span generated to `stdout` in the logs: -```sh -docker-compose logs http-client -``` - -View the span generated by `http-server` in the logs: -```sh -docker-compose logs http-server -``` - -Shut down the services when you are finished with the example: -```sh -docker-compose down -``` diff --git a/example/http/client/client.go b/example/http/client/client.go deleted file mode 100644 index 3cb4773cf10..00000000000 --- a/example/http/client/client.go +++ /dev/null @@ -1,96 +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 main - -import ( - "context" - "flag" - "fmt" - "io/ioutil" - "log" - - "go.opentelemetry.io/otel/api/kv" - "go.opentelemetry.io/otel/api/trace" - "go.opentelemetry.io/otel/semconv" - - "net/http" - "time" - - "go.opentelemetry.io/otel/api/correlation" - "go.opentelemetry.io/otel/api/global" - "go.opentelemetry.io/otel/exporters/stdout" - "go.opentelemetry.io/otel/instrumentation/httptrace" - sdktrace "go.opentelemetry.io/otel/sdk/trace" -) - -func initTracer() { - // Create stdout exporter to be able to retrieve - // the collected spans. - exporter, err := stdout.NewExporter(stdout.WithPrettyPrint()) - if err != nil { - log.Fatal(err) - } - - // For the demonstration, use sdktrace.AlwaysSample sampler to sample all traces. - // In a production application, use sdktrace.ProbabilitySampler with a desired probability. - tp, err := sdktrace.NewProvider(sdktrace.WithConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}), - sdktrace.WithSyncer(exporter)) - if err != nil { - log.Fatal(err) - } - global.SetTraceProvider(tp) -} - -func main() { - initTracer() - url := flag.String("server", "http://localhost:7777/hello", "server url") - flag.Parse() - - client := http.DefaultClient - ctx := correlation.NewContext(context.Background(), - kv.String("username", "donuts"), - ) - - var body []byte - - tr := global.Tracer("example/client") - err := tr.WithSpan(ctx, "say hello", - func(ctx context.Context) error { - req, _ := http.NewRequest("GET", *url, nil) - - ctx, req = httptrace.W3C(ctx, req) - httptrace.Inject(ctx, req) - - fmt.Printf("Sending request...\n") - res, err := client.Do(req) - if err != nil { - panic(err) - } - body, err = ioutil.ReadAll(res.Body) - _ = res.Body.Close() - - return err - }, - trace.WithAttributes(semconv.PeerServiceKey.String("ExampleService"))) - - if err != nil { - panic(err) - } - - fmt.Printf("Response Received: %s\n\n\n", body) - fmt.Printf("Waiting for few seconds to export spans ...\n\n") - time.Sleep(10 * time.Second) - fmt.Printf("Inspect traces on stdout\n") -} diff --git a/example/http/docker-compose.yml b/example/http/docker-compose.yml deleted file mode 100644 index 83f06635551..00000000000 --- a/example/http/docker-compose.yml +++ /dev/null @@ -1,34 +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. -version: "3.7" -services: - http-server: - build: - dockerfile: $PWD/Dockerfile - context: ../.. - target: example-http-server - networks: - - example - http-client: - build: - dockerfile: $PWD/Dockerfile - context: ../.. - target: example-http-client - command: ["/go/bin/client", "-server", "http://http-server:7777/hello"] - networks: - - example - depends_on: - - http-server -networks: - example: diff --git a/example/http/go.mod b/example/http/go.mod deleted file mode 100644 index 6bbc5353a54..00000000000 --- a/example/http/go.mod +++ /dev/null @@ -1,15 +0,0 @@ -module go.opentelemetry.io/otel/example/http - -go 1.14 - -replace ( - go.opentelemetry.io/otel => ../.. - go.opentelemetry.io/otel/exporters/stdout => ../../exporters/stdout - go.opentelemetry.io/otel/sdk => ../../sdk -) - -require ( - go.opentelemetry.io/otel v0.10.0 - go.opentelemetry.io/otel/exporters/stdout v0.10.0 - go.opentelemetry.io/otel/sdk v0.10.0 -) diff --git a/example/http/go.sum b/example/http/go.sum deleted file mode 100644 index cc3ccc8b96f..00000000000 --- a/example/http/go.sum +++ /dev/null @@ -1,100 +0,0 @@ -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/DataDog/sketches-go v0.0.1 h1:RtG+76WKgZuz6FIaGsjoPePmadDBkuD/KC6+ZWu78b8= -github.com/DataDog/sketches-go v0.0.1/go.mod h1:Q5DbzQ+3AkgGwymQO7aZFNP7ns2lZKGtvRBzRXfdi60= -github.com/benbjohnson/clock v1.0.3 h1:vkLuvpK4fmtSCuo60+yC63p7y0BmQ8gm5ZXGuBCJyXg= -github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= -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= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= -github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -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/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -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= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -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/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-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-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -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-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-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= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20191009194640-548a555dbc03 h1:4HYDjxeNXAOTv3o1N2tjo8UUSlhQgAD52FVkwxnWgM8= -google.golang.org/genproto v0.0.0-20191009194640-548a555dbc03/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.31.0 h1:T7P4R73V3SSDPhH7WW7ATbfViLtmamH0DKrP3f9AuDI= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -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.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/example/http/server/modd.conf b/example/http/server/modd.conf deleted file mode 100644 index 22ec99d907d..00000000000 --- a/example/http/server/modd.conf +++ /dev/null @@ -1,21 +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. - -# A basic modd.conf file for Go development. - -# Run go test on ALL modules on startup, and subsequently only on modules -# containing changes. -server.go { - daemon +sigterm: go run server.go -} \ No newline at end of file diff --git a/example/http/server/server.go b/example/http/server/server.go deleted file mode 100644 index bacfd32c023..00000000000 --- a/example/http/server/server.go +++ /dev/null @@ -1,79 +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 main - -import ( - "io" - "log" - "net/http" - - "go.opentelemetry.io/otel/api/correlation" - "go.opentelemetry.io/otel/api/global" - "go.opentelemetry.io/otel/api/trace" - "go.opentelemetry.io/otel/exporters/stdout" - "go.opentelemetry.io/otel/instrumentation/httptrace" - "go.opentelemetry.io/otel/sdk/resource" - sdktrace "go.opentelemetry.io/otel/sdk/trace" - "go.opentelemetry.io/otel/semconv" -) - -func initTracer() { - // Create stdout exporter to be able to retrieve - // the collected spans. - exporter, err := stdout.NewExporter(stdout.WithPrettyPrint()) - if err != nil { - log.Fatal(err) - } - - // For the demonstration, use sdktrace.AlwaysSample sampler to sample all traces. - // In a production application, use sdktrace.ProbabilitySampler with a desired probability. - tp, err := sdktrace.NewProvider(sdktrace.WithConfig(sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}), - sdktrace.WithSyncer(exporter), - sdktrace.WithResource(resource.New(semconv.ServiceNameKey.String("ExampleService")))) - if err != nil { - log.Fatal(err) - } - global.SetTraceProvider(tp) -} - -func main() { - initTracer() - tr := global.Tracer("example/server") - - helloHandler := func(w http.ResponseWriter, req *http.Request) { - attrs, entries, spanCtx := httptrace.Extract(req.Context(), req) - - req = req.WithContext(correlation.ContextWithMap(req.Context(), correlation.NewMap(correlation.MapUpdate{ - MultiKV: entries, - }))) - - ctx, span := tr.Start( - trace.ContextWithRemoteSpanContext(req.Context(), spanCtx), - "hello", - trace.WithAttributes(attrs...), - ) - defer span.End() - - span.AddEvent(ctx, "handling this...") - - _, _ = io.WriteString(w, "Hello, world!\n") - } - - http.HandleFunc("/hello", helloHandler) - err := http.ListenAndServe(":7777", nil) - if err != nil { - panic(err) - } -} diff --git a/example/jaeger/go.sum b/example/jaeger/go.sum index 861f403fa57..bd1dd0ab212 100644 --- a/example/jaeger/go.sum +++ b/example/jaeger/go.sum @@ -41,7 +41,6 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= diff --git a/example/namedtracer/go.sum b/example/namedtracer/go.sum index cc3ccc8b96f..fa2e4687b09 100644 --- a/example/namedtracer/go.sum +++ b/example/namedtracer/go.sum @@ -13,7 +13,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= diff --git a/example/otel-collector/go.sum b/example/otel-collector/go.sum index 4ff93cd71e0..1e0182d2add 100644 --- a/example/otel-collector/go.sum +++ b/example/otel-collector/go.sum @@ -13,7 +13,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= diff --git a/example/prometheus/go.sum b/example/prometheus/go.sum index dfbbddc340c..9f3a9861b29 100644 --- a/example/prometheus/go.sum +++ b/example/prometheus/go.sum @@ -24,7 +24,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= diff --git a/example/zipkin/go.sum b/example/zipkin/go.sum index 1c497554612..bc7daac3e5c 100644 --- a/example/zipkin/go.sum +++ b/example/zipkin/go.sum @@ -18,7 +18,6 @@ github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4s github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= diff --git a/exporters/metric/prometheus/go.sum b/exporters/metric/prometheus/go.sum index e7e3a406aa5..545e209f85c 100644 --- a/exporters/metric/prometheus/go.sum +++ b/exporters/metric/prometheus/go.sum @@ -24,7 +24,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= diff --git a/exporters/otlp/go.sum b/exporters/otlp/go.sum index beedf3ba29c..cc0b46ff711 100644 --- a/exporters/otlp/go.sum +++ b/exporters/otlp/go.sum @@ -13,7 +13,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= diff --git a/exporters/stdout/go.sum b/exporters/stdout/go.sum index de7c170efba..dd02ef06e31 100644 --- a/exporters/stdout/go.sum +++ b/exporters/stdout/go.sum @@ -13,7 +13,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= diff --git a/exporters/trace/jaeger/go.sum b/exporters/trace/jaeger/go.sum index a4b139d6e4e..b3d65368447 100644 --- a/exporters/trace/jaeger/go.sum +++ b/exporters/trace/jaeger/go.sum @@ -43,7 +43,6 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= diff --git a/exporters/trace/zipkin/go.sum b/exporters/trace/zipkin/go.sum index e7bd8312139..5b518c11c43 100644 --- a/exporters/trace/zipkin/go.sum +++ b/exporters/trace/zipkin/go.sum @@ -18,7 +18,6 @@ github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4s github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= diff --git a/go.mod b/go.mod index 7f489c2d08b..fefb4bf10d8 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,6 @@ go 1.14 require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/felixge/httpsnoop v1.0.1 github.com/golang/protobuf v1.4.2 github.com/google/go-cmp v0.5.1 github.com/kr/pretty v0.1.0 // indirect diff --git a/go.sum b/go.sum index 46ef008fe80..69af8e80963 100644 --- a/go.sum +++ b/go.sum @@ -11,8 +11,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= diff --git a/instrumentation/httptrace/api.go b/instrumentation/httptrace/api.go deleted file mode 100644 index 9f733aa6672..00000000000 --- a/instrumentation/httptrace/api.go +++ /dev/null @@ -1,28 +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 httptrace - -import ( - "context" - "net/http" - "net/http/httptrace" -) - -// Client -func W3C(ctx context.Context, req *http.Request) (context.Context, *http.Request) { - ctx = httptrace.WithClientTrace(ctx, NewClientTrace(ctx)) - req = req.WithContext(ctx) - return ctx, req -} diff --git a/instrumentation/httptrace/clienttrace.go b/instrumentation/httptrace/clienttrace.go deleted file mode 100644 index e77e77c762b..00000000000 --- a/instrumentation/httptrace/clienttrace.go +++ /dev/null @@ -1,253 +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 httptrace - -import ( - "context" - "crypto/tls" - "net/http/httptrace" - "net/textproto" - "strings" - "sync" - - "go.opentelemetry.io/otel/semconv" - - "google.golang.org/grpc/codes" - - "go.opentelemetry.io/otel/api/global" - "go.opentelemetry.io/otel/api/kv" - "go.opentelemetry.io/otel/api/trace" -) - -var ( - HTTPStatus = kv.Key("http.status") - HTTPHeaderMIME = kv.Key("http.mime") - HTTPRemoteAddr = kv.Key("http.remote") - HTTPLocalAddr = kv.Key("http.local") -) - -var ( - hookMap = map[string]string{ - "http.dns": "http.getconn", - "http.connect": "http.getconn", - "http.tls": "http.getconn", - } -) - -func parentHook(hook string) string { - if strings.HasPrefix(hook, "http.connect") { - return hookMap["http.connect"] - } - return hookMap[hook] -} - -type clientTracer struct { - context.Context - - tr trace.Tracer - - activeHooks map[string]context.Context - root trace.Span - mtx sync.Mutex -} - -func NewClientTrace(ctx context.Context) *httptrace.ClientTrace { - ct := &clientTracer{ - Context: ctx, - activeHooks: make(map[string]context.Context), - } - - ct.tr = global.Tracer("go.opentelemetry.io/otel/instrumentation/httptrace") - - return &httptrace.ClientTrace{ - GetConn: ct.getConn, - GotConn: ct.gotConn, - PutIdleConn: ct.putIdleConn, - GotFirstResponseByte: ct.gotFirstResponseByte, - Got100Continue: ct.got100Continue, - Got1xxResponse: ct.got1xxResponse, - DNSStart: ct.dnsStart, - DNSDone: ct.dnsDone, - ConnectStart: ct.connectStart, - ConnectDone: ct.connectDone, - TLSHandshakeStart: ct.tlsHandshakeStart, - TLSHandshakeDone: ct.tlsHandshakeDone, - WroteHeaderField: ct.wroteHeaderField, - WroteHeaders: ct.wroteHeaders, - Wait100Continue: ct.wait100Continue, - WroteRequest: ct.wroteRequest, - } -} - -func (ct *clientTracer) start(hook, spanName string, attrs ...kv.KeyValue) { - ct.mtx.Lock() - defer ct.mtx.Unlock() - - if hookCtx, found := ct.activeHooks[hook]; !found { - var sp trace.Span - ct.activeHooks[hook], sp = ct.tr.Start(ct.getParentContext(hook), spanName, trace.WithAttributes(attrs...), trace.WithSpanKind(trace.SpanKindClient)) - if ct.root == nil { - ct.root = sp - } - } else { - // end was called before start finished, add the start attributes and end the span here - span := trace.SpanFromContext(hookCtx) - span.SetAttributes(attrs...) - span.End() - - delete(ct.activeHooks, hook) - } -} - -func (ct *clientTracer) end(hook string, err error, attrs ...kv.KeyValue) { - ct.mtx.Lock() - defer ct.mtx.Unlock() - if ctx, ok := ct.activeHooks[hook]; ok { - span := trace.SpanFromContext(ctx) - if err != nil { - span.SetStatus(codes.Unknown, err.Error()) - } - span.SetAttributes(attrs...) - span.End() - delete(ct.activeHooks, hook) - } else { - // start is not finished before end is called. - // Start a span here with the ending attributes that will be finished when start finishes. - // Yes, it's backwards. v0v - ctx, span := ct.tr.Start(ct.getParentContext(hook), hook, trace.WithAttributes(attrs...), trace.WithSpanKind(trace.SpanKindClient)) - if err != nil { - span.SetStatus(codes.Unknown, err.Error()) - } - ct.activeHooks[hook] = ctx - } -} - -func (ct *clientTracer) getParentContext(hook string) context.Context { - ctx, ok := ct.activeHooks[parentHook(hook)] - if !ok { - return ct.Context - } - return ctx -} - -func (ct *clientTracer) span(hook string) trace.Span { - ct.mtx.Lock() - defer ct.mtx.Unlock() - if ctx, ok := ct.activeHooks[hook]; ok { - return trace.SpanFromContext(ctx) - } - return nil -} - -func (ct *clientTracer) getConn(host string) { - ct.start("http.getconn", "http.getconn", semconv.HTTPHostKey.String(host)) -} - -func (ct *clientTracer) gotConn(info httptrace.GotConnInfo) { - ct.end("http.getconn", - nil, - HTTPRemoteAddr.String(info.Conn.RemoteAddr().String()), - HTTPLocalAddr.String(info.Conn.LocalAddr().String()), - ) -} - -func (ct *clientTracer) putIdleConn(err error) { - ct.end("http.receive", err) -} - -func (ct *clientTracer) gotFirstResponseByte() { - ct.start("http.receive", "http.receive") -} - -func (ct *clientTracer) dnsStart(info httptrace.DNSStartInfo) { - ct.start("http.dns", "http.dns", semconv.HTTPHostKey.String(info.Host)) -} - -func (ct *clientTracer) dnsDone(info httptrace.DNSDoneInfo) { - ct.end("http.dns", info.Err) -} - -func (ct *clientTracer) connectStart(network, addr string) { - ct.start("http.connect."+addr, "http.connect", HTTPRemoteAddr.String(addr)) -} - -func (ct *clientTracer) connectDone(network, addr string, err error) { - ct.end("http.connect."+addr, err) -} - -func (ct *clientTracer) tlsHandshakeStart() { - ct.start("http.tls", "http.tls") -} - -func (ct *clientTracer) tlsHandshakeDone(_ tls.ConnectionState, err error) { - ct.end("http.tls", err) -} - -func (ct *clientTracer) wroteHeaderField(k string, v []string) { - if ct.span("http.headers") == nil { - ct.start("http.headers", "http.headers") - } - ct.root.SetAttributes(kv.String("http."+strings.ToLower(k), sliceToString(v))) -} - -func (ct *clientTracer) wroteHeaders() { - if ct.span("http.headers") != nil { - ct.end("http.headers", nil) - } - ct.start("http.send", "http.send") -} - -func (ct *clientTracer) wroteRequest(info httptrace.WroteRequestInfo) { - if info.Err != nil { - ct.root.SetStatus(codes.Unknown, info.Err.Error()) - } - ct.end("http.send", info.Err) -} - -func (ct *clientTracer) got100Continue() { - ct.span("http.receive").AddEvent(ct.Context, "GOT 100 - Continue") -} - -func (ct *clientTracer) wait100Continue() { - ct.span("http.receive").AddEvent(ct.Context, "GOT 100 - Wait") -} - -func (ct *clientTracer) got1xxResponse(code int, header textproto.MIMEHeader) error { - ct.span("http.receive").AddEvent(ct.Context, "GOT 1xx", - HTTPStatus.Int(code), - HTTPHeaderMIME.String(sm2s(header)), - ) - return nil -} - -func sliceToString(value []string) string { - if len(value) == 0 { - return "undefined" - } - return strings.Join(value, ",") -} - -func sm2s(value map[string][]string) string { - var buf strings.Builder - for k, v := range value { - if buf.Len() != 0 { - buf.WriteString(",") - } - buf.WriteString(k) - buf.WriteString("=") - buf.WriteString(sliceToString(v)) - } - return buf.String() -} diff --git a/instrumentation/httptrace/clienttrace_test.go b/instrumentation/httptrace/clienttrace_test.go deleted file mode 100644 index db213a6f040..00000000000 --- a/instrumentation/httptrace/clienttrace_test.go +++ /dev/null @@ -1,238 +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 httptrace_test - -import ( - "context" - "net/http" - "net/http/httptest" - nhtrace "net/http/httptrace" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "go.opentelemetry.io/otel/api/global" - "go.opentelemetry.io/otel/api/kv" - "go.opentelemetry.io/otel/api/trace/testtrace" - "go.opentelemetry.io/otel/instrumentation/httptrace" -) - -type SpanRecorder map[string]*testtrace.Span - -func (sr *SpanRecorder) OnStart(span *testtrace.Span) {} -func (sr *SpanRecorder) OnEnd(span *testtrace.Span) { (*sr)[span.Name()] = span } - -func TestHTTPRequestWithClientTrace(t *testing.T) { - sr := SpanRecorder{} - tp := testtrace.NewProvider(testtrace.WithSpanRecorder(&sr)) - global.SetTraceProvider(tp) - tr := tp.Tracer("httptrace/client") - - // Mock http server - ts := httptest.NewServer( - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - }), - ) - defer ts.Close() - address := ts.Listener.Addr() - - client := ts.Client() - err := tr.WithSpan(context.Background(), "test", - func(ctx context.Context) error { - req, _ := http.NewRequest("GET", ts.URL, nil) - _, req = httptrace.W3C(ctx, req) - - res, err := client.Do(req) - if err != nil { - t.Fatalf("Request failed: %s", err.Error()) - } - _ = res.Body.Close() - - return nil - }) - if err != nil { - panic("unexpected error in http request: " + err.Error()) - } - - testLen := []struct { - name string - attributes map[kv.Key]kv.Value - parent string - }{ - { - name: "http.connect", - attributes: map[kv.Key]kv.Value{ - kv.Key("http.remote"): kv.StringValue(address.String()), - }, - parent: "http.getconn", - }, - { - name: "http.getconn", - attributes: map[kv.Key]kv.Value{ - kv.Key("http.remote"): kv.StringValue(address.String()), - kv.Key("http.host"): kv.StringValue(address.String()), - }, - parent: "test", - }, - { - name: "http.receive", - parent: "test", - }, - { - name: "http.headers", - parent: "test", - }, - { - name: "http.send", - parent: "test", - }, - { - name: "test", - }, - } - for _, tl := range testLen { - if !assert.Contains(t, sr, tl.name) { - continue - } - span := sr[tl.name] - if tl.parent != "" { - if assert.Contains(t, sr, tl.parent) { - assert.Equal(t, span.ParentSpanID(), sr[tl.parent].SpanContext().SpanID) - } - } - if len(tl.attributes) > 0 { - attrs := span.Attributes() - if tl.name == "http.getconn" { - // http.local attribute uses a non-deterministic port. - local := kv.Key("http.local") - assert.Contains(t, attrs, local) - delete(attrs, local) - } - assert.Equal(t, tl.attributes, attrs) - } - } -} - -type MultiSpanRecorder map[string][]*testtrace.Span - -func (sr *MultiSpanRecorder) Reset() { (*sr) = MultiSpanRecorder{} } -func (sr *MultiSpanRecorder) OnStart(span *testtrace.Span) {} -func (sr *MultiSpanRecorder) OnEnd(span *testtrace.Span) { - (*sr)[span.Name()] = append((*sr)[span.Name()], span) -} - -func TestConcurrentConnectionStart(t *testing.T) { - sr := MultiSpanRecorder{} - global.SetTraceProvider( - testtrace.NewProvider(testtrace.WithSpanRecorder(&sr)), - ) - ct := httptrace.NewClientTrace(context.Background()) - tts := []struct { - name string - run func() - }{ - { - name: "Open1Close1Open2Close2", - run: func() { - ct.ConnectStart("tcp", "127.0.0.1:3000") - ct.ConnectDone("tcp", "127.0.0.1:3000", nil) - ct.ConnectStart("tcp", "[::1]:3000") - ct.ConnectDone("tcp", "[::1]:3000", nil) - }, - }, - { - name: "Open2Close2Open1Close1", - run: func() { - ct.ConnectStart("tcp", "[::1]:3000") - ct.ConnectDone("tcp", "[::1]:3000", nil) - ct.ConnectStart("tcp", "127.0.0.1:3000") - ct.ConnectDone("tcp", "127.0.0.1:3000", nil) - }, - }, - { - name: "Open1Open2Close1Close2", - run: func() { - ct.ConnectStart("tcp", "127.0.0.1:3000") - ct.ConnectStart("tcp", "[::1]:3000") - ct.ConnectDone("tcp", "127.0.0.1:3000", nil) - ct.ConnectDone("tcp", "[::1]:3000", nil) - }, - }, - { - name: "Open1Open2Close2Close1", - run: func() { - ct.ConnectStart("tcp", "127.0.0.1:3000") - ct.ConnectStart("tcp", "[::1]:3000") - ct.ConnectDone("tcp", "[::1]:3000", nil) - ct.ConnectDone("tcp", "127.0.0.1:3000", nil) - }, - }, - { - name: "Open2Open1Close1Close2", - run: func() { - ct.ConnectStart("tcp", "[::1]:3000") - ct.ConnectStart("tcp", "127.0.0.1:3000") - ct.ConnectDone("tcp", "127.0.0.1:3000", nil) - ct.ConnectDone("tcp", "[::1]:3000", nil) - }, - }, - { - name: "Open2Open1Close2Close1", - run: func() { - ct.ConnectStart("tcp", "[::1]:3000") - ct.ConnectStart("tcp", "127.0.0.1:3000") - ct.ConnectDone("tcp", "[::1]:3000", nil) - ct.ConnectDone("tcp", "127.0.0.1:3000", nil) - }, - }, - } - - expectedRemotes := []kv.KeyValue{ - kv.String("http.remote", "127.0.0.1:3000"), - kv.String("http.remote", "[::1]:3000"), - } - for _, tt := range tts { - t.Run(tt.name, func(t *testing.T) { - sr.Reset() - tt.run() - spans := sr["http.connect"] - require.Len(t, spans, 2) - - var gotRemotes []kv.KeyValue - for _, span := range spans { - for k, v := range span.Attributes() { - gotRemotes = append(gotRemotes, kv.Any(string(k), v.AsInterface())) - } - } - assert.ElementsMatch(t, expectedRemotes, gotRemotes) - }) - } -} - -func TestEndBeforeStartCreatesSpan(t *testing.T) { - sr := MultiSpanRecorder{} - global.SetTraceProvider( - testtrace.NewProvider(testtrace.WithSpanRecorder(&sr)), - ) - - ct := httptrace.NewClientTrace(context.Background()) - ct.DNSDone(nhtrace.DNSDoneInfo{}) - ct.DNSStart(nhtrace.DNSStartInfo{Host: "example.com"}) - - name := "http.dns" - require.Contains(t, sr, name) - spans := sr[name] - require.Len(t, spans, 1) -} diff --git a/instrumentation/httptrace/httptrace.go b/instrumentation/httptrace/httptrace.go deleted file mode 100644 index ccea090ef86..00000000000 --- a/instrumentation/httptrace/httptrace.go +++ /dev/null @@ -1,74 +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 httptrace - -import ( - "context" - "net/http" - - "go.opentelemetry.io/otel/api/correlation" - "go.opentelemetry.io/otel/api/global" - "go.opentelemetry.io/otel/api/kv" - "go.opentelemetry.io/otel/api/propagation" - "go.opentelemetry.io/otel/api/trace" - "go.opentelemetry.io/otel/semconv" -) - -// Option is a function that allows configuration of the httptrace Extract() -// and Inject() functions -type Option func(*config) - -type config struct { - propagators propagation.Propagators -} - -func newConfig(opts []Option) *config { - c := &config{propagators: global.Propagators()} - for _, o := range opts { - o(c) - } - return c -} - -// WithPropagators sets the propagators to use for Extraction and Injection -func WithPropagators(props propagation.Propagators) Option { - return func(c *config) { - c.propagators = props - } -} - -// Returns the Attributes, Context Entries, and SpanContext that were encoded by Inject. -func Extract(ctx context.Context, req *http.Request, opts ...Option) ([]kv.KeyValue, []kv.KeyValue, trace.SpanContext) { - c := newConfig(opts) - ctx = propagation.ExtractHTTP(ctx, c.propagators, req.Header) - - attrs := append( - semconv.HTTPServerAttributesFromHTTPRequest("", "", req), - semconv.NetAttributesFromHTTPRequest("tcp", req)..., - ) - - var correlationCtxKVs []kv.KeyValue - correlation.MapFromContext(ctx).Foreach(func(kv kv.KeyValue) bool { - correlationCtxKVs = append(correlationCtxKVs, kv) - return true - }) - - return attrs, correlationCtxKVs, trace.RemoteSpanContextFromContext(ctx) -} - -func Inject(ctx context.Context, req *http.Request, opts ...Option) { - c := newConfig(opts) - propagation.InjectHTTP(ctx, c.propagators, req.Header) -} diff --git a/instrumentation/httptrace/httptrace_test.go b/instrumentation/httptrace/httptrace_test.go deleted file mode 100644 index 3b704b0baee..00000000000 --- a/instrumentation/httptrace/httptrace_test.go +++ /dev/null @@ -1,164 +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 httptrace_test - -import ( - "context" - "net/http" - "net/http/httptest" - "strings" - "testing" - - "github.com/google/go-cmp/cmp" - - "go.opentelemetry.io/otel/api/correlation" - "go.opentelemetry.io/otel/api/kv" - "go.opentelemetry.io/otel/api/propagation" - "go.opentelemetry.io/otel/api/trace/testtrace" - "go.opentelemetry.io/otel/instrumentation/httptrace" - "go.opentelemetry.io/otel/semconv" -) - -func TestRoundtrip(t *testing.T) { - tr := testtrace.NewProvider().Tracer("httptrace/client") - - var expectedAttrs map[kv.Key]string - expectedCorrs := map[kv.Key]string{kv.Key("foo"): "bar"} - - // Mock http server - ts := httptest.NewServer( - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - attrs, corrs, span := httptrace.Extract(r.Context(), r) - - actualAttrs := make(map[kv.Key]string) - for _, attr := range attrs { - if attr.Key == semconv.NetPeerPortKey { - // Peer port will be non-deterministic - continue - } - actualAttrs[attr.Key] = attr.Value.Emit() - } - - if diff := cmp.Diff(actualAttrs, expectedAttrs); diff != "" { - t.Fatalf("[TestRoundtrip] Attributes are different: %v", diff) - } - - actualCorrs := make(map[kv.Key]string) - for _, corr := range corrs { - actualCorrs[corr.Key] = corr.Value.Emit() - } - - if diff := cmp.Diff(actualCorrs, expectedCorrs); diff != "" { - t.Fatalf("[TestRoundtrip] Correlations are different: %v", diff) - } - - if !span.IsValid() { - t.Fatalf("[TestRoundtrip] Invalid span extracted: %v", span) - } - - _, err := w.Write([]byte("OK")) - if err != nil { - t.Fatal(err) - } - }), - ) - defer ts.Close() - - address := ts.Listener.Addr() - hp := strings.Split(address.String(), ":") - expectedAttrs = map[kv.Key]string{ - semconv.HTTPFlavorKey: "1.1", - semconv.HTTPHostKey: address.String(), - semconv.HTTPMethodKey: "GET", - semconv.HTTPSchemeKey: "http", - semconv.HTTPTargetKey: "/", - semconv.HTTPUserAgentKey: "Go-http-client/1.1", - semconv.HTTPRequestContentLengthKey: "3", - semconv.NetHostIPKey: hp[0], - semconv.NetHostPortKey: hp[1], - semconv.NetPeerIPKey: "127.0.0.1", - semconv.NetTransportKey: "IP.TCP", - } - - client := ts.Client() - err := tr.WithSpan(context.Background(), "test", - func(ctx context.Context) error { - ctx = correlation.ContextWithMap(ctx, correlation.NewMap(correlation.MapUpdate{SingleKV: kv.Key("foo").String("bar")})) - req, _ := http.NewRequest("GET", ts.URL, strings.NewReader("foo")) - httptrace.Inject(ctx, req) - - res, err := client.Do(req) - if err != nil { - t.Fatalf("Request failed: %s", err.Error()) - } - _ = res.Body.Close() - - return nil - }) - if err != nil { - panic("unexpected error in http request: " + err.Error()) - } -} - -func TestSpecifyPropagators(t *testing.T) { - tr := testtrace.NewProvider().Tracer("httptrace/client") - - expectedCorrs := map[kv.Key]string{kv.Key("foo"): "bar"} - - // Mock http server - ts := httptest.NewServer( - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - _, corrs, span := httptrace.Extract(r.Context(), r, httptrace.WithPropagators(propagation.New(propagation.WithExtractors(correlation.DefaultHTTPPropagator())))) - - actualCorrs := make(map[kv.Key]string) - for _, corr := range corrs { - actualCorrs[corr.Key] = corr.Value.Emit() - } - - if diff := cmp.Diff(actualCorrs, expectedCorrs); diff != "" { - t.Fatalf("[TestRoundtrip] Correlations are different: %v", diff) - } - - if span.IsValid() { - t.Fatalf("[TestRoundtrip] valid span extracted, expected none: %v", span) - } - - _, err := w.Write([]byte("OK")) - if err != nil { - t.Fatal(err) - } - }), - ) - defer ts.Close() - - client := ts.Client() - err := tr.WithSpan(context.Background(), "test", - func(ctx context.Context) error { - ctx = correlation.ContextWithMap(ctx, correlation.NewMap(correlation.MapUpdate{SingleKV: kv.Key("foo").String("bar")})) - req, _ := http.NewRequest("GET", ts.URL, nil) - httptrace.Inject(ctx, req, httptrace.WithPropagators(propagation.New(propagation.WithInjectors(correlation.DefaultHTTPPropagator())))) - - res, err := client.Do(req) - if err != nil { - t.Fatalf("Request failed: %s", err.Error()) - } - _ = res.Body.Close() - - return nil - }) - if err != nil { - panic("unexpected error in http request: " + err.Error()) - } -} diff --git a/instrumentation/othttp/common.go b/instrumentation/othttp/common.go deleted file mode 100644 index d885d9e70a8..00000000000 --- a/instrumentation/othttp/common.go +++ /dev/null @@ -1,41 +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 othttp - -import ( - "net/http" - - "go.opentelemetry.io/otel/api/kv" -) - -// Attribute keys that can be added to a span. -const ( - ReadBytesKey = kv.Key("http.read_bytes") // if anything was read from the request body, the total number of bytes read - ReadErrorKey = kv.Key("http.read_error") // If an error occurred while reading a request, the string of the error (io.EOF is not recorded) - WroteBytesKey = kv.Key("http.wrote_bytes") // if anything was written to the response writer, the total number of bytes written - WriteErrorKey = kv.Key("http.write_error") // if an error occurred while writing a reply, the string of the error (io.EOF is not recorded) -) - -// Server HTTP metrics -const ( - RequestCount = "http.server.request_count" // Incoming request count total - RequestContentLength = "http.server.request_content_length" // Incoming request bytes total - ResponseContentLength = "http.server.response_content_length" // Incoming response bytes total - ServerLatency = "http.server.duration" // Incoming end to end duration, microseconds -) - -// Filter is a predicate used to determine whether a given http.request should -// be traced. A Filter must return true if the request should be traced. -type Filter func(*http.Request) bool diff --git a/instrumentation/othttp/config.go b/instrumentation/othttp/config.go deleted file mode 100644 index 4b0ec68437a..00000000000 --- a/instrumentation/othttp/config.go +++ /dev/null @@ -1,150 +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 othttp - -import ( - "net/http" - - "go.opentelemetry.io/otel/api/metric" - "go.opentelemetry.io/otel/api/propagation" - "go.opentelemetry.io/otel/api/trace" -) - -// Config represents the configuration options available for the othttp.Handler -// and othttp.Transport types. -type Config struct { - Tracer trace.Tracer - Meter metric.Meter - Propagators propagation.Propagators - SpanStartOptions []trace.StartOption - ReadEvent bool - WriteEvent bool - Filters []Filter - SpanNameFormatter func(string, *http.Request) string -} - -// Option Interface used for setting *optional* Config properties -type Option interface { - Apply(*Config) -} - -// OptionFunc provides a convenience wrapper for simple Options -// that can be represented as functions. -type OptionFunc func(*Config) - -func (o OptionFunc) Apply(c *Config) { - o(c) -} - -// NewConfig creates a new Config struct and applies opts to it. -func NewConfig(opts ...Option) *Config { - c := &Config{} - for _, opt := range opts { - opt.Apply(c) - } - return c -} - -// WithTracer configures a specific tracer. If this option -// isn't specified then the global tracer is used. -func WithTracer(tracer trace.Tracer) Option { - return OptionFunc(func(c *Config) { - c.Tracer = tracer - }) -} - -// WithMeter configures a specific meter. If this option -// isn't specified then the global meter is used. -func WithMeter(meter metric.Meter) Option { - return OptionFunc(func(c *Config) { - c.Meter = meter - }) -} - -// WithPublicEndpoint configures the Handler to link the span with an incoming -// span context. If this option is not provided, then the association is a child -// association instead of a link. -func WithPublicEndpoint() Option { - return OptionFunc(func(c *Config) { - c.SpanStartOptions = append(c.SpanStartOptions, trace.WithNewRoot()) - }) -} - -// WithPropagators configures specific propagators. If this -// option isn't specified then -// go.opentelemetry.io/otel/api/global.Propagators are used. -func WithPropagators(ps propagation.Propagators) Option { - return OptionFunc(func(c *Config) { - c.Propagators = ps - }) -} - -// WithSpanOptions configures an additional set of -// trace.StartOptions, which are applied to each new span. -func WithSpanOptions(opts ...trace.StartOption) Option { - return OptionFunc(func(c *Config) { - c.SpanStartOptions = append(c.SpanStartOptions, opts...) - }) -} - -// WithFilter adds a filter to the list of filters used by the handler. -// If any filter indicates to exclude a request then the request will not be -// traced. All filters must allow a request to be traced for a Span to be created. -// If no filters are provided then all requests are traced. -// Filters will be invoked for each processed request, it is advised to make them -// simple and fast. -func WithFilter(f Filter) Option { - return OptionFunc(func(c *Config) { - c.Filters = append(c.Filters, f) - }) -} - -type event int - -// Different types of events that can be recorded, see WithMessageEvents -const ( - ReadEvents event = iota - WriteEvents -) - -// WithMessageEvents configures the Handler to record the specified events -// (span.AddEvent) on spans. By default only summary attributes are added at the -// end of the request. -// -// Valid events are: -// * ReadEvents: Record the number of bytes read after every http.Request.Body.Read -// using the ReadBytesKey -// * WriteEvents: Record the number of bytes written after every http.ResponeWriter.Write -// using the WriteBytesKey -func WithMessageEvents(events ...event) Option { - return OptionFunc(func(c *Config) { - for _, e := range events { - switch e { - case ReadEvents: - c.ReadEvent = true - case WriteEvents: - c.WriteEvent = true - } - } - }) -} - -// WithSpanNameFormatter takes a function that will be called on every -// request and the returned string will become the Span Name -func WithSpanNameFormatter(f func(operation string, r *http.Request) string) Option { - return OptionFunc(func(c *Config) { - c.SpanNameFormatter = f - }) -} diff --git a/instrumentation/othttp/config_test.go b/instrumentation/othttp/config_test.go deleted file mode 100644 index dec4d2b658e..00000000000 --- a/instrumentation/othttp/config_test.go +++ /dev/null @@ -1,131 +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 othttp - -import ( - "io" - "io/ioutil" - "net/http" - "net/http/httptest" - "testing" - - mocktrace "go.opentelemetry.io/otel/internal/trace" -) - -func TestBasicFilter(t *testing.T) { - rr := httptest.NewRecorder() - - var id uint64 - tracer := mocktrace.MockTracer{StartSpanID: &id} - - h := NewHandler( - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if _, err := io.WriteString(w, "hello world"); err != nil { - t.Fatal(err) - } - }), "test_handler", - WithTracer(&tracer), - WithFilter(func(r *http.Request) bool { - return false - }), - ) - - r, err := http.NewRequest(http.MethodGet, "http://localhost/", nil) - if err != nil { - t.Fatal(err) - } - h.ServeHTTP(rr, r) - if got, expected := rr.Result().StatusCode, http.StatusOK; got != expected { - t.Fatalf("got %d, expected %d", got, expected) - } - if got := rr.Header().Get("Traceparent"); got != "" { - t.Fatal("expected empty trace header") - } - if got, expected := id, uint64(0); got != expected { - t.Fatalf("got %d, expected %d", got, expected) - } - d, err := ioutil.ReadAll(rr.Result().Body) - if err != nil { - t.Fatal(err) - } - if got, expected := string(d), "hello world"; got != expected { - t.Fatalf("got %q, expected %q", got, expected) - } -} - -func TestSpanNameFormatter(t *testing.T) { - var testCases = []struct { - name string - formatter func(s string, r *http.Request) string - operation string - expected string - }{ - { - name: "default handler formatter", - formatter: defaultHandlerFormatter, - operation: "test_operation", - expected: "test_operation", - }, - { - name: "default transport formatter", - formatter: defaultTransportFormatter, - expected: http.MethodGet, - }, - { - name: "custom formatter", - formatter: func(s string, r *http.Request) string { - return r.URL.Path - }, - operation: "", - expected: "/hello", - }, - } - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - rr := httptest.NewRecorder() - var id uint64 - var spanName string - tracer := mocktrace.MockTracer{ - StartSpanID: &id, - OnSpanStarted: func(span *mocktrace.MockSpan) { - spanName = span.Name - }, - } - handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if _, err := io.WriteString(w, "hello world"); err != nil { - t.Fatal(err) - } - }) - h := NewHandler( - handler, - tc.operation, - WithTracer(&tracer), - WithSpanNameFormatter(tc.formatter), - ) - r, err := http.NewRequest(http.MethodGet, "http://localhost/hello", nil) - if err != nil { - t.Fatal(err) - } - h.ServeHTTP(rr, r) - if got, expected := rr.Result().StatusCode, http.StatusOK; got != expected { - t.Fatalf("got %d, expected %d", got, expected) - } - if got, expected := spanName, tc.expected; got != expected { - t.Fatalf("got %q, expected %q", got, expected) - } - }) - } -} diff --git a/instrumentation/othttp/doc.go b/instrumentation/othttp/doc.go deleted file mode 100644 index 80dae5d77b3..00000000000 --- a/instrumentation/othttp/doc.go +++ /dev/null @@ -1,18 +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 othttp provides a http.Handler and functions that are -// intended to be used to add tracing by wrapping -// existing handlers (with Handler) and routes WithRouteTag. -package othttp diff --git a/instrumentation/othttp/filters/filters.go b/instrumentation/othttp/filters/filters.go deleted file mode 100644 index e5192ef7ccf..00000000000 --- a/instrumentation/othttp/filters/filters.go +++ /dev/null @@ -1,128 +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 filters provides a set of filters useful with the -// othttp.WithFilter() option to control which inbound requests are traced. -package filters - -import ( - "net/http" - "strings" - - "go.opentelemetry.io/otel/instrumentation/othttp" -) - -// Any takes a list of Filters and returns a Filter that -// returns true if any Filter in the list returns true. -func Any(fs ...othttp.Filter) othttp.Filter { - return func(r *http.Request) bool { - for _, f := range fs { - if f(r) { - return true - } - } - return false - } -} - -// All takes a list of Filters and returns a Filter that -// returns true only if all Filters in the list return true. -func All(fs ...othttp.Filter) othttp.Filter { - return func(r *http.Request) bool { - for _, f := range fs { - if !f(r) { - return false - } - } - return true - } -} - -// None takes a list of Filters and returns a Filter that returns -// true only if none of the Filters in the list return true. -func None(fs ...othttp.Filter) othttp.Filter { - return func(r *http.Request) bool { - for _, f := range fs { - if f(r) { - return false - } - } - return true - } -} - -// Not provides a convenience mechanism for inverting a Filter -func Not(f othttp.Filter) othttp.Filter { - return func(r *http.Request) bool { - return !f(r) - } -} - -// Hostname returns a Filter that returns true if the request's -// hostname matches the provided string. -func Hostname(h string) othttp.Filter { - return func(r *http.Request) bool { - return r.URL.Hostname() == h - } -} - -// Path returns a Filter that returns true if the request's -// path matches the provided string. -func Path(p string) othttp.Filter { - return func(r *http.Request) bool { - return r.URL.Path == p - } -} - -// PathPrefix returns a Filter that returns true if the request's -// path starts with the provided string. -func PathPrefix(p string) othttp.Filter { - return func(r *http.Request) bool { - return strings.HasPrefix(r.URL.Path, p) - } -} - -// Query returns a Filter that returns true if the request -// includes a query parameter k with a value equal to v. -func Query(k, v string) othttp.Filter { - return func(r *http.Request) bool { - for _, qv := range r.URL.Query()[k] { - if v == qv { - return true - } - } - return false - } -} - -// QueryContains returns a Filter that returns true if the request -// includes a query parameter k with a value that contains v. -func QueryContains(k, v string) othttp.Filter { - return func(r *http.Request) bool { - for _, qv := range r.URL.Query()[k] { - if strings.Contains(qv, v) { - return true - } - } - return false - } -} - -// Method returns a Filter that returns true if the request -// method is equal to the provided value. -func Method(m string) othttp.Filter { - return func(r *http.Request) bool { - return m == r.Method - } -} diff --git a/instrumentation/othttp/filters/filters_test.go b/instrumentation/othttp/filters/filters_test.go deleted file mode 100644 index 7e184363ddf..00000000000 --- a/instrumentation/othttp/filters/filters_test.go +++ /dev/null @@ -1,266 +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 filters - -import ( - "net/http" - "net/url" - "testing" - - "go.opentelemetry.io/otel/instrumentation/othttp" -) - -type scenario struct { - name string - filter othttp.Filter - req *http.Request - exp bool -} - -func TestAny(t *testing.T) { - for _, s := range []scenario{ - { - name: "no matching filters", - filter: Any(Path("/foo"), Hostname("bar.baz")), - req: &http.Request{URL: &url.URL{Path: "/boo", Host: "baz.bar:8080"}}, - exp: false, - }, - { - name: "one matching filter", - filter: Any(Path("/foo"), Hostname("bar.baz")), - req: &http.Request{URL: &url.URL{Path: "/foo", Host: "baz.bar:8080"}}, - exp: true, - }, - { - name: "all matching filters", - filter: Any(Path("/foo"), Hostname("bar.baz")), - req: &http.Request{URL: &url.URL{Path: "/foo", Host: "bar.baz:8080"}}, - exp: true, - }, - } { - res := s.filter(s.req) - if s.exp != res { - t.Errorf("Failed testing %q. Expected %t, got %t", s.name, s.exp, res) - } - } -} - -func TestAll(t *testing.T) { - for _, s := range []scenario{ - { - name: "no matching filters", - filter: All(Path("/foo"), Hostname("bar.baz")), - req: &http.Request{URL: &url.URL{Path: "/boo", Host: "baz.bar:8080"}}, - exp: false, - }, - { - name: "one matching filter", - filter: All(Path("/foo"), Hostname("bar.baz")), - req: &http.Request{URL: &url.URL{Path: "/foo", Host: "baz.bar:8080"}}, - exp: false, - }, - { - name: "all matching filters", - filter: All(Path("/foo"), Hostname("bar.baz")), - req: &http.Request{URL: &url.URL{Path: "/foo", Host: "bar.baz:8080"}}, - exp: true, - }, - } { - res := s.filter(s.req) - if s.exp != res { - t.Errorf("Failed testing %q. Expected %t, got %t", s.name, s.exp, res) - } - } -} - -func TestNone(t *testing.T) { - for _, s := range []scenario{ - { - name: "no matching filters", - filter: None(Path("/foo"), Hostname("bar.baz")), - req: &http.Request{URL: &url.URL{Path: "/boo", Host: "baz.bar:8080"}}, - exp: true, - }, - { - name: "one matching filter", - filter: None(Path("/foo"), Hostname("bar.baz")), - req: &http.Request{URL: &url.URL{Path: "/foo", Host: "baz.bar:8080"}}, - exp: false, - }, - { - name: "all matching filters", - filter: None(Path("/foo"), Hostname("bar.baz")), - req: &http.Request{URL: &url.URL{Path: "/foo", Host: "bar.baz:8080"}}, - exp: false, - }, - } { - res := s.filter(s.req) - if s.exp != res { - t.Errorf("Failed testing %q. Expected %t, got %t", s.name, s.exp, res) - } - } -} - -func TestNot(t *testing.T) { - req := &http.Request{URL: &url.URL{Path: "/foo", Host: "bar.baz:8080"}} - filter := Path("/foo") - if filter(req) == Not(filter)(req) { - t.Error("Not filter should invert the result of the supplied filter") - } -} - -func TestPathPrefix(t *testing.T) { - for _, s := range []scenario{ - { - name: "non-matching prefix", - filter: PathPrefix("/foo"), - req: &http.Request{URL: &url.URL{Path: "/boo/far", Host: "baz.bar:8080"}}, - exp: false, - }, - { - name: "matching prefix", - filter: PathPrefix("/foo"), - req: &http.Request{URL: &url.URL{Path: "/foo/bar", Host: "bar.baz:8080"}}, - exp: true, - }, - } { - res := s.filter(s.req) - if s.exp != res { - t.Errorf("Failed testing %q. Expected %t, got %t", s.name, s.exp, res) - } - } -} - -func TestMethod(t *testing.T) { - for _, s := range []scenario{ - { - name: "non-matching method", - filter: Method(http.MethodGet), - req: &http.Request{Method: http.MethodHead, URL: &url.URL{Path: "/boo/far", Host: "baz.bar:8080"}}, - exp: false, - }, - { - name: "matching method", - filter: Method(http.MethodGet), - req: &http.Request{Method: http.MethodGet, URL: &url.URL{Path: "/boo/far", Host: "baz.bar:8080"}}, - exp: true, - }, - } { - res := s.filter(s.req) - if s.exp != res { - t.Errorf("Failed testing %q. Expected %t, got %t", s.name, s.exp, res) - } - } -} - -func TestQuery(t *testing.T) { - matching, _ := url.Parse("http://bar.baz:8080/foo/bar?key=value") - nonMatching, _ := url.Parse("http://bar.baz:8080/foo/bar?key=other") - for _, s := range []scenario{ - { - name: "non-matching query parameter", - filter: Query("key", "value"), - req: &http.Request{Method: http.MethodHead, URL: nonMatching}, - exp: false, - }, - { - name: "matching query parameter", - filter: Query("key", "value"), - req: &http.Request{Method: http.MethodGet, URL: matching}, - exp: true, - }, - } { - res := s.filter(s.req) - if s.exp != res { - t.Errorf("Failed testing %q. Expected %t, got %t", s.name, s.exp, res) - } - } -} - -func TestQueryContains(t *testing.T) { - matching, _ := url.Parse("http://bar.baz:8080/foo/bar?key=value") - nonMatching, _ := url.Parse("http://bar.baz:8080/foo/bar?key=other") - for _, s := range []scenario{ - { - name: "non-matching query parameter", - filter: QueryContains("key", "alu"), - req: &http.Request{Method: http.MethodHead, URL: nonMatching}, - exp: false, - }, - { - name: "matching query parameter", - filter: QueryContains("key", "alu"), - req: &http.Request{Method: http.MethodGet, URL: matching}, - exp: true, - }, - } { - res := s.filter(s.req) - if s.exp != res { - t.Errorf("Failed testing %q. Expected %t, got %t", s.name, s.exp, res) - } - } -} - -func TestHeader(t *testing.T) { - matching := http.Header{} - matching.Add("key", "value") - nonMatching := http.Header{} - nonMatching.Add("key", "other") - for _, s := range []scenario{ - { - name: "non-matching query parameter", - filter: Header("key", "value"), - req: &http.Request{Method: http.MethodHead, Header: nonMatching}, - exp: false, - }, - { - name: "matching query parameter", - filter: Header("key", "value"), - req: &http.Request{Method: http.MethodGet, Header: matching}, - exp: true, - }, - } { - res := s.filter(s.req) - if s.exp != res { - t.Errorf("Failed testing %q. Expected %t, got %t", s.name, s.exp, res) - } - } -} - -func TestHeaderContains(t *testing.T) { - matching := http.Header{} - matching.Add("key", "value") - nonMatching := http.Header{} - nonMatching.Add("key", "other") - for _, s := range []scenario{ - { - name: "non-matching query parameter", - filter: HeaderContains("key", "alu"), - req: &http.Request{Method: http.MethodHead, Header: nonMatching}, - exp: false, - }, - { - name: "matching query parameter", - filter: HeaderContains("key", "alu"), - req: &http.Request{Method: http.MethodGet, Header: matching}, - exp: true, - }, - } { - res := s.filter(s.req) - if s.exp != res { - t.Errorf("Failed testing %q. Expected %t, got %t", s.name, s.exp, res) - } - } -} diff --git a/instrumentation/othttp/filters/header_go14.go b/instrumentation/othttp/filters/header_go14.go deleted file mode 100644 index e4091f1656b..00000000000 --- a/instrumentation/othttp/filters/header_go14.go +++ /dev/null @@ -1,50 +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. - -// +build go1.14 - -package filters - -import ( - "net/http" - "strings" - - "go.opentelemetry.io/otel/instrumentation/othttp" -) - -// Header returns a Filter that returns true if the request -// includes a header k with a value equal to v. -func Header(k, v string) othttp.Filter { - return func(r *http.Request) bool { - for _, hv := range r.Header.Values(k) { - if v == hv { - return true - } - } - return false - } -} - -// HeaderContains returns a Filter that returns true if the request -// includes a header k with a value that contains v. -func HeaderContains(k, v string) othttp.Filter { - return func(r *http.Request) bool { - for _, hv := range r.Header.Values(k) { - if strings.Contains(hv, v) { - return true - } - } - return false - } -} diff --git a/instrumentation/othttp/filters/header_nongo14.go b/instrumentation/othttp/filters/header_nongo14.go deleted file mode 100644 index 9e512443956..00000000000 --- a/instrumentation/othttp/filters/header_nongo14.go +++ /dev/null @@ -1,51 +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. - -// +build !go1.14 - -package filters - -import ( - "net/http" - "net/textproto" - "strings" - - "go.opentelemetry.io/otel/instrumentation/othttp" -) - -// Header returns a Filter that returns true if the request -// includes a header k with a value equal to v. -func Header(k, v string) othttp.Filter { - return func(r *http.Request) bool { - for _, hv := range r.Header[textproto.CanonicalMIMEHeaderKey(k)] { - if v == hv { - return true - } - } - return false - } -} - -// HeaderContains returns a Filter that returns true if the request -// includes a header k with a value that contains v. -func HeaderContains(k, v string) othttp.Filter { - return func(r *http.Request) bool { - for _, hv := range r.Header[textproto.CanonicalMIMEHeaderKey(k)] { - if strings.Contains(hv, v) { - return true - } - } - return false - } -} diff --git a/instrumentation/othttp/handler.go b/instrumentation/othttp/handler.go deleted file mode 100644 index 20471ffd791..00000000000 --- a/instrumentation/othttp/handler.go +++ /dev/null @@ -1,221 +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 othttp - -import ( - "io" - "net/http" - "time" - - "github.com/felixge/httpsnoop" - - "go.opentelemetry.io/otel/api/global" - "go.opentelemetry.io/otel/api/kv" - "go.opentelemetry.io/otel/api/metric" - "go.opentelemetry.io/otel/api/propagation" - "go.opentelemetry.io/otel/api/trace" - "go.opentelemetry.io/otel/semconv" -) - -var _ http.Handler = &Handler{} - -// Handler is http middleware that corresponds to the http.Handler interface and -// is designed to wrap a http.Mux (or equivalent), while individual routes on -// the mux are wrapped with WithRouteTag. A Handler will add various attributes -// to the span using the kv.Keys defined in this package. -type Handler struct { - operation string - handler http.Handler - - tracer trace.Tracer - meter metric.Meter - propagators propagation.Propagators - spanStartOptions []trace.StartOption - readEvent bool - writeEvent bool - filters []Filter - spanNameFormatter func(string, *http.Request) string - counters map[string]metric.Int64Counter - valueRecorders map[string]metric.Int64ValueRecorder -} - -func defaultHandlerFormatter(operation string, _ *http.Request) string { - return operation -} - -// NewHandler wraps the passed handler, functioning like middleware, in a span -// named after the operation and with any provided Options. -func NewHandler(handler http.Handler, operation string, opts ...Option) http.Handler { - h := Handler{ - handler: handler, - operation: operation, - } - - const domain = "go.opentelemetry.io/otel/instrumentation/othttp" - - defaultOpts := []Option{ - WithTracer(global.Tracer(domain)), - WithMeter(global.Meter(domain)), - WithPropagators(global.Propagators()), - WithSpanOptions(trace.WithSpanKind(trace.SpanKindServer)), - WithSpanNameFormatter(defaultHandlerFormatter), - } - - c := NewConfig(append(defaultOpts, opts...)...) - h.configure(c) - h.createMeasures() - - return &h -} - -func (h *Handler) configure(c *Config) { - h.tracer = c.Tracer - h.meter = c.Meter - h.propagators = c.Propagators - h.spanStartOptions = c.SpanStartOptions - h.readEvent = c.ReadEvent - h.writeEvent = c.WriteEvent - h.filters = c.Filters - h.spanNameFormatter = c.SpanNameFormatter -} - -func handleErr(err error) { - if err != nil { - global.Handle(err) - } -} - -func (h *Handler) createMeasures() { - h.counters = make(map[string]metric.Int64Counter) - h.valueRecorders = make(map[string]metric.Int64ValueRecorder) - - requestBytesCounter, err := h.meter.NewInt64Counter(RequestContentLength) - handleErr(err) - - responseBytesCounter, err := h.meter.NewInt64Counter(ResponseContentLength) - handleErr(err) - - serverLatencyMeasure, err := h.meter.NewInt64ValueRecorder(ServerLatency) - handleErr(err) - - h.counters[RequestContentLength] = requestBytesCounter - h.counters[ResponseContentLength] = responseBytesCounter - h.valueRecorders[ServerLatency] = serverLatencyMeasure -} - -// ServeHTTP serves HTTP requests (http.Handler) -func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - requestStartTime := time.Now() - for _, f := range h.filters { - if !f(r) { - // Simply pass through to the handler if a filter rejects the request - h.handler.ServeHTTP(w, r) - return - } - } - - opts := append([]trace.StartOption{ - trace.WithAttributes(semconv.NetAttributesFromHTTPRequest("tcp", r)...), - trace.WithAttributes(semconv.EndUserAttributesFromHTTPRequest(r)...), - trace.WithAttributes(semconv.HTTPServerAttributesFromHTTPRequest(h.operation, "", r)...), - }, h.spanStartOptions...) // start with the configured options - - ctx := propagation.ExtractHTTP(r.Context(), h.propagators, r.Header) - ctx, span := h.tracer.Start(ctx, h.spanNameFormatter(h.operation, r), opts...) - defer span.End() - - readRecordFunc := func(int64) {} - if h.readEvent { - readRecordFunc = func(n int64) { - span.AddEvent(ctx, "read", ReadBytesKey.Int64(n)) - } - } - bw := bodyWrapper{ReadCloser: r.Body, record: readRecordFunc} - r.Body = &bw - - writeRecordFunc := func(int64) {} - if h.writeEvent { - writeRecordFunc = func(n int64) { - span.AddEvent(ctx, "write", WroteBytesKey.Int64(n)) - } - } - - rww := &respWriterWrapper{ResponseWriter: w, record: writeRecordFunc, ctx: ctx, props: h.propagators} - - // Wrap w to use our ResponseWriter methods while also exposing - // other interfaces that w may implement (http.CloseNotifier, - // http.Flusher, http.Hijacker, http.Pusher, io.ReaderFrom). - - w = httpsnoop.Wrap(w, httpsnoop.Hooks{ - Header: func(httpsnoop.HeaderFunc) httpsnoop.HeaderFunc { - return rww.Header - }, - Write: func(httpsnoop.WriteFunc) httpsnoop.WriteFunc { - return rww.Write - }, - WriteHeader: func(httpsnoop.WriteHeaderFunc) httpsnoop.WriteHeaderFunc { - return rww.WriteHeader - }, - }) - - h.handler.ServeHTTP(w, r.WithContext(ctx)) - - setAfterServeAttributes(span, bw.read, rww.written, rww.statusCode, bw.err, rww.err) - - // Add request metrics - - labels := semconv.HTTPServerMetricAttributesFromHTTPRequest(h.operation, r) - - h.counters[RequestContentLength].Add(ctx, bw.read, labels...) - h.counters[ResponseContentLength].Add(ctx, rww.written, labels...) - - elapsedTime := time.Since(requestStartTime).Microseconds() - - h.valueRecorders[ServerLatency].Record(ctx, elapsedTime, labels...) -} - -func setAfterServeAttributes(span trace.Span, read, wrote int64, statusCode int, rerr, werr error) { - kv := []kv.KeyValue{} - - // TODO: Consider adding an event after each read and write, possibly as an - // option (defaulting to off), so as to not create needlessly verbose spans. - if read > 0 { - kv = append(kv, ReadBytesKey.Int64(read)) - } - if rerr != nil && rerr != io.EOF { - kv = append(kv, ReadErrorKey.String(rerr.Error())) - } - if wrote > 0 { - kv = append(kv, WroteBytesKey.Int64(wrote)) - } - if statusCode > 0 { - kv = append(kv, semconv.HTTPAttributesFromHTTPStatusCode(statusCode)...) - span.SetStatus(semconv.SpanStatusFromHTTPStatusCode(statusCode)) - } - if werr != nil && werr != io.EOF { - kv = append(kv, WriteErrorKey.String(werr.Error())) - } - span.SetAttributes(kv...) -} - -// WithRouteTag annotates a span with the provided route name using the -// RouteKey Tag. -func WithRouteTag(route string, h http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - span := trace.SpanFromContext(r.Context()) - span.SetAttributes(semconv.HTTPRouteKey.String(route)) - h.ServeHTTP(w, r) - }) -} diff --git a/instrumentation/othttp/handler_example_test.go b/instrumentation/othttp/handler_example_test.go deleted file mode 100644 index 080022d0b7e..00000000000 --- a/instrumentation/othttp/handler_example_test.go +++ /dev/null @@ -1,98 +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 othttp_test - -import ( - "context" - "fmt" - "io" - "io/ioutil" - "log" - "net/http" - "strings" - - "go.opentelemetry.io/otel/api/kv" - - "go.opentelemetry.io/otel/api/trace" - "go.opentelemetry.io/otel/instrumentation/othttp" -) - -func ExampleNewHandler() { - /* curl -v -d "a painting" http://localhost:7777/hello/bob/ross - ... - * upload completely sent off: 10 out of 10 bytes - < HTTP/1.1 200 OK - < Traceparent: 00-76ae040ee5753f38edf1c2bd9bd128bd-dd394138cfd7a3dc-01 - < Date: Fri, 04 Oct 2019 02:33:08 GMT - < Content-Length: 45 - < Content-Type: text/plain; charset=utf-8 - < - Hello, bob/ross! - You sent me this: - a painting - */ - - figureOutName := func(ctx context.Context, s string) (string, error) { - pp := strings.SplitN(s, "/", 2) - var err error - switch pp[1] { - case "": - err = fmt.Errorf("expected /hello/:name in %q", s) - default: - trace.SpanFromContext(ctx).SetAttributes(kv.String("name", pp[1])) - } - return pp[1], err - } - - var mux http.ServeMux - mux.Handle("/hello/", - othttp.WithRouteTag("/hello/:name", http.HandlerFunc( - func(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - var name string - // Wrap another function in its own span - if err := trace.SpanFromContext(ctx).Tracer().WithSpan(ctx, "figureOutName", - func(ctx context.Context) error { - var err error - name, err = figureOutName(ctx, r.URL.Path[1:]) - return err - }); err != nil { - log.Println("error figuring out name: ", err) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - - d, err := ioutil.ReadAll(r.Body) - if err != nil { - log.Println("error reading body: ", err) - w.WriteHeader(http.StatusBadRequest) - return - } - - n, err := io.WriteString(w, "Hello, "+name+"!\nYou sent me this:\n"+string(d)) - if err != nil { - log.Printf("error writing reply after %d bytes: %s", n, err) - } - }), - ), - ) - - if err := http.ListenAndServe(":7777", - othttp.NewHandler(&mux, "server", - othttp.WithMessageEvents(othttp.ReadEvents, othttp.WriteEvents), - ), - ); err != nil { - log.Fatal(err) - } -} diff --git a/instrumentation/othttp/handler_test.go b/instrumentation/othttp/handler_test.go deleted file mode 100644 index 3d98481c29a..00000000000 --- a/instrumentation/othttp/handler_test.go +++ /dev/null @@ -1,166 +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 othttp - -import ( - "fmt" - "io" - "io/ioutil" - "net/http" - "net/http/httptest" - "strings" - "testing" - - "github.com/stretchr/testify/assert" - "google.golang.org/grpc/codes" - - "go.opentelemetry.io/otel/api/kv" - "go.opentelemetry.io/otel/api/trace" - mockmeter "go.opentelemetry.io/otel/internal/metric" - mocktrace "go.opentelemetry.io/otel/internal/trace" - "go.opentelemetry.io/otel/semconv" -) - -func assertMetricLabels(t *testing.T, expectedLabels []kv.KeyValue, measurementBatches []mockmeter.Batch) { - for _, batch := range measurementBatches { - assert.ElementsMatch(t, expectedLabels, batch.Labels) - } -} - -func TestHandlerBasics(t *testing.T) { - rr := httptest.NewRecorder() - - var id uint64 - tracer := mocktrace.MockTracer{StartSpanID: &id} - meterimpl, meter := mockmeter.NewMeter() - - operation := "test_handler" - - h := NewHandler( - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if _, err := io.WriteString(w, "hello world"); err != nil { - t.Fatal(err) - } - }), operation, - WithTracer(&tracer), - WithMeter(meter), - ) - - r, err := http.NewRequest(http.MethodGet, "http://localhost/", strings.NewReader("foo")) - if err != nil { - t.Fatal(err) - } - h.ServeHTTP(rr, r) - - if len(meterimpl.MeasurementBatches) == 0 { - t.Fatalf("got 0 recorded measurements, expected 1 or more") - } - - labelsToVerify := []kv.KeyValue{ - semconv.HTTPServerNameKey.String(operation), - semconv.HTTPSchemeHTTP, - semconv.HTTPHostKey.String(r.Host), - semconv.HTTPFlavorKey.String(fmt.Sprintf("1.%d", r.ProtoMinor)), - semconv.HTTPRequestContentLengthKey.Int64(3), - } - - assertMetricLabels(t, labelsToVerify, meterimpl.MeasurementBatches) - - if got, expected := rr.Result().StatusCode, http.StatusOK; got != expected { - t.Fatalf("got %d, expected %d", got, expected) - } - if got := rr.Header().Get("Traceparent"); got == "" { - t.Fatal("expected non empty trace header") - } - if got, expected := id, uint64(1); got != expected { - t.Fatalf("got %d, expected %d", got, expected) - } - d, err := ioutil.ReadAll(rr.Result().Body) - if err != nil { - t.Fatal(err) - } - if got, expected := string(d), "hello world"; got != expected { - t.Fatalf("got %q, expected %q", got, expected) - } -} - -func TestHandlerNoWrite(t *testing.T) { - rr := httptest.NewRecorder() - - var id uint64 - tracer := mocktrace.MockTracer{StartSpanID: &id} - - operation := "test_handler" - var span trace.Span - - h := NewHandler( - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - span = trace.SpanFromContext(r.Context()) - }), operation, - WithTracer(&tracer), - ) - - r, err := http.NewRequest(http.MethodGet, "http://localhost/", nil) - if err != nil { - t.Fatal(err) - } - h.ServeHTTP(rr, r) - - if got, expected := rr.Result().StatusCode, http.StatusOK; got != expected { - t.Fatalf("got %d, expected %d", got, expected) - } - if got := rr.Header().Get("Traceparent"); got != "" { - t.Fatal("expected empty trace header") - } - if got, expected := id, uint64(1); got != expected { - t.Fatalf("got %d, expected %d", got, expected) - } - if mockSpan, ok := span.(*mocktrace.MockSpan); ok { - if got, expected := mockSpan.Status, codes.OK; got != expected { - t.Fatalf("got %q, expected %q", got, expected) - } - } else { - t.Fatalf("Expected *moctrace.MockSpan, got %T", span) - } -} - -func TestResponseWriterOptionalInterfaces(t *testing.T) { - rr := httptest.NewRecorder() - - var id uint64 - tracer := mocktrace.MockTracer{StartSpanID: &id} - - // ResponseRecorder implements the Flusher interface. Make sure the - // wrapped ResponseWriter passed to the handler still implements - // Flusher. - - var isFlusher bool - h := NewHandler( - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - _, isFlusher = w.(http.Flusher) - if _, err := io.WriteString(w, "hello world"); err != nil { - t.Fatal(err) - } - }), "test_handler", - WithTracer(&tracer)) - - r, err := http.NewRequest(http.MethodGet, "http://localhost/", nil) - if err != nil { - t.Fatal(err) - } - h.ServeHTTP(rr, r) - if !isFlusher { - t.Fatal("http.Flusher interface not exposed") - } -} diff --git a/instrumentation/othttp/transport.go b/instrumentation/othttp/transport.go deleted file mode 100644 index aa619ea62a5..00000000000 --- a/instrumentation/othttp/transport.go +++ /dev/null @@ -1,134 +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 othttp - -import ( - "context" - "io" - "net/http" - - "go.opentelemetry.io/otel/api/global" - "go.opentelemetry.io/otel/api/propagation" - "go.opentelemetry.io/otel/api/trace" - "go.opentelemetry.io/otel/semconv" - - "google.golang.org/grpc/codes" -) - -// Transport implements the http.RoundTripper interface and wraps -// outbound HTTP(S) requests with a span. -type Transport struct { - rt http.RoundTripper - - tracer trace.Tracer - propagators propagation.Propagators - spanStartOptions []trace.StartOption - filters []Filter - spanNameFormatter func(string, *http.Request) string -} - -var _ http.RoundTripper = &Transport{} - -// NewTransport wraps the provided http.RoundTripper with one that -// starts a span and injects the span context into the outbound request headers. -func NewTransport(base http.RoundTripper, opts ...Option) *Transport { - t := Transport{ - rt: base, - } - - defaultOpts := []Option{ - WithTracer(global.Tracer("go.opentelemetry.io/otel/instrumentation/othttp")), - WithPropagators(global.Propagators()), - WithSpanOptions(trace.WithSpanKind(trace.SpanKindClient)), - WithSpanNameFormatter(defaultTransportFormatter), - } - - c := NewConfig(append(defaultOpts, opts...)...) - t.configure(c) - - return &t -} - -func (t *Transport) configure(c *Config) { - t.tracer = c.Tracer - t.propagators = c.Propagators - t.spanStartOptions = c.SpanStartOptions - t.filters = c.Filters - t.spanNameFormatter = c.SpanNameFormatter -} - -func defaultTransportFormatter(_ string, r *http.Request) string { - return r.Method -} - -// RoundTrip creates a Span and propagates its context via the provided request's headers -// before handing the request to the configured base RoundTripper. The created span will -// end when the response body is closed or when a read from the body returns io.EOF. -func (t *Transport) RoundTrip(r *http.Request) (*http.Response, error) { - for _, f := range t.filters { - if !f(r) { - // Simply pass through to the base RoundTripper if a filter rejects the request - return t.rt.RoundTrip(r) - } - } - - opts := append([]trace.StartOption{}, t.spanStartOptions...) // start with the configured options - - ctx, span := t.tracer.Start(r.Context(), t.spanNameFormatter("", r), opts...) - - r = r.WithContext(ctx) - span.SetAttributes(semconv.HTTPClientAttributesFromHTTPRequest(r)...) - propagation.InjectHTTP(ctx, t.propagators, r.Header) - - res, err := t.rt.RoundTrip(r) - if err != nil { - span.RecordError(ctx, err, trace.WithErrorStatus(codes.Internal)) - span.End() - return res, err - } - - span.SetAttributes(semconv.HTTPAttributesFromHTTPStatusCode(res.StatusCode)...) - span.SetStatus(semconv.SpanStatusFromHTTPStatusCode(res.StatusCode)) - res.Body = &wrappedBody{ctx: ctx, span: span, body: res.Body} - - return res, err -} - -type wrappedBody struct { - ctx context.Context - span trace.Span - body io.ReadCloser -} - -var _ io.ReadCloser = &wrappedBody{} - -func (wb *wrappedBody) Read(b []byte) (int, error) { - n, err := wb.body.Read(b) - - switch err { - case nil: - // nothing to do here but fall through to the return - case io.EOF: - wb.span.End() - default: - wb.span.RecordError(wb.ctx, err, trace.WithErrorStatus(codes.Internal)) - } - return n, err -} - -func (wb *wrappedBody) Close() error { - wb.span.End() - return wb.body.Close() -} diff --git a/instrumentation/othttp/transport_example_test.go b/instrumentation/othttp/transport_example_test.go deleted file mode 100644 index 9254bd19024..00000000000 --- a/instrumentation/othttp/transport_example_test.go +++ /dev/null @@ -1,27 +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 othttp - -import ( - "net/http" -) - -func ExampleNewTransport() { - // Create an http.Client that uses the othttp.Transport - // wrapped around the http.DefaultTransport - _ = http.Client{ - Transport: NewTransport(http.DefaultTransport), - } -} diff --git a/instrumentation/othttp/transport_test.go b/instrumentation/othttp/transport_test.go deleted file mode 100644 index 86e29adcbae..00000000000 --- a/instrumentation/othttp/transport_test.go +++ /dev/null @@ -1,76 +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 othttp - -import ( - "bytes" - "fmt" - "io/ioutil" - "net/http" - "net/http/httptest" - "testing" - - "go.opentelemetry.io/otel/api/global" - "go.opentelemetry.io/otel/api/propagation" - "go.opentelemetry.io/otel/api/trace" - mocktrace "go.opentelemetry.io/otel/internal/trace" -) - -func TestTransportBasics(t *testing.T) { - var id uint64 - tracer := mocktrace.MockTracer{StartSpanID: &id} - content := []byte("Hello, world!") - - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - ctx := propagation.ExtractHTTP(r.Context(), global.Propagators(), r.Header) - span := trace.RemoteSpanContextFromContext(ctx) - tgtID, err := trace.SpanIDFromHex(fmt.Sprintf("%016x", id)) - if err != nil { - t.Fatalf("Error converting id to SpanID: %s", err.Error()) - } - if span.SpanID != tgtID { - t.Fatalf("testing remote SpanID: got %s, expected %s", span.SpanID, tgtID) - } - if _, err := w.Write(content); err != nil { - t.Fatal(err) - } - })) - defer ts.Close() - - r, err := http.NewRequest(http.MethodGet, ts.URL, nil) - if err != nil { - t.Fatal(err) - } - - tr := NewTransport( - http.DefaultTransport, - WithTracer(&tracer), - ) - - c := http.Client{Transport: tr} - res, err := c.Do(r) - if err != nil { - t.Fatal(err) - } - - body, err := ioutil.ReadAll(res.Body) - if err != nil { - t.Fatal(err) - } - - if !bytes.Equal(body, content) { - t.Fatalf("unexpected content: got %s, expected %s", body, content) - } -} diff --git a/instrumentation/othttp/wrap.go b/instrumentation/othttp/wrap.go deleted file mode 100644 index e1575457b29..00000000000 --- a/instrumentation/othttp/wrap.go +++ /dev/null @@ -1,96 +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 othttp - -import ( - "context" - "io" - "net/http" - - "go.opentelemetry.io/otel/api/propagation" -) - -var _ io.ReadCloser = &bodyWrapper{} - -// bodyWrapper wraps a http.Request.Body (an io.ReadCloser) to track the number -// of bytes read and the last error -type bodyWrapper struct { - io.ReadCloser - record func(n int64) // must not be nil - - read int64 - err error -} - -func (w *bodyWrapper) Read(b []byte) (int, error) { - n, err := w.ReadCloser.Read(b) - n1 := int64(n) - w.read += n1 - w.err = err - w.record(n1) - return n, err -} - -func (w *bodyWrapper) Close() error { - return w.ReadCloser.Close() -} - -var _ http.ResponseWriter = &respWriterWrapper{} - -// respWriterWrapper wraps a http.ResponseWriter in order to track the number of -// bytes written, the last error, and to catch the returned statusCode -// TODO: The wrapped http.ResponseWriter doesn't implement any of the optional -// types (http.Hijacker, http.Pusher, http.CloseNotifier, http.Flusher, etc) -// that may be useful when using it in real life situations. -type respWriterWrapper struct { - http.ResponseWriter - record func(n int64) // must not be nil - - // used to inject the header - ctx context.Context - - props propagation.Propagators - - written int64 - statusCode int - err error - wroteHeader bool -} - -func (w *respWriterWrapper) Header() http.Header { - return w.ResponseWriter.Header() -} - -func (w *respWriterWrapper) Write(p []byte) (int, error) { - if !w.wroteHeader { - w.WriteHeader(http.StatusOK) - } - n, err := w.ResponseWriter.Write(p) - n1 := int64(n) - w.record(n1) - w.written += n1 - w.err = err - return n, err -} - -func (w *respWriterWrapper) WriteHeader(statusCode int) { - if w.wroteHeader { - return - } - w.wroteHeader = true - w.statusCode = statusCode - propagation.InjectHTTP(w.ctx, w.props, w.Header()) - w.ResponseWriter.WriteHeader(statusCode) -} diff --git a/sdk/go.sum b/sdk/go.sum index 6744f1bcad1..f294616bae7 100644 --- a/sdk/go.sum +++ b/sdk/go.sum @@ -13,7 +13,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=