src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecorder.java
author egahlin
Fri, 22 Nov 2019 17:20:43 +0100
changeset 59226 a0f39cc47387
parent 58863 c16ac7a2eba4
permissions -rw-r--r--
8233700: EventStream not closed Reviewed-by: mgronlun, mseledtsov
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     1
/*
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
     2
 * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     4
 *
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    10
 *
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    15
 * accompanied this code).
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    16
 *
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    20
 *
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    23
 * questions.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    24
 */
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    25
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    26
package jdk.jfr.internal;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    27
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    28
import static jdk.jfr.internal.LogLevel.INFO;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    29
import static jdk.jfr.internal.LogLevel.TRACE;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    30
import static jdk.jfr.internal.LogLevel.WARN;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    31
import static jdk.jfr.internal.LogTag.JFR;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    32
import static jdk.jfr.internal.LogTag.JFR_SYSTEM;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    33
59226
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
    34
import java.io.IOException;
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    35
import java.security.AccessControlContext;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    36
import java.security.AccessController;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    37
import java.time.Duration;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    38
import java.time.Instant;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    39
import java.util.ArrayList;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    40
import java.util.Collections;
50745
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
    41
import java.util.HashMap;
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    42
import java.util.HashSet;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    43
import java.util.List;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    44
import java.util.Map;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    45
import java.util.Set;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    46
import java.util.Timer;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    47
import java.util.TimerTask;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    48
import java.util.concurrent.CopyOnWriteArrayList;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    49
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    50
import jdk.jfr.EventType;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    51
import jdk.jfr.FlightRecorder;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    52
import jdk.jfr.FlightRecorderListener;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    53
import jdk.jfr.Recording;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    54
import jdk.jfr.RecordingState;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    55
import jdk.jfr.events.ActiveRecordingEvent;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    56
import jdk.jfr.events.ActiveSettingEvent;
59226
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
    57
