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  Log();
64  virtual ~Log();
65 
66  enum LogType : uint8_t
67  {
68  LogTypeUnknown = 0,
75  LogTypeReserved = 0xFF
76  };
77 
78  void trace(const char* msg, ...) const YARP_ATTRIBUTE_FORMAT(printf, 2, 3);
79  void debug(const char* msg, ...) const YARP_ATTRIBUTE_FORMAT(printf, 2, 3);
80  void info(const char* msg, ...) const YARP_ATTRIBUTE_FORMAT(printf, 2, 3);
81  void warning(const char* msg, ...) const YARP_ATTRIBUTE_FORMAT(printf, 2, 3);
82  void error(const char* msg, ...) const YARP_ATTRIBUTE_FORMAT(printf, 2, 3);
83  YARP_NORETURN void fatal(const char* msg, ...) const YARP_ATTRIBUTE_FORMAT(printf, 2, 3);
84 
85  LogStream trace() const;
86  LogStream debug() const;
87  LogStream info() const;
88  LogStream warning() const;
89  LogStream error() const;
90  LogStream fatal() const;
91 
92  using LogCallback = void (*)(yarp::os::Log::LogType type,
93  const char* msg,
94  const char* file,
95  const unsigned int line,
96  const char* func,
97  double systemtime,
98  double networktime,
99  const char* comp_name);
100 
101 #ifndef YARP_NO_DEPRECATED // Since YARP 3.4
102  YARP_DEPRECATED_MSG("Use setPrintCallback instead")
103  static void setLogCallback(LogCallback);
104 #endif // YARP_NO_DEPRECATED
105 
106  static void setMinimumPrintLevel(LogType level);
107  static LogType minimumPrintLevel();
108  static LogType defaultMinimumPrintLevel();
109 
110  static void setMinimumForwardLevel(LogType level);
111  static LogType minimumForwardLevel();
112  static LogType defaultMinimumForwardLevel();
113 
114  static void setPrintCallback(LogCallback);
115  static LogCallback printCallback();
116  static LogCallback defaultPrintCallback();
117 
118  static void setForwardCallback(LogCallback);
119  static LogCallback forwardCallback();
120  static LogCallback defaultForwardCallback();
121 
122 
123 #ifndef DOXYGEN_SHOULD_SKIP_THIS
124  static void nolog(const char* msg, ...) {}
125  struct NoLog
126  {
127  template <typename T>
128  NoLog& operator<<(const T&)
129  {
130  return *this;
131  }
132  };
133  static NoLog nolog() { return NoLog(); }
134 
135 private:
136  yarp::os::impl::LogPrivate* const mPriv;
137 
138  friend class yarp::os::LogStream;
139 
140  // This callback is called by LogStream
141  static void do_log(yarp::os::Log::LogType type,
142  const char* msg,
143  const char* file,
144  const unsigned int line,
145  const char* func,
146  double systemtime,
147  double networktime,
148  const LogComponent& comp_name);
149 
150  // This component is used for yDebug-family output, and is called by LogStream
151  static const LogComponent& defaultLogComponent();
152 
153  // This component is used for internal debug output, and is called by LogStream
154  static const LogComponent& logInternalComponent();
155 #endif // DOXYGEN_SHOULD_SKIP_THIS
156 }; // class Log
157 
158 } // namespace os
159 } // namespace yarp
160 
161 
162 
163 
164 #define YARP_ONCE_CALLBACK \
165  [](){ \
166  static std::atomic_flag flag = ATOMIC_FLAG_INIT; \
167  return !flag.test_and_set(); \
168  }
169 
170 #define YARP_THREADONCE_CALLBACK \
171  [](){ \
172  thread_local std::atomic_flag flag = ATOMIC_FLAG_INIT; \
173  return !flag.test_and_set(); \
174  }
175 
176 #define YARP_THROTTLE_CALLBACK(period) \
177  [](){ \
178  static double last = -period; \
179  static std::mutex mutex; \
180  std::lock_guard<std::mutex> lock(mutex); \
181  double now = yarp::os::SystemClock::nowSystem(); \
182  if (now >= last + period) { \
183  last = now; \
184  return true; \
185  } \
186  return false; \
187  }
188 
189 #define YARP_THREADTHROTTLE_CALLBACK(period) \
190  [](){ \
191  thread_local double last = -period; \
192  double now = yarp::os::SystemClock::nowSystem(); \
193  if (now >= last + period) { \
194  last = now; \
195  return true; \
196  } \
197  return false; \
198  }
199 
200 
201 
202 #ifndef NDEBUG
203 # define yTrace(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__).trace(__VA_ARGS__)
204 # define yTraceOnce(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_ONCE_CALLBACK).trace(__VA_ARGS__)
205 # define yTraceThreadOnce(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THREADONCE_CALLBACK).trace(__VA_ARGS__)
206 # define yTraceThrottle(period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THROTTLE_CALLBACK(period)).trace(__VA_ARGS__)
207 # define yTraceThreadThrottle(period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THREADTHROTTLE_CALLBACK(period)).trace(__VA_ARGS__)
208 #else
209 # define yTrace(...) yarp::os::Log::nolog(__VA_ARGS__)
210 # define yTraceOnce(...) yarp::os::Log::nolog(__VA_ARGS__)
211 # define yTraceThreadOnce(...) yarp::os::Log::nolog(__VA_ARGS__)
212 # define yTraceThrottle(period, ...) yarp::os::Log::nolog(__VA_ARGS__)
213 # define yTraceThreadThrottle(period, ...) yarp::os::Log::nolog(__VA_ARGS__)
214 #endif
215 
216 #ifndef YARP_NO_DEBUG_OUTPUT
217 # define yDebug(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__).debug(__VA_ARGS__)
218 # define yDebugOnce(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_ONCE_CALLBACK).debug(__VA_ARGS__)
219 # define yDebugThreadOnce(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THREADONCE_CALLBACK).debug(__VA_ARGS__)
220 # define yDebugThrottle(period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THROTTLE_CALLBACK(period)).debug(__VA_ARGS__)
221 # define yDebugThreadThrottle(period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THREADTHROTTLE_CALLBACK(period)).debug(__VA_ARGS__)
222 #else
223 # define yDebug(...) yarp::os::Log::nolog(__VA_ARGS__)
224 # define yDebugOnce(...) yarp::os::Log::nolog(__VA_ARGS__)
225 # define yDebugThreadOnce(...) yarp::os::Log::nolog(__VA_ARGS__)
226 # define yDebugThrottle(period, ...) yarp::os::Log::nolog(__VA_ARGS__)
227 # define yDebugThreadThrottle(period, ...) yarp::os::Log::nolog(__VA_ARGS__)
228 #endif
229 
230 #define yInfo(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__).info(__VA_ARGS__)
231 #define yInfoOnce(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_ONCE_CALLBACK).info(__VA_ARGS__)
232 #define yInfoThreadOnce(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THREADONCE_CALLBACK).info(__VA_ARGS__)
233 #define yInfoThrottle(period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THROTTLE_CALLBACK(period)).info(__VA_ARGS__)
234 #define yInfoThreadThrottle(period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THREADTHROTTLE_CALLBACK(period)).info(__VA_ARGS__)
235 
236 #define yWarning(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__).warning(__VA_ARGS__)
237 #define yWarningOnce(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_ONCE_CALLBACK).warning(__VA_ARGS__)
238 #define yWarningThreadOnce(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THREADONCE_CALLBACK).warning(__VA_ARGS__)
239 #define yWarningThrottle(period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THROTTLE_CALLBACK(period)).warning(__VA_ARGS__)
240 #define yWarningThreadThrottle(period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THREADTHROTTLE_CALLBACK(period)).warning(__VA_ARGS__)
241 
242 #define yError(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__).error(__VA_ARGS__)
243 #define yErrorOnce(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_ONCE_CALLBACK).error(__VA_ARGS__)
244 #define yErrorThreadOnce(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THREADONCE_CALLBACK).error(__VA_ARGS__)
245 #define yErrorThrottle(period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THROTTLE_CALLBACK(period)).error(__VA_ARGS__)
246 #define yErrorThreadThrottle(period, ...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__, YARP_THREADTHROTTLE_CALLBACK(period)).error(__VA_ARGS__)
247 
248 #define yFatal(...) yarp::os::Log(__FILE__, __LINE__, __YFUNCTION__).fatal(__VA_ARGS__)
249 
250 
251 
252 
253 
254 #ifndef NDEBUG
255 # define yAssert(x) \
256  if (!(x)) { \
257  yFatal("Assertion failure at %s:%d (%s)", __FILE__, __LINE__, #x); \
258  }
259 #else
260 # define yAssert(x)
261 #endif
262 
263 #define YARP_FIXME_NOTIMPLEMENTED(what) yWarning("FIXME: %s not yet implemented", what);
264 
265 
269 YARP_os_API void yarp_print_trace(FILE* out, const char* file, unsigned int line);
270 
271 
272 #endif // YARP_OS_LOG_H
yarp::os::Log::InfoType
@ InfoType
Definition: Log.h:71
yarp::os::Log::ErrorType
@ ErrorType
Definition: Log.h:73
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::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, const char *comp_name) LogCallback
Definition: Log.h:99
yarp::os::impl::LogPrivate
Definition: Log.cpp:56
yarp::os::Log::TraceType
@ TraceType
Definition: Log.h:69
yarp::os::Log::WarningType
@ WarningType
Definition: Log.h:72
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:975
yarp::os::Log::LogType
LogType
Definition: Log.h:66
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: numeric.h:47
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:74
yarp::os::Log::DebugType
@ DebugType
Definition: Log.h:70