Class RecordingStream

java.lang.Object
jdk.jfr.consumer.RecordingStream
All Implemented Interfaces:
AutoCloseable, EventStream

public final class RecordingStream extends Object implements AutoCloseable, EventStream
A recording stream produces events from the current JVM (Java Virtual Machine).

The following example shows how to record events using the default configuration and print the Garbage Collection, CPU Load and JVM Information event to standard out.

Configuration c = Configuration.getConfiguration("default");
try (var rs = new RecordingStream(c)) {
    rs.onEvent("jdk.GarbageCollection", System.out::println);
    rs.onEvent("jdk.CPULoad", System.out::println);
    rs.onEvent("jdk.JVMInformation", System.out::println);
    rs.start();
}
Since:
14
  • Constructor Details

    • RecordingStream

      public RecordingStream()
      Creates an event stream for the current JVM (Java Virtual Machine).
      Throws:
      IllegalStateException - if Flight Recorder can't be created (for example, if the Java Virtual Machine (JVM) lacks Flight Recorder support, or if the file repository can't be created or accessed)
    • RecordingStream

      public RecordingStream(Configuration configuration)
      Creates a recording stream using settings from a configuration.

      The following example shows how to create a recording stream that uses a predefined configuration.

      var c = Configuration.getConfiguration("default");
      try (var rs = new RecordingStream(c)) {
          rs.onEvent(System.out::println);
          rs.start();
      }
      
      Parameters:
      configuration - configuration that contains the settings to use, not null
      Throws:
      IllegalStateException - if Flight Recorder can't be created (for example, if the Java Virtual Machine (JVM) lacks Flight Recorder support, or if the file repository can't be created or accessed)
      See Also:
  • Method Details

    • enable

      public EventSettings enable(String name)
      Enables the event with the specified 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. To enable a specific class, use the enable(Class) method or a String representation of the event type ID.

      Parameters:
      name - the settings for the event, not null
      Returns:
      an event setting for further configuration, not null
      See Also:
    • setSettings

      public void setSettings(Map<String,String> settings)
      Replaces all settings for this recording stream.

      The following example records 20 seconds using the "default" configuration and then changes settings to the "profile" configuration.

      Configuration defaultConfiguration = Configuration.getConfiguration("default");
      Configuration profileConfiguration = Configuration.getConfiguration("profile");
      try (var rs = new RecordingStream(defaultConfiguration)) {
          rs.onEvent(System.out::println);
          rs.startAsync();
          Thread.sleep(20_000);
          rs.setSettings(profileConfiguration.getSettings());
          Thread.sleep(20_000);
      }
      
      Parameters:
      settings - the settings to set, not null
      See Also:
    • enable

      public EventSettings enable(Class<? extends Event> eventClass)
      Enables event.
      Parameters:
      eventClass - the event to enable, not null
      Returns:
      an event setting for further configuration, not null
      Throws:
      IllegalArgumentException - if eventClass is an abstract class or not a subclass of Event
    • disable

      public EventSettings disable(String name)
      Disables event with the specified 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. To disable a specific class, use the disable(Class) method or a String representation of the event type ID.

      Parameters:
      name - the settings for the event, not null
      Returns:
      an event setting for further configuration, not null
    • disable

      public EventSettings disable(Class<? extends Event> eventClass)
      Disables event.
      Parameters:
      eventClass - the event to enable, not null
      Returns:
      an event setting for further configuration, not null
      Throws:
      IllegalArgumentException - if eventClass is an abstract class or not a subclass of Event
    • setMaxAge

      public void setMaxAge(Duration maxAge)
      Determines how far back data is kept for the stream.

      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 on

      Parameters:
      maxAge - the length of time that data is kept, or null if infinite
      Throws:
      IllegalArgumentException - if maxAge is negative
      IllegalStateException - if the recording is in the CLOSED state
    • setMaxSize

      public void setMaxSize(long maxSize)
      Determines how much data is kept for the stream.

      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.

      The size is measured in bytes.

      Parameters:
      maxSize - the amount of data to retain, 0 if infinite
      Throws:
      IllegalArgumentException - if maxSize is negative
      IllegalStateException - if the recording is in CLOSED state
    • setReuse

      public void setReuse(boolean reuse)
      Description copied from interface: EventStream
      Specifies that the event object in an 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.

      Specified by:
      setReuse in interface EventStream
      Parameters:
      reuse - true if an event object can be reused, false otherwise
    • setOrdered

      public void setOrdered(boolean ordered)
      Description copied from interface: EventStream
      Specifies that events arrives in chronological order, sorted by the time they were committed to the stream.
      Specified by:
      setOrdered in interface EventStream
      Parameters:
      ordered - if event objects arrive in chronological order to EventStream.onEvent(Consumer)
    • setStartTime

      public void setStartTime(Instant startTime)
      Description copied from interface: EventStream
      Specifies the start time of the stream.

      The start time must be set before starting the stream

      Specified by:
      setStartTime in interface EventStream
      Parameters:
      startTime - the start time, not null
      See Also:
    • setEndTime

      public void setEndTime(Instant endTime)
      Description copied from interface: EventStream
      Specifies the end time of the stream.

      The end time must be set before starting the stream.

      At end time, the stream is closed.

      Specified by:
      setEndTime in interface EventStream
      Parameters:
      endTime - the end time, not null
      See Also:
    • onEvent

      public void onEvent(String eventName, Consumer<RecordedEvent> action)
      Description copied from interface: EventStream
      Registers an action to perform on all events matching a name.
      Specified by:
      onEvent in interface EventStream
      Parameters:
      eventName - the name of the event, not null
      action - an action to perform on each RecordedEvent matching the event name, not null
    • onEvent

      public void onEvent(Consumer<RecordedEvent> action)
      Description copied from interface: EventStream
      Registers an action to perform on all events in the stream.

      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.

      Specified by:
      onEvent in interface EventStream
      Parameters:
      action - an action to perform on each RecordedEvent, not null
      See Also:
    • onFlush

      public void onFlush(Runnable action)
      Description copied from interface: EventStream
      Registers an action to perform after the stream has been flushed.
      Specified by:
      onFlush in interface EventStream
      Parameters:
      action - an action to perform after the stream has been flushed, not null
    • onClose

      public void onClose(Runnable action)
      Description copied from interface: EventStream
      Registers an action to perform when the stream is closed.

      If the stream is already closed, the action will be performed immediately in the current thread.

      Specified by:
      onClose in interface EventStream
      Parameters:
      action - an action to perform after the stream is closed, not null
      See Also:
    • onError

      public void onError(Consumer<Throwable> action)
      Description copied from interface: EventStream
      Registers an action to perform if an exception occurs.

      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.

      Specified by:
      onError in interface EventStream
      Parameters:
      action - an action to perform if an exception occurs, not null
    • close

      public void close()
      Description copied from interface: AutoCloseable
      Closes this resource, relinquishing any underlying resources. This method is invoked automatically on objects managed by the try-with-resources statement.
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface EventStream
    • remove

      public boolean remove(Object action)
      Description copied from interface: EventStream
      Unregisters an action.

      If the action has been registered multiple times, all instances are unregistered.

      Specified by:
      remove in interface EventStream
      Parameters:
      action - the action to unregister, not null
      Returns:
      true if the action was unregistered, false otherwise
      See Also:
    • start

      public void start()
      Description copied from interface: EventStream
      Starts processing of actions.

      Actions are performed in the current thread.

      To stop the stream, use the EventStream.close() method.

      Specified by:
      start in interface EventStream
    • startAsync

      public void startAsync()
      Starts asynchronous processing of actions.

      Actions are performed in a single separate thread.

      To stop the stream, use the close() method.

      The following example prints the CPU usage for ten seconds. When the current thread leaves the try-with-resources block the stream is stopped/closed.

      try (var stream = new RecordingStream()) {
          stream.enable("jdk.CPULoad").withPeriod(Duration.ofSeconds(1));
          stream.onEvent("jdk.CPULoad", event -> {
              System.out.println(event);
          });
          stream.startAsync();
          Thread.sleep(10_000);
      }
      
      Specified by:
      startAsync in interface EventStream
      Throws:
      IllegalStateException - if the stream is already started or closed
    • stop

      public boolean stop()
      Stops the recording stream.

      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:

      AtomicBoolean socketUse = new AtomicBoolean();
      try (var r = new RecordingStream()) {
          r.setMaxSize(Long.MAX_VALUE);
          r.enable("jdk.SocketWrite").withoutThreshold();
          r.enable("jdk.SocketRead").withoutThreshold();
          r.onEvent(event -> socketUse.set(true));
          r.startAsync();
          testFoo();
          r.stop();
          if (socketUse.get()) {
              r.dump(Path.of("socket-events.jfr"));
              throw new AssertionError("testFoo() should not use network");
          }
      }
      
      Returns:
      true if recording is stopped, false otherwise
      Throws:
      IllegalStateException - if the recording is not started or is already stopped
      Since:
      20
    • dump

      public void dump(Path destination) throws IOException
      Writes recording data to a file.

      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.

      Parameters:
      destination - the location where recording data is written, not null
      Throws:
      IOException - if the recording data can't be copied to the specified location, or if the stream is closed, or not started.
      Since:
      17
      See Also:
    • awaitTermination

      public void awaitTermination(Duration timeout) throws InterruptedException
      Description copied from interface: EventStream
      Blocks until all actions are completed, or the stream is closed, or the timeout occurs, or the current thread is interrupted, whichever happens first.
      Specified by:
      awaitTermination in interface EventStream
      Parameters:
      timeout - the maximum time to wait, not null
      Throws:
      InterruptedException - if interrupted while waiting
      See Also:
    • awaitTermination

      public void awaitTermination() throws InterruptedException
      Description copied from interface: EventStream
      Blocks until all actions are completed, or the stream is closed, or the current thread is interrupted, whichever happens first.
      Specified by:
      awaitTermination in interface EventStream
      Throws:
      InterruptedException - if interrupted while waiting
      See Also: