Changeset 8729 for code/trunk/src/libraries/util/OutputHandler.cc
- Timestamp:
- Jul 4, 2011, 2:47:44 AM (14 years ago)
- Location:
- code/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
-
code/trunk/src/libraries/util/OutputHandler.cc
r7401 r8729 69 69 */ 70 70 LogFileWriter() 71 : OutputListener( OutputHandler::logFileOutputListenerName_s)71 : OutputListener("LogFile") 72 72 { 73 73 // Get path for a temporary file … … 85 85 timeinfo = localtime(&rawtime); 86 86 87 this->logFile_.open(this->logFilename_.c_str(), std::fstream::out); 88 this->logFile_ << "Started log on " << asctime(timeinfo) << std::endl; 89 this->logFile_.flush(); 90 91 this->outputStream_ = &this->logFile_; 87 this->openFile(); 88 if (this->logFile_.is_open()) 89 { 90 this->logFile_ << "Started log on " << asctime(timeinfo) << std::endl; 91 this->logFile_.flush(); 92 } 92 93 } 93 94 … … 95 96 ~LogFileWriter() 96 97 { 97 this->logFile_ << "Closed log" << std::endl; 98 this->logFile_.close(); 98 if (this->logFile_.is_open()) 99 { 100 this->logFile_ << "Closed log" << std::endl; 101 this->logFile_.close(); 102 } 99 103 } 100 104 … … 102 106 void setLogPath(const std::string& path) 103 107 { 104 this->logFile_.close(); 105 // Read old file into a buffer 106 std::ifstream old(this->logFilename_.c_str()); 108 if (this->logFile_.is_open()) 109 this->logFile_.close(); 110 111 // Open the new file 107 112 this->logFilename_ = path + logFileBaseName_g; 108 // Open the new file and feed it the content of the old one 113 this->openFile(); 114 } 115 116 //! Erases the log file 117 void clearFile() 118 { 119 if (this->logFile_.is_open()) 120 { 121 this->logFile_.close(); 122 this->openFile(); 123 } 124 } 125 126 private: 127 void openFile() 128 { 109 129 this->logFile_.open(this->logFilename_.c_str(), std::fstream::out); 110 this->logFile_ << old.rdbuf(); 111 this->logFile_.flush(); 112 old.close(); 113 } 114 115 private: 130 131 if (this->logFile_.is_open()) 132 this->outputStream_ = &this->logFile_; 133 else 134 { 135 COUT(2) << "Warning: Failed to open log file. File logging disabled." << std::endl; 136 this->outputStream_ = NULL; 137 } 138 } 139 116 140 std::ofstream logFile_; //!< File handle for the log file 117 141 std::string logFilename_; //!< Filename of the log file … … 133 157 //! Only assigns the output stream with std::cout 134 158 ConsoleWriter() 135 : OutputListener(" consoleLog")159 : OutputListener("Console") 136 160 { 137 161 this->outputStream_ = &std::cout; … … 147 171 OutputListener that writes all the output piece by piece to an array 148 172 associated with the corresponding output level. 173 Used as buffer until all output devices have been initialised. 149 174 @note 150 Only output below or equal to the current soft debug level is written151 to minimise huge arrays for the normal run.175 At some point, OutputHandler::disableMemoryLog() has to be called in 176 order to avoid large memory footprints of this class. 152 177 */ 153 178 class MemoryLogWriter : public OutputListener … … 156 181 friend class OutputHandler; 157 182 158 /**159 @brief160 Sets the right soft debug level and registers itself161 */162 183 MemoryLogWriter() 163 184 : OutputListener("memoryLog") … … 166 187 } 167 188 168 //! Push edthe just written output to the internal array189 //! Push the just written output to the internal array 169 190 void outputChanged(int level) 170 191 { … … 180 201 181 202 private: 182 std::ostringstream 183 std::vector<std::pair<int, std::string> >output_; //!< Vector containing ALL output203 std::ostringstream buffer_; //!< Stream object used to process the output 204 OutputHandler::OutputVector output_; //!< Vector containing ALL output 184 205 }; 185 206 … … 188 209 ///// OutputHandler ///// 189 210 ///////////////////////// 190 const std::string OutputHandler::logFileOutputListenerName_s = "logFile"; 191 int OutputHandler::softDebugLevel_s = hardDebugLevel; 211 int OutputHandler::softDebugLevel_s = hardDebugLevel; 192 212 193 213 //! Creates the LogFileWriter and the MemoryLogWriter … … 195 215 : outputLevel_(OutputLevel::Verbose) 196 216 { 217 // Note: These levels only concern startup before orxonox.ini is read. 197 218 #ifdef ORXONOX_RELEASE 198 const OutputLevel::Value defaultLevelConsole = OutputLevel::Error; 199 const OutputLevel::Value defaultLevelLogFile = OutputLevel::Info; 219 const OutputLevel::Value initialLevelConsole = OutputLevel::Error; 200 220 #else 201 const OutputLevel::Value defaultLevelConsole = OutputLevel::Info; 202 const OutputLevel::Value defaultLevelLogFile = OutputLevel::Debug; 221 const OutputLevel::Value initialLevelConsole = OutputLevel::Info; 203 222 #endif 223 // Use high log level because we rewrite the log file anyway with the 224 // correct level. But if Orxonox were to crash before that, we might be 225 // grateful to have a high debug level, esp. for releases. 226 const OutputLevel::Value intialLevelLogFile = OutputLevel::Debug; 204 227 205 228 this->logFile_ = new LogFileWriter(); 206 229 // Use default level until we get the configValue from the Core 207 this->logFile_->softDebugLevel_ = defaultLevelLogFile;230 this->logFile_->softDebugLevel_ = intialLevelLogFile; 208 231 this->registerOutputListener(this->logFile_); 209 232 210 233 this->consoleWriter_ = new ConsoleWriter(); 211 this->consoleWriter_->softDebugLevel_ = defaultLevelConsole;234 this->consoleWriter_->softDebugLevel_ = initialLevelConsole; 212 235 this->registerOutputListener(this->consoleWriter_); 213 236 214 this-> output_ = new MemoryLogWriter();215 // W e capture as much input as the listener with the highest level216 this-> output_->softDebugLevel_ = getSoftDebugLevel();217 this->registerOutputListener(this-> output_);237 this->memoryBuffer_ = new MemoryLogWriter(); 238 // Write everything, e.g. use hardDebugLevel 239 this->memoryBuffer_->softDebugLevel_ = hardDebugLevel; 240 this->registerOutputListener(this->memoryBuffer_); 218 241 } 219 242 … … 223 246 delete this->logFile_; 224 247 delete this->consoleWriter_; 225 delete this-> output_;248 delete this->memoryBuffer_; // Might already be NULL 226 249 } 227 250 … … 234 257 void OutputHandler::registerOutputListener(OutputListener* listener) 235 258 { 236 for (std:: list<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)259 for (std::vector<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it) 237 260 { 238 261 if ((*it)->name_ == listener->name_) … … 243 266 } 244 267 this->listeners_.push_back(listener); 245 // Update global soft debug level 246 this->setSoftDebugLevel(listener->getOutputListenerName(), listener->getSoftDebugLevel()); 268 this->updateGlobalDebugLevel(); 247 269 } 248 270 249 271 void OutputHandler::unregisterOutputListener(OutputListener* listener) 250 272 { 251 this->listeners_.remove(listener); 273 for (std::vector<OutputListener*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it) 274 { 275 if ((*it)->name_ == listener->name_) 276 { 277 this->listeners_.erase(it); 278 break; 279 } 280 } 281 this->updateGlobalDebugLevel(); 252 282 } 253 283 … … 255 285 { 256 286 this->logFile_->setLogPath(path); 287 this->rewriteLogFile(); 288 } 289 290 void OutputHandler::rewriteLogFile() 291 { 292 logFile_->clearFile(); 293 294 if (logFile_->outputStream_ == NULL) 295 return; 296 297 for (OutputVector::const_iterator it = this->getOutput().begin(); it != this->getOutput().end(); ++it) 298 { 299 if (it->first <= logFile_->softDebugLevel_) 300 (*logFile_->outputStream_) << it->second; 301 } 302 logFile_->outputStream_->flush(); 257 303 } 258 304 … … 267 313 } 268 314 269 OutputHandler::OutputVectorIterator OutputHandler::getOutputVectorBegin() const 270 { 271 return this->output_->output_.begin(); 272 } 273 274 OutputHandler::OutputVectorIterator OutputHandler::getOutputVectorEnd() const 275 { 276 return this->output_->output_.end(); 315 void OutputHandler::disableMemoryLog() 316 { 317 this->unregisterOutputListener(this->memoryBuffer_); 318 // Only clear the buffer so we can still reference the vector 319 this->memoryBuffer_->output_.clear(); 320 } 321 322 const OutputHandler::OutputVector& OutputHandler::getOutput() const 323 { 324 return this->memoryBuffer_->output_; 277 325 } 278 326 279 327 int OutputHandler::getSoftDebugLevel(const std::string& name) const 280 328 { 281 for (std:: list<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)329 for (std::vector<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it) 282 330 { 283 331 if ((*it)->name_ == name) … … 289 337 void OutputHandler::setSoftDebugLevel(const std::string& name, int level) 290 338 { 291 int globalSoftDebugLevel = -1; 292 for (std::list<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it) 339 for (std::vector<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it) 293 340 { 294 341 if ((*it)->name_ == name) 295 342 (*it)->softDebugLevel_ = level; 296 if ((*it)->softDebugLevel_ > globalSoftDebugLevel) 297 globalSoftDebugLevel = (*it)->softDebugLevel_; 298 } 299 // Update global soft debug level 343 } 344 this->updateGlobalDebugLevel(); 345 } 346 347 void OutputHandler::updateGlobalDebugLevel() 348 { 349 int globalSoftDebugLevel = -1; 350 std::vector<OutputListener*>::const_iterator it = this->listeners_.begin(); 351 for (; it != this->listeners_.end(); ++it) 352 globalSoftDebugLevel = std::max(globalSoftDebugLevel, (*it)->softDebugLevel_); 353 300 354 OutputHandler::softDebugLevel_s = globalSoftDebugLevel; 301 355 }
Note: See TracChangeset
for help on using the changeset viewer.