Back to index

nordugrid-arc-nox  1.1.0~rc6
logger.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include <sys/types.h>
00006 #include <sys/stat.h>
00007 #include <dirent.h>
00008 #include <unistd.h>
00009 #include <string.h>
00010 
00011 #include <cstdlib>
00012 #include <iostream>
00013 #include <fstream>
00014 
00015 #include <arc/Logger.h>
00016 
00017 #include "client.h"
00018 
00019 #define olog (std::cerr)
00020 #define odlog(LEVEL) (std::cerr)
00021 
00022 // TODO: Run multiple clients in parallel
00023 
00024 using namespace ARex;
00025 
00026 int logger(const char* url,char const * const * dirs,int num,time_t ex_period = 0);
00027  
00028 int main(int argc,char* argv[]) {
00029   char* url = NULL;
00030 
00031   Arc::LogStream logcerr(std::cerr);
00032   Arc::Logger::getRootLogger().addDestination(logcerr);
00033   Arc::Logger::getRootLogger().setThreshold(Arc::WARNING);
00034 
00035   opterr=0;
00036   time_t ex_period = 0;
00037   int n;
00038   const char* basename = strrchr(argv[0],'/');
00039   if(basename == NULL) basename=argv[0];
00040   while((n=getopt(argc,argv,":hu:d:E:")) != -1) {
00041     switch(n) {
00042       case ':': { olog<<"Missing argument\n"; return 1; };
00043       case '?': { olog<<"Unrecognized option\n"; return 1; };
00044       case 'h': {
00045         std::cout<<"logger [-h] [-d level] [-u url] [-E expiration_period_days] control_dir ..."<<std::endl;
00046          return 0;
00047       };
00048       case 'u': {
00049         url=optarg;
00050       }; break;
00051       case 'd': {
00052         char* p;
00053         int i = strtol(optarg,&p,10);
00054         if(((*p) != 0) || (i<0)) {
00055           olog<<"Improper debug level '"<<optarg<<"'"<<std::endl;
00056           exit(1);
00057         };
00058 //        LogTime::Level(NotifyLevel(FATAL+i));
00059       }; break;
00060       case 'E': {
00061         char* p;
00062         int i = strtol(optarg,&p,10);
00063         if(((*p) != 0) || (i<=0)) {
00064           olog<<"Improper expiration period '"<<optarg<<"'"<<std::endl;
00065           exit(1);
00066         };
00067         ex_period=i; ex_period*=(60*60*24);
00068       }; break;
00069       default: { olog<<"Options processing error\n"; return 1; };
00070     };
00071   };
00072   return logger(url,argv+optind,argc-optind,ex_period);
00073 }
00074 
00075 int logger(const char* url,char const * const * dirs,int num,time_t ex_period) {
00076   int ret = 0;
00077   LoggerClient client;
00078   for(int n = 0;dirs[n] && n<num;n++) {
00079     std::string logdir(dirs[n]); logdir+="/logs/";
00080     std::string logger_url(url?url:"");
00081     struct dirent file_;
00082     struct dirent *file;
00083     odlog(INFO)<<"Processing directory: "<<logdir<<std::endl;
00084     DIR *dir=opendir(logdir.c_str());
00085     if(dir == NULL) continue;
00086     for(;;) {
00087       readdir_r(dir,&file_,&file);
00088       if(file == NULL) break;
00089       std::string logfile = logdir+file->d_name;
00090       struct stat st;
00091       if(stat(logfile.c_str(),&st) != 0) continue;
00092       if(!S_ISREG(st.st_mode)) continue;
00093       odlog(INFO)<<"Processing file: "<<logfile<<std::endl;
00094       bool result = true;
00095       /* read file */
00096       char buf[4096];
00097       std::ifstream f(logfile.c_str());
00098       if(!f.is_open() ) continue; /* can't open file */
00099       JobRecord j(f);
00100       f.close();
00101       if(!j) {
00102         result=false;
00103         odlog(ERROR)<<"Removing unreadable job information in "<<logfile<<std::endl;
00104         unlink(logfile.c_str());
00105       } else {
00106         if(j.url.length()) logger_url=j.url;
00107         if(logger_url.length() == 0) {
00108           odlog(VERBOSE)<<"No service URL provided"<<std::endl;
00109           result = false;
00110         } else {
00111           std::list<JobRecord> recs;
00112           recs.push_back(j);
00113           odlog(VERBOSE)<<"Reporting to: "<<logger_url<<std::endl;
00114          odlog(VERBOSE)<<"Reporting about: "<<(std::string)(j["globaljobid"])<<std::endl;
00115 //          result = client.Report(logger_url.c_str(),recs);
00116           result = client.ReportV2(logger_url.c_str(),recs);
00117         };
00118         if(result) {
00119           odlog(INFO)<<"Passed information about job "<<j["globaljobid"]<<std::endl;
00120           unlink(logfile.c_str());
00121         } else {
00122           odlog(ERROR)<<"Failed to pass information about job "<<
00123                   (std::string)(j["globaljobid"])<<std::endl;
00124           ret=-1;
00125           // Check creation time and remove it if really too old
00126           if((ex_period) && 
00127              (((unsigned int)(time(NULL)-st.st_mtime)) > ex_period)) {
00128             odlog(ERROR)<<"Removing outdated information about job "<<
00129                     (std::string)(j["globaljobid"])<<std::endl;
00130             unlink(logfile.c_str());
00131           };
00132         };
00133       };
00134     };
00135     closedir(dir);
00136   };
00137   return ret;
00138 }
00139