nautilus_common/logging/
mod.rs1pub mod headers;
19pub mod logger;
20pub mod writer;
21
22use std::{
23 collections::HashMap,
24 env,
25 str::FromStr,
26 sync::atomic::{AtomicBool, Ordering},
27};
28
29use log::LevelFilter;
30use nautilus_core::{time::get_atomic_clock_static, UUID4};
31use nautilus_model::identifiers::TraderId;
32use tracing_subscriber::EnvFilter;
33use ustr::Ustr;
34
35use self::{
36 logger::{LogGuard, Logger, LoggerConfig},
37 writer::FileWriterConfig,
38};
39use crate::enums::LogLevel;
40
41pub const RECV: &str = "<--";
42pub const SENT: &str = "-->";
43pub const CMD: &str = "[CMD]";
44pub const EVT: &str = "[EVT]";
45pub const DOC: &str = "[DOC]";
46pub const RPT: &str = "[RPT]";
47pub const REQ: &str = "[REQ]";
48pub const RES: &str = "[RES]";
49
50static LOGGING_INITIALIZED: AtomicBool = AtomicBool::new(false);
51static LOGGING_BYPASSED: AtomicBool = AtomicBool::new(false);
52static LOGGING_REALTIME: AtomicBool = AtomicBool::new(true);
53static LOGGING_COLORED: AtomicBool = AtomicBool::new(true);
54
55#[no_mangle]
57pub extern "C" fn logging_is_initialized() -> u8 {
58 u8::from(LOGGING_INITIALIZED.load(Ordering::Relaxed))
59}
60
61#[no_mangle]
63pub extern "C" fn logging_set_bypass() {
64 LOGGING_BYPASSED.store(true, Ordering::Relaxed);
65}
66
67#[no_mangle]
69pub extern "C" fn logging_shutdown() {
70 todo!()
71}
72
73#[no_mangle]
75pub extern "C" fn logging_is_colored() -> u8 {
76 u8::from(LOGGING_COLORED.load(Ordering::Relaxed))
77}
78
79#[no_mangle]
81pub extern "C" fn logging_clock_set_realtime_mode() {
82 LOGGING_REALTIME.store(true, Ordering::Relaxed);
83}
84
85#[no_mangle]
87pub extern "C" fn logging_clock_set_static_mode() {
88 LOGGING_REALTIME.store(false, Ordering::Relaxed);
89}
90
91#[no_mangle]
93pub extern "C" fn logging_clock_set_static_time(time_ns: u64) {
94 let clock = get_atomic_clock_static();
95 clock.set_time(time_ns.into());
96}
97
98pub fn init_tracing() {
109 if let Ok(v) = env::var("RUST_LOG") {
111 let env_filter = EnvFilter::new(v.clone());
112
113 tracing_subscriber::fmt()
114 .with_env_filter(env_filter)
115 .try_init()
116 .unwrap_or_else(|e| {
117 tracing::error!("Cannot set tracing subscriber because of error: {e}");
118 });
119 println!("Initialized tracing logs with RUST_LOG={v}");
120 }
121}
122
123pub fn init_logging(
135 trader_id: TraderId,
136 instance_id: UUID4,
137 config: LoggerConfig,
138 file_config: FileWriterConfig,
139) -> LogGuard {
140 LOGGING_INITIALIZED.store(true, Ordering::Relaxed);
141 LOGGING_COLORED.store(config.is_colored, Ordering::Relaxed);
142 Logger::init_with_config(trader_id, instance_id, config, file_config)
143}
144
145#[must_use]
146pub const fn map_log_level_to_filter(log_level: LogLevel) -> LevelFilter {
147 match log_level {
148 LogLevel::Off => LevelFilter::Off,
149 LogLevel::Trace => LevelFilter::Trace,
150 LogLevel::Debug => LevelFilter::Debug,
151 LogLevel::Info => LevelFilter::Info,
152 LogLevel::Warning => LevelFilter::Warn,
153 LogLevel::Error => LevelFilter::Error,
154 }
155}
156
157#[must_use]
158pub fn parse_level_filter_str(s: &str) -> LevelFilter {
159 let mut log_level_str = s.to_string().to_uppercase();
160 if log_level_str == "WARNING" {
161 log_level_str = "WARN".to_string();
162 }
163 LevelFilter::from_str(&log_level_str)
164 .unwrap_or_else(|_| panic!("Invalid `LevelFilter` string, was {log_level_str}"))
165}
166
167#[must_use]
168pub fn parse_component_levels(
169 original_map: Option<HashMap<String, serde_json::Value>>,
170) -> HashMap<Ustr, LevelFilter> {
171 match original_map {
172 Some(map) => {
173 let mut new_map = HashMap::new();
174 for (key, value) in map {
175 let ustr_key = Ustr::from(&key);
176 let value = parse_level_filter_str(value.as_str().unwrap());
177 new_map.insert(ustr_key, value);
178 }
179 new_map
180 }
181 None => HashMap::new(),
182 }
183}