src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdCheck.java
changeset 50113 caf115bb98ad
child 50226 408021edf22f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/dcmd/DCmdCheck.java	Tue May 15 20:24:34 2018 +0200
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2012, 2018, 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 jdk.jfr.internal.dcmd;
+
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.StringJoiner;
+
+import jdk.jfr.EventType;
+import jdk.jfr.Recording;
+import jdk.jfr.SettingDescriptor;
+
+/**
+ * JFR.check - invoked from native
+ *
+ */
+final class DCmdCheck extends AbstractDCmd {
+    /**
+     * Execute JFR.check
+     *
+     * @param recordingText name or id of the recording to check, or
+     *        <code>null</code> to show a list of all recordings.
+     *
+     * @param verbose if event settings should be included.
+     *
+     * @return result output
+     *
+     * @throws DCmdException if the check could not be completed.
+     */
+    public String execute(String recordingText, Boolean verbose) throws DCmdException {
+        executeInternal(recordingText, verbose);
+        return getResult();
+    }
+
+    private void executeInternal(String recordingText, Boolean verbose) throws DCmdException {
+        if (verbose == null) {
+            verbose = Boolean.FALSE;
+        }
+
+        if (recordingText != null) {
+            printRecording(findRecording(recordingText), verbose);
+            return;
+        }
+
+        List<Recording> recordings = getRecordings();
+        if (!verbose && recordings.isEmpty()) {
+            println("No available recordings.");
+            println();
+            println("Use JFR.start to start a recording.");
+            return;
+        }
+        boolean first = true;
+        for (Recording recording : recordings) {
+            // Print separation between recordings,
+            if (!first) {
+                println();
+                if (Boolean.TRUE.equals(verbose)) {
+                    println();
+                }
+            }
+            first = false;
+            printRecording(recording, verbose);
+        }
+    }
+
+    private void printRecording(Recording recording, boolean verbose) {
+        printGeneral(recording);
+        if (verbose) {
+            println();
+            printSetttings(recording);
+        }
+    }
+
+    private void printGeneral(Recording recording) {
+        String format = "Recording: recording=%d name=\"%s\"";
+        print(format, recording.getId(), recording.getName());
+
+        Duration duration = recording.getDuration();
+        if (duration != null) {
+            print(" duration=");
+            printTimespan(duration, "");
+        }
+
+        long maxSize = recording.getMaxSize();
+        if (maxSize != 0) {
+            print(" maxsize=");
+            printBytes(maxSize, "");
+        }
+        Duration maxAge = recording.getMaxAge();
+        if (maxAge != null) {
+            print(" maxage=");
+            printTimespan(maxAge, "");
+        }
+
+        print(" (" + recording.getState().toString().toLowerCase() + ")");
+        println();
+    }
+
+    private void printSetttings(Recording recording) {
+        Map<String, String> settings = recording.getSettings();
+        for (EventType eventType : sortByEventPath(getFlightRecorder().getEventTypes())) {
+            StringJoiner sj = new StringJoiner(",", "[", "]");
+            sj.setEmptyValue("");
+            for (SettingDescriptor s : eventType.getSettingDescriptors()) {
+                String settingsPath = eventType.getName() + "#" + s.getName();
+                if (settings.containsKey(settingsPath)) {
+                    sj.add(s.getName() + "=" + settings.get(settingsPath));
+                }
+            }
+            String settingsText = sj.toString();
+            if (!settingsText.isEmpty()) {
+                print(" %s (%s)", eventType.getLabel(), eventType.getName());
+                println();
+                println("   " + settingsText);
+            }
+        }
+    }
+
+    private static List<EventType> sortByEventPath(Collection<EventType> events) {
+        List<EventType> sorted = new ArrayList<>();
+        sorted.addAll(events);
+        Collections.sort(sorted, new Comparator<EventType>() {
+            @Override
+            public int compare(EventType e1, EventType e2) {
+                return e1.getName().compareTo(e2.getName());
+            }
+        });
+        return sorted;
+    }
+}