Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add queue type and length to queue events #144

Merged
merged 1 commit into from
Jan 23, 2025
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
2 changes: 2 additions & 0 deletions ddprof-lib/src/main/cpp/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ typedef struct QueueTimeEvent {
u32 _task;
u32 _scheduler;
u32 _origin;
u32 _queueType;
u32 _queueLength;
} QueueTimeEvent;

#endif // _EVENT_H
2 changes: 2 additions & 0 deletions ddprof-lib/src/main/cpp/flightRecorder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1334,6 +1334,8 @@ void Recording::recordQueueTime(Buffer *buf, int tid, QueueTimeEvent *event) {
buf->putVar64(event->_origin);
buf->putVar64(event->_task);
buf->putVar64(event->_scheduler);
buf->putVar64(event->_queueType);
buf->putVar64(event->_queueLength);
writeContext(buf, Contexts::get(tid));
writeEventSizePrefix(buf, start);
flushIfNeeded(buf);
Expand Down
22 changes: 15 additions & 7 deletions ddprof-lib/src/main/cpp/javaApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,10 +232,15 @@ Java_com_datadoghq_profiler_JavaProfiler_recordSettingEvent0(
tid, length, name_str.c_str(), value_str.c_str(), unit_str.c_str());
}

static int dictionarizeClassName(JNIEnv* env, jstring className) {
JniString str(env, className);
return Profiler::instance()->lookupClass(str.c_str(), str.length());
}

extern "C" DLLEXPORT void JNICALL
Java_com_datadoghq_profiler_JavaProfiler_recordQueueEnd0(
JNIEnv *env, jobject unused, jlong startTime, jlong endTime, jstring task,
jstring scheduler, jthread origin) {
jstring scheduler, jthread origin, jstring queueType, jint queueLength) {
int tid = ProfiledThread::currentTid();
if (tid < 0) {
return;
Expand All @@ -244,24 +249,27 @@ Java_com_datadoghq_profiler_JavaProfiler_recordQueueEnd0(
if (origin_tid < 0) {
return;
}
JniString task_str(env, task);
JniString scheduler_str(env, scheduler);
int task_offset =
Profiler::instance()->lookupClass(task_str.c_str(), task_str.length());
JniString queue_type_str(env, queueType);
int task_offset = dictionarizeClassName(env, task);
if (task_offset < 0) {
return;
}
int scheduler_offset = Profiler::instance()->lookupClass(
scheduler_str.c_str(), scheduler_str.length());
int scheduler_offset = dictionarizeClassName(env, scheduler);
if (scheduler_offset < 0) {
return;
}
int queue_type_offset = dictionarizeClassName(env, queueType);
if (queue_type_offset < 0) {
return;
}
QueueTimeEvent event;
event._start = startTime;
event._end = endTime;
event._task = task_offset;
event._scheduler = scheduler_offset;
event._origin = origin_tid;
event._queueType = queue_type_offset;
event._queueLength = queueLength;
Profiler::instance()->recordQueueTime(tid, &event);
}

Expand Down
2 changes: 2 additions & 0 deletions ddprof-lib/src/main/cpp/jfrMetadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@ void JfrMetadata::initialize(
<< field("origin", T_THREAD, "Origin Thread", F_CPOOL)
<< field("task", T_CLASS, "Task", F_CPOOL)
<< field("scheduler", T_CLASS, "Scheduler", F_CPOOL)
<< field("queueType", T_CLASS, "Queue Type", F_CPOOL)
<< field("queueLength", T_INT, "Queue Length on Entry")
<< field("spanId", T_LONG, "Span ID")
<< field("localRootSpanId", T_LONG, "Local Root Span ID") ||
contextAttributes)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -442,9 +442,14 @@ public boolean isThresholdExceeded(long thresholdMillis, long startTicks, long e
* @param scheduler the name of the thread-pool or executor scheduling the task
* @param origin the thread the task was submitted on
*/
public void recordQueueTime(long startTicks, long endTicks, Class<?> task, Class<?> scheduler,
public void recordQueueTime(long startTicks,
long endTicks,
Class<?> task,
Class<?> scheduler,
Class<?> queueType,
int queueLength,
Thread origin) {
recordQueueEnd0(startTicks, endTicks, task.getName(), scheduler.getName(), origin);
recordQueueEnd0(startTicks, endTicks, task.getName(), scheduler.getName(), origin, queueType.getName(), queueLength);
}

/**
Expand Down Expand Up @@ -578,7 +583,7 @@ private static boolean containsArray(byte[] container, int offset, byte[] contai

private static native void recordSettingEvent0(String name, String value, String unit);

private static native void recordQueueEnd0(long startTicks, long endTicks, String task, String scheduler, Thread origin);
private static native void recordQueueEnd0(long startTicks, long endTicks, String task, String scheduler, Thread origin, String queueType, int queueLength);

private static native long currentTicks0();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,12 @@
import org.openjdk.jmc.flightrecorder.JfrAttributes;
import org.openjdk.jmc.flightrecorder.jdk.JdkAttributes;

import java.util.concurrent.ArrayBlockingQueue;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.openjdk.jmc.common.item.Attribute.attr;
import static org.openjdk.jmc.common.unit.UnitLookup.CLASS;
import static org.openjdk.jmc.common.unit.UnitLookup.EPOCH_MS;
import static org.openjdk.jmc.common.unit.UnitLookup.EPOCH_NS;
import static org.openjdk.jmc.common.unit.UnitLookup.THREAD;
import static org.openjdk.jmc.common.unit.UnitLookup.TIMESTAMP;
import static org.openjdk.jmc.common.unit.UnitLookup.*;

public class QueueTimeTest extends AbstractProfilerTest {
@Override
Expand All @@ -47,7 +45,7 @@ public void run() {
profiler.setContext(1, 2);
long now = profiler.getCurrentTicks();
if (profiler.isThresholdExceeded(9, start, now)) {
profiler.recordQueueTime(start, now, getClass(), QueueTimeTest.class, origin);
profiler.recordQueueTime(start, now, getClass(), QueueTimeTest.class, ArrayBlockingQueue.class, 10, origin);
}
profiler.clearContext();
}
Expand All @@ -68,6 +66,8 @@ public void testRecordQueueTime() throws Exception {
IAttribute<IMCThread> originAttr = attr("origin", "", "", THREAD);
IAttribute<IMCType> taskAttr = attr("task", "", "", CLASS);
IAttribute<IMCType> schedulerAttr = attr("scheduler", "", "", CLASS);
IAttribute<IMCType> queueTypeAttr = attr("queueType", "", "", CLASS);
IAttribute<IQuantity> queueLengthAttr = attr("queueLength", "", "", NUMBER);

IItemCollection activeSettings = verifyEvents("jdk.ActiveSetting");
for (IItemIterable activeSetting : activeSettings) {
Expand All @@ -94,6 +94,8 @@ public void testRecordQueueTime() throws Exception {
assertEquals(1, SPAN_ID.getAccessor(it.getType()).getMember(item).longValue());
assertEquals(2, LOCAL_ROOT_SPAN_ID.getAccessor(it.getType()).getMember(item).longValue());
assertEquals("origin", originAttr.getAccessor(it.getType()).getMember(item).getThreadName());
assertEquals(ArrayBlockingQueue.class.getName(), queueTypeAttr.getAccessor(it.getType()).getMember(item).getTypeName());
assertEquals(10, queueLengthAttr.getAccessor(it.getType()).getMember(item).longValue());
}
}
}
Expand Down
Loading