MAIL_EXPORT_LEVEL_SESSION,
MAIL_EXPORT_LEVEL_USER,
MAIL_EXPORT_LEVEL_DOMAIN,
- MAIL_EXPORT_LEVEL_IP
+ MAIL_EXPORT_LEVEL_IP,
+ MAIL_EXPORT_LEVEL_GLOBAL
};
static const char *mail_export_level_names[] = {
- "command", "session", "user", "domain", "ip"
+ "command", "session", "user", "domain", "ip", "global"
};
struct mail_export_filter {
return 1;
}
+static int client_export_iter_global(struct client *client)
+{
+ struct client_export_cmd *cmd = client->cmd_export;
+ struct mail_global *g = &mail_global_stats;
+
+ i_assert(cmd->level == MAIL_EXPORT_LEVEL_GLOBAL);
+
+ if (!cmd->header_sent) {
+ o_stream_nsend_str(client->output,
+ "reset_timestamp\tlast_update"
+ "\tnum_logins\tnum_cmds\tnum_connected_sessions"MAIL_STATS_HEADER);
+ cmd->header_sent = TRUE;
+ }
+
+ str_truncate(cmd->str, 0);
+ str_printfa(cmd->str, "\t%ld", (long)g->reset_timestamp);
+ client_export_timeval(cmd->str, &g->last_update);
+ str_printfa(cmd->str, "\t%u\t%u\t%u",
+ g->num_logins, g->num_cmds, g->num_connected_sessions);
+ client_export_mail_stats(cmd->str, &g->stats);
+ str_append_c(cmd->str, '\n');
+ o_stream_nsend(client->output, str_data(cmd->str),
+ str_len(cmd->str));
+ return 1;
+}
+
static int client_export_more(struct client *client)
{
if (client->cmd_export->export_iter(client) == 0)
mail_ip_ref(client->mail_ip_iter);
cmd->export_iter = client_export_iter_ip;
break;
+ case MAIL_EXPORT_LEVEL_GLOBAL:
+ cmd->export_iter = client_export_iter_global;
+ break;
}
i_assert(cmd->export_iter != NULL);
return TRUE;
{
domain->num_logins++;
domain->num_connected_sessions++;
+ mail_global_login();
mail_domain_refresh(domain, NULL);
}
{
i_assert(domain->num_connected_sessions > 0);
domain->num_connected_sessions--;
+ mail_global_disconnected();
}
struct mail_domain *mail_domain_lookup(const char *name)
sorted_prev, sorted_next);
DLLIST2_APPEND_FULL(&mail_domains_head, &mail_domains_tail, domain,
sorted_prev, sorted_next);
+ mail_global_refresh(diff_stats);
}
void mail_domains_free_memory(void)
/* Copyright (c) 2011-2014 Dovecot authors, see the included COPYING file */
#include "lib.h"
+#include "ioloop.h"
#include "time-util.h"
#include "mail-stats.h"
EN("mcache", mail_cache_hits)
};
+struct mail_global mail_global_stats;
+
static int mail_stats_parse_timeval(const char *value, struct timeval *tv)
{
const char *p, *secs_str;
}
}
}
+
+void mail_global_init(void)
+{
+ mail_global_stats.reset_timestamp = ioloop_time;
+}
+
+void mail_global_login(void)
+{
+ mail_global_stats.num_logins++;
+ mail_global_stats.num_connected_sessions++;
+}
+
+void mail_global_disconnected(void)
+{
+ i_assert(mail_global_stats.num_connected_sessions > 0);
+ mail_global_stats.num_connected_sessions--;
+}
+
+void mail_global_refresh(const struct mail_stats *diff_stats)
+{
+ if (diff_stats != NULL)
+ mail_stats_add(&mail_global_stats.stats, diff_stats);
+ mail_global_stats.last_update = ioloop_timeval;
+}
struct mail_session *sessions;
};
+struct mail_global {
+ time_t reset_timestamp;
+
+ struct timeval last_update;
+ struct mail_stats stats;
+ unsigned int num_logins;
+ unsigned int num_cmds;
+ unsigned int num_connected_sessions;
+};
+
+extern struct mail_global mail_global_stats;
+
int mail_stats_parse(const char *const *args, struct mail_stats *stats_r,
const char **error_r);
/* diff1 is supposed to have smaller values than diff2. Returns TRUE if this
struct mail_stats *diff_stats_r, const char **error_r);
void mail_stats_add(struct mail_stats *dest, const struct mail_stats *src);
+void mail_global_init(void);
+void mail_global_login(void);
+void mail_global_disconnected(void);
+void mail_global_refresh(const struct mail_stats *diff_stats);
+
#endif
#include "mail-user.h"
#include "mail-domain.h"
#include "mail-ip.h"
+#include "mail-stats.h"
#include "client.h"
static struct mail_server_connection *mail_server_conn = NULL;
mail_users_init();
mail_domains_init();
mail_ips_init();
+ mail_global_init();
master_service_init_finish(master_service);
master_service_run(master_service, client_connected);