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.16
Committed: Sat May 18 18:16:00 2002 UTC (22 years ago) by tdb
Branch: MAIN
Changes since 1.15: +22 -3 lines
Log Message:
i-scream is now licensed under the GPL. I've added the GPL headers to every
source file, and put a full copy of the license in the appropriate places.
I think I've covered everything. This is going to be a mad commit ;)

File Contents

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