00001 #include <stdio.h>
00002 #include <errno.h>
00003 #include <unistd.h>
00004 #include <string.h>
00005 #include <stdlib.h>
00006 #include <sys/types.h>
00007 #include <sys/stat.h>
00008 #include <time.h>
00009 #include <sys/time.h>
00010 #include <utime.h>
00011
00012 #define MAX_LOGFILES 10
00013 #define LOGLINES 400
00014
00015 #define DATA_1 "/online/tonko/log_content_old.html"
00016 #define DATA_2 "/online/tonko/log_content.html"
00017 #define TOUCH "/online/tonko/log_touch.html"
00018
00019
00020 int parseLog(char *b, u_int file, u_int line) ;
00021 int dumpLines(void) ;
00022
00023 static char buff[1024] ;
00024 static struct stat statb ;
00025
00026 #ifndef PROJDIR
00027 #warning "PROJDIR not defined! Assuming /RTS"
00028 #define PROJDIR "/RTS"
00029 #endif
00030
00031
00032 #define LOG_SUFFIX ""
00033
00034 static char logfiles[MAX_LOGFILES][128] = {
00035 PROJDIR"/log/rts.log"LOG_SUFFIX,
00036 PROJDIR"/log/trigger.log"LOG_SUFFIX,
00037 PROJDIR"/log/evp.log"LOG_SUFFIX,
00038 PROJDIR"/log/det.log"LOG_SUFFIX,
00039 PROJDIR"/log/daq.log"LOG_SUFFIX,
00040 PROJDIR"/log/tpx.log"LOG_SUFFIX,
00041 PROJDIR"/log/esb.log"LOG_SUFFIX,
00042
00043 } ;
00044
00045
00046
00047 static FILE *files[MAX_LOGFILES] ;
00048
00049 static int oldsizes[MAX_LOGFILES] ;
00050
00051
00052 static char data_preamble[] = { " \
00053 <!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"> \
00054 <html> \
00055 <head> \
00056 <link rel=\"stylesheet\" type=\"text/css\" href=\"daq.css\"> \
00057 <title>STAR DAQ Logging</title> \
00058 </head> \
00059 <body> \
00060 " };
00061
00062
00063
00064 static struct logline {
00065 u_int sec ;
00066 char tm[24] ;
00067 u_int day ;
00068
00069 u_int repeat ;
00070
00071 u_int file ;
00072 u_int seq ;
00073
00074 char node[10] ;
00075 char rb[10] ;
00076
00077 char sev[32] ;
00078
00079 char task[16] ;
00080 char src[128] ;
00081 u_int line ;
00082
00083 char msg[256] ;
00084 } loglines[LOGLINES] ;
00085
00086 int last_logline = 0 ;
00087
00088
00089 int main(int argc, char *argv[])
00090 {
00091 char *fret ;
00092 int ret ;
00093 int i ;
00094 int data_in, new_lines ;
00095 u_int last_flush ;
00096 u_int lines[MAX_LOGFILES] ;
00097
00098
00099 #ifdef OLD_TEST
00100 for(i=0;i<MAX_LOGFILES;i++) {
00101 printf("%3d: %d %c -%s-\n",i,logfiles[i][0],logfiles[i][0],logfiles[i]) ;
00102 }
00103 return 0 ;
00104 #endif
00105
00106 i = 0 ;
00107
00108
00109 FILE *ff = fopen(TOUCH,"w") ;
00110 fprintf(ff,"%u\n",(u_int)time(NULL)) ;
00111 fclose(ff) ;
00112
00113 while(logfiles[i][0] != 0) {
00114
00115 files[i] = fopen(logfiles[i],"r") ;
00116
00117 if(files[i] == NULL) {
00118 perror(logfiles[i]) ;
00119 }
00120 i++ ;
00121 } ;
00122
00123
00124 last_flush = 0 ;
00125
00126 memset(lines,0,sizeof(lines)) ;
00127
00128 new_lines = 0 ;
00129
00130 for(;;) {
00131
00132 u_int last_delta = time(NULL) - last_flush ;
00133
00134 data_in = 0 ;
00135
00136 for(i=0;i<MAX_LOGFILES;i++) {
00137
00138 if(logfiles[i][0]==0) continue ;
00139
00140
00141
00142
00143 errno = 0 ;
00144 fret = fgets(buff,sizeof(buff),files[i]) ;
00145 if(fret == NULL) {
00146
00147 if(errno) {
00148 perror(logfiles[i]) ;
00149 sleep(1) ;
00150 continue ;
00151 }
00152
00153 errno = 0 ;
00154 ret = stat(logfiles[i],&statb) ;
00155 if(ret < 0) {
00156 perror(logfiles[i]) ;
00157 sleep(1) ;
00158 continue ;
00159 }
00160
00161 if(statb.st_size < oldsizes[i]) {
00162
00163 fclose(files[i]) ;
00164 files[i] = fopen(logfiles[i],"r") ;
00165 oldsizes[i] = 0 ;
00166 lines[i] = 0 ;
00167 continue ;
00168 }
00169
00170 oldsizes[i] = statb.st_size ;
00171
00172 }
00173 else {
00174 data_in++ ;
00175
00176 lines[i]++ ;
00177
00178 if((strstr(buff,"CRITICAL") != NULL) ||\
00179 (strstr(buff,"OPERATOR") != NULL) ||\
00180 (strstr(buff,"CAUTION") != NULL)) {
00181 new_lines++ ;
00182 parseLog(buff,i,lines[i]) ;
00183
00184 }
00185 }
00186
00187 }
00188
00189
00190
00191
00192
00193 if((last_delta >= 60) || (new_lines && (last_delta >= 5))) {
00194 last_flush = time(NULL) ;
00195 last_delta = 0 ;
00196 dumpLines() ;
00197 printf("Dumping %d lines\n",new_lines) ;
00198 new_lines = 0 ;
00199 }
00200
00201 if(!data_in) {
00202 printf("No data...\n") ;
00203 sleep(1) ;
00204 }
00205 else {
00206 static u_int tot_data ;
00207 tot_data += data_in ;
00208
00209 if((tot_data % 10000)==0) {
00210 printf("read %d lines\n",tot_data) ;
00211 }
00212 }
00213
00214
00215 }
00216
00217
00218 return -1 ;
00219 }
00220
00221 int parseLog(char *b, u_int file, u_int seq)
00222 {
00223 u_int cou ;
00224 int i ;
00225 static char tm[16] ;
00226 static char task[128] ;
00227 static char line[128] ;
00228 static char day[8] ;
00229
00230 int use = 0 ;
00231 u_int min_sec = 0xffffffff ;
00232
00233 for(i=0;i<LOGLINES;i++) {
00234 if(loglines[i].sec == 0) {
00235 use = i ;
00236 break ;
00237 }
00238
00239 if(loglines[i].sec <= min_sec) {
00240 min_sec = loglines[i].sec ;
00241 use = i ;
00242 }
00243 }
00244
00245
00246 loglines[use].repeat = 1 ;
00247
00248
00249
00250 b++ ;
00251
00252
00253 cou = 0 ;
00254 while(*b != ' ') {
00255 loglines[use].node[cou++] = *b++ ;
00256 }
00257 loglines[use].node[cou] = 0 ;
00258
00259 while(*(++b) == ' ') ;
00260
00261 cou = 0 ;
00262 while(*b != ' ') {
00263 tm[cou++] = *b++ ;
00264 }
00265 tm[cou] = 0 ;
00266
00267 b++ ;
00268
00269
00270 strncpy(day,b,3) ;
00271 b += 3 ;
00272 loglines[use].day = atoi(day) ;
00273
00274
00275 b++ ;
00276 b++ ;
00277
00278 cou = 0 ;
00279 while(*b != ':') {
00280 task[cou++] = *b++ ;
00281 }
00282 task[cou] = 0 ;
00283
00284
00285 b++ ;
00286 b++ ;
00287
00288 cou = 0 ;
00289 while(*b != ':') {
00290 loglines[use].sev[cou++] = *b++ ;
00291 }
00292 loglines[use].sev[cou] = 0 ;
00293
00294
00295 b++ ;
00296 b++ ;
00297
00298 cou = 0 ;
00299 while(*b != ' ') {
00300 loglines[use].src[cou++] = *b++ ;
00301 }
00302 loglines[use].src[cou] = 0 ;
00303
00304 b += 7 ;
00305
00306 cou = 0 ;
00307 while(*b != ']') {
00308 line[cou++] = *b++ ;
00309 }
00310 line[cou] = 0 ;
00311
00312 loglines[use].line = atoi(line) ;
00313
00314 b += 3 ;
00315
00316 *(b+strlen(b)-1) = 0 ;
00317
00318 strncpy(loglines[use].tm,tm,sizeof(loglines[use].tm)-1) ;
00319
00320 char itm[sizeof(tm)] ;
00321 strcpy(itm,tm) ;
00322
00323 for(cou=0;cou<strlen(tm);cou++) {
00324 if(itm[cou] == ':') itm[cou] = 0 ;
00325 }
00326
00327
00328 loglines[use].sec = loglines[use].day*24*3600 + atoi(itm)*3600 + atoi(itm+3)*60 + atoi(itm+6) ;
00329
00330
00331 char *the_task ;
00332 char rb[10] ;
00333 if((task[1] == 'R') && (task[2] == 'B') && (task[5] == '_') && (task[7] == ']')) {
00334 strncpy(rb+1,task+1,6) ;
00335 rb[0] = ':' ;
00336 rb[7] = 0 ;
00337
00338 cou = 0 ;
00339
00340 the_task = &task[9] ;
00341 if((task[9] == '0') && (task[10]=='x')) {
00342 *(task+strlen(task)-1)=0 ;
00343 while(*the_task++ != '(') ;
00344 }
00345
00346 }
00347 else {
00348 rb[0] = 0 ;
00349
00350 the_task = task+1 ;
00351 *(the_task + strlen(the_task) -1) = 0 ;
00352 }
00353
00354 if(strlen(the_task) == 0) {
00355 strcpy(the_task,"???") ;
00356 }
00357
00358 strncpy(loglines[use].task,the_task,sizeof(loglines[use].task)-1) ;
00359 strncpy(loglines[use].rb,rb,sizeof(loglines[use].rb)-1) ;
00360 strncpy(loglines[use].msg,b,sizeof(loglines[use].msg)-1) ;
00361
00362 printf("Adding %d, last %d: file %d, line %d....\n",use,last_logline,file,seq) ;
00363
00364 loglines[use].seq = seq ;
00365 loglines[use].file = file ;
00366
00367 for(i=0;i<LOGLINES;i++) {
00368 if(i==use) continue ;
00369 if(loglines[i].sec == 0) continue ;
00370
00371 if(loglines[i].line == loglines[use].line) {
00372 if(loglines[i].file == loglines[use].file) {
00373 if(loglines[i].sec == loglines[use].sec) {
00374 if(strcmp(loglines[i].node,loglines[use].node)==0) {
00375 if(strcmp(loglines[i].src,loglines[use].src) == 0) {
00376 if(strcmp(loglines[i].task,loglines[use].task) == 0) {
00377 loglines[use].repeat = loglines[i].repeat + 1 ;
00378 loglines[i].sec = 0 ;
00379 }}}}}}
00380 }
00381
00382
00383 last_logline = use ;
00384
00385 return use ;
00386 }
00387
00388
00389 int compare(const void *s1, const void *s2)
00390 {
00391 struct logline *l1 = (struct logline *)s1 ;
00392 struct logline *l2 = (struct logline *)s2 ;
00393
00394 if(l1->sec < l2->sec) return 1 ;
00395 if(l1->sec > l2->sec) return -1 ;
00396
00397 if(l1->file == l2->file) {
00398 if(l1->seq < l2->seq) return 1 ;
00399 if(l1->seq > l2->seq) return -1 ;
00400 return 0 ;
00401 }
00402
00403
00404 if(l1->file < l2->file) return 1 ;
00405 if(l1->file > l2->file) return -1 ;
00406
00407 else return 0 ;
00408 }
00409
00410 int dumpLines(void)
00411 {
00412 int i ;
00413
00414
00415
00416 time_t now = time(NULL) ;
00417 struct tm *stm = localtime(&now) ;
00418
00419 errno = 0 ;
00420 FILE *o = fopen(DATA_1,"w") ;
00421 if(o==NULL) {
00422 perror(DATA_1) ;
00423 return -1 ;
00424 }
00425
00426 fprintf(o,"%s\n",data_preamble) ;
00427
00428 fprintf(o,"<table width=100%% border=1 cellspacing=0>\n") ;
00429 fprintf(o,"<tr %s><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th></tr>\n",
00430 "",
00431 "Time","#","Node","Severity","Task","Source#line","Msg") ;
00432
00433
00434
00435
00436 int sec = stm->tm_yday*24*3600 + stm->tm_hour*3600 + stm->tm_min*60 + stm->tm_sec ;
00437
00438
00439 qsort(loglines,LOGLINES,sizeof(loglines[0]),compare) ;
00440
00441
00442 for(i=0;i<LOGLINES;i++) {
00443 if(loglines[i].sec == 0) continue ;
00444
00445 int delta = sec - loglines[i].sec ;
00446
00447 char *color ;
00448
00449 if(delta > 120) {
00450 if(strncmp(loglines[i].sev,"CRIT",4)==0) color = "style=color:#FF3333" ;
00451 else if(strncmp(loglines[i].sev,"CAUT",4)==0) color = "style=color:#FF33FF" ;
00452 else if(strncmp(loglines[i].sev,"OPER",4)==0) color = "style=color:#3333FF" ;
00453 else color = "style=color:#333333" ;
00454
00455 }
00456 else {
00457 if(strncmp(loglines[i].sev,"CRIT",4)==0) color = "style=color:#FF0000;font-weight:bold" ;
00458 else if(strncmp(loglines[i].sev,"CAUT",4)==0) color = "style=color:#FF00FF;font-weight:bold" ;
00459 else if(strncmp(loglines[i].sev,"OPER",4)==0) color = "style=color:#0000FF;font-weight:bold" ;
00460 else color = "style=color:#000000;font-weight:bold" ;
00461 }
00462
00463
00464 fprintf(o,"<tr %s><td>%s</td><td>%d</td><td>%s</td><td>%s</td><td>%s%s</td><td>%s#%d</td><td>%s</td></tr>\n",
00465 color,
00466 loglines[i].tm,loglines[i].repeat,
00467 loglines[i].node,loglines[i].sev,loglines[i].task,loglines[i].rb,loglines[i].src,loglines[i].line,loglines[i].msg) ;
00468
00469
00470
00471 }
00472
00473 fprintf(o,"</table>\n") ;
00474
00475 fprintf(o,"\n</body></html>\n") ;
00476 fclose(o) ;
00477
00478 rename(DATA_1,DATA_2) ;
00479
00480
00481 now = time(NULL) ;
00482 struct utimbuf utim ;
00483 utim.actime = now ;
00484 utim.modtime = now ;
00485
00486 utime(DATA_2,&utim) ;
00487 utime(TOUCH,&utim) ;
00488
00489
00490 return 0 ;
00491 }
00492