From cfd87b9fe31d78ca23dedd038fdeb5aeaccf04a1 Mon Sep 17 00:00:00 2001 From: Cameron Bytheway Date: Thu, 7 Nov 2024 07:16:40 -0700 Subject: [PATCH] feat(s2n-quic-core): add nominal counter aggregations (#2369) --- dc/s2n-quic-dc/events/connection.rs | 12 +- dc/s2n-quic-dc/events/endpoint.rs | 4 + dc/s2n-quic-dc/events/map.rs | 19 + dc/s2n-quic-dc/src/event.rs | 2 +- dc/s2n-quic-dc/src/event/generated.rs | 2 + .../src/event/generated/metrics/aggregate.rs | 876 ++++++++-- .../src/event/generated/metrics/probe.rs | 325 +++- quic/s2n-quic-core/events/connection.rs | 72 +- quic/s2n-quic-core/events/endpoint.rs | 14 +- quic/s2n-quic-core/src/connection/error.rs | 105 ++ ...ection__error__metrics__variants_test.snap | 258 +++ quic/s2n-quic-core/src/crypto/tls/error.rs | 57 + ...re__crypto__tls__error__variants_test.snap | 146 ++ quic/s2n-quic-core/src/event/generated.rs | 895 ++++++++++ .../src/event/generated/metrics/aggregate.rs | 1476 +++++++++++------ .../src/event/generated/metrics/probe.rs | 403 +++-- .../src/event/metrics/aggregate.rs | 119 +- .../src/event/metrics/aggregate/info.rs | 14 +- .../src/event/metrics/aggregate/metric.rs | 165 ++ .../event/metrics/aggregate/probe/dynamic.rs | 112 +- .../src/event/metrics/aggregate/recorder.rs | 115 ++ .../src/event/metrics/aggregate/variant.rs | 15 + quic/s2n-quic-core/src/transport/error.rs | 89 +- ...core__transport__error__variants_test.snap | 214 +++ quic/s2n-quic-events/src/output.rs | 4 + .../src/output/metrics/aggregate.rs | 392 ++++- quic/s2n-quic-events/src/parser.rs | 45 +- 27 files changed, 4949 insertions(+), 1001 deletions(-) create mode 100644 quic/s2n-quic-core/src/connection/snapshots/s2n_quic_core__connection__error__metrics__variants_test.snap create mode 100644 quic/s2n-quic-core/src/crypto/tls/snapshots/s2n_quic_core__crypto__tls__error__variants_test.snap create mode 100644 quic/s2n-quic-core/src/event/metrics/aggregate/metric.rs create mode 100644 quic/s2n-quic-core/src/event/metrics/aggregate/recorder.rs create mode 100644 quic/s2n-quic-core/src/event/metrics/aggregate/variant.rs create mode 100644 quic/s2n-quic-core/src/transport/snapshots/s2n_quic_core__transport__error__variants_test.snap diff --git a/dc/s2n-quic-dc/events/connection.rs b/dc/s2n-quic-dc/events/connection.rs index c90c6d9c35..b64624c86f 100644 --- a/dc/s2n-quic-dc/events/connection.rs +++ b/dc/s2n-quic-dc/events/connection.rs @@ -4,23 +4,23 @@ #[event("application:write")] pub struct ApplicationWrite { /// The number of bytes that the application tried to write - #[measure("provided", "b")] + #[measure("provided", Bytes)] total_len: usize, /// The amount that was written - #[measure("committed", "b")] - #[counter("committed.total", "b")] + #[measure("committed", Bytes)] + #[counter("committed.total", Bytes)] write_len: usize, } #[event("application:read")] pub struct ApplicationRead { /// The number of bytes that the application tried to read - #[measure("capacity", "b")] + #[measure("capacity", Bytes)] capacity: usize, /// The amount that was read - #[measure("committed", "b")] - #[counter("committed.total", "b")] + #[measure("committed", Bytes)] + #[counter("committed.total", Bytes)] read_len: usize, } diff --git a/dc/s2n-quic-dc/events/endpoint.rs b/dc/s2n-quic-dc/events/endpoint.rs index e0ceaa74f9..356fc9a694 100644 --- a/dc/s2n-quic-dc/events/endpoint.rs +++ b/dc/s2n-quic-dc/events/endpoint.rs @@ -4,8 +4,12 @@ #[event("endpoint:initialized")] #[subject(endpoint)] struct EndpointInitialized<'a> { + #[nominal_counter("acceptor.protocol")] acceptor_addr: SocketAddress<'a>, + #[nominal_counter("handshake.protocol")] handshake_addr: SocketAddress<'a>, + #[bool_counter("tcp")] tcp: bool, + #[bool_counter("udp")] udp: bool, } diff --git a/dc/s2n-quic-dc/events/map.rs b/dc/s2n-quic-dc/events/map.rs index d9181f27b3..a356832e35 100644 --- a/dc/s2n-quic-dc/events/map.rs +++ b/dc/s2n-quic-dc/events/map.rs @@ -25,6 +25,7 @@ struct PathSecretMapUninitialized { #[subject(endpoint)] /// Emitted when a background handshake is requested struct PathSecretMapBackgroundHandshakeRequested<'a> { + #[nominal_counter("peer_address.protocol")] peer_address: SocketAddress<'a>, } @@ -32,6 +33,7 @@ struct PathSecretMapBackgroundHandshakeRequested<'a> { #[subject(endpoint)] /// Emitted when the entry is inserted into the path secret map struct PathSecretMapEntryInserted<'a> { + #[nominal_counter("peer_address.protocol")] peer_address: SocketAddress<'a>, #[snapshot("[HIDDEN]")] @@ -42,6 +44,7 @@ struct PathSecretMapEntryInserted<'a> { #[subject(endpoint)] /// Emitted when the entry is considered ready for use struct PathSecretMapEntryReady<'a> { + #[nominal_counter("peer_address.protocol")] peer_address: SocketAddress<'a>, #[snapshot("[HIDDEN]")] @@ -52,6 +55,7 @@ struct PathSecretMapEntryReady<'a> { #[subject(endpoint)] /// Emitted when an entry is replaced by a new one for the same `peer_address` struct PathSecretMapEntryReplaced<'a> { + #[nominal_counter("peer_address.protocol")] peer_address: SocketAddress<'a>, #[snapshot("[HIDDEN]")] @@ -65,6 +69,7 @@ struct PathSecretMapEntryReplaced<'a> { #[subject(endpoint)] /// Emitted when an UnknownPathSecret packet was sent struct UnknownPathSecretPacketSent<'a> { + #[nominal_counter("peer_address.protocol")] peer_address: SocketAddress<'a>, #[snapshot("[HIDDEN]")] @@ -75,6 +80,7 @@ struct UnknownPathSecretPacketSent<'a> { #[subject(endpoint)] /// Emitted when an UnknownPathSecret packet was received struct UnknownPathSecretPacketReceived<'a> { + #[nominal_counter("peer_address.protocol")] peer_address: SocketAddress<'a>, #[snapshot("[HIDDEN]")] @@ -85,6 +91,7 @@ struct UnknownPathSecretPacketReceived<'a> { #[subject(endpoint)] /// Emitted when an UnknownPathSecret packet was authentic and processed struct UnknownPathSecretPacketAccepted<'a> { + #[nominal_counter("peer_address.protocol")] peer_address: SocketAddress<'a>, #[snapshot("[HIDDEN]")] @@ -95,6 +102,7 @@ struct UnknownPathSecretPacketAccepted<'a> { #[subject(endpoint)] /// Emitted when an UnknownPathSecret packet was rejected as invalid struct UnknownPathSecretPacketRejected<'a> { + #[nominal_counter("peer_address.protocol")] peer_address: SocketAddress<'a>, #[snapshot("[HIDDEN]")] @@ -105,6 +113,7 @@ struct UnknownPathSecretPacketRejected<'a> { #[subject(endpoint)] /// Emitted when an UnknownPathSecret packet was dropped due to a missing entry struct UnknownPathSecretPacketDropped<'a> { + #[nominal_counter("peer_address.protocol")] peer_address: SocketAddress<'a>, #[snapshot("[HIDDEN]")] @@ -139,6 +148,7 @@ struct ReplayPotentiallyDetected<'a> { #[subject(endpoint)] /// Emitted when an ReplayDetected packet was sent struct ReplayDetectedPacketSent<'a> { + #[nominal_counter("peer_address.protocol")] peer_address: SocketAddress<'a>, #[snapshot("[HIDDEN]")] @@ -149,6 +159,7 @@ struct ReplayDetectedPacketSent<'a> { #[subject(endpoint)] /// Emitted when an ReplayDetected packet was received struct ReplayDetectedPacketReceived<'a> { + #[nominal_counter("peer_address.protocol")] peer_address: SocketAddress<'a>, #[snapshot("[HIDDEN]")] @@ -159,6 +170,7 @@ struct ReplayDetectedPacketReceived<'a> { #[subject(endpoint)] /// Emitted when an StaleKey packet was authentic and processed struct ReplayDetectedPacketAccepted<'a> { + #[nominal_counter("peer_address.protocol")] peer_address: SocketAddress<'a>, #[snapshot("[HIDDEN]")] @@ -171,6 +183,7 @@ struct ReplayDetectedPacketAccepted<'a> { #[subject(endpoint)] /// Emitted when an ReplayDetected packet was rejected as invalid struct ReplayDetectedPacketRejected<'a> { + #[nominal_counter("peer_address.protocol")] peer_address: SocketAddress<'a>, #[snapshot("[HIDDEN]")] @@ -181,6 +194,7 @@ struct ReplayDetectedPacketRejected<'a> { #[subject(endpoint)] /// Emitted when an ReplayDetected packet was dropped due to a missing entry struct ReplayDetectedPacketDropped<'a> { + #[nominal_counter("peer_address.protocol")] peer_address: SocketAddress<'a>, #[snapshot("[HIDDEN]")] @@ -191,6 +205,7 @@ struct ReplayDetectedPacketDropped<'a> { #[subject(endpoint)] /// Emitted when an StaleKey packet was sent struct StaleKeyPacketSent<'a> { + #[nominal_counter("peer_address.protocol")] peer_address: SocketAddress<'a>, #[snapshot("[HIDDEN]")] @@ -201,6 +216,7 @@ struct StaleKeyPacketSent<'a> { #[subject(endpoint)] /// Emitted when an StaleKey packet was received struct StaleKeyPacketReceived<'a> { + #[nominal_counter("peer_address.protocol")] peer_address: SocketAddress<'a>, #[snapshot("[HIDDEN]")] @@ -211,6 +227,7 @@ struct StaleKeyPacketReceived<'a> { #[subject(endpoint)] /// Emitted when an StaleKey packet was authentic and processed struct StaleKeyPacketAccepted<'a> { + #[nominal_counter("peer_address.protocol")] peer_address: SocketAddress<'a>, #[snapshot("[HIDDEN]")] @@ -221,6 +238,7 @@ struct StaleKeyPacketAccepted<'a> { #[subject(endpoint)] /// Emitted when an StaleKey packet was rejected as invalid struct StaleKeyPacketRejected<'a> { + #[nominal_counter("peer_address.protocol")] peer_address: SocketAddress<'a>, #[snapshot("[HIDDEN]")] @@ -231,6 +249,7 @@ struct StaleKeyPacketRejected<'a> { #[subject(endpoint)] /// Emitted when an StaleKey packet was dropped due to a missing entry struct StaleKeyPacketDropped<'a> { + #[nominal_counter("peer_address.protocol")] peer_address: SocketAddress<'a>, #[snapshot("[HIDDEN]")] diff --git a/dc/s2n-quic-dc/src/event.rs b/dc/s2n-quic-dc/src/event.rs index c4c4df4626..862d6c3520 100644 --- a/dc/s2n-quic-dc/src/event.rs +++ b/dc/s2n-quic-dc/src/event.rs @@ -36,7 +36,7 @@ pub mod metrics { pub mod aggregate { pub use crate::event::generated::metrics::aggregate::*; pub use s2n_quic_core::event::metrics::aggregate::{ - info, AsMetric, Info, Recorder, Registry, + info, AsVariant, BoolRecorder, Info, Metric, NominalRecorder, Recorder, Registry, Units, }; pub mod probe { diff --git a/dc/s2n-quic-dc/src/event/generated.rs b/dc/s2n-quic-dc/src/event/generated.rs index 5dac84e1c8..d22529cf5e 100644 --- a/dc/s2n-quic-dc/src/event/generated.rs +++ b/dc/s2n-quic-dc/src/event/generated.rs @@ -10,6 +10,8 @@ pub(crate) mod metrics; pub mod api { #![doc = r" This module contains events that are emitted to the [`Subscriber`](crate::event::Subscriber)"] use super::*; + #[allow(unused_imports)] + use crate::event::metrics::aggregate; pub use s2n_quic_core::event::api::{EndpointType, SocketAddress, Subject}; pub use traits::Subscriber; #[derive(Clone, Debug)] diff --git a/dc/s2n-quic-dc/src/event/generated/metrics/aggregate.rs b/dc/s2n-quic-dc/src/event/generated/metrics/aggregate.rs index b0996e845a..bd168cb728 100644 --- a/dc/s2n-quic-dc/src/event/generated/metrics/aggregate.rs +++ b/dc/s2n-quic-dc/src/event/generated/metrics/aggregate.rs @@ -9,224 +9,362 @@ use crate::event::{ self, api, metrics::aggregate::{ info::{self, Str}, - AsMetric as _, Info, Recorder, Registry, + AsVariant, BoolRecorder, Info, Metric, NominalRecorder, Recorder, Registry, Units, }, }; -static INFO: &[Info; 36usize] = &[ +static INFO: &[Info; 59usize] = &[ info::Builder { id: 0usize, name: Str::new("application_write\0"), - units: Str::new("\0"), + units: Units::None, } .build(), info::Builder { id: 1usize, name: Str::new("application_write.provided\0"), - units: Str::new("b\0"), + units: Units::Bytes, } .build(), info::Builder { id: 2usize, name: Str::new("application_write.committed.total\0"), - units: Str::new("b\0"), + units: Units::Bytes, } .build(), info::Builder { id: 3usize, name: Str::new("application_write.committed\0"), - units: Str::new("b\0"), + units: Units::Bytes, } .build(), info::Builder { id: 4usize, name: Str::new("application_read\0"), - units: Str::new("\0"), + units: Units::None, } .build(), info::Builder { id: 5usize, name: Str::new("application_read.capacity\0"), - units: Str::new("b\0"), + units: Units::Bytes, } .build(), info::Builder { id: 6usize, name: Str::new("application_read.committed.total\0"), - units: Str::new("b\0"), + units: Units::Bytes, } .build(), info::Builder { id: 7usize, name: Str::new("application_read.committed\0"), - units: Str::new("b\0"), + units: Units::Bytes, } .build(), info::Builder { id: 8usize, name: Str::new("endpoint_initialized\0"), - units: Str::new("\0"), + units: Units::None, } .build(), info::Builder { id: 9usize, - name: Str::new("path_secret_map_initialized\0"), - units: Str::new("\0"), + name: Str::new("endpoint_initialized.acceptor.protocol\0"), + units: Units::None, } .build(), info::Builder { id: 10usize, - name: Str::new("path_secret_map_initialized.capacity\0"), - units: Str::new("\0"), + name: Str::new("endpoint_initialized.handshake.protocol\0"), + units: Units::None, } .build(), info::Builder { id: 11usize, - name: Str::new("path_secret_map_uninitialized\0"), - units: Str::new("\0"), + name: Str::new("endpoint_initialized.tcp\0"), + units: Units::None, } .build(), info::Builder { id: 12usize, - name: Str::new("path_secret_map_uninitialized.capacity\0"), - units: Str::new("\0"), + name: Str::new("endpoint_initialized.udp\0"), + units: Units::None, } .build(), info::Builder { id: 13usize, - name: Str::new("path_secret_map_uninitialized.entries\0"), - units: Str::new("\0"), + name: Str::new("path_secret_map_initialized\0"), + units: Units::None, } .build(), info::Builder { id: 14usize, - name: Str::new("path_secret_map_background_handshake_requested\0"), - units: Str::new("\0"), + name: Str::new("path_secret_map_initialized.capacity\0"), + units: Units::None, } .build(), info::Builder { id: 15usize, - name: Str::new("path_secret_map_entry_inserted\0"), - units: Str::new("\0"), + name: Str::new("path_secret_map_uninitialized\0"), + units: Units::None, } .build(), info::Builder { id: 16usize, - name: Str::new("path_secret_map_entry_ready\0"), - units: Str::new("\0"), + name: Str::new("path_secret_map_uninitialized.capacity\0"), + units: Units::None, } .build(), info::Builder { id: 17usize, - name: Str::new("path_secret_map_entry_replaced\0"), - units: Str::new("\0"), + name: Str::new("path_secret_map_uninitialized.entries\0"), + units: Units::None, } .build(), info::Builder { id: 18usize, - name: Str::new("unknown_path_secret_packet_sent\0"), - units: Str::new("\0"), + name: Str::new("path_secret_map_background_handshake_requested\0"), + units: Units::None, } .build(), info::Builder { id: 19usize, - name: Str::new("unknown_path_secret_packet_received\0"), - units: Str::new("\0"), + name: Str::new("path_secret_map_background_handshake_requested.peer_address.protocol\0"), + units: Units::None, } .build(), info::Builder { id: 20usize, - name: Str::new("unknown_path_secret_packet_accepted\0"), - units: Str::new("\0"), + name: Str::new("path_secret_map_entry_inserted\0"), + units: Units::None, } .build(), info::Builder { id: 21usize, - name: Str::new("unknown_path_secret_packet_rejected\0"), - units: Str::new("\0"), + name: Str::new("path_secret_map_entry_inserted.peer_address.protocol\0"), + units: Units::None, } .build(), info::Builder { id: 22usize, - name: Str::new("unknown_path_secret_packet_dropped\0"), - units: Str::new("\0"), + name: Str::new("path_secret_map_entry_ready\0"), + units: Units::None, } .build(), info::Builder { id: 23usize, - name: Str::new("replay_definitely_detected\0"), - units: Str::new("\0"), + name: Str::new("path_secret_map_entry_ready.peer_address.protocol\0"), + units: Units::None, } .build(), info::Builder { id: 24usize, - name: Str::new("replay_potentially_detected\0"), - units: Str::new("\0"), + name: Str::new("path_secret_map_entry_replaced\0"), + units: Units::None, } .build(), info::Builder { id: 25usize, - name: Str::new("replay_potentially_detected.gap\0"), - units: Str::new("\0"), + name: Str::new("path_secret_map_entry_replaced.peer_address.protocol\0"), + units: Units::None, } .build(), info::Builder { id: 26usize, - name: Str::new("replay_detected_packet_sent\0"), - units: Str::new("\0"), + name: Str::new("unknown_path_secret_packet_sent\0"), + units: Units::None, } .build(), info::Builder { id: 27usize, - name: Str::new("replay_detected_packet_received\0"), - units: Str::new("\0"), + name: Str::new("unknown_path_secret_packet_sent.peer_address.protocol\0"), + units: Units::None, } .build(), info::Builder { id: 28usize, - name: Str::new("replay_detected_packet_accepted\0"), - units: Str::new("\0"), + name: Str::new("unknown_path_secret_packet_received\0"), + units: Units::None, } .build(), info::Builder { id: 29usize, - name: Str::new("replay_detected_packet_rejected\0"), - units: Str::new("\0"), + name: Str::new("unknown_path_secret_packet_received.peer_address.protocol\0"), + units: Units::None, } .build(), info::Builder { id: 30usize, - name: Str::new("replay_detected_packet_dropped\0"), - units: Str::new("\0"), + name: Str::new("unknown_path_secret_packet_accepted\0"), + units: Units::None, } .build(), info::Builder { id: 31usize, - name: Str::new("stale_key_packet_sent\0"), - units: Str::new("\0"), + name: Str::new("unknown_path_secret_packet_accepted.peer_address.protocol\0"), + units: Units::None, } .build(), info::Builder { id: 32usize, - name: Str::new("stale_key_packet_received\0"), - units: Str::new("\0"), + name: Str::new("unknown_path_secret_packet_rejected\0"), + units: Units::None, } .build(), info::Builder { id: 33usize, - name: Str::new("stale_key_packet_accepted\0"), - units: Str::new("\0"), + name: Str::new("unknown_path_secret_packet_rejected.peer_address.protocol\0"), + units: Units::None, } .build(), info::Builder { id: 34usize, - name: Str::new("stale_key_packet_rejected\0"), - units: Str::new("\0"), + name: Str::new("unknown_path_secret_packet_dropped\0"), + units: Units::None, } .build(), info::Builder { id: 35usize, + name: Str::new("unknown_path_secret_packet_dropped.peer_address.protocol\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 36usize, + name: Str::new("replay_definitely_detected\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 37usize, + name: Str::new("replay_potentially_detected\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 38usize, + name: Str::new("replay_potentially_detected.gap\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 39usize, + name: Str::new("replay_detected_packet_sent\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 40usize, + name: Str::new("replay_detected_packet_sent.peer_address.protocol\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 41usize, + name: Str::new("replay_detected_packet_received\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 42usize, + name: Str::new("replay_detected_packet_received.peer_address.protocol\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 43usize, + name: Str::new("replay_detected_packet_accepted\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 44usize, + name: Str::new("replay_detected_packet_accepted.peer_address.protocol\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 45usize, + name: Str::new("replay_detected_packet_rejected\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 46usize, + name: Str::new("replay_detected_packet_rejected.peer_address.protocol\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 47usize, + name: Str::new("replay_detected_packet_dropped\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 48usize, + name: Str::new("replay_detected_packet_dropped.peer_address.protocol\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 49usize, + name: Str::new("stale_key_packet_sent\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 50usize, + name: Str::new("stale_key_packet_sent.peer_address.protocol\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 51usize, + name: Str::new("stale_key_packet_received\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 52usize, + name: Str::new("stale_key_packet_received.peer_address.protocol\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 53usize, + name: Str::new("stale_key_packet_accepted\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 54usize, + name: Str::new("stale_key_packet_accepted.peer_address.protocol\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 55usize, + name: Str::new("stale_key_packet_rejected\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 56usize, + name: Str::new("stale_key_packet_rejected.peer_address.protocol\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 57usize, name: Str::new("stale_key_packet_dropped\0"), - units: Str::new("\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 58usize, + name: Str::new("stale_key_packet_dropped.peer_address.protocol\0"), + units: Units::None, } .build(), ]; @@ -234,6 +372,12 @@ pub struct Subscriber { #[allow(dead_code)] counters: Box<[R::Counter; 28usize]>, #[allow(dead_code)] + bool_counters: Box<[R::BoolCounter; 2usize]>, + #[allow(dead_code)] + nominal_counters: Box<[R::NominalCounter]>, + #[allow(dead_code)] + nominal_offsets: Box<[usize; 21usize]>, + #[allow(dead_code)] measures: Box<[R::Measure; 8usize]>, #[allow(dead_code)] gauges: Box<[R::Gauge; 0usize]>, @@ -258,6 +402,9 @@ impl Subscriber { #[inline] pub fn new(registry: R) -> Self { let mut counters = Vec::with_capacity(28usize); + let mut bool_counters = Vec::with_capacity(2usize); + let mut nominal_offsets = Vec::with_capacity(21usize); + let mut nominal_counters = Vec::with_capacity(21usize); let mut measures = Vec::with_capacity(8usize); let mut gauges = Vec::with_capacity(0usize); let mut timers = Vec::with_capacity(0usize); @@ -266,41 +413,285 @@ impl Subscriber { counters.push(registry.register_counter(&INFO[4usize])); counters.push(registry.register_counter(&INFO[6usize])); counters.push(registry.register_counter(&INFO[8usize])); - counters.push(registry.register_counter(&INFO[9usize])); - counters.push(registry.register_counter(&INFO[11usize])); - counters.push(registry.register_counter(&INFO[14usize])); + counters.push(registry.register_counter(&INFO[13usize])); counters.push(registry.register_counter(&INFO[15usize])); - counters.push(registry.register_counter(&INFO[16usize])); - counters.push(registry.register_counter(&INFO[17usize])); counters.push(registry.register_counter(&INFO[18usize])); - counters.push(registry.register_counter(&INFO[19usize])); counters.push(registry.register_counter(&INFO[20usize])); - counters.push(registry.register_counter(&INFO[21usize])); counters.push(registry.register_counter(&INFO[22usize])); - counters.push(registry.register_counter(&INFO[23usize])); counters.push(registry.register_counter(&INFO[24usize])); counters.push(registry.register_counter(&INFO[26usize])); - counters.push(registry.register_counter(&INFO[27usize])); counters.push(registry.register_counter(&INFO[28usize])); - counters.push(registry.register_counter(&INFO[29usize])); counters.push(registry.register_counter(&INFO[30usize])); - counters.push(registry.register_counter(&INFO[31usize])); counters.push(registry.register_counter(&INFO[32usize])); - counters.push(registry.register_counter(&INFO[33usize])); counters.push(registry.register_counter(&INFO[34usize])); - counters.push(registry.register_counter(&INFO[35usize])); + counters.push(registry.register_counter(&INFO[36usize])); + counters.push(registry.register_counter(&INFO[37usize])); + counters.push(registry.register_counter(&INFO[39usize])); + counters.push(registry.register_counter(&INFO[41usize])); + counters.push(registry.register_counter(&INFO[43usize])); + counters.push(registry.register_counter(&INFO[45usize])); + counters.push(registry.register_counter(&INFO[47usize])); + counters.push(registry.register_counter(&INFO[49usize])); + counters.push(registry.register_counter(&INFO[51usize])); + counters.push(registry.register_counter(&INFO[53usize])); + counters.push(registry.register_counter(&INFO[55usize])); + counters.push(registry.register_counter(&INFO[57usize])); + bool_counters.push(registry.register_bool_counter(&INFO[11usize])); + bool_counters.push(registry.register_bool_counter(&INFO[12usize])); + { + #[allow(unused_imports)] + use api::*; + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[9usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[10usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[19usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[21usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[23usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[25usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[27usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[29usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[31usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[33usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[35usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[40usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[42usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[44usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[46usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[48usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[50usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[52usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[54usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[56usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[58usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + } measures.push(registry.register_measure(&INFO[1usize])); measures.push(registry.register_measure(&INFO[3usize])); measures.push(registry.register_measure(&INFO[5usize])); measures.push(registry.register_measure(&INFO[7usize])); - measures.push(registry.register_measure(&INFO[10usize])); - measures.push(registry.register_measure(&INFO[12usize])); - measures.push(registry.register_measure(&INFO[13usize])); - measures.push(registry.register_measure(&INFO[25usize])); + measures.push(registry.register_measure(&INFO[14usize])); + measures.push(registry.register_measure(&INFO[16usize])); + measures.push(registry.register_measure(&INFO[17usize])); + measures.push(registry.register_measure(&INFO[38usize])); Self { counters: counters .try_into() .unwrap_or_else(|_| panic!("invalid len")), + bool_counters: bool_counters + .try_into() + .unwrap_or_else(|_| panic!("invalid len")), + nominal_counters: nominal_counters.into(), + nominal_offsets: nominal_offsets + .try_into() + .unwrap_or_else(|_| panic!("invalid len")), measures: measures .try_into() .unwrap_or_else(|_| panic!("invalid len")), @@ -321,39 +712,205 @@ impl Subscriber { 2usize => (&INFO[4usize], entry), 3usize => (&INFO[6usize], entry), 4usize => (&INFO[8usize], entry), - 5usize => (&INFO[9usize], entry), - 6usize => (&INFO[11usize], entry), - 7usize => (&INFO[14usize], entry), - 8usize => (&INFO[15usize], entry), - 9usize => (&INFO[16usize], entry), - 10usize => (&INFO[17usize], entry), - 11usize => (&INFO[18usize], entry), - 12usize => (&INFO[19usize], entry), - 13usize => (&INFO[20usize], entry), - 14usize => (&INFO[21usize], entry), - 15usize => (&INFO[22usize], entry), - 16usize => (&INFO[23usize], entry), - 17usize => (&INFO[24usize], entry), - 18usize => (&INFO[26usize], entry), - 19usize => (&INFO[27usize], entry), - 20usize => (&INFO[28usize], entry), - 21usize => (&INFO[29usize], entry), - 22usize => (&INFO[30usize], entry), - 23usize => (&INFO[31usize], entry), - 24usize => (&INFO[32usize], entry), - 25usize => (&INFO[33usize], entry), - 26usize => (&INFO[34usize], entry), - 27usize => (&INFO[35usize], entry), + 5usize => (&INFO[13usize], entry), + 6usize => (&INFO[15usize], entry), + 7usize => (&INFO[18usize], entry), + 8usize => (&INFO[20usize], entry), + 9usize => (&INFO[22usize], entry), + 10usize => (&INFO[24usize], entry), + 11usize => (&INFO[26usize], entry), + 12usize => (&INFO[28usize], entry), + 13usize => (&INFO[30usize], entry), + 14usize => (&INFO[32usize], entry), + 15usize => (&INFO[34usize], entry), + 16usize => (&INFO[36usize], entry), + 17usize => (&INFO[37usize], entry), + 18usize => (&INFO[39usize], entry), + 19usize => (&INFO[41usize], entry), + 20usize => (&INFO[43usize], entry), + 21usize => (&INFO[45usize], entry), + 22usize => (&INFO[47usize], entry), + 23usize => (&INFO[49usize], entry), + 24usize => (&INFO[51usize], entry), + 25usize => (&INFO[53usize], entry), + 26usize => (&INFO[55usize], entry), + 27usize => (&INFO[57usize], entry), _ => unsafe { core::hint::unreachable_unchecked() }, }) } #[allow(dead_code)] #[inline(always)] - fn count(&self, info: usize, id: usize, value: u64) { + fn count(&self, info: usize, id: usize, value: T) { let info = &INFO[info]; let counter = &self.counters[id]; counter.record(info, value); } + #[doc = r" Returns all of the registered bool counters"] + #[inline] + pub fn bool_counters(&self) -> impl Iterator + '_ { + self.bool_counters + .iter() + .enumerate() + .map(|(idx, entry)| match idx { + 0usize => (&INFO[11usize], entry), + 1usize => (&INFO[12usize], entry), + _ => unsafe { core::hint::unreachable_unchecked() }, + }) + } + #[allow(dead_code)] + #[inline(always)] + fn count_bool(&self, info: usize, id: usize, value: bool) { + let info = &INFO[info]; + let counter = &self.bool_counters[id]; + counter.record(info, value); + } + #[doc = r" Returns all of the registered nominal counters"] + #[inline] + pub fn nominal_counters( + &self, + ) -> impl Iterator + '_ { + use api::*; + self.nominal_offsets + .iter() + .enumerate() + .map(|(idx, entry)| match idx { + 0usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[9usize], entries, variants) + } + 1usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[10usize], entries, variants) + } + 2usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[19usize], entries, variants) + } + 3usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[21usize], entries, variants) + } + 4usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[23usize], entries, variants) + } + 5usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[25usize], entries, variants) + } + 6usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[27usize], entries, variants) + } + 7usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[29usize], entries, variants) + } + 8usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[31usize], entries, variants) + } + 9usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[33usize], entries, variants) + } + 10usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[35usize], entries, variants) + } + 11usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[40usize], entries, variants) + } + 12usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[42usize], entries, variants) + } + 13usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[44usize], entries, variants) + } + 14usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[46usize], entries, variants) + } + 15usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[48usize], entries, variants) + } + 16usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[50usize], entries, variants) + } + 17usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[52usize], entries, variants) + } + 18usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[54usize], entries, variants) + } + 19usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[56usize], entries, variants) + } + 20usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[58usize], entries, variants) + } + _ => unsafe { core::hint::unreachable_unchecked() }, + }) + } + #[allow(dead_code)] + #[inline(always)] + fn count_nominal(&self, info: usize, id: usize, value: &T) { + let info = &INFO[info]; + let idx = self.nominal_offsets[id] + value.variant_idx(); + let counter = &self.nominal_counters[idx]; + counter.record(info, value.as_variant(), 1usize); + } #[doc = r" Returns all of the registered measures"] #[inline] pub fn measures(&self) -> impl Iterator + '_ { @@ -365,16 +922,16 @@ impl Subscriber { 1usize => (&INFO[3usize], entry), 2usize => (&INFO[5usize], entry), 3usize => (&INFO[7usize], entry), - 4usize => (&INFO[10usize], entry), - 5usize => (&INFO[12usize], entry), - 6usize => (&INFO[13usize], entry), - 7usize => (&INFO[25usize], entry), + 4usize => (&INFO[14usize], entry), + 5usize => (&INFO[16usize], entry), + 6usize => (&INFO[17usize], entry), + 7usize => (&INFO[38usize], entry), _ => unsafe { core::hint::unreachable_unchecked() }, }) } #[allow(dead_code)] #[inline(always)] - fn measure(&self, info: usize, id: usize, value: u64) { + fn measure(&self, info: usize, id: usize, value: T) { let info = &INFO[info]; let measure = &self.measures[id]; measure.record(info, value); @@ -386,7 +943,7 @@ impl Subscriber { } #[allow(dead_code)] #[inline(always)] - fn gauge(&self, info: usize, id: usize, value: u64) { + fn gauge(&self, info: usize, id: usize, value: T) { let info = &INFO[info]; let gauge = &self.gauges[id]; gauge.record(info, value); @@ -398,7 +955,7 @@ impl Subscriber { } #[allow(dead_code)] #[inline(always)] - fn time(&self, info: usize, id: usize, value: u64) { + fn time(&self, info: usize, id: usize, value: core::time::Duration) { let info = &INFO[info]; let timer = &self.timers[id]; timer.record(info, value); @@ -419,10 +976,10 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::ApplicationWrite, ) { - self.count(0usize, 0usize, 1); - self.measure(1usize, 0usize, event.total_len.as_metric("b")); - self.count(2usize, 1usize, event.write_len.as_metric("b")); - self.measure(3usize, 1usize, event.write_len.as_metric("b")); + self.count(0usize, 0usize, 1usize); + self.measure(1usize, 0usize, event.total_len); + self.count(2usize, 1usize, event.write_len); + self.measure(3usize, 1usize, event.write_len); let _ = context; let _ = meta; let _ = event; @@ -434,17 +991,21 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::ApplicationRead, ) { - self.count(4usize, 2usize, 1); - self.measure(5usize, 2usize, event.capacity.as_metric("b")); - self.count(6usize, 3usize, event.read_len.as_metric("b")); - self.measure(7usize, 3usize, event.read_len.as_metric("b")); + self.count(4usize, 2usize, 1usize); + self.measure(5usize, 2usize, event.capacity); + self.count(6usize, 3usize, event.read_len); + self.measure(7usize, 3usize, event.read_len); let _ = context; let _ = meta; let _ = event; } #[inline] fn on_endpoint_initialized(&self, meta: &api::EndpointMeta, event: &api::EndpointInitialized) { - self.count(8usize, 4usize, 1); + self.count(8usize, 4usize, 1usize); + self.count_nominal(9usize, 0usize, &event.acceptor_addr); + self.count_nominal(10usize, 1usize, &event.handshake_addr); + self.count_bool(11usize, 0usize, event.tcp); + self.count_bool(12usize, 1usize, event.udp); let _ = event; let _ = meta; } @@ -454,8 +1015,8 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::PathSecretMapInitialized, ) { - self.count(9usize, 5usize, 1); - self.measure(10usize, 4usize, event.capacity.as_metric("")); + self.count(13usize, 5usize, 1usize); + self.measure(14usize, 4usize, event.capacity); let _ = event; let _ = meta; } @@ -465,9 +1026,9 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::PathSecretMapUninitialized, ) { - self.count(11usize, 6usize, 1); - self.measure(12usize, 5usize, event.capacity.as_metric("")); - self.measure(13usize, 6usize, event.entries.as_metric("")); + self.count(15usize, 6usize, 1usize); + self.measure(16usize, 5usize, event.capacity); + self.measure(17usize, 6usize, event.entries); let _ = event; let _ = meta; } @@ -477,7 +1038,8 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::PathSecretMapBackgroundHandshakeRequested, ) { - self.count(14usize, 7usize, 1); + self.count(18usize, 7usize, 1usize); + self.count_nominal(19usize, 2usize, &event.peer_address); let _ = event; let _ = meta; } @@ -487,7 +1049,8 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::PathSecretMapEntryInserted, ) { - self.count(15usize, 8usize, 1); + self.count(20usize, 8usize, 1usize); + self.count_nominal(21usize, 3usize, &event.peer_address); let _ = event; let _ = meta; } @@ -497,7 +1060,8 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::PathSecretMapEntryReady, ) { - self.count(16usize, 9usize, 1); + self.count(22usize, 9usize, 1usize); + self.count_nominal(23usize, 4usize, &event.peer_address); let _ = event; let _ = meta; } @@ -507,7 +1071,8 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::PathSecretMapEntryReplaced, ) { - self.count(17usize, 10usize, 1); + self.count(24usize, 10usize, 1usize); + self.count_nominal(25usize, 5usize, &event.peer_address); let _ = event; let _ = meta; } @@ -517,7 +1082,8 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::UnknownPathSecretPacketSent, ) { - self.count(18usize, 11usize, 1); + self.count(26usize, 11usize, 1usize); + self.count_nominal(27usize, 6usize, &event.peer_address); let _ = event; let _ = meta; } @@ -527,7 +1093,8 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::UnknownPathSecretPacketReceived, ) { - self.count(19usize, 12usize, 1); + self.count(28usize, 12usize, 1usize); + self.count_nominal(29usize, 7usize, &event.peer_address); let _ = event; let _ = meta; } @@ -537,7 +1104,8 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::UnknownPathSecretPacketAccepted, ) { - self.count(20usize, 13usize, 1); + self.count(30usize, 13usize, 1usize); + self.count_nominal(31usize, 8usize, &event.peer_address); let _ = event; let _ = meta; } @@ -547,7 +1115,8 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::UnknownPathSecretPacketRejected, ) { - self.count(21usize, 14usize, 1); + self.count(32usize, 14usize, 1usize); + self.count_nominal(33usize, 9usize, &event.peer_address); let _ = event; let _ = meta; } @@ -557,7 +1126,8 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::UnknownPathSecretPacketDropped, ) { - self.count(22usize, 15usize, 1); + self.count(34usize, 15usize, 1usize); + self.count_nominal(35usize, 10usize, &event.peer_address); let _ = event; let _ = meta; } @@ -567,7 +1137,7 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::ReplayDefinitelyDetected, ) { - self.count(23usize, 16usize, 1); + self.count(36usize, 16usize, 1usize); let _ = event; let _ = meta; } @@ -577,8 +1147,8 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::ReplayPotentiallyDetected, ) { - self.count(24usize, 17usize, 1); - self.measure(25usize, 7usize, event.gap.as_metric("")); + self.count(37usize, 17usize, 1usize); + self.measure(38usize, 7usize, event.gap); let _ = event; let _ = meta; } @@ -588,7 +1158,8 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::ReplayDetectedPacketSent, ) { - self.count(26usize, 18usize, 1); + self.count(39usize, 18usize, 1usize); + self.count_nominal(40usize, 11usize, &event.peer_address); let _ = event; let _ = meta; } @@ -598,7 +1169,8 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::ReplayDetectedPacketReceived, ) { - self.count(27usize, 19usize, 1); + self.count(41usize, 19usize, 1usize); + self.count_nominal(42usize, 12usize, &event.peer_address); let _ = event; let _ = meta; } @@ -608,7 +1180,8 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::ReplayDetectedPacketAccepted, ) { - self.count(28usize, 20usize, 1); + self.count(43usize, 20usize, 1usize); + self.count_nominal(44usize, 13usize, &event.peer_address); let _ = event; let _ = meta; } @@ -618,7 +1191,8 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::ReplayDetectedPacketRejected, ) { - self.count(29usize, 21usize, 1); + self.count(45usize, 21usize, 1usize); + self.count_nominal(46usize, 14usize, &event.peer_address); let _ = event; let _ = meta; } @@ -628,13 +1202,15 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::ReplayDetectedPacketDropped, ) { - self.count(30usize, 22usize, 1); + self.count(47usize, 22usize, 1usize); + self.count_nominal(48usize, 15usize, &event.peer_address); let _ = event; let _ = meta; } #[inline] fn on_stale_key_packet_sent(&self, meta: &api::EndpointMeta, event: &api::StaleKeyPacketSent) { - self.count(31usize, 23usize, 1); + self.count(49usize, 23usize, 1usize); + self.count_nominal(50usize, 16usize, &event.peer_address); let _ = event; let _ = meta; } @@ -644,7 +1220,8 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::StaleKeyPacketReceived, ) { - self.count(32usize, 24usize, 1); + self.count(51usize, 24usize, 1usize); + self.count_nominal(52usize, 17usize, &event.peer_address); let _ = event; let _ = meta; } @@ -654,7 +1231,8 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::StaleKeyPacketAccepted, ) { - self.count(33usize, 25usize, 1); + self.count(53usize, 25usize, 1usize); + self.count_nominal(54usize, 18usize, &event.peer_address); let _ = event; let _ = meta; } @@ -664,7 +1242,8 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::StaleKeyPacketRejected, ) { - self.count(34usize, 26usize, 1); + self.count(55usize, 26usize, 1usize); + self.count_nominal(56usize, 19usize, &event.peer_address); let _ = event; let _ = meta; } @@ -674,7 +1253,8 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::StaleKeyPacketDropped, ) { - self.count(35usize, 27usize, 1); + self.count(57usize, 27usize, 1usize); + self.count_nominal(58usize, 20usize, &event.peer_address); let _ = event; let _ = meta; } diff --git a/dc/s2n-quic-dc/src/event/generated/metrics/probe.rs b/dc/s2n-quic-dc/src/event/generated/metrics/probe.rs index 22bad27687..1e861382e5 100644 --- a/dc/s2n-quic-dc/src/event/generated/metrics/probe.rs +++ b/dc/s2n-quic-dc/src/event/generated/metrics/probe.rs @@ -5,53 +5,56 @@ // This file was generated with the `s2n-quic-events` crate and any required // changes should be made there. -use crate::event::metrics::aggregate::{self, Info, Recorder}; +use crate::event::metrics::aggregate::{ + self, info, BoolRecorder, Info, NominalRecorder, Recorder as MetricRecorder, +}; use s2n_quic_core::probe::define; mod counter { #![allow(non_snake_case)] - use super::Info; + use super::*; + use crate::event::metrics::aggregate::Metric; pub struct Recorder(fn(u64)); impl Recorder { - pub(super) fn new(info: &'static Info) -> Self { + pub(crate) fn new(info: &'static Info) -> Self { match info.id { 0usize => Self(application_write), 2usize => Self(application_write__committed__total), 4usize => Self(application_read), 6usize => Self(application_read__committed__total), 8usize => Self(endpoint_initialized), - 9usize => Self(path_secret_map_initialized), - 11usize => Self(path_secret_map_uninitialized), - 14usize => Self(path_secret_map_background_handshake_requested), - 15usize => Self(path_secret_map_entry_inserted), - 16usize => Self(path_secret_map_entry_ready), - 17usize => Self(path_secret_map_entry_replaced), - 18usize => Self(unknown_path_secret_packet_sent), - 19usize => Self(unknown_path_secret_packet_received), - 20usize => Self(unknown_path_secret_packet_accepted), - 21usize => Self(unknown_path_secret_packet_rejected), - 22usize => Self(unknown_path_secret_packet_dropped), - 23usize => Self(replay_definitely_detected), - 24usize => Self(replay_potentially_detected), - 26usize => Self(replay_detected_packet_sent), - 27usize => Self(replay_detected_packet_received), - 28usize => Self(replay_detected_packet_accepted), - 29usize => Self(replay_detected_packet_rejected), - 30usize => Self(replay_detected_packet_dropped), - 31usize => Self(stale_key_packet_sent), - 32usize => Self(stale_key_packet_received), - 33usize => Self(stale_key_packet_accepted), - 34usize => Self(stale_key_packet_rejected), - 35usize => Self(stale_key_packet_dropped), + 13usize => Self(path_secret_map_initialized), + 15usize => Self(path_secret_map_uninitialized), + 18usize => Self(path_secret_map_background_handshake_requested), + 20usize => Self(path_secret_map_entry_inserted), + 22usize => Self(path_secret_map_entry_ready), + 24usize => Self(path_secret_map_entry_replaced), + 26usize => Self(unknown_path_secret_packet_sent), + 28usize => Self(unknown_path_secret_packet_received), + 30usize => Self(unknown_path_secret_packet_accepted), + 32usize => Self(unknown_path_secret_packet_rejected), + 34usize => Self(unknown_path_secret_packet_dropped), + 36usize => Self(replay_definitely_detected), + 37usize => Self(replay_potentially_detected), + 39usize => Self(replay_detected_packet_sent), + 41usize => Self(replay_detected_packet_received), + 43usize => Self(replay_detected_packet_accepted), + 45usize => Self(replay_detected_packet_rejected), + 47usize => Self(replay_detected_packet_dropped), + 49usize => Self(stale_key_packet_sent), + 51usize => Self(stale_key_packet_received), + 53usize => Self(stale_key_packet_accepted), + 55usize => Self(stale_key_packet_rejected), + 57usize => Self(stale_key_packet_dropped), _ => unreachable!("invalid info: {info:?}"), } } } - impl super::Recorder for Recorder { - fn record(&self, _info: &'static Info, value: u64) { - (self.0)(value); + impl MetricRecorder for Recorder { + fn record(&self, _info: &'static Info, value: T) { + (self.0)(value.as_u64()); } } - super::define!( + define!( extern "probe" { # [link_name = s2n_quic_dc__event__counter__application_write] fn application_write(value: u64); @@ -111,32 +114,236 @@ mod counter { fn stale_key_packet_dropped(value: u64); } ); + pub mod bool { + #![allow(non_snake_case)] + use super::*; + pub struct Recorder(fn(bool)); + impl Recorder { + pub(crate) fn new(info: &'static Info) -> Self { + match info.id { + 11usize => Self(endpoint_initialized__tcp), + 12usize => Self(endpoint_initialized__udp), + _ => unreachable!("invalid info: {info:?}"), + } + } + } + impl BoolRecorder for Recorder { + fn record(&self, _info: &'static Info, value: bool) { + (self.0)(value); + } + } + define!( + extern "probe" { + # [link_name = s2n_quic_dc__event__counter__bool__endpoint_initialized__tcp] + fn endpoint_initialized__tcp(value: bool); + # [link_name = s2n_quic_dc__event__counter__bool__endpoint_initialized__udp] + fn endpoint_initialized__udp(value: bool); + } + ); + } + pub mod nominal { + #![allow(non_snake_case)] + use super::*; + use crate::event::metrics::aggregate::Metric; + pub struct Recorder(fn(u64, u64, &info::Str)); + impl Recorder { + pub(crate) fn new(info: &'static Info, _variant: &'static info::Variant) -> Self { + match info.id { + 9usize => Self(endpoint_initialized__acceptor__protocol), + 10usize => Self(endpoint_initialized__handshake__protocol), + 19usize => { + Self(path_secret_map_background_handshake_requested__peer_address__protocol) + } + 21usize => Self(path_secret_map_entry_inserted__peer_address__protocol), + 23usize => Self(path_secret_map_entry_ready__peer_address__protocol), + 25usize => Self(path_secret_map_entry_replaced__peer_address__protocol), + 27usize => Self(unknown_path_secret_packet_sent__peer_address__protocol), + 29usize => Self(unknown_path_secret_packet_received__peer_address__protocol), + 31usize => Self(unknown_path_secret_packet_accepted__peer_address__protocol), + 33usize => Self(unknown_path_secret_packet_rejected__peer_address__protocol), + 35usize => Self(unknown_path_secret_packet_dropped__peer_address__protocol), + 40usize => Self(replay_detected_packet_sent__peer_address__protocol), + 42usize => Self(replay_detected_packet_received__peer_address__protocol), + 44usize => Self(replay_detected_packet_accepted__peer_address__protocol), + 46usize => Self(replay_detected_packet_rejected__peer_address__protocol), + 48usize => Self(replay_detected_packet_dropped__peer_address__protocol), + 50usize => Self(stale_key_packet_sent__peer_address__protocol), + 52usize => Self(stale_key_packet_received__peer_address__protocol), + 54usize => Self(stale_key_packet_accepted__peer_address__protocol), + 56usize => Self(stale_key_packet_rejected__peer_address__protocol), + 58usize => Self(stale_key_packet_dropped__peer_address__protocol), + _ => unreachable!("invalid info: {info:?}"), + } + } + } + impl NominalRecorder for Recorder { + fn record( + &self, + _info: &'static Info, + variant: &'static info::Variant, + value: T, + ) { + (self.0)(value.as_u64(), variant.id as _, variant.name); + } + } + define!( + extern "probe" { + # [link_name = s2n_quic_dc__event__counter__nominal__endpoint_initialized__acceptor__protocol] + fn endpoint_initialized__acceptor__protocol( + value: u64, + variant: u64, + variant_name: &info::Str, + ); + # [link_name = s2n_quic_dc__event__counter__nominal__endpoint_initialized__handshake__protocol] + fn endpoint_initialized__handshake__protocol( + value: u64, + variant: u64, + variant_name: &info::Str, + ); + # [link_name = s2n_quic_dc__event__counter__nominal__path_secret_map_background_handshake_requested__peer_address__protocol] + fn path_secret_map_background_handshake_requested__peer_address__protocol( + value: u64, + variant: u64, + variant_name: &info::Str, + ); + # [link_name = s2n_quic_dc__event__counter__nominal__path_secret_map_entry_inserted__peer_address__protocol] + fn path_secret_map_entry_inserted__peer_address__protocol( + value: u64, + variant: u64, + variant_name: &info::Str, + ); + # [link_name = s2n_quic_dc__event__counter__nominal__path_secret_map_entry_ready__peer_address__protocol] + fn path_secret_map_entry_ready__peer_address__protocol( + value: u64, + variant: u64, + variant_name: &info::Str, + ); + # [link_name = s2n_quic_dc__event__counter__nominal__path_secret_map_entry_replaced__peer_address__protocol] + fn path_secret_map_entry_replaced__peer_address__protocol( + value: u64, + variant: u64, + variant_name: &info::Str, + ); + # [link_name = s2n_quic_dc__event__counter__nominal__unknown_path_secret_packet_sent__peer_address__protocol] + fn unknown_path_secret_packet_sent__peer_address__protocol( + value: u64, + variant: u64, + variant_name: &info::Str, + ); + # [link_name = s2n_quic_dc__event__counter__nominal__unknown_path_secret_packet_received__peer_address__protocol] + fn unknown_path_secret_packet_received__peer_address__protocol( + value: u64, + variant: u64, + variant_name: &info::Str, + ); + # [link_name = s2n_quic_dc__event__counter__nominal__unknown_path_secret_packet_accepted__peer_address__protocol] + fn unknown_path_secret_packet_accepted__peer_address__protocol( + value: u64, + variant: u64, + variant_name: &info::Str, + ); + # [link_name = s2n_quic_dc__event__counter__nominal__unknown_path_secret_packet_rejected__peer_address__protocol] + fn unknown_path_secret_packet_rejected__peer_address__protocol( + value: u64, + variant: u64, + variant_name: &info::Str, + ); + # [link_name = s2n_quic_dc__event__counter__nominal__unknown_path_secret_packet_dropped__peer_address__protocol] + fn unknown_path_secret_packet_dropped__peer_address__protocol( + value: u64, + variant: u64, + variant_name: &info::Str, + ); + # [link_name = s2n_quic_dc__event__counter__nominal__replay_detected_packet_sent__peer_address__protocol] + fn replay_detected_packet_sent__peer_address__protocol( + value: u64, + variant: u64, + variant_name: &info::Str, + ); + # [link_name = s2n_quic_dc__event__counter__nominal__replay_detected_packet_received__peer_address__protocol] + fn replay_detected_packet_received__peer_address__protocol( + value: u64, + variant: u64, + variant_name: &info::Str, + ); + # [link_name = s2n_quic_dc__event__counter__nominal__replay_detected_packet_accepted__peer_address__protocol] + fn replay_detected_packet_accepted__peer_address__protocol( + value: u64, + variant: u64, + variant_name: &info::Str, + ); + # [link_name = s2n_quic_dc__event__counter__nominal__replay_detected_packet_rejected__peer_address__protocol] + fn replay_detected_packet_rejected__peer_address__protocol( + value: u64, + variant: u64, + variant_name: &info::Str, + ); + # [link_name = s2n_quic_dc__event__counter__nominal__replay_detected_packet_dropped__peer_address__protocol] + fn replay_detected_packet_dropped__peer_address__protocol( + value: u64, + variant: u64, + variant_name: &info::Str, + ); + # [link_name = s2n_quic_dc__event__counter__nominal__stale_key_packet_sent__peer_address__protocol] + fn stale_key_packet_sent__peer_address__protocol( + value: u64, + variant: u64, + variant_name: &info::Str, + ); + # [link_name = s2n_quic_dc__event__counter__nominal__stale_key_packet_received__peer_address__protocol] + fn stale_key_packet_received__peer_address__protocol( + value: u64, + variant: u64, + variant_name: &info::Str, + ); + # [link_name = s2n_quic_dc__event__counter__nominal__stale_key_packet_accepted__peer_address__protocol] + fn stale_key_packet_accepted__peer_address__protocol( + value: u64, + variant: u64, + variant_name: &info::Str, + ); + # [link_name = s2n_quic_dc__event__counter__nominal__stale_key_packet_rejected__peer_address__protocol] + fn stale_key_packet_rejected__peer_address__protocol( + value: u64, + variant: u64, + variant_name: &info::Str, + ); + # [link_name = s2n_quic_dc__event__counter__nominal__stale_key_packet_dropped__peer_address__protocol] + fn stale_key_packet_dropped__peer_address__protocol( + value: u64, + variant: u64, + variant_name: &info::Str, + ); + } + ); + } } mod measure { #![allow(non_snake_case)] - use super::Info; + use super::*; + use crate::event::metrics::aggregate::Metric; pub struct Recorder(fn(u64)); impl Recorder { - pub(super) fn new(info: &'static Info) -> Self { + pub(crate) fn new(info: &'static Info) -> Self { match info.id { 1usize => Self(application_write__provided), 3usize => Self(application_write__committed), 5usize => Self(application_read__capacity), 7usize => Self(application_read__committed), - 10usize => Self(path_secret_map_initialized__capacity), - 12usize => Self(path_secret_map_uninitialized__capacity), - 13usize => Self(path_secret_map_uninitialized__entries), - 25usize => Self(replay_potentially_detected__gap), + 14usize => Self(path_secret_map_initialized__capacity), + 16usize => Self(path_secret_map_uninitialized__capacity), + 17usize => Self(path_secret_map_uninitialized__entries), + 38usize => Self(replay_potentially_detected__gap), _ => unreachable!("invalid info: {info:?}"), } } } - impl super::Recorder for Recorder { - fn record(&self, _info: &'static Info, value: u64) { - (self.0)(value); + impl MetricRecorder for Recorder { + fn record(&self, _info: &'static Info, value: T) { + (self.0)(value.as_u64()); } } - super::define!( + define!( extern "probe" { # [link_name = s2n_quic_dc__event__measure__application_write__provided] fn application_write__provided(value: u64); @@ -159,31 +366,33 @@ mod measure { } mod gauge { #![allow(non_snake_case)] - use super::Info; + use super::*; + use crate::event::metrics::aggregate::Metric; pub struct Recorder(fn(u64)); impl Recorder { - pub(super) fn new(info: &'static Info) -> Self { + pub(crate) fn new(info: &'static Info) -> Self { unreachable!("invalid info: {info:?}") } } - impl super::Recorder for Recorder { - fn record(&self, _info: &'static Info, value: u64) { - (self.0)(value); + impl MetricRecorder for Recorder { + fn record(&self, _info: &'static Info, value: T) { + (self.0)(value.as_u64()); } } } mod timer { #![allow(non_snake_case)] - use super::Info; - pub struct Recorder(fn(u64)); + use super::*; + use crate::event::metrics::aggregate::Metric; + pub struct Recorder(fn(core::time::Duration)); impl Recorder { - pub(super) fn new(info: &'static Info) -> Self { + pub(crate) fn new(info: &'static Info) -> Self { unreachable!("invalid info: {info:?}") } } - impl super::Recorder for Recorder { - fn record(&self, _info: &'static Info, value: u64) { - (self.0)(value); + impl MetricRecorder for Recorder { + fn record(&self, _info: &'static Info, value: T) { + (self.0)(value.as_duration()); } } } @@ -191,6 +400,8 @@ mod timer { pub struct Registry(()); impl aggregate::Registry for Registry { type Counter = counter::Recorder; + type BoolCounter = counter::bool::Recorder; + type NominalCounter = counter::nominal::Recorder; type Measure = measure::Recorder; type Gauge = gauge::Recorder; type Timer = timer::Recorder; @@ -199,6 +410,18 @@ impl aggregate::Registry for Registry { counter::Recorder::new(info) } #[inline] + fn register_bool_counter(&self, info: &'static Info) -> Self::BoolCounter { + counter::bool::Recorder::new(info) + } + #[inline] + fn register_nominal_counter( + &self, + info: &'static Info, + variant: &'static info::Variant, + ) -> Self::NominalCounter { + counter::nominal::Recorder::new(info, variant) + } + #[inline] fn register_measure(&self, info: &'static Info) -> Self::Measure { measure::Recorder::new(info) } diff --git a/quic/s2n-quic-core/events/connection.rs b/quic/s2n-quic-core/events/connection.rs index 6c0c525e1c..6ab5dc5970 100644 --- a/quic/s2n-quic-core/events/connection.rs +++ b/quic/s2n-quic-core/events/connection.rs @@ -29,8 +29,8 @@ struct PacketSkipped { /// Packet was sent by a connection struct PacketSent { packet_header: PacketHeader, - #[measure("bytes", "b")] - #[counter("bytes.total", "b")] + #[measure("bytes", Bytes)] + #[counter("bytes.total", Bytes)] packet_len: usize, } @@ -67,6 +67,7 @@ struct PathCreated<'a> { struct FrameSent { packet_header: PacketHeader, path_id: u64, + #[nominal_counter("frame")] frame: Frame, } @@ -78,6 +79,7 @@ struct FrameSent { struct FrameReceived<'a> { packet_header: PacketHeader, path: Path<'a>, + #[nominal_counter("frame")] frame: Frame, } @@ -87,9 +89,10 @@ struct FrameReceived<'a> { struct PacketLost<'a> { packet_header: PacketHeader, path: Path<'a>, - #[measure("bytes", "b")] - #[counter("bytes.total", "b")] + #[measure("bytes", Bytes)] + #[counter("bytes.total", Bytes)] bytes_lost: u16, + #[bool_counter("is_mtu_probe")] is_mtu_probe: bool, } @@ -98,23 +101,23 @@ struct PacketLost<'a> { /// Recovery metrics updated struct RecoveryMetrics<'a> { path: Path<'a>, - #[measure("min_rtt", "us")] + #[measure("min_rtt", Duration)] min_rtt: Duration, - #[measure("smoothed_rtt", "us")] + #[measure("smoothed_rtt", Duration)] smoothed_rtt: Duration, - #[measure("latest_rtt", "us")] + #[measure("latest_rtt", Duration)] latest_rtt: Duration, - #[measure("rtt_variance", "us")] + #[measure("rtt_variance", Duration)] rtt_variance: Duration, - #[measure("max_ack_delay", "us")] + #[measure("max_ack_delay", Duration)] max_ack_delay: Duration, #[measure("pto_count")] pto_count: u32, - #[measure("congestion_window", "b")] + #[measure("congestion_window", Duration)] congestion_window: u32, - #[measure("bytes_in_flight", "b")] + #[measure("bytes_in_flight", Duration)] bytes_in_flight: u32, - // TODO add support for counting bools + #[bool_counter("congestion_limited")] congestion_limited: bool, } @@ -122,6 +125,7 @@ struct RecoveryMetrics<'a> { /// Congestion (ECN or packet loss) has occurred struct Congestion<'a> { path: Path<'a>, + #[nominal_counter("source")] source: CongestionSource, } @@ -129,6 +133,7 @@ struct Congestion<'a> { #[deprecated(note = "use on_rx_ack_range_dropped event instead")] /// Events related to ACK processing struct AckProcessed<'a> { + #[nominal_counter("action")] action: AckAction, path: Path<'a>, } @@ -171,6 +176,7 @@ struct AckRangeSent { #[event("transport:packet_dropped")] /// Packet was dropped with the given reason struct PacketDropped<'a> { + #[nominal_counter("reason")] reason: PacketDropReason<'a>, } @@ -184,6 +190,7 @@ struct KeyUpdate { #[event("security:key_space_discarded")] struct KeySpaceDiscarded { + #[nominal_counter("space")] space: KeySpace, } @@ -198,6 +205,7 @@ struct ConnectionStarted<'a> { //= https://tools.ietf.org/id/draft-marx-qlog-event-definitions-quic-h3-02#5.1.3 /// Connection closed struct ConnectionClosed { + #[nominal_counter("error")] error: crate::connection::Error, } @@ -206,6 +214,7 @@ struct ConnectionClosed { struct DuplicatePacket<'a> { packet_header: PacketHeader, path: Path<'a>, + #[nominal_counter("error")] error: DuplicatePacketError, } @@ -219,8 +228,8 @@ struct TransportParametersReceived<'a> { //= https://tools.ietf.org/id/draft-marx-qlog-event-definitions-quic-h3-02#5.3.10 /// Datagram sent by a connection struct DatagramSent { - #[measure("bytes", "b")] - #[counter("bytes.total", "b")] + #[measure("bytes", Bytes)] + #[counter("bytes.total", Bytes)] len: u16, /// The GSO offset at which this datagram was written @@ -237,8 +246,8 @@ struct DatagramSent { //= https://tools.ietf.org/id/draft-marx-qlog-event-definitions-quic-h3-02#5.3.11 /// Datagram received by a connection struct DatagramReceived { - #[measure("bytes", "b")] - #[counter("bytes.total", "b")] + #[measure("bytes", Bytes)] + #[counter("bytes.total", Bytes)] len: u16, } @@ -246,10 +255,10 @@ struct DatagramReceived { //= https://tools.ietf.org/id/draft-marx-qlog-event-definitions-quic-h3-02#5.3.12 /// Datagram dropped by a connection struct DatagramDropped { - #[measure("bytes", "b")] - #[counter("bytes.total", "b")] + #[measure("bytes", Bytes)] + #[counter("bytes.total", Bytes)] len: u16, - // TODO support nominal counters + #[nominal_counter("reason")] reason: DatagramDropReason, } @@ -267,16 +276,19 @@ struct ConnectionIdUpdated<'a> { #[event("recovery:ecn_state_changed")] struct EcnStateChanged<'a> { path: Path<'a>, + #[nominal_counter("state")] state: EcnState, } #[event("connectivity:connection_migration_denied")] struct ConnectionMigrationDenied { + #[nominal_counter("reason")] reason: MigrationDenyReason, } #[event("connectivity:handshake_status_updated")] struct HandshakeStatusUpdated { + #[nominal_counter("status")] status: HandshakeStatus, } @@ -305,15 +317,15 @@ struct TlsServerHello<'a> { #[event("transport:rx_stream_progress")] struct RxStreamProgress { - #[measure("bytes", "b")] - #[counter("bytes.total", "b")] + #[measure("bytes", Bytes)] + #[counter("bytes.total", Bytes)] bytes: usize, } #[event("transport:tx_stream_progress")] struct TxStreamProgress { - #[measure("bytes", "b")] - #[counter("bytes.total", "b")] + #[measure("bytes", Bytes)] + #[counter("bytes.total", Bytes)] bytes: usize, } @@ -327,10 +339,12 @@ pub struct KeepAliveTimerExpired { struct MtuUpdated { path_id: u64, /// The maximum QUIC datagram size, not including UDP and IP headers - #[measure("mtu", "b")] + #[measure("mtu", Bytes)] mtu: u16, + #[nominal_counter("cause")] cause: MtuUpdatedCause, /// The search for the maximum MTU has completed for now + #[bool_counter("search_complete")] search_complete: bool, } @@ -338,8 +352,9 @@ struct MtuUpdated { /// The slow start congestion controller state has been exited struct SlowStartExited { path_id: u64, + #[nominal_counter("cause")] cause: SlowStartExitCause, - #[measure("congestion_window", "b")] + #[measure("congestion_window", Bytes)] congestion_window: u32, } @@ -356,10 +371,11 @@ struct DeliveryRateSampled { /// The pacing rate has been updated struct PacingRateUpdated { path_id: u64, - #[measure("bytes_per_second", "b")] + #[measure("bytes_per_second", Bytes)] bytes_per_second: u64, - #[measure("burst_size", "b")] + #[measure("burst_size", Bytes)] burst_size: u32, + #[measure("pacing_gain")] pacing_gain: f32, } @@ -367,11 +383,13 @@ struct PacingRateUpdated { /// The BBR state has changed struct BbrStateChanged { path_id: u64, + #[nominal_counter("state")] state: BbrState, } #[event("transport:dc_state_changed")] /// The DC state has changed struct DcStateChanged { + #[nominal_counter("state")] state: DcState, } diff --git a/quic/s2n-quic-core/events/endpoint.rs b/quic/s2n-quic-core/events/endpoint.rs index 5714452907..db9d83e141 100644 --- a/quic/s2n-quic-core/events/endpoint.rs +++ b/quic/s2n-quic-core/events/endpoint.rs @@ -34,8 +34,8 @@ struct EndpointPacketReceived { //= https://tools.ietf.org/id/draft-marx-qlog-event-definitions-quic-h3-02#5.3.10 /// Datagram sent by the endpoint struct EndpointDatagramSent { - #[measure("bytes", "b")] - #[measure("bytes.total", "b")] + #[measure("bytes", Bytes)] + #[measure("bytes.total", Bytes)] len: u16, /// The GSO offset at which this datagram was written /// @@ -52,8 +52,8 @@ struct EndpointDatagramSent { //= https://tools.ietf.org/id/draft-marx-qlog-event-definitions-quic-h3-02#5.3.11 /// Datagram received by the endpoint struct EndpointDatagramReceived { - #[measure("bytes", "b")] - #[measure("bytes.total", "b")] + #[measure("bytes", Bytes)] + #[measure("bytes.total", Bytes)] len: u16, } @@ -62,14 +62,16 @@ struct EndpointDatagramReceived { //= https://tools.ietf.org/id/draft-marx-qlog-event-definitions-quic-h3-02#5.3.12 /// Datagram dropped by the endpoint struct EndpointDatagramDropped { - #[measure("bytes", "b")] - #[measure("bytes.total", "b")] + #[measure("bytes", Bytes)] + #[measure("bytes.total", Bytes)] len: u16, + #[nominal_counter("reason")] reason: DatagramDropReason, } #[event("transport:connection_attempt_failed")] #[subject(endpoint)] struct EndpointConnectionAttemptFailed { + #[nominal_counter("error")] error: crate::connection::Error, } diff --git a/quic/s2n-quic-core/src/connection/error.rs b/quic/s2n-quic-core/src/connection/error.rs index b74d8c937f..40f2f18461 100644 --- a/quic/s2n-quic-core/src/connection/error.rs +++ b/quic/s2n-quic-core/src/connection/error.rs @@ -580,3 +580,108 @@ impl From for ProcessingError { Self::DecryptError } } + +mod metrics { + use super::{transport, Error}; + use crate::event::metrics::aggregate::{ + info::{Str, Variant}, + AsVariant, + }; + + macro_rules! impl_variants { + ($($name:ident => $name_str:literal),* $(,)?) => { + impl AsVariant for Error { + const VARIANTS: &'static [Variant] = &{ + const fn count(_id: &str) -> usize { + 1 + } + + const VARIANTS: usize = 0 $( + count($name_str))*; + + const TRANSPORT: &'static [Variant] = transport::error::Code::VARIANTS; + + let mut array = [ + Variant { name: Str::new("\0"), id: 0 }; + VARIANTS + TRANSPORT.len() + ]; + + let mut id = 0; + + $( + array[id] = Variant { + name: Str::new(concat!($name_str, "\0")), + id, + }; + id += 1; + )* + + let mut transport_idx = 0; + while transport_idx < TRANSPORT.len() { + let variant = TRANSPORT[transport_idx]; + array[id] = Variant { + name: variant.name, + id, + }; + id += 1; + transport_idx += 1; + } + + array + }; + + #[inline] + fn variant_idx(&self) -> usize { + let mut idx = 0; + + $( + if matches!(self, Error::$name { .. }) { + return idx; + } + idx += 1; + )* + + if let Error::Transport { code, ..} = self { + code.variant_idx() + idx + } else { + panic!() + } + } + } + + #[allow(dead_code)] + fn exhaustive_test(error: &Error) { + match error { + $( + Error::$name { .. } => {}, + )* + Error::Transport { .. } => {}, + } + } + + #[test] + #[cfg_attr(miri, ignore)] + fn variants_test() { + insta::assert_debug_snapshot!(Error::VARIANTS); + + let mut seen = std::collections::HashSet::new(); + for variant in Error::VARIANTS { + assert!(seen.insert(variant.id)); + } + } + }; + } + + impl_variants!( + Closed => "CLOSED", + Application => "APPLICATION", + StatelessReset => "STATELESS_RESET", + IdleTimerExpired => "IDLE_TIMER_EXPIRED", + NoValidPath => "NO_VALID_PATH", + StreamIdExhausted => "STREAM_ID_EXHAUSTED", + MaxHandshakeDurationExceeded => "MAX_HANDSHAKE_DURATION_EXCEEDED", + ImmediateClose => "IMMEDIATE_CLOSE", + EndpointClosing => "ENDPOINT_CLOSING", + InvalidConfiguration => "INVALID_CONFIGURATION", + Unspecified => "UNSPECIFIED", + ); +} diff --git a/quic/s2n-quic-core/src/connection/snapshots/s2n_quic_core__connection__error__metrics__variants_test.snap b/quic/s2n-quic-core/src/connection/snapshots/s2n_quic_core__connection__error__metrics__variants_test.snap new file mode 100644 index 0000000000..aff70a390d --- /dev/null +++ b/quic/s2n-quic-core/src/connection/snapshots/s2n_quic_core__connection__error__metrics__variants_test.snap @@ -0,0 +1,258 @@ +--- +source: quic/s2n-quic-core/src/connection/error.rs +expression: "Error::VARIANTS" +--- +[ + Variant { + id: 0, + name: "CLOSED", + }, + Variant { + id: 1, + name: "APPLICATION", + }, + Variant { + id: 2, + name: "STATELESS_RESET", + }, + Variant { + id: 3, + name: "IDLE_TIMER_EXPIRED", + }, + Variant { + id: 4, + name: "NO_VALID_PATH", + }, + Variant { + id: 5, + name: "STREAM_ID_EXHAUSTED", + }, + Variant { + id: 6, + name: "MAX_HANDSHAKE_DURATION_EXCEEDED", + }, + Variant { + id: 7, + name: "IMMEDIATE_CLOSE", + }, + Variant { + id: 8, + name: "ENDPOINT_CLOSING", + }, + Variant { + id: 9, + name: "INVALID_CONFIGURATION", + }, + Variant { + id: 10, + name: "UNSPECIFIED", + }, + Variant { + id: 11, + name: "QUIC_NO_ERROR", + }, + Variant { + id: 12, + name: "QUIC_INTERNAL_ERROR", + }, + Variant { + id: 13, + name: "QUIC_CONNECTION_REFUSED", + }, + Variant { + id: 14, + name: "QUIC_FLOW_CONTROL_ERROR", + }, + Variant { + id: 15, + name: "QUIC_STREAM_LIMIT_ERROR", + }, + Variant { + id: 16, + name: "QUIC_STREAM_STATE_ERROR", + }, + Variant { + id: 17, + name: "QUIC_FINAL_SIZE_ERROR", + }, + Variant { + id: 18, + name: "QUIC_FRAME_ENCODING_ERROR", + }, + Variant { + id: 19, + name: "QUIC_TRANSPORT_PARAMETER_ERROR", + }, + Variant { + id: 20, + name: "QUIC_CONNECTION_ID_LIMIT_ERROR", + }, + Variant { + id: 21, + name: "QUIC_PROTOCOL_VIOLATION", + }, + Variant { + id: 22, + name: "QUIC_INVALID_TOKEN", + }, + Variant { + id: 23, + name: "QUIC_APPLICATION_ERROR", + }, + Variant { + id: 24, + name: "QUIC_CRYPTO_BUFFER_EXCEEDED", + }, + Variant { + id: 25, + name: "QUIC_KEY_UPDATE_ERROR", + }, + Variant { + id: 26, + name: "QUIC_AEAD_LIMIT_REACHED", + }, + Variant { + id: 27, + name: "TLS_CLOSE_NOTIFY", + }, + Variant { + id: 28, + name: "TLS_UNEXPECTED_MESSAGE", + }, + Variant { + id: 29, + name: "TLS_BAD_RECORD_MAC", + }, + Variant { + id: 30, + name: "TLS_DECRYPTION_FAILED_RESERVED", + }, + Variant { + id: 31, + name: "TLS_RECORD_OVERFLOW", + }, + Variant { + id: 32, + name: "TLS_DECOMPRESSION_FAILURE_RESERVED", + }, + Variant { + id: 33, + name: "TLS_HANDSHAKE_FAILURE", + }, + Variant { + id: 34, + name: "TLS_NO_CERTIFICATE_RESERVED", + }, + Variant { + id: 35, + name: "TLS_BAD_CERTIFICATE", + }, + Variant { + id: 36, + name: "TLS_UNSUPPORTED_CERTIFICATE", + }, + Variant { + id: 37, + name: "TLS_CERTIFICATE_REVOKED", + }, + Variant { + id: 38, + name: "TLS_CERTIFICATE_EXPIRED", + }, + Variant { + id: 39, + name: "TLS_CERTIFICATE_UNKNOWN", + }, + Variant { + id: 40, + name: "TLS_ILLEGAL_PARAMETER", + }, + Variant { + id: 41, + name: "TLS_UNKNOWN_CA", + }, + Variant { + id: 42, + name: "TLS_ACCESS_DENIED", + }, + Variant { + id: 43, + name: "TLS_DECODE_ERROR", + }, + Variant { + id: 44, + name: "TLS_DECRYPT_ERROR", + }, + Variant { + id: 45, + name: "TLS_EXPORT_RESTRICTION_RESERVED", + }, + Variant { + id: 46, + name: "TLS_PROTOCOL_VERSION", + }, + Variant { + id: 47, + name: "TLS_INSUFFICIENT_SECURITY", + }, + Variant { + id: 48, + name: "TLS_INTERNAL_ERROR", + }, + Variant { + id: 49, + name: "TLS_INAPPROPRIATE_FALLBACK", + }, + Variant { + id: 50, + name: "TLS_USER_CANCELED", + }, + Variant { + id: 51, + name: "TLS_NO_RENEGOTIATION_RESERVED", + }, + Variant { + id: 52, + name: "TLS_MISSING_EXTENSION", + }, + Variant { + id: 53, + name: "TLS_UNSUPPORTED_EXTENSION", + }, + Variant { + id: 54, + name: "TLS_CERTIFICATE_UNOBTAINABLE_RESERVED", + }, + Variant { + id: 55, + name: "TLS_UNRECOGNIZED_NAME", + }, + Variant { + id: 56, + name: "TLS_BAD_CERTIFICATE_STATUS_RESPONSE", + }, + Variant { + id: 57, + name: "TLS_BAD_CERTIFICATE_HASH_VALUE_RESERVED", + }, + Variant { + id: 58, + name: "TLS_UNKNOWN_PSK_IDENTITY", + }, + Variant { + id: 59, + name: "TLS_CERTIFICATE_REQUIRED", + }, + Variant { + id: 60, + name: "TLS_NO_APPLICATION_PROTOCOL", + }, + Variant { + id: 61, + name: "TLS_UNKNOWN_ERROR", + }, + Variant { + id: 62, + name: "QUIC_UNKNOWN_ERROR", + }, +] diff --git a/quic/s2n-quic-core/src/crypto/tls/error.rs b/quic/s2n-quic-core/src/crypto/tls/error.rs index 2b4ed0d0dc..8005598398 100644 --- a/quic/s2n-quic-core/src/crypto/tls/error.rs +++ b/quic/s2n-quic-core/src/crypto/tls/error.rs @@ -1,6 +1,7 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 +use crate::event::metrics::aggregate; use core::fmt; use s2n_codec::DecoderError; @@ -79,12 +80,68 @@ macro_rules! alert_descriptions { )* } + impl aggregate::AsVariant for Error { + const VARIANTS: &'static [aggregate::info::Variant] = &{ + use aggregate::info::{Variant, Str}; + + const fn count(_v: u64) -> usize { + 1 + } + + const LEN: usize = 1 $(+ count($value))*; + let mut array = [Variant { name: Str::new("\0"), id: 0 }; LEN]; + + let mut id = 0; + + $( + array[id] = Variant { + name: Str::new(concat!("TLS_", stringify!($name), "\0")), + id, + }; + id += 1; + )* + + array[id] = aggregate::info::Variant { + name: aggregate::info::Str::new("TLS_UNKNOWN_ERROR\0"), + id, + }; + + array + }; + + #[inline] + fn variant_idx(&self) -> usize { + let mut idx = 0; + + $( + if self.code == $value { + return idx; + } + idx += 1; + )* + + idx + } + } + #[test] fn description_test() { $( assert_eq!(&Error::$name.to_string(), stringify!($name)); )* } + + #[test] + #[cfg_attr(miri, ignore)] + fn variants_test() { + use aggregate::AsVariant; + insta::assert_debug_snapshot!(Error::VARIANTS); + + let mut seen = std::collections::HashSet::new(); + for variant in Error::VARIANTS { + assert!(seen.insert(variant.id)); + } + } }; } diff --git a/quic/s2n-quic-core/src/crypto/tls/snapshots/s2n_quic_core__crypto__tls__error__variants_test.snap b/quic/s2n-quic-core/src/crypto/tls/snapshots/s2n_quic_core__crypto__tls__error__variants_test.snap new file mode 100644 index 0000000000..cf7a71895a --- /dev/null +++ b/quic/s2n-quic-core/src/crypto/tls/snapshots/s2n_quic_core__crypto__tls__error__variants_test.snap @@ -0,0 +1,146 @@ +--- +source: quic/s2n-quic-core/src/crypto/tls/error.rs +expression: "Error::VARIANTS" +--- +[ + Variant { + id: 0, + name: "TLS_CLOSE_NOTIFY", + }, + Variant { + id: 1, + name: "TLS_UNEXPECTED_MESSAGE", + }, + Variant { + id: 2, + name: "TLS_BAD_RECORD_MAC", + }, + Variant { + id: 3, + name: "TLS_DECRYPTION_FAILED_RESERVED", + }, + Variant { + id: 4, + name: "TLS_RECORD_OVERFLOW", + }, + Variant { + id: 5, + name: "TLS_DECOMPRESSION_FAILURE_RESERVED", + }, + Variant { + id: 6, + name: "TLS_HANDSHAKE_FAILURE", + }, + Variant { + id: 7, + name: "TLS_NO_CERTIFICATE_RESERVED", + }, + Variant { + id: 8, + name: "TLS_BAD_CERTIFICATE", + }, + Variant { + id: 9, + name: "TLS_UNSUPPORTED_CERTIFICATE", + }, + Variant { + id: 10, + name: "TLS_CERTIFICATE_REVOKED", + }, + Variant { + id: 11, + name: "TLS_CERTIFICATE_EXPIRED", + }, + Variant { + id: 12, + name: "TLS_CERTIFICATE_UNKNOWN", + }, + Variant { + id: 13, + name: "TLS_ILLEGAL_PARAMETER", + }, + Variant { + id: 14, + name: "TLS_UNKNOWN_CA", + }, + Variant { + id: 15, + name: "TLS_ACCESS_DENIED", + }, + Variant { + id: 16, + name: "TLS_DECODE_ERROR", + }, + Variant { + id: 17, + name: "TLS_DECRYPT_ERROR", + }, + Variant { + id: 18, + name: "TLS_EXPORT_RESTRICTION_RESERVED", + }, + Variant { + id: 19, + name: "TLS_PROTOCOL_VERSION", + }, + Variant { + id: 20, + name: "TLS_INSUFFICIENT_SECURITY", + }, + Variant { + id: 21, + name: "TLS_INTERNAL_ERROR", + }, + Variant { + id: 22, + name: "TLS_INAPPROPRIATE_FALLBACK", + }, + Variant { + id: 23, + name: "TLS_USER_CANCELED", + }, + Variant { + id: 24, + name: "TLS_NO_RENEGOTIATION_RESERVED", + }, + Variant { + id: 25, + name: "TLS_MISSING_EXTENSION", + }, + Variant { + id: 26, + name: "TLS_UNSUPPORTED_EXTENSION", + }, + Variant { + id: 27, + name: "TLS_CERTIFICATE_UNOBTAINABLE_RESERVED", + }, + Variant { + id: 28, + name: "TLS_UNRECOGNIZED_NAME", + }, + Variant { + id: 29, + name: "TLS_BAD_CERTIFICATE_STATUS_RESPONSE", + }, + Variant { + id: 30, + name: "TLS_BAD_CERTIFICATE_HASH_VALUE_RESERVED", + }, + Variant { + id: 31, + name: "TLS_UNKNOWN_PSK_IDENTITY", + }, + Variant { + id: 32, + name: "TLS_CERTIFICATE_REQUIRED", + }, + Variant { + id: 33, + name: "TLS_NO_APPLICATION_PROTOCOL", + }, + Variant { + id: 34, + name: "TLS_UNKNOWN_ERROR", + }, +] diff --git a/quic/s2n-quic-core/src/event/generated.rs b/quic/s2n-quic-core/src/event/generated.rs index d59a19308c..1730af727c 100644 --- a/quic/s2n-quic-core/src/event/generated.rs +++ b/quic/s2n-quic-core/src/event/generated.rs @@ -10,6 +10,8 @@ pub(crate) mod metrics; pub mod api { #![doc = r" This module contains events that are emitted to the [`Subscriber`](crate::event::Subscriber)"] use super::*; + #[allow(unused_imports)] + use crate::event::metrics::aggregate; pub use traits::Subscriber; #[derive(Clone, Debug)] #[non_exhaustive] @@ -269,6 +271,25 @@ pub mod api { #[non_exhaustive] IpV6 { ip: &'a [u8; 16], port: u16 }, } + impl<'a> aggregate::AsVariant for SocketAddress<'a> { + const VARIANTS: &'static [aggregate::info::Variant] = &[ + aggregate::info::Variant { + name: aggregate::info::Str::new("IP_V4\0"), + id: 0usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("IP_V6\0"), + id: 1usize, + }, + ]; + #[inline] + fn variant_idx(&self) -> usize { + match self { + Self::IpV4 { .. } => 0usize, + Self::IpV6 { .. } => 1usize, + } + } + } #[derive(Clone, Debug)] #[non_exhaustive] pub enum DuplicatePacketError { @@ -284,6 +305,25 @@ pub mod api { #[doc = " packet `< 14`, it would trigger this event."] TooOld {}, } + impl aggregate::AsVariant for DuplicatePacketError { + const VARIANTS: &'static [aggregate::info::Variant] = &[ + aggregate::info::Variant { + name: aggregate::info::Str::new("DUPLICATE\0"), + id: 0usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("TOO_OLD\0"), + id: 1usize, + }, + ]; + #[inline] + fn variant_idx(&self) -> usize { + match self { + Self::Duplicate { .. } => 0usize, + Self::TooOld { .. } => 1usize, + } + } + } #[derive(Clone, Debug)] #[non_exhaustive] pub enum Frame { @@ -358,6 +398,125 @@ pub mod api { #[non_exhaustive] DcStatelessResetTokens {}, } + impl aggregate::AsVariant for Frame { + const VARIANTS: &'static [aggregate::info::Variant] = &[ + aggregate::info::Variant { + name: aggregate::info::Str::new("PADDING\0"), + id: 0usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("PING\0"), + id: 1usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("ACK\0"), + id: 2usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("RESET_STREAM\0"), + id: 3usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("STOP_SENDING\0"), + id: 4usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("CRYPTO\0"), + id: 5usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("NEW_TOKEN\0"), + id: 6usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("STREAM\0"), + id: 7usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("MAX_DATA\0"), + id: 8usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("MAX_STREAM_DATA\0"), + id: 9usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("MAX_STREAMS\0"), + id: 10usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("DATA_BLOCKED\0"), + id: 11usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("STREAM_DATA_BLOCKED\0"), + id: 12usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("STREAMS_BLOCKED\0"), + id: 13usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("NEW_CONNECTION_ID\0"), + id: 14usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("RETIRE_CONNECTION_ID\0"), + id: 15usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("PATH_CHALLENGE\0"), + id: 16usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("PATH_RESPONSE\0"), + id: 17usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("CONNECTION_CLOSE\0"), + id: 18usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("HANDSHAKE_DONE\0"), + id: 19usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("DATAGRAM\0"), + id: 20usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("DC_STATELESS_RESET_TOKENS\0"), + id: 21usize, + }, + ]; + #[inline] + fn variant_idx(&self) -> usize { + match self { + Self::Padding { .. } => 0usize, + Self::Ping { .. } => 1usize, + Self::Ack { .. } => 2usize, + Self::ResetStream { .. } => 3usize, + Self::StopSending { .. } => 4usize, + Self::Crypto { .. } => 5usize, + Self::NewToken { .. } => 6usize, + Self::Stream { .. } => 7usize, + Self::MaxData { .. } => 8usize, + Self::MaxStreamData { .. } => 9usize, + Self::MaxStreams { .. } => 10usize, + Self::DataBlocked { .. } => 11usize, + Self::StreamDataBlocked { .. } => 12usize, + Self::StreamsBlocked { .. } => 13usize, + Self::NewConnectionId { .. } => 14usize, + Self::RetireConnectionId { .. } => 15usize, + Self::PathChallenge { .. } => 16usize, + Self::PathResponse { .. } => 17usize, + Self::ConnectionClose { .. } => 18usize, + Self::HandshakeDone { .. } => 19usize, + Self::Datagram { .. } => 20usize, + Self::DcStatelessResetTokens { .. } => 21usize, + } + } + } #[derive(Clone, Debug)] #[non_exhaustive] pub enum StreamType { @@ -366,6 +525,25 @@ pub mod api { #[non_exhaustive] Unidirectional {}, } + impl aggregate::AsVariant for StreamType { + const VARIANTS: &'static [aggregate::info::Variant] = &[ + aggregate::info::Variant { + name: aggregate::info::Str::new("BIDIRECTIONAL\0"), + id: 0usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("UNIDIRECTIONAL\0"), + id: 1usize, + }, + ]; + #[inline] + fn variant_idx(&self) -> usize { + match self { + Self::Bidirectional { .. } => 0usize, + Self::Unidirectional { .. } => 1usize, + } + } + } #[derive(Clone, Debug)] #[non_exhaustive] pub enum PacketHeader { @@ -384,6 +562,50 @@ pub mod api { #[non_exhaustive] StatelessReset {}, } + impl aggregate::AsVariant for PacketHeader { + const VARIANTS: &'static [aggregate::info::Variant] = &[ + aggregate::info::Variant { + name: aggregate::info::Str::new("INITIAL\0"), + id: 0usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("HANDSHAKE\0"), + id: 1usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("ZERO_RTT\0"), + id: 2usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("ONE_RTT\0"), + id: 3usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("RETRY\0"), + id: 4usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("VERSION_NEGOTIATION\0"), + id: 5usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("STATELESS_RESET\0"), + id: 6usize, + }, + ]; + #[inline] + fn variant_idx(&self) -> usize { + match self { + Self::Initial { .. } => 0usize, + Self::Handshake { .. } => 1usize, + Self::ZeroRtt { .. } => 2usize, + Self::OneRtt { .. } => 3usize, + Self::Retry { .. } => 4usize, + Self::VersionNegotiation { .. } => 5usize, + Self::StatelessReset { .. } => 6usize, + } + } + } #[derive(Clone, Debug)] #[non_exhaustive] pub enum PacketType { @@ -402,6 +624,50 @@ pub mod api { #[non_exhaustive] StatelessReset {}, } + impl aggregate::AsVariant for PacketType { + const VARIANTS: &'static [aggregate::info::Variant] = &[ + aggregate::info::Variant { + name: aggregate::info::Str::new("INITIAL\0"), + id: 0usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("HANDSHAKE\0"), + id: 1usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("ZERO_RTT\0"), + id: 2usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("ONE_RTT\0"), + id: 3usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("RETRY\0"), + id: 4usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("VERSION_NEGOTIATION\0"), + id: 5usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("STATELESS_RESET\0"), + id: 6usize, + }, + ]; + #[inline] + fn variant_idx(&self) -> usize { + match self { + Self::Initial { .. } => 0usize, + Self::Handshake { .. } => 1usize, + Self::ZeroRtt { .. } => 2usize, + Self::OneRtt { .. } => 3usize, + Self::Retry { .. } => 4usize, + Self::VersionNegotiation { .. } => 5usize, + Self::StatelessReset { .. } => 6usize, + } + } + } #[derive(Clone, Debug)] #[non_exhaustive] pub enum KeyType { @@ -414,6 +680,35 @@ pub mod api { #[non_exhaustive] OneRtt { generation: u16 }, } + impl aggregate::AsVariant for KeyType { + const VARIANTS: &'static [aggregate::info::Variant] = &[ + aggregate::info::Variant { + name: aggregate::info::Str::new("INITIAL\0"), + id: 0usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("HANDSHAKE\0"), + id: 1usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("ZERO_RTT\0"), + id: 2usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("ONE_RTT\0"), + id: 3usize, + }, + ]; + #[inline] + fn variant_idx(&self) -> usize { + match self { + Self::Initial { .. } => 0usize, + Self::Handshake { .. } => 1usize, + Self::ZeroRtt { .. } => 2usize, + Self::OneRtt { .. } => 3usize, + } + } + } #[derive(Clone, Debug)] #[non_exhaustive] #[doc = " A context from which the event is being emitted"] @@ -426,6 +721,25 @@ pub mod api { #[doc = " This maps to an internal connection id, which is a stable identifier across CID changes."] Connection { id: u64 }, } + impl aggregate::AsVariant for Subject { + const VARIANTS: &'static [aggregate::info::Variant] = &[ + aggregate::info::Variant { + name: aggregate::info::Str::new("ENDPOINT\0"), + id: 0usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("CONNECTION\0"), + id: 1usize, + }, + ]; + #[inline] + fn variant_idx(&self) -> usize { + match self { + Self::Endpoint { .. } => 0usize, + Self::Connection { .. } => 1usize, + } + } + } #[derive(Clone, Debug)] #[doc = " An endpoint may be either a Server or a Client"] pub enum EndpointType { @@ -434,6 +748,25 @@ pub mod api { #[non_exhaustive] Client {}, } + impl aggregate::AsVariant for EndpointType { + const VARIANTS: &'static [aggregate::info::Variant] = &[ + aggregate::info::Variant { + name: aggregate::info::Str::new("SERVER\0"), + id: 0usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("CLIENT\0"), + id: 1usize, + }, + ]; + #[inline] + fn variant_idx(&self) -> usize { + match self { + Self::Server { .. } => 0usize, + Self::Client { .. } => 1usize, + } + } + } #[derive(Clone, Debug)] #[non_exhaustive] pub enum DatagramDropReason { @@ -485,6 +818,80 @@ pub mod api { #[doc = " The peer initiated a connection migration without supplying enough connection IDs to use."] InsufficientConnectionIds {}, } + impl aggregate::AsVariant for DatagramDropReason { + const VARIANTS: &'static [aggregate::info::Variant] = &[ + aggregate::info::Variant { + name: aggregate::info::Str::new("DECODING_FAILED\0"), + id: 0usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("INVALID_RETRY_TOKEN\0"), + id: 1usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("UNSUPPORTED_VERSION\0"), + id: 2usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("INVALID_DESTINATION_CONNECTION_ID\0"), + id: 3usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("INVALID_SOURCE_CONNECTION_ID\0"), + id: 4usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("INVALID_MTU_CONFIGURATION\0"), + id: 5usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("UNKNOWN_DESTINATION_CONNECTION_ID\0"), + id: 6usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("REJECTED_CONNECTION_ATTEMPT\0"), + id: 7usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("UNKNOWN_SERVER_ADDRESS\0"), + id: 8usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("CONNECTION_MIGRATION_DURING_HANDSHAKE\0"), + id: 9usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("REJECTED_CONNECTION_MIGRATION\0"), + id: 10usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("PATH_LIMIT_EXCEEDED\0"), + id: 11usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("INSUFFICIENT_CONNECTION_IDS\0"), + id: 12usize, + }, + ]; + #[inline] + fn variant_idx(&self) -> usize { + match self { + Self::DecodingFailed { .. } => 0usize, + Self::InvalidRetryToken { .. } => 1usize, + Self::UnsupportedVersion { .. } => 2usize, + Self::InvalidDestinationConnectionId { .. } => 3usize, + Self::InvalidSourceConnectionId { .. } => 4usize, + Self::InvalidMtuConfiguration { .. } => 5usize, + Self::UnknownDestinationConnectionId { .. } => 6usize, + Self::RejectedConnectionAttempt { .. } => 7usize, + Self::UnknownServerAddress { .. } => 8usize, + Self::ConnectionMigrationDuringHandshake { .. } => 9usize, + Self::RejectedConnectionMigration { .. } => 10usize, + Self::PathLimitExceeded { .. } => 11usize, + Self::InsufficientConnectionIds { .. } => 12usize, + } + } + } #[derive(Clone, Debug)] #[non_exhaustive] pub enum KeySpace { @@ -497,6 +904,35 @@ pub mod api { #[non_exhaustive] OneRtt {}, } + impl aggregate::AsVariant for KeySpace { + const VARIANTS: &'static [aggregate::info::Variant] = &[ + aggregate::info::Variant { + name: aggregate::info::Str::new("INITIAL\0"), + id: 0usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("HANDSHAKE\0"), + id: 1usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("ZERO_RTT\0"), + id: 2usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("ONE_RTT\0"), + id: 3usize, + }, + ]; + #[inline] + fn variant_idx(&self) -> usize { + match self { + Self::Initial { .. } => 0usize, + Self::Handshake { .. } => 1usize, + Self::ZeroRtt { .. } => 2usize, + Self::OneRtt { .. } => 3usize, + } + } + } #[derive(Clone, Debug)] #[non_exhaustive] pub enum PacketSkipReason { @@ -507,6 +943,25 @@ pub mod api { #[doc = " Skipped a packet number to detect an Optimistic Ack attack"] OptimisticAckMitigation {}, } + impl aggregate::AsVariant for PacketSkipReason { + const VARIANTS: &'static [aggregate::info::Variant] = &[ + aggregate::info::Variant { + name: aggregate::info::Str::new("PTO_PROBE\0"), + id: 0usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("OPTIMISTIC_ACK_MITIGATION\0"), + id: 1usize, + }, + ]; + #[inline] + fn variant_idx(&self) -> usize { + match self { + Self::PtoProbe { .. } => 0usize, + Self::OptimisticAckMitigation { .. } => 1usize, + } + } + } #[derive(Clone, Debug)] #[non_exhaustive] pub enum PacketDropReason<'a> { @@ -565,6 +1020,70 @@ pub mod api { packet_type: PacketType, }, } + impl<'a> aggregate::AsVariant for PacketDropReason<'a> { + const VARIANTS: &'static [aggregate::info::Variant] = &[ + aggregate::info::Variant { + name: aggregate::info::Str::new("CONNECTION_ERROR\0"), + id: 0usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("HANDSHAKE_NOT_COMPLETE\0"), + id: 1usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("VERSION_MISMATCH\0"), + id: 2usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("CONNECTION_ID_MISMATCH\0"), + id: 3usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("UNPROTECT_FAILED\0"), + id: 4usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("DECRYPTION_FAILED\0"), + id: 5usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("DECODING_FAILED\0"), + id: 6usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("NON_EMPTY_RETRY_TOKEN\0"), + id: 7usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("RETRY_DISCARDED\0"), + id: 8usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("UNDERSIZED_INITIAL_PACKET\0"), + id: 9usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("INITIAL_CONNECTION_ID_INVALID_SPACE\0"), + id: 10usize, + }, + ]; + #[inline] + fn variant_idx(&self) -> usize { + match self { + Self::ConnectionError { .. } => 0usize, + Self::HandshakeNotComplete { .. } => 1usize, + Self::VersionMismatch { .. } => 2usize, + Self::ConnectionIdMismatch { .. } => 3usize, + Self::UnprotectFailed { .. } => 4usize, + Self::DecryptionFailed { .. } => 5usize, + Self::DecodingFailed { .. } => 6usize, + Self::NonEmptyRetryToken { .. } => 7usize, + Self::RetryDiscarded { .. } => 8usize, + Self::UndersizedInitialPacket { .. } => 9usize, + Self::InitialConnectionIdInvalidSpace { .. } => 10usize, + } + } + } #[derive(Clone, Debug)] #[non_exhaustive] #[deprecated(note = "use on_rx_ack_range_dropped event instead")] @@ -587,6 +1106,19 @@ pub mod api { stored_range: core::ops::RangeInclusive, }, } + #[allow(deprecated)] + impl aggregate::AsVariant for AckAction { + const VARIANTS: &'static [aggregate::info::Variant] = &[aggregate::info::Variant { + name: aggregate::info::Str::new("RX_ACK_RANGE_DROPPED\0"), + id: 0usize, + }]; + #[inline] + fn variant_idx(&self) -> usize { + match self { + Self::RxAckRangeDropped { .. } => 0usize, + } + } + } #[derive(Clone, Debug)] #[non_exhaustive] pub enum RetryDiscardReason<'a> { @@ -604,6 +1136,35 @@ pub mod api { #[doc = " The Retry packet received contained an invalid retry integrity tag"] InvalidIntegrityTag {}, } + impl<'a> aggregate::AsVariant for RetryDiscardReason<'a> { + const VARIANTS: &'static [aggregate::info::Variant] = &[ + aggregate::info::Variant { + name: aggregate::info::Str::new("SCID_EQUALS_DCID\0"), + id: 0usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("RETRY_ALREADY_PROCESSED\0"), + id: 1usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("INITIAL_ALREADY_PROCESSED\0"), + id: 2usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("INVALID_INTEGRITY_TAG\0"), + id: 3usize, + }, + ]; + #[inline] + fn variant_idx(&self) -> usize { + match self { + Self::ScidEqualsDcid { .. } => 0usize, + Self::RetryAlreadyProcessed { .. } => 1usize, + Self::InitialAlreadyProcessed { .. } => 2usize, + Self::InvalidIntegrityTag { .. } => 3usize, + } + } + } #[derive(Clone, Debug)] #[non_exhaustive] pub enum MigrationDenyReason { @@ -616,6 +1177,35 @@ pub mod api { #[non_exhaustive] ConnectionMigrationDisabled {}, } + impl aggregate::AsVariant for MigrationDenyReason { + const VARIANTS: &'static [aggregate::info::Variant] = &[ + aggregate::info::Variant { + name: aggregate::info::Str::new("BLOCKED_PORT\0"), + id: 0usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("PORT_SCOPE_CHANGED\0"), + id: 1usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("IP_SCOPE_CHANGE\0"), + id: 2usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("CONNECTION_MIGRATION_DISABLED\0"), + id: 3usize, + }, + ]; + #[inline] + fn variant_idx(&self) -> usize { + match self { + Self::BlockedPort { .. } => 0usize, + Self::PortScopeChanged { .. } => 1usize, + Self::IpScopeChange { .. } => 2usize, + Self::ConnectionMigrationDisabled { .. } => 3usize, + } + } + } #[derive(Clone, Debug)] #[non_exhaustive] #[doc = " The current state of the ECN controller for the path"] @@ -633,6 +1223,35 @@ pub mod api { #[doc = " ECN capability has been confirmed"] Capable {}, } + impl aggregate::AsVariant for EcnState { + const VARIANTS: &'static [aggregate::info::Variant] = &[ + aggregate::info::Variant { + name: aggregate::info::Str::new("TESTING\0"), + id: 0usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("UNKNOWN\0"), + id: 1usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("FAILED\0"), + id: 2usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("CAPABLE\0"), + id: 3usize, + }, + ]; + #[inline] + fn variant_idx(&self) -> usize { + match self { + Self::Testing { .. } => 0usize, + Self::Unknown { .. } => 1usize, + Self::Failed { .. } => 2usize, + Self::Capable { .. } => 3usize, + } + } + } #[derive(Clone, Debug)] #[non_exhaustive] #[doc = " Events tracking the progress of handshake status"] @@ -657,6 +1276,35 @@ pub mod api { #[doc = " HANDSHAKE_DONE frame until it is acked by the peer."] HandshakeDoneLost {}, } + impl aggregate::AsVariant for HandshakeStatus { + const VARIANTS: &'static [aggregate::info::Variant] = &[ + aggregate::info::Variant { + name: aggregate::info::Str::new("COMPLETE\0"), + id: 0usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("CONFIRMED\0"), + id: 1usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("HANDSHAKE_DONE_ACKED\0"), + id: 2usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("HANDSHAKE_DONE_LOST\0"), + id: 3usize, + }, + ]; + #[inline] + fn variant_idx(&self) -> usize { + match self { + Self::Complete { .. } => 0usize, + Self::Confirmed { .. } => 1usize, + Self::HandshakeDoneAcked { .. } => 2usize, + Self::HandshakeDoneLost { .. } => 3usize, + } + } + } #[derive(Clone, Debug)] #[non_exhaustive] #[doc = " The source that caused a congestion event"] @@ -668,6 +1316,25 @@ pub mod api { #[doc = " One or more packets were detected lost"] PacketLoss {}, } + impl aggregate::AsVariant for CongestionSource { + const VARIANTS: &'static [aggregate::info::Variant] = &[ + aggregate::info::Variant { + name: aggregate::info::Str::new("ECN\0"), + id: 0usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("PACKET_LOSS\0"), + id: 1usize, + }, + ]; + #[inline] + fn variant_idx(&self) -> usize { + match self { + Self::Ecn { .. } => 0usize, + Self::PacketLoss { .. } => 1usize, + } + } + } #[non_exhaustive] #[derive(Copy, Clone, Debug, Eq, PartialEq)] #[allow(non_camel_case_types)] @@ -681,6 +1348,35 @@ pub mod api { #[non_exhaustive] Unknown {}, } + impl aggregate::AsVariant for CipherSuite { + const VARIANTS: &'static [aggregate::info::Variant] = &[ + aggregate::info::Variant { + name: aggregate::info::Str::new("TLS_AES_128_GCM_SHA256\0"), + id: 0usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("TLS_AES_256_GCM_SHA384\0"), + id: 1usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("TLS_CHACHA20_POLY1305_SHA256\0"), + id: 2usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("UNKNOWN\0"), + id: 3usize, + }, + ]; + #[inline] + fn variant_idx(&self) -> usize { + match self { + Self::TLS_AES_128_GCM_SHA256 { .. } => 0usize, + Self::TLS_AES_256_GCM_SHA384 { .. } => 1usize, + Self::TLS_CHACHA20_POLY1305_SHA256 { .. } => 2usize, + Self::Unknown { .. } => 3usize, + } + } + } #[derive(Clone, Debug)] #[non_exhaustive] pub enum PathChallengeStatus { @@ -689,6 +1385,25 @@ pub mod api { #[non_exhaustive] Abandoned {}, } + impl aggregate::AsVariant for PathChallengeStatus { + const VARIANTS: &'static [aggregate::info::Variant] = &[ + aggregate::info::Variant { + name: aggregate::info::Str::new("VALIDATED\0"), + id: 0usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("ABANDONED\0"), + id: 1usize, + }, + ]; + #[inline] + fn variant_idx(&self) -> usize { + match self { + Self::Validated { .. } => 0usize, + Self::Abandoned { .. } => 1usize, + } + } + } #[derive(Clone, Debug)] #[non_exhaustive] #[doc = " The reason the slow start congestion controller state has been exited"] @@ -710,6 +1425,35 @@ pub mod api { #[doc = " congestion window."] Other {}, } + impl aggregate::AsVariant for SlowStartExitCause { + const VARIANTS: &'static [aggregate::info::Variant] = &[ + aggregate::info::Variant { + name: aggregate::info::Str::new("PACKET_LOSS\0"), + id: 0usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("ECN\0"), + id: 1usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("RTT\0"), + id: 2usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("OTHER\0"), + id: 3usize, + }, + ]; + #[inline] + fn variant_idx(&self) -> usize { + match self { + Self::PacketLoss { .. } => 0usize, + Self::Ecn { .. } => 1usize, + Self::Rtt { .. } => 2usize, + Self::Other { .. } => 3usize, + } + } + } #[derive(Clone, Debug)] #[non_exhaustive] #[doc = " The reason the MTU was updated"] @@ -733,6 +1477,45 @@ pub mod api { #[doc = " MTU probes larger than the current MTU were not acknowledged"] LargerProbesLost {}, } + impl aggregate::AsVariant for MtuUpdatedCause { + const VARIANTS: &'static [aggregate::info::Variant] = &[ + aggregate::info::Variant { + name: aggregate::info::Str::new("NEW_PATH\0"), + id: 0usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("PROBE_ACKNOWLEDGED\0"), + id: 1usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("BLACKHOLE\0"), + id: 2usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("INITIAL_MTU_PACKET_LOST\0"), + id: 3usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("INITIAL_MTU_PACKET_ACKNOWLEDGED\0"), + id: 4usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("LARGER_PROBES_LOST\0"), + id: 5usize, + }, + ]; + #[inline] + fn variant_idx(&self) -> usize { + match self { + Self::NewPath { .. } => 0usize, + Self::ProbeAcknowledged { .. } => 1usize, + Self::Blackhole { .. } => 2usize, + Self::InitialMtuPacketLost { .. } => 3usize, + Self::InitialMtuPacketAcknowledged { .. } => 4usize, + Self::LargerProbesLost { .. } => 5usize, + } + } + } #[derive(Clone, Debug)] #[non_exhaustive] pub enum BbrState { @@ -751,6 +1534,50 @@ pub mod api { #[non_exhaustive] ProbeRtt {}, } + impl aggregate::AsVariant for BbrState { + const VARIANTS: &'static [aggregate::info::Variant] = &[ + aggregate::info::Variant { + name: aggregate::info::Str::new("STARTUP\0"), + id: 0usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("DRAIN\0"), + id: 1usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("PROBE_BW_DOWN\0"), + id: 2usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("PROBE_BW_CRUISE\0"), + id: 3usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("PROBE_BW_REFILL\0"), + id: 4usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("PROBE_BW_UP\0"), + id: 5usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("PROBE_RTT\0"), + id: 6usize, + }, + ]; + #[inline] + fn variant_idx(&self) -> usize { + match self { + Self::Startup { .. } => 0usize, + Self::Drain { .. } => 1usize, + Self::ProbeBwDown { .. } => 2usize, + Self::ProbeBwCruise { .. } => 3usize, + Self::ProbeBwRefill { .. } => 4usize, + Self::ProbeBwUp { .. } => 5usize, + Self::ProbeRtt { .. } => 6usize, + } + } + } #[derive(Clone, Debug)] #[non_exhaustive] pub enum DcState { @@ -763,6 +1590,35 @@ pub mod api { #[non_exhaustive] Complete {}, } + impl aggregate::AsVariant for DcState { + const VARIANTS: &'static [aggregate::info::Variant] = &[ + aggregate::info::Variant { + name: aggregate::info::Str::new("VERSION_NEGOTIATED\0"), + id: 0usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("NO_VERSION_NEGOTIATED\0"), + id: 1usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("PATH_SECRETS_READY\0"), + id: 2usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("COMPLETE\0"), + id: 3usize, + }, + ]; + #[inline] + fn variant_idx(&self) -> usize { + match self { + Self::VersionNegotiated { .. } => 0usize, + Self::NoVersionNegotiated { .. } => 1usize, + Self::PathSecretsReady { .. } => 2usize, + Self::Complete { .. } => 3usize, + } + } + } #[derive(Clone, Debug)] #[non_exhaustive] #[doc = " Application level protocol"] @@ -1949,6 +2805,45 @@ pub mod api { #[doc = " Emitted when the max maximum transmission unit is configured"] MaxMtu { mtu: u16 }, } + impl aggregate::AsVariant for PlatformFeatureConfiguration { + const VARIANTS: &'static [aggregate::info::Variant] = &[ + aggregate::info::Variant { + name: aggregate::info::Str::new("GSO\0"), + id: 0usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("GRO\0"), + id: 1usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("ECN\0"), + id: 2usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("BASE_MTU\0"), + id: 3usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("INITIAL_MTU\0"), + id: 4usize, + }, + aggregate::info::Variant { + name: aggregate::info::Str::new("MAX_MTU\0"), + id: 5usize, + }, + ]; + #[inline] + fn variant_idx(&self) -> usize { + match self { + Self::Gso { .. } => 0usize, + Self::Gro { .. } => 1usize, + Self::Ecn { .. } => 2usize, + Self::BaseMtu { .. } => 3usize, + Self::InitialMtu { .. } => 4usize, + Self::MaxMtu { .. } => 5usize, + } + } + } impl<'a> IntoEvent> for &'a crate::transport::parameters::PreferredAddress { diff --git a/quic/s2n-quic-core/src/event/generated/metrics/aggregate.rs b/quic/s2n-quic-core/src/event/generated/metrics/aggregate.rs index 45c267ced2..a276f5f465 100644 --- a/quic/s2n-quic-core/src/event/generated/metrics/aggregate.rs +++ b/quic/s2n-quic-core/src/event/generated/metrics/aggregate.rs @@ -9,681 +9,807 @@ use crate::event::{ self, api, metrics::aggregate::{ info::{self, Str}, - AsMetric as _, Info, Recorder, Registry, + AsVariant, BoolRecorder, Info, Metric, NominalRecorder, Recorder, Registry, Units, }, }; use alloc::{boxed::Box, vec::Vec}; -static INFO: &[Info; 112usize] = &[ +static INFO: &[Info; 133usize] = &[ info::Builder { id: 0usize, name: Str::new("application_protocol_information\0"), - units: Str::new("\0"), + units: Units::None, } .build(), info::Builder { id: 1usize, name: Str::new("server_name_information\0"), - units: Str::new("\0"), + units: Units::None, } .build(), info::Builder { id: 2usize, name: Str::new("packet_skipped\0"), - units: Str::new("\0"), + units: Units::None, } .build(), info::Builder { id: 3usize, name: Str::new("packet_sent\0"), - units: Str::new("\0"), + units: Units::None, } .build(), info::Builder { id: 4usize, name: Str::new("packet_sent.bytes.total\0"), - units: Str::new("b\0"), + units: Units::Bytes, } .build(), info::Builder { id: 5usize, name: Str::new("packet_sent.bytes\0"), - units: Str::new("b\0"), + units: Units::Bytes, } .build(), info::Builder { id: 6usize, name: Str::new("packet_received\0"), - units: Str::new("\0"), + units: Units::None, } .build(), info::Builder { id: 7usize, name: Str::new("active_path_updated\0"), - units: Str::new("\0"), + units: Units::None, } .build(), info::Builder { id: 8usize, name: Str::new("path_created\0"), - units: Str::new("\0"), + units: Units::None, } .build(), info::Builder { id: 9usize, name: Str::new("frame_sent\0"), - units: Str::new("\0"), + units: Units::None, } .build(), info::Builder { id: 10usize, - name: Str::new("frame_received\0"), - units: Str::new("\0"), + name: Str::new("frame_sent.frame\0"), + units: Units::None, } .build(), info::Builder { id: 11usize, - name: Str::new("packet_lost\0"), - units: Str::new("\0"), + name: Str::new("frame_received\0"), + units: Units::None, } .build(), info::Builder { id: 12usize, - name: Str::new("packet_lost.bytes.total\0"), - units: Str::new("b\0"), + name: Str::new("frame_received.frame\0"), + units: Units::None, } .build(), info::Builder { id: 13usize, - name: Str::new("packet_lost.bytes\0"), - units: Str::new("b\0"), + name: Str::new("packet_lost\0"), + units: Units::None, } .build(), info::Builder { id: 14usize, - name: Str::new("recovery_metrics\0"), - units: Str::new("\0"), + name: Str::new("packet_lost.bytes.total\0"), + units: Units::Bytes, } .build(), info::Builder { id: 15usize, - name: Str::new("recovery_metrics.min_rtt\0"), - units: Str::new("us\0"), + name: Str::new("packet_lost.bytes\0"), + units: Units::Bytes, } .build(), info::Builder { id: 16usize, - name: Str::new("recovery_metrics.smoothed_rtt\0"), - units: Str::new("us\0"), + name: Str::new("packet_lost.is_mtu_probe\0"), + units: Units::None, } .build(), info::Builder { id: 17usize, - name: Str::new("recovery_metrics.latest_rtt\0"), - units: Str::new("us\0"), + name: Str::new("recovery_metrics\0"), + units: Units::None, } .build(), info::Builder { id: 18usize, - name: Str::new("recovery_metrics.rtt_variance\0"), - units: Str::new("us\0"), + name: Str::new("recovery_metrics.min_rtt\0"), + units: Units::Duration, } .build(), info::Builder { id: 19usize, - name: Str::new("recovery_metrics.max_ack_delay\0"), - units: Str::new("us\0"), + name: Str::new("recovery_metrics.smoothed_rtt\0"), + units: Units::Duration, } .build(), info::Builder { id: 20usize, - name: Str::new("recovery_metrics.pto_count\0"), - units: Str::new("\0"), + name: Str::new("recovery_metrics.latest_rtt\0"), + units: Units::Duration, } .build(), info::Builder { id: 21usize, - name: Str::new("recovery_metrics.congestion_window\0"), - units: Str::new("b\0"), + name: Str::new("recovery_metrics.rtt_variance\0"), + units: Units::Duration, } .build(), info::Builder { id: 22usize, - name: Str::new("recovery_metrics.bytes_in_flight\0"), - units: Str::new("b\0"), + name: Str::new("recovery_metrics.max_ack_delay\0"), + units: Units::Duration, } .build(), info::Builder { id: 23usize, - name: Str::new("congestion\0"), - units: Str::new("\0"), + name: Str::new("recovery_metrics.pto_count\0"), + units: Units::None, } .build(), info::Builder { id: 24usize, - name: Str::new("rx_ack_range_dropped\0"), - units: Str::new("\0"), + name: Str::new("recovery_metrics.congestion_window\0"), + units: Units::Duration, } .build(), info::Builder { id: 25usize, - name: Str::new("ack_range_received\0"), - units: Str::new("\0"), + name: Str::new("recovery_metrics.bytes_in_flight\0"), + units: Units::Duration, } .build(), info::Builder { id: 26usize, - name: Str::new("ack_range_sent\0"), - units: Str::new("\0"), + name: Str::new("recovery_metrics.congestion_limited\0"), + units: Units::None, } .build(), info::Builder { id: 27usize, - name: Str::new("packet_dropped\0"), - units: Str::new("\0"), + name: Str::new("congestion\0"), + units: Units::None, } .build(), info::Builder { id: 28usize, - name: Str::new("key_update\0"), - units: Str::new("\0"), + name: Str::new("congestion.source\0"), + units: Units::None, } .build(), info::Builder { id: 29usize, - name: Str::new("key_space_discarded\0"), - units: Str::new("\0"), + name: Str::new("rx_ack_range_dropped\0"), + units: Units::None, } .build(), info::Builder { id: 30usize, - name: Str::new("connection_started\0"), - units: Str::new("\0"), + name: Str::new("ack_range_received\0"), + units: Units::None, } .build(), info::Builder { id: 31usize, - name: Str::new("connection_closed\0"), - units: Str::new("\0"), + name: Str::new("ack_range_sent\0"), + units: Units::None, } .build(), info::Builder { id: 32usize, - name: Str::new("duplicate_packet\0"), - units: Str::new("\0"), + name: Str::new("packet_dropped\0"), + units: Units::None, } .build(), info::Builder { id: 33usize, - name: Str::new("transport_parameters_received\0"), - units: Str::new("\0"), + name: Str::new("packet_dropped.reason\0"), + units: Units::None, } .build(), info::Builder { id: 34usize, - name: Str::new("datagram_sent\0"), - units: Str::new("\0"), + name: Str::new("key_update\0"), + units: Units::None, } .build(), info::Builder { id: 35usize, - name: Str::new("datagram_sent.bytes.total\0"), - units: Str::new("b\0"), + name: Str::new("key_space_discarded\0"), + units: Units::None, } .build(), info::Builder { id: 36usize, - name: Str::new("datagram_sent.bytes\0"), - units: Str::new("b\0"), + name: Str::new("key_space_discarded.space\0"), + units: Units::None, } .build(), info::Builder { id: 37usize, - name: Str::new("datagram_sent.gso_offset\0"), - units: Str::new("\0"), + name: Str::new("connection_started\0"), + units: Units::None, } .build(), info::Builder { id: 38usize, - name: Str::new("datagram_received\0"), - units: Str::new("\0"), + name: Str::new("connection_closed\0"), + units: Units::None, } .build(), info::Builder { id: 39usize, - name: Str::new("datagram_received.bytes.total\0"), - units: Str::new("b\0"), + name: Str::new("connection_closed.error\0"), + units: Units::None, } .build(), info::Builder { id: 40usize, - name: Str::new("datagram_received.bytes\0"), - units: Str::new("b\0"), + name: Str::new("duplicate_packet\0"), + units: Units::None, } .build(), info::Builder { id: 41usize, - name: Str::new("datagram_dropped\0"), - units: Str::new("\0"), + name: Str::new("duplicate_packet.error\0"), + units: Units::None, } .build(), info::Builder { id: 42usize, - name: Str::new("datagram_dropped.bytes.total\0"), - units: Str::new("b\0"), + name: Str::new("transport_parameters_received\0"), + units: Units::None, } .build(), info::Builder { id: 43usize, - name: Str::new("datagram_dropped.bytes\0"), - units: Str::new("b\0"), + name: Str::new("datagram_sent\0"), + units: Units::None, } .build(), info::Builder { id: 44usize, - name: Str::new("connection_id_updated\0"), - units: Str::new("\0"), + name: Str::new("datagram_sent.bytes.total\0"), + units: Units::Bytes, } .build(), info::Builder { id: 45usize, - name: Str::new("ecn_state_changed\0"), - units: Str::new("\0"), + name: Str::new("datagram_sent.bytes\0"), + units: Units::Bytes, } .build(), info::Builder { id: 46usize, - name: Str::new("connection_migration_denied\0"), - units: Str::new("\0"), + name: Str::new("datagram_sent.gso_offset\0"), + units: Units::None, } .build(), info::Builder { id: 47usize, - name: Str::new("handshake_status_updated\0"), - units: Str::new("\0"), + name: Str::new("datagram_received\0"), + units: Units::None, } .build(), info::Builder { id: 48usize, - name: Str::new("tls_exporter_ready\0"), - units: Str::new("\0"), + name: Str::new("datagram_received.bytes.total\0"), + units: Units::Bytes, } .build(), info::Builder { id: 49usize, - name: Str::new("path_challenge_updated\0"), - units: Str::new("\0"), + name: Str::new("datagram_received.bytes\0"), + units: Units::Bytes, } .build(), info::Builder { id: 50usize, - name: Str::new("tls_client_hello\0"), - units: Str::new("\0"), + name: Str::new("datagram_dropped\0"), + units: Units::None, } .build(), info::Builder { id: 51usize, - name: Str::new("tls_server_hello\0"), - units: Str::new("\0"), + name: Str::new("datagram_dropped.bytes.total\0"), + units: Units::Bytes, } .build(), info::Builder { id: 52usize, - name: Str::new("rx_stream_progress\0"), - units: Str::new("\0"), + name: Str::new("datagram_dropped.bytes\0"), + units: Units::Bytes, } .build(), info::Builder { id: 53usize, - name: Str::new("rx_stream_progress.bytes.total\0"), - units: Str::new("b\0"), + name: Str::new("datagram_dropped.reason\0"), + units: Units::None, } .build(), info::Builder { id: 54usize, - name: Str::new("rx_stream_progress.bytes\0"), - units: Str::new("b\0"), + name: Str::new("connection_id_updated\0"), + units: Units::None, } .build(), info::Builder { id: 55usize, - name: Str::new("tx_stream_progress\0"), - units: Str::new("\0"), + name: Str::new("ecn_state_changed\0"), + units: Units::None, } .build(), info::Builder { id: 56usize, - name: Str::new("tx_stream_progress.bytes.total\0"), - units: Str::new("b\0"), + name: Str::new("ecn_state_changed.state\0"), + units: Units::None, } .build(), info::Builder { id: 57usize, - name: Str::new("tx_stream_progress.bytes\0"), - units: Str::new("b\0"), + name: Str::new("connection_migration_denied\0"), + units: Units::None, } .build(), info::Builder { id: 58usize, - name: Str::new("keep_alive_timer_expired\0"), - units: Str::new("\0"), + name: Str::new("connection_migration_denied.reason\0"), + units: Units::None, } .build(), info::Builder { id: 59usize, - name: Str::new("mtu_updated\0"), - units: Str::new("\0"), + name: Str::new("handshake_status_updated\0"), + units: Units::None, } .build(), info::Builder { id: 60usize, - name: Str::new("mtu_updated.mtu\0"), - units: Str::new("b\0"), + name: Str::new("handshake_status_updated.status\0"), + units: Units::None, } .build(), info::Builder { id: 61usize, - name: Str::new("slow_start_exited\0"), - units: Str::new("\0"), + name: Str::new("tls_exporter_ready\0"), + units: Units::None, } .build(), info::Builder { id: 62usize, - name: Str::new("slow_start_exited.congestion_window\0"), - units: Str::new("b\0"), + name: Str::new("path_challenge_updated\0"), + units: Units::None, } .build(), info::Builder { id: 63usize, - name: Str::new("delivery_rate_sampled\0"), - units: Str::new("\0"), + name: Str::new("tls_client_hello\0"), + units: Units::None, } .build(), info::Builder { id: 64usize, - name: Str::new("pacing_rate_updated\0"), - units: Str::new("\0"), + name: Str::new("tls_server_hello\0"), + units: Units::None, } .build(), info::Builder { id: 65usize, - name: Str::new("pacing_rate_updated.bytes_per_second\0"), - units: Str::new("b\0"), + name: Str::new("rx_stream_progress\0"), + units: Units::None, } .build(), info::Builder { id: 66usize, - name: Str::new("pacing_rate_updated.burst_size\0"), - units: Str::new("b\0"), + name: Str::new("rx_stream_progress.bytes.total\0"), + units: Units::Bytes, } .build(), info::Builder { id: 67usize, - name: Str::new("bbr_state_changed\0"), - units: Str::new("\0"), + name: Str::new("rx_stream_progress.bytes\0"), + units: Units::Bytes, } .build(), info::Builder { id: 68usize, - name: Str::new("dc_state_changed\0"), - units: Str::new("\0"), + name: Str::new("tx_stream_progress\0"), + units: Units::None, } .build(), info::Builder { id: 69usize, - name: Str::new("version_information\0"), - units: Str::new("\0"), + name: Str::new("tx_stream_progress.bytes.total\0"), + units: Units::Bytes, } .build(), info::Builder { id: 70usize, - name: Str::new("endpoint_packet_sent\0"), - units: Str::new("\0"), + name: Str::new("tx_stream_progress.bytes\0"), + units: Units::Bytes, } .build(), info::Builder { id: 71usize, - name: Str::new("endpoint_packet_received\0"), - units: Str::new("\0"), + name: Str::new("keep_alive_timer_expired\0"), + units: Units::None, } .build(), info::Builder { id: 72usize, - name: Str::new("endpoint_datagram_sent\0"), - units: Str::new("\0"), + name: Str::new("mtu_updated\0"), + units: Units::None, } .build(), info::Builder { id: 73usize, - name: Str::new("endpoint_datagram_sent.bytes\0"), - units: Str::new("b\0"), + name: Str::new("mtu_updated.mtu\0"), + units: Units::Bytes, } .build(), info::Builder { id: 74usize, - name: Str::new("endpoint_datagram_sent.bytes.total\0"), - units: Str::new("b\0"), + name: Str::new("mtu_updated.cause\0"), + units: Units::None, } .build(), info::Builder { id: 75usize, - name: Str::new("endpoint_datagram_sent.gso_offset\0"), - units: Str::new("\0"), + name: Str::new("mtu_updated.search_complete\0"), + units: Units::None, } .build(), info::Builder { id: 76usize, - name: Str::new("endpoint_datagram_received\0"), - units: Str::new("\0"), + name: Str::new("slow_start_exited\0"), + units: Units::None, } .build(), info::Builder { id: 77usize, - name: Str::new("endpoint_datagram_received.bytes\0"), - units: Str::new("b\0"), + name: Str::new("slow_start_exited.cause\0"), + units: Units::None, } .build(), info::Builder { id: 78usize, - name: Str::new("endpoint_datagram_received.bytes.total\0"), - units: Str::new("b\0"), + name: Str::new("slow_start_exited.congestion_window\0"), + units: Units::Bytes, } .build(), info::Builder { id: 79usize, - name: Str::new("endpoint_datagram_dropped\0"), - units: Str::new("\0"), + name: Str::new("delivery_rate_sampled\0"), + units: Units::None, } .build(), info::Builder { id: 80usize, - name: Str::new("endpoint_datagram_dropped.bytes\0"), - units: Str::new("b\0"), + name: Str::new("pacing_rate_updated\0"), + units: Units::None, } .build(), info::Builder { id: 81usize, - name: Str::new("endpoint_datagram_dropped.bytes.total\0"), - units: Str::new("b\0"), + name: Str::new("pacing_rate_updated.bytes_per_second\0"), + units: Units::Bytes, } .build(), info::Builder { id: 82usize, - name: Str::new("endpoint_connection_attempt_failed\0"), - units: Str::new("\0"), + name: Str::new("pacing_rate_updated.burst_size\0"), + units: Units::Bytes, } .build(), info::Builder { id: 83usize, - name: Str::new("platform_tx\0"), - units: Str::new("\0"), + name: Str::new("pacing_rate_updated.pacing_gain\0"), + units: Units::None, } .build(), info::Builder { id: 84usize, - name: Str::new("platform_tx.packets.total\0"), - units: Str::new("\0"), + name: Str::new("bbr_state_changed\0"), + units: Units::None, } .build(), info::Builder { id: 85usize, - name: Str::new("platform_tx.packets\0"), - units: Str::new("\0"), + name: Str::new("bbr_state_changed.state\0"), + units: Units::None, } .build(), info::Builder { id: 86usize, - name: Str::new("platform_tx.syscalls.total\0"), - units: Str::new("\0"), + name: Str::new("dc_state_changed\0"), + units: Units::None, } .build(), info::Builder { id: 87usize, - name: Str::new("platform_tx.syscalls\0"), - units: Str::new("\0"), + name: Str::new("dc_state_changed.state\0"), + units: Units::None, } .build(), info::Builder { id: 88usize, - name: Str::new("platform_tx.syscalls.blocked.total\0"), - units: Str::new("\0"), + name: Str::new("version_information\0"), + units: Units::None, } .build(), info::Builder { id: 89usize, - name: Str::new("platform_tx.syscalls.blocked\0"), - units: Str::new("\0"), + name: Str::new("endpoint_packet_sent\0"), + units: Units::None, } .build(), info::Builder { id: 90usize, - name: Str::new("platform_tx.errors.total\0"), - units: Str::new("\0"), + name: Str::new("endpoint_packet_received\0"), + units: Units::None, } .build(), info::Builder { id: 91usize, - name: Str::new("platform_tx.errors\0"), - units: Str::new("\0"), + name: Str::new("endpoint_datagram_sent\0"), + units: Units::None, } .build(), info::Builder { id: 92usize, - name: Str::new("platform_tx.errors.dropped.total\0"), - units: Str::new("\0"), + name: Str::new("endpoint_datagram_sent.bytes\0"), + units: Units::Bytes, } .build(), info::Builder { id: 93usize, - name: Str::new("platform_tx.errors.dropped\0"), - units: Str::new("\0"), + name: Str::new("endpoint_datagram_sent.bytes.total\0"), + units: Units::Bytes, } .build(), info::Builder { id: 94usize, - name: Str::new("platform_tx_error\0"), - units: Str::new("\0"), + name: Str::new("endpoint_datagram_sent.gso_offset\0"), + units: Units::None, } .build(), info::Builder { id: 95usize, - name: Str::new("platform_rx\0"), - units: Str::new("\0"), + name: Str::new("endpoint_datagram_received\0"), + units: Units::None, } .build(), info::Builder { id: 96usize, - name: Str::new("platform_rx.packets.total\0"), - units: Str::new("\0"), + name: Str::new("endpoint_datagram_received.bytes\0"), + units: Units::Bytes, } .build(), info::Builder { id: 97usize, - name: Str::new("platform_rx.packets\0"), - units: Str::new("\0"), + name: Str::new("endpoint_datagram_received.bytes.total\0"), + units: Units::Bytes, } .build(), info::Builder { id: 98usize, - name: Str::new("platform_rx.syscalls.total\0"), - units: Str::new("\0"), + name: Str::new("endpoint_datagram_dropped\0"), + units: Units::None, } .build(), info::Builder { id: 99usize, - name: Str::new("platform_rx.syscalls\0"), - units: Str::new("\0"), + name: Str::new("endpoint_datagram_dropped.bytes\0"), + units: Units::Bytes, } .build(), info::Builder { id: 100usize, - name: Str::new("platform_rx.syscalls.blocked.total\0"), - units: Str::new("\0"), + name: Str::new("endpoint_datagram_dropped.bytes.total\0"), + units: Units::Bytes, } .build(), info::Builder { id: 101usize, - name: Str::new("platform_rx.syscalls.blocked\0"), - units: Str::new("\0"), + name: Str::new("endpoint_datagram_dropped.reason\0"), + units: Units::None, } .build(), info::Builder { id: 102usize, - name: Str::new("platform_rx.errors.total\0"), - units: Str::new("\0"), + name: Str::new("endpoint_connection_attempt_failed\0"), + units: Units::None, } .build(), info::Builder { id: 103usize, - name: Str::new("platform_rx.errors\0"), - units: Str::new("\0"), + name: Str::new("endpoint_connection_attempt_failed.error\0"), + units: Units::None, } .build(), info::Builder { id: 104usize, - name: Str::new("platform_rx.errors.dropped.total\0"), - units: Str::new("\0"), + name: Str::new("platform_tx\0"), + units: Units::None, } .build(), info::Builder { id: 105usize, - name: Str::new("platform_rx.errors.dropped\0"), - units: Str::new("\0"), + name: Str::new("platform_tx.packets.total\0"), + units: Units::None, } .build(), info::Builder { id: 106usize, - name: Str::new("platform_rx_error\0"), - units: Str::new("\0"), + name: Str::new("platform_tx.packets\0"), + units: Units::None, } .build(), info::Builder { id: 107usize, - name: Str::new("platform_feature_configured\0"), - units: Str::new("\0"), + name: Str::new("platform_tx.syscalls.total\0"), + units: Units::None, } .build(), info::Builder { id: 108usize, - name: Str::new("platform_event_loop_wakeup\0"), - units: Str::new("\0"), + name: Str::new("platform_tx.syscalls\0"), + units: Units::None, } .build(), info::Builder { id: 109usize, - name: Str::new("platform_event_loop_sleep\0"), - units: Str::new("\0"), + name: Str::new("platform_tx.syscalls.blocked.total\0"), + units: Units::None, } .build(), info::Builder { id: 110usize, - name: Str::new("platform_event_loop_sleep.processing_duration\0"), - units: Str::new("us\0"), + name: Str::new("platform_tx.syscalls.blocked\0"), + units: Units::None, } .build(), info::Builder { id: 111usize, + name: Str::new("platform_tx.errors.total\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 112usize, + name: Str::new("platform_tx.errors\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 113usize, + name: Str::new("platform_tx.errors.dropped.total\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 114usize, + name: Str::new("platform_tx.errors.dropped\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 115usize, + name: Str::new("platform_tx_error\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 116usize, + name: Str::new("platform_rx\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 117usize, + name: Str::new("platform_rx.packets.total\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 118usize, + name: Str::new("platform_rx.packets\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 119usize, + name: Str::new("platform_rx.syscalls.total\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 120usize, + name: Str::new("platform_rx.syscalls\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 121usize, + name: Str::new("platform_rx.syscalls.blocked.total\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 122usize, + name: Str::new("platform_rx.syscalls.blocked\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 123usize, + name: Str::new("platform_rx.errors.total\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 124usize, + name: Str::new("platform_rx.errors\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 125usize, + name: Str::new("platform_rx.errors.dropped.total\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 126usize, + name: Str::new("platform_rx.errors.dropped\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 127usize, + name: Str::new("platform_rx_error\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 128usize, + name: Str::new("platform_feature_configured\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 129usize, + name: Str::new("platform_event_loop_wakeup\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 130usize, + name: Str::new("platform_event_loop_sleep\0"), + units: Units::None, + } + .build(), + info::Builder { + id: 131usize, + name: Str::new("platform_event_loop_sleep.processing_duration\0"), + units: Units::Duration, + } + .build(), + info::Builder { + id: 132usize, name: Str::new("platform_event_loop_started\0"), - units: Str::new("\0"), + units: Units::None, } .build(), ]; @@ -691,7 +817,13 @@ pub struct Subscriber { #[allow(dead_code)] counters: Box<[R::Counter; 74usize]>, #[allow(dead_code)] - measures: Box<[R::Measure; 37usize]>, + bool_counters: Box<[R::BoolCounter; 3usize]>, + #[allow(dead_code)] + nominal_counters: Box<[R::NominalCounter]>, + #[allow(dead_code)] + nominal_offsets: Box<[usize; 17usize]>, + #[allow(dead_code)] + measures: Box<[R::Measure; 38usize]>, #[allow(dead_code)] gauges: Box<[R::Gauge; 0usize]>, #[allow(dead_code)] @@ -715,7 +847,10 @@ impl Subscriber { #[inline] pub fn new(registry: R) -> Self { let mut counters = Vec::with_capacity(74usize); - let mut measures = Vec::with_capacity(37usize); + let mut bool_counters = Vec::with_capacity(3usize); + let mut nominal_offsets = Vec::with_capacity(17usize); + let mut nominal_counters = Vec::with_capacity(17usize); + let mut measures = Vec::with_capacity(38usize); let mut gauges = Vec::with_capacity(0usize); let mut timers = Vec::with_capacity(1usize); counters.push(registry.register_counter(&INFO[0usize])); @@ -727,113 +862,315 @@ impl Subscriber { counters.push(registry.register_counter(&INFO[7usize])); counters.push(registry.register_counter(&INFO[8usize])); counters.push(registry.register_counter(&INFO[9usize])); - counters.push(registry.register_counter(&INFO[10usize])); counters.push(registry.register_counter(&INFO[11usize])); - counters.push(registry.register_counter(&INFO[12usize])); + counters.push(registry.register_counter(&INFO[13usize])); counters.push(registry.register_counter(&INFO[14usize])); - counters.push(registry.register_counter(&INFO[23usize])); - counters.push(registry.register_counter(&INFO[24usize])); - counters.push(registry.register_counter(&INFO[25usize])); - counters.push(registry.register_counter(&INFO[26usize])); + counters.push(registry.register_counter(&INFO[17usize])); counters.push(registry.register_counter(&INFO[27usize])); - counters.push(registry.register_counter(&INFO[28usize])); counters.push(registry.register_counter(&INFO[29usize])); counters.push(registry.register_counter(&INFO[30usize])); counters.push(registry.register_counter(&INFO[31usize])); counters.push(registry.register_counter(&INFO[32usize])); - counters.push(registry.register_counter(&INFO[33usize])); counters.push(registry.register_counter(&INFO[34usize])); counters.push(registry.register_counter(&INFO[35usize])); + counters.push(registry.register_counter(&INFO[37usize])); counters.push(registry.register_counter(&INFO[38usize])); - counters.push(registry.register_counter(&INFO[39usize])); - counters.push(registry.register_counter(&INFO[41usize])); + counters.push(registry.register_counter(&INFO[40usize])); counters.push(registry.register_counter(&INFO[42usize])); + counters.push(registry.register_counter(&INFO[43usize])); counters.push(registry.register_counter(&INFO[44usize])); - counters.push(registry.register_counter(&INFO[45usize])); - counters.push(registry.register_counter(&INFO[46usize])); counters.push(registry.register_counter(&INFO[47usize])); counters.push(registry.register_counter(&INFO[48usize])); - counters.push(registry.register_counter(&INFO[49usize])); counters.push(registry.register_counter(&INFO[50usize])); counters.push(registry.register_counter(&INFO[51usize])); - counters.push(registry.register_counter(&INFO[52usize])); - counters.push(registry.register_counter(&INFO[53usize])); + counters.push(registry.register_counter(&INFO[54usize])); counters.push(registry.register_counter(&INFO[55usize])); - counters.push(registry.register_counter(&INFO[56usize])); - counters.push(registry.register_counter(&INFO[58usize])); + counters.push(registry.register_counter(&INFO[57usize])); counters.push(registry.register_counter(&INFO[59usize])); counters.push(registry.register_counter(&INFO[61usize])); + counters.push(registry.register_counter(&INFO[62usize])); counters.push(registry.register_counter(&INFO[63usize])); counters.push(registry.register_counter(&INFO[64usize])); - counters.push(registry.register_counter(&INFO[67usize])); + counters.push(registry.register_counter(&INFO[65usize])); + counters.push(registry.register_counter(&INFO[66usize])); counters.push(registry.register_counter(&INFO[68usize])); counters.push(registry.register_counter(&INFO[69usize])); - counters.push(registry.register_counter(&INFO[70usize])); counters.push(registry.register_counter(&INFO[71usize])); counters.push(registry.register_counter(&INFO[72usize])); counters.push(registry.register_counter(&INFO[76usize])); counters.push(registry.register_counter(&INFO[79usize])); - counters.push(registry.register_counter(&INFO[82usize])); - counters.push(registry.register_counter(&INFO[83usize])); + counters.push(registry.register_counter(&INFO[80usize])); counters.push(registry.register_counter(&INFO[84usize])); counters.push(registry.register_counter(&INFO[86usize])); counters.push(registry.register_counter(&INFO[88usize])); + counters.push(registry.register_counter(&INFO[89usize])); counters.push(registry.register_counter(&INFO[90usize])); - counters.push(registry.register_counter(&INFO[92usize])); - counters.push(registry.register_counter(&INFO[94usize])); + counters.push(registry.register_counter(&INFO[91usize])); counters.push(registry.register_counter(&INFO[95usize])); - counters.push(registry.register_counter(&INFO[96usize])); counters.push(registry.register_counter(&INFO[98usize])); - counters.push(registry.register_counter(&INFO[100usize])); counters.push(registry.register_counter(&INFO[102usize])); counters.push(registry.register_counter(&INFO[104usize])); - counters.push(registry.register_counter(&INFO[106usize])); + counters.push(registry.register_counter(&INFO[105usize])); counters.push(registry.register_counter(&INFO[107usize])); - counters.push(registry.register_counter(&INFO[108usize])); counters.push(registry.register_counter(&INFO[109usize])); counters.push(registry.register_counter(&INFO[111usize])); + counters.push(registry.register_counter(&INFO[113usize])); + counters.push(registry.register_counter(&INFO[115usize])); + counters.push(registry.register_counter(&INFO[116usize])); + counters.push(registry.register_counter(&INFO[117usize])); + counters.push(registry.register_counter(&INFO[119usize])); + counters.push(registry.register_counter(&INFO[121usize])); + counters.push(registry.register_counter(&INFO[123usize])); + counters.push(registry.register_counter(&INFO[125usize])); + counters.push(registry.register_counter(&INFO[127usize])); + counters.push(registry.register_counter(&INFO[128usize])); + counters.push(registry.register_counter(&INFO[129usize])); + counters.push(registry.register_counter(&INFO[130usize])); + counters.push(registry.register_counter(&INFO[132usize])); + bool_counters.push(registry.register_bool_counter(&INFO[16usize])); + bool_counters.push(registry.register_bool_counter(&INFO[26usize])); + bool_counters.push(registry.register_bool_counter(&INFO[75usize])); + { + #[allow(unused_imports)] + use api::*; + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[10usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[12usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[28usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[33usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[36usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[39usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[41usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[53usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[56usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[58usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[60usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[74usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[77usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[85usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[87usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[101usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + { + let offset = nominal_counters.len(); + let mut count = 0; + for variant in ::VARIANTS.iter() { + nominal_counters + .push(registry.register_nominal_counter(&INFO[103usize], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + nominal_offsets.push(offset); + } + } measures.push(registry.register_measure(&INFO[5usize])); - measures.push(registry.register_measure(&INFO[13usize])); measures.push(registry.register_measure(&INFO[15usize])); - measures.push(registry.register_measure(&INFO[16usize])); - measures.push(registry.register_measure(&INFO[17usize])); measures.push(registry.register_measure(&INFO[18usize])); measures.push(registry.register_measure(&INFO[19usize])); measures.push(registry.register_measure(&INFO[20usize])); measures.push(registry.register_measure(&INFO[21usize])); measures.push(registry.register_measure(&INFO[22usize])); - measures.push(registry.register_measure(&INFO[36usize])); - measures.push(registry.register_measure(&INFO[37usize])); - measures.push(registry.register_measure(&INFO[40usize])); - measures.push(registry.register_measure(&INFO[43usize])); - measures.push(registry.register_measure(&INFO[54usize])); - measures.push(registry.register_measure(&INFO[57usize])); - measures.push(registry.register_measure(&INFO[60usize])); - measures.push(registry.register_measure(&INFO[62usize])); - measures.push(registry.register_measure(&INFO[65usize])); - measures.push(registry.register_measure(&INFO[66usize])); + measures.push(registry.register_measure(&INFO[23usize])); + measures.push(registry.register_measure(&INFO[24usize])); + measures.push(registry.register_measure(&INFO[25usize])); + measures.push(registry.register_measure(&INFO[45usize])); + measures.push(registry.register_measure(&INFO[46usize])); + measures.push(registry.register_measure(&INFO[49usize])); + measures.push(registry.register_measure(&INFO[52usize])); + measures.push(registry.register_measure(&INFO[67usize])); + measures.push(registry.register_measure(&INFO[70usize])); measures.push(registry.register_measure(&INFO[73usize])); - measures.push(registry.register_measure(&INFO[74usize])); - measures.push(registry.register_measure(&INFO[75usize])); - measures.push(registry.register_measure(&INFO[77usize])); measures.push(registry.register_measure(&INFO[78usize])); - measures.push(registry.register_measure(&INFO[80usize])); measures.push(registry.register_measure(&INFO[81usize])); - measures.push(registry.register_measure(&INFO[85usize])); - measures.push(registry.register_measure(&INFO[87usize])); - measures.push(registry.register_measure(&INFO[89usize])); - measures.push(registry.register_measure(&INFO[91usize])); + measures.push(registry.register_measure(&INFO[82usize])); + measures.push(registry.register_measure(&INFO[83usize])); + measures.push(registry.register_measure(&INFO[92usize])); measures.push(registry.register_measure(&INFO[93usize])); + measures.push(registry.register_measure(&INFO[94usize])); + measures.push(registry.register_measure(&INFO[96usize])); measures.push(registry.register_measure(&INFO[97usize])); measures.push(registry.register_measure(&INFO[99usize])); - measures.push(registry.register_measure(&INFO[101usize])); - measures.push(registry.register_measure(&INFO[103usize])); - measures.push(registry.register_measure(&INFO[105usize])); - timers.push(registry.register_timer(&INFO[110usize])); + measures.push(registry.register_measure(&INFO[100usize])); + measures.push(registry.register_measure(&INFO[106usize])); + measures.push(registry.register_measure(&INFO[108usize])); + measures.push(registry.register_measure(&INFO[110usize])); + measures.push(registry.register_measure(&INFO[112usize])); + measures.push(registry.register_measure(&INFO[114usize])); + measures.push(registry.register_measure(&INFO[118usize])); + measures.push(registry.register_measure(&INFO[120usize])); + measures.push(registry.register_measure(&INFO[122usize])); + measures.push(registry.register_measure(&INFO[124usize])); + measures.push(registry.register_measure(&INFO[126usize])); + timers.push(registry.register_timer(&INFO[131usize])); Self { counters: counters .try_into() .unwrap_or_else(|_| panic!("invalid len")), + bool_counters: bool_counters + .try_into() + .unwrap_or_else(|_| panic!("invalid len")), + nominal_counters: nominal_counters.into(), + nominal_offsets: nominal_offsets + .try_into() + .unwrap_or_else(|_| panic!("invalid len")), measures: measures .try_into() .unwrap_or_else(|_| panic!("invalid len")), @@ -858,81 +1195,224 @@ impl Subscriber { 6usize => (&INFO[7usize], entry), 7usize => (&INFO[8usize], entry), 8usize => (&INFO[9usize], entry), - 9usize => (&INFO[10usize], entry), - 10usize => (&INFO[11usize], entry), - 11usize => (&INFO[12usize], entry), - 12usize => (&INFO[14usize], entry), - 13usize => (&INFO[23usize], entry), - 14usize => (&INFO[24usize], entry), - 15usize => (&INFO[25usize], entry), - 16usize => (&INFO[26usize], entry), - 17usize => (&INFO[27usize], entry), - 18usize => (&INFO[28usize], entry), - 19usize => (&INFO[29usize], entry), - 20usize => (&INFO[30usize], entry), - 21usize => (&INFO[31usize], entry), - 22usize => (&INFO[32usize], entry), - 23usize => (&INFO[33usize], entry), - 24usize => (&INFO[34usize], entry), - 25usize => (&INFO[35usize], entry), - 26usize => (&INFO[38usize], entry), - 27usize => (&INFO[39usize], entry), - 28usize => (&INFO[41usize], entry), - 29usize => (&INFO[42usize], entry), - 30usize => (&INFO[44usize], entry), - 31usize => (&INFO[45usize], entry), - 32usize => (&INFO[46usize], entry), - 33usize => (&INFO[47usize], entry), - 34usize => (&INFO[48usize], entry), - 35usize => (&INFO[49usize], entry), - 36usize => (&INFO[50usize], entry), - 37usize => (&INFO[51usize], entry), - 38usize => (&INFO[52usize], entry), - 39usize => (&INFO[53usize], entry), - 40usize => (&INFO[55usize], entry), - 41usize => (&INFO[56usize], entry), - 42usize => (&INFO[58usize], entry), - 43usize => (&INFO[59usize], entry), - 44usize => (&INFO[61usize], entry), - 45usize => (&INFO[63usize], entry), - 46usize => (&INFO[64usize], entry), - 47usize => (&INFO[67usize], entry), - 48usize => (&INFO[68usize], entry), - 49usize => (&INFO[69usize], entry), - 50usize => (&INFO[70usize], entry), - 51usize => (&INFO[71usize], entry), - 52usize => (&INFO[72usize], entry), - 53usize => (&INFO[76usize], entry), - 54usize => (&INFO[79usize], entry), - 55usize => (&INFO[82usize], entry), - 56usize => (&INFO[83usize], entry), - 57usize => (&INFO[84usize], entry), - 58usize => (&INFO[86usize], entry), - 59usize => (&INFO[88usize], entry), - 60usize => (&INFO[90usize], entry), - 61usize => (&INFO[92usize], entry), - 62usize => (&INFO[94usize], entry), - 63usize => (&INFO[95usize], entry), - 64usize => (&INFO[96usize], entry), - 65usize => (&INFO[98usize], entry), - 66usize => (&INFO[100usize], entry), - 67usize => (&INFO[102usize], entry), - 68usize => (&INFO[104usize], entry), - 69usize => (&INFO[106usize], entry), - 70usize => (&INFO[107usize], entry), - 71usize => (&INFO[108usize], entry), - 72usize => (&INFO[109usize], entry), - 73usize => (&INFO[111usize], entry), + 9usize => (&INFO[11usize], entry), + 10usize => (&INFO[13usize], entry), + 11usize => (&INFO[14usize], entry), + 12usize => (&INFO[17usize], entry), + 13usize => (&INFO[27usize], entry), + 14usize => (&INFO[29usize], entry), + 15usize => (&INFO[30usize], entry), + 16usize => (&INFO[31usize], entry), + 17usize => (&INFO[32usize], entry), + 18usize => (&INFO[34usize], entry), + 19usize => (&INFO[35usize], entry), + 20usize => (&INFO[37usize], entry), + 21usize => (&INFO[38usize], entry), + 22usize => (&INFO[40usize], entry), + 23usize => (&INFO[42usize], entry), + 24usize => (&INFO[43usize], entry), + 25usize => (&INFO[44usize], entry), + 26usize => (&INFO[47usize], entry), + 27usize => (&INFO[48usize], entry), + 28usize => (&INFO[50usize], entry), + 29usize => (&INFO[51usize], entry), + 30usize => (&INFO[54usize], entry), + 31usize => (&INFO[55usize], entry), + 32usize => (&INFO[57usize], entry), + 33usize => (&INFO[59usize], entry), + 34usize => (&INFO[61usize], entry), + 35usize => (&INFO[62usize], entry), + 36usize => (&INFO[63usize], entry), + 37usize => (&INFO[64usize], entry), + 38usize => (&INFO[65usize], entry), + 39usize => (&INFO[66usize], entry), + 40usize => (&INFO[68usize], entry), + 41usize => (&INFO[69usize], entry), + 42usize => (&INFO[71usize], entry), + 43usize => (&INFO[72usize], entry), + 44usize => (&INFO[76usize], entry), + 45usize => (&INFO[79usize], entry), + 46usize => (&INFO[80usize], entry), + 47usize => (&INFO[84usize], entry), + 48usize => (&INFO[86usize], entry), + 49usize => (&INFO[88usize], entry), + 50usize => (&INFO[89usize], entry), + 51usize => (&INFO[90usize], entry), + 52usize => (&INFO[91usize], entry), + 53usize => (&INFO[95usize], entry), + 54usize => (&INFO[98usize], entry), + 55usize => (&INFO[102usize], entry), + 56usize => (&INFO[104usize], entry), + 57usize => (&INFO[105usize], entry), + 58usize => (&INFO[107usize], entry), + 59usize => (&INFO[109usize], entry), + 60usize => (&INFO[111usize], entry), + 61usize => (&INFO[113usize], entry), + 62usize => (&INFO[115usize], entry), + 63usize => (&INFO[116usize], entry), + 64usize => (&INFO[117usize], entry), + 65usize => (&INFO[119usize], entry), + 66usize => (&INFO[121usize], entry), + 67usize => (&INFO[123usize], entry), + 68usize => (&INFO[125usize], entry), + 69usize => (&INFO[127usize], entry), + 70usize => (&INFO[128usize], entry), + 71usize => (&INFO[129usize], entry), + 72usize => (&INFO[130usize], entry), + 73usize => (&INFO[132usize], entry), _ => unsafe { core::hint::unreachable_unchecked() }, }) } #[allow(dead_code)] #[inline(always)] - fn count(&self, info: usize, id: usize, value: u64) { + fn count(&self, info: usize, id: usize, value: T) { let info = &INFO[info]; let counter = &self.counters[id]; counter.record(info, value); } + #[doc = r" Returns all of the registered bool counters"] + #[inline] + pub fn bool_counters(&self) -> impl Iterator + '_ { + self.bool_counters + .iter() + .enumerate() + .map(|(idx, entry)| match idx { + 0usize => (&INFO[16usize], entry), + 1usize => (&INFO[26usize], entry), + 2usize => (&INFO[75usize], entry), + _ => unsafe { core::hint::unreachable_unchecked() }, + }) + } + #[allow(dead_code)] + #[inline(always)] + fn count_bool(&self, info: usize, id: usize, value: bool) { + let info = &INFO[info]; + let counter = &self.bool_counters[id]; + counter.record(info, value); + } + #[doc = r" Returns all of the registered nominal counters"] + #[inline] + pub fn nominal_counters( + &self, + ) -> impl Iterator + '_ { + use api::*; + self.nominal_offsets + .iter() + .enumerate() + .map(|(idx, entry)| match idx { + 0usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[10usize], entries, variants) + } + 1usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[12usize], entries, variants) + } + 2usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[28usize], entries, variants) + } + 3usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[33usize], entries, variants) + } + 4usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[36usize], entries, variants) + } + 5usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[39usize], entries, variants) + } + 6usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[41usize], entries, variants) + } + 7usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[53usize], entries, variants) + } + 8usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[56usize], entries, variants) + } + 9usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[58usize], entries, variants) + } + 10usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[60usize], entries, variants) + } + 11usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[74usize], entries, variants) + } + 12usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[77usize], entries, variants) + } + 13usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[85usize], entries, variants) + } + 14usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[87usize], entries, variants) + } + 15usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[101usize], entries, variants) + } + 16usize => { + let offset = *entry; + let variants = ::VARIANTS; + let entries = &self.nominal_counters[offset..offset + variants.len()]; + (&INFO[103usize], entries, variants) + } + _ => unsafe { core::hint::unreachable_unchecked() }, + }) + } + #[allow(dead_code)] + #[inline(always)] + fn count_nominal(&self, info: usize, id: usize, value: &T) { + let info = &INFO[info]; + let idx = self.nominal_offsets[id] + value.variant_idx(); + let counter = &self.nominal_counters[idx]; + counter.record(info, value.as_variant(), 1usize); + } #[doc = r" Returns all of the registered measures"] #[inline] pub fn measures(&self) -> impl Iterator + '_ { @@ -941,48 +1421,49 @@ impl Subscriber { .enumerate() .map(|(idx, entry)| match idx { 0usize => (&INFO[5usize], entry), - 1usize => (&INFO[13usize], entry), - 2usize => (&INFO[15usize], entry), - 3usize => (&INFO[16usize], entry), - 4usize => (&INFO[17usize], entry), - 5usize => (&INFO[18usize], entry), - 6usize => (&INFO[19usize], entry), - 7usize => (&INFO[20usize], entry), - 8usize => (&INFO[21usize], entry), - 9usize => (&INFO[22usize], entry), - 10usize => (&INFO[36usize], entry), - 11usize => (&INFO[37usize], entry), - 12usize => (&INFO[40usize], entry), - 13usize => (&INFO[43usize], entry), - 14usize => (&INFO[54usize], entry), - 15usize => (&INFO[57usize], entry), - 16usize => (&INFO[60usize], entry), - 17usize => (&INFO[62usize], entry), - 18usize => (&INFO[65usize], entry), - 19usize => (&INFO[66usize], entry), - 20usize => (&INFO[73usize], entry), - 21usize => (&INFO[74usize], entry), - 22usize => (&INFO[75usize], entry), - 23usize => (&INFO[77usize], entry), - 24usize => (&INFO[78usize], entry), - 25usize => (&INFO[80usize], entry), - 26usize => (&INFO[81usize], entry), - 27usize => (&INFO[85usize], entry), - 28usize => (&INFO[87usize], entry), - 29usize => (&INFO[89usize], entry), - 30usize => (&INFO[91usize], entry), - 31usize => (&INFO[93usize], entry), - 32usize => (&INFO[97usize], entry), - 33usize => (&INFO[99usize], entry), - 34usize => (&INFO[101usize], entry), - 35usize => (&INFO[103usize], entry), - 36usize => (&INFO[105usize], entry), + 1usize => (&INFO[15usize], entry), + 2usize => (&INFO[18usize], entry), + 3usize => (&INFO[19usize], entry), + 4usize => (&INFO[20usize], entry), + 5usize => (&INFO[21usize], entry), + 6usize => (&INFO[22usize], entry), + 7usize => (&INFO[23usize], entry), + 8usize => (&INFO[24usize], entry), + 9usize => (&INFO[25usize], entry), + 10usize => (&INFO[45usize], entry), + 11usize => (&INFO[46usize], entry), + 12usize => (&INFO[49usize], entry), + 13usize => (&INFO[52usize], entry), + 14usize => (&INFO[67usize], entry), + 15usize => (&INFO[70usize], entry), + 16usize => (&INFO[73usize], entry), + 17usize => (&INFO[78usize], entry), + 18usize => (&INFO[81usize], entry), + 19usize => (&INFO[82usize], entry), + 20usize => (&INFO[83usize], entry), + 21usize => (&INFO[92usize], entry), + 22usize => (&INFO[93usize], entry), + 23usize => (&INFO[94usize], entry), + 24usize => (&INFO[96usize], entry), + 25usize => (&INFO[97usize], entry), + 26usize => (&INFO[99usize], entry), + 27usize => (&INFO[100usize], entry), + 28usize => (&INFO[106usize], entry), + 29usize => (&INFO[108usize], entry), + 30usize => (&INFO[110usize], entry), + 31usize => (&INFO[112usize], entry), + 32usize => (&INFO[114usize], entry), + 33usize => (&INFO[118usize], entry), + 34usize => (&INFO[120usize], entry), + 35usize => (&INFO[122usize], entry), + 36usize => (&INFO[124usize], entry), + 37usize => (&INFO[126usize], entry), _ => unsafe { core::hint::unreachable_unchecked() }, }) } #[allow(dead_code)] #[inline(always)] - fn measure(&self, info: usize, id: usize, value: u64) { + fn measure(&self, info: usize, id: usize, value: T) { let info = &INFO[info]; let measure = &self.measures[id]; measure.record(info, value); @@ -994,7 +1475,7 @@ impl Subscriber { } #[allow(dead_code)] #[inline(always)] - fn gauge(&self, info: usize, id: usize, value: u64) { + fn gauge(&self, info: usize, id: usize, value: T) { let info = &INFO[info]; let gauge = &self.gauges[id]; gauge.record(info, value); @@ -1006,13 +1487,13 @@ impl Subscriber { .iter() .enumerate() .map(|(idx, entry)| match idx { - 0usize => (&INFO[110usize], entry), + 0usize => (&INFO[131usize], entry), _ => unsafe { core::hint::unreachable_unchecked() }, }) } #[allow(dead_code)] #[inline(always)] - fn time(&self, info: usize, id: usize, value: u64) { + fn time(&self, info: usize, id: usize, value: core::time::Duration) { let info = &INFO[info]; let timer = &self.timers[id]; timer.record(info, value); @@ -1033,7 +1514,7 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::ApplicationProtocolInformation, ) { - self.count(0usize, 0usize, 1); + self.count(0usize, 0usize, 1usize); let _ = context; let _ = meta; let _ = event; @@ -1045,7 +1526,7 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::ServerNameInformation, ) { - self.count(1usize, 1usize, 1); + self.count(1usize, 1usize, 1usize); let _ = context; let _ = meta; let _ = event; @@ -1057,7 +1538,7 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::PacketSkipped, ) { - self.count(2usize, 2usize, 1); + self.count(2usize, 2usize, 1usize); let _ = context; let _ = meta; let _ = event; @@ -1069,9 +1550,9 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::PacketSent, ) { - self.count(3usize, 3usize, 1); - self.count(4usize, 4usize, event.packet_len.as_metric("b")); - self.measure(5usize, 0usize, event.packet_len.as_metric("b")); + self.count(3usize, 3usize, 1usize); + self.count(4usize, 4usize, event.packet_len); + self.measure(5usize, 0usize, event.packet_len); let _ = context; let _ = meta; let _ = event; @@ -1083,7 +1564,7 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::PacketReceived, ) { - self.count(6usize, 5usize, 1); + self.count(6usize, 5usize, 1usize); let _ = context; let _ = meta; let _ = event; @@ -1095,7 +1576,7 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::ActivePathUpdated, ) { - self.count(7usize, 6usize, 1); + self.count(7usize, 6usize, 1usize); let _ = context; let _ = meta; let _ = event; @@ -1107,7 +1588,7 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::PathCreated, ) { - self.count(8usize, 7usize, 1); + self.count(8usize, 7usize, 1usize); let _ = context; let _ = meta; let _ = event; @@ -1119,7 +1600,8 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::FrameSent, ) { - self.count(9usize, 8usize, 1); + self.count(9usize, 8usize, 1usize); + self.count_nominal(10usize, 0usize, &event.frame); let _ = context; let _ = meta; let _ = event; @@ -1131,7 +1613,8 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::FrameReceived, ) { - self.count(10usize, 9usize, 1); + self.count(11usize, 9usize, 1usize); + self.count_nominal(12usize, 1usize, &event.frame); let _ = context; let _ = meta; let _ = event; @@ -1143,9 +1626,10 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::PacketLost, ) { - self.count(11usize, 10usize, 1); - self.count(12usize, 11usize, event.bytes_lost.as_metric("b")); - self.measure(13usize, 1usize, event.bytes_lost.as_metric("b")); + self.count(13usize, 10usize, 1usize); + self.count(14usize, 11usize, event.bytes_lost); + self.measure(15usize, 1usize, event.bytes_lost); + self.count_bool(16usize, 0usize, event.is_mtu_probe); let _ = context; let _ = meta; let _ = event; @@ -1157,15 +1641,16 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::RecoveryMetrics, ) { - self.count(14usize, 12usize, 1); - self.measure(15usize, 2usize, event.min_rtt.as_metric("us")); - self.measure(16usize, 3usize, event.smoothed_rtt.as_metric("us")); - self.measure(17usize, 4usize, event.latest_rtt.as_metric("us")); - self.measure(18usize, 5usize, event.rtt_variance.as_metric("us")); - self.measure(19usize, 6usize, event.max_ack_delay.as_metric("us")); - self.measure(20usize, 7usize, event.pto_count.as_metric("")); - self.measure(21usize, 8usize, event.congestion_window.as_metric("b")); - self.measure(22usize, 9usize, event.bytes_in_flight.as_metric("b")); + self.count(17usize, 12usize, 1usize); + self.measure(18usize, 2usize, event.min_rtt); + self.measure(19usize, 3usize, event.smoothed_rtt); + self.measure(20usize, 4usize, event.latest_rtt); + self.measure(21usize, 5usize, event.rtt_variance); + self.measure(22usize, 6usize, event.max_ack_delay); + self.measure(23usize, 7usize, event.pto_count); + self.measure(24usize, 8usize, event.congestion_window); + self.measure(25usize, 9usize, event.bytes_in_flight); + self.count_bool(26usize, 1usize, event.congestion_limited); let _ = context; let _ = meta; let _ = event; @@ -1177,7 +1662,8 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::Congestion, ) { - self.count(23usize, 13usize, 1); + self.count(27usize, 13usize, 1usize); + self.count_nominal(28usize, 2usize, &event.source); let _ = context; let _ = meta; let _ = event; @@ -1189,7 +1675,7 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::RxAckRangeDropped, ) { - self.count(24usize, 14usize, 1); + self.count(29usize, 14usize, 1usize); let _ = context; let _ = meta; let _ = event; @@ -1201,7 +1687,7 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::AckRangeReceived, ) { - self.count(25usize, 15usize, 1); + self.count(30usize, 15usize, 1usize); let _ = context; let _ = meta; let _ = event; @@ -1213,7 +1699,7 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::AckRangeSent, ) { - self.count(26usize, 16usize, 1); + self.count(31usize, 16usize, 1usize); let _ = context; let _ = meta; let _ = event; @@ -1225,7 +1711,8 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::PacketDropped, ) { - self.count(27usize, 17usize, 1); + self.count(32usize, 17usize, 1usize); + self.count_nominal(33usize, 3usize, &event.reason); let _ = context; let _ = meta; let _ = event; @@ -1237,7 +1724,7 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::KeyUpdate, ) { - self.count(28usize, 18usize, 1); + self.count(34usize, 18usize, 1usize); let _ = context; let _ = meta; let _ = event; @@ -1249,7 +1736,8 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::KeySpaceDiscarded, ) { - self.count(29usize, 19usize, 1); + self.count(35usize, 19usize, 1usize); + self.count_nominal(36usize, 4usize, &event.space); let _ = context; let _ = meta; let _ = event; @@ -1261,7 +1749,7 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::ConnectionStarted, ) { - self.count(30usize, 20usize, 1); + self.count(37usize, 20usize, 1usize); let _ = context; let _ = meta; let _ = event; @@ -1273,7 +1761,8 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::ConnectionClosed, ) { - self.count(31usize, 21usize, 1); + self.count(38usize, 21usize, 1usize); + self.count_nominal(39usize, 5usize, &event.error); let _ = context; let _ = meta; let _ = event; @@ -1285,7 +1774,8 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::DuplicatePacket, ) { - self.count(32usize, 22usize, 1); + self.count(40usize, 22usize, 1usize); + self.count_nominal(41usize, 6usize, &event.error); let _ = context; let _ = meta; let _ = event; @@ -1297,7 +1787,7 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::TransportParametersReceived, ) { - self.count(33usize, 23usize, 1); + self.count(42usize, 23usize, 1usize); let _ = context; let _ = meta; let _ = event; @@ -1309,10 +1799,10 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::DatagramSent, ) { - self.count(34usize, 24usize, 1); - self.count(35usize, 25usize, event.len.as_metric("b")); - self.measure(36usize, 10usize, event.len.as_metric("b")); - self.measure(37usize, 11usize, event.gso_offset.as_metric("")); + self.count(43usize, 24usize, 1usize); + self.count(44usize, 25usize, event.len); + self.measure(45usize, 10usize, event.len); + self.measure(46usize, 11usize, event.gso_offset); let _ = context; let _ = meta; let _ = event; @@ -1324,9 +1814,9 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::DatagramReceived, ) { - self.count(38usize, 26usize, 1); - self.count(39usize, 27usize, event.len.as_metric("b")); - self.measure(40usize, 12usize, event.len.as_metric("b")); + self.count(47usize, 26usize, 1usize); + self.count(48usize, 27usize, event.len); + self.measure(49usize, 12usize, event.len); let _ = context; let _ = meta; let _ = event; @@ -1338,9 +1828,10 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::DatagramDropped, ) { - self.count(41usize, 28usize, 1); - self.count(42usize, 29usize, event.len.as_metric("b")); - self.measure(43usize, 13usize, event.len.as_metric("b")); + self.count(50usize, 28usize, 1usize); + self.count(51usize, 29usize, event.len); + self.measure(52usize, 13usize, event.len); + self.count_nominal(53usize, 7usize, &event.reason); let _ = context; let _ = meta; let _ = event; @@ -1352,7 +1843,7 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::ConnectionIdUpdated, ) { - self.count(44usize, 30usize, 1); + self.count(54usize, 30usize, 1usize); let _ = context; let _ = meta; let _ = event; @@ -1364,7 +1855,8 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::EcnStateChanged, ) { - self.count(45usize, 31usize, 1); + self.count(55usize, 31usize, 1usize); + self.count_nominal(56usize, 8usize, &event.state); let _ = context; let _ = meta; let _ = event; @@ -1376,7 +1868,8 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::ConnectionMigrationDenied, ) { - self.count(46usize, 32usize, 1); + self.count(57usize, 32usize, 1usize); + self.count_nominal(58usize, 9usize, &event.reason); let _ = context; let _ = meta; let _ = event; @@ -1388,7 +1881,8 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::HandshakeStatusUpdated, ) { - self.count(47usize, 33usize, 1); + self.count(59usize, 33usize, 1usize); + self.count_nominal(60usize, 10usize, &event.status); let _ = context; let _ = meta; let _ = event; @@ -1400,7 +1894,7 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::TlsExporterReady, ) { - self.count(48usize, 34usize, 1); + self.count(61usize, 34usize, 1usize); let _ = context; let _ = meta; let _ = event; @@ -1412,7 +1906,7 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::PathChallengeUpdated, ) { - self.count(49usize, 35usize, 1); + self.count(62usize, 35usize, 1usize); let _ = context; let _ = meta; let _ = event; @@ -1424,7 +1918,7 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::TlsClientHello, ) { - self.count(50usize, 36usize, 1); + self.count(63usize, 36usize, 1usize); let _ = context; let _ = meta; let _ = event; @@ -1436,7 +1930,7 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::TlsServerHello, ) { - self.count(51usize, 37usize, 1); + self.count(64usize, 37usize, 1usize); let _ = context; let _ = meta; let _ = event; @@ -1448,9 +1942,9 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::RxStreamProgress, ) { - self.count(52usize, 38usize, 1); - self.count(53usize, 39usize, event.bytes.as_metric("b")); - self.measure(54usize, 14usize, event.bytes.as_metric("b")); + self.count(65usize, 38usize, 1usize); + self.count(66usize, 39usize, event.bytes); + self.measure(67usize, 14usize, event.bytes); let _ = context; let _ = meta; let _ = event; @@ -1462,9 +1956,9 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::TxStreamProgress, ) { - self.count(55usize, 40usize, 1); - self.count(56usize, 41usize, event.bytes.as_metric("b")); - self.measure(57usize, 15usize, event.bytes.as_metric("b")); + self.count(68usize, 40usize, 1usize); + self.count(69usize, 41usize, event.bytes); + self.measure(70usize, 15usize, event.bytes); let _ = context; let _ = meta; let _ = event; @@ -1476,7 +1970,7 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::KeepAliveTimerExpired, ) { - self.count(58usize, 42usize, 1); + self.count(71usize, 42usize, 1usize); let _ = context; let _ = meta; let _ = event; @@ -1488,8 +1982,10 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::MtuUpdated, ) { - self.count(59usize, 43usize, 1); - self.measure(60usize, 16usize, event.mtu.as_metric("b")); + self.count(72usize, 43usize, 1usize); + self.measure(73usize, 16usize, event.mtu); + self.count_nominal(74usize, 11usize, &event.cause); + self.count_bool(75usize, 2usize, event.search_complete); let _ = context; let _ = meta; let _ = event; @@ -1501,8 +1997,9 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::SlowStartExited, ) { - self.count(61usize, 44usize, 1); - self.measure(62usize, 17usize, event.congestion_window.as_metric("b")); + self.count(76usize, 44usize, 1usize); + self.count_nominal(77usize, 12usize, &event.cause); + self.measure(78usize, 17usize, event.congestion_window); let _ = context; let _ = meta; let _ = event; @@ -1514,7 +2011,7 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::DeliveryRateSampled, ) { - self.count(63usize, 45usize, 1); + self.count(79usize, 45usize, 1usize); let _ = context; let _ = meta; let _ = event; @@ -1526,9 +2023,10 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::PacingRateUpdated, ) { - self.count(64usize, 46usize, 1); - self.measure(65usize, 18usize, event.bytes_per_second.as_metric("b")); - self.measure(66usize, 19usize, event.burst_size.as_metric("b")); + self.count(80usize, 46usize, 1usize); + self.measure(81usize, 18usize, event.bytes_per_second); + self.measure(82usize, 19usize, event.burst_size); + self.measure(83usize, 20usize, event.pacing_gain); let _ = context; let _ = meta; let _ = event; @@ -1540,7 +2038,8 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::BbrStateChanged, ) { - self.count(67usize, 47usize, 1); + self.count(84usize, 47usize, 1usize); + self.count_nominal(85usize, 13usize, &event.state); let _ = context; let _ = meta; let _ = event; @@ -1552,7 +2051,8 @@ impl event::Subscriber for Subscriber { meta: &api::ConnectionMeta, event: &api::DcStateChanged, ) { - self.count(68usize, 48usize, 1); + self.count(86usize, 48usize, 1usize); + self.count_nominal(87usize, 14usize, &event.state); let _ = context; let _ = meta; let _ = event; @@ -1563,7 +2063,7 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::VersionInformation, ) { - self.count(69usize, 49usize, 1); + self.count(88usize, 49usize, 1usize); let _ = event; let _ = meta; } @@ -1573,7 +2073,7 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::EndpointPacketSent, ) { - self.count(70usize, 50usize, 1); + self.count(89usize, 50usize, 1usize); let _ = event; let _ = meta; } @@ -1583,7 +2083,7 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::EndpointPacketReceived, ) { - self.count(71usize, 51usize, 1); + self.count(90usize, 51usize, 1usize); let _ = event; let _ = meta; } @@ -1593,10 +2093,10 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::EndpointDatagramSent, ) { - self.count(72usize, 52usize, 1); - self.measure(73usize, 20usize, event.len.as_metric("b")); - self.measure(74usize, 21usize, event.len.as_metric("b")); - self.measure(75usize, 22usize, event.gso_offset.as_metric("")); + self.count(91usize, 52usize, 1usize); + self.measure(92usize, 21usize, event.len); + self.measure(93usize, 22usize, event.len); + self.measure(94usize, 23usize, event.gso_offset); let _ = event; let _ = meta; } @@ -1606,9 +2106,9 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::EndpointDatagramReceived, ) { - self.count(76usize, 53usize, 1); - self.measure(77usize, 23usize, event.len.as_metric("b")); - self.measure(78usize, 24usize, event.len.as_metric("b")); + self.count(95usize, 53usize, 1usize); + self.measure(96usize, 24usize, event.len); + self.measure(97usize, 25usize, event.len); let _ = event; let _ = meta; } @@ -1618,9 +2118,10 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::EndpointDatagramDropped, ) { - self.count(79usize, 54usize, 1); - self.measure(80usize, 25usize, event.len.as_metric("b")); - self.measure(81usize, 26usize, event.len.as_metric("b")); + self.count(98usize, 54usize, 1usize); + self.measure(99usize, 26usize, event.len); + self.measure(100usize, 27usize, event.len); + self.count_nominal(101usize, 15usize, &event.reason); let _ = event; let _ = meta; } @@ -1630,51 +2131,52 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::EndpointConnectionAttemptFailed, ) { - self.count(82usize, 55usize, 1); + self.count(102usize, 55usize, 1usize); + self.count_nominal(103usize, 16usize, &event.error); let _ = event; let _ = meta; } #[inline] fn on_platform_tx(&mut self, meta: &api::EndpointMeta, event: &api::PlatformTx) { - self.count(83usize, 56usize, 1); - self.count(84usize, 57usize, event.count.as_metric("")); - self.measure(85usize, 27usize, event.count.as_metric("")); - self.count(86usize, 58usize, event.syscalls.as_metric("")); - self.measure(87usize, 28usize, event.syscalls.as_metric("")); - self.count(88usize, 59usize, event.blocked_syscalls.as_metric("")); - self.measure(89usize, 29usize, event.blocked_syscalls.as_metric("")); - self.count(90usize, 60usize, event.total_errors.as_metric("")); - self.measure(91usize, 30usize, event.total_errors.as_metric("")); - self.count(92usize, 61usize, event.dropped_errors.as_metric("")); - self.measure(93usize, 31usize, event.dropped_errors.as_metric("")); + self.count(104usize, 56usize, 1usize); + self.count(105usize, 57usize, event.count); + self.measure(106usize, 28usize, event.count); + self.count(107usize, 58usize, event.syscalls); + self.measure(108usize, 29usize, event.syscalls); + self.count(109usize, 59usize, event.blocked_syscalls); + self.measure(110usize, 30usize, event.blocked_syscalls); + self.count(111usize, 60usize, event.total_errors); + self.measure(112usize, 31usize, event.total_errors); + self.count(113usize, 61usize, event.dropped_errors); + self.measure(114usize, 32usize, event.dropped_errors); let _ = event; let _ = meta; } #[inline] fn on_platform_tx_error(&mut self, meta: &api::EndpointMeta, event: &api::PlatformTxError) { - self.count(94usize, 62usize, 1); + self.count(115usize, 62usize, 1usize); let _ = event; let _ = meta; } #[inline] fn on_platform_rx(&mut self, meta: &api::EndpointMeta, event: &api::PlatformRx) { - self.count(95usize, 63usize, 1); - self.count(96usize, 64usize, event.count.as_metric("")); - self.measure(97usize, 32usize, event.count.as_metric("")); - self.count(98usize, 65usize, event.syscalls.as_metric("")); - self.measure(99usize, 33usize, event.syscalls.as_metric("")); - self.count(100usize, 66usize, event.blocked_syscalls.as_metric("")); - self.measure(101usize, 34usize, event.blocked_syscalls.as_metric("")); - self.count(102usize, 67usize, event.total_errors.as_metric("")); - self.measure(103usize, 35usize, event.total_errors.as_metric("")); - self.count(104usize, 68usize, event.dropped_errors.as_metric("")); - self.measure(105usize, 36usize, event.dropped_errors.as_metric("")); + self.count(116usize, 63usize, 1usize); + self.count(117usize, 64usize, event.count); + self.measure(118usize, 33usize, event.count); + self.count(119usize, 65usize, event.syscalls); + self.measure(120usize, 34usize, event.syscalls); + self.count(121usize, 66usize, event.blocked_syscalls); + self.measure(122usize, 35usize, event.blocked_syscalls); + self.count(123usize, 67usize, event.total_errors); + self.measure(124usize, 36usize, event.total_errors); + self.count(125usize, 68usize, event.dropped_errors); + self.measure(126usize, 37usize, event.dropped_errors); let _ = event; let _ = meta; } #[inline] fn on_platform_rx_error(&mut self, meta: &api::EndpointMeta, event: &api::PlatformRxError) { - self.count(106usize, 69usize, 1); + self.count(127usize, 69usize, 1usize); let _ = event; let _ = meta; } @@ -1684,7 +2186,7 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::PlatformFeatureConfigured, ) { - self.count(107usize, 70usize, 1); + self.count(128usize, 70usize, 1usize); let _ = event; let _ = meta; } @@ -1694,7 +2196,7 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::PlatformEventLoopWakeup, ) { - self.count(108usize, 71usize, 1); + self.count(129usize, 71usize, 1usize); let _ = event; let _ = meta; } @@ -1704,8 +2206,8 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::PlatformEventLoopSleep, ) { - self.count(109usize, 72usize, 1); - self.time(110usize, 0usize, event.processing_duration.as_metric("us")); + self.count(130usize, 72usize, 1usize); + self.time(131usize, 0usize, event.processing_duration); let _ = event; let _ = meta; } @@ -1715,7 +2217,7 @@ impl event::Subscriber for Subscriber { meta: &api::EndpointMeta, event: &api::PlatformEventLoopStarted, ) { - self.count(111usize, 73usize, 1); + self.count(132usize, 73usize, 1usize); let _ = event; let _ = meta; } diff --git a/quic/s2n-quic-core/src/event/generated/metrics/probe.rs b/quic/s2n-quic-core/src/event/generated/metrics/probe.rs index 3423b766e2..e079a503be 100644 --- a/quic/s2n-quic-core/src/event/generated/metrics/probe.rs +++ b/quic/s2n-quic-core/src/event/generated/metrics/probe.rs @@ -6,15 +6,18 @@ // changes should be made there. use crate::{ - event::metrics::aggregate::{self, Info, Recorder}, + event::metrics::aggregate::{ + self, info, BoolRecorder, Info, NominalRecorder, Recorder as MetricRecorder, + }, probe::define, }; mod counter { #![allow(non_snake_case)] - use super::Info; + use super::*; + use crate::event::metrics::aggregate::Metric; pub struct Recorder(fn(u64)); impl Recorder { - pub(super) fn new(info: &'static Info) -> Self { + pub(crate) fn new(info: &'static Info) -> Self { match info.id { 0usize => Self(application_protocol_information), 1usize => Self(server_name_information), @@ -25,81 +28,81 @@ mod counter { 7usize => Self(active_path_updated), 8usize => Self(path_created), 9usize => Self(frame_sent), - 10usize => Self(frame_received), - 11usize => Self(packet_lost), - 12usize => Self(packet_lost__bytes__total), - 14usize => Self(recovery_metrics), - 23usize => Self(congestion), - 24usize => Self(rx_ack_range_dropped), - 25usize => Self(ack_range_received), - 26usize => Self(ack_range_sent), - 27usize => Self(packet_dropped), - 28usize => Self(key_update), - 29usize => Self(key_space_discarded), - 30usize => Self(connection_started), - 31usize => Self(connection_closed), - 32usize => Self(duplicate_packet), - 33usize => Self(transport_parameters_received), - 34usize => Self(datagram_sent), - 35usize => Self(datagram_sent__bytes__total), - 38usize => Self(datagram_received), - 39usize => Self(datagram_received__bytes__total), - 41usize => Self(datagram_dropped), - 42usize => Self(datagram_dropped__bytes__total), - 44usize => Self(connection_id_updated), - 45usize => Self(ecn_state_changed), - 46usize => Self(connection_migration_denied), - 47usize => Self(handshake_status_updated), - 48usize => Self(tls_exporter_ready), - 49usize => Self(path_challenge_updated), - 50usize => Self(tls_client_hello), - 51usize => Self(tls_server_hello), - 52usize => Self(rx_stream_progress), - 53usize => Self(rx_stream_progress__bytes__total), - 55usize => Self(tx_stream_progress), - 56usize => Self(tx_stream_progress__bytes__total), - 58usize => Self(keep_alive_timer_expired), - 59usize => Self(mtu_updated), - 61usize => Self(slow_start_exited), - 63usize => Self(delivery_rate_sampled), - 64usize => Self(pacing_rate_updated), - 67usize => Self(bbr_state_changed), - 68usize => Self(dc_state_changed), - 69usize => Self(version_information), - 70usize => Self(endpoint_packet_sent), - 71usize => Self(endpoint_packet_received), - 72usize => Self(endpoint_datagram_sent), - 76usize => Self(endpoint_datagram_received), - 79usize => Self(endpoint_datagram_dropped), - 82usize => Self(endpoint_connection_attempt_failed), - 83usize => Self(platform_tx), - 84usize => Self(platform_tx__packets__total), - 86usize => Self(platform_tx__syscalls__total), - 88usize => Self(platform_tx__syscalls__blocked__total), - 90usize => Self(platform_tx__errors__total), - 92usize => Self(platform_tx__errors__dropped__total), - 94usize => Self(platform_tx_error), - 95usize => Self(platform_rx), - 96usize => Self(platform_rx__packets__total), - 98usize => Self(platform_rx__syscalls__total), - 100usize => Self(platform_rx__syscalls__blocked__total), - 102usize => Self(platform_rx__errors__total), - 104usize => Self(platform_rx__errors__dropped__total), - 106usize => Self(platform_rx_error), - 107usize => Self(platform_feature_configured), - 108usize => Self(platform_event_loop_wakeup), - 109usize => Self(platform_event_loop_sleep), - 111usize => Self(platform_event_loop_started), + 11usize => Self(frame_received), + 13usize => Self(packet_lost), + 14usize => Self(packet_lost__bytes__total), + 17usize => Self(recovery_metrics), + 27usize => Self(congestion), + 29usize => Self(rx_ack_range_dropped), + 30usize => Self(ack_range_received), + 31usize => Self(ack_range_sent), + 32usize => Self(packet_dropped), + 34usize => Self(key_update), + 35usize => Self(key_space_discarded), + 37usize => Self(connection_started), + 38usize => Self(connection_closed), + 40usize => Self(duplicate_packet), + 42usize => Self(transport_parameters_received), + 43usize => Self(datagram_sent), + 44usize => Self(datagram_sent__bytes__total), + 47usize => Self(datagram_received), + 48usize => Self(datagram_received__bytes__total), + 50usize => Self(datagram_dropped), + 51usize => Self(datagram_dropped__bytes__total), + 54usize => Self(connection_id_updated), + 55usize => Self(ecn_state_changed), + 57usize => Self(connection_migration_denied), + 59usize => Self(handshake_status_updated), + 61usize => Self(tls_exporter_ready), + 62usize => Self(path_challenge_updated), + 63usize => Self(tls_client_hello), + 64usize => Self(tls_server_hello), + 65usize => Self(rx_stream_progress), + 66usize => Self(rx_stream_progress__bytes__total), + 68usize => Self(tx_stream_progress), + 69usize => Self(tx_stream_progress__bytes__total), + 71usize => Self(keep_alive_timer_expired), + 72usize => Self(mtu_updated), + 76usize => Self(slow_start_exited), + 79usize => Self(delivery_rate_sampled), + 80usize => Self(pacing_rate_updated), + 84usize => Self(bbr_state_changed), + 86usize => Self(dc_state_changed), + 88usize => Self(version_information), + 89usize => Self(endpoint_packet_sent), + 90usize => Self(endpoint_packet_received), + 91usize => Self(endpoint_datagram_sent), + 95usize => Self(endpoint_datagram_received), + 98usize => Self(endpoint_datagram_dropped), + 102usize => Self(endpoint_connection_attempt_failed), + 104usize => Self(platform_tx), + 105usize => Self(platform_tx__packets__total), + 107usize => Self(platform_tx__syscalls__total), + 109usize => Self(platform_tx__syscalls__blocked__total), + 111usize => Self(platform_tx__errors__total), + 113usize => Self(platform_tx__errors__dropped__total), + 115usize => Self(platform_tx_error), + 116usize => Self(platform_rx), + 117usize => Self(platform_rx__packets__total), + 119usize => Self(platform_rx__syscalls__total), + 121usize => Self(platform_rx__syscalls__blocked__total), + 123usize => Self(platform_rx__errors__total), + 125usize => Self(platform_rx__errors__dropped__total), + 127usize => Self(platform_rx_error), + 128usize => Self(platform_feature_configured), + 129usize => Self(platform_event_loop_wakeup), + 130usize => Self(platform_event_loop_sleep), + 132usize => Self(platform_event_loop_started), _ => unreachable!("invalid info: {info:?}"), } } } - impl super::Recorder for Recorder { - fn record(&self, _info: &'static Info, value: u64) { - (self.0)(value); + impl MetricRecorder for Recorder { + fn record(&self, _info: &'static Info, value: T) { + (self.0)(value.as_u64()); } } - super::define!( + define!( extern "probe" { # [link_name = s2n_quic__event__counter__application_protocol_information] fn application_protocol_information(value: u64); @@ -251,61 +254,187 @@ mod counter { fn platform_event_loop_started(value: u64); } ); + pub mod bool { + #![allow(non_snake_case)] + use super::*; + pub struct Recorder(fn(bool)); + impl Recorder { + pub(crate) fn new(info: &'static Info) -> Self { + match info.id { + 16usize => Self(packet_lost__is_mtu_probe), + 26usize => Self(recovery_metrics__congestion_limited), + 75usize => Self(mtu_updated__search_complete), + _ => unreachable!("invalid info: {info:?}"), + } + } + } + impl BoolRecorder for Recorder { + fn record(&self, _info: &'static Info, value: bool) { + (self.0)(value); + } + } + define!( + extern "probe" { + # [link_name = s2n_quic__event__counter__bool__packet_lost__is_mtu_probe] + fn packet_lost__is_mtu_probe(value: bool); + # [link_name = s2n_quic__event__counter__bool__recovery_metrics__congestion_limited] + fn recovery_metrics__congestion_limited(value: bool); + # [link_name = s2n_quic__event__counter__bool__mtu_updated__search_complete] + fn mtu_updated__search_complete(value: bool); + } + ); + } + pub mod nominal { + #![allow(non_snake_case)] + use super::*; + use crate::event::metrics::aggregate::Metric; + pub struct Recorder(fn(u64, u64, &info::Str)); + impl Recorder { + pub(crate) fn new(info: &'static Info, _variant: &'static info::Variant) -> Self { + match info.id { + 10usize => Self(frame_sent__frame), + 12usize => Self(frame_received__frame), + 28usize => Self(congestion__source), + 33usize => Self(packet_dropped__reason), + 36usize => Self(key_space_discarded__space), + 39usize => Self(connection_closed__error), + 41usize => Self(duplicate_packet__error), + 53usize => Self(datagram_dropped__reason), + 56usize => Self(ecn_state_changed__state), + 58usize => Self(connection_migration_denied__reason), + 60usize => Self(handshake_status_updated__status), + 74usize => Self(mtu_updated__cause), + 77usize => Self(slow_start_exited__cause), + 85usize => Self(bbr_state_changed__state), + 87usize => Self(dc_state_changed__state), + 101usize => Self(endpoint_datagram_dropped__reason), + 103usize => Self(endpoint_connection_attempt_failed__error), + _ => unreachable!("invalid info: {info:?}"), + } + } + } + impl NominalRecorder for Recorder { + fn record( + &self, + _info: &'static Info, + variant: &'static info::Variant, + value: T, + ) { + (self.0)(value.as_u64(), variant.id as _, variant.name); + } + } + define!( + extern "probe" { + # [link_name = s2n_quic__event__counter__nominal__frame_sent__frame] + fn frame_sent__frame(value: u64, variant: u64, variant_name: &info::Str); + # [link_name = s2n_quic__event__counter__nominal__frame_received__frame] + fn frame_received__frame(value: u64, variant: u64, variant_name: &info::Str); + # [link_name = s2n_quic__event__counter__nominal__congestion__source] + fn congestion__source(value: u64, variant: u64, variant_name: &info::Str); + # [link_name = s2n_quic__event__counter__nominal__packet_dropped__reason] + fn packet_dropped__reason(value: u64, variant: u64, variant_name: &info::Str); + # [link_name = s2n_quic__event__counter__nominal__key_space_discarded__space] + fn key_space_discarded__space(value: u64, variant: u64, variant_name: &info::Str); + # [link_name = s2n_quic__event__counter__nominal__connection_closed__error] + fn connection_closed__error(value: u64, variant: u64, variant_name: &info::Str); + # [link_name = s2n_quic__event__counter__nominal__duplicate_packet__error] + fn duplicate_packet__error(value: u64, variant: u64, variant_name: &info::Str); + # [link_name = s2n_quic__event__counter__nominal__datagram_dropped__reason] + fn datagram_dropped__reason(value: u64, variant: u64, variant_name: &info::Str); + # [link_name = s2n_quic__event__counter__nominal__ecn_state_changed__state] + fn ecn_state_changed__state(value: u64, variant: u64, variant_name: &info::Str); + # [link_name = s2n_quic__event__counter__nominal__connection_migration_denied__reason] + fn connection_migration_denied__reason( + value: u64, + variant: u64, + variant_name: &info::Str, + ); + # [link_name = s2n_quic__event__counter__nominal__handshake_status_updated__status] + fn handshake_status_updated__status( + value: u64, + variant: u64, + variant_name: &info::Str, + ); + # [link_name = s2n_quic__event__counter__nominal__mtu_updated__cause] + fn mtu_updated__cause(value: u64, variant: u64, variant_name: &info::Str); + # [link_name = s2n_quic__event__counter__nominal__slow_start_exited__cause] + fn slow_start_exited__cause(value: u64, variant: u64, variant_name: &info::Str); + # [link_name = s2n_quic__event__counter__nominal__bbr_state_changed__state] + fn bbr_state_changed__state(value: u64, variant: u64, variant_name: &info::Str); + # [link_name = s2n_quic__event__counter__nominal__dc_state_changed__state] + fn dc_state_changed__state(value: u64, variant: u64, variant_name: &info::Str); + # [link_name = s2n_quic__event__counter__nominal__endpoint_datagram_dropped__reason] + fn endpoint_datagram_dropped__reason( + value: u64, + variant: u64, + variant_name: &info::Str, + ); + # [link_name = s2n_quic__event__counter__nominal__endpoint_connection_attempt_failed__error] + fn endpoint_connection_attempt_failed__error( + value: u64, + variant: u64, + variant_name: &info::Str, + ); + } + ); + } } mod measure { #![allow(non_snake_case)] - use super::Info; + use super::*; + use crate::event::metrics::aggregate::Metric; pub struct Recorder(fn(u64)); impl Recorder { - pub(super) fn new(info: &'static Info) -> Self { + pub(crate) fn new(info: &'static Info) -> Self { match info.id { 5usize => Self(packet_sent__bytes), - 13usize => Self(packet_lost__bytes), - 15usize => Self(recovery_metrics__min_rtt), - 16usize => Self(recovery_metrics__smoothed_rtt), - 17usize => Self(recovery_metrics__latest_rtt), - 18usize => Self(recovery_metrics__rtt_variance), - 19usize => Self(recovery_metrics__max_ack_delay), - 20usize => Self(recovery_metrics__pto_count), - 21usize => Self(recovery_metrics__congestion_window), - 22usize => Self(recovery_metrics__bytes_in_flight), - 36usize => Self(datagram_sent__bytes), - 37usize => Self(datagram_sent__gso_offset), - 40usize => Self(datagram_received__bytes), - 43usize => Self(datagram_dropped__bytes), - 54usize => Self(rx_stream_progress__bytes), - 57usize => Self(tx_stream_progress__bytes), - 60usize => Self(mtu_updated__mtu), - 62usize => Self(slow_start_exited__congestion_window), - 65usize => Self(pacing_rate_updated__bytes_per_second), - 66usize => Self(pacing_rate_updated__burst_size), - 73usize => Self(endpoint_datagram_sent__bytes), - 74usize => Self(endpoint_datagram_sent__bytes__total), - 75usize => Self(endpoint_datagram_sent__gso_offset), - 77usize => Self(endpoint_datagram_received__bytes), - 78usize => Self(endpoint_datagram_received__bytes__total), - 80usize => Self(endpoint_datagram_dropped__bytes), - 81usize => Self(endpoint_datagram_dropped__bytes__total), - 85usize => Self(platform_tx__packets), - 87usize => Self(platform_tx__syscalls), - 89usize => Self(platform_tx__syscalls__blocked), - 91usize => Self(platform_tx__errors), - 93usize => Self(platform_tx__errors__dropped), - 97usize => Self(platform_rx__packets), - 99usize => Self(platform_rx__syscalls), - 101usize => Self(platform_rx__syscalls__blocked), - 103usize => Self(platform_rx__errors), - 105usize => Self(platform_rx__errors__dropped), + 15usize => Self(packet_lost__bytes), + 18usize => Self(recovery_metrics__min_rtt), + 19usize => Self(recovery_metrics__smoothed_rtt), + 20usize => Self(recovery_metrics__latest_rtt), + 21usize => Self(recovery_metrics__rtt_variance), + 22usize => Self(recovery_metrics__max_ack_delay), + 23usize => Self(recovery_metrics__pto_count), + 24usize => Self(recovery_metrics__congestion_window), + 25usize => Self(recovery_metrics__bytes_in_flight), + 45usize => Self(datagram_sent__bytes), + 46usize => Self(datagram_sent__gso_offset), + 49usize => Self(datagram_received__bytes), + 52usize => Self(datagram_dropped__bytes), + 67usize => Self(rx_stream_progress__bytes), + 70usize => Self(tx_stream_progress__bytes), + 73usize => Self(mtu_updated__mtu), + 78usize => Self(slow_start_exited__congestion_window), + 81usize => Self(pacing_rate_updated__bytes_per_second), + 82usize => Self(pacing_rate_updated__burst_size), + 83usize => Self(pacing_rate_updated__pacing_gain), + 92usize => Self(endpoint_datagram_sent__bytes), + 93usize => Self(endpoint_datagram_sent__bytes__total), + 94usize => Self(endpoint_datagram_sent__gso_offset), + 96usize => Self(endpoint_datagram_received__bytes), + 97usize => Self(endpoint_datagram_received__bytes__total), + 99usize => Self(endpoint_datagram_dropped__bytes), + 100usize => Self(endpoint_datagram_dropped__bytes__total), + 106usize => Self(platform_tx__packets), + 108usize => Self(platform_tx__syscalls), + 110usize => Self(platform_tx__syscalls__blocked), + 112usize => Self(platform_tx__errors), + 114usize => Self(platform_tx__errors__dropped), + 118usize => Self(platform_rx__packets), + 120usize => Self(platform_rx__syscalls), + 122usize => Self(platform_rx__syscalls__blocked), + 124usize => Self(platform_rx__errors), + 126usize => Self(platform_rx__errors__dropped), _ => unreachable!("invalid info: {info:?}"), } } } - impl super::Recorder for Recorder { - fn record(&self, _info: &'static Info, value: u64) { - (self.0)(value); + impl MetricRecorder for Recorder { + fn record(&self, _info: &'static Info, value: T) { + (self.0)(value.as_u64()); } } - super::define!( + define!( extern "probe" { # [link_name = s2n_quic__event__measure__packet_sent__bytes] fn packet_sent__bytes(value: u64); @@ -347,6 +476,8 @@ mod measure { fn pacing_rate_updated__bytes_per_second(value: u64); # [link_name = s2n_quic__event__measure__pacing_rate_updated__burst_size] fn pacing_rate_updated__burst_size(value: u64); + # [link_name = s2n_quic__event__measure__pacing_rate_updated__pacing_gain] + fn pacing_rate_updated__pacing_gain(value: u64); # [link_name = s2n_quic__event__measure__endpoint_datagram_sent__bytes] fn endpoint_datagram_sent__bytes(value: u64); # [link_name = s2n_quic__event__measure__endpoint_datagram_sent__bytes__total] @@ -386,40 +517,42 @@ mod measure { } mod gauge { #![allow(non_snake_case)] - use super::Info; + use super::*; + use crate::event::metrics::aggregate::Metric; pub struct Recorder(fn(u64)); impl Recorder { - pub(super) fn new(info: &'static Info) -> Self { + pub(crate) fn new(info: &'static Info) -> Self { unreachable!("invalid info: {info:?}") } } - impl super::Recorder for Recorder { - fn record(&self, _info: &'static Info, value: u64) { - (self.0)(value); + impl MetricRecorder for Recorder { + fn record(&self, _info: &'static Info, value: T) { + (self.0)(value.as_u64()); } } } mod timer { #![allow(non_snake_case)] - use super::Info; - pub struct Recorder(fn(u64)); + use super::*; + use crate::event::metrics::aggregate::Metric; + pub struct Recorder(fn(core::time::Duration)); impl Recorder { - pub(super) fn new(info: &'static Info) -> Self { + pub(crate) fn new(info: &'static Info) -> Self { match info.id { - 110usize => Self(platform_event_loop_sleep__processing_duration), + 131usize => Self(platform_event_loop_sleep__processing_duration), _ => unreachable!("invalid info: {info:?}"), } } } - impl super::Recorder for Recorder { - fn record(&self, _info: &'static Info, value: u64) { - (self.0)(value); + impl MetricRecorder for Recorder { + fn record(&self, _info: &'static Info, value: T) { + (self.0)(value.as_duration()); } } - super::define!( + define!( extern "probe" { # [link_name = s2n_quic__event__timer__platform_event_loop_sleep__processing_duration] - fn platform_event_loop_sleep__processing_duration(value: u64); + fn platform_event_loop_sleep__processing_duration(value: core::time::Duration); } ); } @@ -427,6 +560,8 @@ mod timer { pub struct Registry(()); impl aggregate::Registry for Registry { type Counter = counter::Recorder; + type BoolCounter = counter::bool::Recorder; + type NominalCounter = counter::nominal::Recorder; type Measure = measure::Recorder; type Gauge = gauge::Recorder; type Timer = timer::Recorder; @@ -435,6 +570,18 @@ impl aggregate::Registry for Registry { counter::Recorder::new(info) } #[inline] + fn register_bool_counter(&self, info: &'static Info) -> Self::BoolCounter { + counter::bool::Recorder::new(info) + } + #[inline] + fn register_nominal_counter( + &self, + info: &'static Info, + variant: &'static info::Variant, + ) -> Self::NominalCounter { + counter::nominal::Recorder::new(info, variant) + } + #[inline] fn register_measure(&self, info: &'static Info) -> Self::Measure { measure::Recorder::new(info) } diff --git a/quic/s2n-quic-core/src/event/metrics/aggregate.rs b/quic/s2n-quic-core/src/event/metrics/aggregate.rs index 4b8ee94935..908f1c584c 100644 --- a/quic/s2n-quic-core/src/event/metrics/aggregate.rs +++ b/quic/s2n-quic-core/src/event/metrics/aggregate.rs @@ -5,17 +5,34 @@ pub use crate::event::generated::metrics::aggregate::*; pub mod info; +mod metric; pub mod probe; +mod recorder; +mod variant; + pub use info::Info; +pub use metric::*; +pub use recorder::*; +pub use variant::*; pub trait Registry: 'static + Send + Sync { type Counter: Recorder; + type BoolCounter: BoolRecorder; + type NominalCounter: NominalRecorder; type Measure: Recorder; type Gauge: Recorder; type Timer: Recorder; fn register_counter(&self, info: &'static Info) -> Self::Counter; + fn register_bool_counter(&self, info: &'static Info) -> Self::BoolCounter; + + fn register_nominal_counter( + &self, + info: &'static Info, + variant: &'static info::Variant, + ) -> Self::NominalCounter; + fn register_measure(&self, info: &'static Info) -> Self::Measure; fn register_gauge(&self, info: &'static Info) -> Self::Gauge; @@ -29,6 +46,8 @@ where B: Registry, { type Counter = (A::Counter, B::Counter); + type BoolCounter = (A::BoolCounter, B::BoolCounter); + type NominalCounter = (A::NominalCounter, B::NominalCounter); type Measure = (A::Measure, B::Measure); type Gauge = (A::Gauge, B::Gauge); type Timer = (A::Timer, B::Timer); @@ -38,6 +57,26 @@ where (self.0.register_counter(info), self.1.register_counter(info)) } + #[inline] + fn register_bool_counter(&self, info: &'static Info) -> Self::BoolCounter { + ( + self.0.register_bool_counter(info), + self.1.register_bool_counter(info), + ) + } + + #[inline] + fn register_nominal_counter( + &self, + info: &'static Info, + variant: &'static info::Variant, + ) -> Self::NominalCounter { + ( + self.0.register_nominal_counter(info, variant), + self.1.register_nominal_counter(info, variant), + ) + } + #[inline] fn register_measure(&self, info: &'static Info) -> Self::Measure { (self.0.register_measure(info), self.1.register_measure(info)) @@ -57,6 +96,8 @@ where #[cfg(feature = "alloc")] impl Registry for alloc::sync::Arc { type Counter = T::Counter; + type BoolCounter = T::BoolCounter; + type NominalCounter = T::NominalCounter; type Measure = T::Measure; type Gauge = T::Gauge; type Timer = T::Timer; @@ -67,81 +108,31 @@ impl Registry for alloc::sync::Arc { } #[inline] - fn register_measure(&self, info: &'static Info) -> Self::Measure { - self.as_ref().register_measure(info) - } - - #[inline] - fn register_gauge(&self, info: &'static Info) -> Self::Gauge { - self.as_ref().register_gauge(info) - } - - #[inline] - fn register_timer(&self, info: &'static Info) -> Self::Timer { - self.as_ref().register_timer(info) + fn register_bool_counter(&self, info: &'static Info) -> Self::BoolCounter { + self.as_ref().register_bool_counter(info) } -} - -pub trait Recorder: 'static + Send + Sync { - fn record(&self, info: &'static Info, value: u64); -} -impl Recorder for (A, B) -where - A: Recorder, - B: Recorder, -{ #[inline] - fn record(&self, info: &'static Info, value: u64) { - self.0.record(info, value); - self.1.record(info, value); + fn register_nominal_counter( + &self, + info: &'static Info, + variant: &'static info::Variant, + ) -> Self::NominalCounter { + self.as_ref().register_nominal_counter(info, variant) } -} -#[cfg(target_has_atomic = "64")] -impl Recorder for core::sync::atomic::AtomicU64 { #[inline] - fn record(&self, _info: &'static Info, value: u64) { - self.fetch_add(value, core::sync::atomic::Ordering::Relaxed); + fn register_measure(&self, info: &'static Info) -> Self::Measure { + self.as_ref().register_measure(info) } -} -#[cfg(feature = "alloc")] -impl Recorder for alloc::sync::Arc { #[inline] - fn record(&self, info: &'static Info, value: u64) { - self.as_ref().record(info, value); - } -} - -pub trait AsMetric { - fn as_metric(&self, unit: &str) -> u64; -} - -macro_rules! impl_as_metric_number { - ($($ty:ty),* $(,)?) => { - $( - impl AsMetric for $ty { - #[inline] - fn as_metric(&self, _unit: &str) -> u64 { - *self as _ - } - } - )* + fn register_gauge(&self, info: &'static Info) -> Self::Gauge { + self.as_ref().register_gauge(info) } -} - -impl_as_metric_number!(u8, u16, u32, u64, usize); -impl AsMetric for core::time::Duration { #[inline] - fn as_metric(&self, unit: &str) -> u64 { - match unit { - "s" => self.as_secs(), - "ms" => self.as_millis().try_into().unwrap_or(u64::MAX), - "us" => self.as_micros().try_into().unwrap_or(u64::MAX), - "ns" => self.as_nanos().try_into().unwrap_or(u64::MAX), - _ => panic!("invalid unit - {unit:?}"), - } + fn register_timer(&self, info: &'static Info) -> Self::Timer { + self.as_ref().register_timer(info) } } diff --git a/quic/s2n-quic-core/src/event/metrics/aggregate/info.rs b/quic/s2n-quic-core/src/event/metrics/aggregate/info.rs index d124ace271..de9c41cf97 100644 --- a/quic/s2n-quic-core/src/event/metrics/aggregate/info.rs +++ b/quic/s2n-quic-core/src/event/metrics/aggregate/info.rs @@ -1,22 +1,30 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 +use super::Units; use crate::probe; use core::{ffi::CStr, fmt, ops}; -#[derive(Debug)] +#[derive(Copy, Clone, Debug)] #[non_exhaustive] pub struct Info { pub id: usize, pub name: &'static Str, - pub units: &'static Str, + pub units: Units, +} + +#[derive(Copy, Clone, Debug)] +#[non_exhaustive] +pub struct Variant { + pub id: usize, + pub name: &'static Str, } #[doc(hidden)] pub struct Builder { pub id: usize, pub name: &'static Str, - pub units: &'static Str, + pub units: Units, } impl Builder { diff --git a/quic/s2n-quic-core/src/event/metrics/aggregate/metric.rs b/quic/s2n-quic-core/src/event/metrics/aggregate/metric.rs new file mode 100644 index 0000000000..18254f66a9 --- /dev/null +++ b/quic/s2n-quic-core/src/event/metrics/aggregate/metric.rs @@ -0,0 +1,165 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +use super::info::Str; +use core::time::Duration; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[non_exhaustive] +pub enum Units { + None, + Bytes, + Duration, +} + +impl Units { + pub const fn as_str(&self) -> &'static Str { + match self { + Units::None => Str::new("\0"), + Units::Bytes => Str::new("bytes\0"), + Units::Duration => Str::new("duration\0"), + } + } +} + +pub trait Metric: 'static + Send + Sync + Copy + core::fmt::Debug { + #[inline] + fn is_f32(&self) -> bool { + false + } + fn as_f32(&self) -> f32; + + #[inline] + fn is_f64(&self) -> bool { + false + } + fn as_f64(&self) -> f64; + + #[inline] + fn is_u64(&self) -> bool { + false + } + fn as_u64(&self) -> u64; + + #[inline] + fn is_duration(&self) -> bool { + false + } + fn as_duration(&self) -> Duration; +} + +impl Metric for f32 { + #[inline] + fn as_f32(&self) -> f32 { + *self + } + + #[inline] + fn is_f32(&self) -> bool { + true + } + + #[inline] + fn as_f64(&self) -> f64 { + *self as _ + } + + #[inline] + fn as_u64(&self) -> u64 { + *self as _ + } + + #[inline] + fn as_duration(&self) -> Duration { + Duration::from_secs_f32(*self) + } +} + +impl Metric for f64 { + #[inline] + fn as_f32(&self) -> f32 { + *self as _ + } + + #[inline] + fn as_f64(&self) -> f64 { + *self + } + + #[inline] + fn is_f64(&self) -> bool { + true + } + + #[inline] + fn as_u64(&self) -> u64 { + *self as _ + } + + #[inline] + fn as_duration(&self) -> Duration { + Duration::from_secs_f64(*self) + } +} + +impl Metric for Duration { + #[inline] + fn as_f32(&self) -> f32 { + self.as_secs_f32() + } + + #[inline] + fn as_f64(&self) -> f64 { + self.as_secs_f64() + } + + #[inline] + fn as_u64(&self) -> u64 { + self.as_micros() as _ + } + + #[inline] + fn is_duration(&self) -> bool { + true + } + + #[inline] + fn as_duration(&self) -> Duration { + *self + } +} + +macro_rules! impl_metric_number { + ($($ty:ty),* $(,)?) => { + $( + impl Metric for $ty { + #[inline] + fn as_f32(&self) -> f32 { + *self as _ + } + + #[inline] + fn as_f64(&self) -> f64 { + *self as _ + } + + #[inline] + fn is_u64(&self) -> bool { + true + } + + #[inline] + fn as_u64(&self) -> u64 { + *self as _ + } + + #[inline] + fn as_duration(&self) -> Duration { + Duration::from_micros(*self as _) + } + } + )* + } +} + +impl_metric_number!(u8, u16, u32, u64, usize); diff --git a/quic/s2n-quic-core/src/event/metrics/aggregate/probe/dynamic.rs b/quic/s2n-quic-core/src/event/metrics/aggregate/probe/dynamic.rs index c422cb41be..cde0eecfc3 100644 --- a/quic/s2n-quic-core/src/event/metrics/aggregate/probe/dynamic.rs +++ b/quic/s2n-quic-core/src/event/metrics/aggregate/probe/dynamic.rs @@ -1,22 +1,42 @@ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -use crate::event::metrics::aggregate::{self, info::Str, Info}; +use crate::event::metrics::aggregate::{ + self, + info::{self, Str}, + Info, +}; #[derive(Clone, Debug, Default)] pub struct Registry(()); impl aggregate::Registry for Registry { type Counter = Counter; + type BoolCounter = BoolCounter; + type NominalCounter = NominalCounter; type Measure = Measure; type Gauge = Gauge; - type Timer = Measure; + type Timer = Timer; #[inline] fn register_counter(&self, info: &'static Info) -> Self::Counter { Self::Counter::new(info) } + #[inline] + fn register_bool_counter(&self, info: &'static Info) -> Self::BoolCounter { + Self::BoolCounter::new(info) + } + + #[inline] + fn register_nominal_counter( + &self, + info: &'static Info, + variant: &'static info::Variant, + ) -> Self::NominalCounter { + Self::NominalCounter::new(info, variant) + } + #[inline] fn register_measure(&self, info: &'static Info) -> Self::Measure { Self::Measure::new(info) @@ -34,18 +54,27 @@ impl aggregate::Registry for Registry { } macro_rules! recorder { - ($name:ident, $module:ident, $register:ident, $record:ident) => { + ( + $recorder:ident, + $name:ident, + $module:ident, + $register:ident, + $record:ident, + $as_metric:ident : $metric_ty:ty + $(, $variant:ident : $variant_ty:ty)? + ) => { mod $module { use super::*; use crate::probe::define; + use aggregate::Metric; define!( extern "probe" { #[link_name = $register] - fn register(id: usize, name: &Str, units: &Str); + fn register(id: usize, name: &Str, units: &Str, $($variant: &Str)?); #[link_name = $record] - fn record(id: usize, name: &Str, units: &Str, value: u64); + fn record(id: usize, name: &Str, units: &Str, $($variant: &Str, )? value: $metric_ty); } ); @@ -53,16 +82,16 @@ macro_rules! recorder { pub struct $name(()); impl $name { - pub(super) fn new(info: &'static Info) -> Self { - register(info.id, info.name, info.units); + pub(super) fn new(info: &'static Info $(, $variant: $variant_ty)?) -> Self { + register(info.id, info.name, info.units.as_str(), $($variant.name)?); Self(()) } } - impl aggregate::Recorder for $name { + impl aggregate::$recorder for $name { #[inline] - fn record(&self, info: &'static Info, value: u64) { - record(info.id, info.name, info.units, value); + fn record(&self, info: &'static Info, $($variant: $variant_ty, )? value: T) { + record(info.id, info.name, info.units.as_str(), $($variant.name, )? value.$as_metric()); } } } @@ -72,20 +101,77 @@ macro_rules! recorder { } recorder!( + Recorder, Counter, counter, s2n_quic__counter__register, - s2n_quic__counter__record + s2n_quic__counter__record, + as_u64: u64 ); recorder!( + NominalRecorder, + NominalCounter, + nominal_counter, + s2n_quic__counter__nominal__register, + s2n_quic__counter__nominal__record, + as_u64: u64, + variant: &'static info::Variant +); +recorder!( + Recorder, Measure, measure, s2n_quic__measure__register, - s2n_quic__measure__record + s2n_quic__measure__record, + as_u64: u64 ); recorder!( + Recorder, Gauge, gauge, s2n_quic__gauge__register, - s2n_quic__gauge__record + s2n_quic__gauge__record, + as_u64: u64 +); +recorder!( + Recorder, + Timer, + timer, + s2n_quic__timer__register, + s2n_quic__timer__record, + as_duration: core::time::Duration ); + +mod bool_counter { + use super::*; + use crate::probe::define; + + define!( + extern "probe" { + #[link_name = s2n_quic__counter__bool__register] + fn register(id: usize, name: &Str); + + #[link_name = s2n_quic__counter__bool__record] + fn record(id: usize, name: &Str, value: bool); + } + ); + + #[derive(Copy, Clone, Debug, Default)] + pub struct BoolCounter(()); + + impl BoolCounter { + pub(super) fn new(info: &'static Info) -> Self { + register(info.id, info.name); + Self(()) + } + } + + impl aggregate::BoolRecorder for BoolCounter { + #[inline] + fn record(&self, info: &'static Info, value: bool) { + record(info.id, info.name, value); + } + } +} + +pub use bool_counter::BoolCounter; diff --git a/quic/s2n-quic-core/src/event/metrics/aggregate/recorder.rs b/quic/s2n-quic-core/src/event/metrics/aggregate/recorder.rs new file mode 100644 index 0000000000..a3384cf1b8 --- /dev/null +++ b/quic/s2n-quic-core/src/event/metrics/aggregate/recorder.rs @@ -0,0 +1,115 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +use super::{ + info::{self, Info}, + Metric, +}; + +pub trait Recorder: 'static + Send + Sync { + fn record(&self, info: &'static Info, value: T); +} + +pub trait BoolRecorder: 'static + Send + Sync { + fn record(&self, info: &'static Info, value: bool); +} + +pub trait NominalRecorder: 'static + Send + Sync { + fn record(&self, info: &'static Info, variant: &'static info::Variant, value: T); +} + +macro_rules! impl_recorder { + ($trait:ident $(, $extra_param:ident: $extra_type:ty)?) => { + impl $trait for (A, B) + where + A: $trait, + B: $trait, + { + #[inline] + fn record(&self, info: &'static Info, $($extra_param: $extra_type,)? value: T) { + self.0.record(info, $($extra_param,)? value); + self.1.record(info, $($extra_param,)? value); + } + } + + impl $trait for Option + where + R: $trait, + { + #[inline] + fn record(&self, info: &'static Info, $($extra_param: $extra_type,)? value: T) { + if let Some(recorder) = self { + recorder.record(info, $($extra_param,)? value); + } + } + } + + #[cfg(target_has_atomic = "64")] + impl $trait for core::sync::atomic::AtomicU64 { + #[inline] + fn record(&self, _info: &'static Info, $($extra_param: $extra_type,)? value: T) { + self.fetch_add(value.as_u64(), core::sync::atomic::Ordering::Relaxed); + $(let _ = $extra_param;)? + } + } + + #[cfg(feature = "alloc")] + impl $trait for alloc::sync::Arc + where + R: $trait, + { + #[inline] + fn record(&self, info: &'static Info, $($extra_param: $extra_type,)? value: T) { + self.as_ref().record(info, $($extra_param,)? value ); + } + } + }; +} + +impl_recorder!(Recorder); +impl_recorder!(NominalRecorder, variant: &'static info::Variant); + +impl BoolRecorder for (A, B) +where + A: BoolRecorder, + B: BoolRecorder, +{ + #[inline] + fn record(&self, info: &'static Info, value: bool) { + self.0.record(info, value); + self.1.record(info, value); + } +} + +impl BoolRecorder for Option +where + A: BoolRecorder, +{ + #[inline] + fn record(&self, info: &'static Info, value: bool) { + if let Some(recorder) = self { + recorder.record(info, value); + } + } +} + +#[cfg(target_has_atomic = "64")] +impl BoolRecorder for core::sync::atomic::AtomicU64 { + #[inline] + fn record(&self, _info: &'static Info, value: bool) { + if value { + self.fetch_add(1, core::sync::atomic::Ordering::Relaxed); + } + } +} + +#[cfg(feature = "alloc")] +impl BoolRecorder for alloc::sync::Arc +where + R: BoolRecorder, +{ + #[inline] + fn record(&self, info: &'static Info, value: bool) { + self.as_ref().record(info, value); + } +} diff --git a/quic/s2n-quic-core/src/event/metrics/aggregate/variant.rs b/quic/s2n-quic-core/src/event/metrics/aggregate/variant.rs new file mode 100644 index 0000000000..89cba80bd3 --- /dev/null +++ b/quic/s2n-quic-core/src/event/metrics/aggregate/variant.rs @@ -0,0 +1,15 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 + +use super::info::Variant; + +pub trait AsVariant { + const VARIANTS: &'static [Variant]; + + fn variant_idx(&self) -> usize; + + #[inline] + fn as_variant(&self) -> &'static Variant { + &Self::VARIANTS[self.variant_idx()] + } +} diff --git a/quic/s2n-quic-core/src/transport/error.rs b/quic/s2n-quic-core/src/transport/error.rs index 8b2faa201b..5b208402f6 100644 --- a/quic/s2n-quic-core/src/transport/error.rs +++ b/quic/s2n-quic-core/src/transport/error.rs @@ -5,6 +5,7 @@ use crate::{ crypto::tls, + event::metrics::aggregate, frame::ConnectionClose, varint::{VarInt, VarIntError}, }; @@ -145,6 +146,14 @@ impl fmt::Display for Code { //# of the PADDING frame) is used when the frame type is unknown. const UNKNOWN_FRAME_TYPE: u32 = 0; +//= https://www.rfc-editor.org/rfc/rfc9000#section-20.1 +//# CRYPTO_ERROR (0x0100-0x01ff): The cryptographic handshake failed. A +//# range of 256 values is reserved for carrying error codes specific +//# to the cryptographic handshake that is used. Codes for errors +//# occurring when TLS is used for the cryptographic handshake are +//# described in Section 4.8 of [QUIC-TLS]. +const CRYPTO_ERROR_RANGE: core::ops::RangeInclusive = 0x100..=0x1ff; + /// Internal convenience macro for defining standard error codes macro_rules! impl_errors { ($($(#[doc = $doc:expr])* $name:ident = $code:literal $(.with_frame_type($frame:expr))?),* $(,)?) => { @@ -159,12 +168,78 @@ macro_rules! impl_errors { $( $code => Some(stringify!($name)), )* - code @ 0x100..=0x1ff => tls::Error::new(code as u8).description(), + code if CRYPTO_ERROR_RANGE.contains(&code) => tls::Error::new(code as u8).description(), _ => None } } } + impl aggregate::AsVariant for Code { + const VARIANTS: &'static [aggregate::info::Variant] = &{ + use aggregate::info::{Variant, Str}; + + const fn count(_v: u64) -> usize { + 1 + } + + const QUIC_VARIANTS: usize = 0 $( + count($code))*; + + const TLS: &'static [Variant] = tls::Error::VARIANTS; + + let mut array = [ + Variant { name: Str::new("\0"), id: 0 }; + QUIC_VARIANTS + TLS.len() + 1 + ]; + + let mut id = 0; + + $( + array[id] = Variant { + name: Str::new(concat!("QUIC_", stringify!($name), "\0")), + id, + }; + id += 1; + )* + + let mut tls_idx = 0; + while tls_idx < TLS.len() { + let variant = TLS[tls_idx]; + array[id] = Variant { + name: variant.name, + id, + }; + id += 1; + tls_idx += 1; + } + + array[id] = Variant { + name: Str::new("QUIC_UNKNOWN_ERROR\0"), + id, + }; + + array + }; + + #[inline] + fn variant_idx(&self) -> usize { + let mut idx = 0; + let code = self.0.as_u64(); + + $( + if code == $code { + return idx; + } + idx += 1; + )* + + if CRYPTO_ERROR_RANGE.contains(&code) { + return tls::Error::new(code as _).variant_idx() + idx; + } + + idx + tls::Error::VARIANTS.len() + } + } + impl Error { $( $(#[doc = $doc])* @@ -184,6 +259,18 @@ macro_rules! impl_errors { )* assert_eq!(&Error::from(tls::Error::DECODE_ERROR).to_string(), "DECODE_ERROR"); } + + #[test] + #[cfg_attr(miri, ignore)] + fn variants_test() { + use aggregate::AsVariant; + insta::assert_debug_snapshot!(Code::VARIANTS); + + let mut seen = std::collections::HashSet::new(); + for variant in Code::VARIANTS { + assert!(seen.insert(variant.id)); + } + } }; } diff --git a/quic/s2n-quic-core/src/transport/snapshots/s2n_quic_core__transport__error__variants_test.snap b/quic/s2n-quic-core/src/transport/snapshots/s2n_quic_core__transport__error__variants_test.snap new file mode 100644 index 0000000000..204f640c08 --- /dev/null +++ b/quic/s2n-quic-core/src/transport/snapshots/s2n_quic_core__transport__error__variants_test.snap @@ -0,0 +1,214 @@ +--- +source: quic/s2n-quic-core/src/transport/error.rs +expression: "Code::VARIANTS" +--- +[ + Variant { + id: 0, + name: "QUIC_NO_ERROR", + }, + Variant { + id: 1, + name: "QUIC_INTERNAL_ERROR", + }, + Variant { + id: 2, + name: "QUIC_CONNECTION_REFUSED", + }, + Variant { + id: 3, + name: "QUIC_FLOW_CONTROL_ERROR", + }, + Variant { + id: 4, + name: "QUIC_STREAM_LIMIT_ERROR", + }, + Variant { + id: 5, + name: "QUIC_STREAM_STATE_ERROR", + }, + Variant { + id: 6, + name: "QUIC_FINAL_SIZE_ERROR", + }, + Variant { + id: 7, + name: "QUIC_FRAME_ENCODING_ERROR", + }, + Variant { + id: 8, + name: "QUIC_TRANSPORT_PARAMETER_ERROR", + }, + Variant { + id: 9, + name: "QUIC_CONNECTION_ID_LIMIT_ERROR", + }, + Variant { + id: 10, + name: "QUIC_PROTOCOL_VIOLATION", + }, + Variant { + id: 11, + name: "QUIC_INVALID_TOKEN", + }, + Variant { + id: 12, + name: "QUIC_APPLICATION_ERROR", + }, + Variant { + id: 13, + name: "QUIC_CRYPTO_BUFFER_EXCEEDED", + }, + Variant { + id: 14, + name: "QUIC_KEY_UPDATE_ERROR", + }, + Variant { + id: 15, + name: "QUIC_AEAD_LIMIT_REACHED", + }, + Variant { + id: 16, + name: "TLS_CLOSE_NOTIFY", + }, + Variant { + id: 17, + name: "TLS_UNEXPECTED_MESSAGE", + }, + Variant { + id: 18, + name: "TLS_BAD_RECORD_MAC", + }, + Variant { + id: 19, + name: "TLS_DECRYPTION_FAILED_RESERVED", + }, + Variant { + id: 20, + name: "TLS_RECORD_OVERFLOW", + }, + Variant { + id: 21, + name: "TLS_DECOMPRESSION_FAILURE_RESERVED", + }, + Variant { + id: 22, + name: "TLS_HANDSHAKE_FAILURE", + }, + Variant { + id: 23, + name: "TLS_NO_CERTIFICATE_RESERVED", + }, + Variant { + id: 24, + name: "TLS_BAD_CERTIFICATE", + }, + Variant { + id: 25, + name: "TLS_UNSUPPORTED_CERTIFICATE", + }, + Variant { + id: 26, + name: "TLS_CERTIFICATE_REVOKED", + }, + Variant { + id: 27, + name: "TLS_CERTIFICATE_EXPIRED", + }, + Variant { + id: 28, + name: "TLS_CERTIFICATE_UNKNOWN", + }, + Variant { + id: 29, + name: "TLS_ILLEGAL_PARAMETER", + }, + Variant { + id: 30, + name: "TLS_UNKNOWN_CA", + }, + Variant { + id: 31, + name: "TLS_ACCESS_DENIED", + }, + Variant { + id: 32, + name: "TLS_DECODE_ERROR", + }, + Variant { + id: 33, + name: "TLS_DECRYPT_ERROR", + }, + Variant { + id: 34, + name: "TLS_EXPORT_RESTRICTION_RESERVED", + }, + Variant { + id: 35, + name: "TLS_PROTOCOL_VERSION", + }, + Variant { + id: 36, + name: "TLS_INSUFFICIENT_SECURITY", + }, + Variant { + id: 37, + name: "TLS_INTERNAL_ERROR", + }, + Variant { + id: 38, + name: "TLS_INAPPROPRIATE_FALLBACK", + }, + Variant { + id: 39, + name: "TLS_USER_CANCELED", + }, + Variant { + id: 40, + name: "TLS_NO_RENEGOTIATION_RESERVED", + }, + Variant { + id: 41, + name: "TLS_MISSING_EXTENSION", + }, + Variant { + id: 42, + name: "TLS_UNSUPPORTED_EXTENSION", + }, + Variant { + id: 43, + name: "TLS_CERTIFICATE_UNOBTAINABLE_RESERVED", + }, + Variant { + id: 44, + name: "TLS_UNRECOGNIZED_NAME", + }, + Variant { + id: 45, + name: "TLS_BAD_CERTIFICATE_STATUS_RESPONSE", + }, + Variant { + id: 46, + name: "TLS_BAD_CERTIFICATE_HASH_VALUE_RESERVED", + }, + Variant { + id: 47, + name: "TLS_UNKNOWN_PSK_IDENTITY", + }, + Variant { + id: 48, + name: "TLS_CERTIFICATE_REQUIRED", + }, + Variant { + id: 49, + name: "TLS_NO_APPLICATION_PROTOCOL", + }, + Variant { + id: 50, + name: "TLS_UNKNOWN_ERROR", + }, + Variant { + id: 51, + name: "QUIC_UNKNOWN_ERROR", + }, +] diff --git a/quic/s2n-quic-events/src/output.rs b/quic/s2n-quic-events/src/output.rs index f68c97f4c0..ff859aaf37 100644 --- a/quic/s2n-quic-events/src/output.rs +++ b/quic/s2n-quic-events/src/output.rs @@ -168,6 +168,10 @@ impl ToTokens for Output { //! This module contains events that are emitted to the [`Subscriber`](crate::event::Subscriber) use super::*; + // we may or may not need to derive traits aggregate metrics + #[allow(unused_imports)] + use crate::event::metrics::aggregate; + pub use traits::Subscriber; #api diff --git a/quic/s2n-quic-events/src/output/metrics/aggregate.rs b/quic/s2n-quic-events/src/output/metrics/aggregate.rs index 987f8ad861..dd4809c7ee 100644 --- a/quic/s2n-quic-events/src/output/metrics/aggregate.rs +++ b/quic/s2n-quic-events/src/output/metrics/aggregate.rs @@ -32,24 +32,55 @@ pub fn emit(output: &Output, files: &[File]) -> TokenStream { quote!(counters), quote!(register_counter), format!("{}__event__counter", output.crate_name), + quote!(u64), + quote!(.as_u64()), ); + let mut bool_counters = Registry::new( + quote!(bool_counters), + quote!(register_bool_counter), + format!("{}__event__counter__bool", output.crate_name), + quote!(bool), + quote!(), + ); + bool_counters.registry_type = RegistryType::BoolCounter; + + let mut nominal_counters = Registry::new( + quote!(nominal_counters), + quote!(register_nominal_counter), + format!("{}__event__counter__nominal", output.crate_name), + quote!(u64), + quote!(.as_u64()), + ); + nominal_counters.registry_type = RegistryType::NominalCounter { + nominal_offsets: quote!(nominal_offsets), + }; + let mut measures = Registry::new( quote!(measures), quote!(register_measure), format!("{}__event__measure", output.crate_name), + quote!(u64), + quote!(.as_u64()), ); let mut gauges = Registry::new( quote!(gauges), quote!(register_gauge), format!("{}__event__gauge", output.crate_name), + quote!(u64), + quote!(.as_u64()), ); let mut timers = Registry::new( quote!(timers), quote!(register_timer), format!("{}__event__timer", output.crate_name), + quote!(core::time::Duration), + quote!(.as_duration()), ); + let units_none = Ident::new("None", Span::call_site()); + let units_duration = Ident::new("Duration", Span::call_site()); + for event in events { let ident = &event.ident; let snake = event.ident_snake(); @@ -57,45 +88,72 @@ pub fn emit(output: &Output, files: &[File]) -> TokenStream { let mut on_event = quote!(); - let count_info = &info.push(&snake, ""); + let count_info = &info.push(&snake, &units_none); - let count_id = counters.push(count_info); + let count_id = counters.push(count_info, None); on_event.extend(quote!( - self.count(#count_info, #count_id, 1); + self.count(#count_info, #count_id, 1usize); )); for field in &event.fields { - let entries = [ - (quote!(count), &field.attrs.counter, &mut counters), - (quote!(measure), &field.attrs.measure, &mut measures), - (quote!(gauge), &field.attrs.gauge, &mut gauges), + let metrics = [ + (quote!(count), &field.attrs.counter, &mut counters, None), + ( + quote!(count_nominal), + &field.attrs.nominal_counter, + &mut nominal_counters, + Some(&field.ty), + ), + (quote!(measure), &field.attrs.measure, &mut measures, None), + (quote!(gauge), &field.attrs.gauge, &mut gauges, None), ]; - for (function, list, target) in entries { + for (function, list, target, field_ty) in metrics { + let borrow = if field_ty.is_some() { + quote!(&) + } else { + quote!() + }; for metric in list { let name = format!("{snake}.{}", metric.name.value()); - let units = metric.unit.as_ref().map(|v| v.value()).unwrap_or_default(); - let info = &info.push(&name, &units); - let id = target.push(info); + let units = metric.unit.as_ref().unwrap_or(&units_none); + let info = &info.push(&name, units); + let id = target.push(info, field_ty); let field = field.ident.as_ref().unwrap(); on_event.extend(quote!( - self.#function(#info, #id, event.#field.as_metric(#units)); + self.#function(#info, #id, #borrow event.#field); )); } } - for metric in &field.attrs.timer { - let name = format!("{snake}.{}", metric.name.value()); - let units = "us"; - let info = &info.push(&name, units); - let id = timers.push(info); + let metrics = [ + ( + quote!(time), + &field.attrs.timer, + &mut timers, + &units_duration, + ), + ( + quote!(count_bool), + &field.attrs.bool_counter, + &mut bool_counters, + &units_none, + ), + ]; - let field = field.ident.as_ref().unwrap(); - on_event.extend(quote!( - self.time(#info, #id, event.#field.as_metric(#units)); - )) + for (function, list, target, units) in metrics { + for metric in list { + let name = format!("{snake}.{}", metric.name.value()); + let info = &info.push(&name, units); + let id = target.push(info, None); + + let field = field.ident.as_ref().unwrap(); + on_event.extend(quote!( + self.#function(#info, #id, event.#field); + )) + } } } @@ -136,6 +194,12 @@ pub fn emit(output: &Output, files: &[File]) -> TokenStream { let counters_init = counters.init(); let counters_probes = counters.probe(); let counters_len = counters.len; + let nominal_counters_init = nominal_counters.init(); + let nominal_counters_probes = nominal_counters.probe(); + let nominal_counters_len = nominal_counters.len; + let bool_counters_init = bool_counters.init(); + let bool_counters_probes = bool_counters.probe(); + let bool_counters_len = bool_counters.len; let measures_init = measures.init(); let measures_probes = measures.probe(); let measures_len = measures.len; @@ -160,9 +224,13 @@ pub fn emit(output: &Output, files: &[File]) -> TokenStream { metrics::aggregate::{ Registry, Recorder, + BoolRecorder, + NominalRecorder, Info, info::{self, Str}, - AsMetric as _ + Metric, + AsVariant, + Units, }, api, self @@ -174,6 +242,12 @@ pub fn emit(output: &Output, files: &[File]) -> TokenStream { #[allow(dead_code)] counters: Box<[R::Counter; #counters_len]>, #[allow(dead_code)] + bool_counters: Box<[R::BoolCounter; #bool_counters_len]>, + #[allow(dead_code)] + nominal_counters: Box<[R::NominalCounter]>, + #[allow(dead_code)] + nominal_offsets: Box<[usize; #nominal_counters_len]>, + #[allow(dead_code)] measures: Box<[R::Measure; #measures_len]>, #[allow(dead_code)] gauges: Box<[R::Gauge; #gauges_len]>, @@ -200,17 +274,25 @@ pub fn emit(output: &Output, files: &[File]) -> TokenStream { #[inline] pub fn new(registry: R) -> Self { let mut counters = Vec::with_capacity(#counters_len); + let mut bool_counters = Vec::with_capacity(#bool_counters_len); + let mut nominal_offsets = Vec::with_capacity(#nominal_counters_len); + let mut nominal_counters = Vec::with_capacity(#nominal_counters_len); let mut measures = Vec::with_capacity(#measures_len); let mut gauges = Vec::with_capacity(#gauges_len); let mut timers = Vec::with_capacity(#timers_len); #counters_init + #bool_counters_init + #nominal_counters_init #measures_init #gauges_init #timers_init Self { counters: counters.try_into().unwrap_or_else(|_| panic!("invalid len")), + bool_counters: bool_counters.try_into().unwrap_or_else(|_| panic!("invalid len")), + nominal_counters: nominal_counters.into(), + nominal_offsets: nominal_offsets.try_into().unwrap_or_else(|_| panic!("invalid len")), measures: measures.try_into().unwrap_or_else(|_| panic!("invalid len")), gauges: gauges.try_into().unwrap_or_else(|_| panic!("invalid len")), timers: timers.try_into().unwrap_or_else(|_| panic!("invalid len")), @@ -226,12 +308,42 @@ pub fn emit(output: &Output, files: &[File]) -> TokenStream { #[allow(dead_code)] #[inline(always)] - fn count(&self, info: usize, id: usize, value: u64) { + fn count(&self, info: usize, id: usize, value: T) { let info = &INFO[info]; let counter = &self.counters[id]; counter.record(info, value); } + /// Returns all of the registered bool counters + #[inline] + pub fn bool_counters(&self) -> impl Iterator + '_ { + #bool_counters + } + + #[allow(dead_code)] + #[inline(always)] + fn count_bool(&self, info: usize, id: usize, value: bool) { + let info = &INFO[info]; + let counter = &self.bool_counters[id]; + counter.record(info, value); + } + + /// Returns all of the registered nominal counters + #[inline] + pub fn nominal_counters(&self) -> impl Iterator + '_ { + use api::*; + #nominal_counters + } + + #[allow(dead_code)] + #[inline(always)] + fn count_nominal(&self, info: usize, id: usize, value: &T) { + let info = &INFO[info]; + let idx = self.nominal_offsets[id] + value.variant_idx(); + let counter = &self.nominal_counters[idx]; + counter.record(info, value.as_variant(), 1usize); + } + /// Returns all of the registered measures #[inline] pub fn measures(&self) -> impl Iterator + '_ { @@ -240,7 +352,7 @@ pub fn emit(output: &Output, files: &[File]) -> TokenStream { #[allow(dead_code)] #[inline(always)] - fn measure(&self, info: usize, id: usize, value: u64) { + fn measure(&self, info: usize, id: usize, value: T) { let info = &INFO[info]; let measure = &self.measures[id]; measure.record(info, value); @@ -254,7 +366,7 @@ pub fn emit(output: &Output, files: &[File]) -> TokenStream { #[allow(dead_code)] #[inline(always)] - fn gauge(&self, info: usize, id: usize, value: u64) { + fn gauge(&self, info: usize, id: usize, value: T) { let info = &INFO[info]; let gauge = &self.gauges[id]; gauge.record(info, value); @@ -268,7 +380,7 @@ pub fn emit(output: &Output, files: &[File]) -> TokenStream { #[allow(dead_code)] #[inline(always)] - fn time(&self, info: usize, id: usize, value: u64) { + fn time(&self, info: usize, id: usize, value: core::time::Duration) { let info = &INFO[info]; let timer = &self.timers[id]; timer.record(info, value); @@ -291,10 +403,25 @@ pub fn emit(output: &Output, files: &[File]) -> TokenStream { let probe = quote!( use #s2n_quic_core_path::probe::define; - use crate::event::metrics::aggregate::{self, Recorder, Info}; + use crate::event::metrics::aggregate::{ + self, + Recorder as MetricRecorder, + NominalRecorder, + BoolRecorder, + Info, + info + }; mod counter { #counters_probes + + pub mod bool { + #bool_counters_probes + } + + pub mod nominal { + #nominal_counters_probes + } } mod measure { #measures_probes @@ -311,6 +438,8 @@ pub fn emit(output: &Output, files: &[File]) -> TokenStream { impl aggregate::Registry for Registry { type Counter = counter::Recorder; + type BoolCounter = counter::bool::Recorder; + type NominalCounter = counter::nominal::Recorder; type Measure = measure::Recorder; type Gauge = gauge::Recorder; type Timer = timer::Recorder; @@ -320,6 +449,16 @@ pub fn emit(output: &Output, files: &[File]) -> TokenStream { counter::Recorder::new(info) } + #[inline] + fn register_bool_counter(&self, info: &'static Info) -> Self::BoolCounter { + counter::bool::Recorder::new(info) + } + + #[inline] + fn register_nominal_counter(&self, info: &'static Info, variant: &'static info::Variant) -> Self::NominalCounter { + counter::nominal::Recorder::new(info, variant) + } + #[inline] fn register_measure(&self, info: &'static Info) -> Self::Measure { measure::Recorder::new(info) @@ -355,19 +494,18 @@ struct InfoList { } impl InfoList { - pub fn push(&mut self, name: impl AsRef, units: impl AsRef) -> Info { + pub fn push(&mut self, name: impl AsRef, units: &Ident) -> Info { let id = self.len; self.len += 1; let name = name.as_ref(); let name_t = new_str(name); - let units_t = new_str(units); let entry = quote!( info::Builder { id: #id, name: #name_t, - units: #units_t, + units: Units::#units, }.build(), ); @@ -398,6 +536,12 @@ impl ToTokens for Info { } } +enum RegistryType { + Basic, + BoolCounter, + NominalCounter { nominal_offsets: TokenStream }, +} + struct Registry { len: usize, dest: TokenStream, @@ -407,10 +551,19 @@ struct Registry { probe_new: TokenStream, probe_defs: TokenStream, entries: TokenStream, + registry_type: RegistryType, + metric_ty: TokenStream, + as_metric: TokenStream, } impl Registry { - pub fn new(dest: TokenStream, register: TokenStream, probe_path: String) -> Self { + pub fn new( + dest: TokenStream, + register: TokenStream, + probe_path: String, + metric_ty: TokenStream, + as_metric: TokenStream, + ) -> Self { Self { len: 0, dest, @@ -420,11 +573,23 @@ impl Registry { probe_new: quote!(), probe_defs: quote!(), entries: quote!(), + registry_type: RegistryType::Basic, + metric_ty, + as_metric, } } pub fn init(&mut self) -> TokenStream { - self.init.clone() + if matches!(self.registry_type, RegistryType::NominalCounter { .. }) { + let init = &self.init; + quote!({ + #[allow(unused_imports)] + use api::*; + #init + }) + } else { + self.init.clone() + } } pub fn probe(&self) -> TokenStream { @@ -446,7 +611,7 @@ impl Registry { quote!() } else { quote!( - super::define!( + define!( extern "probe" { #probe_defs } @@ -454,44 +619,91 @@ impl Registry { ) }; - quote!( - #![allow(non_snake_case)] + let metric_ty = &self.metric_ty; + let as_metric = &self.as_metric; - use super::Info; + match self.registry_type { + RegistryType::Basic => { + quote!( + #![allow(non_snake_case)] - pub struct Recorder(fn(u64)); + use super::*; + use crate::event::metrics::aggregate::Metric; - impl Recorder { - pub(super) fn new(info: &'static Info) -> Self { - #probe_new - } + pub struct Recorder(fn(#metric_ty)); + + impl Recorder { + pub(crate) fn new(info: &'static Info) -> Self { + #probe_new + } + } + + impl MetricRecorder for Recorder { + fn record(&self, _info: &'static Info, value: T) { + (self.0)(value #as_metric); + } + } + + #probe_defs + ) } + RegistryType::BoolCounter => { + quote!( + #![allow(non_snake_case)] - impl super::Recorder for Recorder { - fn record(&self, _info: &'static Info, value: u64) { - (self.0)(value); - } + use super::*; + + pub struct Recorder(fn(#metric_ty)); + + impl Recorder { + pub(crate) fn new(info: &'static Info) -> Self { + #probe_new + } + } + + impl BoolRecorder for Recorder { + fn record(&self, _info: &'static Info, value: bool) { + (self.0)(value #as_metric); + } + } + + #probe_defs + ) } + RegistryType::NominalCounter { .. } => { + quote!( + #![allow(non_snake_case)] + + use super::*; + use crate::event::metrics::aggregate::Metric; - #probe_defs - ) + pub struct Recorder(fn(#metric_ty, u64, &info::Str)); + + impl Recorder { + pub(crate) fn new(info: &'static Info, _variant: &'static info::Variant) -> Self { + #probe_new + } + } + + impl NominalRecorder for Recorder { + fn record(&self, _info: &'static Info, variant: &'static info::Variant, value: T) { + (self.0)(value #as_metric, variant.id as _, variant.name); + } + } + + #probe_defs + ) + } + } } - pub fn push(&mut self, info: &Info) -> usize { + pub fn push(&mut self, info: &Info, field_ty: Option<&syn::Type>) -> usize { let id = self.len; self.len += 1; let dest = &self.dest; let register = &self.register; - self.init.extend(quote!( - #dest.push(registry.#register(&INFO[#info])); - )); - - self.entries.extend(quote!( - #id => (&INFO[#info], entry), - )); - let probe = &Ident::new(&info.name, Span::call_site()); let link_name = &Ident::new( &format!("{}__{}", self.probe_path, info.name), @@ -503,10 +715,63 @@ impl Registry { #info_id => Self(#probe), )); - self.probe_defs.extend(quote!( - #[link_name = #link_name] - fn #probe(value: u64); - )); + let metric_ty = &self.metric_ty; + + match &self.registry_type { + RegistryType::Basic | RegistryType::BoolCounter => { + self.init.extend(quote!( + #dest.push(registry.#register(&INFO[#info])); + )); + + self.entries.extend(quote!( + #id => (&INFO[#info], entry), + )); + + self.probe_defs.extend(quote!( + #[link_name = #link_name] + fn #probe(value: #metric_ty); + )); + } + RegistryType::NominalCounter { nominal_offsets } => { + let field_ty = field_ty.expect("need field type for nominal"); + + // trim off any generics + let field_ty_tokens = quote!(#field_ty); + let mut field_ty: syn::Path = syn::parse2(field_ty_tokens).unwrap(); + + if let Some(syn::PathSegment { arguments, .. }) = field_ty.segments.last_mut() { + *arguments = syn::PathArguments::None; + } + + let variants = "e!(<#field_ty as AsVariant>::VARIANTS); + + self.init.extend(quote!({ + let offset = #dest.len(); + let mut count = 0; + + for variant in #variants.iter() { + #dest.push(registry.#register(&INFO[#info], variant)); + count += 1; + } + debug_assert_ne!(count, 0, "field type needs at least one variant"); + #nominal_offsets.push(offset); + })); + + self.entries.extend(quote!( + #id => { + let offset = *entry; + let variants = #variants; + let entries = &self.#dest[offset..offset + variants.len()]; + (&INFO[#info], entries, variants) + } + )); + + self.probe_defs.extend(quote!( + #[link_name = #link_name] + fn #probe(value: #metric_ty, variant: u64, variant_name: &info::Str); + )); + } + } id } @@ -519,7 +784,12 @@ impl ToTokens for Registry { return; } - let dest = &self.dest; + let dest = if let RegistryType::NominalCounter { nominal_offsets } = &self.registry_type { + nominal_offsets + } else { + &self.dest + }; + let entries = &self.entries; tokens.extend(quote!( self.#dest.iter().enumerate().map(|(idx, entry)| { diff --git a/quic/s2n-quic-events/src/parser.rs b/quic/s2n-quic-events/src/parser.rs index 10d82b06bf..e10eb746c3 100644 --- a/quic/s2n-quic-events/src/parser.rs +++ b/quic/s2n-quic-events/src/parser.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{Output, Result}; -use heck::ToSnakeCase; +use heck::{ToShoutySnakeCase, ToSnakeCase}; use proc_macro2::{Ident, Span, TokenStream}; use quote::{quote, ToTokens}; use std::path::PathBuf; @@ -487,6 +487,25 @@ impl Enum { output.api.extend(quote!(#[non_exhaustive])); } + let mut variant_defs = quote!(); + let mut variant_matches = quote!(); + + for (idx, variant) in variants.iter().enumerate() { + let ident = &variant.ident; + let name = ident.to_string(); + let mut name = name.to_shouty_snake_case(); + name.push('\0'); + + variant_defs.extend(quote!(aggregate::info::Variant { + name: aggregate::info::Str::new(#name), + id: #idx, + },)); + + variant_matches.extend(quote!( + Self::#ident { .. } => #idx, + )); + } + output.api.extend(quote!( #derive_attrs #extra_attrs @@ -494,6 +513,18 @@ impl Enum { pub enum #ident #generics { #(#api_fields)* } + + #allow_deprecated + impl #generics aggregate::AsVariant for #ident #generics { + const VARIANTS: &'static [aggregate::info::Variant] = &[#variant_defs]; + + #[inline] + fn variant_idx(&self) -> usize { + match self { + #variant_matches + } + } + } )); } } @@ -694,9 +725,11 @@ pub struct FieldAttrs { pub builder: Option, pub snapshot: Option, pub counter: Vec, + pub bool_counter: Vec, + pub nominal_counter: Vec, pub measure: Vec, pub gauge: Vec, - pub timer: Vec, + pub timer: Vec, pub extra: TokenStream, } @@ -727,6 +760,8 @@ impl FieldAttrs { field!(builder); field!(snapshot); field!(counter[]); + field!(bool_counter[]); + field!(nominal_counter[]); field!(measure[]); field!(gauge[]); field!(timer[]); @@ -798,7 +833,7 @@ impl Variant { #[derive(Debug)] pub struct Metric { pub name: syn::LitStr, - pub unit: Option, + pub unit: Option, } impl syn::parse::Parse for Metric { @@ -817,11 +852,11 @@ impl syn::parse::Parse for Metric { } #[derive(Debug)] -pub struct Timer { +pub struct MetricNoUnit { pub name: syn::LitStr, } -impl syn::parse::Parse for Timer { +impl syn::parse::Parse for MetricNoUnit { fn parse(input: ParseStream) -> syn::Result { let name = input.parse()?; let _: syn::parse::Nothing = input.parse()?;