diff options
Diffstat (limited to 'examples')
-rw-r--r-- | examples/README.md | 5 | ||||
-rw-r--r-- | examples/common/mod.rs | 36 | ||||
-rw-r--r-- | examples/named.rs | 23 | ||||
-rw-r--r-- | examples/singlethread.rs | 29 | ||||
-rw-r--r-- | examples/struct-log-self.rs | 90 |
5 files changed, 183 insertions, 0 deletions
diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..9079cf0 --- /dev/null +++ b/examples/README.md @@ -0,0 +1,5 @@ +This directory contains some general examples on how to use `slog` + +More examples can be found in: https://github.com/slog-rs/misc/tree/master/examples + +Also, some functionality-specific examples can be found in respective crates implementing them. diff --git a/examples/common/mod.rs b/examples/common/mod.rs new file mode 100644 index 0000000..b83755d --- /dev/null +++ b/examples/common/mod.rs @@ -0,0 +1,36 @@ +use slog::*; +use std::{fmt, result}; + +pub struct PrintlnSerializer; + +impl Serializer for PrintlnSerializer { + fn emit_arguments(&mut self, key: Key, val: &fmt::Arguments) -> Result { + print!(", {}={}", key, val); + Ok(()) + } +} + +pub struct PrintlnDrain; + +impl Drain for PrintlnDrain { + type Ok = (); + type Err = (); + + fn log( + &self, + record: &Record, + values: &OwnedKVList, + ) -> result::Result<Self::Ok, Self::Err> { + + print!("{}", record.msg()); + + record + .kv() + .serialize(record, &mut PrintlnSerializer) + .unwrap(); + values.serialize(record, &mut PrintlnSerializer).unwrap(); + + println!(""); + Ok(()) + } +} diff --git a/examples/named.rs b/examples/named.rs new file mode 100644 index 0000000..15a12be --- /dev/null +++ b/examples/named.rs @@ -0,0 +1,23 @@ +//#![feature(trace_macros)] +#[macro_use] +extern crate slog; +use slog::{Fuse, Logger}; + +mod common; + +fn main() { + let log = Logger::root( + Fuse(common::PrintlnDrain), + o!("version" => "2") + ); + + //trace_macros!(true); + info!(log, "foo is {foo}", foo = 2; "a" => "b"); + info!(log, "foo is {foo} {bar}", bar=3, foo = 2; "a" => "b"); + info!(log, "foo is {foo} {bar} {baz}", bar=3, foo = 2, baz=4; "a" => "b"); + info!(log, "foo is {foo} {bar} {baz}", bar = 3, foo = 2, baz = 4;); + info!(log, "foo is {foo} {bar} {baz}", bar=3, foo = 2, baz=4); + info!(log, "foo is {foo} {bar} {baz}", bar=3, foo = 2, baz=4,); + info!(log, "formatted {num_entries} entries of {}", "something", num_entries = 2; "log-key" => true); + info!(log, "{first} {third} {second}", first = 1, second = 2, third=3; "forth" => 4, "fifth" => 5); +} diff --git a/examples/singlethread.rs b/examples/singlethread.rs new file mode 100644 index 0000000..1ca5689 --- /dev/null +++ b/examples/singlethread.rs @@ -0,0 +1,29 @@ +//#![feature(nothreads)] +#[macro_use] +extern crate slog; +use slog::{Fuse, Logger}; +use std::cell::RefCell; +use std::rc::Rc; + +mod common; + +#[derive(Clone)] +struct NoThreadSafeObject { + val: Rc<RefCell<usize>>, +} + +fn main() { + let log = Logger::root(Fuse(common::PrintlnDrain), o!("version" => "2")); + let obj = NoThreadSafeObject { + val: Rc::new(RefCell::new(4)), + }; + + // Move obj2 into a closure. Since it's !Send, this only works + // with nothreads feature. + let obj2 = obj.clone(); + let sublog = log.new(o!("obj.val" => slog::FnValue(move |_| { + format!("{}", obj2.val.borrow()) + }))); + + info!(sublog, "test"); +} diff --git a/examples/struct-log-self.rs b/examples/struct-log-self.rs new file mode 100644 index 0000000..f533766 --- /dev/null +++ b/examples/struct-log-self.rs @@ -0,0 +1,90 @@ +//! Example of how to implement `KV` for a struct +//! to conveniently log data associated with it. +#[macro_use] +extern crate slog; +use slog::*; + +mod common; + +struct Peer { + host: String, + port: u32, +} + +impl Peer { + fn new(host: String, port: u32) -> Self { + Peer { + host: host, + port: port, + } + } +} + +// `KV` can be implemented for a struct +impl KV for Peer { + fn serialize(&self, _record: &Record, serializer: &mut Serializer) -> Result { + serializer.emit_u32(Key::from("peer-port"), self.port)?; + serializer.emit_str(Key::from("peer-host"), &self.host)?; + Ok(()) + } +} + +struct Server { + _host: String, + _port: u32, + // One approach is to create new `Logger` with struct data + // and embedded it into struct itself. This works when struct is mostly + // immutable. + log: Logger, +} + +impl Server { + fn new(host: String, port: u32, log: Logger) -> Server { + let log = log.new(o!("server-host" => host.clone(), "server-port" => port)); + Server { + _host: host, + _port: port, + log: log, + } + } + + fn connection(&self, peer: &Peer) { + // Another approach is to add struct to a logging message when it's + // necessary. This might be necessary when struct data can change + // between different logging statements (not the case here for `Peer`). + info!(self.log, "new connection"; peer); + } +} + +struct PeerCounter { + count: usize, + log: Logger, +} + +impl PeerCounter { + fn new(log: Logger) -> Self { + PeerCounter { count: 0, log: log } + } + + // A hybrid approach with `Logger` with parent logging-context embedded into + // a `struct` and a helper function adding mutable fields. + fn log_info(&self, msg: &str, kv: BorrowedKV) { + info!(self.log, "{}", msg; "current-count" => self.count, kv); + } + + fn count(&mut self, peer: &Peer) { + self.count += 1; + self.log_info("counted peer", b!(peer)); + } +} + +fn main() { + let log = Logger::root(Fuse(common::PrintlnDrain), o!("build-id" => "7.3.3-abcdef")); + + let server = Server::new("localhost".into(), 12345, log.clone()); + + let peer = Peer::new("1.2.3.4".into(), 999); + server.connection(&peer); + let mut counter = PeerCounter::new(log); + counter.count(&peer); +} |