Skip to content
This repository was archived by the owner on Nov 7, 2022. It is now read-only.

Commit 667502b

Browse files
author
Paulo Janotti
authored
ZipkinV1 JSON Receiver: handle LOCAL_COMPONENT binary annotation (#373)
The LOCAL_COMPONENT key is used to express the "component or namespace of a local span" in Zipkin V1. This should be used as a fallback if other information is not available. Opportunistically adding equivalent test to Zipkin V1 Thrift that already handles LOCAL_COMPONENT.
1 parent 1c603aa commit 667502b

5 files changed

Lines changed: 102 additions & 6 deletions

File tree

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[
2+
{
3+
"traceId": "0ed2e63cbe71f5a8",
4+
"name": "checkStock",
5+
"id": "fe351a053fbcac1f",
6+
"parentId": "0ed2e63cbe71f5a8",
7+
"timestamp": 1544805927453923,
8+
"duration": 3740,
9+
"annotations": [],
10+
"binaryAnnotations": [
11+
{
12+
"key": "lc",
13+
"value": "myLocalComponent"
14+
}
15+
]
16+
}
17+
]
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[
2+
{
3+
"trace_id": 1068169210207794600,
4+
"name": "checkStock",
5+
"id": -129168404463703009,
6+
"parent_id": 1068169210207794600,
7+
"timestamp": 1544805927453923,
8+
"duration": 3740,
9+
"annotations": [],
10+
"binary_annotations": [
11+
{
12+
"key": "lc",
13+
"annotation_type": "STRING",
14+
"value": "bXlMb2NhbENvbXBvbmVudA=="
15+
}
16+
]
17+
}
18+
]

translator/trace/zipkinv1_thrift_to_protospan_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,29 @@ import (
2323
"github.com/jaegertracing/jaeger/thrift-gen/zipkincore"
2424
)
2525

26+
func TestZipkinThriftFallbackToLocalComponent(t *testing.T) {
27+
blob, err := ioutil.ReadFile("./testdata/zipkin_v1_thrift_local_component.json")
28+
if err != nil {
29+
t.Fatalf("failed to load test data: %v", err)
30+
}
31+
var ztSpans []*zipkincore.Span
32+
err = json.Unmarshal(blob, &ztSpans)
33+
if err != nil {
34+
t.Fatalf("failed to unmarshal json into zipkin v1 thrift: %v", err)
35+
}
36+
37+
reqs, err := ZipkinV1ThriftBatchToOCProto(ztSpans)
38+
if err != nil {
39+
t.Fatalf("failed to translate zipkinv1 thrift to OC proto: %v", err)
40+
}
41+
42+
got := reqs[0].Node.ServiceInfo.Name
43+
const want = "myLocalComponent"
44+
if got != want {
45+
t.Fatalf("got %q for service name, want %q", got, want)
46+
}
47+
}
48+
2649
func TestZipkinV1ThriftToOCProto(t *testing.T) {
2750
blob, err := ioutil.ReadFile("./testdata/zipkin_v1_thrift_single_batch.json")
2851
if err != nil {

translator/trace/zipkinv1_to_protospan.go

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
agenttracepb "github.com/census-instrumentation/opencensus-proto/gen-go/agent/trace/v1"
2626
tracepb "github.com/census-instrumentation/opencensus-proto/gen-go/trace/v1"
2727
"github.com/golang/protobuf/ptypes/timestamp"
28+
"github.com/jaegertracing/jaeger/thrift-gen/zipkincore"
2829
"github.com/pkg/errors"
2930
)
3031

@@ -143,7 +144,10 @@ func zipkinV1ToOCSpan(zSpan *zipkinV1Span) (*tracepb.Span, *annotationParseResul
143144
}
144145

145146
parsedAnnotations := parseZipkinV1Annotations(zSpan.Annotations)
146-
attributes := zipkinV1BinAnnotationsToOCAttributes(zSpan.BinaryAnnotations)
147+
attributes, localComponent := zipkinV1BinAnnotationsToOCAttributes(zSpan.BinaryAnnotations)
148+
if parsedAnnotations.Endpoint.ServiceName == unknownServiceName && localComponent != "" {
149+
parsedAnnotations.Endpoint.ServiceName = localComponent
150+
}
147151
var startTime, endTime *timestamp.Timestamp
148152
if zSpan.Timestamp == 0 {
149153
startTime = parsedAnnotations.EarlyAnnotationTime
@@ -171,13 +175,17 @@ func zipkinV1ToOCSpan(zSpan *zipkinV1Span) (*tracepb.Span, *annotationParseResul
171175
return ocSpan, parsedAnnotations, nil
172176
}
173177

174-
func zipkinV1BinAnnotationsToOCAttributes(binAnnotations []*binaryAnnotation) *tracepb.Span_Attributes {
178+
func zipkinV1BinAnnotationsToOCAttributes(binAnnotations []*binaryAnnotation) (attributes *tracepb.Span_Attributes, localComponent string) {
175179
if len(binAnnotations) == 0 {
176-
return nil
180+
return nil, ""
177181
}
178182

183+
var fallbackServiceName string
179184
attributeMap := make(map[string]*tracepb.AttributeValue)
180185
for _, binAnnotation := range binAnnotations {
186+
if binAnnotation.Endpoint != nil && binAnnotation.Endpoint.ServiceName != "" {
187+
fallbackServiceName = binAnnotation.Endpoint.ServiceName
188+
}
181189
pbAttrib := &tracepb.AttributeValue{}
182190
if iValue, err := strconv.ParseInt(binAnnotation.Value, 10, 64); err == nil {
183191
pbAttrib.Value = &tracepb.AttributeValue_IntValue{IntValue: iValue}
@@ -187,16 +195,29 @@ func zipkinV1BinAnnotationsToOCAttributes(binAnnotations []*binaryAnnotation) *t
187195
// For now all else go to string
188196
pbAttrib.Value = &tracepb.AttributeValue_StringValue{StringValue: &tracepb.TruncatableString{Value: binAnnotation.Value}}
189197
}
190-
attributeMap[binAnnotation.Key] = pbAttrib
198+
199+
key := binAnnotation.Key
200+
if key == zipkincore.LOCAL_COMPONENT {
201+
// TODO: (@pjanotti) add reference to OpenTracing and change related tags to use them
202+
key = "component"
203+
localComponent = binAnnotation.Value
204+
}
205+
attributeMap[key] = pbAttrib
191206
}
192207

193208
if len(attributeMap) == 0 {
194-
return nil
209+
return nil, ""
210+
}
211+
212+
if localComponent == "" && fallbackServiceName != "" {
213+
localComponent = fallbackServiceName
195214
}
196215

197-
return &tracepb.Span_Attributes{
216+
attributes = &tracepb.Span_Attributes{
198217
AttributeMap: attributeMap,
199218
}
219+
220+
return attributes, localComponent
200221
}
201222

202223
// annotationParseResult stores the results of examining the original annotations,

translator/trace/zipkinv1_to_protospan_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,23 @@ func Test_hexTraceIDToOCTraceID(t *testing.T) {
131131
}
132132
}
133133

134+
func TestZipkinJSONFallbackToLocalComponent(t *testing.T) {
135+
blob, err := ioutil.ReadFile("./testdata/zipkin_v1_local_component.json")
136+
if err != nil {
137+
t.Fatalf("failed to load test data: %v", err)
138+
}
139+
reqs, err := ZipkinV1JSONBatchToOCProto(blob)
140+
if err != nil {
141+
t.Fatalf("failed to translate zipkinv1 to OC proto: %v", err)
142+
}
143+
144+
got := reqs[0].Node.ServiceInfo.Name
145+
const want = "myLocalComponent"
146+
if got != want {
147+
t.Fatalf("got %q for service name, want %q", got, want)
148+
}
149+
}
150+
134151
func TestSingleJSONZipkinV1BatchToOCProto(t *testing.T) {
135152
blob, err := ioutil.ReadFile("./testdata/zipkin_v1_single_batch.json")
136153
if err != nil {

0 commit comments

Comments
 (0)