It deals with specific log files (ie. error log files) and folders containing log files (ie. Traxis or AXS).
Without variables the script just prints a dropdown menu, showing total filesize for all monitored files and folders. Selecting a file will show you the last x number of lines from that file, selecting a folder will show you the filesizes of all logs in that folder.
If either a file, a folder or the combination becomes too large, an optional warning message is printed.
In default mode it will open your first selection in a new window, so you can insert the dropdown menu in your regular 'workstartpage' where you may have your other daily chores tools.
I'd be interested to hear your comments if you try it.
Disclaimer: It works, that's all I claim. Don't know nothing about strict perl, or optimal efficiency.
[perl]
#!/usr/local/bin/perl
## DGEEKWARE LogViewer
## Made by Damian Doyle, damian at 1stekeuze.nl
## 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.
&GetVariables;
$version = "v1.002";
################## CONFIGURATION ####################
# full path to this script (example path and filename, substitute by your own path and filename)
$thisscript = "/cgi-bin/tools/thisfile.cgi";
### FILES TO MONITOR ########
#(these are example paths and names, substitute by your paths and names)
%files = (
"Name1" => "/usr/local/etc/httpd/logs/error_log" ,
"Name2" => "/usr/local/etc/httpd/vhosts/name2/logs/error_log",
"Name3" => "/usr/local/etc/httpd/vhosts/name3/logs/error_log",
"Name4" => "/usr/local/etc/httpd/vhosts/name4/logs/error_log",
"Name5" => "/usr/local/etc/httpd/vhosts/name5/logs/error_log",
"Name6" => "/usr/local/etc/httpd/vhosts/name6/logs/error_log",
);
### FOLDERS TO MONITOR ##########
# where are the folders you want to monitor located ?
# (these are example paths and names, substitute by your paths and names)
%folders = (
"Traxis" => "/usr/local/etc/httpd/cgi-bin/traxis/logs/" ,
"AXS" => "/usr/local/etc/httpd/cgi-bin/axs" ,
);
# what is the extension of the files you want to monitor ? Set extension for each folder name in %logextensions
#(these are example extensions, substitute by your own extensions)
%logextensions = (
"Traxis" => "log",
"AXS" => "txt",
)
;
# set number of lines you want to show
$LINENUMBER = 10;
# number of rows to use for textarea where you read the logs
$ROWLINES = 20;
# open items in new window first time ? (comment to open in same window right away)
$newwindow = 1;
# Messagesystem (comment to disable)
$alarmsystem = 1;
#trigger filesize warning at how many Kb ?
$largesize = 100;
# trigger folder size warning at how many Mb ?
$largefoldersize = "20";
# all monitored logs together should not be more then how many Mb ?
$maxsize = "50";
################## END CONFIGURATION, NO NEED TO CHANGE ANYTHING BELOW ####################
# see what files we have
foreach $name (keys %files) {
# check size
&Size;
# use warning message system ?
if ($alarmsystem) {
if($KB{"$name"} > $largesize)
{ $alarmmessage .= "<font size=2 color=red face=verdana>$name <b>$KB{$name} Kb</b></font><br>";}
}
if($Variables{'SHOW'} eq "$name"){
$file = $files{"$name"};
}
} # ok got it, now check folders
foreach $foldername (keys %folders) {
&Folder;
}
if ($Variables{SHOWALL} ¦¦ $Variables{FOLDER} ¦¦ $Variables{SHOW}) {undef $newwindow;}
&printHeader;
if ($Variables{SHOWALL}) {
foreach $name (keys %files) {
$file = $files{"$name"};
&OpenFile;
$nicename = ucfirst($name);
print "<br><b>$nicename</b> $KB{$name} Kb<br>";
&PrintLOG;
}
}
if ($Variables{FOLDER}) {
&ShowFolder;
}
if ($Variables{SHOW}) {
&OpenFile;
$name = "$Variables{SHOW}";
$nicename = ucfirst($name);
print "<br><b>$nicename</b> $KB{$name} Kb<br>";
&PrintLOG;
}
&printFooter;
#####END OF PROGRAM#####
sub OpenFile{
if (open (OPENFILE, $file))
{
@array=<OPENFILE>;
foreach (@array){$lines++;}
$start=$lines-$LINENUMBER;
if ($start<0){$start=0;}
for ($i=$start; $i<$lines; $i++)
{$printme .= "$i $array[$i]";}
}
close OPENFILE;
}
sub PrintLOG {
if($printme ne "") {
$output = "<textarea cols=100 rows=$ROWLINES>$printme</textarea>";
print "$output"; }
else {print "File has no content.."; }
undef $printme;
undef $lines;
}
sub Size {
$hoegroot = -s $files{"$name"};
$KB = $hoegroot/1024;
$MB = $hoegroot/1048576;
$KB{"$name"} = sprintf("%.1f",$KB);
$totalsize = $totalsize + $MB;
undef $KB;
undef $MB;
}
sub Folder {
foreach $log_extension_name (keys %logextensions) {
if ($log_extension_name eq "$foldername") {
$extensionmatch = $logextensions{"$log_extension_name"};
}
}
opendir(DIR, $folders{"$foldername"}) or &ERROR("can't opendir $folder:<br> $!");
while (defined($folderfile = readdir(DIR))) {
if ($folderfile =~ /(.*)\.$extensionmatch/) {
$countfolderfile++;
$folderhoegroot = -s "$folders{$foldername}/$folderfile";
$totalhoegroot = $folderhoegroot + $totalhoegroot;
}
}
closedir(DIR);
$totalhoegroot = $totalhoegroot/1048576;
$totalhoegroot{"$foldername"} = sprintf("%.1f",$totalhoegroot);
$totalsize = $totalsize + $totalhoegroot;
$totalsize = sprintf("%.1f",$totalsize);
$countfolderfile{"$foldername"} = "$countfolderfile";
if ($alarmsystem) {
if ($totalhoegroot{"$foldername"} > $largefoldersize)
{ $alarmmessage .= "<font size=2 color=red face=verdana>$foldername <b>$totalhoegroot{$foldername} Mb</b></font><br>";}
}
undef $totalhoegroot;
undef $countfolderfile;
}
sub ShowFolder {
$foldername = $Variables{FOLDER};
$folderpath = $folders{"$foldername"};
print "Text files in $foldername ( $folders{$foldername} ) are:<br><br>\n";
opendir(FOLDER, $folderpath) or die "Can't open $folderpath: $!";
while( defined ($filesinfolder = readdir FOLDER) ) {
if ($filesinfolder eq "." ¦¦ $filesinfolder eq "..") {next;}
$extensionmatch = $logextensions{"$foldername"};
if ($filesinfolder =~ /(.*)\.$extensionmatch/) {
$filesinfoldersize = -s "$folders{$foldername}/$filesinfolder";
$filesinfoldersize = $filesinfoldersize/1048576;
$filesinfoldersize = sprintf("%.1f",$filesinfoldersize);
$filesinfolder{$foldername} .= "<br>$filesinfolder <b>$filesinfoldersize Mb</b>";
undef $filesinfoldersize;
}
}
closedir(FOLDER);
print "$filesinfolder{$foldername}";
}
sub printHeader {
print "Content-type: text/html\n\n";
if ($alarmsystem) {
if ($totalsize > $maxsize)
{ $alarmmessage .= "<font size=2 color=red face=verdana>
<b>ATTENTION: Clear the logs</b><br>before we crash the server</font>";}
}
print qq~
<html>
<head>
<style type="text/css">
<!--
input {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: xx-small; font-weight: bold;
color: #FFFFFF; background-color: #5D5D5D;
border: 2px #0A0A44 none; cursor: help
}
select {
font-family: Verdana, Arial, Helvetica, sans-serif; font-size: xx-small;
font-weight: bold; color: #FFFFFF;
background-color: #5D5D5D;
border: 2px #0A0A44 none;
cursor: help
}
-->
</style>
<title>DGEEKWARE LogViewer v1.002 - NO GOOD NO REFUNDS -</title>
</head><body bgcolor=#585858 text=#FFFFCC link=#FF9900 vlink=#FF9900 alink=#FF9900>
$alarmmessage
<font face=arial size=2>
<FORM NAME="form" METHOD="post" ACTION="">
~;
if($newwindow) {
print qq~
<SELECT NAME="where" onChange=window.open(document.form.where.options[selectedIndex].value)>
~;
}
else {
print qq~
<SELECT NAME="where" onChange=self.location.href=self.document.form.where.options[selectedIndex].value>
~;
}
print "<option selected>View logs $totalsize Mb</option>";
print "<option value=\"$thisscript?SHOWALL=1\"$target>Show All</option>";
foreach $foldername (sort keys %folders) {
$nicefolder = ucfirst($foldername);
print qq~
<option value="$thisscript?FOLDER=$foldername">
$nicefolder $totalhoegroot{"$foldername"} Mb, $countfolderfile{"$foldername"} logs
</option>
~;
}
foreach $name (sort keys %files) {
$nicename = ucfirst($name);
print qq~
<option value="$thisscript?SHOW=$name">$nicename $KB{"$name"} Kb</option>
~;
}
print "</select></FORM>";
}
sub printFooter {
print "</body></html>";
}
sub ERROR {
my($ERROR_MESSAGE) = @_;
print qq¦
<HTML>
<HEAD>
<TITLE> Error</TITLE>
</HEAD>
<BODY BGCOLOR=azure>
<table width="80%" border="1" cellspacing="5" cellpadding="5" align="center">
<tr>
<td>
<div align="center"><font face="Verdana, Arial, Helvetica, sans-serif" size="4"><font size="3">
<b>Error
Occurred...</b></font></font></div>
</td>
</tr>
<tr>
<td bgcolor="#CCCCCC"><font color="maroon">
<div align="center"><font color="#0000FF" face="Verdana, Arial, Helvetica, sans-serif" size="2"><b>
<font color="navy"><br>
<br>
$ERROR_MESSAGE</font></b></font><font face="Verdana, Arial, Helvetica, sans-serif" size="2">
<br>
<br><br>
</font></div>
</font> </td>
</tr>
<tr>
<td bgcolor="azure">
<div align="center"><font color="maroon" face="Verdana, Arial, Helvetica, sans-serif" size="2"><i>
<a href="javascript:history.go(-1)"><font color="#0000FF">Return
to Previous Screen</font></a></font></div>
</td>
</tr>
</table>
</BODY>
</HTML>
¦;
exit 0;
}
sub GetVariables{
undef %Variables;
my($buffer,$name,$value,$encoded_value,$pair);
$Variables{$name} = $Variables{$name};
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
if (length($buffer) < 5) {
$buffer = $ENV{QUERY_STRING};
}
my @pairs=split(/&/,$buffer);
foreach $pair(@pairs) {
($name, $value)=split(/=/,$pair);
$encoded_value = $value;
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][A-F0-9])/pack("C",hex($1))/eg;
if($Variables{$name} eq "") {
$Variables{$name} = $value;
$ENCODED{$name} = $encoded_value;
push (@Fields,$name);
}
elsif($value ne ""){
$Variables{$name} = $Variables{$name}."^^^".$value;
}
}
}
[/perl]
It could be modified to do so. Problem with error logs is they can grow very quickly sometimes, and grow slowly the rest of the time. Sudden fast growing error logs are an indication of trouble, so i like to keep an eye on their size at all times. The thing is I don't want a time based system, nor do I want my logs deleted or moved out of sight automatically when they may contain valuable information. There is not always room for moving either.
Wheter you delete them , rename them, move them, send an email message or print a warning is all easily added/changed in the script. I chose the last because my course of action will often be different when I get the printed message.
Wherever it says $alarmmessage = something, you could refer to another sub which details the action you want taken. Not sure if the script will run with cron without modifications, but if it does you could also email yourself a warning and never look at it.
The main purpose of the tool is to give a quick overview of all current (error) log sizes, second purpose of the tool is quick errorlog viewing without the need to ftp.