Main MRPT website > C++ reference for MRPT 1.5.6
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 <mrpt/system/threads.h>
16 #include <cstdio>
17 #include <sstream>
18 #include <iostream>
19 #include <cstdarg> // for logFmt
20 
21 #ifdef _MSC_VER
22  #define WIN32_LEAN_AND_MEAN
23  #include <windows.h> // OutputDebugString() for MSVC
24 #endif
25 
26 using namespace mrpt;
27 using namespace mrpt::system;
28 using namespace mrpt::utils;
29 
30 using namespace std;
31 
32 
33 /**
34  * Implementation file for the COutputLogger header class
35  */
36 
37 // COutputLogger
38 // ////////////////////////////////////////////////////////////
39 
40 mrpt::system::TConsoleColor COutputLogger::logging_levels_to_colors[NUMBER_OF_VERBOSITY_LEVELS] = {
41  CONCOL_BLUE, // LVL_DEBUG
42  CONCOL_NORMAL, // LVL_INFO
43  CONCOL_GREEN, // LVL_WARN
44  CONCOL_RED // LVL_ERROR
45 };
46 
47 std::string COutputLogger::logging_levels_to_names[NUMBER_OF_VERBOSITY_LEVELS] = {
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  this->loggerReset();
56  m_logger_name = name;
57 
58 }
59 COutputLogger::COutputLogger() {
60  this->loggerReset();
61 }
62 COutputLogger::~COutputLogger() { }
63 
64 void COutputLogger::logStr(const VerbosityLevel level, const std::string& msg_str) const {
65  if (level<m_min_verbosity_level)
66  return;
67 
68  // initialize a TMsg object
69  TMsg msg(level, msg_str, *this);
70  if (logging_enable_keep_record)
71  m_history.push_back(msg);
72 
73  if (logging_enable_console_output) {
74  msg.dumpToConsole();
75  }
76 
77  // User callbacks:
78  for (const auto &c : m_listCallbacks)
79  (*c.func)(msg.body,msg.level,msg.name,msg.timestamp,c.userParam);
80 }
81 
82 void COutputLogger::logFmt(const VerbosityLevel level, const char* fmt, ...) const {
83  // see MRPT/libs/base/src/utils/CDeugOutputCapable.cpp for the iniitial
84  // implementtion
85 
86  // check for NULL 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(const char* fmt, va_list argp) const{
100  int result = -1, length = 1024;
101  std::vector<char> buffer;
102  // make sure that the buffer is large enough to handle the string
103  while (result == -1)
104  {
105  buffer.resize(length + 10);
106  result = os::vsnprintf(&buffer[0], length, fmt, argp);
107 
108  // http://www.cplusplus.com/reference/cstdio/vsnprintf/
109  // only when this returned value is non-negative and less than n, the
110  // string has been completely written
111  if (result>=length) result=-1;
112  length*=2;
113  }
114 
115  // return result to the caller
116  return std::string(&buffer[0]);
117 
118 }
119 void COutputLogger::logCond(const VerbosityLevel level, bool cond, const std::string& msg_str) const
120 {
121  if (!cond) return;
122  this->logStr(level,msg_str);
123 }
124 
125 void COutputLogger::setLoggerName(const std::string& name) { m_logger_name = name; }
126 
127 std::string COutputLogger::getLoggerName() const { return m_logger_name; }
128 
129 void COutputLogger::setMinLoggingLevel(const VerbosityLevel level /*= LVL_INFO */) {
130  m_min_verbosity_level = level;
131 }
132 void COutputLogger::setVerbosityLevel(const VerbosityLevel level) {
133  m_min_verbosity_level = level;
134 }
135 
136 void COutputLogger::getLogAsString(std::string& fname) const {
137  fname.clear();
138  for (const auto & h : m_history)
139  fname += h.getAsString();
140 }
141 std::string COutputLogger::getLogAsString() const{
142  std::string str;
143  this->getLogAsString(str);
144  return str;
145 }
146 void COutputLogger::writeLogToFile(const std::string* fname_in /* = NULL */) const {
147  // determine the filename - open it
148  std::string fname;
149  if (fname_in) {
150  fname = *fname_in;
151  }
152  else {
153  fname = m_logger_name + ".log";
154  }
155  CFileOutputStream fstream(fname);
156  ASSERTMSG_(fstream.fileOpenCorrectly(),
157  mrpt::format("\n[%s:] Could not open external file: %s",
158  m_logger_name.c_str(), fname.c_str()) );
159 
160  std::string hist_str;
161  this->getLogAsString(hist_str);
162  fstream.printf("%s", hist_str.c_str());
163  fstream.close();
164 }
165 
166 void COutputLogger::dumpLogToConsole() const{
167  for (const auto &h :m_history)
168  h.dumpToConsole();
169 }
170 
171 std::string COutputLogger::getLoggerLastMsg() const {
172  TMsg last_msg = m_history.back();
173  return last_msg.getAsString();
174 }
175 
176 void COutputLogger::getLoggerLastMsg(std::string& msg_str) const {
177  msg_str = this->getLoggerLastMsg();
178 }
179 
180 
181 void COutputLogger::loggerReset() {
182  m_logger_name = "log"; // just the default name
183 
184  m_history.clear();
185  logging_enable_console_output = true;
186  logging_enable_keep_record = false;
187 
188  // set the minimum logging level allowed for printing. By default its
189  // LVL_INFO
190  m_min_verbosity_level = LVL_INFO;
191 }
192 
193 // TMsg Struct
194 // ////////////////////////////////////////////////////////////
195 
196 COutputLogger::TMsg::TMsg(const mrpt::utils::VerbosityLevel level, const std::string& msg_str, const COutputLogger& logger) {
197  this->reset();
198 
199  name = logger.getLoggerName();
200  this->level = level;
201  timestamp = mrpt::system::getCurrentTime(); // fill with the current time
202  body = msg_str;
203 }
204 COutputLogger::TMsg::~TMsg() { }
205 
207  timestamp = INVALID_TIMESTAMP;
208  level = LVL_INFO;
209  name = "Message"; // default name
210  body.clear();
211 }
212 
213 std::string COutputLogger::TMsg::getAsString() const {
214  stringstream out;
215  out.str("");
216  out << "[" << name << "|" << COutputLogger::logging_levels_to_names[level] << "|"
217  << mrpt::system::timeLocalToString(timestamp,4)
218  << "] " << body;
219  if (!body.empty() && *body.rbegin()!='\n')
220  out<<std::endl;
221 
222  return out.str();
223 }
224 void COutputLogger::TMsg::getAsString(std::string* contents) const {
225  *contents = this->getAsString();
226 }
227 void COutputLogger::TMsg::writeToStream(mrpt::utils::CStream& out) const {
228  const std::string str = getAsString();
229  out.printf("%s", str.c_str());
230 #ifdef _MSC_VER
231  OutputDebugStringA(str.c_str());
232 #endif
233 }
234 void COutputLogger::TMsg::dumpToConsole() const {
235  const std::string str = getAsString();
236 
237  const bool dump_to_cerr = (level==LVL_ERROR); // LVL_ERROR alternatively dumped to stderr instead of stdout
238 
239  // Set console color:
240  const TConsoleColor concol = COutputLogger::logging_levels_to_colors[level];
241  mrpt::system::setConsoleColor(concol, dump_to_cerr);
242  // Output msg:
243  (dump_to_cerr ? std::cerr : std::cout) << str;
244  // Switch back to normal color:
246 #ifdef _MSC_VER
247  OutputDebugStringA(str.c_str()); // call benchmarked: avrg 90 us (50-200 us)
248 #endif
249 }
250 
251 void COutputLogger::logRegisterCallback(output_logger_callback_t userFunc, void *userParam )
252 {
253  ASSERT_(userFunc!=NULL);
254  TCallbackEntry cbe;
255  cbe.func = userFunc;
256  cbe.userParam = userParam;
257  m_listCallbacks.insert(cbe);
258 }
259 
260 void COutputLogger::logDeregisterCallback(output_logger_callback_t userFunc, void *userParam )
261 {
262  ASSERT_(userFunc!=NULL);
263  TCallbackEntry cbe;
264  cbe.func = userFunc;
265  cbe.userParam = userParam;
266  m_listCallbacks.erase(cbe);
267 }
GLuint GLsizei GLsizei * length
Definition: glew.h:1732
int BASE_IMPEXP vsnprintf(char *buf, size_t bufSize, const char *format, va_list args) MRPT_NO_THROWS
An OS-independent version of vsnprintf (Notice the bufSize param, which may be ignored in some compil...
Definition: os.cpp:229
mrpt::system::TTimeStamp BASE_IMPEXP getCurrentTime()
Returns the current (UTC) system time.
Definition: datetime.cpp:71
const GLfloat * c
Definition: glew.h:10088
void BASE_IMPEXP setConsoleColor(TConsoleColor color, bool changeStdErr=false)
Changes the text color in the console for the text written from now on.
Definition: os.cpp:489
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:38
This CStream derived class allow using a file as a write-only, binary stream.
GLuint buffer
Definition: glew.h:1585
TConsoleColor
For use in setConsoleColor.
Definition: os.h:158
GLuint const GLchar * name
Definition: glew.h:1721
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
GLboolean reset
Definition: glew.h:2897
#define INVALID_TIMESTAMP
Represents an invalid timestamp, where applicable.
Definition: datetime.h:17
GLint level
Definition: glew.h:1166
GLsizei const GLcharARB ** string
Definition: glew.h:3293
std::string BASE_IMPEXP 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:321
#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:507



Page generated by Doxygen 1.8.6 for MRPT 1.5.6 Git: 4c65e84 Tue Apr 24 08:18:17 2018 +0200 at mar abr 24 08:26:17 CEST 2018