Skip to content

Commit 385429e

Browse files
jmirabelOlivier Stasse
authored andcommitted
Improve efficiency of class Logger
1 parent 7c48f8a commit 385429e

File tree

5 files changed

+131
-73
lines changed

5 files changed

+131
-73
lines changed

include/dynamic-graph/entity.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ class DYNAMIC_GRAPH_DLLAPI Entity : private boost::noncopyable {
9292
/// \brief Send messages \c msg with level \c t.
9393
/// Add string file and line to message.
9494
void sendMsg(const std::string &msg, MsgType t = MSG_TYPE_INFO,
95-
const char *file = "", int line = 0);
95+
const std::string &lineId = "");
9696

9797
/// \brief Specify the verbosity level of the logger.
9898
void setLoggerVerbosityLevel(LoggerVerbosity lv) { logger_.setVerbosity(lv); }

include/dynamic-graph/logger.h

Lines changed: 98 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,28 @@ namespace dynamicgraph {
2727
/** Enum representing the different kind of messages.
2828
*/
2929
enum MsgType {
30-
MSG_TYPE_DEBUG = 0,
31-
MSG_TYPE_INFO = 1,
32-
MSG_TYPE_WARNING = 2,
33-
MSG_TYPE_ERROR = 3,
34-
MSG_TYPE_DEBUG_STREAM = 4,
35-
MSG_TYPE_INFO_STREAM = 5,
36-
MSG_TYPE_WARNING_STREAM = 6,
37-
MSG_TYPE_ERROR_STREAM = 7
30+
MSG_TYPE_TYPE_BITS = 1<<0 | 1<<1 | 1<<2 | 1<<3, // 15
31+
MSG_TYPE_STREAM_BIT = 1<<4, // 16
32+
33+
MSG_TYPE_DEBUG = 1<<0, // 1
34+
MSG_TYPE_INFO = 1<<1, // 2
35+
MSG_TYPE_WARNING = 1<<2, // 4
36+
MSG_TYPE_ERROR = 1<<3, // 8
37+
MSG_TYPE_DEBUG_STREAM = MSG_TYPE_DEBUG | 1<<4, // 17
38+
MSG_TYPE_INFO_STREAM = MSG_TYPE_INFO | 1<<4, // 18
39+
MSG_TYPE_WARNING_STREAM = MSG_TYPE_WARNING | 1<<4, // 20
40+
MSG_TYPE_ERROR_STREAM = MSG_TYPE_ERROR | 1<<4 // 24
3841
};
3942
} // namespace dynamicgraph
4043

4144
/* --------------------------------------------------------------------- */
4245
/* --- INCLUDE --------------------------------------------------------- */
4346
/* --------------------------------------------------------------------- */
4447

