http://www.mediawiki.org/wiki/Special:Code/MediaWiki/84429

Revision: 84429
Author:   platonides
Date:     2011-03-20 22:18:33 +0000 (Sun, 20 Mar 2011)
Log Message:
-----------
Basic stats

Modified Paths:
--------------
    trunk/extensions/PoolCounter/daemon/Makefile
    trunk/extensions/PoolCounter/daemon/client_data.c
    trunk/extensions/PoolCounter/daemon/locks.c
    trunk/extensions/PoolCounter/daemon/locks.h
    trunk/extensions/PoolCounter/daemon/main.c

Added Paths:
-----------
    trunk/extensions/PoolCounter/daemon/stats.c
    trunk/extensions/PoolCounter/daemon/stats.h
    trunk/extensions/PoolCounter/daemon/stats.list

Modified: trunk/extensions/PoolCounter/daemon/Makefile
===================================================================
--- trunk/extensions/PoolCounter/daemon/Makefile        2011-03-20 22:04:56 UTC 
(rev 84428)
+++ trunk/extensions/PoolCounter/daemon/Makefile        2011-03-20 22:18:33 UTC 
(rev 84429)
@@ -1,9 +1,9 @@
 CC=gcc
 DEFINES=-DENDIAN_BIG=0 -DENDIAN_LITTLE=1 -DHAVE_ACCEPT4=1
 CFLAGS=-Wall $(DEFINES)
-OBJS=main.o client_data.o locks.o hash.o
+OBJS=main.o client_data.o locks.o hash.o stats.o
 LINK=-levent
-HEADERS=prototypes.h client_data.h
+HEADERS=prototypes.h client_data.h stats.h stats.list
 DESTDIR ?=
 
 poolcounterd: $(OBJS)

Modified: trunk/extensions/PoolCounter/daemon/client_data.c
===================================================================
--- trunk/extensions/PoolCounter/daemon/client_data.c   2011-03-20 22:04:56 UTC 
(rev 84428)
+++ trunk/extensions/PoolCounter/daemon/client_data.c   2011-03-20 22:18:33 UTC 
(rev 84429)
@@ -6,6 +6,7 @@
 #include <malloc.h>
 #include "client_data.h"
 #include "locks.h"
