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

Commit

Permalink
work on docs
Browse files Browse the repository at this point in the history
  • Loading branch information
KodrAus committed Mar 24, 2024
1 parent 69218c2 commit c618b72
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 70 deletions.
6 changes: 6 additions & 0 deletions macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ fn hooks() -> HashMap<&'static str, fn(TokenStream, TokenStream) -> syn::Result<
}
#[cfg(not(feature = "sval"))]
{
use syn::spanned::Spanned;

let _ = args;

Err(syn::Error::new(expr.span(), "capturing with `sval` is only possible when the `sval` Cargo feature is enabled"))
Expand All @@ -135,6 +137,8 @@ fn hooks() -> HashMap<&'static str, fn(TokenStream, TokenStream) -> syn::Result<
}
#[cfg(not(feature = "serde"))]
{
use syn::spanned::Spanned;

let _ = args;

Err(syn::Error::new(expr.span(), "capturing with `serde` is only possible when the `serde` Cargo feature is enabled"))
Expand All @@ -157,6 +161,8 @@ fn hooks() -> HashMap<&'static str, fn(TokenStream, TokenStream) -> syn::Result<
}
#[cfg(not(feature = "std"))]
{
use syn::spanned::Spanned;

let _ = args;

Err(syn::Error::new(
Expand Down
138 changes: 85 additions & 53 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*!
Structured diagnostics for Rust applications.
Emit is a structured logging framework for manually instrumenting Rust applications with an expressive syntax.
Emit is a structured logging framework for manually instrumenting Rust applications with an expressive syntax inspired by [Message Templates](https://messagetemplates.org). All diagnostics in Emit are represented as _events_. An event is a notable change in the state of a system that is broadcast to outside observers. Events carry both a human-readable description of what triggered them as well as a structured payload that can be used to process them. Events are temporal; they may be anchored to a point in time at which they occurred, or may cover a span of time for which they are active.
# Getting started
Expand All @@ -17,7 +17,7 @@ version = "*"
`emit` needs to be configured with an _emitter_ that sends events somewhere. In this example we're using `emit_term` to write events to the console. Other emitters exist for rolling files and OpenTelemetry's wire format.
At the start of your `main` function, use [`setup`] to initialize `emit`. At the end of your `main` function, use [`Setup::blocking_flush`] to ensure all emitted events are fully flushed to the outside target.
At the start of your `main` function, use [`setup()`] to initialize `emit`. At the end of your `main` function, use [`setup::Init::blocking_flush`] to ensure all emitted events are fully flushed to the outside target.
```
fn main() {
Expand All @@ -33,14 +33,38 @@ fn main() {
# Logging events
When something significant happens in your application you can emit an event for it. This can be done using the [`emit`], [`debug`], [`info`], [`warn`], and [`error`] macros. The macros accept a string literal _template_ that may have properties captured and interpolated into it using _field value_ syntax:
When something significant happens in your application you can emit an _event_ for it. This can be done using the [`emit`], [`debug`], [`info`], [`warn`], and [`error`] macros. The macros accept a string literal _template_ that may have _properties_ captured and interpolated into it using Rust's field value syntax:
```
let user = "Rust";
emit::info!("Hello, {user}");
```
This macro expands roughly to:
```
let user = "Rust";
// emit::info!("Hello, {user}");
let rt = emit::runtime::shared();
let extent = rt.now();
let props = &[
("user", user),
];
rt.emit(emit::Event::new(
"some_app::some_module",
extent,
emit::Template::new(&[
emit::template::Part::text("Hello, "),
emit::template::Part::hole("user"),
]),
props,
));
```
Properties can also be captured after the template:
```
Expand All @@ -49,29 +73,31 @@ let user = "Rust";
emit::info!("Hello", user);
```
Properties may be named or initialized directly in the macro:
Properties may be named or initialized directly in the template:
```
emit::info!("Hello, {user: \"Rust\"}");
```
Properties can also be named or initialized after the template:
```
emit::info!("Hello", user: "Rust");
```
Any field values that appear in the template between braces or after it are captured as properties on the event. Field values can also appear _before_ the template to customize how events are constructed and emitted. For example, the macros accept a `module` field value to set the name of the containing module for an event:
Field values can also appear _before_ the template to customize how events are constructed and emitted. Field values before the template follow a fixed schema. For example, the macros accept a `module` field value to set the name of the containing module for an event:
```
let user = "Rust";
emit::info!(module: "my_mod", "Hello", user);
```
Think of field values before the template like optional function arguments.
Think of field values before the template like optional function arguments, and field values after the template like a spread of extra parameters.
# Tracing functions
When significant operations are executed in your application you can use span events to instrument them, corrolating any other events within them into a hierarchy. This can be done using the [`span`], [`debug_span`], [`info_span`], [`warn_span`], and [`error_span`] macros. The macros use the same syntax as those for regular events:
When significant operations are invoked in your application you can use _span events_ to time them while also corrolating any other events they emit into a trace hierarchy. This can be done using the [`span`], [`debug_span`], [`info_span`], [`warn_span`], and [`error_span`] macros. The macros use the same syntax as those for regular events:
```
#[emit::info_span!("Invoke with {user}")]
Expand All @@ -80,7 +106,34 @@ fn my_function(user: &str) {
}
```
When `my_function` completes, an event will be emitted with the time it took to execute.
When `my_function` completes, an event will be emitted with the time it took to execute. This macro expands roughly to:
```
// #[emit::info_span!("Invoke with {user}")]
fn my_function(user: &str) {
let rt = emit::runtime::shared();
let timer = emit::Timer::start(rt).on_drop(|extent| {
let props = &[
("user", user),
];
rt.emit(emit::Event::new(
"some_app::some_module",
extent,
emit::Template::new(&[
emit::template::Part::text("Invoke with "),
emit::template::Part::hole("user"),
]),
props,
));
});
// Function body..
drop(timer);
}
```
## Completion
Expand All @@ -101,44 +154,35 @@ fn my_function(id: &str) -> Result<i32, Error> {
}
```
In this example, we use the `arg` paramter to assign a local variable `span` that represents the span for our function. In the `Ok` branch, we let the span complete normally. In the `Err` branch, we complete the span manually with the error produced.
You may also notice we pass a parameter before the template in the `error!` macro in the `Err` branch too. That sets the _extent_ of the event to the time the function spent executing. Parameters before the template are used to control how events are constructed and emitted, they aren't captured as properties. All properties are put within the template itself, or after it.
# Templates and capturing
# Customizing events
# Runtimes
In this example, we use the `arg` field value before the template to assign a local variable `span` that represents the span for our function. In the `Ok` branch, we let the span complete normally. In the `Err` branch, we complete the span manually with the error produced.
# Data model
# Extents and timestamps
## Events
The extent of an event is the time for which it is relevant. This may be a single point in time if the event was triggered by something happening, or a span of time if the event was started at one point and completed at a later one. Extents are represented by the [`Extent`] type, and timestamps by the [`Timestamp`] type.
All diagnostics in Emit are represented as _events_. An event is a notable change in the state of a system that is broadcast to outside observers. Events carry both a human-readable description of what triggered them as well as a structured payload that can be used to process them. Events are temporal; they may be anchored to a point in time at which they occurred, or may cover a span of time for which they are active.
Events are automatically assigned an extent with the current timestamp when they're emitted based on a [`Clock`]. This can be customized with the `extent` field value on the macros.
The core event model includes:
This is an example of a point event:
- **Module (`module`):** The name of the component that triggered the event.
- **Extent (`ts_start`..`ts`):** The point or span of time for which the event is relevant.
- **Template (`tpl` and `msg`):** A human-readable description of the event that its properties may be interpolated into.
- **Properties (`props`):** The payload of the event.
## Extents
The extent of an event is the time for which the event is relevant. This may be a single point in time if the event was triggered by something happening, or a span of time if the event was started at one point and completed at a later one.
```
use std::time::Duration;
## Templates
let now = emit::Timestamp::new(Duration::from_secs(1711317957));
The primary source of information in an event is its _template_. A template is a human-readable description of an event with holes to interpolate values into. Templates are responsible for both capturing local state to include in an event, and to format that state into a human-readable description.
emit::info!(extent: now, "A point event");
```
Templates are a useful low-cardinality identifier for events.
This is an example of a span event:
Emit's templates are inspired by [Message Templates](https://messagetemplates.org).
```
# use std::time::Duration;
# let now = emit::Timestamp::new(Duration::from_secs(1711317957));
let later = now + Duration::from_secs(1000);
## Properties
emit::info!(extent: now..later, "A span event");
```
Emit's properties are structured key-value pairs where keys are strings and values are anything from primitive types to complex records and sequences. Values can use the data model of either `serde` or `sval`.
Span events can wrap a clock in a [`Timer`] to produce an extent that covers a time range.
## Observability signals
Expand Down Expand Up @@ -193,7 +237,7 @@ The set of components needed to produce, receive, filter, and emit events is enc
#[cfg(feature = "alloc")]
extern crate alloc;

use emit_core::{extent::ToExtent, path::Path};
use emit_core::extent::ToExtent;

#[doc(inline)]
pub use emit_macros::*;
Expand All @@ -211,30 +255,18 @@ pub mod timer;
pub mod trace;

pub use self::{
clock::Clock,
ctxt::Ctxt,
emitter::Emitter,
event::Event,
extent::Extent,
filter::Filter,
level::Level,
props::Props,
rng::Rng,
str::Str,
template::Template,
timer::Timer,
timestamp::Timestamp,
trace::{SpanId, TraceId},
value::Value,
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,
};

mod macro_hooks;
mod platform;

#[cfg(feature = "std")]
mod setup;
pub mod setup;
#[cfg(feature = "std")]
pub use setup::*;
pub use setup::{setup, Setup};

#[track_caller]
fn base_emit(
Expand Down
7 changes: 3 additions & 4 deletions src/macro_hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use emit_core::{
props::Props,
rng::Rng,
runtime::Runtime,
str::ToStr,
template::Template,
str::{Str, ToStr},
template::{Formatter, Part, Template},
value::{ToValue, Value},
};

Expand All @@ -30,10 +30,9 @@ use std::error::Error;

use crate::{
base_emit,
template::{Formatter, Part},
timer::TimerGuard,
trace::{SpanId, TraceId},
Level, Str, Timer,
Level, Timer,
};

/**
Expand Down
4 changes: 2 additions & 2 deletions targets/otlp/src/client/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,8 @@ async fn send_request(
let mut span_id = None;

rt.ctxt().with_current(|props| {
trace_id = props.pull::<emit::TraceId, _>(KEY_TRACE_ID);
span_id = props.pull::<emit::SpanId, _>(KEY_SPAN_ID);
trace_id = props.pull::<emit::trace::TraceId, _>(KEY_TRACE_ID);
span_id = props.pull::<emit::trace::SpanId, _>(KEY_SPAN_ID);
});

req = if let (Some(trace_id), Some(span_id)) = (trace_id, span_id) {
Expand Down
4 changes: 2 additions & 2 deletions targets/otlp/src/data/logs/log_record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,15 @@ impl<P: emit::props::Props> sval::Value for PropsLogRecordAttributes<P> {
emit::well_known::KEY_SPAN_ID => {
span_id = v
.by_ref()
.cast::<emit::SpanId>()
.cast::<emit::trace::SpanId>()
.map(|span_id| span_id.to_u64().to_be_bytes())
.unwrap_or_default();
true
}
emit::well_known::KEY_TRACE_ID => {
trace_id = v
.by_ref()
.cast::<emit::TraceId>()
.cast::<emit::trace::TraceId>()
.map(|trace_id| trace_id.to_u128().to_be_bytes())
.unwrap_or_default();
true
Expand Down
6 changes: 3 additions & 3 deletions targets/otlp/src/data/traces/span.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,23 +110,23 @@ impl<P: emit::props::Props> sval::Value for PropsSpanAttributes<P> {
emit::well_known::KEY_SPAN_ID => {
span_id = v
.by_ref()
.cast::<emit::SpanId>()
.cast::<emit::trace::SpanId>()
.map(|span_id| span_id.to_u64().to_be_bytes())
.unwrap_or_default();
true
}
emit::well_known::KEY_SPAN_PARENT => {
parent_span_id = v
.by_ref()
.cast::<emit::SpanId>()
.cast::<emit::trace::SpanId>()
.map(|parent_span_id| parent_span_id.to_u64().to_be_bytes())
.unwrap_or_default();
true
}
emit::well_known::KEY_TRACE_ID => {
trace_id = v
.by_ref()
.cast::<emit::TraceId>()
.cast::<emit::trace::TraceId>()
.map(|trace_id| trace_id.to_u128().to_be_bytes())
.unwrap_or_default();
true
Expand Down
8 changes: 4 additions & 4 deletions targets/term/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ impl emit::emitter::Emitter for Stdout {

impl emit::runtime::InternalEmitter for Stdout {}

fn trace_id_color(trace_id: &emit::TraceId) -> u8 {
fn trace_id_color(trace_id: &emit::trace::TraceId) -> u8 {
let mut hash = 0;

for b in trace_id.to_u128().to_le_bytes() {
Expand All @@ -70,7 +70,7 @@ fn trace_id_color(trace_id: &emit::TraceId) -> u8 {
hash
}

fn span_id_color(span_id: &emit::SpanId) -> u8 {
fn span_id_color(span_id: &emit::trace::SpanId) -> u8 {
let mut hash = 0;

for b in span_id.to_u64().to_le_bytes() {
Expand Down Expand Up @@ -190,8 +190,8 @@ fn print_event(
buf: &mut Buffer,
evt: &emit::event::Event<impl emit::props::Props>,
) {
if let Some(span_id) = evt.props().pull::<emit::SpanId, _>(KEY_SPAN_ID) {
if let Some(trace_id) = evt.props().pull::<emit::TraceId, _>(KEY_TRACE_ID) {
if let Some(span_id) = evt.props().pull::<emit::trace::SpanId, _>(KEY_SPAN_ID) {
if let Some(trace_id) = evt.props().pull::<emit::trace::TraceId, _>(KEY_TRACE_ID) {
let trace_id_color = trace_id_color(&trace_id);

write_fg(buf, "▓", Color::Ansi256(trace_id_color));
Expand Down
4 changes: 2 additions & 2 deletions targets/tracing/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl<C: emit::Ctxt, S: tracing::Subscriber> emit::Ctxt for TracingCtxt<C, S> {
static CALLSITE: tracing::callsite::DefaultCallsite =
tracing::callsite::DefaultCallsite::new(&METADATA);

let tracing_id = if let Some(span_id) = props.pull::<emit::SpanId, _>(KEY_SPAN_ID) {
let tracing_id = if let Some(span_id) = props.pull::<emit::trace::SpanId, _>(KEY_SPAN_ID) {
let fields = tracing::field::FieldSet::new(
&[
emit::well_known::KEY_TRACE_ID,
Expand All @@ -55,7 +55,7 @@ impl<C: emit::Ctxt, S: tracing::Subscriber> emit::Ctxt for TracingCtxt<C, S> {
);

let trace_id = props
.pull::<emit::TraceId, _>(KEY_TRACE_ID)
.pull::<emit::trace::TraceId, _>(KEY_TRACE_ID)
.map(tracing::field::display);

let id = self.1.new_span(&tracing::span::Attributes::new(
Expand Down

0 comments on commit c618b72

Please sign in to comment.