1 /* 2 * Copyright (c) 2018, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.jfr.jvm; 27 28 import java.io.File; 29 import java.io.IOException; 30 import java.time.Duration; 31 import java.util.ArrayList; 32 import java.util.List; 33 34 import jdk.jfr.AnnotationElement; 35 import jdk.jfr.Event; 36 import jdk.jfr.EventType; 37 import jdk.jfr.FlightRecorder; 38 import jdk.jfr.Recording; 39 import jdk.jfr.ValueDescriptor; 40 import jdk.jfr.consumer.RecordedEvent; 41 import jdk.jfr.consumer.RecordingFile; 42 43 /* 44 * @test TestGetThreadId 45 * @key jfr 46 * @library /lib/testlibrary 47 * @modules jdk.jfr/jdk.jfr.internal 48 * @run main/othervm jdk.jfr.jvm.TestJavaEvent 49 */ 50 public class TestJavaEvent { 51 52 private static final int EVENTS_PER_THREAD = 50; 53 private static final int THREAD_COUNT = 100; 54 55 public static class MyEvent extends Event { 56 float floatValue; 57 double doubleValue; 58 int intValue; 59 long longValue; 60 char charValue; 61 byte byteValue; 62 String stringValue; 63 Thread threadValue; 64 Class<?> classValue; 65 66 public void setFloatValue(float value) { 67 floatValue = value; 68 } 69 70 public void setDoubleValue(double value) { 71 doubleValue = value; 72 } 73 74 public void setIntValue(int value) { 75 intValue = value; 76 } 77 78 public void setLongValue(long value) { 79 longValue = value; 80 } 81 82 public void setCharValue(char value) { 83 charValue = value; 84 } 85 86 public void setByteValue(byte value) { 87 byteValue = value; 88 } 89 90 public void setStringValue(String value) { 91 stringValue = value; 92 } 93 94 public void setThreadValue(Thread value) { 95 threadValue = value; 96 } 97 98 public void setClassValue(Class<?> value) { 99 classValue = value; 100 } 101 } 102 103 public static void main(String... args) throws IOException, InterruptedException { 104 Recording r = new Recording(); 105 r.enable(MyEvent.class).withThreshold(Duration.ofNanos(0)).withoutStackTrace(); 106 r.start(); 107 List<Thread> threads = new ArrayList<>(); 108 for (int n = 0; n < THREAD_COUNT; n++) { 109 Thread t = new Thread(TestJavaEvent::emitEvents); 110 threads.add(t); 111 t.start(); 112 } 113 for (Thread t : threads) { 114 t.join(); 115 } 116 117 r.stop(); 118 // prettyPrint(); 119 File file = File.createTempFile("test", ".jfr"); 120 r.dump(file.toPath()); 121 int eventCount = 0; 122 for (RecordedEvent e : RecordingFile.readAllEvents(file.toPath())) { 123 if (e.getEventType().getName().equals(MyEvent.class.getName())) { 124 eventCount++; 125 } 126 System.out.println(e); 127 } 128 System.out.println("Event count was " + eventCount + ", expected " + THREAD_COUNT * EVENTS_PER_THREAD); 129 r.close(); 130 } 131 132 private static void emitEvents() { 133 for (int n = 0; n < EVENTS_PER_THREAD; n++) { 134 MyEvent event = new MyEvent(); 135 event.begin(); 136 event.end(); 137 event.setFloatValue(1.12345f); 138 event.setDoubleValue(1.234567890); 139 event.setIntValue(123456); 140 event.setLongValue(1234567890); 141 event.setCharValue('c'); 142 event.setByteValue((byte) 12); 143 event.setStringValue("1234567890"); 144 event.setThreadValue(Thread.currentThread()); 145 event.setClassValue(Class.class); 146 event.commit(); 147 try { 148 Thread.sleep(1); 149 } catch (InterruptedException e) { 150 // TODO Auto-generated catch block 151 e.printStackTrace(); 152 } 153 } 154 } 155 156 static void prettyPrint() { 157 for (EventType type : FlightRecorder.getFlightRecorder().getEventTypes()) { 158 for (AnnotationElement a : type.getAnnotationElements()) { 159 printAnnotation("", a); 160 } 161 System.out.print("class " + removePackage(type.getName())); 162 System.out.print(" extends Event"); 163 164 System.out.println(" {"); 165 List<ValueDescriptor> values = type.getFields(); 166 for (int i = 0; i < values.size(); i++) { 167 ValueDescriptor v = values.get(i); 168 for (AnnotationElement a : v.getAnnotationElements()) { 169 printAnnotation(" ", a); 170 } 171 System.out.println(" " + removePackage(v.getTypeName() + brackets(v.isArray())) + " " + v.getName()); 172 if (i != values.size() - 1) { 173 System.out.println(); 174 } 175 } 176 System.out.println("}"); 177 System.out.println(); 178 } 179 } 180 181 private static String brackets(boolean isArray) { 182 return isArray ? "[]" : ""; 183 } 184 185 private static String removePackage(String s) { 186 187 int index = s.lastIndexOf("."); 188 return s.substring(index + 1); 189 } 190 191 private static void printAnnotation(String indent, AnnotationElement a) { 192 String name = removePackage(a.getTypeName()); 193 if (a.getValues().isEmpty()) { 194 System.out.println(indent + "@" + name); 195 return; 196 } 197 System.out.print(indent + "@" + name + "("); 198 for (Object o : a.getValues()) { 199 printAnnotationValue(o); 200 } 201 System.out.println(")"); 202 } 203 204 private static void printAnnotationValue(Object o) { 205 if (o instanceof String) { 206 System.out.print("\"" + o + "\""); 207 } else { 208 System.out.print(String.valueOf(o)); 209 } 210 } 211 212 }