YARP
Yet Another Robot Platform
Log.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2020 Istituto Italiano di Tecnologia (IIT)
3  * All rights reserved.
4  *
5  * This software may be modified and distributed under the terms of the
6  * BSD-3-Clause license. See the accompanying LICENSE file for details.
7  */
8 
9 #ifndef YARP_OS_LOG_H
10 #define YARP_OS_LOG_H
11 
12 #include <yarp/os/api.h>
13 
14 #include <cstdint>
15 #include <iosfwd>
16 #include <mutex>
17 
18 #if defined(__GNUC__)
19 # define __YFUNCTION__ __PRETTY_FUNCTION__
20 #elif defined(_MSC_VER)
21 # define __YFUNCTION__ __FUNCSIG__
22 #elif (__cplusplus <= 199711)
23 # define __YFUNCTION__ __func__
24 #else
25 # define __YFUNCTION__ "(unknown function)"
26 #endif // __GNUC__
27 
28 // check arguments of the c-style debug functions to make sure that the
29 // arguments supplied have types appropriate to the format string
30 // specified, and that the conversions specified in the format string
31 // make sense. On gcc the warning is enabled by -Wformat.
32 #if defined(__GNUC__)
33 # define YARP_ATTRIBUTE_FORMAT(style, fmt, args) __attribute__((format(printf, (fmt), (args))))
34 #else
35 # define YARP_ATTRIBUTE_FORMAT(style, fmt, args)
36 #endif
37 
38 
39 // Forward declarations
40 namespace yarp {
41 namespace os {
42 
43 class LogComponent;
44 class LogStream;
45 
46 #ifndef DOXYGEN_SHOULD_SKIP_THIS
47 namespace impl {
48 class LogPrivate;
49 } // namespace impl
50 #endif // DOXYGEN_SHOULD_SKIP_THIS
51 
53 {
54 public:
55  using Predicate = bool(*)();
56 
57  Log(const char* file,
58  const unsigned int line,
59  const char* func,
60  const Predicate pred = nullptr,
61  const LogComponent& comp = defaultLogComponent());
62 
63  // constructor with externaltime
64  Log(const char* file,
65  const unsigned int line,
66  const char* func,
67  const double externaltime,
68  const Predicate pred = nullptr,
69  const LogComponent& comp = defaultLogComponent());
70 
71  Log();
72  virtual ~Log();
73 
74  enum LogType : uint8_t
75  {
76  LogTypeUnknown = 0,
83  LogTypeReserved = 0xFF
84  };
85 
86  void trace(const char* msg, ...) const YARP_ATTRIBUTE_FORMAT(printf, 2, 3);
87  void debug(const char* msg, ...) const YARP_ATTRIBUTE_FORMAT(printf, 2, 3);
88  void info(const char* msg, ...) const YARP_ATTRIBUTE_FORMAT(printf, 2, 3);
89  void warning(const char* msg, ...) const YARP_ATTRIBUTE_FORMAT(printf, 2, 3);
90  void error(const char* msg, ...) const YARP_ATTRIBUTE_FORMAT(printf, 2, 3);
91  YARP_NORETURN void fatal(const char* msg, ...) const YARP_ATTRIBUTE_FORMAT(printf, 2, 3);
92 
93  LogStream trace() const;
94  LogStream debug() const;
95  LogStream info() const;
96  LogStream warning() const;
97  LogStream error() const;
98  LogStream fatal() const;
99 
100  using LogCallback = void (*)(yarp::os::Log::LogType type,
101  const char* msg,
102  const char* file,
103  const unsigned int line,
104  const char* func,
105  double systemtime,
106  double networktime,
107  double externaltime,
108  const char* comp_name);
109 
110 #ifndef YARP_NO_DEPRECATED // Since YARP 3.4
111  YARP_DEPRECATED_MSG("Use setPrintCallback instead")
112  static void setLogCallback(LogCallback);
113 #endif // YARP_NO_DEPRECATED
114 
115  static void setMinimumPrintLevel(LogType level);
116  static LogType minimumPrintLevel();
117  static LogType defaultMinimumPrintLevel();
118 
119  static void setMinimumForwardLevel(LogType level);
120  static LogType minimumForwardLevel();
121  static LogType defaultMinimumForwardLevel();
122 
123  static void setPrintCallback(LogCallback);
124  static LogCallback printCallback();
125  static LogCallback defaultPrintCallback();
126 
127  static void setForwardCallback(LogCallback);
128  static LogCallback forwardCallback();
129  static LogCallback defaultForwardCallback();
130 
131 
132 #ifndef DOXYGEN_SHOULD_SKIP_THIS
133  static void nolog(const char* msg, ...) {}
134  struct NoLog
135  {
136  template <typename T>
137  NoLog& operator<<(const T&)
138  {
139  return *this;
140  }
141  };
142  static NoLog nolog() { return NoLog(); }
143 
144 private:
145  yarp::os::impl::LogPrivate* const mPriv;
146 
147  friend class yarp::os::LogStream;
148 
149  // This callback is called by LogStream
150  static void do_log(yarp::os::Log::LogType type,
151  const char* msg,
152  const char* file,
153  const unsigned int line,
154  const char* func,
155  double systemtime,
156  double networktime,
157  double externaltime,
158  const LogComponent& comp_name);
159 
160  // This component is used for yDebug-family output, and is called by LogStream
161  static const LogComponent& defaultLogComponent();
162 
163  // This component is used for internal debug output, and is called by LogStream
164  static const LogComponent& logInternalComponent();
165 #endif // DOXYGEN_SHOULD_SKIP_THIS
166 }; // class Log
167 
168 } // namespace os
169 } // namespace yarp
170 
171 
172 
173 
174 #define YARP_ONCE_CALLBACK \
175  [](){ \
176  static std::atomic_flag flag = ATOMIC_FLAG_INIT; \
177  return !flag.test_and_set(); \
178  }
179 
180 #define YARP_THREADONCE_CALLBACK \
181  [](){ \
182  thread_local std::atomic_flag flag = ATOMIC_FLAG_INIT; \
183  return !flag.test_and_set(); \
184  }
185 
186 #define YARP_THROTTLE_CALLBACK(period) \
187  [](){ \
188  static double last = -period; \
189  static std::mutex mutex; \
190  std::lock_guard<std::mutex> lock(mutex); \
191  double now = yarp::os::SystemClock::nowSystem(); \
192  if (now >= last + period) { \
193  last = now; \
194  return true; \
195  } \
196  return false; \
197  }
198 
199 #define YARP_THREADTHROTTLE_CALLBACK(period) \
200  [](){ \
201  thread_local double last = -period; \
202  double now = yarp::os::SystemClock::nowSystem(); \
203  if (now >= last + period) { \
204  last = now; \
205  return true; \
206  } \
207  return false; \
208  }
209 
210 
211 
212 #ifndef NDEBUG
213 # define yTrace(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__).trace(__VA_ARGS__)
214 # define yTraceOnce(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_ONCE_CALLBACK).trace(__VA_ARGS__)
215 # define yTraceThreadOnce(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THREADONCE_CALLBACK).trace(__VA_ARGS__)
216 # define yTraceThrottle(period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THROTTLE_CALLBACK(period)).trace(__VA_ARGS__)
217 # define yTraceThreadThrottle(period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THREADTHROTTLE_CALLBACK(period)).trace(__VA_ARGS__)
218 # define yTraceExternalTime(externaltime, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, externaltime).trace(__VA_ARGS__)
219 # define yTraceExternalTimeOnce(externaltime, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, externaltime, YARP_ONCE_CALLBACK).trace(__VA_ARGS__)
220 # define yTraceExternalTimeThreadOnce(externaltime, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, externaltime, YARP_THREADONCE_CALLBACK).trace(__VA_ARGS__)
221 # define yTraceExternalTimeThrottle(externaltime, period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, externaltime, YARP_THROTTLE_CALLBACK(period)).trace(__VA_ARGS__)
222 # define yTraceExternalTimeThreadThrottle(externaltime, period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, externaltime, YARP_THREADTHROTTLE_CALLBACK(period)).trace(__VA_ARGS__)
223 #else
224 # define yTrace(...) yarp::os::Log::nolog(__VA_ARGS__)
225 # define yTraceOnce(...) yarp::os::Log::nolog(__VA_ARGS__)
226 # define yTraceThreadOnce(...) yarp::os::Log::nolog(__VA_ARGS__)
227 # define yTraceThrottle(period, ...) yarp::os::Log::nolog(__VA_ARGS__)
228 # define yTraceThreadThrottle(period, ...) yarp::os::Log::nolog(__VA_ARGS__)
229 # define yTraceExternalTime(externaltime, ...) yarp::os::Log::nolog(__VA_ARGS__)
230 # define yTraceExternalTimeOnce(externaltime, ...) yarp::os::Log::nolog(__VA_ARGS__)
231 # define yTraceExternalTimeThreadOnce(externaltime, ...) yarp::os::Log::nolog(__VA_ARGS__)
232 # define yTraceExternalTimeThrottle(externaltime, period, ...) yarp::os::Log::nolog(__VA_ARGS__)
233 # define yTraceExternalTimeThreadThrottle(externaltime, period, ...) yarp::os::Log::nolog(__VA_ARGS__)
234 #endif
235 
236 #ifndef YARP_NO_DEBUG_OUTPUT
237 # define yDebug(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__).debug(__VA_ARGS__)
238 # define yDebugOnce(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_ONCE_CALLBACK).debug(__VA_ARGS__)
239 # define yDebugThreadOnce(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THREADONCE_CALLBACK).debug(__VA_ARGS__)
240 # define yDebugThrottle(period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THROTTLE_CALLBACK(period)).debug(__VA_ARGS__)
241 # define yDebugThreadThrottle(period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THREADTHROTTLE_CALLBACK(period)).debug(__VA_ARGS__)
242 # define yDebugExternalTime(externaltime, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, externaltime).debug(__VA_ARGS__)
243 # define yDebugExternalTimeOnce(externaltime, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, externaltime, YARP_ONCE_CALLBACK).debug(__VA_ARGS__)
244 # define yDebugExternalTimeThreadOnce(externaltime, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, externaltime, YARP_THREADONCE_CALLBACK).debug(__VA_ARGS__)
245 # define yDebugExternalTimeThrottle(externaltime, period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, externaltime, YARP_THROTTLE_CALLBACK(period)).debug(__VA_ARGS__)
246 # define yDebugExternalTimeThreadThrottle(externaltime, period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, externaltime, YARP_THREADTHROTTLE_CALLBACK(period)).debug(__VA_ARGS__)
247 #else
248 # define yDebug(...) yarp::os::Log::nolog(__VA_ARGS__)
249 # define yDebugOnce(...) yarp::os::Log::nolog(__VA_ARGS__)
250 # define yDebugThreadOnce(...) yarp::os::Log::nolog(__VA_ARGS__)
251 # define yDebugThrottle(period, ...) yarp::os::Log::nolog(__VA_ARGS__)
252 # define yDebugThreadThrottle(period, ...) yarp::os::Log::nolog(__VA_ARGS__)
253 # define yDebugExternalTime(externaltime, ...) yarp::os::Log::nolog(__VA_ARGS__)
254 # define yDebugExternalTimeOnce(externaltime, ...) yarp::os::Log::nolog(__VA_ARGS__)
255 # define yDebugExternalTimeThreadOnce(externaltime, ...) yarp::os::Log::nolog(__VA_ARGS__)
256 # define yDebugExternalTimeThrottle(externaltime, period, ...) yarp::os::Log::nolog(__VA_ARGS__)
257 # define yDebugExternalTimeThreadThrottle(externaltime, period, ...) yarp::os::Log::nolog(__VA_ARGS__)
258 #endif
259 
260 #define yInfo(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__).info(__VA_ARGS__)
261 #define yInfoOnce(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_ONCE_CALLBACK).info(__VA_ARGS__)
262 #define yInfoThreadOnce(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THREADONCE_CALLBACK).info(__VA_ARGS__)
263 #define yInfoThrottle(period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THROTTLE_CALLBACK(period)).info(__VA_ARGS__)
264 #define yInfoThreadThrottle(period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THREADTHROTTLE_CALLBACK(period)).info(__VA_ARGS__)
265 #define yInfoExternalTime(externaltime, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, externaltime).info(__VA_ARGS__)
266 #define yInfoExternalTimeOnce(externaltime, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, externaltime, YARP_ONCE_CALLBACK).info(__VA_ARGS__)
267 #define yInfoExternalTimeThreadOnce(externaltime, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, externaltime, YARP_THREADONCE_CALLBACK).info(__VA_ARGS__)
268 #define yInfoExternalTimeThrottle(externaltime, period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, externaltime, YARP_THROTTLE_CALLBACK(period)).info(__VA_ARGS__)
269 #define yInfoExternalTimeThreadThrottle(externaltime, period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, externaltime, YARP_THREADTHROTTLE_CALLBACK(period)).info(__VA_ARGS__)
270 
271 #define yWarning(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__).warning(__VA_ARGS__)
272 #define yWarningOnce(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_ONCE_CALLBACK).warning(__VA_ARGS__)
273 #define yWarningThreadOnce(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THREADONCE_CALLBACK).warning(__VA_ARGS__)
274 #define yWarningThrottle(period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THROTTLE_CALLBACK(period)).warning(__VA_ARGS__)
275 #define yWarningThreadThrottle(period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THREADTHROTTLE_CALLBACK(period)).warning(__VA_ARGS__)
276 #define yWarningExternalTime(externaltime, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, externaltime).warning(__VA_ARGS__)
277 #define yWarningExternalTimeOnce(externaltime, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, externaltime, YARP_ONCE_CALLBACK).warning(__VA_ARGS__)
278 #define yWarningExternalTimeThreadOnce(externaltime, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, externaltime, YARP_THREADONCE_CALLBACK).warning(__VA_ARGS__)
279 #define yWarningExternalTimeThrottle(externaltime, period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, externaltime, YARP_THROTTLE_CALLBACK(period)).warning(__VA_ARGS__)
280 #define yWarningExternalTimeThreadThrottle(externaltime, period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, externaltime, YARP_THREADTHROTTLE_CALLBACK(period)).warning(__VA_ARGS__)
281 
282 #define yError(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__).error(__VA_ARGS__)
283 #define yErrorOnce(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_ONCE_CALLBACK).error(__VA_ARGS__)
284 #define yErrorThreadOnce(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THREADONCE_CALLBACK).error(__VA_ARGS__)
285 #define yErrorThrottle(period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THROTTLE_CALLBACK(period)).error(__VA_ARGS__)
286 #define yErrorThreadThrottle(period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THREADTHROTTLE_CALLBACK(period)).error(__VA_ARGS__)
287 #define yErrorExternalTime(externaltime, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, externaltime).error(__VA_ARGS__)
288 #define yErrorExternalTimeOnce(externaltime, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, externaltime, YARP_ONCE_CALLBACK).error(__VA_ARGS__)
289 #define yErrorExternalTimeThreadOnce(externaltime, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, externaltime, YARP_THREADONCE_CALLBACK).error(__VA_ARGS__)
290 #define yErrorExternalTimeThrottle(externaltime, period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, externaltime, YARP_THROTTLE_CALLBACK(period)).error(__VA_ARGS__)
291 #define yErrorExternalTimeThreadThrottle(externaltime, period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, externaltime, YARP_THREADTHROTTLE_CALLBACK(period)).error(__VA_ARGS__)
292 
293 #define yFatal(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__).fatal(__VA_ARGS__)
294 #define yFatalExternalTime(externaltime, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, externaltime).fatal(__VA_ARGS__)
295 
296 #ifndef NDEBUG
297 # define yAssert(x) \
298  if (!(x)) { \
299  yFatal("Assertion failure at %s:%d (%s)", __FILE__, __LINE__, #x); \
300  }
301 # define yAssertExternalTime(externaltime, x) \
302  if (!(x)) { \
303  yFatalExternalTime(externaltime, "Assertion failure at %s:%d (%s)", __FILE__, __LINE__, #x); \
304  }
305 #else
306 # define yAssert(x)
307 # define yAssertExternalTime(externaltime, x) { YARP_UNUSED(externaltime); }
308 #endif
309 
310 #define YARP_FIXME_NOTIMPLEMENTED(what) yWarning("FIXME: %s not yet implemented", what);
311 
312 
316 YARP_os_API void yarp_print_trace(FILE* out, const char* file, unsigned int line);
317 
318 
319 #endif // YARP_OS_LOG_H
yarp::os::Log::InfoType
@ InfoType
Definition: Log.h:79
yarp::os::Log::ErrorType
@ ErrorType
Definition: Log.h:81
LogCallback
yarp::os::Log::LogCallback LogCallback
Definition: LogComponent.cpp:12
operator<<
std::ostream & operator<<(std::ostream &os, StrStream &sstr)
Definition: utility.cpp:89
yarp::os::impl::LogPrivate
Definition: Log.cpp:56
yarp::os::Log::TraceType
@ TraceType
Definition: Log.h:77
yarp::os::Log::WarningType
@ WarningType
Definition: Log.h:80
YARP_NORETURN
#define YARP_NORETURN
Definition: api.h:153
yarp_print_trace
void yarp_print_trace(FILE *out, const char *file, unsigned int line)
Low level function for printing a stack trace, if implemented (ACE or gcc/Linux).
Definition: Log.cpp:1021
yarp::os::Log::LogType
LogType
Definition: Log.h:74
yarp::os::LogComponent
Definition: LogComponent.h:20
yarp::os::Log::Predicate
bool(*)() Predicate
Definition: Log.h:55
YARP_ATTRIBUTE_FORMAT
#define YARP_ATTRIBUTE_FORMAT(style, fmt, args)
Definition: Log.h:35
YARP_DEPRECATED_MSG
#define YARP_DEPRECATED_MSG(MSG)
Definition: compiler.h:2873
yarp
Definition: environment.h:18
YARP_os_API
#define YARP_os_API
Definition: api.h:19
yarp::os::LogStream
Definition: LogStream.h:36
api.h
yarp::os::Log
Definition: Log.h:52
yarp::os::Log::FatalType
@ FatalType
Definition: Log.h:82
yarp::os::Log::DebugType
@ DebugType
Definition: Log.h:78
yarp::os::Log::LogCallback
void(*)(yarp::os::Log::LogType type, const char *msg, const char *file, const unsigned int line, const char *func, double systemtime, double networktime, double externaltime, const char *comp_name) LogCallback
Definition: Log.h:108