Part V Parsing a Recording File
The example ParseRecordingFileSample.java
describes various ways you
can parse a recording file. It starts a recording to record several Hello
and Message
events.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import jdk.jfr.Event;
import jdk.jfr.EventType;
import jdk.jfr.Label;
import jdk.jfr.Name;
import jdk.jfr.Recording;
import jdk.jfr.consumer.EventStream;
import jdk.jfr.consumer.RecordingFile;
public class ParseRecordingFileSample {
@Name("com.oracle.Hello")
@Label("Hello World!")
static class Hello extends Event {
@Label("Greeting")
String greeting;
}
@Name("com.oracle.Message")
@Label("Message")
static class Message extends Event {
@Label("Text")
String text;
}
public static void main(String... args) throws IOException {
try (Recording r = new Recording()) {
r.start();
for (int i = 0; i < 3; i++) {
Message messageEvent = new Message();
messageEvent.begin();
messageEvent.text = "message " + i;
messageEvent.commit();
Hello helloEvent = new Hello();
helloEvent.begin();
helloEvent.greeting = "hello " + i;
helloEvent.commit();
}
r.stop();
Path file = Files.createTempFile("recording", ".jfr");
r.dump(file);
try (var recordingFile = new RecordingFile(file)) {
System.out.println("Reading events one by one");
System.out.println("=========================");
while (recordingFile.hasMoreEvents()) {
var e = recordingFile.readEvent();
String eventName = e.getEventType().getName();
System.out.println("Name: " + eventName);
}
System.out.println();
System.out.println("List of registered event types");
System.out.println("==============================");
for (EventType eventType : recordingFile.readEventTypes())
{
System.out.println(eventType.getName());
}
}
System.out.println();
System.out.println("Reading all events at once");
System.out.println("==========================");
for (var e : RecordingFile.readAllEvents(file)) {
String eventName = e.getEventType().getName();
System.out.println("Name: " + eventName);
}
System.out.println();
System.out.println("Reading events one by one, printing only "
+ "com.oracle.Message events");
System.out.println("========================================="
+ "=========================");
try (EventStream eventStream = EventStream.openFile(file)) {
eventStream.onEvent("com.oracle.Message", e -> {
System.out.println(
"Name: " + e.getEventType().getName());
});
eventStream.start();
}
}
}
}
Run ParseRecordingFileSample
with this command:
java ParseRecordingFileSample.java
When running ParseRecordingFileSample
, you don't have to
start Flight Recorder with the command-line option
-XX:StartFlightRecording
; the method Recording.start() starts it. ParseRecordingFileSample
prints the following:
Reading events one by one
=========================
Name: com.oracle.Message
Name: com.oracle.Hello
Name: com.oracle.Message
Name: com.oracle.Hello
Name: com.oracle.Message
Name: com.oracle.Hello
List of registered event types
==============================
jdk.ThreadStart
jdk.ThreadEnd
jdk.ThreadSleep
...
jdk.X509Validation
com.oracle.Message
com.oracle.Hello
Reading all events at once
==========================
Name: com.oracle.Message
Name: com.oracle.Hello
Name: com.oracle.Message
Name: com.oracle.Hello
Name: com.oracle.Message
Name: com.oracle.Hello
Reading events one by one, printing only com.oracle.Message events
==================================================================
Name: com.oracle.Message
Name: com.oracle.Message
Name: com.oracle.Message
Write Recording Data to a File
ParseRecordingFileSample
demonstrates several
ways you can parse a recording file. However, you first need a recording file, and this
sample doesn't create one at the command line. Instead, it calls Recording.dump(Path) to write recording data to a temporary
file:Path file = Files.createTempFile("recording", ".jfr");
r.dump(file);
Read Events One by One
Use this technique for large recordings and if you need to access metadata.
The method RecordingFile.readEvent() reads the next event in the
recording while RecordingEvent.hasMoreEvents() returns
true
if unread events exist in the recording file:
while (recordingFile.hasMoreEvents()) {
var e = recordingFile.readEvent();
String eventName = e.getEventType().getName();
System.out.println("Name: " + eventName);
}
List Registered Event Types
The method RecordingFile.readEventTypes() returns a list of all event types in the recording.
Read All Events at Once
Use this technique for smaller recordings that fit in memory.
The method RecordingFile.readAllEvents(Path) returns a list of all events in the recording file. It's intended for small recording files where it's more convenient to read all events in a single operation. It's not intended for reading large recording files.
Read Only Specific Events with Event Streaming API
To process only specific events, you could read events one by one with RecordingFile.readEvent(), as described previously, then check the event's name. However, if you use the event streaming API, then event objects of the same type are reused to reduced allocation pressure.
This technique involves creating an event stream with EventStream.openFile(Path), then calling EventStream.onEvent(String eventName, Consumer) to
register an action that will be performed if eventName
matches the
event's name:
try (EventStream eventStream = EventStream.openFile(file)) {
eventStream.onEvent("com.oracle.Message", e -> {
System.out.println("Name: " +
e.getEventType().getName());
});
eventStream.start();
}