Custom OrderProcessed event, CPU/allocation/lock workloads, a diagnostic endpoint over the JVM's live FlightRecorder state, a JUnit test using the jdk.jfr.Recording API, and nine captured recordings (flagship, mid-flight snapshot, isolated vs concurrent threshold comparisons, and a real dump+stop duplication bug) with their docs/output/*.txt transcripts.
39 lines
1.7 KiB
Plaintext
39 lines
1.7 KiB
Plaintext
60 GET /api/orders/process calls against the live app while recording "live2"
|
|
(settings=profile) was running. OrderProcessedEvent has @Threshold("20 ms"), and
|
|
only ~1/3 of simulated orders take the slow path (35 ms, "inventory-lock-wait");
|
|
the rest are fast (0-5 ms) and should be filtered out before ever being written.
|
|
|
|
$ jfr print --events com.ankurm.jfr.OrderProcessed recordings/live-demo.jfr | head -21
|
|
com.ankurm.jfr.OrderProcessed {
|
|
startTime = 09:59:08.076 (2026-10-01)
|
|
duration = 35.2 ms
|
|
orderId = "ORD-61"
|
|
warehouse = "BOM-1"
|
|
amountCents = 0
|
|
itemCount = 4
|
|
slowReason = "inventory-lock-wait"
|
|
eventThread = "http-nio-8080-exec-2" (javaThreadId = 31)
|
|
stackTrace = [
|
|
com.ankurm.jfr.service.OrderService.processOrder(String, int) line: 39
|
|
com.ankurm.jfr.web.OrderController.process(int) line: 25
|
|
jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Object, Object[]) line: 104
|
|
java.lang.reflect.Method.invoke(Object, Object[]) line: 565
|
|
org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(Object[]) line: 252
|
|
]
|
|
}
|
|
|
|
com.ankurm.jfr.OrderProcessed {
|
|
startTime = 09:59:08.156 (2026-10-01)
|
|
duration = 35.1 ms
|
|
orderId = "ORD-63"
|
|
|
|
$ jfr print --events com.ankurm.jfr.OrderProcessed recordings/live-demo.jfr | grep -c '^com.ankurm'
|
|
23
|
|
|
|
23 of 60 orders were kept -- every one of them carries slowReason =
|
|
"inventory-lock-wait" and a duration at or above the 20 ms threshold. None of
|
|
the fast-path orders (duration well under 20 ms) appear at all: the threshold
|
|
discarded them before OrderProcessedEvent.commit() ever ran, which is the whole
|
|
point of checking event.shouldCommit() after event.end() instead of always
|
|
calling commit() unconditionally.
|