Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package datadog.trace.common.writer.ddagent;

import static datadog.communication.http.OkHttpUtils.msgpackRequestBodyOf;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonMap;

Expand All @@ -11,6 +12,7 @@
import datadog.communication.serialization.Writable;
import datadog.communication.serialization.msgpack.MsgPackWriter;
import datadog.environment.JavaVirtualMachine;
import datadog.json.JsonReader;
import datadog.trace.api.Config;
import datadog.trace.api.DDTags;
import datadog.trace.api.DDTraceId;
Expand Down Expand Up @@ -203,12 +205,12 @@ private void encodeSpanLinks(

private void encodeSpanEvents(Writable writable, int fieldId, Object eventsObject) {
writable.writeInt(fieldId);
if (!(eventsObject instanceof List) || ((List<?>) eventsObject).isEmpty()) {
List<?> events = parseSpanEvents(eventsObject);
if (events.isEmpty()) {
writable.startArray(0);
return;
}

List<?> events = (List<?>) eventsObject;
int encodableCount = 0;
for (Object event : events) {
if (isEncodableSpanEvent(event)) {
Expand Down Expand Up @@ -237,6 +239,23 @@ private void encodeSpanEvents(Writable writable, int fieldId, Object eventsObjec
}
}

private List<?> parseSpanEvents(Object eventsObject) {
if (eventsObject instanceof List) {
return (List<?>) eventsObject;
}
if (eventsObject instanceof CharSequence) {
try (JsonReader reader = new JsonReader(eventsObject.toString())) {
Object events = reader.nextValue();
Comment thread
AlexeyKuznetsov-DD marked this conversation as resolved.
Comment thread
AlexeyKuznetsov-DD marked this conversation as resolved.
if (events instanceof List) {
return (List<?>) events;
}
} catch (IOException e) {
log.debug("Failed to parse span events from JSON", e);
}
}
return emptyList();
}

private boolean isEncodableSpanEvent(Object event) {
if (!(event instanceof Map)) {
return false;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package datadog.trace.core;

import static datadog.trace.api.DDTags.SPAN_EVENTS;
import static datadog.trace.api.DDTags.SPAN_LINKS;
import static datadog.trace.api.TracePropagationStyle.DATADOG;
import static datadog.trace.api.config.GeneralConfig.EXPERIMENTAL_PROPAGATE_PROCESS_TAGS_ENABLED;
Expand Down Expand Up @@ -400,6 +401,52 @@ void serializeTraceWithSpanLinksAsStructuredLinksOnlyV1() throws Exception {
tracer.close();
}

@Test
void serializeTraceWithJsonSpanEventsV1() throws Exception {
CoreTracer tracer = tracerBuilder().writer(new ListWriter()).build();
DDSpanContext context = createSpanContext(tracer, Collections.emptyMap(), null, true, true, 1);
context.setTag(
SPAN_EVENTS,
"[{\"time_unix_nano\":1234567890,\"name\":\"event.one\","
+ "\"attributes\":{\"str\":\"value\",\"int\":42,\"double\":12.5,"
+ "\"bool\":true,\"arr\":[\"x\",7,2.5,false]}},"
+ "{\"time_unix_nano\":1234567891,\"name\":\"event.two\"}]");
DDSpan span = DDSpan.create("test", 0, context, null);

V1PayloadReader.V1Span payload = V1PayloadReader.readFirstSpan(serializeV1Payload(span));

assertFalse(payload.getAttributes().containsKey(SPAN_EVENTS));
assertEquals(2, payload.getEvents().size());
V1PayloadReader.V1SpanEvent firstEvent = payload.getEvents().get(0);
assertEquals(1234567890L, firstEvent.getTimeUnixNano());
assertEquals("event.one", firstEvent.getName());
assertEquals("value", firstEvent.getAttributes().get("str"));
assertEquals(42L, firstEvent.getAttributes().get("int"));
assertEquals(12.5d, firstEvent.getAttributes().get("double"));
assertEquals(true, firstEvent.getAttributes().get("bool"));
assertEquals(Arrays.asList("x", 7L, 2.5d, false), firstEvent.getAttributes().get("arr"));

V1PayloadReader.V1SpanEvent secondEvent = payload.getEvents().get(1);
assertEquals(1234567891L, secondEvent.getTimeUnixNano());
assertEquals("event.two", secondEvent.getName());
assertEquals(Collections.emptyMap(), secondEvent.getAttributes());
tracer.close();
}

@Test
void serializeTraceWithMalformedJsonSpanEventsAsEmptyV1() throws Exception {
CoreTracer tracer = tracerBuilder().writer(new ListWriter()).build();
DDSpanContext context = createSpanContext(tracer, Collections.emptyMap(), null, true, true, 1);
context.setTag(SPAN_EVENTS, "[{");
DDSpan span = DDSpan.create("test", 0, context, null);

V1PayloadReader.V1Span payload = V1PayloadReader.readFirstSpan(serializeV1Payload(span));

assertFalse(payload.getAttributes().containsKey(SPAN_EVENTS));
assertEquals(Collections.emptyList(), payload.getEvents());
tracer.close();
}

@TableTest({
"protocol | rootFirst",
"v0.4 | true ",
Expand Down