From 566a0733ad21a2ef9613bf1fa71e52e6704650cb Mon Sep 17 00:00:00 2001 From: KodrAus Date: Thu, 24 Aug 2023 20:06:40 +1000 Subject: [PATCH] more refactorings --- core/src/ambient.rs | 98 ++++++++--------- core/src/clock.rs | 6 + core/src/ctxt.rs | 20 ++-- core/src/emitter.rs | 177 ++++++++++++++++++++++++++++++ core/src/event.rs | 13 ++- core/src/extent.rs | 34 ++++-- core/src/lib.rs | 2 +- core/src/props.rs | 75 ++++++------- core/src/target.rs | 177 ------------------------------ core/src/timestamp.rs | 30 ++--- src/lib.rs | 8 +- src/macro_hooks.rs | 4 +- src/setup.rs | 46 ++++---- targets/opentelemetry/src/logs.rs | 4 +- targets/otlp/src/logs.rs | 8 +- targets/term/src/lib.rs | 4 +- 16 files changed, 358 insertions(+), 348 deletions(-) create mode 100644 core/src/emitter.rs delete mode 100644 core/src/target.rs diff --git a/core/src/ambient.rs b/core/src/ambient.rs index d8ffe63..694444c 100644 --- a/core/src/ambient.rs +++ b/core/src/ambient.rs @@ -1,12 +1,12 @@ use crate::{ - clock::Clock, ctxt::Ctxt, empty::Empty, event::Event, filter::Filter, id::IdGen, props::Props, - target::Target, timestamp::Timestamp, + clock::Clock, ctxt::Ctxt, emitter::Emitter, empty::Empty, event::Event, filter::Filter, + id::IdGen, props::Props, timestamp::Timestamp, }; #[derive(Debug, Clone, Copy)] -pub struct Ambient +pub struct Ambient { - target: TTarget, + emitter: TEmitter, filter: TFilter, ctxt: TCtxt, clock: TClock, @@ -22,7 +22,7 @@ impl Default for Ambient { impl Ambient { pub fn new() -> Ambient { Ambient { - target: Empty, + emitter: Empty, filter: Empty, ctxt: Empty, clock: Empty, @@ -31,14 +31,14 @@ impl Ambient { } } -impl Ambient { - pub fn target(&self) -> &TTarget { - &self.target +impl Ambient { + pub fn emitter(&self) -> &TEmitter { + &self.emitter } - pub fn with_target(self, target: U) -> Ambient { + pub fn with_emitter(self, emitter: U) -> Ambient { Ambient { - target, + emitter, filter: self.filter, ctxt: self.ctxt, clock: self.clock, @@ -50,9 +50,9 @@ impl Ambient(self, filter: U) -> Ambient { + pub fn with_filter(self, filter: U) -> Ambient { Ambient { - target: self.target, + emitter: self.emitter, filter, ctxt: self.ctxt, clock: self.clock, @@ -64,9 +64,9 @@ impl Ambient(self, ctxt: U) -> Ambient { + pub fn with_ctxt(self, ctxt: U) -> Ambient { Ambient { - target: self.target, + emitter: self.emitter, filter: self.filter, ctxt, clock: self.clock, @@ -78,9 +78,9 @@ impl Ambient(self, clock: U) -> Ambient { + pub fn with_clock(self, clock: U) -> Ambient { Ambient { - target: self.target, + emitter: self.emitter, filter: self.filter, ctxt: self.ctxt, clock, @@ -92,9 +92,9 @@ impl Ambient(self, id_gen: U) -> Ambient { + pub fn with_id_gen(self, id_gen: U) -> Ambient { Ambient { - target: self.target, + emitter: self.emitter, filter: self.filter, ctxt: self.ctxt, clock: self.clock, @@ -103,36 +103,32 @@ impl Ambient Target - for Ambient +impl Emitter + for Ambient { - fn event(&self, evt: &Event

) { - self.target.event(evt) + fn emit(&self, evt: &Event

) { + self.emitter.emit(evt) } fn blocking_flush(&self, timeout: core::time::Duration) { - self.target.blocking_flush(timeout) + self.emitter.blocking_flush(timeout) } } -impl Filter - for Ambient +impl Filter + for Ambient { fn matches(&self, evt: &Event

) -> bool { self.filter.matches(evt) } } -impl Ctxt - for Ambient +impl Ctxt + for Ambient { type CurrentProps = TCtxt::CurrentProps; type LocalFrame = TCtxt::LocalFrame; - fn with_current(&self, with: F) { - self.ctxt.with_current(with) - } - fn open(&self, props: P) -> Self::LocalFrame { self.ctxt.open(props) } @@ -141,6 +137,10 @@ impl Ctxt self.ctxt.enter(scope) } + fn with_current(&self, with: F) { + self.ctxt.with_current(with) + } + fn exit(&self, scope: &mut Self::LocalFrame) { self.ctxt.exit(scope) } @@ -150,16 +150,16 @@ impl Ctxt } } -impl Clock - for Ambient +impl Clock + for Ambient { fn now(&self) -> Option { self.clock.now() } } -impl IdGen - for Ambient +impl IdGen + for Ambient { fn new_trace_id(&self) -> Option { self.id_gen.new_trace_id() @@ -184,23 +184,23 @@ mod std_support { use std::sync::OnceLock; use crate::{ - clock::ErasedClock, ctxt::ErasedCtxt, filter::ErasedFilter, id::ErasedIdGen, - target::ErasedTarget, + clock::ErasedClock, ctxt::ErasedCtxt, emitter::ErasedEmitter, filter::ErasedFilter, + id::ErasedIdGen, }; use super::*; - trait AmbientTarget: Any + ErasedTarget + Send + Sync + 'static { + trait AmbientTarget: Any + ErasedEmitter + Send + Sync + 'static { fn as_any(&self) -> &dyn Any; - fn as_super(&self) -> &(dyn ErasedTarget + Send + Sync + 'static); + fn as_super(&self) -> &(dyn ErasedEmitter + Send + Sync + 'static); } - impl AmbientTarget for T { + impl AmbientTarget for T { fn as_any(&self) -> &dyn Any { self } - fn as_super(&self) -> &(dyn ErasedTarget + Send + Sync + 'static) { + fn as_super(&self) -> &(dyn ErasedEmitter + Send + Sync + 'static) { self } } @@ -275,11 +275,11 @@ mod std_support { >, > = OnceLock::new(); - pub fn init( - ambient: Ambient, + pub fn init( + ambient: Ambient, ) -> Option< Ambient< - &'static TTarget, + &'static TEmitter, &'static TFilter, &'static TCtxt, &'static TClock, @@ -287,7 +287,7 @@ mod std_support { >, > where - TTarget: Target + Send + Sync + 'static, + TEmitter: Emitter + Send + Sync + 'static, TFilter: Filter + Send + Sync + 'static, TCtxt: Ctxt + Send + Sync + 'static, TCtxt::LocalFrame: Send + 'static, @@ -296,7 +296,7 @@ mod std_support { { AMBIENT .set(Ambient { - target: Box::new(ambient.target), + emitter: Box::new(ambient.emitter), filter: Box::new(ambient.filter), ctxt: Box::new(ambient.ctxt), clock: Box::new(ambient.clock), @@ -307,7 +307,7 @@ mod std_support { let ambient = AMBIENT.get()?; Some(Ambient { - target: ambient.target.as_any().downcast_ref()?, + emitter: ambient.emitter.as_any().downcast_ref()?, filter: ambient.filter.as_any().downcast_ref()?, ctxt: ambient.ctxt.as_any().downcast_ref()?, clock: ambient.clock.as_any().downcast_ref()?, @@ -317,7 +317,7 @@ mod std_support { pub type Get = Option< Ambient< - &'static (dyn ErasedTarget + Send + Sync), + &'static (dyn ErasedEmitter + Send + Sync), &'static (dyn ErasedFilter + Send + Sync), &'static (dyn ErasedCtxt + Send + Sync), &'static (dyn ErasedClock + Send + Sync), @@ -329,7 +329,7 @@ mod std_support { let ambient = AMBIENT.get()?; Some(Ambient { - target: ambient.target.as_super(), + emitter: ambient.emitter.as_super(), filter: ambient.filter.as_super(), ctxt: ambient.ctxt.as_super(), clock: ambient.clock.as_super(), diff --git a/core/src/clock.rs b/core/src/clock.rs index a838cd5..f1cf3d4 100644 --- a/core/src/clock.rs +++ b/core/src/clock.rs @@ -1,3 +1,5 @@ +use core::time::Duration; + use crate::{ empty::Empty, extent::{Extent, ToExtent}, @@ -99,6 +101,10 @@ impl Timer { _ => Extent::empty(), } } + + pub fn elapsed(&self) -> Option { + self.extent().len() + } } impl ToExtent for Timer { diff --git a/core/src/ctxt.rs b/core/src/ctxt.rs index 9bba491..ad24229 100644 --- a/core/src/ctxt.rs +++ b/core/src/ctxt.rs @@ -154,13 +154,9 @@ impl Ctxt for Empty { } mod internal { - use core::marker::PhantomData; + use core::{marker::PhantomData, ops::ControlFlow}; - use crate::{ - key::Key, - props::{ControlFlow, Props}, - value::Value, - }; + use crate::{key::Key, props::Props, value::Value}; pub struct Slot(*const T, PhantomData<*mut fn()>); @@ -175,10 +171,10 @@ mod internal { } impl Props for Slot { - fn for_each<'a, F: FnMut(Key<'a>, Value<'a>) -> ControlFlow>( + fn for_each<'a, F: FnMut(Key<'a>, Value<'a>) -> ControlFlow<()>>( &'a self, for_each: F, - ) -> ControlFlow { + ) -> ControlFlow<()> { self.get().for_each(for_each) } } @@ -194,11 +190,11 @@ mod alloc_support { use super::*; mod internal { - use core::{marker::PhantomData, mem}; + use core::{marker::PhantomData, mem, ops::ControlFlow}; use crate::{ key::Key, - props::{ControlFlow, ErasedProps, Props}, + props::{ErasedProps, Props}, value::Value, }; @@ -237,10 +233,10 @@ mod alloc_support { } impl Props for ErasedCurrentProps { - fn for_each<'a, F: FnMut(Key<'a>, Value<'a>) -> ControlFlow>( + fn for_each<'a, F: FnMut(Key<'a>, Value<'a>) -> ControlFlow<()>>( &'a self, for_each: F, - ) -> ControlFlow { + ) -> ControlFlow<()> { self.get().for_each(for_each) } } diff --git a/core/src/emitter.rs b/core/src/emitter.rs new file mode 100644 index 0000000..7c83a39 --- /dev/null +++ b/core/src/emitter.rs @@ -0,0 +1,177 @@ +use core::time::Duration; + +use crate::{ + empty::Empty, + event::Event, + props::{ErasedProps, Props}, +}; + +pub trait Emitter { + fn emit(&self, evt: &Event

); + + fn blocking_flush(&self, timeout: Duration); + + fn and(self, other: U) -> And + where + Self: Sized, + { + And { + lhs: self, + rhs: other, + } + } + + fn by_ref(&self) -> ByRef { + ByRef(self) + } +} + +impl<'a, T: Emitter + ?Sized> Emitter for &'a T { + fn emit(&self, evt: &Event

) { + (**self).emit(evt) + } + + fn blocking_flush(&self, timeout: Duration) { + (**self).blocking_flush(timeout) + } +} + +#[cfg(feature = "std")] +impl<'a, T: Emitter + ?Sized + 'a> Emitter for Box { + fn emit(&self, evt: &Event

) { + (**self).emit(evt) + } + + fn blocking_flush(&self, timeout: Duration) { + (**self).blocking_flush(timeout) + } +} + +impl Emitter for Option { + fn emit(&self, evt: &Event

) { + match self { + Some(target) => target.emit(evt), + None => Empty.emit(evt), + } + } + + fn blocking_flush(&self, timeout: Duration) { + match self { + Some(target) => target.blocking_flush(timeout), + None => Empty.blocking_flush(timeout), + } + } +} + +impl Emitter for Empty { + fn emit(&self, _: &Event

) {} + fn blocking_flush(&self, _: Duration) {} +} + +impl Emitter for fn(&Event<&dyn ErasedProps>) { + fn emit(&self, evt: &Event

) { + (self)(&evt.erase()) + } + + fn blocking_flush(&self, _: Duration) {} +} + +pub struct FromFn(F); + +impl)> Emitter for FromFn { + fn emit(&self, evt: &Event

) { + (self.0)(&evt.erase()) + } + + fn blocking_flush(&self, _: Duration) {} +} + +pub fn from_fn)>(f: F) -> FromFn { + FromFn(f) +} + +pub struct And { + lhs: T, + rhs: U, +} + +impl Emitter for And { + fn emit(&self, evt: &Event

) { + self.lhs.emit(evt); + self.rhs.emit(evt); + } + + fn blocking_flush(&self, timeout: Duration) { + let timeout = timeout / 2; + + self.lhs.blocking_flush(timeout); + self.rhs.blocking_flush(timeout); + } +} + +pub struct ByRef<'a, T: ?Sized>(&'a T); + +impl<'a, T: Emitter + ?Sized> Emitter for ByRef<'a, T> { + fn emit(&self, evt: &Event

) { + self.0.emit(evt) + } + + fn blocking_flush(&self, timeout: Duration) { + self.0.blocking_flush(timeout) + } +} + +mod internal { + use core::time::Duration; + + use crate::{event::Event, props::ErasedProps}; + + pub trait DispatchEmitter { + fn dispatch_emit(&self, evt: &Event<&dyn ErasedProps>); + fn dispatch_blocking_flush(&self, timeout: Duration); + } + + pub trait SealedEmitter { + fn erase_target(&self) -> crate::internal::Erased<&dyn DispatchEmitter>; + } +} + +pub trait ErasedEmitter: internal::SealedEmitter {} + +impl ErasedEmitter for T {} + +impl internal::SealedEmitter for T { + fn erase_target(&self) -> crate::internal::Erased<&dyn internal::DispatchEmitter> { + crate::internal::Erased(self) + } +} + +impl internal::DispatchEmitter for T { + fn dispatch_emit(&self, evt: &Event<&dyn ErasedProps>) { + self.emit(evt) + } + + fn dispatch_blocking_flush(&self, timeout: Duration) { + self.blocking_flush(timeout) + } +} + +impl<'a> Emitter for dyn ErasedEmitter + 'a { + fn emit(&self, evt: &Event

) { + self.erase_target().0.dispatch_emit(&evt.erase()) + } + + fn blocking_flush(&self, timeout: Duration) { + self.erase_target().0.dispatch_blocking_flush(timeout) + } +} + +impl<'a> Emitter for dyn ErasedEmitter + Send + Sync + 'a { + fn emit(&self, evt: &Event

) { + (self as &(dyn ErasedEmitter + 'a)).emit(evt) + } + + fn blocking_flush(&self, timeout: Duration) { + (self as &(dyn ErasedEmitter + 'a)).blocking_flush(timeout) + } +} diff --git a/core/src/event.rs b/core/src/event.rs index 1e18793..d82e299 100644 --- a/core/src/event.rs +++ b/core/src/event.rs @@ -1,9 +1,9 @@ -use core::fmt; +use core::{fmt, ops::ControlFlow}; use crate::{ extent::{Extent, ToExtent}, key::{Key, ToKey}, - props::{ByRef, Chain, ControlFlow, ErasedProps, Props}, + props::{ByRef, Chain, ErasedProps, Props}, template::{Render, Template}, value::{ToValue, Value}, well_known::{MSG_KEY, TPL_KEY}, @@ -61,7 +61,10 @@ impl<'a, P: Props> Event<'a, P> { } } - pub fn for_each<'kv, F: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow>(&'kv self, for_each: F) { + pub fn for_each<'kv, F: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow<()>>( + &'kv self, + for_each: F, + ) { let _ = Props::for_each(self, for_each); } @@ -93,10 +96,10 @@ impl<'a, P> ToExtent for Event<'a, P> { } impl<'a, P: Props> Props for Event<'a, P> { - fn for_each<'kv, F: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow>( + fn for_each<'kv, F: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow<()>>( &'kv self, mut for_each: F, - ) -> ControlFlow { + ) -> ControlFlow<()> { self.extent.for_each(&mut for_each)?; for_each(TPL_KEY.to_key(), self.tpl.to_value())?; diff --git a/core/src/extent.rs b/core/src/extent.rs index 7ee2041..a2bea68 100644 --- a/core/src/extent.rs +++ b/core/src/extent.rs @@ -1,12 +1,16 @@ use crate::{ empty::Empty, key::{Key, ToKey}, - props::{ControlFlow, Props}, + props::Props, timestamp::Timestamp, value::{ToValue, Value}, well_known::{TIMESTAMP_KEY, TIMESTAMP_START_KEY}, }; -use core::{fmt, ops::Range}; +use core::{ + fmt, + ops::{ControlFlow, Range}, + time::Duration, +}; #[derive(Debug, Clone)] pub struct Extent(Option>); @@ -24,12 +28,28 @@ impl Extent { Extent(None) } - pub fn range(&self) -> Option<&Range> { + pub fn as_range(&self) -> Option<&Range> { self.0.as_ref() } - pub fn to_point(&self) -> Option<&Timestamp> { - self.0.as_ref().map(|ts| &ts.end) + pub fn as_point(&self) -> Option<&Timestamp> { + Some(&self.0.as_ref()?.end) + } + + pub fn as_span(&self) -> Option<&Range> { + let ts = self.0.as_ref()?; + + if ts.start != ts.end { + Some(ts) + } else { + None + } + } + + pub fn len(&self) -> Option { + let ts = self.0.as_ref()?; + + ts.end.duration_since(ts.start) } pub fn is_point(&self) -> bool { @@ -92,10 +112,10 @@ impl fmt::Display for Extent { } impl Props for Extent { - fn for_each<'kv, F: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow>( + fn for_each<'kv, F: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow<()>>( &'kv self, mut for_each: F, - ) -> ControlFlow { + ) -> ControlFlow<()> { if let Some(ref ts) = self.0 { if ts.start != ts.end { for_each(TIMESTAMP_START_KEY.to_key(), ts.start.to_value())?; diff --git a/core/src/lib.rs b/core/src/lib.rs index b0881f4..3c855fb 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -8,6 +8,7 @@ extern crate core; pub mod ambient; pub mod clock; pub mod ctxt; +pub mod emitter; pub mod empty; pub mod event; pub mod extent; @@ -16,7 +17,6 @@ pub mod id; pub mod key; pub mod level; pub mod props; -pub mod target; pub mod template; pub mod timestamp; pub mod value; diff --git a/core/src/props.rs b/core/src/props.rs index 89b00f5..b2a7a71 100644 --- a/core/src/props.rs +++ b/core/src/props.rs @@ -1,4 +1,4 @@ -use core::borrow::Borrow; +use core::{borrow::Borrow, ops::ControlFlow}; use crate::{ empty::Empty, @@ -6,14 +6,11 @@ use crate::{ value::{ToValue, Value}, }; -pub type ControlFlow = core::ops::ControlFlow<()>; -pub use core::ops::ControlFlow::*; - pub trait Props { - fn for_each<'kv, F: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow>( + fn for_each<'kv, F: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow<()>>( &'kv self, for_each: F, - ) -> ControlFlow; + ) -> ControlFlow<()>; fn get<'v, K: ToKey>(&'v self, key: K) -> Option> { let key = key.to_key(); @@ -23,9 +20,9 @@ pub trait Props { if k == key { value = Some(v); - Break(()) + ControlFlow::Break(()) } else { - Continue(()) + ControlFlow::Continue(()) } }); @@ -55,10 +52,10 @@ pub trait Props { } impl<'a, P: Props + ?Sized> Props for &'a P { - fn for_each<'kv, F: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow>( + fn for_each<'kv, F: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow<()>>( &'kv self, for_each: F, - ) -> ControlFlow { + ) -> ControlFlow<()> { (**self).for_each(for_each) } @@ -68,46 +65,46 @@ impl<'a, P: Props + ?Sized> Props for &'a P { } impl Props for Option

{ - fn for_each<'kv, F: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow>( + fn for_each<'kv, F: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow<()>>( &'kv self, for_each: F, - ) -> ControlFlow { + ) -> ControlFlow<()> { match self { Some(props) => props.for_each(for_each), - None => Continue(()), + None => ControlFlow::Continue(()), } } } #[cfg(feature = "alloc")] impl<'a, P: Props + ?Sized + 'a> Props for alloc::boxed::Box

{ - fn for_each<'kv, F: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow>( + fn for_each<'kv, F: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow<()>>( &'kv self, for_each: F, - ) -> ControlFlow { + ) -> ControlFlow<()> { (**self).for_each(for_each) } } impl Props for (K, V) { - fn for_each<'kv, F: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow>( + fn for_each<'kv, F: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow<()>>( &'kv self, mut for_each: F, - ) -> ControlFlow { + ) -> ControlFlow<()> { for_each(self.0.to_key(), self.1.to_value()) } } impl Props for [P] { - fn for_each<'kv, F: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow>( + fn for_each<'kv, F: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow<()>>( &'kv self, mut for_each: F, - ) -> ControlFlow { + ) -> ControlFlow<()> { for p in self { p.for_each(&mut for_each)?; } - Continue(()) + ControlFlow::Continue(()) } } @@ -115,20 +112,20 @@ impl Props for [T; N] where [T]: Props, { - fn for_each<'kv, F: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow>( + fn for_each<'kv, F: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow<()>>( &'kv self, for_each: F, - ) -> ControlFlow { + ) -> ControlFlow<()> { (self as &[_]).for_each(for_each) } } impl Props for Empty { - fn for_each<'kv, F: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow>( + fn for_each<'kv, F: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow<()>>( &'kv self, _: F, - ) -> ControlFlow { - Continue(()) + ) -> ControlFlow<()> { + ControlFlow::Continue(()) } } @@ -138,10 +135,10 @@ pub struct Chain { } impl Props for Chain { - fn for_each<'kv, F: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow>( + fn for_each<'kv, F: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow<()>>( &'kv self, mut for_each: F, - ) -> ControlFlow { + ) -> ControlFlow<()> { self.first.for_each(&mut for_each)?; self.second.for_each(for_each) } @@ -156,10 +153,10 @@ impl Props for Chain { pub struct ByRef<'a, T: ?Sized>(&'a T); impl<'a, P: Props + ?Sized> Props for ByRef<'a, P> { - fn for_each<'kv, F: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow>( + fn for_each<'kv, F: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow<()>>( &'kv self, for_each: F, - ) -> ControlFlow { + ) -> ControlFlow<()> { self.0.for_each(for_each) } } @@ -170,15 +167,15 @@ pub struct Filter { } impl bool> Props for Filter { - fn for_each<'kv, FE: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow>( + fn for_each<'kv, FE: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow<()>>( &'kv self, mut for_each: FE, - ) -> ControlFlow { + ) -> ControlFlow<()> { self.src.for_each(|k, v| { if (self.filter)(k.by_ref(), v.by_ref()) { for_each(k, v) } else { - Continue(()) + ControlFlow::Continue(()) } }) } @@ -194,15 +191,15 @@ impl bool> Props for Filter { } mod internal { - use super::ControlFlow; + use core::ops::ControlFlow; use crate::{key::Key, value::Value}; pub trait DispatchProps { fn dispatch_for_each<'kv, 'f>( &'kv self, - for_each: &'f mut dyn FnMut(Key<'kv>, Value<'kv>) -> ControlFlow, - ) -> ControlFlow; + for_each: &'f mut dyn FnMut(Key<'kv>, Value<'kv>) -> ControlFlow<()>, + ) -> ControlFlow<()>; fn dispatch_get(&self, key: Key) -> Option; } @@ -225,8 +222,8 @@ impl internal::SealedProps for P { impl internal::DispatchProps for P { fn dispatch_for_each<'kv, 'f>( &'kv self, - for_each: &'f mut dyn FnMut(Key<'kv>, Value<'kv>) -> ControlFlow, - ) -> ControlFlow { + for_each: &'f mut dyn FnMut(Key<'kv>, Value<'kv>) -> ControlFlow<()>, + ) -> ControlFlow<()> { self.for_each(for_each) } @@ -236,10 +233,10 @@ impl internal::DispatchProps for P { } impl<'a> Props for dyn ErasedProps + 'a { - fn for_each<'kv, F: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow>( + fn for_each<'kv, F: FnMut(Key<'kv>, Value<'kv>) -> ControlFlow<()>>( &'kv self, mut for_each: F, - ) -> ControlFlow { + ) -> ControlFlow<()> { self.erase_props().0.dispatch_for_each(&mut for_each) } diff --git a/core/src/target.rs b/core/src/target.rs deleted file mode 100644 index 5887afa..0000000 --- a/core/src/target.rs +++ /dev/null @@ -1,177 +0,0 @@ -use core::time::Duration; - -use crate::{ - empty::Empty, - event::Event, - props::{ErasedProps, Props}, -}; - -pub trait Target { - fn event(&self, evt: &Event

); - - fn blocking_flush(&self, timeout: Duration); - - fn and(self, other: U) -> And - where - Self: Sized, - { - And { - lhs: self, - rhs: other, - } - } - - fn by_ref(&self) -> ByRef { - ByRef(self) - } -} - -impl<'a, T: Target + ?Sized> Target for &'a T { - fn event(&self, evt: &Event

) { - (**self).event(evt) - } - - fn blocking_flush(&self, timeout: Duration) { - (**self).blocking_flush(timeout) - } -} - -#[cfg(feature = "std")] -impl<'a, T: Target + ?Sized + 'a> Target for Box { - fn event(&self, evt: &Event

) { - (**self).event(evt) - } - - fn blocking_flush(&self, timeout: Duration) { - (**self).blocking_flush(timeout) - } -} - -impl Target for Option { - fn event(&self, evt: &Event

) { - match self { - Some(target) => target.event(evt), - None => Empty.event(evt), - } - } - - fn blocking_flush(&self, timeout: Duration) { - match self { - Some(target) => target.blocking_flush(timeout), - None => Empty.blocking_flush(timeout), - } - } -} - -impl Target for Empty { - fn event(&self, _: &Event

) {} - fn blocking_flush(&self, _: Duration) {} -} - -impl Target for fn(&Event<&dyn ErasedProps>) { - fn event(&self, evt: &Event

) { - (self)(&evt.erase()) - } - - fn blocking_flush(&self, _: Duration) {} -} - -pub struct FromFn(F); - -impl)> Target for FromFn { - fn event(&self, evt: &Event

) { - (self.0)(&evt.erase()) - } - - fn blocking_flush(&self, _: Duration) {} -} - -pub fn from_fn)>(f: F) -> FromFn { - FromFn(f) -} - -pub struct And { - lhs: T, - rhs: U, -} - -impl Target for And { - fn event(&self, evt: &Event

) { - self.lhs.event(evt); - self.rhs.event(evt); - } - - fn blocking_flush(&self, timeout: Duration) { - let timeout = timeout / 2; - - self.lhs.blocking_flush(timeout); - self.rhs.blocking_flush(timeout); - } -} - -pub struct ByRef<'a, T: ?Sized>(&'a T); - -impl<'a, T: Target + ?Sized> Target for ByRef<'a, T> { - fn event(&self, evt: &Event

) { - self.0.event(evt) - } - - fn blocking_flush(&self, timeout: Duration) { - self.0.blocking_flush(timeout) - } -} - -mod internal { - use core::time::Duration; - - use crate::{event::Event, props::ErasedProps}; - - pub trait DispatchTarget { - fn dispatch_event(&self, evt: &Event<&dyn ErasedProps>); - fn dispatch_blocking_flush(&self, timeout: Duration); - } - - pub trait SealedTarget { - fn erase_to(&self) -> crate::internal::Erased<&dyn DispatchTarget>; - } -} - -pub trait ErasedTarget: internal::SealedTarget {} - -impl ErasedTarget for T {} - -impl internal::SealedTarget for T { - fn erase_to(&self) -> crate::internal::Erased<&dyn internal::DispatchTarget> { - crate::internal::Erased(self) - } -} - -impl internal::DispatchTarget for T { - fn dispatch_event(&self, evt: &Event<&dyn ErasedProps>) { - self.event(evt) - } - - fn dispatch_blocking_flush(&self, timeout: Duration) { - self.blocking_flush(timeout) - } -} - -impl<'a> Target for dyn ErasedTarget + 'a { - fn event(&self, evt: &Event

) { - self.erase_to().0.dispatch_event(&evt.erase()) - } - - fn blocking_flush(&self, timeout: Duration) { - self.erase_to().0.dispatch_blocking_flush(timeout) - } -} - -impl<'a> Target for dyn ErasedTarget + Send + Sync + 'a { - fn event(&self, evt: &Event

) { - (self as &(dyn ErasedTarget + 'a)).event(evt) - } - - fn blocking_flush(&self, timeout: Duration) { - (self as &(dyn ErasedTarget + 'a)).blocking_flush(timeout) - } -} diff --git a/core/src/timestamp.rs b/core/src/timestamp.rs index 02b89d9..7c8a6b7 100644 --- a/core/src/timestamp.rs +++ b/core/src/timestamp.rs @@ -1,4 +1,4 @@ -use core::{cmp, fmt, ops::Sub, str, str::FromStr, time::Duration}; +use core::{cmp, fmt, str, str::FromStr, time::Duration}; use crate::value::{ToValue, Value}; @@ -6,12 +6,16 @@ use crate::value::{ToValue, Value}; pub struct Timestamp(Duration); impl Timestamp { - pub fn new(elapsed_since_unix_epoch: Duration) -> Self { - Timestamp(elapsed_since_unix_epoch) + pub fn new(unix_time: Duration) -> Self { + Timestamp(unix_time) } - pub fn to_unix(&self) -> Duration { - self.0 + pub fn as_unix_time(&self) -> &Duration { + &self.0 + } + + pub fn duration_since(self, earlier: Self) -> Option { + self.0.checked_sub(earlier.0) } #[cfg(feature = "std")] @@ -46,22 +50,6 @@ impl ToValue for Timestamp { } } -impl Sub for Timestamp { - type Output = Duration; - - fn sub(self, rhs: Self) -> Self::Output { - self.0.sub(rhs.0) - } -} - -impl<'a> Sub<&'a Timestamp> for Timestamp { - type Output = Duration; - - fn sub(self, rhs: &'a Timestamp) -> Self::Output { - self.0.sub(rhs.0) - } -} - impl<'v> Value<'v> { pub fn to_timestamp(&self) -> Option { self.downcast_ref::() diff --git a/src/lib.rs b/src/lib.rs index 9dfb255..d953e4c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,7 +14,7 @@ pub use emit_macros::*; #[doc(inline)] pub use emit_core::{ - clock, ctxt, empty, event, extent, filter, id, key, level, props, target, template, timestamp, + clock, ctxt, emitter, empty, event, extent, filter, id, key, level, props, template, timestamp, value, well_known, }; @@ -23,6 +23,7 @@ pub mod local_frame; pub use self::{ clock::{Clock, Timer}, ctxt::Ctxt, + emitter::Emitter, event::Event, extent::Extent, filter::Filter, @@ -30,7 +31,6 @@ pub use self::{ key::Key, level::Level, props::Props, - target::Target, template::Template, timestamp::Timestamp, value::Value, @@ -47,7 +47,7 @@ pub use setup::*; #[track_caller] fn base_emit( - to: impl Target, + to: impl Emitter, when: impl Filter, ctxt: impl Ctxt, ts: impl ToExtent, @@ -58,7 +58,7 @@ fn base_emit( let evt = Event::new(ts, tpl, props.chain(ctxt)); if when.matches(&evt) { - to.event(&evt); + to.emit(&evt); } }); } diff --git a/src/macro_hooks.rs b/src/macro_hooks.rs index ac64b4d..0be59cb 100644 --- a/src/macro_hooks.rs +++ b/src/macro_hooks.rs @@ -4,12 +4,12 @@ use emit_core::{ ambient, clock::Clock, ctxt::Ctxt, + emitter::Emitter, filter::Filter, id::{SpanId, TraceId}, key::ToKey, level::Level, props::Props, - target::Target, template::Template, value::{ToValue, Value}, }; @@ -408,7 +408,7 @@ impl<'a> __PrivateKeyHook for Key<'a> { #[track_caller] pub fn __private_emit( - to: impl Target, + to: impl Emitter, when: impl Filter, extent: impl ToExtent, tpl: Template, diff --git a/src/setup.rs b/src/setup.rs index 7b127b1..7c62b59 100644 --- a/src/setup.rs +++ b/src/setup.rs @@ -3,9 +3,9 @@ use core::time::Duration; use emit_core::{ ambient::Ambient, ctxt::Ctxt, + emitter::{self, Emitter}, empty::Empty, filter::Filter, - target::{self, Target}, }; use crate::platform::{DefaultCtxt, Platform}; @@ -14,11 +14,11 @@ pub fn setup() -> Setup { Setup::default() } -type DefaultTarget = Empty; +type DefaultEmitter = Empty; type DefaultFilter = Empty; -pub struct Setup { - target: TTarget, +pub struct Setup { + emitter: TEmitter, filter: TFilter, ctxt: TCtxt, platform: Platform, @@ -33,7 +33,7 @@ impl Default for Setup { impl Setup { pub fn new() -> Self { Setup { - target: Default::default(), + emitter: Default::default(), filter: Default::default(), ctxt: Default::default(), platform: Default::default(), @@ -41,31 +41,31 @@ impl Setup { } } -impl Setup { - pub fn to(self, target: UTarget) -> Setup { +impl Setup { + pub fn to(self, emitter: UEmitter) -> Setup { Setup { - target, + emitter, filter: self.filter, ctxt: self.ctxt, platform: self.platform, } } - pub fn and_to( + pub fn and_to( self, - target: UTarget, - ) -> Setup, TFilter, TCtxt> { + emitter: UEmitter, + ) -> Setup, TFilter, TCtxt> { Setup { - target: self.target.and(target), + emitter: self.emitter.and(emitter), filter: self.filter, ctxt: self.ctxt, platform: self.platform, } } - pub fn with(self, ctxt: UCtxt) -> Setup { + pub fn with(self, ctxt: UCtxt) -> Setup { Setup { - target: self.target, + emitter: self.emitter, filter: self.filter, ctxt, platform: self.platform, @@ -74,18 +74,18 @@ impl Setup Setup + > Setup where TCtxt::LocalFrame: Send + 'static, { #[must_use = "call `blocking_flush(std::time::Duration::from_secs(5))` at the end of `main` to ensure events are flushed."] - pub fn init(self) -> Init<&'static TTarget> { + pub fn init(self) -> Init<&'static TEmitter> { let ambient = emit_core::ambient::init( Ambient::new() - .with_target(self.target) + .with_emitter(self.emitter) .with_filter(self.filter) .with_ctxt(self.ctxt) .with_clock(self.platform.clock) @@ -94,17 +94,17 @@ where .expect("already initialized"); Init { - target: *ambient.target(), + emitter: *ambient.emitter(), } } } -pub struct Init { - target: TTarget, +pub struct Init { + emitter: TEmitter, } -impl Init { +impl Init { pub fn blocking_flush(&self, timeout: Duration) { - self.target.blocking_flush(timeout); + self.emitter.blocking_flush(timeout); } } diff --git a/targets/opentelemetry/src/logs.rs b/targets/opentelemetry/src/logs.rs index 3f43096..9d8364f 100644 --- a/targets/opentelemetry/src/logs.rs +++ b/targets/opentelemetry/src/logs.rs @@ -21,8 +21,8 @@ pub fn target(logger: Logger) -> OpenTelemetryLogsTarget { pub struct OpenTelemetryLogsTarget(Logger); -impl emit_core::target::Target for OpenTelemetryLogsTarget { - fn event(&self, evt: &emit_core::event::Event

) { +impl emit_core::emitter::Emitter for OpenTelemetryLogsTarget { + fn emit(&self, evt: &emit_core::event::Event

) { self.0.emit(to_record(evt)); } diff --git a/targets/otlp/src/logs.rs b/targets/otlp/src/logs.rs index 1f4e592..a80eb3c 100644 --- a/targets/otlp/src/logs.rs +++ b/targets/otlp/src/logs.rs @@ -60,12 +60,12 @@ impl OtlpLogsTargetBuilder { } } -impl emit_core::target::Target for OtlpLogsTarget { - fn event(&self, evt: &emit_core::event::Event

) { +impl emit_core::emitter::Emitter for OtlpLogsTarget { + fn emit(&self, evt: &emit_core::event::Event

) { let time_unix_nano = evt .extent() - .to_point() - .map(|ts| ts.to_unix().as_nanos() as u64) + .as_point() + .map(|ts| ts.as_unix_time().as_nanos() as u64) .unwrap_or_default(); let observed_time_unix_nano = time_unix_nano; diff --git a/targets/term/src/lib.rs b/targets/term/src/lib.rs index c40d294..16c5266 100644 --- a/targets/term/src/lib.rs +++ b/targets/term/src/lib.rs @@ -14,8 +14,8 @@ thread_local! { static STDOUT: RefCell> = RefCell::new(None); } -impl emit::target::Target for Stdout { - fn event(&self, evt: &emit::Event

) { +impl emit::emitter::Emitter for Stdout { + fn emit(&self, evt: &emit::Event

) { STDOUT.with(|buf| { match buf.try_borrow_mut() { // If there are no overlapping references then use the cached buffer