Changeset 106:cae63ebd430e in rrlib_logging


Ignore:
Timestamp:
10.09.2013 15:50:53 (7 years ago)
Author:
Tobias Föhst <foehst@…>
Branch:
default
Phase:
public
Message:

Added first version of speech synthesis support. Therefor changed streambuffer implementation and sink management.

Files:
12 added
2 deleted
13 edited

Legend:

Unmodified
Added
Removed
  • configuration.cpp

    r101 r106  
    3939#define __rrlib__logging__include_guard__ 
    4040#include "rrlib/logging/configuration/tDomainRegistry.h" 
     41#include "rrlib/logging/sinks/tSink.h" 
    4142 
    4243#include "rrlib/logging/messages.h" 
     
    242243  } 
    243244 
    244   bool sinks_configured = false; 
    245245  if (node.HasAttribute("sink")) 
    246246  { 
    247     sinks_configured = true; 
     247    RRLIB_LOG_PRINT(WARNING, "Use of the sink attribute in xml configuration for rrlib_logging is deprecated. Use sink taggroup instead."); 
    248248    configuration.SetSinkMask(1 << node.GetEnumAttribute<tLogSink>("sink")); 
    249249  } 
     
    254254    if (it->Name() == "sink") 
    255255    { 
    256       if (sinks_configured) 
    257       { 
    258         RRLIB_LOG_PRINT(ERROR, "Sink already configured in domain element!"); 
    259         return false; 
    260       } 
    261       sink_mask |= 1 << it->GetEnumAttribute<tLogSink>("output"); 
     256      if (it->HasAttribute("output")) 
     257      { 
     258        sink_mask |= 1 << it->GetEnumAttribute<tLogSink>("output"); 
     259      } 
    262260    } 
    263261  } 
    264262  if (sink_mask != 0) 
    265263  { 
     264    RRLIB_LOG_PRINT(WARNING, "Use of the output attribute in <sink> is deprecated. Use <stream>, <file>, etc. instead."); 
    266265    configuration.SetSinkMask(sink_mask); 
     266  } 
     267 
     268  for (xml::tNode::const_iterator it = node.ChildrenBegin(); it != node.ChildrenEnd(); ++it) 
     269  { 
     270    if (it->Name() == "sink") 
     271    { 
     272      configuration.ClearSinks(); 
     273      for (xml::tNode::const_iterator sink = it->ChildrenBegin(); sink != sink->ChildrenEnd(); ++sink) 
     274      { 
     275        configuration.AddSink(std::shared_ptr<sinks::tSink>(sinks::tSinkFactory::Instance().Create(sink->Name(), *sink, configuration))); 
     276      } 
     277    } 
    267278  } 
    268279 
  • configuration.h

    r101 r106  
    8181void SetDomainMaxMessageLevel(const std::string &domain_name, tLogLevel level, const tDefaultConfigurationContext &default_context = cDEFAULT_CONTEXT); 
    8282 
    83 void SetDomainSink(const std::string &domain_name, tLogSink sink_1, tLogSink sink_2 = (tLogSink)0, tLogSink sink_3 = (tLogSink)0, tLogSink sink_4 = (tLogSink)0, const tDefaultConfigurationContext &default_context = cDEFAULT_CONTEXT); 
     83void SetDomainSink(const std::string &domain_name, tLogSink sink_1, tLogSink sink_2 = (tLogSink)0, tLogSink sink_3 = (tLogSink)0, tLogSink sink_4 = (tLogSink)0, const tDefaultConfigurationContext &default_context = cDEFAULT_CONTEXT) __attribute__((deprecated)); 
    8484 
    8585void PrintDomainConfigurations(); 
  • configuration/tConfiguration.cpp

    r105 r106  
    3636#include <cstring> 
    3737#include <sstream> 
     38#include <iostream> 
    3839 
    3940//---------------------------------------------------------------------- 
     
    8283    prints_location(parent ? parent->prints_location : default_context.cPRINTS_LOCATION), 
    8384    max_message_level(parent ? parent->max_message_level : default_context.cMAX_LOG_LEVEL), 
    84     sink_mask(parent ? parent->sink_mask | cLOG_SINK_COMBINED_FILE_CHILD_MASK : default_context.cSINK_MASK), 
     85    sinks(parent ? parent->sinks : std::vector<std::shared_ptr<sinks::tSink>>()), 
    8586    stream_buffer_ready(false) 
    8687{ 
     
    9394tConfiguration::~tConfiguration() 
    9495{ 
    95   if (this->file_stream.is_open()) 
    96   { 
    97     this->file_stream.close(); 
    98   } 
    99  
    10096  for (auto it = this->children.begin(); it != this->children.end(); ++it) 
    10197  { 
     
    169165void tConfiguration::SetSinkMask(int sink_mask) 
    170166{ 
    171   this->sink_mask = sink_mask; 
     167  this->ClearSinks(); 
     168  if (sink_mask | eLOG_SINK_STDOUT) 
     169  { 
     170    xml::tNode node; 
     171    node.SetAttribute("id", "stdout"); 
     172    this->AddSink(std::shared_ptr<sinks::tSink>(sinks::tSinkFactory::Instance().Create("stream", node, *this))); 
     173  } 
     174  if (sink_mask | eLOG_SINK_STDERR) 
     175  { 
     176    xml::tNode node; 
     177    node.SetAttribute("id", "stderr"); 
     178    this->AddSink(std::shared_ptr<sinks::tSink>(sinks::tSinkFactory::Instance().Create("stream", node, *this))); 
     179  } 
     180  if (sink_mask | eLOG_SINK_FILE) 
     181  { 
     182    std::cerr << "INFO: The meaning of this sink changed to be the same as combined file. There will be one file for the whole subtree starting at " << this->GetFullQualifiedName() << std::endl; 
     183    xml::tNode node; 
     184    this->AddSink(std::shared_ptr<sinks::tSink>(sinks::tSinkFactory::Instance().Create("file", node, *this))); 
     185  } 
     186  if (sink_mask | eLOG_SINK_COMBINED_FILE) 
     187  { 
     188    xml::tNode node; 
     189    this->AddSink(std::shared_ptr<sinks::tSink>(sinks::tSinkFactory::Instance().Create("file", node, *this))); 
     190  } 
     191} 
     192 
     193//---------------------------------------------------------------------- 
     194// tConfiguration ClearSinks 
     195//---------------------------------------------------------------------- 
     196void tConfiguration::ClearSinks() 
     197{ 
     198  this->sinks.clear(); 
    172199  this->stream_buffer_ready = false; 
    173200 
    174   sink_mask |= cLOG_SINK_COMBINED_FILE_CHILD_MASK; 
    175  
    176   for (auto it = this->children.begin(); it != this->children.end(); ++it) 
    177   { 
    178     (*it)->SetSinkMask(sink_mask); 
     201  for (auto it = this->children.begin(); it != this->children.end(); ++it) 
     202  { 
     203    (*it)->ClearSinks(); 
     204  } 
     205} 
     206 
     207//---------------------------------------------------------------------- 
     208// tConfiguration AddSink 
     209//---------------------------------------------------------------------- 
     210void tConfiguration::AddSink(std::shared_ptr<sinks::tSink> sink) 
     211{ 
     212  this->sinks.push_back(sink); 
     213  this->stream_buffer_ready = false; 
     214 
     215  for (auto it = this->children.begin(); it != this->children.end(); ++it) 
     216  { 
     217    (*it)->AddSink(sink); 
    179218  } 
    180219} 
     
    301340{ 
    302341  this->stream_buffer.Clear(); 
    303   if (this->sink_mask & (1 << eLOG_SINK_STDOUT)) 
    304   { 
    305     this->stream_buffer.AddStream(std::cout); 
    306   } 
    307   if (this->sink_mask & (1 << eLOG_SINK_STDERR)) 
    308   { 
    309     this->stream_buffer.AddStream(std::cerr); 
    310   } 
    311   if (this->sink_mask & (1 << eLOG_SINK_FILE)) 
    312   { 
    313     this->stream_buffer.AddStream(this->FileStream()); 
    314   } 
    315   if (this->sink_mask & (1 << eLOG_SINK_COMBINED_FILE)) 
    316   { 
    317     const tConfiguration *configuration = this; 
    318     while (configuration->parent && configuration->sink_mask & cLOG_SINK_COMBINED_FILE_CHILD_MASK) 
    319     { 
    320       configuration = configuration->parent; 
    321     } 
    322     this->stream_buffer.AddStream(configuration->FileStream()); 
     342  for (auto sink = this->sinks.begin(); sink != this->sinks.end(); ++sink) 
     343  { 
     344    this->stream_buffer.AddSink((*sink)->GetStreamBuffer()); 
    323345  } 
    324346 
     
    327349 
    328350//---------------------------------------------------------------------- 
    329 // tConfiguration FileStream 
    330 //---------------------------------------------------------------------- 
    331 std::ofstream &tConfiguration::FileStream() const 
    332 { 
    333   if (!this->file_stream.is_open()) 
    334   { 
    335     this->OpenFileStream(); 
    336   } 
    337  
    338   return this->file_stream; 
    339 } 
    340  
    341 //---------------------------------------------------------------------- 
    342 // tConfiguration OpenFileStream 
    343 //---------------------------------------------------------------------- 
    344 void tConfiguration::OpenFileStream() const 
    345 { 
    346   const std::string &file_name_prefix(tDomainRegistry::Instance().LogFilenamePrefix()); 
    347   if (file_name_prefix.length() == 0) 
    348   { 
    349     std::stringstream message; 
    350     message << "RRLib Logging >> Prefix for log filenames not set. Can not use eLOG_SINK_FILE or eLOG_SINK_COMBINED_FILE." << std::endl 
    351             << "                 Consider calling e.g. rrlib::logging::SetLogFilenamePrefix(basename(argv[0])) from main." << std::endl; 
    352     throw std::runtime_error(message.str()); 
    353   } 
    354  
    355   std::string fqdn = this->GetFullQualifiedName(); 
    356   std::string file_name(file_name_prefix + (fqdn != "." ? fqdn : "") + ".log"); 
    357   this->file_stream.open(file_name.c_str(), std::ios::out | std::ios::trunc); 
    358   if (!this->file_stream.is_open()) 
    359   { 
    360     std::stringstream message; 
    361     message << "RRLib Logging >> Could not open file `" << file_name << "'!" << std::endl; 
    362     throw std::runtime_error(message.str()); 
    363   } 
    364 } 
    365  
    366 //---------------------------------------------------------------------- 
    367351// End of namespace declaration 
    368352//---------------------------------------------------------------------- 
  • configuration/tConfiguration.h

    r105 r106  
    6666#include <string> 
    6767#include <list> 
    68 #include <fstream> 
     68#include <memory> 
    6969#include <mutex> 
    7070 
     
    7373//---------------------------------------------------------------------- 
    7474#include "rrlib/logging/log_levels.h" 
    75 #include "rrlib/logging/messages/tStreamBuffer.h" 
     75#include "rrlib/logging/messages/tFanOutBuffer.h" 
     76#include "rrlib/logging/sinks/tSink.h" 
    7677 
    7778//---------------------------------------------------------------------- 
     
    100101  eLOG_SINK_COMBINED_FILE,   //!< Messages are printed into one combined file 
    101102  eLOG_SINK_DIMENSION        //!< Endmarker and dimension of tLogSink 
    102 }; 
     103} __attribute__((deprecated)); 
    103104 
    104105struct tDefaultConfigurationContext 
     
    109110  const bool cPRINTS_LOCATION; 
    110111  const tLogLevel cMAX_LOG_LEVEL; 
    111   const int cSINK_MASK; 
    112112}; 
    113113#ifdef RRLIB_LOGGING_LESS_OUTPUT 
    114114static const tDefaultConfigurationContext cDEFAULT_CONTEXT 
    115115{ 
    116   false, false, false, false, tLogLevel::WARNING, 1 << eLOG_SINK_STDOUT 
     116  false, false, false, false, tLogLevel::WARNING 
    117117}; 
    118118#else 
    119119static const tDefaultConfigurationContext cDEFAULT_CONTEXT 
    120120{ 
    121   false, false, false, true, tLogLevel::DEBUG, 1 << eLOG_SINK_STDOUT 
     121  false, false, false, true, tLogLevel::DEBUG 
    122122}; 
    123123#endif 
     
    161161  void SetPrintsLocation(bool value); 
    162162  void SetMaxMessageLevel(tLogLevel level); 
    163   void SetSinkMask(int sink_mask); 
     163  void SetSinkMask(int sink_mask) __attribute__((deprecated)); 
     164  void ClearSinks(); 
     165  void AddSink(std::shared_ptr<sinks::tSink> sink); 
    164166 
    165167  inline bool PrintsName() const 
     
    188190  } 
    189191 
    190   inline tStreamBuffer &StreamBuffer() const 
     192  inline tFanOutBuffer &StreamBuffer() const 
    191193  { 
    192194    if (!this->stream_buffer_ready) 
     
    194196      this->PrepareStreamBuffer(); 
    195197    } 
    196  
    197198    return this->stream_buffer; 
    198199  } 
     
    218219  tLogLevel max_message_level; 
    219220 
    220   int sink_mask; 
     221  std::vector<std::shared_ptr<sinks::tSink>> sinks; 
    221222  mutable bool stream_buffer_ready; 
    222   mutable std::ofstream file_stream; 
    223   mutable tStreamBuffer stream_buffer; 
     223  mutable tFanOutBuffer stream_buffer; 
    224224 
    225225  mutable std::list<tConfiguration *> children; 
     
    244244  void PrepareStreamBuffer() const; 
    245245 
    246   std::ofstream &FileStream() const; 
    247  
    248   void OpenFileStream() const; 
    249  
    250246}; 
    251247 
  • configuration/tDomainRegistry.cpp

    r101 r106  
    4343//---------------------------------------------------------------------- 
    4444 
     45#include "rrlib/logging/sinks/tStream.h" 
     46#include "rrlib/logging/sinks/tFile.h" 
     47 
     48#ifdef _LIB_RRLIB_LOGGING_SINKS_SPEECH_SYNTHESIS_PRESENT_ 
     49#include "rrlib/logging/sinks/tSpeechSynthesis.h" 
     50#endif 
     51 
    4552//---------------------------------------------------------------------- 
    4653// Debugging 
     
    104111    return a.length() > b.length(); 
    105112  }); 
     113 
     114 
     115  sinks::tSinkFactory::Instance().Register<sinks::tStream>("stream"); 
     116  sinks::tSinkFactory::Instance().Register<sinks::tFile>("file"); 
     117 
     118#ifdef _LIB_RRLIB_LOGGING_SINKS_SPEECH_SYNTHESIS_PRESENT_ 
     119  sinks::tSinkFactory::Instance().Register<sinks::tSpeechSynthesis>("speech_synthesis"); 
     120#endif 
     121 
    106122} 
    107123 
  • configuration/tDomainRegistry.h

    r101 r106  
    8080// Forward declarations / typedefs / enums 
    8181//---------------------------------------------------------------------- 
     82class tDomainRegistryImplementation; 
     83typedef design_patterns::tSingletonHolder<tDomainRegistryImplementation, design_patterns::singleton::Longevity> tDomainRegistry; 
     84inline unsigned int GetLongevity(tDomainRegistryImplementation *) 
     85{ 
     86  return 0xFFFFFFFF; 
     87} 
    8288 
    8389//---------------------------------------------------------------------- 
    8490// Class declaration 
    8591//---------------------------------------------------------------------- 
    86 //! The central management facility for logging domains and theirconfiguration 
     92//! The central management facility for logging domains and their configuration 
    8793/*! In RRLib logging messages can be send via several logging domains. 
    8894 *  These have to be created and maintained using a single instance of 
     
    215221}; 
    216222 
    217 typedef design_patterns::tSingletonHolder<tDomainRegistryImplementation, design_patterns::singleton::Longevity> tDomainRegistry; 
    218 inline unsigned int GetLongevity(tDomainRegistryImplementation *) 
    219 { 
    220   return 0xFFFFFFFF; 
    221 } 
    222  
    223223//---------------------------------------------------------------------- 
    224224// End of namespace declaration 
  • make.xml

    r102 r106  
    88      configuration/*.cpp 
    99      messages/*.cpp 
     10      sinks/tFile.cpp 
     11      sinks/tStream.cpp 
    1012      configuration.cpp 
     13      default_log_description.cpp 
    1114      messages.h 
     15    </sources> 
     16  </rrlib> 
     17 
     18  <rrlib name="logging_log_levels"> 
     19    <sources> 
    1220      log_levels.h 
    13       default_log_description.cpp 
     21    </sources> 
     22  </rrlib> 
     23   
     24  <rrlib name="logging_sinks"> 
     25    <sources> 
     26      sinks/tSink.cpp 
     27    </sources> 
     28  </rrlib> 
     29 
     30  <rrlib name="logging_sinks_speech_synthesis" optional="true"> 
     31    <sources> 
     32      sinks/tSpeechSynthesis.cpp 
    1433    </sources> 
    1534  </rrlib> 
  • messages/implementation.cpp

    r101 r106  
    9595// SetColor 
    9696//---------------------------------------------------------------------- 
    97 void SetColor(tStreamBuffer &stream_buffer, tLogLevel level) 
     97void SetColor(tFormattingBuffer &stream_buffer, tLogLevel level) 
    9898{ 
    9999  switch (level) 
  • messages/implementation.h

    r101 r106  
    6767void SendFormattedTimeToStream(tStream &stream); 
    6868void SendFormattedDomainNameToStream(tStream &stream, const std::string &domain_name); 
    69 void SetColor(tStreamBuffer &stream_buffer, tLogLevel level); 
     69void SetColor(tFormattingBuffer &stream_buffer, tLogLevel level); 
    7070void SendFormattedLevelToStream(tStream &stream, tLogLevel level); 
    7171void SendFormattedLocationToStream(tStream &stream, const char *filename, unsigned int line); 
     
    9999  } 
    100100 
    101   tStream stream(domain_configuration.StreamBuffer()); 
     101  tStream stream(&domain_configuration.StreamBuffer()); 
    102102  domain_configuration.StreamBuffer().InitializeMultiLinePadding(); 
    103103 
  • messages/tStream.cpp

    r101 r106  
    3939// Internal includes with "" 
    4040//---------------------------------------------------------------------- 
     41#include "rrlib/logging/messages/tFormattingBuffer.h" 
    4142 
    4243//---------------------------------------------------------------------- 
     
    5960// Forward declarations / typedefs / enums 
    6061//---------------------------------------------------------------------- 
    61 typedef design_patterns::tSingletonHolder<std::mutex, design_patterns::singleton::NoDestruction> tStreamMutex; 
     62typedef design_patterns::tSingletonHolder<std::mutex> tStreamMutex; 
    6263 
    6364//---------------------------------------------------------------------- 
     
    7273// tStream constructors 
    7374//---------------------------------------------------------------------- 
    74 tStream::tStream(tStreamBuffer &stream_buffer) 
    75   : stream(&stream_buffer), 
     75tStream::tStream(std::streambuf *stream_buffer) 
     76  : stream(stream_buffer), 
    7677    lock(tStreamMutex::Instance()) 
    7778{} 
     
    8283tStream::~tStream() 
    8384{ 
    84   tStreamBuffer *buffer = dynamic_cast<tStreamBuffer *>(this->stream.rdbuf()); 
     85  tFormattingBuffer *buffer = dynamic_cast<tFormattingBuffer *>(this->stream.rdbuf()); 
    8586  if (buffer && buffer->EndsWithNewline()) 
    8687  { 
  • messages/tStream.h

    r102 r106  
    6666// Internal includes with "" 
    6767//---------------------------------------------------------------------- 
    68 #include "rrlib/logging/messages/tStreamBuffer.h" 
    6968 
    7069//---------------------------------------------------------------------- 
     
    118117   * \param stream   The std::ostream that is used via this proxy 
    119118   */ 
    120   explicit tStream(tStreamBuffer &stream_buffer); 
     119  explicit tStream(std::streambuf *stream_buffer); 
    121120 
    122121  /*! The ctor of tStream 
     
    125124   */ 
    126125  ~tStream(); 
    127  
    128   /*! Implicit conversion to std::ostream for e.g. std::ostream_iterator 
    129    * 
    130    * To use this proxy class together with e.g. std::copy, which needs 
    131    * a std::ostream_iterator, this method is implemented. 
    132    * 
    133    * \returns A reference to the underlying std::ostream 
    134    */ 
    135   inline operator std::ostream &() 
    136   { 
    137     return this->stream; 
    138   } 
    139126 
    140127  /*! Streaming operator (forwarder) 
  • test/logging_config.xml

    r76 r106  
    33<rrlib_logging> 
    44  <domain name="." prints_time="true" prints_name="true" prints_level="true" max_level="debug_verbose_3"> 
    5     <sink output="stdout" /> 
     5    <sink> 
     6      <stream id="stdout" /> 
     7<!-- 
     8      <file /> 
     9--> 
     10    </sink>     
    611  </domain> 
     12<!-- 
     13  <domain name=".speech_log" prints_time="false" prints_name="false" prints_level="false" prints_location="false" max_level="debug"> 
     14    <sink> 
     15      <speech_synthesis voice="festival://kal_diphone" /> 
     16    </sink> 
     17  </domain> 
     18--> 
    719</rrlib_logging> 
  • test/test_messages.cpp

    r101 r106  
    4141{ 
    4242#include <libgen.h> 
     43#include <unistd.h> 
    4344} 
    4445 
     
    151152  RRLIB_LOG_PRINT(WARNING, "0x", std::setw(20), std::setfill('0'), std::hex, 324); 
    152153 
    153   RRLIB_LOG_PRINT(ERROR, "Das hier ist ein mehrzeiliger\nFehler."); 
     154  RRLIB_LOG_PRINT(ERROR, "Das hier ist ein mehrzeiliger\nFehler.\n"); 
    154155  RRLIB_LOG_PRINT(USER, "Und das hier ein mehrzeiliger\nText fuer den lieben Benutzer."); 
    155156 
     
    169170  RRLIB_LOG_PRINT(DEBUG, "Mal noch einzelne Zeichen: ", 'a', '\0', 'b'); 
    170171 
     172  RRLIB_LOG_PRINT_TO(.speech_log, DEBUG, "This is a speech-log message"); 
     173 
     174  std::cout << "Waiting 10 seconds for optional speech synthesis" << std::endl; 
     175  sleep(10); 
     176 
    171177  rrlib::logging::PrintDomainConfigurations(); 
    172178  return EXIT_SUCCESS; 
Note: See TracChangeset for help on using the changeset viewer.