summaryrefslogtreecommitdiffstats
path: root/src/plugins/old-stats/mail-stats.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/old-stats/mail-stats.c')
-rw-r--r--src/plugins/old-stats/mail-stats.c168
1 files changed, 168 insertions, 0 deletions
diff --git a/src/plugins/old-stats/mail-stats.c b/src/plugins/old-stats/mail-stats.c
new file mode 100644
index 0000000..3662d23
--- /dev/null
+++ b/src/plugins/old-stats/mail-stats.c
@@ -0,0 +1,168 @@
+/* Copyright (c) 2011-2018 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "time-util.h"
+#include "stats.h"
+#include "stats-parser.h"
+#include "mail-stats.h"
+
+static struct stats_parser_field mail_stats_fields[] = {
+#define E(parsename, name, type) { parsename, offsetof(struct mail_stats, name), sizeof(((struct mail_stats *)0)->name), type }
+#define EN(parsename, name) E(parsename, name, STATS_PARSER_TYPE_UINT)
+ E("user_cpu", user_cpu, STATS_PARSER_TYPE_TIMEVAL),
+ E("sys_cpu", sys_cpu, STATS_PARSER_TYPE_TIMEVAL),
+ E("clock_time", clock_time, STATS_PARSER_TYPE_TIMEVAL),
+ EN("min_faults", min_faults),
+ EN("maj_faults", maj_faults),
+ EN("vol_cs", vol_cs),
+ EN("invol_cs", invol_cs),
+ EN("disk_input", disk_input),
+ EN("disk_output", disk_output),
+
+ EN("read_count", read_count),
+ EN("read_bytes", read_bytes),
+ EN("write_count", write_count),
+ EN("write_bytes", write_bytes),
+
+ /*EN("mopen", trans_stats.open_lookup_count),
+ EN("mstat", trans_stats.stat_lookup_count),
+ EN("mfstat", trans_stats.fstat_lookup_count),*/
+ EN("mail_lookup_path", trans_lookup_path),
+ EN("mail_lookup_attr", trans_lookup_attr),
+ EN("mail_read_count", trans_files_read_count),
+ EN("mail_read_bytes", trans_files_read_bytes),
+ EN("mail_cache_hits", trans_cache_hit_count)
+};
+
+static size_t mail_stats_alloc_size(void)
+{
+ return sizeof(struct mail_stats);
+}
+
+static unsigned int mail_stats_field_count(void)
+{
+ return N_ELEMENTS(mail_stats_fields);
+}
+
+static const char *mail_stats_field_name(unsigned int n)
+{
+ i_assert(n < N_ELEMENTS(mail_stats_fields));
+
+ return mail_stats_fields[n].name;
+}
+
+static void
+mail_stats_field_value(string_t *str, const struct stats *stats,
+ unsigned int n)
+{
+ i_assert(n < N_ELEMENTS(mail_stats_fields));
+
+ stats_parser_value(str, &mail_stats_fields[n], stats);
+}
+
+static bool
+mail_stats_diff(const struct stats *stats1, const struct stats *stats2,
+ struct stats *diff_stats_r, const char **error_r)
+{
+ return stats_parser_diff(mail_stats_fields, N_ELEMENTS(mail_stats_fields),
+ stats1, stats2, diff_stats_r, error_r);
+}
+
+static void mail_stats_add(struct stats *dest, const struct stats *src)
+{
+ stats_parser_add(mail_stats_fields, N_ELEMENTS(mail_stats_fields),
+ dest, src);
+}
+
+static bool
+mail_stats_have_changed(const struct stats *_prev, const struct stats *_cur)
+{
+ const struct mail_stats *prev = (const struct mail_stats *)_prev;
+ const struct mail_stats *cur = (const struct mail_stats *)_cur;
+
+ if (cur->disk_input != prev->disk_input ||
+ cur->disk_output != prev->disk_output ||
+ cur->trans_lookup_path != prev->trans_lookup_path ||
+ cur->trans_lookup_attr != prev->trans_lookup_attr ||
+ cur->trans_files_read_count != prev->trans_files_read_count ||
+ cur->trans_files_read_bytes != prev->trans_files_read_bytes ||
+ cur->trans_cache_hit_count != prev->trans_cache_hit_count)
+ return TRUE;
+
+ /* allow a tiny bit of changes that are caused by this
+ timeout handling */
+ if (timeval_diff_msecs(&cur->user_cpu, &prev->user_cpu) != 0)
+ return TRUE;
+ if (timeval_diff_msecs(&cur->sys_cpu, &prev->sys_cpu) != 0)
+ return TRUE;
+
+ if (cur->maj_faults > prev->maj_faults+10)
+ return TRUE;
+ if (cur->invol_cs > prev->invol_cs+10)
+ return TRUE;
+ /* don't check for read/write count/bytes changes, since they get
+ changed by stats checking itself */
+ return FALSE;
+}
+
+static void mail_stats_export(buffer_t *buf, const struct stats *_stats)
+{
+ const struct mail_stats *stats = (const struct mail_stats *)_stats;
+
+ buffer_append(buf, stats, sizeof(*stats));
+}
+
+static bool
+mail_stats_import(const unsigned char *data, size_t size, size_t *pos_r,
+ struct stats *_stats, const char **error_r)
+{
+ struct mail_stats *stats = (struct mail_stats *)_stats;
+
+ if (size < sizeof(*stats)) {
+ *error_r = "mail_stats too small";
+ return FALSE;
+ }
+ memcpy(stats, data, sizeof(*stats));
+ *pos_r = sizeof(*stats);
+ return TRUE;
+}
+
+void mail_stats_add_transaction(struct mail_stats *stats,
+ const struct mailbox_transaction_stats *trans_stats)
+{
+ stats->trans_lookup_path += trans_stats->open_lookup_count;
+ stats->trans_lookup_attr += trans_stats->stat_lookup_count +
+ trans_stats->fstat_lookup_count;
+ stats->trans_files_read_count += trans_stats->files_read_count;
+ stats->trans_files_read_bytes += trans_stats->files_read_bytes;
+ stats->trans_cache_hit_count += trans_stats->cache_hit_count;
+}
+
+const struct stats_vfuncs mail_stats_vfuncs = {
+ "mail",
+ mail_stats_alloc_size,
+ mail_stats_field_count,
+ mail_stats_field_name,
+ mail_stats_field_value,
+ mail_stats_diff,
+ mail_stats_add,
+ mail_stats_have_changed,
+ mail_stats_export,
+ mail_stats_import
+};
+
+/* for the stats_mail plugin: */
+void old_stats_mail_init(void);
+void old_stats_mail_deinit(void);
+
+static struct stats_item *mail_stats_item;
+
+void old_stats_mail_init(void)
+{
+ mail_stats_item = stats_register(&mail_stats_vfuncs);
+}
+
+void old_stats_mail_deinit(void)
+{
+ stats_unregister(&mail_stats_item);
+}