1 #ifndef LIB_EVENT_H
2 #define LIB_EVENT_H
3 /* event.h name is probably a bit too generic, so lets avoid using it. */
4 
5 #include <sys/time.h>
6 
7 struct event;
8 struct event_log_params;
9 
10 /* Hierarchical category of events. Each event can belong to multiple
11    categories. For example [ lib-storage/maildir, syscall/io ]. The categories
12    are expected to live as long as they're used in events. */
13 struct event_category {
14 	struct event_category *parent;
15 	const char *name;
16 
17 	/* non-NULL if this category has been registered
18 
19 	   Do NOT dereference outside of event code in src/lib.
20 
21 	   At any point in time it is safe to (1) check the pointer for
22 	   NULL/non-NULL to determine if this particular category instance
23 	   has been registered, and (2) compare two categories' internal
24 	   pointers to determine if they represent the same category. */
25 	void *internal;
26 };
27 
28 enum event_field_value_type {
29 	EVENT_FIELD_VALUE_TYPE_STR,
30 	EVENT_FIELD_VALUE_TYPE_INTMAX,
31 	EVENT_FIELD_VALUE_TYPE_TIMEVAL,
32 };
33 
34 struct event_field {
35 	const char *key;
36 	enum event_field_value_type value_type;
37 	struct {
38 		const char *str;
39 		intmax_t intmax;
40 		struct timeval timeval;
41 	} value;
42 };
43 
44 struct event_add_field {
45 	const char *key;
46 	/* The first non-0/NULL value is used. */
47 	const char *value;
48 	intmax_t value_intmax;
49 	struct timeval value_timeval;
50 };
51 
52 struct event_passthrough {
53 	/* wrappers to event_set_*() and event_add_*() for passthrough events,
54 	   so these can be chained like:
55 	   event_create_passthrough(parent)->name("name")->...->event() */
56 	struct event_passthrough *
57 		(*append_log_prefix)(const char *prefix);
58 	struct event_passthrough *
59 		(*replace_log_prefix)(const char *prefix);
60 	struct event_passthrough *
61 		(*set_name)(const char *name);
62 	struct event_passthrough *
63 		(*set_source)(const char *filename,
64 			      unsigned int linenum, bool literal_fname);
65 	struct event_passthrough *
66 		(*set_always_log_source)(void);
67 
68 	struct event_passthrough *
69 		(*add_categories)(struct event_category *const *categories);
70 	struct event_passthrough *
71 		(*add_category)(struct event_category *category);
72 	struct event_passthrough *
73 		(*add_fields)(const struct event_add_field *fields);
74 
75 	struct event_passthrough *
76 		(*add_str)(const char *key, const char *value);
77 	struct event_passthrough *
78 		(*add_int)(const char *key, intmax_t num);
79 	struct event_passthrough *
80 		(*add_timeval)(const char *key, const struct timeval *tv);
81 
82 	struct event_passthrough *
83 		(*inc_int)(const char *key, intmax_t num);
84 
85 	struct event_passthrough *
86 		(*clear_field)(const char *key);
87 
88 	struct event *(*event)(void);
89 };
90 
91 typedef const char *
92 event_log_prefix_callback_t(void *context);
93 typedef const char *
94 event_log_message_callback_t(void *context, enum log_type log_type,
95 			     const char *message);
96 
97 /* Returns TRUE if the event has all the categories that the "other" event has
98    (and maybe more). */
99 bool event_has_all_categories(struct event *event, const struct event *other);
100 /* Returns TRUE if the event has all the fields that the "other" event has
101    (and maybe more). Only the fields in the events themselves are checked.
102    Parent events' fields are not checked. */
103 bool event_has_all_fields(struct event *event, const struct event *other);
104 
105 /* Returns the source event duplicated into a new event. Event pointers are
106    dropped. */
107 struct event *event_dup(const struct event *source);
108 /* Returns a flattened version of the source event.
109    Both categories and fields will be flattened.
110    A new reference to the source event is returned if no flattening was
111    needed. Event pointers are dropped if a new event was created. */
112 struct event *event_flatten(struct event *src);
113 /* Returns a minimized version of the source event.
114    Remove parents with no fields or categories, attempt to flatten fields
115    and categories to avoid sending one-off parent events.  (There is a more
116    detailed description in a comment above the function implementation.)
117    A new reference to the source event is returned if no simplification
118    occured. Event pointers are dropped if a new event was created. */
119 struct event *event_minimize(struct event *src);
120 /* Copy all categories from source to dest.
121    Only the categories in source event itself are copied.
122    Parent events' categories aren't copied. */
123 void event_copy_categories(struct event *to, struct event *from);
124 /* Copy all fields from source to dest.
125    Only the fields in source event itself are copied.
126    Parent events' fields aren't copied. */
127 void event_copy_fields(struct event *to, struct event *from);
128 
129 /* Create a new empty event under the parent event, or NULL for root event. */
130 struct event *event_create(struct event *parent, const char *source_filename,
131 			   unsigned int source_linenum);
132 #define event_create(parent) \
133 	event_create((parent), __FILE__, __LINE__)
134 /* This is a temporary "passthrough" event. Its main purpose is to make it
135    easier to create temporary events as part of the event parameter in
136    e_error(), e_warning(), e_info() or e_debug(). These passthrough events are
137    automatically freed when the e_*() call is finished. Because this makes the
138    freeing less obvious, it should be avoided outside e_*()'s event parameter.
139 
140    The passthrough events also change the API to be more convenient towards
141    being used in a parameter. Instead of having to use e.g.
142    event_add_str(event_set_name(event_create(parent), "name"), "key", "value")
143    the event_passthrough API can be a bit more readable as:
144    event_create_passthrough(parent)->set_name("name")->
145    add_str("key", "value")->event(). The passthrough event is converted to
146    a normal event at the end with the event() call. Note that this API works
147    by modifying the last created passthrough event, so it's not possible to
148    have multiple passthrough events created in parallel. */
149 struct event_passthrough *
150 event_create_passthrough(struct event *parent, const char *source_filename,
151 			 unsigned int source_linenum);
152 #define event_create_passthrough(parent) \
153 	event_create_passthrough((parent), __FILE__, __LINE__)
154 
155 /* Reference the event. Returns the event parameter. */
156 struct event *event_ref(struct event *event);
157 /* Unreference the event. If the reference count drops to 0, the event is
158    freed. The current global event's refcount must not drop to 0. */
159 void event_unref(struct event **event);
160 
161 /* Set the event to be the global default event used by i_error(), etc.
162    Returns the event parameter. The event must be explicitly popped before
163    it's freed.
164 
165    The global event stack is also an alternative nonpermanent hierarchy for
166    events. For example the global event can be "IMAP command SELECT", which
167    can be used for filtering events that happen while the SELECT command is
168    being executed. However, for the created struct mailbox the parent event
169    should be the mail_user, not the SELECT command. Otherwise everything else
170    that happens afterwards to the selected mailbox would also count towards
171    SELECT. This means that events shouldn't be using the current global event
172    as their parent event. */
173 struct event *event_push_global(struct event *event);
174 /* Pop the global event. Assert-crash if the current global event isn't the
175    given event parameter. Returns the new global event. */
176 struct event *event_pop_global(struct event *event);
177 /* Returns the current global event. */
178 struct event *event_get_global(void);
179 
180 /* Set the appended log prefix string for this event. All the parent events'
181    log prefixes will be concatenated together when logging. The log type
182    text (e.g. "Info: ") will be inserted before appended log prefixes (but
183    after replaced log prefix).
184 
185    Clears log_prefix callback.
186  */
187 struct event *
188 event_set_append_log_prefix(struct event *event, const char *prefix);
189 /* Replace the full log prefix string for this event. The parent events' log
190    prefixes won't be used. Also, any parent event's message amendment callback
191    is not used.
192 
193    Clears log_prefix callback.
194 */
195 struct event *event_replace_log_prefix(struct event *event, const char *prefix);
196 
197 /* Drop count prefixes from parents when this event is used for logging. This
198    does not affect the parent events. This only counts actual prefixes and not
199    parents. If the count is higher than the actual number of prefixes added by
200    parents, all will be dropped. */
201 struct event *
202 event_drop_parent_log_prefixes(struct event *event, unsigned int count);
203 
204 /* Sets event prefix callback, sets log_prefix empty */
205 struct event *
206 event_set_log_prefix_callback(struct event *event, bool replace,
207 			      event_log_prefix_callback_t *callback,
208 			      void *context);
209 #define event_set_log_prefix_callback(event, replace, callback, context) \
210 	event_set_log_prefix_callback(event, replace, \
211 		(event_log_prefix_callback_t*)callback, TRUE ? context : \
212 		CALLBACK_TYPECHECK(callback, const char *(*)(typeof(context))))
213 
214 /* Sets event message amendment callback */
215 struct event *
216 event_set_log_message_callback(struct event *event,
217 			       event_log_message_callback_t *callback,
218 			       void *context);
219 #define event_set_log_message_callback(event, callback, context) \
220 	event_set_log_message_callback(event, \
221 		(event_log_message_callback_t*)callback, TRUE ? context : \
222 		CALLBACK_TYPECHECK(callback, \
223 			const char *(*)(typeof(context), enum log_type, \
224 					const char *)))
225 
226 /* Set the event's name. The name is specific to a single sending of an event,
227    and it'll be automatically cleared once the event is sent. This should
228    typically be used only in a parameter to e_debug(), etc. */
229 struct event *
230 event_set_name(struct event *event, const char *name);
231 /* Set the source filename:linenum to the event. If literal_fname==TRUE,
232    it's assumed that __FILE__ has been used and the pointer is stored directly,
233    otherwise the filename is strdup()ed. */
234 struct event *
235 event_set_source(struct event *event, const char *filename,
236 		 unsigned int linenum, bool literal_fname);
237 /* Always include the source path:line in the log replies. This is
238    especially useful when logging about unexpected syscall failures, because
239    it allow quickly finding which of the otherwise identical syscalls in the
240    code generated the error. */
241 struct event *event_set_always_log_source(struct event *event);
242 /* Set minimum normal log level for the event. By default events with INFO
243    level and higher are logged. This can be used to easily hide even the INFO
244    log lines unless some verbose-setting is enabled.
245 
246    Note that this functionality is mostly independent of debug logging.
247    Don't use this to enable debug log - use event_set_forced_debug() instead. */
248 struct event *event_set_min_log_level(struct event *event, enum log_type level);
249 enum log_type event_get_min_log_level(const struct event *event);
250 
251 /* Add an internal pointer to an event. It can be looked up only with
252    event_get_ptr(). The keys are in their own namespace and won't conflict
253    with event fields. The pointers are specific to this specific event only -
254    they will be dropped from any duplicated/flattened/minimized events. */
255 struct event *event_set_ptr(struct event *event, const char *key, void *value);
256 /* Return a pointer set with event_set_ptr(), or NULL if it doesn't exist.
257    The pointer is looked up only from the event itself, not its parents. */
258 void *event_get_ptr(const struct event *event, const char *key);
259 
260 /* Add NULL-terminated list of categories to the event. The categories pointer
261    doesn't need to stay valid afterwards, but the event_category structs
262    themselves must be. Returns the event parameter. */
263 struct event *
264 event_add_categories(struct event *event,
265 		     struct event_category *const *categories);
266 /* Add a single category to the event. */
267 struct event *
268 event_add_category(struct event *event, struct event_category *category);
269 
270 /* Add key=value field to the event. If a key already exists, it's replaced.
271    Child events automatically inherit key=values from their parents at the
272    time the event is sent. So changing a key in parent will change the values
273    in the child events as well, unless the key has been overwritten in the
274    child event. Setting the value to "" is the same as event_field_clear().
275    Returns the event parameter. */
276 struct event *
277 event_add_str(struct event *event, const char *key, const char *value);
278 struct event *
279 event_add_int(struct event *event, const char *key, intmax_t num);
280 /* Increase the key's value. If it's not set or isn't an integer type,
281    initialize the value to num. */
282 struct event *
283 event_inc_int(struct event *event, const char *key, intmax_t num);
284 struct event *
285 event_add_timeval(struct event *event, const char *key,
286 		  const struct timeval *tv);
287 /* Same as event_add_str/int(), but do it via event_field struct. The fields
288    terminates with key=NULL. Returns the event parameter. */
289 struct event *
290 event_add_fields(struct event *event, const struct event_add_field *fields);
291 /* Mark a field as nonexistent. If a parent event has the field set, this
292    allows removing it from the child event. Using an event filter with e.g.
293    "key=*" won't match this field anymore, although it's still visible in
294    event_find_field*() and event_get_fields(). This is the same as using
295    event_add_str() with value="". */
296 void event_field_clear(struct event *event, const char *key);
297 
298 /* Returns the parent event, or NULL if it doesn't exist. */
299 struct event *event_get_parent(const struct event *event);
300 /* Get the event's creation time. */
301 void event_get_create_time(const struct event *event, struct timeval *tv_r);
302 /* Get the time when the event was last sent. Returns TRUE if time was
303    returned, FALSE if event has never been sent. */
304 bool event_get_last_send_time(const struct event *event, struct timeval *tv_r);
305 /* Get the event duration field in microseconds. This is calculated from
306    the event's last sent time. */
307 void event_get_last_duration(const struct event *event,
308 			     uintmax_t *duration_usecs_r);
309 /* Returns field for a given key, or NULL if it doesn't exist. */
310 struct event_field *
311 event_find_field_nonrecursive(const struct event *event, const char *key);
312 /* Returns field for a given key, or NULL if it doesn't exist. If the key
313    isn't found from the event itself, find it from parent events. */
314 const struct event_field *
315 event_find_field_recursive(const struct event *event, const char *key);
316 /* Returns the given key's value as string, or NULL if it doesn't exist.
317    If the field isn't stored as a string, the result is allocated from
318    data stack. */
319 const char *
320 event_find_field_recursive_str(const struct event *event, const char *key);
321 /* Returns all key=value fields that the event has.
322    Parent events' fields aren't returned. */
323 const struct event_field *
324 event_get_fields(const struct event *event, unsigned int *count_r);
325 /* Return all categories that the event has.
326    Parent events' categories aren't returned. */
327 struct event_category *const *
328 event_get_categories(const struct event *event, unsigned int *count_r);
329 
330 /* Export the event into a tabescaped string, so its fields are separated
331    with TABs and there are no NUL, CR or LF characters. */
332 void event_export(const struct event *event, string_t *dest);
333 /* Import event. The string is expected to be generated by event_export().
334    All the used categories must already be registered.
335    Returns TRUE on success, FALSE on invalid string. */
336 bool event_import(struct event *event, const char *str, const char **error_r);
337 /* Same as event_import(), but string is already split into an array
338    of strings via *_strsplit_tabescaped(). */
339 bool event_import_unescaped(struct event *event, const char *const *args,
340 			    const char **error_r);
341 
342 /* The event wasn't sent after all - free everything related to it.
343    Most importantly this frees any passthrough events. Typically this shouldn't
344    need to be called. */
345 void event_send_abort(struct event *event);
346 
347 /* Enable "user_cpu_usecs" event field to event by getting current resource
348    usage which will be used in consequent event_send() to calculate
349    cpu time. This function can be called multiple times to update the current
350    resource usage.
351 
352    The "user_cpu_usecs" field is automatically inherited by passthrough events,
353    but not full events.
354 */
355 void event_enable_user_cpu_usecs(struct event *event);
356 
357 void lib_event_init(void);
358 void lib_event_deinit(void);
359 
360 #endif
361