Skip to content
This repository has been archived by the owner on Jun 8, 2024. It is now read-only.

Commit

Permalink
work on span API
Browse files Browse the repository at this point in the history
  • Loading branch information
KodrAus committed Apr 11, 2024
1 parent 8cdffa4 commit 7c86d6a
Show file tree
Hide file tree
Showing 21 changed files with 409 additions and 241 deletions.
1 change: 1 addition & 0 deletions core/src/well_known.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub const LVL_ERROR: &'static str = "error";
pub const KEY_ERR: &'static str = "err";

// Trace
pub const KEY_SPAN_NAME: &'static str = "span_name";
pub const KEY_TRACE_ID: &'static str = "trace_id";
pub const KEY_SPAN_ID: &'static str = "span_id";
pub const KEY_SPAN_PARENT: &'static str = "span_parent";
Expand Down
2 changes: 1 addition & 1 deletion macros/src/module.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use proc_macro2::TokenStream;

pub(crate) fn module_tokens() -> TokenStream {
quote!(emit::__private::__private_module!())
quote!(emit::module!())
}
2 changes: 0 additions & 2 deletions macros/src/props.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ pub struct KeyValue {
span: Span,
pub interpolated: bool,
pub captured: bool,
pub label: String,
pub cfg_attr: Option<Attribute>,
pub attrs: Vec<Attribute>,
}
Expand Down Expand Up @@ -166,7 +165,6 @@ impl Props {
match_bound_tokens: quote_spanned!(fv.span()=> #cfg_attr (#match_bound_ident.0, #match_bound_ident.1)),
direct_bound_tokens: quote_spanned!(fv.span()=> #key_value_tokens),
span: fv.span(),
label,
cfg_attr,
attrs,
captured,
Expand Down
52 changes: 36 additions & 16 deletions macros/src/span.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,21 +155,31 @@ fn inject_sync(
let ctxt_props_tokens = ctxt_props.props_tokens();
let evt_props_tokens = evt_props.props_tokens();
let template_tokens = template.template_tokens();
let template_literal_tokens = template.template_literal_tokens();

quote!({
let (mut __ctxt, __timer, __span_props) = emit::__private::__private_push_span_ctxt(#rt_tokens, #module_tokens, #when_tokens, #template_tokens, #ctxt_props_tokens, #evt_props_tokens);
let (mut __ctxt, __span_arg) = emit::__private::__private_begin_span(
#rt_tokens,
#module_tokens,
#when_tokens,
#template_tokens,
#ctxt_props_tokens,
#evt_props_tokens,
#template_literal_tokens,
|extent, props| {
emit::__private::__private_emit(
#rt_tokens,
#module_tokens,
emit::__private::__private_filter_span_complete(),
extent,
#template_tokens,
emit::Props::chain(props, #evt_props_tokens),
)
}
);
let __ctxt_guard = __ctxt.enter();

let #span_arg = emit::__private::__private_begin_span(__timer, __span_props, |extent, props| {
emit::__private::__private_emit(
#rt_tokens,
#module_tokens,
emit::__private::__private_filter_span_complete(),
extent,
#template_tokens,
emit::Props::chain(props, #evt_props_tokens),
)
});
let #span_arg = __span_arg;

#body
})
Expand All @@ -188,12 +198,18 @@ fn inject_async(
let ctxt_props_tokens = ctxt_props.props_tokens();
let evt_props_tokens = evt_props.props_tokens();
let template_tokens = template.template_tokens();
let template_literal_tokens = template.template_literal_tokens();

quote!({
let (__ctxt, __timer, __span_props) = emit::__private::__private_push_span_ctxt(#rt_tokens, #module_tokens, #when_tokens, #template_tokens, #ctxt_props_tokens, #evt_props_tokens);

__ctxt.in_future(async {
let #span_arg = emit::__private::__private_begin_span(__timer, __span_props, |extent, props| {
let (__ctxt, __span_arg) = emit::__private::__private_begin_span(
#rt_tokens,
#module_tokens,
#when_tokens,
#template_tokens,
#ctxt_props_tokens,
#evt_props_tokens,
#template_literal_tokens,
|extent, props| {
emit::__private::__private_emit(
#rt_tokens,
#module_tokens,
Expand All @@ -202,7 +218,11 @@ fn inject_async(
#template_tokens,
emit::Props::chain(props, #evt_props_tokens),
)
});
}
);

__ctxt.in_future(async {
let #span_arg = __span_arg;

async #body.await
}).await
Expand Down
28 changes: 23 additions & 5 deletions macros/src/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,15 @@ pub fn parse2<A: Parse>(
}

// A runtime representation of the template
let template_tokens = {
let (template_parts_tokens, template_literal_tokens) = {
let mut template_visitor = TemplateVisitor {
props: &props,
parts: Ok(Vec::new()),
literal: String::new(),
};
template.visit_literal(&mut template_visitor);
let template_parts = template_visitor.parts?;
let literal = template_visitor.literal;

/*
Ideally this would be:
Expand All @@ -98,29 +100,38 @@ pub fn parse2<A: Parse>(
Once that is stable then we'll be able to use it here and avoid
"value doesn't live long enough" errors in `let x = tpl!(..);`.
*/
quote!([
#(#template_parts),*
])
(
quote!([
#(#template_parts),*
]),
quote!(#literal),
)
};

Ok((
args,
Template {
template_parts_tokens: template_tokens,
template_parts_tokens,
template_literal_tokens,
},
props,
))
}

pub struct Template {
template_parts_tokens: TokenStream,
template_literal_tokens: TokenStream,
}

impl Template {
pub fn template_parts_tokens(&self) -> TokenStream {
self.template_parts_tokens.clone()
}

pub fn template_literal_tokens(&self) -> TokenStream {
self.template_literal_tokens.clone()
}

pub fn template_tokens(&self) -> TokenStream {
let template_parts = &self.template_parts_tokens;

Expand All @@ -131,6 +142,7 @@ impl Template {
struct TemplateVisitor<'a> {
props: &'a Props,
parts: syn::Result<Vec<TokenStream>>,
literal: String,
}

impl<'a> fv_template::LiteralVisitor for TemplateVisitor<'a> {
Expand All @@ -146,6 +158,10 @@ impl<'a> fv_template::LiteralVisitor for TemplateVisitor<'a> {

debug_assert!(field.interpolated);

self.literal.push_str("{");
self.literal.push_str(&label);
self.literal.push_str("}");

match fmt::template_hole_with_hook(&field.attrs, &hole, true, field.captured) {
Ok(hole_tokens) => match field.cfg_attr {
Some(ref cfg_attr) => parts.push(quote!(#cfg_attr { #hole_tokens })),
Expand All @@ -162,6 +178,8 @@ impl<'a> fv_template::LiteralVisitor for TemplateVisitor<'a> {
return;
};

self.literal.push_str(text);

parts.push(quote!(emit::template::Part::text(#text)));
}
}
86 changes: 86 additions & 0 deletions src/kind.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
use core::{fmt, str::FromStr};

use emit_core::{
event::Event,
filter::Filter,
props::Props,
value::{FromValue, ToValue, Value},
well_known::{EVENT_KIND_METRIC, EVENT_KIND_SPAN, KEY_EVENT_KIND},
};

#[non_exhaustive]
#[derive(PartialEq, Eq, Hash, Clone, Copy)]
pub enum Kind {
Span,
Metric,
}

impl fmt::Debug for Kind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "\"{}\"", self)
}
}

impl fmt::Display for Kind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Kind::Span => f.write_str(EVENT_KIND_SPAN),
Kind::Metric => f.write_str(EVENT_KIND_METRIC),
}
}
}

impl ToValue for Kind {
fn to_value(&self) -> Value {
Value::capture_display(self)
}
}

impl<'v> FromValue<'v> for Kind {
fn from_value(value: Value<'v>) -> Option<Self> {
value
.downcast_ref::<Kind>()
.copied()
.or_else(|| value.parse())
}
}

impl FromStr for Kind {
type Err = ParseKindError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
if s.eq_ignore_ascii_case(EVENT_KIND_SPAN) {
return Ok(Kind::Span);
}

if s.eq_ignore_ascii_case(EVENT_KIND_METRIC) {
return Ok(Kind::Metric);
}

Err(ParseKindError {})
}
}

pub struct ParseKindError {}

pub struct IsKind(Kind);

impl IsKind {
pub fn new(kind: Kind) -> Self {
IsKind(kind)
}
}

pub fn is_span_filter() -> IsKind {
IsKind::new(Kind::Span)
}

pub fn is_metric_filter() -> IsKind {
IsKind::new(Kind::Metric)
}

impl Filter for IsKind {
fn matches<P: Props>(&self, evt: &Event<P>) -> bool {
evt.props().pull::<Kind, _>(KEY_EVENT_KIND) == Some(self.0)
}
}
2 changes: 1 addition & 1 deletion src/level.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ impl<'v> FromValue<'v> for Level {
}
}

pub fn min_level(min: Level) -> MinLevel {
pub fn min_level_filter(min: Level) -> MinLevel {
MinLevel::new(min)
}

Expand Down
28 changes: 6 additions & 22 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,8 @@ extern crate alloc;

use emit_core::extent::ToExtent;

pub use std::module_path as module;

#[doc(inline)]
pub use emit_macros::*;

Expand All @@ -345,15 +347,16 @@ pub use emit_core::{
};

pub mod frame;
pub mod kind;
pub mod level;
pub mod metric;
pub mod span;
pub mod timer;
pub mod trace;

pub use self::{
clock::Clock, ctxt::Ctxt, emitter::Emitter, event::Event, extent::Extent, filter::Filter,
frame::Frame, level::Level, path::Path, props::Props, rng::Rng, str::Str, template::Template,
timer::Timer, timestamp::Timestamp, value::Value,
frame::Frame, level::Level, metric::Metric, path::Path, props::Props, rng::Rng, span::Span,
str::Str, template::Template, timer::Timer, timestamp::Timestamp, value::Value,
};

mod macro_hooks;
Expand All @@ -364,25 +367,6 @@ pub mod setup;
#[cfg(feature = "std")]
pub use setup::{setup, Setup};

#[track_caller]
fn base_emit(
to: impl Emitter,
source: Path,
when: impl Filter,
ctxt: impl Ctxt,
ts: impl ToExtent,
tpl: Template,
props: impl Props,
) {
ctxt.with_current(|ctxt| {
let evt = Event::new(source, ts, tpl, props.chain(ctxt));

if when.matches(&evt) {
to.emit(&evt);
}
});
}

#[doc(hidden)]
pub mod __private {
pub use crate::macro_hooks::*;
Expand Down
Loading

0 comments on commit 7c86d6a

Please sign in to comment.