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