]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: lib-event: Add event_enable_user_cpu_usecs
authorSiavash Tavakoli <siavash.tavakoli@open-xchange.com>
Thu, 4 Mar 2021 23:26:52 +0000 (23:26 +0000)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Thu, 11 Mar 2021 10:35:37 +0000 (10:35 +0000)
- Add an internal rusage struct to events to keep track of resource usage.
- "event_enable_user_cpu_usecs()" enables "user_cpu_usecs" field for the event

If "user_cpu_usecs" field is enabled, user CPU time will be calculated
at the time of sending the event and will be added to event fields.

src/lib/lib-event-private.h
src/lib/lib-event.c
src/lib/lib-event.h

index 5acb9b6ee1381a77ca7d7328ff8d82b4553d2168..835fc7e7a9b5a087a2feaef1278dabf984040035 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef LIB_EVENT_PRIVATE_H
 #define LIB_EVENT_PRIVATE_H
 
+#include <sys/resource.h>
+
 struct event_pointer {
        const char *key;
        void *value;
@@ -45,6 +47,7 @@ struct event {
        struct timeval tv_created_ioloop;
        struct timeval tv_created;
        struct timeval tv_last_sent;
+       struct rusage ru_last;
 
        const char *source_filename;
        unsigned int source_linenum;
index 5ead7f6e2e81757f70cbf968bb9294d044445673..6adc812dba0eb49a296e87ae2f890a711b3ef686 100644 (file)
@@ -66,6 +66,12 @@ static ARRAY(struct event_category *) event_registered_categories_representative
 static ARRAY(struct event *) global_event_stack;
 static uint64_t event_id_counter = 0;
 
+static void get_self_rusage(struct rusage *ru_r)
+{
+       if (getrusage(RUSAGE_SELF, ru_r) < 0)
+               i_fatal("getrusage() failed: %m");
+}
+
 static struct event *
 event_create_internal(struct event *parent, const char *source_filename,
                      unsigned int source_linenum);
@@ -987,6 +993,16 @@ void event_vsend(struct event *event, struct failure_context *ctx,
                 const char *fmt, va_list args)
 {
        i_gettimeofday(&event->tv_last_sent);
+
+       /* Skip adding user_cpu_usecs if not enabled. */
+       if (event->ru_last.ru_utime.tv_sec != 0 ||
+           event->ru_last.ru_utime.tv_usec != 0) {
+               struct rusage ru_current;
+               get_self_rusage(&ru_current);
+               long long udiff = timeval_diff_usecs(&ru_current.ru_utime,
+                                                    &event->ru_last.ru_utime);
+               event_add_int(event, "user_cpu_usecs", udiff > 0 ? udiff : 0);
+       }
        if (event_call_callbacks(event, EVENT_CALLBACK_TYPE_SEND,
                                 ctx, fmt, args)) {
                if (ctx->type != LOG_TYPE_DEBUG ||
@@ -1383,6 +1399,11 @@ const struct event_passthrough event_passthrough_vfuncs = {
        event_passthrough_event,
 };
 
+void event_enable_user_cpu_usecs(struct event *event)
+{
+       get_self_rusage(&event->ru_last);
+}
+
 void lib_event_init(void)
 {
        i_array_init(&event_handlers, 4);
index 0c601370614b72caf2c3c70911c1946928c2829e..2c6ab2bbcf57c4f941f742384dd95e224dc7de91 100644 (file)
@@ -333,6 +333,12 @@ bool event_import_unescaped(struct event *event, const char *const *args,
    need to be called. */
 void event_send_abort(struct event *event);
 
+/* Enable "user_cpu_usecs" event field to event by getting current resource
+   usage which will be used in consequent event_send() to calculate
+   cpu time. This function can be called multiple times to update the current
+   resource usage. */
+void event_enable_user_cpu_usecs(struct event *event);
+
 void lib_event_init(void);
 void lib_event_deinit(void);