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 ClassImp(Manager)
00014
00015 Logging::Manager::Manager()
00016 {
00017
00018 AttachStream("*","stdout");
00019 }
00020
00021 Logging::Manager::~Manager()
00022 {
00023 std::map<std::string,std::ofstream*>::iterator it;
00024 for(it = mOpenFiles.begin(); it!= mOpenFiles.end(); it++) {
00025 (it->second)->flush();
00026 (it->second)->close();
00027 delete(it->second);
00028 }
00029 mOpenFiles.clear();
00030 }
00031
00032 void Logging::Manager::ResetRules()
00033 {
00034 mLevelRules.clear();
00035 mStreamRules.clear();
00036 ApplyRules();
00037 }
00038
00039 void Logging::Manager::SetLevel(std::string logpattern, Level lvl)
00040 {
00041 LevelRule lr;
00042 lr.mLogPattern = logpattern;
00043 lr.mLevel = lvl;
00044 mLevelRules.push_back(lr);
00045 ApplyRules();
00046 }
00047
00048 void Logging::Manager::AttachStream(std::string logpattern, std::string streamname)
00049 {
00050 StreamRule sr;
00051 sr.mLogPattern = logpattern;
00052 sr.mStreamName = streamname;
00053 mStreamRules.push_back(sr);
00054 ApplyRules();
00055 }
00056
00057 LogStream& Logging::Manager::GetStream( std::string name )
00058 {
00059
00060 std::map<std::string,LogStream>::iterator it = mLogStreams.find(name);
00061 if(it != mLogStreams.end()) return it->second;
00062
00063 mLogStreams[name] = LogStream(name);
00064 return mLogStreams[name];
00065 }
00066
00067 std::ostream* Logging::Manager::GetOStream( std::string name )
00068 {
00069 std::map<std::string,std::ofstream*>::iterator it = mOpenFiles.find(name);
00070 if(it != mOpenFiles.end()) return it->second;
00071
00072
00073 std::ofstream* newstream = 0;
00074
00075 if(name.find('%')==std::string::npos) {
00076
00077 newstream = new std::ofstream(name.c_str(), std::ios_base::out | std::ios_base::trunc);
00078 } else {
00079
00080 std::string trialname = name;
00081 std::string::size_type p = trialname.find_last_of('%');
00082 int num = 1;
00083 int notexist=0;
00084
00085
00086 trialname = name;
00087 trialname.replace(p,1,"");
00088 static struct stat stats;
00089 notexist = stat(trialname.c_str(),&stats);
00090
00091 while(notexist==0) {
00092
00093 trialname = name;
00094 trialname.replace(p,1,FormString(".%03d",num++));
00095 notexist = stat(trialname.c_str(),&stats);
00096 }
00097
00098 newstream = new std::ofstream(trialname.c_str(), std::ios_base::out | std::ios_base::trunc);
00099 }
00100
00101 assert(newstream);
00102 assert(newstream->good());
00103
00104 mOpenFiles[name]=newstream;
00105 return newstream;
00106 }
00107
00108 void Logging::Manager::RegisterLog( Log* log )
00109 {
00110 mLogs.insert(log);
00111 ApplyRules(log);
00112 }
00113
00114
00115 void Logging::Manager::DeRegisterLog( Log* log )
00116 {
00117 mLogs.erase(log);
00118 }
00119
00120 void Logging::Manager::ApplyRules()
00121 {
00122 std::set<Log*>::iterator it;
00123 for(it = mLogs.begin(); it!= mLogs.end(); it++) ApplyRules(*it);
00124 }
00125
00126
00127 bool PatternMatches(const std::string& pattern, const std::string& target)
00128 {
00129
00130
00131 if(pattern==target) return true;
00132
00133 std::string::size_type starpos = pattern.find_first_of('*',0);
00134 if(starpos != std::string::npos) {
00135
00136 if(pattern.compare(0,starpos, target,0,starpos) ==0) return true;
00137 }
00138 return false;
00139 }
00140
00141
00142 void Logging::Manager::ApplyRules(Log* log)
00143 {
00144
00145
00146
00147 log->ResetStreams();
00148 for(unsigned int i=0; i< mStreamRules.size(); i++) {
00149 if(PatternMatches(mStreamRules[i].mLogPattern, log->GetName())) {
00150 log->ConnectStream(
00151 &GetStream(mStreamRules[i].mStreamName)
00152 );
00153 }
00154 }
00155
00156 log->Enable(Logging::kDefault);
00157 for(unsigned int i=0; i< mLevelRules.size(); i++) {
00158 if(PatternMatches(mLevelRules[i].mLogPattern, log->GetName())) {
00159 log->Enable(mLevelRules[i].mLevel);
00160 }
00161 }
00162
00163
00164 }