diff --git a/.github/workflows/typo.yml b/.github/workflows/typo.yml new file mode 100644 index 00000000..0ce405b1 --- /dev/null +++ b/.github/workflows/typo.yml @@ -0,0 +1,35 @@ +name: Typos Check + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }} + cancel-in-progress: true + +env: + RUST_BACKTRACE: 1 + +jobs: + typos-check: + name: typos check + runs-on: ubuntu-latest + timeout-minutes: 10 + env: + FORCE_COLOR: 1 + steps: + - uses: actions/checkout@v4 + with: + clean: "true" + + - uses: baptiste0928/cargo-install@v1 + with: + crate: typos-cli + args: --locked + cache-key: typos-check + + - name: do typos check with typos-cli + run: typos diff --git a/CHANGELOG.md b/CHANGELOG.md index e168f1b7..cee9ac0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,11 @@ ## Unreleased +## v0.6.3 + - Add `LocalSpans::to_span_records()`. - Add `#[trace(properties = { "k1": "v1", "k2": "v2" })]`. +- Add `func_name!()`, `full_name!()`, and `file_location!()` to `minitrace::prelude`. ## v0.6.2 diff --git a/README.md b/README.md index eaef118f..93b380ad 100644 --- a/README.md +++ b/README.md @@ -26,10 +26,76 @@ Features: ## Resources - [Docs] -- [Getting Started] - [Examples] - [FAQ](#faq) +## Getting Started + +## In Libraries + +Libraries should include `minitrace` as a dependency without enabling any extra features. + +```toml +[dependencies] +minitrace = "0.6" +``` + +Add a `trace` attribute to the function you want to trace. In this example, a `SpanRecord` will be collected every time the function is called, if a tracing context is set up by the caller. + +```rust +#[minitrace::trace] +pub fn send_request(req: HttpRequest) -> Result<(), Error> { + // ... +} +``` + +Libraries are able to set up an individual tracing context, regardless of whether the caller has set up a tracing context or not. This can be achieved by using `Span::root()` to start a new trace and `Span::set_local_parent()` to set up a local context for the current thread. + +The `full_name!()` macro can detect the function's full name, which is used as the name of the root span. + +```rust +use minitrace::prelude::*; + +pub fn send_request(req: HttpRequest) -> Result<(), Error> { + let root = Span::root(full_name!(), SpanContext::random()); + let _guard = root.set_local_parent(); + + // ... +} +``` + +## In Applications + +Applications should include `minitrace` as a dependency with the `enable` feature set. To disable `minitrace` statically, simply remove the `enable` feature. + +```toml +[dependencies] +minitrace = { version = "0.6", features = ["enable"] } +``` + +Applications should initialize a `Reporter` implementation early in the program's runtime. Span records generated before the reporter is initialized will be ignored. Before terminating, `flush()` should be called to ensure all collected span records are reported. + +When the root span is dropped, all of its children spans and itself will be reported at once. Since that, it's recommended to create root spans for short tasks, such as handling a request, just like the example below. Otherwise, an endingless trace will never be reported. + +```rust +use minitrace::collector::Config; +use minitrace::collector::ConsoleReporter; +use minitrace::prelude::*; + +fn main() { + minitrace::set_reporter(ConsoleReporter, Config::default()); + + loop { + let root = Span::root("worker-loop", SpanContext::random()); + let _guard = root.set_local_parent(); + + handle_request(); + } + + minitrace::flush(); +} +``` + ## Benchmarks **By different architectures:** @@ -108,7 +174,6 @@ Note that we always prioritize performance over features, so that not all tracin **Code base Tested**: minitrace has been tested with high coverage. However, applications utilizing minitrace have not been widely deployed, so that minitrace is currently **NOT** regarded as battle-tested. [Docs]: https://docs.rs/minitrace/ -[Getting Started]: minitrace/examples/get_started.rs [Examples]: minitrace/examples [OpenTelemetry]: https://opentelemetry.io/ [Jaeger]: https://crates.io/crates/minitrace-jaeger diff --git a/minitrace-datadog/Cargo.toml b/minitrace-datadog/Cargo.toml index 2af1b5ec..da7a1ee7 100644 --- a/minitrace-datadog/Cargo.toml +++ b/minitrace-datadog/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "minitrace-datadog" -version = "0.6.2" +version = "0.6.3" authors = ["The TiKV Project Authors"] license = "Apache-2.0" edition = "2021" @@ -13,7 +13,7 @@ categories = ["development-tools::debugging"] keywords = ["tracing", "span", "datadog", "jaeger", "opentelemetry"] [dependencies] -minitrace = { version = "0.6.2", path = "../minitrace" } +minitrace = { version = "0.6.3", path = "../minitrace" } reqwest = { version = "0.11", features = ["blocking"] } rmp-serde = "1" serde = { version = "1", features = ["derive"] } diff --git a/minitrace-jaeger/Cargo.toml b/minitrace-jaeger/Cargo.toml index 7484946f..9c4839b5 100644 --- a/minitrace-jaeger/Cargo.toml +++ b/minitrace-jaeger/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "minitrace-jaeger" -version = "0.6.2" +version = "0.6.3" authors = ["The TiKV Project Authors"] license = "Apache-2.0" edition = "2021" @@ -14,7 +14,7 @@ keywords = ["tracing", "span", "datadog", "jaeger", "opentelemetry"] [dependencies] log = "0.4" -minitrace = { version = "0.6.2", path = "../minitrace" } +minitrace = { version = "0.6.3", path = "../minitrace" } thrift_codec = "0.2" [dev-dependencies] diff --git a/minitrace-macro/Cargo.toml b/minitrace-macro/Cargo.toml index 28db8c60..d860338c 100644 --- a/minitrace-macro/Cargo.toml +++ b/minitrace-macro/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "minitrace-macro" -version = "0.6.2" +version = "0.6.3" authors = ["The TiKV Project Authors"] license = "Apache-2.0" edition = "2021" @@ -24,7 +24,7 @@ syn = { version = "1.0.84", features = ["full", "parsing", "extra-traits", "proc [dev-dependencies] logcall = "0.1.4" -minitrace = { version = "0.6.2", path = "../minitrace" } +minitrace = { version = "0.6.3", path = "../minitrace" } tokio = { version = "1", features = ["full"] } trybuild = "1" # The procedural macro `trace` only supports async-trait higher than 0.1.52 diff --git a/minitrace-opentelemetry/Cargo.toml b/minitrace-opentelemetry/Cargo.toml index ed134e7b..371f1bac 100644 --- a/minitrace-opentelemetry/Cargo.toml +++ b/minitrace-opentelemetry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "minitrace-opentelemetry" -version = "0.6.2" +version = "0.6.3" authors = ["The TiKV Project Authors"] license = "Apache-2.0" edition = "2021" @@ -15,7 +15,7 @@ keywords = ["tracing", "span", "datadog", "jaeger", "opentelemetry"] [dependencies] futures = { version = "0.3", features = ["executor"] } log = "0.4" -minitrace = { version = "0.6.2", path = "../minitrace" } +minitrace = { version = "0.6.3", path = "../minitrace" } opentelemetry = { version = "0.21", features = ["trace"] } opentelemetry_sdk = { version = "0.21", features = ["trace"] } diff --git a/minitrace/Cargo.toml b/minitrace/Cargo.toml index 308bbff0..a63b99a8 100644 --- a/minitrace/Cargo.toml +++ b/minitrace/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "minitrace" -version = "0.6.2" +version = "0.6.3" authors = ["The TiKV Project Authors"] license = "Apache-2.0" edition = "2021" @@ -17,7 +17,7 @@ enable = [] [dependencies] futures = "0.3" -minitrace-macro = { version = "0.6.2", path = "../minitrace-macro" } +minitrace-macro = { version = "0.6.3", path = "../minitrace-macro" } minstant = "0.1" parking_lot = "0.12" pin-project = "1" @@ -37,9 +37,9 @@ futures-timer = "3" log = "0.4" logcall = "0.1.4" minitrace = { path = ".", features = ["enable"] } -minitrace-datadog = { version = "0.6.2", path = "../minitrace-datadog" } -minitrace-jaeger = { version = "0.6.2", path = "../minitrace-jaeger" } -minitrace-opentelemetry = { version = "0.6.2", path = "../minitrace-opentelemetry" } +minitrace-datadog = { version = "0.6.3", path = "../minitrace-datadog" } +minitrace-jaeger = { version = "0.6.3", path = "../minitrace-jaeger" } +minitrace-opentelemetry = { version = "0.6.3", path = "../minitrace-opentelemetry" } mockall = "0.11" once_cell = "1" opentelemetry = { version = "0.21", features = ["trace"] } diff --git a/minitrace/src/lib.rs b/minitrace/src/lib.rs index 9ba60521..91b148e0 100644 --- a/minitrace/src/lib.rs +++ b/minitrace/src/lib.rs @@ -10,7 +10,7 @@ //! //! # Getting Started //! -//! ## Libraries +//! ## In Libraries //! //! Libraries should include `minitrace` as a dependency without enabling any extra features. //! @@ -19,28 +19,27 @@ //! minitrace = "0.6" //! ``` //! -//! Libraries can attach their spans to the caller's span (if caller has set [local parent](#local-span)) -//! via the API boundary. +//! Add a [`trace`] attribute to the function you want to trace. In this example, a +//! [`SpanRecord`] will be collected every time the function is called, if a tracing context +//! is set up by the caller. //! //! ``` -//! use minitrace::prelude::*; -//! # struct QueryResult; +//! # struct HttpRequest; //! # struct Error; -//! -//! struct Connection { +//! #[minitrace::trace] +//! pub fn send_request(req: HttpRequest) -> Result<(), Error> { //! // ... -//! } -//! -//! impl Connection { -//! #[trace] -//! pub fn query(sql: &str) -> Result { -//! // ... -//! # Ok(QueryResult) -//! } +//! # Ok(()) //! } //! ``` //! -//! Libraries can also create a new trace individually to record their work. +//! Libraries are able to set up an individual tracing context, regardless of whether +//! the caller has set up a tracing context or not. This can be achieved by using +//! [`Span::root()`] to start a new trace and [`Span::set_local_parent()`] to set up a +//! local context for the current thread. +//! +//! The [`full_name!()`] macro can detect the function's full name, which is used as +//! the name of the root span. //! //! ``` //! use minitrace::prelude::*; @@ -48,7 +47,7 @@ //! # struct Error; //! //! pub fn send_request(req: HttpRequest) -> Result<(), Error> { -//! let root = Span::root("send_request", SpanContext::random()); +//! let root = Span::root(full_name!(), SpanContext::random()); //! let _guard = root.set_local_parent(); //! //! // ... @@ -56,31 +55,43 @@ //! } //! ``` //! -//! ## Executables +//! ## In Applications //! -//! Executables should include `minitrace` as a dependency with the `enable` feature -//! set. To disable `minitrace` statically, simply don't set the `enable` feature. +//! Applications should include `minitrace` as a dependency with the `enable` feature +//! set. To disable `minitrace` statically, simply remove the `enable` feature. //! //! ```toml //! [dependencies] //! minitrace = { version = "0.6", features = ["enable"] } //! ``` //! -//! Executables should initialize a reporter implementation early in the program's runtime. -//! Span records generated before the implementation is initialized will be ignored. Before -//! terminating, the reporter should be flushed to ensure all span records are reported. +//! Applications should initialize a [`Reporter`] implementation early in the program's runtime. +//! Span records generated before the reporter is initialized will be ignored. Before +//! terminating, [`flush()`] should be called to ensure all collected span records are reported. +//! +//! When the root span is dropped, all of its children spans and itself will be reported at once. +//! Since that, it's recommended to create root spans for short tasks, such as handling a request, +//! just like the example below. Otherwise, an endingless trace will never be reported. //! //! ``` //! use minitrace::collector::Config; //! use minitrace::collector::ConsoleReporter; +//! use minitrace::prelude::*; //! //! fn main() { //! minitrace::set_reporter(ConsoleReporter, Config::default()); //! -//! // ... +//! loop { +//! let root = Span::root("worker-loop", SpanContext::random()); +//! let _guard = root.set_local_parent(); +//! +//! handle_request(); +//! # break; +//! } //! //! minitrace::flush(); //! } +//! # fn handle_request() {} //! ``` //! //! # Key Concepts @@ -287,7 +298,7 @@ //! such as Jaeger. //! //! Executables should initialize a reporter implementation early in the program's -//! runtime. Span records generated before the implementation is initialized will be ignored. +//! runtime. Span records generated before the reporter is initialized will be ignored. //! //! For an easy start, `minitrace` offers a [`ConsoleReporter`] that prints span //! records to stderr. For more advanced use, crates like `minitrace-jaeger`, `minitrace-datadog`, @@ -313,23 +324,22 @@ //! //! `minitrace` is designed to be fast and lightweight, considering four scenarios: //! -//! - **No Tracing**: `minitrace` is not included as dependency in the executable, while the -//! libraries has been instrumented. In this case, it will be completely removed from libraries, -//! causing zero overhead. +//! - **No Tracing**: If the feature `enable` is not set in the application, `minitrace` will be +//! completely optimized away from the final executable binary, achieving zero overhead. //! -//! - **Sample Tracing**: `minitrace` is enabled in the executable, but only a small portion -//! of the traces are enabled via [`Span::root()`], while the other portion start with placeholders -//! by [`Span::noop()`]. The overhead in this case is very small - merely an integer -//! load, comparison, and jump. +//! - **Sample Tracing**: If `enable` is set in the application, but only a small portion +//! of the traces are enabled via [`Span::root()`], while the other portions are started with +//! placeholders using [`Span::noop()`]. The overhead in this case is very small - merely an +//! integer load, comparison, and jump. //! -//! - **Full Tracing with Tail Sampling**: `minitrace` is enabled in the executable, and all -//! traces are enabled. However, only a select few abnormal tracing records (e.g., P99) are -//! reported. Normal traces can be dismissed by using [`Span::cancel()`] to avoid reporting. -//! This could be useful when you are interested in examining program's tail latency. +//! - **Full Tracing with Tail Sampling**: If `enable` is set in the application, and all +//! traces are enabled, however, only a select few interesting tracing records (e.g., P99) are +//! reported, while normal traces are dismissed by using [`Span::cancel()`] to avoid being +//! reported, the overhead of collecting traces is still very small. This could be useful when +//! you are interested in examining program's tail latency. //! -//! - **Full Tracing**: `minitrace` is enabled in the executable, and all traces are enabled. -//! All tracing records are reported. `minitrace` performs 10x to 100x faster than other tracing -//! libraries in this case. +//! - **Full Tracing**: If `enable` is set in the application, and all traces are reported, +//! `minitrace` performs 10x to 100x faster than other tracing libraries in this case. //! //! //! [`Span`]: crate::Span @@ -386,6 +396,12 @@ pub mod prelude { #[doc(no_inline)] pub use crate::event::Event; #[doc(no_inline)] + pub use crate::file_location; + #[doc(no_inline)] + pub use crate::full_name; + #[doc(no_inline)] + pub use crate::func_name; + #[doc(no_inline)] pub use crate::future::FutureExt as _; #[doc(no_inline)] pub use crate::local::LocalSpan; diff --git a/typos.toml b/typos.toml new file mode 100644 index 00000000..01f876a5 --- /dev/null +++ b/typos.toml @@ -0,0 +1,2 @@ +[files] +extend-exclude = ["*.svg"]