/* SRG - Squid Report Generator Report by site Copyright 2003 University of Waikato This file is part of SRG. SRG 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. SRG 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 SRG; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "UserReport.h" #include "SiteReport.h" #include "LocationReport.h" #include "srg.h" #include "prototypes.h" SiteReport::~SiteReport() { list::const_iterator iter; for (iter=locations.begin(); iter != locations.end(); iter++) { delete (*iter); } } void SiteReport::process_line(const log_line *line) { if (srg.debug) fprintf(stderr, "In SiteReport::process_line for site '%s'\n", mName); /* Work out the location of this line */ char *location = strdup(line->request->location); LocationReport *theLocation = (LocationReport *)findLocation(location); if (theLocation==NULL) { if (srg.debug) fprintf(stderr, "Site Location not found in %s - " "creating %s\n", mName, location); /* The location does not exist. Create it. */ theLocation = new LocationReport(location); locations.push_back(theLocation); } /* Process the line */ theLocation->process_line(line); free(location); } void SiteReport::generate_report(const char *basename, const char *user) { char *t = NULL; char *basepath = NULL; char *filename = NULL; FILE *outfile = NULL; /* Create the output filename */ t = md5this(mName); asprintf(&basepath, "%s/%s", basename, t); free(t); asprintf(&t, "%s/%s", srg.outputDir, basepath); if (mkdir(t, 0755) == -1 && errno != EEXIST) { fprintf(stderr, "Error (%s) creating directory in " "site report for %s: %s\n", strerror(errno), mName, t); exit(1); } if (srg.debug) fprintf(stderr, "Creating site report in %s\n", t); free(t); /* Create the index file */ asprintf(&filename, "%s/%s/%s", srg.outputDir, basepath, srg.indexfname); outfile = fopen(filename, "w"); if(outfile==NULL) { fprintf(stderr,"SiteReport: Cannot open output file: %s\n", filename); exit(1); } free(filename); /* Header & Title */ if (srg.groupBy > 0) { html_header(outfile, "../../../"); } else { html_header(outfile, "../../"); } fprintf(outfile, "\n", version, HOME_URL); /* Misc Stats */ fprintf(outfile, "
"); fprintf(outfile, "", localtime(&srg.endTime)->tm_mday, month_names[localtime(&srg.endTime)->tm_mon], localtime(&srg.endTime)->tm_year+1900); if (srg.groupBy > 0) { fprintf(outfile, "", user); } fprintf(outfile, " %s", mName, mName); fprintf(outfile, "
Period:%d %s %d", localtime(&srg.startTime)->tm_mday, month_names[localtime(&srg.startTime)->tm_mon], localtime(&srg.startTime)->tm_year+1900); fprintf(outfile, " - %d %s %d
Group:%s
Site:
"); /* Notices Row */ fprintf(outfile, "
" " 
\n"); /* Main Table */ fprintf(outfile, "
" ""); if (srg.showtimes) fprintf(outfile, ""); if (srg.showrates) fprintf(outfile, ""); fprintf(outfile, "\n"); list::const_iterator iter; summary_info locationstats; float percentin = 0; float percentout = 0; float timespent = 0; float bytespercent = 0; summary_info thissitestats = getStats(); float hitspercentot = 0; float missespercentot = 0; int rows = 0; /* Initialise the Summary Stats Structure */ locationstats.connects = 0; locationstats.bytesTransferred = 0; locationstats.hits = 0; locationstats.misses = 0; locationstats.bytesHit = 0; locationstats.bytesMissed = 0; locationstats.timeSpent = 0; locationstats.deniedHits = 0; locations.sort(LessByBytesTransferred()); for (iter=locations.begin(); iter != locations.end(); iter++) { locationstats = (*iter)->getStats(); if (srg.locationStats) { (*iter)->generate_report(basepath, user, mName); } char *location = (*iter)->getName(); if (locationstats.hits+locationstats.misses == 0) { percentin = -1; percentout = -1; } else { hitspercentot += percentin = (float)(100*locationstats.hits) / (locationstats.hits+locationstats.misses); missespercentot += percentout = (float)(100*locationstats.misses) / (locationstats.hits+locationstats.misses); } if (thissitestats.timeSpent == 0) { timespent = 100; } else { timespent = (float)(100*locationstats.timeSpent) / thissitestats.timeSpent; } if (thissitestats.bytesTransferred == 0) { bytespercent = 100; } else { bytespercent = (float) (100*locationstats.bytesTransferred) / thissitestats.bytesTransferred; } fprintf(outfile, "", ((rows%2)==0) ? " class=\"highlightRow\"" : ""); char *locationhref = NULL; char *locationname = NULL; if (srg.locationStats) { /* Link to location report */ t = md5this(location); asprintf(&locationhref, "%s.%s", t, srg.usephp ? "php" : "html"); free(t); char tmpname[41]; snprintf(tmpname, 40, "%s", location); asprintf(&locationname, "%s%s", tmpname, (strlen(location)>40) ? "…" : ""); } else { asprintf(&locationhref, "http://%s%s", mName, (strcasecmp(location, "^index^")==0) ? "/" : location); char tmpname[41]; snprintf(tmpname, 40, "%s", location); asprintf(&locationname, "%s%s", tmpname, (strlen(location)>40) ? "…" : ""); } fprintf(outfile, "", locationhref, locationname); free(locationhref); free(locationname); t = FormatOutput(locationstats.connects); fprintf(outfile, "", t); free(t); t = FormatOutput(locationstats.bytesTransferred); fprintf(outfile, "", t); free(t); fprintf(outfile, "", bytespercent); if (percentin != -1) { fprintf(outfile, "" "", percentin, percentout); } else { fprintf(outfile, "" ""); } if (srg.showtimes) { t = FormatOutput(locationstats.timeSpent); fprintf(outfile, "" "", timespent, t); free(t); } if (srg.showrates) { if (locationstats.timeSpent == 0) { fprintf(outfile, ""); } else { fprintf(outfile, "", (float)locationstats.bytesTransferred/ (float)locationstats.timeSpent); } } fprintf(outfile, "\n"); rows++; } if (rows == 0) { percentin = percentout = -1; } else { percentin = hitspercentot / rows; percentout = missespercentot / rows; } /* Totals Row */ fprintf(outfile, ""); t = FormatOutput(thissitestats.connects); fprintf(outfile, "", t); free(t); t = FormatOutput(thissitestats.bytesTransferred); fprintf(outfile, "", t); free(t); fprintf(outfile, ""); if (percentin != -1) { fprintf(outfile, "", percentin, percentout); } else { fprintf(outfile, ""); } if (srg.showtimes) { t = FormatOutput(thissitestats.timeSpent); fprintf(outfile, "", t); free(t); } if (srg.showrates) { if (locationstats.timeSpent == 0) { fprintf(outfile, ""); } else { fprintf(outfile, "", (float)thissitestats.bytesTransferred/ (float)thissitestats.timeSpent); } } fprintf(outfile, "\n\t
LOCATIONHITSBYTES" "BYTES %%HITMISSTIME%%TIME(ms)RATE (kB/s)
" "%s%s%s%2.2f%%%2.2f%%%2.2f%%--%2.2f%%%s" "-" "%2.0f
Totals:%s%s100%%" "%2.2f%%%2.2f%%" "--100%%%s-%2.0f

"); if (srg.usephp && srg.authenticate) { fprintf(outfile, "\n\t"); } fprintf(outfile, "\n\t
Back to sites page", srg.indexfname); /* Finish off the HTML */ if (srg.groupBy > 0) { html_footer(outfile, "../../../"); } else { html_footer(outfile, "../../"); } fclose(outfile); free(basepath); } void SiteReport::updateStats() { zeroStats(); list::const_iterator iter; for (iter=locations.begin(); iter != locations.end(); iter++) { summary_info locationStats = (*iter)->getStats(); stats.connects += locationStats.connects; stats.bytesTransferred += locationStats.bytesTransferred; stats.timeSpent += locationStats.timeSpent; stats.hits += locationStats.hits; stats.bytesHit += locationStats.bytesHit; stats.misses += locationStats.misses; stats.bytesMissed += locationStats.bytesMissed; stats.deniedHits += locationStats.deniedHits; } } LocationReport *SiteReport::findLocation(char * location) { list::const_iterator iter; // Iterate through list and compare each element. for (iter=locations.begin(); iter != locations.end(); iter++){ if(strcasecmp((*iter)->getName(),location) ==0) return (LocationReport *)(*iter); } return NULL; } // Get statistics about this report summary_info SiteReport::getStats() { summary_info returnInfo; updateStats(); returnInfo = stats; return returnInfo; }