# 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](/docs/concepts/kernel/tracing-system.md).

## Prerequisites

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

* Familiarized yourself with the Fuchsia tracing system. See
  [Fuchsia tracing system](/docs/concepts/kernel/tracing-system.md).
* Registered your component as a tracing provider. See
  [Registering a trace provider](/docs/development/tracing/tutorial/registering-a-trace-provider.md).
* Included the `libtrace` library to capture trace data. See
  [libtrace: The C and C++ trace event library](/docs/reference/tracing/libraries.md#libtrace-trace-event).

## 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](/docs/reference/tracing/c_cpp_macros.md).

* [Trace an instant event](#instant-event)
* [Disable tracing](#disable-tracing)
* [Determine if tracing is on](#determine-if-tracing-is-on)
* [Time an event](#time-an-event)

### Trace an instant event {#instant-event}

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

* {C and C++}

  ```c
  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](/docs/reference/tracing/c_cpp_macros.md#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++}

  ```c
  #define NTRACE  // disable tracing
  #include <lib/trace/event.h>
  ```

Make sure that you define the `NTRACE` macro before the `#include`statement.

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++}

  ```c
  typedef struct {
  #ifndef NTRACE  // reads as "if tracing is not disabled"
      uint64_t    rx_count;
      uint64_t    tx_count;
  #endif
      uint64_t    npackets;
  } 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++}

  ```c
  #ifndef NTRACE
      status.tx_count++;
      TRACE_INSTANT("bandwidth", "txpackets", TRACE_SCOPE_PROCESS,
                    "count", TA_UINT64(status.tx_count));
  #endif  // NTRACE
  ```

For more information on the `NTRACE` macro, see
[NTRACE](/docs/reference/tracing/c_cpp_macros.md#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++}

  ```c
  #ifndef NTRACE
      if (TRACE_ENABLED()) {
          int v = do_something_expensive();
          TRACE_INSTANT(...
      }
  #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](/docs/reference/tracing/c_cpp_macros.md#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](/src/storage/blobfs/blobfs.cc).

* {C++}

  ```cpp
  zx_status_t VnodeBlob::InitCompressed() {
      TRACE_DURATION("blobfs", "Blobfs::InitCompressed", "size", inode_.blob_size,
                     "blocks", inode_.num_blocks);
      ...
  ```

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](/docs/reference/tracing/c_cpp_macros.md#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](/docs/development/tracing/tutorial/recording-a-fuchsia-trace.md).

