service_logging/
lib.rs

1#![deny(missing_docs)]
2//! Library for aggregating logs and sending to logging service.
3//! Contains implementations for [Coralogix](https://coralogix.com/)
4//! and (for wasm) console.log
5mod logging;
6mod time;
7
8/// ConsoleLogger sends output to the javascript console (wasm32 targets) or stdout (println! for
9/// non-wasm32 targets)
10pub use logging::ConsoleLogger;
11pub use logging::{
12    silent_logger, CoralogixConfig, CoralogixLogger, LogEntry, LogLevel, LogQueue, Logger, Severity,
13};
14
15/// The `log!` macro can be used to create structured log entries for later use by [Logger.send](Logger::send)
16/// The first two parameters are fixed:
17///  - a writable queue (or something with a log() method)
18///  - severity level
19/// All remaining parameters are in the form key:value. Key is any word (using the same syntax
20/// as
21///
22/// ```
23/// use service_logging::{log, LogQueue, Severity::Info};
24/// let mut lq = LogQueue::default();
25///
26/// // log http parameters
27/// log!(lq, Info, method: "GET", url: "https://example.com", status: 200);
28/// ```
29///
30/// Parameters are of the form: (queue, severity, key:value, key:value, ...).
31/// `queue` is any object that implements `fn add(&mut self, e: [LogEntry])`
32/// (such as [LogQueue] or [Context](https://docs.rs/wasm-service/0.2/wasm_service/struct.Context.html))
33///
34/// Values can be anything that implements [ToString]
35/// Key names must use the same syntax as a rust identifier, e.g., no spaces, punctuation, etc.
36///
37/// The following keys are "special" (known to Coralogix and used for categorization
38/// in the coralogix dashboard):  `text`, `category`, `class_name`, `method_name`, `thread_id`
39/// If `text` is not defined, all non-coralogix keys are converted into a json string and
40/// passed as the value of 'text'. (If `text` is also defined, any non-coralogix keys will be
41/// silently dropped).
42#[macro_export]
43macro_rules! log {
44    ( $queue:expr,  $sev:expr,  $( $key:tt $_t:tt  $val:expr ),* ) => {{
45        let mut fields: std::collections::BTreeMap<String, String> = std::collections::BTreeMap::new();
46        let mut has_text = false;
47        let mut entry = service_logging::LogEntry { severity: ($sev), ..Default::default() };
48        $(
49            let val = $val.to_string();
50            let key = stringify!($key);
51            match key {
52                "text" => { entry.text = val; has_text = true; },
53                "category" => { entry.category = Some(val); },
54                "class_name" => { entry.class_name = Some(val); },
55                "method_name" => { entry.method_name = Some(val); },
56                "thread_id" => { entry.thread_id = Some(val); },
57                _ => { fields.insert(key.to_string(), val); }
58            }
59        )*
60        if !has_text {
61            entry.text = match serde_json::to_string(&fields) {
62                Ok(s) => s,
63                Err(e) => format!("error serializing message: {}",e),
64            };
65        }
66        $queue.log(entry);
67    }};
68}