aether/
lib.rs

1//! Minimal logging library that uses explicit and configurable endpoints.
2#![warn(missing_docs)]
3
4use crate::logger::Logger;
5use std::{collections::HashMap, sync::Mutex};
6
7mod builders;
8mod endpoint;
9mod log;
10mod logger;
11mod scoped;
12
13pub use builders::{EndpointBuilder, LoggerBuilder};
14pub use endpoint::EndpointSuper;
15pub use log::{impl_log, LogEntry};
16pub use logger::KeepAlive;
17pub use scoped::{impl_slog, scoped};
18
19lazy_static::lazy_static! {
20    static ref ENDPOINT_TYPE: Mutex<Option<std::any::TypeId>> = Mutex::new(None);
21    static ref LOGGER: Mutex<Option<Logger>> = Mutex::new(None);
22}
23
24/// Log to the endpoint that is currently in scope. Panics if there's no scope active.
25#[macro_export]
26macro_rules! slog {
27    ($($arg:tt)*) => {
28        aether::impl_slog(format!($($arg)*))
29    };
30}
31
32/// Log to the specified endpoint.
33#[macro_export]
34macro_rules! log {
35    ($target:expr, $($arg:tt)*) => {
36        aether::impl_log($target, format!($($arg)*))
37    };
38}
39
40/// Constructs a builder for the logger.
41pub fn init<EP: EndpointSuper>() -> LoggerBuilder<EP> {
42    let mut guard = ENDPOINT_TYPE.lock().unwrap();
43    if guard.replace(std::any::TypeId::of::<EP>()).is_some() {
44        panic!("Logger has already been (at least partially) initialized!");
45    }
46
47    LoggerBuilder {
48        base_path: None,
49        fmt: |log| {
50            format!(
51                "{} [{:?}] {}",
52                log.time.format("%T.%3f"),
53                log.endpoint,
54                log.text
55            )
56        },
57        endpoints: HashMap::new(),
58    }
59}