SkillAgentSearch skills...

Yaets

YAETS (Yet Another Execution Tracing System) is a library designed to trace function execution in C++ asynchronously, combined with Python tools to analyze the results through Gantt charts and histograms.

Install / Use

/learn @fmrico/Yaets
About this skill

Quality Score

0/100

Category

Design

Supported Platforms

Universal

README

YAETS: Yet Another Execution Tracing System

Doxygen Deployment rolling kilted jazzy humble

Doxygen documentation: https://fmrico.github.io/yaets/

YAETS is a library designed to trace function execution in C++ asynchronously, combined with Python tools to analyze the results through Gantt charts and histograms.

histogram gantt

Features

  • Function tracing using the TraceSession, TraceGuard, NamedSharedTrace, and TraceRegistry classes.
  • Asynchronous logging of trace events to prevent performance overhead.
  • Python scripts to visualize traces as Gantt charts or analyze timing gaps between traces using histograms.

Table of Contents

Installation

Requirements

  • C++17 or later
  • CMake for building the project
  • Python 3.6+ for running the scripts
  • Matplotlib for visualizing data in Python

Building the C++ Library without ROS

  1. Clone the repository and navigate to the project directory:

    git clone https://github.com/fmrico/yaets.git
    cd yaets
    
  2. Build the library using CMake:

    mkdir build
    cd build
    cmake ..
    make
    
  3. Install the library:

    sudo make install
    

Building the C++ Library with ROS 2

  1. Clone the repository and navigate to the project directory:

    cd my_ros_ws/src
    git clone https://github.com/fmrico/yaets.git
    cd ..
    
  2. Build the library using Colcon:

    colcon build
    

Usage

C++ Tracing Library

YAETS provides a simple C++ library for tracing function execution times. The key classes are TraceSession and TraceGuard.

Example

#include <yaets/tracing.hpp>

void example_function(yaets::TraceSession& session) {
    TRACE_EVENT(session);  // Automatically traces function entry and exit
    // Your function logic here
}

int main() {
    yaets::TraceSession session("trace_output.log");

    example_function(session);

    session.stop();  // Stop the session and flush all trace events
    return 0;
}

Advanced Tracing with NamedSharedTrace and TraceRegistry

For scenarios where you need to trace shared events across multiple parts of your application, you can use NamedSharedTrace and TraceRegistry.

NamedSharedTrace

The NamedSharedTrace class allows you to start and stop traces from different parts of the code, under a shared trace name.

#include <yaets/tracing.hpp>

int main() {
    yaets::TraceSession session("shared_trace_output.log");

    yaets::NamedSharedTrace trace1(session, "shared_event");
    trace1.start();
    // Perform operations
    trace1.end();

    session.stop();
    return 0;
}

Using TraceRegistry to Manage Shared Traces by ID

With TraceRegistry, you can register and manage multiple NamedSharedTrace instances by ID, allowing you to start and stop traces throughout the application without directly referencing NamedSharedTrace objects.

  1. Initialize TraceRegistry: Register traces with IDs for centralized management.
  2. Start and Stop Traces by ID: Use macros to simplify starting and stopping traces.
#include <yaets/tracing.hpp>

int main() {
    yaets::TraceSession session("registry_trace_output.log");

    // Register traces with unique IDs
    yaets::TraceRegistry::getInstance().registerTrace("trace1", session);
    yaets::TraceRegistry::getInstance().registerTrace("trace2", session);

    // Start and end traces by ID
    yaets::TraceRegistry::getInstance().startTrace("trace1");
    // Operations for trace1
    yaets::TraceRegistry::getInstance().endTrace("trace1");

    yaets::TraceRegistry::getInstance().startTrace("trace2");
    // Operations for trace2
    yaets::TraceRegistry::getInstance().endTrace("trace2");

    session.stop();
    return 0;
}

Using Macros with NamedSharedTrace

To streamline the usage of NamedSharedTrace with TraceRegistry, YAETS provides macros for initializing, starting, and stopping traces by ID. This simplifies code readability and reduces the need to call methods directly on TraceRegistry.

Example 1

include <yaets/tracing.hpp>

int main() {
    yaets::TraceSession session("macro_trace_output.log");

    // Initialize traces by ID
    SHARED_TRACE_INIT(session, "macro_trace1");
    SHARED_TRACE_INIT(session, "macro_trace2");

    // Start and stop traces by ID
    SHARED_TRACE_START("macro_trace1");
    // Operations under macro_trace1
    SHARED_TRACE_END("macro_trace1");

    SHARED_TRACE_START("macro_trace2");
    // Operations under macro_trace2
    SHARED_TRACE_END("macro_trace2");

    session.stop();
    return 0;
}

Example 2

class SensorDriverNode : public rclcpp::Node
{
  ...
  void produce_data()
  {
    SHARED_TRACE_START("brake_process");
    waste_time(shared_from_this(), 200us);

    sensor_msgs::msg::Image image_msg;
    pub_->publish(image_msg);
  }
...
class BrakeActuatorNode : public rclcpp::Node
{
  ...
  void react_obstacle(vision_msgs::msg::Detection3D::SharedPtr msg)
  {
    waste_time(shared_from_this(), 2ms);
    SHARED_TRACE_END("brake_process");
  } 
...
int main(int argc, char * argv[])
{
  ...
  SHARED_TRACE_INIT(session, "brake_process");

How It Works

  • TraceSession: Manages the tracing session and writes events asynchronously to a log file.
  • TraceGuard: Automatically traces the start and end of a function. It is created at the start of the function and destroyed when the function exits, capturing the execution time.
  • NamedSharedTrace: Allows you to create named traces that can be started and stopped independently across different parts of your code.
  • TraceRegistry: Provides centralized management of NamedSharedTrace instances, allowing you to register, start, and stop traces by ID.

Key Methods

  • TraceSession::TraceSession(const std::string & filename): Initializes the session and specifies the output file for trace events.
  • TraceSession::stop(): Stops the session and writes any remaining events to the file.
  • TraceGuard::TraceGuard(TraceSession & session, const std::string & function_name): Captures the function name and start time.
  • TraceGuard::~TraceGuard(): Logs the end time and registers the trace event.
  • NamedSharedTrace::start(): Begins a trace event.
  • NamedSharedTrace::end(): Ends a trace event and logs it to the associated TraceSession.
  • TraceRegistry::registerTrace(const std::string& id, TraceSession& session): Registers a new trace with a unique ID.
  • TraceRegistry::startTrace(const std::string& id): Starts a trace by its ID.
  • TraceRegistry::endTrace(const std::string& id): Ends a trace by its ID.

Python Gantt Chart Script

The Python script gantt.py allows you to visualize the traced functions as a Gantt chart.

Usage

  1. Ensure the trace log file is generated from your C++ program (e.g., trace_output.log).
  2. Run the gantt.py script:
    python3 scripts/gantt.py trace_output.log --max_traces 100
    
    or altenativelly
    ros2 run yaets gantt.py trace_output.log
    
View on GitHub
GitHub Stars87
CategoryDesign
Updated5d ago
Forks2

Languages

C++

Security Score

95/100

Audited on Mar 27, 2026

No findings