/* Read error log produced by tds and classify queries based on structure */ #include #include #include #include #include #include "lasuite.h" #include #include #include using namespace std; struct ERROR{ int count; // How many time this error was met string sql; string error; ERROR (const string &_error, const string &_sql){ error = _error; sql = _sql; count = 1; } ERROR(){ count = 1; } }; static void classify (const string &error, const string &sql, map &errors) { if (sql.size() > 0){ PARSE p (sql.c_str()); EXPR expr; if (f_main(p,expr)!=-1){ string key = expr.getckey(); map::iterator it = errors.find(key); if (it == errors.end()){ errors[key] = ERROR(error,sql); }else{ it->second.count++; } }else{ unsigned last = p.getlastpos(); string sqltmp(sql); strip_end (sqltmp); int len = sqltmp.size()-last; if (len > 30) len = 30; string tmp; if (len > 0){ tmp = string(sqltmp.c_str()+last,len); }else{ tmp = "EOL"; } tlmp_error ("Classify error: %s\n%s\n",tmp.c_str(),sqltmp.c_str()); } } } int main (int argc, char *argv[]) { glocal int ret = -1; glocal const char *formatsql = "./formatsql -i"; glocal bool reformat = false; glocal const char *match = NULL; glocal.ret = (argc,argv); setproginfo ("","0.0","..."); setarg ('r',"reformat","Reformat the SQL using the formatsql program",glocal.reformat,false); setarg (' ',"formatsql","Program to use for the reformating",glocal.formatsql,false); setarg ('m',"match","Process only query having this work in it",glocal.match,false); glocal int ret = 0; glocal map errors; parser_initfunctions(); parser_inittokens(); for (int i=0; i(argv[0],true); if (strncmp(line,"***",3)==0){ if (glocal.match == NULL || strcasestr(glocal.sql.c_str(),glocal.match)!=NULL){ classify (glocal.error,glocal.sql,glocal.errors); } glocal.error = line+3; glocal.sql.clear(); }else if (strcmp(line,"!")==0){ glocal.sql.clear(); }else{ glocal.sql += string(" ") + line; } return 0; tlmp_error ("No file %s\n",fname); glocal.ret = -1; if (glocal.match == NULL || strcasestr(glocal.sql.c_str(),glocal.match)!=NULL){ classify (glocal.error,glocal.sql,glocal.errors); } } int i=1; for (map::iterator it=glocal.errors.begin(); it != glocal.errors.end(); it++,i++){ printf ("%03d-%05d-%s\n",i,it->second.count,it->second.error.c_str()); const char *sql = it->second.sql.c_str(); if (glocal.reformat){ fflush (stdout); FILE *fout = popen (glocal.formatsql,"w"); if (fout != NULL){ fprintf (fout,"%s",sql); pclose (fout); } }else{ printf (" %s\n",sql); } } return glocal.ret; return glocal.ret; }