1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#![deny(missing_docs)]
//! Library for aggregating logs and sending to logging service.
//! Contains implementations for Coralogix and (for wasm) console.log
mod logging;
mod time;

#[cfg(target = "wasm32")]
pub use logging::ConsoleLogger;
pub use logging::{
    CoralogixConfig, CoralogixLogger, LogEntry, LogLevel, LogQueue, Logger, Severity,
};

/// Send logs to logger
pub async fn send_logs(
    entries: Vec<LogEntry>,
    logger: &Box<dyn Logger>,
) -> Result<(), Box<dyn std::error::Error>> {
    if !entries.is_empty() {
        logger.send("http", entries).await?;
    }
    Ok(())
}

/// Common traits for service-logging
pub mod prelude {
    pub use crate::logging::AppendsLog;
    pub use crate::logging::AppendsLogInnerMut;
}

/// The log! macro can be used to create structured log entries for later use by logger.send
///
/// ```
/// use service_logging::{prelude::*, log, LogQueue, Severity};
/// let mut lq = LogQueue::default();
/// let url = "https://example.com";
///
/// log!(lq, Severity::Info,
///     method: "GET",
///     url: url,
///     status: 200
/// );
/// ```
///
/// Parameters are of the form: (queue, severity, key:value, key:value, ...).
/// `queue` is any object that implements `fn add(&mut self, e: LogEntry)`
/// (such as [LogQueue] or [wasm_service::Context])
///
/// Values can be anything that implements [ToString]
/// Key names must use the same syntax as a rust identifier, e.g., no spaces, punctuation, etc.
///
/// The following keys are "special" (known to Coralogix and used for categorization
/// in the coralogix dashboard):  `text`, `category`, `class_name`, `method_name`, `thread_id`
/// If `text` is not defined, all non-coralogix keys are converted into a json string and
/// passed as the value of 'text'. (If `text` is also defined, any non-coralogix keys will be
/// silently dropped).
#[macro_export]
macro_rules! log {
    ( $qu:expr,  $sev:expr,  $( $k:tt $_t:tt  $v:expr ),* ) => {{
        let mut fields: std::collections::BTreeMap<String, String> = std::collections::BTreeMap::new();
        let mut has_text = false;
        let mut entry = service_logging::LogEntry { severity: ($sev), ..service_logging::LogEntry::default() };
        $(
            let val = $v.to_string();
            let key = stringify!($k);
            match key {
                "text" => { entry.text = val; has_text = true; },
                "category" => { entry.category = Some(val); },
                "class_name" => { entry.class_name = Some(val); },
                "method_name" => { entry.method_name = Some(val); },
                "thread_id" => { entry.thread_id = Some(val); },
                _ => { fields.insert(key.to_string(), val); }
            }
        )*
        if !has_text {
            entry.text = match serde_json::to_string(&fields) {
                Ok(s) => s,
                Err(e) => format!("error serializing message: {}",e),
            };
        }
        $qu.log(entry);
    }};
}