relay_metrics.c (50920B)
1 /* Copyright (c) 2021, The Tor Project, Inc. */ 2 /* See LICENSE for licensing information */ 3 4 /** 5 * @file relay_metrics.c 6 * @brief Relay metrics exposed through the MetricsPort 7 **/ 8 9 #define RELAY_METRICS_ENTRY_PRIVATE 10 11 #include "orconfig.h" 12 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" 23 24 #include "app/config/config.h" 25 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" 31 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" 41 42 #include <event2/dns.h> 43 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); 65 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); 70 71 /** The base metrics that is a static array of metrics added to the metrics 72 * store. 73 * 74 * The key member MUST be also the index of the entry in the array. */ 75 static const relay_metrics_entry_t base_metrics[] = 76 { 77 { 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, 83 }, 84 { 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, 90 }, 91 { 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, 97 }, 98 { 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, 104 }, 105 { 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, 111 }, 112 { 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, 118 }, 119 { 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, 125 }, 126 { 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, 132 }, 133 { 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, 139 }, 140 { 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, 146 }, 147 { 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, 153 }, 154 { 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, 160 }, 161 { 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, 167 }, 168 { 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, 174 }, 175 { 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, 181 }, 182 { 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, 188 }, 189 { 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, 195 }, 196 { 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, 202 }, 203 { 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, 209 }, 210 { 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, 216 }, 217 { 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, 223 }, 224 { 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, 230 }, 231 { 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, 237 }, 238 { 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, 244 }, 245 }; 246 static const size_t num_base_metrics = ARRAY_LENGTH(base_metrics); 247 248 /** The only and single store of all the relay metrics. */ 249 static metrics_store_t *the_store; 250 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) 254 { 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 268 } 269 } 270 271 /** Helper function to convert a socket family type into a string. */ 272 static inline const char * 273 af_to_string(const int af) 274 { 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>"; 284 } 285 } 286 287 /** Fill function for the RELAY_METRICS_NUM_CIRCUITS metric. */ 288 static void 289 fill_circuits_values(void) 290 { 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); 295 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())); 300 } 301 302 /** Fill function for the RELAY_METRICS_RELAY_FLAGS metric. */ 303 static void 304 fill_relay_flags(void) 305 { 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; 309 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; 322 } 323 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); 328 329 metrics_store_entry_add_label(sentry, 330 metrics_format_label("type", "Fast")); 331 metrics_store_entry_update(sentry, is_fast); 332 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); 338 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); 344 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); 350 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); 356 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); 362 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); 368 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); 374 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); 380 } 381 382 /** Fill function for the RELAY_METRICS_NUM_TRAFFIC metric. */ 383 static void 384 fill_traffic_values(void) 385 { 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); 390 391 metrics_store_entry_add_label(sentry, 392 metrics_format_label("direction", "read")); 393 metrics_store_entry_update(sentry, get_bytes_read()); 394 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()); 400 } 401 402 /** Fill function for the RELAY_METRICS_NUM_DOS metric. */ 403 static void 404 fill_dos_values(void) 405 { 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); 409 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()); 413 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); 419 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); 425 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()); 431 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()); 437 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()); 443 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()); 449 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()); 455 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()); 461 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()); 467 } 468 469 /** Fill function for the RELAY_METRICS_CC_COUNTERS metric. */ 470 static void 471 fill_cc_counters_values(void) 472 { 473 const relay_metrics_entry_t *rentry = 474 &base_metrics[RELAY_METRICS_CC_COUNTERS]; 475 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()); 483 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()); 492 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); 501 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); 510 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); 518 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); 526 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); 534 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); 542 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); 550 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); 558 } 559 560 /** Fill function for the RELAY_METRICS_CC_GAUGES metric. */ 561 static void 562 fill_cc_gauges_values(void) 563 { 564 const relay_metrics_entry_t *rentry = 565 &base_metrics[RELAY_METRICS_CC_GAUGES]; 566 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)); 575 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)); 584 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)); 593 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)); 602 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)); 611 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)); 620 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)); 629 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)); 638 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)); 647 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)); 656 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)); 665 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)); 674 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)); 683 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)); 692 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)); 701 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)); 710 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)); 719 } 720 721 /** Helper: Fill in single stream metrics output. */ 722 static void 723 fill_single_stream_value(metrics_store_entry_t *sentry, uint8_t cmd) 724 { 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)); 728 } 729 730 /** Fill function for the RELAY_METRICS_NUM_STREAMS metric. */ 731 static void 732 fill_streams_values(void) 733 { 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); 739 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); 743 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); 747 } 748 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) 757 { 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); 767 } 768 769 /** Fill function for the RELAY_METRICS_CONN_COUNTERS metric. */ 770 static void 771 fill_conn_counter_values(void) 772 { 773 const relay_metrics_entry_t *rentry = 774 &base_metrics[RELAY_METRICS_CONN_COUNTERS]; 775 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; 780 } 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)); 790 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)); 799 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)); 808 809 /* No counter for "initiated" + "rejected" connections exists. */ 810 } 811 } 812 813 /** Fill function for the RELAY_METRICS_CONN_GAUGES metric. */ 814 static void 815 fill_conn_gauge_values(void) 816 { 817 const relay_metrics_entry_t *rentry = 818 &base_metrics[RELAY_METRICS_CONN_GAUGES]; 819 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; 824 } 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)); 833 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)); 842 } 843 } 844 845 /** Fill function for the RELAY_METRICS_NUM_DNS metrics. */ 846 static void 847 fill_tcp_exhaustion_values(void) 848 { 849 metrics_store_entry_t *sentry; 850 const relay_metrics_entry_t *rentry = 851 &base_metrics[RELAY_METRICS_NUM_TCP_EXHAUSTION]; 852 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()); 856 } 857 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 }, 869 }; 870 static const size_t num_dns_types = ARRAY_LENGTH(dns_types); 871 #endif 872 873 /** Fill function for the RELAY_METRICS_NUM_DNS_ERRORS metrics. */ 874 static void 875 fill_dns_error_values(void) 876 { 877 metrics_store_entry_t *sentry; 878 const relay_metrics_entry_t *rentry = 879 &base_metrics[RELAY_METRICS_NUM_DNS_ERRORS]; 880 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 }, 899 }; 900 static const size_t num_errors = ARRAY_LENGTH(errors); 901 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)); 909 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)); 918 } 919 tor_free(record_label); 920 } 921 #endif 922 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)); 931 } 932 } 933 934 /** Fill function for the RELAY_METRICS_NUM_DNS metrics. */ 935 static void 936 fill_dns_query_values(void) 937 { 938 metrics_store_entry_t *sentry; 939 const relay_metrics_entry_t *rentry = 940 &base_metrics[RELAY_METRICS_NUM_DNS]; 941 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); 955 } 956 #endif 957 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)); 961 } 962 963 /** Fill function for the RELAY_METRICS_NUM_GLOBAL_RW_LIMIT metrics. */ 964 static void 965 fill_global_bw_limit_values(void) 966 { 967 metrics_store_entry_t *sentry; 968 const relay_metrics_entry_t *rentry = 969 &base_metrics[RELAY_METRICS_NUM_GLOBAL_RW_LIMIT]; 970 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()); 976 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()); 982 } 983 984 /** Fill function for the RELAY_METRICS_NUM_SOCKETS metrics. */ 985 static void 986 fill_socket_values(void) 987 { 988 metrics_store_entry_t *sentry; 989 const relay_metrics_entry_t *rentry = 990 &base_metrics[RELAY_METRICS_NUM_SOCKETS]; 991 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()); 997 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()); 1001 } 1002 1003 /** Fill function for the RELAY_METRICS_NUM_ONIONSKINS metrics. */ 1004 static void 1005 fill_onionskins_values(void) 1006 { 1007 metrics_store_entry_t *sentry; 1008 const relay_metrics_entry_t *rentry = 1009 &base_metrics[RELAY_METRICS_NUM_ONIONSKINS]; 1010 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)); 1023 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); 1032 } 1033 } 1034 1035 /** Fill function for the RELAY_METRICS_NUM_OOM_BYTES metrics. */ 1036 static void 1037 fill_oom_values(void) 1038 { 1039 metrics_store_entry_t *sentry; 1040 const relay_metrics_entry_t *rentry = 1041 &base_metrics[RELAY_METRICS_NUM_OOM_BYTES]; 1042 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); 1048 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); 1054 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); 1060 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); 1066 } 1067 1068 /** Fill function for the RELAY_METRICS_SIGNING_CERT_EXPIRY metrics. */ 1069 static void 1070 fill_signing_cert_expiry(void) 1071 { 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]; 1076 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); 1083 } 1084 } 1085 } 1086 1087 static uint64_t est_intro_actions[EST_INTRO_ACTION_COUNT] = {0}; 1088 1089 void 1090 relay_increment_est_intro_action(est_intro_action_t action) 1091 { 1092 est_intro_actions[action]++; 1093 } 1094 1095 static void 1096 fill_est_intro_cells(void) 1097 { 1098 metrics_store_entry_t *sentry; 1099 const relay_metrics_entry_t *rentry = 1100 &base_metrics[RELAY_METRICS_NUM_EST_INTRO]; 1101 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}, 1110 }; 1111 static const size_t num_actions = ARRAY_LENGTH(actions); 1112 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]); 1120 } 1121 } 1122 1123 static uint64_t est_rend_actions[EST_REND_ACTION_COUNT] = {0}; 1124 1125 void 1126 relay_increment_est_rend_action(est_rend_action_t action) 1127 { 1128 est_rend_actions[action]++; 1129 } 1130 1131 static void 1132 fill_est_rend_cells(void) 1133 { 1134 metrics_store_entry_t *sentry; 1135 const relay_metrics_entry_t *rentry = 1136 &base_metrics[RELAY_METRICS_NUM_EST_REND]; 1137 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}, 1148 }; 1149 static const size_t num_actions = ARRAY_LENGTH(actions); 1150 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]); 1157 } 1158 } 1159 1160 static uint64_t intro1_actions[INTRO1_ACTION_COUNT] = {0}; 1161 1162 void 1163 relay_increment_intro1_action(intro1_action_t action) 1164 { 1165 intro1_actions[action]++; 1166 } 1167 1168 static void 1169 fill_intro1_cells(void) 1170 { 1171 metrics_store_entry_t *sentry; 1172 const relay_metrics_entry_t *rentry = 1173 &base_metrics[RELAY_METRICS_NUM_INTRO1_CELLS]; 1174 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}, 1186 }; 1187 static const size_t num_actions = ARRAY_LENGTH(actions); 1188 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]); 1195 } 1196 } 1197 1198 static uint64_t rend1_actions[REND1_ACTION_COUNT] = {0}; 1199 1200 void 1201 relay_increment_rend1_action(rend1_action_t action) 1202 { 1203 rend1_actions[action]++; 1204 } 1205 1206 static void 1207 fill_rend1_cells(void) 1208 { 1209 metrics_store_entry_t *sentry; 1210 const relay_metrics_entry_t *rentry = 1211 &base_metrics[RELAY_METRICS_NUM_REND1_CELLS]; 1212 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}, 1222 }; 1223 static const size_t num_actions = ARRAY_LENGTH(actions); 1224 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]); 1231 } 1232 } 1233 1234 /** Fill the metrics store for the RELAY_METRICS_CIRC_DESTROY_CELL counter. */ 1235 static void 1236 fill_relay_destroy_cell(void) 1237 { 1238 metrics_store_entry_t *sentry; 1239 const relay_metrics_entry_t *rentry = 1240 &base_metrics[RELAY_METRICS_CIRC_DESTROY_CELL]; 1241 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); 1246 } 1247 1248 /** Fill the metrics store for the RELAY_METRICS_CIRC_DROP_CELL counter. */ 1249 static void 1250 fill_relay_drop_cell(void) 1251 { 1252 metrics_store_entry_t *sentry; 1253 const relay_metrics_entry_t *rentry = 1254 &base_metrics[RELAY_METRICS_CIRC_DROP_CELL]; 1255 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()); 1259 } 1260 1261 /** Fill the metrics store for the RELAY_METRICS_CIRC_PROTO_VIOLATION. */ 1262 static void 1263 fill_relay_circ_proto_violation(void) 1264 { 1265 metrics_store_entry_t *sentry; 1266 const relay_metrics_entry_t *rentry = 1267 &base_metrics[RELAY_METRICS_CIRC_PROTO_VIOLATION]; 1268 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); 1272 } 1273 1274 /** Reset the global store and fill it with all the metrics from base_metrics 1275 * and their associated values. 1276 * 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) 1282 { 1283 /* Reset the current store, we are about to fill it with all the things. */ 1284 metrics_store_reset(the_store); 1285 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; 1290 } 1291 base_metrics[i].fill_fn(); 1292 } 1293 } 1294 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) 1299 { 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; 1303 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(); 1310 1311 if (!stores_list) { 1312 stores_list = smartlist_new(); 1313 smartlist_add(stores_list, the_store); 1314 } 1315 1316 return stores_list; 1317 } 1318 1319 /** Initialize the relay metrics. */ 1320 void 1321 relay_metrics_init(void) 1322 { 1323 if (BUG(the_store)) { 1324 return; 1325 } 1326 the_store = metrics_store_new(); 1327 } 1328 1329 /** Free the relay metrics. */ 1330 void 1331 relay_metrics_free(void) 1332 { 1333 if (!the_store) { 1334 return; 1335 } 1336 /* NULL is set with this call. */ 1337 metrics_store_free(the_store); 1338 }