ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/server/uk/org/iscream/cms/server/client/monitors/Disk__Monitor.java
Revision: 1.17
Committed: Tue May 21 16:47:16 2002 UTC (22 years ago) by tdb
Branch: MAIN
Changes since 1.16: +3 -2 lines
Log Message:
Added URL to GPL headers.

File Contents

# Content
1 /*
2 * i-scream central monitoring system
3 * http://www.i-scream.org.uk
4 * Copyright (C) 2000-2002 i-scream
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21 //---PACKAGE DECLARATION---
22 package uk.org.iscream.cms.server.client.monitors;
23
24 //---IMPORTS---
25 import java.util.HashMap;
26 import java.util.ArrayList;
27 import java.util.Set;
28 import java.util.Iterator;
29 import java.text.NumberFormat;
30 import uk.org.iscream.cms.server.client.*;
31 import uk.org.iscream.cms.server.core.*;
32 import uk.org.iscream.cms.server.util.*;
33 import uk.org.iscream.cms.server.componentmanager.*;
34
35 /**
36 * This Monitor watches the Disks for all machines
37 *
38 * @author $Author: tdb $
39 * @version $Id: Disk__Monitor.java,v 1.16 2002/05/18 18:16:00 tdb Exp $
40 */
41 public class Disk__Monitor extends MonitorSkeleton {
42
43 //---FINAL ATTRIBUTES---
44
45 /**
46 * The current CVS revision of this class
47 */
48 public final String REVISION = "$Revision: 1.16 $";
49
50 /**
51 * A description of this monitor
52 */
53 public final String DESC = "Monitors all host disks.";
54
55 //---STATIC METHODS---
56
57 //---CONSTRUCTORS---
58
59 //---PUBLIC METHODS---
60
61 /**
62 * Analyse a packet of data, and generate an alert if
63 * necessary.
64 *
65 * @param packet the XMLPacket to analyse
66 */
67 public void analysePacket(XMLPacket packet) {
68 String source = packet.getParam("packet.attributes.machine_name");
69 if (!_hosts.containsKey(source)) {
70 _hosts.put(source, new HashMap());
71 }
72
73 HashMap diskRegisters = (HashMap) _hosts.get(source);
74
75 // key prefix
76 String keyPrefix = "packet.disk.p";
77
78 // a temporary holder for all the disk attributes we find
79 ArrayList disks = new ArrayList();
80
81 // unfortunatly we need to check the whole packet
82 // to find the disks, and then get the data attributes
83 Set packetSet = packet.getSet();
84 Iterator i = packetSet.iterator();
85 while (i.hasNext()) {
86 String dataKey = (String) i.next();
87 if(dataKey.startsWith(keyPrefix)) {
88 if(!disks.contains(dataKey)) {
89 String diskNumber = "";
90
91 // pos is after "packet.disk.p"
92 int pos = keyPrefix.length();
93 while (dataKey.charAt(pos) != '.') {
94 diskNumber = diskNumber + dataKey.charAt(pos);
95 pos++;
96 }
97
98 // add the disk to our list, with the packet data
99
100 // used (we won't use this value - but we need it to forget about it ;)
101 disks.add(keyPrefix + diskNumber + ".attributes.used");
102
103 // device
104 disks.add(keyPrefix + diskNumber + ".attributes.name");
105 String device = packet.getParam(keyPrefix + diskNumber + ".attributes.name");
106 // mount point
107 disks.add(keyPrefix + diskNumber + ".attributes.mount");
108 String mount = packet.getParam(keyPrefix + diskNumber + ".attributes.mount");
109
110 // these next two will be used to calculate the %age
111 // total
112 disks.add(keyPrefix + diskNumber + ".attributes.kbytes");
113 String total = packet.getParam(keyPrefix + diskNumber + ".attributes.kbytes");
114 // available
115 disks.add(keyPrefix + diskNumber + ".attributes.avail");
116 String avail = packet.getParam(keyPrefix + diskNumber + ".attributes.avail");
117
118 // *** now process this disk ***
119
120 // check if we've seen this disk before on a previous run
121 // if not, we need to create a register for it
122 // nb. use the mount as the key as this is unlikely to change,
123 // unlike diskNumber which could easily change
124 // (diskNumber is based on the order of df's output!)
125 if(!diskRegisters.containsKey(mount)) {
126 diskRegisters.put(mount, new Register(source, _name, mount));
127 }
128
129 // get the register for this disk
130 Register reg = (Register) diskRegisters.get(mount);
131
132 // get the packet data
133 double diskTotal, diskAvail;
134 try {
135
136 if(total==null || avail==null) {
137 throw new NumberFormatException("Disk data invalid");
138 }
139 diskTotal = Double.parseDouble(total);
140 diskAvail = Double.parseDouble(avail);
141 } catch (NumberFormatException e) {
142 _logger.write(this.toString(), Logger.WARNING, "Received packet from "+source+" with bad disk information: "+e);
143 // don't try to continue and process, try next disk
144 break;
145 }
146
147 boolean useValue = false;
148 try {
149 // try looking for a mount-point specific thresholdMeasure first
150 String option = _cp.getProperty("Host." + source, "Monitor." + _name + "." + mount + ".thresholdMeasure");
151 if (option.equals("VALUE")) {
152 useValue = true;
153 }
154 } catch (PropertyNotFoundException e) {
155 try {
156 // now look for a more general thresholdMeasure
157 String option = _cp.getProperty("Host." + source, "Monitor." + _name + ".thresholdMeasure");
158 if (option.equals("VALUE")) {
159 useValue = true;
160 }
161 } catch (PropertyNotFoundException f) {
162 // we default to percentage in any case
163 }
164 }
165
166 // this bit determines if the disk check is a % check
167 // or a kb check
168 String type;
169 double curValue;
170 int newThreshold;
171 if(useValue) {
172 // kb disk available
173 curValue = diskAvail;
174 // negate check
175 newThreshold = checkAttributeThreshold(curValue, reg, true);
176 type = "kb";
177 } else {
178 // % disk in use
179 curValue = (1 - (diskAvail / diskTotal)) * 100;
180 // normal check
181 newThreshold = checkAttributeThreshold(curValue, reg, false);
182 type = "%";
183 }
184
185 // format the diskInUse to a String
186 NumberFormat nf = NumberFormat.getInstance();
187 nf.setMaximumFractionDigits(2);
188 nf.setMinimumFractionDigits(2);
189 String strCurValue = nf.format(curValue);
190
191 // say which disk had the problem
192 String attributeName = "Disk in use " + type + " on " + mount + " (" + device + ")";
193
194 processAlert(newThreshold, attributeName, reg, source, strCurValue);
195 }
196 }
197 }
198 }
199
200 /**
201 * Overrides the {@link java.lang.Object#toString() Object.toString()}
202 * method to provide clean logging (every class should have this).
203 *
204 * This uses the uk.org.iscream.cms.server.util.NameFormat class
205 * to format the toString()
206 *
207 * @return the name of this class and its CVS revision
208 */
209 public String toString() {
210 return FormatName.getName(
211 _name,
212 getClass().getName(),
213 REVISION);
214 }
215
216 /**
217 * return the String representation of what the monitor does
218 */
219 public String getDescription(){
220 return DESC;
221 }
222
223 //---PRIVATE METHODS---
224
225 /**
226 * Checks a piece of current data, and returns the
227 * threshold it breaches, if any.
228 *
229 * The option to negate the check can be used in
230 * situations where being *below* the threshold
231 * is an 'alertable' situation. In this specific
232 * case, we'd do this with kb disk checks.
233 *
234 * @param value the current value
235 * @param reg the Register for the host
236 * @param negateCheck whether to negate the check
237 * @return the threshold level breached, if any
238 */
239 private int checkAttributeThreshold(double value, Register reg, boolean negateCheck) {
240 for(int thresholdLevel = Alert.thresholdLevels.length - 1; thresholdLevel >= 0; thresholdLevel--) {
241 if (reg.getThreshold(thresholdLevel) != -1.0) {
242 if(!negateCheck) {
243 // normal check - has the value gone *over* the threshold
244 if(((double) reg.getThreshold(thresholdLevel)) < value) {
245 return thresholdLevel;
246 }
247 }
248 else {
249 // negated check - has the value gone *under* the threshold
250 if(((double) reg.getThreshold(thresholdLevel)) > value) {
251 return thresholdLevel;
252 }
253 }
254 }
255 }
256 return Alert.thresholdNORMAL;
257 }
258
259 //---ACCESSOR/MUTATOR METHODS---
260
261 /**
262 * Returns a reference to a specific Queue for this
263 * monitor. This Queue returns only the data packets
264 * (based on type) that we want too look at.
265 *
266 * @return a reference to a Queue
267 */
268 protected Queue getQueue() {
269 return MonitorManager.getInstance().getDataQueue();
270 }
271
272 //---ATTRIBUTES---
273
274 /**
275 * This is the friendly identifier of the
276 * component this class is running in.
277 * eg, a Filter may be called "filter1",
278 * If this class does not have an owning
279 * component, a name from the configuration
280 * can be placed here. This name could also
281 * be changed to null for utility classes.
282 */
283 private String _name = "Disk";
284
285 /**
286 * A reference to the configuration proxy in use
287 */
288 private ConfigurationProxy _cp = ConfigurationProxy.getInstance();
289
290 /**
291 * A HashMap of Registers (or groups of Registers), one
292 * for each host we're monitoring.
293 */
294 private HashMap _hosts = new HashMap();
295
296 //---STATIC ATTRIBUTES---
297
298 }