Mercurial > dovecot > core-2.2
view src/plugins/imap-stats/imap-stats-plugin.c @ 13294:c51fbe64eae1
Initial implementation of statistics gathering daemon and plugins to feed it.
Some statistics are still missing, some of the code is a bit ugly and the
internal protocols will probably still change.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 26 Aug 2011 05:15:12 +0300 |
parents | |
children | ec6d171a54bd |
line wrap: on
line source
/* Copyright (c) 2011 Dovecot authors, see the included COPYING file */ #include "imap-common.h" #include "str.h" #include "imap-commands.h" #include "stats-plugin.h" #include "stats-connection.h" #include "imap-stats-plugin.h" #define IMAP_STATS_IMAP_CONTEXT(obj) \ MODULE_CONTEXT(obj, imap_stats_imap_module) struct stats_client_command { union imap_module_context module_ctx; unsigned int id; bool continued; struct mail_stats stats, pre_stats; struct mailbox_transaction_stats pre_trans_stats; }; static MODULE_CONTEXT_DEFINE_INIT(imap_stats_imap_module, &imap_module_register); const char *imap_stats_plugin_version = DOVECOT_VERSION; static void stats_command_pre(struct client_command_context *cmd) { struct stats_user *suser = STATS_USER_CONTEXT(cmd->client->user); struct stats_client_command *scmd; static unsigned int stats_cmd_id_counter = 0; if (suser == NULL) return; scmd = IMAP_STATS_IMAP_CONTEXT(cmd); if (scmd == NULL) { scmd = p_new(cmd->pool, struct stats_client_command, 1); scmd->id = ++stats_cmd_id_counter; MODULE_CONTEXT_SET(cmd, imap_stats_imap_module, scmd); } mail_stats_get(suser, &scmd->pre_stats); scmd->pre_trans_stats = suser->session_stats.trans_stats; } static void stats_command_post(struct client_command_context *cmd) { struct stats_user *suser = STATS_USER_CONTEXT(cmd->client->user); struct stats_client_command *scmd = IMAP_STATS_IMAP_CONTEXT(cmd); struct mail_stats stats, pre_trans_stats, trans_stats; unsigned int args_pos = 0; string_t *str; bool done; if (scmd == NULL) return; mail_stats_get(suser, &stats); mail_stats_add_diff(&scmd->stats, &scmd->pre_stats, &stats); /* mail_stats_get() can't see the transactions that already went away, so we'll need to use the session's stats difference */ memset(&pre_trans_stats, 0, sizeof(pre_trans_stats)); memset(&trans_stats, 0, sizeof(trans_stats)); pre_trans_stats.trans_stats = scmd->pre_trans_stats; trans_stats.trans_stats = suser->session_stats.trans_stats; mail_stats_add_diff(&scmd->stats, &pre_trans_stats, &trans_stats); str = t_str_new(128); str_append(str, "UPDATE-CMD\t"); str_append(str, guid_128_to_string(suser->session_guid)); done = cmd->state == CLIENT_COMMAND_STATE_DONE; str_printfa(str, "\t%u\t%d\t", scmd->id, done); if (scmd->continued) str_append_c(str, '\t'); else { str_append(str, cmd->name); str_append_c(str, '\t'); args_pos = str_len(str); if (cmd->args != NULL) str_append(str, cmd->args); scmd->continued = TRUE; } mail_stats_export(str, &scmd->stats); str_append_c(str, '\n'); if (str_len(str) > PIPE_BUF) { /* truncate the args so it fits */ i_assert(args_pos != 0); str_delete(str, args_pos, str_len(str) - PIPE_BUF); i_assert(str_len(str) == PIPE_BUF); } stats_connection_send(suser->stats_conn, str); } void imap_stats_plugin_init(struct module *module ATTR_UNUSED) { command_hook_register(stats_command_pre, stats_command_post); } void imap_stats_plugin_deinit(void) { command_hook_unregister(stats_command_pre, stats_command_post); } const char *imap_stats_plugin_dependencies[] = { "stats", NULL }; const char imap_stats_plugin_binary_dependency[] = "imap";