From 0e6d4e5f3c24f28774b60292b99c4f24d67f5218 Mon Sep 17 00:00:00 2001 From: Olivier Stasse <ostasse@laas.fr> Date: Tue, 29 Jan 2019 16:13:54 +0100 Subject: [PATCH] [topic/logger] Add Logger to all entities. It stream messages on a shared file. Each entity has a different verbosity level. Uses a non real time thread to perform logging. No yet working. --- include/dynamic-graph/entity.h | 18 +++++ include/dynamic-graph/fwd.hh | 1 + include/dynamic-graph/logger.h | 76 +++++++----------- src/debug/logger.cpp | 141 +++++++++++++++++---------------- src/dgraph/entity.cpp | 9 +++ tests/entity.cpp | 46 +++++++++++ 6 files changed, 176 insertions(+), 115 deletions(-) diff --git a/include/dynamic-graph/entity.h b/include/dynamic-graph/entity.h index ae5b9f0..015c5d5 100644 --- a/include/dynamic-graph/entity.h +++ b/include/dynamic-graph/entity.h @@ -29,6 +29,7 @@ # include <dynamic-graph/exception-factory.h> # include <dynamic-graph/signal-array.h> # include <dynamic-graph/signal-base.h> +# include <dynamic-graph/logger.h> /// \brief Helper macro for entity declaration. /// @@ -108,6 +109,22 @@ namespace dynamicgraph command::Command* getNewStyleCommand( const std::string& cmdName ); SignalMap getSignalMap() const; + + /** \name Logger related methods */ + /** \{*/ + /// \brief Send messages \param msg with level t. Add string file and line to message. + void sendMsg(const std::string &msg, + MsgType t=MSG_TYPE_INFO, + const char *file="", + int line=0); + + /// \brief Specify the verbosity level of the logger. + void setLoggerVerbosityLevel(LoggerVerbosity lv) + {logger_.setVerbosity(lv);} + + /// \brief Get the logger's verbosity level. + LoggerVerbosity getLoggerVerbosityLevel() + { return logger_.getVerbosity(); }; protected: void addCommand(const std::string& name,command::Command* command); @@ -120,6 +137,7 @@ namespace dynamicgraph std::string name; SignalMap signalMap; CommandMap_t commandMap; + Logger logger_; }; DYNAMIC_GRAPH_DLLAPI std::ostream& diff --git a/include/dynamic-graph/fwd.hh b/include/dynamic-graph/fwd.hh index 6a3f558..1f3fdc2 100644 --- a/include/dynamic-graph/fwd.hh +++ b/include/dynamic-graph/fwd.hh @@ -31,6 +31,7 @@ namespace dynamicgraph class FactoryStorage; class Interpreter; class InterpreterHelper; + class Logger; class OutStringStream; class PluginLoader; class PoolStorage; diff --git a/include/dynamic-graph/logger.h b/include/dynamic-graph/logger.h index f40a0ec..31bd8dd 100644 --- a/include/dynamic-graph/logger.h +++ b/include/dynamic-graph/logger.h @@ -1,7 +1,7 @@ /* * Copyright 2015, 2019 * LAAS-CNRS - * Andrea Del Prete, François Bailly, + * Andrea Del Prete, François Bailly, Olivier Stasse * * This file is part of dynamic-graph. * See license file. @@ -24,16 +24,33 @@ # define LOGGER_EXPORT #endif +namespace dynamicgraph { + + /** Enum representing the different kind of messages. + */ + enum MsgType + { + MSG_TYPE_DEBUG =0, + MSG_TYPE_INFO =1, + MSG_TYPE_WARNING =2, + MSG_TYPE_ERROR =3, + MSG_TYPE_DEBUG_STREAM =4, + MSG_TYPE_INFO_STREAM =5, + MSG_TYPE_WARNING_STREAM =6, + MSG_TYPE_ERROR_STREAM =7 + }; +} /* --------------------------------------------------------------------- */ /* --- INCLUDE --------------------------------------------------------- */ /* --------------------------------------------------------------------- */ -#include <dynamic-graph/signal-helper.h> #include <map> #include <iomanip> // std::setprecision +#include <fstream> +#include <sstream> #include "boost/assign.hpp" - +#include <dynamic-graph/linear-algebra.h> namespace dynamicgraph { @@ -42,47 +59,10 @@ namespace dynamicgraph { #define SEND_MSG(msg,type) sendMsg(msg,type,__FILE__,__LINE__) -#ifdef LOGGER_VERBOSITY_ERROR - #define SEND_DEBUG_STREAM_MSG(msg) - #define SEND_INFO_STREAM_MSG(msg) - #define SEND_WARNING_STREAM_MSG(msg) - #define SEND_ERROR_STREAM_MSG(msg) SEND_MSG(msg,MSG_TYPE_ERROR_STREAM) -#endif - -#ifdef LOGGER_VERBOSITY_WARNING_ERROR - #define SEND_DEBUG_STREAM_MSG(msg) - #define SEND_INFO_STREAM_MSG(msg)\ - #define SEND_WARNING_STREAM_MSG(msg) SEND_MSG(msg,MSG_TYPE_WARNING_STREAM) - #define SEND_ERROR_STREAM_MSG(msg) SEND_MSG(msg,MSG_TYPE_ERROR_STREAM) -#endif - -#ifdef LOGGER_VERBOSITY_INFO_WARNING_ERROR - #define SEND_DEBUG_STREAM_MSG(msg) - #define SEND_INFO_STREAM_MSG(msg) SEND_MSG(msg,MSG_TYPE_INFO_STREAM) - #define SEND_WARNING_STREAM_MSG(msg) SEND_MSG(msg,MSG_TYPE_WARNING_STREAM) - #define SEND_ERROR_STREAM_MSG(msg) SEND_MSG(msg,MSG_TYPE_ERROR_STREAM) -#endif - -#ifdef LOGGER_VERBOSITY_ALL - #define SEND_DEBUG_STREAM_MSG(msg) SEND_MSG(msg,MSG_TYPE_DEBUG_STREAM) - #define SEND_INFO_STREAM_MSG(msg) SEND_MSG(msg,MSG_TYPE_INFO_STREAM) - #define SEND_WARNING_STREAM_MSG(msg) SEND_MSG(msg,MSG_TYPE_WARNING_STREAM) - #define SEND_ERROR_STREAM_MSG(msg) SEND_MSG(msg,MSG_TYPE_ERROR_STREAM) -#endif - - /** Enum representing the different kind of messages. - */ - enum MsgType - { - MSG_TYPE_DEBUG =0, - MSG_TYPE_INFO =1, - MSG_TYPE_WARNING =2, - MSG_TYPE_ERROR =3, - MSG_TYPE_DEBUG_STREAM =4, - MSG_TYPE_INFO_STREAM =5, - MSG_TYPE_WARNING_STREAM =6, - MSG_TYPE_ERROR_STREAM =7 - }; +#define SEND_DEBUG_STREAM_MSG(msg) SEND_MSG(msg,MSG_TYPE_DEBUG_STREAM) +#define SEND_INFO_STREAM_MSG(msg) SEND_MSG(msg,MSG_TYPE_INFO_STREAM) +#define SEND_WARNING_STREAM_MSG(msg) SEND_MSG(msg,MSG_TYPE_WARNING_STREAM) +#define SEND_ERROR_STREAM_MSG(msg) SEND_MSG(msg,MSG_TYPE_ERROR_STREAM) template<typename T> std::string toString(const T& v, const int precision=3, const int width=-1) @@ -159,7 +139,7 @@ namespace dynamicgraph { Logger(double timeSample=0.001, double streamPrintPeriod=1.0); /** Destructor */ - ~Logger(){} + ~Logger(); /** Method to be called at every control iteration * to decrement the internal Logger's counter. */ @@ -182,7 +162,11 @@ namespace dynamicgraph { /** Set the verbosity level of the logger. */ void setVerbosity(LoggerVerbosity lv); + /** Get the verbosity level of the logger. */ + LoggerVerbosity getVerbosity(); + protected: + std::ofstream m_output_fstream; /// Output File Stream LoggerVerbosity m_lv; /// verbosity of the logger double m_timeSample; /// specify the period of call of the countdown method double m_streamPrintPeriod; /// specify the time period of the stream prints @@ -207,8 +191,6 @@ namespace dynamicgraph { { return m==MSG_TYPE_ERROR_STREAM || m==MSG_TYPE_ERROR; } }; - /** Method to get the logger (singleton). */ - Logger& getLogger(); } // namespace dynamicgraph diff --git a/src/debug/logger.cpp b/src/debug/logger.cpp index 412de96..cd37b19 100644 --- a/src/debug/logger.cpp +++ b/src/debug/logger.cpp @@ -1,108 +1,113 @@ /* * Copyright 2015, 2019 * LAAS-CNRS - * Andrea Del Prete, François Bailly + * Andrea Del Prete, François Bailly, Olivier Stasse * * This file is part of dynamic-graph. * See license file. */ #ifndef WIN32 - #include <sys/time.h> +#include <sys/time.h> #else - #include <Windows.h> +#include <Windows.h> #endif +#define ENABLE_RT_LOG #include <stdio.h> #include <iostream> #include <iomanip> // std::setprecision #include <dynamic-graph/logger.h> +#include <dynamic-graph/real-time-logger.h> + namespace dynamicgraph { - using namespace std; + using namespace std; - Logger& getLogger() - { - static Logger l(0.001, 1.0); - return l; - } + Logger::Logger(double timeSample, double streamPrintPeriod) + : m_timeSample(timeSample), + m_streamPrintPeriod(streamPrintPeriod), + m_printCountdown(0.0) + { + m_lv = VERBOSITY_ERROR; + // m_output_fstream.open("/tmp/dg-LOGS.txt",std::ofstream::out|std::ofstream::app); + //dgADD_OSTREAM_TO_RTLOG(m_output_fstream); + } - Logger::Logger(double timeSample, double streamPrintPeriod) - : m_timeSample(timeSample), - m_streamPrintPeriod(streamPrintPeriod), - m_printCountdown(0.0) - { -#ifdef LOGGER_VERBOSITY_ERROR - m_lv = VERBOSITY_ERROR; -#endif -#ifdef LOGGER_VERBOSITY_WARNING_ERROR - m_lv = VERBOSITY_WARNING_ERROR; -#endif -#ifdef LOGGER_VERBOSITY_INFO_WARNING_ERROR - m_lv = VERBOSITY_INFO_WARNING_ERROR; -#endif -#ifdef LOGGER_VERBOSITY_ALL - m_lv = VERBOSITY_ALL; -#endif - } + Logger::~Logger() + { + //m_output_fstream.close(); + + } + + void Logger::setVerbosity(LoggerVerbosity lv) + { + m_lv=lv; + } - void Logger::countdown() - { - if(m_printCountdown<0.0) - m_printCountdown = m_streamPrintPeriod; - m_printCountdown -= m_timeSample; - } + LoggerVerbosity Logger::getVerbosity() + { + return m_lv; + + } + void Logger::countdown() + { + if(m_printCountdown<0.0) + m_printCountdown = m_streamPrintPeriod; + m_printCountdown -= m_timeSample; + } - void Logger::sendMsg(string msg, MsgType type, const char* file, int line) - { - if(m_lv==VERBOSITY_NONE || - (m_lv==VERBOSITY_ERROR && !isErrorMsg(type)) || - (m_lv==VERBOSITY_WARNING_ERROR && !(isWarningMsg(type) || isErrorMsg(type))) || - (m_lv==VERBOSITY_INFO_WARNING_ERROR && isDebugMsg(type))) - return; + void Logger::sendMsg(string msg, MsgType type, const char* file, int line) + { + if(m_lv==VERBOSITY_NONE || + (m_lv==VERBOSITY_ERROR && !isErrorMsg(type)) || + (m_lv==VERBOSITY_WARNING_ERROR && !(isWarningMsg(type) || isErrorMsg(type))) || + (m_lv==VERBOSITY_INFO_WARNING_ERROR && isDebugMsg(type))) + return; - // if print is allowed by current verbosity level - if(isStreamMsg(type)) + // if print is allowed by current verbosity level + if(isStreamMsg(type)) { // check whether counter already exists string id = file+toString(line); map<string,double>::iterator it = m_stream_msg_counters.find(id); if(it == m_stream_msg_counters.end()) - { - // if counter doesn't exist then add one - m_stream_msg_counters.insert(make_pair(id, 0.0)); - it = m_stream_msg_counters.find(id); - } + { + // if counter doesn't exist then add one + m_stream_msg_counters.insert(make_pair(id, 0.0)); + it = m_stream_msg_counters.find(id); + } // if counter is greater than 0 then decrement it and do not print if(it->second>0.0) - { - it->second -= m_timeSample; - return; - } + { + it->second -= m_timeSample; + return; + } else // otherwise reset counter and print it->second = m_streamPrintPeriod; } - printf("%s\n", msg.c_str()); - fflush(stdout); // Prints to screen or whatever your standard out is - } + // std::cout << msg.c_str() << std::endl; + dgRTLOG() << msg.c_str() << "\n"; + //m_output_fstream.flush(); + } - bool Logger::setTimeSample(double t) - { - if(t<=0.0) - return false; - m_timeSample = t; - return true; - } + bool Logger::setTimeSample(double t) + { + if(t<=0.0) + return false; + m_timeSample = t; + return true; + } - bool Logger::setStreamPrintPeriod(double s) - { - if(s<=0.0) - return false; - m_streamPrintPeriod = s; - return true; - } + bool Logger::setStreamPrintPeriod(double s) + { + if(s<=0.0) + return false; + m_streamPrintPeriod = s; + return true; + } } // namespace dynamicgraph diff --git a/src/dgraph/entity.cpp b/src/dgraph/entity.cpp index 1b5e128..87f09ad 100644 --- a/src/dgraph/entity.cpp +++ b/src/dgraph/entity.cpp @@ -278,3 +278,12 @@ getNewStyleCommand( const std::string& commandName ) return commandMap[commandName]; } +void Entity:: +sendMsg(const std::string &msg, + MsgType t, + const char *file, + int line) +{ + logger_.sendMsg("["+name+"]"+msg,t,file,line); +} + diff --git a/tests/entity.cpp b/tests/entity.cpp index eb15d63..f757d8c 100644 --- a/tests/entity.cpp +++ b/tests/entity.cpp @@ -18,6 +18,7 @@ #include <dynamic-graph/exception-factory.h> #include "dynamic-graph/factory.h" #include "dynamic-graph/pool.h" +#include <dynamic-graph/real-time-logger.h> #define BOOST_TEST_MODULE entity @@ -142,6 +143,51 @@ BOOST_AUTO_TEST_CASE (writeCompletionList) BOOST_CHECK (output.is_equal ("")); } +BOOST_AUTO_TEST_CASE (sendMsg) +{ + std::ofstream of; + of.open("/tmp/dg-LOGS.txt",std::ofstream::out|std::ofstream::app); + dgADD_OSTREAM_TO_RTLOG(of); + + dynamicgraph::Entity& entity = + dynamicgraph::PoolStorage::getInstance()->getEntity("my-entity"); + std::string AppendMsg[4] = {" INFO_WARNING_ERROR", + " WARNING_ERROR", + " ERROR", + " ALL", + }; + + output_test_stream output; + + for(unsigned int i=0; + i<4; + i++) + { + for(unsigned int j=0;j<2000;j++) + { + dynamicgraph::LoggerVerbosity aLoggerVerbosityLevel= + (dynamicgraph::LoggerVerbosity) i; + entity.setLoggerVerbosityLevel(aLoggerVerbosityLevel); + if (entity.getLoggerVerbosityLevel()!=aLoggerVerbosityLevel) + output << "Mismatch output"; + + std::string aBaseMsg="Auto Test Case"; + std::string aMsg=aBaseMsg+" DEBUG"; + entity.sendMsg(aMsg, dynamicgraph::MSG_TYPE_DEBUG, __FILE__, __LINE__); + aMsg=aBaseMsg+" INFO"; + entity.sendMsg(aMsg, dynamicgraph::MSG_TYPE_INFO, __FILE__, __LINE__); + aMsg=aBaseMsg+" WARNING"; + entity.sendMsg(aMsg, dynamicgraph::MSG_TYPE_WARNING, __FILE__, __LINE__); + aMsg=aBaseMsg+" DEBUG"; + entity.sendMsg(aMsg, dynamicgraph::MSG_TYPE_ERROR, __FILE__, __LINE__); + }; + }; + + BOOST_CHECK (output.is_equal ("")); + usleep (1000000); + dynamicgraph::RealTimeLogger::destroy(); +} + // WTF? BOOST_AUTO_TEST_CASE (wtf) { -- GitLab