Rerun TextLog 原型详解:字段模型、组件编码与跨语言日志集成
【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun
本文围绕 Rerun 的TextLog原型(archetype)展开,系统讲解其由text/level/color三个组件构成的数据模型、各组件的编码方式与 Rust 源码实现细节,并完整给出 Rust、Python、C++ 三种语言将TextLog与原生日志系统(log、logging、Loguru)打通的官方示例代码。读完后,你将能够在自己的项目中以 Rerun 数据流方式记录结构化文本日志,并通过 Rerun Viewer 的 TextLogView / DataframeView 进行查看与过滤。
1. TextLog 原型是什么
Rerun 官方类型参考文档(docs/content/reference/types/archetypes/text_log.md)对TextLog的定义是:
A log entry in a text log, comprised of a text body and its log level. (文本日志中的一条日志记录,由文本正文及其日志级别组成。)
它是 Rerun 数据模型中的一个原型:原型是把若干组件(component)按语义打包在一起的记录单元,每条日志通过一条实体路径(entity path,如logs、logs/handler)记录到数据流中。原型的完整字段构成如下:
| 字段 | 级别 | 组件类型 | 说明 |
|---|---|---|---|
text | Required(必需) | Text | 日志正文,字符串内容 |
level | Recommended(推荐) | TextLogLevel | 日志严重级别,可用于 Viewer 中过滤日志消息 |
color | Optional(可选) | Color | 日志行在 Viewer 中显示时使用的颜色 |
从源码结构看,这一字段划分与 Rust 实现完全对应:TextLog结构体只有text、level、color三个字段,且NUM_COMPONENTS常量被显式标注为 “1 required, 1 recommended, 1 optional”,共 3 个组件(见 crates/store/re_sdk_types/src/archetypes/text_log.rs)。
TextLog可以被以下视图展示:
- TextLogView(docs/content/reference/types/views/text_log_view.md 中的
TextLogView类型定义):专门的文本日志视图,支持列选择、行过滤与格式化选项; - DataframeView:表格视图,可以把日志当作数据表的一列来查询与展示。
2. 字段级组件模型与编码
2.1 text 字段:Text 组件
Text组件的定义是 “A string of text, e.g. for labels and text documents”(一段文本字符串,例如用于标签和文本文档)。它的关键编码信息(见 docs/content/reference/types/components/text.md):
- Rerun 编码:
Utf8; - Arrow 数据类型:
Utf8。
值得注意的是,Text并不是TextLog专属组件——从该组件文档的 “Used by” 列表可以看到,它同样被Arrows2D/3D、Boxes2D/3D、Points2D/3D、LineStrips2D/3D、TextDocument等大量原型用作标签或文本内容。这意味着 Rerun 在类型系统层面复用了同一个字符串组件,日志正文与图形标注共享同一套 Arrow 序列化管线。
2.2 level 字段:TextLogLevel 组件
TextLogLevel表示 “The severity level of a text log message”(文本日志消息的严重级别),同样是Utf8编码的 Arrow 字符串,推荐取值为以下六种:
"CRITICAL""ERROR""WARN""INFO""DEBUG""TRACE"
在 Rust 侧,TextLogLevel是对Utf8编码的一个 newtype 包装(见 crates/store/re_sdk_types/src/components/text_log_level.rs)。由于底层只是 UTF-8 字符串,级别值并非严格封闭枚举——C++ 示例中当 Loguru 的 verbosity 无法映射到已知级别时,直接以rerun::TextLogLevel(std::to_string(message.verbosity))构造自定义级别,这也是该组件 “Recommended” 而非严格枚举的语义体现。
2.3 color 字段
color是可选的Color组件,用于指定该日志行在 Rerun Viewer 中的显示颜色。它使TextLog能够以颜色编码承载额外的语义(例如区分不同来源、不同子系统的日志)。
3. Rust 实现细节:从 def 定义到生成代码
TextLog的 Rust API 是由类型构建器自动生成的:文件头注释明确标注其基于crates/build/re_type_definitions/rerun/archetypes/text_log.def.rs(即 crates/build/re_type_definitions/rerun/archetypes/text_log.def.rs),由代码生成器产出 crates/store/re_sdk_types/src/archetypes/text_log.rs。阅读这份生成代码可以看清 Rerun 原型体系的核心机制:
(1)每个字段都带组件描述符。生成代码为三个字段分别定义了ComponentDescriptor(如 descriptor_text()),其中携带了完整的三元组信息:
archetype:rerun.archetypes.TextLogcomponent:TextLog:textcomponent_type:rerun.components.Text
描述符是数据在 Arrow 列存中往返序列化时的“身份证”,保证反序列化时能按名称精确找回对应列(见from_arrow_components的实现,text_log.rs#L188-L206)。
(2)字段以 Option 承载 Arrow 批。结构体字段类型为Option<SerializedComponentBatch>:None表示该组件未设置,Some内是一个带描述符的 Arrow 数组批。这使同一结构体既能表达单条记录(with_text/with_level/with_color),也能表达整列批量数据(with_many_*系列方法)。
(3)构造与链式更新 API。生成代码提供了完整的使用面:
TextLog::new(text):以正文构造,level与color初始为None(text_log.rs#L229-L238);.with_level(TextLogLevel::TRACE)、.with_color(...):链式补全推荐/可选字段;.with_many_text(...)等:把多个组件打包进单个批,配合columns()使用;.columns(lengths)/.columns_of_unit_batches():将组件批按长度切分为SerializedComponentColumn列,供RecordingStream::send_columns直接发送列式数据(text_log.rs#L266-L311)。
(4)可视化注册。VisualizableArchetypetrait 实现将TextLog注册到名为TextLog的可视化器(text_log.rs#L222-L227),这是它能够在 Viewer 中被自动渲染的底层依据。
4. 实战示例:与原生日志系统集成
官方类型文档给出的示例名为text_log_integration,其核心思路是两种用法并存:直接记录一条TextLog,以及把宿主语言的整个日志框架接入 Rerun。仓库中提供 Rust、Python、C++ 三版实现,可分别作为对应语言项目的接入模板。
4.1 Rust 版(对接log宏与RUST_LOG)
来源:docs/snippets/all/archetypes/text_log_integration.rs
use rerun::external::log; fn main() -> Result<(), Box<dyn std::error::Error>> { let rec = rerun::RecordingStreamBuilder::new( "rerun_example_text_log_integration", ) .spawn()?; // 用法一:直接记录一条 TextLog rec.log( "logs", &rerun::TextLog::new("this entry has loglevel TRACE") .with_level(rerun::TextLogLevel::TRACE), )?; // 用法二:把 Rerun 挂到标准 logging 接口上 rerun::Logger::new(rec.clone()) // recording streams are ref-counted .with_path_prefix("logs/handler") // 同时支持标准的 `RUST_LOG` 环境变量! .with_filter(rerun::default_log_filter()) .init()?; log::info!( "This INFO log got added through the standard logging interface" ); log::logger().flush(); Ok(()) }要点解析:
- 第一条日志走
rec.log("logs", &TextLog),手工指定TRACE级别; - 第二条日志则完全不感知 Rerun 的存在——
rerun::Logger把RecordingStream(引用计数,可clone()共享)包装成全局loghandler,之后所有log::info!等宏调用都会落到logs/handler实体下; with_filter(rerun::default_log_filter())复用了标准的RUST_LOG过滤语义,级别过滤在数据发出前完成,而非全部写入再在 Viewer 里筛。
4.2 Python 版(对接logging模块)
来源:docs/snippets/all/archetypes/text_log_integration.py
"""Shows integration of Rerun's `TextLog` with the native logging interface.""" import logging import rerun as rr rr.init("rerun_example_text_log_integration", spawn=True) # 用法一:直接记录一条 TextLog rr.log( "logs", rr.TextLog("this entry has loglevel TRACE", level=rr.TextLogLevel.TRACE), ) # 用法二:挂到 Python 标准 logging 的 handler 上 logging.getLogger().addHandler(rr.LoggingHandler("logs/handler")) logging.getLogger().setLevel(-1) logging.info("This INFO log got added through the standard logging interface")Python 侧的接入点是把rr.LoggingHandler附加到 root logger 上:此后任何模块调用logging.info(...)产生的记录都会以TextLog形式写入logs/handler实体。
4.3 C++ 版(对接 Loguru)
来源:docs/snippets/all/archetypes/text_log_integration.cpp
/// 将 C++ Loguru 日志库桥接到 Rerun #include <loguru.hpp> #include <rerun.hpp> void loguru_to_rerun(void* user_data, const loguru::Message& message) { // 注意:`rerun::RecordingStream` 是线程安全的 const rerun::RecordingStream* rec = reinterpret_cast<const rerun::RecordingStream*>(user_data); // 把 Loguru 的 Verbosity 映射为 TextLogLevel rerun::TextLogLevel level; if (message.verbosity == loguru::Verbosity_FATAL) { level = rerun::TextLogLevel::Critical; } else if (message.verbosity == loguru::Verbosity_ERROR) { level = rerun::TextLogLevel::Error; } else if (message.verbosity == loguru::Verbosity_WARNING) { level = rerun::TextLogLevel::Warning; } else if (message.verbosity == loguru::Verbosity_INFO) { level = rerun::TextLogLevel::Info; } else if (message.verbosity == loguru::Verbosity_1) { level = rerun::TextLogLevel::Debug; } else if (message.verbosity == loguru::Verbosity_2) { level = rerun::TextLogLevel::Trace; } else { level = rerun::TextLogLevel(std::to_string(message.verbosity)); } rec->log( "logs/handler/text_log_integration", rerun::TextLog(message.message).with_level(level) ); } int main(int argc, char* argv[]) { const auto rec = rerun::RecordingStream("rerun_example_text_log_integration"); rec.spawn().exit_on_failure(); // 用法一:直接记录一条 rec.log( "logs", rerun::TextLog("this entry has loglevel TRACE") .with_level(rerun::TextLogLevel::Trace) ); // 用法二:注册 Loguru 回调(仅 INFO 及以上) loguru::add_callback( "rerun", loguru_to_rerun, const_cast<void*>(reinterpret_cast<const void*>(&rec)), loguru::Verbosity_INFO ); LOG_F(INFO, "This INFO log got added through the standard logging interface"); // 必须在 `rec` 析构之前移除回调: loguru::remove_callback("rerun"); }C++ 版额外展示了跨语言级别映射的完整分支(FATAL→Critical、ERROR→Error、WARNING→Warning、INFO→Info、_1→Debug、_2→Trace),并提示了两个工程细节:RecordingStream线程安全,可直接在回调中调用;回调必须在流对象析构前remove_callback,避免悬垂指针。
5. 在 Viewer 中查看:TextLogView 与 DataframeView
TextLog记录完成后,展示侧由蓝图(blueprint)视图接管。参考文档 TextLogView 类型定义 说明,该视图当前标记为不稳定(unstable),属性结构为:
columns:要显示的列,其中timeline_columns指定显示哪些时间线列,text_log_columns指定日志数据列;rows:对要显示的行进行过滤;format_options:文本日志视图的格式化选项。
配合TextLogLevel字段,TextLogView 可以按级别过滤日志消息——这正是原型文档中 “This can be used to filter the log messages in the Rerun Viewer” 一句的落地机制。若希望以表格方式做进一步查询(例如把日志与机器人其他数据流按时间对齐),则可将同一实体交给 DataframeView 展示。
6. 小结与延伸阅读
TextLog是 Rerun 数据模型中一个典型的“小而完整”的原型:一个必需的Text正文、一个推荐的TextLogLevel级别和一个可选的Color,三者通过统一的 ArrowUtf8编码进入同一套存储与查询管线,并在展示侧由 TextLogView 与 DataframeView 消费。其设计价值在于:日志不再是散落在终端的瞬态输出,而是成为带时间轴、可过滤、可与其他多模态机器人数据共同查询的一等数据。
如需继续深入当前仓库,建议按以下路径阅读:
- 原型文档:docs/content/reference/types/archetypes/text_log.md;
- 组件文档:Text、TextLogLevel;
- 类型定义源:crates/build/re_type_definitions/rerun/archetypes/text_log.def.rs(生成代码的上游);
- Rust 实现:crates/store/re_sdk_types/src/archetypes/text_log.rs、crates/store/re_sdk_types/src/components/text_log_level.rs;
- 三语言官方示例:Rust、Python、C++。
【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考