stats-plugin.c revision 71748cca1bacd74451fd228db5536828bdfeb190
/* Copyright (c) 2011-2016 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "ioloop.h"
#include "llist.h"
#include "str.h"
#include "time-util.h"
#include "settings-parser.h"
#include "mail-stats.h"
#include "stats.h"
#include "mail-stats-connection.h"
#include "stats-plugin.h"
#define STATS_CONTEXT(obj) \
/* If session isn't refreshed every 15 minutes, it's dropped.
Must be smaller than MAIL_SESSION_IDLE_TIMEOUT_MSECS in stats server */
#define REFRESH_CHECK_INTERVAL 100
#define MAIL_STATS_FIFO_NAME "stats-mail"
struct stats_storage {
struct mail_storage_callbacks old_callbacks;
void *old_context;
};
struct stats_mailbox {
union mailbox_module_context module_ctx;
};
const char *stats_plugin_version = DOVECOT_ABI_VERSION;
struct stats_user_module stats_user_module =
struct stats_storage_module stats_storage_module =
static struct stats_item *mail_stats_item;
static unsigned int stats_user_count = 0;
{
struct mail_stats *mail_stats;
if (stats_user_count == 1) {
/* the first user sets the global user. the second user sets
it to NULL. when we get back to one user we'll need to set
the global user again somewhere. do it here. */
/* skip time spent waiting in ioloop */
} else {
}
}
{
const char *error;
/* we'll count new_stats-pre_io_stats and add the changes to
session_stats. the new_stats can't be directly copied to
session_stats because there are some fields that don't start from
zero, like clock_time. (actually with stats_global_user code we're
requiring that clock_time is the only such field..) */
/* copying is only needed if stats_global_user=NULL */
}
static bool
bool *changed_r, unsigned int *to_next_secs_r)
{
unsigned int diff;
suser->session_stats)) {
return TRUE;
}
if (diff >= SESSION_STATS_FORCE_REFRESH_SECS)
return TRUE;
if (!suser->session_sent_duplicate) {
/* send one duplicate notification so stats reader
knows that this session is idle now */
return TRUE;
}
}
return FALSE;
}
{
unsigned int to_next_secs;
bool changed;
}
}
static struct mailbox_transaction_context *
{
struct mailbox_transaction_context *trans;
struct stats_transaction_context *strans;
return trans;
}
struct stats_transaction_context *strans)
{
struct mailbox_transaction_stats *dest =
}
static int
struct mail_transaction_commit_changes *changes_r)
{
}
static void
{
}
{
bool ret;
if (!ret && !*tryagain_r) {
/* end of search */
return FALSE;
}
if (*tryagain_r ||
/* a) retrying, so this is a long running search.
b) we've returned enough matches */
}
return ret;
}
static void
{
/* most importantly we want to refresh stats for very long running
mailbox syncs */
}
{
return;
}
{
struct stats_mailbox *sbox;
return;
}
{
if (stats_global_user != NULL)
}
{
unsigned int last_update_secs;
if (stats_global_user == NULL)
if (stats_global_user != NULL)
}
}
{
struct mail_stats *mail_stats;
}
{
i_assert(stats_user_count > 0);
if (stats_global_user != NULL) {
/* we were updating the session lazily. do one final update. */
}
/* send final stats before disconnection */
}
{
struct ioloop_context *ioloop_ctx =
struct stats_user *suser;
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 */
return;
return;
}
if (refresh_secs == 0)
return;
i_warning("stats: stats_refresh too large, changing to %u",
}
if (global_stats_conn == NULL) {
if (path[0] != '/')
}
if (stats_user_count == 0) {
/* first user connection */
} 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) {
}
}
v->deinit = stats_user_deinit;
else {
}
/* 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. */
}
static struct mail_storage_hooks stats_mail_storage_hooks = {
};
{
}
void stats_plugin_deinit(void)
{
if (global_stats_conn != NULL)
}