Skip to content

Commit 7daa0a6

Browse files
committed
Use Zipkin annotations if the timestamp is zero
1 parent f445c1d commit 7daa0a6

File tree

2 files changed

+52
-3
lines changed

2 files changed

+52
-3
lines changed

model/converter/thrift/zipkin/to_domain.go

+30-3
Original file line numberDiff line numberDiff line change
@@ -136,15 +136,17 @@ func (td toDomain) transformSpan(zSpan *zipkincore.Span) []*model.Span {
136136
}
137137

138138
flags := td.getFlags(zSpan)
139-
// TODO StartTime and Duration could theoretically be defined only via cs/cr/sr/ss annotations.
139+
140+
startTime, duration := td.getStartTimeAndDuration(zSpan)
141+
140142
result := []*model.Span{{
141143
TraceID: traceID,
142144
SpanID: model.NewSpanID(uint64(zSpan.ID)),
143145
OperationName: zSpan.Name,
144146
References: refs,
145147
Flags: flags,
146-
StartTime: model.EpochMicrosecondsAsTime(uint64(zSpan.GetTimestamp())),
147-
Duration: model.MicrosecondsAsDuration(uint64(zSpan.GetDuration())),
148+
StartTime: model.EpochMicrosecondsAsTime(uint64(startTime)),
149+
Duration: model.MicrosecondsAsDuration(uint64(duration)),
148150
Tags: tags,
149151
Logs: td.getLogs(zSpan.Annotations),
150152
}}
@@ -188,6 +190,31 @@ func (td toDomain) getFlags(zSpan *zipkincore.Span) model.Flags {
188190
return f
189191
}
190192

193+
// Get a correct start time to use for the span if it's not set directly
194+
func (td toDomain) getStartTimeAndDuration(zSpan *zipkincore.Span) (int64, int64) {
195+
timestamp := zSpan.GetTimestamp()
196+
duration := zSpan.GetDuration()
197+
if timestamp == 0 {
198+
cs := td.findAnnotation(zSpan, zipkincore.CLIENT_SEND)
199+
sr := td.findAnnotation(zSpan, zipkincore.SERVER_RECV)
200+
if cs != nil {
201+
timestamp = cs.Timestamp
202+
cr := td.findAnnotation(zSpan, zipkincore.CLIENT_RECV)
203+
if cr != nil {
204+
duration = cr.Timestamp - cs.Timestamp
205+
}
206+
} else if sr != nil {
207+
timestamp = sr.Timestamp
208+
ss := td.findAnnotation(zSpan, zipkincore.SERVER_SEND)
209+
if ss != nil {
210+
duration = ss.Timestamp - sr.Timestamp
211+
}
212+
}
213+
}
214+
return timestamp, duration
215+
}
216+
217+
191218
// generateProcess takes a Zipkin Span and produces a model.Process.
192219
// An optional error may also be returned, but it is not fatal.
193220
func (td toDomain) generateProcess(zSpan *zipkincore.Span) (*model.Process, error) {

model/converter/thrift/zipkin/to_domain_test.go

+22
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,28 @@ func TestToDomainServiceNameInBinAnnotation(t *testing.T) {
9191
assert.Equal(t, "bar", trace.Spans[0].Process.ServiceName)
9292
}
9393

94+
func TestToDomainWithDurationFromServerAnnotations(t *testing.T) {
95+
zSpans := getZipkinSpans(t, `[{ "trace_id": -1, "id": 31, "annotations": [
96+
{"value": "sr", "timestamp": 1, "host": {"service_name": "bar", "ipv4": 23456}},
97+
{"value": "ss", "timestamp": 10, "host": {"service_name": "bar", "ipv4": 23456}}
98+
]}]`)
99+
trace, err := ToDomain(zSpans)
100+
require.Nil(t, err)
101+
assert.Equal(t, 1000, int(trace.Spans[0].StartTime.Nanosecond()))
102+
assert.Equal(t, 9000, int(trace.Spans[0].Duration))
103+
}
104+
105+
func TestToDomainWithDurationFromClientAnnotations(t *testing.T) {
106+
zSpans := getZipkinSpans(t, `[{ "trace_id": -1, "id": 31, "annotations": [
107+
{"value": "cs", "timestamp": 1, "host": {"service_name": "bar", "ipv4": 23456}},
108+
{"value": "cr", "timestamp": 10, "host": {"service_name": "bar", "ipv4": 23456}}
109+
]}]`)
110+
trace, err := ToDomain(zSpans)
111+
require.Nil(t, err)
112+
assert.Equal(t, 1000, int(trace.Spans[0].StartTime.Nanosecond()))
113+
assert.Equal(t, 9000, int(trace.Spans[0].Duration))
114+
}
115+
94116
func TestToDomainMultipleSpanKinds(t *testing.T) {
95117
tests := []struct {
96118
json string

0 commit comments

Comments
 (0)