From efd4e3a3838dc6e7c8428db677b15693c2274623 Mon Sep 17 00:00:00 2001 From: Tyler Yahn Date: Mon, 10 Aug 2020 09:17:09 -0700 Subject: [PATCH] Remove google.golang.org/grpc/codes dependency from API by adding an equivalent codes package (#1046) * Add otel/codes package to replace google.golang.org/grpc/codes * Replace google.golang.org/grpc/codes with otel/codes * Update opentracing bridge to use OTel codes * Update semconv to use OTel codes * Update SDK to convert from OTel codes to gRPC * go mod tidy * Add change to CHANGELOG * Fix word from feedback --- CHANGELOG.md | 1 + api/testharness/harness.go | 4 +- api/trace/api.go | 3 +- api/trace/context_test.go | 3 +- api/trace/noop_span.go | 3 +- api/trace/testtrace/span.go | 3 +- api/trace/testtrace/span_test.go | 3 +- bridge/opentracing/bridge.go | 3 +- bridge/opentracing/go.mod | 1 - bridge/opentracing/internal/mock.go | 3 +- codes/codes.go | 89 +++++++++++++++++++++++++++++ internal/trace/mock_span.go | 3 +- sdk/internal/codes.go | 49 ++++++++++++++++ sdk/trace/span.go | 5 +- sdk/trace/trace_test.go | 13 +++-- semconv/http.go | 3 +- semconv/http_test.go | 3 +- 17 files changed, 159 insertions(+), 33 deletions(-) create mode 100644 codes/codes.go create mode 100644 sdk/internal/codes.go diff --git a/CHANGELOG.md b/CHANGELOG.md index db861616328..46aa3b6cc5e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Renamed `go.opentelemetry.io/otel/api/standard` package to `go.opentelemetry.io/otel/semconv` to avoid the ambiguous and generic name `standard` and better describe the package as containing OpenTelemetry semantic conventions. (#1016) - The environment variable used for resource detection has been changed from `OTEL_RESOURCE_LABELS` to `OTEL_RESOURCE_ATTRIBUTES` (#1042) - Replace `WithSyncer` with `WithBatcher` in examples. (#1044) +- Replace the `google.golang.org/grpc/codes` dependency in the API with an equivalent `go.opentelemetry.io/otel/codes` package. (#1046) ### Removed diff --git a/api/testharness/harness.go b/api/testharness/harness.go index e84c9807b9c..046325b272f 100644 --- a/api/testharness/harness.go +++ b/api/testharness/harness.go @@ -21,10 +21,8 @@ import ( "time" "go.opentelemetry.io/otel/api/kv" - - "google.golang.org/grpc/codes" - "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/internal/matchers" ) diff --git a/api/trace/api.go b/api/trace/api.go index 517284b6e3a..a0e11e5fcff 100644 --- a/api/trace/api.go +++ b/api/trace/api.go @@ -18,9 +18,8 @@ import ( "context" "time" - "google.golang.org/grpc/codes" - "go.opentelemetry.io/otel/api/kv" + "go.opentelemetry.io/otel/codes" ) type Provider interface { diff --git a/api/trace/context_test.go b/api/trace/context_test.go index fd03d146a85..7e4891e66d5 100644 --- a/api/trace/context_test.go +++ b/api/trace/context_test.go @@ -19,10 +19,9 @@ import ( "testing" "time" - "google.golang.org/grpc/codes" - "go.opentelemetry.io/otel/api/kv" "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel/codes" ) func TestSetCurrentSpanOverridesPreviouslySetSpan(t *testing.T) { diff --git a/api/trace/noop_span.go b/api/trace/noop_span.go index e222ad7f579..b35e9ce6439 100644 --- a/api/trace/noop_span.go +++ b/api/trace/noop_span.go @@ -18,9 +18,8 @@ import ( "context" "time" - "google.golang.org/grpc/codes" - "go.opentelemetry.io/otel/api/kv" + "go.opentelemetry.io/otel/codes" ) type NoopSpan struct { diff --git a/api/trace/testtrace/span.go b/api/trace/testtrace/span.go index 05a4452af63..4df34756a53 100644 --- a/api/trace/testtrace/span.go +++ b/api/trace/testtrace/span.go @@ -21,10 +21,9 @@ import ( "sync" "time" - "google.golang.org/grpc/codes" - "go.opentelemetry.io/otel/api/kv" "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel/codes" ) const ( diff --git a/api/trace/testtrace/span_test.go b/api/trace/testtrace/span_test.go index 3e9920cb94e..6697f04e282 100644 --- a/api/trace/testtrace/span_test.go +++ b/api/trace/testtrace/span_test.go @@ -22,11 +22,10 @@ import ( "testing" "time" - "google.golang.org/grpc/codes" - "go.opentelemetry.io/otel/api/kv" "go.opentelemetry.io/otel/api/trace" "go.opentelemetry.io/otel/api/trace/testtrace" + "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/internal/matchers" ottest "go.opentelemetry.io/otel/internal/testing" ) diff --git a/bridge/opentracing/bridge.go b/bridge/opentracing/bridge.go index dd8ee6190db..7f5866c5cda 100644 --- a/bridge/opentracing/bridge.go +++ b/bridge/opentracing/bridge.go @@ -21,8 +21,6 @@ import ( "strings" "sync" - "google.golang.org/grpc/codes" - ot "github.com/opentracing/opentracing-go" otext "github.com/opentracing/opentracing-go/ext" otlog "github.com/opentracing/opentracing-go/log" @@ -32,6 +30,7 @@ import ( otelcore "go.opentelemetry.io/otel/api/kv" otelpropagation "go.opentelemetry.io/otel/api/propagation" oteltrace "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel/codes" otelparent "go.opentelemetry.io/otel/internal/trace/parent" "go.opentelemetry.io/otel/bridge/opentracing/migration" diff --git a/bridge/opentracing/go.mod b/bridge/opentracing/go.mod index f5c2067845c..23644facd3d 100644 --- a/bridge/opentracing/go.mod +++ b/bridge/opentracing/go.mod @@ -7,5 +7,4 @@ replace go.opentelemetry.io/otel => ../.. require ( github.com/opentracing/opentracing-go v1.2.0 go.opentelemetry.io/otel v0.10.0 - google.golang.org/grpc v1.31.0 ) diff --git a/bridge/opentracing/internal/mock.go b/bridge/opentracing/internal/mock.go index 81121ea3e72..cdd6568fe14 100644 --- a/bridge/opentracing/internal/mock.go +++ b/bridge/opentracing/internal/mock.go @@ -21,11 +21,10 @@ import ( "sync" "time" - "google.golang.org/grpc/codes" - otelcorrelation "go.opentelemetry.io/otel/api/correlation" otelcore "go.opentelemetry.io/otel/api/kv" oteltrace "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel/codes" otelparent "go.opentelemetry.io/otel/internal/trace/parent" "go.opentelemetry.io/otel/bridge/opentracing/migration" diff --git a/codes/codes.go b/codes/codes.go new file mode 100644 index 00000000000..7d4aaee22c9 --- /dev/null +++ b/codes/codes.go @@ -0,0 +1,89 @@ +// 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 codes defines the canonical error codes used by OpenTelemetry. +// +// It conforms to [the OpenTelemetry +// specification](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/api.md#statuscanonicalcode). +// This also means that it follows gRPC codes and is based on +// [google.golang.org/grpc/codes](https://godoc.org/google.golang.org/grpc/codes). +// +// This package was added to this project, instead of using that existing +// package, to avoid the large package size it includes and not impose that +// burden on projects using this package. +package codes + +// Code is an 32-bit representation of a status state. +type Code uint32 + +// WARNING: any changes here must be propagated to the +// otel/sdk/internal/codes.go file. +const ( + // OK means success. + OK Code = 0 + // Canceled indicates the operation was canceled (typically by the + // caller). + Canceled Code = 1 + // Unknown error. An example of where this error may be returned is if an + // error is raised by a dependant API that does not contain enough + // information to convert it into a more appropriate error. + Unknown Code = 2 + // InvalidArgument indicates a client specified an invalid argument. Note + // that this differs from FailedPrecondition. InvalidArgument indicates + // arguments that are problematic regardless of the state of the system. + InvalidArgument Code = 3 + // DeadlineExceeded means a deadline expired before the operation could + // complete. For operations that change the state of the system, this error + // may be returned even if the operation has completed successfully. + DeadlineExceeded Code = 4 + // NotFound means some requested entity (e.g., file or directory) was not + // found. + NotFound Code = 5 + // AlreadyExists means some entity that we attempted to create (e.g., file + // or directory) already exists. + AlreadyExists Code = 6 + // PermissionDenied means the caller does not have permission to execute + // the specified operation. PermissionDenied must not be used if the caller + // cannot be identified (use Unauthenticated instead for those errors). + PermissionDenied Code = 7 + // ResourceExhausted means some resource has been exhausted, perhaps a + // per-user quota, or perhaps the entire file system is out of space. + ResourceExhausted Code = 8 + // FailedPrecondition means the operation was rejected because the system + // is not in a state required for the operation's execution. + FailedPrecondition Code = 9 + // Aborted means the operation was aborted, typically due to a concurrency + // issue like sequencer check failures, transaction aborts, etc. + Aborted Code = 10 + // OutOfRange means the operation was attempted past the valid range. + // E.g., seeking or reading past end of file. Unlike InvalidArgument, this + // error indicates a problem that may be fixed if the system state + // changes. + OutOfRange Code = 11 + // Unimplemented means the operation is not implemented or not + // supported/enabled in this service. + Unimplemented Code = 12 + // Internal means an internal errors. It means some invariants expected by + // underlying system has been broken. + Internal Code = 13 + // Unavailable means the service is currently unavailable. This is most + // likely a transient condition and may be corrected by retrying with a + // backoff. + Unavailable Code = 14 + // DataLoss means unrecoverable data loss or corruption has occurred. + DataLoss Code = 15 + // Unauthenticated means the request does not have valid authentication + // credentials for the operation. + Unauthenticated Code = 16 +) diff --git a/internal/trace/mock_span.go b/internal/trace/mock_span.go index 7a7addba563..c00f1ec34b2 100644 --- a/internal/trace/mock_span.go +++ b/internal/trace/mock_span.go @@ -18,10 +18,9 @@ import ( "context" "time" - "google.golang.org/grpc/codes" - "go.opentelemetry.io/otel/api/kv" apitrace "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel/codes" ) // MockSpan is a mock span used in association with MockTracer for testing purpose only. diff --git a/sdk/internal/codes.go b/sdk/internal/codes.go new file mode 100644 index 00000000000..d99990f6788 --- /dev/null +++ b/sdk/internal/codes.go @@ -0,0 +1,49 @@ +// 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 internal + +import ( + grpccodes "google.golang.org/grpc/codes" + + otelcodes "go.opentelemetry.io/otel/codes" +) + +// conversions are the equivalence mapping from OpenTelemetry to gRPC codes. +// Even though the underlying value should be the same all mappings are +// explicit here to avoid any error. +var conversions = map[otelcodes.Code]grpccodes.Code{ + otelcodes.OK: grpccodes.OK, + otelcodes.Canceled: grpccodes.Canceled, + otelcodes.Unknown: grpccodes.Unknown, + otelcodes.InvalidArgument: grpccodes.InvalidArgument, + otelcodes.DeadlineExceeded: grpccodes.DeadlineExceeded, + otelcodes.NotFound: grpccodes.NotFound, + otelcodes.AlreadyExists: grpccodes.AlreadyExists, + otelcodes.PermissionDenied: grpccodes.PermissionDenied, + otelcodes.ResourceExhausted: grpccodes.ResourceExhausted, + otelcodes.FailedPrecondition: grpccodes.FailedPrecondition, + otelcodes.Aborted: grpccodes.Aborted, + otelcodes.OutOfRange: grpccodes.OutOfRange, + otelcodes.Unimplemented: grpccodes.Unimplemented, + otelcodes.Internal: grpccodes.Internal, + otelcodes.Unavailable: grpccodes.Unavailable, + otelcodes.DataLoss: grpccodes.DataLoss, + otelcodes.Unauthenticated: grpccodes.Unauthenticated, +} + +// ConvertCode converts an OpenTelemetry Code into the equivalent gRPC code. +func ConvertCode(code otelcodes.Code) grpccodes.Code { + return conversions[code] +} diff --git a/sdk/trace/span.go b/sdk/trace/span.go index 16abb7afb40..489085e7b4f 100644 --- a/sdk/trace/span.go +++ b/sdk/trace/span.go @@ -22,11 +22,10 @@ import ( "sync" "time" - "google.golang.org/grpc/codes" - "go.opentelemetry.io/otel/api/global" "go.opentelemetry.io/otel/api/kv" apitrace "go.opentelemetry.io/otel/api/trace" + "go.opentelemetry.io/otel/codes" export "go.opentelemetry.io/otel/sdk/export/trace" "go.opentelemetry.io/otel/sdk/internal" ) @@ -90,7 +89,7 @@ func (s *span) SetStatus(code codes.Code, msg string) { return } s.mu.Lock() - s.data.StatusCode = code + s.data.StatusCode = internal.ConvertCode(code) s.data.StatusMessage = msg s.mu.Unlock() } diff --git a/sdk/trace/trace_test.go b/sdk/trace/trace_test.go index 33a22aebd40..69d27ac5182 100644 --- a/sdk/trace/trace_test.go +++ b/sdk/trace/trace_test.go @@ -29,12 +29,13 @@ import ( "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "google.golang.org/grpc/codes" + grpccodes "google.golang.org/grpc/codes" "go.opentelemetry.io/otel/api/kv" "go.opentelemetry.io/otel/api/testharness" "go.opentelemetry.io/otel/api/trace" apitrace "go.opentelemetry.io/otel/api/trace" + otelcodes "go.opentelemetry.io/otel/codes" ottest "go.opentelemetry.io/otel/internal/testing" export "go.opentelemetry.io/otel/sdk/export/trace" "go.opentelemetry.io/otel/sdk/instrumentation" @@ -592,7 +593,7 @@ func TestSetSpanStatus(t *testing.T) { tp, _ := NewProvider(WithSyncer(te)) span := startSpan(tp, "SpanStatus") - span.SetStatus(codes.Canceled, "canceled") + span.SetStatus(otelcodes.Canceled, "canceled") got, err := endSpan(te, span) if err != nil { t.Fatal(err) @@ -606,7 +607,7 @@ func TestSetSpanStatus(t *testing.T) { ParentSpanID: sid, Name: "span0", SpanKind: apitrace.SpanKindInternal, - StatusCode: codes.Canceled, + StatusCode: grpccodes.Canceled, StatusMessage: "canceled", HasRemoteParent: true, InstrumentationLibrary: instrumentation.Library{Name: "SpanStatus"}, @@ -976,7 +977,7 @@ func TestRecordErrorWithStatus(t *testing.T) { testErr := ottest.NewTestError("test error") errTime := time.Now() - testStatus := codes.Unknown + testStatus := otelcodes.Unknown span.RecordError(context.Background(), testErr, apitrace.WithErrorTime(errTime), apitrace.WithErrorStatus(testStatus), @@ -995,7 +996,7 @@ func TestRecordErrorWithStatus(t *testing.T) { ParentSpanID: sid, Name: "span0", SpanKind: apitrace.SpanKindInternal, - StatusCode: codes.Unknown, + StatusCode: grpccodes.Unknown, StatusMessage: "", HasRemoteParent: true, MessageEvents: []export.Event{ @@ -1036,7 +1037,7 @@ func TestRecordErrorNil(t *testing.T) { Name: "span0", SpanKind: apitrace.SpanKindInternal, HasRemoteParent: true, - StatusCode: codes.OK, + StatusCode: grpccodes.OK, StatusMessage: "", InstrumentationLibrary: instrumentation.Library{Name: "RecordErrorNil"}, } diff --git a/semconv/http.go b/semconv/http.go index b82fef93f65..748dde0c080 100644 --- a/semconv/http.go +++ b/semconv/http.go @@ -21,9 +21,8 @@ import ( "strconv" "strings" - "google.golang.org/grpc/codes" - "go.opentelemetry.io/otel/api/kv" + "go.opentelemetry.io/otel/codes" ) // NetAttributesFromHTTPRequest generates attributes of the net diff --git a/semconv/http_test.go b/semconv/http_test.go index 700ca1db05e..cfc26014ecd 100644 --- a/semconv/http_test.go +++ b/semconv/http_test.go @@ -1,5 +1,4 @@ // 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 @@ -22,9 +21,9 @@ import ( "testing" "github.com/stretchr/testify/assert" - "google.golang.org/grpc/codes" otelkv "go.opentelemetry.io/otel/api/kv" + "go.opentelemetry.io/otel/codes" ) type tlsOption int