45-
#include "boost/assign.hpp"
48+
#include <boost/assign.hpp>
49+
#include <boost/preprocessor/stringize.hpp>
4650
#include <dynamic-graph/linear-algebra.h>
51+
#include <dynamic-graph/real-time-logger-def.h>
4752
#include <fstream>
4853
#include <iomanip> // std::setprecision
4954
#include <map>
@@ -54,13 +59,36 @@ namespace dynamicgraph {
5459
//#define LOGGER_VERBOSITY_INFO_WARNING_ERROR
5560
#define LOGGER_VERBOSITY_ALL
5661

57-
#define SEND_MSG(msg, type) sendMsg(msg, type, __FILE__, __LINE__)
62+
#define SEND_MSG(msg, type) \
63+
sendMsg(msg, type, __FILE__ ":" BOOST_PP_STRINGIZE(__LINE__))
5864

5965
#define SEND_DEBUG_STREAM_MSG(msg) SEND_MSG(msg, MSG_TYPE_DEBUG_STREAM)
6066
#define SEND_INFO_STREAM_MSG(msg) SEND_MSG(msg, MSG_TYPE_INFO_STREAM)
6167
#define SEND_WARNING_STREAM_MSG(msg) SEND_MSG(msg, MSG_TYPE_WARNING_STREAM)
6268
#define SEND_ERROR_STREAM_MSG(msg) SEND_MSG(msg, MSG_TYPE_ERROR_STREAM)
6369

70+
#define _DYNAMIC_GRAPH_ENTITY_MSG(entity, type) \
71+
(entity).logger().stream(type, __FILE__ BOOST_PP_STRINGIZE(__LINE__))
72+
73+
#define DYNAMIC_GRAPH_ENTITY_DEBUG(entity) \
74+
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_DEBUG)
75+
#define DYNAMIC_GRAPH_ENTITY_INFO(entity) \
76+
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_INFO)
77+
#define DYNAMIC_GRAPH_ENTITY_WARNING(entity) \
78+
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_WARNING)
79+
#define DYNAMIC_GRAPH_ENTITY_ERROR(entity) \
80+
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_ERROR)
81+
82+
#define DYNAMIC_GRAPH_ENTITY_DEBUG_STREAM(entity) \
83+
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_DEBUG_STREAM)
84+
#define DYNAMIC_GRAPH_ENTITY_INFO_STREAM(entity) \
85+
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_INFO_STREAM)
86+
#define DYNAMIC_GRAPH_ENTITY_WARNING_STREAM(entity) \
87+
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_WARNING_STREAM)
88+
#define DYNAMIC_GRAPH_ENTITY_ERROR_STREAM(entity) \
89+
_DYNAMIC_GRAPH_ENTITY_MSG(entity, MSG_TYPE_ERROR_STREAM)
90+
91+
6492
template <typename T>
6593
std::string toString(const T &v, const int precision = 3,
6694
const int width = -1) {
@@ -111,11 +139,11 @@ std::string toString(const Eigen::MatrixBase<T> &v, const int precision = 3,
111139
}
112140

113141
enum LoggerVerbosity {
114-
VERBOSITY_ALL,
115-
VERBOSITY_INFO_WARNING_ERROR,
116-
VERBOSITY_WARNING_ERROR,
117-
VERBOSITY_ERROR,
118-
VERBOSITY_NONE
142+
VERBOSITY_ALL = MSG_TYPE_DEBUG,
143+
VERBOSITY_INFO_WARNING_ERROR = MSG_TYPE_INFO,
144+
VERBOSITY_WARNING_ERROR = MSG_TYPE_WARNING,
145+
VERBOSITY_ERROR = MSG_TYPE_ERROR,
146+
VERBOSITY_NONE = 0
119147
};
120148

121149
/// \ingroup debug
@@ -139,8 +167,14 @@ enum LoggerVerbosity {
139167
/// VERBOSITY_WARNING_ERROR;
140168
/// entity.setLoggerVerbosityLevel(aLoggerVerbosityLevel);
141169
/// ...
142-
/// std::string aMsg=aBaseMsg+" WARNING";
143-
/// entity.sendMsg(aMsg,dynamicgraph::MSG_TYPE_WARNING, __FILE__,__LINE__);
170+
/// // using macros
171+
/// DYNAMIC_GRAPH_ENTITY_WARNING(entity) << "your message\n";
172+
///
173+
/// // or the equivalent code without macros:
174+
/// // Please use '\n' instead of std::endl and flushing will have no effect
175+
/// entity.logger.stream(dynamicgraph::MSG_TYPE_WARNING,
176+
/// __FILE__ BOOST_PP_STRINGIZE(__LINE__))
177+
/// << your message << '\n';
144178
///
145179
/// \endcode
146180
///
@@ -157,13 +191,49 @@ class Logger {
157191
* to decrement the internal Logger's counter. */
158192
void countdown();
159193

194+
/** Check whether next message should be accepted.
195+
* \note See Logger::stream to see how to use it.
196+
* This will modify the counter associated to lineId as if it was
197+
* published. It should thus be used in conjunction with Logger::stream.
198+
*/
199+
bool acceptMsg (MsgType m, const std::string& lineId) {
200+
if ((m & MSG_TYPE_TYPE_BITS) < m_lv)
201+
return false;
202+
203+
// if print is allowed by current verbosity level
204+
if (isStreamMsg(m)) return checkStreamPeriod(lineId);
205+
return true;
206+
}
207+
208+
/** The most efficient logging method is
209+
* \code
210+
* if (logger.acceptMsg(type, lineId))
211+
* logger.stream() << "my message\n";
212+
* \endcode
213+
*/
214+
RTLoggerStream stream() {
215+
return ::dynamicgraph::RealTimeLogger::instance().emptyStream();
216+
}
217+
160218
/** Print the specified message on standard output if the verbosity level
161-
* allows it. The file name and the line number are used to identify
162-
* the point where sendMsg is called so that streaming messages are
163-
* printed only every streamPrintPeriod iterations.
219+
* allows it. The lineId is used to identify the point where sendMsg is
220+
* called so that streaming messages are printed only every streamPrintPeriod
221+
* iterations.
222+
* \param lineId typically __FILE__ ":" BOOST_PP_STRINGIZE(__LINE__)
164223
*/
165-
void sendMsg(std::string msg, MsgType type, const char *file = "",
166-
int line = 0);
224+
RTLoggerStream stream(MsgType type, const std::string& lineId = "") {
225+
RealTimeLogger &rtlogger = ::dynamicgraph::RealTimeLogger::instance();
226+
if (acceptMsg(type, lineId))
227+
return rtlogger.front();
228+
return rtlogger.emptyStream();
229+
}
230+
231+
/** \deprecated instead, use
232+
* \code
233+
* stream(type, lineId) << msg << '\n';
234+
* \endcode
235+
*/
236+
void sendMsg(std::string msg, MsgType type, const std::string& lineId = "");
167237

168238
/** Set the sampling time at which the method countdown()
169239
* is going to be called. */
@@ -193,13 +263,13 @@ class Logger {
193263
double m_printCountdown;
194264
/// every time this is < 0 (i.e. every _streamPrintPeriod sec) print stuff
195265

266+
typedef std::map<std::string, double> StreamCounterMap_t;
196267
/** Pointer to the dynamic structure which holds
197268
the collection of streaming messages */
198-
std::map<std::string, double> m_stream_msg_counters;
269+
StreamCounterMap_t m_stream_msg_counters;
199270

200-
bool isStreamMsg(MsgType m) {
201-
return m == MSG_TYPE_ERROR_STREAM || m == MSG_TYPE_DEBUG_STREAM ||
202-
m == MSG_TYPE_INFO_STREAM || m == MSG_TYPE_WARNING_STREAM;
271+
inline bool isStreamMsg(MsgType m) {
272+
return (m & MSG_TYPE_STREAM_BIT);
203273
}
204274

205275
bool isDebugMsg(MsgType m) {
@@ -217,6 +287,8 @@ class Logger {
217287
bool isErrorMsg(MsgType m) {
218288
return m == MSG_TYPE_ERROR_STREAM || m == MSG_TYPE_ERROR;
219289
}
290+
291+
bool checkStreamPeriod (const std::string& lineId);
220292
};
221293

222294
} // namespace dynamicgraph

src/debug/logger.cpp

Lines changed: 19 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@
2222

2323
namespace dynamicgraph {
2424

25-
using namespace std;
26-
2725
Logger::Logger(double timeSample, double streamPrintPeriod)
2826
: m_timeSample(timeSample), m_streamPrintPeriod(streamPrintPeriod),
2927
m_printCountdown(0.0) {
@@ -41,38 +39,8 @@ void Logger::countdown() {
4139
m_printCountdown -= m_timeSample;
4240
}
4341

44-
void Logger::sendMsg(string msg, MsgType type, const char *file, int line) {
45-
if (m_lv == VERBOSITY_NONE ||
46-
(m_lv == VERBOSITY_ERROR && !isErrorMsg(type)) ||
47-
(m_lv == VERBOSITY_WARNING_ERROR &&
48-
!(isWarningMsg(type) || isErrorMsg(type))) ||
49-
(m_lv == VERBOSITY_INFO_WARNING_ERROR && isDebugMsg(type)))
50-
return;
51-
52-
// if print is allowed by current verbosity level
53-
if (isStreamMsg(type)) {
54-
// check whether counter already exists
55-
std::ostringstream oss;
56-
oss << file << line;
57-
std::string id(oss.str());
58-
map<string, double>::iterator it = m_stream_msg_counters.find(id);
59-
if (it == m_stream_msg_counters.end()) {
60-
// if counter doesn't exist then add one
61-
m_stream_msg_counters.insert(make_pair(id, 0.0));
62-
it = m_stream_msg_counters.find(id);
63-
}
64-
65-
// if counter is greater than 0 then decrement it and do not print
66-
if (it->second > 0.0) {
67-
it->second -= m_timeSample;
68-
if (it->second <= 0.0)
69-
it->second = m_streamPrintPeriod;
70-
else
71-
return;
72-
} else // otherwise reset counter and print
73-
it->second = m_streamPrintPeriod;
74-
}
75-
dgRTLOG() << msg.c_str() << "\n";
42+
void Logger::sendMsg(std::string msg, MsgType type, const std::string &lineId) {
43+
stream(type, lineId) << msg << '\n';
7644
}
7745

7846
bool Logger::setTimeSample(double t) {
@@ -92,4 +60,21 @@ bool Logger::setStreamPrintPeriod(double s) {
9260
double Logger::getTimeSample() { return m_timeSample; }
9361

9462
double Logger::getStreamPrintPeriod() { return m_streamPrintPeriod; }
63+
64+
bool Logger::checkStreamPeriod(const std::string &lineId) {
65+
// insert element with value 0 if it does not exist.
66+
// otherwise, return a counter to the existing one.
67+
std::pair<StreamCounterMap_t::iterator, bool> result =
68+
m_stream_msg_counters.insert(std::make_pair(lineId, 0.));
69+
70+
// if counter is greater than 0 then decrement it and do not print
71+
double &counter = result.first->second;
72+
if (counter > 0.0) {
73+
counter -= m_timeSample;
74+
return false;
75+
} else // otherwise reset counter and print
76+
counter = m_streamPrintPeriod;
77+
return true;
78+
}
79+
9580
} // namespace dynamicgraph

src/dgraph/entity.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ Command *Entity::getNewStyleCommand(const std::string &commandName) {
207207
return commandMap[commandName];
208208
}
209209

210-
void Entity::sendMsg(const std::string &msg, MsgType t, const char *file,
211-
int line) {
212-
logger_.sendMsg("[" + name + "]" + msg, t, file, line);
210+
void Entity::sendMsg(const std::string &msg, MsgType t,
211+
const std::string &lineId) {
212+
logger_.sendMsg("[" + name + "]" + msg, t, lineId);
213213
}

tests/entity.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -216,15 +216,16 @@ BOOST_AUTO_TEST_CASE(sendMsg) {
216216
if (entity.getLoggerVerbosityLevel() != aLoggerVerbosityLevel)
217217
output << "Mismatch output";
218218

219-
std::string aBaseMsg = "Auto Test Case";
220-
std::string aMsg = aBaseMsg + " DEBUG";
221-
entity.sendMsg(aMsg, dynamicgraph::MSG_TYPE_DEBUG, __FILE__, __LINE__);
222-
aMsg = aBaseMsg + " INFO";
223-
entity.sendMsg(aMsg, dynamicgraph::MSG_TYPE_INFO, __FILE__, __LINE__);
224-
aMsg = aBaseMsg + " WARNING";
225-
entity.sendMsg(aMsg, dynamicgraph::MSG_TYPE_WARNING, __FILE__, __LINE__);
226-
aMsg = aBaseMsg + " DEBUG";
227-
entity.sendMsg(aMsg, dynamicgraph::MSG_TYPE_ERROR, __FILE__, __LINE__);
219+
#define __FILELINE__ __FILE__ BOOST_PP_STRINGIZE(__LINE__)
220+
entity.logger().stream(dynamicgraph::MSG_TYPE_DEBUG, __FILELINE__)
221+
<< "Auto Test Case" << " DEBUG" << '\n';
222+
entity.logger().stream(dynamicgraph::MSG_TYPE_INFO, __FILELINE__)
223+
<< "Auto Test Case" << " INFO" << '\n';
224+
entity.logger().stream(dynamicgraph::MSG_TYPE_WARNING, __FILELINE__)
225+
<< "Auto Test Case" << " WARNING" << '\n';
226+
entity.logger().stream(dynamicgraph::MSG_TYPE_ERROR, __FILELINE__)
227+
<< "Auto Test Case" << " ERROR" << '\n';
228+
#undef __FILELINE__
228229
};
229230
};
230231

0 commit comments

Comments
 (0)