Skip to content
This repository was archived by the owner on Dec 23, 2023. It is now read-only.

Commit 1f25cb4

Browse files
author
Bogdan Drutu
authored
Add annotations and network events as labels in Stackdriver v1 API. (#591)
* Add annotations and network events as labels in v1 API. * Fix minor comments.
1 parent 821b15f commit 1f25cb4

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed

exporters/trace_stackdriver/src/main/java/io/opencensus/exporter/trace/stackdriver/StackdriverV1ExporterHandler.java

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,19 @@
2727
import com.google.devtools.cloudtrace.v1.Trace;
2828
import com.google.devtools.cloudtrace.v1.TraceSpan;
2929
import com.google.devtools.cloudtrace.v1.Traces;
30+
import io.opencensus.common.Duration;
3031
import io.opencensus.common.Function;
3132
import io.opencensus.common.Functions;
3233
import io.opencensus.common.Timestamp;
34+
import io.opencensus.trace.Annotation;
3335
import io.opencensus.trace.AttributeValue;
36+
import io.opencensus.trace.NetworkEvent;
37+
import io.opencensus.trace.NetworkEvent.Type;
3438
import io.opencensus.trace.SpanContext;
3539
import io.opencensus.trace.SpanId;
3640
import io.opencensus.trace.TraceId;
3741
import io.opencensus.trace.export.SpanData;
42+
import io.opencensus.trace.export.SpanData.TimedEvent;
3843
import io.opencensus.trace.export.SpanExporter;
3944
import java.io.IOException;
4045
import java.nio.ByteBuffer;
@@ -51,6 +56,8 @@ final class StackdriverV1ExporterHandler extends SpanExporter.Handler {
5156

5257
private static final String STATUS_CODE = "g.co/status/code";
5358
private static final String STATUS_DESCRIPTION = "g.co/status/description";
59+
private static final String ANNOTATION_LABEL = "ANNOTATION-";
60+
private static final String NETWORK_EVENT_LABEL = "NETWORK-";
5461

5562
private final String projectId;
5663
private final TraceServiceClient traceServiceClient;
@@ -95,6 +102,22 @@ private Trace generateTrace(SpanData spanData) {
95102
spanBuilder.putLabels(label.getKey(), attributeValueToString(label.getValue()));
96103
}
97104

105+
// Add Annotations as labels in the v1 API
106+
int seq = 0;
107+
for (TimedEvent<Annotation> annotation : spanData.getAnnotations().getEvents()) {
108+
spanBuilder.putLabels(
109+
ANNOTATION_LABEL + String.format("%03d", seq++),
110+
renderAnnotation(annotation, spanData.getStartTimestamp()));
111+
}
112+
113+
// Add NetworkEvents as labels in the v1 API
114+
seq = 0;
115+
for (TimedEvent<NetworkEvent> networkEvent : spanData.getNetworkEvents().getEvents()) {
116+
spanBuilder.putLabels(
117+
NETWORK_EVENT_LABEL + String.format("%03d", seq++),
118+
renderNetworkEvents(networkEvent, spanData.getStartTimestamp()));
119+
}
120+
98121
// Add Status as labels in the v1 API.
99122
spanBuilder.putLabels(STATUS_CODE, spanData.getStatus().getCanonicalCode().toString());
100123
if (spanData.getStatus().getDescription() != null) {
@@ -132,6 +155,67 @@ private static TraceSpan.SpanKind toSpanKindProto(SpanData spanData) {
132155
return TraceSpan.SpanKind.SPAN_KIND_UNSPECIFIED;
133156
}
134157

158+
private static String renderNetworkEvents(TimedEvent<NetworkEvent> timedEvent, Timestamp start) {
159+
StringBuilder stringBuilder = new StringBuilder();
160+
renderDelay(stringBuilder, timedEvent.getTimestamp().subtractTimestamp(start));
161+
NetworkEvent networkEvent = timedEvent.getEvent();
162+
if (networkEvent.getType() == Type.RECV) {
163+
stringBuilder.append("Received");
164+
} else if (networkEvent.getType() == Type.SENT) {
165+
stringBuilder.append("Sent");
166+
} else {
167+
stringBuilder.append("Unknown");
168+
}
169+
stringBuilder.append(" message_id=");
170+
stringBuilder.append(networkEvent.getMessageId());
171+
stringBuilder.append(" uncompressed_size=");
172+
stringBuilder.append(networkEvent.getUncompressedMessageSize());
173+
stringBuilder.append(" compressed_size=");
174+
stringBuilder.append(networkEvent.getCompressedMessageSize());
175+
if (networkEvent.getKernelTimestamp() != null) {
176+
stringBuilder.append(" kernel_timestamp=");
177+
stringBuilder.append(networkEvent.getKernelTimestamp().toString());
178+
}
179+
return stringBuilder.toString();
180+
}
181+
182+
private static String renderAnnotation(TimedEvent<Annotation> timedEvent, Timestamp start) {
183+
StringBuilder stringBuilder = new StringBuilder();
184+
renderDelay(stringBuilder, timedEvent.getTimestamp().subtractTimestamp(start));
185+
Annotation annotation = timedEvent.getEvent();
186+
stringBuilder.append(annotation.getDescription());
187+
if (!annotation.getAttributes().isEmpty()) {
188+
stringBuilder.append(" ");
189+
stringBuilder.append(renderAttributes(annotation.getAttributes()));
190+
}
191+
return stringBuilder.toString();
192+
}
193+
194+
private static void renderDelay(StringBuilder stringBuilder, Duration delay) {
195+
long delayUs = delay.getSeconds() * 1000000 + delay.getNanos() / 1000;
196+
stringBuilder.append("[@");
197+
stringBuilder.append(delayUs);
198+
stringBuilder.append(" us] ");
199+
}
200+
201+
private static String renderAttributes(Map<String, AttributeValue> attributes) {
202+
StringBuilder stringBuilder = new StringBuilder();
203+
stringBuilder.append("Attributes:{");
204+
boolean first = true;
205+
for (Map.Entry<String, AttributeValue> entry : attributes.entrySet()) {
206+
if (first) {
207+
first = false;
208+
} else {
209+
stringBuilder.append(", ");
210+
}
211+
stringBuilder.append(entry.getKey());
212+
stringBuilder.append("=");
213+
stringBuilder.append(attributeValueToString(entry.getValue()));
214+
}
215+
stringBuilder.append("}");
216+
return stringBuilder.toString();
217+
}
218+
135219
private static com.google.protobuf.Timestamp toTimestampProto(Timestamp timestamp) {
136220
return com.google.protobuf.Timestamp.newBuilder()
137221
.setSeconds(timestamp.getSeconds())

0 commit comments

Comments
 (0)