micromegas_tracing/
runtime.rs

1//! Runtime integration utilities for micromegas tracing
2//!
3//! This module provides helper functions and utilities for integrating
4//! micromegas tracing with async runtimes, particularly tokio.
5
6#[cfg(feature = "tokio")]
7use crate::dispatch::{flush_thread_buffer, init_thread_stream, unregister_thread_stream};
8
9/// Extension trait for `tokio::runtime::Builder` that adds tracing lifecycle callbacks.
10///
11/// This trait provides a convenient way to configure tokio runtimes with the proper
12/// thread lifecycle callbacks for micromegas tracing, ensuring that:
13/// - Thread streams are initialized when worker threads start
14/// - Event buffers are flushed when threads park (become idle)
15/// - Thread streams are properly unregistered when threads stop
16///
17/// This is useful in both production applications (like ingestion servers) and tests
18/// where you need proper tracing integration with tokio's thread pool.
19///
20/// # Examples
21///
22/// ```no_run
23/// use micromegas_tracing::runtime::TracingRuntimeExt;
24///
25/// let runtime = tokio::runtime::Builder::new_multi_thread()
26///     .enable_all()
27///     .thread_name("my-service")
28///     .with_tracing_callbacks()
29///     .build()
30///     .expect("Failed to build runtime");
31/// ```
32#[cfg(feature = "tokio")]
33pub trait TracingRuntimeExt {
34    /// Configures the runtime builder with standard tracing lifecycle callbacks.
35    ///
36    /// This method adds the following callbacks:
37    /// - `on_thread_start`: Initializes thread-local tracing stream
38    /// - `on_thread_park`: Flushes event buffer when thread becomes idle
39    /// - `on_thread_stop`: Unregisters thread stream to prevent dangling pointers
40    fn with_tracing_callbacks(&mut self) -> &mut Self;
41
42    /// Configures the runtime builder with tracing callbacks and custom thread start logic.
43    ///
44    /// This is useful when you need to perform additional setup during thread start
45    /// while still maintaining the standard tracing lifecycle.
46    ///
47    /// # Arguments
48    ///
49    /// * `on_start` - Custom function to call in addition to `init_thread_stream()`
50    ///
51    /// # Examples
52    ///
53    /// ```no_run
54    /// use micromegas_tracing::runtime::TracingRuntimeExt;
55    /// use std::sync::atomic::{AtomicUsize, Ordering};
56    /// use std::sync::Arc;
57    ///
58    /// let counter = Arc::new(AtomicUsize::new(0));
59    /// let counter_clone = counter.clone();
60    ///
61    /// let runtime = tokio::runtime::Builder::new_multi_thread()
62    ///     .enable_all()
63    ///     .with_tracing_callbacks_and_custom_start(move || {
64    ///         let id = counter_clone.fetch_add(1, Ordering::Relaxed);
65    ///         eprintln!("Worker thread {} starting", id);
66    ///     })
67    ///     .build()
68    ///     .expect("Failed to build runtime");
69    /// ```
70    fn with_tracing_callbacks_and_custom_start<F>(&mut self, on_start: F) -> &mut Self
71    where
72        F: Fn() + Send + Sync + 'static;
73}
74
75#[cfg(feature = "tokio")]
76impl TracingRuntimeExt for tokio::runtime::Builder {
77    fn with_tracing_callbacks(&mut self) -> &mut Self {
78        self.on_thread_start(|| {
79            init_thread_stream();
80        })
81        .on_thread_stop(|| {
82            flush_thread_buffer();
83            unregister_thread_stream();
84        })
85    }
86
87    fn with_tracing_callbacks_and_custom_start<F>(&mut self, on_start: F) -> &mut Self
88    where
89        F: Fn() + Send + Sync + 'static,
90    {
91        self.on_thread_start(move || {
92            init_thread_stream();
93            on_start();
94        })
95        .on_thread_stop(|| {
96            flush_thread_buffer();
97            unregister_thread_stream();
98        })
99    }
100}