A Perl script to print Nagios log records in a human readable date format

Perl date FAQ: Can you share a Perl date example where you print a date in a decent human-readable format?

Update: Be sure to look at the comments below for some great Perl "one liners", i.e., one-line solutions to this problem.

In this blog I'll share the source code for a Perl program that takes nagios.logrecords as input, then outputs the records with a human-readable date format. More specifically, the input records look like this:

[1225306053] SERVICE ALERT: FTPSERVER;FTP SERVICE;OK;SOFT;2;FTP OK - 0.029 second response time on port 21 [220 ProFTPD 1.3.1 Server ready.]
[1225307073] SERVICE ALERT: FTPSERVER;FTP SERVICE;OK;SOFT;3;FTP OK - 0.046 second response time on port 21 [220 ProFTPD 1.3.1 Server ready.]

and the output records look like this:

[2008/10/29 14:47:33] SERVICE ALERT: FTPSERVER;FTP SERVICE;OK;SOFT;2;FTP OK - 0.029 second response time on port 21 [220 ProFTPD 1.3.1 Server ready.]
[2008/10/29 15:04:33] SERVICE ALERT: FTPSERVER;FTP SERVICE;OK;SOFT;3;FTP OK - 0.046 second response time on port 21 [220 ProFTPD 1.3.1 Server ready.]

Perl date format - My Perl Nagios script

UPDATE: For some terrific one-line solutions to this problem, see the Comments section below.

Here's the source code for my Perl script that converts these date fields into a human-readable format:

#!/usr/bin/perl

# ------------------------------------------------------------
# fixnag.pl
# ------------------------------------------------------------
# a script to take nagios.log records as input, and then
# output them with the date field converted to something
# human-readable
# ------------------------------------------------------------

sub epochtime
{
    my $epoch_time = shift;
    ($sec,$min,$hour,$day,$month,$year) = localtime($epoch_time);

    # correct the date and month for humans
    $year = 1900 + $year;
    $month++;

    return sprintf("%02d/%02d/%02d %02d:%02d:%02d", $year, $month, $day, $hour, $min, $sec);
}

while (<>)
{
    my $epoch = substr $_, 1, 10;
    my $remainder = substr $_, 13;
    my $human_date = &epochtime($epoch);
    printf("[%s] %s", $human_date, $remainder);
}

exit;

All you have to do to run this script from the command line is something like this:

$ cat nagios.log | fixnag.pl

How about the following one

How about the following one liner

perl -pe 's/^\[(\d{10})/scalar(localtime $1)/eg' nagios.log

Perl date format one-liner

Very nice, and much simpler -- thanks!

Another oneliner

I prefer the dates in ISO Format and with the "[" included:

perl -MPOSIX -ne 'print if s/(?<=^\[)(\d+)/strftime q"%F %T",localtime $1/e' nagios.log

Simple Command is here

[root@roger ~] perl -pe 's/(\d+)/localtime($1)/e' nagios.log

you will get the result like below,

[Fri Nov 2 05:04:14 2011] SERVICE ALERT: about.ex.com;check_multi_service;OK;HARD;3;EventLog: Started - DNS Client: Started - Windows Time: Started
[Fri Nov 2 05:04:14 2011] SERVICE ALERT: about.ex.com;check_folder_size;OK;HARD;3;OK: c:\Dell is 63MB

Post new comment

The content of this field is kept private and will not be shown publicly.