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


schunk_svh_driver
Author(s): Georg Heppner
autogenerated on Fri Aug 28 2015 12:59:19