| # 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/tracing/README.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/tracing/README.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). |
| |