Adding tracing in your code

This guide shows how to add tracing to your code.

Note: For more information on the Fuchsia tracing system, see Fuchsia tracing system.

Prerequisites

Before you begin, make sure you have completed the following:

Add tracing to your component

Once your component is a trace provider, you can perform the following types of tracing:

Note: The tracing macros should be added to the code of your component. For more information on the C and C++ tracing macros, see Tracing: C and C++ macros.

Trace an instant event {#instant-event}

To write an instant event representing a single moment in time:

  • {C and C++}

    1. TRACE_INSTANT("helloworld", "hello_world_test", TRACE_SCOPE_PROCESS, "message", TA_STRING("Hello, World!"));

This example specifies a category of helloworld, a name of hello_world_test, a scope of TRACE_SCOPE_PROCESS, and a key and value pair.

For more information on the TRACE_INSTANT macro, see TRACE_INSTANT.

Disable tracing {#disable-tracing}

There are cases where you might wish to entirely disable tracing such as when you are about to make a final release. If the NTRACE macro is in your code, then the tracing macros don’t generate any code:

  • {C and C++}

    1. #define NTRACE // disable tracing
    2. #include <lib/trace/event.h>

Make sure that you define the NTRACE macro before the #includestatement.

In this example, the rx_count and tx_count fields are used only with tracing, so if NTRACE is asserted, which indicates that tracing is disabled, the fields don’t take up space in the my_statistics_t structure.

  • {C and C++}

    1. typedef struct {
    2. #ifndef NTRACE // reads as "if tracing is not disabled"
    3. uint64_t rx_count;
    4. uint64_t tx_count;
    5. #endif
    6. uint64_t npackets;
    7. } my_statistics_t;

However, you do need to conditionally compile the code for managing the recording of the statistics. For example, you can use the TRACE_INSTANT macro:

  • {C and C++}

    1. #ifndef NTRACE
    2. status.tx_count++;
    3. TRACE_INSTANT("bandwidth", "txpackets", TRACE_SCOPE_PROCESS,
    4. "count", TA_UINT64(status.tx_count));
    5. #endif // NTRACE

For more information on the NTRACE macro, see NTRACE.

Determine if tracing is on {#determine-if-tracing-is-on}

In some cases, you may need to determine if tracing is on at runtime. If tracing is compiled in your code because NTRACE is not defined, the TRACE_ENABLED() macro determines if tracing for your trace provider is on.

If tracing is compiled out, then TRACE_ENABLED() always returns false.

For example:

  • {C and C++}

    1. #ifndef NTRACE
    2. if (TRACE_ENABLED()) {
    3. int v = do_something_expensive();
    4. TRACE_INSTANT(...
    5. }
    6. #endif // NTRACE

This example uses both the #ifndef and the TRACE_ENABLED() macro together because the function do_something_expensive() might not exist in the trace-disabled version of your code.

For more information on the TRACE_ENABLED macro, see TRACE_ENABLED.

Time an event {#time-an-event}

In some cases, you may need to time a function or procedure.

This example is from a blobfs vnode constructor. See //src/storage/blobfs/blobfs.cc.

  • {C++}

    1. zx_status_t VnodeBlob::InitCompressed() {
    2. TRACE_DURATION("blobfs", "Blobfs::InitCompressed", "size", inode_.blob_size,
    3. "blocks", inode_.num_blocks);
    4. ...

This example records the length of time spent in the constructor, along with the size and number of blocks. Since this is a C++ example, the data types can be inferred by the compiler.

For more information on the TRACE_DURATION macro, see TRACE_DURATION.

Once you have added a tracing statement to your component, you can now collect a trace. For more information, see Recording a Fuchsia trace.