diff --git a/ddprof-lib/src/main/cpp/event.h b/ddprof-lib/src/main/cpp/event.h index 809967038..1bf33ba7e 100644 --- a/ddprof-lib/src/main/cpp/event.h +++ b/ddprof-lib/src/main/cpp/event.h @@ -144,9 +144,10 @@ class TraceRootEvent { public: u64 _local_root_span_id; u32 _label; + u32 _operation; - TraceRootEvent(u64 local_root_span_id, u32 label) : - _local_root_span_id(local_root_span_id), _label(label) {}; + TraceRootEvent(u64 local_root_span_id, u32 label, u32 operation) : + _local_root_span_id(local_root_span_id), _label(label), _operation(operation) {}; }; typedef struct QueueTimeEvent { diff --git a/ddprof-lib/src/main/cpp/flightRecorder.cpp b/ddprof-lib/src/main/cpp/flightRecorder.cpp index d56238a1f..95f710d98 100644 --- a/ddprof-lib/src/main/cpp/flightRecorder.cpp +++ b/ddprof-lib/src/main/cpp/flightRecorder.cpp @@ -1236,6 +1236,7 @@ void Recording::recordTraceRoot(Buffer* buf, int tid, TraceRootEvent* event) { buf->putVar32(tid); buf->put8(0); buf->putVar32(event->_label); + buf->putVar32(event->_operation); buf->putVar64(event->_local_root_span_id); writeEventSizePrefix(buf, start); flushIfNeeded(buf); diff --git a/ddprof-lib/src/main/cpp/javaApi.cpp b/ddprof-lib/src/main/cpp/javaApi.cpp index 3be331ec6..bc2faa966 100644 --- a/ddprof-lib/src/main/cpp/javaApi.cpp +++ b/ddprof-lib/src/main/cpp/javaApi.cpp @@ -142,12 +142,19 @@ Java_com_datadoghq_profiler_JavaProfiler_getMaxContextPages0(JNIEnv* env, jobjec extern "C" DLLEXPORT jboolean JNICALL Java_com_datadoghq_profiler_JavaProfiler_recordTrace0(JNIEnv* env, jobject unused, jlong rootSpanId, jstring endpoint, - jint sizeLimit) { + jstring operation, jint sizeLimit) { JniString endpoint_str(env, endpoint); - u32 label = Profiler::instance()->stringLabelMap()->bounded_lookup(endpoint_str.c_str(), endpoint_str.length(), sizeLimit); - bool acceptValue = label != INT_MAX; + u32 endpointLabel = Profiler::instance()->stringLabelMap()->bounded_lookup( + endpoint_str.c_str(), endpoint_str.length(), sizeLimit); + bool acceptValue = endpointLabel != INT_MAX; if (acceptValue) { - TraceRootEvent event(rootSpanId, label); + u32 operationLabel = 0; + if (operation != NULL) { + JniString operation_str(env, operation); + operationLabel = Profiler::instance()->contextValueMap()->bounded_lookup( + operation_str.c_str(), operation_str.length(), 1 << 16); + } + TraceRootEvent event(rootSpanId, endpointLabel, operationLabel); int tid = ProfiledThread::currentTid(); Profiler::instance()->recordTraceRoot(tid, &event); } diff --git a/ddprof-lib/src/main/cpp/jfrMetadata.cpp b/ddprof-lib/src/main/cpp/jfrMetadata.cpp index 97e217551..dcabb1563 100644 --- a/ddprof-lib/src/main/cpp/jfrMetadata.cpp +++ b/ddprof-lib/src/main/cpp/jfrMetadata.cpp @@ -170,6 +170,7 @@ void JfrMetadata::initialize(const std::vector& contextAttributes) << field("eventThread", T_THREAD, "Event Thread", F_CPOOL) << field("stackTrace", T_STACK_TRACE, "Stack Trace", F_CPOOL) << field("endpoint", T_STRING, "Endpoint", F_CPOOL) + << field("operation", T_ATTRIBUTE_VALUE, "Operation", F_CPOOL) << field("localRootSpanId", T_LONG, "Local Root Span ID")) << (type("datadog.QueueTime", T_QUEUE_TIME, "Queue Time") diff --git a/ddprof-lib/src/main/java/com/datadoghq/profiler/JavaProfiler.java b/ddprof-lib/src/main/java/com/datadoghq/profiler/JavaProfiler.java index 1146c9970..f784fdf7c 100644 --- a/ddprof-lib/src/main/java/com/datadoghq/profiler/JavaProfiler.java +++ b/ddprof-lib/src/main/java/com/datadoghq/profiler/JavaProfiler.java @@ -212,8 +212,16 @@ public String execute(String command) throws IllegalArgumentException, IllegalSt /** * Records the completion of the trace root */ + public boolean recordTraceRoot(long rootSpanId, String endpoint, String operation, int sizeLimit) { + return recordTrace0(rootSpanId, endpoint, operation, sizeLimit); + } + + /** + * Records the completion of the trace root + */ + @Deprecated public boolean recordTraceRoot(long rootSpanId, String endpoint, int sizeLimit) { - return recordTrace0(rootSpanId, endpoint, sizeLimit); + return recordTrace0(rootSpanId, endpoint, null, sizeLimit); } /** @@ -517,7 +525,7 @@ private static boolean containsArray(byte[] container, int offset, byte[] contai private static native long getContextPageOffset0(int tid); private static native int getMaxContextPages0(); - private static native boolean recordTrace0(long rootSpanId, String endpoint, int sizeLimit); + private static native boolean recordTrace0(long rootSpanId, String endpoint, String operation, int sizeLimit); private static native int registerConstant0(String value); diff --git a/ddprof-lib/src/test/cpp/demangle_ut.cpp b/ddprof-lib/src/test/cpp/demangle_ut.cpp index db1530806..1ef677e57 100644 --- a/ddprof-lib/src/test/cpp/demangle_ut.cpp +++ b/ddprof-lib/src/test/cpp/demangle_ut.cpp @@ -4,6 +4,8 @@ #include +#ifndef __APPLE__ + struct DemangleTestContent { std::string test; std::string answer; @@ -181,3 +183,4 @@ TEST(DemangleTest, Positive) { free(demangled); } } +#endif diff --git a/ddprof-test/src/test/java/com/datadoghq/profiler/AbstractProfilerTest.java b/ddprof-test/src/test/java/com/datadoghq/profiler/AbstractProfilerTest.java index bdbbc4801..bbe31e226 100644 --- a/ddprof-test/src/test/java/com/datadoghq/profiler/AbstractProfilerTest.java +++ b/ddprof-test/src/test/java/com/datadoghq/profiler/AbstractProfilerTest.java @@ -62,6 +62,9 @@ public IMemberAccessor customAccessor(IType type) { public static final IAttribute SPAN_ID = attr("spanId", "spanId", "spanId", NUMBER); + public static final IAttribute OPERATION = attr("operation", "operation", + "operation", PLAIN_TEXT); + public static final IAttribute THREAD_STATE = diff --git a/ddprof-test/src/test/java/com/datadoghq/profiler/endpoints/EndpointTest.java b/ddprof-test/src/test/java/com/datadoghq/profiler/endpoints/EndpointTest.java index 02352349c..06e400c25 100644 --- a/ddprof-test/src/test/java/com/datadoghq/profiler/endpoints/EndpointTest.java +++ b/ddprof-test/src/test/java/com/datadoghq/profiler/endpoints/EndpointTest.java @@ -26,7 +26,7 @@ public class EndpointTest extends AbstractProfilerTest { @Test public void testEndpoints() { Endpoint[] endpoints = IntStream.range(0, 1000) - .mapToObj(i -> new Endpoint(i, i + "")) + .mapToObj(i -> new Endpoint(i, i + "", i % 2 == 0 ? "op" + i : null)) .toArray(Endpoint[]::new); int sizeLimit = endpoints.length; // insert up to limit @@ -38,7 +38,7 @@ public void testEndpoints() { record(endpoint, true, sizeLimit); } // reject above size limit - record(new Endpoint(0, UUID.randomUUID().toString()), false, sizeLimit); + record(new Endpoint(0, UUID.randomUUID().toString(), UUID.randomUUID().toString()), false, sizeLimit); stopProfiler(); IItemCollection events = verifyEvents("datadog.Endpoint"); @@ -48,14 +48,17 @@ public void testEndpoints() { for (IItemIterable it : events) { IMemberAccessor endpointAccessor = endpointAttribute.getAccessor(it.getType()); IMemberAccessor rootSpanIdAccessor = LOCAL_ROOT_SPAN_ID.getAccessor(it.getType()); + IMemberAccessor operationAccessor = OPERATION.getAccessor(it.getType()); for (IItem event : it) { long rootSpanId = rootSpanIdAccessor.getMember(event).longValue(); + String operation = operationAccessor.getMember(event); Endpoint endpoint = endpoints[(int) rootSpanId]; recovered.set((int) rootSpanId); String message = endpoint.toString(); String recordedEndpoint = endpointAccessor.getMember(event); assertEquals(endpoint.endpoint, recordedEndpoint, message); assertEquals(endpoint.rootSpanId, rootSpanId, message); + assertEquals(endpoint.operation, operation, message); } } for (int i = 0; i < endpoints.length; i++) { @@ -69,7 +72,7 @@ public void testEndpoints() { } private void record(Endpoint endpoint, boolean shouldAccept, int sizeLimit) { - assertEquals(shouldAccept, profiler.recordTraceRoot(endpoint.rootSpanId, endpoint.endpoint, sizeLimit)); + assertEquals(shouldAccept, profiler.recordTraceRoot(endpoint.rootSpanId, endpoint.endpoint, endpoint.operation, sizeLimit)); } @Override @@ -80,10 +83,12 @@ protected String getProfilerCommand() { static class Endpoint { private final long rootSpanId; private final String endpoint; + private final String operation; - Endpoint(long rootSpanId, String endpoint) { + Endpoint(long rootSpanId, String endpoint, String operation) { this.rootSpanId = rootSpanId; this.endpoint = endpoint; + this.operation = operation; } @Override @@ -91,6 +96,7 @@ public String toString() { return "Endpoint{" + "rootSpanId=" + rootSpanId + ", endpoint='" + endpoint + '\'' + + ", operation='" + operation + '\'' + '}'; } }