1 /* PipeWire 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 PIPEWIRE_LOG_H 26 #define PIPEWIRE_LOG_H 27 28 #include <spa/support/log.h> 29 30 #ifdef __cplusplus 31 extern "C" { 32 #endif 33 34 /** \defgroup pw_log Logging 35 * 36 * \brief Logging functions of PipeWire 37 * 38 * Logging is performed to stdout and stderr. Trace logging is performed 39 * in a lockfree ringbuffer and written out from the main thread as to not 40 * block the realtime threads. 41 */ 42 43 /** 44 * \addtogroup pw_log 45 * \{ 46 */ 47 /** The global log level */ 48 extern enum spa_log_level pw_log_level; 49 50 extern struct spa_log_topic *PW_LOG_TOPIC_DEFAULT; 51 52 /** Configure a logging module. This is usually done automatically 53 * in pw_init() but you can install a custom logger before calling 54 * pw_init(). */ 55 void pw_log_set(struct spa_log *log); 56 57 /** Get the log interface */ 58 struct spa_log *pw_log_get(void); 59 60 /** Configure the logging level */ 61 void pw_log_set_level(enum spa_log_level level); 62 63 /** Log a message for a topic */ 64 void 65 pw_log_logt(enum spa_log_level level, 66 const struct spa_log_topic *topic, 67 const char *file, 68 int line, const char *func, 69 const char *fmt, ...) SPA_PRINTF_FUNC(6, 7); 70 71 /** Log a message for a topic */ 72 void 73 pw_log_logtv(enum spa_log_level level, 74 const struct spa_log_topic *topic, 75 const char *file, 76 int line, const char *func, 77 const char *fmt, va_list args) SPA_PRINTF_FUNC(6, 0); 78 79 80 81 /** Log a message for the default topic */ 82 void 83 pw_log_log(enum spa_log_level level, 84 const char *file, 85 int line, const char *func, 86 const char *fmt, ...) SPA_PRINTF_FUNC(5, 6); 87 88 /** Log a message for the default topic */ 89 void 90 pw_log_logv(enum spa_log_level level, 91 const char *file, 92 int line, const char *func, 93 const char *fmt, va_list args) SPA_PRINTF_FUNC(5, 0); 94 95 /** Initialize the log topic. The returned topic is owned by the pipewire 96 * context and the topic must not be modified or freed. 97 * Do not use this function directly, use one of PW_LOG_TOPIC_* instead. 98 * 99 * \see PW_LOG_TOPIC_STATIC 100 * \see PW_LOG_TOPIC_EXTERN 101 * \see PW_LOG_TOPIC 102 */ 103 void 104 _pw_log_topic_new(struct spa_log_topic *topic); 105 106 /** 107 * Declare a static log topic named \a var. The usual usage is: 108 * \code 109 * PW_LOG_TOPIC_STATIC(my_topic); 110 * #define PW_LOG_TOPIC_DEFAULT my_topic 111 * 112 * void foo() { 113 * pw_log_debug("bar"); 114 * } 115 * \endcode 116 */ 117 #define PW_LOG_TOPIC_STATIC(var, topic) \ 118 static struct spa_log_topic var##__LINE__ = SPA_LOG_TOPIC(0, topic); \ 119 static struct spa_log_topic *var = &(var##__LINE__) 120 121 /** 122 * Declare a static log topic named \a var. 123 * See \ref PW_LOG_TOPIC_STATIC for an example usage. 124 */ 125 #define PW_LOG_TOPIC_EXTERN(var) \ 126 extern struct spa_log_topic *var 127 128 /** 129 * Declare a static log topic named \a var. 130 * See \ref PW_LOG_TOPIC_STATIC for an example usage. 131 */ 132 #define PW_LOG_TOPIC(var, topic) \ 133 struct spa_log_topic var##__LINE__ = SPA_LOG_TOPIC(0, topic); \ 134 struct spa_log_topic *var = &(var##__LINE__) 135 136 #define PW_LOG_TOPIC_INIT(var) \ 137 spa_log_topic_init(pw_log_get(), var); 138 139 /** Check if a loglevel is enabled */ 140 #define pw_log_level_enabled(lev) (pw_log_level >= (lev)) 141 #define pw_log_topic_enabled(lev,t) ((t) && (t)->has_custom_level ? (t)->level >= (lev) : pw_log_level_enabled((lev))) 142 143 144 #define pw_logt(lev,topic,...) \ 145 ({ \ 146 if (SPA_UNLIKELY(pw_log_topic_enabled(lev,topic))) \ 147 pw_log_logt(lev,topic,__FILE__,__LINE__,__func__,__VA_ARGS__); \ 148 }) 149 150 #define pw_log(lev,...) pw_logt(lev,PW_LOG_TOPIC_DEFAULT,__VA_ARGS__) 151 152 #define pw_log_error(...) pw_log(SPA_LOG_LEVEL_ERROR,__VA_ARGS__) 153 #define pw_log_warn(...) pw_log(SPA_LOG_LEVEL_WARN,__VA_ARGS__) 154 #define pw_log_info(...) pw_log(SPA_LOG_LEVEL_INFO,__VA_ARGS__) 155 #define pw_log_debug(...) pw_log(SPA_LOG_LEVEL_DEBUG,__VA_ARGS__) 156 #define pw_log_trace(...) pw_log(SPA_LOG_LEVEL_TRACE,__VA_ARGS__) 157 158 #define pw_logt_error(t,...) pw_logt(SPA_LOG_LEVEL_ERROR,t,__VA_ARGS__) 159 #define pw_logt_warn(t,...) pw_logt(SPA_LOG_LEVEL_WARN,t,__VA_ARGS__) 160 #define pw_logt_info(t,...) pw_logt(SPA_LOG_LEVEL_INFO,t,__VA_ARGS__) 161 #define pw_logt_debug(t,...) pw_logt(SPA_LOG_LEVEL_DEBUG,t,__VA_ARGS__) 162 #define pw_logt_trace(t,...) pw_logt(SPA_LOG_LEVEL_TRACE,t,__VA_ARGS__) 163 164 #ifndef FASTPATH 165 #define pw_log_trace_fp(...) pw_log(SPA_LOG_LEVEL_TRACE,__VA_ARGS__) 166 #else 167 #define pw_log_trace_fp(...) 168 #endif 169 170 /** 171 * \} 172 */ 173 174 #ifdef __cplusplus 175 } 176 #endif 177 #endif /* PIPEWIRE_LOG_H */ 178