Monado OpenXR Runtime
u_logging.h
Go to the documentation of this file.
1 // Copyright 2020, Collabora, Ltd.
2 // SPDX-License-Identifier: BSL-1.0
3 /*!
4  * @file
5  * @brief Basic logging functionality.
6  * @author Jakob Bornecrantz <jakob@collabora.com>
7  * @ingroup aux_log
8  */
9 
10 
11 #pragma once
12 
13 #include "xrt/xrt_compiler.h"
14 
15 #include <stdarg.h>
16 
17 
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21 
22 
23 struct xrt_device;
24 
25 
26 /*!
27  * @defgroup aux_log Logging functions
28  * @ingroup aux_util
29  */
30 
31 /*!
32  * @addtogroup aux_log
33  * @{
34  */
35 
36 /*!
37  * @brief Logging level enum
38  */
40 {
41  U_LOGGING_TRACE, //!< Trace messages, highly verbose.
42  U_LOGGING_DEBUG, //!< Debug messages, verbose.
43  U_LOGGING_INFO, //!< Info messages: not very verbose, not indicating a problem.
44  U_LOGGING_WARN, //!< Warning messages: indicating a potential problem
45  U_LOGGING_ERROR, //!< Error messages: indicating a problem
46  U_LOGGING_RAW, //!< Special level for raw printing, prints a new-line.
47 };
48 
49 /*!
50  * Function typedef for setting the logging sink.
51  *
52  * @param file Source file name associated with a message.
53  * @param line Source file line associated with a message.
54  * @param func Function name associated with a message.
55  * @param level Message level: used for formatting or forwarding to native log functions.
56  * @param format Format string.
57  * @param args Format parameters.
58  * @param data User data.
59  */
60 typedef void (*u_log_sink_func_t)(const char *file,
61  int line,
62  const char *func,
63  enum u_logging_level level,
64  const char *format,
65  va_list args,
66  void *data);
67 
68 /*!
69  * For places where you really want printf, prints a new-line.
70  */
71 #define U_LOG_RAW(...) \
72  do { \
73  u_log(__FILE__, __LINE__, __func__, U_LOGGING_RAW, __VA_ARGS__); \
74  } while (false)
75 
76 /*!
77  * @name Base Logging Utilities
78  * In most cases, you will want to use another macro from this file, or a module/driver-local macro, to do your logging.
79  * @{
80  */
81 /*!
82  * @brief Log a message at @p level , with file, line, and function context (always logs) - typically wrapped
83  * in a helper macro.
84  *
85  * @param level A @ref u_logging_level value for this message.
86  * @param ... Format string and optional format arguments.
87  */
88 #define U_LOG(level, ...) \
89  do { \
90  u_log(__FILE__, __LINE__, __func__, level, __VA_ARGS__); \
91  } while (false)
92 
93 /*!
94  * @brief Log at @p level only if the level is at least @p cond_level - typically wrapped in a helper macro.
95  *
96  * Adds file, line, and function context. Like U_LOG() but conditional.
97  *
98  * @param level A @ref u_logging_level value for this message.
99  * @param cond_level The minimum @ref u_logging_level that will be actually output.
100  * @param ... Format string and optional format arguments.
101  */
102 #define U_LOG_IFL(level, cond_level, ...) \
103  do { \
104  if (cond_level <= level) { \
105  u_log(__FILE__, __LINE__, __func__, level, __VA_ARGS__); \
106  } \
107  } while (false)
108 /*!
109  * @brief Log at @p level for a given @ref xrt_device - typically wrapped in a helper macro.
110  *
111  * Adds file, line, and function context, and forwards device context from provided @p xdev .
112  *
113  * Like U_LOG() but calling u_log_xdev() (which takes a device) instead.
114  *
115  * @param level A @ref u_logging_level value for this message.
116  * @param xdev The @ref xrt_device pointer associated with this message.
117  * @param ... Format string and optional format arguments.
118  */
119 #define U_LOG_XDEV(level, xdev, ...) \
120  do { \
121  u_log_xdev(__FILE__, __LINE__, __func__, level, xdev, __VA_ARGS__); \
122  } while (false)
123 /*!
124  * @brief Log at @p level for a given @ref xrt_device, only if the level is at least @p cond_level - typically wrapped
125  * in a helper macro.
126  *
127  * Adds file, line, and function context, and forwards device context from provided @p xdev .
128  * @param level A @ref u_logging_level value for this message.
129  * @param cond_level The minimum @ref u_logging_level that will be actually output.
130  * @param xdev The @ref xrt_device pointer associated with this message.
131  * @param ... Format string and optional format arguments.
132  */
133 #define U_LOG_XDEV_IFL(level, cond_level, xdev, ...) \
134  do { \
135  if (cond_level <= level) { \
136  u_log_xdev(__FILE__, __LINE__, __func__, level, xdev, __VA_ARGS__); \
137  } \
138  } while (false)
139 
140 /*!
141  * @brief Log a memory hexdump at @p level only if the level is at least @p cond_level - typically wrapped in a helper
142  * macro.
143  *
144  * Adds file, line, and function context. Like U_LOG_IFL()
145  *
146  * @param level A @ref u_logging_level value for this message.
147  * @param cond_level The minimum @ref u_logging_level that will be actually output.
148  * @param data The data to print in hexdump format
149  * @param data_size The size (in bytes) of the data block
150  */
151 #define U_LOG_IFL_HEX(level, cond_level, data, data_size) \
152  do { \
153  if (cond_level <= level) { \
154  u_log_hex(__FILE__, __LINE__, __func__, level, data, data_size); \
155  } \
156  } while (false)
157 
158 /*!
159  * @brief Log a memory hexdump at @p level for a given @ref xrt_device, only if the level is at least @p cond_level -
160  * typically wrapped in a helper macro.
161  *
162  * Adds file, line, and function context, and forwards device context from provided @p xdev .
163  * @param level A @ref u_logging_level value for this message.
164  * @param cond_level The minimum @ref u_logging_level that will be actually output.
165  * @param xdev The @ref xrt_device pointer associated with this message.
166  * @param data The data to print in hexdump format
167  * @param data_size The size (in bytes) of the data block
168  */
169 #define U_LOG_XDEV_IFL_HEX(level, cond_level, xdev, data, data_size) \
170  do { \
171  if (cond_level <= level) { \
172  u_log_xdev_hex(__FILE__, __LINE__, __func__, level, xdev, data, data_size); \
173  } \
174  } while (false)
175 
176 
177 /*!
178  * Returns the global logging level, subsystems own logging level take precedence.
179  */
180 enum u_logging_level
182 
183 /*!
184  * @brief Main non-device-related log implementation function: do not call directly, use a macro that wraps it.
185  *
186  * This function always logs: level is used for printing or passed to native logging functions.
187  *
188  * @param file Source file name associated with a message
189  * @param line Source file line associated with a message
190  * @param func Function name associated with a message
191  * @param level Message level: used for formatting or forwarding to native log functions
192  * @param format Format string
193  * @param ... Format parameters
194  */
195 void
196 u_log(const char *file, int line, const char *func, enum u_logging_level level, const char *format, ...)
197  XRT_PRINTF_FORMAT(5, 6);
198 
199 /*!
200  * @brief Main device-related log implementation function: do not call directly, use a macro that wraps it.
201  *
202  * This function always logs: level is used for printing or passed to native logging functions.
203  * @param file Source file name associated with a message
204  * @param line Source file line associated with a message
205  * @param func Function name associated with a message
206  * @param level Message level: used for formatting or forwarding to native log functions
207  * @param xdev The associated @ref xrt_device
208  * @param format Format string
209  * @param ... Format parameters
210  */
211 void
212 u_log_xdev(const char *file,
213  int line,
214  const char *func,
215  enum u_logging_level level,
216  struct xrt_device *xdev,
217  const char *format,
218  ...) XRT_PRINTF_FORMAT(6, 7);
219 
220 /*!
221  * @brief Log implementation for dumping memory buffers as hex: do not call directly, use a macro that wraps it.
222  *
223  * This function always logs: level is used for printing or passed to native logging functions.
224  *
225  * @param file Source file name associated with a message
226  * @param line Source file line associated with a message
227  * @param func Function name associated with a message
228  * @param level Message level: used for formatting or forwarding to native log functions
229  * @param data Data buffer to dump
230  * @param data_size Size of the data buffer in bytes
231  */
232 void
233 u_log_hex(const char *file,
234  int line,
235  const char *func,
236  enum u_logging_level level,
237  const uint8_t *data,
238  const size_t data_size);
239 
240 /*!
241  * @brief Device-related log implementation for dumping memory buffers as hex: do not call directly, use a macro that
242  * wraps it.
243  *
244  * This function always logs: level is used for printing or passed to native logging functions.
245  * @param file Source file name associated with a message
246  * @param line Source file line associated with a message
247  * @param func Function name associated with a message
248  * @param level Message level: used for formatting or forwarding to native log functions
249  * @param xdev The associated @ref xrt_device
250  * @param data Data buffer to dump
251  * @param data_size Size of the data buffer in bytes
252  */
253 void
254 u_log_xdev_hex(const char *file,
255  int line,
256  const char *func,
257  enum u_logging_level level,
258  struct xrt_device *xdev,
259  const uint8_t *data,
260  const size_t data_size);
261 
262 /*!
263  * Sets the logging sink, log is still passed on to the platform defined output
264  * as well as the sink.
265  *
266  * @param func Logging function for the calls to be sent to.
267  * @param data User data to be passed into @p func.
268  */
269 void
270 u_log_set_sink(u_log_sink_func_t func, void *data);
271 
272 /*!
273  * @}
274  */
275 
276 
277 /*!
278  * @name Logging macros conditional on global log level
279  *
280  * These each imply a log level, and will only log if the global log level is equal or lower.
281  * They are often used for one-off logging in a module with few other logging needs,
282  * where having a module-specific log level would be unnecessary.
283  *
284  * @see U_LOG_IFL, u_log_get_global_level()
285  * @param ... Format string and optional format arguments.
286  * @{
287  */
288 //! Log a message at U_LOGGING_TRACE level, conditional on the global log level
289 #define U_LOG_T(...) U_LOG_IFL_T(u_log_get_global_level(), __VA_ARGS__)
290 
291 //! Log a message at U_LOGGING_DEBUG level, conditional on the global log level
292 #define U_LOG_D(...) U_LOG_IFL_D(u_log_get_global_level(), __VA_ARGS__)
293 
294 //! Log a message at U_LOGGING_INFO level, conditional on the global log level
295 #define U_LOG_I(...) U_LOG_IFL_I(u_log_get_global_level(), __VA_ARGS__)
296 
297 //! Log a message at U_LOGGING_WARN level, conditional on the global log level
298 #define U_LOG_W(...) U_LOG_IFL_W(u_log_get_global_level(), __VA_ARGS__)
299 
300 //! Log a message at U_LOGGING_ERROR level, conditional on the global log level
301 #define U_LOG_E(...) U_LOG_IFL_E(u_log_get_global_level(), __VA_ARGS__)
302 
303 /*!
304  * @}
305  */
306 
307 /*!
308  * @name Logging macros conditional on provided log level
309  *
310  * These are often wrapped within a module, to automatically supply
311  * @p cond_level as appropriate for that module.
312  *
313  * @see U_LOG_IFL
314  * @param cond_level The minimum @ref u_logging_level that will be actually output.
315  * @param ... Format string and optional format arguments.
316  *
317  * @{
318  */
319 //! Conditionally log a message at U_LOGGING_TRACE level.
320 #define U_LOG_IFL_T(cond_level, ...) U_LOG_IFL(U_LOGGING_TRACE, cond_level, __VA_ARGS__)
321 //! Conditionally log a message at U_LOGGING_DEBUG level.
322 #define U_LOG_IFL_D(cond_level, ...) U_LOG_IFL(U_LOGGING_DEBUG, cond_level, __VA_ARGS__)
323 //! Conditionally log a message at U_LOGGING_INFO level.
324 #define U_LOG_IFL_I(cond_level, ...) U_LOG_IFL(U_LOGGING_INFO, cond_level, __VA_ARGS__)
325 //! Conditionally log a message at U_LOGGING_WARN level.
326 #define U_LOG_IFL_W(cond_level, ...) U_LOG_IFL(U_LOGGING_WARN, cond_level, __VA_ARGS__)
327 //! Conditionally log a message at U_LOGGING_ERROR level.
328 #define U_LOG_IFL_E(cond_level, ...) U_LOG_IFL(U_LOGGING_ERROR, cond_level, __VA_ARGS__)
329 
330 //! Conditionally log a memory hexdump at U_LOGGING_TRACE level.
331 #define U_LOG_IFL_T_HEX(cond_level, data, data_size) U_LOG_IFL_HEX(U_LOGGING_TRACE, cond_level, data, data_size)
332 //! Conditionally log a memory hexdump at U_LOGGING_DEBUG level.
333 #define U_LOG_IFL_D_HEX(cond_level, data, data_size) U_LOG_IFL_HEX(U_LOGGING_DEBUG, cond_level, data, data_size)
334 /*!
335  * @}
336  */
337 
338 
339 
340 /*!
341  * @name Device-related logging macros conditional on provided log level
342  *
343  * These are often wrapped within a driver, to automatically supply @p xdev and
344  * @p cond_level from their conventional names and log level member variable.
345  *
346  * @param level A @ref u_logging_level value for this message.
347  * @param cond_level The minimum @ref u_logging_level that will be actually output.
348  * @param xdev The @ref xrt_device pointer associated with this message.
349  * @param ... Format string and optional format arguments.
350  *
351  * @{
352  */
353 //! Conditionally log a device-related message at U_LOGGING_TRACE level.
354 #define U_LOG_XDEV_IFL_T(xdev, cond_level, ...) U_LOG_XDEV_IFL(U_LOGGING_TRACE, cond_level, xdev, __VA_ARGS__)
355 //! Conditionally log a device-related message at U_LOGGING_DEBUG level.
356 #define U_LOG_XDEV_IFL_D(xdev, cond_level, ...) U_LOG_XDEV_IFL(U_LOGGING_DEBUG, cond_level, xdev, __VA_ARGS__)
357 //! Conditionally log a device-related message at U_LOGGING_INFO level.
358 #define U_LOG_XDEV_IFL_I(xdev, cond_level, ...) U_LOG_XDEV_IFL(U_LOGGING_INFO, cond_level, xdev, __VA_ARGS__)
359 //! Conditionally log a device-related message at U_LOGGING_WARN level.
360 #define U_LOG_XDEV_IFL_W(xdev, cond_level, ...) U_LOG_XDEV_IFL(U_LOGGING_WARN, cond_level, xdev, __VA_ARGS__)
361 //! Conditionally log a device-related message at U_LOGGING_ERROR level.
362 #define U_LOG_XDEV_IFL_E(xdev, cond_level, ...) U_LOG_XDEV_IFL(U_LOGGING_ERROR, cond_level, xdev, __VA_ARGS__)
363 
364 //! Conditionally log a device-related memory hexdump at U_LOGGING_TRACE level.
365 #define U_LOG_XDEV_IFL_T_HEX(xdev, cond_level, data, data_size) \
366  U_LOG_XDEV_IFL_HEX(U_LOGGING_TRACE, cond_level, xdev, data, data_size)
367 //! Conditionally log a device-related memory hexdump message at U_LOGGING_DEBUG level.
368 #define U_LOG_XDEV_IFL_D_HEX(xdev, cond_level, data, data_size) \
369  U_LOG_XDEV_IFL_HEX(U_LOGGING_DEBUG, cond_level, xdev, data, data_size)
370 /*!
371  * @}
372  */
373 
374 /*!
375  * @name Device-related logging macros that always log.
376  *
377  * These wrap U_LOG_XDEV() to supply the @p level - which is only used for formatting the output, these macros always
378  * log regardless of level.
379  *
380  * @param xdev The @ref xrt_device pointer associated with this message.
381  * @param ... Format string and optional format arguments.
382  * @{
383  */
384 //! Log a device-related message at U_LOGGING_TRACE level (always logs).
385 #define U_LOG_XDEV_T(xdev, ...) U_LOG_XDEV(U_LOGGING_TRACE, xdev, __VA_ARGS__)
386 //! Log a device-related message at U_LOGGING_DEBUG level (always logs).
387 #define U_LOG_XDEV_D(xdev, ...) U_LOG_XDEV(U_LOGGING_DEBUG, xdev, __VA_ARGS__)
388 //! Log a device-related message at U_LOGGING_INFO level (always logs).
389 #define U_LOG_XDEV_I(xdev, ...) U_LOG_XDEV(U_LOGGING_INFO, xdev, __VA_ARGS__)
390 //! Log a device-related message at U_LOGGING_WARN level (always logs).
391 #define U_LOG_XDEV_W(xdev, ...) U_LOG_XDEV(U_LOGGING_WARN, xdev, __VA_ARGS__)
392 //! Log a device-related message at U_LOGGING_ERROR level (always logs).
393 #define U_LOG_XDEV_E(xdev, ...) U_LOG_XDEV(U_LOGGING_ERROR, xdev, __VA_ARGS__)
394 /*!
395  * @}
396  */
397 
398 /*!
399  * @}
400  */
401 
402 
403 #ifdef __cplusplus
404 }
405 #endif
u_logging_level
Logging level enum.
Definition: u_logging.h:40
void u_log(const char *file, int line, const char *func, enum u_logging_level level, const char *format,...) XRT_PRINTF_FORMAT(5
Main non-device-related log implementation function: do not call directly, use a macro that wraps it.
enum u_logging_level u_log_get_global_level(void)
Returns the global logging level, subsystems own logging level take precedence.
Definition: u_logging.c:63
void(* u_log_sink_func_t)(const char *file, int line, const char *func, enum u_logging_level level, const char *format, va_list args, void *data)
Function typedef for setting the logging sink.
Definition: u_logging.h:60
void void void u_log_hex(const char *file, int line, const char *func, enum u_logging_level level, const uint8_t *data, const size_t data_size)
Log implementation for dumping memory buffers as hex: do not call directly, use a macro that wraps it...
Definition: u_logging.c:136
void void u_log_xdev(const char *file, int line, const char *func, enum u_logging_level level, struct xrt_device *xdev, const char *format,...) XRT_PRINTF_FORMAT(6
Main device-related log implementation function: do not call directly, use a macro that wraps it.
void u_log_set_sink(u_log_sink_func_t func, void *data)
Sets the logging sink, log is still passed on to the platform defined output as well as the sink.
Definition: u_logging.c:80
void u_log_xdev_hex(const char *file, int line, const char *func, enum u_logging_level level, struct xrt_device *xdev, const uint8_t *data, const size_t data_size)
Device-related log implementation for dumping memory buffers as hex: do not call directly,...
Definition: u_logging.c:164
@ U_LOGGING_WARN
Warning messages: indicating a potential problem.
Definition: u_logging.h:44
@ U_LOGGING_DEBUG
Debug messages, verbose.
Definition: u_logging.h:42
@ U_LOGGING_TRACE
Trace messages, highly verbose.
Definition: u_logging.h:41
@ U_LOGGING_RAW
Special level for raw printing, prints a new-line.
Definition: u_logging.h:46
@ U_LOGGING_ERROR
Error messages: indicating a problem.
Definition: u_logging.h:45
@ U_LOGGING_INFO
Info messages: not very verbose, not indicating a problem.
Definition: u_logging.h:43
A single HMD or input device.
Definition: xrt_device.h:230
Header holding common defines.