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 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
//! # Slog - Structured, composable logging for Rust //! //! ``` //! #[macro_use] //! extern crate slog; //! extern crate slog_json; //! extern crate slog_term; //! //! use slog::*; //! use std::thread; //! //! use std::sync::atomic::Ordering::SeqCst; //! use std::sync::atomic::AtomicUsize; //! use std::sync::Arc; //! use std::time::Duration; //! //! const VERSION : &'static str = "0.1.0"; //! //! fn slow_fib(n : u64) -> u64 { //! match n { //! 0|1|2 => 1, //! n => slow_fib(n-1) + slow_fib(n-2), //! } //! } //! //! fn main() { //! // Create a new group of loggers, sharing one drain. //! // //! // Note `o!` macro for more natural `OwnedKeyValue` sequence building. //! let root = Logger::new_root(o!("version" => VERSION, "build-id" => "8dfljdf")); //! //! // Set drains to specify the output format and destination. //! root.set_drain(slog_term::async_stderr()); //! // Build logging context as data becomes available. //! // //! // Create child loggers from existing ones. Children clone `key: value` //! // pairs from their parents. //! let log = root.new(o!("child" => 1)); //! //! // Closures can be used for values that change at runtime. //! // Data captured by the closure needs to be `Send+Sync`. //! let counter = Arc::new(AtomicUsize::new(0)); //! let log = log.new(o!("counter" => { //! let counter = counter.clone(); //! // Note the `move` to capture `counter`, //! // and unfortunate `|_ : &_|` that helps //! // current `rustc` limitations. In the future, //! // a `|_|` could work. //! move |_ : &_| { counter.load(SeqCst)} //! })); //! //! // Note `b!` macro for more natural `BorrowedKeyValue` sequence building. //! log.info("before-fetch-add", b!()); // counter == 0 //! counter.fetch_add(1, SeqCst); //! log.info("after-fetch-add", b!()); // counter == 1 //! //! // Drains can be swapped atomically (race-free). //! log.set_drain( //! // drains are composable //! drain::filter_level( //! Level::Info, //! drain::stream( //! std::io::stderr(), //! // multiple outputs formats are supported //! slog_json::new(), //! ), //! ), //! ); //! //! // Closures can be used for lazy evaluation: //! // This `slow_fib` won't be evaluated, as the current drain discards //! // "trace" level logging records. //! log.debug("debug", b!("lazy-closure" => |_ : &_| slow_fib(40))); //! //! // Loggers are internally atomically reference counted so can be cloned, //! // passed between threads and stored without hassle. //! let join = thread::spawn({ //! let log = log.clone(); //! move || { //! log.info("subthread", b!("stage" => "start")); //! thread::sleep(Duration::new(1, 0)); //! log.info("subthread", b!("stage" => "end")); //! } //! }); //! //! join.join().unwrap(); //! } #![warn(missing_docs)] extern crate crossbeam; extern crate chrono; extern crate rustc_serialize as serialize; use std::sync::Arc; use crossbeam::sync::ArcCell; use std::fmt; /// Convenience function for building `&[OwnedKeyValue]` /// /// ``` /// #[macro_use] /// extern crate slog; /// /// fn main() { /// let root = slog::Logger::new_root(o!("key1" => "value1", "key2" => "value2")); /// } #[macro_export] macro_rules! o( () => { &[] }; ($($k:expr => $v:expr),*) => { { use std; &[$(($k, std::sync::Arc::new($v) as std::sync::Arc<$crate::ser::SyncSerialize>)),*] } }; ); /// Convenience function for building `&[BorrowedKeyValue]` /// /// ``` /// #[macro_use] /// extern crate slog; /// /// fn main() { /// let root = slog::Logger::new_root(o!()); /// root.info("test info log", b!("log-key" => true)); /// } #[macro_export] macro_rules! b( () => { &[] }; ($($k:expr => $v:expr),*) => { &[$(($k, &$v)),*] }; ); /// Drains - logging outputs pub mod drain; use drain::*; /// Logger - logging handle pub mod logger; /// Serialization pub mod ser; /// Output formating pub mod format; pub use logger::Logger; include!("_level.rs"); type DrainRef = Arc<ArcCell<Box<Drain>>>; /// Key value pair that can be owned by `Logger` pub type OwnedKeyValue = (&'static str, Arc<ser::SyncSerialize>); /// Key value pair that can be part of each logging record pub type BorrowedKeyValue<'a> = (&'static str, &'a ser::Serialize);