Few people off the list had made the same request and I sent them the relevant info. With apologizes for spamming those of you who are not interested, I am attaching the requested files to this message.

Cheers,
Hossein

Gary Greene wrote:
We're in the process of rolling out network and machine monitoring here
using Nagios, so I'd be very interested in this, please send the info my way
when you've the opportunity. Thanks.


On 4/28/10 2:34 PM, "Hossein Rafighi" <[email protected]> wrote:

Hi,

We have modified rt-crontool to create Nagios alerts. This woks with
nrpe and unlike SendNgiosAlert doesn't require any additional modules
installation. If you have running Nagios server it can easily pull
relevant stuff from RT. Nagios will send a warning email if:
Tickets are new for more than 24hours
Tickets are open for more than 5days

It will generate a critical email if:
Tickets are new for more than 48hours
Tickets are open for more than 7days.

If the status of a ticket is stalled, then our script will ignore it. It
is our policy to change the ticket status to stalled if a ticket is
required to remain open for more than one week. Since we are a 24x7x360
lab, we decided to include weekends and holidays in the script. If
you're interested let me know and I can send/post scripts and required
steps. Again, this script is modified version of rt-crontool.

Sample email:

***** Nagios 2.8 *****
Notification Type: PROBLEM
Service: Q-CCN
Host: helpdesk
Address: 172.127.2.12
State: WARNING
Date/Time: Tue Apr 27 14:55:37 PDT 2010
Additional Info:
0 new tickets: 0  24h, 0  48h: 1 open: 1  120h, 0  168h


Cheers,
Hossein Rafighi


--
 _____  _____   _____  _   _  _   _  ____ Hossein Rafighi
|_   _||  _  \ |_   _|| | | || \_/ ||  __|TRIUMF, 4004 Wesbrook Mall
  | |  | |_|  )  | |  | | | ||     || |__ Vancouver BC, Canada, V6T 2A3
  | |  |  _  /   | |  | \_/ || \_/ ||  __|Voice: (604) 222-1047
  | |  | | \ \  _| |_ |     || | | || |   Fax:   (604) 222-1074
  |_|  |_|  \_\|_____| \___/ |_| |_||_|   Website: http://www.triumf.ca

*******************************************************************************************************************
*                                                                               
                                  *
* Information in this file is provided as is. Please try it on a test server 
first to make sure it works for you. *
*                                                                               
                                  *
*******************************************************************************************************************


It is assumed you’re using Linux for both Nagios and RT servers. There are two 
requirements when integrating RT with Nagios:
1: Running Nagios server, and Nagios client on the computer hosting RT. 
On the computer hosting RT you must add nrpe to the bottom of: /etc/sudoers:
#>visudo  <--and add the following lines-->
# Do not require a tty for user nrpe
Defaults:nrpe !requiretty
# Allow user nrpe to execute rt-checkticket with any arguments
nrpe      ALL=(ALL)     NOPASSWD: /path-to/your-nagios/rt-checkticket

SAVE AND EXIT SUDOERS.


2: rt-checkticket script.
Download rt-checkticket and put it in /path-to/your-nagios directory on the 
computer hosting RT.
Create rt-checkticket.cfg file and add the following to it. One line per queue 
name:
command[rt-checkQUEUE1]=/usr/bin/sudo /path-to/your-nagios/rt-checkticket -q 
'QUEUE1'
command[rt-checkQUEUE2]=/usr/bin/sudo /path-to/your-nagios/rt-checkticket -q 
'QUEUE2'

SAVE AND EXIT RT-CHECKTICKET


Test to see if your RT is reporting any data:
#>su -s /bin/sh -c "/usr/bin/sudo /path-to/your-nagios/rt-checkticket -q 
'QUEUE1'" nrpe
It shouldn’t give any error. It should display something like:
0 new tickets: 0 > 24h, 0 > 48h; 0 open: 0 > 120h, 0 > 168h (depending on your 
queue you may see different numbers for open/new tickets). If the script 
doesn’t display new/open tickets, then you need to fix whatever the error 
message it gives.

Depending on how your Nagios server is setup you may have to create RT.cfg file 
with info similar to the following:
define servicegroup {
        servicegroup_name RT-tickets
        alias             RT Tickets
}

define contactgroup {
    contactgroup_name           QUEUE1
    alias                       QUEUE1 Admins
    members                     queue1-admin1
}

define service{
        use                     RT-service   
        service_description     Q-QUEUE1
        check_command           check_nrpe!rt-checkQUEUE1
        contact_groups          QUEUE1-admins
}


