Checking the age of a file – Perl in monitoring

An unusual monitoring request

Some time ago we – at the monitoring team got a bit strange request: Check the time when a file was written last time. If the modification time of it is older than “x” minutes, rise a warning message in the monitoring system.

Although, it is kind of indirect monitoring, it can be really relevant regarding the health of an application which is known to write information into a file at known regular intervals.

Tool to use

The first question I should answer is about the tool to be used for implementation of this request. I decided to use Perl script.

Perl is able to invoke shell commands on all platforms it is available for. This is important because the monitoring system we use (HP OVO) can receive data from external to OVO scripts/programs with help of a shell command. That command must be called by the external script with some parameters defining the data to be passed and the element of the OVO system receiving that data (name of the monitor template).

On the other hand Perl is available for all platforms where we use OVO. The only thing I had to take care of is to avoid using of system specific things in the script (features available only for a specific operating system)

The script

Writing the script I tried to use only the basic Perl features available even on oldest servers we have. The resulting script is small, simple and highly portable between operating systems. Attributes of a file stored differently on Linux and Windows. But those basic parameters we need can be found in both.

The script can be started in two different modes: test and production.

  • test_run: The program will write its output to the STDOUT instead of passing
    it to the monitoring system
  • <monitor name>: This is a placeholder for name of the monitor
    (see “monitor templates in HP OVO”) which called the
    program and will handle the result returned.

The latter is an OVO specific feature which can be easily modified according to your needs.

The code

# Created by: Laszlo Vasvary
# Last modification:
# 10.08.2011 script released
#
#
use strict;
use File::DosGlob;

if ( $ARGV[0] eq "" || not(grep {$_ eq $ARGV[1]} ("file_age", "file_size")) || $ARGV[2] eq "" ) {
 die <<eot;
HP OVO file checking utility

Usage:

The program takes three arguments:

1: Name of the file with full path
 You can specify the file name with wildecards.
 The program will read all matching files and at the end it will deal with the
 youngest one choosen by the creation time of that.

2: Parameter to return:

file_age: The progam will return the age of the data in the file.
 It is calculated by extracting the modification time of the file
 from the time of running the program.

 file_size: The progam will return the size of the file in bytes.

3: Run mode:

test_run: The program will write its output to the STDOUT instead of passing
 it to the monitoring system

 <monitor name>: This is a placeholder for name of the monitor
 (see "monitor templates in HP OVO") which called the
 program and will handle the result returned.
eot
}

my @fileList = glob($ARGV[0]);
my $param_to_check = $ARGV[1];
my $run_mode = $ARGV[2];

my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks);
my %latestFile;
my @sortedFileList;
my %file_attribs;
my $timeToCompare = 0;

# Cycle thrugh files matching the pattern, choosing the yougest one, and store it's attrributes
for my $cycle_var ( @fileList ) {
 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat($cycle_var);

 if( $ctime > $timeToCompare ){
 %latestFile = (
 name => $cycle_var,
 device => $dev,
 inode => $ino,
 mode => $mode,
 numoflinks => $nlink,
 userid => $uid,
 groupid => $gid,
 deviceid => $rdev,
 size => $size,
 accesstime => $atime,
 modtime => $mtime,
 createtime => $ctime,
 blocksize => $blksize,
 blocks => $blocks
 );
 }
 $timeToCompare = $ctime;
}

# Pass the requested parameter to the STDOUT in test mode or to monitor using opcmon utility
if ( $ARGV[1] eq "file_age" ) {
 my $file_age = time - $latestFile{modtime};
 if ( $ARGV[2] eq "test_run") {
 print ("Age of the youngest file ", $latestFile{name}, " is ", $file_age, " seconds\n");
 }
 else {
 system("opcmon $ARGV[2]=$file_age")
 }
}
elsif ( $ARGV[1] eq "file_size" ) {
 if ( $ARGV[2] eq "test_run") {
 print ("Size of the youngest file ", $latestFile{name}, " is ", $latestFile{size}, " bytes\n");
 }
 else {
 system("opcmon $ARGV[2]=$latestFile{size}")
 }
}

Author: bithajcsar

I am a system architect with decades of experience behind. During that time I learned that only the continuous development of knowledge and skills can keep a specialist on the cutting edge of his profession. And only those will move the World forward! Another thing I noticed that the stupidly used ICT (Information and Communication Technology) moved people far from each-other, when the goal of the whole thing should be the opposite. A modern computer may provide too many "instant experience and happiness" and chain users - mainly kids - to their monitors. Just a step away from the Matrix! After all those thoughts I decided to share my knowledge and experience in a form understandable for anyone who wants to know more about devices and systems we use every day. My primary targets are kids. They are curious and they can learn so fast that it sometimes seems unbelievable for us. Maybe they will just know a bit more about ICT and will use that in a more clever way. But who knows? Maybe they will go further and later will move the World forward. I hope that I will be able to help them to find a right way and go much further we could imagine now.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s