31 import java.nio.file.Path; |
31 import java.nio.file.Path; |
32 import java.nio.file.Paths; |
32 import java.nio.file.Paths; |
33 import java.text.ParseException; |
33 import java.text.ParseException; |
34 import java.time.Duration; |
34 import java.time.Duration; |
35 import java.util.ArrayDeque; |
35 import java.util.ArrayDeque; |
|
36 import java.util.Deque; |
36 |
37 |
37 import jdk.jfr.Configuration; |
38 import jdk.jfr.Configuration; |
38 import jdk.jfr.EventType; |
39 import jdk.jfr.EventType; |
39 import jdk.jfr.ValueDescriptor; |
40 import jdk.jfr.ValueDescriptor; |
40 |
41 |
41 class UseCasesStream { |
42 final class UseCasesStream { |
42 |
43 |
43 // |
44 // |
44 // Use case: Out-of-the-Box Experience |
45 // Use case: Out-of-the-Box Experience |
45 // |
46 // |
46 // - Simple things should be simple |
47 // - Simple things should be simple |
88 public static void eventForwarding() throws InterruptedException, IOException, ParseException { |
89 public static void eventForwarding() throws InterruptedException, IOException, ParseException { |
89 // KafkaProducer producer = new KafkaProducer<String, String>(); |
90 // KafkaProducer producer = new KafkaProducer<String, String>(); |
90 try (RecordingStream rs = new RecordingStream(Configuration.getConfiguration("default"))) { |
91 try (RecordingStream rs = new RecordingStream(Configuration.getConfiguration("default"))) { |
91 rs.setMaxAge(Duration.ofMinutes(5)); |
92 rs.setMaxAge(Duration.ofMinutes(5)); |
92 rs.setMaxSize(1000_000_000L); |
93 rs.setMaxSize(1000_000_000L); |
93 // es.setParallel(true); |
94 rs.setOrdered(false); |
94 // es.setReuse(true); |
95 rs.setReuse(true); // default |
95 // es.consume(e -> producer.send(new ProducerRecord<String, |
96 // rs.consume(e -> producer.send(new |
96 // String>("topic", |
97 // ProducerRecord<String,String>("topic", e.getString("key"), |
97 // e.getString("key"), e.getString("value")))); |
98 // e.getString("value")))); |
98 rs.start(); |
99 rs.start(); |
99 } |
100 } |
100 // Write primitive values to XML |
101 // Write primitive values to XML |
101 try (RecordingStream rs = new RecordingStream(Configuration.getConfiguration("deafult"))) { |
102 try (RecordingStream rs = new RecordingStream(Configuration.getConfiguration("deafult"))) { |
102 try (PrintWriter p = new PrintWriter(new FileWriter("recording.xml"))) { |
103 try (PrintWriter p = new PrintWriter(new FileWriter("recording.xml"))) { |
103 // es.setParallel(false); |
|
104 // es.setReuse(true); |
|
105 p.println("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"); |
104 p.println("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"); |
106 p.println("<events>"); |
105 p.println("<events>"); |
107 rs.onEvent(e -> { |
106 rs.onEvent(e -> { |
108 EventType type = e.getEventType(); |
107 EventType type = e.getEventType(); |
109 p.println(" <event type=\"" + type.getName() + "\" start=\"" + e.getStartTime() + "\" end=\"" + e.getEndTime() + "\">"); |
108 p.println(" <event type=\"" + type.getName() + "\" start=\"" + e.getStartTime() + "\" end=\"" + e.getEndTime() + "\">"); |
121 } |
120 } |
122 |
121 |
123 // Use case: Repository Access |
122 // Use case: Repository Access |
124 // |
123 // |
125 // - Read the disk repository from another process, for example a side car |
124 // - Read the disk repository from another process, for example a side car |
126 // in |
125 // in aDocker container |
127 // Docker container |
|
128 // - Be able to configure flush interval from command line or jcmd. |
126 // - Be able to configure flush interval from command line or jcmd. |
129 // - Graceful shutdown |
127 // - Graceful shutdown |
130 // |
128 // |
131 public static void repositoryAccess() throws IOException, InterruptedException { |
129 public static void repositoryAccess() throws IOException, InterruptedException { |
132 Path repository = Paths.get("c:\\repository").toAbsolutePath(); |
130 Path repository = Paths.get("c:\\repository").toAbsolutePath(); |
151 // - Events with the same period should arrive together |
149 // - Events with the same period should arrive together |
152 // - Consume events in chronological order |
150 // - Consume events in chronological order |
153 // - Low overhead |
151 // - Low overhead |
154 // |
152 // |
155 public static void tooling() throws IOException, ParseException { |
153 public static void tooling() throws IOException, ParseException { |
156 ArrayDeque<Double> measurements = new ArrayDeque<>(); |
154 Deque<Double> measurements = new ArrayDeque<>(); |
157 try (RecordingStream rs = new RecordingStream(Configuration.getConfiguration("profile"))) { |
155 try (RecordingStream rs = new RecordingStream(Configuration.getConfiguration("profile"))) { |
158 rs.setInterval(Duration.ofSeconds(1)); |
156 rs.setInterval(Duration.ofSeconds(1)); |
159 rs.setMaxAge(Duration.ofMinutes(1)); |
157 rs.setMaxAge(Duration.ofMinutes(1)); |
160 // rs.setOrdered(true); |
158 rs.setOrdered(true); // default |
161 // rs.setReuse(false); |
159 rs.setReuse(false); |
162 // rs.setParallel(true); |
|
163 rs.onEvent("jdk.CPULoad", e -> { |
160 rs.onEvent("jdk.CPULoad", e -> { |
164 double d = e.getDouble("totalMachine"); |
161 double d = e.getDouble("totalMachine"); |
165 measurements.addFirst(d); |
162 measurements.addFirst(d); |
166 if (measurements.size() > 60) { |
163 if (measurements.size() > 60) { |
167 measurements.removeLast(); |
164 measurements.removeLast(); |
177 // - Support event subscriptions in a low latency environment (minimal GC |
174 // - Support event subscriptions in a low latency environment (minimal GC |
178 // pauses) |
175 // pauses) |
179 // - Filter out relevant events to minimize disk overhead and allocation |
176 // - Filter out relevant events to minimize disk overhead and allocation |
180 // pressure |
177 // pressure |
181 // - Avoid impact from other recordings |
178 // - Avoid impact from other recordings |
182 // - Avoid Heisenberg effects, in particular self-recursion |
179 // - Avoid observer effect, in particular self-recursion |
183 // |
180 // |
184 // Non-goals: one-liner |
181 // Non-goals: one-liner |
185 // |
182 // |
186 public static void lowImpact() throws InterruptedException, IOException, ParseException { |
183 public static void lowImpact() throws InterruptedException, IOException, ParseException { |
187 try (RecordingStream rs = new RecordingStream()) { |
184 try (RecordingStream rs = new RecordingStream()) { |
188 rs.enable("jdk.JavaMonitorEnter#threshold").withThreshold(Duration.ofMillis(10)); |
185 rs.setReuse(true); // default |
189 rs.enable("jdk.ExceptionThrow#enabled"); |
186 rs.enable("jdk.JavaMonitorEnter").withThreshold(Duration.ofMillis(10)); |
190 // ep.setReuse(true); |
187 rs.enable("jdk.ExceptionThrow"); |
191 rs.onEvent("jdk.JavaMonitorEnter", System.out::println); |
188 rs.onEvent("jdk.JavaMonitorEnter", System.out::println); |
192 rs.onEvent("jdk.ExceptionThrow", System.out::println); |
189 rs.onEvent("jdk.ExceptionThrow", System.out::println); |
193 rs.start(); |
190 rs.start(); |
194 ; |
191 ; |
195 } |
192 } |