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