/* * NOTE: This copyright does *not* cover user programs that use HQ * program services by normal system calls through the application * program interfaces provided as part of the Hyperic Plug-in Development * Kit or the Hyperic Client Development Kit - this is merely considered * normal use of the program, and does *not* fall under the heading of * "derived work". * * Copyright (C) [2004, 2005, 2006], Hyperic, Inc. * This file is part of HQ. * * HQ is free software; you can redistribute it and/or modify * it under the terms version 2 of the GNU General Public License as * published by the Free Software Foundation. This program is distributed * in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. */ package org.hyperic.hq.plugin.postfix; import java.util.HashMap; import java.io.File; import org.hyperic.hq.product.MeasurementPlugin; import org.hyperic.hq.product.Metric; import org.hyperic.hq.product.MetricInvalidException; import org.hyperic.hq.product.MetricNotFoundException; import org.hyperic.hq.product.MetricUnreachableException; import org.hyperic.hq.product.MetricValue; import org.hyperic.hq.product.PluginException; public class PostfixMeasurementPlugin extends MeasurementPlugin { private static HashMap cache = new HashMap(); //XXX implement a Collector or use Sigar.getDirUsage() private MetricValue getValue(File file, String attr) throws MetricNotFoundException, MetricUnreachableException { HashMap metrics = (HashMap)cache.get(file); if (metrics == null) { metrics = new HashMap(); cache.put(file, metrics); } Integer val = (Integer)metrics.get(attr); if (val == null) { // make sure the queue is a directory. if (!file.isDirectory()) { String msg = "Queue is not a directory: " + file; throw new MetricNotFoundException(msg); } // make sure we can read the queue. if (!file.canRead()) { String msg = "Cannot read " + file + ", check permissions"; throw new MetricUnreachableException(msg); } // recharge the cache if the value is not found int qMetrics[] = getQueueMetrics(file); metrics.put("QueuedMessages", new Integer(qMetrics[0])); metrics.put("QueueSize", new Integer(qMetrics[1])); val = (Integer)metrics.get(attr); } // remove the metric from the cache to force a refresh // next time around val = (Integer)metrics.remove(attr); if (val == null) { throw new MetricNotFoundException("No metric mapped to " + " metric: " + attr); } return new MetricValue(val.intValue()); } public MetricValue getValue(Metric metric) throws PluginException, MetricNotFoundException, MetricUnreachableException { String prop = PostfixServerDetector.PROP_PATH; String domain = metric.getDomainName(); String attr = metric.getAttributeName(); String qpath; //back-compat w/ old template if (domain.equals("system.avail")) { domain = "queue"; attr = Metric.ATTR_AVAIL; qpath = metric.getObjectProperty("Arg"); } else { qpath = metric.getObjectProperty(prop); } if (!domain.equals("queue")) { return super.getValue(metric); //shouldnothappen } if (qpath == null) { String msg = "Missing " + prop + ": " + metric; throw new MetricInvalidException(msg); } File queue = new File(qpath); if (attr.equals(Metric.ATTR_AVAIL)) { double avail = queue.isDirectory() ? Metric.AVAIL_UP : Metric.AVAIL_DOWN; return new MetricValue(avail); } else { return getValue(queue, attr); } } private int[] getQueueMetrics(File queue) { File queueContents[] = queue.listFiles(); int messageCount = 0; int queueSize = 0; for (int i=0; i<queueContents.length; i++) { if (queueContents[i].isDirectory()) { // check hashed directory int tmpVal[] = getQueueMetrics(queueContents[i]); messageCount += tmpVal[0]; queueSize += tmpVal[1]; } else if (queueContents[i].isFile()) { // count the queued message messageCount += 1; // and add the size of the message to the total queueSize += (int)queueContents[i].length(); } else { String absPath = queueContents[i].getAbsolutePath(); getLog().error(absPath + " is not a directory or a file!"); } } int retVal[] = { messageCount, queueSize }; return retVal; } }