Skip to content

Commit

Permalink
Export resource attributes from zipkin exporter (#2589)
Browse files Browse the repository at this point in the history
* Export resource attributes from zipkin exporter

* Update CHANGELOG.md

Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>

* Refactoring

* Refactoring

Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
  • Loading branch information
tttanikawa and MrAlias authored Feb 9, 2022
1 parent 10b58d6 commit 9f42a81
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 19 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
### Changed

- Jaeger exporter takes into additional 70 bytes overhead into consideration when sending UDP packets (#2489, #2512)
- Zipkin exporter exports `Resource` attributes as the `Tags` field. (#2589)

### Deprecated

Expand Down
47 changes: 29 additions & 18 deletions exporters/zipkin/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,27 @@ func attributesToJSONMapString(attributes []attribute.KeyValue) string {
return (string)(jsonBytes)
}

// attributeToStringPair serializes each attribute to a string pair
func attributeToStringPair(kv attribute.KeyValue) (string, string) {
switch kv.Value.Type() {
// For slice attributes, serialize as JSON list string.
case attribute.BOOLSLICE:
json, _ := json.Marshal(kv.Value.AsBoolSlice())
return (string)(kv.Key), (string)(json)
case attribute.INT64SLICE:
json, _ := json.Marshal(kv.Value.AsInt64Slice())
return (string)(kv.Key), (string)(json)
case attribute.FLOAT64SLICE:
json, _ := json.Marshal(kv.Value.AsFloat64Slice())
return (string)(kv.Key), (string)(json)
case attribute.STRINGSLICE:
json, _ := json.Marshal(kv.Value.AsStringSlice())
return (string)(kv.Key), (string)(json)
default:
return (string)(kv.Key), kv.Value.Emit()
}
}

// extraZipkinTags are those that may be added to every outgoing span
var extraZipkinTags = []string{
"otel.status_code",
Expand All @@ -177,25 +198,15 @@ var extraZipkinTags = []string{

func toZipkinTags(data tracesdk.ReadOnlySpan) map[string]string {
attr := data.Attributes()
m := make(map[string]string, len(attr)+len(extraZipkinTags))
resourceAttr := data.Resource().Attributes()
m := make(map[string]string, len(attr)+len(resourceAttr)+len(extraZipkinTags))
for _, kv := range attr {
switch kv.Value.Type() {
// For slice attributes, serialize as JSON list string.
case attribute.BOOLSLICE:
json, _ := json.Marshal(kv.Value.AsBoolSlice())
m[(string)(kv.Key)] = (string)(json)
case attribute.INT64SLICE:
json, _ := json.Marshal(kv.Value.AsInt64Slice())
m[(string)(kv.Key)] = (string)(json)
case attribute.FLOAT64SLICE:
json, _ := json.Marshal(kv.Value.AsFloat64Slice())
m[(string)(kv.Key)] = (string)(json)
case attribute.STRINGSLICE:
json, _ := json.Marshal(kv.Value.AsStringSlice())
m[(string)(kv.Key)] = (string)(json)
default:
m[(string)(kv.Key)] = kv.Value.Emit()
}
k, v := attributeToStringPair(kv)
m[k] = v
}
for _, kv := range resourceAttr {
k, v := attributeToStringPair(kv)
m[k] = v
}

if data.Status().Code != codes.Unset {
Expand Down
42 changes: 41 additions & 1 deletion exporters/zipkin/model_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ import (
func TestModelConversion(t *testing.T) {
resource := resource.NewSchemaless(
semconv.ServiceNameKey.String("model-test"),
semconv.ServiceVersionKey.String("0.1.0"),
attribute.Int64("resource-attr1", 42),
attribute.IntSlice("resource-attr2", []int{0, 1, 2}),
)

inputBatch := tracetest.SpanStubs{
Expand Down Expand Up @@ -408,6 +411,10 @@ func TestModelConversion(t *testing.T) {
"attr3": "[0,1,2]",
"otel.status_code": "Error",
"error": "404, file not found",
"service.name": "model-test",
"service.version": "0.1.0",
"resource-attr1": "42",
"resource-attr2": "[0,1,2]",
},
},
// model for span data with no parent
Expand Down Expand Up @@ -447,6 +454,10 @@ func TestModelConversion(t *testing.T) {
"attr2": "bar",
"otel.status_code": "Error",
"error": "404, file not found",
"service.name": "model-test",
"service.version": "0.1.0",
"resource-attr1": "42",
"resource-attr2": "[0,1,2]",
},
},
// model for span data of unspecified kind
Expand Down Expand Up @@ -486,6 +497,10 @@ func TestModelConversion(t *testing.T) {
"attr2": "bar",
"otel.status_code": "Error",
"error": "404, file not found",
"service.name": "model-test",
"service.version": "0.1.0",
"resource-attr1": "42",
"resource-attr2": "[0,1,2]",
},
},
// model for span data of internal kind
Expand Down Expand Up @@ -525,6 +540,10 @@ func TestModelConversion(t *testing.T) {
"attr2": "bar",
"otel.status_code": "Error",
"error": "404, file not found",
"service.name": "model-test",
"service.version": "0.1.0",
"resource-attr1": "42",
"resource-attr2": "[0,1,2]",
},
},
// model for span data of client kind
Expand Down Expand Up @@ -570,6 +589,10 @@ func TestModelConversion(t *testing.T) {
"peer.hostname": "test-peer-hostname",
"otel.status_code": "Error",
"error": "404, file not found",
"service.name": "model-test",
"service.version": "0.1.0",
"resource-attr1": "42",
"resource-attr2": "[0,1,2]",
},
},
// model for span data of producer kind
Expand Down Expand Up @@ -609,6 +632,10 @@ func TestModelConversion(t *testing.T) {
"attr2": "bar",
"otel.status_code": "Error",
"error": "404, file not found",
"service.name": "model-test",
"service.version": "0.1.0",
"resource-attr1": "42",
"resource-attr2": "[0,1,2]",
},
},
// model for span data of consumer kind
Expand Down Expand Up @@ -648,6 +675,10 @@ func TestModelConversion(t *testing.T) {
"attr2": "bar",
"otel.status_code": "Error",
"error": "404, file not found",
"service.name": "model-test",
"service.version": "0.1.0",
"resource-attr1": "42",
"resource-attr2": "[0,1,2]",
},
},
// model for span data with no events
Expand Down Expand Up @@ -678,6 +709,10 @@ func TestModelConversion(t *testing.T) {
"attr2": "bar",
"otel.status_code": "Error",
"error": "404, file not found",
"service.name": "model-test",
"service.version": "0.1.0",
"resource-attr1": "42",
"resource-attr2": "[0,1,2]",
},
},
// model for span data with an "error" attribute set to "false"
Expand Down Expand Up @@ -712,7 +747,12 @@ func TestModelConversion(t *testing.T) {
Value: "ev2",
},
},
Tags: nil, // should be omitted
Tags: map[string]string{
"service.name": "model-test",
"service.version": "0.1.0",
"resource-attr1": "42",
"resource-attr2": "[0,1,2]",
}, // only resource tags should be included
},
}
gottenOutputBatch := SpanModels(inputBatch)
Expand Down
5 changes: 5 additions & 0 deletions exporters/zipkin/zipkin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ func logStoreLogger(s *logStore) *log.Logger {
func TestExportSpans(t *testing.T) {
resource := resource.NewSchemaless(
semconv.ServiceNameKey.String("exporter-test"),
semconv.ServiceVersionKey.String("0.1.0"),
)

spans := tracetest.SpanStubs{
Expand Down Expand Up @@ -271,6 +272,8 @@ func TestExportSpans(t *testing.T) {
Tags: map[string]string{
"otel.status_code": "Error",
"error": "404, file not found",
"service.name": "exporter-test",
"service.version": "0.1.0",
},
},
// model of child
Expand Down Expand Up @@ -299,6 +302,8 @@ func TestExportSpans(t *testing.T) {
Tags: map[string]string{
"otel.status_code": "Error",
"error": "403, forbidden",
"service.name": "exporter-test",
"service.version": "0.1.0",
},
},
}
Expand Down

0 comments on commit 9f42a81

Please sign in to comment.