Changeset 74:0bf819108799 in rrlib_logging


Ignore:
Timestamp:
07.01.2012 19:41:51 (9 years ago)
Author:
Tobias Föhst <foehst@…>
Branch:
default
Phase:
public
Message:

Added first part of new configuration interface

Files:
2 added
1 deleted
10 edited

Legend:

Unmodified
Added
Removed
  • configuration/tConfiguration.cpp

    r72 r74  
    6565//---------------------------------------------------------------------- 
    6666#ifdef _RRLIB_LOGGING_LESS_OUTPUT_ 
     67const bool cDEFAULT_PRINTS_NAME = false;                //!< Default prints name setting for reduced output mode 
    6768const bool cDEFAULT_PRINTS_TIME = false;                //!< Default prints time setting for reduced output mode 
    68 const bool cDEFAULT_PRINTS_NAME = false;                //!< Default prints name setting for reduced output mode 
    6969const bool cDEFAULT_PRINTS_LEVEL = false;               //!< Default prints level setting for reduced output mode 
    7070const bool cDEFAULT_PRINTS_LOCATION = false;            //!< Default prints location setting for reduced output mode 
     
    7272const int cDEFAULT_SINK_MASK = 1 << eLS_STDOUT;         //!< Default output stream mask 
    7373#else 
     74const bool cDEFAULT_PRINTS_NAME = false;                //!< Default prints name setting for normal output mode 
    7475const bool cDEFAULT_PRINTS_TIME = false;                //!< Default prints time setting for normal output mode 
    75 const bool cDEFAULT_PRINTS_NAME = false;                //!< Default prints name setting for normal output mode 
    7676const bool cDEFAULT_PRINTS_LEVEL = false;               //!< Default prints level setting for normal output mode 
    7777const bool cDEFAULT_PRINTS_LOCATION = true;             //!< Default prints location setting for normal output mode 
     
    9090    : parent(parent), 
    9191    name(name), 
    92     prints_time(cDEFAULT_PRINTS_TIME), 
    93     prints_name(cDEFAULT_PRINTS_NAME), 
    94     prints_level(cDEFAULT_PRINTS_LEVEL), 
    95     prints_location(cDEFAULT_PRINTS_LOCATION), 
    96     max_message_level(cDEFAULT_MAX_LOG_LEVEL)//, 
     92    prints_name(parent ? parent->prints_name : cDEFAULT_PRINTS_NAME), 
     93    prints_time(parent ? parent->prints_time : cDEFAULT_PRINTS_TIME), 
     94    prints_level(parent ? parent->prints_level : cDEFAULT_PRINTS_LEVEL), 
     95    prints_location(parent ? parent->prints_location : cDEFAULT_PRINTS_LOCATION), 
     96    max_message_level(parent ? parent->max_message_level : cDEFAULT_MAX_LOG_LEVEL)//, 
    9797//    sink_mask(cDEFAULT_SINK_MASK) 
    9898{ 
     
    108108  { 
    109109    delete *it; 
     110  } 
     111} 
     112 
     113//---------------------------------------------------------------------- 
     114// tConfiguration SetPrintsName 
     115//---------------------------------------------------------------------- 
     116void tConfiguration::SetPrintsName(bool value) 
     117{ 
     118  std::cout << "SetPrintsName: " << value << " in " << this->GetFullQualifiedName() << std::endl; 
     119  this->prints_name = value; 
     120  for (auto it = this->children.begin(); it != this->children.end(); ++it) 
     121  { 
     122    (*it)->SetPrintsName(value); 
     123  } 
     124} 
     125 
     126//---------------------------------------------------------------------- 
     127// tConfiguration SetPrintsTime 
     128//---------------------------------------------------------------------- 
     129void tConfiguration::SetPrintsTime(bool value) 
     130{ 
     131  this->prints_time = value; 
     132  for (auto it = this->children.begin(); it != this->children.end(); ++it) 
     133  { 
     134    (*it)->SetPrintsTime(value); 
     135  } 
     136} 
     137 
     138//---------------------------------------------------------------------- 
     139// tConfiguration SetPrintsLevel 
     140//---------------------------------------------------------------------- 
     141void tConfiguration::SetPrintsLevel(bool value) 
     142{ 
     143  this->prints_level = value; 
     144  for (auto it = this->children.begin(); it != this->children.end(); ++it) 
     145  { 
     146    (*it)->SetPrintsLevel(value); 
     147  } 
     148} 
     149 
     150//---------------------------------------------------------------------- 
     151// tConfiguration SetPrintsLocation 
     152//---------------------------------------------------------------------- 
     153void tConfiguration::SetPrintsLocation(bool value) 
     154{ 
     155  this->prints_location = value; 
     156  for (auto it = this->children.begin(); it != this->children.end(); ++it) 
     157  { 
     158    (*it)->SetPrintsLocation(value); 
     159  } 
     160} 
     161 
     162//---------------------------------------------------------------------- 
     163// tConfiguration SetMaxMessageLevel 
     164//---------------------------------------------------------------------- 
     165void tConfiguration::SetMaxMessageLevel(tLogLevel level) 
     166{ 
     167  this->max_message_level = level; 
     168  for (auto it = this->children.begin(); it != this->children.end(); ++it) 
     169  { 
     170    (*it)->SetMaxMessageLevel(level); 
    110171  } 
    111172} 
  • configuration/tConfiguration.h

    r71 r74  
    9696  eLS_STDERR,          //!< Messages are printed to stderr 
    9797  eLS_FILE,            //!< Messages are printed to one file per domain 
    98   eLS_COMBINED_FILE,   //!< Messages are collected in one file per recursively configured subtree 
     98  eLS_FILE_SUBTREE,    //!< Messages are collected in one file per subtree 
    9999  eLS_DIMENSION        //!< Endmarker and dimension of eLogStream 
    100100}; 
     
    133133  } 
    134134 
     135  void SetPrintsName(bool value); 
     136  void SetPrintsTime(bool value); 
     137  void SetPrintsLevel(bool value); 
     138  void SetPrintsLocation(bool value); 
     139  void SetMaxMessageLevel(tLogLevel level); 
     140 
     141  inline bool PrintsName() const 
     142  { 
     143    return this->prints_name; 
     144  } 
     145 
    135146  inline bool PrintsTime() const 
    136147  { 
     
    138149  } 
    139150 
    140   inline bool PrintsName() const 
    141   { 
    142     return this->prints_name; 
    143   } 
    144  
    145151  inline bool PrintsLevel() const 
    146152  { 
     
    162168    return this->stream_buffer; 
    163169  } 
    164  
    165   const tConfiguration &GetConfigurationByName(const char *domain_name) const; 
    166170 
    167171//---------------------------------------------------------------------- 
     
    173177  std::string name; 
    174178 
     179  bool prints_name; 
    175180  bool prints_time; 
    176   bool prints_name; 
    177181  bool prints_level; 
    178182  bool prints_location; 
    179183 
    180184  tLogLevel max_message_level; 
    181 //  int sink_mask; 
     185  int sink_mask; 
    182186 
    183187  mutable tStreamBuffer stream_buffer; 
     
    188192 
    189193  tConfiguration(const tConfiguration &other); 
     194 
    190195  tConfiguration &operator = (const tConfiguration other); 
     196 
     197  const tConfiguration &GetConfigurationByName(const char *domain_name) const; 
    191198 
    192199  const tConfiguration &GetConfigurationByFilename(const char *filename) const; 
  • configuration/tDomainRegistry.cpp

    r73 r74  
    137137// tDomainRegistryImplementation GetConfiguration 
    138138//---------------------------------------------------------------------- 
    139 const tConfiguration &tDomainRegistryImplementation::GetConfiguration(const char *filename, const char *domain_name) const 
     139const tConfiguration &tDomainRegistryImplementation::GetConfiguration(const char *filename, const char *domain_name) 
    140140{ 
    141141  if (domain_name) 
    142142  { 
     143    assert(*domain_name && "domain_name must be zero or not empty!"); 
    143144    if (domain_name[0] == '.') 
    144145    { 
    145146      assert(this->global_configuration); 
    146       this->global_configuration->GetConfigurationByName(domain_name + 1); 
     147      return (domain_name[1] == 0) ? *this->global_configuration : this->global_configuration->GetConfigurationByName(domain_name + 1); 
    147148    } 
    148149    return tDomainRegistry::Instance().GetConfigurationByFilename(filename).GetConfigurationByName(domain_name); 
    149150  } 
    150151  return tDomainRegistry::Instance().GetConfigurationByFilename(filename); 
     152} 
     153 
     154//---------------------------------------------------------------------- 
     155// tDomainRegistryImplementation SetLogFilenamePrefix 
     156//---------------------------------------------------------------------- 
     157void tDomainRegistryImplementation::SetLogFilenamePrefix(const std::string &log_filename_prefix) 
     158{ 
     159  assert(log_filename_prefix.length() > 0); 
     160  this->log_filename_prefix = log_filename_prefix; 
     161} 
     162 
     163//---------------------------------------------------------------------- 
     164// tDomainRegistryImplementation LogFilenamePrefix 
     165//---------------------------------------------------------------------- 
     166const std::string &tDomainRegistryImplementation::LogFilenamePrefix() const 
     167{ 
     168  if (this->log_filename_prefix.length() == 0) 
     169  { 
     170    throw std::logic_error("tDomainRegistryImplementation::LogFilenamePrefix() called before filename prefix was set. Consider calling rrlib::logging::SetLogFilenamePrefix(basename(argv[0])) from your main function."); 
     171  } 
     172  return this->log_filename_prefix; 
     173} 
     174 
     175//---------------------------------------------------------------------- 
     176// tDomainRegistryImplementation UpdateMaxDomainNameLength 
     177//---------------------------------------------------------------------- 
     178void tDomainRegistryImplementation::UpdateMaxDomainNameLength(size_t added_domain_name_length) 
     179{ 
     180  this->max_domain_name_length = std::max(this->max_domain_name_length, added_domain_name_length); 
    151181} 
    152182 
     
    189219} 
    190220 
    191 //---------------------------------------------------------------------- 
    192 // tDomainRegistryImplementation UpdateMaxDomainNameLength 
    193 //---------------------------------------------------------------------- 
    194 void tDomainRegistryImplementation::UpdateMaxDomainNameLength(size_t added_domain_name_length) 
    195 { 
    196   this->max_domain_name_length = std::max(this->max_domain_name_length, added_domain_name_length); 
    197 } 
    198  
    199221////---------------------------------------------------------------------- 
    200222//// tDomainRegistry ConfigureFromFile 
     
    218240//#endif 
    219241//} 
    220 // 
     242 
     243 
     244 
    221245//#ifdef _LIB_RRLIB_XML2_WRAPPER_PRESENT_ 
    222246// 
  • configuration/tDomainRegistry.h

    r73 r74  
    115115  ~tDomainRegistryImplementation(); 
    116116 
    117   const tConfiguration &GetConfiguration(const char *filename, const char *domain_name = 0) const; 
    118  
    119   const tConfiguration &GetConfigurationByFilename(const char *filename) const; 
    120  
    121 //  /*! Set a prefix for filenames that are created as log 
    122 //   * 
    123 //   * If their output stream is set to eMS_FILE domains create a log 
    124 //   * file with their name. Additionally, this name must have a prefix 
    125 //   * to distinguish between programs, processes or runs. 
    126 //   * 
    127 //   * The method could be called with basename(argv[0]) in main, for example. 
    128 //   * 
    129 //   * \param file_name_prefix   The string that should be used as prefix 
    130 //   */ 
    131 //  inline void SetOutputFileNamePrefix(const std::string &file_name_prefix) 
    132 //  { 
    133 //    assert(file_name_prefix.length() > 0); 
    134 //    this->file_name_prefix = file_name_prefix; 
    135 //  } 
    136 // 
    137 //  /*! Get the configured file name prefix 
    138 //   * 
    139 //   * Get the file name prefix that was configured 
    140 //   * 
    141 //   * \returns The stored prefix 
    142 //   */ 
    143 //  inline const std::string &GetOutputFileNamePrefix() const 
    144 //  { 
    145 //    return this->file_name_prefix; 
    146 //  } 
     117  const tConfiguration &GetConfiguration(const char *filename, const char *domain_name = 0); 
     118 
     119  /*! Set a prefix for filenames that are created as log 
     120   * 
     121   * If their output stream is set to eMS_FILE domains create a log 
     122   * file with their name. Additionally, this name must have a prefix 
     123   * to distinguish between programs, processes or runs. 
     124   * 
     125   * The method could be called with basename(argv[0]) in main, for example. 
     126   * 
     127   * \param filename_prefix   The string that should be used as prefix 
     128   */ 
     129  void SetLogFilenamePrefix(const std::string &filename_prefix); 
     130 
     131  /*! Get the configured file name prefix 
     132   * 
     133   * Get the file name prefix that was configured 
     134   * 
     135   * \returns The stored prefix 
     136   */ 
     137  const std::string &LogFilenamePrefix() const; 
    147138 
    148139  /*! Set if columns in prefix output should be padded or not 
     
    237228  mutable tConfiguration *global_configuration; 
    238229 
    239 //  std::string file_name_prefix; 
     230  std::string log_filename_prefix; 
    240231  size_t max_domain_name_length; 
    241232  bool pad_prefix_columns; 
  • make.xml

    r68 r74  
    88      configuration/*.cpp 
    99      messages/*.cpp 
     10      configuration.cpp 
    1011      messages.h 
    1112      log_levels.h 
  • messages/implementation.cpp

    r72 r74  
    100100  { 
    101101  case eLL_ERROR: 
    102     stream_buffer.SetColor(eLSBE_BOLD, eLSBC_RED); 
     102    stream_buffer.SetColor(eSBE_BOLD, eSBC_RED); 
    103103    break; 
    104104  case eLL_WARNING: 
    105     stream_buffer.SetColor(eLSBE_BOLD, eLSBC_BLUE); 
     105    stream_buffer.SetColor(eSBE_BOLD, eSBC_BLUE); 
    106106    break; 
    107107  case eLL_DEBUG_WARNING: 
    108     stream_buffer.SetColor(eLSBE_DARK, eLSBC_YELLOW); 
     108    stream_buffer.SetColor(eSBE_DARK, eSBC_YELLOW); 
    109109    break; 
    110110  case eLL_DEBUG: 
    111     stream_buffer.SetColor(eLSBE_DARK, eLSBC_GREEN); 
     111    stream_buffer.SetColor(eSBE_DARK, eSBC_GREEN); 
    112112    break; 
    113113  case eLL_DEBUG_VERBOSE_1: 
    114     stream_buffer.SetColor(eLSBE_REGULAR, eLSBC_CYAN); 
     114    stream_buffer.SetColor(eSBE_REGULAR, eSBC_CYAN); 
    115115    break; 
    116116  case eLL_DEBUG_VERBOSE_2: 
    117     stream_buffer.SetColor(eLSBE_REGULAR, eLSBC_CYAN); 
     117    stream_buffer.SetColor(eSBE_REGULAR, eSBC_CYAN); 
    118118    break; 
    119119  case eLL_DEBUG_VERBOSE_3: 
    120     stream_buffer.SetColor(eLSBE_REGULAR, eLSBC_CYAN); 
     120    stream_buffer.SetColor(eSBE_REGULAR, eSBC_CYAN); 
    121121    break; 
    122122  default: 
  • messages/tStreamBuffer.h

    r71 r74  
    7777enum tStreamBufferEffect 
    7878{ 
    79   eLSBE_REGULAR, 
    80   eLSBE_BOLD, 
    81   eLSBE_DARK, 
    82   eLSBE_UNDERLINED = 4, 
    83   eLSBE_BLINKING, 
    84   eLSBE_INVERTED = 7, 
    85   eLSBE_CONCEALED, 
    86   eLSBE_DIMENSION 
     79  eSBE_REGULAR, 
     80  eSBE_BOLD, 
     81  eSBE_DARK, 
     82  eSBE_UNDERLINED = 4, 
     83  eSBE_BLINKING, 
     84  eSBE_INVERTED = 7, 
     85  eSBE_CONCEALED, 
     86  eSBE_DIMENSION 
    8787}; 
    8888 
    8989enum tStreamBufferColor 
    9090{ 
    91   eLSBC_DEFAULT, 
    92   eLSBC_RED, 
    93   eLSBC_GREEN, 
    94   eLSBC_YELLOW, 
    95   eLSBC_BLUE, 
    96   eLSBC_MAGENTA, 
    97   eLSBC_CYAN, 
    98   eLSBC_GRAY, 
    99   eLSBC_DIMENSION 
     91  eSBC_DEFAULT, 
     92  eSBC_RED, 
     93  eSBC_GREEN, 
     94  eSBC_YELLOW, 
     95  eSBC_BLUE, 
     96  eSBC_MAGENTA, 
     97  eSBC_CYAN, 
     98  eSBC_GRAY, 
     99  eSBC_DIMENSION 
    100100}; 
    101101 
  • tLogDomain.cpp

    r69 r74  
    1 // 
    2 // You received this file as part of RRLib 
    3 // Robotics Research Library 
    4 // 
    5 // Copyright (C) Finroc GbR (finroc.org) 
    6 // 
    7 // This program is free software; you can redistribute it and/or 
    8 // modify it under the terms of the GNU General Public License 
    9 // as published by the Free Software Foundation; either version 2 
    10 // of the License, or (at your option) any later version. 
    11 // 
    12 // This program is distributed in the hope that it will be useful, 
    13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
    14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    15 // GNU General Public License for more details. 
    16 // 
    17 // You should have received a copy of the GNU General Public License 
    18 // along with this program; if not, write to the Free Software 
    19 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
    20 // 
    21 //---------------------------------------------------------------------- 
    22 /*!\file    tLogDomain.cpp 
    23  * 
    24  * \author  Tobias Foehst 
    25  * \author  Max Reichardt 
    26  * 
    27  * \date    2010-06-16 
    28  * 
    29  */ 
    30 //---------------------------------------------------------------------- 
    31 #define __rrlib__logging__include_guard__ 
    32 #include "rrlib/logging/tLogDomain.h" 
    33  
    34 //---------------------------------------------------------------------- 
    35 // External includes (system with <>, local with "") 
    36 //---------------------------------------------------------------------- 
    37  
    38 //---------------------------------------------------------------------- 
    39 // Internal includes with "" 
    40 //---------------------------------------------------------------------- 
    41 #include "rrlib/logging/tLogDomainRegistry.h" 
    42  
    43 //---------------------------------------------------------------------- 
    44 // Debugging 
    45 //---------------------------------------------------------------------- 
    46  
    47 //---------------------------------------------------------------------- 
    48 // Namespace usage 
    49 //---------------------------------------------------------------------- 
    50 using namespace rrlib::logging; 
    51  
    52 //---------------------------------------------------------------------- 
    53 // Forward declarations / typedefs / enums 
    54 //---------------------------------------------------------------------- 
    55  
    56 //---------------------------------------------------------------------- 
    57 // Const values 
    58 //---------------------------------------------------------------------- 
    59  
    60 //---------------------------------------------------------------------- 
    61 // Implementation 
    62 //---------------------------------------------------------------------- 
    63  
    64 //---------------------------------------------------------------------- 
    65 // tLogDomain constructors 
    66 //---------------------------------------------------------------------- 
    67 tLogDomain::tLogDomain(tLogDomainConfigurationSharedPointer configuration) 
    68     : parent(0), 
    69     configuration(configuration), 
    70     mutex(GetMutex()) 
    71 {} 
    72  
    73 tLogDomain::tLogDomain(tLogDomainConfigurationSharedPointer configuration, tLogDomain &parent) 
    74     : parent(&parent), 
    75     configuration(configuration), 
    76     mutex(GetMutex()) 
    77 { 
    78   this->parent->children.push_back(this); 
    79   this->ConfigureSubTree(); 
    80 } 
    81  
    821//---------------------------------------------------------------------- 
    832// tLogDomain destructor 
     
    887  { 
    898    this->file_stream.close(); 
    90   } 
    91 } 
    92  
    93 //---------------------------------------------------------------------- 
    94 // tLogDomain ConfigureSubTree 
    95 //---------------------------------------------------------------------- 
    96 void tLogDomain::ConfigureSubTree() 
    97 { 
    98   if (this->parent && this->parent->configuration->configure_sub_tree) 
    99   { 
    100     *this->configuration = *this->parent->configuration; 
    101     for (std::vector<tLogDomain *>::iterator it = this->children.begin(); it != this->children.end(); ++it) 
    102     { 
    103       (*it)->ConfigureSubTree(); 
    104     } 
    1059  } 
    10610} 
     
    15862} 
    15963 
    160 //---------------------------------------------------------------------- 
    161 // tLogDomain GetTimeString 
    162 //---------------------------------------------------------------------- 
    163 const std::string tLogDomain::GetTimeString() const 
    164 { 
    165   char time_string_buffer[32]; 
    166   time_t t = time(0); 
    167   struct tm *temp = localtime(&t); 
    168   strftime(time_string_buffer, sizeof(time_string_buffer), "[ %T ] ", temp); 
    169   return time_string_buffer; 
    170 } 
    171  
    172 //---------------------------------------------------------------------- 
    173 // tLogDomain GetNameString 
    174 //---------------------------------------------------------------------- 
    175 const std::string tLogDomain::GetNameString() const 
    176 { 
    177   char name_string_buffer[128]; 
    178   snprintf(name_string_buffer, sizeof(name_string_buffer), "%-*s ", static_cast<int>((tLogDomainRegistry::GetInstance()->GetPadPrefixColumns() ? tLogDomainRegistry::GetInstance()->GetMaxDomainNameLength() : 0)), this->GetName().c_str()); 
    179   return name_string_buffer; 
    180 } 
    181  
    182 //---------------------------------------------------------------------- 
    183 // tLogDomain GetLevelString 
    184 //---------------------------------------------------------------------- 
    185 const std::string tLogDomain::GetLevelString(tLogLevel level) const 
    186 { 
    187   const char *level_name = 0; 
    188   switch (level) 
    189   { 
    190   case eLL_ERROR: 
    191     level_name = "[error]"; 
    192     break; 
    193   case eLL_WARNING: 
    194     level_name = "[warning]"; 
    195     break; 
    196   case eLL_DEBUG_WARNING: 
    197     level_name = "[debug]"; 
    198     break; 
    199   case eLL_DEBUG: 
    200     level_name = "[debug]"; 
    201     break; 
    202   case eLL_DEBUG_VERBOSE_1: 
    203     level_name = "[verbose]"; 
    204     break; 
    205   case eLL_DEBUG_VERBOSE_2: 
    206     level_name = "[verbose]"; 
    207     break; 
    208   case eLL_DEBUG_VERBOSE_3: 
    209     level_name = "[verbose]"; 
    210     break; 
    211   default: 
    212     level_name = ""; 
    213     break; 
    214   } 
    215   char name_string_buffer[128]; 
    216   snprintf(name_string_buffer, sizeof(name_string_buffer), "%-*s ", (tLogDomainRegistry::GetInstance()->GetPadPrefixColumns() ? 9 : 0), level_name); 
    217   return name_string_buffer; 
    218 } 
    219  
    220 //---------------------------------------------------------------------- 
    221 // tLogDomain GetLocationString 
    222 //---------------------------------------------------------------------- 
    223 const std::string tLogDomain::GetLocationString(const char *file, unsigned int line) const 
    224 { 
    225   char location_string_buffer[128]; 
    226   snprintf(location_string_buffer, sizeof(location_string_buffer), "[%s:%u] ", file, line); 
    227   return location_string_buffer; 
    228 } 
    229  
    230 //---------------------------------------------------------------------- 
    231 // tLogDomain GetColoredOutputString 
    232 //---------------------------------------------------------------------- 
    233 void tLogDomain::SetupOutputStreamColor(tLogLevel level) const 
    234 { 
    235   switch (level) 
    236   { 
    237   case eLL_ERROR: 
    238     this->stream_buffer.SetColor(eLSBE_BOLD, eLSBC_RED); 
    239     break; 
    240   case eLL_WARNING: 
    241     this->stream_buffer.SetColor(eLSBE_BOLD, eLSBC_BLUE); 
    242     break; 
    243   case eLL_DEBUG_WARNING: 
    244     this->stream_buffer.SetColor(eLSBE_DARK, eLSBC_YELLOW); 
    245     break; 
    246   case eLL_DEBUG: 
    247     this->stream_buffer.SetColor(eLSBE_DARK, eLSBC_GREEN); 
    248     break; 
    249   case eLL_DEBUG_VERBOSE_1: 
    250     this->stream_buffer.SetColor(eLSBE_REGULAR, eLSBC_CYAN); 
    251     break; 
    252   case eLL_DEBUG_VERBOSE_2: 
    253     this->stream_buffer.SetColor(eLSBE_REGULAR, eLSBC_CYAN); 
    254     break; 
    255   case eLL_DEBUG_VERBOSE_3: 
    256     this->stream_buffer.SetColor(eLSBE_REGULAR, eLSBC_CYAN); 
    257     break; 
    258   default: 
    259     ; 
    260   } 
    261 } 
  • tLogDomain.h

    r69 r74  
    1 // 
    2 // You received this file as part of RRLib 
    3 // Robotics Research Library 
    4 // 
    5 // Copyright (C) Finroc GbR (finroc.org) 
    6 // 
    7 // This program is free software; you can redistribute it and/or 
    8 // modify it under the terms of the GNU General Public License 
    9 // as published by the Free Software Foundation; either version 2 
    10 // of the License, or (at your option) any later version. 
    11 // 
    12 // This program is distributed in the hope that it will be useful, 
    13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
    14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
    15 // GNU General Public License for more details. 
    16 // 
    17 // You should have received a copy of the GNU General Public License 
    18 // along with this program; if not, write to the Free Software 
    19 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
    20 // 
    21 //---------------------------------------------------------------------- 
    22 /*!\file    tLogDomain.h 
     1/*! The dtor of tLogDomain 
     2 */ 
     3~tLogDomain(); 
     4 
     5mutable std::ofstream file_stream; 
     6 
     7/*! Open the file stream for file output 
    238 * 
    24  * \author  Tobias Foehst 
    25  * \author  Max Reichardt 
     9 * This method creates a new file which name is build using a prefix 
     10 * and the full qualified domain name. 
     11 * If the file already exists, it will be truncated. 
    2612 * 
    27  * \date    2010-06-16 
     13 * \returns Whether the file stream could be opened or not 
     14 */ 
     15const bool OpenFileOutputStream() const; 
     16 
     17/*! Setup the output stream to be used in this domain 
    2818 * 
    29  * \brief Contains tLogDomain 
     19 * A domain can stream its input to stdout, stderr, an own file and/or its parent's file. 
    3020 * 
    31  * \b tLogDomain 
    32  * 
    33  * The RRLib logging system is structured into hierarchical domains that 
    34  * can be created and configured via tLogDomainRegistry. That given, 
    35  * in the program implementation instances of the class tLogDomain 
    36  * wrap the stream that can be accessed either in C++ iostream style via 
    37  * operator << or in good old-fashioned C style using printf formatting. 
    38  * 
     21 *\param mask   The bitmask that selects the output streams to use 
    3922 */ 
    40 //---------------------------------------------------------------------- 
    41 #ifndef __rrlib__logging__include_guard__ 
    42 #error Invalid include directive. Try #include "rrlib/logging/definitions.h" instead. 
    43 #endif 
    44  
    45 #ifndef __rrlib__logging__tLogDomain_h__ 
    46 #define __rrlib__logging__tLogDomain_h__ 
    47  
    48 //---------------------------------------------------------------------- 
    49 // External includes (system with <>, local with "") 
    50 //---------------------------------------------------------------------- 
    51 #include <string> 
    52 #include <vector> 
    53 #include <fstream> 
    54 #include <iomanip> 
    55 #include <ctime> 
    56 #include <cstdarg> 
    57 #include <cassert> 
    58 #include <memory> 
    59  
    60 //---------------------------------------------------------------------- 
    61 // Internal includes with "" 
    62 //---------------------------------------------------------------------- 
    63 #include "rrlib/logging/tLogDomainConfiguration.h" 
    64 #include "rrlib/logging/tLogStreamBuffer.h" 
    65 #include "rrlib/logging/tLogStream.h" 
    66 #include "rrlib/logging/tLogStreamContext.h" 
    67  
    68 //---------------------------------------------------------------------- 
    69 // Debugging 
    70 //---------------------------------------------------------------------- 
    71  
    72 //---------------------------------------------------------------------- 
    73 // Namespace declaration 
    74 //---------------------------------------------------------------------- 
    75 namespace rrlib 
    76 { 
    77 namespace logging 
    78 { 
    79  
    80 //---------------------------------------------------------------------- 
    81 // Forward declarations / typedefs / enums 
    82 //---------------------------------------------------------------------- 
    83 //! Shared pointer to instances of tLogDomain for user space 
    84 class tLogDomain; 
    85 typedef std::shared_ptr<const tLogDomain> tLogDomainSharedPointer; 
    86  
    87 //---------------------------------------------------------------------- 
    88 // Class declaration 
    89 //---------------------------------------------------------------------- 
    90 //! This class implements messaging via a specific logging domain 
    91 /*! The RRLib logging system is structured into hierarchical domains that 
    92  *  can be created and configured via tLogDomainRegistry. That given, 
    93  *  in the program implementation instances of this class wrap the stream 
    94  *  that can be access either in C++ iostream style via operator << or 
    95  *  in the good old-fashioned C style using printf formatting. 
    96  * 
    97  */ 
    98 class tLogDomain 
    99 { 
    100   friend class tLogDomainRegistry; 
    101  
    102 //---------------------------------------------------------------------- 
    103 // Public methods and typedefs 
    104 //---------------------------------------------------------------------- 
    105 public: 
    106  
    107   /*! The dtor of tLogDomain 
    108    */ 
    109   ~tLogDomain(); 
    110  
    111   /*! Get the full qualified name of this domain 
    112    * 
    113    * Each domain has a full qualified name consisting of its parent's name 
    114    * and the local part that was given at creation time. 
    115    * 
    116    * \returns The full qualified domain name 
    117    */ 
    118   inline const std::string GetName() const 
    119   { 
    120     return this->configuration->name; 
    121   } 
    122  
    123   /*! Get configuration status of this domain's print_time flag 
    124    * 
    125    * The current time is prepended to messages of this domain if the 
    126    * print_time flag is set. 
    127    * 
    128    * \returns Whether the print_time flag is set or not. 
    129    */ 
    130   inline const bool GetPrintTime() const 
    131   { 
    132     return this->configuration->print_time; 
    133   } 
    134  
    135   /*! Get configuration status of this domain's print_name flag 
    136    * 
    137    * The name of this domain prepended to messages of this domain if its 
    138    * print_name flag is set. 
    139    * 
    140    * \returns Whether the print_name flag is set or not. 
    141    */ 
    142   inline const bool GetPrintName() const 
    143   { 
    144     return this->configuration->print_name; 
    145   } 
    146  
    147   /*! Get configuration status of this domain's print_level flag 
    148    * 
    149    * The level of each message is contained in the output of this domain 
    150    * if the print_level flag is set. 
    151    * 
    152    * \returns Whether the print_level flag is set or not. 
    153    */ 
    154   inline const bool GetPrintLevel() const 
    155   { 
    156     return this->configuration->print_level; 
    157   } 
    158  
    159   /*! Get configuration status of this domain's print_location flag 
    160    * 
    161    * The location given to each message is contained in the output of this 
    162    * domain if the print_location flag is set. 
    163    * 
    164    * \returns Whether the print_location flag is set or not. 
    165    */ 
    166   inline const bool GetPrintLocation() const 
    167   { 
    168     return this->configuration->print_location; 
    169   } 
    170  
    171   /*! Get the maximal log level a message must have to be processed 
    172    * 
    173    * Each message has a log level that must not be above the configured limit to be processed. 
    174    * 
    175    * \returns The configured maximal log level 
    176    */ 
    177   inline const tLogLevel GetMaxMessageLevel() const 
    178   { 
    179     return this->configuration->max_message_level; 
    180   } 
    181  
    182   /*! Get a message stream from this domain 
    183    * 
    184    * This method is the streaming interface to this logging domain. 
    185    * It must be used for every output using operator <<. 
    186    * The method then depending on the domain's configuration chooses 
    187    * a stream, prints the prefix that should be prepended to every 
    188    * message and returns the stream to process further input given as 
    189    * operator << cascade in the user's program. 
    190    * To properly specify the arguments of this method consider using 
    191    * the macros defined in rrlib/logging/definitions.h 
    192    * 
    193    * \param description   A string that describes the global context of the message 
    194    * \param function      The name of the function that contains the message (__FUNCTION__) 
    195    * \param file          The file that contains the message 
    196    * \param line          The line that contains the message 
    197    * \param level         The log level of the message 
    198    * 
    199    * \returns A reference to the stream that can be used for the remaining message parts 
    200    */ 
    201   template <typename TDescription> 
    202   inline tLogStream GetMessageStream(const TDescription &description, const char *function, const char *file, unsigned int line, tLogLevel level) const 
    203   { 
    204     tLogStream stream_proxy(std::shared_ptr<tLogStreamContext>(new tLogStreamContext(this->stream_buffer, mutex.get()))); 
    205     this->stream_buffer.Clear(); 
    206     this->stream_buffer.InitializeMultiLinePadding(); 
    207     if (level > this->GetMaxMessageLevel()) 
    208     { 
    209       return stream_proxy; 
    210     } 
    211     this->SetupOutputStream(this->configuration->sink_mask); 
    212     if (level == eLL_USER) 
    213     { 
    214       return stream_proxy; 
    215     } 
    216     if (this->GetPrintTime()) 
    217     { 
    218       stream_proxy << this->GetTimeString(); 
    219     } 
    220     this->SetupOutputStreamColor(level); 
    221 #ifndef _RRLIB_LOGGING_LESS_OUTPUT_ 
    222     if (this->GetPrintName()) 
    223     { 
    224       stream_proxy << this->GetNameString(); 
    225     } 
    226     if (this->GetPrintLevel()) 
    227     { 
    228       stream_proxy << this->GetLevelString(level); 
    229     } 
    230 #endif 
    231     stream_proxy << description << "::" << function << " "; 
    232 #ifndef _RRLIB_LOGGING_LESS_OUTPUT_ 
    233     if (this->GetPrintLocation()) 
    234     { 
    235       stream_proxy << this->GetLocationString(file, line); 
    236     } 
    237 #endif 
    238     stream_proxy << ">> "; 
    239     this->stream_buffer.ResetColor(); 
    240  
    241     switch (level) 
    242     { 
    243     case eLL_ERROR: 
    244       stream_proxy << "ERROR: "; 
    245       break; 
    246     case eLL_WARNING: 
    247     case eLL_DEBUG_WARNING: 
    248       stream_proxy << "WARNING: "; 
    249       break; 
    250     default: 
    251       ; 
    252     } 
    253  
    254     this->stream_buffer.MarkEndOfPrefixForMultiLinePadding(); 
    255  
    256     return stream_proxy; 
    257   } 
    258  
    259   /*! A printf like variant of using logging domains for message output 
    260    * 
    261    * Instead of using operator << to output messages this method can be 
    262    * used. It then itself uses printf to format the given message and 
    263    * streams the result through the result obtained from GetMessageStream. 
    264    * That way the message prefix is only generated in one place and - more 
    265    * important - the underlying technique is the more sane one from 
    266    * iostreams instead of file descriptors. 
    267    * Apart from that: iostreams and file descriptors can not be mixed. So 
    268    * a decision had to be made. 
    269    * 
    270    * \param description   A string that describes the global context of the message 
    271    * \param function      The name of the function that contains the message (__FUNCTION__) 
    272    * \param file          The file that contains the message 
    273    * \param line          The line that contains the message 
    274    * \param level         The log level of the message 
    275    * \param fmt           The format string for printf 
    276    * \param ...           The remaining arguments for printf 
    277    */ 
    278   template <typename TDescription> 
    279   inline void PrintMessage(const TDescription &description, const char *function, const char *file, int line, tLogLevel level, const char *fmt, ...) const 
    280   { 
    281     if (level > this->GetMaxMessageLevel()) 
    282     { 
    283       return; 
    284     } 
    285  
    286     va_list printf_args0; 
    287     va_start(printf_args0, fmt); 
    288     char temp; 
    289     int needed_buffer_size = vsnprintf(&temp, 1, fmt, printf_args0); 
    290     va_end(printf_args0); 
    291  
    292     va_list printf_args; 
    293     va_start(printf_args, fmt); 
    294     this->VPrintMessage(description, function, file, line, level, fmt, needed_buffer_size, printf_args); 
    295     va_end(printf_args); 
    296   } 
    297  
    298   template <typename TDescription> 
    299   inline void PrintMessage(const TDescription &description, const char *function, const char *file, int line, tLogLevel level, tLogDomainSharedPointer(&)(), const char *fmt, ...) const 
    300   { 
    301     if (level > this->GetMaxMessageLevel()) 
    302     { 
    303       return; 
    304     } 
    305  
    306     va_list printf_args0; 
    307     va_start(printf_args0, fmt); 
    308     char temp; 
    309     int needed_buffer_size = vsnprintf(&temp, 1, fmt, printf_args0); 
    310     va_end(printf_args0); 
    311  
    312     va_list printf_args; 
    313     va_start(printf_args, fmt); 
    314     this->VPrintMessage(description, function, file, line, level, fmt, needed_buffer_size, printf_args); 
    315     va_end(printf_args); 
    316   } 
    317  
    318 //---------------------------------------------------------------------- 
    319 // Private fields and methods 
    320 //---------------------------------------------------------------------- 
    321 private: 
    322  
    323   tLogDomain *parent; 
    324   std::vector<tLogDomain *> children; 
    325  
    326   tLogDomainConfigurationSharedPointer configuration; 
    327  
    328   mutable tLogStreamBuffer stream_buffer; 
    329   mutable std::ofstream file_stream; 
    330  
    331   std::shared_ptr<boost::recursive_mutex> mutex; 
    332  
    333   /*! The ctor of a top level domain 
    334    * 
    335    * This ctor is to be called by the registry that creates the top level 
    336    * domain. 
    337    * 
    338    * \param configuration   The configuration for the new domain 
    339    */ 
    340   tLogDomain(tLogDomainConfigurationSharedPointer configuration); 
    341  
    342   /*! The ctor for a new sub domain 
    343    * 
    344    * This ctor is to be called by the registry to create a new subdomain 
    345    * with a given configuration 
    346    * 
    347    * \param configuration   The configuration for the new domain 
    348    * \param parent          The parent domain 
    349    */ 
    350   tLogDomain(tLogDomainConfigurationSharedPointer configuration, tLogDomain &parent); 
    351  
    352   /*! 
    353    * \returns Shared Pointer to output mutex that is shared by all logging domains 
    354    */ 
    355   static std::shared_ptr<boost::recursive_mutex> GetMutex() 
    356   { 
    357     static std::shared_ptr<boost::recursive_mutex> mutex(new boost::recursive_mutex()); 
    358     return mutex; 
    359   } 
    360  
    361   /*! Recursively configure the subtree that begins in this domain 
    362    * 
    363    * If the domain is configured by its parent, the configuration is 
    364    * copied and propagated to this domain's children 
    365    */ 
    366   void ConfigureSubTree(); 
    367  
    368   /*! Open the file stream for file output 
    369    * 
    370    * This method creates a new file which name is build using a prefix 
    371    * and the full qualified domain name. 
    372    * If the file already exists, it will be truncated. 
    373    * 
    374    * \returns Whether the file stream could be opened or not 
    375    */ 
    376   const bool OpenFileOutputStream() const; 
    377  
    378   /*! Setup the output stream to be used in this domain 
    379    * 
    380    * A domain can stream its input to stdout, stderr, an own file and/or its parent's file. 
    381    * 
    382    *\param mask   The bitmask that selects the output streams to use 
    383    */ 
    384   void SetupOutputStream(int mask) const; 
    385  
    386   /*! Get the current time as string for internal use in messages 
    387    * 
    388    * This method formats the current time as string that can be used in 
    389    * messages. 
    390    * 
    391    * \returns The current time as string 
    392    */ 
    393   const std::string GetTimeString() const; 
    394  
    395   /*! Get the domain's name as string for internal use in messages 
    396    * 
    397    * This method formats the name as string that can be used in 
    398    * messages. This string is padded with spaces to the length of the 
    399    * longest domain name 
    400    * 
    401    * \returns The padded name as string 
    402    */ 
    403   const std::string GetNameString() const; 
    404  
    405   /*! Get the given message level as string for internal use in messages 
    406    * 
    407    * This method formats the given level as string that can be used in 
    408    * messages. 
    409    * 
    410    * \param level   The level that should be represented as string 
    411    * 
    412    * \returns The given level as padded string 
    413    */ 
    414   const std::string GetLevelString(tLogLevel level) const; 
    415  
    416   /*! Get the given location as string for internal use in messages 
    417    * 
    418    * This method formats given location consisting of a file name and a 
    419    * line number as string that can be used in messages. 
    420    * 
    421    * \param file   The file name (e.g. from __FILE__) 
    422    * \param line   The line number (e.g. from __LINE__) 
    423    * 
    424    * \returns The given location as string 
    425    */ 
    426   const std::string GetLocationString(const char *file, unsigned int line) const; 
    427  
    428   /*! Setup the underlying streambuffer to produce colored output 
    429    * 
    430    * This method sets up the underlying streambuffer for colored 
    431    * output according to the given level. 
    432    * 
    433    * \param level   The according log level 
    434    */ 
    435   void SetupOutputStreamColor(tLogLevel level) const; 
    436  
    437   template <typename TDescription> 
    438   inline void VPrintMessage(const TDescription &description, const char *function, const char *file, int line, tLogLevel level, const char *fmt, int needed_buffer_size, va_list printf_args) const 
    439   { 
    440     if (needed_buffer_size > 0) 
    441     { 
    442       char formatted_string_buffer[needed_buffer_size + 1]; 
    443       vsnprintf(formatted_string_buffer, sizeof(formatted_string_buffer), fmt, printf_args); 
    444       this->GetMessageStream(description, function, file, line, level) << formatted_string_buffer; 
    445     } 
    446   } 
    447  
    448 }; 
    449  
    450 //---------------------------------------------------------------------- 
    451 // End of namespace declaration 
    452 //---------------------------------------------------------------------- 
    453 } 
    454 } 
    455  
    456 #endif 
     23void SetupOutputStream(int mask) const; 
  • test/test_messages.cpp

    r73 r74  
    4444 
    4545#include "rrlib/util/join.h" 
     46 
     47#include "rrlib/logging/configuration.h" 
     48#include "rrlib/logging/messages.h" 
    4649 
    4750//---------------------------------------------------------------------- 
     
    124127  rrlib::logging::SetLogFilenamePrefix(basename(argv[0])); 
    125128 
    126   std::cout << rrlib::logging::tDomainRegistry::Instance().LogFilenamePrefix() << std::endl; 
     129  rrlib::logging::SetDomainPrintsName(".", true); 
     130  rrlib::logging::SetDomainPrintsTime(".", true); 
     131  rrlib::logging::SetDomainPrintsLevel(".", true); 
     132  rrlib::logging::SetDomainPrintsLocation(".", true); 
     133  rrlib::logging::SetDomainMaxMessageLevel(".", rrlib::logging::eLL_DEBUG_VERBOSE_3); 
     134//  rrlib::logging::SetDomainSink(".", rrlib::logging::eLS_FILE); 
    127135 
    128 //  tLogDomainRegistry::GetInstance()->SetDomainConfiguresSubTree("global", true); 
    129 //  tLogDomainRegistry::GetInstance()->SetDomainPrintsName("global", true); 
    130 //  tLogDomainRegistry::GetInstance()->SetDomainPrintsTime("global", true); 
    131 //  tLogDomainRegistry::GetInstance()->SetDomainPrintsLevel("global", true); 
    132 //  tLogDomainRegistry::GetInstance()->SetDomainPrintsLocation("global", true); 
    133 //  tLogDomainRegistry::GetInstance()->SetDomainMinMessageLevel("global", eLL_VERBOSE); 
    134 //  tLogDomainRegistry::GetInstance()->SetDomainStreamID("global", eLS_FILE); 
    135  
    136 //  tLogDomainRegistry::GetInstance()->SetDomainStreamMask("global", eLSM_STDOUT | eLSM_FILE | eLSM_COMBINED_FILE); 
    137  
    138 //  tLogDomainRegistry::GetInstance()->SetDomainConfiguresSubTree(".example", true); 
    139 //  tLogDomainRegistry::GetInstance()->SetDomainMinMessageLevel(".example", eLL_VERBOSE); 
    140 //  tLogDomainRegistry::GetInstance()->SetDomainStreamID(".example", eLS_COMBINED_FILE); 
    141  
     136  rrlib::logging::SetDomainMaxMessageLevel(".example", rrlib::logging::eLL_DEBUG_VERBOSE_3); 
     137//  rrlib::logging::SetDomainSink(".example", rrlib::logging::eLS_STDOUT, rrlib::logging::eLS_FILE_SUBTREE); 
    142138 
    143139  RRLIB_LOG_PRINT(rrlib::logging::eLL_WARNING, "foo"); 
Note: See TracChangeset for help on using the changeset viewer.