1 /*
2  * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  *
23  */
24 
25 import java.io.File;
26 import java.io.IOException;
27 import java.nio.file.Path;
28 import java.util.List;
29 
30 import jdk.jfr.Event;
31 import jdk.jfr.EventType;
32 import jdk.jfr.FlightRecorder;
33 import jdk.jfr.Recording;
34 import jdk.jfr.consumer.RecordingFile;
35 import jdk.jfr.consumer.RecordedEvent;
36 
37 public class GetFlightRecorder {
38     private static class TestEvent extends Event {
39     }
40     private static class SimpleEvent extends Event {
41         public int id;
42     }
main(String args[])43     public static void main(String args[]) throws Exception {
44         EventType type = EventType.getEventType(TestEvent.class); // This class is loaded before recording has started.
45         if (type.isEnabled()) {
46             throw new RuntimeException("Expected event to be disabled before recording start");
47         }
48 
49         // (1) make sure you can obtain the flight recorder without error.
50         System.out.println("jdk.jfr.FlightRecorder.getFlightRecorder() = " + FlightRecorder.getFlightRecorder());
51 
52         // (2) test that the event class loaded before recording can still work.
53         Recording r = new Recording();
54         r.start();
55         if (!type.isEnabled()) {
56             throw new RuntimeException("Expected event to be enabled during recording");
57         }
58         TestEvent testEvent = new TestEvent();
59         testEvent.commit();
60         loadEventClassDuringRecording();
61         r.stop();
62         if (type.isEnabled()) {
63             throw new RuntimeException("Expected event to be disabled after recording stopped");
64         }
65         System.out.println("Checking SimpleEvent");
66         hasEvent(r, SimpleEvent.class.getName());
67         System.out.println("OK");
68 
69         System.out.println("Checking TestEvent");
70         hasEvent(r, TestEvent.class.getName());
71         System.out.println("OK");
72     }
73 
74     // Classes that are loaded during a recording
75     // should get instrumentation on class load
loadEventClassDuringRecording()76     private static void loadEventClassDuringRecording() {
77         SimpleEvent event = new SimpleEvent();
78         event.commit();
79     }
80 
fromRecording(Recording recording)81     public static List<RecordedEvent> fromRecording(Recording recording) throws IOException {
82         return RecordingFile.readAllEvents(makeCopy(recording));
83     }
84 
makeCopy(Recording recording)85     private static Path makeCopy(Recording recording) throws IOException {
86         Path p = recording.getDestination();
87         if (p == null) {
88             File directory = new File(".");
89             // FIXME: Must come up with a way to give human-readable name
90             // this will at least not clash when running parallel.
91             ProcessHandle h = ProcessHandle.current();
92             p = new File(directory.getAbsolutePath(), "recording-" + recording.getId() + "-pid" + h.pid() + ".jfr").toPath();
93             recording.dump(p);
94         }
95         return p;
96     }
97 
hasEvent(Recording r, String name)98     public static void hasEvent(Recording r, String name) throws IOException {
99         List<RecordedEvent> events = fromRecording(r);
100         hasEvents(events);
101         hasEvent(events, name);
102     }
103 
hasEvents(List<RecordedEvent> events)104     public static void hasEvents(List<RecordedEvent> events) {
105         if (events.isEmpty()) {
106             throw new RuntimeException("No events");
107         }
108     }
109 
hasEvent(List<RecordedEvent> events, String name)110     public static void hasEvent(List<RecordedEvent> events, String name) throws IOException {
111         if (!containsEvent(events, name)) {
112             throw new RuntimeException("Missing event " + name  + " in recording " + events.toString());
113         }
114     }
115 
containsEvent(List<RecordedEvent> events, String name)116     private static boolean containsEvent(List<RecordedEvent> events, String name) {
117         for (RecordedEvent event : events) {
118             if (event.getEventType().getName().equals(name)) {
119                 return true;
120             }
121         }
122         return false;
123     }
124 }
125