00001 #include <iostream>
00002 #include "ECF_base.h"
00003
00004
00005 Logger::Logger()
00006 {
00007 currentLevel_ = 3;
00008 bFileDefined_ = false;
00009 logFrequency_ = 1;
00010 }
00011
00012
00013 Logger::~Logger()
00014 {
00015 logFile_.close();
00016 }
00017
00018
00019 void Logger::registerParameters(StateP state)
00020 {
00021 uint *level = new uint(3);
00022 state->getRegistry()->registerEntry("log.level", (voidP) level, ECF::UINT,
00023 "log level; valid values are 1 (minimal) to 5 (verbose) (default: 3)");
00024 std::string *file = new std::string("");
00025 state->getRegistry()->registerEntry("log.filename", (voidP) file, ECF::STRING,
00026 "log filename (default: none)");
00027 uint *freq = new uint(1);
00028 state->getRegistry()->registerEntry("log.frequency", (voidP) freq, ECF::UINT,
00029 "log only every 'frequency' generations (default: 1)");
00030 }
00031
00032
00033 bool Logger::initialize(StateP state)
00034 {
00035 if(logFile_.is_open())
00036 logFile_.close();
00037
00038
00039 voidP sptr = state->getRegistry()->getEntry("log.level");
00040 currentLevel_ = *((uint*) sptr.get());
00041 sptr = state->getRegistry()->getEntry("log.frequency");
00042 logFrequency_ = *((uint*) sptr.get());
00043
00044 if(state->getRegistry()->isModified("log.filename")) {
00045 sptr = state->getRegistry()->getEntry("log.filename");
00046 logFileName_ = *((std::string*) sptr.get());
00047
00048 logFile_.open(logFileName_.c_str());
00049 if(logFile_)
00050 bFileDefined_ = true;
00051 else {
00052 throw std::string("Error: can't open logfile (") + logFileName_ + ")";
00053 }
00054 }
00055 else
00056 bFileDefined_ = false;
00057
00058 state_ = state;
00059 return true;
00060 }
00061
00062
00063 void Logger::log(int logLevel, std::string message)
00064 {
00065 if(currentLevel_ >= logLevel) {
00066 Log tmp;
00067 if(logLevel > 5) logLevel = 5;
00068 if(logLevel < 0) logLevel = 0;
00069
00070 #ifdef _MPI
00071 message = uint2str(state_->getCommunicator()->getCommGlobalRank()) + ": " + message;
00072 #endif
00073
00074 logs_.push_back(tmp);
00075 logs_.back().logLevel = logLevel;
00076 logs_.back().message = message;
00077
00078 if(logLevel == 1 || state_->getGenerationNo() % logFrequency_ == 0)
00079 std::cout << logs_.back().message << std::endl;
00080 }
00081 }
00082
00083
00084 void Logger::saveTo(std::string fileName)
00085 {
00086 std::ofstream logFile(fileName.c_str(),std::ios::app);
00087 for (unsigned int i = 0; i < logs_.size(); ++i){
00088 logFile << logs_[i].message << std::endl;
00089 }
00090
00091 logFile.close();
00092 logs_.clear();
00093 }
00094
00095
00096 void Logger::saveTo(bool check)
00097 {
00098 if(!bFileDefined_) {
00099 logs_.clear();
00100 return;
00101 }
00102
00103 if(!check && state_->getGenerationNo() > 1 && state_->getGenerationNo() % logFrequency_ != 0) {
00104 logs_.clear();
00105 return;
00106 }
00107
00108 std::stringstream logOutput;
00109
00110 for (unsigned int i = 0; i < logs_.size(); ++i) {
00111 logOutput << logs_[i].message << std::endl;
00112 }
00113
00114 #ifdef _MPI
00115 if(state_->getCommunicator()->getCommGlobalSize() != 1) {
00116
00117 if(state_->getCommunicator()->getCommGlobalRank() == 0) {
00118 std::string remoteLogs = state_->getCommunicator()->recvLogsGlobal();
00119 logFile_ << logOutput.str() << remoteLogs;
00120 }
00121 else {
00122 state_->getCommunicator()->sendLogsGlobal(logOutput.str());
00123 }
00124 }
00125
00126 else
00127 logFile_ << logOutput.str();
00128 #else
00129 logFile_ << logOutput.str();
00130 #endif
00131
00132 logs_.clear();
00133 }
00134
00135
00136 void Logger::saveToX(std::string fileName)
00137 {
00138 std::ofstream logFile(fileName.c_str(), std::ios::app);
00139 logFile<<"<log>"<<std::endl;
00140
00141 for (unsigned int i = 0; i < logs_.size(); ++i){
00142 logFile <<"<message logLevel=\""<< logs_[i].logLevel << "\">" << logs_[i].message <<"</message>"<< std::endl;
00143 }
00144 logFile<<"</log>";
00145
00146 logFile.close();
00147 logs_.clear();
00148 }
00149
00150
00151 void Logger::saveToX()
00152 {
00153 if(!bFileDefined_)
00154 return;
00155 logFile_ << "<log>" << std::endl;
00156 for (unsigned int i = 0; i < logs_.size(); ++i){
00157 logFile_ <<"<message logLevel=\""<< logs_[i].logLevel << "\">" << logs_[i].message <<"</message>"<< std::endl;
00158 }
00159 logFile_ << "</log>";
00160
00161 logs_.clear();
00162 }
00163
00164
00165 void Logger::flushLog()
00166 {
00167 logs_.clear();
00168 }
00169
00170
00171 bool Logger::operate(StateP state)
00172 {
00173 saveTo();
00174 return true;
00175 }
00176
00177
00178 void Logger::setLogFrequency(uint freq)
00179 {
00180 logFrequency_ = freq;
00181 }