From 41120f6a0da2cd66788635f40d672eefe3c23fee Mon Sep 17 00:00:00 2001 From: erdgeist <> Date: Tue, 6 Nov 2007 17:50:41 +0000 Subject: Move stats out of opentracker.c, also have an own file handle udp requests. --- ot_stats.c | 186 ++++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 153 insertions(+), 33 deletions(-) (limited to 'ot_stats.c') diff --git a/ot_stats.c b/ot_stats.c index 6857376..7cfb1dc 100644 --- a/ot_stats.c +++ b/ot_stats.c @@ -17,57 +17,59 @@ #include "ot_mutex.h" #include "ot_stats.h" +/* Clumsy counters... to be rethought */ +static unsigned long long ot_overall_tcp_connections = 0; +static unsigned long long ot_overall_udp_connections = 0; +static unsigned long long ot_overall_tcp_successfulannounces = 0; +static unsigned long long ot_overall_udp_successfulannounces = 0; +static unsigned long long ot_overall_tcp_successfulscrapes = 0; +static unsigned long long ot_overall_udp_successfulscrapes = 0; +static unsigned long long ot_full_scrape_count = 0; +static unsigned long long ot_full_scrape_size = 0; + /* Converter function from memory to human readable hex strings */ static char*to_hex(char*d,ot_byte*s){char*m="0123456789ABCDEF";char *t=d;char*e=d+40;while(d>4];*d++=m[*s++&15];}*d=0;return t;} typedef struct { size_t val; ot_torrent * torrent; } ot_record; /* Fetches stats from tracker */ -size_t return_stats_for_tracker( char *reply, int mode ) { - size_t torrent_count = 0, peer_count = 0, seed_count = 0, j; +size_t stats_top5_txt( char * reply ) { + size_t j; ot_record top5s[5], top5c[5]; - char *r = reply; - int bucket; + char *r = reply, hex_out[42]; + int idx, bucket; byte_zero( top5s, sizeof( top5s ) ); byte_zero( top5c, sizeof( top5c ) ); for( bucket=0; bucketsize; for( j=0; jsize; ++j ) { ot_peerlist *peer_list = ( ((ot_torrent*)(torrents_list->data))[j] ).peer_list; - if( mode == STATS_TOP5 ) { - int idx = 4; while( (idx >= 0) && ( peer_list->peer_count > top5c[idx].val ) ) --idx; - if ( idx++ != 4 ) { - memmove( top5c + idx + 1, top5c + idx, ( 4 - idx ) * sizeof( ot_record ) ); - top5c[idx].val = peer_list->peer_count; - top5c[idx].torrent = (ot_torrent*)(torrents_list->data) + j; - } - idx = 4; while( (idx >= 0) && ( peer_list->seed_count > top5s[idx].val ) ) --idx; - if ( idx++ != 4 ) { - memmove( top5s + idx + 1, top5s + idx, ( 4 - idx ) * sizeof( ot_record ) ); - top5s[idx].val = peer_list->seed_count; - top5s[idx].torrent = (ot_torrent*)(torrents_list->data) + j; - } + int idx = 4; while( (idx >= 0) && ( peer_list->peer_count > top5c[idx].val ) ) --idx; + if ( idx++ != 4 ) { + memmove( top5c + idx + 1, top5c + idx, ( 4 - idx ) * sizeof( ot_record ) ); + top5c[idx].val = peer_list->peer_count; + top5c[idx].torrent = (ot_torrent*)(torrents_list->data) + j; + } + idx = 4; while( (idx >= 0) && ( peer_list->seed_count > top5s[idx].val ) ) --idx; + if ( idx++ != 4 ) { + memmove( top5s + idx + 1, top5s + idx, ( 4 - idx ) * sizeof( ot_record ) ); + top5s[idx].val = peer_list->seed_count; + top5s[idx].torrent = (ot_torrent*)(torrents_list->data) + j; } - peer_count += peer_list->peer_count; seed_count += peer_list->seed_count; } mutex_bucket_unlock( bucket ); } - if( mode == STATS_TOP5 ) { - char hex_out[42]; - int idx; - r += sprintf( r, "Top5 torrents by peers:\n" ); - for( idx=0; idx<5; ++idx ) - if( top5c[idx].torrent ) - r += sprintf( r, "\t%zd\t%s\n", top5c[idx].val, to_hex( hex_out, top5c[idx].torrent->hash) ); - r += sprintf( r, "Top5 torrents by seeds:\n" ); - for( idx=0; idx<5; ++idx ) - if( top5s[idx].torrent ) - r += sprintf( r, "\t%zd\t%s\n", top5s[idx].val, to_hex( hex_out, top5s[idx].torrent->hash) ); - } else - r += sprintf( r, "%zd\n%zd\nopentracker serving %zd torrents\nopentracker", peer_count, seed_count, torrent_count ); + + r += sprintf( r, "Top5 torrents by peers:\n" ); + for( idx=0; idx<5; ++idx ) + if( top5c[idx].torrent ) + r += sprintf( r, "\t%zd\t%s\n", top5c[idx].val, to_hex( hex_out, top5c[idx].torrent->hash) ); + r += sprintf( r, "Top5 torrents by seeds:\n" ); + for( idx=0; idx<5; ++idx ) + if( top5s[idx].torrent ) + r += sprintf( r, "\t%zd\t%s\n", top5s[idx].val, to_hex( hex_out, top5s[idx].torrent->hash) ); return r - reply; } @@ -75,7 +77,7 @@ size_t return_stats_for_tracker( char *reply, int mode ) { /* This function collects 4096 /24s in 4096 possible malloc blocks */ -size_t return_stats_for_slash24s( char *reply, size_t amount, ot_dword thresh ) { +static size_t stats_slash24s_txt( char * reply, size_t amount, ot_dword thresh ) { #define NUM_TOPBITS 12 #define NUM_LOWBITS (24-NUM_TOPBITS) @@ -200,3 +202,121 @@ size_t return_memstat_for_tracker( char **reply ) { return replysize; } + +static unsigned long events_per_time( unsigned long long events, time_t t ) { + return events / ( (unsigned int)t ? (unsigned int)t : 1 ); +} + +static size_t stats_connections_mrtg( char * reply ) { + ot_time t = time( NULL ) - ot_start_time; + return sprintf( reply, + "%llu\n%llu\n%i seconds (%i hours)\nopentracker connections, %lu conns/s :: %lu success/s.", + ot_overall_tcp_connections+ot_overall_udp_connections, + ot_overall_tcp_successfulannounces+ot_overall_udp_successfulannounces, + (int)t, + (int)(t / 3600), + events_per_time( ot_overall_tcp_connections+ot_overall_udp_connections, t ), + events_per_time( ot_overall_tcp_successfulannounces+ot_overall_udp_successfulannounces, t ) + ); +} + +static size_t stats_udpconnections_mrtg( char * reply ) { + ot_time t = time( NULL ) - ot_start_time; + return sprintf( reply, + "%llu\n%llu\n%i seconds (%i hours)\nopentracker udp4 stats, %lu conns/s :: %lu success/s.", + ot_overall_udp_connections, + ot_overall_udp_successfulannounces, + (int)t, + (int)(t / 3600), + events_per_time( ot_overall_udp_connections, t ), + events_per_time( ot_overall_udp_successfulannounces, t ) + ); +} + +static size_t stats_tcpconnections_mrtg( char * reply ) { + time_t t = time( NULL ) - ot_start_time; + return sprintf( reply, + "%llu\n%llu\n%i seconds (%i hours)\nopentracker tcp4 stats, %lu conns/s :: %lu success/s.", + ot_overall_tcp_connections, + ot_overall_tcp_successfulannounces, + (int)t, + (int)(t / 3600), + events_per_time( ot_overall_tcp_connections, t ), + events_per_time( ot_overall_tcp_successfulannounces, t ) + ); +} + + +static size_t stats_fullscrapes_mrtg( char * reply ) { + ot_time t = time( NULL ) - ot_start_time; + return sprintf( reply, + "%llu\n%llu\n%i seconds (%i hours)\nopentracker full scrape stats, %lu conns/s :: %lu bytes/s.", + ot_full_scrape_count * 1000, + ot_full_scrape_size, + (int)t, + (int)(t / 3600), + events_per_time( ot_full_scrape_count, t ), + events_per_time( ot_full_scrape_size, t ) + ); +} + +static size_t stats_peers_mrtg( char * reply ) { + size_t torrent_count = 0, peer_count = 0, seed_count = 0, j; + int bucket; + + for( bucket=0; bucketsize; + for( j=0; jsize; ++j ) { + ot_peerlist *peer_list = ( ((ot_torrent*)(torrents_list->data))[j] ).peer_list; + peer_count += peer_list->peer_count; seed_count += peer_list->seed_count; + } + mutex_bucket_unlock( bucket ); + } + return sprintf( reply, "%zd\n%zd\nopentracker serving %zd torrents\nopentracker", + peer_count, + seed_count, + torrent_count + ); +} + +size_t return_stats_for_tracker( char *reply, int mode, int format ) { + format = format; + switch( mode ) { + case STATS_CONNS: + return stats_connections_mrtg( reply ); + case STATS_UDP: + return stats_udpconnections_mrtg( reply ); + case STATS_TCP: + return stats_tcpconnections_mrtg( reply ); + case STATS_PEERS: + return stats_peers_mrtg( reply ); + case STATS_SLASH24S: + return stats_slash24s_txt( reply, 25, 16 ); + case STATS_TOP5: + return stats_top5_txt( reply ); + case STATS_FULLSCRAPE: + return stats_fullscrapes_mrtg( reply ); + default: + return 0; + } +} + +void stats_issue_event( ot_status_event event, int is_tcp, size_t event_data ) { + switch( event ) { + case EVENT_ACCEPT: + if( is_tcp ) ot_overall_tcp_connections++; else ot_overall_udp_connections++; + break; + case EVENT_ANNOUNCE: + if( is_tcp ) ot_overall_tcp_successfulannounces++; else ot_overall_udp_successfulannounces++; + break; + case EVENT_SCRAPE: + if( is_tcp ) ot_overall_tcp_successfulscrapes++; else ot_overall_udp_successfulscrapes++; + case EVENT_FULLSCRAPE: + ot_full_scrape_count++; + ot_full_scrape_size += event_data; + break; + default: + break; + } +} \ No newline at end of file -- cgit v1.2.3