import jdk.jfr.internal.SecuritySupport.SafePath;
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    58
import jdk.jfr.internal.SecuritySupport.SecureRecorderListener;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    59
import jdk.jfr.internal.instrument.JDKEvents;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    60
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    61
public final class PlatformRecorder {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    62
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
    63
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    64
    private final List<PlatformRecording> recordings = new ArrayList<>();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    65
    private final static List<SecureRecorderListener> changeListeners = new ArrayList<>();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    66
    private final Repository repository;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    67
    private final Timer timer;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    68
    private final static JVM jvm = JVM.getJVM();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    69
    private final EventType activeRecordingEvent;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    70
    private final EventType activeSettingEvent;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    71
    private final Thread shutdownHook;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    72
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    73
    private long recordingCounter = 0;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    74
    private RepositoryChunk currentChunk;
59226
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
    75
    private boolean inShutdown;
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    76
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    77
    public PlatformRecorder() throws Exception {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    78
        repository = Repository.getRepository();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    79
        Logger.log(JFR_SYSTEM, INFO, "Initialized disk repository");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    80
        repository.ensureRepository();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    81
        jvm.createNativeJFR();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    82
        Logger.log(JFR_SYSTEM, INFO, "Created native");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    83
        JDKEvents.initialize();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    84
        Logger.log(JFR_SYSTEM, INFO, "Registered JDK events");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    85
        JDKEvents.addInstrumentation();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    86
        startDiskMonitor();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    87
        activeRecordingEvent = EventType.getEventType(ActiveRecordingEvent.class);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    88
        activeSettingEvent = EventType.getEventType(ActiveSettingEvent.class);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    89
        shutdownHook = SecuritySupport.createThreadWitNoPermissions("JFR: Shutdown Hook", new ShutdownHook(this));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    90
        SecuritySupport.setUncaughtExceptionHandler(shutdownHook, new ShutdownHook.ExceptionHandler());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    91
        SecuritySupport.registerShutdownHook(shutdownHook);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    92
        timer = createTimer();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    93
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    94
52334
a181612f0715 8203629: Produce events in the JDK without a dependency on jdk.jfr
egahlin
parents: 50745
diff changeset
    95
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    96
    private static Timer createTimer() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    97
        try {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    98
            List<Timer> result = new CopyOnWriteArrayList<>();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    99
            Thread t = SecuritySupport.createThreadWitNoPermissions("Permissionless thread", ()-> {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   100
                result.add(new Timer("JFR Recording Scheduler", true));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   101
            });
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
   102
            jvm.exclude(t);
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   103
            t.start();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   104
            t.join();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   105
            return result.get(0);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   106
        } catch (InterruptedException e) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   107
            throw new IllegalStateException("Not able to create timer task. " + e.getMessage(), e);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   108
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   109
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   110
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   111
    public synchronized PlatformRecording newRecording(Map<String, String> settings) {
50197
f4735ff8d17d 8195818: JFR.start should increase autogenerated name by one
egahlin
parents: 50194
diff changeset
   112
        return newRecording(settings, ++recordingCounter);
f4735ff8d17d 8195818: JFR.start should increase autogenerated name by one
egahlin
parents: 50194
diff changeset
   113
    }
f4735ff8d17d 8195818: JFR.start should increase autogenerated name by one
egahlin
parents: 50194
diff changeset
   114
50745
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   115
    // To be used internally when doing dumps.
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   116
    // Caller must have recorder lock and close recording before releasing lock
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   117
    public PlatformRecording newTemporaryRecording() {
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   118
        if(!Thread.holdsLock(this)) {
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   119
            throw new InternalError("Caller must have recorder lock");
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   120
        }
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   121
        return newRecording(new HashMap<>(), 0);
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   122
    }
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   123
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   124
    private synchronized PlatformRecording newRecording(Map<String, String> settings, long id) {
50197
f4735ff8d17d 8195818: JFR.start should increase autogenerated name by one
egahlin
parents: 50194
diff changeset
   125
        PlatformRecording recording = new PlatformRecording(this, id);
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   126
        if (!settings.isEmpty()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   127
            recording.setSettings(settings);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   128
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   129
        recordings.add(recording);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   130
        return recording;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   131
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   132
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   133
    synchronized void finish(PlatformRecording recording) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   134
        if (recording.getState() == RecordingState.RUNNING) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   135
            recording.stop("Recording closed");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   136
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   137
        recordings.remove(recording);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   138
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   139
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   140
    public synchronized List<PlatformRecording> getRecordings() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   141
        return Collections.unmodifiableList(new ArrayList<PlatformRecording>(recordings));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   142
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   143
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   144
    public synchronized static void addListener(FlightRecorderListener changeListener) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   145
        AccessControlContext context = AccessController.getContext();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   146
        SecureRecorderListener sl = new SecureRecorderListener(context, changeListener);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   147
        boolean runInitialized;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   148
        synchronized (PlatformRecorder.class) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   149
            runInitialized = FlightRecorder.isInitialized();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   150
            changeListeners.add(sl);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   151
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   152
        if (runInitialized) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   153
            sl.recorderInitialized(FlightRecorder.getFlightRecorder());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   154
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   155
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   156
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   157
    public synchronized static boolean removeListener(FlightRecorderListener changeListener) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   158
        for (SecureRecorderListener s : new ArrayList<>(changeListeners)) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   159
            if (s.getChangeListener() == changeListener) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   160
                changeListeners.remove(s);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   161
                return true;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   162
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   163
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   164
        return false;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   165
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   166
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   167
    static synchronized List<FlightRecorderListener> getListeners() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   168
        return new ArrayList<>(changeListeners);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   169
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   170
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   171
    Timer getTimer() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   172
        return timer;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   173
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   174
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   175
    public static void notifyRecorderInitialized(FlightRecorder recorder) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   176
        Logger.log(JFR_SYSTEM, TRACE, "Notifying listeners that Flight Recorder is initialized");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   177
        for (FlightRecorderListener r : getListeners()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   178
            r.recorderInitialized(recorder);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   179
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   180
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   181
59226
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
   182
    synchronized void setInShutDown() {
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
   183
        this.inShutdown = true;
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
   184
    }
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
   185
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   186
    // called by shutdown hook
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   187
    synchronized void destroy() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   188
        try {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   189
            timer.cancel();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   190
        } catch (Exception ex) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   191
            Logger.log(JFR_SYSTEM, WARN, "Shutdown hook could not cancel timer");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   192
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   193
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   194
        for (PlatformRecording p : getRecordings()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   195
            if (p.getState() == RecordingState.RUNNING) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   196
                try {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   197
                    p.stop("Shutdown");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   198
                } catch (Exception ex) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   199
                    Logger.log(JFR, WARN, "Recording " + p.getName() + ":" + p.getId() + " could not be stopped");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   200
                }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   201
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   202
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   203
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   204
        JDKEvents.remove();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   205
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   206
        if (jvm.hasNativeJFR()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   207
            if (jvm.isRecording()) {
59226
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
   208
                jvm.endRecording();
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   209
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   210
            jvm.destroyNativeJFR();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   211
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   212
        repository.clear();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   213
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   214
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
   215
    synchronized long start(PlatformRecording recording) {
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   216
        // State can only be NEW or DELAYED because of previous checks
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   217
        Instant now = Instant.now();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   218
        recording.setStartTime(now);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   219
        recording.updateTimer();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   220
        Duration duration = recording.getDuration();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   221
        if (duration != null) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   222
            recording.setStopTime(now.plus(duration));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   223
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   224
        boolean toDisk = recording.isToDisk();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   225
        boolean beginPhysical = true;
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
   226
        long streamInterval = recording.getStreamIntervalMillis();
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   227
        for (PlatformRecording s : getRecordings()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   228
            if (s.getState() == RecordingState.RUNNING) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   229
                beginPhysical = false;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   230
                if (s.isToDisk()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   231
                    toDisk = true;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   232
                }
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
   233
                streamInterval = Math.min(streamInterval, s.getStreamIntervalMillis());
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   234
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   235
        }
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
   236
        long startNanos = -1;
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   237
        if (beginPhysical) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   238
            RepositoryChunk newChunk = null;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   239
            if (toDisk) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   240
                newChunk = repository.newChunk(now);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   241
                MetadataRepository.getInstance().setOutput(newChunk.getUnfishedFile().toString());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   242
            } else {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   243
                MetadataRepository.getInstance().setOutput(null);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   244
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   245
            currentChunk = newChunk;
59226
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
   246
            jvm.beginRecording();
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
   247
            startNanos = jvm.getChunkStartNanos();
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   248
            recording.setState(RecordingState.RUNNING);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   249
            updateSettings();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   250
            writeMetaEvents();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   251
        } else {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   252
            RepositoryChunk newChunk = null;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   253
            if (toDisk) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   254
                newChunk = repository.newChunk(now);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   255
                RequestEngine.doChunkEnd();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   256
                MetadataRepository.getInstance().setOutput(newChunk.getUnfishedFile().toString());
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
   257
                startNanos = jvm.getChunkStartNanos();
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   258
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   259
            recording.setState(RecordingState.RUNNING);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   260
            updateSettings();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   261
            writeMetaEvents();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   262
            if (currentChunk != null) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   263
                finishChunk(currentChunk, now, recording);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   264
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   265
            currentChunk = newChunk;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   266
        }
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
   267
        if (toDisk) {
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
   268
            RequestEngine.setFlushInterval(streamInterval);
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
   269
        }
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
   270
        RequestEngine.doChunkBegin();
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   271
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
   272
        return startNanos;
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   273
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   274
50745
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   275
    synchronized void stop(PlatformRecording recording) {
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   276
        RecordingState state = recording.getState();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   277
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   278
        if (Utils.isAfter(state, RecordingState.RUNNING)) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   279
            throw new IllegalStateException("Can't stop an already stopped recording.");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   280
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   281
        if (Utils.isBefore(state, RecordingState.RUNNING)) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   282
            throw new IllegalStateException("Recording must be started before it can be stopped.");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   283
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   284
        Instant now = Instant.now();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   285
        boolean toDisk = false;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   286
        boolean endPhysical = true;
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
   287
        long streamInterval = Long.MAX_VALUE;
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   288
        for (PlatformRecording s : getRecordings()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   289
            RecordingState rs = s.getState();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   290
            if (s != recording && RecordingState.RUNNING == rs) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   291
                endPhysical = false;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   292
                if (s.isToDisk()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   293
                    toDisk = true;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   294
                }
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
   295
                streamInterval = Math.min(streamInterval, s.getStreamIntervalMillis());
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   296
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   297
        }
50745
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   298
        OldObjectSample.emit(recording);
59226
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
   299
        recording.setFinalStartnanos(jvm.getChunkStartNanos());
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   300
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   301
        if (endPhysical) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   302
            RequestEngine.doChunkEnd();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   303
            if (recording.isToDisk()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   304
                if (currentChunk != null) {
59226
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
   305
                    if (inShutdown) {
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
   306
                        jvm.markChunkFinal();
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
   307
                    }
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   308
                    MetadataRepository.getInstance().setOutput(null);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   309
                    finishChunk(currentChunk, now, null);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   310
                    currentChunk = null;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   311
                }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   312
            } else {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   313
                // last memory
50745
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   314
                dumpMemoryToDestination(recording);
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   315
            }
59226
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
   316
            jvm.endRecording();
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   317
            disableEvents();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   318
        } else {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   319
            RepositoryChunk newChunk = null;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   320
            RequestEngine.doChunkEnd();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   321
            updateSettingsButIgnoreRecording(recording);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   322
            if (toDisk) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   323
                newChunk = repository.newChunk(now);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   324
                MetadataRepository.getInstance().setOutput(newChunk.getUnfishedFile().toString());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   325
            } else {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   326
                MetadataRepository.getInstance().setOutput(null);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   327
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   328
            writeMetaEvents();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   329
            if (currentChunk != null) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   330
                finishChunk(currentChunk, now, null);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   331
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   332
            currentChunk = newChunk;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   333
            RequestEngine.doChunkBegin();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   334
        }
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
   335
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
   336
        if (toDisk) {
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
   337
            RequestEngine.setFlushInterval(streamInterval);
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
   338
        } else {
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
   339
            RequestEngine.setFlushInterval(Long.MAX_VALUE);
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
   340
        }
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   341
        recording.setState(RecordingState.STOPPED);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   342
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   343
50745
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   344
    private void dumpMemoryToDestination(PlatformRecording recording)  {
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   345
        WriteableUserPath dest = recording.getDestination();
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   346
        if (dest != null) {
55256
3b22c7e00573 8224217: RecordingInfo should use textual representation of path
egahlin
parents: 53014
diff changeset
   347
            MetadataRepository.getInstance().setOutput(dest.getRealPathText());
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   348
            recording.clearDestination();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   349
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   350
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   351
    private void disableEvents() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   352
        MetadataRepository.getInstance().disableEvents();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   353
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   354
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   355
    void updateSettings() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   356
        updateSettingsButIgnoreRecording(null);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   357
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   358
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   359
    void updateSettingsButIgnoreRecording(PlatformRecording ignoreMe) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   360
        List<PlatformRecording> recordings = getRunningRecordings();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   361
        List<Map<String, String>> list = new ArrayList<>(recordings.size());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   362
        for (PlatformRecording r : recordings) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   363
            if (r != ignoreMe) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   364
                list.add(r.getSettings());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   365
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   366
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   367
        MetadataRepository.getInstance().setSettings(list);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   368
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   369
59226
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
   370
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
   371
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   372
    synchronized void rotateDisk() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   373
        Instant now = Instant.now();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   374
        RepositoryChunk newChunk = repository.newChunk(now);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   375
        RequestEngine.doChunkEnd();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   376
        MetadataRepository.getInstance().setOutput(newChunk.getUnfishedFile().toString());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   377
        writeMetaEvents();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   378
        if (currentChunk != null) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   379
            finishChunk(currentChunk, now, null);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   380
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   381
        currentChunk = newChunk;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   382
        RequestEngine.doChunkBegin();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   383
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   384
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   385
    private List<PlatformRecording> getRunningRecordings() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   386
        List<PlatformRecording> runningRecordings = new ArrayList<>();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   387
        for (PlatformRecording recording : getRecordings()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   388
            if (recording.getState() == RecordingState.RUNNING) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   389
                runningRecordings.add(recording);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   390
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   391
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   392
        return runningRecordings;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   393
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   394
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   395
    private List<RepositoryChunk> makeChunkList(Instant startTime, Instant endTime) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   396
        Set<RepositoryChunk> chunkSet = new HashSet<>();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   397
        for (PlatformRecording r : getRecordings()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   398
            chunkSet.addAll(r.getChunks());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   399
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   400
        if (chunkSet.size() > 0) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   401
            List<RepositoryChunk> chunks = new ArrayList<>(chunkSet.size());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   402
            for (RepositoryChunk rc : chunkSet) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   403
                if (rc.inInterval(startTime, endTime)) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   404
                    chunks.add(rc);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   405
                }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   406
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   407
            // n*log(n), should be able to do n*log(k) with a priority queue,
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   408
            // where k = number of recordings, n = number of chunks
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   409
            Collections.sort(chunks, RepositoryChunk.END_TIME_COMPARATOR);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   410
            return chunks;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   411
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   412
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   413
        return Collections.emptyList();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   414
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   415
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   416
    private void startDiskMonitor() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   417
        Thread t = SecuritySupport.createThreadWitNoPermissions("JFR Periodic Tasks", () -> periodicTask());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   418
        SecuritySupport.setDaemonThread(t, true);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   419
        t.start();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   420
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   421
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   422
    private void finishChunk(RepositoryChunk chunk, Instant time, PlatformRecording ignoreMe) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   423
        chunk.finish(time);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   424
        for (PlatformRecording r : getRecordings()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   425
            if (r != ignoreMe && r.getState() == RecordingState.RUNNING) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   426
                r.appendChunk(chunk);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   427
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   428
        }
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
   429
        FilePurger.purge();
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   430
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   431
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   432
    private void writeMetaEvents() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   433
        if (activeRecordingEvent.isEnabled()) {
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
   434
            ActiveRecordingEvent event = ActiveRecordingEvent.EVENT.get();
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   435
            for (PlatformRecording r : getRecordings()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   436
                if (r.getState() == RecordingState.RUNNING && r.shouldWriteMetadataEvent()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   437
                    event.id = r.getId();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   438
                    event.name = r.getName();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   439
                    WriteableUserPath p = r.getDestination();
55256
3b22c7e00573 8224217: RecordingInfo should use textual representation of path
egahlin
parents: 53014
diff changeset
   440
                    event.destination = p == null ? null : p.getRealPathText();
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   441
                    Duration d = r.getDuration();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   442
                    event.recordingDuration = d == null ? Long.MAX_VALUE : d.toMillis();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   443
                    Duration age = r.getMaxAge();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   444
                    event.maxAge = age == null ? Long.MAX_VALUE : age.toMillis();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   445
                    Long size = r.getMaxSize();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   446
                    event.maxSize = size == null ? Long.MAX_VALUE : size;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   447
                    Instant start = r.getStartTime();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   448
                    event.recordingStart = start == null ? Long.MAX_VALUE : start.toEpochMilli();
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
   449
                    Duration fi = r.getFlushInterval();
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
   450
                    event.flushInterval = fi == null ? Long.MAX_VALUE : fi.toMillis();
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   451
                    event.commit();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   452
                }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   453
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   454
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   455
        if (activeSettingEvent.isEnabled()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   456
            for (EventControl ec : MetadataRepository.getInstance().getEventControls()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   457
                ec.writeActiveSettingEvent();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   458
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   459
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   460
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   461
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   462
    private void periodicTask() {
53014
339d2fbe8675 8215284: Reduce noise induced by periodic task getFileSize()
mgronlun
parents: 52334
diff changeset
   463
        if (!jvm.hasNativeJFR()) {
339d2fbe8675 8215284: Reduce noise induced by periodic task getFileSize()
mgronlun
parents: 52334
diff changeset
   464
            return;
339d2fbe8675 8215284: Reduce noise induced by periodic task getFileSize()
mgronlun
parents: 52334
diff changeset
   465
        }
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   466
        while (true) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   467
            synchronized (this) {
53014
339d2fbe8675 8215284: Reduce noise induced by periodic task getFileSize()
mgronlun
parents: 52334
diff changeset
   468
                if (jvm.shouldRotateDisk()) {
339d2fbe8675 8215284: Reduce noise induced by periodic task getFileSize()
mgronlun
parents: 52334
diff changeset
   469
                    rotateDisk();
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   470
                }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   471
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   472
            long minDelta = RequestEngine.doPeriodic();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   473
            long wait = Math.min(minDelta, Options.getWaitInterval());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   474
            takeNap(wait);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   475
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   476
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   477
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   478
    private void takeNap(long duration) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   479
        try {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   480
            synchronized (JVM.FILE_DELTA_CHANGE) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   481
                JVM.FILE_DELTA_CHANGE.wait(duration < 10 ? 10 : duration);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   482
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   483
        } catch (InterruptedException e) {
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
   484
            // Ignore
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   485
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   486
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   487
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   488
    synchronized Recording newCopy(PlatformRecording r, boolean stop) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   489
        Recording newRec = new Recording();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   490
        PlatformRecording copy = PrivateAccess.getInstance().getPlatformRecording(newRec);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   491
        copy.setSettings(r.getSettings());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   492
        copy.setMaxAge(r.getMaxAge());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   493
        copy.setMaxSize(r.getMaxSize());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   494
        copy.setDumpOnExit(r.getDumpOnExit());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   495
        copy.setName("Clone of " + r.getName());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   496
        copy.setToDisk(r.isToDisk());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   497
        copy.setInternalDuration(r.getDuration());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   498
        copy.setStartTime(r.getStartTime());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   499
        copy.setStopTime(r.getStopTime());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   500
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   501
        if (r.getState() == RecordingState.NEW) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   502
            return newRec;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   503
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   504
        if (r.getState() == RecordingState.DELAYED) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   505
            copy.scheduleStart(r.getStartTime());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   506
            return newRec;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   507
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   508
        copy.setState(r.getState());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   509
        // recording has started, copy chunks
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   510
        for (RepositoryChunk c : r.getChunks()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   511
            copy.add(c);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   512
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   513
        if (r.getState() == RecordingState.RUNNING) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   514
            if (stop) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   515
                copy.stop("Stopped when cloning recording '" + r.getName() + "'");
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   516
            } else {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   517
                if (r.getStopTime() != null) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   518
                    TimerTask stopTask = copy.createStopTask();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   519
                    copy.setStopTask(copy.createStopTask());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   520
                    getTimer().schedule(stopTask, r.getStopTime().toEpochMilli());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   521
                }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   522
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   523
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   524
        return newRec;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   525
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   526
50745
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   527
    public synchronized void fillWithRecordedData(PlatformRecording target, Boolean pathToGcRoots) {
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   528
        boolean running = false;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   529
        boolean toDisk = false;
50745
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   530
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   531
        for (PlatformRecording r : recordings) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   532
            if (r.getState() == RecordingState.RUNNING) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   533
                running = true;
50745
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   534
                if (r.isToDisk()) {
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   535
                    toDisk = true;
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   536
                }
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   537
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   538
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   539
        // If needed, flush data from memory
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   540
        if (running) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   541
            if (toDisk) {
50745
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   542
                OldObjectSample.emit(recordings, pathToGcRoots);
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   543
                rotateDisk();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   544
            } else {
50745
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   545
                try (PlatformRecording snapshot = newTemporaryRecording()) {
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   546
                    snapshot.setToDisk(true);
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   547
                    snapshot.setShouldWriteActiveRecordingEvent(false);
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   548
                    snapshot.start();
50745
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   549
                    OldObjectSample.emit(recordings, pathToGcRoots);
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   550
                    snapshot.stop("Snapshot dump");
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   551
                    fillWithDiskChunks(target);
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   552
                }
50745
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   553
                return;
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   554
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   555
        }
50745
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   556
        fillWithDiskChunks(target);
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   557
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   558
50745
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   559
    private void fillWithDiskChunks(PlatformRecording target) {
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   560
        for (RepositoryChunk c : makeChunkList(null, null)) {
50745
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   561
            target.add(c);
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   562
        }
50745
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   563
        target.setState(RecordingState.STOPPED);
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   564
        Instant startTime = null;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   565
        Instant endTime = null;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   566
50745
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   567
        for (RepositoryChunk c : target.getChunks()) {
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   568
            if (startTime == null || c.getStartTime().isBefore(startTime)) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   569
                startTime = c.getStartTime();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   570
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   571
            if (endTime == null || c.getEndTime().isAfter(endTime)) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   572
                endTime = c.getEndTime();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   573
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   574
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   575
        Instant now = Instant.now();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   576
        if (startTime == null) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   577
            startTime = now;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   578
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   579
        if (endTime == null) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   580
            endTime = now;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   581
        }
50745
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   582
        target.setStartTime(startTime);
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   583
        target.setStopTime(endTime);
a390cbb82d47 8203929: Limit amount of data for JFR.dump
egahlin
parents: 50197
diff changeset
   584
        target.setInternalDuration(Duration.between(startTime, endTime));
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   585
    }
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 55256
diff changeset
   586
59226
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
   587
    public synchronized void migrate(SafePath repo) throws IOException {
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
   588
        // Must set repository while holding recorder lock so
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
   589
        // the final chunk in repository gets marked correctly
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
   590
        Repository.getRepository().setBasePath(repo);
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
   591
        boolean disk = false;
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
   592
        for (PlatformRecording s : getRecordings()) {
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
   593
            if (RecordingState.RUNNING == s.getState() && s.isToDisk()) {
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
   594
                disk = true;
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
   595
            }
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
   596
        }
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
   597
        if (disk) {
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
   598
            jvm.markChunkFinal();
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
   599
            rotateDisk();
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
   600
        }
a0f39cc47387 8233700: EventStream not closed
egahlin
parents: 58863
diff changeset
   601
    }
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   602
}