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);