diff -r 7a2a740815b7 -r caf115bb98ad src/jdk.management.jfr/share/classes/jdk/management/jfr/RecordingInfo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk.management.jfr/share/classes/jdk/management/jfr/RecordingInfo.java Tue May 15 20:24:34 2018 +0200 @@ -0,0 +1,398 @@ +/* + * Copyright (c) 2016, 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.management.jfr; + +import java.nio.file.Path; +import java.time.Duration; +import java.time.Instant; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import javax.management.openmbean.CompositeData; +import javax.management.openmbean.TabularData; + +import jdk.jfr.Recording; +import jdk.jfr.RecordingState; + +/** + * Management representation of a {@code Recording}. + * + * @see Recording + * + * @since 9 + */ +public final class RecordingInfo { + private final long id; + private final String name; + private final String state; + private final boolean dumpOnExit; + private final long size; + private final boolean disk; + private final long maxAge; + private final long maxSize; + private final long startTime; + private final long stopTime; + private final String destination; + private final long durationInSeconds; + private final Map settings; + + // package private + RecordingInfo(Recording recording) { + id = recording.getId(); + name = recording.getName(); + state = recording.getState().toString(); + dumpOnExit = recording.getDumpOnExit(); + size = recording.getSize(); + disk = recording.isToDisk(); + + Duration d = recording.getMaxAge(); + if (d == null) { + maxAge = 0; + } else { + maxAge = d.getSeconds(); + } + maxSize = recording.getMaxSize(); + Instant s = recording.getStartTime(); + startTime = s == null ? 0L : s.toEpochMilli(); + Instant st = recording.getStopTime(); + stopTime = st == null ? 0L : st.toEpochMilli(); + Path p = recording.getDestination(); + destination = p == null ? null : p.toString(); + Duration duration = recording.getDuration(); + durationInSeconds = duration == null ? 0 : duration.getSeconds(); + settings = recording.getSettings(); + } + + private RecordingInfo(CompositeData cd) { + id = (int) cd.get("id"); + name = (String) cd.get("name"); + state = (String) cd.get("state"); + dumpOnExit = (boolean) cd.get("dumpOnExit"); + size = (long) cd.get("size"); + disk = (boolean) cd.get("disk"); + maxAge = (Long) cd.get("maxAge"); + maxSize = (Long) cd.get("maxSize"); + startTime = (Long) cd.get("startTime"); + stopTime = (Long) cd.get("stopTime"); + destination = (String) cd.get("destination"); + durationInSeconds = (long) cd.get("duration"); + settings = new LinkedHashMap<>(); + Object map = cd.get("settings"); + if (map instanceof TabularData) { + TabularData td = (TabularData) map; + List keyNames = td.getTabularType().getIndexNames(); + int size = keyNames.size(); + for (Object keys : td.keySet()) { + Object[] keyValues = ((List) keys).toArray(); + for (int i = 0; i < size; i++) { + String key = keyNames.get(i); + Object value = keyValues[i]; + if (value instanceof String) { + settings.put(key, (String) value); + } + } + } + } + } + + /** + * Returns the name of the recording associated with this + * {@code RecordingInfo}. + * + * @return the recording name, not {@code null} + * + * @see Recording#getName() + */ + public String getName() { + return name; + } + + /** + * Returns the unique ID for the recording associated with this + * {@code RecordingInfo}. + * + * @return the recording ID + * + * @see Recording#getId() + */ + public long getId() { + return id; + } + + /** + * Returns if the recording associated with this {@code RecordingInfo} + * should be dumped to file when the JVM exits. + * + * @return {@code true} if recording should be dumped on exit, {@code false} + * otherwise + * + * @see Recording#getDumpOnExit() + */ + public boolean getDumpOnExit() { + return dumpOnExit; + } + + /** + * Returns how many seconds data should be kept on disk, or {@code 0} if + * data is to be kept forever. + *

+ * In-memory recordings are not affected by maximum age. + * + * @see Recording#getMaxAge() + * @see Recording#setToDisk(boolean) + * @return how long data should be kept on disk, measured in seconds + * + */ + public long getMaxAge() { + return maxAge; + } + + /** + * Returns the amount of data, measured in bytes, the recording associated + * with this {@code RecordingInfo}, should be kept on disk, before it's + * rotated away, or {@code 0} if data is to be kept indefinitely. + *

+ * In-memory recordings are not affected by maximum size. + * + * @return the amount of data should be kept on disk, in bytes + * + * @see Recording#setToDisk(boolean) + * @see Recording#getMaxSize() + */ + public long getMaxSize() { + return maxSize; + } + + /** + * Returns a {@code String} representation of state of the recording + * associated with this {@code RecordingInfo}. + *

+ * Valid return values are {@code "NEW"}, {@code "DELAYED"}, {@code "STARTING"}, + * {@code "RUNNING"}, {@code "STOPPING"}, {@code "STOPPED"} and {@code "CLOSED"}. + * + * @return the recording state, not {@code null} + * + * @see RecordingState#toString() + * @see Recording#getState() + */ + public String getState() { + return state; + } + + /** + * Returns start time of the recording associated with this + * {@code RecordingInfo}, measured as ms since epoch, or {@code null} if the + * recording hasn't started. + * + * @return the start time of the recording, or {@code null} if the recording + * hasn't started + * + * @see Recording#getStartTime() + */ + public long getStartTime() { + return startTime; + } + + /** + * Returns the actual or expected stop time of the recording associated with + * this {@code RecordingInfo}, measured as ms since epoch, or {@code null} + * if the expected or actual stop time is not known, which can only happen + * if the recording has not yet been stopped. + * + * @return the stop time of recording, or {@code null} if recording hasn't + * been stopped. + * + * @see Recording#getStopTime() + */ + public long getStopTime() { + return stopTime; + } + + /** + * Returns the settings for the recording associated with this + * {@code RecordingInfo}. + * + * @return the recording settings, not {@code null} + * + * @see Recording#getSettings() + */ + public Map getSettings() { + return settings; + } + + /** + * Returns destination path where data, for the recording associated with + * this {@link RecordingInfo}, should be written when the recording stops, + * or {@code null} if the recording should not be written. + * + * @return the destination, or {@code null} if not set + * + * @see Recording#getDestination() + */ + public String getDestination() { + return destination; + } + + /** + * Returns a string description of the recording associated with this + * {@code RecordingInfo} + * + * @return description, not {@code null} + */ + @Override + public String toString() { + Stringifier s = new Stringifier(); + s.add("name", name); + s.add("id", id); + s.add("maxAge", maxAge); + s.add("maxSize", maxSize); + return s.toString(); + } + + /** + * Returns the amount data recorded by recording. associated with this + * {@link RecordingInfo}. + * + * @return the amount of recorded data, measured in bytes + */ + public long getSize() { + return size; + } + + /** + * Returns {@code true} if the recording associated with this + * {@code RecordingInfo} should be flushed to disk, when memory buffers are + * full, {@code false} otherwise. + * + * @return {@code true} if recording is to disk, {@code false} otherwise + */ + public boolean isToDisk() { + return disk; + } + + /** + * Returns the desired duration, measured in seconds, of the recording + * associated with this {@link RecordingInfo}, or {code 0} if no duration + * has been set. + * + * @return the desired duration, or {code 0} if no duration has been set + * + * @see Recording#getDuration() + */ + public long getDuration() { + return durationInSeconds; + } + + /** + * Returns a {@code RecordingInfo} represented by the specified + * {@code CompositeData} object. + *

+ * The specified {@code CompositeData} must have the following item names and + * item types to be valid.

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Supported names and types in a specified {@code CompositeData} object
NameType
id{@code Long}
name{@code String}
state{@code String}
dumpOnExit{@code Boolean}
size{@code Long}
disk{@code Boolean}
maxAge{@code Long}
maxSize{@code Long}
startTime{@code Long}
stopTime{@code Long}
destination{@code String}
duration{@code Long}
settings{@code javax.management.openmbean.CompositeData[]} whose element type + * is the mapped type for {@link SettingDescriptorInfo} as specified in the + * {@link SettingDescriptorInfo#from} method.
+ *
+ * + * @param cd {@code CompositeData} representing the {@code RecordingInfo} to + * return + * + * @throws IllegalArgumentException if {@code cd} does not represent a valid + * {@code RecordingInfo} + * + * @return the {@code RecordingInfo} represented by {@code cd}, or + * {@code null} if {@code cd} is {@code null} + */ + public static RecordingInfo from(CompositeData cd) { + if (cd == null) { + return null; + } + return new RecordingInfo(cd); + } +}