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

# User Rev Content
1 tdb 1.16 /*
2     * i-scream central monitoring system
3 tdb 1.17 * http://www.i-scream.org.uk
4 tdb 1.16 * 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 ajm 1.1 //---PACKAGE DECLARATION---
22 tdb 1.9 package uk.org.iscream.cms.server.client.monitors;
23 ajm 1.1
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 tdb 1.9 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 ajm 1.1
35     /**
36     * This Monitor watches the Disks for all machines
37     *
38 tdb 1.16 * @author $Author: tdb $
39 tdb 1.17 * @version $Id: Disk__Monitor.java,v 1.16 2002/05/18 18:16:00 tdb Exp $
40 ajm 1.1 */
41     public class Disk__Monitor extends MonitorSkeleton {
42    
43     //---FINAL ATTRIBUTES---
44    
45     /**
46     * The current CVS revision of this class
47     */
48 tdb 1.17 public final String REVISION = "$Revision: 1.16 $";
49 ajm 1.1
50 tdb 1.8 /**
51     * A description of this monitor
52     */
53 ajm 1.1 public final String DESC = "Monitors all host disks.";
54    
55     //---STATIC METHODS---
56    
57     //---CONSTRUCTORS---
58    
59     //---PUBLIC METHODS---
60 tdb 1.8
61     /**
62     * Analyse a packet of data, and generate an alert if
63     * necessary.
64     *
65     * @param packet the XMLPacket to analyse
66     */
67 ajm 1.1 public void analysePacket(XMLPacket packet) {
68 ajm 1.7 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 tdb 1.8
75     // key prefix
76     String keyPrefix = "packet.disk.p";
77    
78 tdb 1.11 // a temporary holder for all the disk attributes we find
79 ajm 1.7 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 tdb 1.8 if(dataKey.startsWith(keyPrefix)) {
88 ajm 1.7 if(!disks.contains(dataKey)) {
89     String diskNumber = "";
90    
91     // pos is after "packet.disk.p"
92 tdb 1.8 int pos = keyPrefix.length();
93 ajm 1.7 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 tdb 1.8 disks.add(keyPrefix + diskNumber + ".attributes.used");
102 ajm 1.7
103     // device
104 tdb 1.8 disks.add(keyPrefix + diskNumber + ".attributes.name");
105     String device = packet.getParam(keyPrefix + diskNumber + ".attributes.name");
106 ajm 1.7 // mount point
107 tdb 1.8 disks.add(keyPrefix + diskNumber + ".attributes.mount");
108     String mount = packet.getParam(keyPrefix + diskNumber + ".attributes.mount");
109 ajm 1.7
110     // these next two will be used to calculate the %age
111     // total
112 tdb 1.8 disks.add(keyPrefix + diskNumber + ".attributes.kbytes");
113     String total = packet.getParam(keyPrefix + diskNumber + ".attributes.kbytes");
114 ajm 1.7 // available
115 tdb 1.8 disks.add(keyPrefix + diskNumber + ".attributes.avail");
116     String avail = packet.getParam(keyPrefix + diskNumber + ".attributes.avail");
117 ajm 1.7
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 tdb 1.15 // nb. use the mount as the key as this is unlikely to change,
123 tdb 1.12 // unlike diskNumber which could easily change
124     // (diskNumber is based on the order of df's output!)
125 tdb 1.15 if(!diskRegisters.containsKey(mount)) {
126     diskRegisters.put(mount, new Register(source, _name, mount));
127 ajm 1.7 }
128    
129     // get the register for this disk
130 tdb 1.15 Register reg = (Register) diskRegisters.get(mount);
131 ajm 1.7
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 ajm 1.2 }
139 ajm 1.7 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 ajm 1.2
147 ajm 1.7 boolean useValue = false;
148     try {
149 tdb 1.13 // try looking for a mount-point specific thresholdMeasure first
150     String option = _cp.getProperty("Host." + source, "Monitor." + _name + "." + mount + ".thresholdMeasure");
151 ajm 1.7 if (option.equals("VALUE")) {
152     useValue = true;
153 tdb 1.13 }
154 ajm 1.7 } catch (PropertyNotFoundException e) {
155 tdb 1.13 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 ajm 1.7 }
165 ajm 1.2
166 ajm 1.7 // this bit determines if the disk check is a % check
167     // or a kb check
168     String type;
169 tdb 1.10 double curValue;
170     int newThreshold;
171 ajm 1.7 if(useValue) {
172 tdb 1.10 // kb disk available
173     curValue = diskAvail;
174     // negate check
175     newThreshold = checkAttributeThreshold(curValue, reg, true);
176 ajm 1.7 type = "kb";
177     } else {
178     // % disk in use
179 tdb 1.10 curValue = (1 - (diskAvail / diskTotal)) * 100;
180     // normal check
181     newThreshold = checkAttributeThreshold(curValue, reg, false);
182 ajm 1.7 type = "%";
183 ajm 1.1 }
184 ajm 1.7
185     // format the diskInUse to a String
186     NumberFormat nf = NumberFormat.getInstance();
187     nf.setMaximumFractionDigits(2);
188     nf.setMinimumFractionDigits(2);
189 tdb 1.10 String strCurValue = nf.format(curValue);
190 ajm 1.7
191     // say which disk had the problem
192     String attributeName = "Disk in use " + type + " on " + mount + " (" + device + ")";
193    
194 tdb 1.10 processAlert(newThreshold, attributeName, reg, source, strCurValue);
195 ajm 1.1 }
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 tdb 1.9 * This uses the uk.org.iscream.cms.server.util.NameFormat class
205 ajm 1.1 * 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 tdb 1.8
225     /**
226     * Checks a piece of current data, and returns the
227     * threshold it breaches, if any.
228     *
229 tdb 1.10 * 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 tdb 1.8 * @param reg the Register for the host
236 tdb 1.10 * @param negateCheck whether to negate the check
237 tdb 1.8 * @return the threshold level breached, if any
238     */
239 tdb 1.14 private int checkAttributeThreshold(double value, Register reg, boolean negateCheck) {
240 ajm 1.1 for(int thresholdLevel = Alert.thresholdLevels.length - 1; thresholdLevel >= 0; thresholdLevel--) {
241     if (reg.getThreshold(thresholdLevel) != -1.0) {
242 tdb 1.10 if(!negateCheck) {
243     // normal check - has the value gone *over* the threshold
244 tdb 1.14 if(((double) reg.getThreshold(thresholdLevel)) < value) {
245 tdb 1.10 return thresholdLevel;
246     }
247     }
248     else {
249     // negated check - has the value gone *under* the threshold
250 tdb 1.14 if(((double) reg.getThreshold(thresholdLevel)) > value) {
251 tdb 1.10 return thresholdLevel;
252     }
253 ajm 1.1 }
254     }
255     }
256     return Alert.thresholdNORMAL;
257     }
258    
259     //---ACCESSOR/MUTATOR METHODS---
260 ajm 1.7
261 tdb 1.8 /**
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 ajm 1.7 protected Queue getQueue() {
269     return MonitorManager.getInstance().getDataQueue();
270     }
271    
272 ajm 1.1 //---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 tdb 1.8
290     /**
291     * A HashMap of Registers (or groups of Registers), one
292     * for each host we're monitoring.
293     */
294 ajm 1.1 private HashMap _hosts = new HashMap();
295    
296     //---STATIC ATTRIBUTES---
297    
298     }