changeset 13295:34e2190a56c6

doveadm: Added initial implementation of "stats top" command.
author Timo Sirainen <tss@iki.fi>
date Fri, 26 Aug 2011 05:15:42 +0300
parents c51fbe64eae1
children dc5f038da30f
files src/doveadm/Makefile.am src/doveadm/doveadm-stats.c src/doveadm/doveadm.c src/doveadm/doveadm.h
diffstat 4 files changed, 99 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/doveadm/Makefile.am	Fri Aug 26 05:15:12 2011 +0300
+++ b/src/doveadm/Makefile.am	Fri Aug 26 05:15:42 2011 +0300
@@ -98,6 +98,7 @@
 	doveadm-proxy.c \
 	doveadm-pw.c \
 	doveadm-sis.c \
+	doveadm-stats.c \
 	doveadm-who.c
 
 doveadm_server_SOURCES = \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/doveadm/doveadm-stats.c	Fri Aug 26 05:15:42 2011 +0300
@@ -0,0 +1,95 @@
+/* Copyright (c) 2011 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "network.h"
+#include "istream.h"
+#include "str.h"
+#include "strescape.h"
+#include "doveadm.h"
+#include "doveadm-print.h"
+
+#include <unistd.h>
+
+static const char *const*
+read_next_line(struct istream *input)
+{
+	const char *line;
+	char **args;
+	unsigned int i;
+
+	line = i_stream_read_next_line(input);
+	if (line == NULL)
+		return NULL;
+
+	args = p_strsplit(pool_datastack_create(), line, "\t");
+	for (i = 0; args[i] != NULL; i++)
+		args[i] = str_tabunescape(args[i]);
+	return (void *)args;
+}
+
+static void stats_lookup(const char *path)
+{
+#define TOP_CMD "EXPORT\tsession\tconnected\n"
+	struct istream *input;
+	const char *const *args;
+	unsigned int i;
+	int fd;
+
+	fd = doveadm_connect(path);
+	net_set_nonblock(fd, FALSE);
+
+	input = i_stream_create_fd(fd, (size_t)-1, TRUE);
+	if (write(fd, TOP_CMD, strlen(TOP_CMD)) < 0)
+		i_fatal("write(%s) failed: %m", path);
+
+	/* read header */
+	args = read_next_line(input);
+	if (args == NULL)
+		i_fatal("read(%s) unexpectedly disconnected", path);
+	for (; *args != NULL; args++)
+		doveadm_print_header_simple(*args);
+
+	/* read lines */
+	do {
+		T_BEGIN {
+			args = read_next_line(input);
+			if (args[0] == NULL)
+				args = NULL;
+			if (args != NULL) {
+				for (i = 0; args[i] != NULL; i++)
+					doveadm_print(args[i]);
+			}
+		} T_END;
+	} while (args != NULL);
+	if (input->stream_errno != 0)
+		i_fatal("read(%s) failed: %m", path);
+	i_stream_destroy(&input);
+}
+
+static void cmd_stats_top(int argc, char *argv[])
+{
+	const char *path;
+	int c;
+
+	path = t_strconcat(doveadm_settings->base_dir, "/stats", NULL);
+
+	while ((c = getopt(argc, argv, "s:")) > 0) {
+		switch (c) {
+		case 's':
+			path = optarg;
+			break;
+		default:
+			help(&doveadm_cmd_stats);
+		}
+	}
+	argv += optind - 1;
+	if (argv[1] != NULL)
+		help(&doveadm_cmd_stats);
+
+	doveadm_print_init(DOVEADM_PRINT_TYPE_TABLE);
+	stats_lookup(path);
+}
+
+struct doveadm_cmd doveadm_cmd_stats = {
+	cmd_stats_top, "stats top", "[-s <stats socket path>]"
+};
--- a/src/doveadm/doveadm.c	Fri Aug 26 05:15:12 2011 +0300
+++ b/src/doveadm/doveadm.c	Fri Aug 26 05:15:42 2011 +0300
@@ -259,7 +259,8 @@
 	&doveadm_cmd_kick,
 	&doveadm_cmd_mailbox_mutf7,
 	&doveadm_cmd_sis_deduplicate,
-	&doveadm_cmd_sis_find
+	&doveadm_cmd_sis_find,
+	&doveadm_cmd_stats
 };
 
 int main(int argc, char *argv[])
--- a/src/doveadm/doveadm.h	Fri Aug 26 05:15:12 2011 +0300
+++ b/src/doveadm/doveadm.h	Fri Aug 26 05:15:42 2011 +0300
@@ -26,6 +26,7 @@
 extern struct doveadm_cmd doveadm_cmd_mailbox_mutf7;
 extern struct doveadm_cmd doveadm_cmd_sis_deduplicate;
 extern struct doveadm_cmd doveadm_cmd_sis_find;
+extern struct doveadm_cmd doveadm_cmd_stats;
 
 void doveadm_register_cmd(const struct doveadm_cmd *cmd);