MRPT  1.9.9
COutputLogger.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2019, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "system-precomp.h" // Precompiled headers
11 
12 #include <mrpt/core/exceptions.h>
14 #include <mrpt/system/datetime.h>
15 #include <cstdarg> // for logFmt
16 #include <cstdio>
17 #include <fstream>
18 #include <iostream>
19 #include <sstream>
20 #include <vector>
21 
22 #ifdef _MSC_VER
23 #define WIN32_LEAN_AND_MEAN
24 #include <windows.h> // OutputDebugString() for MSVC
25 #endif
26 
27 using namespace mrpt;
28 using namespace mrpt::system;
29 using namespace std;
30 
31 /**
32  * Implementation file for the COutputLogger header class
33  */
34 
35 // COutputLogger
36 // ////////////////////////////////////////////////////////////
37 
38 static std::array<mrpt::system::TConsoleColor, NUMBER_OF_VERBOSITY_LEVELS>
40  CONCOL_BLUE, // LVL_DEBUG
41  CONCOL_NORMAL, // LVL_INFO
42  CONCOL_GREEN, // LVL_WARN
43  CONCOL_RED // LVL_ERROR
44 };
45 
46 std::array<mrpt::system::TConsoleColor, NUMBER_OF_VERBOSITY_LEVELS>&
48 {
50 }
51 
52 static std::array<std::string, NUMBER_OF_VERBOSITY_LEVELS>
54  "DEBUG", // LVL_DEBUG
55  "INFO ", // LVL_INFO
56  "WARN ", // LVL_WARN
57  "ERROR" // LVL_ERROR
58 };
59 std::array<std::string, NUMBER_OF_VERBOSITY_LEVELS>&
61 {
63 }
64 
66 {
67  this->loggerReset();
68  m_logger_name = name;
69 }
70 COutputLogger::COutputLogger() { this->loggerReset(); }
73  const VerbosityLevel level, const std::string& msg_str) const
74 {
75  if (level < m_min_verbosity_level) return;
76 
77  // initialize a TMsg object
78  TMsg msg(level, msg_str, *this);
79  if (logging_enable_keep_record) m_history.push_back(msg);
80 
81  if (logging_enable_console_output)
82  {
83  msg.dumpToConsole();
84  }
85 
86  // User callbacks:
87  for (const auto& c : m_listCallbacks)
88  c(msg.body, msg.level, msg.name, msg.timestamp);
89 }
90 
92  const VerbosityLevel level, const char* fmt, ...) const
93 {
94  // see MRPT/libs/base/src/utils/CDeugOutputCapable.cpp for the iniitial
95  // implementtion
96 
97  // check for nullptr pointer
98  if (!fmt) return;
99 
100  // initialize the va_list and let generateStringFromFormat do the work
101  // http://c-faq.com/varargs/handoff.html
102  va_list argp;
103  va_start(argp, fmt);
104  std::string str = this->generateStringFromFormat(fmt, argp);
105  va_end(argp);
106 
107  this->logStr(level, str);
108 }
109 
111  const char* fmt, va_list argp) const
112 {
113  int result = -1, length = 1024;
114  std::vector<char> buffer;
115  // make sure that the buffer is large enough to handle the string
116  while (result == -1)
117  {
118  buffer.resize(length + 10);
119  result = os::vsnprintf(&buffer[0], length, fmt, argp);
120 
121  // http://www.cplusplus.com/reference/cstdio/vsnprintf/
122  // only when this returned value is non-negative and less than n, the
123  // string has been completely written
124  if (result >= length) result = -1;
125  length *= 2;
126  }
127 
128  // return result to the caller
129  return std::string(&buffer[0]);
130 }
132  const VerbosityLevel level, bool cond, const std::string& msg_str) const
133 {
134  if (!cond) return;
135  this->logStr(level, msg_str);
136 }
137 
139 {
140  m_logger_name = name;
141 }
142 
143 std::string COutputLogger::getLoggerName() const { return m_logger_name; }
145  const VerbosityLevel level /*= LVL_INFO */)
146 {
147  m_min_verbosity_level = level;
148 }
150 {
151  m_min_verbosity_level = level;
152 }
153 
155 {
156  fname.clear();
157  for (const auto& h : m_history) fname += h.getAsString();
158 }
160 {
161  std::string str;
162  this->getLogAsString(str);
163  return str;
164 }
166  const std::string* fname_in /* = nullptr */) const
167 {
168  // determine the filename - open it
169  std::string fname;
170  if (fname_in)
171  {
172  fname = *fname_in;
173  }
174  else
175  {
176  fname = m_logger_name + ".log";
177  }
178  std::ofstream f(fname);
179  ASSERTMSG_(
180  f.is_open(), mrpt::format(
181  "[%s:] Could not open external file: %s",
182  m_logger_name.c_str(), fname.c_str()));
183 
184  std::string hist_str;
185  this->getLogAsString(hist_str);
186  f << hist_str;
187  f.close();
188 }
189 
191 {
192  for (const auto& h : m_history) h.dumpToConsole();
193 }
194 
196 {
197  TMsg last_msg = m_history.back();
198  return last_msg.getAsString();
199 }
200 
202 {
203  msg_str = this->getLoggerLastMsg();
204 }
205 
207 {
208  m_logger_name = "log"; // just the default name
209 
210  m_history.clear();
211  logging_enable_console_output = true;
212  logging_enable_keep_record = false;
213 
214  // set the minimum logging level allowed for printing. By default its
215  // LVL_INFO
216  m_min_verbosity_level = LVL_INFO;
217 }
218 
219 // TMsg Struct
220 // ////////////////////////////////////////////////////////////
221 
223  const mrpt::system::VerbosityLevel in_level, const std::string& msg_str,
224  const COutputLogger& logger)
225  : timestamp(mrpt::Clock::now()), // fill with the current time
226  level(in_level),
227  name(logger.getLoggerName()),
228  body(msg_str)
229 {
230 }
231 
232 COutputLogger::TMsg::~TMsg() = default;
233 
235 {
236  stringstream out;
237  out << "[" << mrpt::system::timeLocalToString(timestamp, 4) << "|"
239  << "] " << body;
240  if (!body.empty() && *body.rbegin() != '\n') out << std::endl;
241 
242  return out.str();
243 }
245 {
246  *contents = this->getAsString();
247 }
248 void COutputLogger::TMsg::writeToStream(std::ostream& out) const
249 {
250  const std::string str = getAsString();
251  out << str;
252 #ifdef _MSC_VER
253  OutputDebugStringA(str.c_str());
254 #endif
255 }
257 {
258  const std::string str = getAsString();
259 
260  const bool dump_to_cerr = (level == LVL_ERROR); // LVL_ERROR alternatively
261  // dumped to stderr instead
262  // of stdout
263 
264  // Set console color:
265  const TConsoleColor concol =
267  mrpt::system::setConsoleColor(concol, dump_to_cerr);
268  // Output msg:
269  (dump_to_cerr ? std::cerr : std::cout) << str;
270  // Switch back to normal color:
272 #ifdef _MSC_VER
273  OutputDebugStringA(
274  str.c_str()); // call benchmarked: avrg 90 us (50-200 us)
275 #endif
276 }
277 
279 {
280  m_listCallbacks.emplace_back(userFunc);
281 }
282 
283 template <typename T, typename... U>
284 size_t getAddress(std::function<T(U...)> f)
285 {
286  using fnType = T (*)(U...);
287  auto** fnPointer = f.template target<fnType*>();
288  return (size_t)*fnPointer;
289 }
290 
292 {
293  for (auto it = m_listCallbacks.begin(); it != m_listCallbacks.end(); ++it)
294  {
295  if (getAddress(*it) == getAddress(userFunc))
296  {
297  m_listCallbacks.erase(it);
298  return true;
299  }
300  }
301  return false;
302 }
Clock that is compatible with MRPT TTimeStamp representation.
Definition: Clock.h:19
size_t getAddress(std::function< T(U...)> f)
static std::array< mrpt::system::TConsoleColor, NUMBER_OF_VERBOSITY_LEVELS > logging_levels_to_colors
Implementation file for the COutputLogger header class.
VerbosityLevel
Enumeration of available verbosity levels.
virtual ~COutputLogger()
virtual dtor (so we can derive classes from this one)
TMsg(const mrpt::system::VerbosityLevel level, const std::string &msg, const COutputLogger &logger)
Class constructor that passes a message in std::string form as well as a reference to the COutputLogg...
void logFmt(const VerbosityLevel level, const char *fmt,...) const MRPT_printf_format_check(3
Alternative logging method, which mimics the printf behavior.
GLuint buffer
Definition: glext.h:3928
void dumpToConsole() const
Dump the message contents to the standard output.
void setConsoleColor(TConsoleColor color, bool changeStdErr=false)
Changes the text color in the console for the text written from now on.
Definition: os.cpp:484
std::string getLoggerLastMsg() const
Return the last Tmsg instance registered in the logger history.
static std::array< std::string, NUMBER_OF_VERBOSITY_LEVELS > & logging_levels_to_names()
Map from VerbosityLevels to their corresponding names.
void setMinLoggingLevel(const VerbosityLevel level)
Set the minimum logging level for which the incoming logs are going to be taken into account...
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
Definition: datetime.h:86
STL namespace.
void writeToStream(std::ostream &out) const
Write the message contents to the specified stream.
std::deque< output_logger_callback_t > m_listCallbacks
VerbosityLevel level
Verbosity level of the message.
std::string generateStringFromFormat(const char *fmt, va_list argp) const
Helper method for generating a std::string instance from printf-like arguments.
static std::array< std::string, NUMBER_OF_VERBOSITY_LEVELS > logging_levels_to_names
static std::array< mrpt::system::TConsoleColor, NUMBER_OF_VERBOSITY_LEVELS > & logging_levels_to_colors()
Map from VerbosityLevels to their corresponding mrpt::system::TConsoleColor.
std::string getAsString() const
Return a string representation of the underlying message.
std::string body
Actual content of the message.
const GLubyte * c
Definition: glext.h:6406
Versatile class for consistent logging and management of output messages.
std::string getLoggerName() const
Return the name of the COutputLogger instance.
void setLoggerName(const std::string &name)
Set the name of the COutputLogger instance.
void loggerReset()
Reset the contents of the logger instance.
TConsoleColor
For use in setConsoleColor.
Definition: os.h:162
void void logCond(const VerbosityLevel level, bool cond, const std::string &msg_str) const
Log the given message only if the condition is satisfied.
#define ASSERTMSG_(f, __ERROR_MSG)
Defines an assertion mechanism.
Definition: exceptions.h:108
void dumpLogToConsole() const
Dump the current contents of the COutputLogger instance in the terminal window.
GLsizei const GLchar ** string
Definition: glext.h:4116
mrpt::Clock::time_point timestamp
Timestamp of the message.
std::string getLogAsString() const
Get the history of COutputLogger instance in a string representation.
void setVerbosityLevel(const VerbosityLevel level)
alias of setMinLoggingLevel()
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
int vsnprintf(char *buf, size_t bufSize, const char *format, va_list args) noexcept
An OS-independent version of vsnprintf (Notice the bufSize param, which may be ignored in some compil...
Definition: os.cpp:230
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:16
COutputLogger()
Default class constructor.
GLuint GLsizei GLsizei * length
Definition: glext.h:4079
Struct responsible of holding information relevant to the message (in std::string form) issued by the...
std::string timeLocalToString(const mrpt::system::TTimeStamp t, unsigned int secondFractionDigits=6)
Convert a timestamp into this textual form (in local time): HH:MM:SS.MMMMMM.
Definition: datetime.cpp:216
GLint level
Definition: glext.h:3606
GLuint const GLchar * name
Definition: glext.h:4068
void logRegisterCallback(output_logger_callback_t userFunc)
std::string name
Name of the COutputLogger instance that called registered the message.
std::function< void(const std::string &msg, const mrpt::system::VerbosityLevel level, const std::string &loggerName, const mrpt::Clock::time_point &timestamp)> output_logger_callback_t
Callback types for use with mrpt::system::COuputLogger.
void logStr(const VerbosityLevel level, const std::string &msg_str) const
Main method to add the specified message string to the logger.
~TMsg()
Default Destructor.
bool logDeregisterCallback(output_logger_callback_t userFunc)
void writeLogToFile(const std::string *fname_in=nullptr) const
Write the contents of the COutputLogger instance to an external file.



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ce1a28c9f Fri Aug 23 08:02:09 2019 +0200 at vie ago 23 08:10:11 CEST 2019