Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
These are now returned as a SpanProcessor interface from their respective constructors. (#1638)
- Removed setting status to `Error` while recording an error as a span event in `RecordError`. (#1663)
- Removed `WithConfig` from tracer provider to avoid overriding configuration. (#1633)
- Removed `serviceName` parameter from Zipkin exporter and uses resource instead. (#1549)
- Removed `jaeger.WithProcess`. (#1673)

### Fixed
Expand Down
10 changes: 8 additions & 2 deletions example/zipkin/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ import (

"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/trace/zipkin"
"go.opentelemetry.io/otel/sdk/resource"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
"go.opentelemetry.io/otel/semconv"
"go.opentelemetry.io/otel/trace"
)

Expand All @@ -40,7 +42,6 @@ func initTracer(url string) func() {
// ratio.
exporter, err := zipkin.NewRawExporter(
url,
"zipkin-test",
zipkin.WithLogger(logger),
zipkin.WithSDK(&sdktrace.Config{DefaultSampler: sdktrace.AlwaysSample()}),
)
Expand All @@ -50,7 +51,12 @@ func initTracer(url string) func() {

batcher := sdktrace.NewBatchSpanProcessor(exporter)

tp := sdktrace.NewTracerProvider(sdktrace.WithSpanProcessor(batcher))
tp := sdktrace.NewTracerProvider(
sdktrace.WithSpanProcessor(batcher),
sdktrace.WithResource(resource.NewWithAttributes(
semconv.ServiceNameKey.String("zipkin-test"),
)),
)
otel.SetTracerProvider(tp)

return func() {
Expand Down
20 changes: 16 additions & 4 deletions exporters/trace/zipkin/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (

"go.opentelemetry.io/otel/attribute"
export "go.opentelemetry.io/otel/sdk/export/trace"
"go.opentelemetry.io/otel/semconv"
"go.opentelemetry.io/otel/trace"
)

Expand All @@ -31,15 +32,26 @@ const (
keyInstrumentationLibraryVersion = "otel.instrumentation_library.version"
)

func toZipkinSpanModels(batch []*export.SpanSnapshot, serviceName string) []zkmodel.SpanModel {
func toZipkinSpanModels(batch []*export.SpanSnapshot) []zkmodel.SpanModel {
models := make([]zkmodel.SpanModel, 0, len(batch))
for _, data := range batch {
models = append(models, toZipkinSpanModel(data, serviceName))
models = append(models, toZipkinSpanModel(data))
}
return models
}

func toZipkinSpanModel(data *export.SpanSnapshot, serviceName string) zkmodel.SpanModel {
func getServiceName(attrs []attribute.KeyValue) string {
for _, kv := range attrs {
if kv.Key == semconv.ServiceNameKey {
return kv.Value.AsString()
}
}

// Resource holds a default value so this might not be reach.
return ""
}

func toZipkinSpanModel(data *export.SpanSnapshot) zkmodel.SpanModel {
return zkmodel.SpanModel{
SpanContext: toZipkinSpanContext(data),
Name: data.Name,
Expand All @@ -48,7 +60,7 @@ func toZipkinSpanModel(data *export.SpanSnapshot, serviceName string) zkmodel.Sp
Duration: data.EndTime.Sub(data.StartTime),
Shared: false,
LocalEndpoint: &zkmodel.Endpoint{
ServiceName: serviceName,
ServiceName: getServiceName(data.Resource.Attributes()),
},
RemoteEndpoint: nil, // *Endpoint
Annotations: toZipkinAnnotations(data.MessageEvents),
Expand Down
29 changes: 28 additions & 1 deletion exporters/trace/zipkin/model_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,23 @@ import (

"github.com/google/go-cmp/cmp"
zkmodel "github.com/openzipkin/zipkin-go/model"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
export "go.opentelemetry.io/otel/sdk/export/trace"
"go.opentelemetry.io/otel/sdk/instrumentation"
"go.opentelemetry.io/otel/sdk/resource"
"go.opentelemetry.io/otel/semconv"
"go.opentelemetry.io/otel/trace"
)

func TestModelConversion(t *testing.T) {
resource := resource.NewWithAttributes(
semconv.ServiceNameKey.String("model-test"),
)

inputBatch := []*export.SpanSnapshot{
// typical span data
{
Expand Down Expand Up @@ -64,6 +71,7 @@ func TestModelConversion(t *testing.T) {
},
StatusCode: codes.Error,
StatusMessage: "404, file not found",
Resource: resource,
},
// span data with no parent (same as typical, but has
// invalid parent)
Expand Down Expand Up @@ -97,6 +105,7 @@ func TestModelConversion(t *testing.T) {
},
StatusCode: codes.Error,
StatusMessage: "404, file not found",
Resource: resource,
},
// span data of unspecified kind
{
Expand Down Expand Up @@ -129,6 +138,7 @@ func TestModelConversion(t *testing.T) {
},
StatusCode: codes.Error,
StatusMessage: "404, file not found",
Resource: resource,
},
// span data of internal kind
{
Expand Down Expand Up @@ -161,6 +171,7 @@ func TestModelConversion(t *testing.T) {
},
StatusCode: codes.Error,
StatusMessage: "404, file not found",
Resource: resource,
},
// span data of client kind
{
Expand Down Expand Up @@ -193,6 +204,7 @@ func TestModelConversion(t *testing.T) {
},
StatusCode: codes.Error,
StatusMessage: "404, file not found",
Resource: resource,
},
// span data of producer kind
{
Expand Down Expand Up @@ -225,6 +237,7 @@ func TestModelConversion(t *testing.T) {
},
StatusCode: codes.Error,
StatusMessage: "404, file not found",
Resource: resource,
},
// span data of consumer kind
{
Expand Down Expand Up @@ -257,6 +270,7 @@ func TestModelConversion(t *testing.T) {
},
StatusCode: codes.Error,
StatusMessage: "404, file not found",
Resource: resource,
},
// span data with no events
{
Expand All @@ -276,6 +290,7 @@ func TestModelConversion(t *testing.T) {
MessageEvents: nil,
StatusCode: codes.Error,
StatusMessage: "404, file not found",
Resource: resource,
},
// span data with an "error" attribute set to "false"
{
Expand Down Expand Up @@ -307,6 +322,7 @@ func TestModelConversion(t *testing.T) {
},
StatusCode: codes.Error,
StatusMessage: "404, file not found",
Resource: resource,
},
}

Expand Down Expand Up @@ -652,7 +668,7 @@ func TestModelConversion(t *testing.T) {
},
},
}
gottenOutputBatch := toZipkinSpanModels(inputBatch, "model-test")
gottenOutputBatch := toZipkinSpanModels(inputBatch)
require.Equal(t, expectedOutputBatch, gottenOutputBatch)
}

Expand Down Expand Up @@ -780,3 +796,14 @@ func Test_toZipkinTags(t *testing.T) {
})
}
}

func TestServiceName(t *testing.T) {
attrs := []attribute.KeyValue{}
assert.Empty(t, getServiceName(attrs))

attrs = append(attrs, attribute.String("test_key", "test_value"))
assert.Empty(t, getServiceName(attrs))

attrs = append(attrs, semconv.ServiceNameKey.String("my_service"))
assert.Equal(t, "my_service", getServiceName(attrs))
}
30 changes: 14 additions & 16 deletions exporters/trace/zipkin/zipkin.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,10 @@ import (
// the SpanBatcher interface, so it needs to be used together with the
// WithBatcher option when setting up the exporter pipeline.
type Exporter struct {
url string
serviceName string
client *http.Client
logger *log.Logger
o options
url string
client *http.Client
logger *log.Logger
o options

stoppedMu sync.RWMutex
stopped bool
Expand Down Expand Up @@ -82,7 +81,7 @@ func WithSDK(config *sdktrace.Config) Option {
}

// NewRawExporter creates a new Zipkin exporter.
func NewRawExporter(collectorURL, serviceName string, opts ...Option) (*Exporter, error) {
func NewRawExporter(collectorURL string, opts ...Option) (*Exporter, error) {
if collectorURL == "" {
return nil, errors.New("collector URL cannot be empty")
}
Expand All @@ -102,18 +101,17 @@ func NewRawExporter(collectorURL, serviceName string, opts ...Option) (*Exporter
o.client = http.DefaultClient
}
return &Exporter{
url: collectorURL,
client: o.client,
logger: o.logger,
serviceName: serviceName,
o: o,
url: collectorURL,
client: o.client,
logger: o.logger,
o: o,
}, nil
}

// NewExportPipeline sets up a complete export pipeline
// with the recommended setup for trace provider
func NewExportPipeline(collectorURL, serviceName string, opts ...Option) (*sdktrace.TracerProvider, error) {
exporter, err := NewRawExporter(collectorURL, serviceName, opts...)
func NewExportPipeline(collectorURL string, opts ...Option) (*sdktrace.TracerProvider, error) {
exporter, err := NewRawExporter(collectorURL, opts...)
if err != nil {
return nil, err
}
Expand All @@ -128,8 +126,8 @@ func NewExportPipeline(collectorURL, serviceName string, opts ...Option) (*sdktr

// InstallNewPipeline instantiates a NewExportPipeline with the
// recommended configuration and registers it globally.
func InstallNewPipeline(collectorURL, serviceName string, opts ...Option) error {
tp, err := NewExportPipeline(collectorURL, serviceName, opts...)
func InstallNewPipeline(collectorURL string, opts ...Option) error {
tp, err := NewExportPipeline(collectorURL, opts...)
if err != nil {
return err
}
Expand All @@ -152,7 +150,7 @@ func (e *Exporter) ExportSpans(ctx context.Context, ss []*export.SpanSnapshot) e
e.logf("no spans to export")
return nil
}
models := toZipkinSpanModels(ss, e.serviceName)
models := toZipkinSpanModels(ss)
body, err := json.Marshal(models)
if err != nil {
return e.errf("failed to serialize zipkin models to JSON: %v", err)
Expand Down
Loading