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
(Generate patch)

Comparing projects/cms/source/server/uk/org/iscream/cms/server/client/monitors/Disk__Monitor.java (file contents):
Revision 1.5 by ajm, Thu Mar 22 00:59:13 2001 UTC vs.
Revision 1.19 by tdb, Sun Mar 9 21:49:13 2003 UTC

# Line 1 | Line 1
1 + /*
2 + * i-scream central monitoring system
3 + * http://www.i-scream.org.uk
4 + * 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   //---PACKAGE DECLARATION---
22 < package uk.org.iscream.client.monitors;
22 > package uk.org.iscream.cms.server.client.monitors;
23  
24   //---IMPORTS---
25   import java.util.HashMap;
26 < import java.util.ArrayList;
26 > import java.util.HashSet;
27   import java.util.Set;
28   import java.util.Iterator;
29   import java.text.NumberFormat;
30 < import uk.org.iscream.client.*;
31 < import uk.org.iscream.core.*;
32 < import uk.org.iscream.util.*;
33 < import uk.org.iscream.componentmanager.*;
30 > import uk.org.iscream.cms.server.client.*;
31 > import uk.org.iscream.cms.server.core.*;
32 > import uk.org.iscream.cms.util.*;
33 > import uk.org.iscream.cms.server.componentmanager.*;
34  
35   /**
36   * This Monitor watches the Disks for all machines
# Line 27 | Line 47 | public class Disk__Monitor extends MonitorSkeleton {
47       */
48      public final String REVISION = "$Revision$";
49      
50 +    /**
51 +     * A description of this monitor
52 +     */
53      public final String DESC = "Monitors all host disks.";
54      
55   //---STATIC METHODS---
# Line 34 | Line 57 | public class Disk__Monitor extends MonitorSkeleton {
57   //---CONSTRUCTORS---
58  
59   //---PUBLIC METHODS---
60 <
60 >    
61 >    /**
62 >     * Analyse a packet of data, and generate an alert if
63 >     * necessary.
64 >     *
65 >     * @param packet the XMLPacket to analyse
66 >     */
67      public void analysePacket(XMLPacket packet) {
68 <        if (packet.getParam("packet.attributes.type").equals("data")) {
69 <            String source = packet.getParam("packet.attributes.machine_name");
70 <            if (!_hosts.containsKey(source)) {
71 <                _hosts.put(source, new HashMap());
72 <            }
73 <                        
74 <            HashMap diskRegisters = (HashMap) _hosts.get(source);
46 <            
47 <            // a tempory holder for all the disk attributes we find
48 <            ArrayList disks = new ArrayList();
49 <            
50 <            // unfortunatly we need to check the whole packet
51 <            // to find the disks, and then get the data attributes
52 <            Set packetSet = packet.getSet();
53 <            Iterator i = packetSet.iterator();
54 <            while (i.hasNext()) {
55 <                String dataKey = (String) i.next();
56 <                if(dataKey.startsWith("packet.disk.p")) {
57 <                    if(!disks.contains(dataKey)) {
58 <                        String diskNumber = "";
59 <            
60 <                        // pos is after "packet.disk.p"
61 <                        int pos = 13;
62 <                        while (dataKey.charAt(pos) != '.') {
63 <                            diskNumber = diskNumber + dataKey.charAt(pos);
64 <                            pos++;
65 <                        }
66 <                        
67 <                        // add the disk to our list, with the packet data
68 <                        
69 <                        // used (we won't use this value - but we need it to forget about it ;)
70 <                        disks.add("packet.disk.p" + diskNumber + ".attributes.used");
71 <                        
72 <                        // device
73 <                        disks.add("packet.disk.p" + diskNumber + ".attributes.name");
74 <                        String device = packet.getParam("packet.disk.p" + diskNumber + ".attributes.name");
75 <                        // mount point
76 <                        disks.add("packet.disk.p" + diskNumber + ".attributes.mount");
77 <                        String mount = packet.getParam("packet.disk.p" + diskNumber + ".attributes.mount");
68 >        String source = packet.getParam("packet.attributes.machine_name");
69 >        if (!_hosts.containsKey(source)) {
70 >            _hosts.put(source, new HashMap());
71 >        }
72 >        if (!_hostsInode.containsKey(source)) {
73 >            _hostsInode.put(source, new HashMap());
74 >        }
75  
76 <                        // these next two will be used to calculate the %age
77 <                        // total
78 <                        disks.add("packet.disk.p" + diskNumber + ".attributes.kbytes");
79 <                        String total = packet.getParam("packet.disk.p" + diskNumber + ".attributes.kbytes");
80 <                        // available
81 <                        disks.add("packet.disk.p" + diskNumber + ".attributes.avail");
82 <                        String avail = packet.getParam("packet.disk.p" + diskNumber + ".attributes.avail");
76 >        HashMap diskRegisters = (HashMap) _hosts.get(source);
77 >        HashMap diskInodeRegisters = (HashMap) _hostsInode.get(source);
78 >        
79 >        // key prefix
80 >        String keyPrefix = "packet.disk.p";
81 >        
82 >        // a temporary holder for all the disk attributes we find
83 >        HashSet disks = new HashSet();
84  
85 <                        // *** now process this disk ***
85 >        // unfortunatly we need to check the whole packet
86 >        // to find the disks, and then get the data attributes
87 >        Set packetSet = packet.getSet();
88 >        Iterator i = packetSet.iterator();
89 >        while (i.hasNext()) {
90 >            String dataKey = (String) i.next();
91 >            if(dataKey.startsWith(keyPrefix)) {
92 >                // pos is after "packet.disk.p"
93 >                int pos = keyPrefix.length();
94 >                String diskNumber = dataKey.substring(pos, dataKey.indexOf('.', pos));
95 >                String thisDisk = keyPrefix.concat(diskNumber);
96 >                
97 >                if(!disks.contains(thisDisk)) {
98 >                    // add the disk to our list
99 >                    disks.add(thisDisk);
100  
101 <                        // check if we've seen this disk before on a previous run
102 <                        // if not, we need to create a register for it
103 <                        if(!diskRegisters.containsKey(diskNumber)) {
104 <                            diskRegisters.put(diskNumber, new Register(source, _name, mount));
93 <                        }
101 >                    // device
102 >                    String device = packet.getParam(thisDisk + ".attributes.name");
103 >                    // mount point
104 >                    String mount = packet.getParam(thisDisk + ".attributes.mount");
105  
106 <                        // get the register for this disk
107 <                        Register reg = (Register) diskRegisters.get(diskNumber);
106 >                    // these next two will be used to calculate the %age
107 >                    // total
108 >                    String total = packet.getParam(thisDisk + ".attributes.total");
109 >                    // available
110 >                    String avail = packet.getParam(thisDisk + ".attributes.avail");
111 >                    
112 >                    String totalInodes = packet.getParam(thisDisk + ".attributes.totalinodes");
113 >                    String availInodes = packet.getParam(thisDisk + ".attributes.freeinodes");
114  
115 <                        // get the packet data
116 <                        double diskTotal, diskAvail;
117 <                        try {
118 <                
119 <                            if(total==null || avail==null) {
120 <                                throw new NumberFormatException("Disk data invalid");
121 <                            }
122 <                            diskTotal = Double.parseDouble(total);
123 <                            diskAvail = Double.parseDouble(avail);
124 <                        } catch (NumberFormatException e) {
125 <                            _logger.write(this.toString(), Logger.WARNING, "Received packet from "+source+" with bad disk information: "+e);
126 <                            // don't try to continue and process, try next disk
127 <                            break;
115 >                    // *** now process this disk ***
116 >
117 >                    // check if we've seen this disk before on a previous run
118 >                    // if not, we need to create a register for it
119 >                    //   nb. use the mount as the key as this is unlikely to change,
120 >                    //       unlike diskNumber which could easily change
121 >                    //         (diskNumber is based on the order of df's output!)
122 >                    if(!diskRegisters.containsKey(mount)) {
123 >                        diskRegisters.put(mount, new Register(source, _name, mount));
124 >                    }
125 >                    if(!diskInodeRegisters.containsKey(mount)) {
126 >                        diskInodeRegisters.put(mount, new Register(source, _nameInode, mount));
127 >                    }
128 >
129 >                    // get the register for this disk
130 >                    Register reg = (Register) diskRegisters.get(mount);
131 >                    Register regInode = (Register) diskInodeRegisters.get(mount);
132 >
133 >                    // get the packet data
134 >                    double diskTotal, diskAvail;
135 >                    int diskInodeTotal, diskInodeAvail;
136 >                    try {
137 >
138 >                        if(total==null || avail==null || totalInodes==null || availInodes==null) {
139 >                            throw new NumberFormatException("Disk data invalid");
140                          }
141 <                        
142 <                        boolean useValue = false;
141 >                        diskTotal = Double.parseDouble(total);
142 >                        diskAvail = Double.parseDouble(avail);
143 >                        diskInodeTotal = Integer.parseInt(totalInodes);
144 >                        diskInodeAvail = Integer.parseInt(availInodes);
145 >                    } catch (NumberFormatException e) {
146 >                        _logger.write(this.toString(), Logger.WARNING, "Received packet from "+source+" with bad disk information: "+e);
147 >                        // don't try to continue and process, try next disk
148 >                        break;
149 >                    }
150 >
151 >                    boolean useValue = false;
152 >                    boolean useValueInode = false;
153 >                    try {
154 >                        // try looking for a mount-point specific thresholdMeasure first
155 >                        String option = _cp.getProperty("Host." + source, "Monitor." + _name + "." + mount + ".thresholdMeasure");
156 >                        if (option.equals("VALUE")) {
157 >                            useValue = true;
158 >                        }
159 >                        option = _cp.getProperty("Host." + source, "Monitor." + _nameInode + "." + mount + ".thresholdMeasure");
160 >                        if (option.equals("VALUE")) {
161 >                            useValueInode = true;
162 >                        }
163 >                    } catch (PropertyNotFoundException e) {
164                          try {
165 +                            // now look for a more general thresholdMeasure
166                              String option = _cp.getProperty("Host." + source, "Monitor." + _name + ".thresholdMeasure");
167                              if (option.equals("VALUE")) {
168                                  useValue = true;
169 <                            }                            
170 <                        } catch (PropertyNotFoundException e) {
171 <                            // we default to percentage
169 >                            }
170 >                            option = _cp.getProperty("Host." + source, "Monitor." + _nameInode + ".thresholdMeasure");
171 >                            if (option.equals("VALUE")) {
172 >                                useValueInode = true;
173 >                            }
174 >                        } catch (PropertyNotFoundException f) {
175 >                            // we default to percentage in any case
176                          }
122                        
123                        // this  bit determines if the disk check is a % check
124                        // or a kb check
125                        double diskInUse;
126                        String type;
127                        if(useValue) {
128                            // kb disk in use
129                            diskInUse = diskTotal - diskAvail;
130                            type = "kb";
131                        } else {
132                            // % disk in use
133                            diskInUse = (1 - (diskAvail / diskTotal)) * 100;
134                            type = "%";
135                        }
136                        
137                        
138                        
139                        int newThreshold = checkAttributeThreshold(diskInUse, reg);
140            
141                        // format the memoryInUse to a String
142                        NumberFormat nf = NumberFormat.getInstance();
143                        nf.setMaximumFractionDigits(2);
144                        nf.setMinimumFractionDigits(2);
145                        String strDiskInUse = nf.format(diskInUse);
146  
147                        // say which disk had the problem
148                        String attributeName = "Disk in use " + type + " on " + mount + " (" + device + ")";
149                                                
150                        processAlert(newThreshold, attributeName, reg, source, strDiskInUse);
177                      }
178 +
179 +                    // this  bit determines if the disk check is a % check
180 +                    // or a byte check
181 +                    String type;
182 +                    double curValue;
183 +                    int newThreshold;
184 +                    if(useValue) {
185 +                        // byte disk available
186 +                        curValue = diskAvail;
187 +                        // negate check
188 +                        newThreshold = checkAttributeThreshold(curValue, reg, true);
189 +                        type = "bytes";
190 +                    } else {
191 +                        // % disk in use
192 +                        curValue = (1 - ((double)diskAvail / (double)diskTotal)) * 100;
193 +                        // normal check
194 +                        newThreshold = checkAttributeThreshold(curValue, reg, false);
195 +                        type = "%";
196 +                    }
197 +                    
198 +                    String typeInode;
199 +                    double curValueInode;
200 +                    int newThresholdInode;
201 +                    if(useValueInode) {
202 +                        // inodes available
203 +                        curValueInode = diskInodeAvail;
204 +                        // negate check
205 +                        newThresholdInode = checkAttributeThreshold(curValueInode, regInode, true);
206 +                        typeInode = "count";
207 +                    } else {
208 +                        // % inodes in use
209 +                        curValueInode = (1 - ((double)diskInodeAvail / (double)diskInodeTotal)) * 100;
210 +                        // normal check
211 +                        newThresholdInode = checkAttributeThreshold(curValueInode, regInode, false);
212 +                        typeInode = "%";
213 +                    }
214 +                    
215 +                    // format the diskInUse to a String
216 +                    NumberFormat nf = NumberFormat.getInstance();
217 +                    nf.setMaximumFractionDigits(2);
218 +                    nf.setMinimumFractionDigits(2);
219 +                    String strCurValue = nf.format(curValue);
220 +                    String strCurValueInode = nf.format(curValueInode);
221 +
222 +                    // say which disk had the problem
223 +                    String attributeName = "Disk in use " + type + " on " + mount + " (" + device + ")";
224 +                    String attributeNameInode = "Disk inodes in use " + type + " on " + mount + " (" + device +")";
225 +
226 +                    processAlert(newThreshold, attributeName, reg, source, strCurValue);
227 +                    processAlert(newThresholdInode, attributeNameInode, regInode, source, strCurValueInode);
228                  }
229              }
230          }
# Line 158 | Line 234 | public class Disk__Monitor extends MonitorSkeleton {
234       * Overrides the {@link java.lang.Object#toString() Object.toString()}
235       * method to provide clean logging (every class should have this).
236       *
237 <     * This uses the uk.org.iscream.util.NameFormat class
237 >     * This uses the uk.org.iscream.cms.util.NameFormat class
238       * to format the toString()
239       *
240       * @return the name of this class and its CVS revision
# Line 178 | Line 254 | public class Disk__Monitor extends MonitorSkeleton {
254      }
255  
256   //---PRIVATE METHODS---
257 <
258 <    private int checkAttributeThreshold(double diskInUse, Register reg) {
257 >    
258 >    /**
259 >     * Checks a piece of current data, and returns the
260 >     * threshold it breaches, if any.
261 >     *
262 >     * The option to negate the check can be used in
263 >     * situations where being *below* the threshold
264 >     * is an 'alertable' situation. In this specific
265 >     * case, we'd do this with kb disk checks.
266 >     *
267 >     * @param value the current value
268 >     * @param reg the Register for the host
269 >     * @param negateCheck whether to negate the check
270 >     * @return the threshold level breached, if any
271 >     */
272 >    private int checkAttributeThreshold(double value, Register reg, boolean negateCheck) {
273          for(int thresholdLevel = Alert.thresholdLevels.length - 1; thresholdLevel >= 0; thresholdLevel--) {
274              if (reg.getThreshold(thresholdLevel) != -1.0) {
275 <                if(((double) reg.getThreshold(thresholdLevel)) < diskInUse) {
276 <                    return thresholdLevel;
275 >                if(!negateCheck) {
276 >                    // normal check - has the value gone *over* the threshold
277 >                    if(((double) reg.getThreshold(thresholdLevel)) < value) {
278 >                        return thresholdLevel;
279 >                    }
280                  }
281 +                else {
282 +                    // negated check - has the value gone *under* the threshold
283 +                    if(((double) reg.getThreshold(thresholdLevel)) > value) {
284 +                        return thresholdLevel;
285 +                    }
286 +                }
287              }
288          }
289          return Alert.thresholdNORMAL;
290      }
291  
292   //---ACCESSOR/MUTATOR METHODS---
293 <
293 >    
294 >    /**
295 >     * Returns a reference to a specific Queue for this
296 >     * monitor. This Queue returns only the data packets
297 >     * (based on type) that we want too look at.
298 >     *
299 >     * @return a reference to a Queue
300 >     */
301 >    protected Queue getQueue() {
302 >        return MonitorManager.getInstance().getDataQueue();
303 >    }
304 >    
305   //---ATTRIBUTES---
306  
307      /**
# Line 206 | Line 316 | public class Disk__Monitor extends MonitorSkeleton {
316      private String _name = "Disk";
317      
318      /**
319 +     * Inodes have the name "DiskInode" in the
320 +     * configuration.
321 +     */
322 +    private String _nameInode = "DiskInode";
323 +    
324 +    /**
325       * A reference to the configuration proxy in use
326       */
327      private ConfigurationProxy _cp = ConfigurationProxy.getInstance();
328 <
328 >    
329 >    /**
330 >     * A HashMap of Registers (or groups of Registers), one
331 >     * for each host we're monitoring.
332 >     */
333      private HashMap _hosts = new HashMap();
334 +    
335 +    /**
336 +     * A HashMap of Registers (or groups of Registers), one
337 +     * for each host we're monitoring (inodes).
338 +     */
339 +    private HashMap _hostsInode = new HashMap();
340  
341   //---STATIC ATTRIBUTES---
342  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines