#!/usr/bin/perl

# DESCRIPTION: this script controls the NMON process. 
#   + If NMON is launched it does nothing unless the date when NMON was launched (obtained from
#     NMON output file) is not today's date. In this case it stops NMON.This is intended to rotate NMON 
#     log files.
#   + If NMON is not launched the script will launch it. Before it, if NMON output file exists (hostname.nmon)
#     in $nmon_dir (configured as global variable) it is archived. An archive file is maintained for each month
#     day. Archive files for the same month day get overwritten.
#
#  NMON command is launched in recording mode with the following flags:
#   - F: file where NMON writes its output. It is $nmon_dir/hostname.nmon. $nmon_dir is configured as global variable.
#   - t: include top processes.
#   - S: include WLM sections.
#   - P: include paging space section.
#   - V: include disk volume group section.
#   - s: interval in seconds between 2 snapshots. It is set to take a snapshot every 60 seconds.
#   - c: number of snapshots that must be taken. It is set to 1500. This covers 1500 minutes, which is 25 hours.
#
#  This script is supposed to be launched through the cron with a frecuency according to our needs to check possible
#  NMON outages (every 5 minutes, every 10 minutes, ...).


# PACKAGES AND GLOBAL VARIABLES

use strict;
use Time::Local;

my $debug = 0;
my $hostname = `hostname`;
chomp $hostname;
my $nmon_dir = "/u/operador/NMON/";
my $nmon_fich = $nmon_dir.$hostname.".nmon";
my $nmon_cmd = "/usr/bin/nmon -F $nmon_fich -t -S -P -V -s 60 -c 1500";
my $nmon_on = 0;
my $nmon_pid = undef;

# Hash for the months
my %meses = (
  'JAN'=>0,
  'FEB'=>1,
  'MAR'=>2,
  'APR'=>3,
  'MAY'=>4,
  'JUN'=>5,
  'JUL'=>6,
  'AUG'=>7,
  'SEP'=>8,
  'OCT'=>9,
  'NOV'=>10,
  'DEC'=>11
);

# Check if NMON is launched
my @ps_output = `ps -ef | grep nmon | grep -v grep`;
foreach my $linea (@ps_output) {
  if ($linea =~ /$nmon_fich/) {
    chomp $linea;
    $linea =~ s/^\s+(.*)$/$1/;
    my @linea = split /\s+/,$linea;
    $nmon_pid = @linea[1];
    $nmon_on = 1;
  }
}

if ($nmon_on) {
  # If NMON is launched...
  print "nmon is launched (pid $nmon_pid).\n" if $debug;

  # Today's date
  my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst,$unixdate_hoy,$unixdate_fich) = undef;
  ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
  $unixdate_hoy = timelocal(0,0,0,$mday,$mon,$year);
  print "Today's date: $mday-".eval($mon+1)."-".eval($year+1900)." (unix date: $unixdate_hoy).\n" if $debug;

  # Take from $nmon_fich the date when NMON was launched
  open (NMON_FICH,$nmon_fich) or die "$nmon_fich file cannot be openned.\n";
  my @nmon_fich = <NMON_FICH>;
  close NMON_FICH;
  foreach my $linea (@nmon_fich){
    if ($linea =~ /^AAA,date,(\d{1,2})-(\w{3})-(\d{4})/){
      my ($mday,$mon,$year) = ($1,$2,$3);
      $unixdate_fich = timelocal(0,0,0,$mday,$meses{$mon},eval($year-1900));
      print "Date when NMON was launched: $mday-$mon-$year (unix date: $unixdate_fich).\n" if $debug;
      last; 
    }
  }

  # NMON has not been launched today. Stop it.
  if ($unixdate_hoy != $unixdate_fich) {
    print "NMON has not been launched today. Stop it (pid $nmon_pid).\n" if $debug; 
    `kill -9 $nmon_pid`;
  } else {
    print "NMON has been launched today. \nEnd of process.\n" if $debug; 
  }
} else {
  # If NMON is stopped...
  print "NMON is stopped.\n" if $debug;

  if (-e $nmon_fich) {
    # $nmon_fich exists. It must be archived before NMON gets launched.
    my $nmon_arch = undef;

    print "$nmon_fich exists. It must be archived before NMON gets launched.\n" if $debug;

    # Take from $nmon_fich the date when NMON was launched
    open (NMON_FICH,$nmon_fich) or die "$nmon_fich file cannot be openned.\n";
    my @nmon_fich = <NMON_FICH>;
    close NMON_FICH;
    foreach my $linea (@nmon_fich){
      if ($linea =~ /^AAA,date,(\d{1,2})-(\w{3})-/){
        my ($dia,$mes) = ($1,$2);
        $nmon_arch = $nmon_dir.$hostname."-".$dia.".nmon"; 
        print "NMON file: $nmon_arch\n" if $debug;
        last; 
      }
    }
    print "NMON archive file is $nmon_arch.\n" if $debug;
    if (-e $nmon_arch) {
      # If $nmon_arch exists append to it data lines from $nmon_fich
      print "$nmon_arch exists. Data lines from $nmon_fich will be appended.\n" if $debug;

      # Determine last entry number in $nmon_arch
      my $cont = undef;
      open (NMON_ARCH,$nmon_arch) or die "$nmon_arch file cannot be openned.\n";
      my @nmon_arch = <NMON_ARCH>;
      close NMON_ARCH;
      foreach my $linea (@nmon_arch){
        if ($linea =~ /ZZZZ,T0*(\d+),/) {
          $cont = $1;
        } 
      }
      print "Last entry number in $nmon_arch is $cont.\n" if $debug;

      # Data lines get appended
      open (NMON_ARCH,">>".$nmon_arch) or die "$nmon_fich file cannot be openned.\n";
      my $proc_nomfich = 0;
      foreach my $linea (@nmon_fich){
        if ($linea =~ /^ZZZZ,T\d{4},/) { 
          # Update entry counter
          $proc_nomfich = 1;
          $cont = sprintf("%04d", $cont+1);
          print "New line ZZZZ(T$cont): $linea" if $debug;
        }
        unless ($proc_nomfich) { next; }
        if ($linea =~ /^AAA/) { next; }
        if ($linea =~ /^BBB/) { next; }
        # Update T#### lines with correct entry number
        $linea =~ s/(^.+),T\d{4},(.+$)/$1,T$cont,$2/; 
        print NMON_ARCH $linea;
      }
      close NMON_ARCH;
    } else {
      # If $nmon_arch does not exist move $nmon_fich to $nmon_arch
      print "$nmon_arch does not exist. Move $nmon_fich to $nmon_arch.\n" if $debug;
      `mv $nmon_fich $nmon_arch`;
    }
  } else { 
    print "No existe $nmon_fich.\n" if $debug;
  }
  # Launch NMON.
  print "Se arranca nmon. \nFin del proceso.\n" if $debug;
  `$nmon_cmd`;
}
