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.10
Committed: Wed Nov 7 15:58:43 2001 UTC (22 years, 6 months ago) by tdb
Branch: MAIN
Changes since 1.9: +32 -16 lines
Log Message:
Bug Fix for the following tracker ID on sourceforge:
  [ #476364 ] disk monitor using 'value' thresholds

This bug fix addresses the issue with 'kb disk checks' not checking the amount
of disk space free, but rather the disk space in use. Whilst this was probably
the plan initially, it seems somewhat more useful to check the amount of free
space and alert if the value falls too low. This change has now been made.

It should be noted that the documentation talks about 'kb of disk in use', which
is not correct. The comments in the configuration file, however, talk about the
'absolute value of space free'. We'll take the latter as correct.

File Contents

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