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.12
Committed: Wed Nov 7 17:55:40 2001 UTC (22 years, 6 months ago) by tdb
Branch: MAIN
Changes since 1.11: +8 -5 lines
Log Message:
Bug Fix for the following tracker ID on sourceforge:
  [ #479162 ] Disk Monitor - assumption of order

As stated in the above bug report, the state of a disk was stored using only
it's position in (ultimately) df's output. This position could change at runtime
which makes it not that reliable. The consequences of a change in the position
would not have been a disaster, but would have caused some confusion.

The key for storing a disks state is now the physical device name, as this is
will not change. The mount point was considered as the key, but it was decided
that this could change at runtime too.

File Contents

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