Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix wrong representation of status value in zipkin exporter #3340

Merged
merged 9 commits into from Oct 28, 2022
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -22,6 +22,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Slice attributes of `attribute` package are now comparable based on their value, not instance. (#3108 #3252)
- Prometheus exporter will now cumulatively sum histogram buckets. (#3281)
- Export the sum of each histogram datapoint uniquely with the `go.opentelemetry.io/otel/exporters/otlpmetric` exporters. (#3284, #3293)
- Exported `Status` codes in `zipkin` exporter are now upper case. (#3340)
MrAlias marked this conversation as resolved.
Show resolved Hide resolved

## [1.11.0/0.32.3] 2022-10-12

Expand Down
5 changes: 4 additions & 1 deletion exporters/zipkin/model.go
Expand Up @@ -20,6 +20,7 @@ import (
"fmt"
"net"
"strconv"
"strings"

zkmodel "github.com/openzipkin/zipkin-go/model"

Expand Down Expand Up @@ -209,7 +210,9 @@ func toZipkinTags(data tracesdk.ReadOnlySpan) map[string]string {
}

if data.Status().Code != codes.Unset {
m["otel.status_code"] = data.Status().Code.String()
// zipkin expect to receive upper case STATUS values
NewReStarter marked this conversation as resolved.
Show resolved Hide resolved
// rather than default capitalized ones.
m["otel.status_code"] = strings.ToUpper(data.Status().Code.String())
}

if data.Status().Code == codes.Error {
Expand Down
221 changes: 209 additions & 12 deletions exporters/zipkin/model_test.go
Expand Up @@ -18,6 +18,7 @@ import (
"fmt"
"net"
"strconv"
"strings"
"testing"
"time"

Expand Down Expand Up @@ -45,7 +46,85 @@ func TestModelConversion(t *testing.T) {
)

inputBatch := tracetest.SpanStubs{
// typical span data
// typical span data with UNSET status
{
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
TraceID: trace.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F},
SpanID: trace.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8},
}),
Parent: trace.NewSpanContext(trace.SpanContextConfig{
TraceID: trace.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F},
SpanID: trace.SpanID{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38},
}),
SpanKind: trace.SpanKindServer,
Name: "foo",
StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC),
EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC),
Attributes: []attribute.KeyValue{
attribute.Int64("attr1", 42),
attribute.String("attr2", "bar"),
attribute.IntSlice("attr3", []int{0, 1, 2}),
},
Events: []tracesdk.Event{
{
Time: time.Date(2020, time.March, 11, 19, 24, 30, 0, time.UTC),
Name: "ev1",
Attributes: []attribute.KeyValue{
attribute.Int64("eventattr1", 123),
},
},
{
Time: time.Date(2020, time.March, 11, 19, 24, 45, 0, time.UTC),
Name: "ev2",
Attributes: nil,
},
},
Status: tracesdk.Status{
Code: codes.Unset,
Description: "",
},
Resource: res,
},
// typical span data with OK status
{
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
TraceID: trace.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F},
SpanID: trace.SpanID{0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF8},
}),
Parent: trace.NewSpanContext(trace.SpanContextConfig{
TraceID: trace.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F},
SpanID: trace.SpanID{0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 0x38},
}),
SpanKind: trace.SpanKindServer,
Name: "foo",
StartTime: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC),
EndTime: time.Date(2020, time.March, 11, 19, 25, 0, 0, time.UTC),
Attributes: []attribute.KeyValue{
attribute.Int64("attr1", 42),
attribute.String("attr2", "bar"),
attribute.IntSlice("attr3", []int{0, 1, 2}),
},
Events: []tracesdk.Event{
{
Time: time.Date(2020, time.March, 11, 19, 24, 30, 0, time.UTC),
Name: "ev1",
Attributes: []attribute.KeyValue{
attribute.Int64("eventattr1", 123),
},
},
{
Time: time.Date(2020, time.March, 11, 19, 24, 45, 0, time.UTC),
Name: "ev2",
Attributes: nil,
},
},
Status: tracesdk.Status{
Code: codes.Ok,
Description: "",
},
Resource: res,
},
// typical span data with ERROR status
{
SpanContext: trace.NewSpanContext(trace.SpanContextConfig{
TraceID: trace.TraceID{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F},
Expand Down Expand Up @@ -373,7 +452,49 @@ func TestModelConversion(t *testing.T) {
}.Snapshots()

expectedOutputBatch := []zkmodel.SpanModel{
// model for typical span data
// model for typical span data with UNSET status
{
SpanContext: zkmodel.SpanContext{
TraceID: zkmodel.TraceID{
High: 0x001020304050607,
Low: 0x8090a0b0c0d0e0f,
},
ID: zkmodel.ID(0xfffefdfcfbfaf9f8),
ParentID: zkmodelIDPtr(0x3f3e3d3c3b3a3938),
Debug: false,
Sampled: nil,
Err: nil,
},
Name: "foo",
Kind: "SERVER",
Timestamp: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC),
Duration: time.Minute,
Shared: false,
LocalEndpoint: &zkmodel.Endpoint{
ServiceName: "model-test",
},
RemoteEndpoint: nil,
Annotations: []zkmodel.Annotation{
{
Timestamp: time.Date(2020, time.March, 11, 19, 24, 30, 0, time.UTC),
Value: `ev1: {"eventattr1":123}`,
},
{
Timestamp: time.Date(2020, time.March, 11, 19, 24, 45, 0, time.UTC),
Value: "ev2",
},
},
Tags: map[string]string{
"attr1": "42",
"attr2": "bar",
"attr3": "[0,1,2]",
"service.name": "model-test",
"service.version": "0.1.0",
"resource-attr1": "42",
"resource-attr2": "[0,1,2]",
},
},
// model for typical span data with OK status
{
SpanContext: zkmodel.SpanContext{
TraceID: zkmodel.TraceID{
Expand Down Expand Up @@ -409,7 +530,50 @@ func TestModelConversion(t *testing.T) {
"attr1": "42",
"attr2": "bar",
"attr3": "[0,1,2]",
"otel.status_code": "Error",
"otel.status_code": "OK",
"service.name": "model-test",
"service.version": "0.1.0",
"resource-attr1": "42",
"resource-attr2": "[0,1,2]",
},
},
// model for typical span data with ERROR status
{
SpanContext: zkmodel.SpanContext{
TraceID: zkmodel.TraceID{
High: 0x001020304050607,
Low: 0x8090a0b0c0d0e0f,
},
ID: zkmodel.ID(0xfffefdfcfbfaf9f8),
ParentID: zkmodelIDPtr(0x3f3e3d3c3b3a3938),
Debug: false,
Sampled: nil,
Err: nil,
},
Name: "foo",
Kind: "SERVER",
Timestamp: time.Date(2020, time.March, 11, 19, 24, 0, 0, time.UTC),
Duration: time.Minute,
Shared: false,
LocalEndpoint: &zkmodel.Endpoint{
ServiceName: "model-test",
},
RemoteEndpoint: nil,
Annotations: []zkmodel.Annotation{
{
Timestamp: time.Date(2020, time.March, 11, 19, 24, 30, 0, time.UTC),
Value: `ev1: {"eventattr1":123}`,
},
{
Timestamp: time.Date(2020, time.March, 11, 19, 24, 45, 0, time.UTC),
Value: "ev2",
},
},
Tags: map[string]string{
"attr1": "42",
"attr2": "bar",
"attr3": "[0,1,2]",
"otel.status_code": "ERROR",
MrAlias marked this conversation as resolved.
Show resolved Hide resolved
"error": "404, file not found",
"service.name": "model-test",
"service.version": "0.1.0",
Expand Down Expand Up @@ -452,7 +616,7 @@ func TestModelConversion(t *testing.T) {
Tags: map[string]string{
"attr1": "42",
"attr2": "bar",
"otel.status_code": "Error",
"otel.status_code": "ERROR",
"error": "404, file not found",
"service.name": "model-test",
"service.version": "0.1.0",
Expand Down Expand Up @@ -495,7 +659,7 @@ func TestModelConversion(t *testing.T) {
Tags: map[string]string{
"attr1": "42",
"attr2": "bar",
"otel.status_code": "Error",
"otel.status_code": "ERROR",
"error": "404, file not found",
"service.name": "model-test",
"service.version": "0.1.0",
Expand Down Expand Up @@ -538,7 +702,7 @@ func TestModelConversion(t *testing.T) {
Tags: map[string]string{
"attr1": "42",
"attr2": "bar",
"otel.status_code": "Error",
"otel.status_code": "ERROR",
"error": "404, file not found",
"service.name": "model-test",
"service.version": "0.1.0",
Expand Down Expand Up @@ -587,7 +751,7 @@ func TestModelConversion(t *testing.T) {
"net.peer.ip": "1.2.3.4",
"net.peer.port": "9876",
"peer.hostname": "test-peer-hostname",
"otel.status_code": "Error",
"otel.status_code": "ERROR",
"error": "404, file not found",
"service.name": "model-test",
"service.version": "0.1.0",
Expand Down Expand Up @@ -630,7 +794,7 @@ func TestModelConversion(t *testing.T) {
Tags: map[string]string{
"attr1": "42",
"attr2": "bar",
"otel.status_code": "Error",
"otel.status_code": "ERROR",
"error": "404, file not found",
"service.name": "model-test",
"service.version": "0.1.0",
Expand Down Expand Up @@ -673,7 +837,7 @@ func TestModelConversion(t *testing.T) {
Tags: map[string]string{
"attr1": "42",
"attr2": "bar",
"otel.status_code": "Error",
"otel.status_code": "ERROR",
"error": "404, file not found",
"service.name": "model-test",
"service.version": "0.1.0",
Expand Down Expand Up @@ -707,7 +871,7 @@ func TestModelConversion(t *testing.T) {
Tags: map[string]string{
"attr1": "42",
"attr2": "bar",
"otel.status_code": "Error",
"otel.status_code": "ERROR",
"error": "404, file not found",
"service.name": "model-test",
"service.version": "0.1.0",
Expand Down Expand Up @@ -809,7 +973,40 @@ func TestTagsTransformation(t *testing.T) {
want: nil,
},
{
name: "statusCode",
name: "statusCode UNSET",
data: tracetest.SpanStub{
Attributes: []attribute.KeyValue{
attribute.String("key", keyValue),
},
Status: tracesdk.Status{
Code: codes.Unset,
Description: "",
},
},
want: map[string]string{
"key": keyValue,
},
},
{
name: "statusCode OK",
data: tracetest.SpanStub{
Attributes: []attribute.KeyValue{
attribute.String("key", keyValue),
attribute.Bool("ok", true),
},
Status: tracesdk.Status{
Code: codes.Ok,
Description: "",
},
},
want: map[string]string{
"key": keyValue,
"ok": "true",
"otel.status_code": strings.ToUpper(codes.Ok.String()),
MrAlias marked this conversation as resolved.
Show resolved Hide resolved
},
},
{
name: "statusCode ERROR",
data: tracetest.SpanStub{
Attributes: []attribute.KeyValue{
attribute.String("key", keyValue),
Expand All @@ -823,7 +1020,7 @@ func TestTagsTransformation(t *testing.T) {
want: map[string]string{
"error": statusMessage,
"key": keyValue,
"otel.status_code": codes.Error.String(),
"otel.status_code": strings.ToUpper(codes.Error.String()),
MrAlias marked this conversation as resolved.
Show resolved Hide resolved
},
},
{
Expand Down
4 changes: 2 additions & 2 deletions exporters/zipkin/zipkin_test.go
Expand Up @@ -270,7 +270,7 @@ func TestExportSpans(t *testing.T) {
RemoteEndpoint: nil,
Annotations: nil,
Tags: map[string]string{
"otel.status_code": "Error",
"otel.status_code": "ERROR",
"error": "404, file not found",
"service.name": "exporter-test",
"service.version": "0.1.0",
Expand Down Expand Up @@ -300,7 +300,7 @@ func TestExportSpans(t *testing.T) {
RemoteEndpoint: nil,
Annotations: nil,
Tags: map[string]string{
"otel.status_code": "Error",
"otel.status_code": "ERROR",
"error": "403, forbidden",
"service.name": "exporter-test",
"service.version": "0.1.0",
Expand Down