dovecot-2.1: stats: Track [rw]char and sysc[rw] fields in /proc/...

dovecot at dovecot.org dovecot at dovecot.org
Mon Sep 12 18:29:26 EEST 2011


details:   http://hg.dovecot.org/dovecot-2.1/rev/835891cf2eef
changeset: 13457:835891cf2eef
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Sep 12 18:29:17 2011 +0300
description:
stats: Track [rw]char and sysc[rw] fields in /proc/self/io (with Linux).

diffstat:

 src/plugins/stats/stats-plugin.c |  77 ++++++++++++++++++++++++++++++++++++++++
 src/plugins/stats/stats-plugin.h |   3 +
 src/stats/client-export.c        |   4 ++
 src/stats/mail-stats.c           |   5 ++
 src/stats/mail-stats.h           |   3 +
 5 files changed, 92 insertions(+), 0 deletions(-)

diffs (177 lines):

diff -r b1870cf2d3ff -r 835891cf2eef src/plugins/stats/stats-plugin.c
--- a/src/plugins/stats/stats-plugin.c	Mon Sep 12 18:26:29 2011 +0300
+++ b/src/plugins/stats/stats-plugin.c	Mon Sep 12 18:29:17 2011 +0300
@@ -81,6 +81,70 @@
 		trans_stats_add(dest_r, &strans->trans->stats);
 }
 
+static int
+process_io_buffer_parse(const char *buf, struct mail_stats *stats)
+{
+	const char *const *tmp;
+
+	tmp = t_strsplit(buf, "\n");
+	for (; *tmp != NULL; tmp++) {
+		if (strncmp(*tmp, "rchar: ", 7) == 0) {
+			if (str_to_uint64(*tmp + 7, &stats->read_bytes) < 0)
+				return -1;
+		} else if (strncmp(*tmp, "wchar: ", 7) == 0) {
+			if (str_to_uint64(*tmp + 7, &stats->write_bytes) < 0)
+				return -1;
+		} else if (strncmp(*tmp, "syscr: ", 7) == 0) {
+			if (str_to_uint32(*tmp + 7, &stats->read_count) < 0)
+				return -1;
+		} else if (strncmp(*tmp, "syscw: ", 7) == 0) {
+			if (str_to_uint32(*tmp + 7, &stats->write_count) < 0)
+				return -1;
+		}
+	}
+	return 0;
+}
+
+static void process_read_io_stats(struct mail_stats *stats)
+{
+	const char *path = "/proc/self/io";
+	static bool io_disabled = FALSE;
+	char buf[1024];
+	int fd, ret;
+
+	if (io_disabled)
+		return;
+
+	fd = open(path, O_RDONLY);
+	if (fd == -1) {
+		if (errno != ENOENT)
+			i_error("open(%s) failed: %m", path);
+		io_disabled = TRUE;
+		return;
+	}
+	ret = read(fd, buf, sizeof(buf));
+	if (ret <= 0) {
+		if (ret == -1)
+			i_error("read(%s) failed: %m", path);
+		else
+			i_error("read(%s) returned EOF", path);
+	} else if (ret == sizeof(buf)) {
+		/* just shouldn't happen.. */
+		i_error("%s is larger than expected", path);
+		io_disabled = TRUE;
+	} else {
+		buf[ret] = '\0';
+		T_BEGIN {
+			if (process_io_buffer_parse(buf, stats) < 0) {
+				i_error("Invalid input in file %s", path);
+				io_disabled = TRUE;
+			}
+		} T_END;
+	}
+	if (close(fd) < 0)
+		i_error("close(%s) failed: %m", path);
+}
+
 void mail_stats_get(struct stats_user *suser, struct mail_stats *stats_r)
 {
 	struct rusage usage;
@@ -97,6 +161,7 @@
 	stats_r->invol_cs = usage.ru_nivcsw;
 	stats_r->disk_input = (unsigned long long)usage.ru_inblock * 512ULL;
 	stats_r->disk_output = (unsigned long long)usage.ru_oublock * 512ULL;
+	process_read_io_stats(stats_r);
 	user_trans_stats_get(suser, &stats_r->trans_stats);
 }
 
@@ -213,6 +278,10 @@
 	dest->maj_faults += new_stats->maj_faults - old_stats->maj_faults;
 	dest->vol_cs += new_stats->vol_cs - old_stats->vol_cs;
 	dest->invol_cs += new_stats->invol_cs - old_stats->invol_cs;
