nautilus_common/ffi/
logging.rs1use std::{
17 ffi::c_char,
18 ops::{Deref, DerefMut},
19};
20
21use nautilus_core::{
22 UUID4,
23 ffi::{
24 parsing::{optional_bytes_to_json, u8_as_bool},
25 string::{cstr_as_str, cstr_to_ustr, optional_cstr_to_str},
26 },
27};
28use nautilus_model::identifiers::TraderId;
29
30use crate::{
31 enums::{LogColor, LogLevel},
32 logging::{
33 headers, init_logging,
34 logger::{self, LogGuard, LoggerConfig},
35 map_log_level_to_filter, parse_component_levels,
36 writer::FileWriterConfig,
37 },
38};
39
40#[repr(C)]
49#[allow(non_camel_case_types)]
50#[derive(Debug)]
51pub struct LogGuard_API(Box<LogGuard>);
52
53impl Deref for LogGuard_API {
54 type Target = LogGuard;
55
56 fn deref(&self) -> &Self::Target {
57 &self.0
58 }
59}
60
61impl DerefMut for LogGuard_API {
62 fn deref_mut(&mut self) -> &mut Self::Target {
63 &mut self.0
64 }
65}
66
67#[unsafe(no_mangle)]
89pub unsafe extern "C" fn logging_init(
90 trader_id: TraderId,
91 instance_id: UUID4,
92 level_stdout: LogLevel,
93 level_file: LogLevel,
94 directory_ptr: *const c_char,
95 file_name_ptr: *const c_char,
96 file_format_ptr: *const c_char,
97 component_levels_ptr: *const c_char,
98 is_colored: u8,
99 is_bypassed: u8,
100 print_config: u8,
101 log_components_only: u8,
102 max_file_size: u64,
103 max_backup_count: u32,
104) -> LogGuard_API {
105 let level_stdout = map_log_level_to_filter(level_stdout);
106 let level_file = map_log_level_to_filter(level_file);
107
108 let component_levels_json = unsafe { optional_bytes_to_json(component_levels_ptr) };
109 let component_levels = parse_component_levels(component_levels_json)
110 .expect("Failed to parse component log levels");
111
112 let config = LoggerConfig::new(
113 level_stdout,
114 level_file,
115 component_levels,
116 u8_as_bool(log_components_only),
117 u8_as_bool(is_colored),
118 u8_as_bool(print_config),
119 );
120
121 let file_rotate = if max_file_size > 0 {
123 Some((max_file_size, max_backup_count))
124 } else {
125 None
126 };
127
128 let directory = unsafe { optional_cstr_to_str(directory_ptr).map(ToString::to_string) };
129 let file_name = unsafe { optional_cstr_to_str(file_name_ptr).map(ToString::to_string) };
130 let file_format = unsafe { optional_cstr_to_str(file_format_ptr).map(ToString::to_string) };
131
132 let file_config = FileWriterConfig::new(directory, file_name, file_format, file_rotate);
133
134 if u8_as_bool(is_bypassed) {
135 logging_set_bypass();
136 }
137
138 LogGuard_API(Box::new(
139 init_logging(trader_id, instance_id, config, file_config)
140 .expect("Failed to initialize logging"),
141 ))
142}
143
144#[unsafe(no_mangle)]
152pub unsafe extern "C" fn logger_log(
153 level: LogLevel,
154 color: LogColor,
155 component_ptr: *const c_char,
156 message_ptr: *const c_char,
157) {
158 let component = unsafe { cstr_to_ustr(component_ptr) };
159 let message = unsafe { cstr_as_str(message_ptr) };
160
161 logger::log(level, color, component, message);
162}
163
164#[unsafe(no_mangle)]
172pub unsafe extern "C" fn logging_log_header(
173 trader_id: TraderId,
174 machine_id_ptr: *const c_char,
175 instance_id: UUID4,
176 component_ptr: *const c_char,
177) {
178 let component = unsafe { cstr_to_ustr(component_ptr) };
179 let machine_id = unsafe { cstr_as_str(machine_id_ptr) };
180 headers::log_header(trader_id, machine_id, instance_id, component);
181}
182
183#[unsafe(no_mangle)]
189pub unsafe extern "C" fn logging_log_sysinfo(component_ptr: *const c_char) {
190 let component = unsafe { cstr_to_ustr(component_ptr) };
191 headers::log_sysinfo(component);
192}
193
194#[unsafe(no_mangle)]
196pub extern "C" fn logger_flush() {
197 log::logger().flush();
198}
199
200#[unsafe(no_mangle)]
202pub extern "C" fn logger_drop(log_guard: LogGuard_API) {
203 drop(log_guard);
204}
205
206#[unsafe(no_mangle)]
207pub extern "C" fn logging_is_initialized() -> u8 {
208 u8::from(crate::logging::logging_is_initialized())
209}
210
211#[unsafe(no_mangle)]
212pub extern "C" fn logging_set_bypass() {
213 crate::logging::logging_set_bypass();
214}
215
216#[unsafe(no_mangle)]
217pub extern "C" fn logging_shutdown() {
218 crate::logging::logging_shutdown();
219}
220
221#[unsafe(no_mangle)]
222pub extern "C" fn logging_is_colored() -> u8 {
223 u8::from(crate::logging::logging_is_colored())
224}
225
226#[unsafe(no_mangle)]
227pub extern "C" fn logging_clock_set_realtime_mode() {
228 crate::logging::logging_clock_set_realtime_mode();
229}
230
231#[unsafe(no_mangle)]
232pub extern "C" fn logging_clock_set_static_mode() {
233 crate::logging::logging_clock_set_static_mode();
234}
235
236#[unsafe(no_mangle)]
237pub extern "C" fn logging_clock_set_static_time(time_ns: u64) {
238 crate::logging::logging_clock_set_static_time(time_ns);
239}