Then, you need to create a Contact.cfg with the actual email address and 
contact information for each queue-admins you create.
define contact {
    contact_name                        jdoe
    alias                               John Doe
    email                               [email protected]
    contactgroups                       QUEUE1-admins
    service_notification_period         daytime
    host_notification_period            daytime
    service_notification_options        w,u,c,r
    host_notification_options           d,u,r
    service_notification_commands       notify-by-email
    host_notification_commands          host-notify-by-email
}

That should do it.
#!/usr/bin/perl
# 
# ----------------------------------------------------------------
# Based on rt-crontool found in /opt/rt/bin directory.
# Thanks to good people in bestpractical Solutions, LLC.
#
# see "Usage". Returns exit status suitable for Nagios if
# tickets are open too long
#
# Andrew Daviel, Hossein Rafighi April 2010
#
use strict;
use Carp;
use Time::Local ;
my $defhwarn=5*24 ; my $defhcrit=7*24 ; my $defhnwarn=24 ; my $defhncrit=48 ;

# fix lib paths, some may be relative
BEGIN {
    require File::Spec;
    my @libs = ("lib", "local/lib");
    my $bin_path;

    for my $lib (@libs) {
        unless ( File::Spec->file_name_is_absolute($lib) ) {
            unless ($bin_path) {
                if ( File::Spec->file_name_is_absolute(__FILE__) ) {
                    $bin_path = ( File::Spec->splitpath(__FILE__) )[1];
                }
                else {
                    require FindBin;
                    no warnings "once";
                    $bin_path = $FindBin::Bin;
                }
            }
            $lib = File::Spec->catfile( $bin_path, File::Spec->updir, $lib );
        }
        unshift @INC, $lib;
    }
}

use RT;

use Getopt::Std;
my $STATE_OK = 0;
my $STATE_WARNING = 1;
my $STATE_CRITICAL = 2;
my $STATE_UNKNOWN = 3;
my $USAGE = "
Usage: $0 -q <queue> [-w <hours>][-c <hours>][-W <hours>][-C <hours>]

     -q queue name e.g. 'General'
     -c # of hours ticket open to trigger a critical failure ($defhcrit)
     -w # of hours ticket open to trigger a warning ($defhwarn)
     -C # of hours ticket new  to trigger a critical failure ($defhncrit)
     -W # of hours ticket new  to trigger a warning ($defhnwarn)
     -v verbose
";

use RT::Interface::CLI qw(CleanEnv GetCurrentUser GetMessageContent loc);
use RT::Tickets;

#Clean out all the nasties from the environment
CleanEnv();

my ( $search, $search_arg, $log );
# hardcode
$search = 'RT::Search::FromSQL' ;

my %opts; 
unless (getopts('q:c:C:w:W:v', \%opts)) {
   print $USAGE;
   exit 1;
}
unless (defined $opts{'q'}) {
   print $USAGE;
   exit 1;
}
my $rstatus ;

my $queue ; my $hwarn=$defhwarn ; my $hcrit=$defhcrit ; my $hnwarn=$defhnwarn ; 
my $hncrit= $defhncrit ;
my $ncrit = 0 ; my $nwarn = 0 ;
$queue = $opts{'q'};

if (defined $opts{'w'}) { # hours open till warn
  if ($opts{'w'} =~ /(^[\d]+)$/) {
    $hwarn = $1 ;
  } else {
    print "Error: -w requires numeric number of hours\n" ;
    exit 1 ;
  }
}
if (defined $opts{'c'}) { # hours open till critical
  if ($opts{'c'} =~ /(^[\d]+)$/) {
    $hcrit = $1 ;
  } else {
    print "Error: -c requires numeric number of hours\n" ;
    exit 1 ;
  }
}
if (defined $opts{'W'}) {  # hours new till warn
  if ($opts{'W'} =~ /(^[\d]+)$/) {
    $hnwarn = $1 ;
  } else {
    print "Error: -W requires numeric number of hours\n" ;
    exit 1 ;
  }
}
if (defined $opts{'C'}) {  # hours new till critical
  if ($opts{'C'} =~ /(^[\d]+)$/) {
    $hncrit = $1 ;
  } else {
    print "Error: -C requires numeric number of hours\n" ; 
    exit 1 ;
  }
}

# Load the config file
RT::LoadConfig();

# adjust logging to the screen according to options
RT->Config->Set( LogToScreen => $log ) if $log;

#Connect to the database and get RT::SystemUser and RT::Nobody loaded
RT::Init();

#Get the current user all loaded
my $CurrentUser = GetCurrentUser();

unless ( $CurrentUser->Id ) {
    print loc("No RT user found. Please consult your RT administrator.\n");
    exit(1);
}

# We _must_ have a search object
load_module($search);

