/* * Copyright (c) 2008 Massimiliano Ziccardi * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package it.jnrpe.plugin.jmx; import it.jnrpe.commands.CCommandLine; import it.jnrpe.net.IJNRPEConstants; import it.jnrpe.plugin.util.ThresholdUtil; import it.jnrpe.plugins.CReturnValue; import it.jnrpe.plugins.IPluginInterface; import java.io.IOException; import java.io.PrintStream; import java.math.BigDecimal; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.management.MBeanServerConnection; import javax.management.ObjectName; import javax.management.openmbean.CompositeDataSupport; import javax.management.openmbean.CompositeType; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; public class CCheckJMX implements IPluginInterface { private String url; private int verbatim; private JMXConnector connector; private MBeanServerConnection connection; private String warning, critical; private String attribute, info_attribute; private String attribute_key, info_key; private String object; private String username, password; private long checkData; private Object infoData; private static final int RETURN_OK = 0; // The plugin was able to check the // service and it appeared to be // functioning properly private static final String OK_STRING = "JMX OK -"; private static final int RETURN_WARNING = 1; // The plugin was able to check // the service, but it appeared // to be above some "warning" // threshold or did not appear // to be working properly private static final String WARNING_STRING = "JMX WARNING -"; private static final int RETURN_CRITICAL = 2; // The plugin detected that // either the service was not // running or it was above // some "critical" threshold private static final String CRITICAL_STRING = "JMX CRITICAL -"; private static final int RETURN_UNKNOWN = 3; // Invalid command line // arguments were supplied to // the plugin or low-level // failures internal to the // plugin (such as unable to // fork, or open a tcp socket) // that prevent it from // performing the specified // operation. Higher-level // errors (such as name // resolution errors, socket // timeouts, etc) are outside // of the control of plugins // and should generally NOT be // reported as UNKNOWN states. private static final String UNKNOWN_STRING = "JMX UNKNOWN"; public CReturnValue execute(CCommandLine cl) { String sVersion = System.getProperty("java.version"); sVersion = sVersion.replace(".", ""); int iVersion = Integer.parseInt(sVersion.substring(0,2)); if (iVersion < 15) { String sMessage = UNKNOWN_STRING + " - Java 1.5+ required. Current Java version : " + System.getProperty("java.version"); return new CReturnValue(IJNRPEConstants.STATE_UNKNOWN, sMessage); } parse(cl); try { try { connect(); } catch (IOException e) { return new CReturnValue(IJNRPEConstants.STATE_UNKNOWN, UNKNOWN_STRING + " - Could not connect to jmx : " + e.getMessage()); } try { execute(); } catch (Exception e) { return new CReturnValue(IJNRPEConstants.STATE_UNKNOWN, UNKNOWN_STRING + " - Could not execute query : " + e.getMessage()); } } finally { try { disconnect(); } catch (IOException e) { e.printStackTrace(); } } return report(); } private void connect() throws IOException { JMXServiceURL jmxUrl = new JMXServiceURL(url); if (username != null) { Map m = new HashMap(); m.put(JMXConnector.CREDENTIALS, new String[] { username, password }); connector = JMXConnectorFactory.connect(jmxUrl, m); } else { connector = JMXConnectorFactory.connect(jmxUrl); } connection = connector.getMBeanServerConnection(); } private void disconnect() throws IOException { if (connector != null) { connector.close(); connector = null; } } /** * @param args */ // public static void main(String[] args) // { // // JMXQuery query = new JMXQuery(); // // try // { // query.parse(args); // query.connect(); // query.execute(); // int status = query.report(System.out); // System.exit(status); // } // catch (Exception ex) // { // int status = query.report(ex, System.out); // System.exit(status); // } // finally // { // try // { // query.disconnect(); // } // catch (IOException e) // { // int status = query.report(e, System.out); // System.exit(status); // } // } // } // private int report(Exception ex, PrintStream out) // { // if (ex instanceof ParseError) // { // out.print(UNKNOWN_STRING + " "); // reportException(ex, out); // out.println(" Usage: check_jmx -help "); // return RETURN_UNKNOWN; // } // else // { // out.print(CRITICAL_STRING + " "); // reportException(ex, out); // out.println(); // return RETURN_CRITICAL; // } // } private void reportException(Exception ex, PrintStream out) { if (verbatim < 2) out.print(rootCause(ex).getMessage()); else { out.print(ex.getMessage() + " connecting to " + object + " by URL " + url); } if (verbatim >= 3) ex.printStackTrace(out); } private static Throwable rootCause(Throwable ex) { if (ex.getCause() == null) return ex; return rootCause(ex.getCause()); } private CReturnValue report() { int status; String sMessage = null; if (ThresholdUtil.isValueInRange(critical, new BigDecimal(checkData))) { status = RETURN_CRITICAL; sMessage = CRITICAL_STRING; } else if (ThresholdUtil.isValueInRange(warning, new BigDecimal(checkData))) { status = RETURN_WARNING; sMessage = WARNING_STRING; } else { status = RETURN_OK; sMessage = OK_STRING; } boolean shown = false; if (infoData == null || verbatim >= 2) { sMessage += " "; if (attribute_key != null) sMessage += (attribute + '.' + attribute_key + " is " + checkData); else { sMessage += (attribute + " is " + checkData); shown = true; } } if (!shown && infoData != null) { if (infoData instanceof CompositeDataSupport) report((CompositeDataSupport) infoData, sMessage); else sMessage += (infoData.toString()); } return new CReturnValue(status, sMessage); } private void report(CompositeDataSupport data, String sMessage) { CompositeType type = data.getCompositeType(); sMessage += ","; for (Iterator it = type.keySet().iterator(); it.hasNext();) { String key = (String) it.next(); if (data.containsKey(key)) sMessage += (key + '=' + data.get(key)); if (it.hasNext()) sMessage += (';'); } } private boolean compare(long level, boolean more) { if (more) return checkData >= level; else return checkData <= level; } private void execute() throws Exception { Object attr = connection.getAttribute(new ObjectName(object), attribute); if (attr instanceof CompositeDataSupport) { CompositeDataSupport cds = (CompositeDataSupport) attr; if (attribute_key == null) throw new Exception("Attribute key is null for composed data " + object); checkData = parseData(cds.get(attribute_key)); } else { checkData = parseData(attr); } if (info_attribute != null) { Object info_attr = info_attribute.equals(attribute) ? attr : connection.getAttribute(new ObjectName(object), info_attribute); if (info_key != null && (info_attr instanceof CompositeDataSupport) && verbatim < 4) { CompositeDataSupport cds = (CompositeDataSupport) attr; infoData = cds.get(info_key); } else { infoData = info_attr; } } } private long parseData(Object o) { if (o instanceof Number) return ((Number) o).longValue(); else return Long.parseLong(o.toString()); } private void parse(CCommandLine cli) { // try // { // for (int i = 0; i < args.length; i++) // { // String option = args[i]; // if (option.equals("-help")) // { // printHelp(System.out); // System.exit(RETURN_UNKNOWN); // } // -U diventa URL this.url = cli.getOptionValue("url"); // -O diventa OBJECT this.object = cli.getOptionValue("object"); // -A == ATTRIBUTE this.attribute = cli.getOptionValue("attribute"); // -I = INFO_ATTRIBUTE this.info_attribute = cli.getOptionValue("infoattribute"); // -J = info_key this.info_key = cli.getOptionValue("infokey"); // -K = attributekey this.attribute_key = cli.getOptionValue("attributekey"); // -V = verbatim // if (cli.hasOption("verbatim")) // { // this.verbatim = option.length() - 1; // } // -w = warning this.warning = cli.getOptionValue("warning"); // -c = critical this.critical = cli.getOptionValue("critical"); // -username = username this.username = cli.getOptionValue("username"); // -password = password this.password = cli.getOptionValue("password"); // } // url, object e attribute sono mandatory // if (url == null || object == null || attribute == null) // throw new Exception("Required options not specified"); // } // catch (Exception e) // { // throw new ParseError(e); // } } // private void printHelp(PrintStream out) // { // InputStream is = JMXQuery.class.getClassLoader().getResourceAsStream("jmxquery/HELP"); // BufferedReader reader = new BufferedReader(new InputStreamReader(is)); // try // { // while (true) // { // String s = reader.readLine(); // if (s == null) // break; // out.println(s); // } // } // catch (IOException e) // { // out.println(e); // } // finally // { // try // { // reader.close(); // } // catch (IOException e) // { // out.println(e); // } // } // } }