quantum_log/
lib.rs

1//! QuantumLog - 高性能异步日志库
2//!
3//! QuantumLog 是一个专为高性能计算环境设计的异步日志库,
4//! 支持多种输出格式和目标,包括文件、数据库和标准输出。
5//!
6//! # 快速开始
7//!
8//! ```rust
9//! use quantum_log::{init, shutdown};
10//! use tracing::{info, warn, error};
11//!
12//! #[tokio::main]
13//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
14//!     // 初始化 QuantumLog
15//!     init().await?;
16//!     
17//!     // 使用标准的 tracing 宏
18//!     info!("Application started");
19//!     warn!("This is a warning");
20//!     error!("This is an error");
21//!     
22//!     // 优雅关闭
23//!     shutdown().await?;
24//!     Ok(())
25//! }
26//! ```
27//!
28//! # 自定义配置
29//!
30//! ```rust
31//! use quantum_log::{QuantumLogConfig, init_with_config};
32//!
33//! #[tokio::main]
34//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
35//!     let config = QuantumLogConfig {
36//!         global_level: "DEBUG".to_string(),
37//!         ..Default::default()
38//!     };
39//!     
40//!     quantum_log::init_with_config(config).await?;
41//!     
42//!     // 你的应用代码...
43//!     
44//!     quantum_log::shutdown().await?;
45//!     Ok(())
46//! }
47//! ```
48
49pub mod config;
50pub mod core;
51pub mod diagnostics;
52pub mod error;
53pub mod mpi;
54pub mod shutdown;
55pub mod sinks;
56pub mod utils;
57
58#[cfg(feature = "database")]
59pub mod database {
60    pub use crate::sinks::database::*;
61}
62
63pub use config::{
64    load_config_from_file, BackpressureStrategy, OutputFormat, QuantumLogConfig,
65    QuantumLoggerConfig, StdoutConfig,
66};
67pub use diagnostics::{get_diagnostics, DiagnosticsSnapshot};
68pub use error::{QuantumLogError, Result};
69pub use shutdown::{
70    ShutdownCoordinator, ShutdownHandle as QuantumShutdownHandle, ShutdownListener, ShutdownSignal,
71    ShutdownState,
72};
73
74pub use core::event::QuantumLogEvent;
75pub use core::subscriber::{BufferStats, QuantumLogSubscriber, QuantumLogSubscriberBuilder};
76
77use once_cell::sync::Lazy;
78use std::sync::{
79    atomic::{AtomicBool, Ordering},
80    Arc, Mutex,
81};
82// Initialize diagnostics
83use crate::diagnostics::init_diagnostics;
84
85/// 库版本
86pub const VERSION: &str = env!("CARGO_PKG_VERSION");
87
88/// 全局订阅器实例
89static GLOBAL_SUBSCRIBER: Lazy<Arc<Mutex<Option<QuantumLogSubscriber>>>> =
90    Lazy::new(|| Arc::new(Mutex::new(None)));
91
92/// QuantumLog 初始化标记
93/// 用于确保日志系统只被初始化一次
94pub static IS_QUANTUM_LOG_INITIALIZED: AtomicBool = AtomicBool::new(false);
95
96/// 使用默认配置初始化 QuantumLog
97///
98/// 这是一个便捷函数,使用默认配置初始化 QuantumLog。
99/// 默认配置包括:
100/// - 启用控制台输出
101/// - 日志级别为 INFO
102/// - 使用默认格式化器
103///
104/// # 示例
105///
106/// ```rust
107/// use quantum_log::init;
108///
109/// #[tokio::main]
110/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
111///     init().await?;
112///     tracing::info!("Hello, QuantumLog!");
113///     Ok(())
114/// }
115/// ```
116pub async fn init() -> Result<()> {
117    // Ensure diagnostics subsystem is initialized early
118    let _ = init_diagnostics();
119
120    let config = QuantumLogConfig {
121        pre_init_stdout_enabled: true,
122        stdout: Some(crate::config::StdoutConfig {
123            enabled: true,
124            ..Default::default()
125        }),
126        ..Default::default()
127    };
128
129    let mut subscriber = QuantumLogSubscriber::with_config(config)?;
130
131    // 初始化订阅器
132    subscriber.initialize().await?;
133
134    // 存储订阅器实例以便后续关闭
135    if let Ok(mut global) = GLOBAL_SUBSCRIBER.lock() {
136        *global = Some(subscriber.clone());
137    }
138
139    // 安装为全局订阅器
140    subscriber.install_global()?;
141
142    Ok(())
143}
144
145/// 使用指定配置初始化 QuantumLog
146///
147/// # 参数
148///
149/// * `config` - QuantumLog 配置
150///
151/// # 示例
152///
153/// ```rust
154/// use quantum_log::{QuantumLogConfig, init_with_config};
155///
156/// #[tokio::main]
157/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
158///     let config = QuantumLogConfig {
159///         global_level: "DEBUG".to_string(),
160///         ..Default::default()
161///     };
162///     
163///     quantum_log::init_with_config(config).await?;
164///     quantum_log::shutdown().await?;
165///     Ok(())
166/// }
167/// ```
168pub async fn init_with_config(config: QuantumLogConfig) -> Result<()> {
169    // Ensure diagnostics subsystem is initialized early
170    let _ = init_diagnostics();
171
172    let mut subscriber = QuantumLogSubscriber::with_config(config)?;
173
174    // 初始化订阅器
175    subscriber.initialize().await?;
176
177    // 存储订阅器实例以便后续关闭
178    if let Ok(mut global) = GLOBAL_SUBSCRIBER.lock() {
179        *global = Some(subscriber.clone());
180    }
181
182    // 安装为全局订阅器(这会消费 subscriber)
183    subscriber.install_global()?;
184
185    Ok(())
186}
187
188/// 使用构建器初始化 QuantumLog
189///
190/// # 参数
191///
192/// * `builder_fn` - 构建器配置函数
193///
194/// # 示例
195///
196/// ```rust
197/// use quantum_log::{init_with_builder, shutdown};
198///
199/// #[tokio::main]
200/// async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
201///     init_with_builder(|builder| {
202///         builder
203///             .max_buffer_size(5000)
204///             .custom_field("service", "my-app")
205///             .custom_field("version", "1.0.0")
206///     }).await?;
207///     
208///     shutdown().await?;
209///     Ok(())
210/// }
211/// ```
212pub async fn init_with_builder<F>(
213    builder_fn: F,
214) -> std::result::Result<(), Box<dyn std::error::Error + Send + Sync>>
215where
216    F: FnOnce(QuantumLogSubscriberBuilder) -> QuantumLogSubscriberBuilder,
217{
218    // Ensure diagnostics subsystem is initialized early
219    let _ = init_diagnostics();
220
221    let builder = QuantumLogSubscriber::builder();
222    let mut subscriber = builder_fn(builder).build()?;
223
224    // 初始化订阅器
225    subscriber.initialize().await?;
226
227    // 存储订阅器实例以便后续关闭
228    if let Ok(mut global) = GLOBAL_SUBSCRIBER.lock() {
229        *global = Some(subscriber.clone());
230    }
231
232    // 安装为全局订阅器(这会消费 subscriber)
233    subscriber.install_global()?;
234
235    Ok(())
236}
237
238/// 优雅关闭 QuantumLog
239///
240/// 这会关闭所有 sink 并等待它们完成处理所有待处理的事件。
241/// 建议在应用程序退出前调用此函数。
242///
243/// # 示例
244///
245/// ```rust
246/// use quantum_log::{init, shutdown};
247///
248/// #[tokio::main]
249/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
250///     init().await?;
251///     
252///     // 你的应用代码...
253///     
254///     shutdown().await?;
255///     Ok(())
256/// }
257/// ```
258pub async fn shutdown() -> Result<()> {
259    let subscriber = if let Ok(mut global) = GLOBAL_SUBSCRIBER.lock() {
260        global.take()
261    } else {
262        None
263    };
264
265    if let Some(subscriber) = subscriber {
266        subscriber.shutdown().await?;
267    }
268    Ok(())
269}
270
271/// 获取缓冲区统计信息
272///
273/// 返回当前预初始化缓冲区的统计信息,包括当前大小、丢弃的事件数量等。
274///
275/// # 示例
276///
277/// ```rust
278/// use quantum_log::{init, get_buffer_stats, shutdown};
279///
280/// #[tokio::main]
281/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
282///     init().await?;
283///     
284///     let stats = get_buffer_stats();
285///     if let Some(stats) = stats {
286///         println!("Buffer size: {}, Dropped: {}", stats.current_size, stats.dropped_count);
287///     }
288///     
289///     shutdown().await?;
290///     Ok(())
291/// }
292/// ```
293pub fn get_buffer_stats() -> Option<BufferStats> {
294    if let Ok(global) = GLOBAL_SUBSCRIBER.lock() {
295        global
296            .as_ref()
297            .map(|subscriber| subscriber.get_buffer_stats())
298    } else {
299        None
300    }
301}
302
303/// 检查 QuantumLog 是否已初始化
304///
305/// # 示例
306///
307/// ```rust
308/// use quantum_log::{init, is_initialized, shutdown};
309///
310/// #[tokio::main]
311/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
312///     assert!(!is_initialized());
313///     
314///     init().await?;
315///     assert!(is_initialized());
316///     
317///     shutdown().await?;
318///     Ok(())
319/// }
320/// ```
321pub fn is_initialized() -> bool {
322    if let Ok(global) = GLOBAL_SUBSCRIBER.lock() {
323        global
324            .as_ref()
325            .is_some_and(|subscriber| subscriber.is_initialized())
326    } else {
327        false
328    }
329}
330
331/// 获取当前配置的引用
332///
333/// 返回当前 QuantumLog 实例使用的配置。如果 QuantumLog 未初始化,返回 None。
334pub fn get_config() -> Option<QuantumLogConfig> {
335    if let Ok(global) = GLOBAL_SUBSCRIBER.lock() {
336        global
337            .as_ref()
338            .map(|subscriber| subscriber.config().clone())
339    } else {
340        None
341    }
342}
343
344// 外部依赖
345use tokio::sync::oneshot;
346
347/// 关闭句柄,用于优雅关闭日志系统
348#[derive(Debug)]
349pub struct ShutdownHandle {
350    sender: Option<oneshot::Sender<()>>,
351}
352
353impl ShutdownHandle {
354    /// 创建新的关闭句柄
355    pub fn new(sender: oneshot::Sender<()>) -> Self {
356        Self {
357            sender: Some(sender),
358        }
359    }
360
361    /// 触发优雅关闭
362    pub async fn shutdown(mut self) -> Result<()> {
363        if let Some(sender) = self.sender.take() {
364            sender.send(()).map_err(|_| {
365                QuantumLogError::ShutdownError("Failed to send shutdown signal".to_string())
366            })?;
367        }
368        Ok(())
369    }
370}
371
372/// 初始化 QuantumLog 日志系统
373///
374/// 这是设计文档中指定的主要初始化函数,它会:
375/// 1. 检查是否已经初始化,确保只初始化一次
376/// 2. 使用默认配置创建并初始化 QuantumLogSubscriber
377/// 3. 返回 ShutdownHandle 用于优雅关闭
378///
379/// # 返回值
380///
381/// 返回 `ShutdownHandle`,可用于优雅关闭日志系统
382///
383/// # 错误
384///
385/// 如果日志系统已经初始化,将返回错误
386///
387/// # 示例
388///
389/// ```rust
390/// use quantum_log::init_quantum_logger;
391///
392/// #[tokio::main]
393/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
394///     let shutdown_handle = init_quantum_logger().await?;
395///     
396///     // 你的应用代码...
397///     
398///     shutdown_handle.shutdown().await?;
399///     Ok(())
400/// }
401/// ```
402pub async fn init_quantum_logger() -> Result<ShutdownHandle> {
403    // Ensure diagnostics subsystem is initialized early
404    let _ = init_diagnostics();
405
406    // 检查是否已经初始化
407    if IS_QUANTUM_LOG_INITIALIZED
408        .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst)
409        .is_err()
410    {
411        return Err(QuantumLogError::InitializationError(
412            "QuantumLog has already been initialized".to_string(),
413        ));
414    }
415
416    // 创建默认配置的订阅器
417    let mut subscriber = QuantumLogSubscriber::new().map_err(|e| {
418        QuantumLogError::InitializationError(format!("Failed to create subscriber: {}", e))
419    })?;
420
421    // 初始化订阅器
422    subscriber.initialize().await.map_err(|e| {
423        QuantumLogError::InitializationError(format!("Failed to initialize subscriber: {}", e))
424    })?;
425
426    // 创建关闭通道
427    let (shutdown_sender, shutdown_receiver) = oneshot::channel();
428
429    // 克隆订阅器用于关闭任务
430    let subscriber_for_shutdown = subscriber.clone();
431
432    // 保存订阅器到全局状态
433    if let Ok(mut global) = GLOBAL_SUBSCRIBER.lock() {
434        *global = Some(subscriber.clone());
435    } else {
436        // 如果获取锁失败,重置初始化标记
437        IS_QUANTUM_LOG_INITIALIZED.store(false, Ordering::SeqCst);
438        return Err(QuantumLogError::InitializationError(
439            "Failed to acquire global subscriber lock".to_string(),
440        ));
441    }
442
443    // 安装为全局订阅器
444    if let Err(e) = subscriber.install_global() {
445        // 如果安装失败,清理状态
446        IS_QUANTUM_LOG_INITIALIZED.store(false, Ordering::SeqCst);
447        if let Ok(mut global) = GLOBAL_SUBSCRIBER.lock() {
448            *global = None;
449        }
450        return Err(QuantumLogError::InitializationError(format!(
451            "Failed to install global subscriber: {}",
452            e
453        )));
454    }
455
456    // 启动关闭监听任务
457    tokio::spawn(async move {
458        if shutdown_receiver.await.is_ok() {
459            // 执行优雅关闭
460            if let Err(e) = subscriber_for_shutdown.shutdown().await {
461                eprintln!("Error during shutdown: {}", e);
462            }
463            // 重置初始化标记
464            IS_QUANTUM_LOG_INITIALIZED.store(false, Ordering::SeqCst);
465            // 清理全局订阅器
466            if let Ok(mut global) = GLOBAL_SUBSCRIBER.lock() {
467                *global = None;
468            }
469        }
470    });
471
472    Ok(ShutdownHandle::new(shutdown_sender))
473}