00001 #include<string>
00002 #include<iomanip>
00003 #include "cgiClass.h"
00004 #include <sys/types.h>
00005 #include <unistd.h>
00006
00007 #include "ocString.h"
00008
00009 #include "ocTypes.h"
00010 #include "cgiTemplates.h"
00011 #include "ocXML.h"
00012
00013 #include "openLogger.h"
00014 #include "ocFileSys.h"
00015 #include "ocImportParser.h"
00016
00017 typedef map<string,long> cocounts;
00018 typedef map<string,cocounts> aggregates;
00019 typedef map<string,string> lookups;
00020
00021 class summer
00022 {
00023 public:
00024 aggregates aggies;
00025 lookups httpstats;
00026
00027 time_date tstamp;
00028
00029 int ipcol, timecol, tzcol,
00030 uricol, resultcol,
00031 referercol, sizecol,
00032 agentcol, aggregatecol;
00033
00034 string parseFormat;
00035 string printFormat;
00036
00037 string supportResources;
00038
00039
00040 summer():ipcol(0),timecol(3)
00041 ,tzcol(4),uricol(5),resultcol(6)
00042 ,referercol(8),sizecol(7)
00043 ,agentcol(9),aggregatecol(timecol)
00044 ,parseFormat("[%d/%b/%Y:%H:%M:%S")
00045 ,printFormat("%m/%d/%Y")
00046 ,supportResources(".jpg|.gif|.png|.bmp|.css|.js")
00047 {
00048 httpstats["200"]=" OK";
00049 httpstats["301"]=" MOVED_PERMANENTLY";
00050 httpstats["302"]=" FOUND";
00051 httpstats["304"]=" NOT_MODIFIED";
00052 httpstats["400"]=" BAD_REQUEST";
00053 httpstats["401"]=" UNAUTHORIZED";
00054 httpstats["403"]=" FORBIDDEN";
00055 httpstats["404"]=" NOT_FOUND";
00056 httpstats["500"]=" INTERNAL_SERVER_ERROR";
00057 }
00058 ~summer(){;}
00059
00060 bool add( ocFileCols & coldata )
00061 {
00062 bool bret=true;
00063
00064 if( timecol != -1 )
00065 {
00066 tstamp.parse( coldata[timecol].name.c_str(), parseFormat.c_str() );
00067 if( tstamp.year() == 1900) bret=false;
00068 }
00069
00070 string ip = coldata[ipcol].name;
00071
00072 string key;
00073
00074 if( aggregatecol == timecol )
00075 {
00076 key = tstamp.format( printFormat.c_str() );
00077 }
00078 else if( aggregatecol == tzcol )
00079 {
00080 ocString tz = coldata[aggregatecol].name;
00081 key = tz.remove("]");
00082 }
00083 else if( aggregatecol == uricol )
00084 {
00085 ocString uri = coldata[aggregatecol].name;
00086 uri.parse(",");
00087 uri = uri.remainder();
00088 uri = uri.parse("?");
00089 uri = uri.parse(" ");
00090
00091 if( uri.regExMatch( supportResources.c_str()) ) bret=false;
00092 key = uri;
00093 }
00094 else if ( aggregatecol == resultcol )
00095 {
00096
00097 ip += coldata[referercol].name;
00098 key = coldata[aggregatecol].name;
00099 key += httpstats[coldata[aggregatecol].name];
00100 }
00101 else
00102 {
00103 key = coldata[aggregatecol].name;
00104 }
00105
00106 if( bret )
00107 {
00108 aggies[key][ip]++;
00109 }
00110 return bret;
00111 }
00112 bool readFile ( ocString filename, string & filter )
00113 {
00114 char linebuffer[2048];
00115
00116 bool bret = true;
00117 writelog2("filename",filename);
00118
00119 if ( filename.regExMatch("[*]") )
00120 {
00121 writelog2( "found wildcard: ", filename );
00122 filename = filename.remove("*");
00123 string::size_type idx = filename.find_last_of('/');
00124 if( idx != string::npos )
00125 {
00126 string path = filename.substr(0,idx);
00127 writelog2( "path: ", path );
00128 ocString pattern = filename.substr(idx);
00129 writelog2( "pattern: ", pattern );
00130 ocFileSys fs;
00131 if( fs.openDir( path ) )
00132 {
00133 ocDirectory & dir = fs.getDirectoryEntries();
00134 for( int i=0; i<dir.size(); ++i)
00135 {
00136 ocString test = "/";
00137 test += dir[i].name;
00138 if( test.regExMatch( pattern.c_str() ))
00139 {
00140
00141 string fullpath = path;
00142 fullpath += test;
00143 writelog2( "read: ", fullpath );
00144 readFile ( fullpath, filter );
00145 }
00146 }
00147 }
00148 }
00149 }
00150 else
00151 {
00152 ifstream ifile;
00153 ifile.open(filename.c_str());
00154
00155 while( ifile )
00156 {
00157 ocString line;
00158 if( getline(ifile,line ) )
00159 {
00160
00161 line += "\n";
00162 if( filter.length() )
00163 {
00164 if( line.regExMatch(filter.c_str() ) )
00165 {
00166 Agget(line);
00167 writelog2("wrote",line);
00168 }
00169 }
00170 else
00171 {
00172 Agget(line);
00173 writelog2("wrote",line);
00174 }
00175 }
00176 }
00177 writelog("end of file found");
00178 ifile.close();
00179 }
00180 return bret;
00181 }
00182 void Agget( string line )
00183 {
00184
00185 ocFileParser parser;
00186
00187
00188 parser.setCheckQuote(true);
00189 parser.setDelim(" ");
00190 parser.setLineTokens(line.c_str());
00191 parser.parse(true);
00192 ocFileCols & coldata = parser.getCols();
00193 int cols = parser.getColCount();
00194 if(cols) add( coldata );
00195 }
00196
00197 };
00198
00199
00200 long indexIncrement( double in )
00201 {
00202 double lola = log10(abs(in));
00203 double lolita = floor(lola);
00204 double inc = pow( 10.0, lolita );
00205 if( inc < 1 ) inc = 1;
00206 return (long) inc;
00207 }
00208 string scale( int data, int datamax, int pixels )
00209 {
00210 ocString ret;
00211 ret.append( ((data*pixels)/datamax) );
00212 return ret;
00213 }
00214 string toString( long data )
00215 {
00216 ocString ret;
00217 ret.append(data);
00218 return ret;
00219 }
00220
00221 int main( int argc, char ** argv )
00222 {
00223 string logfile, filter, show;
00224 ocString logfiles;
00225 int i = 0;
00226 setuid( 0 );
00227 cgiScript script;
00228
00229
00230
00231 cgiTemplates tmplt;
00232 tmplt.load("adminchart.htmp");
00233 script << tmplt.getParagraph("top");
00234
00235
00236
00237 xmlParser xparser( tmplt.getParagraph("control") );
00238 xparser.parse();
00239 node_vector & xnodes = xparser.nodeList();
00240
00241 for(i=0;i<xnodes.size();i++)
00242 {
00243 xmlNode & node = xnodes[i];
00244 if( node.name == "filter" )
00245 {
00246 filter = node.data;
00247 }
00248 else if( node.name == "logfiles" )
00249 {
00250 logfiles = node.data;
00251 }
00252 else if( node.name == "show" )
00253 {
00254 show = node.data;
00255 }
00256 }
00257
00258
00259 cgiInput & args = script.ClientArguments();
00260 if( args.count("show") ) show = args["show"].c_str();
00261 if( args.count("filter") ) filter = args["filter"].c_str();
00262
00263
00264 ocString heading = tmplt.getParagraph("charttitle");
00265 script << heading.replace("$title",show.c_str() );
00266
00267
00268 summer sums;
00269
00270 if( show == "Time Zone" )
00271 {
00272 sums.aggregatecol = sums.tzcol;
00273 }
00274 else if( show == "Page" )
00275 {
00276 sums.aggregatecol = sums.uricol;
00277 }
00278 else if( show == "Referrer" )
00279 {
00280 sums.aggregatecol = sums.referercol;
00281 }
00282 else if( show == "Request Status" )
00283 {
00284 sums.aggregatecol = sums.resultcol;
00285 }
00286 else if( show == "Browser" )
00287 {
00288 sums.aggregatecol = sums.agentcol;
00289 }
00290
00291 logfile = logfiles.parse(",");
00292 while( logfile.length() )
00293 {
00294 sums.readFile ( logfile, filter );
00295 logfile = logfiles.parse(",");
00296 }
00297
00298 {
00299
00300 ocString label = tmplt.getParagraph("label");
00301 int maxSize = 0;
00302
00303 aggregates::iterator pos;
00304 for( pos=sums.aggies.begin();
00305 pos !=sums.aggies.end();
00306 ++pos )
00307 {
00308 maxSize = pos->second.size() > maxSize ? pos->second.size() : maxSize;
00309 script << label.replace("$label", pos->first.c_str() );
00310 }
00311
00312
00313 script << tmplt.getParagraph("chartdata");
00314 char * tags[] = { "reddata", "greendata", "bluedata" };
00315 int tagMax=3;
00316 int tagEl = 0;
00317
00318 ocString dataEl;
00319 for( pos=sums.aggies.begin();
00320 pos !=sums.aggies.end();
00321 ++pos )
00322 {
00323 dataEl = tmplt.getParagraph(tags[tagEl%tagMax]);
00324 script << dataEl.replace("$num$", scale( pos->second.size(), maxSize, 400 ).c_str())
00325 .replace("$num$", toString(pos->second.size()));
00326 tagEl++;
00327 }
00328
00329
00330 long inc = indexIncrement( maxSize );
00331 script << tmplt.getParagraph("scale");
00332 ocString tick = tmplt.getParagraph("tickmark");
00333 for( long incs=inc; incs<=maxSize; incs+=inc )
00334 {
00335 script << tick.replace("$num$", scale( inc, maxSize, 400 ).c_str() )
00336 .replace("$num$", toString(incs).c_str() ) ;
00337 }
00338 tick = tmplt.getParagraph("ticklabel");
00339 script << tick.replace("$label","Visitors");
00340 }
00341 script << tmplt.getParagraph("end");
00342 return 0;
00343 }
00344