1/*
2 * Copyright (c) 2004, 2010, 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
26package sun.tools.jstat;
27
28import java.util.*;
29import sun.jvmstat.monitor.*;
30import sun.jvmstat.monitor.event.*;
31
32/**
33 * Application to output jvmstat statistics exported by a target Java
34 * Virtual Machine. The jstat tool gets its inspiration from the suite
35 * of 'stat' tools, such as vmstat, iostat, mpstat, etc., available in
36 * various UNIX platforms.
37 *
38 * @author Brian Doherty
39 * @since 1.5
40 */
41public class Jstat {
42    private static Arguments arguments;
43
44    public static void main(String[] args) {
45        try {
46            arguments = new Arguments(args);
47        } catch (IllegalArgumentException e) {
48            System.err.println(e.getMessage());
49            Arguments.printUsage(System.err);
50            System.exit(1);
51        }
52
53        if (arguments.isHelp()) {
54            Arguments.printUsage(System.out);
55            System.exit(0);
56        }
57
58        if (arguments.isOptions()) {
59            OptionLister ol = new OptionLister(arguments.optionsSources());
60            ol.print(System.out);
61            System.exit(0);
62        }
63
64        try {
65            if (arguments.isList()) {
66                logNames();
67            } else if (arguments.isSnap()) {
68                logSnapShot();
69            } else {
70                logSamples();
71            }
72        } catch (MonitorException e) {
73            e.printStackTrace();
74            System.exit(1);
75        }
76        System.exit(0);
77    }
78
79    static void logNames() throws MonitorException {
80        VmIdentifier vmId = arguments.vmId();
81        int interval = arguments.sampleInterval();
82        MonitoredHost monitoredHost = MonitoredHost.getMonitoredHost(vmId);
83        MonitoredVm monitoredVm = monitoredHost.getMonitoredVm(vmId, interval);
84        JStatLogger logger = new JStatLogger(monitoredVm);
85        logger.printNames(arguments.counterNames(), arguments.comparator(),
86                          arguments.showUnsupported(), System.out);
87        monitoredHost.detach(monitoredVm);
88    }
89
90    static void logSnapShot() throws MonitorException {
91        VmIdentifier vmId = arguments.vmId();
92        int interval = arguments.sampleInterval();
93        MonitoredHost monitoredHost = MonitoredHost.getMonitoredHost(vmId);
94        MonitoredVm monitoredVm = monitoredHost.getMonitoredVm(vmId, interval);
95        JStatLogger logger = new JStatLogger(monitoredVm);
96        logger.printSnapShot(arguments.counterNames(), arguments.comparator(),
97                             arguments.isVerbose(), arguments.showUnsupported(),
98                             System.out);
99        monitoredHost.detach(monitoredVm);
100    }
101
102    static void logSamples() throws MonitorException {
103        final VmIdentifier vmId = arguments.vmId();
104        int interval = arguments.sampleInterval();
105        final MonitoredHost monitoredHost =
106                MonitoredHost.getMonitoredHost(vmId);
107        MonitoredVm monitoredVm = monitoredHost.getMonitoredVm(vmId, interval);
108        final JStatLogger logger = new JStatLogger(monitoredVm);
109        OutputFormatter formatter = null;
110
111        if (arguments.isSpecialOption()) {
112            OptionFormat format = arguments.optionFormat();
113            formatter = new OptionOutputFormatter(monitoredVm, format);
114        } else {
115            List<Monitor> logged = monitoredVm.findByPattern(arguments.counterNames());
116            Collections.sort(logged, arguments.comparator());
117            List<Monitor> constants = new ArrayList<Monitor>();
118
119            for (Iterator<Monitor> i = logged.iterator(); i.hasNext(); /* empty */) {
120                Monitor m = i.next();
121                if (!(m.isSupported() || arguments.showUnsupported())) {
122                    i.remove();
123                    continue;
124                }
125                if (m.getVariability() == Variability.CONSTANT) {
126                    i.remove();
127                    if (arguments.printConstants()) constants.add(m);
128                } else if ((m.getUnits() == Units.STRING)
129                        && !arguments.printStrings()) {
130                    i.remove();
131                }
132            }
133
134            if (!constants.isEmpty()) {
135                logger.printList(constants, arguments.isVerbose(),
136                                 arguments.showUnsupported(), System.out);
137                if (!logged.isEmpty()) {
138                    System.out.println();
139                }
140            }
141
142            if (logged.isEmpty()) {
143                monitoredHost.detach(monitoredVm);
144                return;
145            }
146
147            formatter = new RawOutputFormatter(logged,
148                                               arguments.printStrings());
149        }
150
151        // handle user termination requests by stopping sampling loops
152        Runtime.getRuntime().addShutdownHook(new Thread() {
153            public void run() {
154                logger.stopLogging();
155            }
156        });
157
158        // handle target termination events for targets other than ourself
159        HostListener terminator = new HostListener() {
160            public void vmStatusChanged(VmStatusChangeEvent ev) {
161                Integer lvmid = vmId.getLocalVmId();
162                if (ev.getTerminated().contains(lvmid)) {
163                    logger.stopLogging();
164                } else if (!ev.getActive().contains(lvmid)) {
165                    logger.stopLogging();
166                }
167            }
168
169            public void disconnected(HostEvent ev) {
170                if (monitoredHost == ev.getMonitoredHost()) {
171                    logger.stopLogging();
172                }
173            }
174        };
175
176        if (vmId.getLocalVmId() != 0) {
177            monitoredHost.addHostListener(terminator);
178        }
179
180        logger.logSamples(formatter, arguments.headerRate(),
181                          arguments.sampleInterval(), arguments.sampleCount(),
182                          System.out);
183
184        // detach from host events and from the monitored target jvm
185        if (terminator != null) {
186            monitoredHost.removeHostListener(terminator);
187        }
188        monitoredHost.detach(monitoredVm);
189    }
190}
191