Add statistics for detail listeners, too
authorAlan T. DeKok <aland@freeradius.org>
Thu, 21 Jan 2010 10:37:21 +0000 (11:37 +0100)
committerAlan T. DeKok <aland@freeradius.org>
Thu, 4 Feb 2010 08:02:57 +0000 (09:02 +0100)
src/include/detail.h
src/modules/frs_control/frs_control.c
src/modules/frs_detail/frs_detail.c

index 4c164d7..92d9f3e 100644 (file)
@@ -28,6 +28,7 @@ typedef struct listen_detail_t {
        char            *filename_work;
        VALUE_PAIR      *vps;
        FILE            *fp;
+       off_t           offset;
        detail_state_t  state;
        time_t          timestamp;
        time_t          running;
@@ -36,6 +37,8 @@ typedef struct listen_detail_t {
        int             signal;
        int             poll_interval;
        int             retry_interval;
+       int             packets;
+       int             tries;
 
        int             has_rtt;
        int             srtt;
index f3d5cf1..fe11d31 100644 (file)
@@ -1599,6 +1599,69 @@ static int command_print_stats(rad_listen_t *listener, fr_stats_t *stats,
 }
 
 
+#ifdef WITH_DETAIL
+static FR_NAME_NUMBER state_names[] = {
+       { "unopened", STATE_UNOPENED },
+       { "unlocked", STATE_UNLOCKED },
+       { "header", STATE_HEADER },
+       { "reading", STATE_READING },
+       { "queued", STATE_QUEUED },
+       { "running", STATE_RUNNING },
+       { "no-reply", STATE_NO_REPLY },
+       { "replied", STATE_REPLIED },
+
+       { NULL, 0 }
+};
+
+static int command_stats_detail(rad_listen_t *listener, int argc, char *argv[])
+{
+       rad_listen_t *this;
+       listen_detail_t *data;
+       struct stat buf;
+
+       if (argc == 0) {
+               cprintf(listener, "ERROR: Must specify <filename>\n");
+               return 0;
+       }
+
+       data = NULL;
+       for (this = mainconfig.listen; this != NULL; this = this->next) {
+               if (this->type != RAD_LISTEN_DETAIL) continue;
+
+               data = this->data;
+               if (strcmp(argv[1], data->filename) != 0) continue;
+
+               break;
+       }
+
+       cprintf(listener, "\tstate\t%s\n",
+               fr_int2str(state_names, data->state, "?"));
+
+       if ((data->state == STATE_UNOPENED) ||
+           (data->state == STATE_UNLOCKED)) {
+               return 1;
+       }
+
+       /*
+        *      Race conditions: file might not exist.
+        */
+       if (stat(data->filename_work, &buf) < 0) {
+               cprintf(listener, "packets\t0\n");
+               cprintf(listener, "tries\t0\n");
+               cprintf(listener, "offset\t0\n");
+               cprintf(listener, "size\t0\n");
+               return 1;
+       }
+
+       cprintf(listener, "packets\t%d\n", data->packets);
+       cprintf(listener, "tries\t%d\n", data->tries);
+       cprintf(listener, "offset\t%u\n", (unsigned int) data->offset);
+       cprintf(listener, "size\t%u\n", (unsigned int) buf.st_size);
+
+       return 1;
+}
+#endif
+
 #ifdef WITH_PROXY
 static int command_stats_home_server(rad_listen_t *listener, int argc, char *argv[])
 {
@@ -1788,6 +1851,12 @@ static fr_command_table_t command_table_stats[] = {
          command_stats_home_server, NULL },
 #endif
 
+#ifdef WITH_DETAIL
+       { "detail", FR_READ,
+         "stats detail <filename> - show statistics for the given detail file",
+         command_stats_detail, NULL },
+#endif
+
        { NULL, 0, NULL, NULL, NULL }
 };
 
index ea22c90..921dc31 100644 (file)
@@ -423,6 +423,9 @@ static int detail_open(rad_listen_t *this)
 
        data->client_ip.af = AF_UNSPEC;
        data->timestamp = 0;
+       data->offset = 0;
+       data->packets = 0;
+       data->tries = 0;
 
        return 1;
 }
@@ -608,6 +611,8 @@ int detail_recv(rad_listen_t *listener,
         *      Read a header, OR a value-pair.
         */
        while (fgets(buffer, sizeof(buffer), data->fp)) {
+               data->offset = ftell(data->fp); /* for statistics */
+
                /*
                 *      Badly formatted file: delete it.
                 *
@@ -717,10 +722,15 @@ int detail_recv(rad_listen_t *listener,
         */
        if (ferror(data->fp)) goto cleanup;
 
+       data->tries = 0;
+       data->packets++;
+
        /*
         *      Process the packet.
         */
  alloc_packet:
+       data->tries++;
+       
        rad_assert(data->state == STATE_QUEUED);
 
        /*