Rerun TextLog 原型详解:字段模型、组件编码与跨语言日志集成
2026/9/16 19:13:29 网站建设 项目流程

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与原生日志系统(loglogging、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,如logslogs/handler)记录到数据流中。原型的完整字段构成如下:

字段级别组件类型说明
textRequired(必需)Text日志正文,字符串内容
levelRecommended(推荐)TextLogLevel日志严重级别,可用于 Viewer 中过滤日志消息
colorOptional(可选)Color日志行在 Viewer 中显示时使用的颜色

从源码结构看,这一字段划分与 Rust 实现完全对应:TextLog结构体只有textlevelcolor三个字段,且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/3DBoxes2D/3DPoints2D/3DLineStrips2D/3DTextDocument等大量原型用作标签或文本内容。这意味着 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.TextLog
  • component:TextLog:text
  • component_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):以正文构造,levelcolor初始为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::LoggerRecordingStream(引用计数,可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→CriticalERROR→ErrorWARNING→WarningINFO→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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询