static void stats_user_created(struct mail_user *user) { struct ioloop_context *ioloop_ctx = io_loop_get_current_context(current_ioloop); struct stats_user *suser; struct mail_user_vfuncs *v = user->vlast; const char *path, *str, *error; unsigned int refresh_secs; if (ioloop_ctx == NULL) { /* we're probably running some test program, or at least mail-storage-service wasn't used to create this user. disable stats tracking. */ return; } if (user->autocreated) { /* lda / shared user. we're not tracking this one. */ return; } /* get refresh time */ str = mail_user_plugin_getenv(user, "stats_refresh"); if (str == NULL) return; if (settings_get_time(str, &refresh_secs, &error) < 0) { i_error("stats: Invalid stats_refresh setting: %s", error); return; } if (refresh_secs == 0) return; if (refresh_secs > SESSION_STATS_FORCE_REFRESH_SECS) { i_warning("stats: stats_refresh too large, changing to %u", SESSION_STATS_FORCE_REFRESH_SECS); refresh_secs = SESSION_STATS_FORCE_REFRESH_SECS; } if (global_stats_conn == NULL) { path = t_strconcat(user->set->base_dir, "/"MAIL_STATS_SOCKET_NAME, NULL); global_stats_conn = stats_connection_create(path); } stats_connection_ref(global_stats_conn); if (stats_user_count == 0) { /* first user connection */ stats_global_user = user; } else if (stats_user_count == 1) { /* second user connection. we'll need to start doing per-io callback tracking now. (we might have been doing it also previously but just temporarily quickly dropped to having 1 user, in which case stats_global_user=NULL) */ if (stats_global_user != NULL) { stats_add_session(stats_global_user); stats_global_user = NULL; } } stats_user_count++; suser = p_new(user->pool, struct stats_user, 1); suser->module_ctx.super = *v; user->vlast = &suser->module_ctx.super; v->deinit = stats_user_deinit; v->stats_fill = stats_user_stats_fill; suser->refresh_secs = refresh_secs; str = mail_user_plugin_getenv(user, "stats_track_cmds"); if (str != NULL && strcmp(str, "yes") == 0) suser->track_commands = TRUE; suser->stats_conn = global_stats_conn; if (user->session_id != NULL && user->session_id[0] != '\0') suser->stats_session_id = user->session_id; else { guid_128_t guid; guid_128_generate(guid); suser->stats_session_id = p_strdup(user->pool, guid_128_to_string(guid)); } suser->last_session_update = time(NULL); user->stats_enabled = TRUE; suser->ioloop_ctx = ioloop_ctx; io_loop_context_add_callbacks(ioloop_ctx, stats_io_activate, stats_io_deactivate, user); suser->pre_io_stats = stats_alloc(user->pool); suser->session_stats = stats_alloc(user->pool); suser->last_sent_session_stats = stats_alloc(user->pool); MODULE_CONTEXT_SET(user, stats_user_module, suser); mail_stats_connection_connect(suser->stats_conn, user); suser->to_stats_timeout = timeout_add(suser->refresh_secs*1000, session_stats_refresh_timeout, user); /* fill the initial values. this is necessary for the process-global values (e.g. getrusage()) if the process is reused for multiple users. otherwise the next user will start with the previous one's last values. */ mail_user_stats_fill(user, suser->pre_io_stats); }
static void stats_user_created(struct mail_user *user) { struct ioloop_context *ioloop_ctx = io_loop_get_current_context(current_ioloop); struct stats_user *suser; struct mail_user_vfuncs *v = user->vlast; const char *path, *str, *error; unsigned int refresh_secs; if (ioloop_ctx == NULL) { /* we're probably running some test program, or at least mail-storage-service wasn't used to create this user. disable stats tracking. */ return; } if (user->autocreated) { /* lda / shared user. we're not tracking this one. */ return; } /* get refresh time */ str = mail_user_plugin_getenv(user, "stats_refresh"); if (str == NULL) return; if (settings_get_time(str, &refresh_secs, &error) < 0) { i_error("stats: Invalid stats_refresh setting: %s", error); return; } if (refresh_secs == 0) return; if (global_stats_conn == NULL) { path = t_strconcat(user->set->base_dir, "/"MAIL_STATS_SOCKET_NAME, NULL); global_stats_conn = stats_connection_create(path); } stats_connection_ref(global_stats_conn); if (stats_user_count == 0) { /* first user connection */ stats_global_user = user; } else if (stats_user_count == 1) { /* second user connection. we'll need to start doing per-io callback tracking now. (we might have been doing it also previously but just temporarily quickly dropped to having 1 user, in which case stats_global_user=NULL) */ if (stats_global_user != NULL) { stats_add_session(stats_global_user); stats_global_user = NULL; } } stats_user_count++; suser = p_new(user->pool, struct stats_user, 1); suser->module_ctx.super = *v; user->vlast = &suser->module_ctx.super; v->deinit = stats_user_deinit; suser->refresh_secs = refresh_secs; str = mail_user_plugin_getenv(user, "stats_track_cmds"); if (str != NULL && strcmp(str, "yes") == 0) suser->track_commands = TRUE; suser->stats_conn = global_stats_conn; guid_128_generate(suser->session_guid); suser->last_session_update = time(NULL); suser->ioloop_ctx = ioloop_ctx; io_loop_context_add_callbacks(ioloop_ctx, stats_io_activate, stats_io_deactivate, user); MODULE_CONTEXT_SET(user, stats_user_module, suser); stats_connection_connect(suser->stats_conn, user); }