Skip to content
Ergonomic Rust bindings for instrumenting Rust apps with high performance probes using SystemTap, DTrace, etc
Rust C++ Other
Branch: master
Clone or download
Latest commit ae677b0 Nov 22, 2019
Type Name Latest commit message Commit time
Failed to load latest commit information.
bin Add language and scripts to help automate the tedious release process Nov 20, 2019
examples/simple Released version 0.1.0, starting version 0.2.0 Nov 20, 2019
scripts Change azure pipeline scripts to build all crates again Apr 23, 2019
tracers-build Released version 0.1.0, starting version 0.2.0 Nov 20, 2019
tracers-codegen Fix many additional clippy lints Nov 20, 2019
tracers-core Fix many additional clippy lints Nov 20, 2019
tracers-dyn-noop Released version 0.1.0, starting version 0.2.0 Nov 20, 2019
tracers-dyn-stap Released version 0.1.0, starting version 0.2.0 Nov 20, 2019
tracers-libelf-sys Released version 0.1.0, starting version 0.2.0 Nov 20, 2019
tracers-libstapsdt-sys Released version 0.1.0, starting version 0.2.0 Nov 20, 2019
tracers-macros-hack Released version 0.1.0, starting version 0.2.0 Nov 20, 2019
tracers-macros Released version 0.1.0, starting version 0.2.0 Nov 20, 2019
tracers Disable some clippy lints in tests Nov 21, 2019
.cirrus.yml Add Cirrus-CI build config for FreeBSD May 12, 2019
.gitignore Initial commit with working build of the native lib from source Feb 6, 2019
.gitmodules Rename `libelf-sys` to `tracers-libelf-sys` and `libstapsdt-sys` to `… Nov 20, 2019
.tmuxp.yaml Update `.tmuxp.yaml` to reflect new project name May 7, 2019
Cargo.toml Update Cargo manifests and README to reflect renaming of `-sys` crates Nov 20, 2019
LICENSE Add license details to README and sub-projects Apr 5, 2019
LICENSE-APACHE Add license details to README and sub-projects Apr 5, 2019
LICENSE-MIT Add license details to README and sub-projects Apr 5, 2019 Add notes about platform support Nov 20, 2019
azure-pipelines.yml Fix clippy command line Nov 21, 2019

tracers - Rust instrumentation library Azure Build Status - Linux/macOS/Windows Cirrus CI - FreeBSD


tracers is intended to be an easy to use and cross-platform Rust crate which makes it easy to add high-performance low-overhead probes to Rust programs. Underneath it will use each platform's native probing mechanism, like System Tap on Linux, DTrace on BSD, and ETW on Windows. Those platforms without a supported probing mechanism will fall back to a no-op implementation.

A key goal of this crate is to be able to drop it in to any Rust project, create and fire probes wherever it makes sense, and leave those probes in place all the time. When probes are disabled at compile time, there should be zero runtime impact, and when probes are compiled in but not enabled at runtime the probe impact should be no more than one or two CPU instructions.


IMPORTANT: tracers is still experimental. The author is using it internally but this crate is still not yet widely used and may contain subtle and critical defects.

Quick start

In your Cargo.toml you need to add:

tracers = "0.1.0"
tracers-macros = "0.1.0"

tracers-build = "0.1.0"

It's important not to forget to add tracers-build to your build-dependencies, because you'll need that available at build time for the next step, which is to create a src/ file if you don't have one already, and make sure it contains this:

use tracers_build::build;

fn main() {

If you have an existing you'll need to make sure you add a call to tracers_build::build() somewhere in the main function, preferably early.

At this point you have all you need to define a tracer. Here's a simple example:

use tracers_macros::{probe, tracer};

trait SimpleProbes {
fn hello(who: &str);
fn greeting(greeting: &str, name: &str);
fn optional_greeting(greeting: &str, name: &Option<&str>);

fn main() {
loop {
    probe!(SimpleProbes::greeting("hello", "world"));
    let name = Some("world");
    probe!(SimpleProbes::optional_greeting("hello", &name));
    let name: Option<&str> = None;
    probe!(SimpleProbes::optional_greeting("hello", &name));

You have have defined three probes, hello, greeting, and optional_greeting. By default, tracing is disabled at compile time, so when you run this code all of the probing infrastructure will be optimized away and you'll be left with zero runtime overhead.

To actually enable probing you need to activate one of the corresponding features in the tracers crate. For example, in your Cargo.toml:

tracers = { version = "0.1.0", features = [ "force_static_stap"]

will enable SystemTap tracing. If you rebuild again and use a tool like tplist from BCC you should be able to see the probes in the binary.

Note also that the #[tracers] macro generates some useful documentation on your trait. Try cargo doc and find your trait in the docs for additional hints on how to use each probe.

The examples/ directory has some simple examples.


The tracers crate and runtime components should compile and run on any supported Rust platform (although no_std is not yet supported). Adding tracers as a dependency shouldn't break your project on any platform; if it does that's a bug and you're encouraged to open a GitHub issue.

That said, the tracers crate by default doesn't actually trace anything; it compiles away to nothing. To actually enable tracing you need a supported platform. As of this writing that means:

  • Linux with System Tap (the force_static_stap feature)
  • Linux with LTT-ng (the force_static_lttng) feature

There is work being done to support:

  • Windows (with the Event Tracing for Windows system API)
  • FreeBSD and macOS (with DTrace)


Except where otherwise indicated, this project is licensed under either of

at your option.

However, the following -sys crates have the license corresponding to the third-party code which they wrap:


Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in tracers by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.


This section applies to maintainers only.

To release a new version, dependent crates must be released first. The bin/ script helps to automate the process but it's still quite manual.

Release process:

  1. Update the version property of all crates and of all crates' dependencies on other tracers crates to the new target version.

  2. Ensure all dependencies have both a path dependency for local development, and a version dependency for publishing. These must be consistent with the new version being published.

  3. Update the documentation link to reflect the current version.

Crates must be published in this order:

  • tracers-core
  • tracers-libelf-sys
  • tracers-libstapsdt-sys
  • tracers-codegen
  • tracers-macros-hack
  • tracers-macros
  • tracers-dyn-stap
  • tracers-dyn-noop
  • tracers-build
  • tracers
You can’t perform that action at this time.