-
Notifications
You must be signed in to change notification settings - Fork 55
/
AttributesExtractor.java
114 lines (98 loc) · 3.95 KB
/
AttributesExtractor.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
* Copyright The OpenZipkin Authors
* SPDX-License-Identifier: Apache-2.0
*/
package zipkin2.translation.stackdriver;
import com.google.devtools.cloudtrace.v2.AttributeValue;
import com.google.devtools.cloudtrace.v2.Span.Attributes;
import java.util.Map;
import zipkin2.Span;
import static zipkin2.translation.stackdriver.SpanUtil.toTruncatableString;
/**
* LabelExtractor extracts the set of Stackdriver Span labels equivalent to the annotations in a
* given Zipkin Span.
*
* <p>Zipkin annotations are converted to Stackdriver Span labels by using annotation.value as the
* key and annotation.timestamp as the value.
*
* <p>Zipkin tags are converted to Stackdriver Span labels by using annotation.key as the key and
* the String value of annotation.value as the value.
*
* <p>Zipkin annotations with equivalent Stackdriver labels will be renamed to the Stackdriver
* Trace
* name. Any Zipkin annotations without a Stackdriver label equivalent are renamed to
* zipkin.io/[key_name]
*/
final class AttributesExtractor {
private static final String kAgentLabelKey = "/agent";
private static final String kComponentLabelKey = "/component";
private static final String kKindLabelKey = "/kind";
private final Map<String, String> renamedLabels;
AttributesExtractor(Map<String, String> renamedLabels) {
this.renamedLabels = renamedLabels;
}
/**
* Extracts the Stackdriver span labels that are equivalent to the Zipkin Span tags.
*
* @param zipkinSpan The Zipkin Span
* @return {@link Attributes} with the Stackdriver span labels equivalent to the Zipkin tags.
*/
Attributes extract(Span zipkinSpan) {
Attributes.Builder attributes = Attributes.newBuilder();
// Add Kind as a tag for now since there is no structured way of sending it with Stackdriver
// Trace API V2
if (zipkinSpan.kind() != null) {
attributes.putAttributeMap(kKindLabelKey, toAttributeValue(kindLabel(zipkinSpan.kind())));
}
for (Map.Entry<String, String> tag : zipkinSpan.tags().entrySet()) {
attributes.putAttributeMap(getLabelName(tag.getKey()), toAttributeValue(tag.getValue()));
}
// Only use server receive spans to extract endpoint data as spans
// will be rewritten into multiple single-host Stackdriver spans. A client send
// trace might not show the final destination.
if (zipkinSpan.localEndpoint() != null && zipkinSpan.kind() == Span.Kind.SERVER) {
if (zipkinSpan.localEndpoint().ipv4() != null) {
attributes.putAttributeMap(
getLabelName("endpoint.ipv4"), toAttributeValue(zipkinSpan.localEndpoint().ipv4()));
}
if (zipkinSpan.localEndpoint().ipv6() != null) {
attributes.putAttributeMap(
getLabelName("endpoint.ipv6"), toAttributeValue(zipkinSpan.localEndpoint().ipv6()));
}
}
if (zipkinSpan.localEndpoint() != null &&
zipkinSpan.localEndpoint().serviceName() != null &&
!zipkinSpan.localEndpoint().serviceName().isEmpty()) {
attributes.putAttributeMap(
kComponentLabelKey, toAttributeValue(zipkinSpan.localEndpoint().serviceName()));
}
if (zipkinSpan.parentId() == null) {
String agentName = System.getProperty("stackdriver.trace.zipkin.agent", "zipkin-java");
attributes.putAttributeMap(kAgentLabelKey, toAttributeValue(agentName));
}
return attributes.build();
}
static AttributeValue toAttributeValue(String text) {
return AttributeValue.newBuilder()
.setStringValue(toTruncatableString(text))
.build();
}
private String getLabelName(String zipkinName) {
String renamed = renamedLabels.get(zipkinName);
return renamed != null ? renamed : zipkinName;
}
private String kindLabel(Span.Kind kind) {
switch (kind) {
case CLIENT:
return "client";
case SERVER:
return "server";
case PRODUCER:
return "producer";
case CONSUMER:
return "consumer";
default:
return kind.name().toLowerCase();
}
}
}