org.hyperic.hq.plugin.postgresql.ServerMeasurement.java Source code

Java tutorial

Introduction

Here is the source code for org.hyperic.hq.plugin.postgresql.ServerMeasurement.java

Source

/*
 * 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.postgresql;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hyperic.hq.product.Collector;
import org.hyperic.hq.product.Metric;
import org.hyperic.hq.product.MetricNotFoundException;
import org.hyperic.hq.product.MetricUnreachableException;
import org.hyperic.hq.product.MetricValue;
import org.hyperic.hq.product.PluginException;
import org.hyperic.hq.product.SigarMeasurementPlugin;
import org.hyperic.sigar.Sigar;
import org.hyperic.sigar.SigarException;
import org.hyperic.sigar.SigarNotImplementedException;
import org.hyperic.sigar.SigarProxy;
import org.hyperic.sigar.SigarProxyCache;
import org.hyperic.sigar.jmx.SigarInvokerJMX;
import org.hyperic.util.jdbc.DBUtil;

public class ServerMeasurement extends SigarMeasurementPlugin {

    private Log log = LogFactory.getLog(ServerMeasurement.class);
    private long pid = -1;
    private Sigar sigar = null;
    private SigarProxy sigarProxy = null;
    private String actualConfig = "";

    @Override
    public MetricValue getValue(Metric metric)
            throws PluginException, MetricNotFoundException, MetricUnreachableException {
        if (metric.getDomainName().equals("collector")) {
            return Collector.getValue(this, metric);
        }

        MetricValue res;

        initSigar();

        try {
            findPid(metric);
        } catch (PluginException ex) {
            if (metric.isAvail()) {
                log.debug(ex, ex);
                return new MetricValue(Metric.AVAIL_DOWN);
            } else {
                throw ex;
            }
        }

        if (metric.isAvail()) {
            res = new MetricValue(Metric.AVAIL_UP);
        } else {
            String oName = "sigar:Type=" + metric.getObjectProperty("Type") + ",Arg=State.Ppid.eq=" + pid;
            log.debug("[getValue] oName=" + oName);
            String attr = metric.getAttributeName();
            SigarInvokerJMX invoker = SigarInvokerJMX.getInstance(this.sigarProxy, oName);
            try {
                Object systemValue;
                synchronized (this.sigar) {
                    systemValue = invoker.invoke(attr);
                }
                if (systemValue instanceof Double) {
                    res = new MetricValue((Double) systemValue);
                } else if (systemValue instanceof Long) {
                    res = new MetricValue(new Double(((Long) systemValue).longValue()));
                } else if (systemValue instanceof Integer) {
                    res = new MetricValue(new Double(((Integer) systemValue).intValue()));
                } else {
                    PluginException ex = new PluginException(
                            "Error on systemValue '" + systemValue + "' (" + systemValue.getClass() + ")");
                    log.debug(ex, ex);
                    throw ex;
                }
            } catch (SigarNotImplementedException e) {
                pid = -1;
                throw new MetricUnreachableException(e.getMessage(), e);
            } catch (SigarException e) {
                pid = -1;
                throw new MetricNotFoundException(e.getMessage(), e);
            }
        }
        return res;
    }

    protected void initSigar() throws PluginException {
        if (this.sigar == null) {
            try {
                this.sigar = new Sigar();
                this.sigarProxy = SigarProxyCache.newInstance(sigar);
            } catch (UnsatisfiedLinkError ex) {
                log.debug("unable to load sigar: " + ex.getMessage(), ex);
                this.sigar = null;
                this.sigarProxy = null;
                throw new PluginException(ex.getMessage(), ex);
            }
        }

    }

    private void findPid(Metric metric) throws PluginException {
        Properties props = metric.getProperties();
        String user = props.getProperty(PostgreSQL.PROP_USER);
        String pass = props.getProperty(PostgreSQL.PROP_PASS);
        String url = PostgreSQL.prepareUrl(props, null);

        String newConfig = url + "-" + user + "-" + pass;
        boolean isNewConfig = !newConfig.equalsIgnoreCase(actualConfig);
        if (isNewConfig) {
            log.debug("[findPid] new config detected");
            actualConfig = newConfig;
        }

        // look for the PID 
        // IF config have changed (to test is the new config is valid)
        // OR no PID
        // OR always for Availability
        if (isNewConfig || (pid == -1) || (metric.isAvail())) {

            Connection conn = null;
            Statement stmt = null;
            ResultSet rs = null;

            try {
                conn = DriverManager.getConnection(url, user, pass);
                stmt = conn.createStatement();
                stmt.execute("select pg_backend_pid()");

                rs = stmt.getResultSet();
                if (rs.next()) {
                    int conectionPid = rs.getInt(1);
                    pid = new Sigar().getProcState(conectionPid).getPpid();
                    log.debug("[findPid] conection PID:" + conectionPid + " ==> main Process PID:" + pid);
                }
            } catch (SQLException ex) {
                pid = -1;
                throw new PluginException(ex.getMessage(), ex);
            } catch (SigarException ex) {
                pid = -1;
                throw new PluginException(ex.getMessage(), ex);
            } finally {
                DBUtil.closeJDBCObjects(getLog(), conn, stmt, rs);
            }
        }
    }
}