diff options
Diffstat (limited to 'src/lib/event-log.h')
-rw-r--r-- | src/lib/event-log.h | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/src/lib/event-log.h b/src/lib/event-log.h new file mode 100644 index 0000000..e5b7eb8 --- /dev/null +++ b/src/lib/event-log.h @@ -0,0 +1,151 @@ +#ifndef EVENT_LOG_H +#define EVENT_LOG_H + +struct event_filter; + +#include "lib-event.h" + +struct event_log_params { + enum log_type log_type; + const char *source_filename; + unsigned int source_linenum; + + /* Base event used as a reference for base_* parameters (see below) */ + struct event *base_event; + + /* Append the event message to base_str_out in addition to emitting the + event as normal. The message appended to the string buffer includes + prefixes and message callback modifications by parent events up until + the base_event. The event is otherwise sent as normal with the full + prefixes and all modifications up to the root event (unless + no_send=TRUE). This is primarily useful to mimic (part of) event + logging in parallel logs that are visible to users. */ + string_t *base_str_out; + + /* Prefix inserted at the base_event for the sent log message. */ + const char *base_send_prefix; + /* Prefix inserted at the base_event for the log message appended to the + string buffer. */ + const char *base_str_prefix; + + /* Don't actually send the event; only append to the provided string + buffer (base_str_out must not be NULL). */ + bool no_send:1; +}; + +/* Increased every time global event filters have changed. */ +extern unsigned int event_filter_replace_counter; + +void e_error(struct event *event, + const char *source_filename, unsigned int source_linenum, + const char *fmt, ...) ATTR_FORMAT(4, 5); +#define e_error(_event, ...) STMT_START { \ + struct event *_tmp_event = (_event); \ + if (event_want_level(_tmp_event, LOG_TYPE_ERROR)) \ + e_error(_tmp_event, __FILE__, __LINE__, __VA_ARGS__); \ + else \ + event_send_abort(_tmp_event); \ + } STMT_END +void e_warning(struct event *event, + const char *source_filename, unsigned int source_linenum, + const char *fmt, ...) ATTR_FORMAT(4, 5); +#define e_warning(_event, ...) STMT_START { \ + struct event *_tmp_event = (_event); \ + if (event_want_level(_tmp_event, LOG_TYPE_WARNING)) \ + e_warning(_tmp_event, __FILE__, __LINE__, __VA_ARGS__); \ + else \ + event_send_abort(_tmp_event); \ + } STMT_END +void e_info(struct event *event, + const char *source_filename, unsigned int source_linenum, + const char *fmt, ...) ATTR_FORMAT(4, 5); +#define e_info(_event, ...) STMT_START { \ + struct event *_tmp_event = (_event); \ + if (event_want_level(_tmp_event, LOG_TYPE_INFO)) \ + e_info(_tmp_event, __FILE__, __LINE__, __VA_ARGS__); \ + else \ + event_send_abort(_tmp_event); \ + } STMT_END +void e_debug(struct event *event, + const char *source_filename, unsigned int source_linenum, + const char *fmt, ...) ATTR_FORMAT(4, 5); +#define e_debug(_event, ...) STMT_START { \ + struct event *_tmp_event = (_event); \ + if (event_want_debug(_tmp_event)) \ + e_debug(_tmp_event, __FILE__, __LINE__, __VA_ARGS__); \ + else \ + event_send_abort(_tmp_event); \ + } STMT_END + +void e_log(struct event *event, enum log_type level, + const char *source_filename, unsigned int source_linenum, + const char *fmt, ...) ATTR_FORMAT(5, 6); +#define e_log(_event, level, ...) STMT_START { \ + struct event *_tmp_event = (_event); \ + if (event_want_level(_tmp_event, level)) \ + e_log(_tmp_event, level, __FILE__, __LINE__, __VA_ARGS__); \ + else \ + event_send_abort(_tmp_event); \ + } STMT_END + +/* Returns TRUE if event should be logged. Typically event_want_debug_log() + could be used in deciding whether to build an expensive debug log message + (e.g. requires extra disk IO). Note that if this is used, the actual + event being sent won't be matched against event filters because it's never + called. The result of the check is cached in the event, so repeated calls + are efficient. */ +bool event_want_log_level(struct event *event, enum log_type level, + const char *source_filename, + unsigned int source_linenum); +#define event_want_log_level(_event, level) event_want_log_level((_event), (level), __FILE__, __LINE__) +#define event_want_debug_log(_event) event_want_log_level((_event), LOG_TYPE_DEBUG) + +/* Returns TRUE if event should be processed (for logging or sending to stats). + The logging is checked with event_want_log_level() with the same caching + behavior. */ +bool event_want_level(struct event *event, enum log_type level, + const char *source_filename, + unsigned int source_linenum); +#define event_want_level(_event, level) event_want_level((_event), (level), __FILE__, __LINE__) +#define event_want_debug(_event) event_want_level((_event), LOG_TYPE_DEBUG) + +void event_log(struct event *event, const struct event_log_params *params, + const char *fmt, ...) + ATTR_FORMAT(3, 4); +void event_logv(struct event *event, const struct event_log_params *params, + const char *fmt, va_list args) + ATTR_FORMAT(3, 0); + +/* If debugging is forced, the global debug log filter is ignored. Changing + this applies only to this event and any child event that is created + afterwards. It doesn't apply to existing child events (mainly for + performance reasons). + + Note that event_set_forced_debug(event, FALSE) is a no-op. To disable + forced-debug, use event_unset_forced_debug(event). */ +struct event *event_set_forced_debug(struct event *event, bool force); +/* Set the forced-debug to FALSE */ +struct event *event_unset_forced_debug(struct event *event); +/* Set the global filter to logging debug events. */ +void event_set_global_debug_log_filter(struct event_filter *filter); +/* Return the current global debug log event filter. */ +struct event_filter *event_get_global_debug_log_filter(void); +/* Unset global debug log filter, if one exists. */ +void event_unset_global_debug_log_filter(void); + +/* Set the global filter to sending debug events. The debug events are also + sent if they match the global debug log filter. */ +void event_set_global_debug_send_filter(struct event_filter *filter); +/* Return the current global debug send event filter. */ +struct event_filter *event_get_global_debug_send_filter(void); +/* Unset global debug send filter, if one exists. */ +void event_unset_global_debug_send_filter(void); + +/* Set/replace the global core filter, which abort()s on matching events. */ +void event_set_global_core_log_filter(struct event_filter *filter); +/* Return the current global core filter. */ +struct event_filter *event_get_global_core_log_filter(void); +/* Unset the global core filter, if one exists. */ +void event_unset_global_core_log_filter(void); + +#endif |