@ -1,7 +1,7 @@
/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
It is considered beerware . Prost . Skol . Cheers or whatever .
It is considered beerware . Prost . Skol . Cheers or whatever .
$ id $ */
$ id $ */
/* System */
# include <stdlib.h>
@ -50,12 +50,13 @@ static unsigned long long ot_full_scrape_size = 0;
static unsigned long long ot_failed_request_counts [ CODE_HTTPERROR_COUNT ] ;
static unsigned long long ot_renewed [ OT_PEER_TIMEOUT ] ;
static unsigned long long ot_overall_sync_count ;
static unsigned long long ot_overall_stall_count ;
static time_t ot_start_time ;
# ifdef WANT_LOG_NETWORKS
# define STATS_NETWORK_NODE_BITWIDTH 8
# define STATS_NETWORK_NODE_MAXDEPTH 3
# define STATS_NETWORK_NODE_MAXDEPTH 16
# define STATS_NETWORK_NODE_BITMASK ((1<<STATS_NETWORK_NODE_BITWIDTH)-1)
# define STATS_NETWORK_NODE_COUNT (1<<STATS_NETWORK_NODE_BITWIDTH)
@ -68,8 +69,9 @@ union stats_network_node {
static stats_network_node * stats_network_counters_root = NULL ;
static int stat_increase_network_count ( stats_network_node * * node , int depth , uint32_t ip ) {
int foo = ( ip > > ( 32 - STATS_NETWORK_NODE_BITWIDTH * ( + + depth ) ) ) & STATS_NETWORK_NODE_BITMASK ;
static int stat_increase_network_count ( stats_network_node * * node , int depth , uintptr_t ip ) {
ot_ip6 * _ip = ( ot_ip6 * ) ip ;
int foo = ( * _ip ) [ depth ] ;
if ( ! * node ) {
* node = malloc ( sizeof ( stats_network_node ) ) ;
@ -92,8 +94,8 @@ static int stats_shift_down_network_count( stats_network_node **node, int depth,
if ( + + depth = = STATS_NETWORK_NODE_MAXDEPTH )
for ( i = 0 ; i < STATS_NETWORK_NODE_COUNT ; + + i ) {
rest + = ( ( * node ) - > counters [ i ] > > = shift ) ;
return rest ;
}
return rest ;
}
for ( i = 0 ; i < STATS_NETWORK_NODE_COUNT ; + + i ) {
stats_network_node * * childnode = & ( * node ) - > children [ i ] ;
@ -138,7 +140,7 @@ static void stats_get_highscore_networks( stats_network_node *node, int depth, u
memcpy ( networks , networks + 1 , j * sizeof ( * networks ) ) ;
scores [ j ] = node - > counters [ i ] ;
networks [ j ] = node_value | ( i < < ( 32 - depth * STATS_NETWORK_NODE_BITWIDTH ) ) ;
}
}
}
static size_t stats_return_busy_networks ( char * reply ) {
@ -157,6 +159,20 @@ static size_t stats_return_busy_networks( char * reply ) {
# endif
typedef struct {
unsigned long long torrent_count ;
unsigned long long peer_count ;
unsigned long long seed_count ;
} torrent_stats ;
static int torrent_statter ( ot_torrent * torrent , uintptr_t data ) {
torrent_stats * stats = ( torrent_stats * ) data ;
stats - > torrent_count + + ;
stats - > peer_count + = torrent - > peer_list - > peer_count ;
stats - > seed_count + = torrent - > peer_list - > seed_count ;
return 0 ;
}
/* Converter function from memory to human readable hex strings */
static char * to_hex ( char * d , uint8_t * s ) { char * m = " 0123456789ABCDEF " ; char * t = d ; char * e = d + 40 ; while ( d < e ) { * d + + = m [ * s > > 4 ] ; * d + + = m [ * s + + & 15 ] ; } * d = 0 ; return t ; }
@ -207,8 +223,8 @@ size_t stats_top10_txt( char * reply ) {
}
/* This function collects 4096 /24s in 4096 possible
malloc blocks
*/
malloc blocks
*/
static size_t stats_slash24s_txt ( char * reply , size_t amount , uint32_t thresh ) {
# define NUM_TOPBITS 12
@ -300,9 +316,9 @@ static size_t stats_slash24s_txt( char * reply, size_t amount, uint32_t thresh )
/*
struct {
size_t size
size_t space
size_t count
size_t size
size_t space
size_t count
}
*/
@ -313,87 +329,77 @@ static unsigned long events_per_time( unsigned long long events, time_t t ) {
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) \n opentracker connections, %lu conns/s :: %lu success/s. " ,
ot_overall_tcp_connections + ot_overall_udp_connections ,
ot_overall_tcp_successfulannounces + ot_overall_udp_successfulannounces + ot_overall_udp_connects ,
( 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 + ot_overall_udp_connects , t )
) ;
" %llu \n %llu \n %i seconds (%i hours) \n opentracker connections, %lu conns/s :: %lu success/s. " ,
ot_overall_tcp_connections + ot_overall_udp_connections ,
ot_overall_tcp_successfulannounces + ot_overall_udp_successfulannounces + ot_overall_udp_connects ,
( 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 + ot_overall_udp_connects , 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) \n opentracker udp4 stats, %lu conns/s :: %lu success/s. " ,
ot_overall_udp_connections ,
ot_overall_udp_successfulannounces + ot_overall_udp_connects ,
( int ) t ,
( int ) ( t / 3600 ) ,
events_per_time ( ot_overall_udp_connections , t ) ,
events_per_time ( ot_overall_udp_successfulannounces + ot_overall_udp_connects , t )
) ;
" %llu \n %llu \n %i seconds (%i hours) \n opentracker udp4 stats, %lu conns/s :: %lu success/s. " ,
ot_overall_udp_connections ,
ot_overall_udp_successfulannounces + ot_overall_udp_connects ,
( int ) t ,
( int ) ( t / 3600 ) ,
events_per_time ( ot_overall_udp_connections , t ) ,
events_per_time ( ot_overall_udp_successfulannounces + ot_overall_udp_connects , 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) \n opentracker 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 )
) ;
" %llu \n %llu \n %i seconds (%i hours) \n opentracker 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_scrape_mrtg ( char * reply ) {
time_t t = time ( NULL ) - ot_start_time ;
return sprintf ( reply ,
" %llu \n %llu \n %i seconds (%i hours) \n opentracker scrape stats, %lu scrape/s (tcp and udp) " ,
ot_overall_tcp_successfulscrapes ,
ot_overall_udp_successfulscrapes ,
( int ) t ,
( int ) ( t / 3600 ) ,
events_per_time ( ( ot_overall_tcp_successfulscrapes + ot_overall_udp_successfulscrapes ) , t )
) ;
" %llu \n %llu \n %i seconds (%i hours) \n opentracker scrape stats, %lu scrape/s (tcp and udp) " ,
ot_overall_tcp_successfulscrapes ,
ot_overall_udp_successfulscrapes ,
( int ) t ,
( int ) ( t / 3600 ) ,
events_per_time ( ( ot_overall_tcp_successfulscrapes + ot_overall_udp_successfulscrapes ) , 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) \n opentracker 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 )
) ;
" %llu \n %llu \n %i seconds (%i hours) \n opentracker 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 ;
torrent_stats stats = { 0 , 0 , 0 } ;
for ( bucket = 0 ; bucket < OT_BUCKET_COUNT ; + + bucket ) {
ot_vector * torrents_list = mutex_bucket_lock ( bucket ) ;
torrent_count + = torrents_list - > size ;
for ( j = 0 ; j < torrents_list - > size ; + + 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 , 0 ) ;
if ( ! g_opentracker_running )
return 0 ;
}
return sprintf ( reply , " %zd \n %zd \n opentracker serving %zd torrents \n opentracker " ,
peer_count ,
seed_count ,
torrent_count
) ;
iterate_all_torrents ( torrent_statter , ( uintptr_t ) & stats ) ;
return sprintf ( reply , " %llu \n %llu \n opentracker serving %llu torrents \n opentracker " ,
stats . peer_count ,
stats . seed_count ,
stats . torrent_count
) ;
}
static size_t stats_startstop_mrtg ( char * reply )
@ -401,10 +407,10 @@ static size_t stats_startstop_mrtg( char * reply )
size_t torrent_count = mutex_get_torrent_count ( ) ;
return sprintf ( reply , " %zd \n %zd \n opentracker handling %zd torrents \n opentracker " ,
( size_t ) 0 ,
( size_t ) 0 ,
torrent_count
) ;
( size_t ) 0 ,
( size_t ) 0 ,
torrent_count
) ;
}
static size_t stats_toraddrem_mrtg ( char * reply )
@ -426,10 +432,10 @@ static size_t stats_toraddrem_mrtg( char * reply )
}
return sprintf ( reply , " %zd \n %zd \n opentracker handling %zd peers \n opentracker " ,
( size_t ) 0 ,
( size_t ) 0 ,
peer_count
) ;
( size_t ) 0 ,
( size_t ) 0 ,
peer_count
) ;
}
static size_t stats_torrents_mrtg ( char * reply )
@ -437,17 +443,17 @@ static size_t stats_torrents_mrtg( char * reply )
size_t torrent_count = mutex_get_torrent_count ( ) ;
return sprintf ( reply , " %zd \n %zd \n opentracker serving %zd torrents \n opentracker " ,
torrent_count ,
( size_t ) 0 ,
torrent_count
) ;
torrent_count ,
( size_t ) 0 ,
torrent_count
) ;
}
static size_t stats_httperrors_txt ( char * reply ) {
return sprintf ( reply , " 302 RED %llu \n 400 ... %llu \n 400 PAR %llu \n 400 COM %llu \n 403 IP %llu \n 404 INV %llu \n 500 SRV %llu \n " ,
ot_failed_request_counts [ 0 ] , ot_failed_request_counts [ 1 ] , ot_failed_request_counts [ 2 ] ,
ot_failed_request_counts [ 3 ] , ot_failed_request_counts [ 4 ] , ot_failed_request_counts [ 5 ] ,
ot_failed_request_counts [ 6 ] ) ;
ot_failed_request_counts [ 0 ] , ot_failed_request_counts [ 1 ] , ot_failed_request_counts [ 2 ] ,
ot_failed_request_counts [ 3 ] , ot_failed_request_counts [ 4 ] , ot_failed_request_counts [ 5 ] ,
ot_failed_request_counts [ 6 ] ) ;
}
static size_t stats_return_renew_bucket ( char * reply ) {
@ -459,18 +465,28 @@ static size_t stats_return_renew_bucket( char * reply ) {
return r - reply ;
}
static size_t stats_return_sync_mrtg ( char * reply )
{
static size_t stats_return_sync_mrtg ( char * reply ) {
ot_time t = time ( NULL ) - ot_start_time ;
return sprintf ( reply ,
" %llu \n %llu \n %i seconds (%i hours) \n opentracker connections, %lu conns/s :: %lu success/s. " ,
ot_overall_sync_count ,
0LL ,
( 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 + ot_overall_udp_connects , t )
) ;
" %llu \n %llu \n %i seconds (%i hours) \n opentracker connections, %lu conns/s :: %lu success/s. " ,
ot_overall_sync_count ,
0LL ,
( 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 + ot_overall_udp_connects , t )
) ;
}
static size_t stats_return_everything ( char * reply ) {
char * r = reply ;
r + = sprintf ( r , " <stats> \n " ) ;
r + = sprintf ( r , " <uptime>%llu</uptime> \n " , ( unsigned long long ) ( time ( NULL ) - ot_start_time ) ) ;
r + = sprintf ( r , " <torrents>%zd</torrents> \n " , mutex_get_torrent_count ( ) ) ;
/* r += sprintf( r, " <peers>%llu</peers>\n", ); */
r + = sprintf ( reply , " </stats> " ) ;
return r - reply ;
}
extern const char
@ -480,9 +496,9 @@ extern const char
size_t stats_return_tracker_version ( char * reply ) {
return sprintf ( reply , " %s%s%s%s%s%s%s%s%s%s%s%s%s " ,
g_version_opentracker_c , g_version_accesslist_c , g_version_clean_c , g_version_fullscrape_c , g_version_http_c ,
g_version_iovec_c , g_version_mutex_c , g_version_stats_c , g_version_udp_c , g_version_vector_c ,
g_version_scan_urlencoded_query_c , g_version_trackerlogic_c , g_version_livesync_c ) ;
g_version_opentracker_c , g_version_accesslist_c , g_version_clean_c , g_version_fullscrape_c , g_version_http_c ,
g_version_iovec_c , g_version_mutex_c , g_version_stats_c , g_version_udp_c , g_version_vector_c ,
g_version_scan_urlencoded_query_c , g_version_trackerlogic_c , g_version_livesync_c ) ;
}
size_t return_stats_for_tracker ( char * reply , int mode , int format ) {
@ -509,7 +525,7 @@ size_t return_stats_for_tracker( char *reply, int mode, int format ) {
case TASK_STATS_RENEW :
return stats_return_renew_bucket ( reply ) ;
case TASK_STATS_SYNCS :
return stats_return_sync_mrtg ( reply ) ;
return stats_return_sync_mrtg ( reply ) ;
# ifdef WANT_LOG_NETWORKS
case TASK_STATS_BUSY_NETWORKS :
return stats_return_busy_networks ( reply ) ;
@ -560,26 +576,26 @@ void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uintptr_t event
ot_full_scrape_size + = event_data ;
break ;
case EVENT_FULLSCRAPE_REQUEST :
{
ot_ip6 * ip = ( ot_ip6 * ) event_data ; /* ugly hack to transfer ip to stats */
char _debug [ 512 ] ;
int off = snprintf ( _debug , sizeof ( _debug ) , " [%08d] scrp: " , ( unsigned int ) ( g_now_seconds - ot_start_time ) / 60 ) ;
off + = fmt_ip6 ( _debug + off , * ip ) ;
off + = snprintf ( _debug + off , sizeof ( _debug ) - off , " - FULL SCRAPE \n " ) ;
write ( 2 , _debug , off ) ;
ot_full_scrape_request_count + + ;
}
{
ot_ip6 * ip = ( ot_ip6 * ) event_data ; /* ugly hack to transfer ip to stats */
char _debug [ 512 ] ;
int off = snprintf ( _debug , sizeof ( _debug ) , " [%08d] scrp: " , ( unsigned int ) ( g_now_seconds - ot_start_time ) / 60 ) ;
off + = fmt_ip6 ( _debug + off , * ip ) ;
off + = snprintf ( _debug + off , sizeof ( _debug ) - off , " - FULL SCRAPE \n " ) ;
write ( 2 , _debug , off ) ;
ot_full_scrape_request_count + + ;
}
break ;
case EVENT_FULLSCRAPE_REQUEST_GZIP :
{
ot_ip6 * ip = ( ot_ip6 * ) event_data ; /* ugly hack to transfer ip to stats */
char _debug [ 512 ] ;
int off = snprintf ( _debug , sizeof ( _debug ) , " [%08d] scrp: " , ( unsigned int ) ( g_now_seconds - ot_start_time ) / 60 ) ;
off + = fmt_ip6 ( _debug + off , * ip ) ;
off + = snprintf ( _debug + off , sizeof ( _debug ) - off , " - FULL SCRAPE \n " ) ;
write ( 2 , _debug , off ) ;
ot_full_scrape_request_count + + ;
}
{
ot_ip6 * ip = ( ot_ip6 * ) event_data ; /* ugly hack to transfer ip to stats */
char _debug [ 512 ] ;
int off = snprintf ( _debug , sizeof ( _debug ) , " [%08d] scrp: " , ( unsigned int ) ( g_now_seconds - ot_start_time ) / 60 ) ;
off + = fmt_ip6 ( _debug + off , * ip ) ;
off + = snprintf ( _debug + off , sizeof ( _debug ) - off , " - FULL SCRAPE \n " ) ;
write ( 2 , _debug , off ) ;
ot_full_scrape_request_count + + ;
}
break ;
case EVENT_FAILED :
ot_failed_request_counts [ event_data ] + + ;
@ -590,6 +606,9 @@ void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uintptr_t event
case EVENT_SYNC :
ot_overall_sync_count + = event_data ;
break ;
case EVENT_BUCKET_LOCKED :
ot_overall_stall_count + + ;
break ;
default :
break ;
}