@@ -1561,14 +1561,25 @@ void Recording::recordTaskBlock(Buffer *buf, int tid, TaskBlockEvent *event) {
15611561
15621562void Recording::recordSpanNode (Buffer *buf, int tid, u64 spanId, u64 parentSpanId, u64 rootSpanId,
15631563 u64 startNanos, u64 durationNanos, u32 encodedOperation, u32 encodedResource) {
1564+ // Convert epoch nanoseconds to JFR ticks so that standard JFR tooling (JMC, Mission
1565+ // Control) can correlate SpanNode events with other events on the recording timeline.
1566+ // _start_time is in microseconds; multiply by 1000 to get the recording epoch in nanos.
1567+ u64 start_epoch_nanos = _start_time * 1000ULL ;
1568+ u64 startTicks = _start_ticks + (u64 )((double )(long long )(startNanos - start_epoch_nanos)
1569+ * TSC::frequency () / NANOTIME_FREQ );
1570+ u64 durationTicks = (u64 )((double )durationNanos * TSC::frequency () / NANOTIME_FREQ );
1571+
15641572 flushIfNeeded (buf);
15651573 int start = buf->skip (1 );
15661574 buf->putVar64 (T_SPAN_NODE );
1575+ buf->putVar64 (startTicks); // startTime (F_TIME_TICKS)
1576+ buf->putVar64 (durationTicks); // duration (F_DURATION_TICKS)
1577+ buf->putVar32 (tid); // eventThread (F_CPOOL)
15671578 buf->putVar64 (spanId);
15681579 buf->putVar64 (parentSpanId);
15691580 buf->putVar64 (rootSpanId);
1570- buf->putVar64 (startNanos);
1571- buf->putVar64 (durationNanos);
1581+ buf->putVar64 (startNanos); // startNanos — epoch ns, used by backend extractor
1582+ buf->putVar64 (durationNanos); // durationNanos — ns
15721583 buf->putVar32 (encodedOperation);
15731584 buf->putVar32 (encodedResource);
15741585 writeEventSizePrefix (buf, start);
0 commit comments