/src/libtorrent/src/session_stats.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | |
3 | | Copyright (c) 2014-2021, Arvid Norberg |
4 | | Copyright (c) 2016-2017, Alden Torres |
5 | | Copyright (c) 2019, Steven Siloti |
6 | | Copyright (c) 2020, FranciscoPombal |
7 | | All rights reserved. |
8 | | |
9 | | Redistribution and use in source and binary forms, with or without |
10 | | modification, are permitted provided that the following conditions |
11 | | are met: |
12 | | |
13 | | * Redistributions of source code must retain the above copyright |
14 | | notice, this list of conditions and the following disclaimer. |
15 | | * Redistributions in binary form must reproduce the above copyright |
16 | | notice, this list of conditions and the following disclaimer in |
17 | | the documentation and/or other materials provided with the distribution. |
18 | | * Neither the name of the author nor the names of its |
19 | | contributors may be used to endorse or promote products derived |
20 | | from this software without specific prior written permission. |
21 | | |
22 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
23 | | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
24 | | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
25 | | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
26 | | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
27 | | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
28 | | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
29 | | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
30 | | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
31 | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
32 | | POSSIBILITY OF SUCH DAMAGE. |
33 | | |
34 | | */ |
35 | | |
36 | | #include "libtorrent/session_stats.hpp" // for stats_metric |
37 | | #include "libtorrent/aux_/vector.hpp" |
38 | | #include "libtorrent/performance_counters.hpp" // for counters |
39 | | |
40 | | #include <cstring> |
41 | | #include <algorithm> |
42 | | |
43 | | namespace libtorrent { |
44 | | |
45 | | #if TORRENT_ABI_VERSION == 1 |
46 | | constexpr metric_type_t stats_metric::type_counter; |
47 | | constexpr metric_type_t stats_metric::type_gauge; |
48 | | #endif |
49 | | |
50 | | namespace { |
51 | | |
52 | | struct stats_metric_impl |
53 | | { |
54 | | char const* name; |
55 | | int value_index; |
56 | | }; |
57 | | |
58 | | #define METRIC(category, name) { #category "." #name, counters:: name }, |
59 | | aux::array<stats_metric_impl, counters::num_counters> const metrics |
60 | | ({{ |
61 | | // ``error_peers`` is the total number of peer disconnects |
62 | | // caused by an error (not initiated by this client) and |
63 | | // disconnected initiated by this client (``disconnected_peers``). |
64 | | METRIC(peer, error_peers) |
65 | | METRIC(peer, disconnected_peers) |
66 | | |
67 | | // these counters break down the peer errors into more specific |
68 | | // categories. These errors are what the underlying transport |
69 | | // reported (i.e. TCP or uTP) |
70 | | METRIC(peer, eof_peers) |
71 | | METRIC(peer, connreset_peers) |
72 | | METRIC(peer, connrefused_peers) |
73 | | METRIC(peer, connaborted_peers) |
74 | | METRIC(peer, notconnected_peers) |
75 | | METRIC(peer, perm_peers) |
76 | | METRIC(peer, buffer_peers) |
77 | | METRIC(peer, unreachable_peers) |
78 | | METRIC(peer, broken_pipe_peers) |
79 | | METRIC(peer, addrinuse_peers) |
80 | | METRIC(peer, no_access_peers) |
81 | | METRIC(peer, invalid_arg_peers) |
82 | | METRIC(peer, aborted_peers) |
83 | | |
84 | | // the total number of incoming piece requests we've received followed |
85 | | // by the number of rejected piece requests for various reasons. |
86 | | // max_piece_requests mean we already had too many outstanding requests |
87 | | // from this peer, so we rejected it. cancelled_piece_requests are ones |
88 | | // where the other end explicitly asked for the piece to be rejected. |
89 | | METRIC(peer, piece_requests) |
90 | | METRIC(peer, max_piece_requests) |
91 | | METRIC(peer, invalid_piece_requests) |
92 | | METRIC(peer, choked_piece_requests) |
93 | | METRIC(peer, cancelled_piece_requests) |
94 | | METRIC(peer, piece_rejects) |
95 | | |
96 | | // these counters break down the peer errors into |
97 | | // whether they happen on incoming or outgoing peers. |
98 | | METRIC(peer, error_incoming_peers) |
99 | | METRIC(peer, error_outgoing_peers) |
100 | | |
101 | | // these counters break down the peer errors into |
102 | | // whether they happen on encrypted peers (just |
103 | | // encrypted handshake) and rc4 peers (full stream |
104 | | // encryption). These can indicate whether encrypted |
105 | | // peers are more or less likely to fail |
106 | | METRIC(peer, error_rc4_peers) |
107 | | METRIC(peer, error_encrypted_peers) |
108 | | |
109 | | // these counters break down the peer errors into |
110 | | // whether they happen on uTP peers or TCP peers. |
111 | | // these may indicate whether one protocol is |
112 | | // more error prone |
113 | | METRIC(peer, error_tcp_peers) |
114 | | METRIC(peer, error_utp_peers) |
115 | | |
116 | | // these counters break down the reasons to |
117 | | // disconnect peers. |
118 | | METRIC(peer, connect_timeouts) |
119 | | METRIC(peer, uninteresting_peers) |
120 | | METRIC(peer, timeout_peers) |
121 | | METRIC(peer, no_memory_peers) |
122 | | METRIC(peer, too_many_peers) |
123 | | METRIC(peer, transport_timeout_peers) |
124 | | METRIC(peer, num_banned_peers) |
125 | | METRIC(peer, banned_for_hash_failure) |
126 | | |
127 | | METRIC(peer, connection_attempts) |
128 | | METRIC(peer, connection_attempt_loops) |
129 | | METRIC(peer, boost_connection_attempts) |
130 | | METRIC(peer, missed_connection_attempts) |
131 | | METRIC(peer, no_peer_connection_attempts) |
132 | | METRIC(peer, incoming_connections) |
133 | | |
134 | | // the number of peer connections for each kind of socket. |
135 | | // ``num_peers_half_open`` counts half-open (connecting) peers, no other |
136 | | // count includes those peers. |
137 | | // ``num_peers_up_unchoked_all`` is the total number of unchoked peers, |
138 | | // whereas ``num_peers_up_unchoked`` only are unchoked peers that count |
139 | | // against the limit (i.e. excluding peers that are unchoked because the |
140 | | // limit doesn't apply to them). ``num_peers_up_unchoked_optimistic`` is |
141 | | // the number of optimistically unchoked peers. |
142 | | METRIC(peer, num_tcp_peers) |
143 | | METRIC(peer, num_socks5_peers) |
144 | | METRIC(peer, num_http_proxy_peers) |
145 | | METRIC(peer, num_utp_peers) |
146 | | METRIC(peer, num_i2p_peers) |
147 | | METRIC(peer, num_ssl_peers) |
148 | | METRIC(peer, num_ssl_socks5_peers) |
149 | | METRIC(peer, num_ssl_http_proxy_peers) |
150 | | METRIC(peer, num_ssl_utp_peers) |
151 | | |
152 | | METRIC(peer, num_peers_half_open) |
153 | | METRIC(peer, num_peers_connected) |
154 | | METRIC(peer, num_peers_up_interested) |
155 | | METRIC(peer, num_peers_down_interested) |
156 | | METRIC(peer, num_peers_up_unchoked_all) |
157 | | METRIC(peer, num_peers_up_unchoked_optimistic) |
158 | | METRIC(peer, num_peers_up_unchoked) |
159 | | METRIC(peer, num_peers_down_unchoked) |
160 | | METRIC(peer, num_peers_up_requests) |
161 | | METRIC(peer, num_peers_down_requests) |
162 | | METRIC(peer, num_peers_end_game) |
163 | | METRIC(peer, num_peers_up_disk) |
164 | | METRIC(peer, num_peers_down_disk) |
165 | | |
166 | | // These counters count the number of times the |
167 | | // network thread wakes up for each respective |
168 | | // reason. If these counters are very large, it |
169 | | // may indicate a performance issue, causing the |
170 | | // network thread to wake up too ofte, wasting CPU. |
171 | | // mitigate it by increasing buffers and limits |
172 | | // for the specific trigger that wakes up the |
173 | | // thread. |
174 | | METRIC(net, on_read_counter) |
175 | | METRIC(net, on_write_counter) |
176 | | METRIC(net, on_tick_counter) |
177 | | METRIC(net, on_lsd_counter) |
178 | | METRIC(net, on_lsd_peer_counter) |
179 | | METRIC(net, on_udp_counter) |
180 | | METRIC(net, on_accept_counter) |
181 | | METRIC(net, on_disk_queue_counter) |
182 | | METRIC(net, on_disk_counter) |
183 | | |
184 | | // total number of bytes sent and received by the session |
185 | | METRIC(net, sent_payload_bytes) |
186 | | METRIC(net, sent_bytes) |
187 | | METRIC(net, sent_ip_overhead_bytes) |
188 | | METRIC(net, sent_tracker_bytes) |
189 | | METRIC(net, recv_payload_bytes) |
190 | | METRIC(net, recv_bytes) |
191 | | METRIC(net, recv_ip_overhead_bytes) |
192 | | METRIC(net, recv_tracker_bytes) |
193 | | |
194 | | // the number of sockets currently waiting for upload and download |
195 | | // bandwidth from the rate limiter. |
196 | | METRIC(net, limiter_up_queue) |
197 | | METRIC(net, limiter_down_queue) |
198 | | |
199 | | // the number of upload and download bytes waiting to be handed out from |
200 | | // the rate limiter. |
201 | | METRIC(net, limiter_up_bytes) |
202 | | METRIC(net, limiter_down_bytes) |
203 | | |
204 | | // the number of bytes downloaded that had to be discarded because they |
205 | | // failed the hash check |
206 | | METRIC(net, recv_failed_bytes) |
207 | | |
208 | | // the number of downloaded bytes that were discarded because they |
209 | | // were downloaded multiple times (from different peers) |
210 | | METRIC(net, recv_redundant_bytes) |
211 | | |
212 | | // is false by default and set to true when |
213 | | // the first incoming connection is established |
214 | | // this is used to know if the client is behind |
215 | | // NAT or not. |
216 | | METRIC(net, has_incoming_connections) |
217 | | |
218 | | // these gauges count the number of torrents in |
219 | | // different states. Each torrent only belongs to |
220 | | // one of these states. For torrents that could |
221 | | // belong to multiple of these, the most prominent |
222 | | // in picked. For instance, a torrent with an error |
223 | | // counts as an error-torrent, regardless of its other |
224 | | // state. |
225 | | METRIC(ses, num_checking_torrents) |
226 | | METRIC(ses, num_stopped_torrents) |
227 | | METRIC(ses, num_upload_only_torrents) |
228 | | METRIC(ses, num_downloading_torrents) |
229 | | METRIC(ses, num_seeding_torrents) |
230 | | METRIC(ses, num_queued_seeding_torrents) |
231 | | METRIC(ses, num_queued_download_torrents) |
232 | | METRIC(ses, num_error_torrents) |
233 | | |
234 | | // the number of torrents that don't have the |
235 | | // IP filter applied to them. |
236 | | METRIC(ses, non_filter_torrents) |
237 | | |
238 | | // these count the number of times a piece has passed the |
239 | | // hash check, the number of times a piece was successfully |
240 | | // written to disk and the number of total possible pieces |
241 | | // added by adding torrents. e.g. when adding a torrent with |
242 | | // 1000 piece, num_total_pieces_added is incremented by 1000. |
243 | | METRIC(ses, num_piece_passed) |
244 | | METRIC(ses, num_piece_failed) |
245 | | |
246 | | METRIC(ses, num_have_pieces) |
247 | | METRIC(ses, num_total_pieces_added) |
248 | | |
249 | | // the number of allowed unchoked peers |
250 | | METRIC(ses, num_unchoke_slots) |
251 | | |
252 | | // the number of listen sockets that are currently accepting incoming |
253 | | // connections |
254 | | METRIC(ses, num_outstanding_accept) |
255 | | |
256 | | // bittorrent message counters. These counters are incremented |
257 | | // every time a message of the corresponding type is received from |
258 | | // or sent to a bittorrent peer. |
259 | | METRIC(ses, num_incoming_choke) |
260 | | METRIC(ses, num_incoming_unchoke) |
261 | | METRIC(ses, num_incoming_interested) |
262 | | METRIC(ses, num_incoming_not_interested) |
263 | | METRIC(ses, num_incoming_have) |
264 | | METRIC(ses, num_incoming_bitfield) |
265 | | METRIC(ses, num_incoming_request) |
266 | | METRIC(ses, num_incoming_piece) |
267 | | METRIC(ses, num_incoming_cancel) |
268 | | METRIC(ses, num_incoming_dht_port) |
269 | | METRIC(ses, num_incoming_suggest) |
270 | | METRIC(ses, num_incoming_have_all) |
271 | | METRIC(ses, num_incoming_have_none) |
272 | | METRIC(ses, num_incoming_reject) |
273 | | METRIC(ses, num_incoming_allowed_fast) |
274 | | METRIC(ses, num_incoming_ext_handshake) |
275 | | METRIC(ses, num_incoming_pex) |
276 | | METRIC(ses, num_incoming_metadata) |
277 | | METRIC(ses, num_incoming_extended) |
278 | | |
279 | | METRIC(ses, num_outgoing_choke) |
280 | | METRIC(ses, num_outgoing_unchoke) |
281 | | METRIC(ses, num_outgoing_interested) |
282 | | METRIC(ses, num_outgoing_not_interested) |
283 | | METRIC(ses, num_outgoing_have) |
284 | | METRIC(ses, num_outgoing_bitfield) |
285 | | METRIC(ses, num_outgoing_request) |
286 | | METRIC(ses, num_outgoing_piece) |
287 | | METRIC(ses, num_outgoing_cancel) |
288 | | METRIC(ses, num_outgoing_dht_port) |
289 | | METRIC(ses, num_outgoing_suggest) |
290 | | METRIC(ses, num_outgoing_have_all) |
291 | | METRIC(ses, num_outgoing_have_none) |
292 | | METRIC(ses, num_outgoing_reject) |
293 | | METRIC(ses, num_outgoing_allowed_fast) |
294 | | METRIC(ses, num_outgoing_ext_handshake) |
295 | | METRIC(ses, num_outgoing_pex) |
296 | | METRIC(ses, num_outgoing_metadata) |
297 | | METRIC(ses, num_outgoing_extended) |
298 | | METRIC(ses, num_outgoing_hash_request) |
299 | | METRIC(ses, num_outgoing_hashes) |
300 | | METRIC(ses, num_outgoing_hash_reject) |
301 | | |
302 | | // the number of wasted downloaded bytes by reason of the bytes being |
303 | | // wasted. |
304 | | METRIC(ses, waste_piece_timed_out) |
305 | | METRIC(ses, waste_piece_cancelled) |
306 | | METRIC(ses, waste_piece_unknown) |
307 | | METRIC(ses, waste_piece_seed) |
308 | | METRIC(ses, waste_piece_end_game) |
309 | | METRIC(ses, waste_piece_closing) |
310 | | |
311 | | // the number of pieces considered while picking pieces |
312 | | METRIC(picker, piece_picker_partial_loops) |
313 | | METRIC(picker, piece_picker_suggest_loops) |
314 | | METRIC(picker, piece_picker_sequential_loops) |
315 | | METRIC(picker, piece_picker_reverse_rare_loops) |
316 | | METRIC(picker, piece_picker_rare_loops) |
317 | | METRIC(picker, piece_picker_rand_start_loops) |
318 | | METRIC(picker, piece_picker_rand_loops) |
319 | | METRIC(picker, piece_picker_busy_loops) |
320 | | |
321 | | // This breaks down the piece picks into the event that |
322 | | // triggered it |
323 | | METRIC(picker, reject_piece_picks) |
324 | | METRIC(picker, unchoke_piece_picks) |
325 | | METRIC(picker, incoming_redundant_piece_picks) |
326 | | METRIC(picker, incoming_piece_picks) |
327 | | METRIC(picker, end_game_piece_picks) |
328 | | METRIC(picker, snubbed_piece_picks) |
329 | | METRIC(picker, interesting_piece_picks) |
330 | | METRIC(picker, hash_fail_piece_picks) |
331 | | |
332 | | // the number of microseconds it takes from receiving a request from a |
333 | | // peer until we're sending the response back on the socket. |
334 | | METRIC(disk, request_latency) |
335 | | |
336 | | METRIC(disk, disk_blocks_in_use) |
337 | | |
338 | | // ``queued_disk_jobs`` is the number of disk jobs currently queued, |
339 | | // waiting to be executed by a disk thread. |
340 | | METRIC(disk, queued_disk_jobs) |
341 | | METRIC(disk, num_running_disk_jobs) |
342 | | METRIC(disk, num_read_jobs) |
343 | | METRIC(disk, num_write_jobs) |
344 | | METRIC(disk, num_jobs) |
345 | | METRIC(disk, blocked_disk_jobs) |
346 | | |
347 | | METRIC(disk, num_writing_threads) |
348 | | METRIC(disk, num_running_threads) |
349 | | |
350 | | // the number of bytes we have sent to the disk I/O |
351 | | // thread for writing. Every time we hear back from |
352 | | // the disk I/O thread with a completed write job, this |
353 | | // is updated to the number of bytes the disk I/O thread |
354 | | // is actually waiting for to be written (as opposed to |
355 | | // bytes just hanging out in the cache) |
356 | | METRIC(disk, queued_write_bytes) |
357 | | |
358 | | // the number of blocks written and read from disk in total. A block is 16 |
359 | | // kiB. ``num_blocks_written`` and ``num_blocks_read`` |
360 | | METRIC(disk, num_blocks_written) |
361 | | METRIC(disk, num_blocks_read) |
362 | | |
363 | | // the total number of blocks run through SHA-1 hashing |
364 | | METRIC(disk, num_blocks_hashed) |
365 | | |
366 | | // the number of disk I/O operation for reads and writes. One disk |
367 | | // operation may transfer more then one block. |
368 | | METRIC(disk, num_write_ops) |
369 | | METRIC(disk, num_read_ops) |
370 | | |
371 | | // the number of blocks that had to be read back from disk in order to |
372 | | // hash a piece (when verifying against the piece hash) |
373 | | METRIC(disk, num_read_back) |
374 | | |
375 | | // cumulative time spent in various disk jobs, as well |
376 | | // as total for all disk jobs. Measured in microseconds |
377 | | METRIC(disk, disk_read_time) |
378 | | METRIC(disk, disk_write_time) |
379 | | METRIC(disk, disk_hash_time) |
380 | | METRIC(disk, disk_job_time) |
381 | | |
382 | | // for each kind of disk job, a counter of how many jobs of that kind |
383 | | // are currently blocked by a disk fence |
384 | | METRIC(disk, num_fenced_read) |
385 | | METRIC(disk, num_fenced_write) |
386 | | METRIC(disk, num_fenced_hash) |
387 | | METRIC(disk, num_fenced_move_storage) |
388 | | METRIC(disk, num_fenced_release_files) |
389 | | METRIC(disk, num_fenced_delete_files) |
390 | | METRIC(disk, num_fenced_check_fastresume) |
391 | | METRIC(disk, num_fenced_save_resume_data) |
392 | | METRIC(disk, num_fenced_rename_file) |
393 | | METRIC(disk, num_fenced_stop_torrent) |
394 | | METRIC(disk, num_fenced_flush_piece) |
395 | | METRIC(disk, num_fenced_flush_hashed) |
396 | | METRIC(disk, num_fenced_flush_storage) |
397 | | METRIC(disk, num_fenced_file_priority) |
398 | | METRIC(disk, num_fenced_load_torrent) |
399 | | METRIC(disk, num_fenced_clear_piece) |
400 | | METRIC(disk, num_fenced_tick_storage) |
401 | | |
402 | | // The number of nodes in the DHT routing table |
403 | | METRIC(dht, dht_nodes) |
404 | | |
405 | | // The number of replacement nodes in the DHT routing table |
406 | | METRIC(dht, dht_node_cache) |
407 | | |
408 | | // the number of torrents currently tracked by our DHT node |
409 | | METRIC(dht, dht_torrents) |
410 | | |
411 | | // the number of peers currently tracked by our DHT node |
412 | | METRIC(dht, dht_peers) |
413 | | |
414 | | // the number of immutable data items tracked by our DHT node |
415 | | METRIC(dht, dht_immutable_data) |
416 | | |
417 | | // the number of mutable data items tracked by our DHT node |
418 | | METRIC(dht, dht_mutable_data) |
419 | | |
420 | | // the number of RPC observers currently allocated |
421 | | METRIC(dht, dht_allocated_observers) |
422 | | |
423 | | // the total number of DHT messages sent and received |
424 | | METRIC(dht, dht_messages_in) |
425 | | METRIC(dht, dht_messages_out) |
426 | | |
427 | | // the number of incoming DHT requests that were dropped. There are a few |
428 | | // different reasons why incoming DHT packets may be dropped: |
429 | | // |
430 | | // 1. there wasn't enough send quota to respond to them. |
431 | | // 2. the Denial of service logic kicked in, blocking the peer |
432 | | // 3. ignore_dark_internet is enabled, and the packet came from a |
433 | | // non-public IP address |
434 | | // 4. the bencoding of the message was invalid |
435 | | METRIC(dht, dht_messages_in_dropped) |
436 | | |
437 | | // the number of outgoing messages that failed to be |
438 | | // sent |
439 | | METRIC(dht, dht_messages_out_dropped) |
440 | | |
441 | | // the total number of bytes sent and received by the DHT |
442 | | METRIC(dht, dht_bytes_in) |
443 | | METRIC(dht, dht_bytes_out) |
444 | | |
445 | | // the number of DHT messages we've sent and received |
446 | | // by kind. |
447 | | METRIC(dht, dht_ping_in) |
448 | | METRIC(dht, dht_ping_out) |
449 | | METRIC(dht, dht_find_node_in) |
450 | | METRIC(dht, dht_find_node_out) |
451 | | METRIC(dht, dht_get_peers_in) |
452 | | METRIC(dht, dht_get_peers_out) |
453 | | METRIC(dht, dht_announce_peer_in) |
454 | | METRIC(dht, dht_announce_peer_out) |
455 | | METRIC(dht, dht_get_in) |
456 | | METRIC(dht, dht_get_out) |
457 | | METRIC(dht, dht_put_in) |
458 | | METRIC(dht, dht_put_out) |
459 | | METRIC(dht, dht_sample_infohashes_in) |
460 | | METRIC(dht, dht_sample_infohashes_out) |
461 | | |
462 | | // the number of failed incoming DHT requests by kind of request |
463 | | METRIC(dht, dht_invalid_announce) |
464 | | METRIC(dht, dht_invalid_get_peers) |
465 | | METRIC(dht, dht_invalid_find_node) |
466 | | METRIC(dht, dht_invalid_put) |
467 | | METRIC(dht, dht_invalid_get) |
468 | | METRIC(dht, dht_invalid_sample_infohashes) |
469 | | |
470 | | // The number of times a lost packet has been interpreted as congestion, |
471 | | // cutting the congestion window in half. Some lost packets are not |
472 | | // interpreted as congestion, notably MTU-probes |
473 | | METRIC(utp, utp_packet_loss) |
474 | | |
475 | | // The number of timeouts experienced. This is when a connection doesn't |
476 | | // hear back from the other end within a sliding average RTT + 2 average |
477 | | // deviations from the mean (approximately). The actual time out is |
478 | | // configurable and also depends on the state of the socket. |
479 | | METRIC(utp, utp_timeout) |
480 | | |
481 | | // The total number of packets sent and received |
482 | | METRIC(utp, utp_packets_in) |
483 | | METRIC(utp, utp_packets_out) |
484 | | |
485 | | // The number of packets lost but re-sent by the fast-retransmit logic. |
486 | | // This logic is triggered after 3 duplicate ACKs. |
487 | | METRIC(utp, utp_fast_retransmit) |
488 | | |
489 | | // The number of packets that were re-sent, for whatever reason |
490 | | METRIC(utp, utp_packet_resend) |
491 | | |
492 | | // The number of incoming packets where the delay samples were above |
493 | | // and below the delay target, respectively. The delay target is |
494 | | // configurable and is a parameter to the LEDBAT congestion control. |
495 | | METRIC(utp, utp_samples_above_target) |
496 | | METRIC(utp, utp_samples_below_target) |
497 | | |
498 | | // The total number of packets carrying payload received and sent, |
499 | | // respectively. |
500 | | METRIC(utp, utp_payload_pkts_in) |
501 | | METRIC(utp, utp_payload_pkts_out) |
502 | | |
503 | | // The number of packets received that are not valid uTP packets (but |
504 | | // were sufficiently similar to not be treated as DHT or UDP tracker |
505 | | // packets). |
506 | | METRIC(utp, utp_invalid_pkts_in) |
507 | | |
508 | | // The number of duplicate payload packets received. This may happen if |
509 | | // the outgoing ACK is lost. |
510 | | METRIC(utp, utp_redundant_pkts_in) |
511 | | |
512 | | // the number of uTP sockets in each respective state |
513 | | METRIC(utp, num_utp_idle) |
514 | | METRIC(utp, num_utp_syn_sent) |
515 | | METRIC(utp, num_utp_connected) |
516 | | METRIC(utp, num_utp_fin_sent) |
517 | | METRIC(utp, num_utp_close_wait) |
518 | | METRIC(utp, num_utp_deleted) |
519 | | |
520 | | // the buffer sizes accepted by |
521 | | // socket send and receive calls respectively. |
522 | | // The larger the buffers are, the more efficient, |
523 | | // because it require fewer system calls per byte. |
524 | | // The size is 1 << n, where n is the number |
525 | | // at the end of the counter name. i.e. |
526 | | // 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, |
527 | | // 16384, 32768, 65536, 131072, 262144, 524288, 1048576 |
528 | | // bytes |
529 | | METRIC(sock_bufs, socket_send_size3) |
530 | | METRIC(sock_bufs, socket_send_size4) |
531 | | METRIC(sock_bufs, socket_send_size5) |
532 | | METRIC(sock_bufs, socket_send_size6) |
533 | | METRIC(sock_bufs, socket_send_size7) |
534 | | METRIC(sock_bufs, socket_send_size8) |
535 | | METRIC(sock_bufs, socket_send_size9) |
536 | | METRIC(sock_bufs, socket_send_size10) |
537 | | METRIC(sock_bufs, socket_send_size11) |
538 | | METRIC(sock_bufs, socket_send_size12) |
539 | | METRIC(sock_bufs, socket_send_size13) |
540 | | METRIC(sock_bufs, socket_send_size14) |
541 | | METRIC(sock_bufs, socket_send_size15) |
542 | | METRIC(sock_bufs, socket_send_size16) |
543 | | METRIC(sock_bufs, socket_send_size17) |
544 | | METRIC(sock_bufs, socket_send_size18) |
545 | | METRIC(sock_bufs, socket_send_size19) |
546 | | METRIC(sock_bufs, socket_send_size20) |
547 | | METRIC(sock_bufs, socket_recv_size3) |
548 | | METRIC(sock_bufs, socket_recv_size4) |
549 | | METRIC(sock_bufs, socket_recv_size5) |
550 | | METRIC(sock_bufs, socket_recv_size6) |
551 | | METRIC(sock_bufs, socket_recv_size7) |
552 | | METRIC(sock_bufs, socket_recv_size8) |
553 | | METRIC(sock_bufs, socket_recv_size9) |
554 | | METRIC(sock_bufs, socket_recv_size10) |
555 | | METRIC(sock_bufs, socket_recv_size11) |
556 | | METRIC(sock_bufs, socket_recv_size12) |
557 | | METRIC(sock_bufs, socket_recv_size13) |
558 | | METRIC(sock_bufs, socket_recv_size14) |
559 | | METRIC(sock_bufs, socket_recv_size15) |
560 | | METRIC(sock_bufs, socket_recv_size16) |
561 | | METRIC(sock_bufs, socket_recv_size17) |
562 | | METRIC(sock_bufs, socket_recv_size18) |
563 | | METRIC(sock_bufs, socket_recv_size19) |
564 | | METRIC(sock_bufs, socket_recv_size20) |
565 | | |
566 | | // if the outstanding tracker announce limit is reached, tracker |
567 | | // announces are queued, to be issued when an announce slot opens up. |
568 | | // this measure the number of tracker announces currently in the |
569 | | // queue |
570 | | METRIC(tracker, num_queued_tracker_announces) |
571 | | // ... more |
572 | | }}); |
573 | | #undef METRIC |
574 | | } // anonymous namespace |
575 | | |
576 | | std::vector<stats_metric> session_stats_metrics() |
577 | 0 | { |
578 | 0 | aux::vector<stats_metric> stats; |
579 | 0 | stats.resize(metrics.size()); |
580 | 0 | for (int i = 0; i < metrics.end_index(); ++i) |
581 | 0 | { |
582 | 0 | stats[i].name = metrics[i].name; |
583 | 0 | stats[i].value_index = metrics[i].value_index; |
584 | 0 | stats[i].type = metrics[i].value_index >= counters::num_stats_counters |
585 | 0 | ? metric_type_t::gauge : metric_type_t::counter; |
586 | 0 | } |
587 | 0 | return TORRENT_RVO(stats); |
588 | 0 | } |
589 | | |
590 | | int find_metric_idx(string_view name) |
591 | 0 | { |
592 | 0 | auto const i = std::find_if(std::begin(metrics), std::end(metrics) |
593 | 0 | , [name](stats_metric_impl const& metr) |
594 | 0 | { return metr.name == name; }); |
595 | |
|
596 | 0 | if (i == std::end(metrics)) return -1; |
597 | 0 | return i->value_index; |
598 | 0 | } |
599 | | } |