Repository: GoogleCloudPlatform/opentelemetry-operations-go
Pull request #187 (2021-07-20 17:21:42)

Remove 'our' ReadOnlySpan interface
Instead of creating a new interface, we can embed the existing
interface to inherit the private func.

punya: Thanks @bogdandrutu for the suggestion.

Patch:
diff --git a/exporter/trace/cloudtrace.go b/exporter/trace/cloudtrace.go
index 8c273b2..2e95360 100644
--- a/exporter/trace/cloudtrace.go
+++ b/exporter/trace/cloudtrace.go
@@ -37,7 +37,7 @@ type Option func(*options)
 
 // DisplayNameFormatter is is a function that produces the display name of a span
 // given its ReadOnlySpan
-type DisplayNameFormatter func(ReadOnlySpan) string
+type DisplayNameFormatter func(sdktrace.ReadOnlySpan) string
 
 // options contains options for configuring the exporter.
 type options struct {
@@ -245,14 +245,6 @@ func newContextWithTimeout(ctx context.Context, timeout time.Duration) (context.
 
 // ExportSpans exports a ReadOnlySpan to Stackdriver Trace.
 func (e *Exporter) ExportSpans(ctx context.Context, spanData []sdktrace.ReadOnlySpan) error {
-	sd := make([]ReadOnlySpan, len(spanData))
-	for i := range spanData {
-		sd[i] = spanData[i]
-	}
-	return e.traceExporter.ExportSpans(ctx, sd)
-}
-
-func (e *Exporter) ExportCustomSpans(ctx context.Context, spanData []ReadOnlySpan) error {
 	return e.traceExporter.ExportSpans(ctx, spanData)
 }
 
diff --git a/exporter/trace/readonlyspan.go b/exporter/trace/readonlyspan.go
deleted file mode 100644
index 635a252..0000000
--- a/exporter/trace/readonlyspan.go
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2021 Google LLC
-//
-// 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 trace
-
-import (
-	"time"
-
-	"go.opentelemetry.io/otel/attribute"
-	"go.opentelemetry.io/otel/sdk/instrumentation"
-	"go.opentelemetry.io/otel/sdk/resource"
-	sdktrace "go.opentelemetry.io/otel/sdk/trace"
-	"go.opentelemetry.io/otel/trace"
-)
-
-// ReadOnlySpan is a copy of sdktrace.ReadOnlySpan without the private func.
-// It exists so that callers outside the Go SDK (such as the OTel collector exporter)
-// can create their own ReadOnlySpan instances, while retaining compatibility with
-// the Go exporter API.
-type ReadOnlySpan interface {
-	Name() string
-	SpanContext() trace.SpanContext
-	Parent() trace.SpanContext
-	SpanKind() trace.SpanKind
-	StartTime() time.Time
-	EndTime() time.Time
-	Attributes() []attribute.KeyValue
-	Links() []trace.Link
-	Events() []sdktrace.Event
-	Status() sdktrace.Status
-	InstrumentationLibrary() instrumentation.Library
-	Resource() *resource.Resource
-	DroppedAttributes() int
-	DroppedLinks() int
-	DroppedEvents() int
-	ChildSpanCount() int
-}
-
-// Ensure that our notion of ReadOnlySpan remains compatible with the SDK's.
-var _ ReadOnlySpan = sdktrace.ReadOnlySpan(nil)
diff --git a/exporter/trace/trace.go b/exporter/trace/trace.go
index 26e68dc..4b5acc2 100644
--- a/exporter/trace/trace.go
+++ b/exporter/trace/trace.go
@@ -20,6 +20,8 @@ import (
 	"fmt"
 	"time"
 
+	sdktrace "go.opentelemetry.io/otel/sdk/trace"
+
 	traceclient "cloud.google.com/go/trace/apiv2"
 	"google.golang.org/api/option"
 	tracepb "google.golang.org/genproto/googleapis/devtools/cloudtrace/v2"
@@ -52,7 +54,7 @@ func newTraceExporter(o *options) (*traceExporter, error) {
 	return e, nil
 }
 
-func (e *traceExporter) ExportSpans(ctx context.Context, spanData []ReadOnlySpan) error {
+func (e *traceExporter) ExportSpans(ctx context.Context, spanData []sdktrace.ReadOnlySpan) error {
 	// Ship the whole bundle o data.
 	results := make([]*tracepb.Span, len(spanData))
 	for i, sd := range spanData {
@@ -62,7 +64,7 @@ func (e *traceExporter) ExportSpans(ctx context.Context, spanData []ReadOnlySpan
 }
 
 // ConvertSpan converts a ReadOnlySpan to Stackdriver Trace.
-func (e *traceExporter) ConvertSpan(_ context.Context, sd ReadOnlySpan) *tracepb.Span {
+func (e *traceExporter) ConvertSpan(_ context.Context, sd sdktrace.ReadOnlySpan) *tracepb.Span {
 	return protoFromReadOnlySpan(sd, e.o.DefaultTraceAttributes, e.projectID, e.o.DisplayNameFormatter)
 }
 
diff --git a/exporter/trace/trace_proto.go b/exporter/trace/trace_proto.go
index 3d44979..b563888 100644
--- a/exporter/trace/trace_proto.go
+++ b/exporter/trace/trace_proto.go
@@ -25,6 +25,7 @@ import (
 	"go.opentelemetry.io/otel"
 	"go.opentelemetry.io/otel/attribute"
 	"go.opentelemetry.io/otel/codes"
+	sdktrace "go.opentelemetry.io/otel/sdk/trace"
 	"go.opentelemetry.io/otel/trace"
 
 	timestamppb "github.com/golang/protobuf/ptypes/timestamp"
@@ -64,7 +65,7 @@ const (
 
 var userAgent = fmt.Sprintf("opentelemetry-go %s; google-cloud-trace-exporter %s", otel.Version(), Version())
 
-func generateDisplayName(s ReadOnlySpan, format DisplayNameFormatter) string {
+func generateDisplayName(s sdktrace.ReadOnlySpan, format DisplayNameFormatter) string {
 	if format != nil {
 		return format(s)
 	}
@@ -74,7 +75,7 @@ func generateDisplayName(s ReadOnlySpan, format DisplayNameFormatter) string {
 
 // If there are duplicate keys present in the list of attributes,
 // then the first value found for the key is preserved.
-func attributeWithLabelsFromResources(sd ReadOnlySpan) []attribute.KeyValue {
+func attributeWithLabelsFromResources(sd sdktrace.ReadOnlySpan) []attribute.KeyValue {
 	attributes := sd.Attributes()
 	if sd.Resource().Len() == 0 {
 		return attributes
@@ -94,7 +95,7 @@ func attributeWithLabelsFromResources(sd ReadOnlySpan) []attribute.KeyValue {
 	return attributes
 }
 
-func protoFromReadOnlySpan(s ReadOnlySpan, defaultTraceAttributes []attribute.KeyValue, projectID string, format DisplayNameFormatter) *tracepb.Span {
+func protoFromReadOnlySpan(s sdktrace.ReadOnlySpan, defaultTraceAttributes []attribute.KeyValue, projectID string, format DisplayNameFormatter) *tracepb.Span {
 	if s == nil {
 		return nil
 	}


Test patch:
diff --git a/exporter/trace/cloudtrace_test.go b/exporter/trace/cloudtrace_test.go
index d87f905..017b44b 100644
--- a/exporter/trace/cloudtrace_test.go
+++ b/exporter/trace/cloudtrace_test.go
@@ -116,7 +116,7 @@ func TestExporter_DisplayNameFormatter(t *testing.T) {
 	clientOpt := []option.ClientOption{option.WithGRPCConn(mock.ClientConn())}
 
 	spanName := "span1234"
-	format := func(s ReadOnlySpan) string {
+	format := func(s sdktrace.ReadOnlySpan) string {
 		return "TEST_FORMAT" + s.Name()
 	}