Интерфейс EventStream
- Все суперинтерфейсы:
AutoCloseable
- Все известные реализующие классы:
-
RecordingStream,RemoteRecordingStream
public interface EventStream extends AutoCloseable
Поток — это последовательность событий, а способ взаимодействия с потоком — регистрация действий. Интерфейс EventStream не следует реализовывать, и будущие версии JDK могут вообще запретить это.
Для получения уведомления при поступлении события зарегистрируйте действие, используя метод onEvent(Consumer). Для фильтрации потока по событию с определенным именем используйте метод onEvent(String, Consumer).
По умолчанию один и тот же объект RecordedEvent может использоваться для представления двух или более различных событий. Этот объект может быть доставлен несколько раз одному и тому же действию, а также другим действиям. Чтобы использовать объект события после завершения действия, метод setReuse(boolean) должен быть установлен в значение false, чтобы для каждого события выделялся новый объект.
События доставляются партиями. Для получения уведомления о завершении пакетной обработки зарегистрируйте действие, используя метод onFlush(Runnable). Это возможность агрегировать или отправлять данные во внешние системы, пока виртуальная машина Java (JVM) готовит следующую партию.
События в пределах партии сортируются по времени завершения в хронологическом порядке. Правильная упорядоченность событий сохраняется только для событий, доступных JVM в момент сброса, то есть для набора событий, доставленных как единица в одной партии. События, доставленные в партии, могут быть вне порядка по сравнению с событиями, доставленными в предыдущей партии, но никогда не вне порядка с событиями в той же партии. Если порядок не является проблемой, сортировка может быть отключена с помощью метода setOrdered(boolean).
Для отправки событий зарегистрированным действиям поток должен быть запущен. Для запуска обработки в текущей нити вызовите метод start(). Для асинхронной обработки действий в отдельной нити вызовите метод startAsync(). Для ожидания завершения потока используйте метод ожидания завершения awaitTermination() или awaitTermination(Duration).
Когда поток завершается, он автоматически закрывается. Чтобы вручную остановить обработку событий, закройте поток, вызвав метод close(). Поток также может быть автоматически закрыт в исключительных обстоятельствах, например, если выходит из строя отслеживаемая JVM. Для получения уведомления в любом из этих случаев используйте метод onClose(Runnable) для регистрации действия.
Если в действии произойдет непредвиденное исключение, можно перехватить исключение в обработчике ошибок. Обработчик ошибок может быть зарегистрирован с помощью метода onError(Consumer). Если обработчик ошибок не зарегистрирован, по умолчанию поведение заключается в выводе исключения и его стека вызовов в стандартный поток ошибок.
Следующий пример демонстрирует, как использовать EventStream для прослушивания событий в работающей JVM с Flight Recorder
try (var es = EventStream.openRepository()) {
es.onEvent("jdk.CPULoad", event -> {
System.out.println("CPU Load " + event.getEndTime());
System.out.println(" Machine total: " + 100 * event.getFloat("machineTotal") + "%");
System.out.println(" JVM User: " + 100 * event.getFloat("jvmUser") + "%");
System.out.println(" JVM System: " + 100 * event.getFloat("jvmSystem") + "%");
System.out.println();
});
es.onEvent("jdk.GarbageCollection", event -> {
System.out.println("Garbage collection: " + event.getLong("gcId"));
System.out.println(" Cause: " + event.getString("cause"));
System.out.println(" Total pause: " + event.getDuration("sumOfPauses"));
System.out.println(" Longest pause: " + event.getDuration("longestPause"));
System.out.println();
});
es.start();
}
Чтобы начать запись вместе с потоком, см. RecordingStream.
- С момента:
- 14
Краткое описание методов
| Модификатор и тип | Метод | Описание |
|---|---|---|
void |
awaitTermination() |
Ожидает завершения всех действий, или закрытия потока, или прерывания текущей нити, что произойдет раньше. |
void |
awaitTermination |
Ожидает завершения всех действий, или закрытия потока, или истечения таймаута, или прерывания текущей нити, что произойдет раньше. |
void |
close() |
Освобождает все ресурсы, связанные с этим потоком. |
void |
onClose |
Регистрирует действие, которое выполняется при закрытии потока. |
void |
onError |
Регистрирует действие, которое выполняется при возникновении исключения. |
void |
onEvent |
Регистрирует действие, которое выполняется для всех событий, соответствующих имени. |
void |
onEvent |
Регистрирует действие, которое выполняется для всех событий в потоке. |
void |
onFlush |
Регистрирует действие, которое выполняется после сброса потока. |
default void |
onMetadata |
Регистрирует действие, которое выполняется при поступлении новых метаданных в поток. |
static EventStream |
openFile |
Создает поток событий из файла. |
static EventStream |
openRepository() |
Создает поток из репозитория текущей виртуальной машины Java (JVM). |
static EventStream |
openRepository |
Создает поток событий из дискового репозитория. |
boolean |
remove |
Отменяет регистрацию действия. |
void |
setEndTime |
Устанавливает конечное время потока. |
void |
setOrdered |
Указывает, что события поступают в хронологическом порядке, отсортированные по времени их добавления в поток. |
void |
setReuse |
Указывает, что объект события в действии onEvent(Consumer) может быть повторно использован. |
void |
setStartTime |
Устанавливает начальное время потока. |
void |
start() |
Запускает обработку действий. |
void |
startAsync() |
Запускает асинхронную обработку действий. |
Подробности методов
openRepository
static EventStream openRepository() throws IOException
По умолчанию поток начинается с следующего события, сброшенного Flight Recorder.
- Возвращает:
- поток событий, не
null - Выбрасывает:
-
IOException- если поток не может быть открыт, или произошла ошибка ввода-вывода при попытке доступа к хранилищу -
SecurityException- если существует менеджер безопасности, и у вызывающего объекта нетFlightRecorderPermission("accessFlightRecorder")
openRepository
static EventStream openRepository(Path directory) throws IOException
По умолчанию поток начинается с следующего события, сброшенного Flight Recorder.
Следует открывать только надёжные хранилища на диске.
- Параметры:
-
directory- расположение хранилища на диске, неnull - Возвращает:
- поток событий, не
null - Выбрасывает:
-
IOException- если поток не может быть открыт, или произошла ошибка ввода-вывода при попытке доступа к хранилищу -
SecurityException- если существует менеджер безопасности, и его методcheckReadзапрещает чтение каталога или файлов в нём.
openFile
static EventStream openFile(Path file) throws IOException
По умолчанию поток начинается с первого события в файле.
Следует открывать только файлы записей из надёжных источников.
- Параметры:
-
file- расположение файла, неnull - Возвращает:
- поток событий, не
null - Выбрасывает:
-
IOException- если файл не может быть открыт, или при чтении произошла ошибка ввода-вывода -
SecurityException- если существует менеджер безопасности, и его методcheckReadзапрещает чтение файла
onMetadata
default void onMetadata(Consumer<MetadataEvent> action)
Следующий пример демонстрирует, как прослушивать новые типы событий, регистрировать действие, если имя типа события соответствует регулярному выражению, и увеличивать счётчик, если найдено соответствующее событие. Преимущество использования действия на основе типа события вместо универсального метода onEvent(Consumer) заключается в том, что реализация потока может избегать чтения событий, которые не представляют интереса.
static long count = 0;
public static void main(String... args) throws IOException {
Path file = Path.of(args[0]);
String regExp = args[1];
var pr = Pattern.compile(regExp).asMatchPredicate();
try (var s = EventStream.openFile(file)) {
s.setOrdered(false);
s.onMetadata(metadata -> metadata.getAddedEventTypes()
.stream().map(EventType::getName).filter(pr)
.forEach(eventName -> s.onEvent(eventName, event -> count++)));
s.start();
System.out.println(count + " events matches " + regExp);
}
}
- Требования к реализации:
- По умолчанию этот метод пуст.
- Параметры:
-
action- для выполнения, неnull - Выбрасывает:
-
IllegalStateException- если действие добавлено после запуска потока - С:
- 16
onEvent
void onEvent(Consumer<RecordedEvent> action)
Для выполнения действия над подмножеством типов событий рекомендуется использовать onEvent(String, Consumer) и onMetadata(Consumer), так как это, скорее всего, будет более производительным, чем любые механизмы выбора или фильтрации, реализованные в универсальном действии.
- Параметры:
-
action- действие для выполнения для каждогоRecordedEvent, неnull - См. также:
onEvent
void onEvent(String eventName, Consumer<RecordedEvent> action)
- Параметры:
-
eventName- имя события, неnull -
action- действие для выполнения для каждогоRecordedEvent, соответствующего имени события, неnull
onFlush
void onFlush(Runnable action)
- Параметры:
-
action- действие для выполнения после сброса потока, неnull
onError
void onError(Consumer<Throwable> action)
Если действие не зарегистрировано, стек исключений выводится в стандартный вывод ошибок.
Регистрация действия переопределяет стандартное поведение. Если зарегистрировано несколько действий, они выполняются в порядке регистрации.
Если сам этот метод генерирует исключение, поведение является неопределённым.
- Параметры:
-
action- действие для выполнения в случае возникновения исключения, неnull
onClose
void onClose(Runnable action)
Если поток уже закрыт, действие будет выполнено немедленно в текущем потоке.
- Параметры:
-
action- действие для выполнения после закрытия потока, неnull - См. также:
close
void close()
Если поток запущен, асинхронно или синхронно, он останавливается немедленно или после следующего сброса. Этот метод НЕ гарантирует, что все зарегистрированные действия будут завершены до возвращения.
Закрытие уже закрытого потока не имеет эффекта.
- Определено в:
-
closeв интерфейсеAutoCloseable
remove
boolean remove(Object action)
Если действие было зарегистрировано несколько раз, все экземпляры будут удалены.
- Параметры:
-
action- действие для удаления, неnull - Возвращает:
-
trueесли действие было удалено,falseв противном случае - См. также:
setReuse
void setReuse(boolean reuse)
onEvent(Consumer) может быть повторно использован. Если переиспользование установлено в true, действие не должно сохранять ссылку на объект события после завершения действия.
- Параметры:
-
reuse-trueесли объект события может быть повторно использован,falseв противном случае
setOrdered
void setOrdered(boolean ordered)
- Параметры:
-
ordered- если объекты событий поступают в хронологическом порядке вonEvent(Consumer)
setStartTime
void setStartTime(Instant startTime)
Начальное время должно быть установлено до запуска потока
- Параметры:
-
startTime- начальное время, неnull - Выбрасывает:
-
IllegalStateException- если поток уже запущен - См. также:
setEndTime
void setEndTime(Instant endTime)
Конечное время должно быть установлено до запуска потока.
В момент конечного времени поток закрывается.
- Параметры:
-
endTime- конечное время, неnull - Выбрасывает:
-
IllegalStateException- если поток уже запущен - См. также:
start
void start()
Действия выполняются в текущем потоке.
Для остановки потока используйте метод close().
- Выбрасывает:
-
IllegalStateException- если поток уже запущен или закрыт
startAsync
void startAsync()
Действия выполняются в отдельном потоке.
Для остановки потока используйте метод close().
- Выбрасывает:
-
IllegalStateException- если поток уже запущен или закрыт
awaitTermination
void awaitTermination(Duration timeout) throws InterruptedException
- Parameters:
-
timeout- максимальное время ожидания, неnull - Throws:
-
IllegalArgumentException- если таймаут отрицательный -
InterruptedException- если ожидание прервано - See Also:
awaitTermination
void awaitTermination() throws InterruptedException
- Throws:
-
InterruptedException- если ожидание прервано - See Also:
© 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.jfr/jdk/jfr/consumer/EventStream.html