1#![warn(missing_docs)]
21#[macro_use]
22extern crate slog;
23
24use serde::ser::SerializeMap;
25use serde::serde_if_integer128;
26use slog::Key;
27use slog::Record;
28use slog::{FnValue, PushFnValue};
29use slog::{OwnedKVList, SendSyncRefUnwindSafeKV, KV};
30use std::{fmt, io, result};
31
32use std::cell::RefCell;
33use std::fmt::Write;
34use std::sync::{Arc, Mutex};
35
36thread_local! {
40 static TL_BUF: RefCell<String> = RefCell::new(String::with_capacity(128));
41 static OUT_BUF: RefCell<Vec<u8>> = RefCell::new(Vec::with_capacity(512));
42}
43
44struct SerdeSerializer<S: serde::Serializer> {
49 ser_map: S::SerializeMap,
51}
52
53impl<S: serde::Serializer> SerdeSerializer<S> {
54 fn start(ser: S, len: Option<usize>) -> result::Result<Self, slog::Error> {
56 let ser_map = ser.serialize_map(len).map_err(|e| {
57 io::Error::new(
58 io::ErrorKind::Other,
59 format!("serde serialization error: {}", e),
60 )
61 })?;
62 Ok(SerdeSerializer { ser_map })
63 }
64
65 fn end(self) -> result::Result<S::Ok, S::Error> {
67 self.ser_map.end()
68 }
69}
70
71macro_rules! impl_m(
72 ($s:expr, $key:expr, $val:expr) => ({
73 let k_s: &str = $key.as_ref();
74 $s.ser_map.serialize_entry(k_s, $val)
75 .map_err(|e| io::Error::new(io::ErrorKind::Other, format!("serde serialization error: {}", e)))?;
76 Ok(())
77 });
78);
79
80impl<S> slog::Serializer for SerdeSerializer<S>
81where
82 S: serde::Serializer,
83{
84 fn emit_bool(&mut self, key: Key, val: bool) -> slog::Result {
85 impl_m!(self, key, &val)
86 }
87
88 fn emit_unit(&mut self, key: Key) -> slog::Result {
89 impl_m!(self, key, &())
90 }
91
92 fn emit_char(&mut self, key: Key, val: char) -> slog::Result {
93 impl_m!(self, key, &val)
94 }
95
96 fn emit_none(&mut self, key: Key) -> slog::Result {
97 let val: Option<()> = None;
98 impl_m!(self, key, &val)
99 }
100 fn emit_u8(&mut self, key: Key, val: u8) -> slog::Result {
101 impl_m!(self, key, &val)
102 }
103 fn emit_i8(&mut self, key: Key, val: i8) -> slog::Result {
104 impl_m!(self, key, &val)
105 }
106 fn emit_u16(&mut self, key: Key, val: u16) -> slog::Result {
107 impl_m!(self, key, &val)
108 }
109 fn emit_i16(&mut self, key: Key, val: i16) -> slog::Result {
110 impl_m!(self, key, &val)
111 }
112 fn emit_usize(&mut self, key: Key, val: usize) -> slog::Result {
113 impl_m!(self, key, &val)
114 }
115 fn emit_isize(&mut self, key: Key, val: isize) -> slog::Result {
116 impl_m!(self, key, &val)
117 }
118 fn emit_u32(&mut self, key: Key, val: u32) -> slog::Result {
119 impl_m!(self, key, &val)
120 }
121 fn emit_i32(&mut self, key: Key, val: i32) -> slog::Result {
122 impl_m!(self, key, &val)
123 }
124 fn emit_f32(&mut self, key: Key, val: f32) -> slog::Result {
125 impl_m!(self, key, &val)
126 }
127 fn emit_u64(&mut self, key: Key, val: u64) -> slog::Result {
128 impl_m!(self, key, &val)
129 }
130 fn emit_i64(&mut self, key: Key, val: i64) -> slog::Result {
131 impl_m!(self, key, &val)
132 }
133 fn emit_f64(&mut self, key: Key, val: f64) -> slog::Result {
134 impl_m!(self, key, &val)
135 }
136 serde_if_integer128! {
137 fn emit_u128(&mut self, key: Key, val: u128) -> slog::Result {
138 impl_m!(self, key, &val)
139 }
140 fn emit_i128(&mut self, key: Key, val: i128) -> slog::Result {
141 impl_m!(self, key, &val)
142 }
143 }
144 fn emit_str(&mut self, key: Key, val: &str) -> slog::Result {
145 impl_m!(self, key, &val)
146 }
147 fn emit_arguments(&mut self, key: Key, val: &fmt::Arguments) -> slog::Result {
148 TL_BUF.with(|buf| {
149 let mut buf = buf.borrow_mut();
150
151 buf.write_fmt(*val).unwrap();
152
153 let res = { || impl_m!(self, key, &*buf) }();
154 buf.clear();
155 res
156 })
157 }
158
159 #[cfg(feature = "nested-values")]
160 fn emit_serde(&mut self, key: Key, value: &dyn slog::SerdeValue) -> slog::Result {
161 impl_m!(self, key, value.as_serde())
162 }
163}
164pub struct Json<W: io::Write> {
172 newlines: bool,
173 flush: bool,
174 values: Vec<OwnedKVList>,
175 io: Arc<Mutex<W>>,
176 pretty: bool,
177}
178
179impl<W> Json<W>
180where
181 W: io::Write,
182{
183 pub fn default(io: W) -> Json<W> {
185 JsonBuilder::new(io).add_default_keys().build()
186 }
187
188 #[cfg_attr(feature = "cargo-clippy", allow(clippy::new_ret_no_self))]
190 pub fn new(io: W) -> JsonBuilder<W> {
191 JsonBuilder::new(io)
192 }
193
194 fn log_impl<F>(
195 &self,
196 serializer: &mut serde_json::ser::Serializer<&mut Vec<u8>, F>,
197 rinfo: &Record,
198 logger_values: &OwnedKVList,
199 ) -> io::Result<()>
200 where
201 F: serde_json::ser::Formatter,
202 {
203 let mut serializer = SerdeSerializer::start(&mut *serializer, None)?;
204
205 for kv in &self.values {
206 kv.serialize(rinfo, &mut serializer)?;
207 }
208
209 logger_values.serialize(rinfo, &mut serializer)?;
210
211 rinfo.kv().serialize(rinfo, &mut serializer)?;
212
213 let res = serializer.end();
214
215 res.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
216
217 Ok(())
218 }
219}
220
221impl<W> slog::Drain for Json<W>
222where
223 W: io::Write,
224{
225 type Ok = ();
226 type Err = io::Error;
227 fn log(&self, rinfo: &Record, logger_values: &OwnedKVList) -> io::Result<()> {
228 OUT_BUF.with(|out_buf| {
229 let mut io = out_buf.borrow_mut();
230 io.clear();
231 let io = if self.pretty {
232 let mut serializer = serde_json::Serializer::pretty(&mut *io);
233 self.log_impl(&mut serializer, rinfo, logger_values)?;
234 serializer.into_inner()
235 } else {
236 let mut serializer = serde_json::Serializer::new(&mut *io);
237 self.log_impl(&mut serializer, rinfo, logger_values)?;
238 serializer.into_inner()
239 };
240 if self.newlines {
241 use std::io::Write;
242 io.write_all("\n".as_bytes())?;
243 }
244
245 let mut w = self
246 .io
247 .lock()
248 .map_err(|e| io::Error::new(io::ErrorKind::Interrupted, e.to_string()))?;
249 w.write_all(&io)?;
250 if self.flush {
251 w.flush()?;
252 }
253 Ok(())
254 })
255 }
256}
257
258pub struct JsonBuilder<W: io::Write> {
265 newlines: bool,
266 flush: bool,
267 values: Vec<OwnedKVList>,
268 io: W,
269 pretty: bool,
270}
271
272impl<W> JsonBuilder<W>
273where
274 W: io::Write,
275{
276 fn new(io: W) -> Self {
277 JsonBuilder {
278 newlines: true,
279 flush: false,
280 values: vec![],
281 io,
282 pretty: false,
283 }
284 }
285
286 pub fn build(self) -> Json<W> {
290 Json {
291 values: self.values,
292 newlines: self.newlines,
293 flush: self.flush,
294 io: Arc::new(Mutex::new(self.io)),
295 pretty: self.pretty,
296 }
297 }
298
299 pub fn set_newlines(mut self, enabled: bool) -> Self {
301 self.newlines = enabled;
302 self
303 }
304
305 pub fn set_flush(mut self, enabled: bool) -> Self {
307 self.flush = enabled;
308 self
309 }
310
311 pub fn set_pretty(mut self, enabled: bool) -> Self {
313 self.pretty = enabled;
314 self
315 }
316
317 pub fn add_key_value<T>(mut self, value: slog::OwnedKV<T>) -> Self
319 where
320 T: SendSyncRefUnwindSafeKV + 'static,
321 {
322 self.values.push(value.into());
323 self
324 }
325
326 pub fn add_default_keys(self) -> Self {
332 self.add_key_value(o!(
333 "ts" => FnValue(move |_ : &Record| {
334 time::OffsetDateTime::now_utc()
335 .format(&time::format_description::well_known::Rfc3339)
336 .ok()
337 }),
338 "level" => FnValue(move |rinfo : &Record| {
339 rinfo.level().as_short_str()
340 }),
341 "msg" => PushFnValue(move |record : &Record, ser| {
342 ser.emit(record.msg())
343 }),
344 ))
345 }
346}
347