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
//! # Slog - Structured, composable logging for Rust //! ``` //! #[macro_use] //! extern crate slog; //! //! 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. //! let root = Logger::new_root(o!("version" => VERSION, "build-id" => "8dfljdf")); //! //! // Create child loggers from existing ones. Children //! // clone `key: value` pairs from their parents. //! // //! // Build logging context as data becomes available. //! 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(); //! move |_ : &_| { counter.load(SeqCst)} //! })); //! //! 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 //! format::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 serde; extern crate serde_json; extern crate isatty; extern crate ansi_term; extern crate rustc_serialize as serialize; extern crate chrono; 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);