Tracing layer to quickly inspect spans and events

Overview

tracing-texray Latest Version

First, a word of warning: This is alpha software. Don't run this in prod or anywhere where a panic would ruin your day.

tracing-texray is a tracing layer to introspect spans and events in plain text. By examine-ing a specific span, a full tree will be output when that span exits. Using code like the following (actual program elided):

fn main() {
    // initialize & install as the global subscriber
    tracing_texray::init();
    // examine the `load_data` span:
    tracing_texray::examine(tracing::info_span!("load_data")).in_scope(|| {
        do_a_thing()
    });
}

fn do_a_thing() {
    // ...
}

You would see the following output printed to stderr:

load_data                                52ms ├────────────────────────────────┤
  download_results{uri: www.crates.io}   11ms                ├─────┤
   >URI resolved                                             ┼
   >connected                                                   ┼
  compute_stats                          10ms                        ├─────┤
  render_response                         6ms                               ├──┤

In cases where a more powerful solution like tracing-chrome is not required, tracing-texray can render lightweight timeline of what happened when.

Usage

tracing-texray combines two pieces: a global subscriber, and local span examination. By default, tracing-texray won't print anything—it just sits in the background. But: once a span is examine'd, tracing-texray will track the span and all of its children. When the span exits, span diagnostics will be printed to stderr (or another impl io::Write as configured).

First, the layer must be installed globally:

use std::time::Duration;
use tracing_texray::TeXRayLayer;
use tracing_subscriber::{Registry, EnvFilter, layer::SubscriberExt};
fn main() {
    // Option A: Exclusively using tracing_texray:
    tracing_texray::init();
    
    // Option B: install the layer in combination with other layers, eg. tracing_subscriber::fmt:
    let subscriber = Registry::default()
        .with(EnvFilter::try_from_default_env().expect("invalid env filter"))
        .with(tracing_subscriber::fmt::layer())
        .with(
            TeXRayLayer::new()
                // by default, all metadata fields will be printed. If this is too noisy,
                // fitler only the fields you care about
                .only_show_fields(&["name", "operation", "service"])
                // only print spans longer than a certain duration
                .min_duration(Duration::from_millis(100)),
        );
    tracing::subscriber::set_global_default(subscriber).unwrap();
}

Next, wrap any spans you want to track with examine:

use tracing::info_span;
use tracing_texray::examine;

fn somewhere_deep_in_my_program() {
    tracing_texray::examine(info_span!("do_a_thing")).in_scope(|| {
        for id in 0..5 {
            some_other_function(id);
        }
    })
}

fn some_other_function(id: usize) {
    info_span!("inner_task", id = %id).in_scope(|| tracing::info!("buzz"));
    // ...
}

When the do_a_thing span exits, output like the following will be printed:

do_a_thing           509μs ├───────────────────────────────────────────────────┤
  inner_task{id: 0}   92μs         ├────────┤
   >buzz                             ┼
  inner_task{id: 1}   36μs                       ├──┤
   >buzz                                         ┼
  inner_task{id: 2}   35μs                               ├──┤
   >buzz                                                 ┼
  inner_task{id: 3}   36μs                                         ├──┤
   >buzz                                                           ┼
  inner_task{id: 4}   35μs                                                 ├──┤
   >buzz                                                                   ┼
You might also like...
A tracing profiler for the Sega MegaDrive/Genesis
A tracing profiler for the Sega MegaDrive/Genesis

md-profiler, a tracing profiler for the Sega MegaDrive/Genesis This program, meant to be used with this fork of BlastEm, helps you finding bottlenecks

A patch to fix tracing LocalTime problem.

tracing-local-time A patch to fix tracing LocalTime problem. Tracing-subscriber now has a bug in LocalTime, so build ourselves' to fix it. In this pat

A dynamic binary tracing tool

Backlight Backlight is a dynamic binary tracing tool. Install $ git clone [email protected]:JoshMcguigan/backlight.git $ cd backlight $ cargo install-b

tracing - a framework for instrumenting Rust programs to collect structured, event-based diagnostic information

tracing-appender Writers for logging events and spans Documentation | Chat Overview tracing is a framework for instrumenting Rust programs to collect

A rust `tracing` compatible framework inspired by log4rs.

trace4rs This crate allows users to configure output from tracing in the same way as you would configure the output of log4rs. Overview For a usage ex

Utilities for integrating Datadog with opentelemetry + tracing in rust

Non-official datadog tracing and log correlation for Rust services. This crate contains the necessary glue to bridge the gap between OpenTelemetry, tr

Hardware Abstraction Layer for AVR microcontrollers and common boards

avr-hal Hardware Abstraction Layer for AVR microcontrollers and common boards (for example Arduino). Based on the avr-device crate. This is a new vers

The classic game Pong, written in lambda calculus, and a thin layer of Rust.

What? The good old game Pong, written in lambda calculus, and a thin layer of Rust. Why? I was bored. No, seriously, why? Everyone keeps saying that l

