src/jdk.management.jfr/share/classes/jdk/management/jfr/RecordingInfo.java
changeset 50113 caf115bb98ad
child 55256 3b22c7e00573
equal deleted inserted replaced
50112:7a2a740815b7 50113:caf115bb98ad
       
     1 /*
       
     2  * Copyright (c) 2016, 2018, 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.management.jfr;
       
    27 
       
    28 import java.nio.file.Path;
       
    29 import java.time.Duration;
       
    30 import java.time.Instant;
       
    31 import java.util.LinkedHashMap;
       
    32 import java.util.List;
       
    33 import java.util.Map;
       
    34 
       
    35 import javax.management.openmbean.CompositeData;
       
    36 import javax.management.openmbean.TabularData;
       
    37 
       
    38 import jdk.jfr.Recording;
       
    39 import jdk.jfr.RecordingState;
       
    40 
       
    41 /**
       
    42  * Management representation of a {@code Recording}.
       
    43  *
       
    44  * @see Recording
       
    45  *
       
    46  * @since 9
       
    47  */
       
    48 public final class RecordingInfo {
       
    49     private final long id;
       
    50     private final String name;
       
    51     private final String state;
       
    52     private final boolean dumpOnExit;
       
    53     private final long size;
       
    54     private final boolean disk;
       
    55     private final long maxAge;
       
    56     private final long maxSize;
       
    57     private final long startTime;
       
    58     private final long stopTime;
       
    59     private final String destination;
       
    60     private final long durationInSeconds;
       
    61     private final Map<String, String> settings;
       
    62 
       
    63     // package private
       
    64     RecordingInfo(Recording recording) {
       
    65         id = recording.getId();
       
    66         name = recording.getName();
       
    67         state = recording.getState().toString();
       
    68         dumpOnExit = recording.getDumpOnExit();
       
    69         size = recording.getSize();
       
    70         disk = recording.isToDisk();
       
    71 
       
    72         Duration d = recording.getMaxAge();
       
    73         if (d == null) {
       
    74             maxAge = 0;
       
    75         } else {
       
    76             maxAge = d.getSeconds();
       
    77         }
       
    78         maxSize = recording.getMaxSize();
       
    79         Instant s = recording.getStartTime();
       
    80         startTime = s == null ? 0L : s.toEpochMilli();
       
    81         Instant st = recording.getStopTime();
       
    82         stopTime = st == null ? 0L : st.toEpochMilli();
       
    83         Path p = recording.getDestination();
       
    84         destination = p == null ? null : p.toString();
       
    85         Duration duration = recording.getDuration();
       
    86         durationInSeconds = duration == null ? 0 : duration.getSeconds();
       
    87         settings = recording.getSettings();
       
    88     }
       
    89 
       
    90     private RecordingInfo(CompositeData cd) {
       
    91         id = (int) cd.get("id");
       
    92         name = (String) cd.get("name");
       
    93         state = (String) cd.get("state");
       
    94         dumpOnExit = (boolean) cd.get("dumpOnExit");
       
    95         size = (long) cd.get("size");
       
    96         disk = (boolean) cd.get("disk");
       
    97         maxAge = (Long) cd.get("maxAge");
       
    98         maxSize = (Long) cd.get("maxSize");
       
    99         startTime = (Long) cd.get("startTime");
       
   100         stopTime = (Long) cd.get("stopTime");
       
   101         destination = (String) cd.get("destination");
       
   102         durationInSeconds = (long) cd.get("duration");
       
   103         settings = new LinkedHashMap<>();
       
   104         Object map = cd.get("settings");
       
   105         if (map instanceof TabularData) {
       
   106             TabularData td = (TabularData) map;
       
   107             List<String> keyNames = td.getTabularType().getIndexNames();
       
   108             int size = keyNames.size();
       
   109             for (Object keys : td.keySet()) {
       
   110                 Object[] keyValues = ((List<?>) keys).toArray();
       
   111                 for (int i = 0; i < size; i++) {
       
   112                     String key = keyNames.get(i);
       
   113                     Object value = keyValues[i];
       
   114                     if (value instanceof String) {
       
   115                         settings.put(key, (String) value);
       
   116                     }
       
   117                 }
       
   118             }
       
   119         }
       
   120     }
       
   121 
       
   122     /**
       
   123      * Returns the name of the recording associated with this
       
   124      * {@code RecordingInfo}.
       
   125      *
       
   126      * @return the recording name, not {@code null}
       
   127      *
       
   128      * @see Recording#getName()
       
   129      */
       
   130     public String getName() {
       
   131         return name;
       
   132     }
       
   133 
       
   134     /**
       
   135      * Returns the unique ID for the recording associated with this
       
   136      * {@code RecordingInfo}.
       
   137      *
       
   138      * @return the recording ID
       
   139      *
       
   140      * @see Recording#getId()
       
   141      */
       
   142     public long getId() {
       
   143         return id;
       
   144     }
       
   145 
       
   146     /**
       
   147      * Returns if the recording associated with this {@code RecordingInfo}
       
   148      * should be dumped to file when the JVM exits.
       
   149      *
       
   150      * @return {@code true} if recording should be dumped on exit, {@code false}
       
   151      *         otherwise
       
   152      *
       
   153      * @see Recording#getDumpOnExit()
       
   154      */
       
   155     public boolean getDumpOnExit() {
       
   156         return dumpOnExit;
       
   157     }
       
   158 
       
   159     /**
       
   160      * Returns how many seconds data should be kept on disk, or {@code 0} if
       
   161      * data is to be kept forever.
       
   162      * <p>
       
   163      * In-memory recordings are not affected by maximum age.
       
   164      *
       
   165      * @see Recording#getMaxAge()
       
   166      * @see Recording#setToDisk(boolean)
       
   167      * @return how long data should be kept on disk, measured in seconds
       
   168      *
       
   169      */
       
   170     public long getMaxAge() {
       
   171         return maxAge;
       
   172     }
       
   173 
       
   174     /**
       
   175      * Returns the amount of data, measured in bytes, the recording associated
       
   176      * with this {@code RecordingInfo}, should be kept on disk, before it's
       
   177      * rotated away, or {@code 0} if data is to be kept indefinitely.
       
   178      * <p>
       
   179      * In-memory recordings are not affected by maximum size.
       
   180      *
       
   181      * @return the amount of data should be kept on disk, in bytes
       
   182      *
       
   183      * @see Recording#setToDisk(boolean)
       
   184      * @see Recording#getMaxSize()
       
   185      */
       
   186     public long getMaxSize() {
       
   187         return maxSize;
       
   188     }
       
   189 
       
   190     /**
       
   191      * Returns a {@code String} representation of state of the recording
       
   192      * associated with this {@code RecordingInfo}.
       
   193      * <p>
       
   194      * Valid return values are {@code "NEW"}, {@code "DELAYED"}, {@code "STARTING"},
       
   195      * {@code "RUNNING"}, {@code "STOPPING"}, {@code "STOPPED"} and {@code "CLOSED"}.
       
   196      *
       
   197      * @return the recording state, not {@code null}
       
   198      *
       
   199      * @see RecordingState#toString()
       
   200      * @see Recording#getState()
       
   201      */
       
   202     public String getState() {
       
   203         return state;
       
   204     }
       
   205 
       
   206     /**
       
   207      * Returns start time of the recording associated with this
       
   208      * {@code RecordingInfo}, measured as ms since epoch, or {@code null} if the
       
   209      * recording hasn't started.
       
   210      *
       
   211      * @return the start time of the recording, or {@code null} if the recording
       
   212      *         hasn't started
       
   213      *
       
   214      * @see Recording#getStartTime()
       
   215      */
       
   216     public long getStartTime() {
       
   217         return startTime;
       
   218     }
       
   219 
       
   220     /**
       
   221      * Returns the actual or expected stop time of the recording associated with
       
   222      * this {@code RecordingInfo}, measured as ms since epoch, or {@code null}
       
   223      * if the expected or actual stop time is not known, which can only happen
       
   224      * if the recording has not yet been stopped.
       
   225      *
       
   226      * @return the stop time of recording, or {@code null} if recording hasn't
       
   227      *         been stopped.
       
   228      *
       
   229      * @see Recording#getStopTime()
       
   230      */
       
   231     public long getStopTime() {
       
   232         return stopTime;
       
   233     }
       
   234 
       
   235     /**
       
   236      * Returns the settings for the recording associated with this
       
   237      * {@code RecordingInfo}.
       
   238      *
       
   239      * @return the recording settings, not {@code null}
       
   240      *
       
   241      * @see Recording#getSettings()
       
   242      */
       
   243     public Map<String, String> getSettings() {
       
   244         return settings;
       
   245     }
       
   246 
       
   247     /**
       
   248      * Returns destination path where data, for the recording associated with
       
   249      * this {@link RecordingInfo}, should be written when the recording stops,
       
   250      * or {@code null} if the recording should not be written.
       
   251      *
       
   252      * @return the destination, or {@code null} if not set
       
   253      *
       
   254      * @see Recording#getDestination()
       
   255      */
       
   256     public String getDestination() {
       
   257         return destination;
       
   258     }
       
   259 
       
   260     /**
       
   261      * Returns a string description of the recording associated with this
       
   262      * {@code RecordingInfo}
       
   263      *
       
   264      * @return description, not {@code null}
       
   265      */
       
   266     @Override
       
   267     public String toString() {
       
   268         Stringifier s = new Stringifier();
       
   269         s.add("name", name);
       
   270         s.add("id", id);
       
   271         s.add("maxAge", maxAge);
       
   272         s.add("maxSize", maxSize);
       
   273         return s.toString();
       
   274     }
       
   275 
       
   276     /**
       
   277      * Returns the amount data recorded by recording. associated with this
       
   278      * {@link RecordingInfo}.
       
   279      *
       
   280      * @return the amount of recorded data, measured in bytes
       
   281      */
       
   282     public long getSize() {
       
   283         return size;
       
   284     }
       
   285 
       
   286     /**
       
   287      * Returns {@code true} if the recording associated with this
       
   288      * {@code RecordingInfo} should be flushed to disk, when memory buffers are
       
   289      * full, {@code false} otherwise.
       
   290      *
       
   291      * @return {@code true} if recording is to disk, {@code false} otherwise
       
   292      */
       
   293     public boolean isToDisk() {
       
   294         return disk;
       
   295     }
       
   296 
       
   297     /**
       
   298      * Returns the desired duration, measured in seconds, of the recording
       
   299      * associated with this {@link RecordingInfo}, or {code 0} if no duration
       
   300      * has been set.
       
   301      *
       
   302      * @return the desired duration, or {code 0} if no duration has been set
       
   303      *
       
   304      * @see Recording#getDuration()
       
   305      */
       
   306     public long getDuration() {
       
   307         return durationInSeconds;
       
   308     }
       
   309 
       
   310     /**
       
   311      * Returns a {@code RecordingInfo} represented by the specified
       
   312      * {@code CompositeData} object.
       
   313      * <p>
       
   314      * The specified {@code CompositeData} must have the following item names and
       
   315      * item types to be valid. <blockquote>
       
   316      * <table class="striped">
       
   317      * <caption>Supported names and types in a specified {@code CompositeData} object</caption>
       
   318      * <thead>
       
   319      * <tr>
       
   320      * <th scope="col" style="text-align:left">Name</th>
       
   321      * <th scope="col" style="text-align:left">Type</th>
       
   322      * </tr>
       
   323      * </thead>
       
   324      * <tbody>
       
   325      * <tr>
       
   326      * <th scope="row">id</th>
       
   327      * <td>{@code Long}</td>
       
   328      * </tr>
       
   329      * <tr>
       
   330      * <th scope="row">name</th>
       
   331      * <td>{@code String}</td>
       
   332      * </tr>
       
   333      * <tr>
       
   334      * <th scope="row">state</th>
       
   335      * <td>{@code String}</td>
       
   336      * </tr>
       
   337      * <tr>
       
   338      * <th scope="row">dumpOnExit</th>
       
   339      * <td>{@code Boolean}</td>
       
   340      * </tr>
       
   341      * <tr>
       
   342      * <th scope="row">size</th>
       
   343      * <td>{@code Long}</td>
       
   344      * </tr>
       
   345      * <tr>
       
   346      * <th scope="row">disk</th>
       
   347      * <td>{@code Boolean}</td>
       
   348      * </tr>
       
   349      * <tr>
       
   350      * <th scope="row">maxAge</th>
       
   351      * <td>{@code Long}</td>
       
   352      * </tr>
       
   353      * <tr>
       
   354      * <th scope="row">maxSize</th>
       
   355      * <td>{@code Long}</td>
       
   356      * </tr>
       
   357      * <tr>
       
   358      * <th scope="row">startTime</th>
       
   359      * <td>{@code Long}</td>
       
   360      * </tr>
       
   361      * <tr>
       
   362      * <th scope="row">stopTime</th>
       
   363      * <td>{@code Long}</td>
       
   364      * </tr>
       
   365      * <tr>
       
   366      * <th scope="row">destination</th>
       
   367      * <td>{@code String}</td>
       
   368      * </tr>
       
   369      * <tr>
       
   370      * <th scope="row">duration</th>
       
   371      * <td>{@code Long}</td>
       
   372      * </tr>
       
   373      * <tr>
       
   374      * <th scope="row">settings</th>
       
   375      * <td>{@code javax.management.openmbean.CompositeData[]} whose element type
       
   376      * is the mapped type for {@link SettingDescriptorInfo} as specified in the
       
   377      * {@link SettingDescriptorInfo#from} method.</td>
       
   378      * </tr>
       
   379      * </tbody>
       
   380      * </table>
       
   381      * </blockquote>
       
   382      *
       
   383      * @param cd {@code CompositeData} representing the {@code RecordingInfo} to
       
   384      *        return
       
   385      *
       
   386      * @throws IllegalArgumentException if {@code cd} does not represent a valid
       
   387      *         {@code RecordingInfo}
       
   388      *
       
   389      * @return the {@code RecordingInfo} represented by {@code cd}, or
       
   390      *         {@code null} if {@code cd} is {@code null}
       
   391      */
       
   392     public static RecordingInfo from(CompositeData cd) {
       
   393         if (cd == null) {
       
   394             return null;
       
   395         }
       
   396         return new RecordingInfo(cd);
       
   397     }
       
   398 }