mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-07 00:48:38 +00:00
8279613: JFR: Snippify Javadoc
Reviewed-by: mgronlun
This commit is contained in:
parent
8a662105c2
commit
2f71a6b39e
@ -46,22 +46,7 @@ import jdk.jfr.internal.Utils;
|
||||
* <p>
|
||||
* The following example shows how {@code AnnotationElement} can be used to dynamically define events.
|
||||
*
|
||||
* <pre>{@literal
|
||||
* List<AnnotationElement> typeAnnotations = new ArrayList<>();
|
||||
* typeAnnotations.add(new AnnotationElement(Name.class, "com.example.HelloWorld"));
|
||||
* typeAnnotations.add(new AnnotationElement(Label.class, "Hello World"));
|
||||
* typeAnnotations.add(new AnnotationElement(Description.class, "Helps programmer getting started"));
|
||||
*
|
||||
* List<AnnotationElement> fieldAnnotations = new ArrayList<>();
|
||||
* fieldAnnotations.add(new AnnotationElement(Label.class, "Message"));
|
||||
*
|
||||
* List<ValueDescriptor> fields = new ArrayList<>();
|
||||
* fields.add(new ValueDescriptor(String.class, "message", fieldAnnotations));
|
||||
*
|
||||
* EventFactory f = EventFactory.create(typeAnnotations, fields);
|
||||
* Event event = f.newEvent();
|
||||
* event.commit();
|
||||
* }</pre>
|
||||
* {@snippet class="Snippets" region="AnnotationElementOverview"}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
|
||||
@ -31,27 +31,7 @@ package jdk.jfr;
|
||||
* <p>
|
||||
* The following example shows how to implement an {@code Event} class.
|
||||
*
|
||||
* <pre>{@literal
|
||||
* import jdk.jfr.Event;
|
||||
* import jdk.jfr.Description;
|
||||
* import jdk.jfr.Label;
|
||||
*
|
||||
* public class Example {
|
||||
*
|
||||
* @Label("Hello World")
|
||||
* @Description("Helps programmer getting started")
|
||||
* static class HelloWorld extends Event {
|
||||
* @Label("Message")
|
||||
* String message;
|
||||
* }
|
||||
*
|
||||
* public static void main(String... args) {
|
||||
* HelloWorld event = new HelloWorld();
|
||||
* event.message = "hello, world!";
|
||||
* event.commit();
|
||||
* }
|
||||
* }
|
||||
* }</pre>
|
||||
* {@snippet class="Snippets" region="EventOverview"}
|
||||
* <p>
|
||||
* After an event is allocated and its field members are populated, it can be
|
||||
* written to the Flight Recorder system by using the {@link #commit()} method.
|
||||
|
||||
@ -52,29 +52,7 @@ import jdk.jfr.internal.Utils;
|
||||
* <p>
|
||||
* The following example shows how to implement a dynamic {@code Event} class.
|
||||
*
|
||||
* <pre>
|
||||
* {@code
|
||||
* List<ValueDescriptor> fields = new ArrayList<>();
|
||||
* List<AnnotationElement> messageAnnotations = Collections.singletonList(new AnnotationElement(Label.class, "Message"));
|
||||
* fields.add(new ValueDescriptor(String.class, "message", messageAnnotations));
|
||||
* List<AnnotationElement> numberAnnotations = Collections.singletonList(new AnnotationElement(Label.class, "Number"));
|
||||
* fields.add(new ValueDescriptor(int.class, "number", numberAnnotations));
|
||||
*
|
||||
* String[] category = { "Example", "Getting Started" };
|
||||
* List<AnnotationElement> eventAnnotations = new ArrayList<>();
|
||||
* eventAnnotations.add(new AnnotationElement(Name.class, "com.example.HelloWorld"));
|
||||
* eventAnnotations.add(new AnnotationElement(Label.class, "Hello World"));
|
||||
* eventAnnotations.add(new AnnotationElement(Description.class, "Helps programmer getting started"));
|
||||
* eventAnnotations.add(new AnnotationElement(Category.class, category));
|
||||
*
|
||||
* EventFactory f = EventFactory.create(eventAnnotations, fields);
|
||||
*
|
||||
* Event event = f.newEvent();
|
||||
* event.set(0, "hello, world!");
|
||||
* event.set(1, 4711);
|
||||
* event.commit();
|
||||
* }
|
||||
* </pre>
|
||||
* {@snippet class="Snippets" region="EventFactoryOverview"}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
|
||||
@ -38,21 +38,9 @@ import jdk.jfr.internal.management.EventSettingsModifier;
|
||||
* chaining.
|
||||
* <p>
|
||||
* The following example shows how to use the {@code EventSettings} class.
|
||||
* <pre>
|
||||
* {@code
|
||||
* Recording r = new Recording();
|
||||
* r.enable("jdk.CPULoad")
|
||||
* .withPeriod(Duration.ofSeconds(1));
|
||||
* r.enable("jdk.FileWrite")
|
||||
* .withoutStackTrace()
|
||||
* .withThreshold(Duration.ofNanos(10));
|
||||
* r.start();
|
||||
* Thread.sleep(10_000);
|
||||
* r.stop();
|
||||
* r.dump(Files.createTempFile("recording", ".jfr"));
|
||||
*
|
||||
* }
|
||||
* </pre>
|
||||
* {@snippet class="Snippets" region="EventSettingOverview"}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
public abstract class EventSettings {
|
||||
|
||||
@ -92,15 +92,7 @@ public final class FlightRecorder {
|
||||
* <p>
|
||||
* The following example shows how to create a snapshot and write a subset of the data to a file.
|
||||
*
|
||||
* <pre>{@literal
|
||||
* try (Recording snapshot = FlightRecorder.getFlightRecorder().takeSnapshot()) {
|
||||
* if (snapshot.getSize() > 0) {
|
||||
* snapshot.setMaxSize(100_000_000);
|
||||
* snapshot.setMaxAge(Duration.ofMinutes(5));
|
||||
* snapshot.dump(Paths.get("snapshot.jfr"));
|
||||
* }
|
||||
* }
|
||||
* }</pre>
|
||||
* {@snippet class="Snippets" region="FlightRecorderTakeSnapshot"}
|
||||
*
|
||||
* The caller must close the recording when access to the data is no longer
|
||||
* needed.
|
||||
|
||||
@ -36,36 +36,7 @@ import java.lang.annotation.Target;
|
||||
* In the following example, a transaction event is defined with two
|
||||
* user-defined annotations, {@code @Severity} and {@code @TransactionId}.
|
||||
*
|
||||
* <pre>{@literal
|
||||
* @MetadataDefinition
|
||||
* @Label("Severity")
|
||||
* @Description("Value between 0 and 100 that indicates severity. 100 is most severe.")
|
||||
* @Retention(RetentionPolicy.RUNTIME)
|
||||
* @Target({ElementType.TYPE})
|
||||
* public @interface Severity {
|
||||
* int value() default 50;
|
||||
* }
|
||||
*
|
||||
* @MetadataDefinition
|
||||
* @Label("Transaction Id")
|
||||
* @Relational
|
||||
* @Retention(RetentionPolicy.RUNTIME)
|
||||
* @Target({ElementType.FIELD})
|
||||
* public @interface TransactionId {
|
||||
* }
|
||||
*
|
||||
* @Severity(80)
|
||||
* @Label("Transaction Blocked")
|
||||
* class TransactionBlocked extends Event {
|
||||
* @TransactionId
|
||||
* @Label("Transaction")
|
||||
* long transactionId1;
|
||||
*
|
||||
* @TransactionId
|
||||
* @Label("Transaction Blocker")
|
||||
* long transactionId2;
|
||||
* }
|
||||
* }</pre>
|
||||
* {@snippet class="Snippets" region="MetadataDefinitionOverview"}
|
||||
*
|
||||
* Adding {@code @MetadataDefinition} to the declaration of {@code @Severity} and {@code @TransactionId}
|
||||
* ensures the information is saved by Flight Recorder.
|
||||
|
||||
@ -46,15 +46,7 @@ import jdk.jfr.internal.WriteableUserPath;
|
||||
* <p>
|
||||
* The following example shows how configure, start, stop and dump recording data to disk.
|
||||
*
|
||||
* <pre>{@literal
|
||||
* Configuration c = Configuration.getConfiguration("default");
|
||||
* Recording r = new Recording(c);
|
||||
* r.start();
|
||||
* System.gc();
|
||||
* Thread.sleep(5000);
|
||||
* r.stop();
|
||||
* r.dump(Files.createTempFile("my-recording", ".jfr"));
|
||||
* }</pre>
|
||||
* {@snippet class="Snippets" region="RecordingOverview"}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
@ -143,9 +135,9 @@ public final class Recording implements Closeable {
|
||||
* <p>
|
||||
* The following example shows how create a recording that uses a predefined configuration.
|
||||
*
|
||||
* <pre>{@literal
|
||||
* {@snippet :
|
||||
* Recording r = new Recording(Configuration.getConfiguration("default"));
|
||||
* }</pre>
|
||||
* }
|
||||
*
|
||||
* The newly created recording is in the {@link RecordingState#NEW} state. To
|
||||
* start the recording, invoke the {@link Recording#start()} method.
|
||||
@ -307,21 +299,21 @@ public final class Recording implements Closeable {
|
||||
* <p>
|
||||
* The following example shows how to set event settings for a recording.
|
||||
*
|
||||
* <pre>{@literal
|
||||
* {@snippet :
|
||||
* Map<String, String> settings = new HashMap<>();
|
||||
* settings.putAll(EventSettings.enabled("jdk.CPUSample").withPeriod(Duration.ofSeconds(2)).toMap());
|
||||
* settings.putAll(EventSettings.enabled(MyEvent.class).withThreshold(Duration.ofSeconds(2)).withoutStackTrace().toMap());
|
||||
* settings.put("jdk.ExecutionSample#period", "10 ms");
|
||||
* recording.setSettings(settings);
|
||||
* }</pre>
|
||||
* }
|
||||
*
|
||||
* The following example shows how to merge settings.
|
||||
*
|
||||
* <pre>{@literal
|
||||
* {@snippet :
|
||||
* Map<String, String> settings = recording.getSettings();
|
||||
* settings.putAll(additionalSettings);
|
||||
* recording.setSettings(settings);
|
||||
* }</pre>
|
||||
* }
|
||||
*
|
||||
* @param settings the settings to set, not {@code null}
|
||||
*/
|
||||
|
||||
@ -37,30 +37,7 @@ import jdk.jfr.internal.settings.JDKSettingControl;
|
||||
* The following example shows a naive implementation of a setting control for
|
||||
* regular expressions:
|
||||
*
|
||||
* <pre>{@literal
|
||||
* final class RegExpControl extends SettingControl {
|
||||
* private Pattern pattern = Pattern.compile(".*");
|
||||
*
|
||||
* @Override
|
||||
* public void setValue(String value) {
|
||||
* this.pattern = Pattern.compile(value);
|
||||
* }
|
||||
*
|
||||
* @Override
|
||||
* public String combine(Set<String> values) {
|
||||
* return String.join("|", values);
|
||||
* }
|
||||
*
|
||||
* @Override
|
||||
* public String getValue() {
|
||||
* return pattern.toString();
|
||||
* }
|
||||
*
|
||||
* public boolean matches(String s) {
|
||||
* return pattern.matcher(s).find();
|
||||
* }
|
||||
* }
|
||||
* }</pre>
|
||||
* {@snippet class="Snippets" region="SettingControlOverview1"}
|
||||
*
|
||||
* The {@code setValue(String)}, {@code getValue()} and
|
||||
* {@code combine(Set<String>)} methods are invoked when a setting value
|
||||
@ -85,55 +62,13 @@ import jdk.jfr.internal.settings.JDKSettingControl;
|
||||
* The following example shows how to create an event that uses the
|
||||
* regular expression filter defined above.
|
||||
*
|
||||
* <pre>{@literal
|
||||
* abstract class HTTPRequest extends Event {
|
||||
* @Label("Request URI")
|
||||
* protected String uri;
|
||||
*
|
||||
* @Label("Servlet URI Filter")
|
||||
* @SettingDefinition
|
||||
* protected boolean uriFilter(RegExpControl regExp) {
|
||||
* return regExp.matches(uri);
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @Label("HTTP Get Request")
|
||||
* class HTTPGetRequest extends HTTPRequest {
|
||||
* }
|
||||
*
|
||||
* @Label("HTTP Post Request")
|
||||
* class HTTPPostRequest extends HTTPRequest {
|
||||
* }
|
||||
*
|
||||
* class ExampleServlet extends HttpServlet {
|
||||
* protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
|
||||
* HTTPGetRequest request = new HTTPGetRequest();
|
||||
* request.begin();
|
||||
* request.uri = req.getRequestURI();
|
||||
* ...
|
||||
* request.commit();
|
||||
* }
|
||||
*
|
||||
* protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
|
||||
* HTTPPostRequest request = new HTTPPostRequest();
|
||||
* request.begin();
|
||||
* request.uri = req.getRequestURI();
|
||||
* ...
|
||||
* request.commit();
|
||||
* }
|
||||
* }
|
||||
* }</pre>
|
||||
* {@snippet class="Snippets" region="SettingControlOverview2"}
|
||||
*
|
||||
* <p>
|
||||
* The following example shows how an event can be filtered by assigning the
|
||||
* {@code "uriFilter"} setting with the specified regular expressions.
|
||||
*
|
||||
* <pre>{@literal
|
||||
* Recording r = new Recording();
|
||||
* r.enable("HTTPGetRequest").with("uriFilter", "https://www.example.com/list/.*");
|
||||
* r.enable("HTTPPostRequest").with("uriFilter", "https://www.example.com/login/.*");
|
||||
* r.start();
|
||||
* }</pre>
|
||||
* {@snippet class="Snippets" region="SettingControlOverview3"}
|
||||
*
|
||||
* @see SettingDefinition
|
||||
*
|
||||
|
||||
@ -95,25 +95,7 @@ import jdk.jfr.internal.consumer.FileAccess;
|
||||
* The following example shows how an {@code EventStream} can be used to listen
|
||||
* to events on a JVM running Flight Recorder
|
||||
*
|
||||
* <pre>{@literal
|
||||
* 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();
|
||||
* }
|
||||
* }</pre>
|
||||
* {@snippet class="Snippets" region="EventStreamOverview"}
|
||||
* <p>
|
||||
* To start recording together with the stream, see {@link RecordingStream}.
|
||||
*
|
||||
|
||||
@ -225,23 +225,7 @@ public class RecordedObject {
|
||||
* for callers of this method is to validate the field before attempting access.
|
||||
* <p>
|
||||
* Example
|
||||
*
|
||||
* <pre>{@literal
|
||||
* if (event.hasField("intValue")) {
|
||||
* int intValue = event.getValue("intValue");
|
||||
* System.out.println("Int value: " + intValue);
|
||||
* }
|
||||
*
|
||||
* if (event.hasField("objectClass")) {
|
||||
* RecordedClass clazz = event.getValue("objectClass");
|
||||
* System.out.println("Class name: " + clazz.getName());
|
||||
* }
|
||||
*
|
||||
* if (event.hasField("sampledThread")) {
|
||||
* RecordedThread sampledThread = event.getValue("sampledThread");
|
||||
* System.out.println("Sampled thread: " + sampledThread.getJavaName());
|
||||
* }
|
||||
* }</pre>
|
||||
* {@snippet class="Snippets" region="RecordedObjectGetValue"}
|
||||
*
|
||||
* @param <T> the return type
|
||||
* @param name of the field to get, not {@code null}
|
||||
|
||||
@ -49,14 +49,7 @@ import jdk.jfr.internal.consumer.RecordingInput;
|
||||
* <p>
|
||||
* The following example shows how read and print all events in a recording file.
|
||||
*
|
||||
* <pre>{@literal
|
||||
* try (RecordingFile recordingFile = new RecordingFile(Paths.get("recording.jfr"))) {
|
||||
* while (recordingFile.hasMoreEvents()) {
|
||||
* RecordedEvent event = recordingFile.readEvent();
|
||||
* System.out.println(event);
|
||||
* }
|
||||
* }
|
||||
* }</pre>
|
||||
* {@snippet class="Snippets" region="RecordingFileOverview"}
|
||||
*
|
||||
* @since 9
|
||||
*/
|
||||
|
||||
@ -56,15 +56,8 @@ import jdk.jfr.internal.consumer.EventDirectoryStream;
|
||||
* 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.
|
||||
* <pre>{@literal
|
||||
* 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();
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* {@snippet class="Snippets" region="RecordingStreamOverview"}
|
||||
*
|
||||
* @since 14
|
||||
*/
|
||||
@ -140,13 +133,7 @@ public final class RecordingStream implements AutoCloseable, EventStream {
|
||||
* The following example shows how to create a recording stream that uses a
|
||||
* predefined configuration.
|
||||
*
|
||||
* <pre>{@literal
|
||||
* var c = Configuration.getConfiguration("default");
|
||||
* try (var rs = new RecordingStream(c)) {
|
||||
* rs.onEvent(System.out::println);
|
||||
* rs.start();
|
||||
* }
|
||||
* }</pre>
|
||||
* {@snippet class="Snippets" region="RecordingStreamConstructor"}
|
||||
*
|
||||
* @param configuration configuration that contains the settings to use,
|
||||
* not {@code null}
|
||||
@ -189,17 +176,7 @@ public final class RecordingStream implements AutoCloseable, EventStream {
|
||||
* The following example records 20 seconds using the "default" configuration
|
||||
* and then changes settings to the "profile" configuration.
|
||||
*
|
||||
* <pre>{@literal
|
||||
* 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);
|
||||
* }
|
||||
* }</pre>
|
||||
* {@snippet class="Snippets" region="RecordingStreamSetSettings"}
|
||||
*
|
||||
* @param settings the settings to set, not {@code null}
|
||||
*
|
||||
@ -384,16 +361,8 @@ public final class RecordingStream implements AutoCloseable, EventStream {
|
||||
* 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.
|
||||
* <pre>{@literal
|
||||
* 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);
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* {@snippet class="Snippets" region="RecordingStreamStartAsync"}
|
||||
*
|
||||
* @throws IllegalStateException if the stream is already started or closed
|
||||
*/
|
||||
|
||||
@ -27,29 +27,8 @@
|
||||
* This package contains classes for consuming Flight Recorder data.
|
||||
* <p>
|
||||
* In the following example, the program prints a histogram of all method samples in a recording.
|
||||
* <pre>{@literal
|
||||
* public static void main(String[] args) throws IOException {
|
||||
* if (args.length != 1) {
|
||||
* System.err.println("Must specify a recording file.");
|
||||
* return;
|
||||
* }
|
||||
*
|
||||
* RecordingFile.readAllEvents(Path.of(args[0])).stream()
|
||||
* .filter(e -> e.getEventType().getName().equals("jdk.ExecutionSample"))
|
||||
* .map(e -> e.getStackTrace())
|
||||
* .filter(s -> s != null)
|
||||
* .map(s -> s.getFrames().get(0))
|
||||
* .filter(f -> f.isJavaFrame())
|
||||
* .map(f -> f.getMethod())
|
||||
* .collect(
|
||||
* Collectors.groupingBy(m -> m.getType().getName() + "." + m.getName() + " " + m.getDescriptor(),
|
||||
* Collectors.counting()))
|
||||
* .entrySet()
|
||||
* .stream()
|
||||
* .sorted((a, b) -> b.getValue().compareTo(a.getValue()))
|
||||
* .forEach(e -> System.out.printf("%8d %s\n", e.getValue(), e.getKey()));
|
||||
* }
|
||||
* }</pre>
|
||||
* {@snippet class="Snippets" region="PackageOverview"}
|
||||
* <p>
|
||||
* <b>Null-handling</b>
|
||||
* <p>
|
||||
|
||||
@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package example2;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.time.Duration;
|
||||
import java.util.stream.Collectors;
|
||||
import jdk.jfr.consumer.EventStream;
|
||||
import jdk.jfr.consumer.RecordingFile;
|
||||
import jdk.jfr.consumer.RecordedClass;
|
||||
import jdk.jfr.consumer.RecordedThread;
|
||||
import jdk.jfr.consumer.RecordingStream;
|
||||
import jdk.jfr.Configuration;
|
||||
import jdk.jfr.consumer.RecordedEvent;
|
||||
|
||||
public class Snippets {
|
||||
|
||||
class PackageOveriview {
|
||||
// @start region="PackageOverview"
|
||||
public static void main(String[] args) throws IOException {
|
||||
if (args.length != 1) {
|
||||
System.err.println("Must specify a recording file.");
|
||||
return;
|
||||
}
|
||||
|
||||
RecordingFile.readAllEvents(Path.of(args[0])).stream()
|
||||
.filter(e -> e.getEventType().getName().equals("jdk.ExecutionSample"))
|
||||
.map(e -> e.getStackTrace())
|
||||
.filter(s -> s != null)
|
||||
.map(s -> s.getFrames().get(0))
|
||||
.filter(f -> f.isJavaFrame())
|
||||
.map(f -> f.getMethod())
|
||||
.collect(
|
||||
Collectors.groupingBy(m -> m.getType().getName() + "." + m.getName() + " " + m.getDescriptor(),
|
||||
Collectors.counting()))
|
||||
.entrySet()
|
||||
.stream()
|
||||
.sorted((a, b) -> b.getValue().compareTo(a.getValue()))
|
||||
.forEach(e -> System.out.printf("%8d %s\n", e.getValue(), e.getKey()));
|
||||
}
|
||||
// @end
|
||||
}
|
||||
|
||||
void EventStreamOverview() throws Exception {
|
||||
// @start region="EventStreamOverview"
|
||||
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();
|
||||
}
|
||||
// @end
|
||||
}
|
||||
|
||||
void RecordingFileOverview() throws Exception {
|
||||
// @start region="RecordingFileOverview"
|
||||
try (RecordingFile recordingFile = new RecordingFile(Paths.get("recording.jfr"))) {
|
||||
while (recordingFile.hasMoreEvents()) {
|
||||
RecordedEvent event = recordingFile.readEvent();
|
||||
System.out.println(event);
|
||||
}
|
||||
}
|
||||
// @end
|
||||
}
|
||||
|
||||
void RecordedObjectGetValue() {
|
||||
RecordedEvent event = null;
|
||||
// @start region="RecordedObjectGetValue"
|
||||
if (event.hasField("intValue")) {
|
||||
int intValue = event.getValue("intValue");
|
||||
System.out.println("Int value: " + intValue);
|
||||
}
|
||||
|
||||
if (event.hasField("objectClass")) {
|
||||
RecordedClass clazz = event.getValue("objectClass");
|
||||
System.out.println("Class name: " + clazz.getName());
|
||||
}
|
||||
|
||||
if (event.hasField("sampledThread")) {
|
||||
RecordedThread sampledThread = event.getValue("sampledThread");
|
||||
System.out.println("Sampled thread: " + sampledThread.getJavaName());
|
||||
}
|
||||
// @end
|
||||
}
|
||||
|
||||
void RecordingStreamOverview() throws Exception {
|
||||
// @start region="RecordingStreamOverview"
|
||||
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();
|
||||
}
|
||||
// @end
|
||||
}
|
||||
|
||||
void RecordingStreamConstructor() throws Exception {
|
||||
// @start region="RecordingStreamConstructor"
|
||||
var c = Configuration.getConfiguration("default");
|
||||
try (var rs = new RecordingStream(c)) {
|
||||
rs.onEvent(System.out::println);
|
||||
rs.start();
|
||||
}
|
||||
// @end
|
||||
}
|
||||
|
||||
void RecordingStreamSetSettings() throws Exception {
|
||||
// @start region="RecordingStreamSetSettings"
|
||||
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);
|
||||
}
|
||||
// @end
|
||||
}
|
||||
|
||||
void RecordingStreamStartAsync() throws Exception {
|
||||
// @start region="RecordingStreamStartAsync"
|
||||
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);
|
||||
}
|
||||
// @end
|
||||
}
|
||||
}
|
||||
291
src/jdk.jfr/share/classes/jdk/jfr/snippet-files/Snippets.java
Normal file
291
src/jdk.jfr/share/classes/jdk/jfr/snippet-files/Snippets.java
Normal file
@ -0,0 +1,291 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package example1;
|
||||
|
||||
import jdk.jfr.AnnotationElement;
|
||||
import jdk.jfr.ValueDescriptor;
|
||||
import jdk.jfr.EventFactory;
|
||||
import jdk.jfr.Event;
|
||||
import jdk.jfr.Name;
|
||||
import jdk.jfr.Label;
|
||||
import jdk.jfr.Description;
|
||||
import jdk.jfr.Category;
|
||||
import jdk.jfr.Recording;
|
||||
import jdk.jfr.MetadataDefinition;
|
||||
import jdk.jfr.Relational;
|
||||
import jdk.jfr.consumer.RecordingFile;
|
||||
import jdk.jfr.Configuration;
|
||||
import jdk.jfr.SettingDefinition;
|
||||
import jdk.jfr.SettingControl;
|
||||
import jdk.jfr.FlightRecorder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.annotation.ElementType;
|
||||
|
||||
public class Snippets {
|
||||
|
||||
void AnnotationElementOverview() {
|
||||
// @start region="AnnotationElementOverview"
|
||||
List<AnnotationElement> typeAnnotations = new ArrayList<>();
|
||||
typeAnnotations.add(new AnnotationElement(Name.class, "com.example.HelloWorld"));
|
||||
typeAnnotations.add(new AnnotationElement(Label.class, "Hello World"));
|
||||
typeAnnotations.add(new AnnotationElement(Description.class, "Helps programmer getting started"));
|
||||
|
||||
List<AnnotationElement> fieldAnnotations = new ArrayList<>();
|
||||
fieldAnnotations.add(new AnnotationElement(Label.class, "Message"));
|
||||
|
||||
List<ValueDescriptor> fields = new ArrayList<>();
|
||||
fields.add(new ValueDescriptor(String.class, "message", fieldAnnotations));
|
||||
|
||||
EventFactory f = EventFactory.create(typeAnnotations, fields);
|
||||
Event event = f.newEvent();
|
||||
event.commit();
|
||||
// @end
|
||||
}
|
||||
|
||||
// @start region="EventOverview"
|
||||
public class Example {
|
||||
|
||||
@Label("Hello World")
|
||||
@Description("Helps programmer getting started")
|
||||
static class HelloWorld extends Event {
|
||||
@Label("Message")
|
||||
String message;
|
||||
}
|
||||
|
||||
public static void main(String... args) {
|
||||
HelloWorld event = new HelloWorld();
|
||||
event.message = "hello, world!";
|
||||
event.commit();
|
||||
}
|
||||
}
|
||||
// @end
|
||||
|
||||
void EventFactoryOverview() {
|
||||
// @start region="EventFactoryOverview"
|
||||
List<ValueDescriptor> fields = new ArrayList<>();
|
||||
List<AnnotationElement> messageAnnotations = Collections.singletonList(new AnnotationElement(Label.class, "Message"));
|
||||
fields.add(new ValueDescriptor(String.class, "message", messageAnnotations));
|
||||
List<AnnotationElement> numberAnnotations = Collections.singletonList(new AnnotationElement(Label.class, "Number"));
|
||||
fields.add(new ValueDescriptor(int.class, "number", numberAnnotations));
|
||||
|
||||
String[] category = { "Example", "Getting Started" };
|
||||
List<AnnotationElement> eventAnnotations = new ArrayList<>();
|
||||
eventAnnotations.add(new AnnotationElement(Name.class, "com.example.HelloWorld"));
|
||||
eventAnnotations.add(new AnnotationElement(Label.class, "Hello World"));
|
||||
eventAnnotations.add(new AnnotationElement(Description.class, "Helps programmer getting started"));
|
||||
eventAnnotations.add(new AnnotationElement(Category.class, category));
|
||||
|
||||
EventFactory f = EventFactory.create(eventAnnotations, fields);
|
||||
|
||||
Event event = f.newEvent();
|
||||
event.set(0, "hello, world!");
|
||||
event.set(1, 4711);
|
||||
event.commit();
|
||||
// @end
|
||||
}
|
||||
|
||||
void EventSettingOverview() throws Exception {
|
||||
// @start region="EventSettingOverview"
|
||||
Recording r = new Recording();
|
||||
r.enable("jdk.CPULoad")
|
||||
.withPeriod(Duration.ofSeconds(1));
|
||||
r.enable("jdk.FileWrite")
|
||||
.withoutStackTrace()
|
||||
.withThreshold(Duration.ofNanos(10));
|
||||
r.start();
|
||||
Thread.sleep(10_000);
|
||||
r.stop();
|
||||
r.dump(Files.createTempFile("recording", ".jfr"));
|
||||
// @end
|
||||
}
|
||||
|
||||
void FlightRecorderTakeSnapshot() throws Exception {
|
||||
// @start region="FlightRecorderTakeSnapshot"
|
||||
try (Recording snapshot = FlightRecorder.getFlightRecorder().takeSnapshot()) {
|
||||
if (snapshot.getSize() > 0) {
|
||||
snapshot.setMaxSize(100_000_000);
|
||||
snapshot.setMaxAge(Duration.ofMinutes(5));
|
||||
snapshot.dump(Paths.get("snapshot.jfr"));
|
||||
}
|
||||
}
|
||||
// @end
|
||||
}
|
||||
|
||||
// @start region="MetadataDefinitionOverview"
|
||||
@MetadataDefinition
|
||||
@Label("Severity")
|
||||
@Description("Value between 0 and 100 that indicates severity. 100 is most severe.")
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.TYPE })
|
||||
public @interface Severity {
|
||||
int value() default 50;
|
||||
}
|
||||
|
||||
@MetadataDefinition
|
||||
@Label("Transaction Id")
|
||||
@Relational
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.FIELD })
|
||||
public @interface TransactionId {
|
||||
}
|
||||
|
||||
@Severity(80)
|
||||
@Label("Transaction Blocked")
|
||||
class TransactionBlocked extends Event {
|
||||
@TransactionId
|
||||
@Label("Transaction")
|
||||
long transactionId1;
|
||||
|
||||
@TransactionId
|
||||
@Label("Transaction Blocker")
|
||||
long transactionId2;
|
||||
}
|
||||
// @end
|
||||
|
||||
void RecordingnOverview() throws Exception {
|
||||
// @start region="RecordingOverview"
|
||||
Configuration c = Configuration.getConfiguration("default");
|
||||
Recording r = new Recording(c);
|
||||
r.start();
|
||||
System.gc();
|
||||
Thread.sleep(5000);
|
||||
r.stop();
|
||||
r.dump(Files.createTempFile("my-recording", ".jfr"));
|
||||
// @end
|
||||
}
|
||||
|
||||
// @start region="SettingControlOverview1"
|
||||
final class RegExpControl extends SettingControl {
|
||||
private Pattern pattern = Pattern.compile(".*");
|
||||
|
||||
@Override
|
||||
public void setValue(String value) {
|
||||
this.pattern = Pattern.compile(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String combine(Set<String> values) {
|
||||
return String.join("|", values);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue() {
|
||||
return pattern.toString();
|
||||
}
|
||||
|
||||
public boolean matches(String s) {
|
||||
return pattern.matcher(s).find();
|
||||
}
|
||||
}
|
||||
// @end
|
||||
|
||||
class HttpServlet {
|
||||
}
|
||||
|
||||
class HttpServletRequest {
|
||||
public String getRequestURI() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class HttpServletResponse {
|
||||
}
|
||||
|
||||
// @start region="SettingControlOverview2"
|
||||
abstract class HTTPRequest extends Event {
|
||||
@Label("Request URI")
|
||||
protected String uri;
|
||||
|
||||
@Label("Servlet URI Filter")
|
||||
@SettingDefinition
|
||||
protected boolean uriFilter(RegExpControl regExp) {
|
||||
return regExp.matches(uri);
|
||||
}
|
||||
}
|
||||
|
||||
@Label("HTTP Get Request")
|
||||
class HTTPGetRequest extends HTTPRequest {
|
||||
}
|
||||
|
||||
@Label("HTTP Post Request")
|
||||
class HTTPPostRequest extends HTTPRequest {
|
||||
}
|
||||
|
||||
class ExampleServlet extends HttpServlet {
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
|
||||
HTTPGetRequest request = new HTTPGetRequest();
|
||||
request.begin();
|
||||
request.uri = req.getRequestURI();
|
||||
code: // @replace regex='code:' replacement="..."
|
||||
request.commit();
|
||||
}
|
||||
|
||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
|
||||
HTTPPostRequest request = new HTTPPostRequest();
|
||||
request.begin();
|
||||
request.uri = req.getRequestURI();
|
||||
code: // @replace regex='code:' replacement="..."
|
||||
request.commit();
|
||||
}
|
||||
}
|
||||
// @end
|
||||
|
||||
void SettingControlOverview3() {
|
||||
// @start region="SettingControlOverview3"
|
||||
Recording r = new Recording();
|
||||
r.enable("HTTPGetRequest").with("uriFilter", "https://www.example.com/list/.*");
|
||||
r.enable("HTTPPostRequest").with("uriFilter", "https://www.example.com/login/.*");
|
||||
r.start();
|
||||
// @end
|
||||
}
|
||||
|
||||
// @start region="SettingDefinitionOverview"
|
||||
class HelloWorld extends Event {
|
||||
|
||||
@Label("Message")
|
||||
String message;
|
||||
|
||||
@SettingDefinition
|
||||
@Label("Message Filter")
|
||||
public boolean filter(RegExpControl regExp) {
|
||||
return regExp.matches(message);
|
||||
}
|
||||
}
|
||||
// @end
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user