+#include "stats.h"
 
 struct client_data* new_client_data(int fd) {
        struct client_data* cd;
@@ -98,6 +99,7 @@
        
        if ( send( cli_data->fd, msg, len, 0) != len ) {
                perror( "Something failed sending message" );
+               incr_stats( failed_sends );
        }
        /* Wait for answer */
        event_add( &cli_data->ev, NULL );

Modified: trunk/extensions/PoolCounter/daemon/locks.c
===================================================================
--- trunk/extensions/PoolCounter/daemon/locks.c 2011-03-20 22:04:56 UTC (rev 
84428)
+++ trunk/extensions/PoolCounter/daemon/locks.c 2011-03-20 22:18:33 UTC (rev 
84429)
@@ -5,6 +5,7 @@
 #include "locks.h"
 #include "hash.h"
 #include "client_data.h"
+#include "stats.h"
 
 void init_lock(struct locks* l) {
        l->state = UNLOCKED;
@@ -42,7 +43,7 @@
        return num;
 }
 
-char* process_line(struct client_data* cli_data, char* line, int line_len) {
+const char* process_line(struct client_data* cli_data, char* line, int 
line_len) {
        struct locks* l = &cli_data->client_locks;
        if (line_len > 0 && line[line_len-1] == '\r') {
                line_len--;
@@ -51,6 +52,7 @@
        
        if ( !strncmp( line, "ACQ4ME ", 7 ) || !strncmp( line, "ACQ4ANY ", 8 ) 
) {
                if ( l->state != UNLOCKED ) {
+                       incr_stats( lock_mismatch );
                        return "LOCK_HELD\n";
                }
                
@@ -71,7 +73,7 @@
                if ( !pCounter ) {
                        pCounter = malloc( sizeof( *pCounter ) );
                        if ( !pCounter ) {
-                               fprintf(stderr, "Out of memory\n");
+                               fprintf( stderr, "Out of memory\n" );
                                return "ERROR OUT_OF_MEMORY\n";
                        }
                        pCounter->htentry.key = strdup( key );
@@ -84,10 +86,13 @@
                        DOUBLE_LLIST_INIT( pCounter->for_anyone );
                        
                        hashtable_insert( primary_hashtable, (struct 
hashtable_entry *) pCounter );
+                       incr_stats( hashtable_entries );
                }
                
-               if ( pCounter->count >= maxqueue )
+               if ( pCounter->count >= maxqueue ) {
+                       incr_stats( full_queues );
                        return "QUEUE_FULL\n";
+               }
                
                l->parent = pCounter;
                pCounter->count++;
@@ -95,7 +100,9 @@
                if ( pCounter->processing < workers ) {
                        l->state = PROCESSING;
                        pCounter->processing++;
+                       incr_stats( processing_workers );
                        DOUBLE_LLIST_ADD( &pCounter->working, &l->siblings );
+                       incr_stats( total_acquired );
                        return "LOCKED\n";
                } else {
                        struct timeval wait_time;
@@ -106,6 +113,7 @@
                                l->state = WAITING;
                                DOUBLE_LLIST_ADD( &pCounter->for_them, 
&l->siblings );
                        }
+                       incr_stats( waiting_workers );
                        
                        wait_time.tv_sec = timeout;
                        wait_time.tv_usec = 0;
@@ -115,11 +123,15 @@
                }
        } else if ( !strncmp(line, "RELEASE", 7) ) {
                if ( l->state == UNLOCKED ) {
+                       incr_stats( release_mismatch );
                        return "NOT_LOCKED\n";
                } else {
                        remove_client_lock( l, 1 );
+                       incr_stats( total_releases );
                        return "RELEASED\n";
                }
+       } else if ( !strncmp( line, "STATS ", 6 ) ) {
+               return provide_stats( line + 6 );
        } else {
                return "ERROR BAD_COMMAND\n";
        }
@@ -128,6 +140,7 @@
 void process_timeout(struct locks* l) {
        if ( ( l->state == WAIT_ANY ) || ( l->state == WAITING ) ) {
                send_client( l, "TIMEOUT\n" );
+               decr_stats( waiting_workers );
                remove_client_lock( l, 0 );
        }
 }
@@ -139,6 +152,7 @@
                while ( l->parent->for_anyone.next != &l->parent->for_anyone ) {
                        send_client( (void*)l->parent->for_anyone.next, 
"DONE\n" );
                        remove_client_lock( (void*)l->parent->for_anyone.next, 
0 );
+                       decr_stats( waiting_workers );
                }
        }
        
@@ -162,14 +176,18 @@
                        DOUBLE_LLIST_ADD( &l->parent->working, 
&new_owner->siblings );
                        send_client( new_owner, "LOCKED\n" );
                        new_owner->state = PROCESSING;
+                       incr_stats( total_acquired );
+                       decr_stats( waiting_workers );
                } else {
-                       l->parent->processing--;                        
+                       l->parent->processing--;
+                       decr_stats( processing_workers );
                }
        }
        
        l->state = UNLOCKED;
        l->parent->count--;
        if ( !l->parent->count ) {
+               decr_stats( hashtable_entries );
                hashtable_remove( l->parent->htentry.parent_hashtable, 
&l->parent->htentry );
                free( l->parent->htentry.key );
                free( l->parent );

Modified: trunk/extensions/PoolCounter/daemon/locks.h
===================================================================
--- trunk/extensions/PoolCounter/daemon/locks.h 2011-03-20 22:04:56 UTC (rev 
84428)
+++ trunk/extensions/PoolCounter/daemon/locks.h 2011-03-20 22:18:33 UTC (rev 
84429)
@@ -39,7 +39,7 @@
 struct client_data;
 void init_lock(struct locks* l);
 void finish_lock(struct locks* l);
-char* process_line(struct client_data* cli_data, char* line, int line_len);
+const char* process_line(struct client_data* cli_data, char* line, int 
line_len);
 void process_timeout(struct locks* l);
 void remove_client_lock(struct locks* l, int wakeup_anyones);
 void send_client(struct locks* l, const char* msg);

Modified: trunk/extensions/PoolCounter/daemon/main.c
===================================================================
--- trunk/extensions/PoolCounter/daemon/main.c  2011-03-20 22:04:56 UTC (rev 
84428)
+++ trunk/extensions/PoolCounter/daemon/main.c  2011-03-20 22:18:33 UTC (rev 
84429)
@@ -12,6 +12,7 @@
 #include "client_data.h"
 #include "prototypes.h"
 #include "locks.h"
+#include "stats.h"
 
 static int open_sockets = 1; /* Program will automatically close when this 
reaches 0 */
 
@@ -38,6 +39,8 @@
                return 1;
        }
        
+       stats.start = time( NULL );
+       
        event_set( &listener_ev, listener, EV_READ | EV_PERSIST, on_connect, 
NULL );
        
        event_add( &listener_ev, NULL );
@@ -91,6 +94,7 @@
 #endif
        
        if ( fd == -1 ) {
+               incr_stats( connect_errors );
                perror( "Error accepting" );
                return;
        }
