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
00014
00015 DEFINE_LOG(log_manager)
00016
00017 Logging::Manager::Manager()
00018 {
00019
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
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);
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
00084 std::ofstream* newstream = 0;
00085
00086 if(name.find('%')==std::string::npos) {
00087
00088 newstream = new std::ofstream(name.c_str(), std::ios_base::out | std::ios_base::trunc);
00089 } else {
00090
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
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
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
00137
00138 }
00139
00140
00141 bool PatternMatches(const std::string& pattern, const std::string& target)
00142 {
00143
00144
00145 if(pattern==target) return true;
00146
00147 std::string::size_type starpos = pattern.find_first_of('*',0);
00148 if(starpos != std::string::npos) {
00149
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
00159
00160
00161 log->ResetStreams();
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);
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 }