Commit 0e6d4e5f authored by Olivier Stasse's avatar Olivier Stasse Committed by olivier stasse
Browse files

[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.
parent fab8909c
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
# include <dynamic-graph/exception-factory.h> # include <dynamic-graph/exception-factory.h>
# include <dynamic-graph/signal-array.h> # include <dynamic-graph/signal-array.h>
# include <dynamic-graph/signal-base.h> # include <dynamic-graph/signal-base.h>
# include <dynamic-graph/logger.h>
/// \brief Helper macro for entity declaration. /// \brief Helper macro for entity declaration.
/// ///
...@@ -108,6 +109,22 @@ namespace dynamicgraph ...@@ -108,6 +109,22 @@ namespace dynamicgraph
command::Command* getNewStyleCommand( const std::string& cmdName ); command::Command* getNewStyleCommand( const std::string& cmdName );
SignalMap getSignalMap() const; 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: protected:
void addCommand(const std::string& name,command::Command* command); void addCommand(const std::string& name,command::Command* command);
...@@ -120,6 +137,7 @@ namespace dynamicgraph ...@@ -120,6 +137,7 @@ namespace dynamicgraph
std::string name; std::string name;
SignalMap signalMap; SignalMap signalMap;
CommandMap_t commandMap; CommandMap_t commandMap;
Logger logger_;
}; };
DYNAMIC_GRAPH_DLLAPI std::ostream& DYNAMIC_GRAPH_DLLAPI std::ostream&
......
...@@ -31,6 +31,7 @@ namespace dynamicgraph ...@@ -31,6 +31,7 @@ namespace dynamicgraph
class FactoryStorage; class FactoryStorage;
class Interpreter; class Interpreter;
class InterpreterHelper; class InterpreterHelper;
class Logger;
class OutStringStream; class OutStringStream;
class PluginLoader; class PluginLoader;
class PoolStorage; class PoolStorage;
......
/* /*
* Copyright 2015, 2019 * Copyright 2015, 2019
* LAAS-CNRS * LAAS-CNRS
* Andrea Del Prete, François Bailly, * Andrea Del Prete, François Bailly, Olivier Stasse
* *
* This file is part of dynamic-graph. * This file is part of dynamic-graph.
* See license file. * See license file.
...@@ -24,16 +24,33 @@ ...@@ -24,16 +24,33 @@
# define LOGGER_EXPORT # define LOGGER_EXPORT
#endif #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 --------------------------------------------------------- */
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
#include <dynamic-graph/signal-helper.h>
#include <map> #include <map>
#include <iomanip> // std::setprecision #include <iomanip> // std::setprecision
#include <fstream>
#include <sstream>
#include "boost/assign.hpp" #include "boost/assign.hpp"
#include <dynamic-graph/linear-algebra.h>
namespace dynamicgraph { namespace dynamicgraph {
...@@ -42,47 +59,10 @@ namespace dynamicgraph { ...@@ -42,47 +59,10 @@ namespace dynamicgraph {
#define SEND_MSG(msg,type) sendMsg(msg,type,__FILE__,__LINE__) #define SEND_MSG(msg,type) sendMsg(msg,type,__FILE__,__LINE__)
#ifdef LOGGER_VERBOSITY_ERROR #define SEND_DEBUG_STREAM_MSG(msg) SEND_MSG(msg,MSG_TYPE_DEBUG_STREAM)
#define SEND_DEBUG_STREAM_MSG(msg) #define SEND_INFO_STREAM_MSG(msg) SEND_MSG(msg,MSG_TYPE_INFO_STREAM)
#define SEND_INFO_STREAM_MSG(msg) #define SEND_WARNING_STREAM_MSG(msg) SEND_MSG(msg,MSG_TYPE_WARNING_STREAM)
#define SEND_WARNING_STREAM_MSG(msg) #define SEND_ERROR_STREAM_MSG(msg) SEND_MSG(msg,MSG_TYPE_ERROR_STREAM)
#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
};
template<typename T> template<typename T>
std::string toString(const T& v, const int precision=3, const int width=-1) std::string toString(const T& v, const int precision=3, const int width=-1)
...@@ -159,7 +139,7 @@ namespace dynamicgraph { ...@@ -159,7 +139,7 @@ namespace dynamicgraph {
Logger(double timeSample=0.001, double streamPrintPeriod=1.0); Logger(double timeSample=0.001, double streamPrintPeriod=1.0);
/** Destructor */ /** Destructor */
~Logger(){} ~Logger();
/** Method to be called at every control iteration /** Method to be called at every control iteration
* to decrement the internal Logger's counter. */ * to decrement the internal Logger's counter. */
...@@ -182,7 +162,11 @@ namespace dynamicgraph { ...@@ -182,7 +162,11 @@ namespace dynamicgraph {
/** Set the verbosity level of the logger. */ /** Set the verbosity level of the logger. */
void setVerbosity(LoggerVerbosity lv); void setVerbosity(LoggerVerbosity lv);
/** Get the verbosity level of the logger. */
LoggerVerbosity getVerbosity();
protected: protected:
std::ofstream m_output_fstream; /// Output File Stream
LoggerVerbosity m_lv; /// verbosity of the logger LoggerVerbosity m_lv; /// verbosity of the logger
double m_timeSample; /// specify the period of call of the countdown method double m_timeSample; /// specify the period of call of the countdown method
double m_streamPrintPeriod; /// specify the time period of the stream prints double m_streamPrintPeriod; /// specify the time period of the stream prints
...@@ -207,8 +191,6 @@ namespace dynamicgraph { ...@@ -207,8 +191,6 @@ namespace dynamicgraph {
{ return m==MSG_TYPE_ERROR_STREAM || m==MSG_TYPE_ERROR; } { return m==MSG_TYPE_ERROR_STREAM || m==MSG_TYPE_ERROR; }
}; };
/** Method to get the logger (singleton). */
Logger& getLogger();
} // namespace dynamicgraph } // namespace dynamicgraph
......
/* /*
* Copyright 2015, 2019 * Copyright 2015, 2019
* LAAS-CNRS * LAAS-CNRS
* Andrea Del Prete, François Bailly * Andrea Del Prete, François Bailly, Olivier Stasse
* *
* This file is part of dynamic-graph. * This file is part of dynamic-graph.
* See license file. * See license file.
*/ */
#ifndef WIN32 #ifndef WIN32
#include <sys/time.h> #include <sys/time.h>
#else #else
#include <Windows.h> #include <Windows.h>
#endif #endif
#define ENABLE_RT_LOG
#include <stdio.h> #include <stdio.h>
#include <iostream> #include <iostream>
#include <iomanip> // std::setprecision #include <iomanip> // std::setprecision
#include <dynamic-graph/logger.h> #include <dynamic-graph/logger.h>
#include <dynamic-graph/real-time-logger.h>
namespace dynamicgraph namespace dynamicgraph
{ {
using namespace std; using namespace std;
Logger& getLogger() Logger::Logger(double timeSample, double streamPrintPeriod)
{ : m_timeSample(timeSample),
static Logger l(0.001, 1.0); m_streamPrintPeriod(streamPrintPeriod),
return l; 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) Logger::~Logger()
: m_timeSample(timeSample), {
m_streamPrintPeriod(streamPrintPeriod), //m_output_fstream.close();
m_printCountdown(0.0)
{ }
#ifdef LOGGER_VERBOSITY_ERROR
m_lv = VERBOSITY_ERROR; void Logger::setVerbosity(LoggerVerbosity lv)
#endif {
#ifdef LOGGER_VERBOSITY_WARNING_ERROR m_lv=lv;
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
}
void Logger::countdown() LoggerVerbosity Logger::getVerbosity()
{ {
if(m_printCountdown<0.0) return m_lv;
m_printCountdown = m_streamPrintPeriod;
m_printCountdown -= m_timeSample; }
} 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) void Logger::sendMsg(string msg, MsgType type, const char* file, int line)
{ {
if(m_lv==VERBOSITY_NONE || if(m_lv==VERBOSITY_NONE ||
(m_lv==VERBOSITY_ERROR && !isErrorMsg(type)) || (m_lv==VERBOSITY_ERROR && !isErrorMsg(type)) ||
(m_lv==VERBOSITY_WARNING_ERROR && !(isWarningMsg(type) || isErrorMsg(type))) || (m_lv==VERBOSITY_WARNING_ERROR && !(isWarningMsg(type) || isErrorMsg(type))) ||
(m_lv==VERBOSITY_INFO_WARNING_ERROR && isDebugMsg(type))) (m_lv==VERBOSITY_INFO_WARNING_ERROR && isDebugMsg(type)))
return; return;
// if print is allowed by current verbosity level // if print is allowed by current verbosity level
if(isStreamMsg(type)) if(isStreamMsg(type))
{ {
// check whether counter already exists // check whether counter already exists
string id = file+toString(line); string id = file+toString(line);
map<string,double>::iterator it = m_stream_msg_counters.find(id); map<string,double>::iterator it = m_stream_msg_counters.find(id);
if(it == m_stream_msg_counters.end()) if(it == m_stream_msg_counters.end())
{ {
// if counter doesn't exist then add one // if counter doesn't exist then add one
m_stream_msg_counters.insert(make_pair(id, 0.0)); m_stream_msg_counters.insert(make_pair(id, 0.0));
it = m_stream_msg_counters.find(id); it = m_stream_msg_counters.find(id);
} }
// if counter is greater than 0 then decrement it and do not print // if counter is greater than 0 then decrement it and do not print
if(it->second>0.0) if(it->second>0.0)
{ {
it->second -= m_timeSample; it->second -= m_timeSample;
return; return;
} }
else // otherwise reset counter and print else // otherwise reset counter and print
it->second = m_streamPrintPeriod; it->second = m_streamPrintPeriod;
} }
printf("%s\n", msg.c_str()); // std::cout << msg.c_str() << std::endl;
fflush(stdout); // Prints to screen or whatever your standard out is dgRTLOG() << msg.c_str() << "\n";
} //m_output_fstream.flush();
}
bool Logger::setTimeSample(double t) bool Logger::setTimeSample(double t)
{ {
if(t<=0.0) if(t<=0.0)
return false; return false;
m_timeSample = t; m_timeSample = t;
return true; return true;
} }
bool Logger::setStreamPrintPeriod(double s) bool Logger::setStreamPrintPeriod(double s)
{ {
if(s<=0.0) if(s<=0.0)
return false; return false;
m_streamPrintPeriod = s; m_streamPrintPeriod = s;
return true; return true;
} }
} // namespace dynamicgraph } // namespace dynamicgraph
...@@ -278,3 +278,12 @@ getNewStyleCommand( const std::string& commandName ) ...@@ -278,3 +278,12 @@ getNewStyleCommand( const std::string& commandName )
return commandMap[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);
}
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <dynamic-graph/exception-factory.h> #include <dynamic-graph/exception-factory.h>
#include "dynamic-graph/factory.h" #include "dynamic-graph/factory.h"
#include "dynamic-graph/pool.h" #include "dynamic-graph/pool.h"
#include <dynamic-graph/real-time-logger.h>
#define BOOST_TEST_MODULE entity #define BOOST_TEST_MODULE entity
...@@ -142,6 +143,51 @@ BOOST_AUTO_TEST_CASE (writeCompletionList) ...@@ -142,6 +143,51 @@ BOOST_AUTO_TEST_CASE (writeCompletionList)
BOOST_CHECK (output.is_equal ("")); 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? // WTF?
BOOST_AUTO_TEST_CASE (wtf) BOOST_AUTO_TEST_CASE (wtf)
{ {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment