/* * 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 max 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 max 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 STOPEED} 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 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} *

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

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
The name and type the specified CompositeData must contain
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); } }