1 #ifndef EVENT_LOG_H
2 #define EVENT_LOG_H
3 
4 struct event_filter;
5 
6 #include "lib-event.h"
7 
8 struct event_log_params {
9 	enum log_type log_type;
10 	const char *source_filename;
11 	unsigned int source_linenum;
12 
13 	/* Base event used as a reference for base_* parameters (see below) */
14 	struct event *base_event;
15 
16 	/* Append the event message to base_str_out in addition to emitting the
17 	   event as normal. The message appended to the string buffer includes
18 	   prefixes and message callback modifications by parent events up until
19 	   the base_event. The event is otherwise sent as normal with the full
20 	   prefixes and all modifications up to the root event (unless
21 	   no_send=TRUE). This is primarily useful to mimic (part of) event
22 	   logging in parallel logs that are visible to users. */
23 	string_t *base_str_out;
24 
25 	/* Prefix inserted at the base_event for the sent log message. */
26 	const char *base_send_prefix;
27 	/* Prefix inserted at the base_event for the log message appended to the
28 	   string buffer. */
29 	const char *base_str_prefix;
30 
31 	/* Don't actually send the event; only append to the provided string
32 	   buffer (base_str_out must not be NULL). */
33 	bool no_send:1;
34 };
35 
36 /* Increased every time global event filters have changed. */
37 extern unsigned int event_filter_replace_counter;
38 
39 void e_error(struct event *event,
40 	     const char *source_filename, unsigned int source_linenum,
41 	     const char *fmt, ...) ATTR_FORMAT(4, 5);
42 #define e_error(_event, ...) STMT_START { \
43 	struct event *_tmp_event = (_event); \
44 	if (event_want_level(_tmp_event, LOG_TYPE_ERROR)) \
45 		e_error(_tmp_event, __FILE__, __LINE__, __VA_ARGS__); \
46 	else \
47 		event_send_abort(_tmp_event); \
48 	} STMT_END
49 void e_warning(struct event *event,
50 	       const char *source_filename, unsigned int source_linenum,
51 	       const char *fmt, ...) ATTR_FORMAT(4, 5);
52 #define e_warning(_event, ...) STMT_START { \
53 	struct event *_tmp_event = (_event); \
54 	 if (event_want_level(_tmp_event, LOG_TYPE_WARNING)) \
55 		e_warning(_tmp_event, __FILE__, __LINE__, __VA_ARGS__); \
56 	else \
57 		event_send_abort(_tmp_event); \
58 	} STMT_END
59 void e_info(struct event *event,
60 	    const char *source_filename, unsigned int source_linenum,
61 	    const char *fmt, ...) ATTR_FORMAT(4, 5);
62 #define e_info(_event, ...) STMT_START { \
63 	struct event *_tmp_event = (_event); \
64 	if (event_want_level(_tmp_event, LOG_TYPE_INFO)) \
65 		e_info(_tmp_event, __FILE__, __LINE__, __VA_ARGS__); \
66 	else \
67 		event_send_abort(_tmp_event); \
68 	} STMT_END
69 void e_debug(struct event *event,
70 	     const char *source_filename, unsigned int source_linenum,
71 	     const char *fmt, ...) ATTR_FORMAT(4, 5);
72 #define e_debug(_event, ...) STMT_START { \
73 	struct event *_tmp_event = (_event); \
74 	if (event_want_debug(_tmp_event)) \
75 		e_debug(_tmp_event, __FILE__, __LINE__, __VA_ARGS__); \
76 	else \
77 		event_send_abort(_tmp_event); \
78 	} STMT_END
79 
80 void e_log(struct event *event, enum log_type level,
81 	   const char *source_filename, unsigned int source_linenum,
82 	   const char *fmt, ...) ATTR_FORMAT(5, 6);
83 #define e_log(_event, level, ...) STMT_START { \
84 	struct event *_tmp_event = (_event); \
85 	if (event_want_level(_tmp_event, level)) \
86 		e_log(_tmp_event, level, __FILE__, __LINE__, __VA_ARGS__); \
87 	else \
88 		event_send_abort(_tmp_event); \
89 	} STMT_END
90 
91 /* Returns TRUE if event should be logged. Typically event_want_debug_log()
92    could be used in deciding whether to build an expensive debug log message
93    (e.g. requires extra disk IO). Note that if this is used, the actual
94    event being sent won't be matched against event filters because it's never
95    called. The result of the check is cached in the event, so repeated calls
96    are efficient. */
97 bool event_want_log_level(struct event *event, enum log_type level,
98 			  const char *source_filename,
99 			  unsigned int source_linenum);
100 #define event_want_log_level(_event, level) event_want_log_level((_event), (level), __FILE__, __LINE__)
101 #define event_want_debug_log(_event) event_want_log_level((_event), LOG_TYPE_DEBUG)
102 
103 /* Returns TRUE if event should be processed (for logging or sending to stats).
104    The logging is checked with event_want_log_level() with the same caching
105    behavior.  */
106 bool event_want_level(struct event *event, enum log_type level,
107 		      const char *source_filename,
108 		      unsigned int source_linenum);
109 #define event_want_level(_event, level) event_want_level((_event), (level), __FILE__, __LINE__)
110 #define event_want_debug(_event) event_want_level((_event), LOG_TYPE_DEBUG)
111 
112 void event_log(struct event *event, const struct event_log_params *params,
113 	       const char *fmt, ...)
114 	ATTR_FORMAT(3, 4);
115 void event_logv(struct event *event, const struct event_log_params *params,
116 		const char *fmt, va_list args)
117 	ATTR_FORMAT(3, 0);
118 
119 /* If debugging is forced, the global debug log filter is ignored. Changing
120    this applies only to this event and any child event that is created
121    afterwards. It doesn't apply to existing child events (mainly for
122    performance reasons).
123 
124    Note that event_set_forced_debug(event, FALSE) is a no-op. To disable
125    forced-debug, use event_unset_forced_debug(event). */
126 struct event *event_set_forced_debug(struct event *event, bool force);
127 /* Set the forced-debug to FALSE */
128 struct event *event_unset_forced_debug(struct event *event);
129 /* Set the global filter to logging debug events. */
130 void event_set_global_debug_log_filter(struct event_filter *filter);
131 /* Return the current global debug log event filter. */
132 struct event_filter *event_get_global_debug_log_filter(void);
133 /* Unset global debug log filter, if one exists. */
134 void event_unset_global_debug_log_filter(void);
135 
136 /* Set the global filter to sending debug events. The debug events are also
137    sent if they match the global debug log filter. */
138 void event_set_global_debug_send_filter(struct event_filter *filter);
139 /* Return the current global debug send event filter. */
140 struct event_filter *event_get_global_debug_send_filter(void);
141 /* Unset global debug send filter, if one exists. */
142 void event_unset_global_debug_send_filter(void);
143 
144 /* Set/replace the global core filter, which abort()s on matching events. */
145 void event_set_global_core_log_filter(struct event_filter *filter);
146 /* Return the current global core filter. */
147 struct event_filter *event_get_global_core_log_filter(void);
148 /* Unset the global core filter, if one exists. */
149 void event_unset_global_core_log_filter(void);
150 
151 #endif
152