tracing

repository·main·Indexed 27 days ago

https://github.com/tokio-rs/tracing

A runtime-agnostic framework for instrumenting Rust programs to collect structured, event-based diagnostic information. Maintained by the Tokio project, the ecosystem includes the primary instrumentation API (tracing), core primitives (tracing-core), subscriber implementations (tracing-subscriber), and utilities for file output (tracing-appender), error instrumentation (tracing-error), and automatic function instrumentation (tracing-attributes).

Tokens
32.7K
Snippets
85
Records
194
Agent score
89%

What's inside tracing

  1. Overview of tracing-subscriber

    main
    tracing-subscriber provides utilities for implementing and composing Subscriber implementations for the tracing framework. While tracing provides the instrumentation API to collect scoped, structured, and async-aware diagnostics, tracing-subscriber contains the tools to actually process that data. It is suitable for both authors creating new Subscriber types and application developers who want to use 'batteries-included' implementations to handle their application's diagnostic data.
  2. Use tracing-log for log crate compatibility

    main

    The tracing-log crate provides compatibility between the tracing framework and the log facade. It allows you to bridge diagnostic information between the two ecosystems using the following components:

    • LogTracer: A log::Log implementation that consumes log::Records and outputs them as tracing::Events. This is useful for capturing logs from libraries that use the log crate and routing them into your tracing subscriber.
    • AsTrace and AsLog traits: Traits used for converting between tracing and log types.
  3. Instrument asynchronous code with tracing-futures

    main

    The tracing-futures crate provides utilities to instrument asynchronous code (futures, sinks, streams, or executors) using the tracing framework. It primarily provides two traits:

    • Instrument: Allows a tracing [span] to be attached to a future, sink, stream, or executor.
    • WithSubscriber: Allows a tracing [Subscriber] to be attached to a future, sink, stream, or executor.
  4. Understand the role of tracing-core

    main

    The tracing-core crate provides the fundamental primitives for the tracing framework. It is primarily used by developers implementing Subscriber traits to collect trace data.

    Note for Application Authors: Most application and library authors should use the [tracing] crate instead of tracing-core, as tracing provides a more feature-complete API for instrumentation. Use tracing-core directly only if you require extremely stable dependencies or are building a Subscriber implementation.

  5. Understand the Tracing project structure

    main

    The tracing ecosystem is composed of several crates with different roles:

    • tracing: The primary instrumentation API used by libraries and applications to emit trace data.
    • tracing-core: The core API primitives. Authors of trace subscribers should depend on this crate for higher stability.
    • tracing-subscriber: Provides implementations for Subscriber and utilities for composing them.
    • tracing-appender: Utilities for outputting data, such as file appenders and non-blocking writers.
    • tracing-error: Provides SpanTrace for instrumenting errors with tracing spans.
    • tracing-attributes: Procedural macro attributes for automatic function instrumentation.
    • tracing-futures: Utilities for instrumenting futures.

    Note that some crates (like tracing-macros, tracing-log, tracing-serde, tracing-tower) are experimental or unstable.

  6. Use tracing-journald to log to systemd-journald

    main
    The tracing-journald crate provides a tracing_subscriber::Layer implementation that allows you to log tracing spans and events natively to systemd-journald. This is intended for use on Linux distributions that use systemd to preserve structured diagnostic information.
  7. Use MockSubscriber to assert on tracing diagnostics

    main

    The tracing-mock crate provides a mock Subscriber that allows you to assert on the order and contents of spans and events emitted by your code.

    Key components:

    • subscriber::mock(): Starts the builder for a mock subscriber.
    • expect::span() and expect::event(): Used to define expected trace elements.
    • .only(): Ensures that no other traces (spans or events) are received beyond what is explicitly defined.
    • .run_with_handle(): Returns a tuple of (subscriber, handle). The handle is used to verify that all expected traces were completed.
    use tracing::subscriber::with_default;
    use tracing_mock::{expect, subscriber};
    
    fn yak_shaving() {
        tracing::info!("preparing to shave yaks");
    }
    
    let (subscriber, handle) = subscriber::mock()
        .event(expect::event().with_fields(expect::msg("preparing to shave yaks")))
        .only()
        .run_with_handle();
    
    with_default(subscriber, || {
        yak_shaving();
    });
    
    handle.assert_finished();
  8. Set up a global subscriber in an application

    main

    Use tracing_subscriber::fmt::init() to install a global subscriber. This subscriber will be used by all threads for the remainder of the program's duration, similar to how the log crate works. The default configuration is based on the RUST_LOG environment variable.

    use tracing::info;
    use tracing_subscriber;
    
    fn main() {
        // install global subscriber configured based on RUST_LOG envvar.
        tracing_subscriber::fmt::init();
    
        let number_of_yaks = 3;
        // this creates a new event, outside of any spans.
        info!(number_of_yaks, "preparing to shave yaks");
    
        let number_shaved = yak_shave::shave_all(number_of_yaks);
        info!(
            all_yaks_shaved = number_shaved == number_of_yaks,
            "yak shaving completed."
        );
    }
  9. Install tracing-mock

    main

    Add tracing-mock to your Cargo.toml. Because tracing-mock is currently in beta, it is recommended to specify an exact version to avoid breaking changes during cargo update.

    Minimum supported Rust version: 1.65.

    [dependencies]
    tracing-mock = "= 0.1.0-beta.3"
  10. Check supported Rust versions for tracing-subscriber

    main

    The minimum supported Rust version (MSRV) for tracing-subscriber is 1.65.

    Tracing follows the Tokio project's compiler support policy: the current stable Rust compiler and the three most recent minor versions before it are always supported. Increasing the minimum supported compiler version within this policy is not considered a semver breaking change.