@@ -104,6 +108,7 @@
        
        cli = new_client_data( fd );
        if ( !cli ) {
+               incr_stats( connect_errors );
                perror( "Couldn't allocate the client data! :(" );
                close( fd );
                return;

Added: trunk/extensions/PoolCounter/daemon/stats.c
===================================================================
--- trunk/extensions/PoolCounter/daemon/stats.c                         (rev 0)
+++ trunk/extensions/PoolCounter/daemon/stats.c 2011-03-20 22:18:33 UTC (rev 
84429)
@@ -0,0 +1,40 @@
+#include <stdio.h>
+#include <string.h>
+#include "stats.h"
+
+
+struct stats stats;
+
+#define COMMAND(item) + sizeof(#item) + 2 + MAX_COUNT_LEN
+static char stats_buffer[
+       sizeof("Uptime: 100000 days, 23h 59m 59s") + 2
+       #include "stats.list"
+];
+#undef COMMAND
+
+const char* provide_stats(const char* type)
+{
+       int seconds = time(NULL) - stats.start;
+       int minutes = seconds / 60;
+       seconds %= 60;
+       int hours = minutes / 60;
+       minutes %= 60;
+       unsigned int days = hours / 24;
+       
+       int n;
+       n = sprintf( stats_buffer, "uptime: %u days, %dh %dm %ds\n", days, 
hours, minutes, seconds );
+       
+       if ( !strcasecmp( type, "FULL" ) ) {
+               #define COMMAND(item) n += sprintf( stats_buffer + n, #item ": 
%" PRcount "\n", stats.item );
+               #include "stats.list"
+               #undef COMMAND
+               strcpy( stats_buffer + n, "\n" );
+       } else if ( strcasecmp( type, "UPTIME" ) ) {
+               #define COMMAND(item) if ( !strcasecmp( type, #item ) ) 
sprintf( stats_buffer, #item ": %" PRcount "\n", stats.item ); else
+               #include "stats.list"
+               #undef COMMAND
+               
+               strcpy( stats_buffer, "ERROR WRONG_STAT" );
+       }
+       return stats_buffer;
+}


Property changes on: trunk/extensions/PoolCounter/daemon/stats.c
___________________________________________________________________
Added: svn:eol-style
   + native

Added: trunk/extensions/PoolCounter/daemon/stats.h
===================================================================
--- trunk/extensions/PoolCounter/daemon/stats.h                         (rev 0)
+++ trunk/extensions/PoolCounter/daemon/stats.h 2011-03-20 22:18:33 UTC (rev 
84429)
@@ -0,0 +1,23 @@
+
+#include <time.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+typedef int64_t count_t;
+#define PRcount PRIi64
+#define MAX_COUNT_LEN sizeof("−9223372036854775808")
+
+struct stats {
+       time_t start;
+       
+#define COMMAND(item) volatile count_t item;
+#include "stats.list"
+#undef COMMAND
+
+};
+
+extern struct stats stats;
+const char* provide_stats(const char* type);
+
+#define incr_stats(item) stats.item++
+#define decr_stats(item) stats.item--


Property changes on: trunk/extensions/PoolCounter/daemon/stats.h
___________________________________________________________________
Added: svn:eol-style
   + native

Added: trunk/extensions/PoolCounter/daemon/stats.list
===================================================================
--- trunk/extensions/PoolCounter/daemon/stats.list                              
(rev 0)
+++ trunk/extensions/PoolCounter/daemon/stats.list      2011-03-20 22:18:33 UTC 
(rev 84429)
@@ -0,0 +1,13 @@
+
+/* Preprocessor template for iterating the stats items */
+COMMAND(total_acquired) /* Total number of acquired locks */
+COMMAND(total_releases) /* Total number of released locks */
+COMMAND(hashtable_entries) /* Number of locks currently held */
+COMMAND(processing_workers) /* Number of workers currently doing work */
+COMMAND(waiting_workers) /* Number of workers currently waiting for a lock */
+COMMAND(connect_errors) /* Clients whose connection couldn't be served */
+COMMAND(failed_sends) /* Number of send() calls which didn't succeed */
+COMMAND(full_queues) /* Number of times locks were refused because the queue 
already had so many workers */
+COMMAND(lock_mismatch) /* Number of times a user tried to do a lock without a 
previous release */
+COMMAND(release_mismatch) /* Number of times a user tried to do a release 
without a previous lock */
+


Property changes on: trunk/extensions/PoolCounter/daemon/stats.list
___________________________________________________________________
Added: svn:eol-style
   + native


_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to