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