#trace-points #generate #bindings #generation #tracing #lttng-ust #semi-automatically

lttng-ust-generate

Semi-automatically generate lttng-ust tracepoints (generation code)

2 releases

Uses old Rust 2015

0.1.1 Feb 13, 2018
0.1.0 Feb 12, 2018

#6 in #trace-points


Used in 2 crates

MIT license

35KB
636 lines

lttng-ust-generate

Compile-time support for lttng-ust in Rust. See the root module docs for more details.


lib.rs:

Rust bindings to LTTNG-UST

This library provides a way for Rust code to define LTTNG tracepoints. If your current platform doesn't support LTTNG, (i.e. you're not on a Linux system) this crate probably isn't too useful to you. However, if you are on Linux and you have a need for high-performance tracing with a rich tooling ecosystem, this is the crate for you!

Getting started

To get started, you'll need to add lttng-ust-generate to the [build-dependencies] section of your Cargo.toml. Then, in your build.rs, add the following code:

use std::env;
use std::path::PathBuf;

use lttng_ust_generate::{Provider, Generator, CTFType, CIntegerType};

let mut provider = Provider::new("my_first_rust_provider"); // stage 1
provider.create_class("my_first_class") //stage 2
    .add_field("my_integer_field", CTFType::Integer(CIntegerType::I32))
    .add_field("my_string_field", CTFType::SequenceText)
    .instantiate("my_first_tracepoint"); // stage 3

Generator::default()
    .generated_lib_name("tracepoint_library_link_name")
    .register_provider(provider)
    .output_file_name(PathBuf::from(env::var("OUT_DIR").unwrap()).join("tracepoints.rs"))
    .generate()
    .expect("Unable to generate tracepoint bindings");

To break this down, there are basically three phases to the creation of tracepoints in lttng-ust-rs. The first is creating a provider, which we do using the Provider::new constructor above. Provider names should be globally unique to ease identification of your particular application or library on systems with many lttng-ust events registered.

Second, we need to create an event class. An event class describes the layout of a tracepoint event. Events can have up to 10 different fields. All field names should be unique within the event class. See CTFType for a list of all the types we currently support and how those types map to the ctf_* macros from man 3 lttng-ust. Also important to note is the order of the .add_field calls, since these determine the order of the arguments to the generated tracepoint function.

Finally, we can instantiate our event class to create a specific event. This is what causes lttng-usg-generate to actually emit a tracepoint we can use in our code.

To actually use the tracepoints generated here, you'll also need the lttng-ust crate, which contains all the runtime support for lttng-ust-rs. So after adding lttng-ust = "0.1.0" to your Cargo.toml, in the main file for your project (probably lib.rs or main.rs) add something like the following:

import_tracepoints!(concat!(env!("OUT_DIR"), "/tracepoints.rs"), tracepoints)

While we recommend placing this in the root of your crate, the macro should work anywhere. Note the first argument will generate the path we used above when invoking the generator. The second argument to the macro is the name of the module where all the tracepoints should be placed.

Now we can use our tracepoint from anywhere in the code like so:

tracepoints::my_first_rust_provider::my_first_tracepoint(42, "the meaning of life");

Have a look in the examples directory of the repository on GitHub for a complete usage sample.

Happy tracing!

Dependencies

~8MB
~159K SLoC