Skip to main content

Schema Reference

ROSQL expects telemetry data in the OpenTelemetry schema conventions for ROS2. This document defines the complete schema: table definitions, span attributes, field mappings, and schema profiles.

If you're building a ROS2-to-OTel bridge or setting up your own telemetry storage, implement these conventions to get full ROSQL feature support.


Span attributes

ROS2 action executions

AttributeTypeExampleUsed by ROSQL for
ros.nodestring/bt_navigatorWHERE node = '...'
ros.action.namestring/navigate_to_poseWHERE action_name = '...'
ros.action.typestringnav2_msgs/action/NavigateToPoseAction type filtering
ros.action.goal_idstringUUIDGoal correlation
ros.action.statusstringsucceeded / aborted / canceledAction status filtering

ROS2 pub/sub tracing

AttributeTypeExampleUsed by ROSQL for
ros.topicstring/cmd_velTopic filtering, MESSAGE PATHS
ros.message_typestringgeometry_msgs/msg/TwistMessage type filtering
ros.publisher_nodestring/controller_serverPublisher attribution
ros.subscriber_nodestring/motor_driverSubscriber attribution

ParentSpanId convention for MESSAGE JOURNEY

The publish span's SpanId must be set as the ParentSpanId of the corresponding subscribe span. This creates the causal chain that MESSAGE JOURNEY traverses.

Publisher span (SpanId: "abc")
└── Subscriber span (ParentSpanId: "abc", SpanId: "def")
└── Downstream span (ParentSpanId: "def", SpanId: "ghi")

Implementing this correctly requires middleware-level instrumentation — it cannot be done purely at the application level without code changes to every node.


Metric naming conventions

Metric nameUnitDescription
ros2.topic.rx_rate_hzHzTopic receive rate
ros2.topic.rx_bandwidth_bpsB/sTopic bandwidth
ros2.topic.last_message_age_msmsAge of last received message
system.cpu.total_usage_pct%Total CPU usage
system.memory.usage_pct%Memory usage

Required tables

These three tables are required for basic ROSQL functionality.

otel_traces

CREATE TABLE otel_traces (
timestamp TIMESTAMPTZ NOT NULL,
trace_id TEXT NOT NULL,
span_id TEXT NOT NULL,
parent_span_id TEXT NOT NULL DEFAULT '',
span_name_col TEXT NOT NULL,
span_kind TEXT NOT NULL DEFAULT 'INTERNAL',
service_name TEXT NOT NULL DEFAULT '',
duration BIGINT NOT NULL, -- nanoseconds
status_code TEXT NOT NULL DEFAULT 'OK',
span_attributes JSONB NOT NULL DEFAULT '{}',
resource_attributes JSONB NOT NULL DEFAULT '{}'
);

Used by: FROM traces, MESSAGE JOURNEY, MESSAGE PATHS, TRACE, HEALTH(), ANOMALY(), DURING(), CORRELATE, SINCE last action failure

otel_logs

CREATE TABLE otel_logs (
timestamp TIMESTAMPTZ NOT NULL,
trace_id TEXT NOT NULL DEFAULT '',
span_id TEXT NOT NULL DEFAULT '',
severity_text TEXT NOT NULL DEFAULT 'INFO',
severity_number INTEGER NOT NULL DEFAULT 9,
service_name TEXT NOT NULL DEFAULT '',
body TEXT NOT NULL DEFAULT '',
resource_attributes JSONB NOT NULL DEFAULT '{}',
log_attributes JSONB NOT NULL DEFAULT '{}'
);

Used by: FROM logs, HEALTH()

otel_metrics

CREATE TABLE otel_metrics (
timestamp TIMESTAMPTZ NOT NULL,
metric_name TEXT NOT NULL,
value DOUBLE PRECISION NOT NULL,
attributes JSONB NOT NULL DEFAULT '{}',
service_name TEXT NOT NULL DEFAULT ''
);

Used by: FROM metrics, HEALTH(), CORRELATE


Optional tables

These tables enable additional ROSQL features. If absent, ROSQL returns a clear DataSourceUnavailable error with guidance.

topic_messages

CREATE TABLE topic_messages (
robot_id TEXT NOT NULL,
topic_name TEXT NOT NULL,
timestamp TIMESTAMPTZ NOT NULL,
fields JSONB NOT NULL DEFAULT '{}',
message_type TEXT NOT NULL DEFAULT ''
);

Used by: FROM topics, FROM odom (and other topic aliases), PATH DEVIATION

mcap_metadata

CREATE TABLE mcap_metadata (
robot_id TEXT NOT NULL,
session_id TEXT NOT NULL,
start_time TIMESTAMPTZ NOT NULL,
end_time TIMESTAMPTZ NOT NULL,
s3_key TEXT NOT NULL,
topics TEXT[] NOT NULL DEFAULT '{}'
);

Used by: FROM recordings, SHOW RECORDING


ROSQL field mappings

From otel_traces

ROSQL fieldColumnStorage unit
trace_idtrace_id
span_idspan_id
parent_span_idparent_span_id
span_namespan_name_col
serviceservice_name
durationdurationnanoseconds
statusstatus_codeOK / ERROR
nodespan_attributes->>'ros.node'
action_namespan_attributes->>'ros.action.name'
action_statusspan_attributes->>'ros.action.status'
topicspan_attributes->>'ros.topic'

From otel_metrics

ROSQL fieldResolved asStorage unit
metric_namemetric_name
metric_valuevaluevaries
publish_ratevalue WHERE metric_name = 'ros2.topic.rx_rate_hz'Hz
bandwidthvalue WHERE metric_name = 'ros2.topic.rx_bandwidth_bps'B/s
cpu_usagevalue WHERE metric_name = 'system.cpu.total_usage_pct'%
memory_usagevalue WHERE metric_name = 'system.memory.usage_pct'%

From otel_logs

ROSQL fieldColumn
messagebody
severityseverity_text
severity_numberseverity_number

Schema profiles

ProfileConventionExampleDefault for
otel-postgresLowercasetrace_id, status_codePostgreSQL, MySQL
otel-clickhousePascalCaseTraceId, StatusCodeClickHouse
rosql compile "FROM traces WHERE status = 'ERROR'" \
--backend postgres \
--schema otel-postgres

Custom schema profiles: tracked in #22.


Topic aliases

ROSQL sourceResolves to
FROM odomFROM topics WHERE topic_name = '/odom'
FROM joint_statesFROM topics WHERE topic_name = '/joint_states'
FROM batteryFROM topics WHERE topic_name = '/battery_state'
FROM cmd_velFROM topics WHERE topic_name = '/cmd_vel'
FROM imuFROM topics WHERE topic_name = '/imu/data'