diff options
Diffstat (limited to 'ot_stats.c')
| -rw-r--r-- | ot_stats.c | 995 |
1 files changed, 498 insertions, 497 deletions
| @@ -4,16 +4,16 @@ | |||
| 4 | $id$ */ | 4 | $id$ */ |
| 5 | 5 | ||
| 6 | /* System */ | 6 | /* System */ |
| 7 | #include <stdlib.h> | ||
| 8 | #include <arpa/inet.h> | 7 | #include <arpa/inet.h> |
| 9 | #include <sys/types.h> | 8 | #include <inttypes.h> |
| 10 | #include <sys/uio.h> | 9 | #include <pthread.h> |
| 11 | #include <sys/mman.h> | ||
| 12 | #include <stdio.h> | 10 | #include <stdio.h> |
| 11 | #include <stdlib.h> | ||
| 13 | #include <string.h> | 12 | #include <string.h> |
| 14 | #include <pthread.h> | 13 | #include <sys/mman.h> |
| 14 | #include <sys/types.h> | ||
| 15 | #include <sys/uio.h> | ||
| 15 | #include <unistd.h> | 16 | #include <unistd.h> |
| 16 | #include <inttypes.h> | ||
| 17 | #ifdef WANT_SYSLOGS | 17 | #ifdef WANT_SYSLOGS |
| 18 | #include <syslog.h> | 18 | #include <syslog.h> |
| 19 | #endif | 19 | #endif |
| @@ -25,61 +25,63 @@ | |||
| 25 | #include "ip6.h" | 25 | #include "ip6.h" |
| 26 | 26 | ||
| 27 | /* Opentracker */ | 27 | /* Opentracker */ |
| 28 | #include "trackerlogic.h" | 28 | #include "ot_accesslist.h" |
| 29 | #include "ot_mutex.h" | ||
| 30 | #include "ot_iovec.h" | 29 | #include "ot_iovec.h" |
| 30 | #include "ot_mutex.h" | ||
| 31 | #include "ot_stats.h" | 31 | #include "ot_stats.h" |
| 32 | #include "ot_accesslist.h" | 32 | #include "trackerlogic.h" |
| 33 | 33 | ||
| 34 | #ifndef NO_FULLSCRAPE_LOGGING | 34 | #ifndef NO_FULLSCRAPE_LOGGING |
| 35 | #define LOG_TO_STDERR( ... ) fprintf( stderr, __VA_ARGS__ ) | 35 | #define LOG_TO_STDERR(...) fprintf(stderr, __VA_ARGS__) |
| 36 | #else | 36 | #else |
| 37 | #define LOG_TO_STDERR( ... ) | 37 | #define LOG_TO_STDERR(...) |
| 38 | #endif | 38 | #endif |
| 39 | 39 | ||
| 40 | /* Forward declaration */ | 40 | /* Forward declaration */ |
| 41 | static void stats_make( int *iovec_entries, struct iovec **iovector, ot_tasktype mode ); | 41 | static void stats_make(size_t *iovec_entries, struct iovec **iovector, ot_tasktype mode); |
| 42 | #define OT_STATS_TMPSIZE 8192 | 42 | #define OT_STATS_TMPSIZE 8192 |
| 43 | 43 | ||
| 44 | /* Clumsy counters... to be rethought */ | 44 | /* Clumsy counters... to be rethought */ |
| 45 | static unsigned long long ot_overall_tcp_connections = 0; | 45 | static unsigned long long ot_overall_tcp_connections; |
| 46 | static unsigned long long ot_overall_udp_connections = 0; | 46 | static unsigned long long ot_overall_udp_connections; |
| 47 | static unsigned long long ot_overall_tcp_successfulannounces = 0; | 47 | static unsigned long long ot_overall_tcp_successfulannounces; |
| 48 | static unsigned long long ot_overall_udp_successfulannounces = 0; | 48 | static unsigned long long ot_overall_udp_successfulannounces; |
| 49 | static unsigned long long ot_overall_tcp_successfulscrapes = 0; | 49 | static unsigned long long ot_overall_tcp_successfulscrapes; |
| 50 | static unsigned long long ot_overall_udp_successfulscrapes = 0; | 50 | static unsigned long long ot_overall_udp_successfulscrapes; |
| 51 | static unsigned long long ot_overall_udp_connectionidmissmatches = 0; | 51 | static unsigned long long ot_overall_udp_connectionidmissmatches; |
| 52 | static unsigned long long ot_overall_tcp_connects = 0; | 52 | static unsigned long long ot_overall_tcp_connects; |
| 53 | static unsigned long long ot_overall_udp_connects = 0; | 53 | static unsigned long long ot_overall_udp_connects; |
| 54 | static unsigned long long ot_overall_completed = 0; | 54 | static unsigned long long ot_overall_completed; |
| 55 | static unsigned long long ot_full_scrape_count = 0; | 55 | static unsigned long long ot_full_scrape_count; |
| 56 | static unsigned long long ot_full_scrape_request_count = 0; | 56 | static unsigned long long ot_full_scrape_request_count; |
| 57 | static unsigned long long ot_full_scrape_size = 0; | 57 | static unsigned long long ot_full_scrape_size; |
| 58 | static unsigned long long ot_failed_request_counts[CODE_HTTPERROR_COUNT]; | 58 | static unsigned long long ot_failed_request_counts[CODE_HTTPERROR_COUNT]; |
| 59 | static char * ot_failed_request_names[] = { "302 Redirect", "400 Parse Error", "400 Invalid Parameter", "400 Invalid Parameter (compact=0)", "400 Not Modest", "402 Payment Required", "403 Access Denied", "404 Not found", "500 Internal Server Error" }; | 59 | static char *ot_failed_request_names[] = { |
| 60 | "302 Redirect", "400 Parse Error", "400 Invalid Parameter", "400 Invalid Parameter (compact=0)", "400 Not Modest", | ||
| 61 | "402 Payment Required", "403 Access Denied", "404 Not found", "500 Internal Server Error"}; | ||
| 60 | static unsigned long long ot_renewed[OT_PEER_TIMEOUT]; | 62 | static unsigned long long ot_renewed[OT_PEER_TIMEOUT]; |
| 61 | static unsigned long long ot_overall_sync_count; | 63 | static unsigned long long ot_overall_sync_count; |
| 62 | static unsigned long long ot_overall_stall_count; | 64 | static unsigned long long ot_overall_stall_count; |
| 63 | 65 | ||
| 64 | static time_t ot_start_time; | 66 | static time_t ot_start_time; |
| 65 | 67 | ||
| 66 | #define STATS_NETWORK_NODE_BITWIDTH 4 | 68 | #define STATS_NETWORK_NODE_BITWIDTH 4 |
| 67 | #define STATS_NETWORK_NODE_COUNT (1<<STATS_NETWORK_NODE_BITWIDTH) | 69 | #define STATS_NETWORK_NODE_COUNT (1 << STATS_NETWORK_NODE_BITWIDTH) |
| 68 | 70 | ||
| 69 | #define __BYTE(P,D) (((uint8_t*)P)[D/8]) | 71 | #define __BYTE(P, D) (((uint8_t *)P)[D / 8]) |
| 70 | #define __MSK (STATS_NETWORK_NODE_COUNT-1) | 72 | #define __MSK (STATS_NETWORK_NODE_COUNT - 1) |
| 71 | #define __SHFT(D) ((D^STATS_NETWORK_NODE_BITWIDTH)&STATS_NETWORK_NODE_BITWIDTH) | 73 | #define __SHFT(D) ((D ^ STATS_NETWORK_NODE_BITWIDTH) & STATS_NETWORK_NODE_BITWIDTH) |
| 72 | 74 | ||
| 73 | #define __LDR(P,D) ((__BYTE((P),(D))>>__SHFT((D)))&__MSK) | 75 | #define __LDR(P, D) ((__BYTE((P), (D)) >> __SHFT((D))) & __MSK) |
| 74 | #define __STR(P,D,V) __BYTE((P),(D))=(__BYTE((P),(D))&~(__MSK<<__SHFT((D))))|((V)<<__SHFT((D))) | 76 | #define __STR(P, D, V) __BYTE((P), (D)) = (__BYTE((P), (D)) & ~(__MSK << __SHFT((D)))) | ((V) << __SHFT((D))) |
| 75 | 77 | ||
| 76 | #ifdef WANT_V6 | 78 | #if 0 |
| 77 | #define STATS_NETWORK_NODE_MAXDEPTH (68-STATS_NETWORK_NODE_BITWIDTH) | 79 | // XXX |
| 78 | #define STATS_NETWORK_NODE_LIMIT (48-STATS_NETWORK_NODE_BITWIDTH) | 80 | #define STATS_NETWORK_NODE_MAXDEPTH (68 - STATS_NETWORK_NODE_BITWIDTH) |
| 79 | #else | 81 | #define STATS_NETWORK_NODE_LIMIT (48 - STATS_NETWORK_NODE_BITWIDTH) |
| 80 | #define STATS_NETWORK_NODE_MAXDEPTH (28-STATS_NETWORK_NODE_BITWIDTH) | ||
| 81 | #define STATS_NETWORK_NODE_LIMIT (24-STATS_NETWORK_NODE_BITWIDTH) | ||
| 82 | #endif | 82 | #endif |
| 83 | #define STATS_NETWORK_NODE_MAXDEPTH (28 - STATS_NETWORK_NODE_BITWIDTH) | ||
| 84 | #define STATS_NETWORK_NODE_LIMIT (24 - STATS_NETWORK_NODE_BITWIDTH) | ||
| 83 | 85 | ||
| 84 | typedef union stats_network_node stats_network_node; | 86 | typedef union stats_network_node stats_network_node; |
| 85 | union stats_network_node { | 87 | union stats_network_node { |
| @@ -91,121 +93,125 @@ union stats_network_node { | |||
| 91 | static stats_network_node *stats_network_counters_root; | 93 | static stats_network_node *stats_network_counters_root; |
| 92 | #endif | 94 | #endif |
| 93 | 95 | ||
| 94 | static int stat_increase_network_count( stats_network_node **pnode, int depth, uintptr_t ip ) { | 96 | static int stat_increase_network_count(stats_network_node **pnode, int depth, uintptr_t ip) { |
| 95 | int foo = __LDR(ip,depth); | 97 | int foo = __LDR(ip, depth); |
| 96 | stats_network_node *node; | 98 | stats_network_node *node; |
| 97 | 99 | ||
| 98 | if( !*pnode ) { | 100 | if (!*pnode) { |
| 99 | *pnode = malloc( sizeof( stats_network_node ) ); | 101 | *pnode = malloc(sizeof(stats_network_node)); |
| 100 | if( !*pnode ) | 102 | if (!*pnode) |
| 101 | return -1; | 103 | return -1; |
| 102 | memset( *pnode, 0, sizeof( stats_network_node ) ); | 104 | memset(*pnode, 0, sizeof(stats_network_node)); |
| 103 | } | 105 | } |
| 104 | node = *pnode; | 106 | node = *pnode; |
| 105 | 107 | ||
| 106 | if( depth < STATS_NETWORK_NODE_MAXDEPTH ) | 108 | if (depth < STATS_NETWORK_NODE_MAXDEPTH) |
| 107 | return stat_increase_network_count( node->children + foo, depth+STATS_NETWORK_NODE_BITWIDTH, ip ); | 109 | return stat_increase_network_count(node->children + foo, depth + STATS_NETWORK_NODE_BITWIDTH, ip); |
| 108 | 110 | ||
| 109 | node->counters[ foo ]++; | 111 | node->counters[foo]++; |
| 110 | return 0; | 112 | return 0; |
| 111 | } | 113 | } |
| 112 | 114 | ||
| 113 | static int stats_shift_down_network_count( stats_network_node **node, int depth, int shift ) { | 115 | static int stats_shift_down_network_count(stats_network_node **node, int depth, int shift) { |
| 114 | int i, rest = 0; | 116 | size_t i, rest = 0; |
| 115 | 117 | ||
| 116 | if( !*node ) | 118 | if (!*node) |
| 117 | return 0; | 119 | return 0; |
| 118 | 120 | ||
| 119 | for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) | 121 | for (i = 0; i < STATS_NETWORK_NODE_COUNT; ++i) |
| 120 | if( depth < STATS_NETWORK_NODE_MAXDEPTH ) | 122 | if (depth < STATS_NETWORK_NODE_MAXDEPTH) |
| 121 | rest += stats_shift_down_network_count( (*node)->children + i, depth+STATS_NETWORK_NODE_BITWIDTH, shift ); | 123 | rest += stats_shift_down_network_count((*node)->children + i, depth + STATS_NETWORK_NODE_BITWIDTH, shift); |
| 122 | else | 124 | else |
| 123 | rest += (*node)->counters[i] >>= shift; | 125 | rest += (*node)->counters[i] >>= shift; |
| 124 | 126 | ||
| 125 | if( !rest ) { | 127 | if (!rest) { |
| 126 | free( *node ); | 128 | free(*node); |
| 127 | *node = NULL; | 129 | *node = NULL; |
| 128 | } | 130 | } |
| 129 | 131 | ||
| 130 | return rest; | 132 | return rest; |
| 131 | } | 133 | } |
| 132 | 134 | ||
| 133 | static size_t stats_get_highscore_networks( stats_network_node *node, int depth, ot_ip6 node_value, size_t *scores, ot_ip6 *networks, int network_count, int limit ) { | 135 | static size_t stats_get_highscore_networks(stats_network_node *node, int depth, ot_ip6 node_value, size_t *scores, ot_ip6 *networks, int network_count, |
| 134 | size_t score = 0; | 136 | int limit) { |
| 135 | int i; | 137 | size_t i, score = 0; |
| 136 | 138 | ||
| 137 | if( !node ) return 0; | 139 | if (!node) |
| 140 | return 0; | ||
| 138 | 141 | ||
| 139 | if( depth < limit ) { | 142 | if (depth < limit) { |
| 140 | for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) | 143 | for (i = 0; i < STATS_NETWORK_NODE_COUNT; ++i) |
| 141 | if( node->children[i] ) { | 144 | if (node->children[i]) { |
| 142 | __STR(node_value,depth,i); | 145 | __STR(node_value, depth, i); |
| 143 | score += stats_get_highscore_networks( node->children[i], depth+STATS_NETWORK_NODE_BITWIDTH, node_value, scores, networks, network_count, limit ); | 146 | score += stats_get_highscore_networks(node->children[i], depth + STATS_NETWORK_NODE_BITWIDTH, node_value, scores, networks, network_count, limit); |
| 144 | } | 147 | } |
| 145 | return score; | 148 | return score; |
| 146 | } | 149 | } |
| 147 | 150 | ||
| 148 | if( depth > limit && depth < STATS_NETWORK_NODE_MAXDEPTH ) { | 151 | if (depth > limit && depth < STATS_NETWORK_NODE_MAXDEPTH) { |
| 149 | for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) | 152 | for (i = 0; i < STATS_NETWORK_NODE_COUNT; ++i) |
| 150 | if( node->children[i] ) | 153 | if (node->children[i]) |
| 151 | score += stats_get_highscore_networks( node->children[i], depth+STATS_NETWORK_NODE_BITWIDTH, node_value, scores, networks, network_count, limit ); | 154 | score += stats_get_highscore_networks(node->children[i], depth + STATS_NETWORK_NODE_BITWIDTH, node_value, scores, networks, network_count, limit); |
| 152 | return score; | 155 | return score; |
| 153 | } | 156 | } |
| 154 | 157 | ||
| 155 | if( depth > limit && depth == STATS_NETWORK_NODE_MAXDEPTH ) { | 158 | if (depth > limit && depth == STATS_NETWORK_NODE_MAXDEPTH) { |
| 156 | for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) | 159 | for (i = 0; i < STATS_NETWORK_NODE_COUNT; ++i) |
| 157 | score += node->counters[i]; | 160 | score += node->counters[i]; |
| 158 | return score; | 161 | return score; |
| 159 | } | 162 | } |
| 160 | 163 | ||
| 161 | /* if( depth == limit ) */ | 164 | /* if( depth == limit ) */ |
| 162 | for( i=0; i<STATS_NETWORK_NODE_COUNT; ++i ) { | 165 | for (i = 0; i < STATS_NETWORK_NODE_COUNT; ++i) { |
| 163 | int j=1; | 166 | int j = 1; |
| 164 | size_t node_score; | 167 | size_t node_score; |
| 165 | 168 | ||
| 166 | if( depth == STATS_NETWORK_NODE_MAXDEPTH ) | 169 | if (depth == STATS_NETWORK_NODE_MAXDEPTH) |
| 167 | node_score = node->counters[i]; | 170 | node_score = node->counters[i]; |
| 168 | else | 171 | else |
| 169 | node_score = stats_get_highscore_networks( node->children[i], depth+STATS_NETWORK_NODE_BITWIDTH, node_value, scores, networks, network_count, limit ); | 172 | node_score = stats_get_highscore_networks(node->children[i], depth + STATS_NETWORK_NODE_BITWIDTH, node_value, scores, networks, network_count, limit); |
| 170 | 173 | ||
| 171 | score += node_score; | 174 | score += node_score; |
| 172 | 175 | ||
| 173 | if( node_score <= scores[0] ) continue; | 176 | if (node_score <= scores[0]) |
| 177 | continue; | ||
| 174 | 178 | ||
| 175 | __STR(node_value,depth,i); | 179 | __STR(node_value, depth, i); |
| 176 | while( j < network_count && node_score > scores[j] ) ++j; | 180 | while (j < network_count && node_score > scores[j]) |
| 181 | ++j; | ||
| 177 | --j; | 182 | --j; |
| 178 | 183 | ||
| 179 | memcpy( scores, scores + 1, j * sizeof( *scores ) ); | 184 | memcpy(scores, scores + 1, j * sizeof(*scores)); |
| 180 | memcpy( networks, networks + 1, j * sizeof( *networks ) ); | 185 | memcpy(networks, networks + 1, j * sizeof(*networks)); |
| 181 | scores[ j ] = node_score; | 186 | scores[j] = node_score; |
| 182 | memcpy( networks + j, node_value, sizeof( *networks ) ); | 187 | memcpy(networks + j, node_value, sizeof(*networks)); |
| 183 | } | 188 | } |
| 184 | 189 | ||
| 185 | return score; | 190 | return score; |
| 186 | } | 191 | } |
| 187 | 192 | ||
| 188 | static size_t stats_return_busy_networks( char * reply, stats_network_node *tree, int amount, int limit ) { | 193 | static size_t stats_return_busy_networks(char *reply, stats_network_node *tree, size_t amount, int limit) { |
| 189 | ot_ip6 networks[amount]; | 194 | ot_ip6 networks[amount]; |
| 190 | ot_ip6 node_value; | 195 | ot_ip6 node_value; |
| 191 | size_t scores[amount]; | 196 | size_t scores[amount]; |
| 192 | int i; | 197 | size_t i; |
| 193 | char * r = reply; | 198 | char *r = reply; |
| 194 | 199 | ||
| 195 | memset( scores, 0, sizeof( scores ) ); | 200 | memset(scores, 0, sizeof(scores)); |
| 196 | memset( networks, 0, sizeof( networks ) ); | 201 | memset(networks, 0, sizeof(networks)); |
| 197 | memset( node_value, 0, sizeof( node_value ) ); | 202 | memset(node_value, 0, sizeof(node_value)); |
| 198 | 203 | ||
| 199 | stats_get_highscore_networks( tree, 0, node_value, scores, networks, amount, limit ); | 204 | stats_get_highscore_networks(tree, 0, node_value, scores, networks, amount, limit); |
| 200 | 205 | ||
| 201 | r += sprintf( r, "Networks, limit /%d:\n", limit+STATS_NETWORK_NODE_BITWIDTH ); | 206 | r += sprintf(r, "Networks, limit /%d:\n", limit + STATS_NETWORK_NODE_BITWIDTH); |
| 202 | for( i=amount-1; i>=0; --i) { | 207 | for (i = amount; i > 0; --i) { |
| 203 | if( scores[i] ) { | 208 | if (scores[i - 1]) { |
| 204 | r += sprintf( r, "%08zd: ", scores[i] ); | 209 | r += sprintf(r, "%08zd: ", scores[i - 1]); |
| 205 | #ifdef WANT_V6 | 210 | // #ifdef WANT_V6 |
| 206 | r += fmt_ip6c( r, networks[i] ); | 211 | r += fmt_ip6c(r, networks[i - 1]); |
| 207 | #else | 212 | #if 0 |
| 208 | r += fmt_ip4( r, networks[i]); | 213 | // XXX |
| 214 | r += fmt_ip4( r, networks[i - 1]); | ||
| 209 | #endif | 215 | #endif |
| 210 | *r++ = '\n'; | 216 | *r++ = '\n'; |
| 211 | } | 217 | } |
| @@ -215,64 +221,65 @@ static size_t stats_return_busy_networks( char * reply, stats_network_node *tree | |||
| 215 | return r - reply; | 221 | return r - reply; |
| 216 | } | 222 | } |
| 217 | 223 | ||
| 218 | static size_t stats_slash24s_txt( char *reply, size_t amount ) { | 224 | static size_t stats_slash24s_txt(char *reply, size_t amount) { |
| 219 | stats_network_node *slash24s_network_counters_root = NULL; | 225 | stats_network_node *slash24s_network_counters_root = NULL; |
| 220 | char *r=reply; | 226 | char *r = reply; |
| 221 | int bucket; | 227 | size_t i, bucket, peer_size = OT_PEER_SIZE4; |
| 222 | size_t i; | ||
| 223 | 228 | ||
| 224 | for( bucket=0; bucket<OT_BUCKET_COUNT; ++bucket ) { | 229 | for (bucket = 0; bucket < OT_BUCKET_COUNT; ++bucket) { |
| 225 | ot_vector *torrents_list = mutex_bucket_lock( bucket ); | 230 | ot_vector *torrents_list = mutex_bucket_lock(bucket); |
| 226 | for( i=0; i<torrents_list->size; ++i ) { | 231 | for (i = 0; i < torrents_list->size; ++i) { |
| 227 | ot_peerlist *peer_list = ( ((ot_torrent*)(torrents_list->data))[i] ).peer_list; | 232 | ot_peerlist *peer_list = (((ot_torrent *)(torrents_list->data))[i]).peer_list4; |
| 228 | ot_vector *bucket_list = &peer_list->peers; | 233 | ot_vector *bucket_list = &peer_list->peers; |
| 229 | int num_buckets = 1; | 234 | int num_buckets = 1; |
| 230 | 235 | ||
| 231 | if( OT_PEERLIST_HASBUCKETS( peer_list ) ) { | 236 | if (OT_PEERLIST_HASBUCKETS(peer_list)) { |
| 232 | num_buckets = bucket_list->size; | 237 | num_buckets = bucket_list->size; |
| 233 | bucket_list = (ot_vector *)bucket_list->data; | 238 | bucket_list = (ot_vector *)bucket_list->data; |
| 234 | } | 239 | } |
| 235 | 240 | ||
| 236 | while( num_buckets-- ) { | 241 | while (num_buckets--) { |
| 237 | ot_peer *peers = (ot_peer*)bucket_list->data; | 242 | ot_peer *peers = (ot_peer *)bucket_list->data; |
| 238 | size_t numpeers = bucket_list->size; | 243 | size_t numpeers = bucket_list->size; |
| 239 | while( numpeers-- ) | 244 | while (numpeers--) { |
| 240 | if( stat_increase_network_count( &slash24s_network_counters_root, 0, (uintptr_t)(peers++) ) ) | 245 | if (stat_increase_network_count(&slash24s_network_counters_root, 0, (uintptr_t)(peers))) |
| 241 | goto bailout_unlock; | 246 | goto bailout_unlock; |
| 247 | peers += peer_size; | ||
| 248 | } | ||
| 242 | ++bucket_list; | 249 | ++bucket_list; |
| 243 | } | 250 | } |
| 244 | } | 251 | } |
| 245 | mutex_bucket_unlock( bucket, 0 ); | 252 | mutex_bucket_unlock(bucket, 0); |
| 246 | if( !g_opentracker_running ) | 253 | if (!g_opentracker_running) |
| 247 | goto bailout_error; | 254 | goto bailout_error; |
| 248 | } | 255 | } |
| 249 | 256 | ||
| 250 | /* The tree is built. Now analyze */ | 257 | /* The tree is built. Now analyze */ |
| 251 | r += stats_return_busy_networks( r, slash24s_network_counters_root, amount, STATS_NETWORK_NODE_MAXDEPTH ); | 258 | r += stats_return_busy_networks(r, slash24s_network_counters_root, amount, STATS_NETWORK_NODE_MAXDEPTH); |
| 252 | r += stats_return_busy_networks( r, slash24s_network_counters_root, amount, STATS_NETWORK_NODE_LIMIT ); | 259 | r += stats_return_busy_networks(r, slash24s_network_counters_root, amount, STATS_NETWORK_NODE_LIMIT); |
| 253 | goto success; | 260 | goto success; |
| 254 | 261 | ||
| 255 | bailout_unlock: | 262 | bailout_unlock: |
| 256 | mutex_bucket_unlock( bucket, 0 ); | 263 | mutex_bucket_unlock(bucket, 0); |
| 257 | bailout_error: | 264 | bailout_error: |
| 258 | r = reply; | 265 | r = reply; |
| 259 | success: | 266 | success: |
| 260 | stats_shift_down_network_count( &slash24s_network_counters_root, 0, sizeof(int)*8-1 ); | 267 | stats_shift_down_network_count(&slash24s_network_counters_root, 0, sizeof(int) * 8 - 1); |
| 261 | 268 | ||
| 262 | return r-reply; | 269 | return r - reply; |
| 263 | } | 270 | } |
| 264 | 271 | ||
| 265 | #ifdef WANT_SPOT_WOODPECKER | 272 | #ifdef WANT_SPOT_WOODPECKER |
| 266 | static stats_network_node *stats_woodpeckers_tree; | 273 | static stats_network_node *stats_woodpeckers_tree; |
| 267 | static pthread_mutex_t g_woodpeckers_mutex = PTHREAD_MUTEX_INITIALIZER; | 274 | static pthread_mutex_t g_woodpeckers_mutex = PTHREAD_MUTEX_INITIALIZER; |
| 268 | 275 | ||
| 269 | static size_t stats_return_woodpeckers( char * reply, int amount ) { | 276 | static size_t stats_return_woodpeckers(char *reply, int amount) { |
| 270 | char * r = reply; | 277 | char *r = reply; |
| 271 | 278 | ||
| 272 | pthread_mutex_lock( &g_woodpeckers_mutex ); | 279 | pthread_mutex_lock(&g_woodpeckers_mutex); |
| 273 | r += stats_return_busy_networks( r, stats_woodpeckers_tree, amount, STATS_NETWORK_NODE_MAXDEPTH ); | 280 | r += stats_return_busy_networks(r, stats_woodpeckers_tree, amount, STATS_NETWORK_NODE_MAXDEPTH); |
| 274 | pthread_mutex_unlock( &g_woodpeckers_mutex ); | 281 | pthread_mutex_unlock(&g_woodpeckers_mutex); |
| 275 | return r-reply; | 282 | return r - reply; |
| 276 | } | 283 | } |
| 277 | #endif | 284 | #endif |
| 278 | 285 | ||
| @@ -282,496 +289,490 @@ typedef struct { | |||
| 282 | unsigned long long seed_count; | 289 | unsigned long long seed_count; |
| 283 | } torrent_stats; | 290 | } torrent_stats; |
| 284 | 291 | ||
| 285 | static int torrent_statter( ot_torrent *torrent, uintptr_t data ) { | 292 | static int torrent_statter(ot_torrent *torrent, uintptr_t data) { |
| 286 | torrent_stats *stats = (torrent_stats*)data; | 293 | torrent_stats *stats = (torrent_stats *)data; |
| 287 | stats->torrent_count++; | 294 | stats->torrent_count++; |
| 288 | stats->peer_count += torrent->peer_list->peer_count; | 295 | stats->peer_count += torrent->peer_list6->peer_count + torrent->peer_list4->peer_count; |
| 289 | stats->seed_count += torrent->peer_list->seed_count; | 296 | stats->seed_count += torrent->peer_list6->seed_count + torrent->peer_list4->seed_count; |
| 290 | return 0; | 297 | return 0; |
| 291 | } | 298 | } |
| 292 | 299 | ||
| 293 | /* Converter function from memory to human readable hex strings */ | 300 | /* Converter function from memory to human readable hex strings */ |
| 294 | 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;} | 301 | static char *to_hex(char *d, uint8_t *s) { |
| 302 | char *m = "0123456789ABCDEF"; | ||
| 303 | char *t = d; | ||
| 304 | char *e = d + 40; | ||
| 305 | while (d < e) { | ||
| 306 | *d++ = m[*s >> 4]; | ||
| 307 | *d++ = m[*s++ & 15]; | ||
| 308 | } | ||
| 309 | *d = 0; | ||
| 310 | return t; | ||
| 311 | } | ||
| 312 | |||
| 313 | typedef struct { | ||
| 314 | size_t val; | ||
| 315 | ot_hash hash; | ||
| 316 | } ot_record; | ||
| 317 | |||
| 318 | static inline void stats_insert_into_highscore(size_t val, ot_record* list, size_t amount, ot_hash* hash) { | ||
| 319 | size_t i; | ||
| 320 | for (i = 0; (i < amount) && (list[i].val > val); ++i) | ||
| 321 | {} | ||
| 322 | /* if we score better than a record in the list, we need to make room in the high | ||
| 323 | score array by moving lower scoring entries up */ | ||
| 324 | if (i < amount) { | ||
| 325 | memmove(list + i + 1, list + i, (amount - i - 1) * sizeof(ot_record)); | ||
| 326 | |||
| 327 | memcpy(&list[i].hash, hash, sizeof(ot_hash)); | ||
| 328 | list[i].val = val; | ||
| 329 | } | ||
| 330 | } | ||
| 295 | 331 | ||
| 296 | typedef struct { size_t val; ot_hash hash; } ot_record; | ||
| 297 | 332 | ||
| 298 | /* Fetches stats from tracker */ | 333 | /* Fetches stats from tracker */ |
| 299 | size_t stats_top_txt( char * reply, int amount ) { | 334 | size_t stats_top_txt(char *reply, size_t amount) { |
| 300 | size_t j; | 335 | size_t j, idx, bucket; |
| 301 | ot_record top100s[100], top100c[100]; | 336 | ot_record top100s[100], top100c[100], top100l[100]; |
| 302 | char *r = reply, hex_out[42]; | 337 | char *r = reply, hex_out[42]; |
| 303 | int idx, bucket; | ||
| 304 | 338 | ||
| 305 | if( amount > 100 ) | 339 | if (amount > 100) |
| 306 | amount = 100; | 340 | amount = 100; |
| 307 | 341 | ||
| 308 | byte_zero( top100s, sizeof( top100s ) ); | 342 | byte_zero(top100s, sizeof(top100s)); |
| 309 | byte_zero( top100c, sizeof( top100c ) ); | 343 | byte_zero(top100c, sizeof(top100c)); |
| 344 | byte_zero(top100l, sizeof(top100l)); | ||
| 310 | 345 | ||
| 311 | for( bucket=0; bucket<OT_BUCKET_COUNT; ++bucket ) { | 346 | /* Iterate over complete torrent list */ |
| 312 | ot_vector *torrents_list = mutex_bucket_lock( bucket ); | 347 | for (bucket = 0; bucket < OT_BUCKET_COUNT; ++bucket) { |
| 313 | for( j=0; j<torrents_list->size; ++j ) { | 348 | ot_vector *torrents_list = mutex_bucket_lock(bucket); |
| 314 | ot_torrent *torrent = (ot_torrent*)(torrents_list->data) + j; | 349 | for (j = 0; j < torrents_list->size; ++j) { |
| 315 | idx = amount - 1; | 350 | ot_torrent *torrent = (ot_torrent *)(torrents_list->data) + j; |
| 316 | while( (idx >= 0) && ( torrent->peer_list->peer_count > top100c[idx].val ) ) | 351 | size_t peer_count = torrent->peer_list6->peer_count + torrent->peer_list4->peer_count; |
| 317 | --idx; | 352 | size_t seed_count = torrent->peer_list6->seed_count + torrent->peer_list4->seed_count; |
| 318 | if ( idx++ != amount - 1 ) { | 353 | size_t leech_count = peer_count - seed_count; |
| 319 | memmove( top100c + idx + 1, top100c + idx, ( amount - 1 - idx ) * sizeof( ot_record ) ); | 354 | |
| 320 | memcpy( &top100c[idx].hash, &torrent->hash, sizeof(ot_hash)); | 355 | stats_insert_into_highscore(peer_count, top100c, amount, &torrent->hash); |
| 321 | top100c[idx].val = torrent->peer_list->peer_count; | 356 | stats_insert_into_highscore(seed_count, top100s, amount, &torrent->hash); |
| 322 | } | 357 | stats_insert_into_highscore(leech_count, top100l, amount, &torrent->hash); |
| 323 | idx = amount - 1; | ||
| 324 | while( (idx >= 0) && ( torrent->peer_list->seed_count > top100s[idx].val ) ) | ||
| 325 | --idx; | ||
| 326 | if ( idx++ != amount - 1 ) { | ||
| 327 | memmove( top100s + idx + 1, top100s + idx, ( amount - 1 - idx ) * sizeof( ot_record ) ); | ||
| 328 | memcpy( &top100s[idx].hash, &torrent->hash, sizeof(ot_hash)); | ||
| 329 | top100s[idx].val = torrent->peer_list->seed_count; | ||
| 330 | } | ||
| 331 | } | 358 | } |
| 332 | mutex_bucket_unlock( bucket, 0 ); | 359 | mutex_bucket_unlock(bucket, 0); |
| 333 | if( !g_opentracker_running ) | 360 | if (!g_opentracker_running) |
| 334 | return 0; | 361 | return 0; |
| 335 | } | 362 | } |
| 336 | 363 | ||
| 337 | r += sprintf( r, "Top %d torrents by peers:\n", amount ); | 364 | r += sprintf(r, "Top %zd torrents by peers:\n", amount); |
| 338 | for( idx=0; idx<amount; ++idx ) | 365 | for (idx = 0; idx < amount; ++idx) |
| 339 | if( top100c[idx].val ) | 366 | if (top100c[idx].val) |
| 340 | r += sprintf( r, "\t%zd\t%s\n", top100c[idx].val, to_hex( hex_out, top100c[idx].hash) ); | 367 | r += sprintf(r, "\t%zd\t%s\n", top100c[idx].val, to_hex(hex_out, top100c[idx].hash)); |
| 341 | r += sprintf( r, "Top %d torrents by seeds:\n", amount ); | 368 | r += sprintf(r, "Top %zd torrents by seeds:\n", amount); |
| 342 | for( idx=0; idx<amount; ++idx ) | 369 | for (idx = 0; idx < amount; ++idx) |
| 343 | if( top100s[idx].val ) | 370 | if (top100s[idx].val) |
| 344 | r += sprintf( r, "\t%zd\t%s\n", top100s[idx].val, to_hex( hex_out, top100s[idx].hash) ); | 371 | r += sprintf(r, "\t%zd\t%s\n", top100s[idx].val, to_hex(hex_out, top100s[idx].hash)); |
| 372 | r += sprintf(r, "Top %zd torrents by leechers:\n", amount); | ||
| 373 | for (idx = 0; idx < amount; ++idx) | ||
| 374 | if (top100l[idx].val) | ||
| 375 | r += sprintf(r, "\t%zd\t%s\n", top100l[idx].val, to_hex(hex_out, top100l[idx].hash)); | ||
| 345 | 376 | ||
| 346 | return r - reply; | 377 | return r - reply; |
| 347 | } | 378 | } |
| 348 | 379 | ||
| 349 | static unsigned long events_per_time( unsigned long long events, time_t t ) { | 380 | static unsigned long events_per_time(unsigned long long events, time_t t) { return events / ((unsigned int)t ? (unsigned int)t : 1); } |
| 350 | return events / ( (unsigned int)t ? (unsigned int)t : 1 ); | ||
| 351 | } | ||
| 352 | 381 | ||
| 353 | static size_t stats_connections_mrtg( char * reply ) { | 382 | static size_t stats_connections_mrtg(char *reply) { |
| 354 | ot_time t = time( NULL ) - ot_start_time; | 383 | ot_time t = time(NULL) - ot_start_time; |
| 355 | return sprintf( reply, | 384 | return sprintf(reply, "%llu\n%llu\n%i seconds (%i hours)\nopentracker connections, %lu conns/s :: %lu success/s.", |
| 356 | "%llu\n%llu\n%i seconds (%i hours)\nopentracker connections, %lu conns/s :: %lu success/s.", | 385 | ot_overall_tcp_connections + ot_overall_udp_connections, |
| 357 | ot_overall_tcp_connections+ot_overall_udp_connections, | 386 | ot_overall_tcp_successfulannounces + ot_overall_udp_successfulannounces + ot_overall_udp_connects, (int)t, (int)(t / 3600), |
| 358 | ot_overall_tcp_successfulannounces+ot_overall_udp_successfulannounces+ot_overall_udp_connects, | 387 | events_per_time(ot_overall_tcp_connections + ot_overall_udp_connections, t), |
| 359 | (int)t, | 388 | events_per_time(ot_overall_tcp_successfulannounces + ot_overall_udp_successfulannounces + ot_overall_udp_connects, t)); |
| 360 | (int)(t / 3600), | ||
| 361 | events_per_time( ot_overall_tcp_connections+ot_overall_udp_connections, t ), | ||
| 362 | events_per_time( ot_overall_tcp_successfulannounces+ot_overall_udp_successfulannounces+ot_overall_udp_connects, t ) | ||
| 363 | ); | ||
| 364 | } | 389 | } |
| 365 | 390 | ||
| 366 | static size_t stats_udpconnections_mrtg( char * reply ) { | 391 | static size_t stats_udpconnections_mrtg(char *reply) { |
| 367 | ot_time t = time( NULL ) - ot_start_time; | 392 | ot_time t = time(NULL) - ot_start_time; |
| 368 | return sprintf( reply, | 393 | return sprintf(reply, "%llu\n%llu\n%i seconds (%i hours)\nopentracker udp4 stats, %lu conns/s :: %lu success/s.", ot_overall_udp_connections, |
| 369 | "%llu\n%llu\n%i seconds (%i hours)\nopentracker udp4 stats, %lu conns/s :: %lu success/s.", | 394 | ot_overall_udp_successfulannounces + ot_overall_udp_connects, (int)t, (int)(t / 3600), events_per_time(ot_overall_udp_connections, t), |
| 370 | ot_overall_udp_connections, | 395 | events_per_time(ot_overall_udp_successfulannounces + ot_overall_udp_connects, t)); |
| 371 | ot_overall_udp_successfulannounces+ot_overall_udp_connects, | ||
| 372 | (int)t, | ||
| 373 | (int)(t / 3600), | ||
| 374 | events_per_time( ot_overall_udp_connections, t ), | ||
| 375 | events_per_time( ot_overall_udp_successfulannounces+ot_overall_udp_connects, t ) | ||
| 376 | ); | ||
| 377 | } | 396 | } |
| 378 | 397 | ||
| 379 | static size_t stats_tcpconnections_mrtg( char * reply ) { | 398 | static size_t stats_tcpconnections_mrtg(char *reply) { |
| 380 | time_t t = time( NULL ) - ot_start_time; | 399 | time_t t = time(NULL) - ot_start_time; |
| 381 | return sprintf( reply, | 400 | return sprintf(reply, "%llu\n%llu\n%i seconds (%i hours)\nopentracker tcp4 stats, %lu conns/s :: %lu success/s.", ot_overall_tcp_connections, |
| 382 | "%llu\n%llu\n%i seconds (%i hours)\nopentracker tcp4 stats, %lu conns/s :: %lu success/s.", | 401 | ot_overall_tcp_successfulannounces, (int)t, (int)(t / 3600), events_per_time(ot_overall_tcp_connections, t), |
| 383 | ot_overall_tcp_connections, | 402 | events_per_time(ot_overall_tcp_successfulannounces, t)); |
| 384 | ot_overall_tcp_successfulannounces, | ||
| 385 | (int)t, | ||
| 386 | (int)(t / 3600), | ||
| 387 | events_per_time( ot_overall_tcp_connections, t ), | ||
| 388 | events_per_time( ot_overall_tcp_successfulannounces, t ) | ||
| 389 | ); | ||
| 390 | } | 403 | } |
| 391 | 404 | ||
| 392 | static size_t stats_scrape_mrtg( char * reply ) { | 405 | static size_t stats_scrape_mrtg(char *reply) { |
| 393 | time_t t = time( NULL ) - ot_start_time; | 406 | time_t t = time(NULL) - ot_start_time; |
| 394 | return sprintf( reply, | 407 | return sprintf(reply, "%llu\n%llu\n%i seconds (%i hours)\nopentracker scrape stats, %lu scrape/s (tcp and udp)", ot_overall_tcp_successfulscrapes, |
| 395 | "%llu\n%llu\n%i seconds (%i hours)\nopentracker scrape stats, %lu scrape/s (tcp and udp)", | 408 | ot_overall_udp_successfulscrapes, (int)t, (int)(t / 3600), |
| 396 | ot_overall_tcp_successfulscrapes, | 409 | events_per_time((ot_overall_tcp_successfulscrapes + ot_overall_udp_successfulscrapes), t)); |
| 397 | ot_overall_udp_successfulscrapes, | ||
| 398 | (int)t, | ||
| 399 | (int)(t / 3600), | ||
| 400 | events_per_time( (ot_overall_tcp_successfulscrapes+ot_overall_udp_successfulscrapes), t ) | ||
| 401 | ); | ||
| 402 | } | 410 | } |
| 403 | 411 | ||
| 404 | static size_t stats_fullscrapes_mrtg( char * reply ) { | 412 | static size_t stats_fullscrapes_mrtg(char *reply) { |
| 405 | ot_time t = time( NULL ) - ot_start_time; | 413 | ot_time t = time(NULL) - ot_start_time; |
| 406 | return sprintf( reply, | 414 | 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, |
| 407 | "%llu\n%llu\n%i seconds (%i hours)\nopentracker full scrape stats, %lu conns/s :: %lu bytes/s.", | 415 | 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)); |
| 408 | ot_full_scrape_count * 1000, | ||
| 409 | ot_full_scrape_size, | ||
| 410 | (int)t, | ||
| 411 | (int)(t / 3600), | ||
| 412 | events_per_time( ot_full_scrape_count, t ), | ||
| 413 | events_per_time( ot_full_scrape_size, t ) | ||
| 414 | ); | ||
| 415 | } | 416 | } |
| 416 | 417 | ||
| 417 | static size_t stats_peers_mrtg( char * reply ) { | 418 | static size_t stats_peers_mrtg(char *reply) { |
| 418 | torrent_stats stats = {0,0,0}; | 419 | torrent_stats stats = {0, 0, 0}; |
| 419 | 420 | ||
| 420 | iterate_all_torrents( torrent_statter, (uintptr_t)&stats ); | 421 | iterate_all_torrents(torrent_statter, (uintptr_t)&stats); |
| 421 | 422 | ||
| 422 | return sprintf( reply, "%llu\n%llu\nopentracker serving %llu torrents\nopentracker", | 423 | return sprintf(reply, "%llu\n%llu\nopentracker serving %llu torrents\nopentracker", stats.peer_count, stats.seed_count, stats.torrent_count); |
| 423 | stats.peer_count, | ||
| 424 | stats.seed_count, | ||
| 425 | stats.torrent_count | ||
| 426 | ); | ||
| 427 | } | 424 | } |
| 428 | 425 | ||
| 429 | static size_t stats_torrents_mrtg( char * reply ) | 426 | static size_t stats_torrents_mrtg(char *reply) { |
| 430 | { | ||
| 431 | size_t torrent_count = mutex_get_torrent_count(); | 427 | size_t torrent_count = mutex_get_torrent_count(); |
| 432 | 428 | ||
| 433 | return sprintf( reply, "%zd\n%zd\nopentracker serving %zd torrents\nopentracker", | 429 | return sprintf(reply, "%zd\n%zd\nopentracker serving %zd torrents\nopentracker", torrent_count, (size_t)0, torrent_count); |
| 434 | torrent_count, | ||
| 435 | (size_t)0, | ||
| 436 | torrent_count | ||
| 437 | ); | ||
| 438 | } | 430 | } |
| 439 | 431 | ||
| 440 | static size_t stats_httperrors_txt ( char * reply ) { | 432 | static size_t stats_httperrors_txt(char *reply) { |
| 441 | return sprintf( reply, "302 RED %llu\n400 ... %llu\n400 PAR %llu\n400 COM %llu\n403 IP %llu\n404 INV %llu\n500 SRV %llu\n", | 433 | return sprintf(reply, "302 RED %llu\n400 ... %llu\n400 PAR %llu\n400 COM %llu\n403 IP %llu\n404 INV %llu\n500 SRV %llu\n", ot_failed_request_counts[0], |
| 442 | ot_failed_request_counts[0], ot_failed_request_counts[1], ot_failed_request_counts[2], | 434 | ot_failed_request_counts[1], ot_failed_request_counts[2], ot_failed_request_counts[3], ot_failed_request_counts[4], |
| 443 | ot_failed_request_counts[3], ot_failed_request_counts[4], ot_failed_request_counts[5], | 435 | ot_failed_request_counts[5], ot_failed_request_counts[6]); |
| 444 | ot_failed_request_counts[6] ); | ||
| 445 | } | 436 | } |
| 446 | 437 | ||
| 447 | static size_t stats_return_renew_bucket( char * reply ) { | 438 | static size_t stats_return_renew_bucket(char *reply) { |
| 448 | char *r = reply; | 439 | char *r = reply; |
| 449 | int i; | 440 | int i; |
| 450 | 441 | ||
| 451 | for( i=0; i<OT_PEER_TIMEOUT; ++i ) | 442 | for (i = 0; i < OT_PEER_TIMEOUT; ++i) |
| 452 | r+=sprintf(r,"%02i %llu\n", i, ot_renewed[i] ); | 443 | r += sprintf(r, "%02i %llu\n", i, ot_renewed[i]); |
| 453 | return r - reply; | 444 | return r - reply; |
| 454 | } | 445 | } |
| 455 | 446 | ||
| 456 | static size_t stats_return_sync_mrtg( char * reply ) { | 447 | static size_t stats_return_sync_mrtg(char *reply) { |
| 457 | ot_time t = time( NULL ) - ot_start_time; | 448 | ot_time t = time(NULL) - ot_start_time; |
| 458 | return sprintf( reply, | 449 | return sprintf(reply, "%llu\n%llu\n%i seconds (%i hours)\nopentracker connections, %lu conns/s :: %lu success/s.", ot_overall_sync_count, 0LL, (int)t, |
| 459 | "%llu\n%llu\n%i seconds (%i hours)\nopentracker connections, %lu conns/s :: %lu success/s.", | 450 | (int)(t / 3600), events_per_time(ot_overall_tcp_connections + ot_overall_udp_connections, t), |
| 460 | ot_overall_sync_count, | 451 | events_per_time(ot_overall_tcp_successfulannounces + ot_overall_udp_successfulannounces + ot_overall_udp_connects, t)); |
| 461 | 0LL, | ||
| 462 | (int)t, | ||
| 463 | (int)(t / 3600), | ||
| 464 | events_per_time( ot_overall_tcp_connections+ot_overall_udp_connections, t ), | ||
| 465 | events_per_time( ot_overall_tcp_successfulannounces+ot_overall_udp_successfulannounces+ot_overall_udp_connects, t ) | ||
| 466 | ); | ||
| 467 | } | 452 | } |
| 468 | 453 | ||
| 469 | static size_t stats_return_completed_mrtg( char * reply ) { | 454 | static size_t stats_return_completed_mrtg(char *reply) { |
| 470 | ot_time t = time( NULL ) - ot_start_time; | 455 | ot_time t = time(NULL) - ot_start_time; |
| 471 | 456 | ||
| 472 | return sprintf( reply, | 457 | return sprintf(reply, "%llu\n%llu\n%i seconds (%i hours)\nopentracker, %lu completed/h.", ot_overall_completed, 0LL, (int)t, (int)(t / 3600), |
| 473 | "%llu\n%llu\n%i seconds (%i hours)\nopentracker, %lu completed/h.", | 458 | events_per_time(ot_overall_completed, t / 3600)); |
| 474 | ot_overall_completed, | ||
| 475 | 0LL, | ||
| 476 | (int)t, | ||
| 477 | (int)(t / 3600), | ||
| 478 | events_per_time( ot_overall_completed, t / 3600 ) | ||
| 479 | ); | ||
| 480 | } | 459 | } |
| 481 | 460 | ||
| 482 | #ifdef WANT_LOG_NUMWANT | 461 | #ifdef WANT_LOG_NUMWANT |
| 483 | extern unsigned long long numwants[201]; | 462 | extern unsigned long long numwants[201]; |
| 484 | static size_t stats_return_numwants( char * reply ) { | 463 | static size_t stats_return_numwants(char *reply) { |
| 485 | char * r = reply; | 464 | char *r = reply; |
| 486 | int i; | 465 | int i; |
| 487 | for( i=0; i<=200; ++i ) | 466 | for (i = 0; i <= 200; ++i) |
| 488 | r += sprintf( r, "%03d => %lld\n", i, numwants[i] ); | 467 | r += sprintf(r, "%03d => %lld\n", i, numwants[i]); |
| 489 | return r-reply; | 468 | return r - reply; |
| 490 | } | 469 | } |
| 491 | #endif | 470 | #endif |
| 492 | 471 | ||
| 493 | #ifdef WANT_FULLLOG_NETWORKS | 472 | #ifdef WANT_FULLLOG_NETWORKS |
| 494 | static void stats_return_fulllog( int *iovec_entries, struct iovec **iovector, char *r ) { | 473 | static void stats_return_fulllog(size_t *iovec_entries, struct iovec **iovector, char *r) { |
| 495 | ot_log *loglist = g_logchain_first, *llnext; | 474 | ot_log *loglist = g_logchain_first, *llnext; |
| 496 | char * re = r + OT_STATS_TMPSIZE; | 475 | char *re = r + OT_STATS_TMPSIZE; |
| 497 | 476 | ||
| 498 | g_logchain_first = g_logchain_last = 0; | 477 | g_logchain_first = g_logchain_last = 0; |
| 499 | 478 | ||
| 500 | while( loglist ) { | 479 | while (loglist) { |
| 501 | if( r + ( loglist->size + 64 ) >= re ) { | 480 | if (r + (loglist->size + 64) >= re) { |
| 502 | r = iovec_fix_increase_or_free( iovec_entries, iovector, r, 32 * OT_STATS_TMPSIZE ); | 481 | r = iovec_fix_increase_or_free(iovec_entries, iovector, r, 32 * OT_STATS_TMPSIZE); |
| 503 | if( !r ) return; | 482 | if (!r) |
| 483 | return; | ||
| 504 | re = r + 32 * OT_STATS_TMPSIZE; | 484 | re = r + 32 * OT_STATS_TMPSIZE; |
| 505 | } | 485 | } |
| 506 | r += sprintf( r, "%08ld: ", loglist->time ); | 486 | r += sprintf(r, "%08ld: ", loglist->time); |
| 507 | r += fmt_ip6c( r, loglist->ip ); | 487 | r += fmt_ip6c(r, loglist->ip); |
| 508 | *r++ = '\n'; | 488 | *r++ = '\n'; |
| 509 | memcpy( r, loglist->data, loglist->size ); | 489 | memcpy(r, loglist->data, loglist->size); |
| 510 | r += loglist->size; | 490 | r += loglist->size; |
| 511 | *r++ = '\n'; | 491 | *r++ = '\n'; |
| 512 | *r++ = '*'; | 492 | *r++ = '*'; |
| 513 | *r++ = '\n'; | 493 | *r++ = '\n'; |
| 514 | *r++ = '\n'; | 494 | *r++ = '\n'; |
| 515 | 495 | ||
| 516 | llnext = loglist->next; | 496 | llnext = loglist->next; |
| 517 | free( loglist->data ); | 497 | free(loglist->data); |
| 518 | free( loglist ); | 498 | free(loglist); |
| 519 | loglist = llnext; | 499 | loglist = llnext; |
| 520 | } | 500 | } |
| 521 | iovec_fixlast( iovec_entries, iovector, r ); | 501 | iovec_fixlast(iovec_entries, iovector, r); |
| 522 | } | 502 | } |
| 523 | #endif | 503 | #endif |
| 524 | 504 | ||
| 525 | static size_t stats_return_everything( char * reply ) { | 505 | static size_t stats_return_everything(char *reply) { |
| 526 | torrent_stats stats = {0,0,0}; | 506 | torrent_stats stats = {0, 0, 0}; |
| 527 | int i; | 507 | int i; |
| 528 | char * r = reply; | 508 | char *r = reply; |
| 529 | 509 | ||
| 530 | iterate_all_torrents( torrent_statter, (uintptr_t)&stats ); | 510 | iterate_all_torrents(torrent_statter, (uintptr_t)&stats); |
| 531 | 511 | ||
| 532 | r += sprintf( r, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ); | 512 | r += sprintf(r, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); |
| 533 | r += sprintf( r, "<stats>\n" ); | 513 | r += sprintf(r, "<stats>\n"); |
| 534 | r += sprintf( r, " <tracker_id>%" PRIu32 "</tracker_id>\n", g_tracker_id ); | 514 | r += sprintf(r, " <tracker_id>%" PRIu32 "</tracker_id>\n", g_tracker_id); |
| 535 | r += sprintf( r, " <version>\n" ); r += stats_return_tracker_version( r ); r += sprintf( r, " </version>\n" ); | 515 | r += sprintf(r, " <version>\n"); |
| 536 | r += sprintf( r, " <uptime>%llu</uptime>\n", (unsigned long long)(time( NULL ) - ot_start_time) ); | 516 | r += stats_return_tracker_version(r); |
| 537 | r += sprintf( r, " <torrents>\n" ); | 517 | r += sprintf(r, " </version>\n"); |
| 538 | r += sprintf( r, " <count_mutex>%zd</count_mutex>\n", mutex_get_torrent_count() ); | 518 | r += sprintf(r, " <uptime>%llu</uptime>\n", (unsigned long long)(time(NULL) - ot_start_time)); |
| 539 | r += sprintf( r, " <count_iterator>%llu</count_iterator>\n", stats.torrent_count ); | 519 | r += sprintf(r, " <torrents>\n"); |
| 540 | r += sprintf( r, " </torrents>\n" ); | 520 | r += sprintf(r, " <count_mutex>%zd</count_mutex>\n", mutex_get_torrent_count()); |
| 541 | r += sprintf( r, " <peers>\n <count>%llu</count>\n </peers>\n", stats.peer_count ); | 521 | r += sprintf(r, " <count_iterator>%llu</count_iterator>\n", stats.torrent_count); |
| 542 | r += sprintf( r, " <seeds>\n <count>%llu</count>\n </seeds>\n", stats.seed_count ); | 522 | r += sprintf(r, " </torrents>\n"); |
| 543 | r += sprintf( r, " <completed>\n <count>%llu</count>\n </completed>\n", ot_overall_completed ); | 523 | r += sprintf(r, " <peers>\n <count>%llu</count>\n </peers>\n", stats.peer_count); |
| 544 | r += sprintf( r, " <connections>\n" ); | 524 | r += sprintf(r, " <seeds>\n <count>%llu</count>\n </seeds>\n", stats.seed_count); |
| 545 | r += sprintf( r, " <tcp>\n <accept>%llu</accept>\n <announce>%llu</announce>\n <scrape>%llu</scrape>\n </tcp>\n", ot_overall_tcp_connections, ot_overall_tcp_successfulannounces, ot_overall_tcp_successfulscrapes ); | 525 | r += sprintf(r, " <completed>\n <count>%llu</count>\n </completed>\n", ot_overall_completed); |
| 546 | r += sprintf( r, " <udp>\n <overall>%llu</overall>\n <connect>%llu</connect>\n <announce>%llu</announce>\n <scrape>%llu</scrape>\n <missmatch>%llu</missmatch>\n </udp>\n", ot_overall_udp_connections, ot_overall_udp_connects, ot_overall_udp_successfulannounces, ot_overall_udp_successfulscrapes, ot_overall_udp_connectionidmissmatches ); | 526 | r += sprintf(r, " <connections>\n"); |
| 547 | r += sprintf( r, " <livesync>\n <count>%llu</count>\n </livesync>\n", ot_overall_sync_count ); | 527 | r += sprintf(r, " <tcp>\n <accept>%llu</accept>\n <announce>%llu</announce>\n <scrape>%llu</scrape>\n </tcp>\n", |
| 548 | r += sprintf( r, " </connections>\n" ); | 528 | ot_overall_tcp_connections, ot_overall_tcp_successfulannounces, ot_overall_tcp_successfulscrapes); |
| 549 | r += sprintf( r, " <debug>\n" ); | 529 | r += sprintf(r, " <udp>\n <overall>%llu</overall>\n <connect>%llu</connect>\n <announce>%llu</announce>\n <scrape>%llu</scrape>\n <missmatch>%llu</missmatch>\n </udp>\n", |
| 550 | r += sprintf( r, " <renew>\n" ); | 530 | ot_overall_udp_connections, ot_overall_udp_connects, ot_overall_udp_successfulannounces, ot_overall_udp_successfulscrapes, |
| 551 | for( i=0; i<OT_PEER_TIMEOUT; ++i ) | 531 | ot_overall_udp_connectionidmissmatches); |
| 552 | r += sprintf( r, " <count interval=\"%02i\">%llu</count>\n", i, ot_renewed[i] ); | 532 | r += sprintf(r, " <livesync>\n <count>%llu</count>\n </livesync>\n", ot_overall_sync_count); |
| 553 | r += sprintf( r, " </renew>\n" ); | 533 | r += sprintf(r, " </connections>\n"); |
| 554 | r += sprintf( r, " <http_error>\n" ); | 534 | r += sprintf(r, " <debug>\n"); |
| 555 | for( i=0; i<CODE_HTTPERROR_COUNT; ++i ) | 535 | r += sprintf(r, " <renew>\n"); |
| 556 | r += sprintf( r, " <count code=\"%s\">%llu</count>\n", ot_failed_request_names[i], ot_failed_request_counts[i] ); | 536 | for (i = 0; i < OT_PEER_TIMEOUT; ++i) |
| 557 | r += sprintf( r, " </http_error>\n" ); | 537 | r += sprintf(r, " <count interval=\"%02i\">%llu</count>\n", i, ot_renewed[i]); |
| 558 | r += sprintf( r, " <mutex_stall>\n <count>%llu</count>\n </mutex_stall>\n", ot_overall_stall_count ); | 538 | r += sprintf(r, " </renew>\n"); |
| 559 | r += sprintf( r, " </debug>\n" ); | 539 | r += sprintf(r, " <http_error>\n"); |
| 560 | r += sprintf( r, "</stats>" ); | 540 | for (i = 0; i < CODE_HTTPERROR_COUNT; ++i) |
| 541 | r += sprintf(r, " <count code=\"%s\">%llu</count>\n", ot_failed_request_names[i], ot_failed_request_counts[i]); | ||
| 542 | r += sprintf(r, " </http_error>\n"); | ||
| 543 | r += sprintf(r, " <mutex_stall>\n <count>%llu</count>\n </mutex_stall>\n", ot_overall_stall_count); | ||
| 544 | r += sprintf(r, " </debug>\n"); | ||
| 545 | r += sprintf(r, "</stats>"); | ||
| 561 | return r - reply; | 546 | return r - reply; |
| 562 | } | 547 | } |
| 563 | 548 | ||
| 564 | extern const char | 549 | size_t stats_return_tracker_version(char *reply) { |
| 565 | *g_version_opentracker_c, *g_version_accesslist_c, *g_version_clean_c, *g_version_fullscrape_c, *g_version_http_c, | 550 | #define QUOTE(name) #name |
| 566 | *g_version_iovec_c, *g_version_mutex_c, *g_version_stats_c, *g_version_udp_c, *g_version_vector_c, | 551 | #define SQUOTE(name) QUOTE(name) |
| 567 | *g_version_scan_urlencoded_query_c, *g_version_trackerlogic_c, *g_version_livesync_c, *g_version_rijndael_c; | 552 | return sprintf(reply, "https://erdgeist.org/gitweb/opentracker/commit/?id=" SQUOTE(GIT_VERSION) "\n"); |
| 568 | |||
| 569 | size_t stats_return_tracker_version( char *reply ) { | ||
| 570 | return sprintf( reply, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s", | ||
| 571 | g_version_opentracker_c, g_version_accesslist_c, g_version_clean_c, g_version_fullscrape_c, g_version_http_c, | ||
| 572 | g_version_iovec_c, g_version_mutex_c, g_version_stats_c, g_version_udp_c, g_version_vector_c, | ||
| 573 | g_version_scan_urlencoded_query_c, g_version_trackerlogic_c, g_version_livesync_c, g_version_rijndael_c ); | ||
| 574 | } | 553 | } |
| 575 | 554 | ||
| 576 | size_t return_stats_for_tracker( char *reply, int mode, int format ) { | 555 | size_t return_stats_for_tracker(char *reply, int mode, int format) { |
| 577 | (void) format; | 556 | (void)format; |
| 578 | switch( mode & TASK_TASK_MASK ) { | 557 | switch (mode & TASK_TASK_MASK) { |
| 579 | case TASK_STATS_CONNS: | 558 | case TASK_STATS_CONNS: |
| 580 | return stats_connections_mrtg( reply ); | 559 | return stats_connections_mrtg(reply); |
| 581 | case TASK_STATS_SCRAPE: | 560 | case TASK_STATS_SCRAPE: |
| 582 | return stats_scrape_mrtg( reply ); | 561 | return stats_scrape_mrtg(reply); |
| 583 | case TASK_STATS_UDP: | 562 | case TASK_STATS_UDP: |
| 584 | return stats_udpconnections_mrtg( reply ); | 563 | return stats_udpconnections_mrtg(reply); |
| 585 | case TASK_STATS_TCP: | 564 | case TASK_STATS_TCP: |
| 586 | return stats_tcpconnections_mrtg( reply ); | 565 | return stats_tcpconnections_mrtg(reply); |
| 587 | case TASK_STATS_FULLSCRAPE: | 566 | case TASK_STATS_FULLSCRAPE: |
| 588 | return stats_fullscrapes_mrtg( reply ); | 567 | return stats_fullscrapes_mrtg(reply); |
| 589 | case TASK_STATS_COMPLETED: | 568 | case TASK_STATS_COMPLETED: |
| 590 | return stats_return_completed_mrtg( reply ); | 569 | return stats_return_completed_mrtg(reply); |
| 591 | case TASK_STATS_HTTPERRORS: | 570 | case TASK_STATS_HTTPERRORS: |
| 592 | return stats_httperrors_txt( reply ); | 571 | return stats_httperrors_txt(reply); |
| 593 | case TASK_STATS_VERSION: | 572 | case TASK_STATS_VERSION: |
| 594 | return stats_return_tracker_version( reply ); | 573 | return stats_return_tracker_version(reply); |
| 595 | case TASK_STATS_RENEW: | 574 | case TASK_STATS_RENEW: |
| 596 | return stats_return_renew_bucket( reply ); | 575 | return stats_return_renew_bucket(reply); |
| 597 | case TASK_STATS_SYNCS: | 576 | case TASK_STATS_SYNCS: |
| 598 | return stats_return_sync_mrtg( reply ); | 577 | return stats_return_sync_mrtg(reply); |
| 599 | #ifdef WANT_LOG_NUMWANT | 578 | #ifdef WANT_LOG_NUMWANT |
| 600 | case TASK_STATS_NUMWANTS: | 579 | case TASK_STATS_NUMWANTS: |
| 601 | return stats_return_numwants( reply ); | 580 | return stats_return_numwants(reply); |
| 602 | #endif | 581 | #endif |
| 603 | default: | 582 | default: |
| 604 | return 0; | 583 | return 0; |
| 605 | } | 584 | } |
| 606 | } | 585 | } |
| 607 | 586 | ||
| 608 | static void stats_make( int *iovec_entries, struct iovec **iovector, ot_tasktype mode ) { | 587 | static void stats_make(size_t *iovec_entries, struct iovec **iovector, ot_tasktype mode) { |
| 609 | char *r; | 588 | char *r; |
| 610 | 589 | ||
| 611 | *iovec_entries = 0; | 590 | *iovec_entries = 0; |
| 612 | *iovector = NULL; | 591 | *iovector = NULL; |
| 613 | if( !( r = iovec_increase( iovec_entries, iovector, OT_STATS_TMPSIZE ) ) ) | 592 | if (!(r = iovec_increase(iovec_entries, iovector, OT_STATS_TMPSIZE))) |
| 614 | return; | 593 | return; |
| 615 | 594 | ||
| 616 | switch( mode & TASK_TASK_MASK ) { | 595 | switch (mode & TASK_TASK_MASK) { |
| 617 | case TASK_STATS_TORRENTS: r += stats_torrents_mrtg( r ); break; | 596 | case TASK_STATS_TORRENTS: |
| 618 | case TASK_STATS_PEERS: r += stats_peers_mrtg( r ); break; | 597 | r += stats_torrents_mrtg(r); |
| 619 | case TASK_STATS_SLASH24S: r += stats_slash24s_txt( r, 128 ); break; | 598 | break; |
| 620 | case TASK_STATS_TOP10: r += stats_top_txt( r, 10 ); break; | 599 | case TASK_STATS_PEERS: |
| 621 | case TASK_STATS_TOP100: | 600 | r += stats_peers_mrtg(r); |
| 622 | r = iovec_fix_increase_or_free( iovec_entries, iovector, r, 4 * OT_STATS_TMPSIZE ); | 601 | break; |
| 623 | if( !r ) return; | 602 | case TASK_STATS_SLASH24S: |
| 624 | r += stats_top_txt( r, 100 ); break; | 603 | r += stats_slash24s_txt(r, 128); |
| 625 | case TASK_STATS_EVERYTHING: r += stats_return_everything( r ); break; | 604 | break; |
| 605 | case TASK_STATS_TOP10: | ||
| 606 | r += stats_top_txt(r, 10); | ||
| 607 | break; | ||
| 608 | case TASK_STATS_TOP100: | ||
| 609 | r = iovec_fix_increase_or_free(iovec_entries, iovector, r, 4 * OT_STATS_TMPSIZE); | ||
| 610 | if (!r) | ||
| 611 | return; | ||
| 612 | r += stats_top_txt(r, 100); | ||
| 613 | break; | ||
| 614 | case TASK_STATS_EVERYTHING: | ||
| 615 | r = iovec_fix_increase_or_free(iovec_entries, iovector, r, OT_STATS_TMPSIZE + 64 * OT_PEER_TIMEOUT); | ||
| 616 | if (!r) | ||
| 617 | return; | ||
| 618 | r += stats_return_everything(r); | ||
| 619 | break; | ||
| 626 | #ifdef WANT_SPOT_WOODPECKER | 620 | #ifdef WANT_SPOT_WOODPECKER |
| 627 | case TASK_STATS_WOODPECKERS: r += stats_return_woodpeckers( r, 128 ); break; | 621 | case TASK_STATS_WOODPECKERS: |
| 622 | r += stats_return_woodpeckers(r, 128); | ||
| 623 | break; | ||
| 628 | #endif | 624 | #endif |
| 629 | #ifdef WANT_FULLLOG_NETWORKS | 625 | #ifdef WANT_FULLLOG_NETWORKS |
| 630 | case TASK_STATS_FULLLOG: stats_return_fulllog( iovec_entries, iovector, r ); | 626 | case TASK_STATS_FULLLOG: |
| 631 | return; | 627 | stats_return_fulllog(iovec_entries, iovector, r); |
| 628 | return; | ||
| 632 | #endif | 629 | #endif |
| 633 | default: | 630 | default: |
| 634 | iovec_free(iovec_entries, iovector); | 631 | iovec_free(iovec_entries, iovector); |
| 635 | return; | 632 | return; |
| 636 | } | 633 | } |
| 637 | iovec_fixlast( iovec_entries, iovector, r ); | 634 | iovec_fixlast(iovec_entries, iovector, r); |
| 638 | } | 635 | } |
| 639 | 636 | ||
| 640 | void stats_issue_event( ot_status_event event, PROTO_FLAG proto, uintptr_t event_data ) { | 637 | void stats_issue_event(ot_status_event event, PROTO_FLAG proto, uintptr_t event_data) { |
| 641 | switch( event ) { | 638 | switch (event) { |
| 642 | case EVENT_ACCEPT: | 639 | case EVENT_ACCEPT: |
| 643 | if( proto == FLAG_TCP ) ot_overall_tcp_connections++; else ot_overall_udp_connections++; | 640 | if (proto == FLAG_TCP) |
| 641 | ot_overall_tcp_connections++; | ||
| 642 | else | ||
| 643 | ot_overall_udp_connections++; | ||
| 644 | #ifdef WANT_LOG_NETWORKS | 644 | #ifdef WANT_LOG_NETWORKS |
| 645 | stat_increase_network_count( &stats_network_counters_root, 0, event_data ); | 645 | stat_increase_network_count(&stats_network_counters_root, 0, event_data); |
| 646 | #endif | 646 | #endif |
| 647 | break; | 647 | break; |
| 648 | case EVENT_ANNOUNCE: | 648 | case EVENT_ANNOUNCE: |
| 649 | if( proto == FLAG_TCP ) ot_overall_tcp_successfulannounces++; else ot_overall_udp_successfulannounces++; | 649 | if (proto == FLAG_TCP) |
| 650 | break; | 650 | ot_overall_tcp_successfulannounces++; |
| 651 | case EVENT_CONNECT: | 651 | else |
| 652 | if( proto == FLAG_TCP ) ot_overall_tcp_connects++; else ot_overall_udp_connects++; | 652 | ot_overall_udp_successfulannounces++; |
| 653 | break; | 653 | break; |
| 654 | case EVENT_COMPLETED: | 654 | case EVENT_CONNECT: |
| 655 | if (proto == FLAG_TCP) | ||
| 656 | ot_overall_tcp_connects++; | ||
| 657 | else | ||
| 658 | ot_overall_udp_connects++; | ||
| 659 | break; | ||
| 660 | case EVENT_COMPLETED: | ||
| 655 | #ifdef WANT_SYSLOGS | 661 | #ifdef WANT_SYSLOGS |
| 656 | if( event_data) { | 662 | if (event_data) { |
| 657 | struct ot_workstruct *ws = (struct ot_workstruct *)event_data; | 663 | struct ot_workstruct *ws = (struct ot_workstruct *)event_data; |
| 658 | char timestring[64]; | 664 | char timestring[64]; |
| 659 | char hash_hex[42], peerid_hex[42], ip_readable[64]; | 665 | char hash_hex[42], peerid_hex[42], ip_readable[64]; |
| 660 | struct tm time_now; | 666 | struct tm time_now; |
| 661 | time_t ttt; | 667 | time_t ttt; |
| 662 | 668 | ||
| 663 | time( &ttt ); | 669 | time(&ttt); |
| 664 | localtime_r( &ttt, &time_now ); | 670 | localtime_r(&ttt, &time_now); |
| 665 | strftime( timestring, sizeof( timestring ), "%FT%T%z", &time_now ); | 671 | strftime(timestring, sizeof(timestring), "%FT%T%z", &time_now); |
| 666 | 672 | ||
| 667 | to_hex( hash_hex, *ws->hash ); | 673 | to_hex(hash_hex, *ws->hash); |
| 668 | if( ws->peer_id ) | 674 | if (ws->peer_id) |
| 669 | to_hex( peerid_hex, (uint8_t*)ws->peer_id ); | 675 | to_hex(peerid_hex, (uint8_t *)ws->peer_id); |
| 670 | else { | 676 | else { |
| 671 | *peerid_hex=0; | 677 | *peerid_hex = 0; |
| 672 | } | 678 | } |
| 673 | 679 | ||
| 674 | #ifdef WANT_V6 | 680 | ip_readable[fmt_ip6c(ip_readable, (char *)&ws->peer)] = 0; |
| 675 | ip_readable[ fmt_ip6c( ip_readable, (char*)&ws->peer ) ] = 0; | 681 | #if 0 |
| 676 | #else | 682 | /* XXX */ |
| 677 | ip_readable[ fmt_ip4( ip_readable, (char*)&ws->peer ) ] = 0; | 683 | ip_readable[ fmt_ip4( ip_readable, (char*)&ws->peer ) ] = 0; |
| 678 | #endif | 684 | #endif |
| 679 | syslog( LOG_INFO, "time=%s event=completed info_hash=%s peer_id=%s ip=%s", timestring, hash_hex, peerid_hex, ip_readable ); | 685 | syslog(LOG_INFO, "time=%s event=completed info_hash=%s peer_id=%s ip=%s", timestring, hash_hex, peerid_hex, ip_readable); |
| 680 | } | ||
| 681 | #endif | ||
| 682 | ot_overall_completed++; | ||
| 683 | break; | ||
| 684 | case EVENT_SCRAPE: | ||
| 685 | if( proto == FLAG_TCP ) ot_overall_tcp_successfulscrapes++; else ot_overall_udp_successfulscrapes++; | ||
| 686 | break; | ||
| 687 | case EVENT_FULLSCRAPE: | ||
| 688 | ot_full_scrape_count++; | ||
| 689 | ot_full_scrape_size += event_data; | ||
| 690 | break; | ||
| 691 | case EVENT_FULLSCRAPE_REQUEST: | ||
| 692 | { | ||
| 693 | ot_ip6 *ip = (ot_ip6*)event_data; /* ugly hack to transfer ip to stats */ | ||
| 694 | char _debug[512]; | ||
| 695 | int off = snprintf( _debug, sizeof(_debug), "[%08d] scrp: ", (unsigned int)(g_now_seconds - ot_start_time)/60 ); | ||
| 696 | off += fmt_ip6c( _debug+off, *ip ); | ||
| 697 | off += snprintf( _debug+off, sizeof(_debug)-off, " - FULL SCRAPE\n" ); | ||
| 698 | (void)write( 2, _debug, off ); | ||
| 699 | ot_full_scrape_request_count++; | ||
| 700 | } | ||
| 701 | break; | ||
| 702 | case EVENT_FULLSCRAPE_REQUEST_GZIP: | ||
| 703 | { | ||
| 704 | ot_ip6 *ip = (ot_ip6*)event_data; /* ugly hack to transfer ip to stats */ | ||
| 705 | char _debug[512]; | ||
| 706 | int off = snprintf( _debug, sizeof(_debug), "[%08d] scrp: ", (unsigned int)(g_now_seconds - ot_start_time)/60 ); | ||
| 707 | off += fmt_ip6c(_debug+off, *ip ); | ||
| 708 | off += snprintf( _debug+off, sizeof(_debug)-off, " - FULL SCRAPE\n" ); | ||
| 709 | (void)write( 2, _debug, off ); | ||
| 710 | ot_full_scrape_request_count++; | ||
| 711 | } | 686 | } |
| 712 | break; | 687 | #endif |
| 713 | case EVENT_FAILED: | 688 | ot_overall_completed++; |
| 714 | ot_failed_request_counts[event_data]++; | 689 | break; |
| 715 | break; | 690 | case EVENT_SCRAPE: |
| 716 | case EVENT_RENEW: | 691 | if (proto == FLAG_TCP) |
| 717 | ot_renewed[event_data]++; | 692 | ot_overall_tcp_successfulscrapes++; |
| 718 | break; | 693 | else |
| 719 | case EVENT_SYNC: | 694 | ot_overall_udp_successfulscrapes++; |
| 720 | ot_overall_sync_count+=event_data; | 695 | break; |
| 721 | break; | 696 | case EVENT_FULLSCRAPE: |
| 722 | case EVENT_BUCKET_LOCKED: | 697 | ot_full_scrape_count++; |
| 723 | ot_overall_stall_count++; | 698 | ot_full_scrape_size += event_data; |
| 724 | break; | 699 | break; |
| 700 | case EVENT_FULLSCRAPE_REQUEST: { | ||
| 701 | ot_ip6 *ip = (ot_ip6 *)event_data; /* ugly hack to transfer ip to stats */ | ||
| 702 | char _debug[512]; | ||
| 703 | int off = snprintf(_debug, sizeof(_debug), "[%08d] scrp: ", (unsigned int)(g_now_seconds - ot_start_time) / 60); | ||
| 704 | off += fmt_ip6c(_debug + off, *ip); | ||
| 705 | off += snprintf(_debug + off, sizeof(_debug) - off, " - FULL SCRAPE\n"); | ||
| 706 | (void)write(2, _debug, off); | ||
| 707 | ot_full_scrape_request_count++; | ||
| 708 | } break; | ||
| 709 | case EVENT_FULLSCRAPE_REQUEST_GZIP: { | ||
| 710 | ot_ip6 *ip = (ot_ip6 *)event_data; /* ugly hack to transfer ip to stats */ | ||
| 711 | char _debug[512]; | ||
| 712 | int off = snprintf(_debug, sizeof(_debug), "[%08d] scrp: ", (unsigned int)(g_now_seconds - ot_start_time) / 60); | ||
| 713 | off += fmt_ip6c(_debug + off, *ip); | ||
| 714 | off += snprintf(_debug + off, sizeof(_debug) - off, " - FULL SCRAPE\n"); | ||
| 715 | (void)write(2, _debug, off); | ||
| 716 | ot_full_scrape_request_count++; | ||
| 717 | } break; | ||
| 718 | case EVENT_FAILED: | ||
| 719 | ot_failed_request_counts[event_data]++; | ||
| 720 | break; | ||
| 721 | case EVENT_RENEW: | ||
| 722 | ot_renewed[event_data]++; | ||
| 723 | break; | ||
| 724 | case EVENT_SYNC: | ||
| 725 | ot_overall_sync_count += event_data; | ||
| 726 | break; | ||
| 727 | case EVENT_BUCKET_LOCKED: | ||
| 728 | ot_overall_stall_count++; | ||
| 729 | break; | ||
| 725 | #ifdef WANT_SPOT_WOODPECKER | 730 | #ifdef WANT_SPOT_WOODPECKER |
| 726 | case EVENT_WOODPECKER: | 731 | case EVENT_WOODPECKER: |
| 727 | pthread_mutex_lock( &g_woodpeckers_mutex ); | 732 | pthread_mutex_lock(&g_woodpeckers_mutex); |
| 728 | stat_increase_network_count( &stats_woodpeckers_tree, 0, event_data ); | 733 | stat_increase_network_count(&stats_woodpeckers_tree, 0, event_data); |
| 729 | pthread_mutex_unlock( &g_woodpeckers_mutex ); | 734 | pthread_mutex_unlock(&g_woodpeckers_mutex); |
| 730 | break; | 735 | break; |
| 731 | #endif | 736 | #endif |
| 732 | case EVENT_CONNID_MISSMATCH: | 737 | case EVENT_CONNID_MISSMATCH: |
| 733 | ++ot_overall_udp_connectionidmissmatches; | 738 | ++ot_overall_udp_connectionidmissmatches; |
| 734 | default: | 739 | default: |
| 735 | break; | 740 | break; |
| 736 | } | 741 | } |
| 737 | } | 742 | } |
| 738 | 743 | ||
| 739 | void stats_cleanup() { | 744 | void stats_cleanup(void) { |
| 740 | #ifdef WANT_SPOT_WOODPECKER | 745 | #ifdef WANT_SPOT_WOODPECKER |
| 741 | pthread_mutex_lock( &g_woodpeckers_mutex ); | 746 | pthread_mutex_lock(&g_woodpeckers_mutex); |
| 742 | stats_shift_down_network_count( &stats_woodpeckers_tree, 0, 1 ); | 747 | stats_shift_down_network_count(&stats_woodpeckers_tree, 0, 1); |
| 743 | pthread_mutex_unlock( &g_woodpeckers_mutex ); | 748 | pthread_mutex_unlock(&g_woodpeckers_mutex); |
| 744 | #endif | 749 | #endif |
| 745 | } | 750 | } |
| 746 | 751 | ||
| 747 | static void * stats_worker( void * args ) { | 752 | static void *stats_worker(void *args) { |
| 748 | int iovec_entries; | 753 | size_t iovec_entries; |
| 749 | struct iovec *iovector; | 754 | struct iovec *iovector; |
| 750 | 755 | ||
| 751 | (void) args; | 756 | (void)args; |
| 752 | 757 | ||
| 753 | while( 1 ) { | 758 | while (1) { |
| 754 | ot_tasktype tasktype = TASK_STATS; | 759 | ot_tasktype tasktype = TASK_STATS; |
| 755 | ot_taskid taskid = mutex_workqueue_poptask( &tasktype ); | 760 | ot_taskid taskid = mutex_workqueue_poptask(&tasktype); |
| 756 | stats_make( &iovec_entries, &iovector, tasktype ); | 761 | stats_make(&iovec_entries, &iovector, tasktype); |
| 757 | if( mutex_workqueue_pushresult( taskid, iovec_entries, iovector ) ) | 762 | if (mutex_workqueue_pushresult(taskid, iovec_entries, iovector)) |
| 758 | iovec_free( &iovec_entries, &iovector ); | 763 | iovec_free(&iovec_entries, &iovector); |
| 759 | } | 764 | } |
| 760 | return NULL; | 765 | return NULL; |
| 761 | } | 766 | } |
| 762 | 767 | ||
| 763 | void stats_deliver( int64 sock, int tasktype ) { | 768 | void stats_deliver(int64 sock, int tasktype) { mutex_workqueue_pushtask(sock, tasktype); } |
| 764 | mutex_workqueue_pushtask( sock, tasktype ); | ||
| 765 | } | ||
| 766 | 769 | ||
| 767 | static pthread_t thread_id; | 770 | static pthread_t thread_id; |
| 768 | void stats_init( ) { | 771 | void stats_init(void) { |
| 769 | ot_start_time = g_now_seconds; | 772 | ot_start_time = g_now_seconds; |
| 770 | pthread_create( &thread_id, NULL, stats_worker, NULL ); | 773 | pthread_create(&thread_id, NULL, stats_worker, NULL); |
| 771 | } | 774 | } |
| 772 | 775 | ||
| 773 | void stats_deinit( ) { | 776 | void stats_deinit(void) { |
| 774 | pthread_cancel( thread_id ); | 777 | pthread_cancel(thread_id); |
| 775 | } | 778 | } |
| 776 | |||
| 777 | const char *g_version_stats_c = "$Source$: $Revision$\n"; | ||
