Differences

This shows you the differences between two versions of the page.

Link to this comparison view

monitors:rasusagepl [2010/06/09 07:51] (current)
Line 1: Line 1:
 +====== ras-usage ======
 +
 +^ Author | [[ nelis@nlr.nl | Wim Nelis ]] |
 +^ Compatibility | Xymon 4.2 |
 +^ Requirements | Perl, unix |
 +^ Download | None |
 +^ Last Update | 2010-06-09 |
 +
 +===== Description =====
 +Script ras-usage.pl monitors the number of web users of a Juniper RAS cluster, as well as the state of each node in the cluster: active or passive. It is a server-side script, which uses SNMP to retrieve the information. It reports results in two tests, "​usage"​ en "​cluster"​.
 +
 +Test "​usage"​ measures the number of web-users, and uses NCV to report it to Xymon. The number of active users is checked against the number of licenses. If more than 90% of the licenses are in use, the status of this test becomes yellow.
 +
 +Test "​cluster"​ shows which node is active and which nodes are passive. This test is reported both to the individual nodes and to the cluster service. If a node is passive, it's status will be "​clear"​. This allows Xymon to build a history of state changes, while a status change does not result in an alert.
 +
 +===== Installation =====
 +As the script is a server-side script, all istallation steps below are performed at the Xymon server.
 +
 +Copy script ras-usage.pl into an appropriate directory, typically ~xymon/​server/​ext. Modify the installation constants to match your environment. Those constants are shown between angle brackets, e.g. <​Cluster>​.
 +
 +Edit file ~xymon/​server/​etc/​hobbitserver.cfg:​
 +<​code>​
 +TEST2RRD="​....,​usage=ncv"​
 +GRAPHS="​....,​usage"​
 +NCV_usage="​usage:​GAUGE"​
 +</​code>​
 +
 +Edit file ~xymon/​server/​etc/​hobbitlaunch.cfg to include:
 +<​code>​
 +[usage]
 +        ENVFILE /​home/​xymon/​server/​etc/​hobbitserver.cfg
 +        CMD /​home/​xymon/​server/​ext/​ras-usage.pl
 +        LOGFILE $BBSERVERLOGS/​ras-usage.log
 +        INTERVAL 5m
 +</​code>​
 +You might need to adapt the pathnames to match your environment.
 +
 +Edit file ~xymon/​server/​etc/​hobbitgraph.cfg to include:
 +<​code>​
 +[usage]
 +        TITLE , Concurrent usage
 +        YAXIS VPN clients []
 +        -l 0
 +        DEF:​cnt=usage.rrd:​usage:​AVERAGE
 +#       ​DEF:​max=usage.rrd:​usage:​MAX
 +#       ​CDEF:​xtr=max,​cnt,​-
 +        AREA:​cnt#​00CC00:​Usage
 +        GPRINT:​cnt:​MAX:​ Max\: %6.2lf %s
 +        GPRINT:​cnt:​AVERAGE:​Avg\:​ %6.2lf %s
 +        GPRINT:​cnt:​LAST:​Cur\:​ %6.2lf %s\n
 +#       ​AREA:​xtr#​0000CC:​MaxUse:​STACK
 +#       ​GPRINT:​max:​MAX:​Max\:​ %6.2lf %s
 +#       ​GPRINT:​max:​AVERAGE:​Avg\:​ %6.2lf %s
 +#       ​GPRINT:​max:​LAST:​Cur\:​ %6.2lf %s
 +</​code>​
 +If you have defined the consolidation function (CF) MAX in the RRD created by Xymon, the comment lines can be un-commented to show the maximum use as well.
 +
 +
 +
 +===== Source =====
 +==== ras-usage.pl ====
 +
 +<hidden onHidden="​Show ras-usage.pl ⇲" onVisible="​Hide ras-usage.pl ⇱">​
 +<​code>​
 +#​!/​usr/​bin/​perl -w
 +#
 +# RAS-usage: determine the number of users (VPN clients) of the Juniper
 +#  SA-2500 remote access cluster. All members of the cluster know how many
 +#  users there are. The result is reported to Xymon using the clustername
 +#  as hostname.
 +#
 +# - Added test cluster, which is reported for each multi-node cluster
 +#   ​showing which node is active and which node(s) are passive. Based
 +#   on ideas of Tom Schmitt.
 +#
 +use strict ;
 +use POSIX qw/ strftime / ;              # Format time
 +
 +#
 +# Installation constants.
 +#
 +my $XyDisp= $ENV{BBSERVERHOSTNAME} ;    # Name of monitor server
 +my $XySend= $ENV{BB} ;                  # Monitor interface program
 +my $FmtDate= '​%Y.%m.%d %H:​%M:​%S'​ ;      # Default date format
 +   ​$FmtDate= $ENV{BBDATEFORMAT} if defined $ENV{BBDATEFORMAT} ;
 +my $TestName= '​usage'​ ;                 # Xymon test name
 +
 +#
 +# Define the Juniper RAS clusters.
 +# Each entry describes one cluster. The key of an entry is name of the cluster.
 +# The value of an entry is a reference to a list of names of the physical nodes
 +# in the cluster. It is assumed that the DNS name is equal to the Xymon name in
 +# all these cases.
 +#
 +my %Ras= (
 +        <​cluster> ​ => [ '<​Node-0>',​ '<​Node-1>'​ ],
 +   ) ;
 +#
 +# Define the number of available licenses per cluster.
 +#
 +my %MaxUsers= (                         # Number of available licenses
 +        <​cluster> ​ => <​Count>,​
 +   ) ;
 +
 +#
 +# Define the SNMP query command to determine the number of users. The OIDs
 +# of interest in subtree .1.3.6.1.4.1.12532. are:
 +#   2.0 - Number of Signed-In Web Users
 +#   3.0 - Number of Signed-In Mail Users
 +#   9.0 - the number of concurrent meeting users
 +#  12.0 - The Total number of Users Logged In for the IVE Node
 +#  13.0 - The Total number of Users Logged In for the Cluster
 +#
 +my $SnmpUser ​  = '​snmpget -c <​ComString>​ -v 2c %s .1.3.6.1.4.1.12532.2.0'​ ;
 +
 +#
 +# Define the SNMP query to determine which physical server holds the Virtual
 +# IP address of the cluster.
 +#
 +my $SnmpCluster= '​snmpget -c <​ComString>​ -v 2c %s .1.3.6.1.2.1.4.20.1.1.%s'​ ;
 +
 +#
 +# Variable allocation.
 +#
 +my $Now= strftime( $FmtDate, localtime ) ;      # Timestamp of tests
 +my $HostName ;                          # Xymon host name
 +my $Server ;                            # RAS node name
 +my $Cmd ;                               # Full blown snmpget command
 +my $Color ;                             # Test status
 +my $Users ;                             # Number of users
 +my %Cluster ;                           # Status of cluster nodes
 +my @Lines ;                             # Command output
 +my $Result ;                            # Test result
 +
 +#
 +# Function UnpackIp transforms a binary formatted IPv4 address into a
 +# dotted decimal encoded string.
 +#
 +sub UnpackIp($) { return join('​.',​unpack('​C4',​$_[0])) } ;
 +
 +#
 +# Main program.
 +# -------------
 +#
 +foreach $HostName ( keys %Ras ) {
 +  $Color = '​green'​ ;                    # Preset variables
 +  $Users = undef ;
 +  $Result= ''​ ;
 +
 + #
 + # -A- Determine for each cluster the number of web users.
 + #
 + # The number of users is retrieved from the nodes. It was found that an
 + # `snmpget` often fails if it is directed to the cluster service.
 + #
 +  foreach $Server ( @{$Ras{$HostName}} ) {
 +    $Cmd= sprintf( $SnmpUser, $Server ) ;
 +    @Lines= `$Cmd` ;
 +    next                        unless defined $Lines[0] ;
 +    next                        unless $Lines[0]=~ m/ = Gauge32: (\d+)\s*$/ ;
 +    $Users= $1 ;                        # Concurrent web users
 +    last ;
 +  }  # of foreach
 +
 +  #
 +  # Determine the test status and build the tail of the message.
 +  #
 +  unless ( defined $Users ) {
 +    $Color= '​red'​ ;
 +    $Result= "&​$Color Cluster members are not accessible.\"​\n"​ ;
 +  } else {
 +    if ( $Users > 0.9 * $MaxUsers{$HostName} ) {
 +      $Color = '​yellow'​ ;
 +      $Result= "&​$Color High number of users&#​58;​ $Users\n"​ ;
 +    }  # of if
 +    $Result.= "<​!--\nusage = $Users\n-->"​ ;
 +  }  # of else
 +  ​
 +  #
 +  # Build the header of the message, and send it to Xymon.
 +  #
 +  $Result= "​\"​status $HostName.$TestName $Color $Now\n"​ .
 +         "​Number of users of Remote Access Service\n\n"​ .
 +         ​$Result . "​\"​\n"​ ;
 +  `$XySend $XyDisp $Result` ;           # Inform Xymon
 +
 + #
 + # -B- Determine the cluster status of each multi-node cluster.
 + # ​    Test '​cluster'​ shows which node is active, and which are passive.
 + #
 +  next                          unless @{$Ras{$HostName}} > 1 ;
 +
 +  $Color ​ = '​green'​ ;
 +  $Result = ''​ ;
 +  %Cluster= () ;
 +  my $VirtualIp= UnpackIp( gethostbyname($HostName) ) ;
 +
 +  foreach $Server ( @{$Ras{$HostName}} ) {
 +    $Cmd= sprintf( $SnmpCluster,​ $Server, $VirtualIp ) ;
 +    @Lines= `$Cmd` ;
 +    if ( defined $Lines[0] ) {
 +      if ( $Lines[0]=~ m/​$VirtualIp$/​ ) {
 +        $Cluster{$Server}= [ '​green',​ "​$Server is the active node in cluster $HostName"​ ] ;
 +        $Result.= "&​green $Server ​ active node\n"​ ;
 +      } elsif ( $Lines[0]=~ m/No Such Instance currently exists at this OID$/ ) {
 +        $Cluster{$Server}= [ '​clear',​ "​$Server is a passive node in cluster $HostName"​ ] ;
 +        $Result.= "&​green $Server ​ passive node\n"​ ;
 +      } else {
 +        $Color ​ = '​yellow' ​     unless $Color eq '​red'​ ;
 +        $Cluster{$Server}= [ '​yellow',​ "​$Server has sent an unrecognised response:​\n"​ .
 +                                       " ​ $Lines[0]"​ ] ;
 +        $Result.= "&​yellow $Server ​ unrecognised response\n"​ ;
 +      }  # of else
 +    } else {
 +      $Color ​ = '​red'​ ;
 +      $Cluster{$Server}= [ $Color, "​$Server has sent no response"​ ] ;
 +      $Result.= "&​$Color $Server ​ no response\n"​ ;
 +    }  # of else
 +  }  # of foreach
 +
 +  #
 +  # Report the status of all nodes together for the cluster service.
 +  #
 +  $Result= "​\"​status $HostName.cluster $Color $Now\n"​ .
 +         "​Node status in this cluster\n\n"​ .
 +         ​$Result . "​\"​\n"​ ;
 +  `$XySend $XyDisp $Result` ;           # Inform Xymon
 +
 +  #
 +  # Report the individual node status to each node individually.
 +  #
 +  foreach $Server ( keys %Cluster ) {
 +    $Color = $Cluster{$Server}[0] ;
 +    $Result= "​\"​status $Server.cluster $Color $Now\n"​ .
 +           ​$Cluster{$Server}[1] . "​\"​\n"​ ;
 +    `$XySend $XyDisp $Result` ;         # Inform Xymon
 +  }  # of foreach
 +}  # of foreach
 +</​code>​
 +</​hidden>​
 +
 +===== Known  Bugs and Issues =====
 +This script is used  to monitor a two-node Juniper SA-2500 cluster. I assume it will work as well on the other Juniper RAS clusters.
 +
 +===== Credits =====
 +Test "​cluster"​ is an implementation of ideas of Tom Schmitt.
 +
 +===== Changelog =====
 +
 +  * **2010-06-09**
 +    * Initial release
  
  • monitors/rasusagepl.txt
  • Last modified: 2010/06/09 07:51
  • (external edit)