From ca9a9d4636f4a65b5e9f8e504a41cee1ec316a5b Mon Sep 17 00:00:00 2001 From: mxinden-bot Date: Sat, 30 May 2026 14:50:54 +0000 Subject: [PATCH] Bug 2043832 - happy-eyeballs glean metrics for https rr Adds happy_eyeballs_h3_discovery (was h3 advertised via Alt-Svc, an HTTPS record, both, or neither) and happy_eyeballs_https_rr_features (which features received HTTPS records carry: h3 ALPN, ECH, IP hints, against a total denominator), and drops the now redundant happy_eyeballs_https_record_available. --- .../http/happy_eyeballs_glue/src/lib.rs | 6 +- .../http/happy_eyeballs_glue/src/metrics.rs | 62 +++++++++++++++--- netwerk/protocol/http/metrics.yaml | 64 ++++++++++++++----- 3 files changed, 105 insertions(+), 27 deletions(-) diff --git a/netwerk/protocol/http/happy_eyeballs_glue/src/lib.rs b/netwerk/protocol/http/happy_eyeballs_glue/src/lib.rs index 25f7c52c3f4c8..61718a72ddf98 100644 --- a/netwerk/protocol/http/happy_eyeballs_glue/src/lib.rs +++ b/netwerk/protocol/http/happy_eyeballs_glue/src/lib.rs @@ -72,6 +72,8 @@ pub unsafe extern "C" fn happy_eyeballs_create( }) .collect(); + let metrics = metrics::Metrics::new(&alt_svc_vec); + let network_config = happy_eyeballs::NetworkConfig { alt_svc: alt_svc_vec, ip: ip_preference.into(), @@ -94,7 +96,7 @@ pub unsafe extern "C" fn happy_eyeballs_create( refcnt: unsafe { AtomicRefcnt::new() }, inner: he, profiler, - metrics: metrics::Metrics::new(), + metrics, }); boxed .profiler @@ -344,7 +346,7 @@ impl HappyEyeballs { } self.profiler.dns_response_https(id, &infos); - self.metrics.dns_response_https(id, !infos.is_empty()); + self.metrics.dns_response_https(id, &infos); let result = happy_eyeballs::DnsResult::Https(Ok(infos)); let input = happy_eyeballs::Input::DnsResult { id, result }; diff --git a/netwerk/protocol/http/happy_eyeballs_glue/src/metrics.rs b/netwerk/protocol/http/happy_eyeballs_glue/src/metrics.rs index f52f6419a6a5d..57d370808a673 100644 --- a/netwerk/protocol/http/happy_eyeballs_glue/src/metrics.rs +++ b/netwerk/protocol/http/happy_eyeballs_glue/src/metrics.rs @@ -34,12 +34,20 @@ pub(crate) struct Metrics { conn_infos: HashMap, attempt_count: u32, cancelled_count: u32, + alt_svc_h3: bool, https_record_received: bool, + https_rr_h3: bool, + https_rr_ech: bool, + https_rr_ipv4hint: bool, + https_rr_ipv6hint: bool, outcome: Option, } impl Metrics { - pub(crate) fn new() -> Self { + pub(crate) fn new(alt_svc: &[happy_eyeballs::AltSvc]) -> Self { + let alt_svc_h3 = alt_svc + .iter() + .any(|a| matches!(a.http_version, happy_eyeballs::HttpVersion::H3)); Self { start: Instant::now(), first_attempt_dispatched: false, @@ -47,7 +55,12 @@ impl Metrics { conn_infos: HashMap::new(), attempt_count: 0, cancelled_count: 0, + alt_svc_h3, https_record_received: false, + https_rr_h3: false, + https_rr_ech: false, + https_rr_ipv4hint: false, + https_rr_ipv6hint: false, outcome: None, } } @@ -77,8 +90,18 @@ impl Metrics { .accumulate_single_sample_signed(elapsed_ms); } - pub(crate) fn dns_response_https(&mut self, id: happy_eyeballs::Id, has_records: bool) { - self.https_record_received |= has_records; + pub(crate) fn dns_response_https( + &mut self, + id: happy_eyeballs::Id, + infos: &[happy_eyeballs::ServiceInfo], + ) { + self.https_record_received |= !infos.is_empty(); + self.https_rr_h3 |= infos + .iter() + .any(|i| i.alpn_http_versions.contains(&happy_eyeballs::HttpVersion::H3)); + self.https_rr_ech |= infos.iter().any(|i| i.ech_config.is_some()); + self.https_rr_ipv4hint |= infos.iter().any(|i| !i.ipv4_hints.is_empty()); + self.https_rr_ipv6hint |= infos.iter().any(|i| !i.ipv6_hints.is_empty()); self.dns_response(id); } @@ -145,14 +168,35 @@ impl Drop for Metrics { .accumulate_single_sample_signed(info.index.into()); } - let https_label = if self.https_record_received { - "available" - } else { - "unavailable" + let h3_discovery_label = match (self.alt_svc_h3, self.https_rr_h3) { + (false, false) => "none", + (true, false) => "altsvc_only", + (false, true) => "https_rr_only", + (true, true) => "both", }; - glean::happy_eyeballs_https_record_available - .get(https_label) + glean::happy_eyeballs_h3_discovery + .get(h3_discovery_label) .add(1); + + if self.https_record_received { + glean::happy_eyeballs_https_rr_features.get("total").add(1); + if self.https_rr_h3 { + glean::happy_eyeballs_https_rr_features.get("h3_alpn").add(1); + } + if self.https_rr_ech { + glean::happy_eyeballs_https_rr_features.get("ech").add(1); + } + if self.https_rr_ipv4hint { + glean::happy_eyeballs_https_rr_features + .get("ipv4hint") + .add(1); + } + if self.https_rr_ipv6hint { + glean::happy_eyeballs_https_rr_features + .get("ipv6hint") + .add(1); + } + } } } diff --git a/netwerk/protocol/http/metrics.yaml b/netwerk/protocol/http/metrics.yaml index 17d467bc5b7a4..1335d4ec98c39 100644 --- a/netwerk/protocol/http/metrics.yaml +++ b/netwerk/protocol/http/metrics.yaml @@ -164,22 +164,6 @@ netwerk: expires: never - happy_eyeballs_https_record_available: - type: labeled_counter - description: > - Happy Eyeballs: whether an HTTPS service record was available during - connection establishment. - labels: - - available - - unavailable - bugs: - - https://bugzilla.mozilla.org/show_bug.cgi?id=2026606 - data_reviews: - - https://bugzilla.mozilla.org/show_bug.cgi?id=2026606 - notification_emails: - - necko@mozilla.com - expires: never - happy_eyeballs_cancelled_attempt_count: type: custom_distribution description: > @@ -217,6 +201,54 @@ netwerk: - necko@mozilla.com expires: never + happy_eyeballs_h3_discovery: + type: labeled_counter + description: > + Happy Eyeballs: how HTTP/3 (h3) reachability was advertised for a + connection, crossing whether an Alt-Svc header advertised h3 with + whether an HTTPS DNS record advertised h3 in its ALPN set. The + "altsvc_only" bucket is the case where a site advertises h3 via Alt-Svc + but publishes no h3-capable HTTPS record: the first connection cannot + use h3 and must spend an extra round trip discovering it, where an + HTTPS record would have allowed h3 immediately. + labels: + - none + - altsvc_only + - https_rr_only + - both + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=2043832 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=2043832 + notification_emails: + - necko@mozilla.com + expires: never + + happy_eyeballs_https_rr_features: + type: labeled_counter + description: > + Happy Eyeballs: which connection-bootstrapping features the HTTPS DNS + records carried, combined across all HTTPS records received for a + connection (the union of features over every record, not per record). + The "total" label is incremented once per connection that saw at least + one non-empty HTTPS record and serves as the denominator; each feature + label is incremented once per connection whose combined records carried + that feature. "ech" and the address hints can only be delivered ahead + of the first connection via the DNS record, not via an Alt-Svc header. + labels: + - total + - h3_alpn + - ech + - ipv4hint + - ipv6hint + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=2043832 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=2043832 + notification_emails: + - necko@mozilla.com + expires: never + network: byte_range_request: type: labeled_counter