Nagios

From Resin 3.0

Jump to: navigation, search

Contents

Using the REST interface of the Resin administration application with Nagios

The Resin 4.0 administration application includes a REST interface which allows external applications such as Nagios to poll for status updates. This page includes some basic scripts and instructions to make writing plugins using the REST interface easier from Nagios.

Configure the /resin-admin application

You'll first need to edit resin.xml to set an external directory for your Resin REST plugin scripts. Create a directory to hold the Resin REST plugins and scripts. For this example, we'll use /usr/local/nagios/resin

mkdir -p /usr/local/nagios/resin

Next, configure this directory in the Resin administration application:

<!--
   - Administration application /resin-admin
  -->
<web-app id="/resin-admin" root-directory="${resin.root}/doc/admin">
  <prologue>
    <resin:set var="resin_admin_external" value="false"/>
    <resin:set var="resin_admin_insecure" value="true"/>
    <resin:set var="resin_admin_ext_path" value="/usr/local/nagios/resin"/>
  </prologue>
</web-app>

Save the utility shell script and Nagios library

Save the following shell script and save it as "check_resin.sh" in the external directory from the previous step:

  #!/bin/bash
  
  function usage {
    echo "usage: $0 --host=<host> --port=<port> --resource=<resource> "
    echo "          [--username=<username> --password=<password>]"
    echo "          [--warning-range=<range> --critical-range=<range>]"
  
    exit 3
  }
  
  PORT=80
  
  for i in $*; do
    case $i in
      --host=*)
        HOST=`echo $i | awk -F= '{print $2}'`
        ;;
      --port=*)
        PORT=`echo $i | awk -F= '{print $2}'`
        ;;
      --resource=*)
        RESOURCE=`echo $i | awk -F= '{print $2}'`
        ;;
      --username=*)
        USERNAME=`echo $i | awk -F= '{print $2}'`
        ;;
      --password=*)
        PASSWORD=`echo $i | awk -F= '{print $2}'`
        ;;
      --warning-range=*)
        WARNING=`echo $i | awk -F= '{print $2}'`
        ;;
      --critical-range=*)
        CRITICAL=`echo $i | awk -F= '{print $2}'`
        ;;
      *)
        echo "unrecognized argument: $i"
        usage
        ;;
    esac
  done
  
  if [ -z $HOST ]; then
    echo "--host argument missing"
    usage
  fi
  
  if [ -z $RESOURCE ]; then
    echo "--resource argument missing"
    usage
  fi
  
  if [ ! -z $USERNAME ] && [ ! -z $PASSWORD ]; then 
    LOGIN="-u $USERNAME:$PASSWORD"
  else 
    LOGIN=
  fi
  
  QUERY="q=$RESOURCE"
  
  if [ ! -z $WARNING ]; then
    QUERY="$QUERY&nagios_warning_range=$WARNING"
  fi
  
  if [ ! -z $CRITICAL ]; then
    QUERY="$QUERY&nagios_critical_range=$CRITICAL"
  fi
  
  OUTPUT=`/usr/bin/curl $LOGIN "http://$HOST:$PORT/resin-admin/rest.php?$QUERY" 2>/dev/null`
  
  if [ $? -ne 0 ]; then
    echo $OUTPUT
    exit 2
  fi
  
  echo $OUTPUT | exec awk '
  { print $0 }
  $1 ~ /OK/ { exit 0 }
  $1 ~ /WARNING/ { exit 1 }
  $1 ~ /CRITICAL/ { exit 2 }
  { exit 3 }
  '

