diff --git a/tokio-trace/CHANGELOG.md b/tokio-trace/CHANGELOG.md new file mode 100644 index 000000000..eaf3ae894 --- /dev/null +++ b/tokio-trace/CHANGELOG.md @@ -0,0 +1,3 @@ +# 0.1.0 (April 22, 2019) + +- Initial release diff --git a/tokio-trace/Cargo.toml b/tokio-trace/Cargo.toml index 5e365b475..79185f99b 100644 --- a/tokio-trace/Cargo.toml +++ b/tokio-trace/Cargo.toml @@ -1,21 +1,26 @@ [package] name = "tokio-trace" -version = "0.0.1" -authors = ["Eliza Weisman "] +# When releasing to crates.io: +# - Update html_root_url. +# - Update doc url +# - Cargo.toml +# - README.md +# - Update CHANGELOG.md. +# - Create "v0.1.x" git tag +version = "0.1.0" +authors = ["Tokio Contributors "] license = "MIT" repository = "https://github.com/tokio-rs/tokio" homepage = "https://tokio.rs" +documentation = "https://docs.rs/tokio-trace/0.1.0/tokio_trace" description = """ A scoped, structured logging and diagnostics system. """ categories = ["development-tools::debugging", "asynchronous"] keywords = ["logging", "tracing"] -# Not yet ready for production. -publish = false - [dependencies] -tokio-trace-core = { path = "./tokio-trace-core" } +tokio-trace-core = "0.2" log = { version = "0.4", optional = true } cfg-if = "0.1.7" diff --git a/tokio-trace/README.md b/tokio-trace/README.md index 7f1adc0d7..09c1fb7e3 100644 --- a/tokio-trace/README.md +++ b/tokio-trace/README.md @@ -2,7 +2,7 @@ A scoped, structured logging and diagnostics system. -[Documentation](https://tokio-rs.github.io/tokio/doc/tokio_trace/) +[Documentation](https://docs.rs/tokio-trace/0.1.0/tokio_trace/index.html) ## Overview @@ -29,7 +29,7 @@ First, add this to your `Cargo.toml`: ```toml [dependencies] -tokio-trace = { git = "https://github.com/tokio-rs/tokio" } +tokio-trace = "0.1" ``` Next, add this to your crate: diff --git a/tokio-trace/src/field.rs b/tokio-trace/src/field.rs index 9f8fdad97..5b0e37496 100644 --- a/tokio-trace/src/field.rs +++ b/tokio-trace/src/field.rs @@ -10,6 +10,8 @@ use Metadata; /// Indexing a field with a string results in an iterative search that performs /// string comparisons. Thus, if possible, once the key for a field is known, it /// should be used whenever possible. +/// +/// [`Field`]: ../struct.Field.html pub trait AsField: ::sealed::Sealed { /// Attempts to convert `&self` into a `Field` with the specified `metadata`. /// diff --git a/tokio-trace/src/level_filters.rs b/tokio-trace/src/level_filters.rs index 4d383112c..dff70b4ea 100644 --- a/tokio-trace/src/level_filters.rs +++ b/tokio-trace/src/level_filters.rs @@ -1,15 +1,59 @@ +//! Trace verbosity level filtering. +//! +//! # Compile time filters +//! +//! Trace verbosity levels can be statically disabled at compile time via Cargo +//! features, similar to the [`log` crate]. Trace instrumentation at disabled +//! levels will be skipped and will not even be present in the resulting binary +//! unless the verbosity level is specified dynamically. This level is +//! configured separately for release and debug builds. The features are: +//! +//! * `max_level_off` +//! * `max_level_error` +//! * `max_level_warn` +//! * `max_level_info` +//! * `max_level_debug` +//! * `max_level_trace` +//! * `release_max_level_off` +//! * `release_max_level_error` +//! * `release_max_level_warn` +//! * `release_max_level_info` +//! * `release_max_level_debug` +//! * `release_max_level_trace` +//! +//! These features control the value of the `STATIC_MAX_LEVEL` constant. The +//! instrumentation macros macros check this value before recording an event or +//! constructing a span. By default, no levels are disabled. +//! +//! For example, a crate can disable trace level instrumentation in debug builds +//! and trace, debug, and info level instrumentation in release builds with the +//! following configuration: +//! +//! ```toml +//! [dependencies] +//! tokio-trace = { version = "0.1", features = ["max_level_debug", "release_max_level_warn"] } +//! ``` +//! +//! [`log` crate]: https://docs.rs/log/0.4.6/log/#compile-time-filters use std::cmp::Ordering; use tokio_trace_core::Level; -/// `LevelFilter` is used to statistically filter the logging messages based on its `Level`. -/// Logging messages will be discarded if its `Level` is greater than `LevelFilter`. +/// A filter comparable to trace verbosity `Level`. +/// +/// If a `Level` is considered less than a `LevelFilter`, it should be +/// considered disabled; if greater than or equal to the `LevelFilter`, that +/// level is enabled. +/// +/// Note that this is essentially identical to the `Level` type, but with the +/// addition of an `OFF` level that completely disables all trace +/// instrumentation. #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] pub struct LevelFilter(Option); impl LevelFilter { /// The "off" level. /// - /// Designates that logging should be to turned off. + /// Designates that trace instrumentation should be completely disabled. pub const OFF: LevelFilter = LevelFilter(None); /// The "error" level. /// @@ -51,12 +95,17 @@ impl PartialOrd for Level { } } -/// The statically resolved maximum trace level. +/// The statically configured maximum trace level. /// -/// See the crate level documentation for information on how to configure this. +/// See the [module-level documentation] for information on how to configure +/// this. /// -/// This value is checked by the `event` macro. Code that manually calls functions on that value -/// should compare the level against this value. +/// This value is checked by the `event!` and `span!` macros. Code that +/// manually constructs events or spans via the `Event::record` function or +/// `Span` constructors should compare the level against this value to +/// determine if those spans or events are enabled. +/// +/// [module-level documentation]: ../index.html#compile-time-filters pub const STATIC_MAX_LEVEL: LevelFilter = MAX_LEVEL; cfg_if! { diff --git a/tokio-trace/src/lib.rs b/tokio-trace/src/lib.rs index fb8d2efb2..43de2858c 100644 --- a/tokio-trace/src/lib.rs +++ b/tokio-trace/src/lib.rs @@ -1,3 +1,6 @@ +#![doc(html_root_url = "https://docs.rs/tokio-trace/0.1.0")] +#![deny(missing_debug_implementations, missing_docs, unreachable_pub)] +#![cfg_attr(test, deny(warnings))] //! A scoped, structured logging and diagnostics system. //! //! # Overview @@ -32,6 +35,20 @@ //! another context. The span in which a thread is currently executing is //! referred to as the _current_ span. //! +//! For example: +//! ``` +//! #[macro_use] +//! extern crate tokio_trace; +//! +//! use tokio_trace::Level; +//! +//! # fn main() { +//! span!(Level::TRACE, "my_span").enter(|| { +//! // perform some work in the context of `my_span`... +//! }); +//! # } +//!``` +//! //! Spans form a tree structure — unless it is a root span, all spans have a //! _parent_, and may have one or more _children_. When a new span is created, //! the current span becomes the new span's parent. The total execution time of @@ -39,10 +56,43 @@ //! represented by its children. Thus, a parent span always lasts for at least //! as long as the longest-executing span in its subtree. //! +//! ``` +//! # #[macro_use] extern crate tokio_trace; +//! # use tokio_trace::Level; +//! # fn main() { +//! // this span is considered the "root" of a new trace tree: +//! span!(Level::INFO, "root").enter(|| { +//! // since we are now inside "root", this span is considered a child +//! // of "root": +//! span!(Level::DEBUG, "outer_child").enter(|| { +//! // this span is a child of "outer_child", which is in turn a +//! // child of "root": +//! span!(Level::TRACE, "inner_child").enter(|| { +//! // and so on... +//! }); +//! }); +//! }); +//! # } +//!``` +//! //! In addition, data may be associated with spans. A span may have _fields_ — //! a set of key-value pairs describing the state of the program during that //! span; an optional name, and metadata describing the source code location //! where the span was originally entered. +//! ``` +//! # #[macro_use] extern crate tokio_trace; +//! # use tokio_trace::Level; +//! # fn main() { +//! // construct a new span with three fields: +//! // - "foo", with a value of 42, +//! // - "bar", with the value "false" +//! // - "baz", with no initial value +//! let my_span = span!(Level::INFO, "my_span", foo = 42, bar = false, baz); +//! +//! // record a value for the field "baz" declared above: +//! my_span.record("baz", &"hello world"); +//! # } +//!``` //! //! ### When to use spans //! @@ -95,9 +145,22 @@ //! records emitted by unstructured logging code, but unlike a typical log line, //! an `Event` may occur within the context of a `Span`. Like a `Span`, it //! may have fields, and implicitly inherits any of the fields present on its -//! parent span, and it may be linked with one or more additional -//! spans that are not its parent; in this case, the event is said to _follow -//! from_ those spans. +//! parent span. +//! +//! For example: +//! ``` +//! # #[macro_use] extern crate tokio_trace; +//! # use tokio_trace::Level; +//! # fn main() { +//! // records an event outside of any span context: +//! event!(Level::INFO, "something happened"); +//! +//! span!(Level::INFO, "my_span").enter(|| { +//! // records an event within "my_span". +//! event!(Level::DEBUG, "something happened inside my_span"); +//! }); +//! # } +//!``` //! //! Essentially, `Event`s exist to bridge the gap between traditional //! unstructured logging and span-based tracing. Similar to log records, they @@ -139,7 +202,7 @@ //! //! ```toml //! [dependencies] -//! tokio-trace = { git = "https://github.com/tokio-rs/tokio" } +//! tokio-trace = "0.1" //! ``` //! //! Next, add this to your crate: @@ -230,13 +293,13 @@ //! You can find examples showing how to use this crate in the examples //! directory. //! -//! ### In libraries +//! ## In libraries //! //! Libraries should link only to the `tokio-trace` crate, and use the provided //! macros to record whatever information will be useful to downstream //! consumers. //! -//! ### In executables +//! ## In executables //! //! In order to record trace events, executables have to use a `Subscriber` //! implementation compatible with `tokio-trace`. A `Subscriber` implements a @@ -264,6 +327,7 @@ //! # fn new() -> Self { FooSubscriber } //! # } //! # fn main() { +//! //! let my_subscriber = FooSubscriber::new(); //! //! tokio_trace::subscriber::with_default(my_subscriber, || { @@ -299,6 +363,21 @@ //! trace tree. This is useful when a project using `tokio-trace` have //! dependencies which use `log`. //! +//! +//! ## Crate Feature Flags +//! +//! The following crate feature flags are available: +//! +//! * A set of features controlling the [static verbosity level]. +//! * `log` causes trace instrumentation points to emit [`log`] records as well +//! as trace events. This is inteded for use in libraries whose users may be +//! using either `tokio-trace` or `log`. +//! +//! ```toml +//! [dependencies] +//! tokio-trace = { version = "0.1", features = ["log"] } +//! ``` +//! //! [`log`]: https://docs.rs/log/0.4.6/log/ //! [`Span`]: span/struct.Span //! [`Event`]: struct.Event.html @@ -312,6 +391,7 @@ //! [`tokio-trace-futures`]: https://github.com/tokio-rs/tokio-trace-nursery/tree/master/tokio-trace-futures //! [`tokio-trace-fmt`]: https://github.com/tokio-rs/tokio-trace-nursery/tree/master/tokio-trace-fmt //! [`tokio-trace-log`]: https://github.com/tokio-rs/tokio-trace-nursery/tree/master/tokio-trace-log +//! [static verbosity level]: level_filters/index.html#compile-time-filters #[macro_use] extern crate cfg_if; extern crate tokio_trace_core; diff --git a/tokio-trace/src/span.rs b/tokio-trace/src/span.rs index 57d3b8d94..dfdaa5ec3 100644 --- a/tokio-trace/src/span.rs +++ b/tokio-trace/src/span.rs @@ -4,7 +4,7 @@ //! //! A thread of execution is said to _enter_ a span when it begins executing, //! and _exit_ the span when it switches to another context. Spans may be -//! entered through the [`enter`](`Span::enter`) method, which enters the target span, +//! entered through the [`enter`] method, which enters the target span, //! performs a given function (either a closure or a function pointer), exits //! the span, and then returns the result. //! @@ -68,11 +68,10 @@ //! Because spans may be entered and exited multiple times before they close, //! [`Subscriber`]s have separate trait methods which are called to notify them //! of span exits and when span handles are dropped. When execution exits a -//! span, [`exit`](::Subscriber::exit) will always be called with that span's ID -//! to notify the subscriber that the span has been exited. When span handles -//! are dropped, the [`drop_span`](::Subscriber::drop_span) method is called -//! with that span's ID. The subscriber may use this to determine whether or not -//! the span will be entered again. +//! span, [`exit`] will always be called with that span's ID to notify the +//! subscriber that the span has been exited. When span handles are dropped, the +//! [`drop_span`] method is called with that span's ID. The subscriber may use +//! this to determine whether or not the span will be entered again. //! //! If there is only a single handle with the capacity to exit a span, dropping //! that handle "close" the span, since the capacity to enter it no longer @@ -87,34 +86,20 @@ //! }); // --> Subscriber::exit(my_span) //! //! // The handle to `my_span` only lives inside of this block; when it is -//! // dropped, the subscriber will be informed that `my_span` has closed. +//! // dropped, the subscriber will be informed via `drop_span`. //! -//! } // --> Subscriber::close(my_span) +//! } // --> Subscriber::drop_span(my_span) //! # } //! ``` //! -//! A span may be explicitly closed by dropping a handle to it, if it is the only -//! handle to that span. -//! time it is exited. For example: -//! ``` -//! # #[macro_use] extern crate tokio_trace; -//! # use tokio_trace::Level; -//! # fn main() { -//! use tokio_trace::Span; -//! -//! let my_span = span!(Level::TRACE, "my_span"); -//! // Drop the handle to the span. -//! drop(my_span); // --> Subscriber::drop_span(my_span) -//! # } -//! ``` //! However, if multiple handles exist, the span can still be re-entered even if //! one or more is dropped. For determining when _all_ handles to a span have -//! been dropped, `Subscriber`s have a [`clone_span`](::Subscriber::clone_span) -//! method, which is called every time a span handle is cloned. Combined with -//! `drop_span`, this may be used to track the number of handles to a given span -//! — if `drop_span` has been called one more time than the number of calls to -//! `clone_span` for a given ID, then no more handles to the span with that ID -//! exist. The subscriber may then treat it as closed. +//! been dropped, `Subscriber`s have a [`clone_span`] method, which is called +//! every time a span handle is cloned. Combined with `drop_span`, this may be +//! used to track the number of handles to a given span — if `drop_span` has +//! been called one more time than the number of calls to `clone_span` for a +//! given ID, then no more handles to the span with that ID exist. The +//! subscriber may then treat it as closed. //! //! # Accessing a Span's Attributes //! @@ -125,7 +110,12 @@ //! to the [`Subscriber`] when the span is created; it may then choose to cache //! the data for future use, record it in some manner, or discard it completely. //! -//! [`Subscriber`]: ::Subscriber +//! [`clone_span`]: ../subscriber/trait.Subscriber.html#method.clone_span +//! [`drop_span`]: ../subscriber/trait.Subscriber.html#method.drop_span +//! [`exit`]: ../subscriber/trait.Subscriber.html#tymethod.exit +//! [`Subscriber`]: ../subscriber/trait.Subscriber.html +//! [`Attributes`]: struct.Attributes.html +//! [`enter`]: struct.Span.html#method.enter pub use tokio_trace_core::span::{Attributes, Id, Record}; use std::{ @@ -136,6 +126,8 @@ use {dispatcher::Dispatch, field, Metadata}; /// Trait implemented by types which have a span `Id`. pub trait AsId: ::sealed::Sealed { + /// Returns the `Id` of the span that `self` corresponds to, or `None` if + /// this corresponds to a disabled span. fn as_id(&self) -> Option<&Id>; } @@ -188,8 +180,8 @@ struct Entered<'a> { // ===== impl Span ===== impl Span { - /// Constructs a new `Span` with the given [metadata] and set of [field - /// values]. + /// Constructs a new `Span` with the given [metadata] and set of + /// [field values]. /// /// The new span will be constructed by the currently-active [`Subscriber`], /// with the current span as its parent (if one exists). @@ -197,10 +189,10 @@ impl Span { /// After the span is constructed, [field values] and/or [`follows_from`] /// annotations may be added to it. /// - /// [metadata]: ::metadata::Metadata - /// [`Subscriber`]: ::subscriber::Subscriber - /// [field values]: ::field::ValueSet - /// [`follows_from`]: ::span::Span::follows_from + /// [metadata]: ../metadata + /// [`Subscriber`]: ../subscriber/trait.Subscriber.html + /// [field values]: ../field/struct.ValueSet.html + /// [`follows_from`]: ../struct.Span.html#method.follows_from #[inline] pub fn new(meta: &'static Metadata<'static>, values: &field::ValueSet) -> Span { let new_span = Attributes::new(meta, values); @@ -213,9 +205,9 @@ impl Span { /// After the span is constructed, [field values] and/or [`follows_from`] /// annotations may be added to it. /// - /// [metadata]: ::metadata::Metadata - /// [field values]: ::field::ValueSet - /// [`follows_from`]: ::span::Span::follows_from + /// [metadata]: ../metadata + /// [field values]: ../field/struct.ValueSet.html + /// [`follows_from`]: ../struct.Span.html#method.follows_from #[inline] pub fn new_root(meta: &'static Metadata<'static>, values: &field::ValueSet) -> Span { Self::make(meta, Attributes::new_root(meta, values)) @@ -227,9 +219,9 @@ impl Span { /// After the span is constructed, [field values] and/or [`follows_from`] /// annotations may be added to it. /// - /// [metadata]: ::metadata::Metadata - /// [field values]: ::field::ValueSet - /// [`follows_from`]: ::span::Span::follows_from + /// [metadata]: ../metadata + /// [field values]: ../field/struct.ValueSet.html + /// [`follows_from`]: ../struct.Span.html#method.follows_from pub fn child_of( parent: I, meta: &'static Metadata<'static>, @@ -278,8 +270,8 @@ impl Span { result } - /// Returns a [`Field`](::field::Field) for the field with the given `name`, if - /// one exists, + /// Returns a [`Field`](../field/struct.Field.html) for the field with the + /// given `name`, if one exists, pub fn field(&self, field: &Q) -> Option where Q: field::AsField, @@ -288,7 +280,7 @@ impl Span { } /// Returns true if this `Span` has a field for the given - /// [`Field`](::field::Field) or field name. + /// [`Field`](../field/struct.Field.html) or field name. #[inline] pub fn has_field(&self, field: &Q) -> bool where @@ -450,7 +442,7 @@ impl Inner { /// writing custom span handles, but should generally not be called directly /// when entering a span. #[inline] - fn enter<'a>(&'a self) -> Entered<'a> { + fn enter(&self) -> Entered { self.subscriber.enter(&self.id); Entered { inner: self } } diff --git a/tokio-trace/src/subscriber.rs b/tokio-trace/src/subscriber.rs index 07ee29727..cafa6b065 100644 --- a/tokio-trace/src/subscriber.rs +++ b/tokio-trace/src/subscriber.rs @@ -8,9 +8,9 @@ pub use tokio_trace_core::subscriber::*; /// executing, new spans or events are dispatched to the subscriber that /// tagged that span, instead. /// -/// [`Span`]: ::span::Span -/// [`Subscriber`]: ::Subscriber -/// [`Event`]: ::Event +/// [`Span`]: ../span/struct.Span.html +/// [`Subscriber`]: ../subscriber/trait.Subscriber.html +/// [`Event`]: :../event/struct.Event.html pub fn with_default(subscriber: S, f: impl FnOnce() -> T) -> T where S: Subscriber + Send + Sync + 'static,