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-2017, 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 "base-precomp.h" // Precompiled headers
11 
12 #include <mrpt/utils/CStream.h>
15 #include <cstdio>
16 #include <sstream>
17 #include <iostream>
18 #include <cstdarg> // for logFmt
19 
20 #ifdef _MSC_VER
21 #define WIN32_LEAN_AND_MEAN
22 #include <windows.h> // OutputDebugString() for MSVC
23 #endif
24 
25 using namespace mrpt;
26 using namespace mrpt::system;
27 using namespace mrpt::utils;
28 
29 using namespace std;
30 
31 /**
32  * Implementation file for the COutputLogger header class
33  */
34 
35 // COutputLogger
36 // ////////////////////////////////////////////////////////////
37 
39  COutputLogger::logging_levels_to_colors[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::string COutputLogger::logging_levels_to_names[NUMBER_OF_VERBOSITY_LEVELS] =
47  {
48  "DEBUG", // LVL_DEBUG
49  "INFO ", // LVL_INFO
50  "WARN ", // LVL_WARN
51  "ERROR" // LVL_ERROR
52 };
53 
54 COutputLogger::COutputLogger(const std::string& name)
55 {
56  this->loggerReset();
57  m_logger_name = name;
58 }
59 COutputLogger::COutputLogger() { this->loggerReset(); }
60 COutputLogger::~COutputLogger() {}
61 void COutputLogger::logStr(
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.func)(msg.body, msg.level, msg.name, msg.timestamp, c.userParam);
78 }
79 
80 void COutputLogger::logFmt(
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 
99 std::string COutputLogger::generateStringFromFormat(
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 }
120 void COutputLogger::logCond(
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 
127 void COutputLogger::setLoggerName(const std::string& name)
128 {
129  m_logger_name = name;
130 }
131 
132 std::string COutputLogger::getLoggerName() const { return m_logger_name; }
133 void COutputLogger::setMinLoggingLevel(
134  const VerbosityLevel level /*= LVL_INFO */)
135 {
136  m_min_verbosity_level = level;
137 }
138 void COutputLogger::setVerbosityLevel(const VerbosityLevel level)
139 {
140  m_min_verbosity_level = level;
141 }
142 
143 void COutputLogger::getLogAsString(std::string& fname) const
144 {
145  fname.clear();
146  for (const auto& h : m_history) fname += h.getAsString();
147 }
148 std::string COutputLogger::getLogAsString() const
149 {
150  std::string str;
151  this->getLogAsString(str);
152  return str;
153 }
154 void COutputLogger::writeLogToFile(
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  CFileOutputStream fstream(fname);
168  ASSERTMSG_(
169  fstream.fileOpenCorrectly(),
170  mrpt::format(
171  "\n[%s:] Could not open external file: %s", m_logger_name.c_str(),
172  fname.c_str()));
173 
174  std::string hist_str;
175  this->getLogAsString(hist_str);
176  fstream.printf("%s", hist_str.c_str());
177  fstream.close();
178 }
179 
180 void COutputLogger::dumpLogToConsole() const
181 {
182  for (const auto& h : m_history) h.dumpToConsole();
183 }
184 
185 std::string COutputLogger::getLoggerLastMsg() const
186 {
187  TMsg last_msg = m_history.back();
188  return last_msg.getAsString();
189 }
190 
191 void COutputLogger::getLoggerLastMsg(std::string& msg_str) const
192 {
193  msg_str = this->getLoggerLastMsg();
194 }
195 
196 void COutputLogger::loggerReset()
197 {
198  m_logger_name = "log"; // just the default name
199 
200  m_history.clear();
201  logging_enable_console_output = true;
202  logging_enable_keep_record = false;
203 
204  // set the minimum logging level allowed for printing. By default its
205  // LVL_INFO
206  m_min_verbosity_level = LVL_INFO;
207 }
208 
209 // TMsg Struct
210 // ////////////////////////////////////////////////////////////
211 
212 COutputLogger::TMsg::TMsg(
213  const mrpt::utils::VerbosityLevel level, const std::string& msg_str,
214  const COutputLogger& logger)
215 {
216  this->reset();
217 
218  name = logger.getLoggerName();
219  this->level = level;
220  timestamp = mrpt::system::getCurrentTime(); // fill with the current time
221  body = msg_str;
222 }
223 COutputLogger::TMsg::~TMsg() {}
225 {
226  timestamp = INVALID_TIMESTAMP;
227  level = LVL_INFO;
228  name = "Message"; // default name
229  body.clear();
230 }
231 
232 std::string COutputLogger::TMsg::getAsString() const
233 {
234  stringstream out;
235  out.str("");
236  out << "[" << name << "|" << COutputLogger::logging_levels_to_names[level]
237  << "|" << mrpt::system::timeLocalToString(timestamp, 4) << "] " << body;
238  if (!body.empty() && *body.rbegin() != '\n') out << std::endl;
239 
240  return out.str();
241 }
242 void COutputLogger::TMsg::getAsString(std::string* contents) const
243 {
244  *contents = this->getAsString();
245 }
246 void COutputLogger::TMsg::writeToStream(mrpt::utils::CStream& out) const
247 {
248  const std::string str = getAsString();
249  out.printf("%s", str.c_str());
250 #ifdef _MSC_VER
251  OutputDebugStringA(str.c_str());
252 #endif
253 }
254 void COutputLogger::TMsg::dumpToConsole() const
255 {
256  const std::string str = getAsString();
257 
258  const bool dump_to_cerr = (level == LVL_ERROR); // LVL_ERROR alternatively
259  // dumped to stderr instead
260  // of stdout
261 
262  // Set console color:
263  const TConsoleColor concol = COutputLogger::logging_levels_to_colors[level];
264  mrpt::system::setConsoleColor(concol, dump_to_cerr);
265  // Output msg:
266  (dump_to_cerr ? std::cerr : std::cout) << str;
267  // Switch back to normal color:
269 #ifdef _MSC_VER
270  OutputDebugStringA(
271  str.c_str()); // call benchmarked: avrg 90 us (50-200 us)
272 #endif
273 }
274 
275 void COutputLogger::logRegisterCallback(
276  output_logger_callback_t userFunc, void* userParam)
277 {
278  ASSERT_(userFunc != nullptr);
279  TCallbackEntry cbe;
280  cbe.func = userFunc;
281  cbe.userParam = userParam;
282  m_listCallbacks.insert(cbe);
283 }
284 
285 void COutputLogger::logDeregisterCallback(
286  output_logger_callback_t userFunc, void* userParam)
287 {
288  ASSERT_(userFunc != nullptr);
289  TCallbackEntry cbe;
290  cbe.func = userFunc;
291  cbe.userParam = userParam;
292  m_listCallbacks.erase(cbe);
293 }
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
This namespace provides a OS-independent interface to many useful functions: filenames manipulation...
Definition: math_frwds.h:30
GLuint buffer
Definition: glext.h:3917
mrpt::system::TTimeStamp getCurrentTime()
Returns the current (UTC) system time.
Definition: datetime.cpp:73
void setConsoleColor(TConsoleColor color, bool changeStdErr=false)
Changes the text color in the console for the text written from now on.
Definition: os.cpp:479
STL namespace.
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:41
This CStream derived class allow using a file as a write-only, binary stream.
const GLubyte * c
Definition: glext.h:6313
TConsoleColor
For use in setConsoleColor.
Definition: os.h:178
GLsizei const GLchar ** string
Definition: glext.h:4101
#define INVALID_TIMESTAMP
Represents an invalid timestamp, where applicable.
Definition: datetime.h:16
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:227
GLuint GLsizei GLsizei * length
Definition: glext.h:4064
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:314
GLint level
Definition: glext.h:3600
GLuint const GLchar * name
Definition: glext.h:4054
#define ASSERT_(f)
#define ASSERTMSG_(f, __ERROR_MSG)
virtual int printf(const char *fmt,...) MRPT_printf_format_check(2
Writes a string to the stream in a textual form.
Definition: CStream.cpp:597



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019