blob: 3ac2f8f949c86a1cb7b8fb214e62cf9045d07079 [file] [log] [blame]
Takahiro Suzuki241c10e2020-12-17 20:17:57 +09001// Copyright (c) 2017 Uber Technologies, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package jaeger
16
17import (
18 "time"
19
20 "github.com/opentracing/opentracing-go"
21
22 j "github.com/uber/jaeger-client-go/thrift-gen/jaeger"
23 "github.com/uber/jaeger-client-go/utils"
24)
25
26// BuildJaegerThrift builds jaeger span based on internal span.
27// TODO: (breaking change) move to internal package.
28func BuildJaegerThrift(span *Span) *j.Span {
29 span.Lock()
30 defer span.Unlock()
31 startTime := utils.TimeToMicrosecondsSinceEpochInt64(span.startTime)
32 duration := span.duration.Nanoseconds() / int64(time.Microsecond)
33 jaegerSpan := &j.Span{
34 TraceIdLow: int64(span.context.traceID.Low),
35 TraceIdHigh: int64(span.context.traceID.High),
36 SpanId: int64(span.context.spanID),
37 ParentSpanId: int64(span.context.parentID),
38 OperationName: span.operationName,
39 Flags: int32(span.context.samplingState.flags()),
40 StartTime: startTime,
41 Duration: duration,
42 Tags: buildTags(span.tags, span.tracer.options.maxTagValueLength),
43 Logs: buildLogs(span.logs),
44 References: buildReferences(span.references),
45 }
46 return jaegerSpan
47}
48
49// BuildJaegerProcessThrift creates a thrift Process type.
50// TODO: (breaking change) move to internal package.
51func BuildJaegerProcessThrift(span *Span) *j.Process {
52 span.Lock()
53 defer span.Unlock()
54 return buildJaegerProcessThrift(span.tracer)
55}
56
57func buildJaegerProcessThrift(tracer *Tracer) *j.Process {
58 process := &j.Process{
59 ServiceName: tracer.serviceName,
60 Tags: buildTags(tracer.tags, tracer.options.maxTagValueLength),
61 }
62 if tracer.process.UUID != "" {
63 process.Tags = append(process.Tags, &j.Tag{Key: TracerUUIDTagKey, VStr: &tracer.process.UUID, VType: j.TagType_STRING})
64 }
65 return process
66}
67
68func buildTags(tags []Tag, maxTagValueLength int) []*j.Tag {
69 jTags := make([]*j.Tag, 0, len(tags))
70 for _, tag := range tags {
71 jTag := buildTag(&tag, maxTagValueLength)
72 jTags = append(jTags, jTag)
73 }
74 return jTags
75}
76
77func buildLogs(logs []opentracing.LogRecord) []*j.Log {
78 jLogs := make([]*j.Log, 0, len(logs))
79 for _, log := range logs {
80 jLog := &j.Log{
81 Timestamp: utils.TimeToMicrosecondsSinceEpochInt64(log.Timestamp),
82 Fields: ConvertLogsToJaegerTags(log.Fields),
83 }
84 jLogs = append(jLogs, jLog)
85 }
86 return jLogs
87}
88
89func buildTag(tag *Tag, maxTagValueLength int) *j.Tag {
90 jTag := &j.Tag{Key: tag.key}
91 switch value := tag.value.(type) {
92 case string:
93 vStr := truncateString(value, maxTagValueLength)
94 jTag.VStr = &vStr
95 jTag.VType = j.TagType_STRING
96 case []byte:
97 if len(value) > maxTagValueLength {
98 value = value[:maxTagValueLength]
99 }
100 jTag.VBinary = value
101 jTag.VType = j.TagType_BINARY
102 case int:
103 vLong := int64(value)
104 jTag.VLong = &vLong
105 jTag.VType = j.TagType_LONG
106 case uint:
107 vLong := int64(value)
108 jTag.VLong = &vLong
109 jTag.VType = j.TagType_LONG
110 case int8:
111 vLong := int64(value)
112 jTag.VLong = &vLong
113 jTag.VType = j.TagType_LONG
114 case uint8:
115 vLong := int64(value)
116 jTag.VLong = &vLong
117 jTag.VType = j.TagType_LONG
118 case int16:
119 vLong := int64(value)
120 jTag.VLong = &vLong
121 jTag.VType = j.TagType_LONG
122 case uint16:
123 vLong := int64(value)
124 jTag.VLong = &vLong
125 jTag.VType = j.TagType_LONG
126 case int32:
127 vLong := int64(value)
128 jTag.VLong = &vLong
129 jTag.VType = j.TagType_LONG
130 case uint32:
131 vLong := int64(value)
132 jTag.VLong = &vLong
133 jTag.VType = j.TagType_LONG
134 case int64:
135 vLong := int64(value)
136 jTag.VLong = &vLong
137 jTag.VType = j.TagType_LONG
138 case uint64:
139 vLong := int64(value)
140 jTag.VLong = &vLong
141 jTag.VType = j.TagType_LONG
142 case float32:
143 vDouble := float64(value)
144 jTag.VDouble = &vDouble
145 jTag.VType = j.TagType_DOUBLE
146 case float64:
147 vDouble := float64(value)
148 jTag.VDouble = &vDouble
149 jTag.VType = j.TagType_DOUBLE
150 case bool:
151 vBool := value
152 jTag.VBool = &vBool
153 jTag.VType = j.TagType_BOOL
154 default:
155 vStr := truncateString(stringify(value), maxTagValueLength)
156 jTag.VStr = &vStr
157 jTag.VType = j.TagType_STRING
158 }
159 return jTag
160}
161
162func buildReferences(references []Reference) []*j.SpanRef {
163 retMe := make([]*j.SpanRef, 0, len(references))
164 for _, ref := range references {
165 if ref.Type == opentracing.ChildOfRef {
166 retMe = append(retMe, spanRef(ref.Context, j.SpanRefType_CHILD_OF))
167 } else if ref.Type == opentracing.FollowsFromRef {
168 retMe = append(retMe, spanRef(ref.Context, j.SpanRefType_FOLLOWS_FROM))
169 }
170 }
171 return retMe
172}
173
174func spanRef(ctx SpanContext, refType j.SpanRefType) *j.SpanRef {
175 return &j.SpanRef{
176 RefType: refType,
177 TraceIdLow: int64(ctx.traceID.Low),
178 TraceIdHigh: int64(ctx.traceID.High),
179 SpanId: int64(ctx.spanID),
180 }
181}