Rust Hardware Abstraction Layer (HAL) crate for the Vorago VA108xx family of MCUs

HAL for the Vorago VA108xx MCU family This repository contains the Hardware Abstraction Layer (HAL), which is an additional hardware abstraction on to

Comments
  • Deadlock?

    Deadlock?

    To play around with this crate, I tried my hand at using it in mini-redis: https://github.com/jswrenn/mini-redis/commit/a2ae42cea84819f24c1df05ef91ee483d5fed4bf. I launched my patched mini-redis with:

    RUST_BACKTRACE=1 RUSTFLAGS="--cfg tokio_unstable" RUST_LOG=trace cargo run --bin mini-redis-server
    

    ...and, in another terminal, ran:

    $ redis-benchmark -t set -n 1
    

    Unfortunately, mini-redis then seems to deadlock before the benchmark can complete:

    $ RUST_BACKTRACE=1 RUSTFLAGS="--cfg tokio_unstable" RUST_LOG=trace cargo run --bin mini-redis-server
        Finished dev [unoptimized + debuginfo] target(s) in 0.03s
         Running `target/debug/mini-redis-server`
    mini-redis-server::Handler::run                                                                                            18ms ├────────────────────────────┤
      run                                                                                                                      14ms ├──────────────────────┤
        read_frame                                                                                                            172μs ┆
        from_frame{frame: Array([Bulk(b"CONFIG"), Bulk(b"GET"), Bulk(b"save")])}                                               66μs  ┆
        apply{self: Unknown(Unknown { command_name: "config" }), db: Db { shared: Shared { state: Mutex { data: State { entr  432μs  │
          apply                                                                                                               254μs   ┆
        read_frame                                                                                                             95μs   ┆
        from_frame{frame: Array([Bulk(b"CONFIG"), Bulk(b"GET"), Bulk(b"appendonly")])}                                         55μs    ┆
        apply{self: Unknown(Unknown { command_name: "config" }), db: Db { shared: Shared { state: Mutex { data: State { entr 1015μs    ├┤
          apply                                                                                                               640μs    │
        read_frame                                                                                                            232μs               ┆
    

    (At this point, I have to kill the mini-redis-server process in another terminal.)

    Any thoughts about what might be going on here?

    opened by jswrenn 2
Owner
Russell Cohen
Software engineer based in Boston. Currently @aws, formerly @mit and @SumoLogic.
Russell Cohen
Emit ETW events in tracing-enabled Rust applications.

tracing-etw Emit ETW events in tracing-enabled Rust applications. This crate depends on rust_win_etw. There are four ETW events. fn NewSpan(span_id: u

Microsoft 11 Aug 10, 2022
tracing-glog is a glog-inspired formatter for tracing-subscriber.

tracing-glog tracing-glog is a glog-inspired formatter for tracing-subscriber. tracing-glog should be used with tracing-subscriber, as it is a formatt

David Barsky 7 Oct 8, 2022
A tracing layer for macOS/iOS's `oslog`

tracing_oslog This is a tracing layer for the Apple OS logging framework. Activities are used to handle spans, Example use tracing_oslog::OsLogger; l

Lucy 12 Dec 6, 2022
AWS Cloudwatch layer for tracing-subscriber

tracing-cloudwatch tracing-cloudwatch is a custom tracing-subscriber layer that sends your application's tracing events(logs) to AWS CloudWatch Logs.

ymgyt 7 May 14, 2023
A convenient tracing config and init lib, with symlinking and local timezone.

clia-tracing-config A convenient tracing config and init lib, with symlinking and local timezone. Use these formats default, and can be configured: pr

Cris Liao 5 Jan 3, 2023
This crate bridges between gstreamer and tracing ecosystems.

This crate provides a bridge between gstreamer and the tracing ecosystem. The goal is to allow Rust applications utilizing GStreamer to better integra

Standard Cognition OSS 17 Jun 7, 2022
An example of a fairing for rocket to use tracing (as this pops up at many places in dicussions and questions)

Rocket Tracing Fairing Example This repository aims to give a short example of how you can add a Fairing to your Rocket for tracing and how to use it

Christof Weickhardt 9 Nov 23, 2022
Middlewares and tools to integrate axum + tracing + opentelemetry

axum-tracing-opentelemetry Middlewares and tools to integrate axum + tracing + opentelemetry. Read OpenTelemetry header from incoming request Start a

David Bernard 31 Jan 4, 2023
High-performance QEMU memory and instruction tracing

Cannoli Cannoli is a high-performance tracing engine for qemu-user. It can record a trace of both PCs executed, as well as memory operations. It consi

Margin Research 412 Oct 18, 2023
Error propagation tracing in Rust.

Propagate Error propagation tracing in Rust. Why Propagate? Being able to trace the cause of an error is critical for many types of software written i

Ben Reeves 10 Sep 23, 2021