00001 #include<string>
00002 #include<iomanip>
00003 #include "cgiClass.h"
00004 #include <sys/types.h>
00005 #include <unistd.h>
00006 #include "connectstring"
00007 #include "ocString.h"
00008
00009 #include "ocTypes.h"
00010 #include "cgiTemplates.h"
00011 #include "ocXML.h"
00012 #include "read_base.hpp"
00013 #include <set>
00014
00015 typedef vector<string> tagVec;
00016
00017 typedef map<string,long> cocounts;
00018 typedef map<string,string> lookups;
00019 typedef set<string> visitors;
00020 typedef map<string,visitors> aggregates;
00021 typedef vector<string> mapinserts;
00022
00023 class reporter: public read_base
00024 {
00025 public:
00026 long maxCount;
00027 cocounts coco;
00028 aggregates aggies;
00029 lookups httpstats;
00030 ocString pageClause;
00031 ocString refererClause;
00032 ocString dailyPageClause;
00033 ocString monthlyPageClause;
00034 ocString dailyVisitsClause;
00035 ocString monthlyVisitsClause;
00036 ocString byBrowserClause;
00037 ocString byRequestStatusClause;
00038 ocString byDetailClause;
00039 string log_file;
00040
00041 string show;
00042
00043
00044 tagVec tags;
00045 int tagMax;
00046
00047
00048 reporter():read_base(),maxCount(0),tagMax(3)
00049 {
00050 httpstats["200"]=" OK";
00051 httpstats["301"]=" MOVED_PERMANENTLY";
00052 httpstats["302"]=" FOUND";
00053 httpstats["304"]=" NOT_MODIFIED";
00054 httpstats["400"]=" BAD_REQUEST";
00055 httpstats["401"]=" UNAUTHORIZED";
00056 httpstats["403"]=" FORBIDDEN";
00057 httpstats["404"]=" NOT_FOUND";
00058 httpstats["500"]=" INTERNAL_SERVER_ERROR";
00059 tags.push_back("reddata");
00060 tags.push_back("greendata");
00061 tags.push_back("bluedata");
00062
00063 refererClause = "select Referer, count(*)"
00064 "from Site_History where log_file = '$log_file$' and Referer not like '%//$SVR$%' "
00065 "group by Referer order by Referer";
00066
00067 pageClause = "select Resource_Requested, count(*)"
00068 "from Site_History where log_file = '$log_file$' "
00069 "group by Resource_Requested order by Resource_Requested";
00070
00071 dailyPageClause = "select date_format(Request_Time,'%m/%d/%y'), count(*)"
00072 "from Site_History where log_file = '$log_file$' "
00073 "group by date_format(Request_Time,'%m/%d/%y') order by Request_Time desc";
00074
00075 monthlyPageClause = "select date_format(Request_Time,'%m/%y'), count(*)"
00076 "from Site_History where log_file = '$log_file$' "
00077 "group by date_format(Request_Time,'%m/%y') order by Request_Time desc";
00078
00079 dailyVisitsClause = "select distinct date_format(Request_Time,'%m/%d/%y'), Remote_Host "
00080 "from Site_History where log_file = '$log_file$' "
00081 "order by Request_Time desc";
00082
00083 monthlyVisitsClause = "select distinct date_format(Request_Time,'%m/%y'), Remote_Host "
00084 "from Site_History where log_file = '$log_file$' "
00085 "order by Request_Time desc";
00086
00087 byBrowserClause = "select User_Agent, count(*)"
00088 "from Site_History where log_file = '$log_file$' "
00089 "group by User_Agent order by User_Agent";
00090
00091 byRequestStatusClause = "select Original_Status, count(*)"
00092 "from Site_History where log_file = '$log_file$' "
00093 "group by Original_Status order by Original_Status";
00094 byDetailClause = "select Remote_Host, Request_Time, Method, Resource_Requested, Referer, User_Agent "
00095 "from Site_History where where log_file = '$log_file$' and Remote_Host = '$calling$' "
00096 "order by Request_Time desc";
00097 ifstream setUp( "siteStatSetup.xml" );
00098 if( setUp )
00099 {
00100 xmlParser parser( &setUp );
00101 parser.parse();
00102 node_vector::iterator pos = parser.findFirstNodeByName( "logfile" );
00103 if( pos != parser.nodeList().end() )
00104 {
00105 log_file = pos->attr["name"];
00106 }
00107 }
00108 }
00109 ~reporter(){;}
00110 void referer( cgiScript & script, cgiTemplates & tmplt )
00111 {
00112
00113 string thisSvr = script.ServerName().c_str();
00114
00115 generic( script, tmplt, refererClause.replace("$log_file$",log_file).replace("$SVR$", thisSvr ) );
00116 }
00117 void pages( cgiScript & script, cgiTemplates & tmplt )
00118 {
00119 generic( script, tmplt, pageClause.replace("$log_file$",log_file) );
00120 }
00121 void monthly_pages( cgiScript & script, cgiTemplates & tmplt )
00122 {
00123 generic( script, tmplt, monthlyPageClause.replace("$log_file$",log_file) );
00124 }
00125 void daily_pages( cgiScript & script, cgiTemplates & tmplt )
00126 {
00127 generic( script, tmplt, dailyPageClause.replace("$log_file$",log_file) );
00128 }
00129 void browsers( cgiScript & script, cgiTemplates & tmplt )
00130 {
00131 generic( script, tmplt, byBrowserClause.replace("$log_file$",log_file) );
00132 }
00133 void request_status( cgiScript & script, cgiTemplates & tmplt )
00134 {
00135 generic( script, tmplt, byRequestStatusClause.replace("$log_file$",log_file), &httpstats );
00136 }
00137 void generic( cgiScript & script, cgiTemplates & tmplt , string sql, lookups * plk = 0 )
00138 {
00139
00140 mapinserts ordr;
00141 string sep = tmplt.getParagraph("chartdata");
00142 ocString label = tmplt.getParagraph("label");
00143 bool open = rs.open( sql );
00144 if( !open ) script << "<h3>No Data</h3><!-- " << sql << " -->" << endl;
00145 while( open )
00146 {
00147 string label = rs.getField(0).format();
00148 if( plk )
00149 {
00150 lookups::iterator pos = plk->find(label);
00151 if( pos != plk->end() )
00152 {
00153 label = pos->second;
00154 }
00155 }
00156 long count = atol(rs.getField(1).format().c_str());
00157 ordr.push_back(label);
00158 coco[label] = count;
00159 maxCount = maxCount>count?maxCount:count;
00160 open = rs.next();
00161 }
00162
00163 ocString dataEl;
00164 long inc = indexIncrement( maxCount );
00165 for( int idx=0; idx<ordr.size(); idx++ )
00166 {
00167 string lval = ordr[idx];
00168 script << label.replace("$label", lval );
00169 script << sep;
00170 dataEl = tmplt.getParagraph(tags[idx%tagMax]);
00171 script << dataEl.replace("$num$", scale( coco[lval], maxCount, 500 ).c_str())
00172 .replace("$num$", toString(coco[lval]));
00173 }
00174 tickMarks(script, tmplt);
00175 }
00176
00177 void daily_visitors( cgiScript & script, cgiTemplates & tmplt )
00178 {
00179 rollup(script, tmplt,dailyVisitsClause.replace("$log_file$",log_file) );
00180 }
00181 void monthly_visitors( cgiScript & script, cgiTemplates & tmplt )
00182 {
00183 rollup(script, tmplt,monthlyVisitsClause.replace("$log_file$",log_file) );
00184 }
00185 void detail( cgiScript & script, cgiTemplates & tmplt)
00186 {
00187 cgiInput & args = script.ClientArguments();
00188 if( args.count("caller") )
00189 {
00190 string caller = args["caller"];
00191 string sql = byDetailClause.replace("$log_file$",log_file).replace("$calling$", caller);
00192 bool open = rs.open( sql );
00193 if( !open ) script << "<h3>No Data</h3><!-- " << sql << " -->" << endl;
00194 while( open )
00195 {
00196
00197
00198 open = rs.next();
00199 }
00200 }
00201 }
00202 void rollup( cgiScript & script, cgiTemplates & tmplt , string sql)
00203 {
00204
00205 mapinserts ordr;
00206 string sep = tmplt.getParagraph("chartdata");
00207 ocString label = tmplt.getParagraph("label");
00208 bool open = rs.open( sql );
00209 if( !open ) script << "<h3>No Data</h3><!-- " << sql << " -->" << endl;
00210 while( open )
00211 {
00212 string label = rs.getField(0).format();
00213 string aggie = rs.getField(1).format();
00214 if( aggies.find(label) == aggies.end() )
00215 {
00216 ordr.push_back(label);
00217 }
00218
00219 visitors & lk = aggies[label];
00220 addAgregate( lk, aggie );
00221 maxCount = maxCount>lk.size()?maxCount:lk.size();
00222
00223 open = rs.next();
00224 }
00225
00226 ocString dataEl;
00227 long inc = indexIncrement( maxCount );
00228 for( int idx=0; idx<ordr.size(); idx++ )
00229 {
00230 string lval = ordr[idx];
00231 long count = aggies[ lval ].size();
00232 script << label.replace("$label", lval );
00233 script << sep;
00234 dataEl = tmplt.getParagraph(tags[idx%tagMax]);
00235 script << dataEl.replace("$num$", scale( count, maxCount, 500 ).c_str())
00236 .replace("$num$", toString(count));
00237 }
00238 tickMarks(script, tmplt);
00239 }
00240
00241 void addAgregate( visitors & lk, string val )
00242 {
00243 if( lk.find(val) == lk.end() )
00244 {
00245 lk.insert( val );
00246 }
00247 }
00248 void tickMarks( cgiScript & script, cgiTemplates & tmplt )
00249 {
00250 long inc = indexIncrement( maxCount );
00251 script << tmplt.getParagraph("scale");
00252 ocString tick = tmplt.getParagraph("tickmark");
00253 for( long incs=inc; incs<=maxCount; incs+=inc )
00254 {
00255 script << tick.replace("$num$", scale( inc, maxCount, 500 ).c_str() )
00256 .replace("$num$", toString(incs).c_str() ) ;
00257 }
00258 tick = tmplt.getParagraph("ticklabel");
00259 script << tick.replace("$label",show);
00260 }
00261
00262 long indexIncrement( double in )
00263 {
00264 double lola = log10(fabs(in));
00265 double lolita = floor(lola);
00266 double inc = pow( 10.0, lolita );
00267 if( inc < 1 ) inc = 1;
00268 return (long) inc;
00269 }
00270 string scale( int data, int datamax, int pixels )
00271 {
00272 ocString ret;
00273 ret.append( ((data*pixels)/datamax) );
00274 return ret;
00275 }
00276 string toString( long data )
00277 {
00278 ocString ret;
00279 ret.append(data);
00280 return ret;
00281 }
00282 };
00283
00284
00285
00286
00287
00288 int main( int argc, char ** argv )
00289 {
00290
00291 cgiScript script;
00292 string show,filter;
00293 cgiTemplates tmplt;
00294 tmplt.load("adminchart.htmp");
00295 script << tmplt.getParagraph("top");
00296
00297
00298 cgiInput & args = script.ClientArguments();
00299 if( args.count("show") ) show = args["show"].c_str();
00300 if( args.count("filter") ) filter = args["filter"].c_str();
00301
00302
00303 ocString heading = tmplt.getParagraph("charttitle");
00304 script << heading.replace("$title",show.c_str() );
00305
00306
00307
00308 reporter rptr;
00309 rptr.show = show;
00310
00311
00312 if( show == "Daily Pages" )
00313 {
00314 rptr.daily_pages( script, tmplt );
00315 }
00316 else if( show == "Monthly Pages" )
00317 {
00318 rptr.monthly_pages( script, tmplt );
00319 }
00320 else if( show == "Daily Visitors" )
00321 {
00322 rptr.daily_visitors( script, tmplt );
00323 }
00324 else if( show == "Monthly Visitors" )
00325 {
00326 rptr.monthly_visitors( script, tmplt );
00327 }
00328 else if( show == "Page" )
00329 {
00330 rptr.pages( script, tmplt );
00331 }
00332 else if( show == "Referrer" )
00333 {
00334 rptr.referer( script, tmplt );
00335 }
00336 else if( show == "Request Status" )
00337 {
00338 rptr.request_status( script, tmplt );
00339 }
00340 else if( show == "Browser" )
00341 {
00342 rptr.browsers( script, tmplt );
00343 }
00344 else if( show == "detail" )
00345 {
00346 rptr.detail( script, tmplt );
00347 }
00348
00349 script << tmplt.getParagraph("end");
00350 return 0;
00351 }
00352