{"id":19331984,"url":"https://github.com/tikv/tracing-active-tree","last_synced_at":"2025-07-14T04:06:45.428Z","repository":{"id":205560412,"uuid":"713772862","full_name":"tikv/tracing-active-tree","owner":"tikv","description":null,"archived":false,"fork":false,"pushed_at":"2023-11-26T09:35:01.000Z","size":34,"stargazers_count":4,"open_issues_count":0,"forks_count":3,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-02T05:11:45.491Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tikv.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-11-03T07:55:03.000Z","updated_at":"2024-11-23T14:01:45.000Z","dependencies_parsed_at":null,"dependency_job_id":"b1f02e6c-59be-46f0-834c-43dcab138317","html_url":"https://github.com/tikv/tracing-active-tree","commit_stats":null,"previous_names":["tikv/tracing-active-tree"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tikv%2Ftracing-active-tree","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tikv%2Ftracing-active-tree/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tikv%2Ftracing-active-tree/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tikv%2Ftracing-active-tree/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tikv","download_url":"https://codeload.github.com/tikv/tracing-active-tree/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250340484,"owners_count":21414558,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-10T02:43:21.656Z","updated_at":"2025-04-22T23:32:38.348Z","avatar_url":"https://github.com/tikv.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# tracing-active-tree\n\n`tracing-active-tree` is a Rust library that allows developers to retrieve the current calling stack at runtime on demand. The calling stack is organized as [span](https://docs.rs/tracing/latest/tracing/span/index.html) trees, and can be used for both synchronous and asynchronous contexts.\n\nOne common use case for this library is to print or log the calling trees on error for troubleshooting purposes. Unlike capturing stack backtraces using [`std::backtrace::Backtrace`](https://doc.rust-lang.org/std/backtrace/struct.Backtrace.html), `tracing-active-tree` offers several advantages:\n\n- It supports asynchronous functions.\n- It records trees with additional context [attributes](https://docs.rs/tracing/latest/tracing/#configuring-attributes).\n\nHowever, `tracing-active-tree` has a few disadvantages as well:\n\n- [Spans](https://docs.rs/tracing/latest/tracing/span/index.html) need to be declared beforehand.\n- It requires more CPU and memory resources.\n\nTwo similar libraries, [`async-backtrace`](https://github.com/tokio-rs/async-backtrace) and [`await-tree`](https://github.com/risingwavelabs/await-tree/), are also available. `tracing-active-tree` takes inspiration from their implementation. However, both `async-backtrace` and `await-tree` require declaring spans using methods and structs provided by the library, which may be inconvenient for existing codebases. In contrast, `tracing-active-tree` does not require any changes to the existing code. It only requires registering an extra [Layer](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/layer/trait.Layer.html) to the tracing subscribers [registry](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/registry/index.html).\n\n## Installation\n\nAdd the following line to your `Cargo.toml` file:\n\n```toml\ntracing-active-tree = { git = \"https://github.com/tikv/tracing-active-tree.git\", branch = \"master\" }\n```\n\n## Usage\n\n*Run the following example using `cargo run --example simple`.*\n\n1. Import the library:\n\n    ```rust\n    use tracing_active_tree::layer::{self, CurrentStacksLayer};\n    ```\n\n1. Create spans that you wish to display in the calling trees:\n\n    ```rust\n    #[instrument(fields(answer = 43))]\n    async fn foo() {\n        bar().await;\n    }\n\n    #[instrument]\n    async fn bar() {\n        futures::join!(fiz(), buz());\n    }\n\n    #[instrument(skip_all)]\n    async fn fiz() {\n        tokio::task::yield_now().await;\n    }\n\n    #[instrument(skip_all)]\n    async fn buz() {\n        baz().await;\n    }\n\n    #[instrument(skip_all)]\n    async fn baz() {\n    }\n    ```\n\n1. Register the `CurrentStacksLayer` to the tracing subscriber:\n\n    ```rust\n        tracing_subscriber::registry()\n            .with(layer::global().clone())\n            .init();\n    ```\n\n1. Dump the tree:\n\n    ```rust\n    #[instrument(skip_all)]\n    async fn baz() {\n        println!(\"{}\", debug_dump_current_tree());\n    }\n\n    fn debug_dump_current_tree() -\u003e String {\n        layer::global().fmt_string()\n    }\n    ```\n\n1. The following tree will be printed to the stdout:\n\n    ```sh\n    1\n    └[examples/simple.rs:5] [span_id=1] [\"foo\"] [answer=43] [elapsed=114.659µs]\n     └[examples/simple.rs:10] [span_id=2] [\"bar\"] [elapsed=92.5µs]\n      ├[examples/simple.rs:15] [span_id=3] [\"fiz\"] [elapsed=79.072µs]\n      └[examples/simple.rs:20] [span_id=4] [\"buz\"] [elapsed=65.938µs]\n       └[examples/simple.rs:25] [span_id=5] [\"baz\"] [elapsed=59.61µs]\n    ```\n\n## Benchmark\n\nThere are overheads when tracing. When tracing huge task trees, the overhead may be obvious. Run benches in the `benches` folder to check it.\n\nYou may also enable the feature `coarsetime` for a better performance of fetching system time.\n\nHere are some examples of the overheads. Generally, huge (both wide or deep) trees will bring performance penalty:\n\n```console\n\u003e cargo bench --features=\"coarsetime\" --bench deep_tree\ndeep_baseline           time:   [194.64 µs 208.66 µs 223.05 µs]\ndeep_with_subs          time:   [4.7118 ms 4.8690 ms 5.0579 ms]\n```\n\nTracing wide(a root future waits for many futures) trees have poorer performance than tracing deep(a tree like a linked list) trees:\n\n```console\n\u003e cargo bench --features=\"coarsetime\" --bench wide_tree\nwide_baseline           time:   [895.63 µs 924.51 µs 953.05 µs]\nwide_with_subs          time:   [16.192 ms 17.383 ms 18.629 ms]\n```\n\n\u003e **NOTE**\n\u003e \n\u003e When you tweaking the parameters of those benchmarks, you may notice that the performance regression isn't linear with the amount of tree nodes. This implies that it is possible to optimize this. They should be linear.\n\nBut there isn't observable overheads when spawning many tiny tasks: \n\n```console\n\u003e cargo bench --features=\"coarsetime\" --bench many_tasks\nmany_tasks_baseline     time:   [4.3762 ms 4.4394 ms 4.5032 ms]\nmany_tasks_with_subs    time:   [4.1975 ms 4.2936 ms 4.3886 ms]\n```\n\n## Contributing\n\nIf you're interested in contributing to `tracing-active-tree`, or want to build it from source, see [CONTRIBUTING.md](./CONTRIBUTING.md).\n\n## License\n\n`tracing-active-tree` is licensed under the Apache 2.0 license. See the [LICENSE](./LICENSE) file for more details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftikv%2Ftracing-active-tree","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftikv%2Ftracing-active-tree","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftikv%2Ftracing-active-tree/lists"}