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.23
Committed: Thu Feb 10 17:36:00 2005 UTC (19 years, 3 months ago) by tdb
Branch: MAIN
CVS Tags: HEAD
Changes since 1.22: +5 -5 lines
Log Message:
Commit various fixes from skel (Daniel Piddock):

CMS Server:
 - DiskMonitor was overflowing due to using an int variable for the
   inode count. Upped to a long.
 - Updated URL to iscream cms javadoc

RRD graphing:
 - added uptime logging and graph creation
 - diskio - Cope with modern linux device paths
   (eg "ide/host0/bus0/target0/lun0/disc") by replacing / with hex
 - diskio - Cope with windows device paths (eg "0 C: D:") by
   replacing : and space with hex
 - disk - Cope with windows mount points (eg C:\) by
   replacing : and \ with hex
 - net - Cope with windows network "device names". Basically
   the whole network card as it appears in Device Manager,
   not "Local Area Connection"
 - Include total processes (for winhost)

Also modified the PHP code to catch up. Patch slightly modified from that
submitted, but only minor alterations.

Thanks skel!

File Contents

# User Rev Content
1 tdb 1.16 /*
2     * i-scream central monitoring system
3 tdb 1.22 * http://www.i-scream.org
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 tdb 1.19 import java.util.HashSet;
27 ajm 1.1 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 tdb 1.18 import uk.org.iscream.cms.util.*;
33 tdb 1.9 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.23 * @version $Id: Disk__Monitor.java,v 1.22 2004/08/01 10:40:45 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.23 public final String REVISION = "$Revision: 1.22 $";
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 tdb 1.21 if(!checkBooleanConfig("Host." + source, "Monitor." + _name + ".enable")) {
70 tdb 1.20 return;
71     }
72 ajm 1.7 if (!_hosts.containsKey(source)) {
73     _hosts.put(source, new HashMap());
74     }
75 tdb 1.19 if (!_hostsInode.containsKey(source)) {
76     _hostsInode.put(source, new HashMap());
77     }
78 ajm 1.7
79     HashMap diskRegisters = (HashMap) _hosts.get(source);
80 tdb 1.19 HashMap diskInodeRegisters = (HashMap) _hostsInode.get(source);
81 tdb 1.8
82     // key prefix
83     String keyPrefix = "packet.disk.p";
84    
85 tdb 1.11 // a temporary holder for all the disk attributes we find
86 tdb 1.19 HashSet disks = new HashSet();
87 ajm 1.7
88     // unfortunatly we need to check the whole packet
89     // to find the disks, and then get the data attributes
90     Set packetSet = packet.getSet();
91     Iterator i = packetSet.iterator();
92     while (i.hasNext()) {
93     String dataKey = (String) i.next();
94 tdb 1.8 if(dataKey.startsWith(keyPrefix)) {
95 tdb 1.19 // pos is after "packet.disk.p"
96     int pos = keyPrefix.length();
97     String diskNumber = dataKey.substring(pos, dataKey.indexOf('.', pos));
98     String thisDisk = keyPrefix.concat(diskNumber);
99    
100     if(!disks.contains(thisDisk)) {
101     // add the disk to our list
102     disks.add(thisDisk);
103 ajm 1.7
104     // device
105 tdb 1.19 String device = packet.getParam(thisDisk + ".attributes.name");
106 ajm 1.7 // mount point
107 tdb 1.19 String mount = packet.getParam(thisDisk + ".attributes.mount");
108 ajm 1.7
109     // these next two will be used to calculate the %age
110     // total
111 tdb 1.19 String total = packet.getParam(thisDisk + ".attributes.total");
112 ajm 1.7 // available
113 tdb 1.19 String avail = packet.getParam(thisDisk + ".attributes.avail");
114    
115     String totalInodes = packet.getParam(thisDisk + ".attributes.totalinodes");
116     String availInodes = packet.getParam(thisDisk + ".attributes.freeinodes");
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 tdb 1.19 if(!diskInodeRegisters.containsKey(mount)) {
129     diskInodeRegisters.put(mount, new Register(source, _nameInode, mount));
130     }
131 ajm 1.7
132     // get the register for this disk
133 tdb 1.15 Register reg = (Register) diskRegisters.get(mount);
134 tdb 1.19 Register regInode = (Register) diskInodeRegisters.get(mount);
135 ajm 1.7
136     // get the packet data
137     double diskTotal, diskAvail;
138 tdb 1.23 long diskInodeTotal, diskInodeAvail;
139 ajm 1.7 try {
140    
141 tdb 1.19 if(total==null || avail==null || totalInodes==null || availInodes==null) {
142 ajm 1.7 throw new NumberFormatException("Disk data invalid");
143 ajm 1.2 }
144 ajm 1.7 diskTotal = Double.parseDouble(total);
145     diskAvail = Double.parseDouble(avail);
146 tdb 1.23 diskInodeTotal = Long.parseLong(totalInodes);
147     diskInodeAvail = Long.parseLong(availInodes);
148 ajm 1.7 } catch (NumberFormatException e) {
149     _logger.write(this.toString(), Logger.WARNING, "Received packet from "+source+" with bad disk information: "+e);
150     // don't try to continue and process, try next disk
151     break;
152     }
153 ajm 1.2
154 ajm 1.7 boolean useValue = false;
155 tdb 1.19 boolean useValueInode = false;
156 ajm 1.7 try {
157 tdb 1.13 // try looking for a mount-point specific thresholdMeasure first
158     String option = _cp.getProperty("Host." + source, "Monitor." + _name + "." + mount + ".thresholdMeasure");
159 ajm 1.7 if (option.equals("VALUE")) {
160     useValue = true;
161 tdb 1.13 }
162 tdb 1.19 option = _cp.getProperty("Host." + source, "Monitor." + _nameInode + "." + mount + ".thresholdMeasure");
163     if (option.equals("VALUE")) {
164     useValueInode = true;
165     }
166 ajm 1.7 } catch (PropertyNotFoundException e) {
167 tdb 1.13 try {
168     // now look for a more general thresholdMeasure
169     String option = _cp.getProperty("Host." + source, "Monitor." + _name + ".thresholdMeasure");
170     if (option.equals("VALUE")) {
171     useValue = true;
172     }
173 tdb 1.19 option = _cp.getProperty("Host." + source, "Monitor." + _nameInode + ".thresholdMeasure");
174     if (option.equals("VALUE")) {
175     useValueInode = true;
176     }
177 tdb 1.13 } catch (PropertyNotFoundException f) {
178     // we default to percentage in any case
179     }
180 ajm 1.7 }
181 ajm 1.2
182 ajm 1.7 // this bit determines if the disk check is a % check
183 tdb 1.19 // or a byte check
184 ajm 1.7 String type;
185 tdb 1.10 double curValue;
186     int newThreshold;
187 ajm 1.7 if(useValue) {
188 tdb 1.19 // byte disk available
189 tdb 1.10 curValue = diskAvail;
190     // negate check
191     newThreshold = checkAttributeThreshold(curValue, reg, true);
192 tdb 1.19 type = "bytes";
193 ajm 1.7 } else {
194     // % disk in use
195 tdb 1.19 curValue = (1 - ((double)diskAvail / (double)diskTotal)) * 100;
196 tdb 1.10 // normal check
197     newThreshold = checkAttributeThreshold(curValue, reg, false);
198 ajm 1.7 type = "%";
199 ajm 1.1 }
200 tdb 1.19
201     String typeInode;
202     double curValueInode;
203     int newThresholdInode;
204     if(useValueInode) {
205     // inodes available
206     curValueInode = diskInodeAvail;
207     // negate check
208     newThresholdInode = checkAttributeThreshold(curValueInode, regInode, true);
209     typeInode = "count";
210     } else {
211     // % inodes in use
212     curValueInode = (1 - ((double)diskInodeAvail / (double)diskInodeTotal)) * 100;
213     // normal check
214     newThresholdInode = checkAttributeThreshold(curValueInode, regInode, false);
215     typeInode = "%";
216     }
217    
218 ajm 1.7 // format the diskInUse to a String
219     NumberFormat nf = NumberFormat.getInstance();
220     nf.setMaximumFractionDigits(2);
221     nf.setMinimumFractionDigits(2);
222 tdb 1.10 String strCurValue = nf.format(curValue);
223 tdb 1.19 String strCurValueInode = nf.format(curValueInode);
224 ajm 1.7
225     // say which disk had the problem
226     String attributeName = "Disk in use " + type + " on " + mount + " (" + device + ")";
227 tdb 1.19 String attributeNameInode = "Disk inodes in use " + type + " on " + mount + " (" + device +")";
228 ajm 1.7
229 tdb 1.10 processAlert(newThreshold, attributeName, reg, source, strCurValue);
230 tdb 1.19 processAlert(newThresholdInode, attributeNameInode, regInode, source, strCurValueInode);
231 ajm 1.1 }
232     }
233     }
234     }
235    
236     /**
237     * Overrides the {@link java.lang.Object#toString() Object.toString()}
238     * method to provide clean logging (every class should have this).
239     *
240 tdb 1.18 * This uses the uk.org.iscream.cms.util.NameFormat class
241 ajm 1.1 * to format the toString()
242     *
243     * @return the name of this class and its CVS revision
244     */
245     public String toString() {
246     return FormatName.getName(
247     _name,
248     getClass().getName(),
249     REVISION);
250     }
251    
252     /**
253     * return the String representation of what the monitor does
254     */
255     public String getDescription(){
256     return DESC;
257     }
258    
259     //---PRIVATE METHODS---
260 tdb 1.8
261     /**
262     * Checks a piece of current data, and returns the
263     * threshold it breaches, if any.
264     *
265 tdb 1.10 * The option to negate the check can be used in
266     * situations where being *below* the threshold
267     * is an 'alertable' situation. In this specific
268     * case, we'd do this with kb disk checks.
269     *
270     * @param value the current value
271 tdb 1.8 * @param reg the Register for the host
272 tdb 1.10 * @param negateCheck whether to negate the check
273 tdb 1.8 * @return the threshold level breached, if any
274     */
275 tdb 1.14 private int checkAttributeThreshold(double value, Register reg, boolean negateCheck) {
276 ajm 1.1 for(int thresholdLevel = Alert.thresholdLevels.length - 1; thresholdLevel >= 0; thresholdLevel--) {
277     if (reg.getThreshold(thresholdLevel) != -1.0) {
278 tdb 1.10 if(!negateCheck) {
279     // normal check - has the value gone *over* the threshold
280 tdb 1.14 if(((double) reg.getThreshold(thresholdLevel)) < value) {
281 tdb 1.10 return thresholdLevel;
282     }
283     }
284     else {
285     // negated check - has the value gone *under* the threshold
286 tdb 1.14 if(((double) reg.getThreshold(thresholdLevel)) > value) {
287 tdb 1.10 return thresholdLevel;
288     }
289 ajm 1.1 }
290     }
291     }
292     return Alert.thresholdNORMAL;
293     }
294    
295     //---ACCESSOR/MUTATOR METHODS---
296 ajm 1.7
297 tdb 1.8 /**
298     * Returns a reference to a specific Queue for this
299     * monitor. This Queue returns only the data packets
300     * (based on type) that we want too look at.
301     *
302     * @return a reference to a Queue
303     */
304 ajm 1.7 protected Queue getQueue() {
305     return MonitorManager.getInstance().getDataQueue();
306     }
307    
308 ajm 1.1 //---ATTRIBUTES---
309    
310     /**
311     * This is the friendly identifier of the
312     * component this class is running in.
313     * eg, a Filter may be called "filter1",
314     * If this class does not have an owning
315     * component, a name from the configuration
316     * can be placed here. This name could also
317     * be changed to null for utility classes.
318     */
319     private String _name = "Disk";
320    
321     /**
322 tdb 1.19 * Inodes have the name "DiskInode" in the
323     * configuration.
324     */
325     private String _nameInode = "DiskInode";
326    
327     /**
328 ajm 1.1 * A reference to the configuration proxy in use
329     */
330     private ConfigurationProxy _cp = ConfigurationProxy.getInstance();
331 tdb 1.8
332     /**
333     * A HashMap of Registers (or groups of Registers), one
334     * for each host we're monitoring.
335     */
336 ajm 1.1 private HashMap _hosts = new HashMap();
337 tdb 1.19
338     /**
339     * A HashMap of Registers (or groups of Registers), one
340     * for each host we're monitoring (inodes).
341     */
342     private HashMap _hostsInode = new HashMap();
343 ajm 1.1
344     //---STATIC ATTRIBUTES---
345    
346     }