+	dest->read_count += new_stats->read_count - old_stats->read_count;
+	dest->write_count += new_stats->write_count - old_stats->write_count;
+	dest->read_bytes += new_stats->read_bytes - old_stats->read_bytes;
+	dest->write_bytes += new_stats->write_bytes - old_stats->write_bytes;
 
 	timeval_add_diff(&dest->user_cpu, &new_stats->user_cpu,
 			 &old_stats->user_cpu);
@@ -238,6 +307,12 @@
 		    (unsigned long long)stats->disk_input);
 	str_printfa(str, "\tdiskout=%llu",
 		    (unsigned long long)stats->disk_output);
+	str_printfa(str, "\trchar=%llu",
+		    (unsigned long long)stats->read_bytes);
+	str_printfa(str, "\twchar=%llu",
+		    (unsigned long long)stats->write_bytes);
+	str_printfa(str, "\tsyscr=%u", stats->read_count);
+	str_printfa(str, "\tsyscw=%u", stats->write_count);
 	str_printfa(str, "\tmlpath=%lu",
 		    tstats->open_lookup_count + tstats->stat_lookup_count);
 	str_printfa(str, "\tmlattr=%lu",
@@ -278,6 +353,8 @@
 		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;
 }
 
diff -r b1870cf2d3ff -r 835891cf2eef src/plugins/stats/stats-plugin.h
--- a/src/plugins/stats/stats-plugin.h	Mon Sep 12 18:26:29 2011 +0300
+++ b/src/plugins/stats/stats-plugin.h	Mon Sep 12 18:29:17 2011 +0300
@@ -18,6 +18,9 @@
 	uint32_t vol_cs, invol_cs;
 	/* disk input/output bytes */
 	uint64_t disk_input, disk_output;
+	/* read()/write() syscall count and number of bytes */
+	uint32_t read_count, write_count;
+	uint64_t read_bytes, write_bytes;
 	struct mailbox_transaction_stats trans_stats;
 };
 
diff -r b1870cf2d3ff -r 835891cf2eef src/stats/client-export.c
--- a/src/stats/client-export.c	Mon Sep 12 18:26:29 2011 +0300
+++ b/src/stats/client-export.c	Mon Sep 12 18:29:17 2011 +0300
@@ -100,6 +100,7 @@
 #define MAIL_STATS_HEADER "\tuser_cpu\tsys_cpu" \
 	"\tmin_faults\tmaj_faults\tvol_cs\tinvol_cs" \
 	"\tdisk_input\tdisk_output" \
+	"\tread_count\tread_bytes\twrite_count\twrite_bytes" \
 	"\tmail_lookup_path\tmail_lookup_attr" \
 	"\tmail_read_count\tmail_read_bytes\tmail_cache_hits\n"
 
@@ -112,6 +113,9 @@
 	str_printfa(str, "\t%llu\t%llu",
 		    (unsigned long long)stats->disk_input,
 		    (unsigned long long)stats->disk_output);
+	str_printfa(str, "\t%u\t%llu\t%u\t%llu",
+		    stats->read_count, (unsigned long long)stats->read_bytes,
+		    stats->write_count, (unsigned long long)stats->write_bytes);
 	str_printfa(str, "\t%u\t%u\t%u\t%llu\t%u",
 		    stats->mail_lookup_path, stats->mail_lookup_attr,
 		    stats->mail_read_count,
diff -r b1870cf2d3ff -r 835891cf2eef src/stats/mail-stats.c
--- a/src/stats/mail-stats.c	Mon Sep 12 18:26:29 2011 +0300
+++ b/src/stats/mail-stats.c	Mon Sep 12 18:29:17 2011 +0300
@@ -26,6 +26,11 @@
 	EN("diskin", disk_input),
 	EN("diskout", disk_output),
 
+	EN("rchar", read_bytes),
+	EN("wchar", write_bytes),
+	EN("syscr", read_count),
+	EN("syscw", write_count),
+
 	EN("mlpath", mail_lookup_path),
 	EN("mlattr", mail_lookup_attr),
 	EN("mrcount", mail_read_count),
diff -r b1870cf2d3ff -r 835891cf2eef src/stats/mail-stats.h
--- a/src/stats/mail-stats.h	Mon Sep 12 18:26:29 2011 +0300
+++ b/src/stats/mail-stats.h	Mon Sep 12 18:29:17 2011 +0300
@@ -10,6 +10,9 @@
 	uint32_t vol_cs, invol_cs;
 	uint64_t disk_input, disk_output;
 
+	uint32_t read_count, write_count;
+	uint64_t read_bytes, write_bytes;
+
 	uint32_t mail_lookup_path, mail_lookup_attr, mail_read_count;
 	uint32_t mail_cache_hits;
 	uint64_t mail_read_bytes;


More information about the dovecot-cvs mailing list