This is an automated email from the git hooks/post-receive script.
dgoulet pushed a change to branch main in repository tor.
from 3fa08dc9a7 Merge branch 'tor-gitlab/mr/697' new 8f50f490a6 Update 3 files new d1264d11c3 metrics: Add support for histograms. new 1a60fa547f metrics: Add HS service side circuit build time metrics. new 59456cb3cf Merge branch 'tor-gitlab/mr/700'
The 4 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "add" were already present in the repository and have only been added to this reference.
Summary of changes: changes/ticket40757 | 8 ++ changes/ticket40760 | 3 + src/feature/dirauth/process_descs.c | 13 +-- src/feature/hs/hs_metrics.c | 23 +++-- src/feature/hs/hs_metrics.h | 49 ++++++---- src/feature/hs/hs_metrics_entry.c | 29 ++++++ src/feature/hs/hs_metrics_entry.h | 8 ++ src/feature/hs/hs_service.c | 11 +++ src/feature/relay/relay_metrics.c | 170 +++++++++++++++++----------------- src/lib/metrics/metrics_common.c | 2 + src/lib/metrics/metrics_common.h | 23 +++++ src/lib/metrics/metrics_store.c | 6 +- src/lib/metrics/metrics_store.h | 6 +- src/lib/metrics/metrics_store_entry.c | 157 ++++++++++++++++++++++++++++++- src/lib/metrics/metrics_store_entry.h | 13 ++- src/lib/metrics/prometheus.c | 70 +++++++++++++- src/test/test_hs_metrics.c | 8 +- src/test/test_metrics.c | 146 ++++++++++++++++++++++++++++- src/test/test_process_descs.c | 8 +- 19 files changed, 610 insertions(+), 143 deletions(-) create mode 100644 changes/ticket40757 create mode 100644 changes/ticket40760
This is an automated email from the git hooks/post-receive script.
dgoulet pushed a commit to branch main in repository tor.
commit 8f50f490a67fdbd13cb2ab8bec561d831c943676 Author: nonameformee 545-nonameformee@gitlab.torproject.org AuthorDate: Sun Mar 12 11:40:52 2023 +0000
Update 3 files
- /src/feature/dirauth/process_descs.c - /src/test/test_process_descs.c - /changes/ticket40760 --- changes/ticket40760 | 3 +++ src/feature/dirauth/process_descs.c | 13 ++----------- src/test/test_process_descs.c | 8 +++----- 3 files changed, 8 insertions(+), 16 deletions(-)
diff --git a/changes/ticket40760 b/changes/ticket40760 new file mode 100644 index 0000000000..b5e3df7904 --- /dev/null +++ b/changes/ticket40760 @@ -0,0 +1,3 @@ + o Minor feature (authority): + - Reject 0.4.5.x series at the authority level. Closes ticket 40760. + diff --git a/src/feature/dirauth/process_descs.c b/src/feature/dirauth/process_descs.c index 3cdace452f..7fd930e246 100644 --- a/src/feature/dirauth/process_descs.c +++ b/src/feature/dirauth/process_descs.c @@ -404,17 +404,8 @@ dirserv_rejects_tor_version(const char *platform, static const char please_upgrade_string[] = "Tor version is insecure or unsupported. Please upgrade!";
- /* Anything before 0.4.5.6 is unsupported. Reject them. */ - if (!tor_version_as_new_as(platform,"0.4.5.6")) { - if (msg) { - *msg = please_upgrade_string; - } - return true; - } - - /* Reject 0.4.6.x series. */ - if (tor_version_as_new_as(platform, "0.4.6.0") && - !tor_version_as_new_as(platform, "0.4.7.0-alpha-dev")) { + /* Anything before 0.4.7.0 is unsupported. Reject them. */ + if (!tor_version_as_new_as(platform,"0.4.7.0-alpha-dev")) { if (msg) { *msg = please_upgrade_string; } diff --git a/src/test/test_process_descs.c b/src/test/test_process_descs.c index abcb6ae2fe..c13e8b58c4 100644 --- a/src/test/test_process_descs.c +++ b/src/test/test_process_descs.c @@ -47,17 +47,15 @@ test_process_descs_versions(void *arg) { "Tor 0.4.3.0-alpha-dev", true }, { "Tor 0.4.3.8", true }, { "Tor 0.4.4.9", true }, - - /* The 0.4.5.x series stable is supported. */ { "Tor 0.4.5.5-rc", true }, - { "Tor 0.4.5.6", false }, - { "Tor 0.4.5.15", false }, - + { "Tor 0.4.5.6", true }, + { "Tor 0.4.5.15", true }, { "Tor 0.4.6.0-alpha-dev", true }, { "Tor 0.4.6.1-alpha", true }, { "Tor 0.4.6.5", true }, { "Tor 0.4.6.50", true }, /* Non existing one in the 0.4.6 series */
+ /* The 0.4.7.x series is supported. */ { "Tor 0.4.7.0-alpha-dev", false }, { "Tor 0.4.7.3-alpha", false }, { "Tor 0.4.7.12", false },
This is an automated email from the git hooks/post-receive script.
dgoulet pushed a commit to branch main in repository tor.
commit d1264d11c3320b8a28c3715acca8a8ace1d70569 Author: Gabriela Moldovan gabi@torproject.org AuthorDate: Wed Mar 8 17:51:58 2023 +0000
metrics: Add support for histograms.
This will enable us to add e.g. circuit build metrics (#40717).
Signed-off-by: Gabriela Moldovan gabi@torproject.org --- changes/ticket40757 | 3 + src/feature/hs/hs_metrics.c | 7 +- src/feature/hs/hs_metrics_entry.h | 4 + src/feature/relay/relay_metrics.c | 170 +++++++++++++++++----------------- src/lib/metrics/metrics_common.c | 2 + src/lib/metrics/metrics_common.h | 23 +++++ src/lib/metrics/metrics_store.c | 6 +- src/lib/metrics/metrics_store.h | 6 +- src/lib/metrics/metrics_store_entry.c | 157 ++++++++++++++++++++++++++++++- src/lib/metrics/metrics_store_entry.h | 13 ++- src/lib/metrics/prometheus.c | 70 +++++++++++++- src/test/test_metrics.c | 146 ++++++++++++++++++++++++++++- 12 files changed, 504 insertions(+), 103 deletions(-)
diff --git a/changes/ticket40757 b/changes/ticket40757 new file mode 100644 index 0000000000..e2d8c1ed47 --- /dev/null +++ b/changes/ticket40757 @@ -0,0 +1,3 @@ + o Minor features (metrics): + - Add support for histograms. + Part of ticket 40757. diff --git a/src/feature/hs/hs_metrics.c b/src/feature/hs/hs_metrics.c index 4c6d957cf8..38cdb49e40 100644 --- a/src/feature/hs/hs_metrics.c +++ b/src/feature/hs/hs_metrics.c @@ -76,7 +76,8 @@ add_metric_with_labels(hs_service_t *service, hs_metrics_key_t metric, if (!num_error_reasons) { metrics_store_entry_t *entry = metrics_store_add( store, base_metrics[metric].type, base_metrics[metric].name, - base_metrics[metric].help); + base_metrics[metric].help, base_metrics[metric].bucket_count, + base_metrics[metric].buckets);
metrics_store_entry_add_label(entry, metrics_format_label("onion", service->onion_address)); @@ -97,7 +98,9 @@ add_metric_with_labels(hs_service_t *service, hs_metrics_key_t metric, metrics_store_entry_t *entry = metrics_store_add(store, base_metrics[metric].type, base_metrics[metric].name, - base_metrics[metric].help); + base_metrics[metric].help, + base_metrics[metric].bucket_count, + base_metrics[metric].buckets); /* Add labels to the entry. */ metrics_store_entry_add_label(entry, metrics_format_label("onion", service->onion_address)); diff --git a/src/feature/hs/hs_metrics_entry.h b/src/feature/hs/hs_metrics_entry.h index 07693972c0..b966f0c226 100644 --- a/src/feature/hs/hs_metrics_entry.h +++ b/src/feature/hs/hs_metrics_entry.h @@ -70,6 +70,10 @@ typedef struct hs_metrics_entry_t { const char *name; /* Metrics output help comment. */ const char *help; + /* The buckets, if the metric type is METRICS_TYPE_HISTOGRAM. */ + const int64_t *buckets; + /* The number of buckets, if the metric type is METRICS_TYPE_HISTOGRAM. */ + size_t bucket_count; /* True iff a port label should be added to the metrics entry. */ bool port_as_label; } hs_metrics_entry_t; diff --git a/src/feature/relay/relay_metrics.c b/src/feature/relay/relay_metrics.c index cdf34a3404..99204931fc 100644 --- a/src/feature/relay/relay_metrics.c +++ b/src/feature/relay/relay_metrics.c @@ -222,8 +222,8 @@ fill_circuits_values(void) { const relay_metrics_entry_t *rentry = &base_metrics[RELAY_METRICS_NUM_CIRCUITS]; - metrics_store_entry_t *sentry = - metrics_store_add(the_store, rentry->type, rentry->name, rentry->help); + metrics_store_entry_t *sentry = metrics_store_add( + the_store, rentry->type, rentry->name, rentry->help, 0, NULL);
metrics_store_entry_add_label(sentry, metrics_format_label("state", "opened")); @@ -255,57 +255,57 @@ fill_relay_flags(void)
const relay_metrics_entry_t *rentry = &base_metrics[RELAY_METRICS_RELAY_FLAGS]; - metrics_store_entry_t *sentry = - metrics_store_add(the_store, rentry->type, rentry->name, rentry->help); + metrics_store_entry_t *sentry = metrics_store_add( + the_store, rentry->type, rentry->name, rentry->help, 0, NULL);
metrics_store_entry_add_label(sentry, metrics_format_label("type", "Fast")); metrics_store_entry_update(sentry, is_fast);
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("type", "Exit")); metrics_store_entry_update(sentry, is_exit);
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("type", "Authority")); metrics_store_entry_update(sentry, is_authority);
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("type", "Stable")); metrics_store_entry_update(sentry, is_stable);
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("type", "HSDir")); metrics_store_entry_update(sentry, is_hs_dir);
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("type", "Running")); metrics_store_entry_update(sentry, is_running);
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("type", "V2Dir")); metrics_store_entry_update(sentry, is_v2_dir);
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("type", "Sybil")); metrics_store_entry_update(sentry, is_sybil);
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("type", "Guard")); metrics_store_entry_update(sentry, is_guard); @@ -317,15 +317,15 @@ fill_traffic_values(void) { const relay_metrics_entry_t *rentry = &base_metrics[RELAY_METRICS_NUM_TRAFFIC]; - metrics_store_entry_t *sentry = - metrics_store_add(the_store, rentry->type, rentry->name, rentry->help); + metrics_store_entry_t *sentry = metrics_store_add( + the_store, rentry->type, rentry->name, rentry->help, 0, NULL);
metrics_store_entry_add_label(sentry, metrics_format_label("direction", "read")); metrics_store_entry_update(sentry, get_bytes_read());
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("direction", "written")); metrics_store_entry_update(sentry, get_bytes_written()); @@ -336,57 +336,57 @@ static void fill_dos_values(void) { const relay_metrics_entry_t *rentry = &base_metrics[RELAY_METRICS_NUM_DOS]; - metrics_store_entry_t *sentry = - metrics_store_add(the_store, rentry->type, rentry->name, rentry->help); + metrics_store_entry_t *sentry = metrics_store_add( + the_store, rentry->type, rentry->name, rentry->help, 0, NULL);
metrics_store_entry_add_label(sentry, metrics_format_label("type", "circuit_rejected")); metrics_store_entry_update(sentry, dos_get_num_cc_rejected());
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("type", "circuit_killed_max_cell")); metrics_store_entry_update(sentry, stats_n_circ_max_cell_reached);
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("type", "circuit_killed_max_cell_outq")); metrics_store_entry_update(sentry, stats_n_circ_max_cell_outq_reached);
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("type", "marked_address")); metrics_store_entry_update(sentry, dos_get_num_cc_marked_addr());
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("type", "marked_address_maxq")); metrics_store_entry_update(sentry, dos_get_num_cc_marked_addr_maxq());
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("type", "conn_rejected")); metrics_store_entry_update(sentry, dos_get_num_conn_addr_connect_rejected());
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("type", "concurrent_conn_rejected")); metrics_store_entry_update(sentry, dos_get_num_conn_addr_rejected());
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("type", "single_hop_refused")); metrics_store_entry_update(sentry, dos_get_num_single_hop_refused());
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("type", "introduce2_rejected")); metrics_store_entry_update(sentry, hs_dos_get_intro2_rejected_count()); @@ -399,8 +399,8 @@ fill_cc_counters_values(void) const relay_metrics_entry_t *rentry = &base_metrics[RELAY_METRICS_CC_COUNTERS];
- metrics_store_entry_t *sentry = - metrics_store_add(the_store, rentry->type, rentry->name, rentry->help); + metrics_store_entry_t *sentry = metrics_store_add( + the_store, rentry->type, rentry->name, rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("state", "starvation")); metrics_store_entry_add_label(sentry, @@ -408,7 +408,7 @@ fill_cc_counters_values(void) metrics_store_entry_update(sentry, congestion_control_get_num_rtt_reset());
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("state", "clock_stalls")); metrics_store_entry_add_label(sentry, @@ -417,7 +417,7 @@ fill_cc_counters_values(void) congestion_control_get_num_clock_stalls());
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("state", "flow_control")); metrics_store_entry_add_label(sentry, @@ -426,7 +426,7 @@ fill_cc_counters_values(void) cc_stats_flow_num_xoff_sent);
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("state", "flow_control")); metrics_store_entry_add_label(sentry, @@ -435,7 +435,7 @@ fill_cc_counters_values(void) cc_stats_flow_num_xon_sent);
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("state", "cc_limits")); metrics_store_entry_add_label(sentry, @@ -443,7 +443,7 @@ fill_cc_counters_values(void) metrics_store_entry_update(sentry, cc_stats_vegas_above_delta);
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("state", "cc_limits")); metrics_store_entry_add_label(sentry, @@ -451,7 +451,7 @@ fill_cc_counters_values(void) metrics_store_entry_update(sentry, cc_stats_vegas_above_ss_cwnd_max);
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("state", "cc_limits")); metrics_store_entry_add_label(sentry, @@ -459,7 +459,7 @@ fill_cc_counters_values(void) metrics_store_entry_update(sentry, cc_stats_vegas_below_ss_inc_floor);
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("state", "cc_circuits")); metrics_store_entry_add_label(sentry, @@ -467,7 +467,7 @@ fill_cc_counters_values(void) metrics_store_entry_update(sentry, cc_stats_circs_created);
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("state", "cc_circuits")); metrics_store_entry_add_label(sentry, @@ -475,7 +475,7 @@ fill_cc_counters_values(void) metrics_store_entry_update(sentry, cc_stats_circs_closed);
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("state", "cc_circuits")); metrics_store_entry_add_label(sentry, @@ -490,8 +490,8 @@ fill_cc_gauges_values(void) const relay_metrics_entry_t *rentry = &base_metrics[RELAY_METRICS_CC_GAUGES];
- metrics_store_entry_t *sentry = - metrics_store_add(the_store, rentry->type, rentry->name, rentry->help); + metrics_store_entry_t *sentry = metrics_store_add( + the_store, rentry->type, rentry->name, rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("state", "slow_start_exit")); metrics_store_entry_add_label(sentry, @@ -500,7 +500,7 @@ fill_cc_gauges_values(void) tor_llround(cc_stats_vegas_exit_ss_cwnd_ma));
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("state", "slow_start_exit")); metrics_store_entry_add_label(sentry, @@ -509,7 +509,7 @@ fill_cc_gauges_values(void) tor_llround(cc_stats_vegas_exit_ss_bdp_ma));
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("state", "slow_start_exit")); metrics_store_entry_add_label(sentry, @@ -518,7 +518,7 @@ fill_cc_gauges_values(void) tor_llround(cc_stats_vegas_exit_ss_inc_ma));
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("state", "on_circ_close")); metrics_store_entry_add_label(sentry, @@ -527,7 +527,7 @@ fill_cc_gauges_values(void) tor_llround(cc_stats_circ_close_cwnd_ma));
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("state", "on_circ_close")); metrics_store_entry_add_label(sentry, @@ -536,7 +536,7 @@ fill_cc_gauges_values(void) tor_llround(cc_stats_circ_close_ss_cwnd_ma));
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("state", "buffers")); metrics_store_entry_add_label(sentry, @@ -545,7 +545,7 @@ fill_cc_gauges_values(void) tor_llround(cc_stats_flow_xon_outbuf_ma));
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("state", "buffers")); metrics_store_entry_add_label(sentry, @@ -554,7 +554,7 @@ fill_cc_gauges_values(void) tor_llround(cc_stats_flow_xoff_outbuf_ma));
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("state", "cc_backoff")); metrics_store_entry_add_label(sentry, @@ -563,7 +563,7 @@ fill_cc_gauges_values(void) tor_llround(cc_stats_vegas_csig_blocked_ma));
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("state", "cc_backoff")); metrics_store_entry_add_label(sentry, @@ -572,7 +572,7 @@ fill_cc_gauges_values(void) tor_llround(cc_stats_vegas_gamma_drop_ma));
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("state", "cc_backoff")); metrics_store_entry_add_label(sentry, @@ -581,7 +581,7 @@ fill_cc_gauges_values(void) tor_llround(cc_stats_vegas_delta_drop_ma));
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("state", "cc_backoff")); metrics_store_entry_add_label(sentry, @@ -590,7 +590,7 @@ fill_cc_gauges_values(void) tor_llround(cc_stats_vegas_ss_csig_blocked_ma));
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("state", "cc_cwnd_update")); metrics_store_entry_add_label(sentry, @@ -599,7 +599,7 @@ fill_cc_gauges_values(void) tor_llround(cc_stats_vegas_csig_alpha_ma));
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("state", "cc_cwnd_update")); metrics_store_entry_add_label(sentry, @@ -608,7 +608,7 @@ fill_cc_gauges_values(void) tor_llround(cc_stats_vegas_csig_beta_ma));
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("state", "cc_cwnd_update")); metrics_store_entry_add_label(sentry, @@ -617,7 +617,7 @@ fill_cc_gauges_values(void) tor_llround(cc_stats_vegas_csig_delta_ma));
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("state", "cc_estimates")); metrics_store_entry_add_label(sentry, @@ -626,7 +626,7 @@ fill_cc_gauges_values(void) tor_llround(cc_stats_vegas_ss_queue_ma));
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("state", "cc_estimates")); metrics_store_entry_add_label(sentry, @@ -635,7 +635,7 @@ fill_cc_gauges_values(void) tor_llround(cc_stats_vegas_queue_ma));
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("state", "cc_estimates")); metrics_store_entry_add_label(sentry, @@ -659,16 +659,16 @@ fill_streams_values(void) { const relay_metrics_entry_t *rentry = &base_metrics[RELAY_METRICS_NUM_STREAMS]; - metrics_store_entry_t *sentry = - metrics_store_add(the_store, rentry->type, rentry->name, rentry->help); + metrics_store_entry_t *sentry = metrics_store_add( + the_store, rentry->type, rentry->name, rentry->help, 0, NULL); fill_single_stream_value(sentry, RELAY_COMMAND_BEGIN);
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); fill_single_stream_value(sentry, RELAY_COMMAND_BEGIN_DIR);
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); fill_single_stream_value(sentry, RELAY_COMMAND_RESOLVE); }
@@ -704,31 +704,31 @@ fill_conn_counter_values(void) if (i == 10) { continue; } - metrics_store_entry_t *sentry = - metrics_store_add(the_store, rentry->type, rentry->name, rentry->help); + metrics_store_entry_t *sentry = metrics_store_add( + the_store, rentry->type, rentry->name, rentry->help, 0, NULL); fill_single_connection_value(sentry, i, "initiated", "created", AF_INET, rep_hist_get_conn_created(false, i, AF_INET)); sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); fill_single_connection_value(sentry, i, "initiated", "created", AF_INET6, rep_hist_get_conn_created(false, i, AF_INET6));
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); fill_single_connection_value(sentry, i, "received", "created", AF_INET, rep_hist_get_conn_created(true, i, AF_INET)); sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); fill_single_connection_value(sentry, i, "received", "created", AF_INET6, rep_hist_get_conn_created(true, i, AF_INET6));
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); fill_single_connection_value(sentry, i, "received", "rejected", AF_INET, rep_hist_get_conn_rejected(i, AF_INET)); sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); fill_single_connection_value(sentry, i, "received", "rejected", AF_INET6, rep_hist_get_conn_rejected(i, AF_INET6));
@@ -748,21 +748,21 @@ fill_conn_gauge_values(void) if (i == 10) { continue; } - metrics_store_entry_t *sentry = - metrics_store_add(the_store, rentry->type, rentry->name, rentry->help); + metrics_store_entry_t *sentry = metrics_store_add( + the_store, rentry->type, rentry->name, rentry->help, 0, NULL); fill_single_connection_value(sentry, i, "initiated", "opened", AF_INET, rep_hist_get_conn_opened(false, i, AF_INET)); sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); fill_single_connection_value(sentry, i, "initiated", "opened", AF_INET6, rep_hist_get_conn_opened(false, i, AF_INET6));
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); fill_single_connection_value(sentry, i, "received", "opened", AF_INET, rep_hist_get_conn_opened(true, i, AF_INET)); sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); fill_single_connection_value(sentry, i, "received", "opened", AF_INET6, rep_hist_get_conn_opened(true, i, AF_INET6)); } @@ -777,7 +777,7 @@ fill_tcp_exhaustion_values(void) &base_metrics[RELAY_METRICS_NUM_TCP_EXHAUSTION];
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_update(sentry, rep_hist_get_n_tcp_exhaustion()); }
@@ -835,7 +835,7 @@ fill_dns_error_values(void)
for (size_t j = 0; j < num_errors; j++) { sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, record_label); metrics_store_entry_add_label(sentry, metrics_format_label("reason", errors[j].name)); @@ -849,7 +849,7 @@ fill_dns_error_values(void) /* Put in the DNS errors, unfortunately not per-type for now. */ for (size_t j = 0; j < num_errors; j++) { sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("reason", errors[j].name)); metrics_store_entry_update(sentry, @@ -873,7 +873,7 @@ fill_dns_query_values(void) char *record_label = tor_strdup(metrics_format_label("record", dns_types[i].name)); sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, record_label); metrics_store_entry_update(sentry, rep_hist_get_n_dns_request(dns_types[i].type)); @@ -882,7 +882,7 @@ fill_dns_query_values(void) #endif
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_update(sentry, rep_hist_get_n_dns_request(0)); }
@@ -895,13 +895,13 @@ fill_global_bw_limit_values(void) &base_metrics[RELAY_METRICS_NUM_GLOBAL_RW_LIMIT];
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("side", "read")); metrics_store_entry_update(sentry, rep_hist_get_n_read_limit_reached());
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("side", "write")); metrics_store_entry_update(sentry, rep_hist_get_n_write_limit_reached()); @@ -916,13 +916,13 @@ fill_socket_values(void) &base_metrics[RELAY_METRICS_NUM_SOCKETS];
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("state", "opened")); metrics_store_entry_update(sentry, get_n_open_sockets());
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_update(sentry, get_max_sockets()); }
@@ -940,7 +940,7 @@ fill_onionskins_values(void) char *type_label = tor_strdup(metrics_format_label("type", handshake_type_to_str(t))); sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, type_label); metrics_store_entry_add_label(sentry, metrics_format_label("action", "processed")); @@ -948,7 +948,7 @@ fill_onionskins_values(void) rep_hist_get_circuit_n_handshake_assigned(t));
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, type_label); metrics_store_entry_add_label(sentry, metrics_format_label("action", "dropped")); @@ -967,25 +967,25 @@ fill_oom_values(void) &base_metrics[RELAY_METRICS_NUM_OOM_BYTES];
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("subsys", "cell")); metrics_store_entry_update(sentry, oom_stats_n_bytes_removed_cell);
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("subsys", "dns")); metrics_store_entry_update(sentry, oom_stats_n_bytes_removed_dns);
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("subsys", "geoip")); metrics_store_entry_update(sentry, oom_stats_n_bytes_removed_geoip);
sentry = metrics_store_add(the_store, rentry->type, rentry->name, - rentry->help); + rentry->help, 0, NULL); metrics_store_entry_add_label(sentry, metrics_format_label("subsys", "hsdir")); metrics_store_entry_update(sentry, oom_stats_n_bytes_removed_hsdir); diff --git a/src/lib/metrics/metrics_common.c b/src/lib/metrics/metrics_common.c index f3f7e22d88..5836a581f1 100644 --- a/src/lib/metrics/metrics_common.c +++ b/src/lib/metrics/metrics_common.c @@ -24,6 +24,8 @@ metrics_type_to_str(const metrics_type_t type) return "counter"; case METRICS_TYPE_GAUGE: return "gauge"; + case METRICS_TYPE_HISTOGRAM: + return "histogram"; default: tor_assert_unreached(); } diff --git a/src/lib/metrics/metrics_common.h b/src/lib/metrics/metrics_common.h index 3644ad3d50..6c8e8bdbdc 100644 --- a/src/lib/metrics/metrics_common.h +++ b/src/lib/metrics/metrics_common.h @@ -10,6 +10,7 @@ #define TOR_LIB_METRICS_METRICS_COMMON_H
#include "lib/cc/torint.h" +#include "lib/container/smartlist.h"
/** Helper macro that must be used to construct the right namespaced metrics * name. A name is a string so stringify the result. */ @@ -28,8 +29,18 @@ typedef enum { METRICS_TYPE_COUNTER, /* Can go up or down. */ METRICS_TYPE_GAUGE, + /* Cumulative counters for multiple observation buckets. */ + METRICS_TYPE_HISTOGRAM, } metrics_type_t;
+typedef struct metrics_histogram_bucket_t { + /* The value of the counter of this bucket. */ + uint64_t value; + /* Technically, this should be a floating point value, but in practice, we + * can make do with integer buckets. */ + int64_t bucket; +} metrics_histogram_bucket_t; + /** Metric counter object (METRICS_TYPE_COUNTER). */ typedef struct metrics_counter_t { uint64_t value; @@ -40,6 +51,18 @@ typedef struct metrics_gauge_t { int64_t value; } metrics_gauge_t;
+/** Metric histogram object (METRICS_TYPE_HISTOGRAM). */ +typedef struct metrics_histogram_t { + /* The observation buckets. */ + metrics_histogram_bucket_t *buckets; + /* The number of observation buckets. */ + size_t bucket_count; + /* The sum of all observations */ + int64_t sum; + /* The total number of observations */ + uint64_t count; +} metrics_histogram_t; + const char *metrics_type_to_str(const metrics_type_t type);
/* Helpers. */ diff --git a/src/lib/metrics/metrics_store.c b/src/lib/metrics/metrics_store.c index b017e97688..db80ca029b 100644 --- a/src/lib/metrics/metrics_store.c +++ b/src/lib/metrics/metrics_store.c @@ -107,7 +107,9 @@ metrics_store_get_all(const metrics_store_t *store, const char *name) * unique identifier. The help string can be omitted. */ metrics_store_entry_t * metrics_store_add(metrics_store_t *store, metrics_type_t type, - const char *name, const char *help) + const char *name, const char *help, size_t bucket_count, + const int64_t *buckets) + { smartlist_t *entries; metrics_store_entry_t *entry; @@ -120,7 +122,7 @@ metrics_store_add(metrics_store_t *store, metrics_type_t type, entries = smartlist_new(); strmap_set(store->entries, name, entries); } - entry = metrics_store_entry_new(type, name, help); + entry = metrics_store_entry_new(type, name, help, bucket_count, buckets); smartlist_add(entries, entry);
return entry; diff --git a/src/lib/metrics/metrics_store.h b/src/lib/metrics/metrics_store.h index d85f484bd6..d06c87303c 100644 --- a/src/lib/metrics/metrics_store.h +++ b/src/lib/metrics/metrics_store.h @@ -26,8 +26,10 @@ metrics_store_t *metrics_store_new(void);
/* Modifiers. */ metrics_store_entry_t *metrics_store_add(metrics_store_t *store, - metrics_type_t type, - const char *name, const char *help); + metrics_type_t type, const char *name, + const char *help, size_t bucket_count, + const int64_t *buckets); + void metrics_store_reset(metrics_store_t *store);
/* Accessors. */ diff --git a/src/lib/metrics/metrics_store_entry.c b/src/lib/metrics/metrics_store_entry.c index 971d9379bd..649fd660c3 100644 --- a/src/lib/metrics/metrics_store_entry.c +++ b/src/lib/metrics/metrics_store_entry.c @@ -6,6 +6,7 @@ * @brief Metrics store entry which contains the gathered data. **/
+#include "metrics_common.h" #define METRICS_STORE_ENTRY_PRIVATE
#include <string.h> @@ -22,10 +23,11 @@ * Public API. */
-/** Return newly allocated store entry of type COUNTER. */ +/** Return newly allocated store entry of the specified type. */ metrics_store_entry_t * metrics_store_entry_new(const metrics_type_t type, const char *name, - const char *help) + const char *help, size_t bucket_count, + const int64_t *buckets) { metrics_store_entry_t *entry = tor_malloc_zero(sizeof(*entry));
@@ -38,6 +40,18 @@ metrics_store_entry_new(const metrics_type_t type, const char *name, entry->help = tor_strdup(help); }
+ if (type == METRICS_TYPE_HISTOGRAM && bucket_count > 0) { + tor_assert(buckets); + + entry->u.histogram.bucket_count = bucket_count; + entry->u.histogram.buckets = + tor_malloc_zero(sizeof(metrics_histogram_bucket_t) * bucket_count); + + for (size_t i = 0; i < bucket_count; ++i) { + entry->u.histogram.buckets[i].bucket = buckets[i]; + } + } + return entry; }
@@ -52,6 +66,11 @@ metrics_store_entry_free_(metrics_store_entry_t *entry) smartlist_free(entry->labels); tor_free(entry->name); tor_free(entry->help); + + if (entry->type == METRICS_TYPE_HISTOGRAM) { + tor_free(entry->u.histogram.buckets); + } + tor_free(entry); }
@@ -61,6 +80,11 @@ metrics_store_entry_update(metrics_store_entry_t *entry, const int64_t value) { tor_assert(entry);
+ /* Histogram values are updated using metrics_store_hist_entry_update */ + if (BUG(entry->type == METRICS_TYPE_HISTOGRAM)) { + return; + } + switch (entry->type) { case METRICS_TYPE_COUNTER: /* Counter can ONLY be positive. */ @@ -73,6 +97,43 @@ metrics_store_entry_update(metrics_store_entry_t *entry, const int64_t value) /* Gauge can increment or decrement. And can be positive or negative. */ entry->u.gauge.value += value; break; + case METRICS_TYPE_HISTOGRAM: + tor_assert_unreached(); + } +} + +/** Update a store entry with value for the specified observation obs. + * + * Note: entry **must** be a histogram. */ +void +metrics_store_hist_entry_update(metrics_store_entry_t *entry, + const int64_t value, const int64_t obs) +{ + if (BUG(entry->type != METRICS_TYPE_HISTOGRAM)) { + return; + } + + /* Counter can ONLY be positive for histograms. */ + if (BUG(value < 0)) { + return; + } + + /* If we're about to overflow or underflow the sum, reset all counters back + * to 0 before recording the observation. */ + if (PREDICT_UNLIKELY( + (obs > 0 && entry->u.histogram.sum > INT64_MAX - obs) || + (obs < 0 && entry->u.histogram.sum < INT64_MIN - obs))) { + metrics_store_entry_reset(entry); + } + + entry->u.histogram.count += value; + entry->u.histogram.sum += obs; + + for (size_t i = 0; i < entry->u.histogram.bucket_count; ++i) { + metrics_histogram_bucket_t *hb = &entry->u.histogram.buckets[i]; + if (obs <= hb->bucket) { + hb->value += value; + } } }
@@ -81,8 +142,22 @@ void metrics_store_entry_reset(metrics_store_entry_t *entry) { tor_assert(entry); - /* Everything back to 0. */ - memset(&entry->u, 0, sizeof(entry->u)); + + switch (entry->type) { + case METRICS_TYPE_COUNTER: FALLTHROUGH; + case METRICS_TYPE_GAUGE: + /* Everything back to 0. */ + memset(&entry->u, 0, sizeof(entry->u)); + break; + case METRICS_TYPE_HISTOGRAM: + for (size_t i = 0; i < entry->u.histogram.bucket_count; ++i) { + metrics_histogram_bucket_t *hb = &entry->u.histogram.buckets[i]; + hb->value = 0; + } + entry->u.histogram.sum = 0; + entry->u.histogram.count = 0; + break; + } }
/** Return store entry value. */ @@ -91,6 +166,11 @@ metrics_store_entry_get_value(const metrics_store_entry_t *entry) { tor_assert(entry);
+ /* Histogram values are accessed using metrics_store_hist_entry_get_value. */ + if (BUG(entry->type == METRICS_TYPE_HISTOGRAM)) { + return 0; + } + switch (entry->type) { case METRICS_TYPE_COUNTER: if (entry->u.counter.value > INT64_MAX) { @@ -99,6 +179,9 @@ metrics_store_entry_get_value(const metrics_store_entry_t *entry) return entry->u.counter.value; case METRICS_TYPE_GAUGE: return entry->u.gauge.value; + case METRICS_TYPE_HISTOGRAM: + tor_assert_unreached(); + return 0; }
// LCOV_EXCL_START @@ -106,6 +189,35 @@ metrics_store_entry_get_value(const metrics_store_entry_t *entry) // LCOV_EXCL_STOP }
+/** Return store entry value for the specified bucket. + * + * Note: entry **must** be a histogram. */ +uint64_t +metrics_store_hist_entry_get_value(const metrics_store_entry_t *entry, + const int64_t bucket) +{ + tor_assert(entry); + + if (BUG(entry->type != METRICS_TYPE_HISTOGRAM)) { + return 0; + } + + for (size_t i = 0; i <= entry->u.histogram.bucket_count; ++i) { + metrics_histogram_bucket_t hb = entry->u.histogram.buckets[i]; + if (bucket == hb.bucket) { + if (hb.value > INT64_MAX) { + return INT64_MAX; + } else { + return hb.value; + } + } + } + + tor_assertf_nonfatal(false, "attempted to get the value of non-existent " + "bucket %" PRId64, bucket); + return 0; +} + /** Add a label into the given entry.*/ void metrics_store_entry_add_label(metrics_store_entry_t *entry, @@ -147,3 +259,40 @@ metrics_store_find_entry_with_label(const smartlist_t *entries,
return NULL; } + +/** Return true iff the specified entry is a histogram. */ +bool +metrics_store_entry_is_histogram(const metrics_store_entry_t *entry) +{ + if (entry->type == METRICS_TYPE_HISTOGRAM) { + return true; + } + + return false; +} + +/** Return the total number of observations for the specified histogram. */ +uint64_t +metrics_store_hist_entry_get_count(const metrics_store_entry_t *entry) +{ + tor_assert(entry); + + if (BUG(entry->type != METRICS_TYPE_HISTOGRAM)) { + return 0; + } + + return entry->u.histogram.count; +} + +/** Return the sum of all observations for the specified histogram. */ +int64_t +metrics_store_hist_entry_get_sum(const metrics_store_entry_t *entry) +{ + tor_assert(entry); + + if (BUG(entry->type != METRICS_TYPE_HISTOGRAM)) { + return 0; + } + + return entry->u.histogram.sum; +} diff --git a/src/lib/metrics/metrics_store_entry.h b/src/lib/metrics/metrics_store_entry.h index 0e09e099fe..53fa437406 100644 --- a/src/lib/metrics/metrics_store_entry.h +++ b/src/lib/metrics/metrics_store_entry.h @@ -38,6 +38,7 @@ struct metrics_store_entry_t { union { metrics_counter_t counter; metrics_gauge_t gauge; + metrics_histogram_t histogram; } u; };
@@ -48,7 +49,9 @@ typedef struct metrics_store_entry_t metrics_store_entry_t; /* Allocators. */ metrics_store_entry_t *metrics_store_entry_new(const metrics_type_t type, const char *name, - const char *help); + const char *help, + size_t bucket_count, + const int64_t *buckets);
void metrics_store_entry_free_(metrics_store_entry_t *entry); #define metrics_store_entry_free(entry) \ @@ -56,10 +59,16 @@ void metrics_store_entry_free_(metrics_store_entry_t *entry);
/* Accessors. */ int64_t metrics_store_entry_get_value(const metrics_store_entry_t *entry); +uint64_t metrics_store_hist_entry_get_value(const metrics_store_entry_t *entry, + const int64_t bucket); bool metrics_store_entry_has_label(const metrics_store_entry_t *entry, const char *label); metrics_store_entry_t *metrics_store_find_entry_with_label( const smartlist_t *entries, const char *label); +bool metrics_store_entry_is_histogram(const metrics_store_entry_t *entry); +uint64_t metrics_store_hist_entry_get_count( + const metrics_store_entry_t *entry); +int64_t metrics_store_hist_entry_get_sum(const metrics_store_entry_t *entry);
/* Modifiers. */ void metrics_store_entry_add_label(metrics_store_entry_t *entry, @@ -67,5 +76,7 @@ void metrics_store_entry_add_label(metrics_store_entry_t *entry, void metrics_store_entry_reset(metrics_store_entry_t *entry); void metrics_store_entry_update(metrics_store_entry_t *entry, const int64_t value); +void metrics_store_hist_entry_update(metrics_store_entry_t *entry, + const int64_t value, const int64_t obs);
#endif /* !defined(TOR_LIB_METRICS_METRICS_STORE_ENTRY_H) */ diff --git a/src/lib/metrics/prometheus.c b/src/lib/metrics/prometheus.c index aac23ac92e..2f98f8ebb6 100644 --- a/src/lib/metrics/prometheus.c +++ b/src/lib/metrics/prometheus.c @@ -17,6 +17,8 @@
#include "lib/metrics/prometheus.h"
+#include <string.h> + /** Return a static buffer containing all the labels properly formatted * for the output as a string. * @@ -33,13 +35,54 @@ format_labels(smartlist_t *labels) }
line = smartlist_join_strings(labels, ",", 0, NULL); - tor_snprintf(buf, sizeof(buf), "{%s}", line); + tor_snprintf(buf, sizeof(buf), "%s", line);
end: tor_free(line); return buf; }
+/** Write the string representation of the histogram entry to the specified + * buffer. + * + * Note: entry **must** be a histogram. + */ +static void +format_histogram(const metrics_store_entry_t *entry, buf_t *data) +{ + tor_assert(entry->type == METRICS_TYPE_HISTOGRAM); + + const char *labels = format_labels(entry->labels); + + for (size_t i = 0; i < entry->u.histogram.bucket_count; ++i) { + metrics_histogram_bucket_t hb = entry->u.histogram.buckets[i]; + if (strlen(labels) > 0) { + buf_add_printf(data, "%s_bucket{%s,le="%.2f"} %" PRIi64 "\n", + entry->name, labels, (double)hb.bucket, hb.value); + } else { + buf_add_printf(data, "%s_bucket{le="%.2f"} %" PRIi64 "\n", + entry->name, (double)hb.bucket, hb.value); + } + } + + if (strlen(labels) > 0) { + buf_add_printf(data, "%s_bucket{%s,le="+Inf"} %" PRIi64 "\n", + entry->name, labels, + metrics_store_hist_entry_get_count(entry)); + buf_add_printf(data, "%s_sum{%s} %" PRIi64 "\n", entry->name, labels, + metrics_store_hist_entry_get_sum(entry)); + buf_add_printf(data, "%s_count{%s} %" PRIi64 "\n", entry->name, labels, + metrics_store_hist_entry_get_count(entry)); + } else { + buf_add_printf(data, "%s_bucket{le="+Inf"} %" PRIi64 "\n", entry->name, + metrics_store_hist_entry_get_count(entry)); + buf_add_printf(data, "%s_sum %" PRIi64 "\n", entry->name, + metrics_store_hist_entry_get_sum(entry)); + buf_add_printf(data, "%s_count %" PRIi64 "\n", entry->name, + metrics_store_hist_entry_get_count(entry)); + } +} + /** Format the given entry in to the buffer data. */ void prometheus_format_store_entry(const metrics_store_entry_t *entry, buf_t *data, @@ -53,7 +96,26 @@ prometheus_format_store_entry(const metrics_store_entry_t *entry, buf_t *data, buf_add_printf(data, "# TYPE %s %s\n", entry->name, metrics_type_to_str(entry->type)); } - buf_add_printf(data, "%s%s %" PRIi64 "\n", entry->name, - format_labels(entry->labels), - metrics_store_entry_get_value(entry)); + + switch (entry->type) { + case METRICS_TYPE_COUNTER: FALLTHROUGH; + case METRICS_TYPE_GAUGE: + { + const char *labels = format_labels(entry->labels); + if (strlen(labels) > 0) { + buf_add_printf(data, "%s{%s} %" PRIi64 "\n", entry->name, + labels, + metrics_store_entry_get_value(entry)); + } else { + buf_add_printf(data, "%s %" PRIi64 "\n", entry->name, + metrics_store_entry_get_value(entry)); + } + break; + } + case METRICS_TYPE_HISTOGRAM: + format_histogram(entry, data); + break; + default: + tor_assert_unreached(); + } } diff --git a/src/test/test_metrics.c b/src/test/test_metrics.c index ba1a763f0c..0bf072dbfc 100644 --- a/src/test/test_metrics.c +++ b/src/test/test_metrics.c @@ -28,11 +28,16 @@ #include "lib/encoding/confline.h" #include "lib/metrics/metrics_store.h"
+#include <limits.h> + #define TEST_METRICS_ENTRY_NAME "entryA" #define TEST_METRICS_ENTRY_HELP "Description of entryA" #define TEST_METRICS_ENTRY_LABEL_1 "label="farfadet"" #define TEST_METRICS_ENTRY_LABEL_2 "label="ponki""
+#define TEST_METRICS_HIST_ENTRY_NAME "test_hist_entry" +#define TEST_METRICS_HIST_ENTRY_HELP "Description of test_hist_entry" + static void set_metrics_port(or_options_t *options) { @@ -189,7 +194,8 @@ test_prometheus(void *arg) /* Add entry and validate its content. */ entry = metrics_store_add(store, METRICS_TYPE_COUNTER, TEST_METRICS_ENTRY_NAME, - TEST_METRICS_ENTRY_HELP); + TEST_METRICS_ENTRY_HELP, + 0, NULL); tt_assert(entry); metrics_store_entry_add_label(entry, TEST_METRICS_ENTRY_LABEL_1);
@@ -208,11 +214,61 @@ test_prometheus(void *arg) metrics_store_free(store); }
+static void +test_prometheus_histogram(void *arg) +{ + metrics_store_t *store = NULL; + metrics_store_entry_t *entry = NULL; + buf_t *buf = buf_new(); + char *output = NULL; + const int64_t buckets[] = { 10, 20, 3000 }; + + (void) arg; + + /* Fresh new store. No entries. */ + store = metrics_store_new(); + tt_assert(store); + + /* Add a histogram entry and validate its content. */ + entry = metrics_store_add(store, METRICS_TYPE_HISTOGRAM, + TEST_METRICS_HIST_ENTRY_NAME, + TEST_METRICS_HIST_ENTRY_HELP, + ARRAY_LENGTH(buckets), buckets); + tt_assert(entry); + metrics_store_entry_add_label(entry, TEST_METRICS_ENTRY_LABEL_1); + + static const char *expected = + "# HELP " TEST_METRICS_HIST_ENTRY_NAME " " + TEST_METRICS_HIST_ENTRY_HELP "\n" + "# TYPE " TEST_METRICS_HIST_ENTRY_NAME " histogram\n" + TEST_METRICS_HIST_ENTRY_NAME "_bucket{" + TEST_METRICS_ENTRY_LABEL_1 ",le="10.00"} 0\n" + TEST_METRICS_HIST_ENTRY_NAME "_bucket{" + TEST_METRICS_ENTRY_LABEL_1 ",le="20.00"} 0\n" + TEST_METRICS_HIST_ENTRY_NAME "_bucket{" + TEST_METRICS_ENTRY_LABEL_1 ",le="3000.00"} 0\n" + TEST_METRICS_HIST_ENTRY_NAME "_bucket{" + TEST_METRICS_ENTRY_LABEL_1 ",le="+Inf"} 0\n" + TEST_METRICS_HIST_ENTRY_NAME "_sum{" TEST_METRICS_ENTRY_LABEL_1 "} 0\n" + TEST_METRICS_HIST_ENTRY_NAME "_count{" TEST_METRICS_ENTRY_LABEL_1 "} 0\n"; + + metrics_store_get_output(METRICS_FORMAT_PROMETHEUS, store, buf); + output = buf_extract(buf, NULL); + tt_str_op(expected, OP_EQ, output); + + done: + buf_free(buf); + tor_free(output); + metrics_store_free(store); +} + static void test_store(void *arg) { metrics_store_t *store = NULL; metrics_store_entry_t *entry = NULL; + const int64_t buckets[] = { 10, 20, 3000 }; + const size_t bucket_count = ARRAY_LENGTH(buckets);
(void) arg;
@@ -224,7 +280,7 @@ test_store(void *arg) /* Add entry and validate its content. */ entry = metrics_store_add(store, METRICS_TYPE_COUNTER, TEST_METRICS_ENTRY_NAME, - TEST_METRICS_ENTRY_HELP); + TEST_METRICS_ENTRY_HELP, 0, NULL); tt_assert(entry); tt_int_op(entry->type, OP_EQ, METRICS_TYPE_COUNTER); tt_str_op(entry->name, OP_EQ, TEST_METRICS_ENTRY_NAME); @@ -251,7 +307,7 @@ test_store(void *arg) /* Add entry and validate its content. */ entry = metrics_store_add(store, METRICS_TYPE_COUNTER, TEST_METRICS_ENTRY_NAME, - TEST_METRICS_ENTRY_HELP); + TEST_METRICS_ENTRY_HELP, 0, NULL); tt_assert(entry); metrics_store_entry_add_label(entry, TEST_METRICS_ENTRY_LABEL_2);
@@ -261,6 +317,89 @@ test_store(void *arg) tt_assert(entries); tt_int_op(smartlist_len(entries), OP_EQ, 2);
+ /* Add a histogram entry and validate its content. */ + entry = metrics_store_add(store, METRICS_TYPE_HISTOGRAM, + TEST_METRICS_HIST_ENTRY_NAME, + TEST_METRICS_HIST_ENTRY_HELP, + bucket_count, buckets); + + tt_assert(entry); + tt_int_op(entry->type, OP_EQ, METRICS_TYPE_HISTOGRAM); + tt_str_op(entry->name, OP_EQ, TEST_METRICS_HIST_ENTRY_NAME); + tt_str_op(entry->help, OP_EQ, TEST_METRICS_HIST_ENTRY_HELP); + tt_uint_op(entry->u.histogram.bucket_count, OP_EQ, bucket_count); + + for (size_t i = 0; i < bucket_count; ++i) { + tt_uint_op(entry->u.histogram.buckets[i].bucket, OP_EQ, buckets[i]); + tt_uint_op(entry->u.histogram.buckets[i].value, OP_EQ, 0); + } + + /* Access the entry. */ + tt_assert(metrics_store_get_all(store, TEST_METRICS_HIST_ENTRY_NAME)); + + /* Record various observations. */ + metrics_store_hist_entry_update(entry, 3, 11); + tt_int_op(metrics_store_hist_entry_get_value(entry, 10), OP_EQ, 0); + tt_int_op(metrics_store_hist_entry_get_value(entry, 20), OP_EQ, 3); + tt_int_op(metrics_store_hist_entry_get_value(entry, 3000), OP_EQ, 3); + tt_int_op(metrics_store_hist_entry_get_value(entry, 3000), OP_EQ, 3); + tt_int_op(metrics_store_hist_entry_get_count(entry), OP_EQ, 3); + tt_int_op(metrics_store_hist_entry_get_sum(entry), OP_EQ, 11); + + metrics_store_hist_entry_update(entry, 1, 42); + tt_int_op(metrics_store_hist_entry_get_value(entry, 10), OP_EQ, 0); + tt_int_op(metrics_store_hist_entry_get_value(entry, 20), OP_EQ, 3); + tt_int_op(metrics_store_hist_entry_get_value(entry, 3000), OP_EQ, 4); + tt_int_op(metrics_store_hist_entry_get_value(entry, 3000), OP_EQ, 4); + tt_int_op(metrics_store_hist_entry_get_count(entry), OP_EQ, 4); + tt_int_op(metrics_store_hist_entry_get_sum(entry), OP_EQ, 53); + + /* Ensure this resets all buckets back to 0. */ + metrics_store_entry_reset(entry); + for (size_t i = 0; i < bucket_count; ++i) { + tt_uint_op(entry->u.histogram.buckets[i].bucket, OP_EQ, buckets[i]); + tt_uint_op(entry->u.histogram.buckets[i].value, OP_EQ, 0); + } + + /* tt_int_op assigns the third argument to a variable of type long, which + * overflows on some platforms (e.g. on some 32-bit systems). We disable + * these checks for those platforms. */ +#if LONG_MAX >= INT64_MAX + metrics_store_hist_entry_update(entry, 1, INT64_MAX - 13); + tt_int_op(metrics_store_hist_entry_get_sum(entry), OP_EQ, INT64_MAX - 13); + metrics_store_hist_entry_update(entry, 1, 13); + tt_int_op(metrics_store_hist_entry_get_sum(entry), OP_EQ, INT64_MAX); + /* Uh-oh, the sum of all observations is now greater than INT64_MAX. Make + * sure we reset the entry instead of overflowing the sum. */ + metrics_store_hist_entry_update(entry, 1, 1); + tt_int_op(metrics_store_hist_entry_get_value(entry, 10), OP_EQ, 1); + tt_int_op(metrics_store_hist_entry_get_value(entry, 20), OP_EQ, 1); + tt_int_op(metrics_store_hist_entry_get_value(entry, 3000), OP_EQ, 1); + tt_int_op(metrics_store_hist_entry_get_value(entry, 3000), OP_EQ, 1); + tt_int_op(metrics_store_hist_entry_get_count(entry), OP_EQ, 1); + tt_int_op(metrics_store_hist_entry_get_sum(entry), OP_EQ, 1); +#endif + +#if LONG_MIN <= INT64_MIN + metrics_store_entry_reset(entry); + /* In practice, we're not going to have negative observations (as we only use + * histograms for timings, which are always positive), but technically + * prometheus _does_ support negative observations. */ + metrics_store_hist_entry_update(entry, 1, INT64_MIN + 13); + tt_int_op(metrics_store_hist_entry_get_sum(entry), OP_EQ, INT64_MIN + 13); + metrics_store_hist_entry_update(entry, 1, -13); + tt_int_op(metrics_store_hist_entry_get_sum(entry), OP_EQ, INT64_MIN); + /* Uh-oh, the sum of all observations is now less than INT64_MIN. Make + * sure we reset the entry instead of underflowing the sum. */ + metrics_store_hist_entry_update(entry, 1, -1); + tt_int_op(metrics_store_hist_entry_get_value(entry, 10), OP_EQ, 1); + tt_int_op(metrics_store_hist_entry_get_value(entry, 20), OP_EQ, 1); + tt_int_op(metrics_store_hist_entry_get_value(entry, 3000), OP_EQ, 1); + tt_int_op(metrics_store_hist_entry_get_value(entry, 3000), OP_EQ, 1); + tt_int_op(metrics_store_hist_entry_get_count(entry), OP_EQ, 1); + tt_int_op(metrics_store_hist_entry_get_sum(entry), OP_EQ, -1); +#endif + done: metrics_store_free(store); } @@ -270,6 +409,7 @@ struct testcase_t metrics_tests[] = { { "config", test_config, TT_FORK, NULL, NULL }, { "connection", test_connection, TT_FORK, NULL, NULL }, { "prometheus", test_prometheus, TT_FORK, NULL, NULL }, + { "prometheus_histogram", test_prometheus_histogram, TT_FORK, NULL, NULL }, { "store", test_store, TT_FORK, NULL, NULL },
END_OF_TESTCASES
This is an automated email from the git hooks/post-receive script.
dgoulet pushed a commit to branch main in repository tor.
commit 1a60fa547f5c061b1dd4dda4569ddcbb5bf3ad9a Author: Gabriela Moldovan gabi@torproject.org AuthorDate: Wed Mar 8 17:52:20 2023 +0000
metrics: Add HS service side circuit build time metrics.
This adds 2 histogram metrics for hidden services: * `tor_hs_rend_circ_build_time` - the rendezvous circuit build time in milliseconds * `tor_hs_intro_circ_build_time` - the introduction circuit build time in milliseconds
The text representation representation of the new metrics looks like this: ``` # HELP tor_hs_rend_circ_build_time The rendezvous circuit build time in milliseconds # TYPE tor_hs_rend_circ_build_time histogram tor_hs_rend_circ_build_time_bucket{onion="<elided>",le="1000.00"} 2 tor_hs_rend_circ_build_time_bucket{onion="<elided>",le="5000.00"} 10 tor_hs_rend_circ_build_time_bucket{onion="<elided>",le="10000.00"} 10 tor_hs_rend_circ_build_time_bucket{onion="<elided>",le="30000.00"} 10 tor_hs_rend_circ_build_time_bucket{onion="<elided>",le="60000.00"} 10 tor_hs_rend_circ_build_time_bucket{onion="<elided>",le="+Inf"} 10 tor_hs_rend_circ_build_time_sum{onion="<elided>"} 10824 tor_hs_rend_circ_build_time_count{onion="<elided>"} 10 # HELP tor_hs_intro_circ_build_time The introduction circuit build time in milliseconds # TYPE tor_hs_intro_circ_build_time histogram tor_hs_intro_circ_build_time_bucket{onion="<elided>",le="1000.00"} 0 tor_hs_intro_circ_build_time_bucket{onion="<elided>",le="5000.00"} 6 tor_hs_intro_circ_build_time_bucket{onion="<elided>",le="10000.00"} 6 tor_hs_intro_circ_build_time_bucket{onion="<elided>",le="30000.00"} 6 tor_hs_intro_circ_build_time_bucket{onion="<elided>",le="60000.00"} 6 tor_hs_intro_circ_build_time_bucket{onion="<elided>",le="+Inf"} 6 tor_hs_intro_circ_build_time_sum{onion="<elided>"} 9843 tor_hs_intro_circ_build_time_count{onion="<elided>"} 6 ```
Signed-off-by: Gabriela Moldovan gabi@torproject.org --- changes/ticket40757 | 5 ++++ src/feature/hs/hs_metrics.c | 16 +++++++++---- src/feature/hs/hs_metrics.h | 49 ++++++++++++++++++++++++++------------- src/feature/hs/hs_metrics_entry.c | 29 +++++++++++++++++++++++ src/feature/hs/hs_metrics_entry.h | 4 ++++ src/feature/hs/hs_service.c | 11 +++++++++ src/test/test_hs_metrics.c | 8 +++---- 7 files changed, 98 insertions(+), 24 deletions(-)
diff --git a/changes/ticket40757 b/changes/ticket40757 index e2d8c1ed47..68cd5ac19b 100644 --- a/changes/ticket40757 +++ b/changes/ticket40757 @@ -1,3 +1,8 @@ o Minor features (metrics): - Add support for histograms. Part of ticket 40757. + o Minor features (hs, metrics): + - Add tor_hs_rend_circ_build_time and tor_hs_intro_circ_build_time + histograms to measure hidden service rend/intro circuit build time + durations. + Part of ticket 40757. diff --git a/src/feature/hs/hs_metrics.c b/src/feature/hs/hs_metrics.c index 38cdb49e40..46c72cf539 100644 --- a/src/feature/hs/hs_metrics.c +++ b/src/feature/hs/hs_metrics.c @@ -68,6 +68,8 @@ add_metric_with_labels(hs_service_t *service, hs_metrics_key_t metric, case HS_METRICS_NUM_ESTABLISHED_RDV: FALLTHROUGH; case HS_METRICS_NUM_RDV: FALLTHROUGH; case HS_METRICS_NUM_ESTABLISHED_INTRO: FALLTHROUGH; + case HS_METRICS_INTRO_CIRC_BUILD_TIME: FALLTHROUGH; + case HS_METRICS_REND_CIRC_BUILD_TIME: FALLTHROUGH; default: break; } @@ -144,7 +146,7 @@ void hs_metrics_update_by_service(const hs_metrics_key_t key, const hs_service_t *service, uint16_t port, const char *reason, - int64_t n) + int64_t n, int64_t obs) { tor_assert(service);
@@ -165,8 +167,14 @@ hs_metrics_update_by_service(const hs_metrics_key_t key, entry, metrics_format_label("port", port_to_str(port)))) && ((!reason || metrics_store_entry_has_label( entry, metrics_format_label("reason", reason))))) { + + if (metrics_store_entry_is_histogram(entry)) { + metrics_store_hist_entry_update(entry, n, obs); + } else { metrics_store_entry_update(entry, n); - break; + } + + break; } } SMARTLIST_FOREACH_END(entry); } @@ -182,7 +190,7 @@ void hs_metrics_update_by_ident(const hs_metrics_key_t key, const ed25519_public_key_t *ident_pk, const uint16_t port, const char *reason, - int64_t n) + int64_t n, int64_t obs) { hs_service_t *service;
@@ -196,7 +204,7 @@ hs_metrics_update_by_ident(const hs_metrics_key_t key, * service and thus the only way to know is to lookup the service. */ return; } - hs_metrics_update_by_service(key, service, port, reason, n); + hs_metrics_update_by_service(key, service, port, reason, n, obs); }
/** Return a list of all the onion service metrics stores. This is the diff --git a/src/feature/hs/hs_metrics.h b/src/feature/hs/hs_metrics.h index a32f76e3bc..4eff4cb498 100644 --- a/src/feature/hs/hs_metrics.h +++ b/src/feature/hs/hs_metrics.h @@ -27,58 +27,75 @@ const smartlist_t *hs_metrics_get_stores(void); void hs_metrics_update_by_ident(const hs_metrics_key_t key, const ed25519_public_key_t *ident_pk, const uint16_t port, const char *reason, - int64_t n); + int64_t n, int64_t obs); void hs_metrics_update_by_service(const hs_metrics_key_t key, const hs_service_t *service, uint16_t port, const char *reason, - int64_t n); + int64_t n, int64_t obs);
/** New introducion request received. */ -#define hs_metrics_new_introduction(s) \ - hs_metrics_update_by_service(HS_METRICS_NUM_INTRODUCTIONS, (s), 0, NULL, 1) +#define hs_metrics_new_introduction(s) \ + hs_metrics_update_by_service(HS_METRICS_NUM_INTRODUCTIONS, (s), 0, NULL, 1, \ + 0)
/** Introducion request rejected. */ #define hs_metrics_reject_intro_req(s, reason) \ hs_metrics_update_by_service(HS_METRICS_NUM_REJECTED_INTRO_REQ, (s), 0, \ - (reason), 1) + (reason), 1, 0)
/** Number of bytes written to the application from the service. */ #define hs_metrics_app_write_bytes(i, port, n) \ hs_metrics_update_by_ident(HS_METRICS_APP_WRITE_BYTES, (i), (port), NULL, \ - (n)) + (n), 0)
/** Number of bytes read from the application to the service. */ -#define hs_metrics_app_read_bytes(i, port, n) \ - hs_metrics_update_by_ident(HS_METRICS_APP_READ_BYTES, (i), (port), NULL, (n)) +#define hs_metrics_app_read_bytes(i, port, n) \ + hs_metrics_update_by_ident(HS_METRICS_APP_READ_BYTES, (i), (port), NULL, \ + (n), 0)
/** Newly established rendezvous. This is called as soon as the circuit purpose * is REND_JOINED which is when the RENDEZVOUS2 cell is sent. */ -#define hs_metrics_new_established_rdv(s) \ - hs_metrics_update_by_service(HS_METRICS_NUM_ESTABLISHED_RDV, (s), 0, NULL, 1) +#define hs_metrics_new_established_rdv(s) \ + hs_metrics_update_by_service(HS_METRICS_NUM_ESTABLISHED_RDV, (s), 0, NULL, \ + 1, 0)
/** New rendezvous circuit failure. */ #define hs_metrics_failed_rdv(i, reason) \ - hs_metrics_update_by_ident(HS_METRICS_NUM_FAILED_RDV, (i), 0, (reason), 1) + hs_metrics_update_by_ident(HS_METRICS_NUM_FAILED_RDV, (i), 0, (reason), 1, 0)
/** Established rendezvous closed. This is called when the circuit in * REND_JOINED state is marked for close. */ -#define hs_metrics_close_established_rdv(i) \ - hs_metrics_update_by_ident(HS_METRICS_NUM_ESTABLISHED_RDV, (i), 0, NULL, -1) +#define hs_metrics_close_established_rdv(i) \ + hs_metrics_update_by_ident(HS_METRICS_NUM_ESTABLISHED_RDV, (i), 0, NULL, \ + -1, 0)
/** New rendezvous circuit being launched. */ #define hs_metrics_new_rdv(i) \ - hs_metrics_update_by_ident(HS_METRICS_NUM_RDV, (i), 0, NULL, 1) + hs_metrics_update_by_ident(HS_METRICS_NUM_RDV, (i), 0, NULL, 1, 0)
/** New introduction circuit has been established. This is called when the * INTRO_ESTABLISHED has been received by the service. */ #define hs_metrics_new_established_intro(s) \ hs_metrics_update_by_service(HS_METRICS_NUM_ESTABLISHED_INTRO, (s), 0, \ - NULL, 1) + NULL, 1, 0)
/** Established introduction circuit closes. This is called when * INTRO_ESTABLISHED circuit is marked for close. */ #define hs_metrics_close_established_intro(i) \ hs_metrics_update_by_ident(HS_METRICS_NUM_ESTABLISHED_INTRO, (i), 0, NULL, \ - -1) + -1, 0) + +/** Record an introduction circuit build time duration. This is called + * when the INTRO_ESTABLISHED has been received by the service. */ +#define hs_metrics_intro_circ_build_time(s, obs) \ + hs_metrics_update_by_service(HS_METRICS_INTRO_CIRC_BUILD_TIME, (s), 0, \ + NULL, 1, obs) + +/** Record a rendezvous circuit build time duration. This is called as soon as + * the circuit purpose is REND_JOINED which is when the RENDEZVOUS2 cell is + * sent. */ +#define hs_metrics_rdv_circ_build_time(s, obs) \ + hs_metrics_update_by_service(HS_METRICS_REND_CIRC_BUILD_TIME, (s), 0, NULL, \ + 1, obs)
#endif /* !defined(TOR_FEATURE_HS_HS_METRICS_H) */ diff --git a/src/feature/hs/hs_metrics_entry.c b/src/feature/hs/hs_metrics_entry.c index 9181d770e0..3524d72334 100644 --- a/src/feature/hs/hs_metrics_entry.c +++ b/src/feature/hs/hs_metrics_entry.c @@ -18,6 +18,19 @@
#include "feature/hs/hs_metrics_entry.h"
+/* Histogram time buckets (in milliseconds). */ +static const int64_t hs_metrics_circ_build_time_buckets[] = +{ + 1000, /* 1s */ + 5000, /* 5s */ + 10000, /* 10s */ + 30000, /* 30s */ + 60000 /* 60s */ +}; + +static const size_t hs_metrics_circ_build_time_buckets_size = + ARRAY_LENGTH(hs_metrics_circ_build_time_buckets); + /** The base metrics that is a static array of metrics that are added to every * single new stores. * @@ -75,6 +88,22 @@ const hs_metrics_entry_t base_metrics[] = .name = METRICS_NAME(hs_intro_rejected_intro_req_count), .help = "Total number of rejected introduction circuits", }, + { + .key = HS_METRICS_INTRO_CIRC_BUILD_TIME, + .type = METRICS_TYPE_HISTOGRAM, + .name = METRICS_NAME(hs_intro_circ_build_time), + .buckets = hs_metrics_circ_build_time_buckets, + .bucket_count = hs_metrics_circ_build_time_buckets_size, + .help = "The introduction circuit build time in milliseconds", + }, + { + .key = HS_METRICS_REND_CIRC_BUILD_TIME, + .type = METRICS_TYPE_HISTOGRAM, + .name = METRICS_NAME(hs_rend_circ_build_time), + .buckets = hs_metrics_circ_build_time_buckets, + .bucket_count = hs_metrics_circ_build_time_buckets_size, + .help = "The rendezvous circuit build time in milliseconds", + }, };
/** Size of base_metrics array that is number of entries. */ diff --git a/src/feature/hs/hs_metrics_entry.h b/src/feature/hs/hs_metrics_entry.h index b966f0c226..4c9abd06d7 100644 --- a/src/feature/hs/hs_metrics_entry.h +++ b/src/feature/hs/hs_metrics_entry.h @@ -58,6 +58,10 @@ typedef enum { HS_METRICS_NUM_ESTABLISHED_INTRO = 6, /** Number of rejected introducton requests. */ HS_METRICS_NUM_REJECTED_INTRO_REQ = 7, + /** Introduction circuit build time in milliseconds. */ + HS_METRICS_INTRO_CIRC_BUILD_TIME = 8, + /** Rendezvous circuit build time in milliseconds. */ + HS_METRICS_REND_CIRC_BUILD_TIME = 9, } hs_metrics_key_t;
/** The metadata of an HS metrics. */ diff --git a/src/feature/hs/hs_service.c b/src/feature/hs/hs_service.c index b5a69b8d59..14cd9efec1 100644 --- a/src/feature/hs/hs_service.c +++ b/src/feature/hs/hs_service.c @@ -33,6 +33,7 @@ #include "lib/crypt_ops/crypto_ope.h" #include "lib/crypt_ops/crypto_rand.h" #include "lib/crypt_ops/crypto_util.h" +#include "lib/time/tvdiff.h"
#include "feature/hs/hs_circuit.h" #include "feature/hs/hs_common.h" @@ -3412,6 +3413,11 @@ service_rendezvous_circ_has_opened(origin_circuit_t *circ) * will even out the metric. */ if (TO_CIRCUIT(circ)->purpose == CIRCUIT_PURPOSE_S_REND_JOINED) { hs_metrics_new_established_rdv(service); + + struct timeval now; + tor_gettimeofday(&now); + int64_t duration = tv_mdiff(&TO_CIRCUIT(circ)->timestamp_began, &now); + hs_metrics_rdv_circ_build_time(service, duration); }
goto done; @@ -3465,8 +3471,13 @@ service_handle_intro_established(origin_circuit_t *circ, goto err; }
+ struct timeval now; + tor_gettimeofday(&now); + int64_t duration = tv_mdiff(&TO_CIRCUIT(circ)->timestamp_began, &now); + /* Update metrics. */ hs_metrics_new_established_intro(service); + hs_metrics_intro_circ_build_time(service, duration);
log_info(LD_REND, "Successfully received an INTRO_ESTABLISHED cell " "on circuit %u for service %s", diff --git a/src/test/test_hs_metrics.c b/src/test/test_hs_metrics.c index b7c0ab53da..c3c7ef57bc 100644 --- a/src/test/test_hs_metrics.c +++ b/src/test/test_hs_metrics.c @@ -40,7 +40,7 @@ test_metrics(void *arg)
/* Update entry by identifier. */ hs_metrics_update_by_ident(HS_METRICS_NUM_INTRODUCTIONS, - &service->keys.identity_pk, 0, NULL, 42); + &service->keys.identity_pk, 0, NULL, 42, 0);
/* Confirm the entry value. */ const smartlist_t *entries = metrics_store_get_all(service->metrics.store, @@ -53,14 +53,14 @@ test_metrics(void *arg)
/* Update entry by service now. */ hs_metrics_update_by_service(HS_METRICS_NUM_INTRODUCTIONS, - service, 0, NULL, 42); + service, 0, NULL, 42, 0); tt_int_op(metrics_store_entry_get_value(entry), OP_EQ, 84);
const char *reason = HS_METRICS_ERR_INTRO_REQ_BAD_AUTH_KEY;
/* Update tor_hs_intro_rejected_intro_req_count */ hs_metrics_update_by_ident(HS_METRICS_NUM_REJECTED_INTRO_REQ, - &service->keys.identity_pk, 0, reason, 112); + &service->keys.identity_pk, 0, reason, 112, 0);
entries = metrics_store_get_all(service->metrics.store, "tor_hs_intro_rejected_intro_req_count"); @@ -75,7 +75,7 @@ test_metrics(void *arg)
/* Update tor_hs_intro_rejected_intro_req_count entry by service now. */ hs_metrics_update_by_service(HS_METRICS_NUM_REJECTED_INTRO_REQ, service, 0, - reason, 10); + reason, 10, 0); tt_int_op(metrics_store_entry_get_value(entry), OP_EQ, 122);
done:
This is an automated email from the git hooks/post-receive script.
dgoulet pushed a commit to branch main in repository tor.
commit 59456cb3cf34e09ee3e4f765659d1396d86c544f Merge: 8f50f490a6 1a60fa547f Author: David Goulet dgoulet@torproject.org AuthorDate: Mon Mar 13 11:22:31 2023 -0400
Merge branch 'tor-gitlab/mr/700'
changes/ticket40757 | 8 ++ src/feature/hs/hs_metrics.c | 23 +++-- src/feature/hs/hs_metrics.h | 49 ++++++---- src/feature/hs/hs_metrics_entry.c | 29 ++++++ src/feature/hs/hs_metrics_entry.h | 8 ++ src/feature/hs/hs_service.c | 11 +++ src/feature/relay/relay_metrics.c | 170 +++++++++++++++++----------------- src/lib/metrics/metrics_common.c | 2 + src/lib/metrics/metrics_common.h | 23 +++++ src/lib/metrics/metrics_store.c | 6 +- src/lib/metrics/metrics_store.h | 6 +- src/lib/metrics/metrics_store_entry.c | 157 ++++++++++++++++++++++++++++++- src/lib/metrics/metrics_store_entry.h | 13 ++- src/lib/metrics/prometheus.c | 70 +++++++++++++- src/test/test_hs_metrics.c | 8 +- src/test/test_metrics.c | 146 ++++++++++++++++++++++++++++- 16 files changed, 602 insertions(+), 127 deletions(-)
tor-commits@lists.torproject.org