1 /* Copyright (c) 2021, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
5 * @file relay_metrics.c
6 * @brief Relay metrics exposed through the MetricsPort
9 #define RELAY_METRICS_ENTRY_PRIVATE
13 #include "core/or/or.h"
14 #include "core/mainloop/connection.h"
15 #include "core/mainloop/mainloop.h"
16 #include "core/or/congestion_control_common.h"
17 #include "core/or/congestion_control_vegas.h"
18 #include "core/or/congestion_control_flow.h"
19 #include "core/or/circuitlist.h"
20 #include "core/or/dos.h"
21 #include "core/or/relay.h"
23 #include "app/config/config.h"
25 #include "lib/container/smartlist.h"
26 #include "lib/log/util_bug.h"
27 #include "lib/malloc/malloc.h"
28 #include "lib/math/fp.h"
29 #include "lib/metrics/metrics_store.h"
31 #include "feature/hs/hs_dos.h"
32 #include "feature/nodelist/nodelist.h"
33 #include "feature/nodelist/node_st.h"
34 #include "feature/nodelist/routerstatus_st.h"
35 #include "feature/nodelist/torcert.h"
36 #include "feature/relay/relay_metrics.h"
37 #include "feature/relay/router.h"
38 #include "feature/relay/routerkeys.h"
39 #include "feature/stats/rephist.h"
41 #include <event2/dns.h>
43 /** Declarations of each fill function for metrics defined in base_metrics. */
44 static void fill_cc_counters_values(void);
45 static void fill_cc_gauges_values(void);
46 static void fill_circuits_values(void);
47 static void fill_conn_counter_values(void);
48 static void fill_conn_gauge_values(void);
49 static void fill_dns_error_values(void);
50 static void fill_dns_query_values(void);
51 static void fill_dos_values(void);
52 static void fill_global_bw_limit_values(void);
53 static void fill_socket_values(void);
54 static void fill_onionskins_values(void);
55 static void fill_oom_values(void);
56 static void fill_streams_values(void);
57 static void fill_relay_flags(void);
58 static void fill_tcp_exhaustion_values(void);
59 static void fill_traffic_values(void);
60 static void fill_signing_cert_expiry(void);
62 static void fill_est_intro_cells(void);
63 static void fill_est_rend_cells(void);
64 static void fill_intro1_cells(void);
65 static void fill_rend1_cells(void);
67 /** The base metrics that is a static array of metrics added to the metrics
70 * The key member MUST be also the index of the entry in the array. */
71 static const relay_metrics_entry_t base_metrics
[] =
74 .key
= RELAY_METRICS_NUM_OOM_BYTES
,
75 .type
= METRICS_TYPE_COUNTER
,
76 .name
= METRICS_NAME(relay_load_oom_bytes_total
),
77 .help
= "Total number of bytes the OOM has freed by subsystem",
78 .fill_fn
= fill_oom_values
,
81 .key
= RELAY_METRICS_NUM_ONIONSKINS
,
82 .type
= METRICS_TYPE_COUNTER
,
83 .name
= METRICS_NAME(relay_load_onionskins_total
),
84 .help
= "Total number of onionskins handled",
85 .fill_fn
= fill_onionskins_values
,
88 .key
= RELAY_METRICS_NUM_SOCKETS
,
89 .type
= METRICS_TYPE_GAUGE
,
90 .name
= METRICS_NAME(relay_load_socket_total
),
91 .help
= "Total number of sockets",
92 .fill_fn
= fill_socket_values
,
95 .key
= RELAY_METRICS_NUM_GLOBAL_RW_LIMIT
,
96 .type
= METRICS_TYPE_COUNTER
,
97 .name
= METRICS_NAME(relay_load_global_rate_limit_reached_total
),
98 .help
= "Total number of global connection bucket limit reached",
99 .fill_fn
= fill_global_bw_limit_values
,
102 .key
= RELAY_METRICS_NUM_DNS
,
103 .type
= METRICS_TYPE_COUNTER
,
104 .name
= METRICS_NAME(relay_exit_dns_query_total
),
105 .help
= "Total number of DNS queries done by this relay",
106 .fill_fn
= fill_dns_query_values
,
109 .key
= RELAY_METRICS_NUM_DNS_ERRORS
,
110 .type
= METRICS_TYPE_COUNTER
,
111 .name
= METRICS_NAME(relay_exit_dns_error_total
),
112 .help
= "Total number of DNS errors encountered by this relay",
113 .fill_fn
= fill_dns_error_values
,
116 .key
= RELAY_METRICS_NUM_TCP_EXHAUSTION
,
117 .type
= METRICS_TYPE_COUNTER
,
118 .name
= METRICS_NAME(relay_load_tcp_exhaustion_total
),
119 .help
= "Total number of times we ran out of TCP ports",
120 .fill_fn
= fill_tcp_exhaustion_values
,
123 .key
= RELAY_METRICS_CONN_COUNTERS
,
124 .type
= METRICS_TYPE_COUNTER
,
125 .name
= METRICS_NAME(relay_connections_total
),
126 .help
= "Total number of created/rejected connections",
127 .fill_fn
= fill_conn_counter_values
,
130 .key
= RELAY_METRICS_CONN_GAUGES
,
131 .type
= METRICS_TYPE_GAUGE
,
132 .name
= METRICS_NAME(relay_connections
),
133 .help
= "Total number of opened connections",
134 .fill_fn
= fill_conn_gauge_values
,
137 .key
= RELAY_METRICS_NUM_STREAMS
,
138 .type
= METRICS_TYPE_COUNTER
,
139 .name
= METRICS_NAME(relay_streams_total
),
140 .help
= "Total number of streams",
141 .fill_fn
= fill_streams_values
,
144 .key
= RELAY_METRICS_CC_COUNTERS
,
145 .type
= METRICS_TYPE_COUNTER
,
146 .name
= METRICS_NAME(relay_congestion_control_total
),
147 .help
= "Congestion control related counters",
148 .fill_fn
= fill_cc_counters_values
,
151 .key
= RELAY_METRICS_CC_GAUGES
,
152 .type
= METRICS_TYPE_GAUGE
,
153 .name
= METRICS_NAME(relay_congestion_control
),
154 .help
= "Congestion control related gauges",
155 .fill_fn
= fill_cc_gauges_values
,
158 .key
= RELAY_METRICS_NUM_DOS
,
159 .type
= METRICS_TYPE_COUNTER
,
160 .name
= METRICS_NAME(relay_dos_total
),
161 .help
= "Denial of Service defenses related counters",
162 .fill_fn
= fill_dos_values
,
165 .key
= RELAY_METRICS_NUM_TRAFFIC
,
166 .type
= METRICS_TYPE_COUNTER
,
167 .name
= METRICS_NAME(relay_traffic_bytes
),
168 .help
= "Traffic related counters",
169 .fill_fn
= fill_traffic_values
,
172 .key
= RELAY_METRICS_RELAY_FLAGS
,
173 .type
= METRICS_TYPE_GAUGE
,
174 .name
= METRICS_NAME(relay_flag
),
175 .help
= "Relay flags from consensus",
176 .fill_fn
= fill_relay_flags
,
179 .key
= RELAY_METRICS_NUM_CIRCUITS
,
180 .type
= METRICS_TYPE_GAUGE
,
181 .name
= METRICS_NAME(relay_circuits_total
),
182 .help
= "Total number of circuits",
183 .fill_fn
= fill_circuits_values
,
186 .key
= RELAY_METRICS_SIGNING_CERT_EXPIRY
,
187 .type
= METRICS_TYPE_GAUGE
,
188 .name
= METRICS_NAME(relay_signing_cert_expiry_timestamp
),
189 .help
= "Timestamp at which the current online keys will expire",
190 .fill_fn
= fill_signing_cert_expiry
,
193 .key
= RELAY_METRICS_NUM_EST_REND
,
194 .type
= METRICS_TYPE_COUNTER
,
195 .name
= METRICS_NAME(relay_est_rend_total
),
196 .help
= "Total number of EST_REND cells we received",
197 .fill_fn
= fill_est_rend_cells
,
200 .key
= RELAY_METRICS_NUM_EST_INTRO
,
201 .type
= METRICS_TYPE_COUNTER
,
202 .name
= METRICS_NAME(relay_est_intro_total
),
203 .help
= "Total number of EST_INTRO cells we received",
204 .fill_fn
= fill_est_intro_cells
,
207 .key
= RELAY_METRICS_NUM_INTRO1_CELLS
,
208 .type
= METRICS_TYPE_COUNTER
,
209 .name
= METRICS_NAME(relay_intro1_total
),
210 .help
= "Total number of INTRO1 cells we received",
211 .fill_fn
= fill_intro1_cells
,
214 .key
= RELAY_METRICS_NUM_REND1_CELLS
,
215 .type
= METRICS_TYPE_COUNTER
,
216 .name
= METRICS_NAME(relay_rend1_total
),
217 .help
= "Total number of REND1 cells we received",
218 .fill_fn
= fill_rend1_cells
,
221 static const size_t num_base_metrics
= ARRAY_LENGTH(base_metrics
);
223 /** The only and single store of all the relay metrics. */
224 static metrics_store_t
*the_store
;
226 /** Helper function to convert an handshake type into a string. */
227 static inline const char *
228 handshake_type_to_str(const uint16_t type
)
231 case ONION_HANDSHAKE_TYPE_TAP
:
233 case ONION_HANDSHAKE_TYPE_FAST
:
235 case ONION_HANDSHAKE_TYPE_NTOR
:
237 case ONION_HANDSHAKE_TYPE_NTOR_V3
:
241 tor_assert_unreached();
246 /** Helper function to convert a socket family type into a string. */
247 static inline const char *
248 af_to_string(const int af
)
262 /** Fill function for the RELAY_METRICS_NUM_CIRCUITS metric. */
264 fill_circuits_values(void)
266 const relay_metrics_entry_t
*rentry
=
267 &base_metrics
[RELAY_METRICS_NUM_CIRCUITS
];
268 metrics_store_entry_t
*sentry
= metrics_store_add(
269 the_store
, rentry
->type
, rentry
->name
, rentry
->help
, 0, NULL
);
271 metrics_store_entry_add_label(sentry
,
272 metrics_format_label("state", "opened"));
273 metrics_store_entry_update(sentry
,
274 smartlist_len(circuit_get_global_list()));
277 /** Fill function for the RELAY_METRICS_RELAY_FLAGS metric. */
279 fill_relay_flags(void)
281 uint8_t is_fast
= 0, is_exit
= 0, is_authority
= 0, is_stable
= 0;
282 uint8_t is_running
= 0, is_v2_dir
= 0, is_guard
= 0, is_sybil
= 0;
283 uint8_t is_hs_dir
= 0;
286 node_get_by_id((const char *) router_get_my_id_digest());
288 is_fast
= me
->rs
->is_fast
;
289 is_exit
= me
->rs
->is_exit
;
290 is_authority
= me
->rs
->is_authority
;
291 is_stable
= me
->rs
->is_stable
;
292 is_running
= me
->rs
->is_flagged_running
;
293 is_v2_dir
= me
->rs
->is_v2_dir
;
294 is_guard
= me
->rs
->is_possible_guard
;
295 is_sybil
= me
->rs
->is_sybil
;
296 is_hs_dir
= me
->rs
->is_hs_dir
;
299 const relay_metrics_entry_t
*rentry
=
300 &base_metrics
[RELAY_METRICS_RELAY_FLAGS
];
301 metrics_store_entry_t
*sentry
= metrics_store_add(
302 the_store
, rentry
->type
, rentry
->name
, rentry
->help
, 0, NULL
);
304 metrics_store_entry_add_label(sentry
,
305 metrics_format_label("type", "Fast"));
306 metrics_store_entry_update(sentry
, is_fast
);
308 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
309 rentry
->help
, 0, NULL
);
310 metrics_store_entry_add_label(sentry
,
311 metrics_format_label("type", "Exit"));
312 metrics_store_entry_update(sentry
, is_exit
);
314 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
315 rentry
->help
, 0, NULL
);
316 metrics_store_entry_add_label(sentry
,
317 metrics_format_label("type", "Authority"));
318 metrics_store_entry_update(sentry
, is_authority
);
320 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
321 rentry
->help
, 0, NULL
);
322 metrics_store_entry_add_label(sentry
,
323 metrics_format_label("type", "Stable"));
324 metrics_store_entry_update(sentry
, is_stable
);
326 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
327 rentry
->help
, 0, NULL
);
328 metrics_store_entry_add_label(sentry
,
329 metrics_format_label("type", "HSDir"));
330 metrics_store_entry_update(sentry
, is_hs_dir
);
332 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
333 rentry
->help
, 0, NULL
);
334 metrics_store_entry_add_label(sentry
,
335 metrics_format_label("type", "Running"));
336 metrics_store_entry_update(sentry
, is_running
);
338 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
339 rentry
->help
, 0, NULL
);
340 metrics_store_entry_add_label(sentry
,
341 metrics_format_label("type", "V2Dir"));
342 metrics_store_entry_update(sentry
, is_v2_dir
);
344 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
345 rentry
->help
, 0, NULL
);
346 metrics_store_entry_add_label(sentry
,
347 metrics_format_label("type", "Sybil"));
348 metrics_store_entry_update(sentry
, is_sybil
);
350 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
351 rentry
->help
, 0, NULL
);
352 metrics_store_entry_add_label(sentry
,
353 metrics_format_label("type", "Guard"));
354 metrics_store_entry_update(sentry
, is_guard
);
357 /** Fill function for the RELAY_METRICS_NUM_TRAFFIC metric. */
359 fill_traffic_values(void)
361 const relay_metrics_entry_t
*rentry
=
362 &base_metrics
[RELAY_METRICS_NUM_TRAFFIC
];
363 metrics_store_entry_t
*sentry
= metrics_store_add(
364 the_store
, rentry
->type
, rentry
->name
, rentry
->help
, 0, NULL
);
366 metrics_store_entry_add_label(sentry
,
367 metrics_format_label("direction", "read"));
368 metrics_store_entry_update(sentry
, get_bytes_read());
370 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
371 rentry
->help
, 0, NULL
);
372 metrics_store_entry_add_label(sentry
,
373 metrics_format_label("direction", "written"));
374 metrics_store_entry_update(sentry
, get_bytes_written());
377 /** Fill function for the RELAY_METRICS_NUM_DOS metric. */
379 fill_dos_values(void)
381 const relay_metrics_entry_t
*rentry
= &base_metrics
[RELAY_METRICS_NUM_DOS
];
382 metrics_store_entry_t
*sentry
= metrics_store_add(
383 the_store
, rentry
->type
, rentry
->name
, rentry
->help
, 0, NULL
);
385 metrics_store_entry_add_label(sentry
,
386 metrics_format_label("type", "circuit_rejected"));
387 metrics_store_entry_update(sentry
, dos_get_num_cc_rejected());
389 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
390 rentry
->help
, 0, NULL
);
391 metrics_store_entry_add_label(sentry
,
392 metrics_format_label("type", "circuit_killed_max_cell"));
393 metrics_store_entry_update(sentry
, stats_n_circ_max_cell_reached
);
395 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
396 rentry
->help
, 0, NULL
);
397 metrics_store_entry_add_label(sentry
,
398 metrics_format_label("type", "circuit_killed_max_cell_outq"));
399 metrics_store_entry_update(sentry
, stats_n_circ_max_cell_outq_reached
);
401 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
402 rentry
->help
, 0, NULL
);
403 metrics_store_entry_add_label(sentry
,
404 metrics_format_label("type", "marked_address"));
405 metrics_store_entry_update(sentry
, dos_get_num_cc_marked_addr());
407 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
408 rentry
->help
, 0, NULL
);
409 metrics_store_entry_add_label(sentry
,
410 metrics_format_label("type", "marked_address_maxq"));
411 metrics_store_entry_update(sentry
, dos_get_num_cc_marked_addr_maxq());
413 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
414 rentry
->help
, 0, NULL
);
415 metrics_store_entry_add_label(sentry
,
416 metrics_format_label("type", "conn_rejected"));
417 metrics_store_entry_update(sentry
, dos_get_num_conn_addr_connect_rejected());
419 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
420 rentry
->help
, 0, NULL
);
421 metrics_store_entry_add_label(sentry
,
422 metrics_format_label("type", "concurrent_conn_rejected"));
423 metrics_store_entry_update(sentry
, dos_get_num_conn_addr_rejected());
425 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
426 rentry
->help
, 0, NULL
);
427 metrics_store_entry_add_label(sentry
,
428 metrics_format_label("type", "single_hop_refused"));
429 metrics_store_entry_update(sentry
, dos_get_num_single_hop_refused());
431 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
432 rentry
->help
, 0, NULL
);
433 metrics_store_entry_add_label(sentry
,
434 metrics_format_label("type", "introduce2_rejected"));
435 metrics_store_entry_update(sentry
, hs_dos_get_intro2_rejected_count());
438 /** Fill function for the RELAY_METRICS_CC_COUNTERS metric. */
440 fill_cc_counters_values(void)
442 const relay_metrics_entry_t
*rentry
=
443 &base_metrics
[RELAY_METRICS_CC_COUNTERS
];
445 metrics_store_entry_t
*sentry
= metrics_store_add(
446 the_store
, rentry
->type
, rentry
->name
, rentry
->help
, 0, NULL
);
447 metrics_store_entry_add_label(sentry
,
448 metrics_format_label("state", "starvation"));
449 metrics_store_entry_add_label(sentry
,
450 metrics_format_label("action", "rtt_reset"));
451 metrics_store_entry_update(sentry
, congestion_control_get_num_rtt_reset());
453 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
454 rentry
->help
, 0, NULL
);
455 metrics_store_entry_add_label(sentry
,
456 metrics_format_label("state", "clock_stalls"));
457 metrics_store_entry_add_label(sentry
,
458 metrics_format_label("action", "rtt_skipped"));
459 metrics_store_entry_update(sentry
,
460 congestion_control_get_num_clock_stalls());
462 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
463 rentry
->help
, 0, NULL
);
464 metrics_store_entry_add_label(sentry
,
465 metrics_format_label("state", "flow_control"));
466 metrics_store_entry_add_label(sentry
,
467 metrics_format_label("action", "xoff_num_sent"));
468 metrics_store_entry_update(sentry
,
469 cc_stats_flow_num_xoff_sent
);
471 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
472 rentry
->help
, 0, NULL
);
473 metrics_store_entry_add_label(sentry
,
474 metrics_format_label("state", "flow_control"));
475 metrics_store_entry_add_label(sentry
,
476 metrics_format_label("action", "xon_num_sent"));
477 metrics_store_entry_update(sentry
,
478 cc_stats_flow_num_xon_sent
);
480 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
481 rentry
->help
, 0, NULL
);
482 metrics_store_entry_add_label(sentry
,
483 metrics_format_label("state", "cc_limits"));
484 metrics_store_entry_add_label(sentry
,
485 metrics_format_label("action", "above_delta"));
486 metrics_store_entry_update(sentry
, cc_stats_vegas_above_delta
);
488 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
489 rentry
->help
, 0, NULL
);
490 metrics_store_entry_add_label(sentry
,
491 metrics_format_label("state", "cc_limits"));
492 metrics_store_entry_add_label(sentry
,
493 metrics_format_label("action", "above_ss_cwnd_max"));
494 metrics_store_entry_update(sentry
, cc_stats_vegas_above_ss_cwnd_max
);
496 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
497 rentry
->help
, 0, NULL
);
498 metrics_store_entry_add_label(sentry
,
499 metrics_format_label("state", "cc_limits"));
500 metrics_store_entry_add_label(sentry
,
501 metrics_format_label("action", "below_ss_inc_floor"));
502 metrics_store_entry_update(sentry
, cc_stats_vegas_below_ss_inc_floor
);
504 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
505 rentry
->help
, 0, NULL
);
506 metrics_store_entry_add_label(sentry
,
507 metrics_format_label("state", "cc_circuits"));
508 metrics_store_entry_add_label(sentry
,
509 metrics_format_label("action", "circs_created"));
510 metrics_store_entry_update(sentry
, cc_stats_circs_created
);
512 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
513 rentry
->help
, 0, NULL
);
514 metrics_store_entry_add_label(sentry
,
515 metrics_format_label("state", "cc_circuits"));
516 metrics_store_entry_add_label(sentry
,
517 metrics_format_label("action", "circs_closed"));
518 metrics_store_entry_update(sentry
, cc_stats_circs_closed
);
520 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
521 rentry
->help
, 0, NULL
);
522 metrics_store_entry_add_label(sentry
,
523 metrics_format_label("state", "cc_circuits"));
524 metrics_store_entry_add_label(sentry
,
525 metrics_format_label("action", "circs_exited_ss"));
526 metrics_store_entry_update(sentry
, cc_stats_vegas_circ_exited_ss
);
529 /** Fill function for the RELAY_METRICS_CC_GAUGES metric. */
531 fill_cc_gauges_values(void)
533 const relay_metrics_entry_t
*rentry
=
534 &base_metrics
[RELAY_METRICS_CC_GAUGES
];
536 metrics_store_entry_t
*sentry
= metrics_store_add(
537 the_store
, rentry
->type
, rentry
->name
, rentry
->help
, 0, NULL
);
538 metrics_store_entry_add_label(sentry
,
539 metrics_format_label("state", "slow_start_exit"));
540 metrics_store_entry_add_label(sentry
,
541 metrics_format_label("action", "cwnd"));
542 metrics_store_entry_update(sentry
,
543 tor_llround(cc_stats_vegas_exit_ss_cwnd_ma
));
545 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
546 rentry
->help
, 0, NULL
);
547 metrics_store_entry_add_label(sentry
,
548 metrics_format_label("state", "slow_start_exit"));
549 metrics_store_entry_add_label(sentry
,
550 metrics_format_label("action", "bdp"));
551 metrics_store_entry_update(sentry
,
552 tor_llround(cc_stats_vegas_exit_ss_bdp_ma
));
554 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
555 rentry
->help
, 0, NULL
);
556 metrics_store_entry_add_label(sentry
,
557 metrics_format_label("state", "slow_start_exit"));
558 metrics_store_entry_add_label(sentry
,
559 metrics_format_label("action", "inc"));
560 metrics_store_entry_update(sentry
,
561 tor_llround(cc_stats_vegas_exit_ss_inc_ma
));
563 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
564 rentry
->help
, 0, NULL
);
565 metrics_store_entry_add_label(sentry
,
566 metrics_format_label("state", "on_circ_close"));
567 metrics_store_entry_add_label(sentry
,
568 metrics_format_label("action", "cwnd"));
569 metrics_store_entry_update(sentry
,
570 tor_llround(cc_stats_circ_close_cwnd_ma
));
572 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
573 rentry
->help
, 0, NULL
);
574 metrics_store_entry_add_label(sentry
,
575 metrics_format_label("state", "on_circ_close"));
576 metrics_store_entry_add_label(sentry
,
577 metrics_format_label("action", "ss_cwnd"));
578 metrics_store_entry_update(sentry
,
579 tor_llround(cc_stats_circ_close_ss_cwnd_ma
));
581 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
582 rentry
->help
, 0, NULL
);
583 metrics_store_entry_add_label(sentry
,
584 metrics_format_label("state", "buffers"));
585 metrics_store_entry_add_label(sentry
,
586 metrics_format_label("action", "xon_outbuf"));
587 metrics_store_entry_update(sentry
,
588 tor_llround(cc_stats_flow_xon_outbuf_ma
));
590 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
591 rentry
->help
, 0, NULL
);
592 metrics_store_entry_add_label(sentry
,
593 metrics_format_label("state", "buffers"));
594 metrics_store_entry_add_label(sentry
,
595 metrics_format_label("action", "xoff_outbuf"));
596 metrics_store_entry_update(sentry
,
597 tor_llround(cc_stats_flow_xoff_outbuf_ma
));
599 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
600 rentry
->help
, 0, NULL
);
601 metrics_store_entry_add_label(sentry
,
602 metrics_format_label("state", "cc_backoff"));
603 metrics_store_entry_add_label(sentry
,
604 metrics_format_label("action", "chan_blocked_pct"));
605 metrics_store_entry_update(sentry
,
606 tor_llround(cc_stats_vegas_csig_blocked_ma
));
608 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
609 rentry
->help
, 0, NULL
);
610 metrics_store_entry_add_label(sentry
,
611 metrics_format_label("state", "cc_backoff"));
612 metrics_store_entry_add_label(sentry
,
613 metrics_format_label("action", "gamma_drop"));
614 metrics_store_entry_update(sentry
,
615 tor_llround(cc_stats_vegas_gamma_drop_ma
));
617 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
618 rentry
->help
, 0, NULL
);
619 metrics_store_entry_add_label(sentry
,
620 metrics_format_label("state", "cc_backoff"));
621 metrics_store_entry_add_label(sentry
,
622 metrics_format_label("action", "delta_drop"));
623 metrics_store_entry_update(sentry
,
624 tor_llround(cc_stats_vegas_delta_drop_ma
));
626 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
627 rentry
->help
, 0, NULL
);
628 metrics_store_entry_add_label(sentry
,
629 metrics_format_label("state", "cc_backoff"));
630 metrics_store_entry_add_label(sentry
,
631 metrics_format_label("action", "ss_chan_blocked_pct"));
632 metrics_store_entry_update(sentry
,
633 tor_llround(cc_stats_vegas_ss_csig_blocked_ma
));
635 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
636 rentry
->help
, 0, NULL
);
637 metrics_store_entry_add_label(sentry
,
638 metrics_format_label("state", "cc_cwnd_update"));
639 metrics_store_entry_add_label(sentry
,
640 metrics_format_label("action", "alpha_pct"));
641 metrics_store_entry_update(sentry
,
642 tor_llround(cc_stats_vegas_csig_alpha_ma
));
644 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
645 rentry
->help
, 0, NULL
);
646 metrics_store_entry_add_label(sentry
,
647 metrics_format_label("state", "cc_cwnd_update"));
648 metrics_store_entry_add_label(sentry
,
649 metrics_format_label("action", "beta_pct"));
650 metrics_store_entry_update(sentry
,
651 tor_llround(cc_stats_vegas_csig_beta_ma
));
653 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
654 rentry
->help
, 0, NULL
);
655 metrics_store_entry_add_label(sentry
,
656 metrics_format_label("state", "cc_cwnd_update"));
657 metrics_store_entry_add_label(sentry
,
658 metrics_format_label("action", "delta_pct"));
659 metrics_store_entry_update(sentry
,
660 tor_llround(cc_stats_vegas_csig_delta_ma
));
662 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
663 rentry
->help
, 0, NULL
);
664 metrics_store_entry_add_label(sentry
,
665 metrics_format_label("state", "cc_estimates"));
666 metrics_store_entry_add_label(sentry
,
667 metrics_format_label("action", "ss_queue"));
668 metrics_store_entry_update(sentry
,
669 tor_llround(cc_stats_vegas_ss_queue_ma
));
671 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
672 rentry
->help
, 0, NULL
);
673 metrics_store_entry_add_label(sentry
,
674 metrics_format_label("state", "cc_estimates"));
675 metrics_store_entry_add_label(sentry
,
676 metrics_format_label("action", "queue"));
677 metrics_store_entry_update(sentry
,
678 tor_llround(cc_stats_vegas_queue_ma
));
680 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
681 rentry
->help
, 0, NULL
);
682 metrics_store_entry_add_label(sentry
,
683 metrics_format_label("state", "cc_estimates"));
684 metrics_store_entry_add_label(sentry
,
685 metrics_format_label("action", "bdp"));
686 metrics_store_entry_update(sentry
,
687 tor_llround(cc_stats_vegas_bdp_ma
));
690 /** Helper: Fill in single stream metrics output. */
692 fill_single_stream_value(metrics_store_entry_t
*sentry
, uint8_t cmd
)
694 metrics_store_entry_add_label(sentry
,
695 metrics_format_label("type", relay_command_to_string(cmd
)));
696 metrics_store_entry_update(sentry
, rep_hist_get_exit_stream_seen(cmd
));
699 /** Fill function for the RELAY_METRICS_NUM_STREAMS metric. */
701 fill_streams_values(void)
703 const relay_metrics_entry_t
*rentry
=
704 &base_metrics
[RELAY_METRICS_NUM_STREAMS
];
705 metrics_store_entry_t
*sentry
= metrics_store_add(
706 the_store
, rentry
->type
, rentry
->name
, rentry
->help
, 0, NULL
);
707 fill_single_stream_value(sentry
, RELAY_COMMAND_BEGIN
);
709 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
710 rentry
->help
, 0, NULL
);
711 fill_single_stream_value(sentry
, RELAY_COMMAND_BEGIN_DIR
);
713 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
714 rentry
->help
, 0, NULL
);
715 fill_single_stream_value(sentry
, RELAY_COMMAND_RESOLVE
);
718 /** Helper: Fill in single connection metrics output. */
720 fill_single_connection_value(metrics_store_entry_t
*sentry
,
721 unsigned int conn_type
,
722 const char* direction
,
727 metrics_store_entry_add_label(sentry
,
728 metrics_format_label("type", conn_type_to_string(conn_type
)));
729 metrics_store_entry_add_label(sentry
,
730 metrics_format_label("direction", direction
));
731 metrics_store_entry_add_label(sentry
,
732 metrics_format_label("state", state
));
733 metrics_store_entry_add_label(sentry
,
734 metrics_format_label("family", af_to_string(socket_family
)));
735 metrics_store_entry_update(sentry
, value
);
738 /** Fill function for the RELAY_METRICS_CONN_COUNTERS metric. */
740 fill_conn_counter_values(void)
742 const relay_metrics_entry_t
*rentry
=
743 &base_metrics
[RELAY_METRICS_CONN_COUNTERS
];
745 for (unsigned int i
= CONN_TYPE_MIN_
; i
< CONN_TYPE_MAX_
; i
++) {
746 /* Type is unused. Ugly but else we clobber the output. */
750 metrics_store_entry_t
*sentry
= metrics_store_add(
751 the_store
, rentry
->type
, rentry
->name
, rentry
->help
, 0, NULL
);
752 fill_single_connection_value(sentry
, i
, "initiated", "created", AF_INET
,
753 rep_hist_get_conn_created(false, i
, AF_INET
));
754 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
755 rentry
->help
, 0, NULL
);
756 fill_single_connection_value(sentry
, i
, "initiated", "created", AF_INET6
,
757 rep_hist_get_conn_created(false, i
,
760 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
761 rentry
->help
, 0, NULL
);
762 fill_single_connection_value(sentry
, i
, "received", "created", AF_INET
,
763 rep_hist_get_conn_created(true, i
, AF_INET
));
764 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
765 rentry
->help
, 0, NULL
);
766 fill_single_connection_value(sentry
, i
, "received", "created", AF_INET6
,
767 rep_hist_get_conn_created(true, i
, AF_INET6
));
769 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
770 rentry
->help
, 0, NULL
);
771 fill_single_connection_value(sentry
, i
, "received", "rejected", AF_INET
,
772 rep_hist_get_conn_rejected(i
, AF_INET
));
773 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
774 rentry
->help
, 0, NULL
);
775 fill_single_connection_value(sentry
, i
, "received", "rejected", AF_INET6
,
776 rep_hist_get_conn_rejected(i
, AF_INET6
));
778 /* No counter for "initiated" + "rejected" connections exists. */
782 /** Fill function for the RELAY_METRICS_CONN_GAUGES metric. */
784 fill_conn_gauge_values(void)
786 const relay_metrics_entry_t
*rentry
=
787 &base_metrics
[RELAY_METRICS_CONN_GAUGES
];
789 for (unsigned int i
= CONN_TYPE_MIN_
; i
< CONN_TYPE_MAX_
; i
++) {
790 /* Type is unused. Ugly but else we clobber the output. */
794 metrics_store_entry_t
*sentry
= metrics_store_add(
795 the_store
, rentry
->type
, rentry
->name
, rentry
->help
, 0, NULL
);
796 fill_single_connection_value(sentry
, i
, "initiated", "opened", AF_INET
,
797 rep_hist_get_conn_opened(false, i
, AF_INET
));
798 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
799 rentry
->help
, 0, NULL
);
800 fill_single_connection_value(sentry
, i
, "initiated", "opened", AF_INET6
,
801 rep_hist_get_conn_opened(false, i
, AF_INET6
));
803 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
804 rentry
->help
, 0, NULL
);
805 fill_single_connection_value(sentry
, i
, "received", "opened", AF_INET
,
806 rep_hist_get_conn_opened(true, i
, AF_INET
));
807 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
808 rentry
->help
, 0, NULL
);
809 fill_single_connection_value(sentry
, i
, "received", "opened", AF_INET6
,
810 rep_hist_get_conn_opened(true, i
, AF_INET6
));
814 /** Fill function for the RELAY_METRICS_NUM_DNS metrics. */
816 fill_tcp_exhaustion_values(void)
818 metrics_store_entry_t
*sentry
;
819 const relay_metrics_entry_t
*rentry
=
820 &base_metrics
[RELAY_METRICS_NUM_TCP_EXHAUSTION
];
822 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
823 rentry
->help
, 0, NULL
);
824 metrics_store_entry_update(sentry
, rep_hist_get_n_tcp_exhaustion());
827 /* NOTE: Disable the record type label until libevent is fixed. */
829 /** Helper array containing mapping for the name of the different DNS records
830 * and their corresponding libevent values. */
831 static struct dns_type
{
835 { .name
= "A", .type
= DNS_IPv4_A
},
836 { .name
= "PTR", .type
= DNS_PTR
},
837 { .name
= "AAAA", .type
= DNS_IPv6_AAAA
},
839 static const size_t num_dns_types
= ARRAY_LENGTH(dns_types
);
842 /** Fill function for the RELAY_METRICS_NUM_DNS_ERRORS metrics. */
844 fill_dns_error_values(void)
846 metrics_store_entry_t
*sentry
;
847 const relay_metrics_entry_t
*rentry
=
848 &base_metrics
[RELAY_METRICS_NUM_DNS_ERRORS
];
850 /* Helper array to map libeven DNS errors to their names and so we can
851 * iterate over this array to add all metrics. */
852 static struct dns_error
{
856 { .name
= "success", .key
= DNS_ERR_NONE
},
857 { .name
= "format", .key
= DNS_ERR_FORMAT
},
858 { .name
= "serverfailed", .key
= DNS_ERR_SERVERFAILED
},
859 { .name
= "notexist", .key
= DNS_ERR_NOTEXIST
},
860 { .name
= "notimpl", .key
= DNS_ERR_NOTIMPL
},
861 { .name
= "refused", .key
= DNS_ERR_REFUSED
},
862 { .name
= "truncated", .key
= DNS_ERR_TRUNCATED
},
863 { .name
= "unknown", .key
= DNS_ERR_UNKNOWN
},
864 { .name
= "tor_timeout", .key
= DNS_ERR_TIMEOUT
},
865 { .name
= "shutdown", .key
= DNS_ERR_SHUTDOWN
},
866 { .name
= "cancel", .key
= DNS_ERR_CANCEL
},
867 { .name
= "nodata", .key
= DNS_ERR_NODATA
},
869 static const size_t num_errors
= ARRAY_LENGTH(errors
);
871 /* NOTE: Disable the record type label until libevent is fixed. */
873 for (size_t i
= 0; i
< num_dns_types
; i
++) {
874 /* Dup the label because metrics_format_label() returns a pointer to a
875 * string on the stack and we need that label for all metrics. */
877 tor_strdup(metrics_format_label("record", dns_types
[i
].name
));
879 for (size_t j
= 0; j
< num_errors
; j
++) {
880 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
881 rentry
->help
, 0, NULL
);
882 metrics_store_entry_add_label(sentry
, record_label
);
883 metrics_store_entry_add_label(sentry
,
884 metrics_format_label("reason", errors
[j
].name
));
885 metrics_store_entry_update(sentry
,
886 rep_hist_get_n_dns_error(dns_types
[i
].type
, errors
[j
].key
));
888 tor_free(record_label
);
892 /* Put in the DNS errors, unfortunately not per-type for now. */
893 for (size_t j
= 0; j
< num_errors
; j
++) {
894 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
895 rentry
->help
, 0, NULL
);
896 metrics_store_entry_add_label(sentry
,
897 metrics_format_label("reason", errors
[j
].name
));
898 metrics_store_entry_update(sentry
,
899 rep_hist_get_n_dns_error(0, errors
[j
].key
));
903 /** Fill function for the RELAY_METRICS_NUM_DNS metrics. */
905 fill_dns_query_values(void)
907 metrics_store_entry_t
*sentry
;
908 const relay_metrics_entry_t
*rentry
=
909 &base_metrics
[RELAY_METRICS_NUM_DNS
];
911 /* NOTE: Disable the record type label until libevent is fixed (#40490). */
913 for (size_t i
= 0; i
< num_dns_types
; i
++) {
914 /* Dup the label because metrics_format_label() returns a pointer to a
915 * string on the stack and we need that label for all metrics. */
917 tor_strdup(metrics_format_label("record", dns_types
[i
].name
));
918 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
919 rentry
->help
, 0, NULL
);
920 metrics_store_entry_add_label(sentry
, record_label
);
921 metrics_store_entry_update(sentry
,
922 rep_hist_get_n_dns_request(dns_types
[i
].type
));
923 tor_free(record_label
);
927 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
928 rentry
->help
, 0, NULL
);
929 metrics_store_entry_update(sentry
, rep_hist_get_n_dns_request(0));
932 /** Fill function for the RELAY_METRICS_NUM_GLOBAL_RW_LIMIT metrics. */
934 fill_global_bw_limit_values(void)
936 metrics_store_entry_t
*sentry
;
937 const relay_metrics_entry_t
*rentry
=
938 &base_metrics
[RELAY_METRICS_NUM_GLOBAL_RW_LIMIT
];
940 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
941 rentry
->help
, 0, NULL
);
942 metrics_store_entry_add_label(sentry
,
943 metrics_format_label("side", "read"));
944 metrics_store_entry_update(sentry
, rep_hist_get_n_read_limit_reached());
946 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
947 rentry
->help
, 0, NULL
);
948 metrics_store_entry_add_label(sentry
,
949 metrics_format_label("side", "write"));
950 metrics_store_entry_update(sentry
, rep_hist_get_n_write_limit_reached());
953 /** Fill function for the RELAY_METRICS_NUM_SOCKETS metrics. */
955 fill_socket_values(void)
957 metrics_store_entry_t
*sentry
;
958 const relay_metrics_entry_t
*rentry
=
959 &base_metrics
[RELAY_METRICS_NUM_SOCKETS
];
961 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
962 rentry
->help
, 0, NULL
);
963 metrics_store_entry_add_label(sentry
,
964 metrics_format_label("state", "opened"));
965 metrics_store_entry_update(sentry
, get_n_open_sockets());
967 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
968 rentry
->help
, 0, NULL
);
969 metrics_store_entry_update(sentry
, get_max_sockets());
972 /** Fill function for the RELAY_METRICS_NUM_ONIONSKINS metrics. */
974 fill_onionskins_values(void)
976 metrics_store_entry_t
*sentry
;
977 const relay_metrics_entry_t
*rentry
=
978 &base_metrics
[RELAY_METRICS_NUM_ONIONSKINS
];
980 for (uint16_t t
= 0; t
<= MAX_ONION_HANDSHAKE_TYPE
; t
++) {
981 /* Dup the label because metrics_format_label() returns a pointer to a
982 * string on the stack and we need that label for all metrics. */
984 tor_strdup(metrics_format_label("type", handshake_type_to_str(t
)));
985 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
986 rentry
->help
, 0, NULL
);
987 metrics_store_entry_add_label(sentry
, type_label
);
988 metrics_store_entry_add_label(sentry
,
989 metrics_format_label("action", "processed"));
990 metrics_store_entry_update(sentry
,
991 rep_hist_get_circuit_n_handshake_assigned(t
));
993 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
994 rentry
->help
, 0, NULL
);
995 metrics_store_entry_add_label(sentry
, type_label
);
996 metrics_store_entry_add_label(sentry
,
997 metrics_format_label("action", "dropped"));
998 metrics_store_entry_update(sentry
,
999 rep_hist_get_circuit_n_handshake_dropped(t
));
1000 tor_free(type_label
);
1004 /** Fill function for the RELAY_METRICS_NUM_OOM_BYTES metrics. */
1006 fill_oom_values(void)
1008 metrics_store_entry_t
*sentry
;
1009 const relay_metrics_entry_t
*rentry
=
1010 &base_metrics
[RELAY_METRICS_NUM_OOM_BYTES
];
1012 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
1013 rentry
->help
, 0, NULL
);
1014 metrics_store_entry_add_label(sentry
,
1015 metrics_format_label("subsys", "cell"));
1016 metrics_store_entry_update(sentry
, oom_stats_n_bytes_removed_cell
);
1018 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
1019 rentry
->help
, 0, NULL
);
1020 metrics_store_entry_add_label(sentry
,
1021 metrics_format_label("subsys", "dns"));
1022 metrics_store_entry_update(sentry
, oom_stats_n_bytes_removed_dns
);
1024 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
1025 rentry
->help
, 0, NULL
);
1026 metrics_store_entry_add_label(sentry
,
1027 metrics_format_label("subsys", "geoip"));
1028 metrics_store_entry_update(sentry
, oom_stats_n_bytes_removed_geoip
);
1030 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
1031 rentry
->help
, 0, NULL
);
1032 metrics_store_entry_add_label(sentry
,
1033 metrics_format_label("subsys", "hsdir"));
1034 metrics_store_entry_update(sentry
, oom_stats_n_bytes_removed_hsdir
);
1037 /** Fill function for the RELAY_METRICS_SIGNING_CERT_EXPIRY metrics. */
1039 fill_signing_cert_expiry(void)
1041 metrics_store_entry_t
*sentry
;
1042 const tor_cert_t
*signing_key
;
1043 const relay_metrics_entry_t
*rentry
=
1044 &base_metrics
[RELAY_METRICS_SIGNING_CERT_EXPIRY
];
1046 if (get_options()->OfflineMasterKey
) {
1047 signing_key
= get_master_signing_key_cert();
1049 sentry
= metrics_store_add(the_store
, rentry
->type
, rentry
->name
,
1050 rentry
->help
, 0, NULL
);
1051 metrics_store_entry_update(sentry
, signing_key
->valid_until
);
1057 fill_est_intro_cells(void)
1059 metrics_store_entry_t
*sentry
;
1060 const relay_metrics_entry_t
*rentry
=
1061 &base_metrics
[RELAY_METRICS_NUM_EST_INTRO
];
1065 est_intro_action_t key
;
1067 {.name
= "success", .key
= EST_INTRO_SUCCESS
},
1068 {.name
= "malformed", .key
= EST_INTRO_MALFORMED
},
1069 {.name
= "unsuitable_circuit", .key
= EST_INTRO_UNSUITABLE_CIRCUIT
},
1070 {.name
= "circuit_dead", .key
= EST_INTRO_CIRCUIT_DEAD
},
1072 static const size_t num_actions
= ARRAY_LENGTH(actions
);
1074 for (size_t i
= 0; i
< num_actions
; ++i
) {
1076 metrics_store_add(the_store
, rentry
->type
, rentry
->name
, rentry
->help
);
1077 metrics_store_entry_add_label(
1078 sentry
, metrics_format_label("action", actions
[i
].name
));
1079 metrics_store_entry_update(
1080 sentry
, (long)rep_hist_get_est_intro_action_count(actions
[i
].key
));
1085 fill_est_rend_cells(void)
1087 metrics_store_entry_t
*sentry
;
1088 const relay_metrics_entry_t
*rentry
=
1089 &base_metrics
[RELAY_METRICS_NUM_EST_REND
];
1093 est_rend_action_t key
;
1095 {.name
= "success", .key
= EST_REND_SUCCESS
},
1096 {.name
= "unsuitable_circuit", .key
= EST_REND_UNSUITABLE_CIRCUIT
},
1097 {.name
= "single_hop", .key
= EST_REND_SINGLE_HOP
},
1098 {.name
= "malformed", .key
= EST_REND_MALFORMED
},
1099 {.name
= "duplicate_cookie", .key
= EST_REND_DUPLICATE_COOKIE
},
1100 {.name
= "circuit_dead", .key
= EST_REND_CIRCUIT_DEAD
},
1102 static const size_t num_actions
= ARRAY_LENGTH(actions
);
1104 for (size_t i
= 0; i
< num_actions
; ++i
) {
1106 metrics_store_add(the_store
, rentry
->type
, rentry
->name
, rentry
->help
);
1107 metrics_store_entry_add_label(
1108 sentry
, metrics_format_label("action", actions
[i
].name
));
1109 metrics_store_entry_update(
1110 sentry
, (long)rep_hist_get_est_rend_action_count(actions
[i
].key
));
1115 fill_intro1_cells(void)
1117 metrics_store_entry_t
*sentry
;
1118 const relay_metrics_entry_t
*rentry
=
1119 &base_metrics
[RELAY_METRICS_NUM_INTRO1_CELLS
];
1123 intro1_action_t key
;
1125 {.name
= "success", .key
= INTRO1_SUCCESS
},
1126 {.name
= "circuit_dead", .key
= INTRO1_CIRCUIT_DEAD
},
1127 {.name
= "malformed", .key
= INTRO1_MALFORMED
},
1128 {.name
= "unknown_service", .key
= INTRO1_UNKNOWN_SERVICE
},
1129 {.name
= "rate_limited", .key
= INTRO1_RATE_LIMITED
},
1130 {.name
= "circuit_reused", .key
= INTRO1_CIRCUIT_REUSED
},
1131 {.name
= "single_hop", .key
= INTRO1_SINGLE_HOP
},
1133 static const size_t num_actions
= ARRAY_LENGTH(actions
);
1135 for (size_t i
= 0; i
< num_actions
; ++i
) {
1137 metrics_store_add(the_store
, rentry
->type
, rentry
->name
, rentry
->help
);
1138 metrics_store_entry_add_label(
1139 sentry
, metrics_format_label("action", actions
[i
].name
));
1140 metrics_store_entry_update(
1141 sentry
, (long)rep_hist_get_intro1_action_count(actions
[i
].key
));
1146 fill_rend1_cells(void)
1148 metrics_store_entry_t
*sentry
;
1149 const relay_metrics_entry_t
*rentry
=
1150 &base_metrics
[RELAY_METRICS_NUM_REND1_CELLS
];
1156 {.name
= "success", .key
= REND1_SUCCESS
},
1157 {.name
= "unsuitable_circuit", .key
= REND1_UNSUITABLE_CIRCUIT
},
1158 {.name
= "malformed", .key
= REND1_MALFORMED
},
1159 {.name
= "unknown_cookie", .key
= REND1_UNKNOWN_COOKIE
},
1160 {.name
= "circuit_dead", .key
= REND1_CIRCUIT_DEAD
},
1162 static const size_t num_actions
= ARRAY_LENGTH(actions
);
1164 for (size_t i
= 0; i
< num_actions
; ++i
) {
1166 metrics_store_add(the_store
, rentry
->type
, rentry
->name
, rentry
->help
);
1167 metrics_store_entry_add_label(
1168 sentry
, metrics_format_label("action", actions
[i
].name
));
1169 metrics_store_entry_update(
1170 sentry
, (long)rep_hist_get_rend1_action_count(actions
[i
].key
));
1174 /** Reset the global store and fill it with all the metrics from base_metrics
1175 * and their associated values.
1177 * To pull this off, every metrics has a "fill" function that is called and in
1178 * charge of adding the metrics to the store, appropriate labels and finally
1179 * updating the value to report. */
1183 /* Reset the current store, we are about to fill it with all the things. */
1184 metrics_store_reset(the_store
);
1186 /* Call the fill function for each metrics. */
1187 for (size_t i
= 0; i
< num_base_metrics
; i
++) {
1188 if (BUG(!base_metrics
[i
].fill_fn
)) {
1191 base_metrics
[i
].fill_fn();
1195 /** Return a list of all the relay metrics stores. This is the
1196 * function attached to the .get_metrics() member of the subsys_t. */
1198 relay_metrics_get_stores(void)
1200 /* We can't have the caller to free the returned list so keep it static,
1201 * simply update it. */
1202 static smartlist_t
*stores_list
= NULL
;
1204 /* We dynamically fill the store with all the metrics upon a request. The
1205 * reason for this is because the exposed metrics of a relay are often
1206 * internal counters in the fast path and thus we fetch the value when a
1207 * metrics port request arrives instead of keeping a local metrics store of
1212 stores_list
= smartlist_new();
1213 smartlist_add(stores_list
, the_store
);
1219 /** Initialize the relay metrics. */
1221 relay_metrics_init(void)
1223 if (BUG(the_store
)) {
1226 the_store
= metrics_store_new();
1229 /** Free the relay metrics. */
1231 relay_metrics_free(void)
1236 /* NULL is set with this call. */
1237 metrics_store_free(the_store
);