Back to index

nordugrid-arc-nox  1.1.0~rc6
UsageReporter.cpp
Go to the documentation of this file.
00001 #include "jura.h"
00002 #include "UsageReporter.h"
00003 #include "JobLogFile.h"
00004 
00005 //TODO cross-platform
00006 #include <dirent.h>
00007 #include <signal.h>
00008 #include <errno.h>
00009 #include <time.h>
00010 #include <sstream>
00011 
00012 #include "arc/ArcRegex.h"
00013 
00014 namespace Arc
00015 {
00016 
00021   UsageReporter::UsageReporter(std::string job_log_dir_, time_t expiration_time_,
00022                             std::list<std::string> urls_):
00023     logger(Arc::Logger::rootLogger, "JURA.UsageReporter"),
00024     job_log_dir(job_log_dir_),
00025     expiration_time(expiration_time_),
00026     urls(urls_)
00027   {
00028     logger.msg(Arc::INFO, "Initialised, job log dir: %s",
00029               job_log_dir.c_str());
00030     logger.msg(Arc::VERBOSE, "Expiration time: %d seconds",
00031               expiration_time);
00032     if (!urls.empty())
00033       logger.msg(Arc::VERBOSE, "Interactive mode.",
00034                expiration_time);
00035     //Collection of logging destinations:
00036     dests=new Arc::Destinations();
00037   }
00038 
00042   int UsageReporter::report()
00043   {
00044     //ngjobid->url mapping to keep track of which loggerurl is replaced
00045     //by the '-u' options
00046     std::map<std::string,std::string> dest_to_duplicate;
00047     //Collect job log file names from job log dir
00048     //(to know where to get usage data from)
00049     DIR *dirp;
00050     dirent *entp;
00051     errno=0;
00052     if ( (dirp=opendir(job_log_dir.c_str()))==NULL )
00053       {
00054        logger.msg(Arc::ERROR, 
00055                  "Could not open log directory \"%s\": %s",
00056                  job_log_dir.c_str(),
00057                  strerror(errno)
00058                  );
00059        return -1;
00060       }
00061 
00062     // Seek "<jobnumber>.<randomstring>" files.
00063     Arc::RegularExpression logfilepattern("^[0-9]+\\.[^.]+$");
00064     errno = 0;
00065     while ((entp = readdir(dirp)) != NULL)
00066       {
00067        if (logfilepattern.match(entp->d_name))
00068          {
00069            //Parse log file
00070            Arc::JobLogFile *logfile;
00071            //TODO handle DOS-style path separator!
00072            std::string fname=job_log_dir+"/"+entp->d_name;
00073            logfile=new Arc::JobLogFile(fname);
00074 
00075            //A. Non-interactive mode: each jlf is parsed, and if valid, 
00076            //   submitted to the destination given  by "loggerurl=..."
00077            if (urls.empty())
00078              {
00079               // Check creation time and remove it if really too old
00080               if( expiration_time>0 && logfile->olderThan(expiration_time) )
00081                 {
00082                   logger.msg(Arc::INFO,
00083                             "Removing outdated job log file %s",
00084                             logfile->getFilename().c_str()
00085                             );
00086                   logfile->remove();
00087                 } 
00088               else
00089                 {
00090                   //Pass job log file content to the appropriate 
00091                   //logging destination
00092                   dests->report(*logfile);
00093                   //(deep copy performed)
00094                 }
00095              }
00096 
00097            //B. Interactive mode: submit only to services specified by
00098            //   command line option '-u'. Avoid repetition if several jlfs
00099            //   are created with same content and different destination.
00100            //   Keep all jlfs on disk.
00101            else
00102              {
00103               if ( dest_to_duplicate.find( (*logfile)["ngjobid"] ) ==
00104                    dest_to_duplicate.end() )
00105                 {
00106                   dest_to_duplicate[ (*logfile)["ngjobid"] ]=
00107                     (*logfile)["loggerurl"];
00108                 }
00109 
00110               //submit only 1x to each!
00111               if ( dest_to_duplicate[ (*logfile)["ngjobid"] ] ==
00112                    (*logfile)["loggerurl"] )
00113                 {
00114                   //Duplicate content of log file, overwriting URL with
00115                   //each '-u' command line option, disabling file deletion
00116                   Arc::JobLogFile *dupl_logfile=
00117                     new Arc::JobLogFile(*logfile);
00118                   dupl_logfile->allowRemove(false);
00119 
00120                   for (std::list<std::string>::iterator it=urls.begin();
00121                       it!=urls.end();
00122                       ++it)
00123                     {
00124                      (*dupl_logfile)["loggerurl"] = *it;
00125 
00126                      //Pass duplicated job log content to the appropriate 
00127                      //logging destination
00128                      dests->report(*dupl_logfile);
00129                      //(deep copy performed)
00130 
00131                     }
00132                   delete dupl_logfile;
00133                 }
00134              }
00135 
00136            delete logfile;
00137          }
00138        errno = 0;
00139       }
00140 
00141     if (errno!=0)
00142       {
00143        logger.msg(Arc::ERROR, 
00144                  "Error reading log directory \"%s\": %s",
00145                  job_log_dir.c_str(),
00146                  strerror(errno)
00147                  );
00148        return -2;
00149       }
00150     return 0;
00151   }
00152   
00153   UsageReporter::~UsageReporter()
00154   {
00155     delete dests;
00156     logger.msg(Arc::INFO, "Finished, job log dir: %s",
00157               job_log_dir.c_str());
00158   }
00159   
00160 }