jdk/test/sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.java
author duke
Sat, 01 Dec 2007 00:00:00 +0000
changeset 2 90ce3da70b43
child 5506 202f599c92aa
permissions -rw-r--r--
Initial load

/*
 * Copyright 2004 Sun Microsystems, Inc.  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.
 *
 * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

import java.util.regex.*;
import java.util.*;
import java.net.URISyntaxException;
import java.io.IOException;
import sun.jvmstat.monitor.*;
import sun.jvmstat.monitor.event.*;

public class MonitorVmStartTerminate {

    private static final int SLEEPERS = 10;
    private static final int SLEEPTIME = 5000;     // sleep time for a sleeper
    private static final int EXECINTERVAL = 3000;   // wait time between exec's
    private static final int JOINTIME = (SLEEPERS * EXECINTERVAL)
                                        + SLEEPTIME * 2;

    public static void main(String args[]) throws Exception {

        long now = System.currentTimeMillis();

        String sleeperArgs = SLEEPTIME + " " + now;
        String sleeperPattern = "Sleeper " + sleeperArgs + " \\d+$";

        MonitoredHost host = MonitoredHost.getMonitoredHost("localhost");
        host.setInterval(200);

        SleeperListener listener = new SleeperListener(host, sleeperPattern);
        host.addHostListener(listener);

        SleeperStarter ss = new SleeperStarter(SLEEPERS, EXECINTERVAL,
                                               sleeperArgs);
        ss.start();

        System.out.println("Waiting for "
                           + SLEEPERS + " sleepers to terminate");
        try {
            ss.join(JOINTIME);
        } catch (InterruptedException e) {
            System.err.println("Timed out waiting for sleepers");
        }

        if (listener.getStarted() != SLEEPERS) {
            throw new RuntimeException(
                    "Too few sleepers started: "
                    + " started = " + listener.getStarted()
                    + " SLEEPERS = " + SLEEPERS);
        }

        if (listener.getStarted() != listener.getTerminated()) {
            throw new RuntimeException(
                    "Started count != terminated count: "
                    + " started = " + listener.getStarted()
                    + " terminated = " + listener.getTerminated());
        }
    }
}

class SleeperListener implements HostListener {
    private static final boolean DEBUG = false;

    int started;
    int terminated;
    MonitoredHost host;
    Matcher patternMatcher;
    ArrayList targets;

    public SleeperListener(MonitoredHost host, String sleeperPattern) {
        this.host = host;
        Pattern pattern = Pattern.compile(sleeperPattern);
        patternMatcher = pattern.matcher("");
        targets = new ArrayList();
    }

    private void printList(Iterator i, String msg) {
        System.out.println(msg + ":");
        while (i.hasNext()) {
            Integer lvmid = (Integer)i.next();
            try {
                VmIdentifier vmid = new VmIdentifier("//" + lvmid.intValue());
                MonitoredVm target = host.getMonitoredVm(vmid);

                StringMonitor cmdMonitor =
                        (StringMonitor)target.findByName("sun.rt.javaCommand");
                String cmd = cmdMonitor.stringValue();

                System.out.println("\t" + lvmid.intValue() + ": "
                                   + "\"" + cmd + "\"" + ": ");
            } catch (URISyntaxException e) {
                System.err.println("Unexpected URISyntaxException: "
                                   + e.getMessage());
            } catch (MonitorException e) {
                System.out.println("\t" + lvmid.intValue()
                                   + ": error reading monitoring data: "
                                   + " target possibly terminated?");
            }
        }
    }


    private int addStarted(Iterator i) {
        int found = 0;
        while (i.hasNext()) {
            try {
                Integer lvmid = (Integer)i.next();
                VmIdentifier vmid = new VmIdentifier("//" + lvmid.intValue());
                MonitoredVm target = host.getMonitoredVm(vmid);

                StringMonitor cmdMonitor =
                        (StringMonitor)target.findByName("sun.rt.javaCommand");
                String cmd = cmdMonitor.stringValue();

                patternMatcher.reset(cmd);
                System.out.print("Started: " + lvmid.intValue()
                                 + ": " + "\"" + cmd + "\"" + ": ");

                if (patternMatcher.matches()) {
                    System.out.println("matches pattern - recorded");
                    targets.add(lvmid);
                    found++;
                }
                else {
                    System.out.println("does not match pattern - ignored");
                }
            } catch (URISyntaxException e) {
                System.err.println("Unexpected URISyntaxException: "
                                   + e.getMessage());
            } catch (MonitorException e) {
                System.err.println("Unexpected MonitorException: "
                                   + e.getMessage());
            }
        }
        return found;
    }

    private int removeTerminated(Iterator i) {
        int found = 0;
        while (i.hasNext()) {
            Integer lvmid = (Integer)i.next();
            /*
             * we don't attempt to attach to the target here as it's
             * now dead and has no jvmstat share memory file. Just see
             * if the process id is among those that we saved when we
             * started the targets (note - duplicated allowed and somewhat
             * expected on windows);
             */
            System.out.print("Terminated: " + lvmid.intValue() + ": ");
            if (targets.contains(lvmid)) {
                System.out.println("matches pattern - termination recorded");
                targets.remove(lvmid);
                found++;
            }
            else {
                System.out.println("does not match pattern - ignored");
            }
        }
        return found;
    }

    public synchronized int getStarted() {
        return started;
    }

    public synchronized int getTerminated() {
        return terminated;
    }

    public void vmStatusChanged(VmStatusChangeEvent ev) {
        if (DEBUG) {
            printList(ev.getActive().iterator(), "Active");
            printList(ev.getStarted().iterator(), "Started");
            printList(ev.getTerminated().iterator(), "Terminated");
        }

        int recentlyStarted = addStarted(ev.getStarted().iterator());
        int recentlyTerminated = removeTerminated(
                ev.getTerminated().iterator());

        synchronized (this) {
            started += recentlyStarted;
            terminated += recentlyTerminated;
        }
    }

    public void disconnected(HostEvent ev) {
    }
}

class SleeperStarter extends Thread {

    JavaProcess[] processes;
    int execInterval;
    String args;

    public SleeperStarter(int sleepers, int execInterval, String args) {
        this.execInterval = execInterval;
        this.args = args;
        this.processes = new JavaProcess[sleepers];
    }

    private synchronized int active() {
        int active = processes.length;
        for(int i = 0; i < processes.length; i++) {
            try {
                int exitValue = processes[i].exitValue();
                active--;
            } catch (IllegalThreadStateException e) {
                // process hasn't exited yet
            }
        }
        return active;
    }

    public void run() {
       System.out.println("Starting " + processes.length + " sleepers");

       String[] classpath = {
           "-classpath",
           System.getProperty("java.class.path")
       };

       for (int i = 0; i < processes.length; i++) {
           try {
               System.out.println("Starting Sleeper " + i);
               synchronized(this) {
                   processes[i] = new JavaProcess("Sleeper", args + " " + i);
                   processes[i].addOptions(classpath);
               }
               processes[i].start();
               Thread.sleep(execInterval);
           } catch (InterruptedException ignore) {
           } catch (IOException e) {
               System.err.println(
                       "IOException trying to start Sleeper " + i + ": "
                       + e.getMessage());
           }
       }

       // spin waiting for the processes to terminate
       while (active() > 0) ;

       // give final termination event a change to propogate to
       // the HostListener
       try { Thread.sleep(2000); } catch (InterruptedException ignore) { }
    }
}