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