logger.h 6.82 KB
Newer Older
1
2
3
/*
 * Copyright 2015, 2019
 * LAAS-CNRS
4
 * Andrea Del Prete, François Bailly, Olivier Stasse
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 *
 * This file is part of dynamic-graph.
 * See license file.
 */

#ifndef __dynamic_graph_logger_H__
#define __dynamic_graph_logger_H__

/* --------------------------------------------------------------------- */
/* --- API ------------------------------------------------------------- */
/* --------------------------------------------------------------------- */

#if defined (WIN32)
#  if defined (logger_EXPORTS)
#    define LOGGER_EXPORT __declspec(dllexport)
#  else
#    define LOGGER_EXPORT __declspec(dllimport)
#  endif
#else
#  define LOGGER_EXPORT
#endif

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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
  };
}
43
44
45
46
47
48
49

/* --------------------------------------------------------------------- */
/* --- INCLUDE --------------------------------------------------------- */
/* --------------------------------------------------------------------- */

#include <map>
#include <iomanip> // std::setprecision
50
51
#include <fstream>
#include <sstream>
52
#include "boost/assign.hpp"
53
#include <dynamic-graph/linear-algebra.h>
54
55
56
57
58
59
60
61

namespace dynamicgraph {

//#define LOGGER_VERBOSITY_INFO_WARNING_ERROR
#define LOGGER_VERBOSITY_ALL

#define SEND_MSG(msg,type)         sendMsg(msg,type,__FILE__,__LINE__)

62
63
64
65
#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)
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131

  template<typename T>
  std::string toString(const T& v, const int precision=3, const int width=-1)
  {
    std::stringstream ss;
    if(width>precision)
      ss<<std::fixed<<std::setw(width)<<std::setprecision(precision)<<v;
    else
      ss<<std::fixed<<std::setprecision(precision)<<v;
    return ss.str();
  }

  template<typename T>
  std::string toString(const std::vector<T>& v, const int precision=3, const int width=-1,
                       const std::string separator=", ")
  {
    std::stringstream ss;
    if(width>precision)
    {
      for(int i=0; i<v.size()-1; i++)
        ss<<std::fixed<<std::setw(width)<<std::setprecision(precision)<<v[i]<<separator;
      ss<<std::fixed<<std::setw(width)<<std::setprecision(precision)<<v[v.size()-1];
    }
    else
    {
      for(int i=0; i<v.size()-1; i++)
        ss<<std::fixed<<std::setprecision(precision)<<v[i]<<separator;
      ss<<std::fixed<<std::setprecision(precision)<<v[v.size()-1];
    }

    return ss.str();
  }

//      template<typename T, int N>
//      std::string toString(const Eigen::Matrix<T, N, 1, 0, N, 1>& v, const std::string separator=", ",
//                           const int precision=3, const int width=-1)
  template<typename T>
  std::string toString(const Eigen::MatrixBase<T>& v,
                       const int precision=3, const int width=-1, const std::string separator=", ")
  {
    std::stringstream ss;
    if(width>precision)
    {
      for(int i=0; i<v.size()-1; i++)
        ss<<std::fixed<<std::setw(width)<<std::setprecision(precision)<<v[i]<<separator;
      ss<<std::fixed<<std::setw(width)<<std::setprecision(precision)<<v[v.size()-1];
    }
    else
    {
      for(int i=0; i<v.size()-1; i++)
        ss<<std::fixed<<std::setprecision(precision)<<v[i]<<separator;
      ss<<std::setprecision(precision)<<v[v.size()-1];
    }

    return ss.str();
  }

  enum LoggerVerbosity
  {
    VERBOSITY_ALL,
    VERBOSITY_INFO_WARNING_ERROR,
    VERBOSITY_WARNING_ERROR,
    VERBOSITY_ERROR,
    VERBOSITY_NONE
  };

132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
  /// \ingroup debug
  ///
  /// \brief Class for logging messages
  ///
  /// It is intended to be used like this:
  /// \code
  /// #define ENABLE_RT_LOG
  /// #include <dynamic-graph/real-time-logger.h>
  ///
  /// // Somewhere in the main function of your executable
  /// int main (int argc, char** argv) {
  ///   std::ofstream of;
  ///   of.open("/tmp/dg-LOGS.txt",std::ofstream::out|std::ofstream::app); 
  ///   dgADD_OSTREAM_TO_RTLOG (of);
  /// }
  ///
  /// // Somewhere in your library
  /// dynamicgraph::LoggerVerbosity aLoggerVerbosityLevel = VERBOSITY_WARNING_ERROR;
  /// entity.setLoggerVerbosityLevel(aLoggerVerbosityLevel);
  /// ...
  /// std::string aMsg=aBaseMsg+" WARNING";
  /// entity.sendMsg(aMsg,dynamicgraph::MSG_TYPE_WARNING, __FILE__,__LINE__);
  ///
  /// \endcode
  ///
  /// 
158
159
160
161
162
163
164
165
  class Logger
  {
  public:

    /** Constructor */
    Logger(double timeSample=0.001, double streamPrintPeriod=1.0);

    /** Destructor */
166
    ~Logger();
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188

    /** Method to be called at every control iteration
       * to decrement the internal Logger's counter. */
    void countdown();

    /** Print the specified message on standard output if the verbosity level
     * allows it. The file name and the line number are used to identify
     * the point where sendMsg is called so that streaming messages are
     * printed only every streamPrintPeriod iterations.
     */
    void sendMsg(std::string msg, MsgType type, const char* file="", int line=0);

    /** Set the sampling time at which the method countdown()
       * is going to be called. */
    bool setTimeSample(double t);

    /** Set the time period for printing of streaming messages. */
    bool setStreamPrintPeriod(double s);

    /** Set the verbosity level of the logger. */
    void setVerbosity(LoggerVerbosity lv);

189
190
191
    /** Get the verbosity level of the logger. */
    LoggerVerbosity getVerbosity();

192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
  protected:
    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
    double          m_printCountdown;    /// every time this is < 0 (i.e. every _streamPrintPeriod sec) print stuff

    /** Pointer to the dynamic structure which holds the collection of streaming messages */
    std::map<std::string, double> m_stream_msg_counters;

    bool isStreamMsg(MsgType m)
    { return m==MSG_TYPE_ERROR_STREAM || m==MSG_TYPE_DEBUG_STREAM || m==MSG_TYPE_INFO_STREAM || m==MSG_TYPE_WARNING_STREAM; }

    bool isDebugMsg(MsgType m)
    { return m==MSG_TYPE_DEBUG_STREAM || m==MSG_TYPE_DEBUG; }

    bool isInfoMsg(MsgType m)
    { return m==MSG_TYPE_INFO_STREAM || m==MSG_TYPE_INFO; }

    bool isWarningMsg(MsgType m)
    { return m==MSG_TYPE_WARNING_STREAM || m==MSG_TYPE_WARNING; }

    bool isErrorMsg(MsgType m)
    { return m==MSG_TYPE_ERROR_STREAM || m==MSG_TYPE_ERROR; }
  };

}        // namespace dynamicgraph



#endif // #ifndef __sot_torque_control_logger_H__