00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00022
00023 #include "icl_core_logging/LoggingManager.h"
00024
00025 #include <assert.h>
00026 #include <iostream>
00027 #include <sstream>
00028 #include <cstdlib>
00029
00030 #include <boost/lexical_cast.hpp>
00031 #include <boost/tuple/tuple.hpp>
00032
00033 #include <icl_core/os_lxrt.h>
00034 #include <icl_core_config/Config.h>
00035 #include "icl_core_logging/FileLogOutput.h"
00036 #include "icl_core_logging/LogStream.h"
00037 #include "icl_core_logging/StdLogOutput.h"
00038 #include "icl_core_config/GetoptParser.h"
00039 #include "icl_core_config/GetoptParameter.h"
00040
00041 namespace icl_core {
00042 namespace logging {
00043
00044 void LoggingManager::initialize()
00045 {
00046 if (!m_initialized)
00047 {
00048 m_initialized = true;
00049
00050
00051 ::icl_core::config::ConfigIterator output_stream_it =
00052 ::icl_core::config::find("\\/IclCore\\/Logging\\/(OutputStream.*)\\/(.*)");
00053 while (output_stream_it.next())
00054 {
00055 ::icl_core::String entry_name = output_stream_it.matchGroup(1);
00056 ::icl_core::String value_name = output_stream_it.matchGroup(2);
00057 if (value_name == "OutputStreamName")
00058 {
00059 m_output_stream_config[entry_name].output_stream_name = output_stream_it.value();
00060 }
00061 else if (value_name == "Name")
00062 {
00063 m_output_stream_config[entry_name].name = output_stream_it.value();
00064 }
00065 else if (value_name == "LogLevel")
00066 {
00067 if (!stringToLogLevel(output_stream_it.value(), m_output_stream_config[entry_name].log_level))
00068 {
00069 std::cerr << "LOGGING CONFIG ERROR: Illegal log level in " << output_stream_it.key() << std::endl;
00070 }
00071 }
00072 else if (value_name.substr(0, 9) == "LogStream")
00073 {
00074 m_output_stream_config[entry_name].log_streams.push_back(output_stream_it.value());
00075 }
00076 }
00077
00078
00079 ::icl_core::config::ConfigIterator log_stream_it =
00080 ::icl_core::config::find("\\/IclCore\\/Logging\\/(LogStream.*)\\/(.*)");
00081 while (log_stream_it.next())
00082 {
00083 ::icl_core::String entry_name = log_stream_it.matchGroup(1);
00084 ::icl_core::String value_name = log_stream_it.matchGroup(2);
00085 if (value_name == "Name")
00086 {
00087 m_log_stream_config[entry_name].name = log_stream_it.value();
00088 }
00089 else if (value_name == "LogLevel")
00090 {
00091 if (!stringToLogLevel(log_stream_it.value(), m_log_stream_config[entry_name].log_level))
00092 {
00093 std::cerr << "LOGGING CONFIG ERROR: Illegal log level in " << log_stream_it.key() << std::endl;
00094 }
00095 }
00096 }
00097 }
00098
00099 configure();
00100
00101
00102 icl_core::String quick_debug_filename;
00103 if (icl_core::config::paramOpt<icl_core::String>("quick-debug", quick_debug_filename))
00104 {
00105
00106 icl_core::String output_stream_name = "QuickDebug";
00107 LogOutputStreamMap::const_iterator find_it = m_log_output_streams.find(output_stream_name);
00108 if (find_it != m_log_output_streams.end())
00109 {
00110 size_t count = 0;
00111 do
00112 {
00113 ++count;
00114 find_it = m_log_output_streams.find(output_stream_name
00115 + boost::lexical_cast<icl_core::String>(count));
00116 }
00117 while (find_it != m_log_output_streams.end());
00118 output_stream_name = output_stream_name + boost::lexical_cast<icl_core::String>(count);
00119 }
00120
00121
00122 LogOutputStream *output_stream = new FileLogOutput(output_stream_name, quick_debug_filename,
00123 eLL_TRACE, true);
00124 m_log_output_streams[output_stream_name] = output_stream;
00125 QuickDebug::instance().addOutputStream(output_stream);
00126 QuickDebug::instance().m_initial_level = eLL_TRACE;
00127 }
00128
00129
00130 if (m_default_log_output != 0)
00131 {
00132 m_default_log_output->start();
00133 }
00134 for (LogOutputStreamMap::iterator output_stream_it = m_log_output_streams.begin();
00135 output_stream_it != m_log_output_streams.end();
00136 ++output_stream_it)
00137 {
00138 output_stream_it->second->start();
00139 }
00140 }
00141
00142 void LoggingManager::configure()
00143 {
00144
00145 if (m_output_stream_config.empty() && m_default_log_output == NULL)
00146 {
00147 m_default_log_output = StdLogOutput::create("Default", "/IclCore/Logging/Default");
00148 }
00149
00150
00151 for (LogStreamFactoryMap::iterator log_stream_it = m_log_stream_factories.begin();
00152 log_stream_it != m_log_stream_factories.end(); ++log_stream_it)
00153 {
00154 if (m_log_streams.find(log_stream_it->first) == m_log_streams.end())
00155 {
00156 registerLogStream((*log_stream_it->second)());
00157 }
00158 }
00159
00160
00161 if (!m_output_stream_config.empty() && m_default_log_output != NULL)
00162 {
00163 for (LogStreamMap::iterator it = m_log_streams.begin(); it != m_log_streams.end(); ++it)
00164 {
00165 it->second->removeOutputStream(m_default_log_output);
00166 }
00167
00168 m_default_log_output->shutdown();
00169 delete m_default_log_output;
00170 m_default_log_output = 0;
00171 }
00172
00173
00174 for (LogOutputStreamConfigMap::iterator loc_it = m_output_stream_config.begin();
00175 loc_it != m_output_stream_config.end(); ++loc_it)
00176 {
00177
00178
00179 if (loc_it->second.name == ::icl_core::String())
00180 {
00181 loc_it->second.name = loc_it->second.output_stream_name;
00182 }
00183
00184
00185 LogOutputStreamMap::const_iterator find_log_output_stream =
00186 m_log_output_streams.find(loc_it->second.name);
00187 if (find_log_output_stream == m_log_output_streams.end())
00188 {
00189 LogOutputStreamFactoryMap::const_iterator find_log_output_stream_factory =
00190 m_log_output_stream_factories.find(loc_it->second.output_stream_name);
00191 if (find_log_output_stream_factory == m_log_output_stream_factories.end())
00192 {
00193
00194
00195 continue;
00196 }
00197 LogOutputStream *log_output_stream =
00198 (*find_log_output_stream_factory->second)(loc_it->second.name,
00199 "/IclCore/Logging/" + loc_it->first,
00200 loc_it->second.log_level);
00201 boost::tuples::tie(find_log_output_stream, boost::tuples::ignore) =
00202 m_log_output_streams.insert(std::make_pair(loc_it->second.name, log_output_stream));
00203 }
00204
00205
00206 if (find_log_output_stream != m_log_output_streams.end())
00207 {
00208
00209
00210 if (loc_it->second.log_streams.empty())
00211 {
00212 for (LogStreamMap::iterator it = m_log_streams.begin(); it != m_log_streams.end(); ++it)
00213 {
00214 it->second->addOutputStream(find_log_output_stream->second);
00215 }
00216 }
00217 else
00218 {
00219 for (StringList::const_iterator it = loc_it->second.log_streams.begin();
00220 it != loc_it->second.log_streams.end(); ++it)
00221 {
00222 LogStreamMap::iterator find_it = m_log_streams.find(*it);
00223 if (find_it == m_log_streams.end())
00224 {
00225
00226
00227
00228 continue;
00229 }
00230 else
00231 {
00232 find_it->second->addOutputStream(find_log_output_stream->second);
00233 }
00234 }
00235 }
00236 }
00237 }
00238
00239
00240
00241 for (LogStreamConfigMap::const_iterator lsc_it = m_log_stream_config.begin();
00242 lsc_it != m_log_stream_config.end(); ++lsc_it)
00243 {
00244 LogStreamMap::iterator find_it = m_log_streams.find(lsc_it->second.name);
00245 if (find_it == m_log_streams.end())
00246 {
00247
00248
00249
00250 continue;
00251 }
00252 else
00253 {
00254 find_it->second->m_initial_level = lsc_it->second.log_level;
00255 }
00256 }
00257
00258
00259 if (icl_core::config::Getopt::instance().paramOptPresent("log-level"))
00260 {
00261 LogLevel initial_level = cDEFAULT_LOG_LEVEL;
00262 icl_core::String log_level = icl_core::config::Getopt::instance().paramOpt("log-level");
00263 if (!stringToLogLevel(log_level, initial_level))
00264 {
00265 std::cerr << "Illegal log level " << log_level << std::endl;
00266 std::cerr << "Valid levels are 'Trace', 'Debug', 'Info', 'Warning', 'Error' and 'Mute'." << std::endl;
00267 }
00268 else
00269 {
00270 if (m_default_log_output == NULL)
00271 {
00272 m_default_log_output = StdLogOutput::create("Default", "/IclCore/Logging/Default");
00273 }
00274 m_default_log_output->setLogLevel(initial_level);
00275
00276 for (LogStreamMap::iterator lsm_it = m_log_streams.begin(); lsm_it != m_log_streams.end(); ++lsm_it)
00277 {
00278 lsm_it->second->m_initial_level = initial_level;
00279 lsm_it->second->addOutputStream(m_default_log_output);
00280 }
00281
00282 for (LogOutputStreamMap::iterator los_it = m_log_output_streams.begin(); los_it
00283 != m_log_output_streams.end(); ++los_it)
00284 {
00285 los_it->second->setLogLevel(initial_level);
00286 }
00287 }
00288 }
00289 }
00290
00291 void LoggingManager::setLogLevel(icl_core::logging::LogLevel log_level)
00292 {
00293 for (LogStreamMap::iterator lsm_it = m_log_streams.begin(); lsm_it != m_log_streams.end(); ++lsm_it)
00294 {
00295 lsm_it->second->m_initial_level = log_level;
00296 }
00297
00298 for (LogOutputStreamMap::iterator los_it = m_log_output_streams.begin();
00299 los_it != m_log_output_streams.end(); ++los_it)
00300 {
00301 los_it->second->setLogLevel(log_level);
00302 }
00303 }
00304
00305 void LoggingManager::assertInitialized() const
00306 {
00307 if (!initialized())
00308 {
00309 assert(0);
00310 }
00311 }
00312
00313 void LoggingManager::registerLogOutputStream(const ::icl_core::String& name, LogOutputStreamFactory factory)
00314 {
00315 m_log_output_stream_factories[name] = factory;
00316 }
00317
00318 void LoggingManager::removeLogOutputStream(LogOutputStream *log_output_stream, bool remove_from_list)
00319 {
00320 for (LogStreamMap::iterator log_stream_it = m_log_streams.begin();
00321 log_stream_it != m_log_streams.end();
00322 ++log_stream_it)
00323 {
00324 log_stream_it->second->removeOutputStream(log_output_stream);
00325 }
00326
00327 if (remove_from_list)
00328 {
00329 m_log_output_streams.erase(log_output_stream->name());
00330 }
00331 }
00332
00333 void LoggingManager::registerLogStream(const icl_core::String& name, LogStreamFactory factory)
00334 {
00335 m_log_stream_factories[name] = factory;
00336 }
00337
00338 void LoggingManager::registerLogStream(LogStream *log_stream)
00339 {
00340 m_log_streams[log_stream->name()] = log_stream;
00341
00342 if (m_default_log_output != 0)
00343 {
00344 log_stream->addOutputStream(m_default_log_output);
00345 }
00346 }
00347
00348 void LoggingManager::removeLogStream(const icl_core::String& log_stream_name)
00349 {
00350 if (!m_shutdown_running)
00351 {
00352 m_log_streams.erase(log_stream_name);
00353 }
00354 }
00355
00356 LoggingManager::LoggingManager()
00357 {
00358 m_initialized = false;
00359 m_shutdown_running = false;
00360 m_default_log_output = NULL;
00361
00362 icl_core::String help_text =
00363 "Override the log level of all streams and connect them to stdout. "
00364 "Possible values are 'Trace', 'Debug', 'Info', 'Warning', 'Error' and 'Mute'.";
00365 icl_core::config::addParameter(icl_core::config::GetoptParameter("log-level:", "l", help_text));
00366 icl_core::config::addParameter(icl_core::config::GetoptParameter(
00367 "quick-debug:", "qd",
00368 "Activate the QuickDebug log stream and write it "
00369 "to the specified file."));
00370 }
00371
00372 LoggingManager::~LoggingManager()
00373 {
00374 shutdown();
00375 }
00376
00377 void LoggingManager::printConfiguration() const
00378 {
00379 std::cerr << "LoggingManager configuration:" << std::endl;
00380
00381 std::cerr << " Log output stream factories:" << std::endl;
00382 for (LogOutputStreamFactoryMap::const_iterator it = m_log_output_stream_factories.begin();
00383 it != m_log_output_stream_factories.end(); ++it)
00384 {
00385 std::cerr << " " << it->first << std::endl;
00386 }
00387
00388 std::cerr << " Log output streams:" << std::endl;
00389 if (m_default_log_output)
00390 {
00391 m_default_log_output->printConfiguration();
00392 }
00393 for (LogOutputStreamMap::const_iterator it = m_log_output_streams.begin();
00394 it != m_log_output_streams.end(); ++it)
00395 {
00396 it->second->printConfiguration();
00397 }
00398
00399 std::cerr << " Log streams:" << std::endl;
00400 for (LogStreamMap::const_iterator it = m_log_streams.begin(); it != m_log_streams.end(); ++it)
00401 {
00402 std::cerr << " " << it->first << " -> ";
00403 it->second->printConfiguration();
00404 std::cerr << std::endl;
00405 }
00406 }
00407
00408 void LoggingManager::changeLogFormat(const ::icl_core::String& name, const char *format)
00409 {
00410 for (LogOutputStreamMap::const_iterator it = m_log_output_streams.begin();
00411 it != m_log_output_streams.end(); ++it)
00412 {
00413 if (it->first == name)
00414 {
00415 it->second->changeLogFormat(format);
00416 }
00417 }
00418 }
00419
00420 void LoggingManager::shutdown()
00421 {
00422 m_initialized = false;
00423 m_shutdown_running = true;
00424
00425
00426
00427 if (m_default_log_output != 0)
00428 {
00429 removeLogOutputStream(m_default_log_output, false);
00430 m_default_log_output->shutdown();
00431 delete m_default_log_output;
00432 m_default_log_output = 0;
00433 }
00434
00435
00436
00437 for (LogOutputStreamMap::iterator output_stream_it = m_log_output_streams.begin();
00438 output_stream_it != m_log_output_streams.end();
00439 ++output_stream_it)
00440 {
00441 removeLogOutputStream(output_stream_it->second, false);
00442 output_stream_it->second->shutdown();
00443 delete output_stream_it->second;
00444 }
00445
00446
00447 m_log_output_streams.clear();
00448
00449
00450 for (LogStreamMap::iterator log_stream_it = m_log_streams.begin();
00451 log_stream_it != m_log_streams.end();
00452 ++log_stream_it)
00453 {
00454 delete log_stream_it->second;
00455 }
00456
00457
00458 m_log_streams.clear();
00459
00460 m_shutdown_running = false;
00461 }
00462
00464 #ifdef _IC_BUILDER_DEPRECATED_STYLE_
00465
00466 LoggingManager& LoggingManager::Instance()
00467 {
00468 return instance();
00469 }
00470
00474 void LoggingManager::Configure()
00475 {
00476 configure();
00477 }
00478
00482 void LoggingManager::Initialize()
00483 {
00484 initialize();
00485 }
00486
00490 bool LoggingManager::Initialized() const
00491 {
00492 return initialized();
00493 }
00494
00498 void LoggingManager::AssertInitialized() const
00499 {
00500 assertInitialized();
00501 }
00502
00506 void LoggingManager::RegisterLogOutputStream(const icl_core::String& name,
00507 LogOutputStreamFactory factory)
00508 {
00509 registerLogOutputStream(name, factory);
00510 }
00511
00515 void LoggingManager::RemoveLogOutputStream(LogOutputStream *log_output_stream,
00516 bool remove_from_list)
00517 {
00518 removeLogOutputStream(log_output_stream, remove_from_list);
00519 }
00520
00524 void LoggingManager::RegisterLogStream(const icl_core::String& name,
00525 LogStreamFactory factory)
00526 {
00527 registerLogStream(name, factory);
00528 }
00529
00533 void LoggingManager::RegisterLogStream(LogStream *log_stream)
00534 {
00535 registerLogStream(log_stream);
00536 }
00537
00541 void LoggingManager::RemoveLogStream(const icl_core::String& log_stream_name)
00542 {
00543 removeLogStream(log_stream_name);
00544 }
00545
00549 void LoggingManager::PrintConfiguration() const
00550 {
00551 printConfiguration();
00552 }
00553
00557 void LoggingManager::ChangeLogFormat(const icl_core::String& name,
00558 const char *format)
00559 {
00560 changeLogFormat(name, format);
00561 }
00562
00566 void LoggingManager::Shutdown()
00567 {
00568 shutdown();
00569 }
00570
00571 #endif
00572
00573
00574 namespace hidden {
00575
00576 LogOutputStreamRegistrar::LogOutputStreamRegistrar(const ::icl_core::String& name,
00577 LogOutputStreamFactory factory)
00578 {
00579 LoggingManager::instance().registerLogOutputStream(name, factory);
00580 }
00581
00582 LogStreamRegistrar::LogStreamRegistrar(const ::icl_core::String& name, LogStreamFactory factory)
00583 {
00584 LoggingManager::instance().registerLogStream(name, factory);
00585 }
00586
00587 }
00588
00589 LifeCycle::LifeCycle(int &argc, char *argv[])
00590 {
00591 icl_core::config::initialize(argc, argv, icl_core::config::Getopt::eCLC_Cleanup, icl_core::config::Getopt::ePRC_Relaxed);
00592 LoggingManager::instance().initialize();
00593 }
00594
00595 LifeCycle::~LifeCycle()
00596 {
00597 LoggingManager::instance().shutdown();
00598 }
00599
00600 }
00601 }