Next, save the following Nagios library script as "nagios.php" in the external directory from the previous step:

  <?php

  # Nagios style range checker
  # http://nagiosplug.sourceforge.net/developer-guidelines.html#THRESHOLDFORMAT
  function out_of_range($value, $range)
  {
    if (! $range)
      return true;

    if ($range[0] == "@") {
      return ! out_of_range($value, substr($range, 1));
    }

    $bounds = explode(":", $range);

    if (count($bounds) == 0)
      return true;

    $lower = 0;
    $upper = trim($bounds[0]);

    if (count($bounds) == 2) {
      $lower = trim($bounds[0]);
      $upper = trim($bounds[1]);
    }
    elseif (count($bounds) > 2) {
      // bogus range, can't be in it
      return true;
    }

    if (is_numeric($lower)) {
      if ($upper == "")
        return ($value < $lower);

      return ($value < $lower || $value > $upper);
    }

    if ($lower == "~") {
      if (is_numeric($upper))
        return $value > $upper;

      // ~: == (-inf, inf)
      return false;
    }

    return true;
  }

  function nagios_is_warning($value) 
  {
    if (isset($_REQUEST["nagios_warning_range"]))
      return out_of_range($value, $_REQUEST["nagios_warning_range"]);

    return false;
  }

  function nagios_is_critical($value) 
  {
    if (isset($_REQUEST["nagios_critical_range"]))
      return out_of_range($value, $_REQUEST["nagios_critical_range"]);

    return false;
  }

  function nagios_output($value, $msg)
  {
    if (nagios_is_critical($value))
      nagios_output_critical($msg);

    elseif (nagios_is_warning($value))
      nagios_output_warning($msg);

    else 
      nagios_output_ok($msg);
  }

  function nagios_output_ok($msg)
  {
    echo "OK - {$msg}\n";
  }

  function nagios_output_warning($msg)
  {
    echo "WARNING - {$msg}\n";
  }

  function nagios_output_critical($msg)
  {
    echo "CRITICAL - {$msg}\n";
  }

  function nagios_output_unknown($msg)
  {
    echo "UNKNOWN - {$msg}\n";
  }

  header("Content-Type: text/plain; charset=utf-8");

  mbean_init();

  ?>

Add plugins

You can create your own plugin or use one of the examples below install it in the external REST plugin directory. Use a ".rest" extension on the script.

check_thread_pool.rest

This plugin checks the number of active threads in the Resin thread pool.

<?php

include_once "nagios.php";

$jvm_thread = $g_mbean_server->lookup("java.lang:type=Threading");
$thread_pool = $g_server->ThreadPool;

$msg = "pool active: {$thread_pool->ThreadActiveCount}, " .
       "pool idle: {$thread_pool->ThreadIdleCount}, " .
       "pool count: {$thread_pool->ThreadCount}, " .
       "jvm count: {$jvm_thread->ThreadCount}, " . 
       "jvm peak: {$jvm_thread->PeakThreadCount}";

nagios_output($thread_pool->ThreadActiveCount, $msg);

?>

check_heap.rest

<?php

include_once "nagios.php";

$mem_free = $g_server->RuntimeMemoryFree;

$msg = "free memory: {$mem_free}";

nagios_output($mem_free, $msg);

?>

check_uptime.rest

<?php

include_once "nagios.php";

$start_time = $g_server->StartTime->time / 1000;
$now = $g_server->CurrentTime->time / 1000;
$uptime = $now - $start_time;

$msg = sprintf("%d days %02d:%02d:%02d",
               $uptime / (24 * 3600),
               $uptime / 3600 % 24,
               $uptime / 60 % 60,
               $uptime % 60);
$msg .= " -- " . format_datetime($g_server->StartTime);

nagios_output($uptime, $msg);

?>

Install Nagios objects

Create Nagios commands for each plugin, for example:

  define command{
        command_name    resin_threads

        command_line /usr/local/nagios/resin/check_resin.sh --host=$HOSTADDRESS$ --port=$ARG1$ --resource=check_thread_pool \
                                                            --username=admin --password=admin \
                                                            --warning-range=$ARG2$ --critical-range=$ARG3$
        }

Then add a service to poll the plugins:

  define service {
        use                             local-service         ; Name of service template to use
        host_name                       localhost
        service_description             Resin threads
        check_command                   resin_threads!8080!256!384
        notifications_enabled           0
        }

Finally, restart Nagios and the service should appear.

Personal tools