Main MRPT website > C++ reference for MRPT 1.9.9
COutputLogger.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2018, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "system-precomp.h" // Precompiled headers
11 
13 #include <mrpt/system/datetime.h>
14 #include <mrpt/core/exceptions.h>
15 #include <cstdio>
16 #include <sstream>
17 #include <iostream>
18 #include <fstream>
19 #include <vector>
20 #include <cstdarg> // for logFmt
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 
40  CONCOL_BLUE, // LVL_DEBUG
41  CONCOL_NORMAL, // LVL_INFO
42  CONCOL_GREEN, // LVL_WARN
43  CONCOL_RED // LVL_ERROR
44 };
45 
47  {
48  "DEBUG", // LVL_DEBUG
49  "INFO ", // LVL_INFO
50  "WARN ", // LVL_WARN
51  "ERROR" // LVL_ERROR
52 };
53 
55 {
56  this->loggerReset();
57  m_logger_name = name;
58 }
59 COutputLogger::COutputLogger() { this->loggerReset(); }
62  const VerbosityLevel level, const std::string& msg_str) const
63 {
64  if (level < m_min_verbosity_level) return;
65 
66  // initialize a TMsg object
67  TMsg msg(level, msg_str, *this);
68  if (logging_enable_keep_record) m_history.push_back(msg);
69 
70  if (logging_enable_console_output)
71  {
72  msg.dumpToConsole();
73  }
74 
75  // User callbacks:
76  for (const auto& c : m_listCallbacks)
77  c(msg.body, msg.level, msg.name, msg.timestamp);
78 }
79 
81  const VerbosityLevel level, const char* fmt, ...) const
82 {
83  // see MRPT/libs/base/src/utils/CDeugOutputCapable.cpp for the iniitial
84  // implementtion
85 
86  // check for nullptr pointer
87  if (!fmt) return;
88 
89  // initialize the va_list and let generateStringFromFormat do the work
90  // http://c-faq.com/varargs/handoff.html
91  va_list argp;
92  va_start(argp, fmt);
93  std::string str = this->generateStringFromFormat(fmt, argp);
94  va_end(argp);
95 
96  this->logStr(level, str);
97 }
98 
100  const char* fmt, va_list argp) const
101 {
102  int result = -1, length = 1024;
103  std::vector<char> buffer;
104  // make sure that the buffer is large enough to handle the string
105  while (result == -1)
106  {
107  buffer.resize(length + 10);
108  result = os::vsnprintf(&buffer[0], length, fmt, argp);
109 
110  // http://www.cplusplus.com/reference/cstdio/vsnprintf/
111  // only when this returned value is non-negative and less than n, the
112  // string has been completely written
113  if (result >= length) result = -1;
114  length *= 2;
115  }
116 
117  // return result to the caller
118  return std::string(&buffer[0]);
119 }
121  const VerbosityLevel level, bool cond, const std::string& msg_str) const
122 {
123  if (!cond) return;
124  this->logStr(level, msg_str);
125 }
126 
128 {
129  m_logger_name = name;
130 }
131 
132 std::string COutputLogger::getLoggerName() const { return m_logger_name; }
134  const VerbosityLevel level /*= LVL_INFO */)
135 {
136  m_min_verbosity_level = level;
137 }
139 {
140  m_min_verbosity_level = level;
141 }
142 
144 {
145  fname.clear();
146  for (const auto& h : m_history) fname += h.getAsString();
147 }
149 {
150  std::string str;
151  this->getLogAsString(str);
152  return str;
153 }
155  const std::string* fname_in /* = nullptr */) const
156 {
157  // determine the filename - open it
158  std::string fname;
159  if (fname_in)
160  {
161  fname = *fname_in;
162  }
163  else
164  {
165  fname = m_logger_name + ".log";
166  }
167  std::ofstream f(fname);
168  ASSERTMSG_(
169  f.is_open(), mrpt::format(
170  "[%s:] Could not open external file: %s",
171  m_logger_name.c_str(), fname.c_str()));
172 
173  std::string hist_str;
174  this->getLogAsString(hist_str);
175  f << hist_str;
176  f.close();
177 }
178 
180 {
181  for (const auto& h : m_history) h.dumpToConsole();
182 }
183 
185 {
186  TMsg last_msg = m_history.back();
187  return last_msg.getAsString();
188 }
189 
191 {
192  msg_str = this->getLoggerLastMsg();
193 }
194 
196 {
197  m_logger_name = "log"; // just the default name
198 
199  m_history.clear();
200  logging_enable_console_output = true;
201  logging_enable_keep_record = false;
202 
203  // set the minimum logging level allowed for printing. By default its
204  // LVL_INFO
205  m_min_verbosity_level = LVL_INFO;
206 }
207 
208 // TMsg Struct
209 // ////////////////////////////////////////////////////////////
210 
212  const mrpt::system::VerbosityLevel in_level, const std::string& msg_str,
213  const COutputLogger& logger)
214 {
215  this->reset();
216 
217  name = logger.getLoggerName();
218  this->level = in_level;
219  timestamp = mrpt::system::getCurrentTime(); // fill with the current time
220  body = msg_str;
221 }
224 {
225  timestamp = INVALID_TIMESTAMP;
226  level = LVL_INFO;
227  name = "Message"; // default name
228  body.clear();
229 }
230 
232 {
233  stringstream out;
234  out.str("");
235  out << "[" << name << "|" << COutputLogger::logging_levels_to_names[level]
236  << "|" << mrpt::system::timeLocalToString(timestamp, 4) << "] " << body;
237  if (!body.empty() && *body.rbegin() != '\n') out << std::endl;
238 
239  return out.str();
240 }
242 {
243  *contents = this->getAsString();
244 }
245 void COutputLogger::TMsg::writeToStream(std::ostream& out) const
246 {
247  const std::string str = getAsString();
248  out << str;
249 #ifdef _MSC_VER
250  OutputDebugStringA(str.c_str());
251 #endif
252 }
254 {
255  const std::string str = getAsString();
256 
257  const bool dump_to_cerr = (level == LVL_ERROR); // LVL_ERROR alternatively
258  // dumped to stderr instead
259  // of stdout
260 
261  // Set console color:
263  mrpt::system::setConsoleColor(concol, dump_to_cerr);
264  // Output msg:
265  (dump_to_cerr ? std::cerr : std::cout) << str;
266  // Switch back to normal color:
268 #ifdef _MSC_VER
269  OutputDebugStringA(
270  str.c_str()); // call benchmarked: avrg 90 us (50-200 us)
271 #endif
272 }
273 
275 {
276  m_listCallbacks.emplace_back(userFunc);
277 }
278 
279 template <typename T, typename... U>
280 size_t getAddress(std::function<T(U...)> f)
281 {
282  using fnType = T (*)(U...);
283  fnType** fnPointer = f.template target<fnType*>();
284  return (size_t)*fnPointer;
285 }
286 
288 {
289  for (auto it = m_listCallbacks.begin(); it != m_listCallbacks.end(); ++it)
290  {
291  if (getAddress(*it) == getAddress(userFunc))
292  {
293  m_listCallbacks.erase(it);
294  return true;
295  }
296  }
297  return false;
298 }
mrpt::system::TTimeStamp timestamp
Timestamp of the message.
size_t getAddress(std::function< T(U...)> f)
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.
This namespace provides a OS-independent interface to many useful functions: filenames manipulation...
Definition: math_frwds.h:25
GLuint buffer
Definition: glext.h:3917
mrpt::system::TTimeStamp getCurrentTime()
Returns the current (UTC) system time.
Definition: datetime.cpp:74
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:480
std::string getLoggerLastMsg() const
Return the last Tmsg instance registered in the logger history.
void setMinLoggingLevel(const VerbosityLevel level)
Set the minimum logging level for which the incoming logs are going to be taken into account...
STL namespace.
void writeToStream(std::ostream &out) const
Write the message contents to the specified stream.
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.
void reset()
Reset the contents of the TMsg instance.
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:6313
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.
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:16
void writeLogToFile(const std::string *fname_in=NULL) const
Write the contents of the COutputLogger instance to an external file.
TConsoleColor
For use in setConsoleColor.
Definition: os.h:175
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:101
void dumpLogToConsole() const
Dump the current contents of the COutputLogger instance in the terminal window.
std::function< void(const std::string &msg, const mrpt::system::VerbosityLevel level, const std::string &loggerName, const mrpt::system::TTimeStamp timestamp)> output_logger_callback_t
Callback types for use with mrpt::system::COuputLogger.
GLsizei const GLchar ** string
Definition: glext.h:4101
#define INVALID_TIMESTAMP
Represents an invalid timestamp, where applicable.
Definition: datetime.h:15
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:228
COutputLogger()
Default class constructor.
static mrpt::system::TConsoleColor logging_levels_to_colors[NUMBER_OF_VERBOSITY_LEVELS]
Map from VerbosityLevels to their corresponding mrpt::system::TConsoleColor.
GLuint GLsizei GLsizei * length
Definition: glext.h:4064
Struct responsible of holding information relevant to the message (in std::string form) issued by the...
GLboolean reset
Definition: glext.h:3582
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:315
GLint level
Definition: glext.h:3600
GLuint const GLchar * name
Definition: glext.h:4054
void logRegisterCallback(output_logger_callback_t userFunc)
std::string name
Name of the COutputLogger instance that called registered the message.
void logStr(const VerbosityLevel level, const std::string &msg_str) const
Main method to add the specified message string to the logger.
static std::string logging_levels_to_names[NUMBER_OF_VERBOSITY_LEVELS]
Map from VerbosityLevels to their corresponding names.
bool logDeregisterCallback(output_logger_callback_t userFunc)



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ad3a9d8ae Tue May 1 23:10:22 2018 -0700 at lun oct 28 00:14:14 CET 2019