45 |
45 |
46 /** |
46 /** |
47 * A recording stream produces events from the current JVM (Java Virtual |
47 * A recording stream produces events from the current JVM (Java Virtual |
48 * Machine). |
48 * Machine). |
49 * <p> |
49 * <p> |
50 * The following example records events using the default configuration and |
50 * The following example, shows how to record events using the default |
51 * prints the Garbage Collection, CPU Load and JVM Information event. |
51 * configuration and print the Garbage Collection, CPU Load and JVM Information |
|
52 * event to standard out. |
52 * |
53 * |
53 * <pre> |
54 * <pre> |
54 * <code> |
55 * <code> |
55 * var c = Configuration.getConfiguration("default"); |
56 * Configuration c = Configuration.getConfiguration("default"); |
56 * try (var rs = new RecordingStream(c)) { |
57 * try (RecordingStream rs = new RecordingStream(c)) { |
57 * rs.onEvent("jdk.GarbageCollection", System.out::println); |
58 * rs.onEvent("jdk.GarbageCollection", System.out::println); |
58 * rs.onEvent("jdk.CPULoad", System.out::println); |
59 * rs.onEvent("jdk.CPULoad", System.out::println); |
59 * rs.onEvent("jdk.JVMInformation", System.out::println); |
60 * rs.onEvent("jdk.JVMInformation", System.out::println); |
60 * rs.start(); |
61 * rs.start(); |
61 * } |
62 * } |
65 * |
66 * |
66 */ |
67 */ |
67 public final class RecordingStream implements AutoCloseable, EventStream { |
68 public final class RecordingStream implements AutoCloseable, EventStream { |
68 |
69 |
69 private final Recording recording; |
70 private final Recording recording; |
70 private final EventDirectoryStream stream; |
71 private final EventDirectoryStream directoryStream; |
71 |
72 |
72 /** |
73 /** |
73 * Creates an event stream for the current JVM (Java Virtual Machine). |
74 * Creates an event stream for the current JVM (Java Virtual Machine). |
74 * <p> |
|
75 * The following example shows how to create a recording stream that prints |
|
76 * CPU usage and information about garbage collections. |
|
77 * |
|
78 * <pre> |
|
79 * <code> |
|
80 * try (var rs = new RecordingStream()) { |
|
81 * rs.enable("jdk.GarbageCollection"); |
|
82 * rs.enable("jdk.CPULoad").withPeriod(Duration.ofSeconds(1)); |
|
83 * rs.onEvent(System.out::println); |
|
84 * rs.start(); |
|
85 * } |
|
86 * </code> |
|
87 * </pre> |
|
88 * |
75 * |
89 * @throws IllegalStateException if Flight Recorder can't be created (for |
76 * @throws IllegalStateException if Flight Recorder can't be created (for |
90 * example, if the Java Virtual Machine (JVM) lacks Flight Recorder |
77 * example, if the Java Virtual Machine (JVM) lacks Flight Recorder |
91 * support, or if the file repository can't be created or accessed) |
78 * support, or if the file repository can't be created or accessed) |
92 * |
79 * |
98 Utils.checkAccessFlightRecorder(); |
85 Utils.checkAccessFlightRecorder(); |
99 AccessControlContext acc = AccessController.getContext(); |
86 AccessControlContext acc = AccessController.getContext(); |
100 this.recording = new Recording(); |
87 this.recording = new Recording(); |
101 this.recording.setFlushInterval(Duration.ofMillis(1000)); |
88 this.recording.setFlushInterval(Duration.ofMillis(1000)); |
102 try { |
89 try { |
103 this.stream = new EventDirectoryStream(acc, null, SecuritySupport.PRIVILIGED, true); |
90 this.directoryStream = new EventDirectoryStream(acc, null, SecuritySupport.PRIVILIGED, true); |
104 } catch (IOException ioe) { |
91 } catch (IOException ioe) { |
|
92 this.recording.close(); |
105 throw new IllegalStateException(ioe.getMessage()); |
93 throw new IllegalStateException(ioe.getMessage()); |
106 } |
94 } |
107 } |
95 } |
108 |
96 |
109 /** |
97 /** |
272 */ |
260 */ |
273 public void setMaxSize(long maxSize) { |
261 public void setMaxSize(long maxSize) { |
274 recording.setMaxSize(maxSize); |
262 recording.setMaxSize(maxSize); |
275 } |
263 } |
276 |
264 |
|
265 /** |
|
266 * Determines how often events are made available for streaming. |
|
267 * |
|
268 * @param interval the interval at which events are made available to the |
|
269 * stream, no {@code null} |
|
270 * |
|
271 * @throws IllegalArgumentException if <code>interval</code> is negative |
|
272 * |
|
273 * @throws IllegalStateException if the stream is closed |
|
274 */ |
|
275 public void setFlushInterval(Duration interval) { |
|
276 recording.setFlushInterval(interval); |
|
277 } |
|
278 |
|
279 @Override |
|
280 public void setReuse(boolean reuse) { |
|
281 directoryStream.setReuse(reuse); |
|
282 } |
|
283 |
|
284 @Override |
|
285 public void setOrdered(boolean ordered) { |
|
286 directoryStream.setOrdered(ordered); |
|
287 } |
|
288 |
|
289 @Override |
|
290 public void setStartTime(Instant startTime) { |
|
291 directoryStream.setStartTime(startTime); |
|
292 } |
|
293 |
|
294 @Override |
|
295 public void setEndTime(Instant endTime) { |
|
296 directoryStream.setStartTime(endTime); |
|
297 } |
|
298 |
277 @Override |
299 @Override |
278 public void onEvent(String eventName, Consumer<RecordedEvent> action) { |
300 public void onEvent(String eventName, Consumer<RecordedEvent> action) { |
279 stream.onEvent(eventName, action); |
301 directoryStream.onEvent(eventName, action); |
280 } |
302 } |
281 |
303 |
282 @Override |
304 @Override |
283 public void onEvent(Consumer<RecordedEvent> action) { |
305 public void onEvent(Consumer<RecordedEvent> action) { |
284 stream.onEvent(action); |
306 directoryStream.onEvent(action); |
285 } |
307 } |
286 |
308 |
287 @Override |
309 @Override |
288 public void onFlush(Runnable action) { |
310 public void onFlush(Runnable action) { |
289 stream.onFlush(action); |
311 directoryStream.onFlush(action); |
290 } |
312 } |
291 |
313 |
292 @Override |
314 @Override |
293 public void onClose(Runnable action) { |
315 public void onClose(Runnable action) { |
294 stream.onClose(action); |
316 directoryStream.onClose(action); |
|
317 } |
|
318 |
|
319 @Override |
|
320 public void onError(Consumer<Throwable> action) { |
|
321 directoryStream.onError(action); |
295 } |
322 } |
296 |
323 |
297 @Override |
324 @Override |
298 public void close() { |
325 public void close() { |
299 recording.close(); |
326 recording.close(); |
300 stream.close(); |
327 directoryStream.close(); |
301 } |
328 } |
302 |
329 |
303 @Override |
330 @Override |
304 public boolean remove(Object action) { |
331 public boolean remove(Object action) { |
305 return stream.remove(action); |
332 return directoryStream.remove(action); |
306 } |
333 } |
307 |
334 |
308 @Override |
335 @Override |
309 public void start() { |
336 public void start() { |
310 PlatformRecording pr = PrivateAccess.getInstance().getPlatformRecording(recording); |
337 PlatformRecording pr = PrivateAccess.getInstance().getPlatformRecording(recording); |
311 long startNanos = pr.start(); |
338 long startNanos = pr.start(); |
312 stream.start(startNanos); |
339 directoryStream.start(startNanos); |
313 } |
340 } |
314 |
341 |
315 @Override |
342 @Override |
316 public void startAsync() { |
343 public void startAsync() { |
317 PlatformRecording pr = PrivateAccess.getInstance().getPlatformRecording(recording); |
344 PlatformRecording pr = PrivateAccess.getInstance().getPlatformRecording(recording); |
318 long startNanos = pr.start(); |
345 long startNanos = pr.start(); |
319 stream.startAsync(startNanos); |
346 directoryStream.startAsync(startNanos); |
320 } |
347 } |
321 |
348 |
322 @Override |
349 @Override |
323 public void awaitTermination(Duration timeout) { |
350 public void awaitTermination(Duration timeout) { |
324 stream.awaitTermination(timeout); |
351 directoryStream.awaitTermination(timeout); |
325 } |
|
326 |
|
327 /** |
|
328 * Determines how often events are made available for streaming. |
|
329 * |
|
330 * @param interval the interval at which events are made available to the |
|
331 * stream, no {@code null} |
|
332 * |
|
333 * @throws IllegalArgumentException if <code>interval</code> is negative |
|
334 * |
|
335 * @throws IllegalStateException if the stream is closed |
|
336 */ |
|
337 public void setFlushInterval(Duration interval) { |
|
338 recording.setFlushInterval(interval); |
|
339 } |
352 } |
340 |
353 |
341 @Override |
354 @Override |
342 public void awaitTermination() { |
355 public void awaitTermination() { |
343 stream.awaitTermination(); |
356 directoryStream.awaitTermination(); |
344 } |
|
345 |
|
346 @Override |
|
347 public void setReuse(boolean reuse) { |
|
348 stream.setReuse(reuse); |
|
349 } |
|
350 |
|
351 @Override |
|
352 public void setOrdered(boolean ordered) { |
|
353 stream.setOrdered(ordered); |
|
354 } |
|
355 |
|
356 @Override |
|
357 public void setStartTime(Instant startTime) { |
|
358 stream.setStartTime(startTime); |
|
359 } |
|
360 |
|
361 @Override |
|
362 public void setEndTime(Instant endTime) { |
|
363 stream.setStartTime(endTime); |
|
364 } |
|
365 |
|
366 @Override |
|
367 public void onError(Consumer<Throwable> action) { |
|
368 stream.onError(action); |
|
369 } |
357 } |
370 } |
358 } |