#!/usr/local/bin/pike -w
#pragma strict_types
typedef function(array(int | string), void | int : void)
CLcallback; // just to show off ;-)
int main(int ac, array(string) av)
{
Report rep = Report();
array(string) args;
CLcallback line_cb;
function(string : void) output;
if( equal(args = av - ({ "-d", "--debug" }), av ) )
{
line_cb = rep->add;
output = rep->output;
}
else
{
line_cb = debug_cb;
output = lambda(string s) { write("DEBUG: logfile = %s\n", s); };
}
if(sizeof(args)<2)
{
werror("Usage: %s [ --debug ] logfile1 [ logfile2 ... ]\n", basename(args[0]));
return 1;
}
int ret = 0;
foreach(args[1..], string fname)
{
rep->clear();
if(CommonLog.read(line_cb, fname) )
output(fname);
else
(werror("Failed to read logfile %s\n", fname), ret = 2);
}
return ret;
}
void debug_cb(array(int | string) data, void | int offset)
{
write("data = %O\noffset = %d\n======================\n", data, offset);
}
class Report
{
mapping(int:int) codes = ([]), four_o_fours = ([]);
void clear() { codes = ([]), four_o_fours = ([]); }
void add(array(int | string) data, void | int offset)
{
codes[data[13]]++;
if(data[13]==404)
four_o_fours[data[11]]++;
}
void output(string file)
{
int total = (int)`+(@values(codes));
write("Reply status code frequencies in logfile %s :\n"+
"CODE\tHOWMANY\tPERCENTAGE\n"+"="*60+"\n", file);
foreach(sort(indices(codes)), int code)
write("%d :\t%d\t%f %%\n", code, codes[code], (((float)codes[code])/total)*100.0);
write("TOTAL:\t%d\n\n", total);
write("Top-10 \"404\" requests:\nTimes\tPath\n"+"="*60+"\n");
array paths, tallies;
[ paths, tallies ] = ({ indices(four_o_fours), values(four_o_fours) });
sort(tallies, paths);
[ paths, tallies ] = map( ({ paths, tallies }), reverse );
for(int i=0;i<min(10,sizeof(tallies));i++)
write("%d\t%s\n", tallies[i], paths[i]);
write("="*60+"\nFile %s : report complete\n\n", file);
}
}