Skip to content

Implement Communication Logs (network trace recording) endpoints #209

@bburda

Description

@bburda

Summary

Communication logs (ComLogs) allow clients to request the gateway to record ROS 2 network traffic for a specific entity over a period of time. This is similar to a "packet capture" or network trace, but for ROS 2 topics, services, and actions.

In ROS 2, this maps naturally to rosbag2 recording - capturing selected topics to a bag file that can later be downloaded as bulk data.

The workflow is: create a comlog session → start recording → pause/resume as needed → stop → download the result.


Proposed solution

1. POST /api/v1/{entity-path}/comlogs

Create a new communication log recording session for an entity.

Applies to entity types: Components, Apps

Path parameters:

Parameter Type Required Description
{entity-path} URL segment Yes e.g., apps/temp_sensor

Request body:

{
  "topics": ["/temp_sensor/readings", "/temp_sensor/status"],
  "max_duration": 300,
  "max_size": 104857600
}
Field Type Required Description
topics string[] No Specific topics to record. If omitted, record all topics associated with this entity.
max_duration integer No Auto-stop after this many seconds
max_size integer No Auto-stop when recording reaches this size in bytes

Response 201 Created:

{
  "id": "comlog_001",
  "status": "idle",
  "created_at": "2026-02-14T10:30:00Z"
}
Field Type Required Description
id string Yes Unique comlog identifier
status string Yes Initial status is always idle
created_at string (ISO 8601) Yes When the session was created

Location header: /api/v1/{entity-path}/comlogs/comlog_001

Error: 404 if entity doesn't exist.


2. GET /api/v1/{entity-path}/comlogs

List all communication log sessions for an entity.

Response 200 OK:

{
  "items": [
    {
      "id": "comlog_001",
      "status": "capturing",
      "created_at": "2026-02-14T10:30:00Z",
      "size": 1048576,
      "duration": 45
    },
    {
      "id": "comlog_002",
      "status": "completed",
      "created_at": "2026-02-14T09:00:00Z",
      "size": 52428800,
      "duration": 300
    }
  ]
}

3. GET /api/v1/{entity-path}/comlogs/{comlog-id}

Read a specific comlog session's status and details.

Path parameters:

Parameter Type Required Description
{comlog-id} string Yes Comlog session identifier

Response 200 OK:

{
  "id": "comlog_001",
  "status": "capturing",
  "created_at": "2026-02-14T10:30:00Z",
  "started_at": "2026-02-14T10:30:05Z",
  "size": 1048576,
  "duration": 45,
  "topics": ["/temp_sensor/readings", "/temp_sensor/status"],
  "max_duration": 300,
  "max_size": 104857600
}

Status values:

Status Description
idle Created but not yet started
capturing Actively recording
paused Recording paused, can be resumed
completed Recording finished (stopped, max reached, or entity went offline)

Error: 404 if comlog doesn't exist.


4. PUT /api/v1/{entity-path}/comlogs/{comlog-id}

Control a communication log session - start, stop, or pause recording.

Request body:

{
  "action": "start"
}
Field Type Required Description
action string Yes One of: start, stop, pause

Action transitions:

Current Status Valid Actions Result Status
idle start capturing
capturing stop, pause completed, paused
paused start, stop capturing, completed
completed - No valid actions (immutable)

Response 204 No Content on success.

Error responses:

Status Error Code When
400 invalid-parameter Unknown action value
404 resource-not-found Comlog doesn't exist
409 invalid-request Invalid state transition (e.g., start on a completed log)

5. DELETE /api/v1/{entity-path}/comlogs/{comlog-id}

Delete a communication log session and its recorded data.

If the comlog is still capturing or paused, it is stopped first, then deleted.

Response 204 No Content

Error: 404 if comlog doesn't exist.


Downloading ComLog Data

Once a comlog reaches completed status, the recorded data should be downloadable as bulk data. The comlog entry should include a link to the bulk data endpoint:

{
  "id": "comlog_001",
  "status": "completed",
  "_links": {
    "data": "/api/v1/apps/temp_sensor/bulk-data/comlogs/comlog_001"
  }
}

Additional context

ROS 2 mapping - rosbag2

Communication log recording maps to the rosbag2 library:

  1. Create session: Determine topics associated with the entity (from DiscoveryManager - topics published/subscribed by the app's node)
  2. Start recording: Open a rosbag2 writer, subscribe to selected topics, write messages to bag
  3. Pause/resume: Temporarily stop writing (keep topics subscribed) or unsubscribe/resubscribe
  4. Stop: Flush and close the bag file
  5. Download: Serve the bag file via bulk data endpoints

rosbag2 dependencies: rosbag2_cpp, rosbag2_storage

Architecture

  • Create a ComLogManager class
  • Each session: id, entity_id, status, config, bag_writer
  • Lifecycle managed by PUT actions
  • Bag files stored in a configurable directory (e.g., /tmp/ros2_medkit/comlogs/)
  • Auto-stop conditions checked by periodic timer

Topic discovery per entity

For an App entity, topics are:

  • Topics published by that node (from DiscoveryManager.publishers_by_node)
  • Topics subscribed by that node (from DiscoveryManager.subscribers_by_node)

For a Component entity: aggregate topics from all hosted Apps.

Route registration

srv->Post((api_path("/apps") + R"(/([^/]+)/comlogs$)"), handler);
srv->Get((api_path("/apps") + R"(/([^/]+)/comlogs$)"), handler);
srv->Get((api_path("/apps") + R"(/([^/]+)/comlogs/([^/]+)$)"), handler);
srv->Put((api_path("/apps") + R"(/([^/]+)/comlogs/([^/]+)$)"), handler);
srv->Delete((api_path("/apps") + R"(/([^/]+)/comlogs/([^/]+)$)"), handler);
// Same for /components/

Tests

  • Unit test: create comlog → 201 with idle status
  • Unit test: start → status changes to capturing
  • Unit test: pause → capturing changes to paused
  • Unit test: stop → status changes to completed
  • Unit test: invalid transition (start on completed) → 409
  • Unit test: delete while capturing → stops then deletes
  • Unit test: list comlogs → returns all sessions
  • Integration test: create, start, wait, stop, verify data available

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions