Skip to content
Snippets Groups Projects
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
No related branches found
No related tags found
No related merge requests found
......@@ -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&
......
......@@ -31,6 +31,7 @@ namespace dynamicgraph
class FactoryStorage;
class Interpreter;
class InterpreterHelper;
class Logger;
class OutStringStream;
class PluginLoader;
class PoolStorage;
......
/*
* 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
......
/*
* 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
......@@ -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);
}
......@@ -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)
{
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment