diff --git a/.github/workflows/protogen.yml b/.github/workflows/protogen.yml index a82d841efda..8b8f641170c 100644 --- a/.github/workflows/protogen.yml +++ b/.github/workflows/protogen.yml @@ -14,8 +14,8 @@ jobs: - uses: actions/setup-go@v2 with: go-version: '^1.14.0' - - run: sudo apt-get -y install pax - - run: make -f Makefile.proto protobuf + - run: sudo apt-get -y install rsync wget unzip + - run: make -f Makefile.proto protobuf clean - uses: stefanzweifel/git-auto-commit-action@v4 id: commit-changes with: diff --git a/CHANGELOG.md b/CHANGELOG.md index ba0378f986b..1e2ea008c1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Move the OpenCensus example into `example` directory. (#1359) - Moved the SDK's `internal.IDGenerator` interface in to the `sdk/trace` package to enable support for externally-defined ID generators. (#1363) +- `NewExporter` and `Start` functions in `go.opentelemetry.io/otel/exporters/otlp` now receive `context.Context` as a first parameter. (#1357) +- Zipkin exporter relies on the status code for success rather than body read but still read the response body. (#1328) ## [0.14.0] - 2020-11-19 diff --git a/Makefile b/Makefile index 85506a3b36d..130be713a82 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ TOOLS_MOD_DIR := ./internal/tools # All source code and documents. Used in spell check. ALL_DOCS := $(shell find . -name '*.md' -type f | sort) # All directories with go.mod files related to opentelemetry library. Used for building, testing and linting. -ALL_GO_MOD_DIRS := $(filter-out $(TOOLS_MOD_DIR), $(shell find . -type f -name 'go.mod' -exec dirname {} \; | sort)) +ALL_GO_MOD_DIRS := $(filter-out $(TOOLS_MOD_DIR), $(shell find . -type f -name 'go.mod' -exec dirname {} \; | egrep -v '^./example' | sort)) $(shell find ./example -type f -name 'go.mod' -exec dirname {} \; | sort) ALL_COVERAGE_MOD_DIRS := $(shell find . -type f -name 'go.mod' -exec dirname {} \; | egrep -v '^./example|^$(TOOLS_MOD_DIR)' | sort) # Mac OS Catalina 10.5.x doesn't support 386. Hence skip 386 test diff --git a/Makefile.proto b/Makefile.proto index 417c3b31c47..5e51af3a5c9 100644 --- a/Makefile.proto +++ b/Makefile.proto @@ -13,60 +13,117 @@ # See the License for the specific language governing permissions and # limitations under the License. # -# This Makefile.proto has rules to generate *.pb.go files in -# `exporters/otlp/internal/opentelemetry-proto-gen` from the .proto files in -# `exporters/otlp/internal/opentelemetry-proto` using protoc with a go plugin. +# This Makefile.proto has rules to generate go code for otlp +# exporter. It does it by copying the proto files from +# `exporters/otlp/internal/opentelemetry-proto` (which is a +# submodule that needs to be checked out) into `gen/proto`, changing +# the go_package option to a valid string, generating the go files and +# finally copying the files into the module. The files are not +# generated in place, because protoc generates a too-deep directory +# structure. # -# The protoc binary and other tools are sourced from a docker image -# `PROTOC_IMAGE`. +# Currently, all the generated code is in +# `exporters/otlp/internal/opentelemetry-proto-gen`. # -# Prereqs: The archiving utility `pax` is installed. +# Prereqs: wget (for downloading the zip file with protoc binary), +# unzip (for unpacking the archive), rsync (for copying back the +# generated files). -PROTOC_IMAGE := namely/protoc-all:1.29_2 -PROTOBUF_VERSION := v1 -OTEL_PROTO_SUBMODULE := exporters/otlp/internal/opentelemetry-proto -PROTOBUF_GEN_DIR := exporters/otlp/internal/opentelemetry-proto-gen -PROTOBUF_TEMP_DIR := gen/pb-go -PROTO_SOURCE_DIR := gen/proto -SUBMODULE_PROTO_FILES := $(wildcard $(OTEL_PROTO_SUBMODULE)/opentelemetry/proto/*/$(PROTOBUF_VERSION)/*.proto \ - $(OTEL_PROTO_SUBMODULE)/opentelemetry/proto/collector/*/$(PROTOBUF_VERSION)/*.proto) -SOURCE_PROTO_FILES := $(subst $(OTEL_PROTO_SUBMODULE),$(PROTO_SOURCE_DIR),$(SUBMODULE_PROTO_FILES)) +PROTOC_VERSION := 3.14.0 -default: protobuf +TOOLS_DIR := $(abspath ./.tools) +TOOLS_MOD_DIR := ./internal/tools +PROTOBUF_VERSION := v1 +OTEL_PROTO_SUBMODULE := exporters/otlp/internal/opentelemetry-proto +GEN_TEMP_DIR := gen +SUBMODULE_PROTO_FILES := $(wildcard $(OTEL_PROTO_SUBMODULE)/opentelemetry/proto/*/$(PROTOBUF_VERSION)/*.proto) $(wildcard $(OTEL_PROTO_SUBMODULE)/opentelemetry/proto/collector/*/$(PROTOBUF_VERSION)/*.proto) -.PHONY: protobuf protobuf-source gen-protobuf copy-protobufs -protobuf: protobuf-source gen-protobuf copy-protobufs +ifeq ($(strip $(SUBMODULE_PROTO_FILES)),) +$(error Submodule at $(OTEL_PROTO_SUBMODULE) is not checked out, use "git submodule update --init") +endif -protobuf-source: $(SOURCE_PROTO_FILES) | $(PROTO_SOURCE_DIR)/ +PROTOBUF_GEN_DIR := exporters/otlp/internal/opentelemetry-proto-gen +PROTOBUF_TEMP_DIR := $(GEN_TEMP_DIR)/pb-go +PROTO_SOURCE_DIR := $(GEN_TEMP_DIR)/proto +SOURCE_PROTO_FILES := $(subst $(OTEL_PROTO_SUBMODULE),$(PROTO_SOURCE_DIR),$(SUBMODULE_PROTO_FILES)) -# Changes go_package in .proto file to point to repo-local location -define exec-replace-pkgname -sed 's,go_package = "github.com/open-telemetry/opentelemetry-proto/gen/go,go_package = "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen,' < $(1) > $(2) +.DEFAULT_GOAL := protobuf -endef +UNAME_S := $(shell uname -s) +UNAME_M := $(shell uname -m) + +ifeq ($(UNAME_S),Linux) + +PROTOC_OS := linux +PROTOC_ARCH := $(UNAME_M) + +else ifeq ($(UNAME_S),Darwin) + +PROTOC_OS := osx +PROTOC_ARCH := x86_64 + +endif -# replace opentelemetry-proto package name by go.opentelemetry.io/otel specific version -$(SOURCE_PROTO_FILES): $(PROTO_SOURCE_DIR)/%.proto: $(OTEL_PROTO_SUBMODULE)/%.proto - @mkdir -p $(@D) - $(call exec-replace-pkgname,$<,$@) +PROTOC_ZIP_URL := https://github.com/protocolbuffers/protobuf/releases/download/v$(PROTOC_VERSION)/protoc-$(PROTOC_VERSION)-$(PROTOC_OS)-$(PROTOC_ARCH).zip -# Command to run protoc using docker image -define exec-protoc-all -docker run -v `pwd`:/defs $(PROTOC_IMAGE) $(1) +$(TOOLS_DIR)/PROTOC_$(PROTOC_VERSION): + @rm -f "$(TOOLS_DIR)"/PROTOC_* && \ + touch "$@" +# Depend on a versioned file (like PROTOC_3.14.0), so when version +# gets bumped, we will depend on a nonexistent file and thus download +# a newer version. +$(TOOLS_DIR)/protoc/bin/protoc: $(TOOLS_DIR)/PROTOC_$(PROTOC_VERSION) + echo "Fetching protoc $(PROTOC_VERSION)" && \ + rm -rf $(TOOLS_DIR)/protoc && \ + wget -O $(TOOLS_DIR)/protoc.zip $(PROTOC_ZIP_URL) && \ + unzip $(TOOLS_DIR)/protoc.zip -d $(TOOLS_DIR)/protoc-tmp && \ + rm $(TOOLS_DIR)/protoc.zip && \ + touch $(TOOLS_DIR)/protoc-tmp/bin/protoc && \ + mv $(TOOLS_DIR)/protoc-tmp $(TOOLS_DIR)/protoc + +$(TOOLS_DIR)/protoc-gen-gogofast: $(TOOLS_MOD_DIR)/go.mod $(TOOLS_MOD_DIR)/go.sum $(TOOLS_MOD_DIR)/tools.go + cd $(TOOLS_MOD_DIR) && \ + go build -o $(TOOLS_DIR)/protoc-gen-gogofast github.com/gogo/protobuf/protoc-gen-gogofast && \ + go mod tidy + +# Return a sed expression for replacing the go_package option in proto +# file with a one that's valid for us. +# +# Example: $(call get-sed-expr,$(PROTOBUF_GEN_DIR)) +define get-sed-expr +'s,go_package = "github.com/open-telemetry/opentelemetry-proto/gen/go,go_package = "go.opentelemetry.io/otel/$(1),' endef -gen-protobuf: $(SOURCE_PROTO_FILES) | $(PROTOBUF_GEN_DIR)/ - $(foreach file,$(subst ${PROTO_SOURCE_DIR}/,,$(SOURCE_PROTO_FILES)),$(call exec-protoc-all, -i $(PROTO_SOURCE_DIR) -f ${file} -l gogo -o ${PROTOBUF_TEMP_DIR})) +.PHONY: protobuf +protobuf: protobuf-source gen-protobuf copy-protobufs + +.PHONY: protobuf-source +protobuf-source: $(SOURCE_PROTO_FILES) + +# This copies proto files from submodule into $(PROTO_SOURCE_DIR), +# thus satisfying the $(SOURCE_PROTO_FILES) prerequisite. The copies +# have their package name replaced by go.opentelemetry.io/otel. +$(PROTO_SOURCE_DIR)/%.proto: $(OTEL_PROTO_SUBMODULE)/%.proto + @ \ + mkdir -p $(@D); \ + sed -e $(call get-sed-expr,$(PROTOBUF_GEN_DIR)) "$<" >"$@.tmp"; \ + mv "$@.tmp" "$@" -# requires `pax` to be installed, as it has consistent options for both BSD (Darwin) and Linux -copy-protobufs: | $(PROTOBUF_GEN_DIR)/ - find ./$(PROTOBUF_TEMP_DIR)/go.opentelemetry.io/otel/$(PROTOBUF_GEN_DIR) -type f -print0 | \ - pax -0 -s ',^./$(PROTOBUF_TEMP_DIR)/go.opentelemetry.io/otel/$(PROTOBUF_GEN_DIR),,' -rw ./$(PROTOBUF_GEN_DIR) +.PHONY: gen-protobuf +gen-protobuf: $(SOURCE_PROTO_FILES) $(TOOLS_DIR)/protoc-gen-gogofast $(TOOLS_DIR)/protoc/bin/protoc + @ \ + mkdir -p "$(PROTOBUF_TEMP_DIR)"; \ + set -e; for f in $^; do \ + if [[ "$${f}" == $(TOOLS_DIR)/* ]]; then continue; fi; \ + echo "protoc $${f#"$(PROTO_SOURCE_DIR)/"}"; \ + PATH="$(TOOLS_DIR):$${PATH}" $(TOOLS_DIR)/protoc/bin/protoc --proto_path="$(PROTO_SOURCE_DIR)" --gogofast_out="plugins=grpc:$(PROTOBUF_TEMP_DIR)" "$${f}"; \ + done -$(PROTO_SOURCE_DIR)/ $(PROTOBUF_GEN_DIR)/: - mkdir -p $@ +.PHONY: copy-protobufs +copy-protobufs: + @rsync -a $(PROTOBUF_TEMP_DIR)/go.opentelemetry.io/otel/exporters . .PHONY: clean clean: - rm -rf ./gen + rm -rf $(GEN_TEMP_DIR) diff --git a/bridge/opencensus/go.sum b/bridge/opencensus/go.sum index 15c1a955767..57a8a6fff2c 100644 --- a/bridge/opencensus/go.sum +++ b/bridge/opencensus/go.sum @@ -10,8 +10,8 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.5.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/bridge/opentracing/bridge.go b/bridge/opentracing/bridge.go index dfac76fc64a..5e6e29aa97a 100644 --- a/bridge/opentracing/bridge.go +++ b/bridge/opentracing/bridge.go @@ -320,7 +320,7 @@ func (t *BridgeTracer) SetWarningHandler(handler BridgeWarningHandler) { t.warningHandler = handler } -// SetWarningHandler overrides the underlying OpenTelemetry +// SetOpenTelemetryTracer overrides the underlying OpenTelemetry // tracer. The passed tracer should know how to operate in the // environment that uses OpenTracing API. func (t *BridgeTracer) SetOpenTelemetryTracer(tracer trace.Tracer) { diff --git a/bridge/opentracing/go.sum b/bridge/opentracing/go.sum index f54f9cb911d..d24ca0c3d56 100644 --- a/bridge/opentracing/go.sum +++ b/bridge/opentracing/go.sum @@ -1,7 +1,7 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/google/go-cmp v0.5.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= 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= diff --git a/example/basic/go.sum b/example/basic/go.sum index 57f074623d2..ae3c891c195 100644 --- a/example/basic/go.sum +++ b/example/basic/go.sum @@ -4,8 +4,8 @@ github.com/benbjohnson/clock v1.0.3 h1:vkLuvpK4fmtSCuo60+yC63p7y0BmQ8gm5ZXGuBCJy github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/google/go-cmp v0.5.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= +github.com/google/go-cmp v0.5.4/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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/example/jaeger/go.sum b/example/jaeger/go.sum index b088e72c00c..aaa87c97e12 100644 --- a/example/jaeger/go.sum +++ b/example/jaeger/go.sum @@ -89,8 +89,8 @@ 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/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= diff --git a/example/namedtracer/go.sum b/example/namedtracer/go.sum index 57f074623d2..ae3c891c195 100644 --- a/example/namedtracer/go.sum +++ b/example/namedtracer/go.sum @@ -4,8 +4,8 @@ github.com/benbjohnson/clock v1.0.3 h1:vkLuvpK4fmtSCuo60+yC63p7y0BmQ8gm5ZXGuBCJy github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/google/go-cmp v0.5.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= +github.com/google/go-cmp v0.5.4/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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/example/opencensus/go.sum b/example/opencensus/go.sum index aec2a1be51f..0f352e86792 100644 --- a/example/opencensus/go.sum +++ b/example/opencensus/go.sum @@ -14,8 +14,8 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.5.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= +github.com/google/go-cmp v0.5.4/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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/example/otel-collector/go.sum b/example/otel-collector/go.sum index 125f50ba892..b6ddbb33ead 100644 --- a/example/otel-collector/go.sum +++ b/example/otel-collector/go.sum @@ -32,8 +32,8 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a 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.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= +github.com/google/go-cmp v0.5.4/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/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= diff --git a/example/otel-collector/main.go b/example/otel-collector/main.go index c357209a3ce..a2452f87485 100644 --- a/example/otel-collector/main.go +++ b/example/otel-collector/main.go @@ -49,7 +49,7 @@ func initProvider() func() { // `localhost:30080` address. Otherwise, replace `localhost` with the // address of your cluster. If you run the app inside k8s, then you can // probably connect directly to the service through dns - exp, err := otlp.NewExporter( + exp, err := otlp.NewExporter(ctx, otlp.WithInsecure(), otlp.WithAddress("localhost:30080"), otlp.WithGRPCDialOption(grpc.WithBlock()), // useful for testing diff --git a/example/prometheus/go.sum b/example/prometheus/go.sum index 29f13df06c0..5ad64efdd1b 100644 --- a/example/prometheus/go.sum +++ b/example/prometheus/go.sum @@ -34,8 +34,8 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw 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.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= diff --git a/example/zipkin/go.sum b/example/zipkin/go.sum index 42fd0cf2cb1..d226056d1ae 100644 --- a/example/zipkin/go.sum +++ b/example/zipkin/go.sum @@ -38,8 +38,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw 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.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= diff --git a/exporters/metric/prometheus/go.sum b/exporters/metric/prometheus/go.sum index 29f13df06c0..5ad64efdd1b 100644 --- a/exporters/metric/prometheus/go.sum +++ b/exporters/metric/prometheus/go.sum @@ -34,8 +34,8 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw 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.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= diff --git a/exporters/otlp/alignment_test.go b/exporters/otlp/alignment_test.go index f20a0bd1b2d..276625637a1 100644 --- a/exporters/otlp/alignment_test.go +++ b/exporters/otlp/alignment_test.go @@ -26,8 +26,8 @@ import ( func TestMain(m *testing.M) { fields := []ottest.FieldOffset{ { - Name: "Exporter.lastConnectErrPtr", - Offset: unsafe.Offsetof(Exporter{}.lastConnectErrPtr), + Name: "grpcConnection.lastConnectErrPtr", + Offset: unsafe.Offsetof(grpcConnection{}.lastConnectErrPtr), }, } if !ottest.Aligned8Byte(fields, os.Stderr) { diff --git a/exporters/otlp/connection.go b/exporters/otlp/connection.go index 48c799c80e2..283d6d42d55 100644 --- a/exporters/otlp/connection.go +++ b/exporters/otlp/connection.go @@ -15,52 +15,113 @@ package otlp // import "go.opentelemetry.io/otel/exporters/otlp" import ( + "context" + "fmt" "math/rand" + "sync" "sync/atomic" "time" "unsafe" + + "google.golang.org/grpc" + "google.golang.org/grpc/metadata" ) -func (e *Exporter) lastConnectError() error { - errPtr := (*error)(atomic.LoadPointer(&e.lastConnectErrPtr)) +type grpcConnection struct { + // Ensure pointer is 64-bit aligned for atomic operations on both 32 and 64 bit machines. + lastConnectErrPtr unsafe.Pointer + + // mu protects the connection as it is accessed by the + // exporter goroutines and background connection goroutine + mu sync.Mutex + cc *grpc.ClientConn + + // these fields are read-only after constructor is finished + c config + metadata metadata.MD + newConnectionHandler func(cc *grpc.ClientConn) error + + // these channels are created once + disconnectedCh chan bool + backgroundConnectionDoneCh chan struct{} + stopCh chan struct{} + + // this is for tests, so they can replace the closing + // routine without a worry of modifying some global variable + // or changing it back to original after the test is done + closeBackgroundConnectionDoneCh func(ch chan struct{}) +} + +func newGRPCConnection(c config, handler func(cc *grpc.ClientConn) error) *grpcConnection { + conn := new(grpcConnection) + conn.newConnectionHandler = handler + if c.collectorAddr == "" { + c.collectorAddr = fmt.Sprintf("%s:%d", DefaultCollectorHost, DefaultCollectorPort) + } + conn.c = c + if len(conn.c.headers) > 0 { + conn.metadata = metadata.New(conn.c.headers) + } + conn.closeBackgroundConnectionDoneCh = func(ch chan struct{}) { + close(ch) + } + return conn +} + +func (oc *grpcConnection) startConnection(ctx context.Context) { + oc.stopCh = make(chan struct{}) + oc.disconnectedCh = make(chan bool) + oc.backgroundConnectionDoneCh = make(chan struct{}) + + if err := oc.connect(ctx); err == nil { + oc.setStateConnected() + } else { + oc.setStateDisconnected(err) + } + go oc.indefiniteBackgroundConnection() +} + +func (oc *grpcConnection) lastConnectError() error { + errPtr := (*error)(atomic.LoadPointer(&oc.lastConnectErrPtr)) if errPtr == nil { return nil } return *errPtr } -func (e *Exporter) saveLastConnectError(err error) { +func (oc *grpcConnection) saveLastConnectError(err error) { var errPtr *error if err != nil { errPtr = &err } - atomic.StorePointer(&e.lastConnectErrPtr, unsafe.Pointer(errPtr)) + atomic.StorePointer(&oc.lastConnectErrPtr, unsafe.Pointer(errPtr)) } -func (e *Exporter) setStateDisconnected(err error) { - e.saveLastConnectError(err) +func (oc *grpcConnection) setStateDisconnected(err error) { + oc.saveLastConnectError(err) select { - case e.disconnectedCh <- true: + case oc.disconnectedCh <- true: default: } + _ = oc.newConnectionHandler(nil) } -func (e *Exporter) setStateConnected() { - e.saveLastConnectError(nil) +func (oc *grpcConnection) setStateConnected() { + oc.saveLastConnectError(nil) } -func (e *Exporter) connected() bool { - return e.lastConnectError() == nil +func (oc *grpcConnection) connected() bool { + return oc.lastConnectError() == nil } const defaultConnReattemptPeriod = 10 * time.Second -func (e *Exporter) indefiniteBackgroundConnection() { +func (oc *grpcConnection) indefiniteBackgroundConnection() { defer func() { - e.backgroundConnectionDoneCh <- true + oc.closeBackgroundConnectionDoneCh(oc.backgroundConnectionDoneCh) }() - connReattemptPeriod := e.c.reconnectionPeriod + connReattemptPeriod := oc.c.reconnectionPeriod if connReattemptPeriod <= 0 { connReattemptPeriod = defaultConnReattemptPeriod } @@ -79,17 +140,26 @@ func (e *Exporter) indefiniteBackgroundConnection() { // 2. Otherwise block until we are disconnected, and // then retry connecting select { - case <-e.stopCh: + case <-oc.stopCh: return - case <-e.disconnectedCh: + case <-oc.disconnectedCh: + // Quickly check if we haven't stopped at the + // same time. + select { + case <-oc.stopCh: + return + + default: + } + // Normal scenario that we'll wait for } - if err := e.connect(); err == nil { - e.setStateConnected() + if err := oc.connect(context.Background()); err == nil { + oc.setStateConnected() } else { - e.setStateDisconnected(err) + oc.setStateDisconnected(err) } // Apply some jitter to avoid lockstep retrials of other @@ -97,17 +167,110 @@ func (e *Exporter) indefiniteBackgroundConnection() { // innocent DDOS, by clogging the machine's resources and network. jitter := time.Duration(rng.Int63n(maxJitterNanos)) select { - case <-e.stopCh: + case <-oc.stopCh: return case <-time.After(connReattemptPeriod + jitter): } } } -func (e *Exporter) connect() error { - cc, err := e.dialToCollector() +func (oc *grpcConnection) connect(ctx context.Context) error { + cc, err := oc.dialToCollector(ctx) if err != nil { return err } - return e.enableConnections(cc) + oc.setConnection(cc) + return oc.newConnectionHandler(cc) +} + +// setConnection sets cc as the client connection and returns true if +// the connection state changed. +func (oc *grpcConnection) setConnection(cc *grpc.ClientConn) bool { + oc.mu.Lock() + defer oc.mu.Unlock() + + // If previous clientConn is same as the current then just return. + // This doesn't happen right now as this func is only called with new ClientConn. + // It is more about future-proofing. + if oc.cc == cc { + return false + } + + // If the previous clientConn was non-nil, close it + if oc.cc != nil { + _ = oc.cc.Close() + } + oc.cc = cc + return true +} + +func (oc *grpcConnection) dialToCollector(ctx context.Context) (*grpc.ClientConn, error) { + addr := oc.c.collectorAddr + + dialOpts := []grpc.DialOption{} + if oc.c.grpcServiceConfig != "" { + dialOpts = append(dialOpts, grpc.WithDefaultServiceConfig(oc.c.grpcServiceConfig)) + } + if oc.c.clientCredentials != nil { + dialOpts = append(dialOpts, grpc.WithTransportCredentials(oc.c.clientCredentials)) + } else if oc.c.canDialInsecure { + dialOpts = append(dialOpts, grpc.WithInsecure()) + } + if oc.c.compressor != "" { + dialOpts = append(dialOpts, grpc.WithDefaultCallOptions(grpc.UseCompressor(oc.c.compressor))) + } + if len(oc.c.grpcDialOptions) != 0 { + dialOpts = append(dialOpts, oc.c.grpcDialOptions...) + } + + ctx, cancel := oc.contextWithStop(ctx) + defer cancel() + ctx = oc.contextWithMetadata(ctx) + return grpc.DialContext(ctx, addr, dialOpts...) +} + +func (oc *grpcConnection) contextWithMetadata(ctx context.Context) context.Context { + if oc.metadata.Len() > 0 { + return metadata.NewOutgoingContext(ctx, oc.metadata) + } + return ctx +} + +func (oc *grpcConnection) shutdown(ctx context.Context) error { + close(oc.stopCh) + // Ensure that the backgroundConnector returns + select { + case <-oc.backgroundConnectionDoneCh: + case <-ctx.Done(): + return ctx.Err() + } + + close(oc.disconnectedCh) + + oc.mu.Lock() + cc := oc.cc + oc.cc = nil + oc.mu.Unlock() + + if cc != nil { + return cc.Close() + } + + return nil +} + +func (oc *grpcConnection) contextWithStop(ctx context.Context) (context.Context, context.CancelFunc) { + // Unify the parent context Done signal with the connection's + // stop channel. + ctx, cancel := context.WithCancel(ctx) + go func(ctx context.Context, cancel context.CancelFunc) { + select { + case <-ctx.Done(): + // Nothing to do, either cancelled or deadline + // happened. + case <-oc.stopCh: + cancel() + } + }(ctx, cancel) + return ctx, cancel } diff --git a/exporters/otlp/example_test.go b/exporters/otlp/example_test.go index cf3a8eb0103..a34811e25e2 100644 --- a/exporters/otlp/example_test.go +++ b/exporters/otlp/example_test.go @@ -28,12 +28,13 @@ import ( ) func Example_insecure() { - exp, err := otlp.NewExporter(otlp.WithInsecure()) + ctx := context.Background() + exp, err := otlp.NewExporter(ctx, otlp.WithInsecure()) if err != nil { log.Fatalf("Failed to create the collector exporter: %v", err) } defer func() { - ctx, cancel := context.WithTimeout(context.Background(), time.Second) + ctx, cancel := context.WithTimeout(ctx, time.Second) defer cancel() if err := exp.Shutdown(ctx); err != nil { otel.Handle(err) @@ -54,7 +55,7 @@ func Example_insecure() { tracer := otel.Tracer("test-tracer") // Then use the OpenTelemetry tracing library, like we normally would. - ctx, span := tracer.Start(context.Background(), "CollectorExporter-Example") + ctx, span := tracer.Start(ctx, "CollectorExporter-Example") defer span.End() for i := 0; i < 10; i++ { @@ -72,12 +73,13 @@ func Example_withTLS() { log.Fatalf("failed to create gRPC client TLS credentials: %v", err) } - exp, err := otlp.NewExporter(otlp.WithTLSCredentials(creds)) + ctx := context.Background() + exp, err := otlp.NewExporter(ctx, otlp.WithTLSCredentials(creds)) if err != nil { log.Fatalf("failed to create the collector exporter: %v", err) } defer func() { - ctx, cancel := context.WithTimeout(context.Background(), time.Second) + ctx, cancel := context.WithTimeout(ctx, time.Second) defer cancel() if err := exp.Shutdown(ctx); err != nil { otel.Handle(err) @@ -98,7 +100,7 @@ func Example_withTLS() { tracer := otel.Tracer("test-tracer") // Then use the OpenTelemetry tracing library, like we normally would. - ctx, span := tracer.Start(context.Background(), "Securely-Talking-To-Collector-Span") + ctx, span := tracer.Start(ctx, "Securely-Talking-To-Collector-Span") defer span.End() for i := 0; i < 10; i++ { diff --git a/exporters/otlp/go.mod b/exporters/otlp/go.mod index dcd433d2da8..dd68a564bc0 100644 --- a/exporters/otlp/go.mod +++ b/exporters/otlp/go.mod @@ -10,7 +10,7 @@ replace ( require ( github.com/gogo/protobuf v1.3.1 github.com/golang/protobuf v1.4.2 // indirect - github.com/google/go-cmp v0.5.3 + github.com/google/go-cmp v0.5.4 github.com/stretchr/testify v1.6.1 go.opentelemetry.io/otel v0.14.0 go.opentelemetry.io/otel/sdk v0.14.0 diff --git a/exporters/otlp/go.sum b/exporters/otlp/go.sum index 2688698810a..467779a83ee 100644 --- a/exporters/otlp/go.sum +++ b/exporters/otlp/go.sum @@ -31,8 +31,8 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a 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.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= +github.com/google/go-cmp v0.5.4/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/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= diff --git a/exporters/otlp/otlp.go b/exporters/otlp/otlp.go index 16754394ce9..f8c1c5b0e76 100644 --- a/exporters/otlp/otlp.go +++ b/exporters/otlp/otlp.go @@ -20,12 +20,9 @@ package otlp // import "go.opentelemetry.io/otel/exporters/otlp" import ( "context" "errors" - "fmt" "sync" - "unsafe" "google.golang.org/grpc" - "google.golang.org/grpc/metadata" colmetricpb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/collector/metrics/v1" coltracepb "go.opentelemetry.io/otel/exporters/otlp/internal/opentelemetry-proto-gen/collector/trace/v1" @@ -43,22 +40,16 @@ type Exporter struct { // mu protects the non-atomic and non-channel variables mu sync.RWMutex // senderMu protects the concurrent unsafe sends on the shared gRPC client connection. - senderMu sync.Mutex - started bool - traceExporter coltracepb.TraceServiceClient - metricExporter colmetricpb.MetricsServiceClient - grpcClientConn *grpc.ClientConn - lastConnectErrPtr unsafe.Pointer - - startOnce sync.Once - stopOnce sync.Once - stopCh chan struct{} - disconnectedCh chan bool - - backgroundConnectionDoneCh chan bool - - c config - metadata metadata.MD + senderMu sync.Mutex + started bool + traceExporter coltracepb.TraceServiceClient + metricExporter colmetricpb.MetricsServiceClient + cc *grpcConnection + + startOnce sync.Once + stopOnce sync.Once + + exportKindSelector metricsdk.ExportKindSelector } var _ tracesdk.SpanExporter = (*Exporter)(nil) @@ -82,9 +73,9 @@ func newConfig(opts ...ExporterOption) config { } // NewExporter constructs a new Exporter and starts it. -func NewExporter(opts ...ExporterOption) (*Exporter, error) { +func NewExporter(ctx context.Context, opts ...ExporterOption) (*Exporter, error) { exp := NewUnstartedExporter(opts...) - if err := exp.Start(); err != nil { + if err := exp.Start(ctx); err != nil { return nil, err } return exp, nil @@ -93,19 +84,29 @@ func NewExporter(opts ...ExporterOption) (*Exporter, error) { // NewUnstartedExporter constructs a new Exporter and does not start it. func NewUnstartedExporter(opts ...ExporterOption) *Exporter { e := new(Exporter) - e.c = newConfig(opts...) - if len(e.c.headers) > 0 { - e.metadata = metadata.New(e.c.headers) - } + cfg := newConfig(opts...) + e.exportKindSelector = cfg.exportKindSelector + e.cc = newGRPCConnection(cfg, e.handleNewConnection) return e } +func (e *Exporter) handleNewConnection(cc *grpc.ClientConn) error { + e.mu.Lock() + defer e.mu.Unlock() + if cc != nil { + e.metricExporter = colmetricpb.NewMetricsServiceClient(cc) + e.traceExporter = coltracepb.NewTraceServiceClient(cc) + } else { + e.metricExporter = nil + e.traceExporter = nil + } + return nil +} + var ( - errAlreadyStarted = errors.New("already started") - errNotStarted = errors.New("not started") - errDisconnected = errors.New("exporter disconnected") - errStopped = errors.New("exporter stopped") - errContextCanceled = errors.New("context canceled") + errNoClient = errors.New("no client") + errAlreadyStarted = errors.New("already started") + errDisconnected = errors.New("exporter disconnected") ) // Start dials to the collector, establishing a connection to it. It also @@ -113,108 +114,25 @@ var ( // messages that consist of the node identifier. Start invokes a background // connector that will reattempt connections to the collector periodically // if the connection dies. -func (e *Exporter) Start() error { +func (e *Exporter) Start(ctx context.Context) error { var err = errAlreadyStarted e.startOnce.Do(func() { e.mu.Lock() e.started = true - e.disconnectedCh = make(chan bool, 1) - e.stopCh = make(chan struct{}) - e.backgroundConnectionDoneCh = make(chan bool) e.mu.Unlock() - // An optimistic first connection attempt to ensure that - // applications under heavy load can immediately process - // data. See https://github.com/census-ecosystem/opencensus-go-exporter-ocagent/pull/63 - if err := e.connect(); err == nil { - e.setStateConnected() - } else { - e.setStateDisconnected(err) - } - go e.indefiniteBackgroundConnection() - err = nil + e.cc.startConnection(ctx) }) return err } -func (e *Exporter) prepareCollectorAddress() string { - if e.c.collectorAddr != "" { - return e.c.collectorAddr - } - return fmt.Sprintf("%s:%d", DefaultCollectorHost, DefaultCollectorPort) -} - -func (e *Exporter) enableConnections(cc *grpc.ClientConn) error { - e.mu.RLock() - started := e.started - e.mu.RUnlock() - - if !started { - return errNotStarted - } - - e.mu.Lock() - // If previous clientConn is same as the current then just return. - // This doesn't happen right now as this func is only called with new ClientConn. - // It is more about future-proofing. - if e.grpcClientConn == cc { - e.mu.Unlock() - return nil - } - // If the previous clientConn was non-nil, close it - if e.grpcClientConn != nil { - _ = e.grpcClientConn.Close() - } - e.grpcClientConn = cc - e.traceExporter = coltracepb.NewTraceServiceClient(cc) - e.metricExporter = colmetricpb.NewMetricsServiceClient(cc) - e.mu.Unlock() - - return nil -} - -func (e *Exporter) contextWithMetadata(ctx context.Context) context.Context { - if e.metadata.Len() > 0 { - return metadata.NewOutgoingContext(ctx, e.metadata) - } - return ctx -} - -func (e *Exporter) dialToCollector() (*grpc.ClientConn, error) { - addr := e.prepareCollectorAddress() - - dialOpts := []grpc.DialOption{} - if e.c.grpcServiceConfig != "" { - dialOpts = append(dialOpts, grpc.WithDefaultServiceConfig(e.c.grpcServiceConfig)) - } - if e.c.clientCredentials != nil { - dialOpts = append(dialOpts, grpc.WithTransportCredentials(e.c.clientCredentials)) - } else if e.c.canDialInsecure { - dialOpts = append(dialOpts, grpc.WithInsecure()) - } - if e.c.compressor != "" { - dialOpts = append(dialOpts, grpc.WithDefaultCallOptions(grpc.UseCompressor(e.c.compressor))) - } - if len(e.c.grpcDialOptions) != 0 { - dialOpts = append(dialOpts, e.c.grpcDialOptions...) - } - - ctx := e.contextWithMetadata(context.Background()) - return grpc.DialContext(ctx, addr, dialOpts...) -} - -// closeStopCh is used to wrap the exporters stopCh channel closing for testing. -var closeStopCh = func(stopCh chan struct{}) { - close(stopCh) -} - // Shutdown closes all connections and releases resources currently being used // by the exporter. If the exporter is not started this does nothing. func (e *Exporter) Shutdown(ctx context.Context) error { e.mu.RLock() - cc := e.grpcClientConn + cc := e.cc started := e.started e.mu.RUnlock() @@ -225,23 +143,13 @@ func (e *Exporter) Shutdown(ctx context.Context) error { var err error e.stopOnce.Do(func() { - if cc != nil { - // Clean things up before checking this error. - err = cc.Close() - } + // Clean things up before checking this error. + err = cc.shutdown(ctx) // At this point we can change the state variable started e.mu.Lock() e.started = false e.mu.Unlock() - closeStopCh(e.stopCh) - - // Ensure that the backgroundConnector returns - select { - case <-e.backgroundConnectionDoneCh: - case <-ctx.Done(): - err = ctx.Err() - } }) return err @@ -251,16 +159,8 @@ func (e *Exporter) Shutdown(ctx context.Context) error { // interface. It transforms and batches metric Records into OTLP Metrics and // transmits them to the configured collector. func (e *Exporter) Export(parent context.Context, cps metricsdk.CheckpointSet) error { - // Unify the parent context Done signal with the exporter stopCh. - ctx, cancel := context.WithCancel(parent) + ctx, cancel := e.cc.contextWithStop(parent) defer cancel() - go func(ctx context.Context, cancel context.CancelFunc) { - select { - case <-ctx.Done(): - case <-e.stopCh: - cancel() - } - }(ctx, cancel) // Hardcode the number of worker goroutines to 1. We later will // need to see if there's a way to adjust that number for longer @@ -270,32 +170,31 @@ func (e *Exporter) Export(parent context.Context, cps metricsdk.CheckpointSet) e return err } - if !e.connected() { + if !e.cc.connected() { return errDisconnected } - select { - case <-e.stopCh: - return errStopped - case <-ctx.Done(): - return errContextCanceled - default: + err = func() error { e.senderMu.Lock() - _, err := e.metricExporter.Export(e.contextWithMetadata(ctx), &colmetricpb.ExportMetricsServiceRequest{ + defer e.senderMu.Unlock() + if e.metricExporter == nil { + return errNoClient + } + _, err := e.metricExporter.Export(e.cc.contextWithMetadata(ctx), &colmetricpb.ExportMetricsServiceRequest{ ResourceMetrics: rms, }) - e.senderMu.Unlock() - if err != nil { - return err - } + return err + }() + if err != nil { + e.cc.setStateDisconnected(err) } - return nil + return err } // ExportKindFor reports back to the OpenTelemetry SDK sending this Exporter // metric telemetry that it needs to be provided in a cumulative format. func (e *Exporter) ExportKindFor(desc *metric.Descriptor, kind aggregation.Kind) metricsdk.ExportKind { - return e.c.exportKindSelector.ExportKindFor(desc, kind) + return e.exportKindSelector.ExportKindFor(desc, kind) } // ExportSpans exports a batch of SpanData. @@ -304,28 +203,31 @@ func (e *Exporter) ExportSpans(ctx context.Context, sds []*tracesdk.SpanData) er } func (e *Exporter) uploadTraces(ctx context.Context, sdl []*tracesdk.SpanData) error { - select { - case <-e.stopCh: + ctx, cancel := e.cc.contextWithStop(ctx) + defer cancel() + + if !e.cc.connected() { return nil - default: - if !e.connected() { - return nil - } + } - protoSpans := transform.SpanData(sdl) - if len(protoSpans) == 0 { - return nil - } + protoSpans := transform.SpanData(sdl) + if len(protoSpans) == 0 { + return nil + } + err := func() error { e.senderMu.Lock() - _, err := e.traceExporter.Export(e.contextWithMetadata(ctx), &coltracepb.ExportTraceServiceRequest{ + defer e.senderMu.Unlock() + if e.traceExporter == nil { + return errNoClient + } + _, err := e.traceExporter.Export(e.cc.contextWithMetadata(ctx), &coltracepb.ExportTraceServiceRequest{ ResourceSpans: protoSpans, }) - e.senderMu.Unlock() - if err != nil { - e.setStateDisconnected(err) - return err - } + return err + }() + if err != nil { + e.cc.setStateDisconnected(err) } - return nil + return err } diff --git a/exporters/otlp/otlp_integration_test.go b/exporters/otlp/otlp_integration_test.go index 70f32c46571..ced8d103558 100644 --- a/exporters/otlp/otlp_integration_test.go +++ b/exporters/otlp/otlp_integration_test.go @@ -72,12 +72,13 @@ func newExporterEndToEndTest(t *testing.T, additionalOpts []otlp.ExporterOption) } opts = append(opts, additionalOpts...) - exp, err := otlp.NewExporter(opts...) + ctx := context.Background() + exp, err := otlp.NewExporter(ctx, opts...) if err != nil { t.Fatalf("failed to create a new collector exporter: %v", err) } defer func() { - ctx, cancel := context.WithTimeout(context.Background(), time.Second) + ctx, cancel := context.WithTimeout(ctx, time.Second) defer cancel() if err := exp.Shutdown(ctx); err != nil { panic(err) @@ -110,11 +111,11 @@ func newExporterEndToEndTest(t *testing.T, additionalOpts []otlp.ExporterOption) // Now create few spans m := 4 for i := 0; i < m; i++ { - _, span := tr1.Start(context.Background(), "AlwaysSample") + _, span := tr1.Start(ctx, "AlwaysSample") span.SetAttributes(label.Int64("i", int64(i))) span.End() - _, span = tr2.Start(context.Background(), "AlwaysSample") + _, span = tr2.Start(ctx, "AlwaysSample") span.SetAttributes(label.Int64("i", int64(i))) span.End() } @@ -124,7 +125,6 @@ func newExporterEndToEndTest(t *testing.T, additionalOpts []otlp.ExporterOption) pusher := push.New(processor, exp) pusher.Start() - ctx := context.Background() meter := pusher.MeterProvider().Meter("test-meter") labels := []label.KeyValue{label.Bool("test", true)} @@ -190,7 +190,7 @@ func newExporterEndToEndTest(t *testing.T, additionalOpts []otlp.ExporterOption) <-time.After(40 * time.Millisecond) // Now shutdown the exporter - ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond) + ctx, cancel := context.WithTimeout(ctx, time.Millisecond) defer cancel() if err := exp.Shutdown(ctx); err != nil { t.Fatalf("failed to stop the exporter: %v", err) @@ -307,31 +307,33 @@ func TestNewExporter_invokeStartThenStopManyTimes(t *testing.T) { _ = mc.stop() }() - exp, err := otlp.NewExporter(otlp.WithInsecure(), + ctx := context.Background() + exp, err := otlp.NewExporter(ctx, + otlp.WithInsecure(), otlp.WithReconnectionPeriod(50*time.Millisecond), otlp.WithAddress(mc.address)) if err != nil { t.Fatalf("error creating exporter: %v", err) } defer func() { - if err := exp.Shutdown(context.Background()); err != nil { + if err := exp.Shutdown(ctx); err != nil { panic(err) } }() // Invoke Start numerous times, should return errAlreadyStarted for i := 0; i < 10; i++ { - if err := exp.Start(); err == nil || !strings.Contains(err.Error(), "already started") { + if err := exp.Start(ctx); err == nil || !strings.Contains(err.Error(), "already started") { t.Fatalf("#%d unexpected Start error: %v", i, err) } } - if err := exp.Shutdown(context.Background()); err != nil { + if err := exp.Shutdown(ctx); err != nil { t.Fatalf("failed to Shutdown the exporter: %v", err) } // Invoke Shutdown numerous times for i := 0; i < 10; i++ { - if err := exp.Shutdown(context.Background()); err != nil { + if err := exp.Shutdown(ctx); err != nil { t.Fatalf(`#%d got error (%v) expected none`, i, err) } } @@ -341,14 +343,16 @@ func TestNewExporter_collectorConnectionDiesThenReconnects(t *testing.T) { mc := runMockCol(t) reconnectionPeriod := 20 * time.Millisecond - exp, err := otlp.NewExporter(otlp.WithInsecure(), + ctx := context.Background() + exp, err := otlp.NewExporter(ctx, + otlp.WithInsecure(), otlp.WithAddress(mc.address), otlp.WithReconnectionPeriod(reconnectionPeriod)) if err != nil { t.Fatalf("Unexpected error: %v", err) } defer func() { - _ = exp.Shutdown(context.Background()) + _ = exp.Shutdown(ctx) }() // We'll now stop the collector right away to simulate a connection @@ -363,7 +367,7 @@ func TestNewExporter_collectorConnectionDiesThenReconnects(t *testing.T) { // No endpoint up. require.Error( t, - exp.ExportSpans(context.Background(), []*exporttrace.SpanData{{Name: "in the midst"}}), + exp.ExportSpans(ctx, []*exporttrace.SpanData{{Name: "in the midst"}}), "transport: Error while dialing dial tcp %s: connect: connection refused", mc.address, ) @@ -377,7 +381,7 @@ func TestNewExporter_collectorConnectionDiesThenReconnects(t *testing.T) { n := 10 for i := 0; i < n; i++ { - require.NoError(t, exp.ExportSpans(context.Background(), []*exporttrace.SpanData{{Name: "Resurrected"}})) + require.NoError(t, exp.ExportSpans(ctx, []*exporttrace.SpanData{{Name: "Resurrected"}})) } nmaSpans := nmc.getSpans() @@ -412,13 +416,15 @@ func TestNewExporter_collectorOnBadConnection(t *testing.T) { _, collectorPortStr, _ := net.SplitHostPort(ln.Addr().String()) address := fmt.Sprintf("localhost:%s", collectorPortStr) - exp, err := otlp.NewExporter(otlp.WithInsecure(), + ctx := context.Background() + exp, err := otlp.NewExporter(ctx, + otlp.WithInsecure(), otlp.WithReconnectionPeriod(50*time.Millisecond), otlp.WithAddress(address)) if err != nil { t.Fatalf("Despite an indefinite background reconnection, got error: %v", err) } - _ = exp.Shutdown(context.Background()) + _ = exp.Shutdown(ctx) } func TestNewExporter_withAddress(t *testing.T) { @@ -432,11 +438,12 @@ func TestNewExporter_withAddress(t *testing.T) { otlp.WithReconnectionPeriod(50*time.Millisecond), otlp.WithAddress(mc.address)) + ctx := context.Background() defer func() { - _ = exp.Shutdown(context.Background()) + _ = exp.Shutdown(ctx) }() - if err := exp.Start(); err != nil { + if err := exp.Start(ctx); err != nil { t.Fatalf("Unexpected Start error: %v", err) } } @@ -447,16 +454,17 @@ func TestNewExporter_withHeaders(t *testing.T) { _ = mc.stop() }() - exp, _ := otlp.NewExporter( + ctx := context.Background() + exp, _ := otlp.NewExporter(ctx, otlp.WithInsecure(), otlp.WithReconnectionPeriod(50*time.Millisecond), otlp.WithAddress(mc.address), otlp.WithHeaders(map[string]string{"header1": "value1"}), ) - require.NoError(t, exp.ExportSpans(context.Background(), []*exporttrace.SpanData{{Name: "in the midst"}})) + require.NoError(t, exp.ExportSpans(ctx, []*exporttrace.SpanData{{Name: "in the midst"}})) defer func() { - _ = exp.Shutdown(context.Background()) + _ = exp.Shutdown(ctx) }() headers := mc.getHeaders() @@ -473,14 +481,15 @@ func TestNewExporter_withMultipleAttributeTypes(t *testing.T) { <-time.After(5 * time.Millisecond) - exp, _ := otlp.NewExporter( + ctx := context.Background() + exp, _ := otlp.NewExporter(ctx, otlp.WithInsecure(), otlp.WithReconnectionPeriod(50*time.Millisecond), otlp.WithAddress(mc.address), ) defer func() { - _ = exp.Shutdown(context.Background()) + _ = exp.Shutdown(ctx) }() tp := sdktrace.NewTracerProvider( @@ -492,7 +501,7 @@ func TestNewExporter_withMultipleAttributeTypes(t *testing.T) { sdktrace.WithMaxExportBatchSize(10), ), ) - defer func() { _ = tp.Shutdown(context.Background()) }() + defer func() { _ = tp.Shutdown(ctx) }() tr := tp.Tracer("test-tracer") testKvs := []label.KeyValue{ @@ -504,7 +513,7 @@ func TestNewExporter_withMultipleAttributeTypes(t *testing.T) { label.Bool("Bool", true), label.String("String", "test"), } - _, span := tr.Start(context.Background(), "AlwaysSample") + _, span := tr.Start(ctx, "AlwaysSample") span.SetAttributes(testKvs...) span.End() @@ -520,7 +529,7 @@ func TestNewExporter_withMultipleAttributeTypes(t *testing.T) { <-time.After(40 * time.Millisecond) // Now shutdown the exporter - ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond) + ctx, cancel := context.WithTimeout(ctx, time.Millisecond) defer cancel() if err := exp.Shutdown(ctx); err != nil { t.Fatalf("failed to stop the exporter: %v", err) diff --git a/exporters/otlp/otlp_test.go b/exporters/otlp/otlp_test.go index 5c2e0e655bf..afcb28ddfea 100644 --- a/exporters/otlp/otlp_test.go +++ b/exporters/otlp/otlp_test.go @@ -23,21 +23,18 @@ import ( ) func TestExporterShutdownHonorsTimeout(t *testing.T) { - orig := closeStopCh ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute) - defer func() { - cancel() - closeStopCh = orig - }() - closeStopCh = func(stopCh chan struct{}) { + defer cancel() + + e := NewUnstartedExporter() + orig := e.cc.closeBackgroundConnectionDoneCh + e.cc.closeBackgroundConnectionDoneCh = func(ch chan struct{}) { go func() { <-ctx.Done() - close(stopCh) + orig(ch) }() } - - e := NewUnstartedExporter() - if err := e.Start(); err != nil { + if err := e.Start(ctx); err != nil { t.Fatalf("failed to start exporter: %v", err) } @@ -51,21 +48,18 @@ func TestExporterShutdownHonorsTimeout(t *testing.T) { } func TestExporterShutdownHonorsCancel(t *testing.T) { - orig := closeStopCh ctx, cancel := context.WithTimeout(context.Background(), 1*time.Minute) - defer func() { - cancel() - closeStopCh = orig - }() - closeStopCh = func(stopCh chan struct{}) { + defer cancel() + + e := NewUnstartedExporter() + orig := e.cc.closeBackgroundConnectionDoneCh + e.cc.closeBackgroundConnectionDoneCh = func(ch chan struct{}) { go func() { <-ctx.Done() - close(stopCh) + orig(ch) }() } - - e := NewUnstartedExporter() - if err := e.Start(); err != nil { + if err := e.Start(ctx); err != nil { t.Fatalf("failed to start exporter: %v", err) } @@ -84,7 +78,7 @@ func TestExporterShutdownNoError(t *testing.T) { defer cancel() e := NewUnstartedExporter() - if err := e.Start(); err != nil { + if err := e.Start(ctx); err != nil { t.Fatalf("failed to start exporter: %v", err) } @@ -95,7 +89,7 @@ func TestExporterShutdownNoError(t *testing.T) { func TestExporterShutdownManyTimes(t *testing.T) { ctx := context.Background() - e, err := NewExporter() + e, err := NewExporter(ctx) if err != nil { t.Fatalf("failed to start an exporter: %v", err) } diff --git a/exporters/stdout/go.sum b/exporters/stdout/go.sum index 57f074623d2..ae3c891c195 100644 --- a/exporters/stdout/go.sum +++ b/exporters/stdout/go.sum @@ -4,8 +4,8 @@ github.com/benbjohnson/clock v1.0.3 h1:vkLuvpK4fmtSCuo60+yC63p7y0BmQ8gm5ZXGuBCJy github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/google/go-cmp v0.5.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= +github.com/google/go-cmp v0.5.4/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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/exporters/trace/jaeger/go.mod b/exporters/trace/jaeger/go.mod index 7c3539d8cb1..afda97de602 100644 --- a/exporters/trace/jaeger/go.mod +++ b/exporters/trace/jaeger/go.mod @@ -9,7 +9,7 @@ replace ( require ( github.com/apache/thrift v0.13.0 - github.com/google/go-cmp v0.5.3 + github.com/google/go-cmp v0.5.4 github.com/stretchr/testify v1.6.1 go.opentelemetry.io/otel v0.14.0 go.opentelemetry.io/otel/sdk v0.14.0 diff --git a/exporters/trace/jaeger/go.sum b/exporters/trace/jaeger/go.sum index d719931b5a0..5ef4eb0bcd1 100644 --- a/exporters/trace/jaeger/go.sum +++ b/exporters/trace/jaeger/go.sum @@ -89,8 +89,8 @@ 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/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= diff --git a/exporters/trace/zipkin/go.mod b/exporters/trace/zipkin/go.mod index 6a87d9f33f4..1fc35bf15c4 100644 --- a/exporters/trace/zipkin/go.mod +++ b/exporters/trace/zipkin/go.mod @@ -8,7 +8,7 @@ replace ( ) require ( - github.com/google/go-cmp v0.5.3 + github.com/google/go-cmp v0.5.4 github.com/openzipkin/zipkin-go v0.2.5 github.com/stretchr/testify v1.6.1 go.opentelemetry.io/otel v0.14.0 diff --git a/exporters/trace/zipkin/go.sum b/exporters/trace/zipkin/go.sum index 1a4f5840508..4bffaf98aa9 100644 --- a/exporters/trace/zipkin/go.sum +++ b/exporters/trace/zipkin/go.sum @@ -38,8 +38,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw 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.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= diff --git a/exporters/trace/zipkin/zipkin.go b/exporters/trace/zipkin/zipkin.go index 51f57e37d58..935331451a9 100644 --- a/exporters/trace/zipkin/zipkin.go +++ b/exporters/trace/zipkin/zipkin.go @@ -20,6 +20,7 @@ import ( "encoding/json" "errors" "fmt" + "io" "io/ioutil" "log" "net/http" @@ -112,14 +113,14 @@ func NewRawExporter(collectorURL, serviceName string, opts ...Option) (*Exporter // NewExportPipeline sets up a complete export pipeline // with the recommended setup for trace provider func NewExportPipeline(collectorURL, serviceName string, opts ...Option) (*sdktrace.TracerProvider, error) { - exp, err := NewRawExporter(collectorURL, serviceName, opts...) + exporter, err := NewRawExporter(collectorURL, serviceName, opts...) if err != nil { return nil, err } - tp := sdktrace.NewTracerProvider(sdktrace.WithBatcher(exp)) - if exp.o.config != nil { - tp.ApplyConfig(*exp.o.config) + tp := sdktrace.NewTracerProvider(sdktrace.WithBatcher(exporter)) + if exporter.o.config != nil { + tp.ApplyConfig(*exporter.o.config) } return tp, err @@ -166,19 +167,21 @@ func (e *Exporter) ExportSpans(ctx context.Context, batch []*export.SpanData) er if err != nil { return e.errf("request to %s failed: %v", e.url, err) } - e.logf("zipkin responded with status %d", resp.StatusCode) + defer resp.Body.Close() - _, err = ioutil.ReadAll(resp.Body) + // Zipkin API returns a 202 on success and the content of the body isn't interesting + // but it is still being read because according to https://golang.org/pkg/net/http/#Response + // > The default HTTP client's Transport may not reuse HTTP/1.x "keep-alive" TCP connections + // > if the Body is not read to completion and closed. + _, err = io.Copy(ioutil.Discard, resp.Body) if err != nil { - // Best effort to clean up here. - resp.Body.Close() return e.errf("failed to read response body: %v", err) } - err = resp.Body.Close() - if err != nil { - return e.errf("failed to close response body: %v", err) + if resp.StatusCode != http.StatusAccepted { + return e.errf("failed to send spans to zipkin server with status %d", resp.StatusCode) } + return nil } diff --git a/exporters/trace/zipkin/zipkin_test.go b/exporters/trace/zipkin/zipkin_test.go index da0b3b4a994..e469f5d88e6 100644 --- a/exporters/trace/zipkin/zipkin_test.go +++ b/exporters/trace/zipkin/zipkin_test.go @@ -192,6 +192,7 @@ func (c *mockZipkinCollector) handler(w http.ResponseWriter, r *http.Request) { c.lock.Lock() defer c.lock.Unlock() c.models = append(c.models, models...) + w.WriteHeader(http.StatusAccepted) } func (c *mockZipkinCollector) Close() { @@ -340,9 +341,8 @@ func TestExportSpans(t *testing.T) { ctx := context.Background() require.Len(t, ls.Messages, 0) require.NoError(t, exporter.ExportSpans(ctx, spans[0:1])) - require.Len(t, ls.Messages, 2) + require.Len(t, ls.Messages, 1) require.Contains(t, ls.Messages[0], "send a POST request") - require.Contains(t, ls.Messages[1], "zipkin responded") ls.Messages = nil require.NoError(t, exporter.ExportSpans(ctx, nil)) require.Len(t, ls.Messages, 1) @@ -350,7 +350,6 @@ func TestExportSpans(t *testing.T) { ls.Messages = nil require.NoError(t, exporter.ExportSpans(ctx, spans[1:2])) require.Contains(t, ls.Messages[0], "send a POST request") - require.Contains(t, ls.Messages[1], "zipkin responded") checkFunc := func() bool { return collector.ModelsLen() == len(models) } diff --git a/go.mod b/go.mod index 5dfec2aa1d7..1847746362e 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,6 @@ module go.opentelemetry.io/otel go 1.14 require ( - github.com/google/go-cmp v0.5.3 + github.com/google/go-cmp v0.5.4 github.com/stretchr/testify v1.6.1 ) diff --git a/go.sum b/go.sum index 118ac6a984f..76002a62e42 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/google/go-cmp v0.5.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/internal/tools/go.mod b/internal/tools/go.mod index 2c6a978ade3..8fb7cca4465 100644 --- a/internal/tools/go.mod +++ b/internal/tools/go.mod @@ -4,7 +4,8 @@ go 1.14 require ( github.com/client9/misspell v0.3.4 - github.com/golangci/golangci-lint v1.32.2 + github.com/gogo/protobuf v1.3.1 + github.com/golangci/golangci-lint v1.33.0 github.com/itchyny/gojq v0.11.2 golang.org/x/tools v0.0.0-20201013201025-64a9e34f3752 ) diff --git a/internal/tools/go.sum b/internal/tools/go.sum index f548d3eae5c..c4e1682b1cd 100644 --- a/internal/tools/go.sum +++ b/internal/tools/go.sum @@ -103,6 +103,8 @@ github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14j github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +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= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -127,14 +129,12 @@ github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6 h1:YYWNAGTKWhKpc github.com/golangci/errcheck v0.0.0-20181223084120-ef45e06d44b6/go.mod h1:DbHgvLiFKX1Sh2T1w8Q/h4NAI8MHIpzCdnBUDTXU3I0= github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613 h1:9kfjN3AdxcbsZBf8NjltjWihK2QfBBBZuv91cMFfDHw= github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8= -github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3 h1:pe9JHs3cHHDQgOFXJJdYkK6fLz2PWyYtP4hthoCMvs8= -github.com/golangci/goconst v0.0.0-20180610141641-041c5f2b40f3/go.mod h1:JXrF4TWy4tXYn62/9x8Wm/K/dm06p8tCKwFRDPZG/1o= github.com/golangci/gocyclo v0.0.0-20180528144436-0a533e8fa43d h1:pXTK/gkVNs7Zyy7WKgLXmpQ5bHTrq5GDsp8R9Qs67g0= github.com/golangci/gocyclo v0.0.0-20180528144436-0a533e8fa43d/go.mod h1:ozx7R9SIwqmqf5pRP90DhR2Oay2UIjGuKheCBCNwAYU= github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a h1:iR3fYXUjHCR97qWS8ch1y9zPNsgXThGwjKPrYfqMPks= github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= -github.com/golangci/golangci-lint v1.32.2 h1:CgIeFWTLJ3Nt1w/WU1RO351j/CjN6LIVjppbJfI9nMk= -github.com/golangci/golangci-lint v1.32.2/go.mod h1:ydr+IqtIVyAh72L16aK0bNdNg/YGa+AEgdbKj9MluzI= +github.com/golangci/golangci-lint v1.33.0 h1:/o4OtOR3Idim4FHKBJXcy+6ZjNDm82gwK/v6+gWyH9U= +github.com/golangci/golangci-lint v1.33.0/go.mod h1:zMnMLSCaDlrXExYsuq2LOweE9CHVqYk5jexk23UsjYM= github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc h1:gLLhTLMk2/SutryVJ6D4VZCU3CUqr8YloG7FPIBWFpI= github.com/golangci/ineffassign v0.0.0-20190609212857-42439a7714cc/go.mod h1:e5tpTHCfVze+7EpLEozzMB3eafxo2KT5veNg1k6byQU= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= @@ -216,6 +216,8 @@ github.com/itchyny/gojq v0.11.2 h1:lKhMKfH7fTKMWj2Zr8az/9TliCn0TTXVc/BXfQ8Jhfc= github.com/itchyny/gojq v0.11.2/go.mod h1:XtmtF1PxeDpwLC1jyz/xAmV78ANlP0S9LVEPsKweK0A= github.com/itchyny/timefmt-go v0.1.1 h1:rLpnm9xxb39PEEVzO0n4IRp0q6/RmBc7Dy/rE4HrA0U= github.com/itchyny/timefmt-go v0.1.1/go.mod h1:0osSSCQSASBJMsIZnhAaF1C2fCBTJZXrnj37mG8/c+A= +github.com/jgautheron/goconst v0.0.0-20201117150253-ccae5bf973f3 h1:7nkB9fLPMwtn/R6qfPcHileL/x9ydlhw8XyDrLI1ZXg= +github.com/jgautheron/goconst v0.0.0-20201117150253-ccae5bf973f3/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a h1:GmsqmapfzSJkm28dhRoHz2tLRbJmqhU86IPgBtN3mmk= github.com/jingyugao/rowserrcheck v0.0.0-20191204022205-72ab7603b68a/go.mod h1:xRskid8CManxVta/ALEhJha/pweKBaVG6fWgc0yH25s= github.com/jirfag/go-printf-func-name v0.0.0-20191110105641-45db9963cdd3 h1:jNYPNLe3d8smommaoQlK7LOA5ESyUJJ+Wf79ZtA7Vp4= @@ -229,6 +231,7 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= @@ -245,8 +248,10 @@ 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/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kyoh86/exportloopref v0.1.7 h1:u+iHuTbkbTS2D/JP7fCuZDo/t3rBVGo3Hf58Rc+lQVY= -github.com/kyoh86/exportloopref v0.1.7/go.mod h1:h1rDl2Kdj97+Kwh4gdz3ujE7XHmH51Q0lUiZ1z4NLj8= +github.com/kunwardeep/paralleltest v1.0.2 h1:/jJRv0TiqPoEy/Y8dQxCFJhD56uS/pnvtatgTZBHokU= +github.com/kunwardeep/paralleltest v1.0.2/go.mod h1:ZPqNm1fVHPllh5LPVujzbVz1JN2GhLxSfY+oqUsvG30= +github.com/kyoh86/exportloopref v0.1.8 h1:5Ry/at+eFdkX9Vsdw3qU4YkvGtzuVfzT4X7S77LoN/M= +github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= @@ -411,8 +416,8 @@ github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tdakkota/asciicheck v0.0.0-20200416190851-d7f85be797a2 h1:Xr9gkxfOP0KQWXKNqmwe8vEeSUiUj4Rlee9CMVX2ZUQ= github.com/tdakkota/asciicheck v0.0.0-20200416190851-d7f85be797a2/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= -github.com/tetafro/godot v0.4.9 h1:dSOiuasshpevY73eeI3+zaqFnXSBKJ3mvxbyhh54VRo= -github.com/tetafro/godot v0.4.9/go.mod h1:/7NLHhv08H1+8DNj0MElpAACw1ajsCuf3TKNQxA5S+0= +github.com/tetafro/godot v1.3.0 h1:rKXb6aAz2AnwS98jYlU3snCFFXnIInQdaGiftNwpj+k= +github.com/tetafro/godot v1.3.0/go.mod h1:/7NLHhv08H1+8DNj0MElpAACw1ajsCuf3TKNQxA5S+0= github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e h1:RumXZ56IrCj4CL+g1b9OL/oH0QnsF976bC8xQFYUD5Q= github.com/timakin/bodyclose v0.0.0-20190930140734-f7f2e9bca95e/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= @@ -543,6 +548,7 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190221204921-83362c3779f5/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -568,13 +574,13 @@ golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200117220505-0cba7a3a9ee9/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200321224714-0d839f3cf2ed/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200410194907-79a7a3126eef/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200414032229-332987a829c3/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200422022333-3d57cf2e726e h1:3Dzrrxi54Io7Aoyb0PYLsI47K2TxkRQg+cqUn+m04do= golang.org/x/tools v0.0.0-20200422022333-3d57cf2e726e/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200624225443-88f3c62a19ff/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200625211823-6506e20df31f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305 h1:yaM5S0KcY0lIoZo7Fl+oi91b/DdlU2zuWpfHrpWbCS0= diff --git a/internal/tools/tools.go b/internal/tools/tools.go index f0418c71d3a..306a95e0daf 100644 --- a/internal/tools/tools.go +++ b/internal/tools/tools.go @@ -21,4 +21,5 @@ import ( _ "github.com/golangci/golangci-lint/cmd/golangci-lint" _ "github.com/itchyny/gojq" _ "golang.org/x/tools/cmd/stringer" + _ "github.com/gogo/protobuf/protoc-gen-gogofast" ) diff --git a/sdk/go.mod b/sdk/go.mod index bc05b947ef5..27d13c8a9ea 100644 --- a/sdk/go.mod +++ b/sdk/go.mod @@ -7,7 +7,7 @@ replace go.opentelemetry.io/otel => ../ require ( github.com/DataDog/sketches-go v0.0.1 github.com/benbjohnson/clock v1.0.3 - github.com/google/go-cmp v0.5.3 + github.com/google/go-cmp v0.5.4 github.com/google/gofuzz v1.1.0 // indirect github.com/stretchr/testify v1.6.1 go.opentelemetry.io/otel v0.14.0 diff --git a/sdk/go.sum b/sdk/go.sum index 57f074623d2..ae3c891c195 100644 --- a/sdk/go.sum +++ b/sdk/go.sum @@ -4,8 +4,8 @@ github.com/benbjohnson/clock v1.0.3 h1:vkLuvpK4fmtSCuo60+yC63p7y0BmQ8gm5ZXGuBCJy github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/google/go-cmp v0.5.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo= -github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= +github.com/google/go-cmp v0.5.4/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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/sdk/metric/aggregator/aggregator.go b/sdk/metric/aggregator/aggregator.go index 0539a0fd79b..afda991e863 100644 --- a/sdk/metric/aggregator/aggregator.go +++ b/sdk/metric/aggregator/aggregator.go @@ -31,7 +31,7 @@ func NewInconsistentAggregatorError(a1, a2 export.Aggregator) error { return fmt.Errorf("%w: %T and %T", aggregation.ErrInconsistentType, a1, a2) } -// RangeTest is a commmon routine for testing for valid input values. +// RangeTest is a common routine for testing for valid input values. // This rejects NaN values. This rejects negative values when the // metric instrument does not support negative values, including // monotonic counter metrics and absolute ValueRecorder metrics.