mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-10 04:01:51 +00:00
308 lines
9.8 KiB
Rust
308 lines
9.8 KiB
Rust
//! An object that can be used to pass through a channel and be cloned. It can therefore be used
|
|
//! via the broadcast channel.
|
|
|
|
use parking_lot::Mutex;
|
|
use serde::ser::SerializeMap;
|
|
use serde::serde_if_integer128;
|
|
use serde::Serialize;
|
|
use slog::{BorrowedKV, Key, Level, OwnedKVList, Record, RecordStatic, Serializer, SingleKV, KV};
|
|
use std::cell::RefCell;
|
|
use std::fmt;
|
|
use std::fmt::Write;
|
|
use std::sync::Arc;
|
|
use take_mut::take;
|
|
|
|
thread_local! {
|
|
static TL_BUF: RefCell<String> = RefCell::new(String::with_capacity(128))
|
|
}
|
|
|
|
/// Serialized record.
|
|
#[derive(Clone)]
|
|
pub struct AsyncRecord {
|
|
msg: String,
|
|
level: Level,
|
|
location: Box<slog::RecordLocation>,
|
|
tag: String,
|
|
logger_values: OwnedKVList,
|
|
kv: Arc<Mutex<dyn KV + Send>>,
|
|
}
|
|
|
|
impl AsyncRecord {
|
|
/// Serializes a `Record` and an `OwnedKVList`.
|
|
pub fn from(record: &Record, logger_values: &OwnedKVList) -> Self {
|
|
let mut ser = ToSendSerializer::new();
|
|
record
|
|
.kv()
|
|
.serialize(record, &mut ser)
|
|
.expect("`ToSendSerializer` can't fail");
|
|
|
|
AsyncRecord {
|
|
msg: fmt::format(*record.msg()),
|
|
level: record.level(),
|
|
location: Box::new(*record.location()),
|
|
tag: String::from(record.tag()),
|
|
logger_values: logger_values.clone(),
|
|
kv: Arc::new(Mutex::new(ser.finish())),
|
|
}
|
|
}
|
|
|
|
pub fn to_json_string(&self) -> Result<String, String> {
|
|
serde_json::to_string(&self).map_err(|e| format!("{:?}", e))
|
|
}
|
|
}
|
|
|
|
pub struct ToSendSerializer {
|
|
kv: Box<dyn KV + Send>,
|
|
}
|
|
|
|
impl ToSendSerializer {
|
|
fn new() -> Self {
|
|
ToSendSerializer { kv: Box::new(()) }
|
|
}
|
|
|
|
fn finish(self) -> Box<dyn KV + Send> {
|
|
self.kv
|
|
}
|
|
}
|
|
|
|
impl Serializer for ToSendSerializer {
|
|
fn emit_bool(&mut self, key: Key, val: bool) -> slog::Result {
|
|
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
|
|
Ok(())
|
|
}
|
|
fn emit_unit(&mut self, key: Key) -> slog::Result {
|
|
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, ()))));
|
|
Ok(())
|
|
}
|
|
fn emit_none(&mut self, key: Key) -> slog::Result {
|
|
let val: Option<()> = None;
|
|
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
|
|
Ok(())
|
|
}
|
|
fn emit_char(&mut self, key: Key, val: char) -> slog::Result {
|
|
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
|
|
Ok(())
|
|
}
|
|
fn emit_u8(&mut self, key: Key, val: u8) -> slog::Result {
|
|
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
|
|
Ok(())
|
|
}
|
|
fn emit_i8(&mut self, key: Key, val: i8) -> slog::Result {
|
|
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
|
|
Ok(())
|
|
}
|
|
fn emit_u16(&mut self, key: Key, val: u16) -> slog::Result {
|
|
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
|
|
Ok(())
|
|
}
|
|
fn emit_i16(&mut self, key: Key, val: i16) -> slog::Result {
|
|
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
|
|
Ok(())
|
|
}
|
|
fn emit_u32(&mut self, key: Key, val: u32) -> slog::Result {
|
|
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
|
|
Ok(())
|
|
}
|
|
fn emit_i32(&mut self, key: Key, val: i32) -> slog::Result {
|
|
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
|
|
Ok(())
|
|
}
|
|
fn emit_f32(&mut self, key: Key, val: f32) -> slog::Result {
|
|
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
|
|
Ok(())
|
|
}
|
|
fn emit_u64(&mut self, key: Key, val: u64) -> slog::Result {
|
|
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
|
|
Ok(())
|
|
}
|
|
fn emit_i64(&mut self, key: Key, val: i64) -> slog::Result {
|
|
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
|
|
Ok(())
|
|
}
|
|
fn emit_f64(&mut self, key: Key, val: f64) -> slog::Result {
|
|
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
|
|
Ok(())
|
|
}
|
|
fn emit_u128(&mut self, key: Key, val: u128) -> slog::Result {
|
|
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
|
|
Ok(())
|
|
}
|
|
fn emit_i128(&mut self, key: Key, val: i128) -> slog::Result {
|
|
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
|
|
Ok(())
|
|
}
|
|
fn emit_usize(&mut self, key: Key, val: usize) -> slog::Result {
|
|
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
|
|
Ok(())
|
|
}
|
|
fn emit_isize(&mut self, key: Key, val: isize) -> slog::Result {
|
|
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
|
|
Ok(())
|
|
}
|
|
fn emit_str(&mut self, key: Key, val: &str) -> slog::Result {
|
|
let val = val.to_owned();
|
|
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
|
|
Ok(())
|
|
}
|
|
fn emit_arguments(&mut self, key: Key, val: &fmt::Arguments) -> slog::Result {
|
|
let val = fmt::format(*val);
|
|
take(&mut self.kv, |kv| Box::new((kv, SingleKV(key, val))));
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl Serialize for AsyncRecord {
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
where
|
|
S: serde::Serializer,
|
|
{
|
|
// Get the current time
|
|
let dt = chrono::Local::now().format("%b %e %T").to_string();
|
|
|
|
let rs = RecordStatic {
|
|
location: &self.location,
|
|
level: self.level,
|
|
tag: &self.tag,
|
|
};
|
|
let mut map_serializer = SerdeSerializer::new(serializer)?;
|
|
|
|
// Serialize the time and log level first
|
|
map_serializer.serialize_entry("time", &dt)?;
|
|
map_serializer.serialize_entry("level", self.level.as_short_str())?;
|
|
|
|
let kv = self.kv.lock();
|
|
|
|
// Convoluted pattern to avoid binding `format_args!` to a temporary.
|
|
// See: https://stackoverflow.com/questions/56304313/cannot-use-format-args-due-to-temporary-value-is-freed-at-the-end-of-this-state
|
|
let mut f = |msg: std::fmt::Arguments| {
|
|
map_serializer.serialize_entry("msg", msg.to_string())?;
|
|
|
|
let record = Record::new(&rs, &msg, BorrowedKV(&(*kv)));
|
|
self.logger_values
|
|
.serialize(&record, &mut map_serializer)
|
|
.map_err(serde::ser::Error::custom)?;
|
|
record
|
|
.kv()
|
|
.serialize(&record, &mut map_serializer)
|
|
.map_err(serde::ser::Error::custom)
|
|
};
|
|
f(format_args!("{}", self.msg))?;
|
|
map_serializer.end()
|
|
}
|
|
}
|
|
|
|
struct SerdeSerializer<S: serde::Serializer> {
|
|
/// Current state of map serializing: `serde::Serializer::MapState`
|
|
ser_map: S::SerializeMap,
|
|
}
|
|
|
|
impl<S: serde::Serializer> SerdeSerializer<S> {
|
|
fn new(ser: S) -> Result<Self, S::Error> {
|
|
let ser_map = ser.serialize_map(None)?;
|
|
Ok(SerdeSerializer { ser_map })
|
|
}
|
|
|
|
fn serialize_entry<K, V>(&mut self, key: K, value: V) -> Result<(), S::Error>
|
|
where
|
|
K: serde::Serialize,
|
|
V: serde::Serialize,
|
|
{
|
|
self.ser_map.serialize_entry(&key, &value)
|
|
}
|
|
|
|
/// Finish serialization, and return the serializer
|
|
fn end(self) -> Result<S::Ok, S::Error> {
|
|
self.ser_map.end()
|
|
}
|
|
}
|
|
|
|
// NOTE: This is borrowed from slog_json
|
|
macro_rules! impl_m(
|
|
($s:expr, $key:expr, $val:expr) => ({
|
|
let k_s: &str = $key.as_ref();
|
|
$s.ser_map.serialize_entry(k_s, $val)
|
|
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, format!("serde serialization error: {}", e)))?;
|
|
Ok(())
|
|
});
|
|
);
|
|
|
|
impl<S> slog::Serializer for SerdeSerializer<S>
|
|
where
|
|
S: serde::Serializer,
|
|
{
|
|
fn emit_bool(&mut self, key: Key, val: bool) -> slog::Result {
|
|
impl_m!(self, key, &val)
|
|
}
|
|
|
|
fn emit_unit(&mut self, key: Key) -> slog::Result {
|
|
impl_m!(self, key, &())
|
|
}
|
|
|
|
fn emit_char(&mut self, key: Key, val: char) -> slog::Result {
|
|
impl_m!(self, key, &val)
|
|
}
|
|
|
|
fn emit_none(&mut self, key: Key) -> slog::Result {
|
|
let val: Option<()> = None;
|
|
impl_m!(self, key, &val)
|
|
}
|
|
fn emit_u8(&mut self, key: Key, val: u8) -> slog::Result {
|
|
impl_m!(self, key, &val)
|
|
}
|
|
fn emit_i8(&mut self, key: Key, val: i8) -> slog::Result {
|
|
impl_m!(self, key, &val)
|
|
}
|
|
fn emit_u16(&mut self, key: Key, val: u16) -> slog::Result {
|
|
impl_m!(self, key, &val)
|
|
}
|
|
fn emit_i16(&mut self, key: Key, val: i16) -> slog::Result {
|
|
impl_m!(self, key, &val)
|
|
}
|
|
fn emit_usize(&mut self, key: Key, val: usize) -> slog::Result {
|
|
impl_m!(self, key, &val)
|
|
}
|
|
fn emit_isize(&mut self, key: Key, val: isize) -> slog::Result {
|
|
impl_m!(self, key, &val)
|
|
}
|
|
fn emit_u32(&mut self, key: Key, val: u32) -> slog::Result {
|
|
impl_m!(self, key, &val)
|
|
}
|
|
fn emit_i32(&mut self, key: Key, val: i32) -> slog::Result {
|
|
impl_m!(self, key, &val)
|
|
}
|
|
fn emit_f32(&mut self, key: Key, val: f32) -> slog::Result {
|
|
impl_m!(self, key, &val)
|
|
}
|
|
fn emit_u64(&mut self, key: Key, val: u64) -> slog::Result {
|
|
impl_m!(self, key, &val)
|
|
}
|
|
fn emit_i64(&mut self, key: Key, val: i64) -> slog::Result {
|
|
impl_m!(self, key, &val)
|
|
}
|
|
fn emit_f64(&mut self, key: Key, val: f64) -> slog::Result {
|
|
impl_m!(self, key, &val)
|
|
}
|
|
serde_if_integer128! {
|
|
fn emit_u128(&mut self, key: Key, val: u128) -> slog::Result {
|
|
impl_m!(self, key, &val)
|
|
}
|
|
fn emit_i128(&mut self, key: Key, val: i128) -> slog::Result {
|
|
impl_m!(self, key, &val)
|
|
}
|
|
}
|
|
fn emit_str(&mut self, key: Key, val: &str) -> slog::Result {
|
|
impl_m!(self, key, &val)
|
|
}
|
|
fn emit_arguments(&mut self, key: Key, val: &fmt::Arguments) -> slog::Result {
|
|
TL_BUF.with(|buf| {
|
|
let mut buf = buf.borrow_mut();
|
|
|
|
buf.write_fmt(*val).unwrap();
|
|
|
|
let res = { || impl_m!(self, key, &*buf) }();
|
|
buf.clear();
|
|
res
|
|
})
|
|
}
|
|
}
|