AutoCloseable
, EventStream
public final class RemoteRecordingStream extends Object implements EventStream
EventStream
that can serialize events over the network using an MBeanServerConnection
. The following example shows how to record garbage collection pauses and CPU usage on a remote host and print the events to standard out.
String host = "com.example"; int port = 4711; String url = "service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi"; JMXServiceURL u = new JMXServiceURL(url); JMXConnector c = JMXConnectorFactory.connect(u); MBeanServerConnection conn = c.getMBeanServerConnection(); try (var rs = new RemoteRecordingStream(conn)) { rs.enable("jdk.GCPhasePause").withoutThreshold(); rs.enable("jdk.CPULoad").withPeriod(Duration.ofSeconds(1)); rs.onEvent("jdk.CPULoad", System.out::println); rs.onEvent("jdk.GCPhasePause", System.out::println); rs.start(); }
Constructor | Description |
---|---|
RemoteRecordingStream |
Creates an event stream that operates against a MBeanServerConnection that has a registered FlightRecorderMXBean . |
RemoteRecordingStream |
Creates an event stream that operates against a MBeanServerConnection that has a registered FlightRecorderMXBean . |
Modifier and Type | Method | Description |
---|---|---|
void |
awaitTermination() |
Blocks until all actions are completed, or the stream is closed, or the current thread is interrupted, whichever happens first. |
void |
awaitTermination |
Blocks until all actions are completed, or the stream is closed, or the timeout occurs, or the current thread is interrupted, whichever happens first. |
void |
close() |
Releases all resources associated with this stream. |
EventSettings |
disable |
Disables event with the specified name. |
void |
dump |
Writes recording data to a file. |
EventSettings |
enable |
Enables the event with the specified name. |
void |
onClose |
Registers an action to perform when the stream is closed. |
void |
onError |
Registers an action to perform if an exception occurs. |
void |
onEvent |
Registers an action to perform on all events matching a name. |
void |
onEvent |
Registers an action to perform on all events in the stream. |
void |
onFlush |
Registers an action to perform after the stream has been flushed. |
boolean |
remove |
Unregisters an action. |
void |
setEndTime |
Specifies the end time of the stream. |
void |
setMaxAge |
Determines how far back data is kept for the stream. |
void |
setMaxSize |
Determines how much data is kept for the stream. |
void |
setOrdered |
Specifies that events arrives in chronological order, sorted by the time they were committed to the stream. |
void |
setReuse |
Specifies that the event object in an EventStream.onEvent(Consumer) action can be reused. |
void |
setSettings |
Replaces all settings for this recording stream. |
void |
setStartTime |
Specifies the start time of the stream. |
void |
start() |
Starts processing of actions. |
void |
startAsync() |
Starts asynchronous processing of actions. |
boolean |
stop() |
Stops the recording stream. |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
onMetadata
public RemoteRecordingStream(MBeanServerConnection connection) throws IOException
MBeanServerConnection
that has a registered FlightRecorderMXBean
. To configure event settings, use setSettings(Map)
.
connection
- the MBeanServerConnection
where the FlightRecorderMXBean
is registered, not null
IOException
- if a stream can't be opened, an I/O error occurs when trying to access the repository or the FlightRecorderMXBean
SecurityException
- if a security manager exists and its checkRead
method denies read access to the directory, or files in the directory.public RemoteRecordingStream(MBeanServerConnection connection, Path directory) throws IOException
MBeanServerConnection
that has a registered FlightRecorderMXBean
. To configure event settings, use setSettings(Map)
.
connection
- the MBeanServerConnection
where the FlightRecorderMXBean
is registered, not null
directory
- the directory to store event data that is downloaded, not null
IOException
- if a stream can't be opened, an I/O error occurs when trying to access the repository or the FlightRecorderMXBean
SecurityException
- if a security manager exists and its checkRead
method denies read access to the directory, or files in the directory.public void setSettings(Map<String,String> settings)
The following example connects to a remote host and stream events using settings from the "default" configuration.
{ String host = "com.example"; int port = 4711; String url = "service:jmx:rmi:///jndi/rmi://" + host + ":" + port + "/jmxrmi"; JMXServiceURL u = new JMXServiceURL(url); JMXConnector c = JMXConnectorFactory.connect(u); MBeanServerConnection conn = c.getMBeanServerConnection(); try (final var rs = new RemoteRecordingStream(conn)) { rs.onMetadata(e -> { for (Configuration c : e.getConfigurations()) { if (c.getName().equals("default")) { rs.setSettings(c.getSettings()); } } }); rs.onEvent(System.out::println); rs.start(); }
settings
- the settings to set, not null
public EventSettings disable(String name)
If multiple events with same name (for example, the same class is loaded in different class loaders), then all events that match the name are disabled.
name
- the settings for the event, not null
null
public EventSettings enable(String name)
If multiple events have the same name (for example, the same class is loaded in different class loaders), then all events that match the name are enabled.
name
- the settings for the event, not null
null
public void setMaxAge(Duration maxAge)
To control the amount of recording data stored on disk, the maximum length of time to retain the data can be specified. Data stored on disk that is older than the specified length of time is removed by the Java Virtual Machine (JVM).
If neither maximum limit or the maximum age is set, the size of the recording may grow indefinitely if events are not consumed.
maxAge
- the length of time that data is kept, or null
if infiniteIllegalArgumentException
- if maxAge
is negativeIllegalStateException
- if the recording is in the CLOSED
statepublic void setMaxSize(long maxSize)
To control the amount of recording data that is stored on disk, the maximum amount of data to retain can be specified. When the maximum limit is exceeded, the Java Virtual Machine (JVM) removes the oldest chunk to make room for a more recent chunk.
If neither maximum limit or the maximum age is set, the size of the recording may grow indefinitely if events are not consumed.
The size is measured in bytes.
maxSize
- the amount of data to retain, 0
if infiniteIllegalArgumentException
- if maxSize
is negativeIllegalStateException
- if the recording is in CLOSED
statepublic void onEvent(Consumer<RecordedEvent> action)
EventStream
To perform an action on a subset of event types, consider using EventStream.onEvent(String, Consumer)
and EventStream.onMetadata(Consumer)
as it is likely more performant than any selection or filtering mechanism implemented in a generic action.
onEvent
in interface EventStream
action
- an action to perform on each RecordedEvent
, not null
public void onEvent(String eventName, Consumer<RecordedEvent> action)
EventStream
onEvent
in interface EventStream
eventName
- the name of the event, not null
action
- an action to perform on each RecordedEvent
matching the event name, not null
public void onFlush(Runnable action)
EventStream
onFlush
in interface EventStream
action
- an action to perform after the stream has been flushed, not null
public void onError(Consumer<Throwable> action)
EventStream
If an action is not registered, an exception stack trace is printed to standard error.
Registering an action overrides the default behavior. If multiple actions have been registered, they are performed in the order of registration.
If this method itself throws an exception, resulting behavior is undefined.
onError
in interface EventStream
action
- an action to perform if an exception occurs, not null
public void onClose(Runnable action)
EventStream
If the stream is already closed, the action will be performed immediately in the current thread.
onClose
in interface EventStream
action
- an action to perform after the stream is closed, not null
public void close()
EventStream
If a stream is started, asynchronously or synchronously, it is stopped immediately or after the next flush. This method does NOT guarantee that all registered actions are completed before return.
Closing a previously closed stream has no effect.
close
in interface AutoCloseable
close
in interface EventStream
public boolean remove(Object action)
EventStream
If the action has been registered multiple times, all instances are unregistered.
remove
in interface EventStream
action
- the action to unregister, not null
true
if the action was unregistered, false
otherwisepublic void setReuse(boolean reuse)
EventStream
EventStream.onEvent(Consumer)
action can be reused. If reuse is set to true
, an action should not keep a reference to the event object after the action has completed.
setReuse
in interface EventStream
reuse
- true
if an event object can be reused, false
otherwisepublic void setOrdered(boolean ordered)
EventStream
setOrdered
in interface EventStream
ordered
- if event objects arrive in chronological order to EventStream.onEvent(Consumer)
public void setStartTime(Instant startTime)
EventStream
The start time must be set before starting the stream
setStartTime
in interface EventStream
startTime
- the start time, not null
public void setEndTime(Instant endTime)
EventStream
The end time must be set before starting the stream.
At end time, the stream is closed.
setEndTime
in interface EventStream
endTime
- the end time, not null
public void start()
EventStream
Actions are performed in the current thread.
To stop the stream, use the EventStream.close()
method.
start
in interface EventStream
public void startAsync()
EventStream
Actions are performed in a single separate thread.
To stop the stream, use the EventStream.close()
method.
startAsync
in interface EventStream
public boolean stop()
Stops a started stream and waits until all events in the recording have been consumed.
Invoking this method in an action, for example in the onEvent(Consumer)
method, could block the stream indefinitely. To stop the stream abruptly, use the close()
method.
The following code snippet illustrates how this method can be used in conjunction with the startAsync()
method to monitor what happens during a test method:
AtomicLong bytesWritten = new AtomicLong();
try (var r = new RemoteRecordingStream(connection)) {
r.setMaxSize(Long.MAX_VALUE);
r.enable("jdk.FileWrite").withoutThreshold();
r.onEvent(event ->
bytesWritten.addAndGet(event.getLong("bytesWritten"))
);
r.startAsync();
testFoo();
r.stop();
if (bytesWritten.get() > 1_000_000L) {
r.dump(Path.of("file-write-events.jfr"));
throw new AssertionError("testFoo() writes too much data to disk");
}
}
true
if recording is stopped, false
otherwiseIllegalStateException
- if the recording is not started or is already stoppedpublic void dump(Path destination) throws IOException
The recording stream must be started, but not closed.
It's highly recommended that a max age or max size is set before starting the stream. Otherwise, the dump may not contain any events.
destination
- the location where recording data is written, not null
IOException
- if the recording data can't be copied to the specified location, or if the stream is closed, or not started.SecurityException
- if a security manager exists and the caller doesn't have FilePermission
to write to the destination pathpublic void awaitTermination(Duration timeout) throws InterruptedException
EventStream
awaitTermination
in interface EventStream
timeout
- the maximum time to wait, not null
InterruptedException
- if interrupted while waitingpublic void awaitTermination() throws InterruptedException
EventStream
awaitTermination
in interface EventStream
InterruptedException
- if interrupted while waiting
© 1993, 2023, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
https://docs.oracle.com/en/java/javase/21/docs/api/jdk.management.jfr/jdk/management/jfr/RemoteRecordingStream.html