Merge branch 'maint-0.4.8'
[tor.git] / src / feature / relay / relay_metrics.c
blob492a5945b85b44ebe7646b80046dcd83d22068c3
1 /* Copyright (c) 2021, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
4 /**
5 * @file relay_metrics.c
6 * @brief Relay metrics exposed through the MetricsPort
7 **/
9 #define RELAY_METRICS_ENTRY_PRIVATE
11 #include "orconfig.h"
13 #include "core/or/or.h"
14 #include "core/mainloop/connection.h"
15 #include "core/mainloop/mainloop.h"
16 #include "core/or/command.h"
17 #include "core/or/congestion_control_common.h"
18 #include "core/or/congestion_control_vegas.h"
19 #include "core/or/congestion_control_flow.h"
20 #include "core/or/circuitlist.h"
21 #include "core/or/dos.h"
22 #include "core/or/relay.h"
24 #include "app/config/config.h"
26 #include "lib/container/smartlist.h"
27 #include "lib/log/util_bug.h"
28 #include "lib/malloc/malloc.h"
29 #include "lib/math/fp.h"
30 #include "lib/metrics/metrics_store.h"
32 #include "feature/hs/hs_dos.h"
33 #include "feature/nodelist/nodelist.h"
34 #include "feature/nodelist/node_st.h"
35 #include "feature/nodelist/routerstatus_st.h"
36 #include "feature/nodelist/torcert.h"
37 #include "feature/relay/relay_metrics.h"
38 #include "feature/relay/router.h"
39 #include "feature/relay/routerkeys.h"
40 #include "feature/stats/rephist.h"
42 #include <event2/dns.h>
44 /** Declarations of each fill function for metrics defined in base_metrics. */
45 static void fill_cc_counters_values(void);
46 static void fill_cc_gauges_values(void);
47 static void fill_circuits_values(void);
48 static void fill_conn_counter_values(void);
49 static void fill_conn_gauge_values(void);
50 static void fill_dns_error_values(void);
51 static void fill_dns_query_values(void);
52 static void fill_dos_values(void);
53 static void fill_global_bw_limit_values(void);
54 static void fill_socket_values(void);
55 static void fill_onionskins_values(void);
56 static void fill_oom_values(void);
57 static void fill_streams_values(void);
58 static void fill_relay_circ_proto_violation(void);
59 static void fill_relay_destroy_cell(void);
60 static void fill_relay_drop_cell(void);
61 static void fill_relay_flags(void);
62 static void fill_tcp_exhaustion_values(void);
63 static void fill_traffic_values(void);
64 static void fill_signing_cert_expiry(void);
66 static void fill_est_intro_cells(void);
67 static void fill_est_rend_cells(void);
68 static void fill_intro1_cells(void);
69 static void fill_rend1_cells(void);
71 /** The base metrics that is a static array of metrics added to the metrics
72 * store.
74 * The key member MUST be also the index of the entry in the array. */
75 static const relay_metrics_entry_t base_metrics[] =
78 .key = RELAY_METRICS_NUM_OOM_BYTES,
79 .type = METRICS_TYPE_COUNTER,
80 .name = METRICS_NAME(relay_load_oom_bytes_total),
81 .help = "Total number of bytes the OOM has freed by subsystem",
82 .fill_fn = fill_oom_values,
85 .key = RELAY_METRICS_NUM_ONIONSKINS,
86 .type = METRICS_TYPE_COUNTER,
87 .name = METRICS_NAME(relay_load_onionskins_total),
88 .help = "Total number of onionskins handled",
89 .fill_fn = fill_onionskins_values,
92 .key = RELAY_METRICS_NUM_SOCKETS,
93 .type = METRICS_TYPE_GAUGE,
94 .name = METRICS_NAME(relay_load_socket_total),
95 .help = "Total number of sockets",
96 .fill_fn = fill_socket_values,
99 .key = RELAY_METRICS_NUM_GLOBAL_RW_LIMIT,
100 .type = METRICS_TYPE_COUNTER,
101 .name = METRICS_NAME(relay_load_global_rate_limit_reached_total),
102 .help = "Total number of global connection bucket limit reached",
103 .fill_fn = fill_global_bw_limit_values,
106 .key = RELAY_METRICS_NUM_DNS,
107 .type = METRICS_TYPE_COUNTER,
108 .name = METRICS_NAME(relay_exit_dns_query_total),
109 .help = "Total number of DNS queries done by this relay",
110 .fill_fn = fill_dns_query_values,
113 .key = RELAY_METRICS_NUM_DNS_ERRORS,
114 .type = METRICS_TYPE_COUNTER,
115 .name = METRICS_NAME(relay_exit_dns_error_total),
116 .help = "Total number of DNS errors encountered by this relay",
117 .fill_fn = fill_dns_error_values,
120 .key = RELAY_METRICS_NUM_TCP_EXHAUSTION,
121 .type = METRICS_TYPE_COUNTER,
122 .name = METRICS_NAME(relay_load_tcp_exhaustion_total),
123 .help = "Total number of times we ran out of TCP ports",
124 .fill_fn = fill_tcp_exhaustion_values,
127 .key = RELAY_METRICS_CONN_COUNTERS,
128 .type = METRICS_TYPE_COUNTER,
129 .name = METRICS_NAME(relay_connections_total),
130 .help = "Total number of created/rejected connections",
131 .fill_fn = fill_conn_counter_values,
134 .key = RELAY_METRICS_CONN_GAUGES,
135 .type = METRICS_TYPE_GAUGE,
136 .name = METRICS_NAME(relay_connections),
137 .help = "Total number of opened connections",
138 .fill_fn = fill_conn_gauge_values,
141 .key = RELAY_METRICS_NUM_STREAMS,
142 .type = METRICS_TYPE_COUNTER,
143 .name = METRICS_NAME(relay_streams_total),
144 .help = "Total number of streams",
145 .fill_fn = fill_streams_values,
148 .key = RELAY_METRICS_CC_COUNTERS,
149 .type = METRICS_TYPE_COUNTER,
150 .name = METRICS_NAME(relay_congestion_control_total),
151 .help = "Congestion control related counters",
152 .fill_fn = fill_cc_counters_values,
155 .key = RELAY_METRICS_CC_GAUGES,
156 .type = METRICS_TYPE_GAUGE,
157 .name = METRICS_NAME(relay_congestion_control),
158 .help = "Congestion control related gauges",
159 .fill_fn = fill_cc_gauges_values,
162 .key = RELAY_METRICS_NUM_DOS,
163 .type = METRICS_TYPE_COUNTER,
164 .name = METRICS_NAME(relay_dos_total),
165 .help = "Denial of Service defenses related counters",
166 .fill_fn = fill_dos_values,
169 .key = RELAY_METRICS_NUM_TRAFFIC,
170 .type = METRICS_TYPE_COUNTER,
171 .name = METRICS_NAME(relay_traffic_bytes),
172 .help = "Traffic related counters",
173 .fill_fn = fill_traffic_values,
176 .key = RELAY_METRICS_RELAY_FLAGS,
177 .type = METRICS_TYPE_GAUGE,
178 .name = METRICS_NAME(relay_flag),
179 .help = "Relay flags from consensus",
180 .fill_fn = fill_relay_flags,
183 .key = RELAY_METRICS_NUM_CIRCUITS,
184 .type = METRICS_TYPE_GAUGE,
185 .name = METRICS_NAME(relay_circuits_total),
186 .help = "Total number of circuits",
187 .fill_fn = fill_circuits_values,
190 .key = RELAY_METRICS_SIGNING_CERT_EXPIRY,
191 .type = METRICS_TYPE_GAUGE,
192 .name = METRICS_NAME(relay_signing_cert_expiry_timestamp),
193 .help = "Timestamp at which the current online keys will expire",
194 .fill_fn = fill_signing_cert_expiry,
197 .key = RELAY_METRICS_NUM_EST_REND,
198 .type = METRICS_TYPE_COUNTER,
199 .name = METRICS_NAME(relay_est_rend_total),
200 .help = "Total number of EST_REND cells we received",
201 .fill_fn = fill_est_rend_cells,
204 .key = RELAY_METRICS_NUM_EST_INTRO,
205 .type = METRICS_TYPE_COUNTER,
206 .name = METRICS_NAME(relay_est_intro_total),
207 .help = "Total number of EST_INTRO cells we received",
208 .fill_fn = fill_est_intro_cells,
211 .key = RELAY_METRICS_NUM_INTRO1_CELLS,
212 .type = METRICS_TYPE_COUNTER,
213 .name = METRICS_NAME(relay_intro1_total),
214 .help = "Total number of INTRO1 cells we received",
215 .fill_fn = fill_intro1_cells,
218 .key = RELAY_METRICS_NUM_REND1_CELLS,
219 .type = METRICS_TYPE_COUNTER,
220 .name = METRICS_NAME(relay_rend1_total),
221 .help = "Total number of REND1 cells we received",
222 .fill_fn = fill_rend1_cells,
225 .key = RELAY_METRICS_CIRC_DESTROY_CELL,
226 .type = METRICS_TYPE_COUNTER,
227 .name = METRICS_NAME(relay_destroy_cell_total),
228 .help = "Total number of DESTROY cell we received",
229 .fill_fn = fill_relay_destroy_cell,
232 .key = RELAY_METRICS_CIRC_PROTO_VIOLATION,
233 .type = METRICS_TYPE_COUNTER,
234 .name = METRICS_NAME(relay_circ_proto_violation_total),
235 .help = "Total number of circuit protocol violation",
236 .fill_fn = fill_relay_circ_proto_violation,
239 .key = RELAY_METRICS_CIRC_DROP_CELL,
240 .type = METRICS_TYPE_COUNTER,
241 .name = METRICS_NAME(relay_drop_cell_total),
242 .help = "Total number of DROP cell we received",
243 .fill_fn = fill_relay_drop_cell,
246 static const size_t num_base_metrics = ARRAY_LENGTH(base_metrics);
248 /** The only and single store of all the relay metrics. */
249 static metrics_store_t *the_store;
251 /** Helper function to convert an handshake type into a string. */
252 static inline const char *
253 handshake_type_to_str(const uint16_t type)
255 switch (type) {
256 case ONION_HANDSHAKE_TYPE_TAP:
257 return "tap";
258 case ONION_HANDSHAKE_TYPE_FAST:
259 return "fast";
260 case ONION_HANDSHAKE_TYPE_NTOR:
261 return "ntor";
262 case ONION_HANDSHAKE_TYPE_NTOR_V3:
263 return "ntor_v3";
264 default:
265 // LCOV_EXCL_START
266 tor_assert_unreached();
267 // LCOV_EXCL_STOP
271 /** Helper function to convert a socket family type into a string. */
272 static inline const char *
273 af_to_string(const int af)
275 switch (af) {
276 case AF_INET:
277 return "ipv4";
278 case AF_INET6:
279 return "ipv6";
280 case AF_UNIX:
281 return "unix";
282 default:
283 return "<unknown>";
287 /** Fill function for the RELAY_METRICS_NUM_CIRCUITS metric. */
288 static void
289 fill_circuits_values(void)
291 const relay_metrics_entry_t *rentry =
292 &base_metrics[RELAY_METRICS_NUM_CIRCUITS];
293 metrics_store_entry_t *sentry = metrics_store_add(
294 the_store, rentry->type, rentry->name, rentry->help, 0, NULL);
296 metrics_store_entry_add_label(sentry,
297 metrics_format_label("state", "opened"));
298 metrics_store_entry_update(sentry,
299 smartlist_len(circuit_get_global_list()));
302 /** Fill function for the RELAY_METRICS_RELAY_FLAGS metric. */
303 static void
304 fill_relay_flags(void)
306 uint8_t is_fast = 0, is_exit = 0, is_authority = 0, is_stable = 0;
307 uint8_t is_running = 0, is_v2_dir = 0, is_guard = 0, is_sybil = 0;
308 uint8_t is_hs_dir = 0;
310 const node_t *me =
311 node_get_by_id((const char *) router_get_my_id_digest());
312 if (me && me->rs) {
313 is_fast = me->rs->is_fast;
314 is_exit = me->rs->is_exit;
315 is_authority = me->rs->is_authority;
316 is_stable = me->rs->is_stable;
317 is_running = me->rs->is_flagged_running;
318 is_v2_dir = me->rs->is_v2_dir;
319 is_guard = me->rs->is_possible_guard;
320 is_sybil = me->rs->is_sybil;
321 is_hs_dir = me->rs->is_hs_dir;
324 const relay_metrics_entry_t *rentry =
325 &base_metrics[RELAY_METRICS_RELAY_FLAGS];
326 metrics_store_entry_t *sentry = metrics_store_add(
327 the_store, rentry->type, rentry->name, rentry->help, 0, NULL);
329 metrics_store_entry_add_label(sentry,
330 metrics_format_label("type", "Fast"));
331 metrics_store_entry_update(sentry, is_fast);
333 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
334 rentry->help, 0, NULL);
335 metrics_store_entry_add_label(sentry,
336 metrics_format_label("type", "Exit"));
337 metrics_store_entry_update(sentry, is_exit);
339 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
340 rentry->help, 0, NULL);
341 metrics_store_entry_add_label(sentry,
342 metrics_format_label("type", "Authority"));
343 metrics_store_entry_update(sentry, is_authority);
345 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
346 rentry->help, 0, NULL);
347 metrics_store_entry_add_label(sentry,
348 metrics_format_label("type", "Stable"));
349 metrics_store_entry_update(sentry, is_stable);
351 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
352 rentry->help, 0, NULL);
353 metrics_store_entry_add_label(sentry,
354 metrics_format_label("type", "HSDir"));
355 metrics_store_entry_update(sentry, is_hs_dir);
357 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
358 rentry->help, 0, NULL);
359 metrics_store_entry_add_label(sentry,
360 metrics_format_label("type", "Running"));
361 metrics_store_entry_update(sentry, is_running);
363 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
364 rentry->help, 0, NULL);
365 metrics_store_entry_add_label(sentry,
366 metrics_format_label("type", "V2Dir"));
367 metrics_store_entry_update(sentry, is_v2_dir);
369 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
370 rentry->help, 0, NULL);
371 metrics_store_entry_add_label(sentry,
372 metrics_format_label("type", "Sybil"));
373 metrics_store_entry_update(sentry, is_sybil);
375 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
376 rentry->help, 0, NULL);
377 metrics_store_entry_add_label(sentry,
378 metrics_format_label("type", "Guard"));
379 metrics_store_entry_update(sentry, is_guard);
382 /** Fill function for the RELAY_METRICS_NUM_TRAFFIC metric. */
383 static void
384 fill_traffic_values(void)
386 const relay_metrics_entry_t *rentry =
387 &base_metrics[RELAY_METRICS_NUM_TRAFFIC];
388 metrics_store_entry_t *sentry = metrics_store_add(
389 the_store, rentry->type, rentry->name, rentry->help, 0, NULL);
391 metrics_store_entry_add_label(sentry,
392 metrics_format_label("direction", "read"));
393 metrics_store_entry_update(sentry, get_bytes_read());
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("direction", "written"));
399 metrics_store_entry_update(sentry, get_bytes_written());
402 /** Fill function for the RELAY_METRICS_NUM_DOS metric. */
403 static void
404 fill_dos_values(void)
406 const relay_metrics_entry_t *rentry = &base_metrics[RELAY_METRICS_NUM_DOS];
407 metrics_store_entry_t *sentry = metrics_store_add(
408 the_store, rentry->type, rentry->name, rentry->help, 0, NULL);
410 metrics_store_entry_add_label(sentry,
411 metrics_format_label("type", "circuit_rejected"));
412 metrics_store_entry_update(sentry, dos_get_num_cc_rejected());
414 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
415 rentry->help, 0, NULL);
416 metrics_store_entry_add_label(sentry,
417 metrics_format_label("type", "circuit_killed_max_cell"));
418 metrics_store_entry_update(sentry, stats_n_circ_max_cell_reached);
420 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
421 rentry->help, 0, NULL);
422 metrics_store_entry_add_label(sentry,
423 metrics_format_label("type", "circuit_killed_max_cell_outq"));
424 metrics_store_entry_update(sentry, stats_n_circ_max_cell_outq_reached);
426 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
427 rentry->help, 0, NULL);
428 metrics_store_entry_add_label(sentry,
429 metrics_format_label("type", "marked_address"));
430 metrics_store_entry_update(sentry, dos_get_num_cc_marked_addr());
432 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
433 rentry->help, 0, NULL);
434 metrics_store_entry_add_label(sentry,
435 metrics_format_label("type", "marked_address_maxq"));
436 metrics_store_entry_update(sentry, dos_get_num_cc_marked_addr_maxq());
438 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
439 rentry->help, 0, NULL);
440 metrics_store_entry_add_label(sentry,
441 metrics_format_label("type", "conn_rejected"));
442 metrics_store_entry_update(sentry, dos_get_num_conn_addr_connect_rejected());
444 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
445 rentry->help, 0, NULL);
446 metrics_store_entry_add_label(sentry,
447 metrics_format_label("type", "concurrent_conn_rejected"));
448 metrics_store_entry_update(sentry, dos_get_num_conn_addr_rejected());
450 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
451 rentry->help, 0, NULL);
452 metrics_store_entry_add_label(sentry,
453 metrics_format_label("type", "single_hop_refused"));
454 metrics_store_entry_update(sentry, dos_get_num_single_hop_refused());
456 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
457 rentry->help, 0, NULL);
458 metrics_store_entry_add_label(sentry,
459 metrics_format_label("type", "introduce2_rejected"));
460 metrics_store_entry_update(sentry, hs_dos_get_intro2_rejected_count());
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("type", "stream_rejected"));
466 metrics_store_entry_update(sentry, dos_get_num_stream_rejected());
469 /** Fill function for the RELAY_METRICS_CC_COUNTERS metric. */
470 static void
471 fill_cc_counters_values(void)
473 const relay_metrics_entry_t *rentry =
474 &base_metrics[RELAY_METRICS_CC_COUNTERS];
476 metrics_store_entry_t *sentry = metrics_store_add(
477 the_store, rentry->type, rentry->name, rentry->help, 0, NULL);
478 metrics_store_entry_add_label(sentry,
479 metrics_format_label("state", "starvation"));
480 metrics_store_entry_add_label(sentry,
481 metrics_format_label("action", "rtt_reset"));
482 metrics_store_entry_update(sentry, congestion_control_get_num_rtt_reset());
484 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
485 rentry->help, 0, NULL);
486 metrics_store_entry_add_label(sentry,
487 metrics_format_label("state", "clock_stalls"));
488 metrics_store_entry_add_label(sentry,
489 metrics_format_label("action", "rtt_skipped"));
490 metrics_store_entry_update(sentry,
491 congestion_control_get_num_clock_stalls());
493 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
494 rentry->help, 0, NULL);
495 metrics_store_entry_add_label(sentry,
496 metrics_format_label("state", "flow_control"));
497 metrics_store_entry_add_label(sentry,
498 metrics_format_label("action", "xoff_num_sent"));
499 metrics_store_entry_update(sentry,
500 cc_stats_flow_num_xoff_sent);
502 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
503 rentry->help, 0, NULL);
504 metrics_store_entry_add_label(sentry,
505 metrics_format_label("state", "flow_control"));
506 metrics_store_entry_add_label(sentry,
507 metrics_format_label("action", "xon_num_sent"));
508 metrics_store_entry_update(sentry,
509 cc_stats_flow_num_xon_sent);
511 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
512 rentry->help, 0, NULL);
513 metrics_store_entry_add_label(sentry,
514 metrics_format_label("state", "cc_limits"));
515 metrics_store_entry_add_label(sentry,
516 metrics_format_label("action", "above_delta"));
517 metrics_store_entry_update(sentry, cc_stats_vegas_above_delta);
519 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
520 rentry->help, 0, NULL);
521 metrics_store_entry_add_label(sentry,
522 metrics_format_label("state", "cc_limits"));
523 metrics_store_entry_add_label(sentry,
524 metrics_format_label("action", "above_ss_cwnd_max"));
525 metrics_store_entry_update(sentry, cc_stats_vegas_above_ss_cwnd_max);
527 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
528 rentry->help, 0, NULL);
529 metrics_store_entry_add_label(sentry,
530 metrics_format_label("state", "cc_limits"));
531 metrics_store_entry_add_label(sentry,
532 metrics_format_label("action", "below_ss_inc_floor"));
533 metrics_store_entry_update(sentry, cc_stats_vegas_below_ss_inc_floor);
535 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
536 rentry->help, 0, NULL);
537 metrics_store_entry_add_label(sentry,
538 metrics_format_label("state", "cc_circuits"));
539 metrics_store_entry_add_label(sentry,
540 metrics_format_label("action", "circs_created"));
541 metrics_store_entry_update(sentry, cc_stats_circs_created);
543 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
544 rentry->help, 0, NULL);
545 metrics_store_entry_add_label(sentry,
546 metrics_format_label("state", "cc_circuits"));
547 metrics_store_entry_add_label(sentry,
548 metrics_format_label("action", "circs_closed"));
549 metrics_store_entry_update(sentry, cc_stats_circs_closed);
551 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
552 rentry->help, 0, NULL);
553 metrics_store_entry_add_label(sentry,
554 metrics_format_label("state", "cc_circuits"));
555 metrics_store_entry_add_label(sentry,
556 metrics_format_label("action", "circs_exited_ss"));
557 metrics_store_entry_update(sentry, cc_stats_vegas_circ_exited_ss);
560 /** Fill function for the RELAY_METRICS_CC_GAUGES metric. */
561 static void
562 fill_cc_gauges_values(void)
564 const relay_metrics_entry_t *rentry =
565 &base_metrics[RELAY_METRICS_CC_GAUGES];
567 metrics_store_entry_t *sentry = metrics_store_add(
568 the_store, rentry->type, rentry->name, rentry->help, 0, NULL);
569 metrics_store_entry_add_label(sentry,
570 metrics_format_label("state", "slow_start_exit"));
571 metrics_store_entry_add_label(sentry,
572 metrics_format_label("action", "cwnd"));
573 metrics_store_entry_update(sentry,
574 tor_llround(cc_stats_vegas_exit_ss_cwnd_ma));
576 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
577 rentry->help, 0, NULL);
578 metrics_store_entry_add_label(sentry,
579 metrics_format_label("state", "slow_start_exit"));
580 metrics_store_entry_add_label(sentry,
581 metrics_format_label("action", "bdp"));
582 metrics_store_entry_update(sentry,
583 tor_llround(cc_stats_vegas_exit_ss_bdp_ma));
585 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
586 rentry->help, 0, NULL);
587 metrics_store_entry_add_label(sentry,
588 metrics_format_label("state", "slow_start_exit"));
589 metrics_store_entry_add_label(sentry,
590 metrics_format_label("action", "inc"));
591 metrics_store_entry_update(sentry,
592 tor_llround(cc_stats_vegas_exit_ss_inc_ma));
594 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
595 rentry->help, 0, NULL);
596 metrics_store_entry_add_label(sentry,
597 metrics_format_label("state", "on_circ_close"));
598 metrics_store_entry_add_label(sentry,
599 metrics_format_label("action", "cwnd"));
600 metrics_store_entry_update(sentry,
601 tor_llround(cc_stats_circ_close_cwnd_ma));
603 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
604 rentry->help, 0, NULL);
605 metrics_store_entry_add_label(sentry,
606 metrics_format_label("state", "on_circ_close"));
607 metrics_store_entry_add_label(sentry,
608 metrics_format_label("action", "ss_cwnd"));
609 metrics_store_entry_update(sentry,
610 tor_llround(cc_stats_circ_close_ss_cwnd_ma));
612 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
613 rentry->help, 0, NULL);
614 metrics_store_entry_add_label(sentry,
615 metrics_format_label("state", "buffers"));
616 metrics_store_entry_add_label(sentry,
617 metrics_format_label("action", "xon_outbuf"));
618 metrics_store_entry_update(sentry,
619 tor_llround(cc_stats_flow_xon_outbuf_ma));
621 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
622 rentry->help, 0, NULL);
623 metrics_store_entry_add_label(sentry,
624 metrics_format_label("state", "buffers"));
625 metrics_store_entry_add_label(sentry,
626 metrics_format_label("action", "xoff_outbuf"));
627 metrics_store_entry_update(sentry,
628 tor_llround(cc_stats_flow_xoff_outbuf_ma));
630 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
631 rentry->help, 0, NULL);
632 metrics_store_entry_add_label(sentry,
633 metrics_format_label("state", "cc_backoff"));
634 metrics_store_entry_add_label(sentry,
635 metrics_format_label("action", "chan_blocked_pct"));
636 metrics_store_entry_update(sentry,
637 tor_llround(cc_stats_vegas_csig_blocked_ma));
639 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
640 rentry->help, 0, NULL);
641 metrics_store_entry_add_label(sentry,
642 metrics_format_label("state", "cc_backoff"));
643 metrics_store_entry_add_label(sentry,
644 metrics_format_label("action", "gamma_drop"));
645 metrics_store_entry_update(sentry,
646 tor_llround(cc_stats_vegas_gamma_drop_ma));
648 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
649 rentry->help, 0, NULL);
650 metrics_store_entry_add_label(sentry,
651 metrics_format_label("state", "cc_backoff"));
652 metrics_store_entry_add_label(sentry,
653 metrics_format_label("action", "delta_drop"));
654 metrics_store_entry_update(sentry,
655 tor_llround(cc_stats_vegas_delta_drop_ma));
657 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
658 rentry->help, 0, NULL);
659 metrics_store_entry_add_label(sentry,
660 metrics_format_label("state", "cc_backoff"));
661 metrics_store_entry_add_label(sentry,
662 metrics_format_label("action", "ss_chan_blocked_pct"));
663 metrics_store_entry_update(sentry,
664 tor_llround(cc_stats_vegas_ss_csig_blocked_ma));
666 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
667 rentry->help, 0, NULL);
668 metrics_store_entry_add_label(sentry,
669 metrics_format_label("state", "cc_cwnd_update"));
670 metrics_store_entry_add_label(sentry,
671 metrics_format_label("action", "alpha_pct"));
672 metrics_store_entry_update(sentry,
673 tor_llround(cc_stats_vegas_csig_alpha_ma));
675 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
676 rentry->help, 0, NULL);
677 metrics_store_entry_add_label(sentry,
678 metrics_format_label("state", "cc_cwnd_update"));
679 metrics_store_entry_add_label(sentry,
680 metrics_format_label("action", "beta_pct"));
681 metrics_store_entry_update(sentry,
682 tor_llround(cc_stats_vegas_csig_beta_ma));
684 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
685 rentry->help, 0, NULL);
686 metrics_store_entry_add_label(sentry,
687 metrics_format_label("state", "cc_cwnd_update"));
688 metrics_store_entry_add_label(sentry,
689 metrics_format_label("action", "delta_pct"));
690 metrics_store_entry_update(sentry,
691 tor_llround(cc_stats_vegas_csig_delta_ma));
693 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
694 rentry->help, 0, NULL);
695 metrics_store_entry_add_label(sentry,
696 metrics_format_label("state", "cc_estimates"));
697 metrics_store_entry_add_label(sentry,
698 metrics_format_label("action", "ss_queue"));
699 metrics_store_entry_update(sentry,
700 tor_llround(cc_stats_vegas_ss_queue_ma));
702 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
703 rentry->help, 0, NULL);
704 metrics_store_entry_add_label(sentry,
705 metrics_format_label("state", "cc_estimates"));
706 metrics_store_entry_add_label(sentry,
707 metrics_format_label("action", "queue"));
708 metrics_store_entry_update(sentry,
709 tor_llround(cc_stats_vegas_queue_ma));
711 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
712 rentry->help, 0, NULL);
713 metrics_store_entry_add_label(sentry,
714 metrics_format_label("state", "cc_estimates"));
715 metrics_store_entry_add_label(sentry,
716 metrics_format_label("action", "bdp"));
717 metrics_store_entry_update(sentry,
718 tor_llround(cc_stats_vegas_bdp_ma));
721 /** Helper: Fill in single stream metrics output. */
722 static void
723 fill_single_stream_value(metrics_store_entry_t *sentry, uint8_t cmd)
725 metrics_store_entry_add_label(sentry,
726 metrics_format_label("type", relay_command_to_string(cmd)));
727 metrics_store_entry_update(sentry, rep_hist_get_exit_stream_seen(cmd));
730 /** Fill function for the RELAY_METRICS_NUM_STREAMS metric. */
731 static void
732 fill_streams_values(void)
734 const relay_metrics_entry_t *rentry =
735 &base_metrics[RELAY_METRICS_NUM_STREAMS];
736 metrics_store_entry_t *sentry = metrics_store_add(
737 the_store, rentry->type, rentry->name, rentry->help, 0, NULL);
738 fill_single_stream_value(sentry, RELAY_COMMAND_BEGIN);
740 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
741 rentry->help, 0, NULL);
742 fill_single_stream_value(sentry, RELAY_COMMAND_BEGIN_DIR);
744 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
745 rentry->help, 0, NULL);
746 fill_single_stream_value(sentry, RELAY_COMMAND_RESOLVE);
749 /** Helper: Fill in single connection metrics output. */
750 static void
751 fill_single_connection_value(metrics_store_entry_t *sentry,
752 unsigned int conn_type,
753 const char* direction,
754 const char* state,
755 int socket_family,
756 uint64_t value)
758 metrics_store_entry_add_label(sentry,
759 metrics_format_label("type", conn_type_to_string(conn_type)));
760 metrics_store_entry_add_label(sentry,
761 metrics_format_label("direction", direction));
762 metrics_store_entry_add_label(sentry,
763 metrics_format_label("state", state));
764 metrics_store_entry_add_label(sentry,
765 metrics_format_label("family", af_to_string(socket_family)));
766 metrics_store_entry_update(sentry, value);
769 /** Fill function for the RELAY_METRICS_CONN_COUNTERS metric. */
770 static void
771 fill_conn_counter_values(void)
773 const relay_metrics_entry_t *rentry =
774 &base_metrics[RELAY_METRICS_CONN_COUNTERS];
776 for (unsigned int i = CONN_TYPE_MIN_; i < CONN_TYPE_MAX_ ; i++) {
777 /* Type is unused. Ugly but else we clobber the output. */
778 if (i == 10) {
779 continue;
781 metrics_store_entry_t *sentry = metrics_store_add(
782 the_store, rentry->type, rentry->name, rentry->help, 0, NULL);
783 fill_single_connection_value(sentry, i, "initiated", "created", AF_INET,
784 rep_hist_get_conn_created(false, i, AF_INET));
785 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
786 rentry->help, 0, NULL);
787 fill_single_connection_value(sentry, i, "initiated", "created", AF_INET6,
788 rep_hist_get_conn_created(false, i,
789 AF_INET6));
791 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
792 rentry->help, 0, NULL);
793 fill_single_connection_value(sentry, i, "received", "created", AF_INET,
794 rep_hist_get_conn_created(true, i, AF_INET));
795 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
796 rentry->help, 0, NULL);
797 fill_single_connection_value(sentry, i, "received", "created", AF_INET6,
798 rep_hist_get_conn_created(true, i, AF_INET6));
800 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
801 rentry->help, 0, NULL);
802 fill_single_connection_value(sentry, i, "received", "rejected", AF_INET,
803 rep_hist_get_conn_rejected(i, AF_INET));
804 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
805 rentry->help, 0, NULL);
806 fill_single_connection_value(sentry, i, "received", "rejected", AF_INET6,
807 rep_hist_get_conn_rejected(i, AF_INET6));
809 /* No counter for "initiated" + "rejected" connections exists. */
813 /** Fill function for the RELAY_METRICS_CONN_GAUGES metric. */
814 static void
815 fill_conn_gauge_values(void)
817 const relay_metrics_entry_t *rentry =
818 &base_metrics[RELAY_METRICS_CONN_GAUGES];
820 for (unsigned int i = CONN_TYPE_MIN_; i < CONN_TYPE_MAX_ ; i++) {
821 /* Type is unused. Ugly but else we clobber the output. */
822 if (i == 10) {
823 continue;
825 metrics_store_entry_t *sentry = metrics_store_add(
826 the_store, rentry->type, rentry->name, rentry->help, 0, NULL);
827 fill_single_connection_value(sentry, i, "initiated", "opened", AF_INET,
828 rep_hist_get_conn_opened(false, i, AF_INET));
829 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
830 rentry->help, 0, NULL);
831 fill_single_connection_value(sentry, i, "initiated", "opened", AF_INET6,
832 rep_hist_get_conn_opened(false, i, AF_INET6));
834 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
835 rentry->help, 0, NULL);
836 fill_single_connection_value(sentry, i, "received", "opened", AF_INET,
837 rep_hist_get_conn_opened(true, i, AF_INET));
838 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
839 rentry->help, 0, NULL);
840 fill_single_connection_value(sentry, i, "received", "opened", AF_INET6,
841 rep_hist_get_conn_opened(true, i, AF_INET6));
845 /** Fill function for the RELAY_METRICS_NUM_DNS metrics. */
846 static void
847 fill_tcp_exhaustion_values(void)
849 metrics_store_entry_t *sentry;
850 const relay_metrics_entry_t *rentry =
851 &base_metrics[RELAY_METRICS_NUM_TCP_EXHAUSTION];
853 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
854 rentry->help, 0, NULL);
855 metrics_store_entry_update(sentry, rep_hist_get_n_tcp_exhaustion());
858 /* NOTE: Disable the record type label until libevent is fixed. */
859 #if 0
860 /** Helper array containing mapping for the name of the different DNS records
861 * and their corresponding libevent values. */
862 static struct dns_type {
863 const char *name;
864 uint8_t type;
865 } dns_types[] = {
866 { .name = "A", .type = DNS_IPv4_A },
867 { .name = "PTR", .type = DNS_PTR },
868 { .name = "AAAA", .type = DNS_IPv6_AAAA },
870 static const size_t num_dns_types = ARRAY_LENGTH(dns_types);
871 #endif
873 /** Fill function for the RELAY_METRICS_NUM_DNS_ERRORS metrics. */
874 static void
875 fill_dns_error_values(void)
877 metrics_store_entry_t *sentry;
878 const relay_metrics_entry_t *rentry =
879 &base_metrics[RELAY_METRICS_NUM_DNS_ERRORS];
881 /* Helper array to map libeven DNS errors to their names and so we can
882 * iterate over this array to add all metrics. */
883 static struct dns_error {
884 const char *name;
885 uint8_t key;
886 } errors[] = {
887 { .name = "success", .key = DNS_ERR_NONE },
888 { .name = "format", .key = DNS_ERR_FORMAT },
889 { .name = "serverfailed", .key = DNS_ERR_SERVERFAILED },
890 { .name = "notexist", .key = DNS_ERR_NOTEXIST },
891 { .name = "notimpl", .key = DNS_ERR_NOTIMPL },
892 { .name = "refused", .key = DNS_ERR_REFUSED },
893 { .name = "truncated", .key = DNS_ERR_TRUNCATED },
894 { .name = "unknown", .key = DNS_ERR_UNKNOWN },
895 { .name = "tor_timeout", .key = DNS_ERR_TIMEOUT },
896 { .name = "shutdown", .key = DNS_ERR_SHUTDOWN },
897 { .name = "cancel", .key = DNS_ERR_CANCEL },
898 { .name = "nodata", .key = DNS_ERR_NODATA },
900 static const size_t num_errors = ARRAY_LENGTH(errors);
902 /* NOTE: Disable the record type label until libevent is fixed. */
903 #if 0
904 for (size_t i = 0; i < num_dns_types; i++) {
905 /* Dup the label because metrics_format_label() returns a pointer to a
906 * string on the stack and we need that label for all metrics. */
907 char *record_label =
908 tor_strdup(metrics_format_label("record", dns_types[i].name));
910 for (size_t j = 0; j < num_errors; j++) {
911 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
912 rentry->help, 0, NULL);
913 metrics_store_entry_add_label(sentry, record_label);
914 metrics_store_entry_add_label(sentry,
915 metrics_format_label("reason", errors[j].name));
916 metrics_store_entry_update(sentry,
917 rep_hist_get_n_dns_error(dns_types[i].type, errors[j].key));
919 tor_free(record_label);
921 #endif
923 /* Put in the DNS errors, unfortunately not per-type for now. */
924 for (size_t j = 0; j < num_errors; j++) {
925 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
926 rentry->help, 0, NULL);
927 metrics_store_entry_add_label(sentry,
928 metrics_format_label("reason", errors[j].name));
929 metrics_store_entry_update(sentry,
930 rep_hist_get_n_dns_error(0, errors[j].key));
934 /** Fill function for the RELAY_METRICS_NUM_DNS metrics. */
935 static void
936 fill_dns_query_values(void)
938 metrics_store_entry_t *sentry;
939 const relay_metrics_entry_t *rentry =
940 &base_metrics[RELAY_METRICS_NUM_DNS];
942 /* NOTE: Disable the record type label until libevent is fixed (#40490). */
943 #if 0
944 for (size_t i = 0; i < num_dns_types; i++) {
945 /* Dup the label because metrics_format_label() returns a pointer to a
946 * string on the stack and we need that label for all metrics. */
947 char *record_label =
948 tor_strdup(metrics_format_label("record", dns_types[i].name));
949 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
950 rentry->help, 0, NULL);
951 metrics_store_entry_add_label(sentry, record_label);
952 metrics_store_entry_update(sentry,
953 rep_hist_get_n_dns_request(dns_types[i].type));
954 tor_free(record_label);
956 #endif
958 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
959 rentry->help, 0, NULL);
960 metrics_store_entry_update(sentry, rep_hist_get_n_dns_request(0));
963 /** Fill function for the RELAY_METRICS_NUM_GLOBAL_RW_LIMIT metrics. */
964 static void
965 fill_global_bw_limit_values(void)
967 metrics_store_entry_t *sentry;
968 const relay_metrics_entry_t *rentry =
969 &base_metrics[RELAY_METRICS_NUM_GLOBAL_RW_LIMIT];
971 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
972 rentry->help, 0, NULL);
973 metrics_store_entry_add_label(sentry,
974 metrics_format_label("side", "read"));
975 metrics_store_entry_update(sentry, rep_hist_get_n_read_limit_reached());
977 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
978 rentry->help, 0, NULL);
979 metrics_store_entry_add_label(sentry,
980 metrics_format_label("side", "write"));
981 metrics_store_entry_update(sentry, rep_hist_get_n_write_limit_reached());
984 /** Fill function for the RELAY_METRICS_NUM_SOCKETS metrics. */
985 static void
986 fill_socket_values(void)
988 metrics_store_entry_t *sentry;
989 const relay_metrics_entry_t *rentry =
990 &base_metrics[RELAY_METRICS_NUM_SOCKETS];
992 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
993 rentry->help, 0, NULL);
994 metrics_store_entry_add_label(sentry,
995 metrics_format_label("state", "opened"));
996 metrics_store_entry_update(sentry, get_n_open_sockets());
998 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
999 rentry->help, 0, NULL);
1000 metrics_store_entry_update(sentry, get_max_sockets());
1003 /** Fill function for the RELAY_METRICS_NUM_ONIONSKINS metrics. */
1004 static void
1005 fill_onionskins_values(void)
1007 metrics_store_entry_t *sentry;
1008 const relay_metrics_entry_t *rentry =
1009 &base_metrics[RELAY_METRICS_NUM_ONIONSKINS];
1011 for (uint16_t t = 0; t <= MAX_ONION_HANDSHAKE_TYPE; t++) {
1012 /* Dup the label because metrics_format_label() returns a pointer to a
1013 * string on the stack and we need that label for all metrics. */
1014 char *type_label =
1015 tor_strdup(metrics_format_label("type", handshake_type_to_str(t)));
1016 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
1017 rentry->help, 0, NULL);
1018 metrics_store_entry_add_label(sentry, type_label);
1019 metrics_store_entry_add_label(sentry,
1020 metrics_format_label("action", "processed"));
1021 metrics_store_entry_update(sentry,
1022 rep_hist_get_circuit_n_handshake_assigned(t));
1024 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
1025 rentry->help, 0, NULL);
1026 metrics_store_entry_add_label(sentry, type_label);
1027 metrics_store_entry_add_label(sentry,
1028 metrics_format_label("action", "dropped"));
1029 metrics_store_entry_update(sentry,
1030 rep_hist_get_circuit_n_handshake_dropped(t));
1031 tor_free(type_label);
1035 /** Fill function for the RELAY_METRICS_NUM_OOM_BYTES metrics. */
1036 static void
1037 fill_oom_values(void)
1039 metrics_store_entry_t *sentry;
1040 const relay_metrics_entry_t *rentry =
1041 &base_metrics[RELAY_METRICS_NUM_OOM_BYTES];
1043 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
1044 rentry->help, 0, NULL);
1045 metrics_store_entry_add_label(sentry,
1046 metrics_format_label("subsys", "cell"));
1047 metrics_store_entry_update(sentry, oom_stats_n_bytes_removed_cell);
1049 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
1050 rentry->help, 0, NULL);
1051 metrics_store_entry_add_label(sentry,
1052 metrics_format_label("subsys", "dns"));
1053 metrics_store_entry_update(sentry, oom_stats_n_bytes_removed_dns);
1055 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
1056 rentry->help, 0, NULL);
1057 metrics_store_entry_add_label(sentry,
1058 metrics_format_label("subsys", "geoip"));
1059 metrics_store_entry_update(sentry, oom_stats_n_bytes_removed_geoip);
1061 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
1062 rentry->help, 0, NULL);
1063 metrics_store_entry_add_label(sentry,
1064 metrics_format_label("subsys", "hsdir"));
1065 metrics_store_entry_update(sentry, oom_stats_n_bytes_removed_hsdir);
1068 /** Fill function for the RELAY_METRICS_SIGNING_CERT_EXPIRY metrics. */
1069 static void
1070 fill_signing_cert_expiry(void)
1072 metrics_store_entry_t *sentry;
1073 const tor_cert_t *signing_key;
1074 const relay_metrics_entry_t *rentry =
1075 &base_metrics[RELAY_METRICS_SIGNING_CERT_EXPIRY];
1077 if (get_options()->OfflineMasterKey) {
1078 signing_key = get_master_signing_key_cert();
1079 if (signing_key) {
1080 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
1081 rentry->help, 0, NULL);
1082 metrics_store_entry_update(sentry, signing_key->valid_until);
1087 static uint64_t est_intro_actions[EST_INTRO_ACTION_COUNT] = {0};
1089 void
1090 relay_increment_est_intro_action(est_intro_action_t action)
1092 est_intro_actions[action]++;
1095 static void
1096 fill_est_intro_cells(void)
1098 metrics_store_entry_t *sentry;
1099 const relay_metrics_entry_t *rentry =
1100 &base_metrics[RELAY_METRICS_NUM_EST_INTRO];
1102 static struct {
1103 const char *name;
1104 est_intro_action_t key;
1105 } actions[] = {
1106 {.name = "success", .key = EST_INTRO_SUCCESS},
1107 {.name = "malformed", .key = EST_INTRO_MALFORMED},
1108 {.name = "unsuitable_circuit", .key = EST_INTRO_UNSUITABLE_CIRCUIT},
1109 {.name = "circuit_dead", .key = EST_INTRO_CIRCUIT_DEAD},
1111 static const size_t num_actions = ARRAY_LENGTH(actions);
1113 for (size_t i = 0; i < num_actions; ++i) {
1114 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
1115 rentry->help, 0, NULL);
1116 metrics_store_entry_add_label(
1117 sentry, metrics_format_label("action", actions[i].name));
1118 metrics_store_entry_update(sentry,
1119 (long)est_intro_actions[actions[i].key]);
1123 static uint64_t est_rend_actions[EST_REND_ACTION_COUNT] = {0};
1125 void
1126 relay_increment_est_rend_action(est_rend_action_t action)
1128 est_rend_actions[action]++;
1131 static void
1132 fill_est_rend_cells(void)
1134 metrics_store_entry_t *sentry;
1135 const relay_metrics_entry_t *rentry =
1136 &base_metrics[RELAY_METRICS_NUM_EST_REND];
1138 static struct {
1139 const char *name;
1140 est_rend_action_t key;
1141 } actions[] = {
1142 {.name = "success", .key = EST_REND_SUCCESS},
1143 {.name = "unsuitable_circuit", .key = EST_REND_UNSUITABLE_CIRCUIT},
1144 {.name = "single_hop", .key = EST_REND_SINGLE_HOP},
1145 {.name = "malformed", .key = EST_REND_MALFORMED},
1146 {.name = "duplicate_cookie", .key = EST_REND_DUPLICATE_COOKIE},
1147 {.name = "circuit_dead", .key = EST_REND_CIRCUIT_DEAD},
1149 static const size_t num_actions = ARRAY_LENGTH(actions);
1151 for (size_t i = 0; i < num_actions; ++i) {
1152 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
1153 rentry->help, 0, NULL);
1154 metrics_store_entry_add_label(
1155 sentry, metrics_format_label("action", actions[i].name));
1156 metrics_store_entry_update(sentry, (long)est_rend_actions[actions[i].key]);
1160 static uint64_t intro1_actions[INTRO1_ACTION_COUNT] = {0};
1162 void
1163 relay_increment_intro1_action(intro1_action_t action)
1165 intro1_actions[action]++;
1168 static void
1169 fill_intro1_cells(void)
1171 metrics_store_entry_t *sentry;
1172 const relay_metrics_entry_t *rentry =
1173 &base_metrics[RELAY_METRICS_NUM_INTRO1_CELLS];
1175 static struct {
1176 const char *name;
1177 intro1_action_t key;
1178 } actions[] = {
1179 {.name = "success", .key = INTRO1_SUCCESS},
1180 {.name = "circuit_dead", .key = INTRO1_CIRCUIT_DEAD},
1181 {.name = "malformed", .key = INTRO1_MALFORMED},
1182 {.name = "unknown_service", .key = INTRO1_UNKNOWN_SERVICE},
1183 {.name = "rate_limited", .key = INTRO1_RATE_LIMITED},
1184 {.name = "circuit_reused", .key = INTRO1_CIRCUIT_REUSED},
1185 {.name = "single_hop", .key = INTRO1_SINGLE_HOP},
1187 static const size_t num_actions = ARRAY_LENGTH(actions);
1189 for (size_t i = 0; i < num_actions; ++i) {
1190 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
1191 rentry->help, 0, NULL);
1192 metrics_store_entry_add_label(
1193 sentry, metrics_format_label("action", actions[i].name));
1194 metrics_store_entry_update(sentry, (long)intro1_actions[actions[i].key]);
1198 static uint64_t rend1_actions[REND1_ACTION_COUNT] = {0};
1200 void
1201 relay_increment_rend1_action(rend1_action_t action)
1203 rend1_actions[action]++;
1206 static void
1207 fill_rend1_cells(void)
1209 metrics_store_entry_t *sentry;
1210 const relay_metrics_entry_t *rentry =
1211 &base_metrics[RELAY_METRICS_NUM_REND1_CELLS];
1213 static struct {
1214 const char *name;
1215 rend1_action_t key;
1216 } actions[] = {
1217 {.name = "success", .key = REND1_SUCCESS},
1218 {.name = "unsuitable_circuit", .key = REND1_UNSUITABLE_CIRCUIT},
1219 {.name = "malformed", .key = REND1_MALFORMED},
1220 {.name = "unknown_cookie", .key = REND1_UNKNOWN_COOKIE},
1221 {.name = "circuit_dead", .key = REND1_CIRCUIT_DEAD},
1223 static const size_t num_actions = ARRAY_LENGTH(actions);
1225 for (size_t i = 0; i < num_actions; ++i) {
1226 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
1227 rentry->help, 0, NULL);
1228 metrics_store_entry_add_label(
1229 sentry, metrics_format_label("action", actions[i].name));
1230 metrics_store_entry_update(sentry, (long)rend1_actions[actions[i].key]);
1234 /** Fill the metrics store for the RELAY_METRICS_CIRC_DESTROY_CELL counter. */
1235 static void
1236 fill_relay_destroy_cell(void)
1238 metrics_store_entry_t *sentry;
1239 const relay_metrics_entry_t *rentry =
1240 &base_metrics[RELAY_METRICS_CIRC_DESTROY_CELL];
1242 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
1243 rentry->help, 0, NULL);
1244 metrics_store_entry_update(sentry,
1245 (int64_t) stats_n_destroy_cells_processed);
1248 /** Fill the metrics store for the RELAY_METRICS_CIRC_DROP_CELL counter. */
1249 static void
1250 fill_relay_drop_cell(void)
1252 metrics_store_entry_t *sentry;
1253 const relay_metrics_entry_t *rentry =
1254 &base_metrics[RELAY_METRICS_CIRC_DROP_CELL];
1256 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
1257 rentry->help, 0, NULL);
1258 metrics_store_entry_update(sentry, rep_hist_get_drop_cell_received_count());
1261 /** Fill the metrics store for the RELAY_METRICS_CIRC_PROTO_VIOLATION. */
1262 static void
1263 fill_relay_circ_proto_violation(void)
1265 metrics_store_entry_t *sentry;
1266 const relay_metrics_entry_t *rentry =
1267 &base_metrics[RELAY_METRICS_CIRC_PROTO_VIOLATION];
1269 sentry = metrics_store_add(the_store, rentry->type, rentry->name,
1270 rentry->help, 0, NULL);
1271 metrics_store_entry_update(sentry, circ_n_proto_violation);
1274 /** Reset the global store and fill it with all the metrics from base_metrics
1275 * and their associated values.
1277 * To pull this off, every metrics has a "fill" function that is called and in
1278 * charge of adding the metrics to the store, appropriate labels and finally
1279 * updating the value to report. */
1280 static void
1281 fill_store(void)
1283 /* Reset the current store, we are about to fill it with all the things. */
1284 metrics_store_reset(the_store);
1286 /* Call the fill function for each metrics. */
1287 for (size_t i = 0; i < num_base_metrics; i++) {
1288 if (BUG(!base_metrics[i].fill_fn)) {
1289 continue;
1291 base_metrics[i].fill_fn();
1295 /** Return a list of all the relay metrics stores. This is the
1296 * function attached to the .get_metrics() member of the subsys_t. */
1297 const smartlist_t *
1298 relay_metrics_get_stores(void)
1300 /* We can't have the caller to free the returned list so keep it static,
1301 * simply update it. */
1302 static smartlist_t *stores_list = NULL;
1304 /* We dynamically fill the store with all the metrics upon a request. The
1305 * reason for this is because the exposed metrics of a relay are often
1306 * internal counters in the fast path and thus we fetch the value when a
1307 * metrics port request arrives instead of keeping a local metrics store of
1308 * those values. */
1309 fill_store();
1311 if (!stores_list) {
1312 stores_list = smartlist_new();
1313 smartlist_add(stores_list, the_store);
1316 return stores_list;
1319 /** Initialize the relay metrics. */
1320 void
1321 relay_metrics_init(void)
1323 if (BUG(the_store)) {
1324 return;
1326 the_store = metrics_store_new();
1329 /** Free the relay metrics. */
1330 void
1331 relay_metrics_free(void)
1333 if (!the_store) {
1334 return;
1336 /* NULL is set with this call. */
1337 metrics_store_free(the_store);