Add a stats command to keyd
authorJonathan McDowell <noodles@earth.li>
Sun, 10 Apr 2011 17:47:35 +0000 (10:47 -0700)
committerJonathan McDowell <noodles@earth.li>
Sun, 10 Apr 2011 17:47:35 +0000 (10:47 -0700)
  Add KEYD_CMD_STATS to obtain info about when keyd started, how many
  connects it has seen and how many instances of each command.

keyd.c
keyd.h
keydctl.8
keydctl.c

diff --git a/keyd.c b/keyd.c
index 1a349a600b8d78b836bc7249f444de523b29e8ac..5d5b7ba8c883b68326361f7789bbb228e6ac1593 100644 (file)
--- a/keyd.c
+++ b/keyd.c
@@ -17,6 +17,7 @@
 #include <sys/socket.h>
 #include <sys/types.h>
 #include <sys/un.h>
+#include <time.h>
 #include <unistd.h>
 
 #include "charfuncs.h"
@@ -31,6 +32,8 @@
 #include "parsekey.h"
 #include "version.h"
 
+static struct keyd_stats *stats;
+
 void daemonize(void)
 {
        pid_t pid;
@@ -150,6 +153,11 @@ int sock_do(int fd)
        }
        
        if (ret == 0) {
+               if (cmd < KEYD_CMD_LAST) {
+                       stats->command_stats[cmd]++;
+               } else {
+                       stats->command_stats[KEYD_CMD_UNKNOWN]++;
+               }
                switch (cmd) {
                case KEYD_CMD_VERSION:
                        cmd = KEYD_REPLY_OK;
@@ -341,6 +349,14 @@ int sock_do(int fd)
                        ret = 1;
                        trytocleanup();
                        break;
+               case KEYD_CMD_STATS:
+                       cmd = KEYD_REPLY_OK;
+                       write(fd, &cmd, sizeof(cmd));
+                       cmd = sizeof(*stats);
+                       write(fd, &cmd, sizeof(cmd));
+                       write(fd, stats,
+                               sizeof(*stats));
+                       break;
                default:
                        logthing(LOGTHING_ERROR, "Got unknown command: %d",
                                        cmd);
@@ -372,6 +388,7 @@ int sock_accept(int fd)
        }
 
        if (ret != -1) {
+               stats->connects++;
                while (!sock_do(srv)) ;
                sock_close(srv);
        }
@@ -429,6 +446,15 @@ int main(int argc, char *argv[])
        catchsignals();
        signal(SIGPIPE, SIG_IGN);
 
+
+       stats = calloc(1, sizeof(*stats));
+       if (!stats) {
+               logthing(LOGTHING_ERROR,
+                       "Couldn't allocate memory for stats structure.");
+               exit(EXIT_FAILURE);
+       }
+       stats->started = time(NULL);
+
        snprintf(sockname, 1023, "%s/%s", config.db_dir, KEYD_SOCKET);
        fd = sock_init(sockname);
 
@@ -449,6 +475,8 @@ int main(int argc, char *argv[])
                unlink(sockname);
        }
 
+       free(stats);
+
        cleanuplogthing();
        cleanupconfig();
 
diff --git a/keyd.h b/keyd.h
index 30af955234a7161ff0c28c17cedf6b45f5a36602..ce19d8dd13f0c78fda9911fd8e9456ea627da9a6 100644 (file)
--- a/keyd.h
+++ b/keyd.h
@@ -24,6 +24,7 @@ enum keyd_ops {
        KEYD_CMD_KEYITER,
        KEYD_CMD_CLOSE,
        KEYD_CMD_QUIT,
+       KEYD_CMD_STATS,
        KEYD_CMD_LAST                   /* Placeholder */
 };
 
@@ -34,4 +35,10 @@ enum keyd_reply {
 
 static uint32_t keyd_version = 2;
 
+struct keyd_stats {
+       time_t started;
+       uint32_t connects;
+       uint32_t command_stats[KEYD_CMD_LAST];
+};
+
 #endif /* __KEYD_H__ */
index 44e7ba66d9b34165cf06b5ad5caf5c27b369fb40..425d81e7dbefb3e32003375682848fc24757ce0f 100644 (file)
--- a/keydctl.8
+++ b/keydctl.8
@@ -32,8 +32,9 @@ otherwise. Outputs nothing to stdout/stderr.
 Request that keyd exits cleanly
 .TP
 .B status
-Display the status of a running keyd. Currently just the protocol version
-in use.
+Display the status of a running keyd. Currently the protocol version in use,
+when keyd was started, the number of client connections seen and a breakdown
+of the commands seen.
 .SH FILES
 .br
 .nf
index 96af7d2e61c12e018ffa9fb0238fbb191e990b0c..c66ce28794173515aaceef42fec5c10804108916 100644 (file)
--- a/keydctl.c
+++ b/keydctl.c
@@ -8,6 +8,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -138,10 +139,37 @@ static void keyd_close(void)
 static void keyd_status(void)
 {
        uint32_t reply;
+       struct keyd_stats stats;
 
        keyd_do_command(KEYD_CMD_VERSION, &reply, sizeof(reply));
        printf("Using keyd protocol version %d.\n", reply);
 
+       keyd_do_command(KEYD_CMD_STATS, &stats, sizeof(stats));
+       printf("keyd running since %s", ctime(&stats.started));
+       printf("%d client connections received\n", stats.connects);
+
+       printf("Command statistics:\n");
+       printf("  Version:          %d\n",
+               stats.command_stats[KEYD_CMD_VERSION]);
+       printf("  Get key:          %d\n", stats.command_stats[KEYD_CMD_GET]);
+       printf("  Store key:        %d\n",
+               stats.command_stats[KEYD_CMD_STORE]);
+       printf("  Delete key:       %d\n",
+               stats.command_stats[KEYD_CMD_DELETE]);
+       printf("  Search key:       %d\n",
+               stats.command_stats[KEYD_CMD_GETTEXT]);
+       printf("  Get full keyid:   %d\n",
+               stats.command_stats[KEYD_CMD_GETFULLKEYID]);
+       printf("  Iterate all keys: %d\n",
+               stats.command_stats[KEYD_CMD_KEYITER]);
+       printf("  Close:            %d\n",
+               stats.command_stats[KEYD_CMD_CLOSE]);
+       printf("  Quit:             %d\n", stats.command_stats[KEYD_CMD_QUIT]);
+       printf("  Get statistics:   %d\n",
+               stats.command_stats[KEYD_CMD_STATS]);
+       printf("  Unknown:          %d\n",
+               stats.command_stats[KEYD_CMD_UNKNOWN]);
+
        return;
 }