# search for new tickets
$search_arg = "Queue = '$queue' AND Status = 'new'" ;
#find a bunch of tickets
my $tickets = RT::Tickets->new($CurrentUser);
my $search  = $search->new(
    TicketsObj  => $tickets,
    Argument    => $search_arg,
    CurrentUser => $CurrentUser
);

my $now = time() ;
$search->Prepare();
if ($opts{'v'}) { print "New tickets in $queue, warn over $hnwarn hours, 
critical over $hncrit hours\n" ; }
my $tickets = $search->TicketsObj;
my $nnew = 0 ; my $nncrit = 0 ; my $nnwarn = 0 ;
while ( my $ticket = $tickets->Next() ) {
  $nnew++ ;
  my $created ; my $lcreated ; my $age ; 
  my $id = $ticket->Id ;
  my $name = $ticket->QueueObj->Name() ;
  my $date = $ticket->Created ;
  my $update = $ticket->LastUpdated ;
  my $status = $ticket->Status ;
  if ($ticket->Created =~ 
/([\d]+)-([\d]+)-([\d]+)[\s]+([\d]+):([\d]+):([\d]+)/) {
    $created = timegm($6,$5,$4,$3,$2-1,$1) ;
    $lcreated = localtime($created) ;
    $age = int(($now - $created) / 3600) ; # open $age hours
  } else {
    print "ERROR parsing $ticket->Created\n" ;
  }
  if ($opts{'v'}) {
    print "Ticket #: $id\tQueue: $name\tCreated On: $date GMT\tLast Updated: 
$update GMT\tStatus: $status\t$age hours\n";
  }
  if ($age > $hncrit) {
    $nncrit++ ;
  } 
  if ($age > $hnwarn) {
    $nnwarn++ ;
  }
}

# search for open tickets

$search_arg = "Queue = '$queue' AND Status = 'open'" ;
#find a bunch of tickets
my $tickets = RT::Tickets->new($CurrentUser);
my $search  = $search->new(
    TicketsObj  => $tickets,
    Argument    => $search_arg,
    CurrentUser => $CurrentUser
);

$search->Prepare();

if ($opts{'v'}) { print "Open tickets in $queue, warn over $hwarn hours, 
critical over $hcrit hours\n" ; }

# TicketsFound is an RT::Tickets object
my $tickets = $search->TicketsObj;

my $nwarn = 0 ; my $nopen = 0 ; my $ncrit = 0 ;
#for each ticket we've found
while ( my $ticket = $tickets->Next() ) {
  my $created ; my $lcreated ; my $age ; 
  my $id = $ticket->Id ;
  my $name = $ticket->QueueObj->Name() ;
  my $date = $ticket->Created ;
  my $update = $ticket->LastUpdated ;
  my $status = $ticket->Status ;
  if ($ticket->Created =~ 
/([\d]+)-([\d]+)-([\d]+)[\s]+([\d]+):([\d]+):([\d]+)/) {
    $created = timegm($6,$5,$4,$3,$2-1,$1) ;
    $lcreated = localtime($created) ;
    $age = int(($now - $created) / 3600) ; # open $age hours
  } else {
    print "ERROR parsing $ticket->Created\n" ;
  }
  $nopen++ ;
  if ($age > $hcrit) {
    $ncrit++ ;
  } 
  if ($age > $hwarn) {
    $nwarn++ ;
  }
  if ($opts{'v'}) { print "Ticket #: $id\tQueue: $name\tCreated On: $date 
GMT\tLast Updated: $update GMT\tStatus: $status\t$age hours\n"; }
}
my $hwarnh = $hwarn.'h' ;
my $hcrith = $hcrit.'h' ;
my $hnwarnh = $hnwarn.'h' ;
my $hncrith = $hncrit.'h' ;
print "$nnew new tickets: $nnwarn > $hnwarnh, $nncrit > $hncrith; $nopen open: 
$nwarn > $hwarnh, $ncrit > $hcrith\n" ;
if ($ncrit or  $nncrit) { exit $STATE_CRITICAL; }
if ($nwarn or $nnwarn) { exit $STATE_WARNING; }
exit $STATE_OK;

# {{{ load_module 

=head2 load_module

Loads a perl module, dying nicely if it can't find it.

=cut

sub load_module {
    my $modname = shift;
    eval "require $modname";
    if ($@) {
        die loc( "Failed to load module [_1]. ([_2])", $modname, $@ );
    }

}

# }}}

# {{{ loc 

=head2 loc LIST

Localize this string, with the current user's currentuser object

=cut

sub loc {
    $CurrentUser->loc(@_);
}

# }}}

Discover RT's hidden secrets with RT Essentials from O'Reilly Media.
Buy a copy at http://rtbook.bestpractical.com

Reply via email to