dsp.c: Update calls to ast_format_cmp to check result properly
[asterisk/asterisk.git] / include / asterisk / logger.h
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*!
20   \file logger.h
21   \brief Support for logging to various files, console and syslog
22         Configuration in file logger.conf
23 */
24
25 #ifndef _ASTERISK_LOGGER_H
26 #define _ASTERISK_LOGGER_H
27
28 #include "asterisk/options.h"   /* need option_debug */
29
30 #if defined(__cplusplus) || defined(c_plusplus)
31 extern "C" {
32 #endif
33
34 #define EVENTLOG "event_log"
35 #define QUEUELOG        "queue_log"
36
37 #define DEBUG_M(a) { \
38         a; \
39 }
40
41 #define VERBOSE_PREFIX_1 " "
42 #define VERBOSE_PREFIX_2 "  == "
43 #define VERBOSE_PREFIX_3 "    -- "
44 #define VERBOSE_PREFIX_4 "       > "
45
46 #define AST_CALLID_BUFFER_LENGTH 13
47
48 enum ast_logger_results {
49         AST_LOGGER_SUCCESS = 0, /*!< Log channel was created or deleted successfully*/
50         AST_LOGGER_FAILURE = 1, /*!< Log channel already exists for create or doesn't exist for deletion of log channel */
51         AST_LOGGER_DECLINE = -1, /*!< Log channel request was not accepted */
52         AST_LOGGER_ALLOC_ERROR = -2 /*!< filename allocation error */
53 };
54
55 /*! \brief Used for sending a log message
56         This is the standard logger function.  Probably the only way you will invoke it would be something like this:
57         ast_log(AST_LOG_WHATEVER, "Problem with the %s Captain.  We should get some more.  Will %d be enough?\n", "flux capacitor", 10);
58         where WHATEVER is one of ERROR, DEBUG, EVENT, NOTICE, or WARNING depending
59         on which log you wish to output to. These are implemented as macros, that
60         will provide the function with the needed arguments.
61
62         \param level    Type of log event
63         \param file     Will be provided by the AST_LOG_* macro
64         \param line     Will be provided by the AST_LOG_* macro
65         \param function Will be provided by the AST_LOG_* macro
66         \param fmt      This is what is important.  The format is the same as your favorite breed of printf.  You know how that works, right? :-)
67  */
68
69 void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...)
70         __attribute__((format(printf, 5, 6)));
71
72 void ast_log_ap(int level, const char *file, int line, const char *function, const char *fmt, va_list ap)
73          __attribute__((format(printf, 5, 0)));
74
75 /*!
76  * \brief Used for sending a log message with protection against recursion.
77  *
78  * \note This function should be used by all error messages that might be directly
79  * or indirectly caused by logging.
80  *
81  * \see ast_log for documentation on the parameters.
82  */
83 void ast_log_safe(int level, const char *file, int line, const char *function, const char *fmt, ...)
84         __attribute__((format(printf, 5, 6)));
85
86 /* XXX needs documentation */
87 typedef unsigned int ast_callid;
88
89 /*! \brief Used for sending a log message with a known call_id
90         This is a modified logger function which is functionally identical to the above logger function,
91         it just include a call_id argument as well. If NULL is specified here, no attempt will be made to
92         join the log message with a call_id.
93
94         \param level    Type of log event
95         \param file     Will be provided by the AST_LOG_* macro
96         \param line     Will be provided by the AST_LOG_* macro
97         \param function Will be provided by the AST_LOG_* macro
98         \param callid   This is the ast_callid that is associated with the log message. May be NULL.
99         \param fmt      This is what is important.  The format is the same as your favorite breed of printf.  You know how that works, right? :-)
100 */
101 void ast_log_callid(int level, const char *file, int line, const char *function, ast_callid callid, const char *fmt, ...)
102         __attribute__((format(printf, 6, 7)));
103
104 /*!
105  * \brief Retrieve the existing log channels
106  * \param logentry A callback to an updater function
107  * \param data Data passed into the callback for manipulation
108  *
109  * For each of the logging channels, logentry will be executed with the
110  * channel file name, log type, status of the log, and configuration levels.
111  *
112  * \retval 0 on success
113  * \retval 1 on failure
114  * \retval -2 on allocation error
115  */
116 int ast_logger_get_channels(int (*logentry)(const char *channel, const char *type,
117         const char *status, const char *configuration, void *data), void *data);
118
119 /*!
120  * \brief Create a log channel
121  *
122  * \param log_channel Log channel to create
123  * \param components Logging config levels to add to the log channel
124  */
125 int ast_logger_create_channel(const char *log_channel, const char *components);
126
127 /*!
128  * \brief Delete the specified log channel
129  *
130  * \param log_channel The log channel to delete
131  */
132 int ast_logger_remove_channel(const char *log_channel);
133
134 /*!
135  * \brief Log a backtrace of the current thread's execution stack to the Asterisk log
136  */
137 void ast_log_backtrace(void);
138
139 /*! \brief Reload logger while rotating log files */
140 int ast_logger_rotate(void);
141
142 /*!
143  * \brief Rotate the specified log channel.
144  *
145  * \param log_channel The log channel to rotate
146  */
147 int ast_logger_rotate_channel(const char *log_channel);
148
149 void __attribute__((format(printf, 5, 6))) ast_queue_log(const char *queuename, const char *callid, const char *agent, const char *event, const char *fmt, ...);
150
151 /*!
152  * \brief Send a verbose message (based on verbose level)
153  *
154  * \details This works like ast_log, but prints verbose messages to the console depending on verbosity level set.
155  *
156  * ast_verbose(VERBOSE_PREFIX_3 "Whatever %s is happening\n", "nothing");
157  *
158  * This will print the message to the console if the verbose level is set to a level >= 3
159  *
160  * Note the absence of a comma after the VERBOSE_PREFIX_3.  This is important.
161  * VERBOSE_PREFIX_1 through VERBOSE_PREFIX_4 are defined.
162  *
163  * \version 11 added level parameter
164  */
165 void __attribute__((format(printf, 5, 6))) __ast_verbose(const char *file, int line, const char *func, int level, const char *fmt, ...);
166
167 /*!
168  * \brief Send a verbose message (based on verbose level) with deliberately specified callid
169  *
170  * \details just like __ast_verbose, only __ast_verbose_callid allows you to specify which callid is being used
171  * for the log without needing to bind it to a thread. NULL is a valid argument for this function and will
172  * allow you to specify that a log will never display a call id even when there is a call id bound to the
173  * thread.
174  */
175 void __attribute__((format(printf, 6, 7))) __ast_verbose_callid(const char *file, int line, const char *func, int level, ast_callid callid, const char *fmt, ...);
176
177 #define ast_verbose(...) __ast_verbose(__FILE__, __LINE__, __PRETTY_FUNCTION__, -1, __VA_ARGS__)
178 #define ast_verbose_callid(callid, ...) __ast_verbose_callid(__FILE__, __LINE__, __PRETTY_FUNCTION__, -1, callid, __VA_ARGS__)
179
180 void __attribute__((format(printf, 6, 0))) __ast_verbose_ap(const char *file, int line, const char *func, int level, ast_callid callid, const char *fmt, va_list ap);
181
182 void __attribute__((format(printf, 2, 3))) ast_child_verbose(int level, const char *fmt, ...);
183
184 int ast_register_verbose(void (*verboser)(const char *string)) attribute_warn_unused_result;
185 int ast_unregister_verbose(void (*verboser)(const char *string)) attribute_warn_unused_result;
186
187 /*
188  * These gymnastics are due to platforms which designate char as unsigned by
189  * default.  Level is the negative character -- offset by 1, because \0 is
190  * the string terminator.
191  */
192 #define VERBOSE_MAGIC2LEVEL(x) (((char) -*(signed char *) (x)) - 1)
193 #define VERBOSE_HASMAGIC(x)     (*(signed char *) (x) < 0)
194
195 void ast_console_puts(const char *string);
196
197 /*!
198  * \brief log the string to the console, and all attached console clients
199  *
200  * \param string The message to write to the console
201  * \param level The log level of the message
202  *
203  * \version 1.6.1 added level parameter
204  */
205 void ast_console_puts_mutable(const char *string, int level);
206
207 /*!
208  * \brief log the string to the console, and all attached console clients
209  * \since 14.0.0
210  *
211  * \param message The message to write to the console
212  * \param sublevel If the log level supports it, the sub-level of the message
213  * \param level The log level of the message
214  */
215 void ast_console_puts_mutable_full(const char *message, int level, int sublevel);
216
217 void ast_console_toggle_mute(int fd, int silent);
218
219 /*!
220  * \brief enables or disables logging of a specified level to the console
221  * fd specifies the index of the console receiving the level change
222  * level specifies the index of the logging level being toggled
223  * state indicates whether logging will be on or off (0 for off, 1 for on)
224  */
225 void ast_console_toggle_loglevel(int fd, int level, int state);
226
227 /* Note: The AST_LOG_* macros below are the same as
228  * the LOG_* macros and are intended to eventually replace
229  * the LOG_* macros to avoid name collisions with the syslog(3)
230  * log levels. However, please do NOT remove
231  * the LOG_* macros from the source since these may be still
232  * needed for third-party modules
233  */
234
235 #define _A_ __FILE__, __LINE__, __PRETTY_FUNCTION__
236
237 #ifdef LOG_DEBUG
238 #undef LOG_DEBUG
239 #endif
240 #define __LOG_DEBUG    0
241 #define LOG_DEBUG      __LOG_DEBUG, _A_
242
243 #ifdef AST_LOG_DEBUG
244 #undef AST_LOG_DEBUG
245 #endif
246 #define AST_LOG_DEBUG      __LOG_DEBUG, _A_
247
248 #ifdef LOG_TRACE
249 #undef LOG_TRACE
250 #endif
251 #define __LOG_TRACE   1
252 #define LOG_TRACE     __LOG_TRACE, _A_
253
254 #ifdef AST_LOG_TRACE
255 #undef AST_LOG_TRACE
256 #endif
257 #define AST_LOG_TRACE     __LOG_TRACE, _A_
258
259 #ifdef LOG_NOTICE
260 #undef LOG_NOTICE
261 #endif
262 #define __LOG_NOTICE   2
263 #define LOG_NOTICE     __LOG_NOTICE, _A_
264
265 #ifdef AST_LOG_NOTICE
266 #undef AST_LOG_NOTICE
267 #endif
268 #define AST_LOG_NOTICE     __LOG_NOTICE, _A_
269
270 #ifdef LOG_WARNING
271 #undef LOG_WARNING
272 #endif
273 #define __LOG_WARNING  3
274 #define LOG_WARNING    __LOG_WARNING, _A_
275
276 #ifdef AST_LOG_WARNING
277 #undef AST_LOG_WARNING
278 #endif
279 #define AST_LOG_WARNING    __LOG_WARNING, _A_
280
281 #ifdef LOG_ERROR
282 #undef LOG_ERROR
283 #endif
284 #define __LOG_ERROR    4
285 #define LOG_ERROR      __LOG_ERROR, _A_
286
287 #ifdef AST_LOG_ERROR
288 #undef AST_LOG_ERROR
289 #endif
290 #define AST_LOG_ERROR      __LOG_ERROR, _A_
291
292 #ifdef LOG_VERBOSE
293 #undef LOG_VERBOSE
294 #endif
295 #define __LOG_VERBOSE  5
296 #define LOG_VERBOSE    __LOG_VERBOSE, _A_
297
298 #ifdef AST_LOG_VERBOSE
299 #undef AST_LOG_VERBOSE
300 #endif
301 #define AST_LOG_VERBOSE    __LOG_VERBOSE, _A_
302
303 #ifdef LOG_DTMF
304 #undef LOG_DTMF
305 #endif
306 #define __LOG_DTMF  6
307 #define LOG_DTMF    __LOG_DTMF, _A_
308
309 #ifdef AST_LOG_DTMF
310 #undef AST_LOG_DTMF
311 #endif
312 #define AST_LOG_DTMF    __LOG_DTMF, _A_
313
314 #define NUMLOGLEVELS 32
315
316 /*!
317  * \brief Get the debug level for a module
318  * \param module the name of module
319  * \return the debug level
320  */
321 unsigned int ast_debug_get_by_module(const char *module);
322
323 /*!
324  * \brief Register a new logger level
325  * \param name The name of the level to be registered
326  * \retval -1 if an error occurs
327  * \retval non-zero level to be used with ast_log for sending messages to this level
328  * \since 1.8
329  */
330 int ast_logger_register_level(const char *name);
331
332 /*!
333  * \brief Unregister a previously registered logger level
334  * \param name The name of the level to be unregistered
335  * \return nothing
336  * \since 1.8
337  */
338 void ast_logger_unregister_level(const char *name);
339
340 /*!
341  * \brief Get the logger configured date format
342  *
343  * \retval The date format string
344  *
345  * \since 13.0.0
346  */
347 const char *ast_logger_get_dateformat(void);
348
349 /*!
350  * \brief factory function to create a new uniquely identifying callid.
351  *
352  * \retval The call id
353  */
354 ast_callid ast_create_callid(void);
355
356 /*!
357  * \brief extracts the callerid from the thread
358  *
359  * \retval Non-zero Call id related to the thread
360  * \retval 0 if no call_id is present in the thread
361  */
362 ast_callid ast_read_threadstorage_callid(void);
363
364 /*!
365  * \brief Sets what is stored in the thread storage to the given
366  *        callid if it does not match what is already there.
367  *
368  * \retval 0 - success
369  * \retval non-zero - failure
370  */
371 int ast_callid_threadassoc_change(ast_callid callid);
372
373 /*!
374  * \brief Adds a known callid to thread storage of the calling thread
375  *
376  * \retval 0 - success
377  * \retval non-zero - failure
378  */
379 int ast_callid_threadassoc_add(ast_callid callid);
380
381 /*!
382  * \brief Removes callid from thread storage of the calling thread
383  *
384  * \retval 0 - success
385  * \retval non-zero - failure
386  */
387 int ast_callid_threadassoc_remove(void);
388
389 /*!
390  * \brief Checks thread storage for a callid and stores a reference if it exists.
391  *        If not, then a new one will be created, bound to the thread, and a reference
392  *        to it will be stored.
393  *
394  * \param callid pointer to store the callid
395  * \retval 0 - callid was found
396  * \retval 1 - callid was created
397  * \retval -1 - the function failed somehow (presumably memory problems)
398  */
399 int ast_callid_threadstorage_auto(ast_callid *callid);
400
401 /*!
402  * \brief Use in conjunction with ast_callid_threadstorage_auto. Cleans up the
403  *        references and if the callid was created by threadstorage_auto, unbinds
404  *        the callid from the threadstorage
405  * \param callid The callid set by ast_callid_threadstorage_auto
406  * \param callid_created The integer returned through ast_callid_threadstorage_auto
407  */
408 void ast_callid_threadstorage_auto_clean(ast_callid callid, int callid_created);
409
410 /*!
411  * \brief copy a string representation of the callid into a target string
412  *
413  * \param buffer destination of callid string (should be able to store 13 characters or more)
414  * \param buffer_size maximum writable length of the string (Less than 13 will result in truncation)
415  * \param callid Callid for which string is being requested
416  */
417 void ast_callid_strnprint(char *buffer, size_t buffer_size, ast_callid callid);
418
419 /*!
420  * \brief Send a log message to a dynamically registered log level
421  * \param level The log level to send the message to
422  *
423  * Like ast_log, the log message may include printf-style formats, and
424  * the data for these must be provided as additional parameters after
425  * the log message.
426  *
427  * \return nothing
428  * \since 1.8
429  */
430
431 #define ast_log_dynamic_level(level, ...) ast_log(level, __FILE__, __LINE__, __PRETTY_FUNCTION__, __VA_ARGS__)
432
433 #define DEBUG_ATLEAST(level) \
434         (option_debug >= (level) \
435                 || (ast_opt_dbg_module \
436                 && ((int)ast_debug_get_by_module(AST_MODULE) >= (level) \
437                                 || (int)ast_debug_get_by_module(__FILE__) >= (level))))
438
439 /*!
440  * \brief Log a DEBUG message
441  * \param level The minimum value of option_debug for this message
442  *        to get logged
443  */
444 #define ast_debug(level, ...) \
445         do { \
446                 if (DEBUG_ATLEAST(level)) { \
447                         ast_log(AST_LOG_DEBUG, __VA_ARGS__); \
448                 } \
449         } while (0)
450
451 extern int ast_verb_sys_level;
452
453 #define VERBOSITY_ATLEAST(level) ((level) <= ast_verb_sys_level)
454
455 #define ast_verb(level, ...) \
456         do { \
457                 if (VERBOSITY_ATLEAST(level) ) { \
458                         __ast_verbose(__FILE__, __LINE__, __PRETTY_FUNCTION__, level, __VA_ARGS__); \
459                 } \
460         } while (0)
461
462 #define ast_verb_callid(level, callid, ...) \
463         do { \
464                 if (VERBOSITY_ATLEAST(level) ) { \
465                         __ast_verbose_callid(__FILE__, __LINE__, __PRETTY_FUNCTION__, level, callid, __VA_ARGS__); \
466                 } \
467         } while (0)
468
469 /*!
470  * \brief Re-evaluate the system max verbosity level (ast_verb_sys_level).
471  *
472  * \return Nothing
473  */
474 void ast_verb_update(void);
475
476 /*!
477  * \brief Register this thread's console verbosity level pointer.
478  *
479  * \param level Where the verbose level value is.
480  *
481  * \return Nothing
482  */
483 void ast_verb_console_register(int *level);
484
485 /*!
486  * \brief Unregister this thread's console verbosity level.
487  *
488  * \return Nothing
489  */
490 void ast_verb_console_unregister(void);
491
492 /*!
493  * \brief Get this thread's console verbosity level.
494  *
495  * \retval verbosity level of the console.
496  */
497 int ast_verb_console_get(void);
498
499 /*!
500  * \brief Set this thread's console verbosity level.
501  *
502  * \param verb_level New level to set.
503  *
504  * \return Nothing
505  */
506 void ast_verb_console_set(int verb_level);
507
508 /*!
509  * \brief Test if logger is initialized
510  *
511  * \retval true if the logger is initialized
512  */
513 int ast_is_logger_initialized(void);
514
515 /*!
516  * \brief Set the maximum number of messages allowed in the processing queue
517  *
518  * \param queue_limit
519  *
520  * \return Nothing
521  */
522 void ast_logger_set_queue_limit(int queue_limit);
523
524 /*!
525  * \brief Get the maximum number of messages allowed in the processing queue
526  *
527  * \return Queue limit
528  */
529 int ast_logger_get_queue_limit(void);
530
531
532 /*!
533  \page Scope_Trace Scope Trace
534
535 The Scope Trace facility allows you to instrument code and output scope entry
536 and exit messages with associated data.
537
538 To start using it:
539  * You must have used --enable-dev-mode.
540  * In logger.conf, set a logger channel to output the "trace" level.
541  * Instrument your code as specified below.
542  * Use the cli or cli.conf to enable tracing: CLI> core set trace <trace_level> [ module ]
543
544 Its simplest usage requires only 1 macro call that...
545         - Registers a descructor for a special variable that gets called when the
546           variable goes out of scope.  Uses the same principle as RAII_VAR.
547           The destructor prints the name of the function with an "exiting" indicator
548           along with an optional message.
549         - Prints the name of the function with an "entering" indicator along with
550           an optional message.
551
552 Simple Example:
553 The following code...
554 \code
555 static struct pjmedia_sdp_session *create_local_sdp(pjsip_inv_session *inv,
556         struct ast_sip_session *session, const pjmedia_sdp_session *offer)
557 {
558         SCOPE_TRACE(1, "%s\n", ast_sip_session_get_name(session));
559         ...
560 }
561 \endcode
562 would produce...
563 \b [2020-05-17 15:16:51 -0600] TRACE[953402] : --> res_pjsip_session.c:4283 create_local_sdp PJSIP/1173-00000001
564 \b [2020-05-17 15:16:51 -0600] TRACE[953402] : <-- res_pjsip_session.c:4283 create_local_sdp PJSIP/1173-00000001
565
566 There is one odd bit.  There's no way to capture the line number of there the scope exited
567 so it's always going to be the line where SCOPE_TRACE is located.
568
569 Similar to RAII_VAR, any block scope can be traced including "if", "for", "while", etc.
570 \note "case" statements don't create a scope block by themselves but you can create
571 a block for it, or use the generic trace functions mentioned below.
572
573 Scope Output and Level:
574
575 Rather than sending trace messages to the debug facility, a new facility "trace" has been
576 added to logger.  A corresponding CLI command "core set trace", and a corresponding "trace"
577 parameter in asterisk.conf were added.  This allows a separate log channel to be created
578 just for storing trace messages.  The levels are the same as those for debug and verbose.
579
580 Scope Indenting:
581
582 Each time SCOPE_TRACE or SCOPE_TRACE is called, a thread-local indent value is
583 incremented on scope enter, and decremented on scope exit.  This allows output
584 like the following (timestamp omitted for brevity):
585
586 TRACE[953402] : --> res_pjsip_session.c:3940 session_inv_on_tsx_state_changed PJSIP/1173-00000001 TSX State: Proceeding  Inv State: CALLING
587 TRACE[953402] :         --> res_pjsip_session.c:3680 handle_incoming PJSIP/1173-00000001
588 TRACE[953402] :                 --> res_pjsip_session.c:3661 handle_incoming_response PJSIP/1173-00000001 Method: INVITE Status: 100
589 TRACE[953402] :                         --> res_pjsip_session.c:3669 handle_incoming_response PJSIP/1173-00000001 Method: INVITE Status: 100 Supplement: chan_pjsip
590 TRACE[953402] :                                 --> chan_pjsip.c:3265 chan_pjsip_incoming_response_after_media PJSIP/1173-00000001 Method: INVITE Status: 100  After Media
591 TRACE[953402] :                                         --> chan_pjsip.c:3194 chan_pjsip_incoming_response PJSIP/1173-00000001 Method: INVITE Status: 100
592 TRACE[953402] :                                             chan_pjsip.c:3245 chan_pjsip_incoming_response PJSIP/1173-00000001 Method: INVITE Status: 100  Ignored
593 TRACE[953402] :                                         <-- chan_pjsip.c:3194 chan_pjsip_incoming_response PJSIP/1173-00000001 Method: INVITE Status: 100
594 TRACE[953402] :                                 <-- chan_pjsip.c:3265 chan_pjsip_incoming_response_after_media PJSIP/1173-00000001 Method: INVITE Status: 100  After Media
595 TRACE[953402] :                         <-- res_pjsip_session.c:3669 handle_incoming_response PJSIP/1173-00000001 Method: INVITE Status: 100 Supplement: chan_pjsip
596 TRACE[953402] :                 <-- res_pjsip_session.c:3661 handle_incoming_response PJSIP/1173-00000001 Method: INVITE Status: 100
597 TRACE[953402] :         <-- res_pjsip_session.c:3680 handle_incoming PJSIP/1173-00000001
598 TRACE[953402] : <-- res_pjsip_session.c:3940 session_inv_on_tsx_state_changed PJSIP/1173-00000001 TSX State: Proceeding  Inv State: CALLING
599
600 \note The trace level indicates which messages to print and has no effect on indent.
601
602 Generic Trace Messages:
603
604 Sometimes you may just want to print a message to the trace log with the appropriate indent
605 such as when executing a "case" clause in a "switch" statement. For example, the deepest
606 message in the sample output above (chan_pjsip.c:3245) is just a single message instead of
607 an entry/exit message.  To do so, you can use the ast_trace macros...
608 \code
609         ast_trace(1, "%s Method: %.*s Status: %d  Ignored\n", ast_sip_session_get_name(session),
610                 (int)rdata->msg_info.cseq->method.name.slen, rdata->msg_info.cseq->method.name.ptr, status.code);
611 \endcode
612
613 /note Final note:  The trace facility, like debug, is only available when AST_DEVMODE is defined.
614
615  */
616
617 /*!
618  * \brief Get the trace level for a module
619  * \param module the name of module
620  * \return the trace level
621  */
622 unsigned int ast_trace_get_by_module(const char *module);
623
624 #define TRACE_ATLEAST(level) \
625         (option_trace >= (level) \
626                 || (ast_opt_trace_module \
627                         && ((int)ast_trace_get_by_module(AST_MODULE) >= (level) \
628                                 || (int)ast_trace_get_by_module(__FILE__) >= (level))))
629
630 /*!
631  * \brief Controls if and when indenting is applied.
632  */
633 enum ast_trace_indent_type {
634         /*! Use the existing indent level */
635         AST_TRACE_INDENT_SAME = 0,
636         /*! Increment the indent before printing the message */
637         AST_TRACE_INDENT_INC_BEFORE,
638         /*! Increment the indent after printing the message */
639         AST_TRACE_INDENT_INC_AFTER,
640         /*! Decrement the indent before printing the message */
641         AST_TRACE_INDENT_DEC_BEFORE,
642         /*! Decrement the indent after printing the message */
643         AST_TRACE_INDENT_DEC_AFTER,
644         /*! Set the indent to the one provided */
645         AST_TRACE_INDENT_PROVIDED,
646         /*! Don't use or alter the level */
647         AST_TRACE_INDENT_NONE,
648 };
649
650 #ifdef AST_DEVMODE
651
652 void __attribute__((format (printf, 6, 7))) __ast_trace(const char *file, int line, const char *func,
653         enum ast_trace_indent_type indent_type, unsigned long indent, const char* format, ...);
654
655 /*!
656  * \brief Print a trace message
657  *
658  * \param level The trace level
659  * \param indent_type One of the \ref ast_trace_indent_type values
660  * \param (optional) A printf style format string
661  * \param (optional) Arguments
662  *
663  */
664 #define ast_trace_raw(level, indent_type, ...) \
665         ast_debug(level < 0 ? __scope_level : level, " " __VA_ARGS__); \
666         if (TRACE_ATLEAST(level < 0 ? __scope_level : level)) { \
667                 __ast_trace(__FILE__, __LINE__, __PRETTY_FUNCTION__, indent_type, 0, " " __VA_ARGS__); \
668         }
669
670 /*!
671  * \brief Print a basic trace message
672  *
673  * \param level The trace level
674  * \param (optional) A printf style format string
675  * \param (optional) Arguments
676  *
677  *  This will print the file, line and function at the current indent level
678  */
679 #define ast_trace(level, ...) \
680         ast_debug(level < 0 ? __scope_level : level, " " __VA_ARGS__); \
681         if (TRACE_ATLEAST(level < 0 ? __scope_level : level)) { \
682                 __ast_trace(__FILE__, __LINE__, __PRETTY_FUNCTION__, AST_TRACE_INDENT_SAME, 0, " " __VA_ARGS__); \
683         }
684
685 /*!
686  * \brief Get the current indent level
687  *
688  * \returns The current indent level
689  */
690 unsigned long _ast_trace_get_indent(void);
691 #define ast_trace_get_indent() _ast_trace_get_indent()
692
693 /*!
694  * \brief Set the current indent level
695  *
696  * \param indent The new indent level
697  */
698 void _ast_trace_set_indent(unsigned long indent);
699 #define ast_trace_set_indent(indent) _ast_trace_set_indent(indent)
700
701 /*!
702  * \brief Increment the indent level
703  *
704  * \returns The new indent level
705  */
706 unsigned long _ast_trace_inc_indent(void);
707 #define ast_trace_inc_indent() _ast_trace_inc_indent()
708
709 /*!
710  * \brief Decrement the indent level
711  *
712  * \returns The new indent level
713  */
714 unsigned long _ast_trace_dec_indent(void);
715 #define ast_trace_dec_indent() _ast_trace_dec_indent()
716
717 /*!
718  * \brief Print a trace message with details when a scope is entered or existed.
719  *
720  * \param level The trace level
721  * \param (optional) A printf style format string
722  * \param (optional) Arguments
723  *
724  *  This will print the file, line and function plus details at the current indent level.
725  * \note Like RAII_VAR, this macro must be called before any code in the scope.
726  *
727  * \note The variables used to detect scope change will look like
728  * __scopevar1234__EXIT and __scopevar1234__ENTER.
729  * The ENTER variable and function are needed to prevent mixed code and declaration issues.
730  * If we simple called __ast_trace, then this macro would need to be the last line
731  * of scope variable declaration.  The following would fail.
732  *
733  *      SCOPE_TRACE(1, "Help!\n");
734  *      int i;
735  */
736 #define SCOPE_TRACE(level, ...) \
737         const char *__trace_funcname = __PRETTY_FUNCTION__; \
738         auto void __scopevar ## __LINE__ ## __EXIT(void * v); \
739         void __scopevar ## __LINE__ ## __EXIT(void * v __attribute__((unused))) { \
740                 if (TRACE_ATLEAST(level)) { \
741                         __ast_trace(__FILE__, __LINE__, __trace_funcname, AST_TRACE_INDENT_DEC_BEFORE, 0, " " __VA_ARGS__); \
742                 } \
743         } \
744         void *__scopevar ## __LINE__ ## __TRACER __attribute__((cleanup(__scopevar ## __LINE__ ## __EXIT))) = (void *) __PRETTY_FUNCTION__ ; \
745         auto int __scopevar ## __LINE__ ## __ENTER(void); \
746         int __scopevar ## __LINE__ ## __ENTER(void) { \
747                 if (TRACE_ATLEAST(level)) { \
748                         __ast_trace(__FILE__, __LINE__, __trace_funcname, AST_TRACE_INDENT_INC_AFTER, 0, " " __VA_ARGS__); \
749                 } \
750                 return 0; \
751         } \
752         int __scopevar ## __LINE__ ## __RETURN __attribute__((unused)) = __scopevar ## __LINE__ ## __ENTER()
753
754 /*!
755  * \brief Non RAII_VAR Scope Trace macros
756  * The advantage of these macros is that the EXITs will have the actual
757  * line number where the scope exited.  Much less code is required as well.
758  */
759
760 /*!
761  * \brief Scope Enter
762  *
763  * \param level The trace level
764  * \param (optional) A printf style format string
765  * \param (optional) Arguments
766  */
767 #define SCOPE_ENTER(level, ...) \
768         int __scope_level = level; \
769         int __scope_task = 0; \
770         ast_debug(__scope_level, " " __VA_ARGS__); \
771         if (TRACE_ATLEAST(level)) { \
772                 __ast_trace(__FILE__, __LINE__, __PRETTY_FUNCTION__, AST_TRACE_INDENT_INC_AFTER, 0, " " __VA_ARGS__); \
773         } \
774
775 #define SCOPE_ENTER_TASK(level, indent, ...) \
776         int __scope_level = level; \
777         int __scope_task = 1; \
778         ast_debug(__scope_level, " " __VA_ARGS__); \
779         if (TRACE_ATLEAST(level)) { \
780                 __ast_trace(__FILE__, __LINE__, __PRETTY_FUNCTION__, AST_TRACE_INDENT_PROVIDED, indent, " " __VA_ARGS__); \
781         } \
782
783 /*!
784  * \brief Scope Exit
785  *
786  * \param (optional) A printf style format string
787  * \param (optional) Arguments
788  *
789  * \details
790  * This macro can be used at the exit points of a statement block since it just prints the message.
791  */
792 #define SCOPE_EXIT(...) \
793         ast_debug(__scope_level, " " __VA_ARGS__); \
794         if (TRACE_ATLEAST(__scope_level)) { \
795                 __ast_trace(__FILE__, __LINE__, __PRETTY_FUNCTION__, AST_TRACE_INDENT_DEC_BEFORE, 0, " " __VA_ARGS__); \
796                 if (__scope_task) { \
797                         _ast_trace_set_indent(0); \
798                 } \
799         } \
800
801 /*!
802  * \brief Scope Exit with expression
803  *
804  * \param __expr An expression to execute after printing the message
805  * \param (optional) A printf style format string
806  * \param (optional) Arguments
807  *
808  * \details
809  * Handy for getting out of or continuing loops.
810  *
811  * \example
812  * while(something) {
813  *     SCOPE_ENTER(2, "In a while\n");
814  *     if (something) {
815  *         SCOPE_EXIT_EXPR(break, "Somethiung broke me\n");
816  *     } else {
817  *         SCOPE_EXIT_EXPR(contniue, "Somethiung continued me\n");
818  *     }
819  * }
820  */
821 #define SCOPE_EXIT_EXPR(__expr, ...) \
822         ast_debug(__scope_level, " " __VA_ARGS__); \
823         if (TRACE_ATLEAST(__scope_level)) { \
824                 __ast_trace(__FILE__, __LINE__, __PRETTY_FUNCTION__, AST_TRACE_INDENT_DEC_BEFORE, 0, " " __VA_ARGS__); \
825                 if (__scope_task) { \
826                         _ast_trace_set_indent(0); \
827                 } \
828         } \
829         __expr
830
831 /*!
832  * \brief Scope Exit with return
833  *
834  * \param (optional) A printf style format string
835  * \param (optional) Arguments
836  *
837  * \details
838  * This macro can be used at the exit points of a function when no value
839  * needs to be returned.
840  */
841 #define SCOPE_EXIT_RTN(...) \
842         ast_debug(__scope_level, " " __VA_ARGS__); \
843         if (TRACE_ATLEAST(__scope_level)) { \
844                 __ast_trace(__FILE__, __LINE__, __PRETTY_FUNCTION__, AST_TRACE_INDENT_DEC_BEFORE, 0, " " __VA_ARGS__); \
845                 if (__scope_task) { \
846                         _ast_trace_set_indent(0); \
847                 } \
848         } \
849         return
850
851 /*!
852  * \brief Scope Exit with return value
853  *
854  * \param __return_value The return value
855  * \param (optional) A printf style format string
856  * \param (optional) Arguments
857  *
858  * \details
859  * This macro can be used at the exit points of a function when a value
860  * needs to be returned.
861  */
862 #define SCOPE_EXIT_RTN_VALUE(__return_value, ...) \
863         ast_debug(__scope_level, " " __VA_ARGS__); \
864         if (TRACE_ATLEAST(__scope_level)) { \
865                 __ast_trace(__FILE__, __LINE__, __PRETTY_FUNCTION__, AST_TRACE_INDENT_DEC_BEFORE, 0, " " __VA_ARGS__); \
866                 if (__scope_task) { \
867                         _ast_trace_set_indent(0); \
868                 } \
869         } \
870         return(__return_value)
871
872 #else  /* AST_DEVMODE */
873 #define ast_trace_raw(level, indent_type, ...) \
874         ast_debug(level < 0 ? __scope_level : level, " " __VA_ARGS__)
875
876 #define ast_trace(level, ...) \
877         ast_debug(level < 0 ? __scope_level : level, " " __VA_ARGS__)
878
879 #define ast_trace_get_indent() (0)
880 #define ast_trace_set_indent(indent)
881 #define ast_trace_inc_indent()
882 #define ast_trace_dec_indent()
883 #define SCOPE_TRACE(__level, ...)
884
885 #define SCOPE_ENTER(level, ...) \
886         int __scope_level = level; \
887         ast_debug(level, " " __VA_ARGS__)
888
889 #define SCOPE_ENTER_TASK(level, indent, ...) \
890         int __scope_level = level; \
891         ast_debug(level, " " __VA_ARGS__)
892
893 #define SCOPE_EXIT(...) \
894         ast_debug(__scope_level, " " __VA_ARGS__)
895
896 #define SCOPE_EXIT_EXPR(__expr, ...) \
897         ast_debug(__scope_level, " " __VA_ARGS__); \
898         __expr
899
900 #define SCOPE_EXIT_RTN(...) \
901         ast_debug(__scope_level, " " __VA_ARGS__); \
902         return
903
904 #define SCOPE_EXIT_RTN_VALUE(__return_value, ...) \
905         ast_debug(__scope_level, " " __VA_ARGS__); \
906         return __return_value
907
908 #endif /* AST_DEVMODE */
909
910 /*!
911  * The following macros will print log messages before running
912  * the associated SCOPE_ macro.
913  */
914
915 #define SCOPE_EXIT_LOG(__log_level, ...) \
916 ({ \
917         ast_log(__log_level, " " __VA_ARGS__); \
918         SCOPE_EXIT(" " __VA_ARGS__); \
919 })
920
921 #define SCOPE_EXIT_LOG_RTN(__log_level, ...) \
922 ({ \
923         ast_log(__log_level, " " __VA_ARGS__); \
924         SCOPE_EXIT_RTN(" " __VA_ARGS__); \
925 })
926
927 #define SCOPE_EXIT_LOG_RTN_VALUE(__value, __log_level, ...) \
928 ({ \
929         ast_log(__log_level, " " __VA_ARGS__); \
930         SCOPE_EXIT_RTN_VALUE(__value, " " __VA_ARGS__); \
931 })
932
933 #define SCOPE_EXIT_LOG_EXPR(__expr, __log_level, ...) \
934 ({ \
935         ast_log(__log_level, " " __VA_ARGS__); \
936         SCOPE_EXIT_EXPR(__expr, " " __VA_ARGS__); \
937 })
938
939 #define ast_trace_log(__level, __log_level, ...) \
940 ({ \
941         ast_log(__log_level, " " __VA_ARGS__); \
942         ast_trace(__level < 0 ? __scope_level : __level, " " __VA_ARGS__); \
943 })
944
945
946 #if defined(__cplusplus) || defined(c_plusplus)
947 }
948 #endif
949
950 #endif /* _ASTERISK_LOGGER_H */