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}") } }
