DEV.co
Open-Source Observability · tokio-rs

tracing

Tracing is a Rust framework for collecting structured, event-based diagnostic information at the application level. It provides instrumentation macros and a subscriber-based architecture that does not require the Tokio runtime, making it suitable for any Rust program.

Source: GitHub — github.com/tokio-rs/tracing
6.8k
GitHub stars
908
Forks
Rust
Primary language
MIT
License (OSI-approved)

Key facts

Objective fields from the source. Values we can't verify are shown as “Unknown” rather than guessed.

FieldValue
Repositorytokio-rs/tracing
Ownertokio-rs
Primary languageRust
LicenseMIT — OSI-approved
Stars6.8k
Forks908
Open issues862
Latest releasetracing-appender-0.2.5 (2026-04-17)
Last updated2026-05-30
Sourcehttps://github.com/tokio-rs/tracing

What tracing is

Tracing provides a façade for structured logging and diagnostics via macros (#[instrument], info!, debug!, etc.) and a pluggable Subscriber trait for collection backends. It supports span-based context tracking, field attachment, and async-aware instrumentation through combinators like Future::instrument.

Quickstart

Get the tracing source

Clone the repository and explore it locally.

terminalbash
git clone https://github.com/tokio-rs/tracing.gitcd tracing# follow the project's README for install & configuration

Need it deployed, integrated, or customized instead? DEV.co ships production installs.

Best use cases

Microservices and distributed tracing

Structured event collection and span correlation enable integration with distributed tracing systems; tracing-subscriber can bridge to OpenTelemetry or similar exporters.

Library instrumentation

Libraries depend only on the tracing crate facade, emitting diagnostic data without forcing a logging implementation on consumers; downstream applications choose the subscriber.

Async Rust applications

Built-in support for async/await contexts via #[instrument] and Future::instrument avoids common span lifetime issues in futures-based code.

Implementation considerations

  • Choose a Subscriber implementation early (tracing-subscriber fmt, or integrate with OpenTelemetry/Jaeger); default global subscriber must be installed at application entry point.
  • Use #[instrument] for function-level spans in async code; manual span::enter() guards require careful lifetime management in futures.
  • Plan field cardinality and naming conventions to avoid high-cardinality keys (e.g., user IDs) that can exhaust storage in downstream collectors.
  • For libraries, depend only on the tracing crate; leave subscriber configuration to the application layer to avoid conflicts.
  • Test span context propagation across thread boundaries; tracing uses thread-local storage by default and does not automatically bridge threads.

When to avoid it — and what to weigh

  • Synchronous-only, simple logging needs — If your application requires only basic line-by-line logging without structured fields or span context, the overhead and conceptual weight of tracing may not justify its use.
  • Minimal Rust expertise in team — Tracing relies on Rust macros and trait-based abstractions; teams unfamiliar with proc macros or advanced Rust patterns may find the learning curve steep.
  • Real-time, ultra-low-latency systems — Structured event capture and span management introduce overhead; validation in latency-critical paths is required before adoption.
  • Static or no subscriber choice needed — If your use case demands a single, compile-time fixed logging backend, tracing's dynamic subscriber selection may add unnecessary flexibility.

License & commercial use

Licensed under MIT, a permissive OSI-approved license. Allows commercial use, modification, and distribution with minimal restrictions (retain license notice).

MIT license permits commercial use without royalties or restrictions. No proprietary lock-in. Verify any downstream dependencies (e.g., tracing-subscriber, exporters) for their own license terms before production deployment.

DEV.co evaluation signals

Editorial assessment — not user reviews. Directional, with an explicit confidence level.

SignalAssessment
MaintenanceActive
DocumentationStrong
License clarityClear
Deployment complexityLow
DEV.co fitStrong
Assessment confidenceHigh
Security considerations

No inherent security vulnerabilities documented in the provided data. Consider: (1) Subscriber implementations must sanitize/redact sensitive fields before output (e.g., passwords, tokens); (2) Span/event cardinality must be bounded to prevent denial-of-service via event floods; (3) Evaluate third-party Subscriber backends (OpenTelemetry, exporters) for their own security posture. Code review of any custom Subscriber traits is recommended.

Alternatives to consider

log crate + env_logger

Simpler, lower-level logging; no structured tracing or span context. Suitable if structured diagnostics are not needed.

slog

Structured logging with composable drains; predates tracing. Less async-aware and less tightly integrated with Tokio ecosystem.

OpenTelemetry SDK directly

Full-featured observability platform; heavier weight and more operational overhead. Tracing integrates with OTel via exporters rather than replacing it.

Software development agency

Build on tracing with DEV.co software developers

Tracing is production-ready for structured diagnostics in Rust services. Review the docs, assess subscriber backend options, and contact our team to design an observability strategy for your architecture.

Talk to DEV.co

Related open-source tools

Surfaced by semantic similarity across the DEV.co open-source index.

Related on DEV.co

Explore the category and the services that help you build with it.

tracing FAQ

Does tracing require Tokio?
No. Tracing is a standalone instrumentation framework. It does not depend on Tokio runtime, though it is well-integrated for async/await code.
Can libraries use tracing without forcing a subscriber on users?
Yes. Libraries depend only on the tracing crate façade and emit events/spans. Applications choose and install a Subscriber; events outside a subscriber context are dropped silently.
How does tracing handle span context in async code?
Use #[instrument] macro or Future::instrument combinator. These ensure spans enter/exit correctly relative to future polling, avoiding the pitfall of manual span guards that hold across await points.
What is the overhead of tracing instrumentation?
Macros expand to event emission; unsampled events have minimal cost (a conditional check and field allocation). Subscriber performance depends on backend choice (fmt is low overhead; exporters may add latency). Measure in your specific workload before production.

Work with a software development agency

DEV.co is a software development agency delivering custom software development services to companies building on open source. Our software developers and web developers design, integrate, and ship production systems — spanning web development, APIs, AI, data, and cloud. If tracing is part of your open-source observability roadmap, our team can implement, customize, migrate, and maintain it.

Evaluate Tracing for Your Rust Stack

Tracing is production-ready for structured diagnostics in Rust services. Review the docs, assess subscriber backend options, and contact our team to design an observability strategy for your architecture.