Logger.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. /*
  2. * TI Voxel Lib component.
  3. *
  4. * Copyright (c) 2014 Texas Instruments Inc.
  5. */
  6. #ifndef VOXEL_LOGGER_H
  7. #define VOXEL_LOGGER_H
  8. #include <iostream>
  9. #include <sstream>
  10. #include <thread>
  11. #include "Common.h"
  12. namespace Voxel
  13. {
  14. /**
  15. * \addtogroup Util
  16. * @{
  17. */
  18. enum LogLevel
  19. {
  20. LOG_CRITICAL,
  21. LOG_ERROR,
  22. LOG_WARNING,
  23. LOG_INFO,
  24. LOG_DEBUG
  25. };
  26. typedef OutputStream &(*OStreamManipulator)(OutputStream &);
  27. class VOXEL_EXPORT LoggerOutStream
  28. {
  29. public:
  30. typedef Function<void(const String &)> LoggerOutStreamFunctionType;
  31. protected:
  32. LoggerOutStreamFunctionType _outputFunction;
  33. OutputStringStream _s;
  34. public:
  35. LoggerOutStream() {}
  36. void setOutputFunction(LoggerOutStreamFunctionType o) { _outputFunction = o; }
  37. template <typename T>
  38. LoggerOutStream &operator <<(const T &value)
  39. {
  40. if(!_outputFunction)
  41. return *this;
  42. _s << value;
  43. if(_s.tellp() > 0) // Something written?
  44. {
  45. _outputFunction(_s.str());
  46. _s.clear();
  47. _s.str("");
  48. }
  49. return *this;
  50. }
  51. inline LoggerOutStream &operator <<(OStreamManipulator manip)
  52. {
  53. (*manip)(_s);
  54. return *this;
  55. }
  56. };
  57. class VOXEL_EXPORT Logger
  58. {
  59. protected:
  60. OutputStream &_out = std::cerr;
  61. mutable Mutex _mutex;
  62. LogLevel _logLevel, // Allow log statements equal to or below _logLevel
  63. _currentLogLevel; // This holds log level for current statements
  64. static const String _logLevelNames[5];
  65. Map<IndexType, LoggerOutStream> _outputStreams;
  66. IndexType _outputStreamCount = 0;
  67. public:
  68. Logger(LogLevel loglevel = LOG_ERROR): _logLevel(loglevel), _currentLogLevel(loglevel)
  69. {}
  70. Logger &operator =(const Logger &other) { _logLevel = other._logLevel; _currentLogLevel = other._currentLogLevel; return *this; }
  71. inline Logger &operator()(LogLevel loglevel)
  72. {
  73. _currentLogLevel = loglevel;
  74. return *this << _logLevelNames[loglevel] << ": ";
  75. }
  76. inline LogLevel getDefaultLogLevel()
  77. {
  78. return _logLevel;
  79. }
  80. inline LogLevel getCurrentLogLevel()
  81. {
  82. return _currentLogLevel;
  83. }
  84. inline void setDefaultLogLevel(LogLevel loglevel)
  85. {
  86. _logLevel = loglevel;
  87. }
  88. inline OutputStream &getStream()
  89. {
  90. return _out;
  91. }
  92. inline IndexType addOutputStream(LoggerOutStream::LoggerOutStreamFunctionType f)
  93. {
  94. IndexType i = _outputStreamCount;
  95. _outputStreams[i].setOutputFunction(f);
  96. _outputStreamCount++;
  97. return i;
  98. }
  99. inline bool removeOutputStream(IndexType index)
  100. {
  101. auto x = _outputStreams.find(index);
  102. if(x != _outputStreams.end())
  103. {
  104. _outputStreams.erase(x);
  105. return true;
  106. }
  107. return false;
  108. }
  109. template <typename T>
  110. Logger &operator <<(const T &value)
  111. {
  112. if(_currentLogLevel <= _logLevel)
  113. {
  114. _out << value;
  115. for(auto &x: _outputStreams)
  116. x.second << value;
  117. }
  118. return *this;
  119. }
  120. typedef Logger &(*LoggerManipulator)(Logger &);
  121. inline Logger &operator <<(LoggerManipulator manip)
  122. {
  123. if(_currentLogLevel <= _logLevel)
  124. return (*manip)(*this);
  125. else
  126. return *this;
  127. }
  128. inline Logger &operator <<(OStreamManipulator manip)
  129. {
  130. if(_currentLogLevel <= _logLevel)
  131. {
  132. (*manip)(_out);
  133. for(auto &x: _outputStreams)
  134. x.second << manip;
  135. }
  136. return *this;
  137. }
  138. virtual ~Logger()
  139. {
  140. }
  141. };
  142. extern Logger VOXEL_EXPORT logger;
  143. //VOXEL_EXPORT Logger & endl(Logger &l);
  144. class VOXEL_EXPORT LogLevelChanger
  145. {
  146. LogLevel _currentLogLevel;
  147. LogLevel _desiredLogLevel;
  148. public:
  149. LogLevelChanger(LogLevel desired): _desiredLogLevel(desired)
  150. {
  151. _currentLogLevel = logger.getDefaultLogLevel();
  152. logger.setDefaultLogLevel(_desiredLogLevel);
  153. }
  154. ~LogLevelChanger()
  155. {
  156. logger.setDefaultLogLevel(_currentLogLevel);
  157. }
  158. };
  159. /**
  160. * @}
  161. */
  162. }
  163. #endif // VOXEL_LOGGER_H