1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package info.rolandkrueger.roklib.system;
25
26 import java.io.BufferedReader;
27 import java.io.File;
28 import java.io.IOException;
29 import java.io.InputStreamReader;
30 import java.util.logging.Logger;
31 import java.util.regex.Matcher;
32 import java.util.regex.Pattern;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 public class VMStatSwappingDetectionThread extends MemorySwappingDetectionThread
56 {
57 protected static Logger sLogger = Logger.getLogger (VMStatSwappingDetectionThread.class
58 .getPackage ().getName ());
59 private final static String CMD_STRING = "%s %d";
60
61
62
63
64
65 private final static Pattern SWAP_PATTERN = Pattern
66 .compile ("^(?:\\s*\\d+){6}\\s*(\\d+)\\s*(\\d+).*$");
67
68 private String mVMStatBinaryLocation;
69 private int mSamplingRate;
70 private Process mVMStatProcess;
71 private BufferedReader mProcessReader;
72 private String mLine;
73 private Matcher mMatcher;
74
75
76
77
78
79
80
81
82
83
84
85
86
87 public VMStatSwappingDetectionThread (MemorySwappingEventListener listener,
88 String vmstatBinaryLocation, int samplingRate)
89 {
90 super (listener);
91 mVMStatBinaryLocation = vmstatBinaryLocation;
92 if (mVMStatBinaryLocation.matches ("\\s"))
93 throw new IllegalArgumentException (
94 "Using a whitespace character in the vmstat binary location string is not allowed.");
95
96 File vmstatBinary = new File (mVMStatBinaryLocation);
97 if (! vmstatBinary.canRead ())
98 throw new IllegalArgumentException ("Unable to read the given file for the vmstat binary.");
99
100 mSamplingRate = samplingRate;
101 if (samplingRate <= 0)
102 throw new IllegalArgumentException ("Sampling rate must be at least 1.");
103 }
104
105
106
107
108
109
110 public synchronized boolean startProcess ()
111 {
112
113 ProcessBuilder procBuilder = new ProcessBuilder (String.format (CMD_STRING,
114 mVMStatBinaryLocation, mSamplingRate).split (" "));
115 procBuilder.redirectErrorStream (true);
116
117 try
118 {
119 mVMStatProcess = procBuilder.start ();
120 mProcessReader = new BufferedReader (new InputStreamReader (mVMStatProcess.getInputStream ()));
121 } catch (IOException ioExc)
122 {
123 sLogger.warning ("Unable to start vmstat process with binary :" + mVMStatBinaryLocation);
124 return false;
125 }
126 super.start ();
127 return true;
128 }
129
130 @Override
131 protected boolean isSwapEventDetected ()
132 {
133 if (mProcessReader == null)
134 throw new IllegalStateException ("Thread must be started with startProcess().");
135 try
136 {
137 mLine = mProcessReader.readLine ();
138 if (mLine == null)
139 {
140 sLogger.info ("vmstat process has finished.");
141 stopThread ();
142 return false;
143 }
144 } catch (IOException e)
145 {
146 stopThread ();
147 return false;
148 }
149
150 mMatcher = SWAP_PATTERN.matcher (mLine);
151 if (mMatcher.matches ())
152 {
153 if (! mMatcher.group (1).equals ("0") || ! mMatcher.group (2).equals ("0")) return true;
154 }
155
156 return false;
157 }
158
159 @Override
160 protected void stopThreadImpl ()
161 {
162 if (mVMStatProcess != null)
163 {
164 sLogger.info ("Stopping vmstat process.");
165 mVMStatProcess.destroy ();
166 }
167 }
168
169 }