1use std::{any::type_name, task::Poll};
4
5use tracing::{debug, error, info, trace, trace_span, warn, Span};
6
7pub trait Logging {
9 const KIND: &'static str;
11
12 fn with_logger<F, R>(&self, f: F) -> R
14 where
15 F: FnOnce(&Logger) -> R;
16
17 fn with_logger_mut<F, R>(&mut self, f: F) -> R
19 where
20 F: FnOnce(&mut Logger) -> R;
21
22 fn set_logging_name(&mut self, name: &str) {
24 self.with_logger_mut(|logger| logger.set_transport_name(Some(name.to_string())));
25 }
26
27 fn get_logging_name(&mut self) -> Option<String> {
29 self.with_logger_mut(|logger| logger.get_transport_name().map(|name| name.to_string()))
30 }
31
32 fn enable_logging(&mut self) {
34 self.with_logger_mut(|logger| logger.enable());
35 }
36
37 fn disable_logging(&mut self) {
39 self.with_logger_mut(|logger| logger.disable());
40 }
41
42 fn is_logging_enabled(&self) -> bool {
44 self.with_logger(|logger| logger.is_enabled())
45 }
46}
47
48pub struct Logger {
50 kind: String,
51 name: Option<String>,
52 enabled: bool,
53}
54
55impl Logger {
56 pub fn new<T>() -> Self
58 where
59 T: Logging,
60 {
61 let kind = T::KIND.to_string();
62 let name = None;
63 let enabled = false;
64 Logger {
65 kind,
66 name,
67 enabled,
68 }
69 }
70
71 pub fn new_for_already_named<T>(transport_name: &str) -> Self
80 where
81 T: Logging,
82 {
83 let kind = T::KIND.to_string();
84 let name = Some(transport_name.to_string());
85 let enabled = false;
86 Logger {
87 kind,
88 name,
89 enabled,
90 }
91 }
92
93 #[inline]
98 pub fn log_open_success(&self) {
99 if self.enabled {
100 let span = self.span();
101 let _guard = span.enter();
102 info!("transport open");
103 }
104 }
105
106 #[inline]
111 pub fn log_open_failure(&self, error: impl std::error::Error) {
112 if self.enabled {
113 let span = self.span();
114 let _guard = span.enter();
115 error!("opening transport failed: {error}");
116 }
117 }
118
119 #[inline]
124 pub fn log_ready<S, F>(&self, result: &Poll<Result<S, F>>)
125 where
126 F: std::error::Error,
127 {
128 match result {
129 Poll::Ready(Ok(_)) => self.log_ready_success(),
130 Poll::Ready(Err(error)) => self.log_ready_failure(error),
131 _ => {} }
133 }
134
135 #[inline]
139 pub fn log_ready_success(&self) {
140 }
142
143 #[inline]
145 pub fn log_ready_failure(&self, error: impl std::error::Error) {
146 if self.enabled {
147 let span = self.span();
148 let _guard = span.enter();
149 error!("failed to become ready for sending: {error}");
150 }
151 }
152
153 #[inline]
159 pub fn log_message_staging<O, S, F>(&self, result: &Result<S, F>)
160 where
161 F: std::error::Error,
162 {
163 match result {
164 Ok(_) => {
165 self.log_message_staging_success::<O>();
166 }
167 Err(error) => self.log_message_staging_failure(error),
168 }
169 }
170
171 #[inline]
177 pub fn log_message_staging_success<O>(&self) {
178 if self.enabled {
179 let span = self.span();
180 let _guard = span.enter();
181 trace!(
182 message_type = type_name::<O>(),
183 "staged message for sending"
184 );
185 }
186 }
187
188 #[inline]
194 pub fn log_message_staging_failure(&self, error: impl std::error::Error) {
195 if self.enabled {
196 let span = self.span();
197 let _guard = span.enter();
198 error!("failed to stage message for sending: {error}");
199 }
200 }
201
202 #[inline]
208 pub fn log_message_preparation<O, S, F>(
209 &self,
210 send_buffer_len_before: usize,
211 send_buffer_len_after: usize,
212 result: &Result<S, F>,
213 ) where
214 F: std::error::Error,
215 {
216 match result {
217 Ok(_) => {
218 let message_size = send_buffer_len_after - send_buffer_len_before;
219 self.log_message_preparation_success::<O>(Some(message_size));
220 }
221 Err(error) => self.log_message_preparation_failure(error),
222 }
223 }
224
225 #[inline]
230 pub fn log_message_preparation_success<O>(&self, size: Option<usize>) {
231 if self.enabled {
232 let span = self.span();
233 let _guard = span.enter();
234 if let Some(size) = size {
235 trace!(
236 message_type = type_name::<O>(),
237 size_in_bytes = size,
238 "prepared message for sending"
239 );
240 } else {
241 trace!(
242 message_type = type_name::<O>(),
243 "prepared message for sending"
244 );
245 }
246 }
247 }
248
249 #[inline]
254 pub fn log_message_preparation_failure(&self, error: impl std::error::Error) {
255 if self.enabled {
256 let span = self.span();
257 let _guard = span.enter();
258 error!("failed to prepare message for sending: {error}");
259 }
260 }
261
262 #[inline]
268 pub fn log_sending<O, F>(&self, result: &Result<(), F>, size: Option<usize>)
269 where
270 F: std::error::Error,
271 {
272 match result {
273 Ok(_) => self.log_sending_success::<O>(size),
274 Err(error) => self.log_sending_failure(error),
275 }
276 }
277
278 #[inline]
280 pub fn log_sending_success<O>(&self, size: Option<usize>) {
281 if self.enabled {
282 let span = self.span();
283 let _guard = span.enter();
284 if let Some(size) = size {
285 debug!(
286 message_type = type_name::<O>(),
287 size_in_bytes = size,
288 "message sent"
289 );
290 } else {
291 debug!(message_type = type_name::<O>(), "message sent");
292 }
293 }
294 }
295
296 #[inline]
298 pub fn log_sending_failure(&self, error: impl std::error::Error) {
299 if self.enabled {
300 let span = self.span();
301 let _guard = span.enter();
302 error!("failed to send message: {error}");
303 }
304 }
305
306 #[inline]
315 pub fn log_message_arrived_unknown(&self, size: Option<usize>) {
316 if self.enabled {
317 let span = self.span();
318 let _guard = span.enter();
319 if let Some(size) = size {
320 trace!(size_in_bytes = size, "new message arrived");
321 } else {
322 trace!("new message arrived");
323 }
324 }
325 }
326
327 #[inline]
333 pub fn log_message_arrived_success<I>(&self, _item: &I, size: Option<usize>) {
334 if self.enabled {
335 let span = self.span();
336 let _guard = span.enter();
337 if let Some(size) = size {
338 trace!(
339 message_type = type_name::<I>(),
340 size_in_bytes = size,
341 "new message arrived"
342 );
343 } else {
344 trace!(message_type = type_name::<I>(), "new message arrived");
345 }
346 }
347 }
348
349 #[inline]
355 pub fn log_message_arrived_failure(&self, error: impl std::error::Error) {
356 if self.enabled {
357 let span = self.span();
358 let _guard = span.enter();
359 error!("failed to process arriving message: {error}");
360 }
361 }
362
363 #[inline]
369 pub fn log_receiving<I, F>(
370 &self,
371 result: &Poll<Option<Result<I, F>>>,
372 message_length: Option<usize>,
373 ) where
374 F: std::error::Error,
375 {
376 match result {
377 Poll::Ready(Some(Ok(item))) => self.log_receiving_success(item, message_length),
378 Poll::Ready(Some(Err(error))) => self.log_receiving_failure(error),
379 Poll::Ready(None) => self.log_remote_closed(),
380 _ => {} }
382 }
383
384 #[inline]
386 pub fn log_receiving_success<I>(&self, _item: &I, size: Option<usize>) {
387 if self.enabled {
388 let span = self.span();
389 let _guard = span.enter();
390 if let Some(size) = size {
391 debug!(
392 message_type = type_name::<I>(),
393 size_in_bytes = size,
394 "received message"
395 );
396 } else {
397 debug!(message_type = type_name::<I>(), "received message");
398 }
399 }
400 }
401
402 #[inline]
404 pub fn log_receiving_failure(&self, error: impl std::error::Error) {
405 if self.enabled {
406 let span = self.span();
407 let _guard = span.enter();
408 error!("failed to receive message: {error}");
409 }
410 }
411
412 pub fn log_receive_from_void(&self) {
414 if self.enabled {
415 let span = self.span();
416 let _guard = span.enter();
417 warn!("attempted to receive from void");
418 }
419 }
420
421 #[inline]
427 pub fn log_flush<S, F>(&self, result: &Poll<Result<S, F>>)
428 where
429 F: std::error::Error,
430 {
431 match result {
432 Poll::Ready(Ok(_)) => self.log_flush_success(),
433 Poll::Ready(Err(error)) => self.log_flush_failure(error),
434 _ => {} }
436 }
437
438 #[inline]
440 pub fn log_flush_success(&self) {
441 if self.enabled {
442 let span = self.span();
443 let _guard = span.enter();
444 debug!("outgoing messages flushed");
445 }
446 }
447
448 #[inline]
450 pub fn log_flush_failure(&self, error: impl std::error::Error) {
451 if self.enabled {
452 let span = self.span();
453 let _guard = span.enter();
454 error!("failed to flush outgoing messages: {error}");
455 }
456 }
457
458 #[inline]
463 pub fn log_close<S, F>(&self, result: &Poll<Result<S, F>>)
464 where
465 F: std::error::Error,
466 {
467 match result {
468 Poll::Ready(Ok(_)) => self.log_closed_success(),
469 Poll::Ready(Err(error)) => self.log_closed_failure(error),
470 _ => {} }
472 }
473
474 #[inline]
476 pub fn log_closed_success(&self) {
477 if self.enabled {
478 let span = self.span();
479 let _guard = span.enter();
480 info!("transport closed");
481 }
482 }
483
484 #[inline]
486 pub fn log_closed_failure(&self, error: impl std::error::Error) {
487 if self.enabled {
488 let span = self.span();
489 let _guard = span.enter();
490 error!("failed to close transport: {error}");
491 }
492 }
493
494 #[inline]
496 pub fn log_remote_closed(&self) {
497 if self.enabled {
498 let span = self.span();
499 let _guard = span.enter();
500 info!("remote transport closed");
501 }
502 }
503
504 #[inline]
506 pub fn log_incoming_filtered_out<I>(&self) {
507 if self.enabled {
508 let span = self.span();
509 let _guard = span.enter();
510 trace!(
511 message_type = type_name::<I>(),
512 "incoming message filtered out"
513 );
514 }
515 }
516
517 #[inline]
519 pub fn log_outgoing_filtered_out<I>(&self) {
520 if self.enabled {
521 let span = self.span();
522 let _guard = span.enter();
523 trace!(
524 message_type = type_name::<I>(),
525 "outgoing message filtered out"
526 );
527 }
528 }
529
530 pub fn set_transport_name(&mut self, name: Option<String>) {
532 self.name = name;
533 }
534
535 pub fn get_transport_name(&self) -> Option<&str> {
537 self.name.as_deref()
538 }
539
540 pub fn enable(&mut self) {
542 self.enabled = true;
543 }
544
545 pub fn disable(&mut self) {
547 self.enabled = false;
548 }
549
550 pub fn is_enabled(&self) -> bool {
552 self.enabled
553 }
554
555 pub fn override_kind<T>(&mut self)
557 where
558 T: Logging,
559 {
560 self.kind = T::KIND.to_string();
561 }
562
563 pub fn override_kind_with_str(&mut self, kind: &str) {
565 self.kind = kind.to_string();
566 }
567
568 pub fn override_kind_buffered<T>(&mut self)
570 where
571 T: Logging,
572 {
573 self.kind = format!("{}(buffered)", T::KIND);
574 }
575
576 pub fn override_kind_part<T>(&mut self, variant: usize)
578 where
579 T: Logging,
580 {
581 self.kind = format!("{}({variant})", T::KIND);
582 }
583
584 pub fn span(&self) -> Span {
586 if let Some(name) = &self.name {
587 trace_span!("dnet", transport = self.kind, name = name.as_str())
588 } else {
589 trace_span!("dnet", transport = self.kind)
590 }
591 }
592}