blob: 03c05b8815a2cf08749d44978e8005d20ef85637 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2004 Sun Microsystems, Inc. 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.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23
24import java.util.regex.*;
25import java.util.*;
26import java.net.URISyntaxException;
27import java.io.IOException;
28import sun.jvmstat.monitor.*;
29import sun.jvmstat.monitor.event.*;
30
31public class MonitorVmStartTerminate {
32
33 private static final int SLEEPERS = 10;
34 private static final int SLEEPTIME = 5000; // sleep time for a sleeper
35 private static final int EXECINTERVAL = 3000; // wait time between exec's
36 private static final int JOINTIME = (SLEEPERS * EXECINTERVAL)
37 + SLEEPTIME * 2;
38
39 public static void main(String args[]) throws Exception {
40
41 long now = System.currentTimeMillis();
42
43 String sleeperArgs = SLEEPTIME + " " + now;
44 String sleeperPattern = "Sleeper " + sleeperArgs + " \\d+$";
45
46 MonitoredHost host = MonitoredHost.getMonitoredHost("localhost");
47 host.setInterval(200);
48
49 SleeperListener listener = new SleeperListener(host, sleeperPattern);
50 host.addHostListener(listener);
51
52 SleeperStarter ss = new SleeperStarter(SLEEPERS, EXECINTERVAL,
53 sleeperArgs);
54 ss.start();
55
56 System.out.println("Waiting for "
57 + SLEEPERS + " sleepers to terminate");
58 try {
59 ss.join(JOINTIME);
60 } catch (InterruptedException e) {
61 System.err.println("Timed out waiting for sleepers");
62 }
63
64 if (listener.getStarted() != SLEEPERS) {
65 throw new RuntimeException(
66 "Too few sleepers started: "
67 + " started = " + listener.getStarted()
68 + " SLEEPERS = " + SLEEPERS);
69 }
70
71 if (listener.getStarted() != listener.getTerminated()) {
72 throw new RuntimeException(
73 "Started count != terminated count: "
74 + " started = " + listener.getStarted()
75 + " terminated = " + listener.getTerminated());
76 }
77 }
78}
79
80class SleeperListener implements HostListener {
81 private static final boolean DEBUG = false;
82
83 int started;
84 int terminated;
85 MonitoredHost host;
86 Matcher patternMatcher;
87 ArrayList targets;
88
89 public SleeperListener(MonitoredHost host, String sleeperPattern) {
90 this.host = host;
91 Pattern pattern = Pattern.compile(sleeperPattern);
92 patternMatcher = pattern.matcher("");
93 targets = new ArrayList();
94 }
95
96 private void printList(Iterator i, String msg) {
97 System.out.println(msg + ":");
98 while (i.hasNext()) {
99 Integer lvmid = (Integer)i.next();
100 try {
101 VmIdentifier vmid = new VmIdentifier("//" + lvmid.intValue());
102 MonitoredVm target = host.getMonitoredVm(vmid);
103
104 StringMonitor cmdMonitor =
105 (StringMonitor)target.findByName("sun.rt.javaCommand");
106 String cmd = cmdMonitor.stringValue();
107
108 System.out.println("\t" + lvmid.intValue() + ": "
109 + "\"" + cmd + "\"" + ": ");
110 } catch (URISyntaxException e) {
111 System.err.println("Unexpected URISyntaxException: "
112 + e.getMessage());
113 } catch (MonitorException e) {
114 System.out.println("\t" + lvmid.intValue()
115 + ": error reading monitoring data: "
116 + " target possibly terminated?");
117 }
118 }
119 }
120
121
122 private int addStarted(Iterator i) {
123 int found = 0;
124 while (i.hasNext()) {
125 try {
126 Integer lvmid = (Integer)i.next();
127 VmIdentifier vmid = new VmIdentifier("//" + lvmid.intValue());
128 MonitoredVm target = host.getMonitoredVm(vmid);
129
130 StringMonitor cmdMonitor =
131 (StringMonitor)target.findByName("sun.rt.javaCommand");
132 String cmd = cmdMonitor.stringValue();
133
134 patternMatcher.reset(cmd);
135 System.out.print("Started: " + lvmid.intValue()
136 + ": " + "\"" + cmd + "\"" + ": ");
137
138 if (patternMatcher.matches()) {
139 System.out.println("matches pattern - recorded");
140 targets.add(lvmid);
141 found++;
142 }
143 else {
144 System.out.println("does not match pattern - ignored");
145 }
146 } catch (URISyntaxException e) {
147 System.err.println("Unexpected URISyntaxException: "
148 + e.getMessage());
149 } catch (MonitorException e) {
150 System.err.println("Unexpected MonitorException: "
151 + e.getMessage());
152 }
153 }
154 return found;
155 }
156
157 private int removeTerminated(Iterator i) {
158 int found = 0;
159 while (i.hasNext()) {
160 Integer lvmid = (Integer)i.next();
161 /*
162 * we don't attempt to attach to the target here as it's
163 * now dead and has no jvmstat share memory file. Just see
164 * if the process id is among those that we saved when we
165 * started the targets (note - duplicated allowed and somewhat
166 * expected on windows);
167 */
168 System.out.print("Terminated: " + lvmid.intValue() + ": ");
169 if (targets.contains(lvmid)) {
170 System.out.println("matches pattern - termination recorded");
171 targets.remove(lvmid);
172 found++;
173 }
174 else {
175 System.out.println("does not match pattern - ignored");
176 }
177 }
178 return found;
179 }
180
181 public synchronized int getStarted() {
182 return started;
183 }
184
185 public synchronized int getTerminated() {
186 return terminated;
187 }
188
189 public void vmStatusChanged(VmStatusChangeEvent ev) {
190 if (DEBUG) {
191 printList(ev.getActive().iterator(), "Active");
192 printList(ev.getStarted().iterator(), "Started");
193 printList(ev.getTerminated().iterator(), "Terminated");
194 }
195
196 int recentlyStarted = addStarted(ev.getStarted().iterator());
197 int recentlyTerminated = removeTerminated(
198 ev.getTerminated().iterator());
199
200 synchronized (this) {
201 started += recentlyStarted;
202 terminated += recentlyTerminated;
203 }
204 }
205
206 public void disconnected(HostEvent ev) {
207 }
208}
209
210class SleeperStarter extends Thread {
211
212 JavaProcess[] processes;
213 int execInterval;
214 String args;
215
216 public SleeperStarter(int sleepers, int execInterval, String args) {
217 this.execInterval = execInterval;
218 this.args = args;
219 this.processes = new JavaProcess[sleepers];
220 }
221
222 private synchronized int active() {
223 int active = processes.length;
224 for(int i = 0; i < processes.length; i++) {
225 try {
226 int exitValue = processes[i].exitValue();
227 active--;
228 } catch (IllegalThreadStateException e) {
229 // process hasn't exited yet
230 }
231 }
232 return active;
233 }
234
235 public void run() {
236 System.out.println("Starting " + processes.length + " sleepers");
237
238 String[] classpath = {
239 "-classpath",
240 System.getProperty("java.class.path")
241 };
242
243 for (int i = 0; i < processes.length; i++) {
244 try {
245 System.out.println("Starting Sleeper " + i);
246 synchronized(this) {
247 processes[i] = new JavaProcess("Sleeper", args + " " + i);
248 processes[i].addOptions(classpath);
249 }
250 processes[i].start();
251 Thread.sleep(execInterval);
252 } catch (InterruptedException ignore) {
253 } catch (IOException e) {
254 System.err.println(
255 "IOException trying to start Sleeper " + i + ": "
256 + e.getMessage());
257 }
258 }
259
260 // spin waiting for the processes to terminate
261 while (active() > 0) ;
262
263 // give final termination event a change to propogate to
264 // the HostListener
265 try { Thread.sleep(2000); } catch (InterruptedException ignore) { }
266 }
267}