#!/usr/bin/perl -w
#mail-logs.pl v0.5
#
# This script requires the use of Net:SMTP, and Time::Local that can
# be gotten from CPAN if needed. To check if you have these, in a shell,
# run:
#
# perl -e '{use Net::SMTP;use Time::Local;}'
#
# If you don't get an error you have both modules installed.
#
#
# Copyright (C) 2001, 2002, 2003, 2004 Aaron Thompson
# thompson@cns.uni.edu
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# or visit http://www.gnu.org/copyleft/gpl.html
#
# Written to send a days log files in an email via SMTP. This was written to
# be used with a daily cron that runs ~12:00.
#
#
# Changes Between Versions... (CHANGELOG)
# =======================================
# v0.1
# ____________
# first working version.
# -> mailed Syslog logfiles.
#
# v0.2
# ____________
# -> added file names deviders to email
# -> added support for previous days SMB logs
# -> added support for previous days Bru logs
#
# v0.3
# ____________
# -> added support for previous and current days aide files.
# -> added/fixed zcat support for compressed logs.
#
# v0.4
# ____________
# -> fixed call to date commands to properly get 'yesterday' (instead of using hack).
# -> cleaned up &mailAide
#
# v0.5
# -----------
# -> wrote get_date function the will return a date in the proper format...
# get_date(format,n) format is defined in the coments for the sub, and n
# is the number of days before 'today'.
#
# -> defined file format for web logs.
#
# -> fixed so no email is sent for empty log data
#
# -> fixed mail_samba_logs
#
# -> added support for wtmp.
#
######################################################################
use strict;
use Net::SMTP;
use Time::Local;
#verbose = 1 will print more info verbose = 0 will not.
my $verbose = 1;
# Hostname stuph - this is the hostname the script is running on...
# Usually you can get this with 'hostname -f'.
my $hostname = "host.domain";
# The current year (use by mail_samba_logs, get_date)
# Currently this gets set again via localtime when get_date is called.
my $global_year = "2003";
# The last command, including path and option to take a file for input.
# (used by mail_wtmp_logs).
my $last_command = "/usr/bin/last -af";
#initialize 'list' of logfiles.
# Each entry in the hash should have the base file name as the key and a
# format as understood by get_date. If you add a format that is not defined
# in get_date you will need to define an entry in the 'OPTION' block.
my %log_files = ("/var/log/messages" => "std",
"/var/log/syslog" => "std",
"/var/log/boot" => "std",
"/var/log/daemon.log" => "std",
"/var/log/debug" => "std",
"/var/log/kern.log" => "std",
"/var/log/mail" => "std",
"/var/log/vsfpd.log" => "std",
"/var/log/user.log" => "std",
"/var/log/setuid" => "std",
"/var/log/uucp" => "std",
"/var/log/apache/access.log" => "apache",
"/var/log/apache/error.log" => "apache-error",
"/var/log/apache-ssl/access.log" => "apache",
"/var/log/apache-ssl/error.log" => "apache-error",
"/var/log/bruexeclog" => "bru",
"/var/log/samba/log." => "smb",
"/var/log/wtmp" => "wtmp");
#mail defaults
my $server = "smtpserver.domain"; #default smtp server
my $mail_to = "someone\@somewhere"; #default email reciever
my $mail_from = "mail-logs\@$hostname"; #default email sender
&mail_logs;
exit(0);
######################################################################
sub mail_logs{
my ($file_base, $file, $yesterday, $result, $count);
for $file_base (keys(%log_files)){
$yesterday = get_date($log_files{$file_base},1);
$result = "";
print "processing $file_base ...\n" if($verbose);
if ($log_files{$file_base} eq "smb"){
$result = mail_samba_logs($file_base);
}
elsif($log_files{$file_base} eq "wtmp"){
$result = mail_wtmp_logs($file_base);
}
else{
for $file (<$file_base*>){
print " processing $file ..." if($verbose);
if($file =~ /gz/){
open (IN,"/bin/gunzip -c $file|") or die "Could not open $file for reading!\n";
@_=<IN>;
close(IN);
$count = grep /$yesterday/, @_;
if ($count > 0){
$result .= "$file\n##################################################\n";
$result .= $_ for (grep /$yesterday/, @_);
}#fi
}
else{
open (IN,"$file") or die "Could not open $file for reading!\n";
@_=<IN>;
close(IN);
$count = grep /$yesterday/, @_;
if ($count > 0){
$result .= "$file\n##################################################\n";
$result .= $_ for (grep /$yesterday/, @_);
}#fi
}#fi
print " done.\n" if($verbose);
}#rof
}#fi
if ($result){
print " sending email for $file_base ... " if($verbose);
my $subject = "$file_base ($hostname).";
send_mail($mail_to,$mail_from,$subject,$result);
print "done.\n" if($verbose);
}#fi
print "done with $file_base.\n" if($verbose);
}#rof
}
######################################################################
sub send_mail{
#$smtp info found:
#http://faqchest.dynhost.com/prgm/perlu-l/perl-00/perl-0010/perl-001005/perl00103111_16616.html
# creditted to the Perl Cookbook by O'Reilly
my ($mail_to,$mail_from,$subject,$message) = @_;
my $smtp = Net::SMTP->new($server);
$smtp->mail($ENV{USER});
$smtp->to($mail_to);
$smtp->data();
$smtp->datasend("To: $mail_to\n");
$smtp->datasend("From: $mail_from\n");
$smtp->datasend("Subject: $subject\n");
$smtp->datasend("\n");
$smtp->datasend($message);
$smtp->dataend();
$smtp->quit;
}
######################################################################
sub get_date{
# format: std,apache,apache-error,bru
# day: null==today, number is the days that should be subtracted from today
#
# n days ago inspiration..
# http://www.experts-exchange.com/Programming/Programming_Platforms/Unix_Programming/Q_20812482.html
#
my ($format,$day) = @_;
if(! defined($day)){$day=0;}
my @month_short = ("Jan","Feb","Mar","Apr","May","Jun",
"Jul","Aug","Sep","Oct","Nov","Dec");
my ($sec,$min,$hours,$mday,$mon,$year);
if ($day<0){
($sec,$min,$hours,$mday,$mon,$year) = localtime((timelocal(localtime)+(abs($day)*86400)));
}
else{
($sec,$min,$hours,$mday,$mon,$year) = localtime((timelocal(localtime)-($day*86400)));
}#fi
## Set the global year.
$global_year = ($year+1900);
my $value;
OPTION: {
if($format eq "std"){ $value = "$month_short[$mon]" . " ";
$value .= " " if ($mday < 10);
$value .= "$mday";
last OPTION;
}#fi
if($format eq "apache") { ($mday < 10) ? $value = "0" : $value = "";
$value .= "$mday/$month_short[$mon]/". $global_year;
last OPTION;
}#fi
if($format eq "apache-error") { $value = get_date("std",$day);
last OPTION;
}#fi
if($format eq "bru") { $value = $global_year . ($mon+1);
($mday < 10) ? $value .= "0$mday" : $value .= "$mday";
last OPTION;
}#fi
if($format eq "smb") { $value = $global_year."/".($mon+1)."/$mday";
last OPTION;
}#fi
if($format eq "wtmp") { $value = "$month_short[$mon]" . " ";
$value .= " " if ($mday < 10);
$value .= "$mday";
last OPTION;
}#fi
}#:NOITPO
$value;
}
######################################################################
sub mail_samba_logs{
my ($file_base) = @_;
my $yesterday = get_date("smb",2);
my ($result, $keep_flag,$count);
for my $file (<$file_base*>){
print " processing $file ..." if($verbose);
if($file =~ /gz/){
open (IN,"/bin/gunzip -c $file|") or die "Could not open $file for reading!\n";
@_=<IN>;
close(IN);
$count = grep /$yesterday/, @_;
if ($count > 0){
$result .= "\n$file\n##################################################\n";
$keep_flag = 0 ;
for my $line (@_){
if ($line =~ /$yesterday/){$result.= $line; $keep_flag=1;}
else{
if(($keep_flag > 0) and ($line =~ /^\[$global_year/)){$keep_flag=0;}
else{$result .= $line;}
}#fi
}#rof
}#fi
}
else{
open (IN,"$file") or die "Could not open $file for reading!\n";
@_=<IN>;
close(IN);
$count = grep /$yesterday/, @_;
if ($count > 0){
$result .= "\n$file\n##################################################\n";
$keep_flag = 0 ;
for my $line (@_){
if ($line =~ /$yesterday/){$result.= $line; $keep_flag=1;}
else{
if(($keep_flag > 0) and ($line =~ /^\[$global_year/)){$keep_flag=0;}
else{$result .= $line;}
}#fi
}#rof
}#fi
}#fi
print " done.\n" if($verbose);
}#rof
$result;
}
######################################################################
sub mail_wtmp_logs{
my ($file_base) = @_;
my $yesterday = get_date("wtmp",1);
my ($count,$result);
for my $file (<$file_base*>){
print " processing $file ..." if($verbose);
open(IN, "$last_command $file|") or die "Could not open $file with $last_command !\n";
@_=<IN>;
close(IN);
$count = grep /$yesterday/, @_;
if($count > 0){
$result .= "\n$file\n##################################################\n";
$result .= $_ for (grep /$yesterday/, @_);
}#fi
print " done.\n" if($verbose);
}#rof
$result;
}
syntax highlighted by Code2HTML, v. 0.9.1
Return to mail-logs page