#!/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); } }