| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

Manager.cc

Go to the documentation of this file.
00001 #include "Manager.hh"
00002 #include "FormString.hh"
00003 #include <iostream>
00004 #include <fstream>
00005 #include <cassert>
00006 
00007 #include <sys/types.h>
00008 #include <sys/stat.h>
00009 #include <unistd.h>
00010 
00011 using namespace Logging;
00012 
00013 //hxt ClassImp(Manager)
00014 
00015 DEFINE_LOG(log_manager) // it logs itself!
00016 
00017 Logging::Manager::Manager()
00018 {
00019    // At first creation, start up a default stream with a default rule that everything goes there.
00020   AttachStream("*","stdout");
00021 }
00022 
00023 Logging::Manager::~Manager()
00024 {
00025   std::map<std::string,std::ofstream*>::iterator it;
00026   for(it = mOpenFiles.begin(); it!= mOpenFiles.end(); it++) {
00027     (it->second)->flush();
00028     (it->second)->close();
00029     delete(it->second);
00030   }
00031   mOpenFiles.clear();
00032 }
00033 
00034 void Logging::Manager::ResetRules()
00035 {
00036   mLevelRules.clear();
00037   mStreamRules.clear();
00038   ApplyRules();
00039 }
00040 
00041 void Logging::Manager::AppendSetLevelRule(std::string logpattern, Level lvl)
00042 {
00043   LevelRule lr;
00044   lr.mLogPattern = logpattern;
00045   lr.mLevel      = lvl;
00046   mLevelRules.push_back(lr);
00047   ApplyRules();
00048 }
00049 
00050 void Logging::Manager::PrependSetLevelRule(std::string logpattern, Level lvl)
00051 {
00052   LevelRule lr;
00053   lr.mLogPattern = logpattern;
00054   lr.mLevel      = lvl;
00055   mLevelRules.push_front(lr);
00056   ApplyRules();
00057 }
00058 
00059 void Logging::Manager::AttachStream(std::string logpattern, std::string streamname)
00060 {
00061   StreamRule sr;
00062   sr.mLogPattern = logpattern;
00063   sr.mStreamName = streamname;
00064   mStreamRules.push_back(sr);
00065   ApplyRules();
00066 }
00067 
00068 LogStream& Logging::Manager::GetStream( std::string name )
00069 {
00070   // Find an old one by this name
00071   std::map<std::string,LogStream>::iterator it = mLogStreams.find(name);
00072   if(it != mLogStreams.end()) return it->second;
00073 
00074   mLogStreams[name] = LogStream(name); // Make a new one
00075   return mLogStreams[name];  
00076 }
00077 
00078 std::ostream* Logging::Manager::GetOStream( std::string name )
00079 {
00080   std::map<std::string,std::ofstream*>::iterator it = mOpenFiles.find(name);
00081   if(it != mOpenFiles.end()) return it->second;
00082 
00083   // OK, it doesn't exist. Create the file.
00084   std::ofstream* newstream = 0;
00085 
00086   if(name.find('%')==std::string::npos) {
00087     // Just create a new file; replace any existing file.
00088     newstream = new std::ofstream(name.c_str(), std::ios_base::out | std::ios_base::trunc);
00089   } else {
00090     // Use a log file number. Increment until we find an empty file.
00091     std::string trialname = name;  
00092     std::string::size_type p = trialname.find_last_of('%');
00093     int num = 1;
00094     int notexist=0;
00095 
00096     // Attempt to just name it the base name.
00097     trialname = name;
00098     trialname.replace(p,1,"");
00099     static struct stat stats;
00100     notexist = stat(trialname.c_str(),&stats);
00101 
00102     while(notexist==0) {
00103       // Ok, that file exists,so replace % with .001 and try again. (Then .002, etc)
00104       trialname = name;
00105       trialname.replace(p,1,FormString(".%03d",num++));
00106       notexist = stat(trialname.c_str(),&stats);
00107     }
00108 
00109     newstream = new std::ofstream(trialname.c_str(), std::ios_base::out | std::ios_base::trunc);
00110   }
00111 
00112   assert(newstream);
00113   assert(newstream->good());
00114 
00115   mOpenFiles[name]=newstream;
00116   return newstream;
00117 }
00118 
00119 void Logging::Manager::RegisterLog( Log* log )
00120 {
00121   mLogs.insert(log);
00122   ApplyRules(log);
00123 }
00124 
00125 
00126 void Logging::Manager::DeRegisterLog( Log* log )
00127 {
00128   mLogs.erase(log);
00129 }
00130 
00131 void Logging::Manager::ApplyRules()
00132 {
00133   std::set<Log*>::iterator it;
00134   for(it = mLogs.begin(); it!= mLogs.end(); it++) ApplyRules(*it);
00135   
00136   //PrintRules();
00137   //PrintCurrentConfig();
00138 }
00139 
00140 
00141 bool PatternMatches(const std::string& pattern, const std::string& target)
00142 {
00143   // Poor man's pattern matcher.
00144   // Match thing to thing
00145   if(pattern==target) return true;
00146   // Match blah* to blahanything
00147   std::string::size_type starpos = pattern.find_first_of('*',0);
00148   if(starpos != std::string::npos) {
00149                  // There was a wildcard. See if the substring before matches.
00150     if(pattern.compare(0,starpos, target,0,starpos) ==0) return true;
00151   }
00152   return false;
00153 }
00154 
00155 
00156 void Logging::Manager::ApplyRules(Log* log)
00157 {
00158   // The core of the configuration utility. 
00159   // Try to apply all the currently-cached rules, in order, to the the given log.
00160 
00161   log->ResetStreams(); // Clear out any existing streams.
00162   for(unsigned int i=0; i< mStreamRules.size(); i++) {
00163     if(PatternMatches(mStreamRules[i].mLogPattern, log->GetName())) {
00164       log->ConnectStream(
00165         &GetStream(mStreamRules[i].mStreamName) 
00166         );
00167     }
00168   }
00169 
00170   log->Enable(Logging::kDefault); // Set to default level  
00171   for(unsigned int i=0; i< mLevelRules.size(); i++) {
00172     if(PatternMatches(mLevelRules[i].mLogPattern, log->GetName())) {
00173       log->Enable(mLevelRules[i].mLevel);
00174     }
00175   }
00176 }
00177 
00178 void Logging::Manager::PrintRules(Logging::Level lvl)
00179 {
00180   LOG(log_manager,lvl) << "Complete level rules:";
00181   for(unsigned int i=0; i< mLevelRules.size(); i++) {
00182     LOG(log_manager,lvl) << mLevelRules[i].mLogPattern << " --> " << LevelToString(mLevelRules[i].mLevel); 
00183   }
00184   LOG(log_manager,lvl) << "Complete stream rules:";
00185   for(unsigned int i=0; i< mStreamRules.size(); i++) {
00186     LOG(log_manager,lvl) << mStreamRules[i].mLogPattern << " --> " << mStreamRules[i].mStreamName; 
00187   }
00188 }
00189 
00190 void Logging::Manager::PrintCurrentConfig(Logging::Level lvl)
00191 {
00192   LOG(log_manager,lvl) << "Current logs:";
00193   LOG(log_manager,lvl) << "LogName     Current Level     Streams";
00194   std::set<Log*>::iterator it;
00195   for(it = mLogs.begin(); it!= mLogs.end(); it++) {
00196     Log* log = *it; 
00197     assert(log);
00198     const std::set<LogStream*>& streams = log->GetStreams(); 
00199     std::set<LogStream*>::const_iterator sit;
00200     std::string streamnames;
00201     for(sit=streams.begin();sit!=streams.end(); ++sit) {
00202       streamnames += (*sit)->GetName();
00203       streamnames += " ";
00204     }
00205 
00206     LOG(log_manager,lvl) << log->GetName() << "\t" 
00207                          << LevelToString(log->GetLevel()) << "\t"
00208                          << streamnames;
00209   }
00210 }
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Mon Apr 11 20:06:22 2011 for Log by doxygen 1.4.7