Rerun 日志文件加载实战:用 Importer 机制一行代码导入任意文件
【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun
导读
本篇文章围绕 Rerun 官方示例 examples/python/log_file/README.md 展开,系统讲解如何通过 Python SDK 的log_file_from_path/log_file_from_contents两个 API,借助 Rerun 的Importer(导入器)机制,将磁盘上任意 Rerun 能理解的文件(RRD、MCAP、Parquet、URDF、图像等)直接注入当前可视化会话。读完本文,你将掌握这两种 API 的完整签名、参数语义、运行方式,以及它们背后从 Python 绑定到 Rust 底层re_importer的完整调用链,能够在自己项目中用最短代码完成"打开任意文件"的日志记录。
示例概览:一行 Python 加载任意文件
示例的全部逻辑浓缩在 examples/python/log_file/log_file.py 中:遍历命令行传入的文件路径,对每个文件调用一次 Rerun SDK 的日志 API,即可让 Viewer 理解并可视化该文件内容。
for filepath in args.filepaths: if not args.from_contents: # 方式一:直接传入文件路径 rr.log_file_from_path(filepath, entity_path_prefix="log_file_example") else: # 方式二:文件内容已在内存中时,直接传入字节 try: with open(filepath, "rb") as file: rr.log_file_from_contents(filepath, file.read(), entity_path_prefix="log_file_example") except Exception: pass运行方式
README 给出了标准的启动命令(在仓库根目录执行):
python examples/python/log_file/log_file.py examples/assets其中examples/assets目录内置了多种示例资源(如example.rrd、example.png、example.glb、example.ply、example.obj、example.txt等,见 examples/assets),运行后 Viewer 会把这些文件逐一分发到对应的 Importer 进行解析并可视化。命令执行前需先安装 SDK:
pip install rerun-sdk命令行参数结构
示例脚本的参数分为两层:
- 通过
rr.script_add_args(parser)注入的 Rerun SDK 标准参数(如连接/保存选项、--serve等),再由rr.script_setup(args, "rerun_example_log_file")完成会话初始化与配置,最后用rr.script_teardown(args)收尾——这也是所有官方示例的标准三段式写法; - 示例自定义参数:
--from-contents:切换为"按内容"记录模式(仅适用于常规文件,外部加载器不支持);filepaths(位置参数,nargs="+"):一个或多个待加载文件的路径。
核心 API:log_file_from_path与log_file_from_contents
两个 API 的权威实现位于 rerun_py/rerun_sdk/rerun/_log.py#L220-L319,类型签名见 rerun_py/rerun_bindings/rerun_bindings.pyi#L911-L926。
def log_file_from_path( file_path: str | Path, *, entity_path_prefix: str | None = None, static: bool = False, recording: RecordingStream | None = None, ) -> None def log_file_from_contents( file_path: str | Path, file_contents: bytes, *, entity_path_prefix: str | None = None, static: bool = False, recording: RecordingStream | None = None, ) -> None参数详解
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
file_path | str \| Path | 必填 | 待记录文件的路径(log_file_from_contents中用于标识内容来源的文件名) |
file_contents | bytes | 必填(仅 contents 版本) | 已读入内存的文件原始字节 |
entity_path_prefix | str \| None | None | 日志实体路径的前缀,便于将导入内容统一归入指定命名空间 |
static | bool | False | 为True时组件作为静态数据记录:无时间关联、在所有时间线上存在、无条件遮蔽同类型时序数据;为False时自动打上log_time(以及启用时的log_tick)时间戳,同时也会带上通过 [rerun.set_time] 设置的其他时间线 |
recording | RecordingStream \| None | None | 指定使用的 RecordingStream;不传时使用当前激活的数据记录(参见 [rerun.init]、[rerun.set_global_data_recording]) |
两种 API 的取舍
log_file_from_path:直接把文件路径交给 Importer 框架。适合文件尚在磁盘、无需改动原始数据的场景,也是默认推荐方式;log_file_from_contents:当你已经以二进制形式持有文件内容(如从网络、数据库、内存流中拿到数据)时,直接传入字节即可,避免先落盘再读取。示例注释特别强调该方式"仅适用于常规文件,外部加载器(external loaders)不支持"。
两者语义一致:一个路径可能被多个 Importer 同时处理;调用会阻塞,直到至少一个 Importer 开始向数据流推送数据,或所有 Importer 均失败。
底层原理:从 Python 到 Rust 的完整调用链
Python 层函数只是薄封装,实际工作发生在 Rust 端。
1. Python 绑定层
_log.py中的两个函数分别调用绑定接口bindings.log_file_from_path(...)/bindings.log_file_from_contents(...),将Path、entity_path_prefix、static_、recording(转换为原生PyRecordingStream)透传给rerun_py的 pyo3 绑定,最终落到 crates/top/re_sdk/src/recording_stream.rs#L1455-L1482 的RecordingStream::log_file_from_path/log_file_from_contents(两个方法均在importersfeature 下编译)。
2. 统一的log_file内部实现
两条路径汇合到私有方法log_file(recording_stream.rs#L1488-L1589),核心步骤为:
- 校验初始化状态:若 RecordingStream 尚未正确初始化(无
store_info),打印告警并直接返回; - 构造日志通道:通过
re_log_channel::log_channel(LogSource::File { path })建立一条异步数据管道; - 组装 ImporterSettings:携带当前 recording 的
application_id、recording_id、entity_path_prefix、时间点等上下文;当static=false时,会在当前线程的所有时间线上采集当前时刻,并递增log_tick序号(即使未启用log_tick也会递增); - 分发导入:按是否提供内容分别调用
re_importer::import_from_file_contents(...)或re_importer::import_from_path(...)(FileSource::Sdk); - 后台消费:单独启动一个线程(线程名形如
log_file_from_path("...")),不断从通道接收LogMsg并调用record_msg写入当前 recording,句柄被存入importer_handles统一管理。源码注释明确"此调用会阻塞直到至少一个 Importer 开始流式输出或全部失败",正是通道两端同步等待的结果。
3. 外部导入器协议
re_importer还支持发现系统中的外部导入器(ExternalImporter,见 crates/data_flow/re_importer/src/importer_external.rs)。外部导入器会以子进程方式被调用,并接收一组约定好的 CLI 参数(crates/data_flow/re_importer/src/lib.rs#L106-L116),例如:
--application-id <application_id>--recording-id <store_id>--entity-path-prefix <entity_path_prefix>(若设置)--static(当时间点为 timeless 时)--time_sequence <timeline1>=<seq1> <timeline2>=<seq2> ...--time_timestamp_nanos <timeline1>=<ts1> <timeline2>=<ts2> ...(自 epoch 起的纳秒)
Importer 生态:仓库内置了哪些导入器
从 crates/data_flow/re_importer/src/lib.rs#L19-L58 可以看到当前仓库注册的导入器集合,它们共同构成了"打开任意文件"的能力矩阵:
| 导入器 | 源码模块 | 处理的输入 |
|---|---|---|
RrdImporter | importer_rrd.rs | Rerun 原生 RRD 录制文件 |
McapImporter | importer_mcap | MCAP 格式(ROS 生态常见,需mcapfeature,web 端不可用) |
ParquetImporter | importer_parquet.rs | Parquet 列式数据(需parquetfeature,非 wasm) |
LeRobotDatasetImporter | importer_lerobot.rs | LeRobot 机器人数据集目录(需lerobotfeature,非 wasm) |
UrdfImporter | importer_urdf | URDF 机器人模型描述文件(需urdffeature) |
DirectoryImporter | importer_directory.rs | 目录(这解释了示例可以传入examples/assets目录的原因) |
ArchetypeImporter | importer_archetype.rs | 通用 archetype 数据 |
ExternalImporter | importer_external.rs | 外部可执行导入器(非 wasm) |
此外,MCAP 导入器还支持通过FOXGLOVE_LENSES_IDENTIFIER("foxglove")与URDF_DECODER_IDENTIFIER("urdf")启用 Foxglove lenses 与从robot_description话题提取 URDF 的解码能力(lib.rs#L67-L92)。
源码级验证:官方测试与跨语言绑定
仓库提供了针对该能力的测试与多语言绑定,可作为正确用法的权威参考:
- Rust 测试:crates/top/re_sdk/tests/log_file.rs#L47-L69 中
log_file_from_path_retargets_blueprint_to_current_application验证了一个重要行为:通过log_file_from_path导入的 RRD 文件中的 blueprint,会被重定向到当前 recording 的应用,保证导入的蓝图与当前会话一致; - C 绑定:crates/top/rerun_c/src/lib.rs#L1193-L1273 提供了
rr_recording_stream_log_file_from_path/rr_recording_stream_log_file_from_contents两个 C API,与 Python/Rust 签名一一对应,说明该能力是 SDK 层的通用能力而非 Python 独有; - Rust SDK 文档:recording_stream.rs#L1447-L1482 对两个方法给出了与 Python 侧一致的语义说明,可作为跨语言的行为契约。
使用建议与注意事项
- 目录与文件皆可:
filepaths可以同时混传文件和目录(如官方命令直接传入examples/assets目录),由DirectoryImporter递归处理后分发到具体文件导入器; - 命名空间隔离:为每个文件传入不同的
entity_path_prefix,可避免多个文件在实体树中互相覆盖,示例统一使用"log_file_example"前缀; - 静态 vs 时序数据:机器人数据通常带时间轴,保持默认
static=False以保留时间线信息;只有无时间概念的数据才考虑static=True; - 外部加载器限制:
--from-contents模式对外部加载器不适用,若依赖外部导入器请优先走路径模式; - 阻塞语义:调用会阻塞到至少一个 Importer 开始推送数据或全部失败,适合在初始化阶段同步调用,避免在热路径中使用;
- 平台限制:MCAP、Parquet、LeRobot、外部导入器在 wasm/web 目标下不可用,桌面端(native)功能最全(见 re_importer/src/lib.rs 各 feature 的
cfg标注)。
小结
通过rr.log_file_from_path/rr.log_file_from_contents,Rerun 把"打开任意文件"收敛为一次 API 调用:Python 侧两个函数透传给 Rust 端RecordingStream::log_file,由re_importer依据文件类型分派到 RRD、MCAP、Parquet、URDF、LeRobot 等内置导入器或外部导入器,并通过后台线程把解析结果流式写入当前 recording。无论你是在写数据回放工具、加载机器人数据集,还是快速预览录制的日志文件,都可以直接复用示例 log_file.py 的模式,把文件加载逻辑压缩到几行代码之内。
【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考