1 // Copyright (c) 2023 Huawei Device Co., Ltd. 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 use std::time::{Duration, Instant}; 15 16 /// Time statistics of a request in each stage. 17 #[derive(Default, Clone)] 18 pub struct TimeGroup { 19 // TODO add total request time. 20 dns_start: Option<Instant>, 21 dns_end: Option<Instant>, 22 dns_duration: Option<Duration>, 23 tcp_start: Option<Instant>, 24 tcp_end: Option<Instant>, 25 tcp_duration: Option<Duration>, 26 #[cfg(feature = "http3")] 27 quic_start: Option<Instant>, 28 #[cfg(feature = "http3")] 29 quic_end: Option<Instant>, 30 #[cfg(feature = "http3")] 31 quic_duration: Option<Duration>, 32 #[cfg(feature = "__tls")] 33 tls_start: Option<Instant>, 34 #[cfg(feature = "__tls")] 35 tls_end: Option<Instant>, 36 #[cfg(feature = "__tls")] 37 tls_duration: Option<Duration>, 38 conn_start: Option<Instant>, 39 conn_end: Option<Instant>, 40 conn_duration: Option<Duration>, 41 // start send bytes to peer. 42 transfer_start: Option<Instant>, 43 // received first byte from peer. 44 transfer_end: Option<Instant>, 45 transfer_duration: Option<Duration>, 46 } 47 48 impl TimeGroup { set_dns_start(&mut self, start: Instant)49 pub(crate) fn set_dns_start(&mut self, start: Instant) { 50 self.dns_start = Some(start) 51 } 52 set_dns_end(&mut self, end: Instant)53 pub(crate) fn set_dns_end(&mut self, end: Instant) { 54 if let Some(start) = self.dns_start { 55 self.dns_duration = end.checked_duration_since(start); 56 } 57 self.dns_end = Some(end) 58 } 59 set_tcp_start(&mut self, start: Instant)60 pub(crate) fn set_tcp_start(&mut self, start: Instant) { 61 self.tcp_start = Some(start) 62 } 63 set_tcp_end(&mut self, end: Instant)64 pub(crate) fn set_tcp_end(&mut self, end: Instant) { 65 if let Some(start) = self.tcp_start { 66 self.tcp_duration = end.checked_duration_since(start); 67 } 68 self.tcp_end = Some(end) 69 } 70 71 #[cfg(feature = "http3")] set_quic_start(&mut self, start: Instant)72 pub(crate) fn set_quic_start(&mut self, start: Instant) { 73 self.quic_start = Some(start) 74 } 75 76 #[cfg(feature = "http3")] set_quic_end(&mut self, end: Instant)77 pub(crate) fn set_quic_end(&mut self, end: Instant) { 78 if let Some(start) = self.quic_start { 79 self.quic_duration = end.checked_duration_since(start); 80 } 81 self.quic_end = Some(end) 82 } 83 84 #[cfg(feature = "__tls")] set_tls_start(&mut self, start: Instant)85 pub(crate) fn set_tls_start(&mut self, start: Instant) { 86 self.tls_start = Some(start) 87 } 88 89 #[cfg(feature = "__tls")] set_tls_end(&mut self, end: Instant)90 pub(crate) fn set_tls_end(&mut self, end: Instant) { 91 if let Some(start) = self.tls_start { 92 self.tls_duration = end.checked_duration_since(start) 93 } 94 self.tls_end = Some(end) 95 } 96 set_transfer_start(&mut self, start: Instant)97 pub(crate) fn set_transfer_start(&mut self, start: Instant) { 98 self.transfer_start = Some(start) 99 } 100 set_transfer_end(&mut self, end: Instant)101 pub(crate) fn set_transfer_end(&mut self, end: Instant) { 102 if let Some(start) = self.transfer_start { 103 self.transfer_duration = end.checked_duration_since(start) 104 } 105 self.transfer_end = Some(end) 106 } 107 set_connect_start(&mut self, start: Instant)108 pub(crate) fn set_connect_start(&mut self, start: Instant) { 109 self.conn_start = Some(start) 110 } 111 set_connect_end(&mut self, end: Instant)112 pub(crate) fn set_connect_end(&mut self, end: Instant) { 113 if let Some(start) = self.conn_start { 114 self.conn_duration = end.checked_duration_since(start) 115 } 116 self.conn_end = Some(end) 117 } 118 119 #[cfg(feature = "http3")] update_quic_start(&mut self, start: Option<Instant>)120 pub(crate) fn update_quic_start(&mut self, start: Option<Instant>) { 121 self.quic_start = start 122 } 123 124 #[cfg(feature = "http3")] update_quic_end(&mut self, end: Option<Instant>)125 pub(crate) fn update_quic_end(&mut self, end: Option<Instant>) { 126 self.quic_end = end 127 } 128 129 #[cfg(feature = "http3")] update_quic_duration(&mut self, duration: Option<Duration>)130 pub(crate) fn update_quic_duration(&mut self, duration: Option<Duration>) { 131 self.quic_duration = duration 132 } 133 update_tcp_start(&mut self, start: Option<Instant>)134 pub(crate) fn update_tcp_start(&mut self, start: Option<Instant>) { 135 self.tcp_start = start 136 } 137 update_tcp_end(&mut self, end: Option<Instant>)138 pub(crate) fn update_tcp_end(&mut self, end: Option<Instant>) { 139 self.tcp_end = end 140 } 141 update_tcp_duration(&mut self, duration: Option<Duration>)142 pub(crate) fn update_tcp_duration(&mut self, duration: Option<Duration>) { 143 self.tcp_duration = duration 144 } 145 146 #[cfg(feature = "__tls")] update_tls_start(&mut self, start: Option<Instant>)147 pub(crate) fn update_tls_start(&mut self, start: Option<Instant>) { 148 self.tls_start = start 149 } 150 151 #[cfg(feature = "__tls")] update_tls_end(&mut self, end: Option<Instant>)152 pub(crate) fn update_tls_end(&mut self, end: Option<Instant>) { 153 self.tls_end = end 154 } 155 156 #[cfg(feature = "__tls")] update_tls_duration(&mut self, duration: Option<Duration>)157 pub(crate) fn update_tls_duration(&mut self, duration: Option<Duration>) { 158 self.tls_duration = duration 159 } 160 update_dns_start(&mut self, start: Option<Instant>)161 pub(crate) fn update_dns_start(&mut self, start: Option<Instant>) { 162 self.dns_start = start 163 } 164 update_dns_end(&mut self, end: Option<Instant>)165 pub(crate) fn update_dns_end(&mut self, end: Option<Instant>) { 166 self.dns_end = end 167 } 168 update_dns_duration(&mut self, duration: Option<Duration>)169 pub(crate) fn update_dns_duration(&mut self, duration: Option<Duration>) { 170 self.dns_duration = duration 171 } 172 update_connection_start(&mut self, start: Option<Instant>)173 pub(crate) fn update_connection_start(&mut self, start: Option<Instant>) { 174 self.conn_start = start 175 } 176 update_connection_end(&mut self, end: Option<Instant>)177 pub(crate) fn update_connection_end(&mut self, end: Option<Instant>) { 178 self.conn_end = end 179 } 180 update_connection_duration(&mut self, duration: Option<Duration>)181 pub(crate) fn update_connection_duration(&mut self, duration: Option<Duration>) { 182 self.conn_duration = duration 183 } 184 update_transport_conn_time(&mut self, time_group: &TimeGroup)185 pub(crate) fn update_transport_conn_time(&mut self, time_group: &TimeGroup) { 186 self.update_dns_start(time_group.dns_start_time()); 187 self.update_dns_end(time_group.dns_end_time()); 188 self.update_dns_duration(time_group.dns_duration()); 189 190 self.update_tcp_start(time_group.tcp_start_time()); 191 self.update_tcp_end(time_group.tcp_end_time()); 192 self.update_tcp_duration(time_group.tcp_duration()); 193 194 #[cfg(feature = "http3")] 195 self.update_quic_start(time_group.quic_start_time()); 196 #[cfg(feature = "http3")] 197 self.update_quic_end(time_group.quic_end_time()); 198 #[cfg(feature = "http3")] 199 self.update_quic_duration(time_group.quic_duration()); 200 201 self.update_tcp_start(time_group.tcp_start_time()); 202 self.update_tcp_end(time_group.tcp_end_time()); 203 self.update_tcp_duration(time_group.tcp_duration()); 204 205 #[cfg(feature = "__tls")] 206 self.update_tls_start(time_group.tls_start_time()); 207 #[cfg(feature = "__tls")] 208 self.update_tls_end(time_group.tls_end_time()); 209 #[cfg(feature = "__tls")] 210 self.update_tls_duration(time_group.tls_duration()); 211 212 self.update_connection_start(time_group.connect_start_time()); 213 self.update_connection_end(time_group.connect_end_time()); 214 self.update_connection_duration(time_group.connect_duration()); 215 } 216 217 /// Gets the point in time when the tcp connection starts to be 218 /// established. tcp_start_time(&self) -> Option<Instant>219 pub fn tcp_start_time(&self) -> Option<Instant> { 220 self.tcp_start 221 } 222 223 /// Gets the point in time when the tcp connection was established. tcp_end_time(&self) -> Option<Instant>224 pub fn tcp_end_time(&self) -> Option<Instant> { 225 self.tcp_end 226 } 227 228 /// Gets the total time taken to establish a tcp connection. tcp_duration(&self) -> Option<Duration>229 pub fn tcp_duration(&self) -> Option<Duration> { 230 self.tcp_duration 231 } 232 233 /// Gets the point in time when the quic connection starts to be 234 /// established. 235 #[cfg(feature = "http3")] quic_start_time(&self) -> Option<Instant>236 pub fn quic_start_time(&self) -> Option<Instant> { 237 self.quic_start 238 } 239 240 /// Gets the point in time when the quic connection was established. 241 #[cfg(feature = "http3")] quic_end_time(&self) -> Option<Instant>242 pub fn quic_end_time(&self) -> Option<Instant> { 243 self.quic_end 244 } 245 246 /// Gets the total time taken to establish a quic connection. 247 #[cfg(feature = "http3")] quic_duration(&self) -> Option<Duration>248 pub fn quic_duration(&self) -> Option<Duration> { 249 self.quic_duration 250 } 251 252 /// Gets the start point in time of the tls handshake. 253 #[cfg(feature = "__tls")] tls_start_time(&self) -> Option<Instant>254 pub fn tls_start_time(&self) -> Option<Instant> { 255 self.tls_start 256 } 257 258 /// Gets the point in time when the tls connection was established. 259 #[cfg(feature = "__tls")] tls_end_time(&self) -> Option<Instant>260 pub fn tls_end_time(&self) -> Option<Instant> { 261 self.tls_end 262 } 263 264 /// Gets the time taken for the tls connection to be established. 265 #[cfg(feature = "__tls")] tls_duration(&self) -> Option<Duration>266 pub fn tls_duration(&self) -> Option<Duration> { 267 self.tls_duration 268 } 269 270 /// Gets the point in time when the dns query started (not currently 271 /// recorded). dns_start_time(&self) -> Option<Instant>272 pub fn dns_start_time(&self) -> Option<Instant> { 273 self.dns_start 274 } 275 276 /// Gets the point in time when the dns query ended (not currently 277 /// recorded). dns_end_time(&self) -> Option<Instant>278 pub fn dns_end_time(&self) -> Option<Instant> { 279 self.dns_end 280 } 281 282 /// Gets the time spent on dns queries (not currently recorded). dns_duration(&self) -> Option<Duration>283 pub fn dns_duration(&self) -> Option<Duration> { 284 self.dns_duration 285 } 286 287 /// Gets the start point in time of data transmission. transfer_start_time(&self) -> Option<Instant>288 pub fn transfer_start_time(&self) -> Option<Instant> { 289 self.transfer_start 290 } 291 292 /// Gets the point in time the data was received. transfer_end_time(&self) -> Option<Instant>293 pub fn transfer_end_time(&self) -> Option<Instant> { 294 self.transfer_end 295 } 296 297 /// Gets the time it takes from the time the data is sent to the time it is 298 /// received. transfer_duration(&self) -> Option<Duration>299 pub fn transfer_duration(&self) -> Option<Duration> { 300 self.transfer_duration 301 } 302 303 /// Gets the point in time to start establishing the request connection. connect_start_time(&self) -> Option<Instant>304 pub fn connect_start_time(&self) -> Option<Instant> { 305 self.conn_start 306 } 307 308 /// Gets the point in time when the request connection was established. connect_end_time(&self) -> Option<Instant>309 pub fn connect_end_time(&self) -> Option<Instant> { 310 self.conn_end 311 } 312 313 /// Gets the time it took to establish the requested connection. connect_duration(&self) -> Option<Duration>314 pub fn connect_duration(&self) -> Option<Duration> { 315 self.conn_duration 316 } 317 } 318