cu29_helpers/
lib.rs

1use cu29_clock::RobotClock;
2use cu29_log_runtime::LoggerRuntime;
3use cu29_runtime::curuntime::CopperContext;
4use cu29_traits::{CuResult, UnifiedLogType};
5use cu29_unifiedlog::{stream_write, UnifiedLogger, UnifiedLoggerBuilder};
6use simplelog::TermLogger;
7#[cfg(debug_assertions)]
8use simplelog::{ColorChoice, Config, LevelFilter, TerminalMode};
9use std::path::Path;
10use std::sync::{Arc, Mutex};
11
12/// This is a basic setup for a copper application to get you started.
13/// Duplicate and customize as needed when your needs grow.
14///
15/// unifiedlogger_output_base_name: The base name of the log file. The logger will create a set of files based on this name
16///                                  for example if named "toto.copper" it will create toto_0.copper, toto_1.copper etc.
17///
18/// text_log: if true, the log will be printed to the console as a simple log.
19/// It is useful to debug an application in real-time but should be set to false in production
20/// as it is an order of magnitude slower than the default copper structured logging.
21/// It will create a LoggerRuntime that can be used as a robot clock source too.
22///
23/// slab_size: The logger will pre-allocate large files of those sizes. With the name of the given file _0, _1 etc.
24/// clock: if you let it to None it will create a default clock otherwise you can provide your own, for example a simulation clock.
25///        with let (clock , mock) = RobotClock::mock();
26pub fn basic_copper_setup(
27    unifiedlogger_output_base_name: &Path,
28    slab_size: Option<usize>,
29    _text_log: bool,
30    clock: Option<RobotClock>,
31) -> CuResult<CopperContext> {
32    let preallocated_size = slab_size.unwrap_or(1024 * 1024 * 10);
33    let UnifiedLogger::Write(logger) = UnifiedLoggerBuilder::new()
34        .write(true)
35        .create(true)
36        .file_base_name(unifiedlogger_output_base_name)
37        .preallocated_size(preallocated_size)
38        .build()
39        .expect("Failed to create logger")
40    else {
41        panic!("Failed to create logger")
42    };
43    let unified_logger = Arc::new(Mutex::new(logger));
44    let structured_stream = stream_write(
45        unified_logger.clone(),
46        UnifiedLogType::StructuredLogLine,
47        4096 * 10,
48    );
49
50    #[cfg(debug_assertions)]
51    let extra: Option<TermLogger> = if _text_log {
52        let slow_text_logger = TermLogger::new(
53            LevelFilter::Debug,
54            Config::default(),
55            TerminalMode::Mixed,
56            ColorChoice::Auto,
57        );
58        Some(*slow_text_logger)
59    } else {
60        None
61    };
62
63    #[cfg(not(debug_assertions))]
64    let extra: Option<TermLogger> = None;
65
66    let clock = clock.unwrap_or_default();
67    let structured_logging = LoggerRuntime::init(clock.clone(), structured_stream, extra);
68    Ok(CopperContext {
69        unified_logger: unified_logger.clone(),
70        logger_runtime: structured_logging,
71        clock,
72    })
73}