Skip to main content
Version: 0.3

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


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'