/*!
@mainpage Bonjour!

Welcome to the <strong>\lt_api</strong> (liblttng-ctl) documentation!

The
<a href="https://lttng.org/"><em>Linux Trace Toolkit: next generation</em></a>
is an open-source software package used for correlated tracing of the
Linux kernel, user applications, and user libraries.

liblttng-ctl, which is part of the LTTng-tools project, makes it
possible to control <a href="https://lttng.org/">LTTng</a> tracing, but
also to
\ref api_trigger "receive notifications when specific events occur".

<h2>Plumbing</h2>

The following diagram shows the components of LTTng:

@image html plumbing.png "Components of LTTng."

As you can see, liblttng-ctl is a bridge between a user application
and a session daemon (see \lt_man{lttng-sessiond,8} and
\ref api-gen-sessiond-conn "Session daemon connection").

The \lt_man{lttng,1} command-line tool which ships with LTTng-tools, for
example, uses liblttng-ctl to perform its commands.

See the
<a href="https://lttng.org/docs/v\lt_version_maj_min/#doc-plumbing"><em>Components of LTTng</em></a>
section of the LTTng Documentation to learn more.

<h2>Contents</h2>

This API documentation has three main modules:

- The \ref api_session "recording session API"
  makes it possible to create, manipulate
  (\ref api_session_snapshot "take a snapshot",
  \ref api_session_rotation "rotate",
  \ref api_session_clear "clear", and the rest), and destroy
  <em>recording sessions</em>.

  A recording session is a per-Unix user dialogue for everything related
  to event recording.

  A recording session owns \lt_obj_channels which
  own \lt_obj_rers. Those objects constitute
  the main configuration of a recording session.

- The \ref api_inst_pt "instrumentation point listing API"
  makes it possible to get details about the
  available LTTng tracepoints, Java/Python loggers, and Linux kernel
  system calls without needing any \lt_obj_session.

- The \ref api_trigger "trigger API" makes it possible to
  create and register <em>triggers</em>.

  A trigger associates a condition to an action: when the
  condition of a trigger is satisfied, LTTng attempts to execute its
  action.

  This API is fully decoupled from the
  \ref api_session "recording session API".

  Amongst the interesting available trigger conditions and actions
  are the
  <em>\link api_trigger_cond_er_matches “event rule matches”\endlink</em>
  condition and the
  <em>\link api_trigger_action_notify “notify”\endlink</em>
  action. With those, your application can
  \ref api_notif "receive an asynchronous message"
  (a notification) when a specified event rule matches
  an LTTng event.

The three modules above often refer to the \ref api_gen which offers
common enumerations, macros, and functions.

See <a href="topics.html">Topics</a> for the complete table
of contents.

<h2>Build with liblttng-ctl</h2>

To build an application with liblttng-ctl:

<dl>
  <dt>Header file
  <dd>
    Include <code>%lttng/lttng.h</code>:

    @code
    #include <lttng/lttng.h>
    @endcode

    With
    <a href="https://www.freedesktop.org/wiki/Software/pkg-config/">pkg-config</a>,
    get the required C&nbsp;flags with:

    @code{.unparsed}
    $ pkg-config --cflags lttng-ctl
    @endcode

  <dt>Linking
  <dd>
    Link your application with <code>liblttng-ctl</code>:

    @code{.unparsed}
    $ cc my-app.o ... -llttng-ctl
    @endcode

    With pkg-config, get the required linker options with:

    @code{.unparsed}
    $ pkg-config --libs lttng-ctl
    @endcode
</dl>

@defgroup api_gen General API

The general \lt_api offers:

- \ref lttng_error_code "Error code enumerators" and lttng_strerror().

- \ref api-gen-sessiond-conn "Session daemon connection" functions:

  - lttng_session_daemon_alive()
  - lttng_set_tracing_group()

- The lttng_get_kernel_tracer_status() function to get the current
  LTTng kernel tracer status.

<h1>\anchor api-gen-sessiond-conn Session daemon connection</h1>

Many functions of the \lt_api require a connection to a listening LTTng
session daemon (see \lt_man{lttng-sessiond,8}) to control LTTng tracing.

liblttng-ctl connects to a session daemon through a Unix domain socket
when you call some of its public functions, \em not when it loads.

Each Unix user may have its own independent running session daemon.
However, liblttng-ctl must connect to the session daemon of the
\c root user (the root session daemon) to control Linux kernel tracing.

How liblttng-ctl chooses which session daemon to connect to is as
follows, considering \lt_var{U} is the Unix user of the process running
liblttng-ctl:

<dl>
  <dt>\lt_var{U} is \c root
  <dd>Connect to the root session daemon.

  <dt>\lt_var{U} is not \c root
  <dd>
    <dl>
      <dt>If \lt_var{U} is part of the current liblttng-ctl Unix <em>tracing group</em>
      <dd>
        Try to connect to the root session daemon.

        If the root session daemon isn't running, then connect to the
        session daemon of \lt_var{U}.

      <dt>If \lt_var{U} is not part of the tracing group
      <dd>
        Connect to the session daemon of \lt_var{U}.
    </dl>
</dl>

The Unix tracing group of the root session daemon is one of:

<dl>
  <dt>
    With the <code>\--group=<em>GROUP</em></code> option of the root
    session daemon
  <dd>
    Exactly <code><em>GROUP</em></code>.

    In that case, you must call lttng_set_tracing_group(), passing
    exactly <code><em>GROUP</em></code>, \em before you call a
    liblttng-ctl function which needs to connect to a session daemon.

  <dt>
    Without the <code>\--group</code> option of the root
    session daemon
  <dd>
    Exactly \c tracing (also the default Unix tracing group of
    liblttng-ctl, therefore you don't need to call
    lttng_set_tracing_group()).
</dl>

Check that your application can successfully connect to a session daemon
with lttng_session_daemon_alive().

LTTng-instrumented user applications automatically register to both the
root and user session daemons. This makes it possible for both session
daemons to list the available instrumented applications and their
\ref api_inst_pt "instrumentation points".

@defgroup api_uprobe_loc Linux user space probe location API

A <strong><em>Linux user space probe location</em></strong> is an object
which locates a Linux
<a href="https://www.kernel.org/doc/html/latest/trace/uprobetracer.html">user space probe</a>.

The purpose of such an object is to provide the location of the target
Linux user space probe when you create:

- A \ref api_rer "Linux user space recording event rule".
- A \ref api_uprobe_er "Linux user space probe event rule".

The two ways to locate a Linux user space probe are:

<table>
  <tr>
    <th>Location type
    <th>Location enumerator
    <th>Creation function
  <tr>
    <td>By the entry of a user space function within some binary
    <td>#LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION
    <td>lttng_userspace_probe_location_function_create()
  <tr>
    <td>
      By a SystemTap Userland Statically Defined Tracing (USDT)
      probe within some binary
    <td>#LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT
    <td>lttng_userspace_probe_location_tracepoint_create()
</table>

Get the type of a Linux kprobe location with
lttng_userspace_probe_location_get_type().

Destroy a Linux kprobe location with
lttng_userspace_probe_location_destroy().

@defgroup api_session Recording session API

A <strong><em>recording session</em></strong> is a stateful dialogue
between an application and a session daemon for everything related to
event recording.

Everything that you do when you control LTTng tracers to record events
happens within a recording session. In particular, a recording session:

- Has its own name, unique for a given session daemon.

- Has its own set of trace files, if any.

- Has its own state of
  \link lttng_session::enabled activity\endlink (started or stopped).

  An active recording session is an implicit
  \lt_obj_rer condition.

- Has its own \ref api-session-modes "mode"
  (local, network streaming, snapshot, or live).

- Has its own \lt_obj_channels to which are attached
  their own recording event rules.

- Has its own \ref api_proc_filter "process filter".

Those attributes and objects are completely isolated between different
recording sessions.

A recording session is like an
<a href="https://en.wikipedia.org/wiki/Automated_teller_machine">ATM</a>
session: the operations you do on the
banking system through the ATM don't alter the data of other users of
the same system. In the case of the ATM, a session lasts as long as your
bank card is inside. In the case of LTTng, a recording session lasts
from a call to lttng_create_session_ext() to the completion of its
destruction operation (which you can initiate with
lttng_destroy_session_ext()).

A recording session belongs to a session daemon (see
\lt_man{lttng-sessiond,8} and
\ref api-gen-sessiond-conn "Session daemon connection"). For a given
session daemon, each Unix user has its own, private recording sessions.
Note, however, that the \c root Unix user may operate on or destroy
another user's recording session.

@image html many-sessions.png "Each Unix user has its own, private recording sessions."

@sa The “RECORDING SESSION” section of \lt_man{lttng-concepts,7}.

<h1>Operations</h1>

The recording session operations are:

<table>
  <tr>
    <th>Operation
    <th>Means
  <tr>
    <td>Creation
    <td>
      -# Create a \lt_obj_session_descr
         with one of the dedicated creation functions depending on the
         \ref api-session-modes "recording session mode".

      -# Call lttng_create_session_ext(), passing the recording session
         descriptor of step&nbsp;1.

      -# When you're done with the recording session descriptor, destroy
         it with lttng_session_descriptor_destroy().

      @sa \lt_man{lttng-create,1}
  <tr>
    <td>Destruction
    <td>
      -# Call lttng_destroy_session_ext(), passing the name of the
         recording session to destroy.

         This function initiates a destruction operation, returning
         immediately.

         This function can set a pointer to a
         \ref api_session_destr_handle "destruction handle"
         (#lttng_destruction_handle) so that you can wait for the
         completion of the operation. Without such a handle, you can't
         know when the destruction operation completes and whether or
         not it does successfully.

      -# <strong>If you have a destruction handle from
         step&nbsp;1</strong>, then:

         -# Call lttng_destruction_handle_wait_for_completion() to wait
            for the completion of the destruction operation.

         -# Call lttng_destruction_handle_get_result() to get whether or
            not the destruction operation successfully completed.

            You can also call
            lttng_destruction_handle_get_rotation_state() and
            lttng_destruction_handle_get_archive_location() at this
            point.

         -# Destroy the destruction handle with
            lttng_destruction_handle_destroy().

      @sa \lt_man{lttng-destroy,1}
  <tr>
    <td>Basic property access
    <td>
      See:

      - The members of #lttng_session
      - lttng_session_descriptor_get_session_name()
      - lttng_session_get_creation_time()
      - lttng_set_session_shm_path()
      - lttng_data_pending()
  <tr>
    <td>\lt_obj_c_domain access
    <td>
      -# Call lttng_list_domains(), passing the name of the recording
         session of which to get the tracing domains.

         This function sets a pointer to an array of
         \link #lttng_domain tracing domain summaries\endlink
         and returns the number of entries.

      -# Access the properties of each tracing domain summary through
         structure members.

      -# When you're done with the array of tracing domain summaries,
         free it with <code>free()</code>.
  <tr>
    <td>\lt_obj_c_channel access
    <td>
      -# Create a \link #lttng_handle recording session handle\endlink
         with lttng_create_handle() to specify the name of the
         recording session and the summary of the
         \lt_obj_domain of the channels to access.

      -# Call lttng_list_channels(), passing the recording session
         handle of step&nbsp;1.

         This function sets a pointer to an array of
         \link #lttng_channel channel summaries\endlink
         and returns the number of entries.

      -# Destroy the recording session handle of step&nbsp;1 with
         lttng_destroy_handle().

      -# Access the \ref api-channel-channel-props "properties" of each
         channel summary through structure members or using dedicated
         getters.

      -# When you're done with the array of channel summaries,
         free it with <code>free()</code>.
  <tr>
    <td>Activity control
    <td>
      See:

      - lttng_start_tracing()
      - lttng_stop_tracing()
      - lttng_stop_tracing_no_wait()

      The \link api_trigger_action_start_session “start recording session”\endlink
      and
      \link api_trigger_action_stop_session “stop recording session”\endlink
      trigger actions can also
      activate and deactivate a recording session.
  <tr>
    <td>Listing
    <td>
      -# Call lttng_list_sessions().

         This function sets a pointer to an array of
         \link #lttng_session recording session summaries\endlink
         and returns the number of entries.

      -# Access the properties of each recording session summary through
         structure members or using dedicated getters.

      -# When you're done with the array of recording session summaries,
         free it with <code>free()</code>.

      @sa \lt_man{lttng-list,1}
  <tr>
    <td>Process filter access
    <td>See \ref api_proc_filter
  <tr>
    <td>Clearing
    <td>See \ref api_session_clear
  <tr>
    <td>Snapshot recording
    <td>
      See \ref api_session_snapshot

      The
      \link api_trigger_action_snapshot “take recording session snapshot”\endlink
      trigger action can also
      take a recording session snapshot.
  <tr>
    <td>Rotation
    <td>
      See \ref api_session_rotation

      The
      \link api_trigger_action_rotate “rotate recording session”\endlink
      trigger action can also
      rotate a recording session.
  <tr>
    <td>Saving and loading
    <td>See \ref api_session_save_load
  <tr>
    <td>Trace data regeneration
    <td>
      See:

      - lttng_regenerate_metadata()
      - lttng_regenerate_statedump()

      @sa \lt_man{lttng-regenerate,1}
</table>

<h1>\anchor api-session-modes Recording session modes</h1>

LTTng offers four <strong><em>recording session modes</em></strong>:

<table>
  <tr>
    <th>Mode
    <th>Description
    <th>Descriptor creation function(s)
  <tr>
    <td>\anchor api-session-local-mode Local
    <td>
      Write the trace data to the local file system, or do not write any
      trace data.
    <td>
      - lttng_session_descriptor_create()
      - lttng_session_descriptor_local_create()
  <tr>
    <td>\anchor api-session-net-mode Network streaming
    <td>
      Send the trace data over the network to a listening relay daemon
      (see \lt_man{lttng-relayd,8}).
    <td>lttng_session_descriptor_network_create()
  <tr>
    <td>\anchor api-session-snapshot-mode Snapshot
    <td>
      Only write the trace data to the local file system or send it to a
      listening relay daemon when LTTng
      takes a \ref api_session_snapshot "snapshot".

      LTTng takes a snapshot of such a recording session when:

      - You call lttng_snapshot_record().

      - LTTng executes a
        \link api_trigger_action_snapshot “take recording session snapshot”\endlink
        trigger action.

      LTTng forces the
      \ref api-channel-er-loss-mode "event record loss mode" of all
      the channels of such a recording session to be
      “\ref api-channel-overwrite-mode "overwrite"”.
    <td>
      - lttng_session_descriptor_snapshot_create()
      - lttng_session_descriptor_snapshot_local_create()
      - lttng_session_descriptor_snapshot_network_create()
  <tr>
    <td>\anchor api-session-live-mode Live
    <td>
      Send the trace data over the network to a listening relay daemon
      for live reading.

      An LTTng live reader (for example,
      <a href="https://babeltrace.org/">Babeltrace&nbsp;2</a>) can
      connect to the same relay daemon to receive trace data while the
      recording session is active.
    <td>
      lttng_session_descriptor_live_network_create()
</table>

@sa The “Recording session modes” section of \lt_man{lttng-concepts,7}.

<h1>\anchor api-session-url Output URL format</h1>

Some functions of the \lt_api require an <strong><em>output
URL</em></strong>.

An output URL is a C&nbsp;string which specifies where to send trace
data and, when LTTng connects to a relay daemon (see
\lt_man{lttng-relayd,8}), control commands.

There are three available output URL formats:

<table>
  <tr>
    <th>Type
    <th>Description
    <th>Format
  <tr>
    <td>\anchor api-session-local-url Local
    <td>
      Send trace data to the local file system, without connecting to a
      relay daemon.

      Accepted by:

      - lttng_create_session() (deprecated)
      - lttng_create_session_snapshot() (deprecated)
      - lttng_snapshot_output_set_local_path()
      - lttng_save_session_attr_set_output_url()
      - lttng_load_session_attr_set_input_url()
      - lttng_load_session_attr_set_override_url()
    <td>
      <code>file://<em>TRACEDIR</em></code>

      <dl>
        <dt><code><em>TRACEDIR</em></code>
        <dd>
          Absolute path to the directory containing the trace data on
          the local file system.
      </dl>
  <tr>
    <td>\anchor api-session-one-port-url Remote: single port
    <td>
      Send trace data and/or control commands to a specific relay daemon
      with a specific TCP port.

      Accepted by:

      - lttng_session_descriptor_network_create()
      - lttng_session_descriptor_snapshot_network_create()
      - lttng_session_descriptor_live_network_create()
      - lttng_snapshot_output_set_network_urls()
      - lttng_snapshot_output_set_ctrl_url()
      - lttng_snapshot_output_set_data_url()
      - lttng_load_session_attr_set_override_ctrl_url()
      - lttng_load_session_attr_set_override_data_url()
    <td>
      <code><em>PROTO</em>://<em>HOST</em></code>[<code>:<em>PORT</em></code>][<code>/<em>TRACEDIR</em></code>]

      <dl>
        <dt><code><em>PROTO</em></code>
        <dd>
          Network protocol, amongst:

          <dl>
            <dt>\c net
            <dd>
              TCP over IPv4.

            <dt>\c net6
            <dd>
              TCP over IPv6.

            <dt>\c tcp
            <dd>
              Same as <code>net</code>.

            <dt>\c tcp6
            <dd>
              Same as <code>net6</code>.
          </dl>

        <dt><code><em>HOST</em></code>
        <dd>
          Hostname or IP address.

          An IPv6 address must be enclosed in square brackets (<code>[</code>
          and&nbsp;<code>]</code>); see
          <a href="https://www.ietf.org/rfc/rfc2732.txt">RFC&nbsp;2732</a>.

        <dt><code><em>PORT</em></code>
        <dd>
          TCP port.

          If it's missing, then the default control and data ports are
          respectively \lt_def_net_ctrl_port and
          \lt_def_net_data_port.

        <dt><code><em>TRACEDIR</em></code>
        <dd>
          Path of the directory containing the trace data on the remote
          file system.

          This path is relative to the base output directory of the
          LTTng relay daemon (see the <em>Output directory</em>
          section of \lt_man{lttng-relayd,8}).
      </dl>
  <tr>
    <td>\anchor api-session-two-port-url Remote: control and data ports
    <td>
      Send trace data and control commands to a specific relay daemon
      with specific TCP ports.

      This form is usually a shorthand for two
      \ref api-session-one-port-url "single-port output URLs" with
      specified ports.

      Accepted by:

      - lttng_create_session_snapshot() (deprecated)
      - lttng_create_session_live() (deprecated)
      - lttng_session_descriptor_network_create()
      - lttng_session_descriptor_snapshot_network_create()
      - lttng_session_descriptor_live_network_create()
      - lttng_snapshot_output_set_network_url()
      - lttng_snapshot_output_set_network_urls()
      - lttng_snapshot_output_set_ctrl_url()
      - lttng_load_session_attr_set_override_url()
      - lttng_load_session_attr_set_override_ctrl_url()
    <td>
      <code><em>PROTO</em>://<em>HOST</em>:<em>CTRLPORT</em>:<em>DATAPORT</em></code>[<code>/<em>TRACEDIR</em></code>]

      <dl>
        <dt><code><em>PROTO</em></code>
        <dd>
          Network protocol, amongst:

          <dl>
            <dt>\c net
            <dd>
              TCP over IPv4.

            <dt>\c net6
            <dd>
              TCP over IPv6.

            <dt>\c tcp
            <dd>
              Same as <code>net</code>.

            <dt>\c tcp6
            <dd>
              Same as <code>net6</code>.
          </dl>

        <dt><code><em>HOST</em></code>
        <dd>
          Hostname or IP address.

          An IPv6 address must be enclosed in square brackets (<code>[</code>
          and&nbsp;<code>]</code>); see
          <a href="https://www.ietf.org/rfc/rfc2732.txt">RFC&nbsp;2732</a>.

        <dt><code><em>CTRLPORT</em></code>
        <dd>
          Control TCP port.

        <dt><code><em>DATAPORT</em></code>
        <dd>
          Trace data TCP port.

        <dt><code><em>TRACEDIR</em></code>
        <dd>
          Path of the directory containing the trace data on the remote
          file system.

          This path is relative to the base output directory of the
          LTTng relay daemon (see the <code>\--output</code> option of
          \lt_man{lttng-relayd,8}).
      </dl>
</table>

@defgroup api_session_descr Recording session descriptor API
@ingroup api_session

A <strong><em>recording session descriptor</em></strong> describes the
properties of a \lt_obj_session to be (not created
yet).

To create a recording session from a recording session descriptor:

-# Create a recording session descriptor
   with one of the dedicated creation functions, depending on the
   \ref api-session-modes "recording session mode":

   <dl>
     <dt>\ref api-session-local-mode "Local mode"
     <dd>
       One of:

       - lttng_session_descriptor_create()
       - lttng_session_descriptor_local_create()

     <dt>\ref api-session-net-mode "Network streaming mode"
     <dd>
       lttng_session_descriptor_network_create()

     <dt>\ref api-session-snapshot-mode "Snapshot mode"
     <dd>
       One of:

       - lttng_session_descriptor_snapshot_create()
       - lttng_session_descriptor_snapshot_local_create()
       - lttng_session_descriptor_snapshot_network_create()

     <dt>\ref api-session-live-mode "Live mode"
     <dd>
       lttng_session_descriptor_live_network_create()
   </dl>

-# Call lttng_create_session_ext(), passing the recording session
   descriptor of step&nbsp;1.

   After a successful call to this function, you can call
   lttng_session_descriptor_get_session_name() to get the name of the
   created recording session (set when creating the descriptor or
   automatically generated).

-# When you're done with the recording session descriptor, destroy
   it with lttng_session_descriptor_destroy().

@defgroup api_session_destr_handle Recording session destruction handle API
@ingroup api_session

A <strong><em>recording session destruction handle</em></strong>
represents a \lt_obj_session destruction operation.

The main purposes of a recording session destruction handle is to:

- Wait for the completion of the recording session
  destruction operation with
  lttng_destruction_handle_wait_for_completion() and get whether or not
  it was successful with lttng_destruction_handle_get_result().

- Get the state of any
  \ref api_session_rotation "recording session rotation"
  which the recording session destruction operation caused
  with lttng_destruction_handle_get_rotation_state(), and the location
  of its trace chunk archive with
  lttng_destruction_handle_get_archive_location().

To destroy a recording session:

-# Call lttng_destroy_session_ext(), passing the name of the recording
   session to destroy.

   This function initiates a destruction operation, returning
   immediately.

   This function can set a pointer to a
   \link #lttng_destruction_handle destruction handle\endlink so that
   you can wait for the completion of the operation. Without such a
   handle, you can't know when the destruction operation completes and
   whether or not it does successfully.

-# Call lttng_destruction_handle_wait_for_completion() to wait
   for the completion of the destruction operation.

-# Call lttng_destruction_handle_get_result() to get whether or
   not the destruction operation successfully completed.

-# <strong>If LTTng performed at least one
   \ref api_session_rotation "rotation" of the destroyed recording
   session</strong>, then
   call lttng_destruction_handle_get_rotation_state()
   to know whether or not the last rotation was successful and
   lttng_destruction_handle_get_archive_location() to get the location
   of its trace chunk archive.

-# Destroy the destruction handle with
   lttng_destruction_handle_destroy().

@defgroup api_channel Domain and channel API
@ingroup api_session

<h1>\anchor api-channel-domain Tracing domain</h1>

A <strong><em>tracing domain</em></strong> identifies a type of LTTng
tracer.

A tracing domain has its own properties and features.

There are currently five available tracing domains:

<table>
  <tr>
    <th>Domain name
    <th>Type enumerator
  <tr>
    <td>Linux kernel
    <td>#LTTNG_DOMAIN_KERNEL
  <tr>
    <td>User space
    <td>#LTTNG_DOMAIN_UST
  <tr>
    <td><a href="https://docs.oracle.com/javase/8/docs/api/java/util/logging/package-summary.html">\lt_jul</a> (JUL)
    <td>#LTTNG_DOMAIN_JUL
  <tr>
    <td><a href="https://logging.apache.org/log4j/1.x/">\lt_log4j1</a>
    <td>#LTTNG_DOMAIN_LOG4J
  <tr>
    <td><a href="https://logging.apache.org/log4j/2.x/">\lt_log4j2</a>
    <td>#LTTNG_DOMAIN_LOG4J2
  <tr>
    <td><a href="https://docs.python.org/3/library/logging.html">Python logging</a>
    <td>#LTTNG_DOMAIN_PYTHON
</table>

A \lt_obj_channel is always part of a tracing domain.

Many liblttng-ctl functions require a tracing domain type (sometimes
within a
\link #lttng_handle recording session handle\endlink)
to target specific tracers or to avoid ambiguity. For example, because
the Linux kernel and user space tracing domains support named
tracepoints as \ref api_inst_pt "instrumentation points", you need to
specify a tracing domain when you create a
\lt_obj_rer with lttng_enable_event_with_exclusions() because both
tracing domains could have LTTng tracepoints sharing the same name.

@sa The “TRACING DOMAIN” section of \lt_man{lttng-concepts,7}.

<h1>\anchor api-channel-channel Channel</h1>

A <strong><em>channel</em></strong> is an object which is responsible
for a set of ring buffers.

Each ring buffer is divided into multiple <em>sub-buffers</em>. When a
\lt_obj_rer matches an event, LTTng can record it to one or more
sub-buffers of one or more channels.

A channel is always associated to a \lt_obj_domain.
The \link #LTTNG_DOMAIN_JUL \lt_jul\endlink,
\link #LTTNG_DOMAIN_LOG4J \lt_log4j1\endlink,
\link #LTTNG_DOMAIN_LOG4J2 \lt_log4j2\endlink, and
\link #LTTNG_DOMAIN_PYTHON Python\endlink tracing
domains each have a default channel which you can't configure.

Note that the some functions, like lttng_enable_event_with_exclusions(),
can automatically create a default channel with sane defaults when no
channel exists for the provided \lt_obj_domain.

A channel owns \lt_obj_rers.

@image html concepts.png "A recording session contains channels that are members of tracing domains and contain recording event rules."

You can't destroy a channel.

<h2>Operations</h2>

The channel operations are:

<table>
  <tr>
    <th>Operation
    <th>Means
  <tr>
    <td>Creation
    <td>
      -# Call lttng_channel_create() with a \lt_obj_domain summary to
         create an initial channel summary.

         This function calls lttng_channel_set_default_attr() to set
         the properties of the created channel summary to default values
         depending on the tracing domain summary.

      -# Set the properties of the channel summary of step&nbsp;1
         through direct members or with dedicated setters.

         See the property table below.

      -# Create a \link #lttng_handle recording session handle\endlink
         structure to specify the name of the recording session and the
         tracing domain of the channel to create.

      -# Call lttng_enable_channel() with the recording session handle
         of step&nbsp;3 and the channel summary of step&nbsp;1
         o create the channel.

      -# Destroy the recording session handle with
         lttng_destroy_handle() and the channel summary with
         lttng_channel_destroy().

      @sa \lt_man{lttng-enable-channel,1}
  <tr>
    <td>Basic property access
    <td>
      See the \ref api-channel-channel-props "property table" below.
  <tr>
    <td>\lt_obj_c_rer access
    <td>
      -# Create a \link #lttng_handle recording session handle\endlink
         with lttng_create_handle() to specify the name of the
         recording session and the summary of the
         \lt_obj_domain of the channel of which to get the recording
         event rule descriptors.

      -# Call lttng_list_events(), passing the recording session
         handle of step&nbsp;1 and a channel name.

         This function sets a pointer to an array of
         \link #lttng_event recording event rule descriptors\endlink
         and returns the number of entries.

      -# Destroy the recording session handle of step&nbsp;1 with
         lttng_destroy_handle().

      -# Access the properties of each
         recording event rule descriptor through structure members or
         using dedicated getters.

      -# When you're done with the array of recording event rule
         descriptors, free it with <code>free()</code>.
  <tr>
    <td>Event record context field adding
    <td>
      -# Initialize an #lttng_event_context structure, setting
         its properties to describe the context field to be added.

      -# Create a \link #lttng_handle recording session handle\endlink
         structure to specify the name of the recording session and the
         tracing domain of the channel to target.

      -# Call lttng_add_context() with the recording session handle
         of step&nbsp;2 and the context field descriptor of step&nbsp;1,
         optionally passing the name of the channel to target.

      -# Destroy the recording session handle with
         lttng_destroy_handle().

      @sa \lt_man{lttng-add-context,1}
  <tr>
    <td>Enabling
    <td>
      Use lttng_enable_channel().

      @sa \lt_man{lttng-enable-channel,1}
  <tr>
    <td>Disabling
    <td>
      Use lttng_disable_channel().

      @sa \lt_man{lttng-disable-channel,1}
  <tr>
    <td>Statistics
    <td>
      See:

      - lttng_channel_get_discarded_event_count()
      - lttng_channel_get_lost_packet_count()
</table>

<h2>\anchor api-channel-channel-props Properties</h2>

The properties of a channel are:

<table>
  <tr>
    <th>Property name
    <th>Description
    <th>Access
  <tr>
    <td>Buffer ownership model
    <td>
      See \ref api-channel-buf-ownership-model "Buffer ownership model".
    <td>
      The lttng_domain::buf_type member for the containing tracing
      domain.

      All the channels of a given tracing domain share the same
      buffer ownership model.
  <tr>
    <td>Buffer allocation policy
    <td>
      See \ref api-channel-buf-alloc-policy "Buffer allocation policy".
    <td>
      - lttng_channel_get_allocation_policy()
      - lttng_channel_set_allocation_policy()
  <tr>
    <td>Event record loss mode
    <td>
      See \ref api-channel-er-loss-mode "Event record loss mode".
    <td>
      The lttng_channel_attr::overwrite member.
  <tr>
    <td>Sub-buffer size
    <td>
      See \ref api-channel-sub-buf-size-count "Sub-buffer size and count".
    <td>
      The lttng_channel_attr::subbuf_size member.
  <tr>
    <td>Sub-buffer count
    <td>
      See \ref api-channel-sub-buf-size-count "Sub-buffer size and count".
    <td>
      The lttng_channel_attr::num_subbuf member.
  <tr>
    <td>Maximum trace file size
    <td>
      See \ref api-channel-max-trace-file-size-count "Maximum trace file size and count".
    <td>
      The lttng_channel_attr::tracefile_size member.
  <tr>
    <td>Maximum trace file count
    <td>
      See \ref api-channel-max-trace-file-size-count "Maximum trace file size and count".
    <td>
      The lttng_channel_attr::tracefile_count member.
  <tr>
    <td>Read timer period
    <td>
      See \ref api-channel-read-timer "Read timer".
    <td>
      The lttng_channel_attr::read_timer_interval member.
  <tr>
    <td>Switch timer period
    <td>
      See \ref api-channel-switch-timer "Switch timer".
    <td>
      The lttng_channel_attr::switch_timer_interval member.
  <tr>
    <td>Live timer period
    <td>
      See \ref api-channel-live-timer "Live timer".
    <td>
      The \lt_p{live_timer_period} parameter of
      lttng_session_descriptor_live_network_create() when you create
      the descriptor of a \ref api-session-live-mode "live" recording
      session to contain the channel.
  <tr>
    <td>Monitor timer period
    <td>
      See \ref api-channel-monitor-timer "Monitor timer".
    <td>
      - lttng_channel_get_monitor_timer_interval()
      - lttng_channel_set_monitor_timer_interval()
  <tr>
    <td>Output type (Linux kernel channel)
    <td>
      Whether to use <code>mmap()</code> or <code>splice()</code>.
    <td>
      The lttng_channel_attr::output member.
  <tr>
    <td>\anchor api-channel-blocking-timeout Blocking timeout (user space channel)
    <td>
      How long to block (if ever) at the instrumentation point site when
      a sub-buffer is not available for applications executed with the
      \c LTTNG_UST_ALLOW_BLOCKING environment variable set.
    <td>
      - lttng_channel_get_blocking_timeout()
      - lttng_channel_set_blocking_timeout()
</table>

All the properties above are immutable once a channel exists.

@sa The “CHANNEL AND RING BUFFER” section of
\lt_man{lttng-concepts,7}.

<h3>\anchor api-channel-buf-ownership-model Buffer ownership model</h3>

The buffer ownership model of a channel
specifies whether the system, each Unix user, or each process
owns its own ring buffers
(\ref api-channel-buf-alloc-policy "one per CPU or one for the whole channel").

When you read “allocate ring buffers” below, it's either one per CPU or
one per channel, depending on the configured
\ref api-channel-buf-alloc-policy "buffer allocation policy".
The following diagrams assume a per-CPU allocation policy.

The available \link #LTTNG_DOMAIN_UST user space\endlink
tracing buffer ownership models are, considering \lt_var{U} is the Unix
user of the process running liblttng-ctl:

<dl>
  <dt>
    \anchor api-channel-per-user-buf
    \link #LTTNG_BUFFER_PER_UID Per-user buffering\endlink
  <dd>
    Allocate ring buffers to be shared by all the instrumented
    processes of:

    <dl>
      <dt>If \lt_var{U} is <code>root</code>
      <dd>
        Each Unix user.

        @image html per-user-buffering-root.png

      <dt>Otherwise
      <dd>
        \lt_var{U}

        @image html per-user-buffering.png
    </dl>

  <dt>
    \anchor api-channel-per-proc-buf
    \link #LTTNG_BUFFER_PER_PID Per-process buffering\endlink
  <dd>
    Allocate ring buffers for each instrumented process of:

    <dl>
      <dt>If \lt_var{U} is <code>root</code>
      <dd>
        All Unix users.

        @image html per-process-buffering-root.png

      <dt>Otherwise
      <dd>
        \lt_var{U}

        @image html per-process-buffering.png
    </dl>
</dl>

The per-process option tends to consume more memory than the per-user
option because systems generally have more instrumented processes than
Unix users running instrumented processes. However, the per-process
ownership model ensures that one process having a high event throughput
won't fill all the shared sub-buffers of the same Unix user, only its
own.

The buffer ownership model of a
\link #LTTNG_DOMAIN_KERNEL Linux kernel\endlink channel is always to
allocate a single set of ring buffers--one per CPU--for the whole system
(#LTTNG_BUFFER_GLOBAL). This model is similar to the
\ref api-channel-per-user-buf "per-user" option
with a per-channel
\ref api-channel-buf-alloc-policy "allocation policy",
but with a single, global user “running” the kernel.

To set the buffer ownership model of a channel when you create it:

- Set the lttng_domain::buf_type member of the structure which you pass
  within the #lttng_handle structure to lttng_enable_channel().

  Note that, for a given \lt_obj_session, \em all
  the channels of a given \lt_obj_domain must share the same buffer
  ownership model.

@sa The “Buffering scheme” section of \lt_man{lttng-concepts,7}.

<h3>\anchor api-channel-buf-alloc-policy Buffer allocation policy</h3>

The buffer allocation policy of a channel
specifies whether LTTng tracers allocate ring buffers per
channel or per CPU
(\ref api-channel-buf-ownership-model "for a given user or process").

When you read “allocate one ring buffer” below, it's either one per user
or one per process, depending on the configured
\ref api-channel-buf-ownership-model "buffer ownership model".
The following diagrams assume a per-user ownership model.

The available \link #LTTNG_DOMAIN_UST user space\endlink
tracing buffer allocation policies are, considering \lt_var{U} is the
Unix user of the process running liblttng-ctl:

<dl>
  <dt>
    \anchor api-channel-per-cpu-buf
    \link #LTTNG_CHANNEL_ALLOCATION_POLICY_PER_CPU Per-CPU buffering\endlink
  <dd>
    Allocate one ring buffer for each CPU:

    <dl>
      <dt>If \lt_var{U} is <code>root</code>
      <dd>
        For each Unix user/process.

        @image html per-user-buffering-root.png

      <dt>Otherwise
      <dd>
        For \lt_var{U}.

        @image html per-user-buffering.png
    </dl>

    When you create a channel having this policy, LTTng automatically
    adds a nonremovable #LTTNG_EVENT_CONTEXT_CPU_ID context field
    (see lttng_add_context()).

  <dt>
    \anchor api-channel-per-chan-buf
    \link #LTTNG_CHANNEL_ALLOCATION_POLICY_PER_CHANNEL Per-channel buffering\endlink
  <dd>
    Allocate one ring buffer for the whole channel:

    <dl>
      <dt>If \lt_var{U} is <code>root</code>
      <dd>
        For each Unix user/process.

        @image html per-channel-buffering-root.png

      <dt>Otherwise
      <dd>
        For \lt_var{U}.

        @image html per-channel-buffering.png
    </dl>

    When you create a channel having this policy, LTTng does \em not
    automatically adds an #LTTNG_EVENT_CONTEXT_CPU_ID context field:
    add it manually afterwards with lttng_add_context() if needed.
</dl>

As of LTTng-tools&nbsp;\lt_version_maj_min, the buffer allocation policy
of a \link #LTTNG_DOMAIN_KERNEL Linux kernel\endlink channel is always
to allocate a single set of ring buffers--one per CPU--for
the whole system.

To set the buffer allocation policy of a channel when you create it:

- Call lttng_channel_set_allocation_policy() with the
  #lttng_channel structure you pass to lttng_enable_channel().

@sa The “Buffering scheme” section of \lt_man{lttng-concepts,7}.

<h3>\anchor api-channel-er-loss-mode Event record loss mode</h3>

When LTTng emits an event, LTTng can record it to a specific, available
sub-buffer within the ring buffers of specific channels. When there's no
space left in a sub-buffer, the tracer marks it as consumable and
another, available sub-buffer starts receiving the following event
records. An LTTng consumer daemon eventually consumes the marked
sub-buffer, which returns to the available state.

In an ideal world, sub-buffers are consumed faster than they are filled.
In the real world, however, all sub-buffers can be full at some point,
leaving no space to record the following events.

By default, LTTng-modules and LTTng-UST are <em>non-blocking</em>
tracers: when there's no available sub-buffer to record an event, it's
acceptable to lose event records when the alternative would be to cause
substantial delays in the execution of the instrumented application.
LTTng privileges performance over integrity; it aims at perturbing the
instrumented application as little as possible in order to make the
detection of subtle race conditions and rare interrupt cascades
possible.

Since LTTng&nbsp;2.10, the LTTng user space tracer, LTTng-UST, supports
a <em>blocking mode</em>: see lttng_channel_get_blocking_timeout() and
lttng_channel_set_blocking_timeout().

When it comes to losing event records because there's no available
sub-buffer, or because the blocking timeout of the channel is reached,
the <strong><em>event record loss mode</em></strong> of the channel
determines what to do. The available event record loss modes are:

<dl>
  <dt>\anchor api-channel-discard-mode Discard mode
  <dd>
    Drop the newest event records until a sub-buffer becomes available.

    This is the only available mode when you specify a blocking timeout
    with lttng_channel_set_blocking_timeout().

    With this mode, LTTng increments a count of discarded event records
    when it discards an event record and saves this count to the trace.
    A trace reader can use the saved discarded event record count of the
    trace to decide whether or not to perform some analysis even if
    trace data is known to be missing.

    Get the number of discarded event records of a channel with
    lttng_channel_get_discarded_event_count().

  <dt>\anchor api-channel-overwrite-mode Overwrite mode
  <dd>
    Clear the sub-buffer containing the oldest event records and start
    writing the newest event records there.

    This mode is sometimes called <em>flight recorder mode</em> because
    it's similar to a
    <a href="https://en.wikipedia.org/wiki/Flight_recorder">flight recorder</a>:
    always keep a fixed amount of the latest data. It's also
    similar to the roll mode of an oscilloscope.

    Since LTTng&nbsp;2.8, with this mode, LTTng writes to a given
    sub-buffer its sequence number within its data stream. With a
    \ref api-session-local-mode "local",
    \ref api-session-net-mode "network streaming", or
    \ref api-session-live-mode "live" recording session, a trace
    reader can use such sequence numbers to report discarded packets. A
    trace reader can use the saved discarded sub-buffer (packet) count
    of the trace to decide whether or not to perform some analysis even
    if trace data is known to be missing.

    Get the number of discarded packets (sub-buffers) of a channel with
    lttng_channel_get_lost_packet_count().

    With this mode, LTTng doesn't write to the trace the exact number of
    lost event records in the lost sub-buffers.
</dl>

Which mechanism you should choose depends on your context: prioritize
the newest or the oldest event records in the ring buffer?

Beware that, in overwrite mode, the tracer abandons a <em>whole
sub-buffer</em> as soon as a there's no space left for a new event
record, whereas in discard mode, the tracer only discards the event
record that doesn't fit.

To set the event record loss mode of a channel when you create it:

- Set the lttng_channel_attr::overwrite member of the lttng_channel::attr
  member of the structure you pass to lttng_enable_channel().

There are a few ways to decrease your probability of losing event
records. The
\ref api-channel-sub-buf-size-count "Sub-buffer size and count" section
shows how to fine-tune the sub-buffer size and count of a channel to
virtually stop losing event records, though at the cost of greater
memory usage.

@sa The “Event record loss mode” section of
\lt_man{lttng-concepts,7}.

<h3>\anchor api-channel-sub-buf-size-count Sub-buffer size and count</h3>

A channel has one or more ring buffer which LTTng allocates according to
its configured \ref api-channel-buf-ownership-model "ownership model"
and \ref api-channel-buf-alloc-policy "allocation policy".

To set the size of each sub-buffer the ring buffers of a channel have
when you create it:

- Set the lttng_channel_attr::subbuf_size member of the
  lttng_channel::attr member of the structure you pass to
  lttng_enable_channel().

To set the number of sub-buffers each ring buffer of a channel has
when you create it:

- Set the lttng_channel_attr::num_subbuf member of the
  lttng_channel::attr member of the structure you pass to
  lttng_enable_channel().

Note that LTTng switching the current sub-buffer of a ring buffer
(marking a full one as consumable and switching to an available one for
LTTng to record the next events) introduces noticeable CPU overhead.
Knowing this, the following list presents a few practical situations
along with how to configure the sub-buffer size and count for them:

<dl>
  <dt>High event throughput
  <dd>
    In general, prefer large sub-buffers to lower the risk of losing
    event records.

    Having larger sub-buffers also ensures a lower sub-buffer
    \ref api-channel-switch-timer "switching frequency".

    The sub-buffer count is only meaningful if you create the channel in
    \ref api-channel-overwrite-mode "overwrite mode": in this case, if
    LTTng overwrites a sub-buffer, then the other sub-buffers are left
    unaltered.

  <dt>Low event throughput
  <dd>
    In general, prefer smaller sub-buffers since the risk of losing
    event records is low.

    Because LTTng emits events less frequently, the sub-buffer switching
    frequency should remain low and therefore the overhead of the tracer
    shouldn't be a problem.

  <dt>Low memory system
  <dd>
    If your target system has a low memory limit, then
    prefer fewer first, then smaller sub-buffers.

    Even if the system is limited in memory, you want to keep the
    sub-buffers as large as possible to avoid a high sub-buffer
    switching frequency.
</dl>

Note that LTTng uses <a href="https://diamon.org/ctf/">CTF</a> as its
trace format, which means event record data is very compact. For
example, the average LTTng kernel event record weights about
32&nbsp;bytes. Therefore, a sub-buffer size of 1&nbsp;MiB is considered
large.

The previous scenarios highlight the major trade-off between a few large
sub-buffers and more, smaller sub-buffers: sub-buffer switching
frequency vs. how many event records are lost in
\ref api-channel-overwrite-mode "overwrite mode".
Assuming a constant event throughput and using the overwrite mode, the
two following configurations have the same ring buffer total size:

<dl>
  <dt>Two sub-buffers of 4&nbsp;MiB each
  <dd>
    Expect a very low sub-buffer switching frequency, but if LTTng ever
    needs to overwrite a sub-buffer, then half of the event records so
    far (4&nbsp;MiB) are definitely lost.

  <dt>Eight sub-buffers of 1&nbsp;MiB each
  <dd>
    Expect four times the tracer overhead of the configuration above,
    but if LTTng needs to overwrite a sub-buffer, then only the eighth
    of event records so far (1&nbsp;MiB) are definitely lost.
</dl>

In \ref api-channel-discard-mode "discard mode", the sub-buffer count
parameter is pointless: use two sub-buffers and set their size according
to your requirements.

@sa The “Sub-buffer size and count” section of
\lt_man{lttng-concepts,7}.

<h3>\anchor api-channel-max-trace-file-size-count Maximum trace file size and count</h3>

By default, trace files can grow as large as needed.

To set the maximum size of each trace file that LTTng writes from the
ring buffers of a channel when you create it:

- Set the lttng_channel_attr::tracefile_size member of the
  lttng_channel::attr member of the structure you pass to
  lttng_enable_channel().

When the size of a trace file reaches the fixed maximum size of the
channel, LTTng creates another file to contain the next event records.
LTTng appends a file count to each trace file name in this case.

If you set the trace file size attribute when you create a channel, then
the maximum number of trace files that LTTng creates is
<em>unlimited</em> by default.

To limit the size of each trace file that LTTng writes from the
ring buffers of a channel when you create it:

- Set the lttng_channel_attr::tracefile_count member of the
  lttng_channel::attr member of the structure you pass to
  lttng_enable_channel().

When the number of trace files reaches the fixed maximum count of the
channel, LTTng overwrites the oldest trace file. This mechanism is
called <em>trace file rotation</em>.

@attention
    @parblock
    Even if you don't limit the trace file count, always assume that
    LTTng manages all the trace files of the recording session.

    In other words, there's no safe way to know if LTTng still holds a
    given trace file open with the trace file rotation feature.

    The only way to obtain an unmanaged, self-contained LTTng trace
    before you \link lttng_destroy_session_ext() destroy the
    recording session\endlink is with the
    \ref api_session_rotation "recording session rotation" feature,
    which is available since LTTng&nbsp;2.11.
    @endparblock

@sa The “Maximum trace file size and count” section of
\lt_man{lttng-concepts,7}.

<h3>\anchor api-channel-timers Timers</h3>

Each channel can have up to four optional
<strong><em>timers</em></strong>:

<dl>
  <dt>\anchor api-channel-switch-timer Switch timer
  <dd>
    When this timer expires, a sub-buffer switch happens: for each ring
    buffer of the channel, LTTng marks the current sub-buffer as
    consumable and switches to an available one to record the next
    events.

    A switch timer is useful to ensure that LTTng consumes and commits
    trace data to trace files or to a distant relay daemon
    (see \lt_man{lttng-relayd,8}) periodically in case of a low event
    throughput.

    Such a timer is also convenient when you use
    \ref api-channel-sub-buf-size-count "large sub-buffers"
    to cope with a sporadic high event throughput, even if the
    throughput is otherwise low.

    To set the period of the switch timer of a channel when you create
    it:

    - Set the lttng_channel_attr::switch_timer_interval member of the
      lttng_channel::attr member of the structure you pass to
      lttng_enable_channel().

    A channel only has a switch timer when its
    recording session is \em not in
    \ref api-session-live-mode "live mode". lttng_enable_channel()
    ignores the lttng_channel_attr::switch_timer_interval member with a
    live recording session. For a live recording session, the
    \ref api-channel-live-timer "live timer" plays the role of the
    switch timer.

  <dt>\anchor api-channel-live-timer Live timer
  <dd>
    Like the \ref api-channel-switch-timer "switch timer", but for a
    channel which belongs to a
    \ref api-session-live-mode "live" recording session.

    If this timer expires but there's no sub-buffer to consume, then
    LTTng sends a message with a timestamp to the connected relay daemon
    (see \lt_man{lttng-relayd,8}) so that its live readers can progress.

    To set the period of the live timer of a channel when you create
    its recording session:

    - Set the \lt_p{live_timer_period} parameter when you call
      lttng_session_descriptor_live_network_create() to create a
      live recording session descriptor to pass to
      lttng_create_session_ext().

    @note
        All the channels of a live recording session share the same
        live timer period.

  <dt>\anchor api-channel-read-timer Read timer
  <dd>
    When this timer expires, LTTng checks for full, consumable
    sub-buffers.

    By default, the LTTng tracers use an asynchronous message mechanism
    to signal a full sub-buffer so that a consumer daemon can consume
    it.

    When such messages must be avoided, for example in real-time
    applications, use this timer instead.

    To set the period of the read timer of a channel when you create
    it:

    - Set the lttng_channel_attr::read_timer_interval member of the
      lttng_channel::attr member of the structure you pass to
      lttng_enable_channel().

  <dt>\anchor api-channel-monitor-timer Monitor timer
  <dd>
    When this timer expires, the consumer daemon samples some channel
    statistics to evaluate the following trigger conditions:

    - \ref api_trigger_cond_session_consumed_size "Recording session consumed data size becomes greater than".
    - \ref api_trigger_cond_buffer_usage "Channel buffer usage becomes greater/less than".
    - \ref api_trigger_cond_buffer_usage "Channel buffer usage becomes less than".

    If you disable the monitor timer of a channel&nbsp;\lt_var{C}, then:

    - The consumed data size value of the recording session
      of&nbsp;\lt_var{C} could be wrong for triggers with a
      “recording session consumed data size becomes greater than”
      condition: the consumed data size of&nbsp;\lt_var{C} won't be
      part of the grand total.

    - Triggers with a
      “channel buffer usage becomes greater than” or
      “channel buffer usage becomes less than” condition
      for&nbsp;\lt_var{C} will never fire.

      See \ref api_trigger to learn more about triggers.

    To set the period of the monitor timer of a channel when you create
    it:

    - Call lttng_channel_set_monitor_timer_interval() with the
      #lttng_channel structure you pass to lttng_enable_channel().
</dl>

@sa The “Timers” section of \lt_man{lttng-concepts,7}.

@defgroup api_rer Recording event rule API
@ingroup api_channel

<h1>Concepts</h1>

An <em>instrumentation point</em> is a point, within a piece of
software, which, when executed, creates an LTTng <em>event</em>.
See \ref api_inst_pt to learn how to list the available instrumentation
points.

An <em>event rule</em> is a set of \ref api-rer-conds "conditions" to
match a set of events.

A <strong><em>recording event rule</em></strong> is a specific type of
event rule of which the action is to serialize and write the matched
event as an <em>event record</em> to a sub-buffer of its attached
\lt_obj_channel.

An event record has a \ref api-rer-er-name "name" and fields.

When LTTng creates an event&nbsp;\lt_var{E}, a recording event
rule&nbsp;\lt_var{ER} is said to <em>match</em>&nbsp;\lt_var{E}
when&nbsp;\lt_var{E} satisfies \em all the conditions
of&nbsp;\lt_var{ER}. This concept is similar to a regular expression
which matches a set of strings.

When a recording event rule matches an event, LTTng \em emits the event,
therefore attempting to record it.

@attention
    @parblock
    The event creation and emission processes are \em documentation
    concepts to help understand the journey from an instrumentation
    point to an event record.

    The actual creation of an event can be costly because LTTng needs to
    evaluate the arguments of the instrumentation point.

    In practice, LTTng implements various optimizations for the
    \link #LTTNG_DOMAIN_KERNEL Linux kernel\endlink and
    \link #LTTNG_DOMAIN_UST user space\endlink \lt_obj_domains
    to avoid actually creating an event when the tracer knows, thanks to
    properties which are independent from the event payload and current
    \link #lttng_event_context_type context\endlink, that it would never
    emit such an event. Those properties are:

    - The \ref api-rer-conds-inst-pt-type "instrumentation point type".

    - The \ref api-rer-conds-event-name "instrumentation point name" (or
      event name).

    - The \ref api-rer-conds-ll "instrumentation point log level".

    - The \link lttng_event::enabled status\endlink (enabled or
      disabled) of the rule itself.

    - The \link lttng_channel::enabled status\endlink (enabled or
      disabled) of the \lt_obj_channel containing the rule.

    - The \link lttng_session::enabled activity\endlink (started or
      stopped) of the \lt_obj_session containing the rule.

    - Whether or not the process for which LTTng would create the event
      is \ref api_proc_filter "allowed to record events".

    In other words: if, for a given instrumentation point&nbsp;\lt_var{IP},
    the LTTng tracer knows that it would never emit an event,
    executing&nbsp;\lt_var{IP} represents a simple boolean variable check
    and, for a \link #LTTNG_DOMAIN_KERNEL Linux kernel\endlink
    \lt_obj_rer, a few current process attribute checks.
    @endparblock

You always attach a recording event rule to a
\lt_obj_channel, which belongs to
a \lt_obj_session, when you
\link lttng_enable_event_with_exclusions() create it\endlink.
A channel owns recording event rules.

When multiple matching recording event rules are attached to the same
channel, LTTng attempts to serialize and record the matched event
<em>once</em>.

@image html event-rule.png "Logical path from an instrumentation point to an event record."

As of LTTng-tools&nbsp;\lt_version_maj_min, you cannot remove a
recording event rule: it exists as long as its \lt_obj_session exists.

<h1>Operations</h1>

The recording event rule operations are:

<table>
  <tr>
    <th>Operation
    <th>Means
  <tr>
    <td>Creation
    <td>
      -# Call lttng_event_create() to create an initial
         \link #lttng_event recording event rule descriptor\endlink.

      -# Set the properties of the recording event rule descriptor of
         step&nbsp;1 through direct members or with dedicated setters.

         See the property table below.

      -# Create a \link #lttng_handle recording session handle\endlink
         structure to specify the name of the recording session and the
         tracing domain of the recording event rule to create.

      -# Call lttng_enable_event_with_exclusions() with the recording
         session handle of step&nbsp;3, the recording event rule
         descriptor of step&nbsp;1, the name of a
         \lt_obj_channel to which to attach the
         created recording event rule, and, depending on the selected
         function, other properties to create the rule.

      -# Destroy the recording session handle with
         lttng_destroy_handle() and the recording event rule descriptor
         with lttng_event_destroy().

      @sa \lt_man{lttng-enable-event,1}
  <tr>
    <td>Property access
    <td>
      See:

      - The members of #lttng_event
      - lttng_event_get_userspace_probe_location()
      - lttng_event_set_userspace_probe_location()
      - lttng_event_get_filter_expression()
      - lttng_event_get_exclusion_name_count()
      - lttng_event_get_exclusion_name()

      @sa \ref api-rer-conds "Recording event rule conditions".
  <tr>
    <td>Enabling
    <td>
      With an #lttng_event instance which comes from
      lttng_list_events(), use lttng_enable_event().

      Otherwise, use lttng_enable_event_with_exclusions().

      @sa \lt_man{lttng-enable-event,1}
  <tr>
    <td>Disabling
    <td>
      Use lttng_disable_event() or lttng_disable_event_ext().

      @sa \lt_man{lttng-disable-event,1}
</table>

<h1>\anchor api-rer-conds Recording event rule conditions</h1>

For LTTng to emit and record an event&nbsp;\lt_var{E},&nbsp;\lt_var{E}
must satisfy \em all the conditions of a recording event
rule&nbsp;\lt_var{ER}, that is:

<dl>
  <dt>Explicit conditions
  <dd>
    You set the following conditions when you
    \link lttng_enable_event_with_exclusions() create\endlink
    \lt_var{ER} from some
    \link #lttng_event recording event rule descriptor\endlink
    \c event_rule (#lttng_event).

    <table>
      <tr>
        <th>Name
        <th>Description
      <tr>
        <td>
          \anchor api-rer-conds-inst-pt-type
          \ref api-rer-conds-inst-pt-type "Instrumentation point type"
        <td>
          \lt_var{E} satisfies the instrumentation point type condition
          of \lt_var{ER} if the instrumentation point from which LTTng
          creates&nbsp;\lt_var{E} is, depending on the
          \lt_obj_domain which contains \lt_var{ER}:

          <dl>
            <dt>#LTTNG_DOMAIN_KERNEL
            <dd>
              Depending on
              \link lttng_event::type <code>event_rule.type</code>\endlink:

              <dl>
                <dt>#LTTNG_EVENT_TRACEPOINT
                <dd>
                  An LTTng kernel tracepoint, that is, a statically
                  defined point in the source code of the kernel image
                  or of a kernel module with LTTng kernel tracer macros.

                  @sa lttng_list_tracepoints()

                <dt>#LTTNG_EVENT_SYSCALL
                <dd>
                  The entry and exit of a Linux kernel system call.

                  @sa lttng_list_syscalls()

                <dt>#LTTNG_EVENT_PROBE
                <dd>
                  A Linux
                  <a href="https://www.kernel.org/doc/html/latest/trace/kprobes.html">kprobe</a>,
                  that is, a single probe dynamically placed in the
                  compiled kernel code.

                  \link lttng_event_attr_u::probe
                  <code>event_rule.attr.probe</code>\endlink
                  indicates the kprobe location,
                  while \link lttng_event::name
                  <code>event_rule.name</code>\endlink
                  is the name of the created kprobe instrumentation
                  point (future event name).

                  The payload of a Linux kprobe event is empty.

                <dt>#LTTNG_EVENT_FUNCTION
                <dd>
                  A Linux
                  <a href="https://www.kernel.org/doc/html/latest/trace/kprobes.html">kretprobe</a>,
                  that is, two probes dynamically placed at the entry
                  and exit of a function in the compiled kernel code.

                  \link lttng_event_attr_u::probe
                  <code>event_rule.attr.probe</code>\endlink
                  indicates the kretprobe location,
                  while \link lttng_event::name
                  <code>event_rule.name</code>\endlink
                  is the name of the created kretprobe instrumentation
                  point (future event name).

                  The payload of a Linux kretprobe event is empty.

                <dt>#LTTNG_EVENT_USERSPACE_PROBE
                <dd>
                  A Linux
                  <a href="https://www.kernel.org/doc/html/latest/trace/uprobetracer.html">user space probe</a>,
                  that is, a single probe dynamically placed at the
                  entry of a compiled user space application/library
                  function through the kernel.

                  Set and get the location of the user space probe with
                  lttng_event_set_userspace_probe_location() and
                  lttng_event_get_userspace_probe_location().

                  \link lttng_event::name <code>event_rule.name</code>\endlink
                  is the name of the created user space probe
                  instrumentation point (future event name).

                  The payload of a Linux user space probe
                  event is empty.
              </dl>

            <dt>#LTTNG_DOMAIN_UST
            <dd>
              An LTTng user space tracepoint, that is, a statically
              defined point in the source code of a C/C++
              application/library with LTTng user space tracer macros.

              \link lttng_event::type <code>event_rule.type</code>\endlink
              must be #LTTNG_EVENT_TRACEPOINT.

              @sa lttng_list_tracepoints()

            <dt>#LTTNG_DOMAIN_JUL
            <dt>#LTTNG_DOMAIN_LOG4J
            <dt>#LTTNG_DOMAIN_PYTHON
            <dd>
              A Java/Python logging statement.

              \link lttng_event::type <code>event_rule.type</code>\endlink
              must be #LTTNG_EVENT_TRACEPOINT.

              @sa lttng_list_tracepoints()
          </dl>
      <tr>
        <td>
          \anchor api-rer-conds-event-name
          \ref api-rer-conds-event-name "Event name"
        <td>
          An event&nbsp;\lt_var{E} satisfies the event name condition
          of&nbsp;\lt_var{ER} if the two following statements are
          \b true:

          - \link lttng_event::name <code>event_rule.name</code>\endlink
            matches, depending on
            \link lttng_event::type <code>event_rule.type</code>\endlink
            (see \ref api-rer-conds-inst-pt-type "Instrumentation point type"
            above):

            <dl>
              <dt>#LTTNG_EVENT_TRACEPOINT
              <dd>
                The full name of the LTTng tracepoint or Java/Python
                logger from which LTTng creates&nbsp;\lt_var{E}.

                Note that the full name of a
                \link #LTTNG_DOMAIN_UST user space\endlink tracepoint is
                <code><em>PROVIDER</em>:<em>NAME</em></code>, where
                <code><em>PROVIDER</em></code> is the tracepoint
                provider name and <code><em>NAME</em></code> is the
                tracepoint name.

              <dt>#LTTNG_EVENT_SYSCALL
              <dd>
                The name of the system call, \em without any
                <code>sys_</code> prefix, from which LTTng
                creates&nbsp;\lt_var{E}.
            </dl>

            @sa \ref api-rer-er-name "Event record name".

          - If the \lt_obj_domain
            containing&nbsp;\lt_var{ER} is #LTTNG_DOMAIN_UST:
            none of the event name exclusion patterns of
            \c event_rule matches the full name of the user
            space tracepoint from which LTTng creates&nbsp;\lt_var{E}.

            Set the event name exclusion patterns of
            \c event_rule when you call
            lttng_enable_event_with_exclusions().

            Get the event name exclusion patterns of
            \c event_rule with
            lttng_event_get_exclusion_name_count() and
            lttng_event_get_exclusion_name().

          This condition is only meaningful when
          \link lttng_event::type <code>event_rule.type</code>\endlink
          is #LTTNG_EVENT_TRACEPOINT or
          #LTTNG_EVENT_SYSCALL: it's always satisfied for the other
          \ref api-rer-conds-inst-pt-type "instrumentation point types".

          In all cases,
          \link lttng_event::name <code>event_rule.name</code>\endlink
          and the event name exclusion patterns of
          \c event_rule are <em>globbing patterns</em>: the
          <code>*</code> character means “match anything”. To match a
          literal <code>*</code> character, use <code>\\*</code>.
      <tr>
        <td>
          \anchor api-rer-conds-ll
          \ref api-rer-conds-ll "Instrumentation point log level"
        <td>
          An event&nbsp;\lt_var{E} satisfies the instrumentation point
          log level condition of&nbsp;\lt_var{ER} if, depending on
          \link lttng_event::loglevel_type <code>event_rule.loglevel_type</code>\endlink,
          the log level of the LTTng user space tracepoint or
          logging statement from which LTTng creates&nbsp;\lt_var{E}
          is:

          <dl>
            <dt>#LTTNG_EVENT_LOGLEVEL_ALL
            <dd>
              Anything (the condition is always satisfied).

            <dt>#LTTNG_EVENT_LOGLEVEL_RANGE
            <dd>
              At least as severe as
              \link lttng_event::loglevel <code>event_rule.loglevel</code>\endlink.

            <dt>#LTTNG_EVENT_LOGLEVEL_SINGLE
            <dd>
              Exactly
              \link lttng_event::loglevel <code>event_rule.loglevel</code>\endlink.
          </dl>

          This condition is only meaningful when the \lt_obj_domain
          containing&nbsp;\lt_var{ER} is \em not #LTTNG_DOMAIN_KERNEL:
          it's always satisfied for #LTTNG_DOMAIN_KERNEL.
      <tr>
        <td>
          \anchor api-rer-conds-filter
          \ref api-rer-conds-filter "Event payload and context filter"
        <td>
          An event&nbsp;\lt_var{E} satisfies the event payload and
          context filter condition of&nbsp;\lt_var{ER} if
          \c event_rule has no filter expression or if its filter
          expression \lt_var{EXPR} evaluates to \b true
          when LTTng creates&nbsp;\lt_var{E}.

          This condition is only meaningful when
          \link lttng_event::type <code>event_rule.type</code>\endlink
          is #LTTNG_EVENT_TRACEPOINT or #LTTNG_EVENT_SYSCALL:
          it's always satisfied for the other
          \ref api-rer-conds-inst-pt-type "instrumentation point types".

          Set the event payload and context filter expression of
          \c event_rule when you call
          lttng_enable_event_with_exclusions().

          Get the event payload and context filter expression of
          \c event_rule descriptor with
          lttng_event_get_filter_expression().

          @include{doc} dox/filter-expr.dox
    </table>

  <dt>Implicit conditions
  <dd>
    - \lt_var{ER} itself is \link lttng_event::enabled enabled\endlink.

      A recording event rule is enabled on
      \link lttng_enable_event_with_exclusions() creation\endlink.

      @sa lttng_enable_event() --
          Creates or enables a recording event rule.
      @sa lttng_disable_event_ext() --
          Disables a recording event rule.

    - The \lt_obj_channel which contains&nbsp;\lt_var{ER} is
      \link lttng_channel::enabled enabled\endlink.

      A channel is enabled on
      \link lttng_enable_channel() creation\endlink.

      @sa lttng_enable_channel() --
          Creates or enables a channel.
      @sa lttng_disable_channel() --
          Disables a channel.

    - The \lt_obj_session which contains&nbsp;\lt_var{ER} is
      \link lttng_session::enabled active\endlink (started).

      A recording session is inactive (stopped) on
      \link lttng_create_session_ext() creation\endlink.

      @sa lttng_start_tracing() --
          Starts a recording session.
      @sa lttng_stop_tracing() --
          Stops a recording session.

    - The process for which LTTng creates&nbsp;\lt_var{E} is
      \ref api_proc_filter "allowed to record events".

      All processes are allowed to record events on recording session
      \link lttng_create_session_ext() creation\endlink.
</dl>

<h1>\anchor api-rer-er-name Event record name</h1>

When LTTng records an event&nbsp;\lt_var{E}, the resulting event record
has a name which depends on the
\ref api-rer-conds-inst-pt-type "instrumentation point type condition"
of the recording event rule&nbsp;\lt_var{ER} which matched&nbsp;\lt_var{E}
as well as on the \lt_obj_domain which contains&nbsp;\lt_var{ER}:

<table>
  <tr>
    <th>Tracing domain
    <th>Instrumentation point type
    <th>Event record name
  <tr>
    <td>#LTTNG_DOMAIN_KERNEL or #LTTNG_DOMAIN_UST
    <td>#LTTNG_EVENT_TRACEPOINT
    <td>
      Full name of the tracepoint from which LTTng creates&nbsp;\lt_var{E}.

      Note that the full name of a
      \link #LTTNG_DOMAIN_UST user space\endlink tracepoint is
      <code><em>PROVIDER</em>:<em>NAME</em></code>, where
      <code><em>PROVIDER</em></code> is the tracepoint provider name and
      <code><em>NAME</em></code> is the tracepoint name.
  <tr>
    <td>#LTTNG_DOMAIN_JUL
    <td>#LTTNG_EVENT_TRACEPOINT
    <td>
      <code>lttng_jul:event</code>

      Such an event record has a string field <code>logger_name</code>
      which contains the name of the \lt_jul
      logger from which LTTng creates&nbsp;\lt_var{E}.
  <tr>
    <td>#LTTNG_DOMAIN_LOG4J
    <td>#LTTNG_EVENT_TRACEPOINT
    <td>
      <code>lttng_log4j:event</code>

      Such an event record has a string field <code>logger_name</code>
      which contains the name of the \lt_log4j1 logger
      from which LTTng creates&nbsp;\lt_var{E}.
  <tr>
    <td>#LTTNG_DOMAIN_LOG4J2
    <td>#LTTNG_EVENT_TRACEPOINT
    <td>
      <code>lttng_log4j2:event</code>

      Such an event record has a string field <code>logger_name</code>
      which contains the name of the \lt_log4j2 logger
      from which LTTng creates&nbsp;\lt_var{E}.
  <tr>
    <td>#LTTNG_DOMAIN_PYTHON
    <td>#LTTNG_EVENT_TRACEPOINT
    <td>
      <code>lttng_python:event</code>

      Such an event record has a string field <code>logger_name</code>
      which contains the name of the Python logger from which LTTng
      creates&nbsp;\lt_var{E}.
  <tr>
    <td>#LTTNG_DOMAIN_KERNEL
    <td>#LTTNG_EVENT_SYSCALL
    <td>
      Location:

      <dl>
        <dt>Entry
        <dd>
          <code>syscall_entry_<em>NAME</em></code>, where
          <code><em>NAME</em></code> is the name of the system call from
          which LTTng creates&nbsp;\lt_var{E}, \em without any
          <code>sys_</code> prefix.

        <dt>Exit
        <dd>
          <code>syscall_exit_<em>NAME</em></code>, where
          <code><em>NAME</em></code> is the name of the system call from
          which LTTng creates&nbsp;\lt_var{E}, \em without any
          <code>sys_</code> prefix.
      </dl>
  <tr>
    <td>#LTTNG_DOMAIN_KERNEL
    <td>#LTTNG_EVENT_PROBE or  #LTTNG_EVENT_USERSPACE_PROBE
    <td>
      The lttng_event::name member of the
      descriptor you used to create \lt_var{ER} with
      lttng_enable_event_with_exclusions().
  <tr>
    <td>#LTTNG_DOMAIN_KERNEL
    <td>#LTTNG_EVENT_FUNCTION
    <td>
      Location:

      <dl>
        <dt>Entry
        <dd><code><em>NAME</em>_entry</code>

        <dt>Exit
        <dd><code><em>NAME</em>_exit</code>
      </dl>

      where <code><em>NAME</em></code> is the lttng_event::name member
      of the descriptor you used to create
      \lt_var{ER} with lttng_enable_event_with_exclusions().
</table>

@defgroup api_proc_filter Process filter API
@ingroup api_session

@warning
    @parblock
    The documentation of the process filter API is
    <strong>missing</strong>.

    See <code>lttng/tracker.h</code>.
    @endparblock

@defgroup api_session_clear Recording session clearing API
@ingroup api_session

This API makes it possible to clear a \lt_obj_session, that is, to
delete the contents of its tracing buffers and/or of all its
\ref api-session-local-mode "local" and
\ref api-session-net-mode "streamed" trace data.

To clear a recording session:

-# Call lttng_clear_session(), passing the name of the recording session
   to clear.

   This function initiates a clearing operation, returning immediately.

   This function can set a pointer to a
   \link #lttng_clear_handle clearing handle\endlink
   so that you can wait for the completion of the
   operation. Without such a handle, you can't know when the clearing
   operation completes and whether or not it does successfully.

-# <strong>If you have a clearing handle from step&nbsp;1</strong>,
   then:

   -# Call lttng_clear_handle_wait_for_completion() to wait for the
      completion of the clearing operation.

   -# Call lttng_clear_handle_get_result() to get whether or not the
      clearing operation successfully completed.

   -# Destroy the clearing handle with lttng_clear_handle_destroy().

@sa \lt_man{lttng-clear,1}

@defgroup api_session_snapshot Recording session snapshot API
@ingroup api_session

@warning
    @parblock
    The documentation of the recording session snapshot API is
    <strong>incomplete</strong>.

    The text below shows the typical usage of this API, but the
    types, enumerators, and functions of
    <code>lttng/snapshot.h</code> aren't documented
    individually.
    @endparblock

A <strong><em>recording session snapshot</em></strong> is a dump,
local or remote, of the
current ring buffers of all the \lt_obj_channels of a \lt_obj_session,
\em without \ref api_session_clear "clearing" them.

Unlike recording session \ref api_session_rotation "rotations",
snapshots may overlap: successive snapshots may contain the same
event records.

@image html snapshot.png "Recording session snapshot."

See \ref api_session_descr,
lttng_session_descriptor_snapshot_create(),
lttng_session_descriptor_snapshot_local_create(),
and lttng_session_descriptor_snapshot_network_create()
to learn how to create a recording session in snapshot mode.

When you create a recording session descriptor with
lttng_session_descriptor_snapshot_create(), the recording session which
lttng_create_session_ext() creates from it has no default
\ref api-session-snapshot-output "snapshot output":
you need to either set one with lttng_snapshot_add_output() or
provide one when you take a snapshot with lttng_snapshot_record().

<h1>\anchor api-session-snapshot-output Snapshot output API usage</h1>

A recording session may have zero or one
<strong><em>default snapshot output</em></strong>.

To set the default snapshot output of a recording session:

-# Create a snapshot output descriptor with
   lttng_snapshot_output_create().

-# Configure the descriptor as needed:

   - Set a custom snapshot ID with lttng_snapshot_output_set_id().

   - Set the name with lttng_snapshot_output_set_name().

   - Set the maximum total size (bytes) of snapshot trace files with
     lttng_snapshot_output_set_size().

   - Specify the output destination with one of:

     <dl>
       <dt>Local filesystem path
       <dd>lttng_snapshot_output_set_local_path()

       <dt>Single remote URL (LTTng relay daemon; see \lt_man{lttng-relayd,8})
       <dd>lttng_snapshot_output_set_network_url()

       <dt>Separate control/data URLs
       <dd>lttng_snapshot_output_set_network_urls()

       <dt>Individual control and data URLs
       <dd>
         lttng_snapshot_output_set_ctrl_url() and
         lttng_snapshot_output_set_data_url()
     </dl>

     See \ref api-session-url "Output URL format" to learn more about
     output URLs.

-# Set the default snapshot output of the targeted recording session
   from the descriptor with
   lttng_snapshot_add_output().

-# When you're done with the descriptor, destroy it with
   lttng_snapshot_output_destroy().

   This only destroys the descriptor; it doesn't remove the default
   snapshot output of the targeted recording session (use
   lttng_snapshot_del_output() for this).

To inspect the existing snapshot outputs of a given recording session:

-# Get the list of snapshot output descriptors for the recording session
   with lttng_snapshot_list_output().

-# Iterate the list of step&nbsp;1 with
   lttng_snapshot_output_list_get_next() until it returns \c NULL.

   With a (borrowed) snapshot output descriptor, you may get:

   - Its ID with lttng_snapshot_output_get_id().

   - Its name with lttng_snapshot_output_get_name() (borrowed).

   - The maximum total size (bytes) of snapshot trace files
     with lttng_snapshot_output_get_maxsize().

   - Its \ref api-session-url "control and data URLs" with
     lttng_snapshot_output_get_ctrl_url()
     and lttng_snapshot_output_get_data_url() (borrowed).

-# When you're done with the snapshot output descriptor list, destroy it
   with lttng_snapshot_output_list_destroy().

<h1>Snapshot API usage</h1>

To take a snapshot of a recording session:

-# Ensure that the targeted recording session has a
   \ref api-session-snapshot-output "default snapshot output",
   or create a snapshot output descriptor to pass directly to
   lttng_snapshot_record().

-# Call lttng_snapshot_record().

   Passing \c NULL as the output uses the default snapshot output of the
   targeted recording session.

   The \lt_p{wait} parameter is currently ignored: the call always
   blocks until the snapshot operation completes.

   The function returns&nbsp;0 on success, or a negative
   #lttng_error_code enumerator on error.

@note
    The \ref api_trigger_action_snapshot “take recording session snapshot”
    trigger action can also take a snapshot.

@sa
    - \lt_man{lttng-snapshot,1}
    - \lt_man{lttng-concepts,7}

@defgroup api_session_rotation Recording session rotation API
@ingroup api_session

@warning
    @parblock
    The documentation of the recording session rotation API is
    <strong>incomplete</strong>.

    The text below shows the typical usage of this API, but the
    types, enumerators, and functions of
    <code>lttng/rotation.h</code> aren't documented
    individually.
    @endparblock

A <strong><em>recording session rotation</em></strong> is the action of
archiving the <em>current trace chunk</em> of a \lt_obj_session to the
file system.

Once LTTng archives a trace chunk, it doesn't manage it anymore: you
can read it, modify it, move it, or remove it.

@image html rotation.png "Recording session rotation."

<h1>Trace chunk archive</h1>

A <strong><em>trace chunk archive</em></strong> is a collection of
metadata and data stream files which form a self-contained LTTng trace.
See the “Trace chunk naming” section of \lt_man{lttng-concepts,7} to
learn how LTTng names a trace chunk archive directory.

The current trace chunk of a given recording session includes:

- The stream files which LTTng already wrote to the file system, and
  which are \em not part of a previously archived trace chunk, since the
  most recent event amongst:

  - The first time the recording session was started.

    @sa
        - lttng_start_tracing()
        - \ref api_trigger_action_start_session
        - \lt_man{lttng-start,1}

  - The last rotation, performed with:

    - lttng_rotate_session().

      @sa \lt_man{lttng-rotate,1}

    - A rotation schedule previously set with
      lttng_session_add_rotation_schedule().

      @sa \lt_man{lttng-enable-rotation,1}

    - An executed
      \ref api_trigger_action_rotate “rotate recording session snapshot”
      trigger action.

- The content of all the <em>non-flushed</em> sub-buffers of the
  \lt_obj_channels of the recording session.

<h1>Immediate rotation API usage</h1>

To perform an \b immediate recording session rotation:

-# Call lttng_rotate_session(), passing:

   - The name of the recording session to rotate.

   - An optional, immediate rotation descriptor
     (or \c NULL to use default options).

   - An #lttng_rotation_handle (rotation handle) pointer; on success,
     lttng_rotate_session() returns&nbsp;0 and sets the handle.

-# With the rotation handle of step&nbsp;1:

   -# Query the rotation state (enumerator of #lttng_rotation_state)
      with lttng_rotation_handle_get_state() until the current state
      is #LTTNG_ROTATION_STATE_COMPLETED.

   -# Borrow the resulting
      \ref api_session_trace_archive_loc "trace chunk archive location"
      with lttng_rotation_handle_get_archive_location().

   -# When you're done with the rotation handle, destroy it
      with lttng_rotation_handle_destroy().

@sa \lt_man{lttng-rotate,1}

<h1>Rotation schedule API usage</h1>

A recording session <strong><em>rotation schedule</em></strong> allows
automatic rotation based on a size or time threshold.

To add a rotation schedule to a given recording session:

-# Create and configure a rotation schedule descriptor with one of:

   <dl>
     <dt>Based on current trace chunk size
     <dd>
       Create with lttng_rotation_schedule_size_threshold_create().

       Then, set the size (bytes) threshold with
       lttng_rotation_schedule_size_threshold_set_threshold().

     <dt>Based on time
     <dd>
       Create with lttng_rotation_schedule_periodic_create().

       Then, set the period (µs) with
       lttng_rotation_schedule_periodic_set_period().
   </dl>

-# Add the rotation schedule to the targeted recording session
   using the descriptor of step&nbsp;1
   with lttng_session_add_rotation_schedule().

   @note
       As of LTTng-tools&nbsp;\lt_version_maj_min, you may only add
       one rotation schedule of each type to a given recording
       session.

-# When you're done with the rotation schedule descriptor,
   destroy it with lttng_rotation_schedule_destroy().

   This function doesn't cancel the rotation schedule: use
   lttng_session_remove_rotation_schedule() to remove a rotation
   schedule from a recording session.

To inspect the existing rotation schedules of a given recording session:

-# Get the list of rotation schedules of the recording session with
   lttng_session_list_rotation_schedules().

-# Borrow a rotation schedule from the list of step&nbsp;1 with
   lttng_rotation_schedules_get_count() and
   lttng_rotation_schedules_get_at_index().

   With a rotation schedule, you may get:

   - Its type with lttng_rotation_schedule_get_type()
     (an #lttng_rotation_schedule_type enumerator).

   - Depending on its type:

     <dl>
       <dt>#LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD
       <dd>
         Its current trace chunk size (bytes) threshold
         with lttng_rotation_schedule_size_threshold_get_threshold().

       <dt>#LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC
       <dd>
         Its period (µs) with
         lttng_rotation_schedule_periodic_get_period().
     </dl>

-# When you're done with the rotation schedule list, destroy it
   with lttng_rotation_schedules_destroy().

@sa
    - \lt_man{lttng-enable-rotation,1}
    - \lt_man{lttng-disable-rotation,1}

@defgroup api_session_trace_archive_loc Trace chunk archive location API
@ingroup api_session_rotation

@warning
    @parblock
    The documentation of the trace chunk archive API is
    <strong>incomplete</strong>.

    The text below shows the typical usage of this API, but the
    types, enumerators, and functions of
    <code>lttng/location.h</code> aren't documented
    individually.
    @endparblock

A <strong><em>trace chunk archive location</em></strong> indicates
where LTTng wrote a \lt_obj_session trace chunk archive after a
recording session \ref api_session_rotation "rotation" or
\link lttng_destroy_session_ext() destruction\endlink.

The type of a trace chunk archive location is
#lttng_trace_archive_location.

A trace chunk archive location can refer to a local directory or to
a remote LTTng relay daemon (see \lt_man{lttng-relayd,8}).

To inspect an existing trace chunk archive location, call
lttng_trace_archive_location_get_type() to get its type
(enumerator of #lttng_trace_archive_location_type).
Depending on the returned type:

<table>
  <tr>
    <th>Location type
    <th>Type enumerator
    <th>Property access
  <tr>
    <td>Local filesystem location
    <td>#LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL
    <td>
      Borrow the absolute directory path with
      lttng_trace_archive_location_local_get_absolute_path().
  <tr>
    <td>Remote location (LTTng relay daemon)
    <td>#LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
    <td>
      Retrieve:

      - The protocol type (enumerator of
        #lttng_trace_archive_location_relay_protocol_type) with
        lttng_trace_archive_location_relay_get_protocol_type().

      - The relay daemon host (hostname or IP address) with
        lttng_trace_archive_location_relay_get_host() (borrowed).

      - The control port with
        lttng_trace_archive_location_relay_get_control_port().

      - The data port with
        lttng_trace_archive_location_relay_get_data_port().

      - The path, relative to the output directory of the relay daemon,
        with lttng_trace_archive_location_relay_get_relative_path()
        (borrowed).
</table>

Each accessor returns an #lttng_trace_archive_location_status enumerator
amongst:

<dl>
  <dt>#LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK
  <dd>Success.

  <dt>#LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID
  <dd>Unsatisfied precondition.

  <dt>#LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_ERROR
  <dd>Other error.
</dl>

@defgroup api_session_save_load Recording session saving and loading API
@ingroup api_session

@warning
    @parblock
    The documentation of the recording session saving and loading API is
    <strong>missing</strong>.

    See <code>lttng/save.h</code> and <code>lttng/load.h</code>.
    @endparblock

@defgroup api_inst_pt Instrumentation point listing API

The lttng_list_tracepoints() and lttng_list_syscalls() functions set a
pointer to an array of
<strong><em>\ref api-rer-inst-pt-descr "instrumentation point descriptors"</em></strong>.

With those two functions, you can get details about the available
LTTng tracepoints, Java/Python loggers, and Linux kernel system calls,
as long as you can
\ref api-gen-sessiond-conn "connect to a session daemon".
You can then use the discovered information to create corresponding
\lt_obj_rers so that you can record the events
which LTTng creates from instrumentation points.

See \ref api_rer to learn more about instrumentation points, events,
event records, and recording event rules.

@defgroup api_trigger Trigger API

A trigger associates a \ref api_trigger_cond "condition" to
an \ref api_trigger_action "action".

When the condition of a trigger is satisfied, LTTng attempts to execute
its action.

A trigger belongs to a session daemon (see
\lt_man{lttng-sessiond,8} and
\ref api-gen-sessiond-conn "Session daemon connection"), \em not to a
specific \lt_obj_session.

To create and register a trigger:

-# Create the \ref api_trigger_cond "condition" and
   \ref api_trigger_action "action" objects.

   If you need LTTng to execute more than one action when
   the trigger condition is satisfied, then use an
   \ref api_trigger_action_list "action list".

-# Create the trigger object with lttng_trigger_create(), passing the
   condition and action of step&nbsp;1.

-# Register the trigger to the connected session daemon with one of:

   <dl>
     <dt>Let LTTng assign an automatic trigger name
     <dd>lttng_register_trigger_with_automatic_name()

     <dt>Set a unique trigger name
     <dd>lttng_register_trigger_with_name()
   </dl>

-# When you're done with the trigger object, destroy it
   with lttng_trigger_destroy().

For a given session daemon, each Unix user has its own, private
triggers. Note, however, that the \c root Unix user may, for the root
session daemon:

- Add a trigger as another Unix user and
  remove a trigger which belongs to another Unix user.

  See lttng_trigger_set_owner_uid().

- List all the triggers, regardless of their owner.

Unregister a trigger with lttng_unregister_trigger().

To list the available triggers your Unix user has access to:

-# Get the trigger list with lttng_list_triggers().

-# Get triggers from the list with lttng_triggers_get_count()
   and lttng_triggers_get_at_index().

   Get the condition and action of a such a trigger with
   lttng_trigger_get_const_condition() and
   lttng_trigger_get_const_action().

-# When you're done with the trigger list,
   destroy it with lttng_triggers_destroy().

@sa
    - The “TRIGGER” section of \lt_man{lttng-concepts,7}.
    - \lt_man{lttng-add-trigger,1}
    - \lt_man{lttng-list-triggers,1}
    - \lt_man{lttng-remove-trigger,1}

@defgroup api_trigger_cond Trigger condition API
@ingroup api_trigger

A <strong><em>trigger condition</em></strong> is the part of a
\ref api_trigger "trigger" which must be satisfied for LTTng to execute
its \ref api_trigger_action "action".

As of LTTng-tools&nbsp;\lt_version_maj_min, the following trigger
conditions are available:

<table>
  <tr>
    <th>Condition type
    <th>Type enumerator
    <th>Creation function
  <tr>
    <td>\ref api_trigger_cond_session_consumed_size "Recording session consumed data size becomes greater than"
    <td>#LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE
    <td>lttng_condition_session_consumed_size_create()
  <tr>
    <td>\ref api_trigger_cond_buffer_usage "Channel buffer usage becomes greater than"
    <td>#LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH
    <td>lttng_condition_buffer_usage_high_create()
  <tr>
    <td>\ref api_trigger_cond_buffer_usage "Channel buffer usage becomes less than"
    <td>#LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
    <td>lttng_condition_buffer_usage_low_create()
  <tr>
    <td>\ref api_trigger_cond_rotation "Recording session rotation starts"
    <td>#LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
    <td>lttng_condition_session_rotation_ongoing_create()
  <tr>
    <td>\ref api_trigger_cond_rotation "Recording session rotation finishes"
    <td>#LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
    <td>lttng_condition_session_rotation_completed_create()
  <tr>
    <td>\ref api_trigger_cond_er_matches "Event rule matches"
    <td>#LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES
    <td>lttng_condition_event_rule_matches_create()
</table>

Get the type of a trigger condition with lttng_condition_get_type().

Destroy a trigger condition with lttng_condition_destroy().

<h1>\anchor api-trigger-cond-eval Evaluation</h1>

When a trigger with a some condition&nbsp;\lt_var{C} fires,
LTTng can capture some data. With the
\link api_trigger_action_notify “notify”\endlink action, a user
may then read the captured value(s) from the \b evaluation
of&nbsp;\lt_var{C} (through lttng_notification_get_evaluation()).

The opaque type of a trigger condition evaluation is #lttng_evaluation.

Trigger condition and condition evaluation objects share the same
\link #lttng_condition_type type enumeration\endlink: get the
condition type of an evaluation with lttng_evaluation_get_type().

The available captured values are, depending on the trigger condition
type:

<table>
  <tr>
    <th>Condition type(s)
    <th>Captured value(s)
    <th>Access
  <tr>
    <td>#LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE
    <td>Total \lt_obj_session consumed size.
    <td>lttng_evaluation_session_consumed_size_get_consumed_size()
  <tr>
    <td>
      #LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH and
      #LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW
    <td>\lt_obj_c_channel buffer usage ratio and size.
    <td>
      lttng_evaluation_buffer_usage_get_usage_ratio() and
      lttng_evaluation_buffer_usage_get_usage()
  <tr>
    <td>#LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING
    <td>\lt_obj_c_session rotation ID.
    <td>lttng_evaluation_session_rotation_get_id()
  <tr>
    <td>#LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED
    <td>\lt_obj_c_session rotation ID and resulting trace archive location.
    <td>
      lttng_evaluation_session_rotation_get_id() and
      lttng_evaluation_session_rotation_completed_get_location()
  <tr>
    <td>#LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES
    <td>Captured event payload and context fields.
    <td>lttng_evaluation_event_rule_matches_get_captured_values()
</table>

Destroy a trigger condition evaluation with
lttng_evaluation_destroy().

@defgroup api_trigger_cond_session_consumed_size “Recording session consumed data size becomes greater than” trigger condition API
@ingroup api_trigger_cond

A <strong><em>“recording session consumed data size becomes greater than”</em></strong>
trigger condition is considered satisfied when the total \em consumed
size of the tracing data of all the \lt_obj_channels of a given
\lt_obj_session becomes greater than some configured threshold.

A “recording session consumed data size becomes greater than”
trigger condition has the type
#LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE.

Every time the \ref api-channel-monitor-timer "monitor timer" of a
channel expires, LTTng updates the statistics, like the total consumed
tracing data size, of its owning recording session. This is when LTTng
tries to evaluate
“recording session consumed data size becomes greater than” conditions.

To create a valid “recording session consumed data size becomes greater
than” trigger condition:

-# Create the initial trigger condition
   with lttng_condition_session_consumed_size_create().

-# Set a threshold (consumed bytes) with
   lttng_condition_session_consumed_size_set_threshold().

-# Set a target recording session name with
   lttng_condition_session_consumed_size_set_session_name().

Get the threshold of a
“recording session consumed data size becomes greater than”
trigger condition with
lttng_condition_session_consumed_size_get_threshold().

Get the target recording session name of a
“recording session consumed data size becomes greater than”
trigger condition with
lttng_condition_session_consumed_size_get_session_name().

<h1>Evaluation</h1>

When a trigger with a “recording session consumed data size becomes
greater than” condition fires, LTTng captures the total consumed size.
With the \link api_trigger_action_notify “notify”\endlink action, a user
may then read the captured value from the condition evaluation with
lttng_evaluation_session_consumed_size_get_consumed_size().

@defgroup api_trigger_cond_buffer_usage “Channel buffer usage becomes greater/less than” trigger condition API
@ingroup api_trigger_cond

A <strong><em>“channel buffer usage becomes greater/less than”</em></strong>
trigger condition is considered satisfied when the ring buffer usage of
a given \lt_obj_channel becomes greater or less than some configured
threshold.

A “channel buffer usage becomes greater than”
trigger condition has the type
#LTTNG_CONDITION_TYPE_BUFFER_USAGE_HIGH.

A “channel buffer usage becomes less than”
trigger condition has the type
#LTTNG_CONDITION_TYPE_BUFFER_USAGE_LOW.

Every time the \ref api-channel-monitor-timer "monitor timer" of a
channel expires, LTTng updates its statistics, including its
buffer usage. This is when LTTng tries to evaluate
“channel buffer usage becomes greater/less than” conditions.

To create a valid “channel buffer usage becomes greater/less than”
trigger condition:

-# Create the initial trigger condition with one of:

   <dl>
     <dt>Channel buffer usage becomes greater than
     <dd>lttng_condition_buffer_usage_high_create()

     <dt>Channel buffer usage becomes less than
     <dd>lttng_condition_buffer_usage_low_create()
   </dl>

-# Set a buffer usage threshold with one of:

   <dl>
     <dt>By ratio (0 to 1)
     <dd>lttng_condition_buffer_usage_set_threshold_ratio()

     <dt>By size (bytes)
     <dd>lttng_condition_buffer_usage_set_threshold()
   </dl>

-# Set a target \lt_obj_session name with
   lttng_condition_buffer_usage_set_session_name().

-# Set a target \lt_obj_domain with
   lttng_condition_buffer_usage_set_domain_type().

-# Set a target channel name with
   lttng_condition_buffer_usage_set_channel_name().

Get the buffer usage threshold of a
“channel buffer usage becomes greater/less than”
trigger condition with
lttng_condition_buffer_usage_get_threshold_ratio()
or
lttng_condition_buffer_usage_get_threshold().

Get the target recording session name, tracing domain,
and channel name of a
“channel buffer usage becomes greater/less than”
trigger condition with
lttng_condition_buffer_usage_get_session_name(),
lttng_condition_buffer_usage_get_domain_type(), and
lttng_condition_buffer_usage_get_channel_name().

<h1>Evaluation</h1>

When a trigger with a “channel buffer usage becomes greater/less than”
condition fires, LTTng captures the current ring buffer usage.
With the \link api_trigger_action_notify “notify”\endlink action, a user
may then read the captured value from the condition evaluation with
lttng_evaluation_buffer_usage_get_usage_ratio() and
lttng_evaluation_buffer_usage_get_usage().

@defgroup api_trigger_cond_rotation “Recording session rotation starts/finishes” trigger condition API
@ingroup api_trigger_cond

A <strong><em>“recording session rotation starts/finishes”</em></strong>
trigger condition is considered satisfied when the
\ref api_session_rotation "rotation" operation of a given
\lt_obj_session starts or finishes.

A “recording session rotation starts”
trigger condition has the type
#LTTNG_CONDITION_TYPE_SESSION_ROTATION_ONGOING.

A “recording session rotation finishes”
trigger condition has the type
#LTTNG_CONDITION_TYPE_SESSION_ROTATION_COMPLETED.

To create a valid “recording session rotation starts/finishes”
trigger condition:

-# Create the initial trigger condition with one of:

   <dl>
     <dt>Recording session rotation starts
     <dd>lttng_condition_session_rotation_ongoing_create()

     <dt>Recording session rotation finishes
     <dd>lttng_condition_session_rotation_completed_create()
   </dl>

-# Set a target \lt_obj_session name with
   lttng_condition_buffer_usage_set_session_name().

Get the target recording session name of a
“recording session rotation starts/finishes”
trigger condition with
lttng_condition_session_rotation_get_session_name().

<h1>Evaluation</h1>

When a trigger with a “recording session rotation starts/finishes”
condition fires, LTTng captures the recording session rotation ID.
Moreover, when a “recording session rotation finishes” condition fires,
LTTng captures the resulting trace archive location.
With the \link api_trigger_action_notify “notify”\endlink action, a user
may then read the captured value(s) from the condition evaluation with
lttng_evaluation_session_rotation_get_id() and
lttng_evaluation_session_rotation_completed_get_location().

@defgroup api_trigger_cond_er_matches “Event rule matches” trigger condition API
@ingroup api_trigger_cond

An <strong><em>“event rule matches”</em></strong> trigger condition is
considered satisfied when its \ref api_er "event rule"
matches an LTTng event.

An “event rule matches” trigger condition has the type
#LTTNG_CONDITION_TYPE_EVENT_RULE_MATCHES.

Create an “event rule matches” trigger condition
with lttng_condition_event_rule_matches_create().

Get the event rule of an “event rule matches” trigger condition
with lttng_condition_event_rule_matches_get_rule().

<h1>Evaluation</h1>

When a trigger with an “event rule matches” condition fires, LTTng
can evaluate one or more
\ref api_ev_expr "event expressions" and then \em capture theirs
results. As of LTTng-tools&nbsp;\lt_version_maj_min, the only available
event expressions are event payload and context field references.
With the \link api_trigger_action_notify “notify”\endlink action,
a user may then
read the captured values from the condition evaluation with
lttng_evaluation_event_rule_matches_get_captured_values().

To make LTTng capture event payload and context fields when an
“event rule matches” trigger condition is satisfied,
append capture descriptors to the condition object with
lttng_condition_event_rule_matches_append_capture_descriptor() before
you create the trigger with lttng_trigger_create().

Get the capture descriptors of an “event rule matches” trigger
condition with
lttng_condition_event_rule_matches_get_capture_descriptor_count()
and
lttng_condition_event_rule_matches_get_capture_descriptor_at_index().

@defgroup api_er Event rule API
@ingroup api_trigger_cond_er_matches

<h1>Concepts</h1>

An <em>instrumentation point</em> is a point, within a piece of
software, which, when executed, creates an LTTng <em>event</em>.
See \ref api_inst_pt to learn how to list the available instrumentation
points.

An <em>event rule</em> is a set of \ref api-er-conds "conditions" to
match a set of events.

An event has a \ref api-er-event-name "name" and fields.

When LTTng creates an event&nbsp;\lt_var{E}, an event
rule&nbsp;\lt_var{ER} is said to <em>match</em>&nbsp;\lt_var{E}
when&nbsp;\lt_var{E} satisfies \em all the conditions
of&nbsp;\lt_var{ER}. This concept is similar to a regular expression
which matches a set of strings.

When an event rule matches an event, LTTng \em emits the event,
therefore attempting to execute an action.

@attention
    @parblock
    The event creation and emission processes are \em documentation
    concepts to help understand the journey from an instrumentation
    point to the execution of an action.

    The actual creation of an event can be costly because LTTng needs to
    evaluate the arguments of the instrumentation point.

    In practice, LTTng implements various optimizations for the
    Linux kernel and user space tracing domains to avoid actually
    creating an event when the tracer
    knows, thanks to properties which are independent from the event
    payload and current
    \link #lttng_event_context_type context\endlink, that it would never
    emit such an event. Those properties are:

    - The \ref api-er-conds-inst-pt-type "instrumentation point type".

    - The \ref api-er-conds-event-name "instrumentation point name" (or
      event name).

    - The \ref api-er-conds-ll "instrumentation point log level".

    In other words: if, for a given instrumentation
    point&nbsp;\lt_var{IP}, the LTTng tracer knows that it would never
    emit an event, executing&nbsp;\lt_var{IP} represents a simple
    boolean variable check and, for a Linux kernel
    event rule, a few current process attribute checks.
    @endparblock

The only purpose of an event rule object is to create an
\link api_trigger_cond_er_matches “event rule matches” trigger condition\endlink
from it. When the event rule of the trigger condition matches an event,
LTTng can execute a user-defined
\ref api_trigger_action "action" such as sending an LTTng
notification, starting a recording session, and more.

Get the type of an event rule with lttng_event_rule_get_type().

Destroy an event rule with lttng_event_rule_destroy().

@sa
    - The “INSTRUMENTATION POINT, EVENT RULE, AND EVENT”
      section of \lt_man{lttng-concepts,7}.
    - \lt_man{lttng-event-rule,7}.

<h1>\anchor api-er-conds Event rule conditions</h1>

For LTTng to emit an event&nbsp;\lt_var{E},&nbsp;\lt_var{E}
must satisfy \em all the conditions of an event
rule&nbsp;\lt_var{ER}.

You set the following conditions when or after you create \lt_var{ER}
with one of the creation functions listed below:

<table>
  <tr>
    <th>Condition
    <th>Description
  <tr>
    <td>
      \anchor api-er-conds-inst-pt-type
      \ref api-er-conds-inst-pt-type "Instrumentation point type"
    <td>
      \lt_var{E} satisfies the instrumentation point type condition
      of&nbsp;\lt_var{ER} if the instrumentation point from which LTTng
      creates&nbsp;\lt_var{E} is, depending on the
      \link lttng_event_rule_get_type() type\endlink of&nbsp;\lt_var{ER}:

      <dl>
        <dt>#LTTNG_EVENT_RULE_TYPE_KERNEL_TRACEPOINT
        <dd>
          An \ref api_kernel_tp_er "LTTng kernel tracepoint",
          that is, a statically defined point in the source code of
          the kernel image or of a kernel module with LTTng kernel
          tracer macros.

          Create&nbsp;\lt_var{ER} with
          lttng_event_rule_kernel_tracepoint_create().

          @sa lttng_list_tracepoints()

        <dt>#LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL
        <dd>
          The entry, exit, or entry and exit of a
          \ref api_kernel_syscall_er "Linux kernel system call".

          Create&nbsp;\lt_var{ER} with
          lttng_event_rule_kernel_syscall_create().

          @sa lttng_list_syscalls()

        <dt>#LTTNG_EVENT_RULE_TYPE_KERNEL_KPROBE
        <dd>
          A \ref api_kprobe_er "Linux kprobe",
          that is, a single probe dynamically placed in the
          compiled kernel code.

          You indicate the \ref api_kprobe_loc "location" of the Linux
          kprobe to instrument when you create&nbsp;\lt_var{ER}
          with lttng_event_rule_kernel_kprobe_create().

          Although lttng_event_rule_kernel_kprobe_create() sets an
          initial event name from the kprobe location, you can override
          it with lttng_event_rule_kernel_kprobe_set_event_name().

          The payload of a Linux kprobe event is empty.

        <dt>#LTTNG_EVENT_RULE_TYPE_KERNEL_UPROBE
        <dd>
          A \ref api_uprobe_er "Linux user space probe",
          that is, a single probe dynamically placed at the
          entry of a compiled user space application/library
          function through the kernel.

          You indicate the \ref api_uprobe_loc "location" of the Linux
          user space probe to instrument when you
          create&nbsp;\lt_var{ER}
          with lttng_event_rule_kernel_uprobe_create().

          Although lttng_event_rule_kernel_uprobe_create() sets an
          initial event name from the user space probe location,
          you can override it with
          lttng_event_rule_kernel_uprobe_set_event_name().

          The payload of a Linux user space probe event is empty.

        <dt>#LTTNG_EVENT_RULE_TYPE_USER_TRACEPOINT
        <dd>
          An \ref api_user_tp_er "LTTng user space tracepoint",
          that is, a statically
          defined point in the source code of a C/C++
          application/library with LTTng user space tracer macros.

          Create&nbsp;\lt_var{ER} with
          lttng_event_rule_user_tracepoint_create().

          @sa lttng_list_tracepoints()

        <dt>#LTTNG_EVENT_RULE_TYPE_JUL_LOGGING
        <dd>
          A \ref api_jul_er "\lt_jul logging statement".

          Create&nbsp;\lt_var{ER} with
          lttng_event_rule_jul_logging_create().

          @sa lttng_list_tracepoints()

        <dt>#LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING
        <dd>
          An \ref api_log4j1_er "\lt_log4j1 logging statement".

          Create&nbsp;\lt_var{ER} with
          lttng_event_rule_log4j_logging_create().

          @sa lttng_list_tracepoints()

        <dt>#LTTNG_EVENT_RULE_TYPE_LOG4J2_LOGGING
        <dd>
          An \ref api_log4j2_er "\lt_log4j2 logging statement".

          Create&nbsp;\lt_var{ER} with
          lttng_event_rule_log4j2_logging_create().

          @sa lttng_list_tracepoints()

        <dt>#LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING
        <dd>
          A \ref api_py_er "Python logging statement".

          Create&nbsp;\lt_var{ER} with
          lttng_event_rule_python_logging_create().

          @sa lttng_list_tracepoints()
      </dl>
  <tr>
    <td>
      \anchor api-er-conds-event-name
      \ref api-er-conds-event-name "Event name"
    <td>
      An event&nbsp;\lt_var{E} satisfies the event name condition
      of&nbsp;\lt_var{ER} if the two following statements are
      \b true:

      - The event name pattern of&nbsp;\lt_var{ER} matches, depending on
        the \link lttng_event_rule_get_type() type\endlink
        of&nbsp;\lt_var{ER}
        (see \ref api-er-conds-inst-pt-type "Instrumentation point type"
        above):

        <dl>
          <dt>#LTTNG_EVENT_RULE_TYPE_KERNEL_TRACEPOINT
          <dt>#LTTNG_EVENT_RULE_TYPE_USER_TRACEPOINT
          <dt>#LTTNG_EVENT_RULE_TYPE_JUL_LOGGING
          <dt>#LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING
          <dt>#LTTNG_EVENT_RULE_TYPE_LOG4J2_LOGGING
          <dt>#LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING
          <dd>
            The full name of the LTTng tracepoint or Java/Python
            logger from which LTTng creates&nbsp;\lt_var{E}.

            Note that the full name of an
            LTTng user space tracepoint is
            <code><em>PROVIDER</em>:<em>NAME</em></code>, where
            <code><em>PROVIDER</em></code> is the tracepoint
            provider name and <code><em>NAME</em></code> is the
            tracepoint name.

          <dt>#LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL
          <dd>
            The name of the system call, \em without any
            <code>sys_</code> prefix, from which LTTng
            creates&nbsp;\lt_var{E}.
        </dl>

        When you create&nbsp;\lt_var{ER}, the initial event name pattern
        is equivalent to <code>*</code> (any event name).

        Set the event name pattern of&nbsp;\lt_var{ER} with one of:

        - lttng_event_rule_kernel_tracepoint_set_name_pattern()
        - lttng_event_rule_kernel_syscall_set_name_pattern()
        - lttng_event_rule_user_tracepoint_set_name_pattern()
        - lttng_event_rule_jul_logging_set_name_pattern()
        - lttng_event_rule_log4j_logging_set_name_pattern()
        - lttng_event_rule_log4j2_logging_set_name_pattern()
        - lttng_event_rule_python_logging_set_name_pattern()

        Get the event name pattern of&nbsp;\lt_var{ER} with one of:

        - lttng_event_rule_kernel_tracepoint_get_name_pattern()
        - lttng_event_rule_kernel_syscall_get_name_pattern()
        - lttng_event_rule_user_tracepoint_get_name_pattern()
        - lttng_event_rule_jul_logging_get_name_pattern()
        - lttng_event_rule_log4j_logging_get_name_pattern()
        - lttng_event_rule_log4j2_logging_get_name_pattern()
        - lttng_event_rule_python_logging_get_name_pattern()

        @sa \ref api-er-event-name "Event name".

      - If the type of&nbsp;\lt_var{ER} is
        #LTTNG_EVENT_RULE_TYPE_USER_TRACEPOINT, then
        none of the event name exclusion patterns of&nbsp;\lt_var{ER}
        matches the full name of the user space tracepoint from
        which LTTng creates&nbsp;\lt_var{E}.

        When you create&nbsp;\lt_var{ER}, the initial event name
        exclusion pattern set is empty (no exclusions).

        Add an event name exclusion pattern to&nbsp;\lt_var{ER} with
        lttng_event_rule_user_tracepoint_add_name_pattern_exclusion().

        Get an event name exclusion pattern of&nbsp;\lt_var{ER} with
        lttng_event_rule_user_tracepoint_get_name_pattern_exclusion_at_index().

      This condition isn't meaningful (always satisfied)
      if the type of&nbsp;\lt_var{ER}
      is #LTTNG_EVENT_RULE_TYPE_KERNEL_KPROBE or
      #LTTNG_EVENT_RULE_TYPE_KERNEL_UPROBE.

      In all cases, the event name and event name exclusion
      patterns are <em>globbing patterns</em>: the
      <code>*</code> character means “match anything”. To match a
      literal <code>*</code> character, use <code>\\*</code>.
  <tr>
    <td>
      \anchor api-er-conds-ll
      \ref api-er-conds-ll "Instrumentation point log level"
    <td>
      An event&nbsp;\lt_var{E} satisfies the instrumentation point
      log level condition of&nbsp;\lt_var{ER} if the log level&nbsp;\lt_var{LL}
      of the LTTng user space tracepoint or
      logging statement from which LTTng creates&nbsp;\lt_var{E}
      satisfies the \ref api_ll_rule "log level rule" \lt_var{LLR}
      of&nbsp;\lt_var{ER}.

      An event&nbsp;\lt_var{E} satisfies this condition if
      \lt_var{LL} is, depending on the
      \link lttng_log_level_rule_get_type() type\endlink
      of&nbsp;\lt_var{LLR}:

      <dl>
        <dt>#LTTNG_LOG_LEVEL_RULE_TYPE_AT_LEAST_AS_SEVERE_AS
        <dd>
          At least as severe as what
          lttng_log_level_rule_at_least_as_severe_as_get_level()
          returns with&nbsp;\lt_var{LLR}.

        <dt>#LTTNG_LOG_LEVEL_RULE_TYPE_EXACTLY
        <dd>
          Exactly what lttng_log_level_rule_exactly_get_level()
          returns with&nbsp;\lt_var{LLR}.
      </dl>

      If&nbsp;\lt_var{ER} has no log level rule, then this condition
      is always satisfied.

      This condition isn't meaningful (always satisfied)
      if the type of&nbsp;\lt_var{ER}
      is one of:

      - #LTTNG_EVENT_RULE_TYPE_KERNEL_TRACEPOINT
      - #LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL
      - #LTTNG_EVENT_RULE_TYPE_KERNEL_KPROBE
      - #LTTNG_EVENT_RULE_TYPE_KERNEL_UPROBE

      When you create&nbsp;\lt_var{ER}, there's no initial log level
      rule (this condition is always satisfied).

      Set the log level rule of&nbsp;\lt_var{ER} with one of:

      - lttng_event_rule_user_tracepoint_set_log_level_rule()
      - lttng_event_rule_jul_logging_set_log_level_rule()
      - lttng_event_rule_log4j_logging_set_log_level_rule()
      - lttng_event_rule_log4j2_logging_set_log_level_rule()
      - lttng_event_rule_python_logging_set_log_level_rule()

      Get the log level rule of&nbsp;\lt_var{ER} with one of:

      - lttng_event_rule_user_tracepoint_get_log_level_rule()
      - lttng_event_rule_jul_logging_get_log_level_rule()
      - lttng_event_rule_log4j_logging_get_log_level_rule()
      - lttng_event_rule_log4j2_logging_get_log_level_rule()
      - lttng_event_rule_python_logging_get_log_level_rule()
  <tr>
    <td>
      \anchor api-er-conds-filter
      \ref api-er-conds-filter "Event payload and context filter"
    <td>
      An event&nbsp;\lt_var{E} satisfies the event payload and
      context filter condition of&nbsp;\lt_var{ER}
      if&nbsp;\lt_var{ER} has no filter expression or if its filter
      expression&nbsp;\lt_var{EXPR} evaluates to \b true
      when LTTng creates&nbsp;\lt_var{E}.

      This condition isn't meaningful (always satisfied)
      if the type of&nbsp;\lt_var{ER} is
      #LTTNG_EVENT_RULE_TYPE_KERNEL_KPROBE or
      #LTTNG_EVENT_RULE_TYPE_KERNEL_UPROBE.

      When you create&nbsp;\lt_var{ER}, the initial event payload and
      context filter is equivalent to <code>1</code> (no filter: the
      condition is always satisfied).

      Set the event payload and context filter expression
      of&nbsp;\lt_var{ER} with one of:

      - lttng_event_rule_kernel_tracepoint_set_filter()
      - lttng_event_rule_kernel_syscall_set_filter()
      - lttng_event_rule_user_tracepoint_set_filter()
      - lttng_event_rule_jul_logging_set_filter()
      - lttng_event_rule_log4j_logging_set_filter()
      - lttng_event_rule_log4j2_logging_set_filter()
      - lttng_event_rule_python_logging_set_filter()

      Get the event payload and context filter expression
      of&nbsp;\lt_var{ER} with one of:

      - lttng_event_rule_kernel_tracepoint_get_filter()
      - lttng_event_rule_kernel_syscall_get_filter()
      - lttng_event_rule_user_tracepoint_get_filter()
      - lttng_event_rule_jul_logging_get_filter()
      - lttng_event_rule_log4j_logging_get_filter()
      - lttng_event_rule_log4j2_logging_get_filter()
      - lttng_event_rule_python_logging_get_filter()

      @include{doc} dox/filter-expr.dox
</table>

<h1>\anchor api-er-event-name Event name</h1>

When LTTng emits an event&nbsp;\lt_var{E}, the resulting event
has a name which depends on the
\ref api-er-conds-inst-pt-type "instrumentation point type condition"
of the event rule&nbsp;\lt_var{ER} which matched&nbsp;\lt_var{E}:

<table>
  <tr>
    <th>Instrumentation point type
    <th>Event name
  <tr>
    <td>
      #LTTNG_EVENT_RULE_TYPE_KERNEL_TRACEPOINT or
      #LTTNG_EVENT_RULE_TYPE_USER_TRACEPOINT
    <td>
      Full name of the tracepoint from which LTTng creates&nbsp;\lt_var{E}.

      Note that the full name of an
      #LTTNG_EVENT_RULE_TYPE_USER_TRACEPOINT event rule is
      <code><em>PROVIDER</em>:<em>NAME</em></code>, where
      <code><em>PROVIDER</em></code> is the tracepoint provider name and
      <code><em>NAME</em></code> is the tracepoint name.
  <tr>
    <td>#LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL
    <td>
      Location:

      <dl>
        <dt>Entry
        <dd>
          <code>syscall_entry_<em>NAME</em></code>, where
          <code><em>NAME</em></code> is the name of the system call from
          which LTTng creates&nbsp;\lt_var{E}, \em without any
          <code>sys_</code> prefix.

        <dt>Exit
        <dd>
          <code>syscall_exit_<em>NAME</em></code>, where
          <code><em>NAME</em></code> is the name of the system call from
          which LTTng creates&nbsp;\lt_var{E}, \em without any
          <code>sys_</code> prefix.
      </dl>
  <tr>
    <td>
      #LTTNG_EVENT_RULE_TYPE_KERNEL_KPROBE or
      #LTTNG_EVENT_RULE_TYPE_KERNEL_UPROBE
    <td>
      Location:

      <dl>
        <dt>Entry
        <dd><code><em>NAME</em>_entry</code>

        <dt>Exit
        <dd><code><em>NAME</em>_exit</code>
      </dl>

      where <code><em>NAME</em></code> is the <em>event name</em>
      of&nbsp;\lt_var{ER}.

      Both lttng_event_rule_kernel_kprobe_create() and
      lttng_event_rule_kernel_uprobe_create() set an
      initial event name from the probe location.

      Override the event name of&nbsp;\lt_var{ER} with
      lttng_event_rule_kernel_kprobe_set_event_name() or
      lttng_event_rule_kernel_uprobe_set_event_name().

      Get the event name of&nbsp;\lt_var{ER} with
      lttng_event_rule_kernel_kprobe_get_event_name() or
      lttng_event_rule_kernel_uprobe_get_event_name().
  <tr>
    <td>#LTTNG_EVENT_RULE_TYPE_JUL_LOGGING
    <td>
      <code>lttng_jul:event</code>

      Such an event has a string field <code>logger_name</code>
      which contains the name of the \lt_jul
      logger from which LTTng creates&nbsp;\lt_var{E}.
  <tr>
    <td>#LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING
    <td>
      <code>lttng_log4j:event</code>

      Such an event has a string field <code>logger_name</code>
      which contains the name of the \lt_log4j1 logger
      from which LTTng creates&nbsp;\lt_var{E}.
  <tr>
    <td>#LTTNG_EVENT_RULE_TYPE_LOG4J2_LOGGING
    <td>
      <code>lttng_log4j2:event</code>

      Such an event has a string field <code>logger_name</code>
      which contains the name of the \lt_log4j2 logger
      from which LTTng creates&nbsp;\lt_var{E}.
  <tr>
    <td>#LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING
    <td>
      <code>lttng_python:event</code>

      Such an event has a string field <code>logger_name</code>
      which contains the name of the Python logger from which LTTng
      creates&nbsp;\lt_var{E}.
</table>

@defgroup api_ll_rule Log level rule API
@ingroup api_er

A <strong><em>log level rule</em></strong> indicates how to match an
instrumentation point log level within an \ref api_er "event rule".

See the \ref api-er-conds-ll "instrumentation point log level" event
rule condition to learn more.

Create a log level rule for which a log level must be exactly
a given value with lttng_log_level_rule_exactly_create().

Create a log level rule for which a log level must be at least
as severe as a given value with
lttng_log_level_rule_at_least_as_severe_as_create().

Get the type of a log level rule with
lttng_log_level_rule_get_type().

Destroy a log level rule with
lttng_log_level_rule_destroy().

@defgroup api_kernel_tp_er LTTng kernel tracepoint event rule API
@ingroup api_er

An <strong><em>LTTng kernel tracepoint event rule</em></strong> is
an event rule with the #LTTNG_EVENT_RULE_TYPE_KERNEL_TRACEPOINT
type.

An LTTng kernel tracepoint is a statically defined point in the source
code of the kernel image or of a kernel module with LTTng kernel
tracer macros.

Create an LTTng kernel tracepoint event rule with
lttng_event_rule_kernel_tracepoint_create().

The specific \ref api-er-conds "event rule conditions" accessors of
an LTTng kernel tracepoint event rule are:

<table>
  <tr>
    <th>Condition
    <th>Setter
    <th>Getter
  <tr>
    <td>\ref api-er-conds-event-name "Event name"
    <td>lttng_event_rule_kernel_tracepoint_set_name_pattern()
    <td>lttng_event_rule_kernel_tracepoint_get_name_pattern()
  <tr>
    <td>\ref api-er-conds-filter "Event payload and context filter"
    <td>lttng_event_rule_kernel_tracepoint_set_filter()
    <td>lttng_event_rule_kernel_tracepoint_get_filter()
</table>

@defgroup api_kernel_syscall_er Linux kernel system call event rule API
@ingroup api_er

A <strong><em>Linux kernel system call event rule</em></strong> is
an event rule with the #LTTNG_EVENT_RULE_TYPE_KERNEL_SYSCALL
type.

A Linux kernel system call event rule matches an event which LTTng
creates from the entry, exit, or both of a kernel
<a href="https://en.wikipedia.org/wiki/System_call">system call</a>.

Create a Linux kernel system call event rule with
lttng_event_rule_kernel_syscall_create().

The specific \ref api-er-conds "event rule conditions" accessors of
a Linux kernel system call event rule are:

<table>
  <tr>
    <th>Condition
    <th>Setter
    <th>Getter
  <tr>
    <td>\ref api-er-conds-event-name "Event name"
    <td>lttng_event_rule_kernel_syscall_set_name_pattern()
    <td>lttng_event_rule_kernel_syscall_get_name_pattern()
  <tr>
    <td>\ref api-er-conds-filter "Event payload and context filter"
    <td>lttng_event_rule_kernel_syscall_set_filter()
    <td>lttng_event_rule_kernel_syscall_get_filter()
</table>

@defgroup api_kprobe_er Linux kprobe event rule API
@ingroup api_er

A <strong><em>Linux kprobe event rule</em></strong> is
an event rule with the #LTTNG_EVENT_RULE_TYPE_KERNEL_KPROBE
type.

A Linux
<a href="https://www.kernel.org/doc/html/latest/trace/kprobes.html">kprobe</a>
is a kernel debugging/tracing mechanism that
intercepts and monitors kernel function calls.

A Linux kprobe lets you insert handlers into nearly any kernel routine
dynamically at run time, without having to recompile the kernel. LTTng
is able to attach to such a dynamic probe and create an event from its
execution.

Create a Linux kprobe event rule with
lttng_event_rule_kernel_kprobe_create().

lttng_event_rule_kernel_kprobe_create() sets an
initial event name from the kprobe location. Override
the event name of a Linux kprobe event rule
with lttng_event_rule_kernel_kprobe_set_event_name(). Get the
event name with lttng_event_rule_kernel_kprobe_get_event_name().

Get the location, as passed to lttng_event_rule_kernel_kprobe_create(),
of a Linux kprobe event rule with
lttng_event_rule_kernel_kprobe_get_location().

@defgroup api_kprobe_loc Linux kprobe location API
@ingroup api_kprobe_er

A <strong><em>Linux kprobe location</em></strong> is an object which
locates a Linux
<a href="https://www.kernel.org/doc/html/latest/trace/kprobes.html">kprobe</a>.

The purpose of such an object is to provide the location of the target
Linux kprobe when you create a
\ref api_kprobe_er "Linux kprobe event rule".

The two ways to locate a Linux kprobe are:

<table>
  <tr>
    <th>Location type
    <th>Location enumerator
    <th>Creation function
  <tr>
    <td>By offset from a named symbol
    <td>#LTTNG_KERNEL_PROBE_LOCATION_TYPE_SYMBOL_OFFSET
    <td>lttng_kernel_probe_location_symbol_create()
  <tr>
    <td>By address within the kernel
    <td>#LTTNG_KERNEL_PROBE_LOCATION_TYPE_ADDRESS
    <td>lttng_kernel_probe_location_address_create()
</table>

Get the type of a Linux kprobe location with
lttng_kernel_probe_location_get_type().

Destroy a Linux kprobe location with
lttng_kernel_probe_location_destroy().

@defgroup api_uprobe_er Linux user space probe event rule API
@ingroup api_er

A <strong><em>Linux user space probe event rule</em></strong> is
an event rule with the #LTTNG_EVENT_RULE_TYPE_KERNEL_UPROBE
type.

A Linux
<a href="https://www.kernel.org/doc/html/latest/trace/uprobetracer.html">user space probe</a>
is a user space tracing mechanism that allows intercepting and
monitoring function calls in user space applications.

A Linux user space probe makes it possible to insert handlers into
almost any user space function dynamically at run time, without
modifying or recompiling the application. LTTng can attach to such a
dynamic probe and and create an event from its execution.

Create a Linux user space probe event rule with
lttng_event_rule_kernel_uprobe_create().

lttng_event_rule_kernel_uprobe_create() sets an
initial event name from the user space probe location. Override
the event name of a Linux user space probe event rule
with lttng_event_rule_kernel_uprobe_set_event_name(). Get the
event name with lttng_event_rule_kernel_uprobe_get_event_name().

Get the location, as passed to lttng_event_rule_kernel_uprobe_create(),
of a Linux kprobe event rule with
lttng_event_rule_kernel_uprobe_get_location().

@defgroup api_user_tp_er LTTng user space tracepoint event rule API
@ingroup api_er

An <strong><em>LTTng user space tracepoint event rule</em></strong> is
an event rule with the #LTTNG_EVENT_RULE_TYPE_USER_TRACEPOINT
type.

An LTTng user space tracepoint is a statically
defined point in the source code of a C/C++
application/library with LTTng user space tracer macros.

Create an LTTng user space tracepoint event rule with
lttng_event_rule_user_tracepoint_create().

The specific \ref api-er-conds "event rule conditions" accessors of
an LTTng user space tracepoint event rule are:

<table>
  <tr>
    <th>Condition
    <th>Setter
    <th>Getter
  <tr>
    <td>\ref api-er-conds-event-name "Event name"
    <td>
      lttng_event_rule_user_tracepoint_set_name_pattern() and
      lttng_event_rule_user_tracepoint_add_name_pattern_exclusion()
    <td>
      lttng_event_rule_user_tracepoint_get_name_pattern() and
      lttng_event_rule_user_tracepoint_get_name_pattern_exclusion_at_index()
  <tr>
    <td>\ref api-er-conds-ll "Instrumentation point log level"
    <td>lttng_event_rule_user_tracepoint_set_log_level_rule()
    <td>lttng_event_rule_user_tracepoint_get_log_level_rule()
  <tr>
    <td>\ref api-er-conds-filter "Event payload and context filter"
    <td>lttng_event_rule_user_tracepoint_set_filter()
    <td>lttng_event_rule_user_tracepoint_get_filter()
</table>

@defgroup api_jul_er JUL event rule API
@ingroup api_er

A <strong><em>\lt_jul event rule</em></strong> is
an event rule with the #LTTNG_EVENT_RULE_TYPE_JUL_LOGGING
type.

<a href="https://docs.oracle.com/en/java/javase/24/docs/api/index.html">\lt_jul</a>
(JUL) is a built-in Java framework that provides a simple and
flexible way to log messages from applications. It supports
configurable levels of logging, output formatting, and
log routing through handlers (console and file, for example). The
LTTng-UST project provides a JUL handler which creates an LTTng event
from an emitted JUL logging statement.

Create a \lt_jul event rule with
lttng_event_rule_jul_logging_create().

The specific \ref api-er-conds "event rule conditions" accessors of
a \lt_jul event rule are:

<table>
  <tr>
    <th>Condition
    <th>Setter
    <th>Getter
  <tr>
    <td>\ref api-er-conds-event-name "Event name"
    <td>
      lttng_event_rule_jul_logging_set_name_pattern()
    <td>
      lttng_event_rule_jul_logging_get_name_pattern()
  <tr>
    <td>\ref api-er-conds-ll "Instrumentation point log level"
    <td>lttng_event_rule_jul_logging_set_log_level_rule()
    <td>lttng_event_rule_jul_logging_get_log_level_rule()
  <tr>
    <td>\ref api-er-conds-filter "Event payload and context filter"
    <td>lttng_event_rule_jul_logging_set_filter()
    <td>lttng_event_rule_jul_logging_get_filter()
</table>

@sa
    - \ref api_log4j1_er
    - \ref api_log4j2_er

@defgroup api_log4j1_er Apache log4j 1.x event rule API
@ingroup api_er

An <strong><em>\lt_log4j1 event rule</em></strong> is
an event rule with the #LTTNG_EVENT_RULE_TYPE_LOG4J_LOGGING
type.

<a href="https://logging.apache.org/log4j/1.x/">\lt_log4j1</a> is a
widely used Java logging framework that offers a reliable and
configurable way to log messages from applications. It supports multiple
logging levels, flexible output formatting, and routing through
appenders such as console, file, or network destinations. The LTTng-UST
project provides an \lt_log4j1 appender which creates an LTTng event
from an emitted log4j&nbsp;1.x logging statement.

Create an \lt_log4j1 event rule with
lttng_event_rule_log4j_logging_create().

The specific \ref api-er-conds "event rule conditions" accessors of
an \lt_log4j1 event rule are:

<table>
  <tr>
    <th>Condition
    <th>Setter
    <th>Getter
  <tr>
    <td>\ref api-er-conds-event-name "Event name"
    <td>
      lttng_event_rule_log4j_logging_set_name_pattern()
    <td>
      lttng_event_rule_log4j_logging_get_name_pattern()
  <tr>
    <td>\ref api-er-conds-ll "Instrumentation point log level"
    <td>lttng_event_rule_log4j_logging_set_log_level_rule()
    <td>lttng_event_rule_log4j_logging_get_log_level_rule()
  <tr>
    <td>\ref api-er-conds-filter "Event payload and context filter"
    <td>lttng_event_rule_log4j_logging_set_filter()
    <td>lttng_event_rule_log4j_logging_get_filter()
</table>

@sa
    - \ref api_jul_er
    - \ref api_log4j2_er

@defgroup api_log4j2_er Apache Log4j 2 event rule API
@ingroup api_er

An <strong><em>\lt_log4j2 event rule</em></strong> is
an event rule with the #LTTNG_EVENT_RULE_TYPE_LOG4J2_LOGGING
type.

<a href="https://logging.apache.org/log4j/2.x/index.html">\lt_log4j2</a>
is a modern, high-performance Java logging framework designed as a
successor to
\link api_log4j1_er \lt_log4j1\endlink. It provides advanced features
like asynchronous logging, filtering, and support for custom log levels,
along with flexible output formatting and routing via appenders (console,
file, or network, for example). The LTTng-UST project provides an
\lt_log4j2 appender which creates an LTTng event
from an emitted Log4j&nbsp;2 logging statement.

Create an \lt_log4j2 event rule with
lttng_event_rule_log4j2_logging_create().

The specific \ref api-er-conds "event rule conditions" accessors of
an \lt_log4j2 event rule are:

<table>
  <tr>
    <th>Condition
    <th>Setter
    <th>Getter
  <tr>
    <td>\ref api-er-conds-event-name "Event name"
    <td>
      lttng_event_rule_log4j2_logging_set_name_pattern()
    <td>
      lttng_event_rule_log4j2_logging_get_name_pattern()
  <tr>
    <td>\ref api-er-conds-ll "Instrumentation point log level"
    <td>lttng_event_rule_log4j2_logging_set_log_level_rule()
    <td>lttng_event_rule_log4j2_logging_get_log_level_rule()
  <tr>
    <td>\ref api-er-conds-filter "Event payload and context filter"
    <td>lttng_event_rule_log4j2_logging_set_filter()
    <td>lttng_event_rule_log4j2_logging_get_filter()
</table>

@sa
    - \ref api_jul_er
    - \ref api_log4j1_er

@defgroup api_py_er Python logging event rule API
@ingroup api_er

A <strong><em>Python logging event rule</em></strong> is
an event rule with the #LTTNG_EVENT_RULE_TYPE_PYTHON_LOGGING
type.

<a href="https://docs.python.org/3/library/logging.html"><code>logging</code></a>
is a standard Python module that provides a flexible framework for
emitting log messages from applications. It supports different severity
levels, configurable formatting, and routing through handlers such as
console and file output. The LTTng-UST project provides a Python logging
handler which creates an LTTng event
from an emitted Python logging statement.

Create a Python logging event rule with
lttng_event_rule_python_logging_create().

The specific \ref api-er-conds "event rule conditions" accessors of
a Python logging event rule are:

<table>
  <tr>
    <th>Condition
    <th>Setter
    <th>Getter
  <tr>
    <td>\ref api-er-conds-event-name "Event name"
    <td>
      lttng_event_rule_python_logging_set_name_pattern()
    <td>
      lttng_event_rule_python_logging_get_name_pattern()
  <tr>
    <td>\ref api-er-conds-ll "Instrumentation point log level"
    <td>lttng_event_rule_python_logging_set_log_level_rule()
    <td>lttng_event_rule_python_logging_get_log_level_rule()
  <tr>
    <td>\ref api-er-conds-filter "Event payload and context filter"
    <td>lttng_event_rule_python_logging_set_filter()
    <td>lttng_event_rule_python_logging_get_filter()
</table>

@defgroup api_ev_expr Event expression API
@ingroup api_trigger_cond_er_matches

An <strong><em>event expression</em></strong> is a structured
representation of logic that can reference event fields, apply
operators, and compose conditions. Such an object is similar to an
<a href="https://en.wikipedia.org/wiki/Abstract_syntax_tree">abstract
syntax tree</a> (AST) node of which the dynamic input comes from the
context and payload fields of an event.

See \ref api_er to learn more about LTTng events.

As of LTTng-tools&nbsp;\lt_version_maj_min, the event expression API
only offers field reference expressions. Its sole purpose is to append
capture descriptors to an
\link api_trigger_cond_er_matches “event rule matches”\endlink
trigger condition with
lttng_condition_event_rule_matches_append_capture_descriptor(). With
more expression types (constants, operators, conditionals, and the
rest), you'll be able to programmatically create an
\ref api-er-conds-filter "event payload and context filter" expression.

The available event field expression types are:

<table>
  <tr>
    <th>Event expression type
    <th>Type enumerator
    <th>Creation function
    <th>Accessor(s)
  <tr>
    <td>Payload field reference
    <td>#LTTNG_EVENT_EXPR_TYPE_EVENT_PAYLOAD_FIELD
    <td>lttng_event_expr_event_payload_field_create()
    <td>lttng_event_expr_event_payload_field_get_name()
  <tr>
    <td>Statically-known context field reference
    <td>#LTTNG_EVENT_EXPR_TYPE_CHANNEL_CONTEXT_FIELD
    <td>lttng_event_expr_channel_context_field_create()
    <td>lttng_event_expr_channel_context_field_get_name()
  <tr>
    <td>Application-specific context field reference
    <td>#LTTNG_EVENT_EXPR_TYPE_APP_SPECIFIC_CONTEXT_FIELD
    <td>lttng_event_expr_app_specific_context_field_create()
    <td>
      lttng_event_expr_app_specific_context_field_get_provider_name()
      and
      lttng_event_expr_app_specific_context_field_get_type_name()
  <tr>
    <td>Array field element reference
    <td>#LTTNG_EVENT_EXPR_TYPE_ARRAY_FIELD_ELEMENT
    <td>lttng_event_expr_array_field_element_create()
    <td>
      lttng_event_expr_array_field_element_get_parent_expr() and
      lttng_event_expr_array_field_element_get_index()
</table>

Get the type of an event expression with
lttng_event_expr_get_type().

Check whether or not two event expressions are equal with
lttng_event_expr_is_equal().

Destroy an event expression with
lttng_event_expr_destroy().

@defgroup api_ev_field_val Event field value API
@ingroup api_trigger_cond_er_matches

An <strong><em>event field value</em></strong> is
the payload or context value of an event field.

See \ref api_er to learn more about LTTng events.

When you create an
\link api_trigger_cond_er_matches “event rule matches”\endlink
trigger condition, you may append capture descriptors
with lttng_condition_event_rule_matches_append_capture_descriptor().

Then, when a trigger with such an “event rule matches” condition fires,
the captured event field values are available through
lttng_evaluation_event_rule_matches_get_captured_values().

Get the type of an event field value with
lttng_event_field_value_get_type().

The available event field value types are:

<table>
  <tr>
    <th>Event field value type
    <th>Type enumerator(s)
    <th>Accessors
  <tr>
    <td>Unsigned integer/enumeration
    <td>
      #LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_INT and
      #LTTNG_EVENT_FIELD_VALUE_TYPE_UNSIGNED_ENUM
    <td>lttng_event_field_value_unsigned_int_get_value()
  <tr>
    <td>Signed integer/enumeration
    <td>
      #LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_INT and
      #LTTNG_EVENT_FIELD_VALUE_TYPE_SIGNED_ENUM
    <td>lttng_event_field_value_signed_int_get_value()
  <tr>
    <td>Real number
    <td>#LTTNG_EVENT_FIELD_VALUE_TYPE_REAL
    <td>lttng_event_field_value_real_get_value()
  <tr>
    <td>String
    <td>#LTTNG_EVENT_FIELD_VALUE_TYPE_STRING
    <td>lttng_event_field_value_string_get_value()
  <tr>
    <td>Array
    <td>#LTTNG_EVENT_FIELD_VALUE_TYPE_ARRAY
    <td>
      lttng_event_field_value_array_get_length() and
      lttng_event_field_value_array_get_element_at_index()
</table>

@defgroup api_trigger_action Trigger action API
@ingroup api_trigger

A <strong><em>trigger action</em></strong> is the part of a
\ref api_trigger "trigger" which LTTng executes
when its trigger \ref api_trigger_cond "condition" is satisfied.

As of LTTng-tools&nbsp;\lt_version_maj_min, the following trigger
actions are available:

<table>
  <tr>
    <th>Action type
    <th>Type enumerator
    <th>Creation function
  <tr>
    <td>\ref api_trigger_action_notify "Notify"
    <td>#LTTNG_ACTION_TYPE_NOTIFY
    <td>lttng_action_notify_create()
  <tr>
    <td>\ref api_trigger_action_start_session "Start recording session"
    <td>#LTTNG_ACTION_TYPE_START_SESSION
    <td>lttng_action_start_session_create()
  <tr>
    <td>\ref api_trigger_action_stop_session "Stop recording session"
    <td>#LTTNG_ACTION_TYPE_STOP_SESSION
    <td>lttng_action_stop_session_create()
  <tr>
    <td>\ref api_trigger_action_rotate "Rotate recording session snapshot"
    <td>#LTTNG_ACTION_TYPE_ROTATE_SESSION
    <td>lttng_action_rotate_session_create()
  <tr>
    <td>\ref api_trigger_action_snapshot "Take recording session snapshot"
    <td>#LTTNG_ACTION_TYPE_SNAPSHOT_SESSION
    <td>lttng_action_snapshot_session_create()
</table>

LTTng can execute more than one action when a trigger fires: create
a trigger action list with lttng_action_list_create().

Get the type of a trigger condition with lttng_condition_get_type().

By default, LTTng executes the action of a trigger every time it fires.
See \ref api_trigger_action_rate_policy to change the rate policy of a
trigger action (every&nbsp;\lt_var{N} times or
once after&nbsp;\lt_var{N} times).

Destroy a trigger condition with lttng_condition_destroy().

@defgroup api_trigger_action_rate_policy Trigger action rate policy API
@ingroup api_trigger_action

A trigger which \em fires (its condition is satisfied) leads to an
<em>execution request</em> for its action. If its action is an
\ref api_trigger_action_list "action list", then LTTng creates an
execution request for each action of the list, in order.

An execution request of a given action&nbsp;\lt_var{A} first increments
the <em>execution request count</em>&nbsp;\lt_var{C} of&nbsp;\lt_var{A}.
The <strong><em>rate policy</em></strong> of&nbsp;\lt_var{A} dictates
how frequently&nbsp;\lt_var{A} is allowed to execute relative
to&nbsp;\lt_var{C}.

In other words, the rate policy of a trigger action determines whether
and when an execution request becomes an actual execution.

As of LTTng-tools&nbsp;\lt_version_maj_min, the available trigger
action rate policies are:

<table>
  <tr>
    <th>Rate policy
    <th>Description
    <th>Type enumerator
    <th>Creation function
  <tr>
    <td>
      \anchor api-trigger-action-rate-policy-every-n
      “Every&nbsp;\lt_var{N} times”
    <td>
      LTTng executes&nbsp;\lt_var{A} every time&nbsp;\lt_var{C} is a
      multiple of&nbsp;\lt_var{N}.
    <td>#LTTNG_RATE_POLICY_TYPE_EVERY_N
    <td>lttng_rate_policy_every_n_create()
  <tr>
    <td>“Once after&nbsp;\lt_var{N} times”
    <td>
      LTTng executes&nbsp;\lt_var{A} a single time, when&nbsp;\lt_var{C}
      is greater than or equal to&nbsp;\lt_var{N}.
    <td>#LTTNG_RATE_POLICY_TYPE_ONCE_AFTER_N
    <td>lttng_rate_policy_once_after_n_create()
</table>

Get the type of a trigger action rate policy with
lttng_rate_policy_get_type().

Destroy a trigger action rate policy with
lttng_rate_policy_destroy().

Set the rate policy of a trigger action with the following functions,
depending on the action type:

<table>
  <tr>
    <th>Trigger action type
    <th>Rate policy setter
  <tr>
    <td>#LTTNG_ACTION_TYPE_NOTIFY
    <td>lttng_action_notify_set_rate_policy()
  <tr>
    <td>#LTTNG_ACTION_TYPE_START_SESSION
    <td>lttng_action_start_session_set_rate_policy()
  <tr>
    <td>#LTTNG_ACTION_TYPE_STOP_SESSION
    <td>lttng_action_stop_session_set_rate_policy()
  <tr>
    <td>#LTTNG_ACTION_TYPE_ROTATE_SESSION
    <td>lttng_action_rotate_session_set_rate_policy()
  <tr>
    <td>#LTTNG_ACTION_TYPE_SNAPSHOT_SESSION
    <td>lttng_action_snapshot_session_set_rate_policy()
</table>

@defgroup api_trigger_action_list Trigger action list API
@ingroup api_trigger_action

A <strong><em>trigger action list</em></strong> is an ordered sequence
of trigger actions.

A trigger action list is an action itself: it has
the type #LTTNG_ACTION_TYPE_LIST.

When a trigger having an action list as its action fires, LTTng
attempts to execute its contained actions, in order. Whether or not
LTTng executes a contained action depends on its
\ref api_trigger_action_rate_policy "rate policy". An action list
doesn't have a rate policy itself.

Create a trigger action list with lttng_action_list_create().

Add a trigger action to an action list with
lttng_action_list_add_action().

Get a trigger action from an action list with
lttng_action_list_get_count() and
lttng_action_list_get_at_index().

@defgroup api_trigger_action_notify “Notify” trigger action API
@ingroup api_trigger_action

A <strong><em>“notify”</em></strong> trigger action
sends a notification to any
\ref api_notif "notification channel" subscribed to the satisfied
\ref api_trigger_cond "condition" when its containing trigger fires.

A “notify” trigger action has the type
#LTTNG_ACTION_TYPE_NOTIFY.

Create a “notify” trigger action with
lttng_action_notify_create().

Set and get the \ref api_trigger_action_rate_policy "rate policy"
of a “notify” trigger action with
lttng_action_notify_set_rate_policy() and
lttng_action_notify_get_rate_policy().

@defgroup api_notif Notification channel API
@ingroup api_trigger_action_notify

A <strong><em>notification channel</em></strong> is a special
\ref api-gen-sessiond-conn "connection to an LTTng session daemon"
with which you subscribe to <em>notifications</em> which LTTng
sends when specific \ref api_trigger_cond "trigger conditions"
are satisfied.

LTTng sends a notification to subscribed notification channels when it
executes a \link api_trigger_action_notify “notify”\endlink
trigger action.

To use a notification channel:

-# Create a notification channel with
   lttng_notification_channel_create().

   This call establishes a dedicated, persistent connection with an
   LTTng session daemon.

-# Call lttng_notification_channel_subscribe() one or more times to
   subscribe the notifications which LTTng sends when triggers
   with specific \ref api_trigger_cond "conditions" fire.

-# Call lttng_notification_channel_get_next_notification() to block
   the current thread until the channel receives a new notification.
   Repeat as needed.

   You may also call the non-blocking
   lttng_notification_channel_has_pending_notification() function to
   check whether or not
   lttng_notification_channel_get_next_notification() would return
   immediately.

   With a notification object in hand, you may get:

   - The trigger which fired to send this notification with
     lttng_notification_get_trigger().

   - The satisfied trigger condition with
     lttng_notification_get_condition().

   - The \ref api-trigger-cond-eval "evaluation" of the satisfied
     trigger condition
     with lttng_notification_get_evaluation().

     This object contains values which LTTng captured when the
     trigger fired.

   When you're done with the notification, destroy it with
   lttng_notification_destroy().

-# When you're done with the notification channel, destroy it
   with lttng_notification_channel_destroy().

During the lifetime of the notification channel, you may call
lttng_notification_channel_subscribe() and
lttng_notification_channel_unsubscribe() as you will to modify its
subscriptions.

@note
    If your goal is to capture a large amount of tracing data with
    a trigger having an
    \link api_trigger_cond_er_matches “event rule matches”\endlink
    condition and a
    \link api_trigger_action_notify “notify”\endlink action, then
    prefer creating and using a \lt_obj_session instead.

@defgroup api_trigger_action_start_session “Start recording session” trigger action API
@ingroup api_trigger_action

A <strong><em>“start recording session”</em></strong> trigger action
starts a specific \lt_obj_session when its containing trigger fires.

LTTng finds the recording session to start <em>by name</em> when it
executes the action.

Executing this action is equivalent to calling
lttng_start_tracing() with the same recording session name.

A “start recording session” trigger action has the type
#LTTNG_ACTION_TYPE_START_SESSION.

To create a valid “start recording session” trigger action:

-# Create the initial trigger action with
   lttng_action_start_session_create().

-# Set the target recording session name with
   lttng_action_start_session_set_session_name().

Get the target recording session name of a
“start recording session” trigger action with
lttng_action_start_session_get_session_name().

Set and get the \ref api_trigger_action_rate_policy "rate policy"
of a “start recording session” trigger action with
lttng_action_start_session_set_rate_policy() and
lttng_action_start_session_get_rate_policy().

@defgroup api_trigger_action_stop_session “Stop recording session” trigger action API
@ingroup api_trigger_action

A <strong><em>“stop recording session”</em></strong> trigger action
\link lttng_stop_tracing() stops\endlink
a specific \lt_obj_session when its containing trigger fires.

LTTng finds the recording session to stop <em>by name</em> when it
executes the action.

Executing this action is equivalent to calling
lttng_stop_tracing() with the same recording session name.

A “start recording session” trigger action has the type
#LTTNG_ACTION_TYPE_STOP_SESSION.

To create a valid “stop recording session” trigger action:

-# Create the initial trigger action with
   lttng_action_stop_session_create().

-# Set the target recording session name with
   lttng_action_stop_session_set_session_name().

Get the target recording session name of a
“stop recording session” trigger action with
lttng_action_stop_session_get_session_name().

Set and get the \ref api_trigger_action_rate_policy "rate policy"
of a “stop recording session” trigger action with
lttng_action_stop_session_set_rate_policy() and
lttng_action_stop_session_get_rate_policy().

@defgroup api_trigger_action_rotate “Rotate recording session snapshot” trigger action API
@ingroup api_trigger_action

A <strong><em>“rotate recording session”</em></strong> trigger action
\ref api_session_rotation "rotates"
a specific \lt_obj_session when its containing trigger fires.

LTTng finds the recording session to rotate <em>by name</em> when it
executes the action.

Executing this action is equivalent to calling
lttng_rotate_session() with the same recording session name.

A “start recording session” trigger action has the type
#LTTNG_ACTION_TYPE_ROTATE_SESSION.

To create a valid “rotate recording session” trigger action:

-# Create the initial trigger action with
   lttng_action_rotate_session_create().

-# Set the target recording session name with
   lttng_action_rotate_session_set_session_name().

Get the target recording session name of a
“rotate recording session” trigger action with
lttng_action_rotate_session_get_session_name().

Set and get the \ref api_trigger_action_rate_policy "rate policy"
of a “rotate recording session” trigger action with
lttng_action_rotate_session_set_rate_policy() and
lttng_action_rotate_session_get_rate_policy().

@defgroup api_trigger_action_snapshot “Take recording session snapshot” trigger action API
@ingroup api_trigger_action

A <strong><em>“take recording session snapshot”</em></strong> trigger
action \ref api_session_snapshot "takes a snapshot" of
a specific \lt_obj_session when its containing trigger fires.

LTTng finds the recording session of which to take a snapshot
<em>by name</em> when it executes the action.

Executing this action is equivalent to calling
lttng_snapshot_record() with the same recording session name.

A “start recording session” trigger action has the type
#LTTNG_ACTION_TYPE_SNAPSHOT_SESSION.

To create a valid “take recording session snapshot” trigger action:

-# Create the initial trigger action with
   lttng_action_snapshot_session_create().

-# Set the target recording session name with
   lttng_action_snapshot_session_set_session_name().

The initial recording snapshot output of a
“take recording session snapshot” trigger action is the default
snapshot output of the target recording session. Override the snapshot
output of the action with
lttng_action_snapshot_session_set_output().

Get the target recording session name of a
“take recording session snapshot” trigger action with
lttng_action_snapshot_session_get_session_name().

Set and get the \ref api_trigger_action_rate_policy "rate policy"
of a “take recording session snapshot” trigger action with
lttng_action_snapshot_session_set_rate_policy() and
lttng_action_snapshot_session_get_rate_policy().

@defgroup api_error Error query API

@warning
    @parblock
    The documentation of the error query API is
    <strong>incomplete</strong>.

    The text below shows the typical usage of this API, but the
    types, enumerators, and functions of
    <code>lttng/error-query.h</code> aren't documented
    individually.
    @endparblock

An <strong><em>error query</em></strong> retrieves error information for
a given \ref api_trigger "trigger",
its \ref api_trigger_cond "condition",
or its \ref api_trigger "action" from an
\ref api-gen-sessiond-conn "LTTng session daemon".

To perform an error query:

-# Create the error query object with one of:

   <table>
     <tr>
       <th>Target
       <th>Creation function
     <tr>
       <td>Trigger
       <td>lttng_error_query_trigger_create()
     <tr>
       <td>Trigger condition
       <td>lttng_error_query_condition_create()
     <tr>
       <td>Trigger action
       <td>
         lttng_error_query_action_create(), which accepts a
         \ref api_error_action_path "trigger action path"
         to locate a specific action within
         the action tree formed with
         \ref api_trigger_action_list "action lists".
   </table>

-# Execute the error query against the LTTng session daemon endpoint
   with lttng_error_query_execute(), passing an
   #lttng_error_query_results pointer.

   You need to pass the
   #lttng_session_daemon_command_endpoint endpoint to
   lttng_error_query_execute().

-# Retrieve the number of results with
   lttng_error_query_results_get_count().

-# Borrow a result by index from the results with
   lttng_error_query_results_get_result().

   For a given result:

   - Get the result type with lttng_error_query_result_get_type().

   - Borrow the name and description with
     lttng_error_query_result_get_name() and
     lttng_error_query_result_get_description().

   - If the result type is #LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER,
     retrieve the counter value with
     lttng_error_query_result_counter_get_value().

-# When you're done with the results, destroy them
   with lttng_error_query_results_destroy().

-# Whe you're done with the error query, destroy it with
   lttng_error_query_destroy().

@defgroup api_error_action_path Trigger action path API
@ingroup api_error

@warning
    @parblock
    The documentation of the trigger action path API is
    <strong>incomplete</strong>.

    The text below shows the typical usage of this API, but the
    types, enumerators, and functions of
    <code>lttng/action/path.h</code> aren't documented
    individually.
    @endparblock

A <strong><em>trigger action path</em></strong> specifies how to
traverse a
\ref api_trigger_action "trigger action" tree, formed with
\ref api_trigger_action_list "action lists",
to reach a specific action.

The current purpose of a trigger action path
is to locate a specific action when executing an error query
with lttng_error_query_action_create().

To use a trigger action path:

-# Create an action path with lttng_action_path_create(), passing an
   array of action indexes (within nested action lists) and the number
   of indexes.

-# Pass the trigger action path to lttng_error_query_action_create() to
   locate the specific action when you create an error query.

-# When you're done with the trigger action path, destroy it
   with lttng_action_path_destroy().

Get an action index from a trigger action path with
lttng_action_path_get_index_count() and
lttng_action_path_get_index_at_index().
*/
