PipeWire  0.3.59
log.h
Go to the documentation of this file.
1 /* Simple Plugin API
2  *
3  * Copyright © 2018 Wim Taymans
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  */
24 
25 #ifndef SPA_LOG_H
26 #define SPA_LOG_H
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 #include <stdarg.h>
33 
34 #include <spa/utils/type.h>
35 #include <spa/utils/defs.h>
36 #include <spa/utils/hook.h>
37 
56 #define SPA_LOG_TOPIC_DEFAULT NULL
57 
58 enum spa_log_level {
65 };
66 
70 #define SPA_TYPE_INTERFACE_Log SPA_TYPE_INFO_INTERFACE_BASE "Log"
71 
72 
73 struct spa_log {
76 #define SPA_VERSION_LOG 0
77  struct spa_interface iface;
82 };
83 
94 struct spa_log_topic {
95 #define SPA_VERSION_LOG_TOPIC 0
98  uint32_t version;
100  const char *topic;
102  enum spa_log_level level;
104  bool has_custom_level;
105 };
106 
107 struct spa_log_methods {
108 #define SPA_VERSION_LOG_METHODS 1
109  uint32_t version;
125  void (*log) (void *object,
126  enum spa_log_level level,
127  const char *file,
128  int line,
129  const char *func,
130  const char *fmt, ...) SPA_PRINTF_FUNC(6, 7);
131 
147  void (*logv) (void *object,
148  enum spa_log_level level,
149  const char *file,
150  int line,
151  const char *func,
152  const char *fmt,
153  va_list args) SPA_PRINTF_FUNC(6, 0);
171  void (*logt) (void *object,
172  enum spa_log_level level,
173  const struct spa_log_topic *topic,
174  const char *file,
175  int line,
176  const char *func,
177  const char *fmt, ...) SPA_PRINTF_FUNC(7, 8);
178 
196  void (*logtv) (void *object,
197  enum spa_log_level level,
198  const struct spa_log_topic *topic,
199  const char *file,
200  int line,
201  const char *func,
202  const char *fmt,
203  va_list args) SPA_PRINTF_FUNC(7, 0);
204 
210  void (*topic_init) (void *object, struct spa_log_topic *topic);
211 };
212 
213 
214 #define SPA_LOG_TOPIC(v, t) \
215  (struct spa_log_topic){ .version = (v), .topic = (t)}
216 
217 #define spa_log_topic_init(l, topic) \
218 do { \
219  struct spa_log *_l = l; \
220  if (SPA_LIKELY(_l)) { \
221  struct spa_interface *_if = &_l->iface; \
222  spa_interface_call(_if, struct spa_log_methods, \
223  topic_init, 1, topic); \
224  } \
225 } while(0)
226 
227 /* Unused, left for backwards compat */
228 #define spa_log_level_enabled(l,lev) ((l) && (l)->level >= (lev))
229 
230 #define spa_log_level_topic_enabled(l,topic,lev) \
231 ({ \
232  struct spa_log *_log = l; \
233  enum spa_log_level _lev = _log ? _log->level : SPA_LOG_LEVEL_NONE; \
234  struct spa_log_topic *_t = (struct spa_log_topic *)(topic); \
235  if (_t && _t->has_custom_level) \
236  _lev = _t->level; \
237  _lev >= (lev); \
238 })
239 
240 /* Transparently calls to version 0 log if v1 is not supported */
241 #define spa_log_logt(l,lev,topic,...) \
242 ({ \
243  struct spa_log *_l = l; \
244  struct spa_interface *_if = &_l->iface; \
245  if (SPA_UNLIKELY(spa_log_level_topic_enabled(_l, topic, lev))) { \
246  if (!spa_interface_call(_if, \
247  struct spa_log_methods, logt, 1, \
248  lev, topic, \
249  __VA_ARGS__)) \
250  spa_interface_call(_if, \
251  struct spa_log_methods, log, 0, \
252  lev, __VA_ARGS__); \
253  } \
254 })
255 
256 /* Transparently calls to version 0 logv if v1 is not supported */
257 #define spa_log_logtv(l,lev,topic,...) \
258 ({ \
259  struct spa_log *_l = l; \
260  struct spa_interface *_if = &_l->iface; \
261  if (SPA_UNLIKELY(spa_log_level_topic_enabled(_l, topic, lev))) { \
262  if (!spa_interface_call(_if, \
263  struct spa_log_methods, logtv, 1, \
264  lev, topic, \
265  __VA_ARGS__)) \
266  spa_interface_call(_if, \
267  struct spa_log_methods, logv, 0, \
268  lev, __VA_ARGS__); \
269  } \
270 })
271 
272 #define spa_logt_lev(l,lev,t,...) \
273  spa_log_logt(l,lev,t,__FILE__,__LINE__,__func__,__VA_ARGS__)
274 
275 #define spa_log_lev(l,lev,...) \
276  spa_logt_lev(l,lev,SPA_LOG_TOPIC_DEFAULT,__VA_ARGS__)
277 
278 #define spa_log_log(l,lev,...) \
279  spa_log_logt(l,lev,SPA_LOG_TOPIC_DEFAULT,__VA_ARGS__)
280 
281 #define spa_log_logv(l,lev,...) \
282  spa_log_logtv(l,lev,SPA_LOG_TOPIC_DEFAULT,__VA_ARGS__)
283 
284 #define spa_log_error(l,...) spa_log_lev(l,SPA_LOG_LEVEL_ERROR,__VA_ARGS__)
285 #define spa_log_warn(l,...) spa_log_lev(l,SPA_LOG_LEVEL_WARN,__VA_ARGS__)
286 #define spa_log_info(l,...) spa_log_lev(l,SPA_LOG_LEVEL_INFO,__VA_ARGS__)
287 #define spa_log_debug(l,...) spa_log_lev(l,SPA_LOG_LEVEL_DEBUG,__VA_ARGS__)
288 #define spa_log_trace(l,...) spa_log_lev(l,SPA_LOG_LEVEL_TRACE,__VA_ARGS__)
289 
290 #define spa_logt_error(l,t,...) spa_logt_lev(l,SPA_LOG_LEVEL_ERROR,t,__VA_ARGS__)
291 #define spa_logt_warn(l,t,...) spa_logt_lev(l,SPA_LOG_LEVEL_WARN,t,__VA_ARGS__)
292 #define spa_logt_info(l,t,...) spa_logt_lev(l,SPA_LOG_LEVEL_INFO,t,__VA_ARGS__)
293 #define spa_logt_debug(l,t,...) spa_logt_lev(l,SPA_LOG_LEVEL_DEBUG,t,__VA_ARGS__)
294 #define spa_logt_trace(l,t,...) spa_logt_lev(l,SPA_LOG_LEVEL_TRACE,t,__VA_ARGS__)
295 
296 #ifndef FASTPATH
297 #define spa_log_trace_fp(l,...) spa_log_lev(l,SPA_LOG_LEVEL_TRACE,__VA_ARGS__)
298 #else
299 #define spa_log_trace_fp(l,...)
300 #endif
301 
302 #define spa_log_hexdump(l,lev,indent,data,len) \
303 ({ \
304  char str[512]; \
305  uint8_t *buf = (uint8_t *)(data); \
306  size_t i, j = (len); \
307  int pos = 0; \
308  \
309  for (i = 0; i < j; i++) { \
310  if (i % 16 == 0) \
311  pos = 0; \
312  pos += sprintf(str + pos, "%02x ", buf[i]); \
313  if (i % 16 == 15 || i == j - 1) \
314  spa_log_lev(l,lev, "%*s" "%s",indent,"", str); \
315  } \
316 })
317 
321 #define SPA_KEY_LOG_LEVEL "log.level"
322 #define SPA_KEY_LOG_COLORS "log.colors"
323 #define SPA_KEY_LOG_FILE "log.file"
325 #define SPA_KEY_LOG_TIMESTAMP "log.timestamp"
326 #define SPA_KEY_LOG_LINE "log.line"
327 #define SPA_KEY_LOG_PATTERNS "log.patterns"
333 #ifdef __cplusplus
334 } /* extern "C" */
335 #endif
336 #endif /* SPA_LOG_H */
spa/utils/defs.h
spa_log_level
Definition: log.h:65
@ SPA_LOG_LEVEL_INFO
Definition: log.h:69
@ SPA_LOG_LEVEL_NONE
Definition: log.h:66
@ SPA_LOG_LEVEL_TRACE
Definition: log.h:71
@ SPA_LOG_LEVEL_DEBUG
Definition: log.h:70
@ SPA_LOG_LEVEL_ERROR
Definition: log.h:67
@ SPA_LOG_LEVEL_WARN
Definition: log.h:68
#define SPA_PRINTF_FUNC(fmt, arg1)
Definition: defs.h:289
spa/utils/hook.h
spa/utils/type.h
Definition: hook.h:158
Definition: log.h:117
void(*) void(*) void(* logt)(void *object, enum spa_log_level level, const struct spa_log_topic *topic, const char *file, int line, const char *func, const char *fmt,...) 1(7
Log a message with the given log level for the given topic.
Definition: log.h:182
uint32_t version
Definition: log.h:120
void(*) void(*) void(*) void(*) void(* topic_init)(void *object, struct spa_log_topic *topic)
Initializes a spa_log_topic to the correct logging level.
Definition: log.h:221
void(*) void(* logv)(void *object, enum spa_log_level level, const char *file, int line, const char *func, const char *fmt, va_list args) 1(6
Log a message with the given log level.
Definition: log.h:158
void(* log)(void *object, enum spa_log_level level, const char *file, int line, const char *func, const char *fmt,...) 1(6
Log a message with the given log level.
Definition: log.h:136
void(*) void(*) void(*) void(* logtv)(void *object, enum spa_log_level level, const struct spa_log_topic *topic, const char *file, int line, const char *func, const char *fmt, va_list args) 1(7
Log a message with the given log level for the given topic.
Definition: log.h:207
Identifier for a topic.
Definition: log.h:103
uint32_t version
the version of this topic.
Definition: log.h:108
bool has_custom_level
False if this topic follows the Log level.
Definition: log.h:114
enum spa_log_level level
Logging level set for this topic.
Definition: log.h:112
const char * topic
The string identifier for the topic.
Definition: log.h:110
Definition: log.h:81
struct spa_interface iface
Definition: log.h:86
enum spa_log_level level
Logging level, everything above this level is not logged.
Definition: log.h:90