1![Tracing — Structured, application-level diagnostics][splash] 2 3[splash]: https://raw.githubusercontent.com/tokio-rs/tracing/master/assets/splash.svg 4 5# tracing-error 6 7Utilities for enriching error handling with [`tracing`] diagnostic 8information. 9 10[![Crates.io][crates-badge]][crates-url] 11[![Documentation][docs-badge]][docs-url] 12[![Documentation (master)][docs-master-badge]][docs-master-url] 13[![MIT licensed][mit-badge]][mit-url] 14[![Build Status][actions-badge]][actions-url] 15[![Discord chat][discord-badge]][discord-url] 16![maintenance status][maint-badge] 17 18[Documentation (release)][docs-url] | [Documentation (master)][docs-master-url] | [Chat][discord-url] 19 20[crates-badge]: https://img.shields.io/crates/v/tracing-error.svg 21[crates-url]: https://crates.io/crates/tracing-error/0.2.0 22[docs-badge]: https://docs.rs/tracing-error/badge.svg 23[docs-url]: https://docs.rs/tracing-error/0.2.0/tracing_error 24[docs-master-badge]: https://img.shields.io/badge/docs-master-blue 25[docs-master-url]: https://tracing-rs.netlify.com/tracing_error 26[mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg 27[mit-url]: LICENSE 28[actions-badge]: https://github.com/tokio-rs/tracing/workflows/CI/badge.svg 29[actions-url]:https://github.com/tokio-rs/tracing/actions?query=workflow%3ACI 30[discord-badge]: https://img.shields.io/discord/500028886025895936?logo=discord&label=discord&logoColor=white 31[discord-url]: https://discord.gg/EeF3cQw 32[maint-badge]: https://img.shields.io/badge/maintenance-experimental-blue.svg 33 34# Overview 35 36[`tracing`] is a framework for instrumenting Rust programs to collect 37scoped, structured, and async-aware diagnostics. This crate provides 38integrations between [`tracing`] instrumentation and Rust error handling. It 39enables enriching error types with diagnostic information from `tracing` 40[span] contexts, formatting those contexts when errors are displayed, and 41automatically generate `tracing` [events] when errors occur. 42 43The crate provides the following: 44 45* [`SpanTrace`], a captured trace of the current `tracing` [span] context 46 47* [`ErrorLayer`], a [subscriber layer] which enables capturing `SpanTrace`s 48 49**Note**: This crate is currently experimental. 50 51*Compiler support: [requires `rustc` 1.49+][msrv]* 52 53[msrv]: #supported-rust-versions 54 55## Usage 56 57`tracing-error` provides the [`SpanTrace`] type, which captures the current 58`tracing` span context when it is constructed and allows it to be displayed 59at a later time. 60 61For example: 62 63```rust 64use std::{fmt, error::Error}; 65use tracing_error::SpanTrace; 66 67#[derive(Debug)] 68pub struct MyError { 69 context: SpanTrace, 70 // ... 71} 72 73impl fmt::Display for MyError { 74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 75 // ... format other parts of the error ... 76 77 self.context.fmt(f)?; 78 79 // ... format other error context information, cause chain, etc ... 80 # Ok(()) 81 } 82} 83 84impl Error for MyError {} 85 86impl MyError { 87 pub fn new() -> Self { 88 Self { 89 context: SpanTrace::capture(), 90 // ... other error information ... 91 } 92 } 93} 94``` 95 96This crate also provides [`TracedError`], for attaching a [`SpanTrace`] to an 97existing error. The easiest way to wrap errors in `TracedError` is to either 98use the [`InstrumentResult`] and [`InstrumentError`] traits or the `From`/`Into` 99traits. 100 101```rust 102use tracing_error::prelude::*; 103 104std::fs::read_to_string("myfile.txt").in_current_span()?; 105``` 106 107Once an error has been wrapped with with a [`TracedError`], the [`SpanTrace`] 108can be extracted one of three ways: either via [`TracedError`]'s 109`Display`/`Debug` implementations, or via the [`ExtractSpanTrace`] trait. 110 111For example, here is how one might print the errors but specialize the 112printing when the error is a placeholder for a wrapping [`SpanTrace`]: 113 114```rust 115use std::error::Error; 116use tracing_error::ExtractSpanTrace as _; 117 118fn print_extracted_spantraces(error: &(dyn Error + 'static)) { 119 let mut error = Some(error); 120 let mut ind = 0; 121 122 eprintln!("Error:"); 123 124 while let Some(err) = error { 125 if let Some(spantrace) = err.span_trace() { 126 eprintln!("found a spantrace:\n{}", spantrace); 127 } else { 128 eprintln!("{:>4}: {}", ind, err); 129 } 130 131 error = err.source(); 132 ind += 1; 133 } 134} 135 136``` 137 138Whereas here, we can still display the content of the `SpanTraces` without 139any special casing by simply printing all errors in our error chain. 140 141```rust 142use std::error::Error; 143 144fn print_naive_spantraces(error: &(dyn Error + 'static)) { 145 let mut error = Some(error); 146 let mut ind = 0; 147 148 eprintln!("Error:"); 149 150 while let Some(err) = error { 151 eprintln!("{:>4}: {}", ind, err); 152 error = err.source(); 153 ind += 1; 154 } 155} 156``` 157 158Applications that wish to use `tracing-error`-enabled errors should 159construct an [`ErrorLayer`] and add it to their [`Subscriber`] in order to 160enable capturing [`SpanTrace`]s. For example: 161 162```rust 163use tracing_error::ErrorLayer; 164use tracing_subscriber::prelude::*; 165 166fn main() { 167 let subscriber = tracing_subscriber::Registry::default() 168 // any number of other subscriber layers may be added before or 169 // after the `ErrorLayer`... 170 .with(ErrorLayer::default()); 171 172 // set the subscriber as the default for the application 173 tracing::subscriber::set_global_default(subscriber); 174} 175``` 176 177## Feature Flags 178 179- `traced-error` - Enables the [`TracedError`] type and related traits 180 - [`InstrumentResult`] and [`InstrumentError`] extension traits, which 181 provide an [`in_current_span()`] method for bundling errors with a 182 [`SpanTrace`]. 183 - [`ExtractSpanTrace`] extension trait, for extracting `SpanTrace`s from 184 behind `dyn Error` trait objects. 185 186## Supported Rust Versions 187 188Tracing is built against the latest stable release. The minimum supported 189version is 1.49. The current Tracing version is not guaranteed to build on Rust 190versions earlier than the minimum supported version. 191 192Tracing follows the same compiler support policies as the rest of the Tokio 193project. The current stable Rust compiler and the three most recent minor 194versions before it will always be supported. For example, if the current stable 195compiler version is 1.45, the minimum supported version will not be increased 196past 1.42, three minor versions prior. Increasing the minimum supported compiler 197version is not considered a semver breaking change as long as doing so complies 198with this policy. 199 200## Related Crates 201 202In addition to this repository, here are also several third-party crates which 203are not maintained by the `tokio` project. These include: 204 205- [`color-spantrace`] provides a formatter for rendering SpanTrace in the style 206 of `color-backtrace` 207- [`color-eyre`] provides a customized version of `eyre::Report` for capturing 208 span traces and backtraces with new errors and pretty printing them in error 209 reports. 210 211[`color-spantrace`]: https://github.com/yaahc/color-spantrace 212[`color-eyre`]: https://github.com/yaahc/color-eyre 213 214## License 215 216This project is licensed under the [MIT license](LICENSE). 217 218### Contribution 219 220Unless you explicitly state otherwise, any contribution intentionally submitted 221for inclusion in Tracing by you, shall be licensed as MIT, without any additional 222terms or conditions. 223 224[`SpanTrace`]: https://docs.rs/tracing-error/*/tracing_error/struct.SpanTrace.html 225[`ErrorLayer`]: https://docs.rs/tracing-error/*/tracing_error/struct.ErrorLayer.html 226[`TracedError`]: https://docs.rs/tracing-error/*/tracing_error/struct.TracedError.html 227[`InstrumentResult`]: https://docs.rs/tracing-error/*/tracing_error/trait.InstrumentResult.html 228[`InstrumentError`]: https://docs.rs/tracing-error/*/tracing_error/trait.InstrumentError.html 229[`ExtractSpanTrace`]: https://docs.rs/tracing-error/*/tracing_error/trait.ExtractSpanTrace.html 230[`in_current_span()`]: https://docs.rs/tracing-error/*/tracing_error/trait.InstrumentResult.html#tymethod.in_current_span 231[span]: https://docs.rs/tracing/latest/tracing/span/index.html 232[events]: https://docs.rs/tracing/latest/tracing/struct.Event.html 233[`Subscriber`]: https://docs.rs/tracing/latest/tracing/trait.Subscriber.html 234[subscriber layer]: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/layer/trait.Layer.html 235[`tracing`]: https://docs.rs/tracing 236[`std::error::Error`]: https://doc.rust-lang.org/stable/std/error/trait.Error.html 237[`SpanTrace`]: https://docs.rs/tracing-error/0.2.0/tracing_error/struct.SpanTrace.html 238[`ErrorLayer`]: https://docs.rs/tracing-error/0.2.0/tracing_error/struct.ErrorLayer.html 239