2

我正在尝试使用 Babeltrace 1 检查 LTTNG 事件日志中的某个事件链。使用 Babeltrace 集合加载 LTTNG 日志:

import babeltrace

my_collection = babeltrace.TraceCollection()
my_collection.add_traces_recursive(trace_path, 'ctf')

我正在寻找的特殊事件与正在发生的正常事件几乎没有区别,除了链已经开始后还有一些额外的事件。所以我需要寻找这些特殊事件,然后向后搜索真正的开始。

问题是 Babeltrace 只让我在事件列表中前进。简单的解决方案似乎是在我自己的列表中创建事件的克隆:

events = [e for e in my_collection.events]

这样做的问题是列表中的所有事件现在都引用了最后一个事件。这表明 Babeltrace 一遍又一遍地重用同一个对象,并且生成器只返回对该单个对象的引用。

我试过使用copy.copy

events = [copy.copy(e) for e in my_collection.events]

这没有帮助,而且copy.deepcopy根本不起作用。我也试过itertools.tee

events = list(itertools.tee(my_collection.events))

但这会返回一个_tee不能用作正确事件对象的对象列表。

有没有办法使用 Babeltrace 事件集合生成器向后搜索?或者有没有办法正确克隆事件对象以创建我自己的列表?

4

1 回答 1

3

Babeltrace 的共同维护者在这里。

实际上,Babeltrace 1 为每个迭代步骤重用了相同的事件记录对象。这意味着您无法保持“旧”事件记录在其数据在幕后发生变化时保持活动状态。

Babeltrace 1 的 Python 绑定是库对象的基本包装器。这意味着同样的约束也适用。此外,Babeltrace 1 不提供任何事件记录对象复制功能,所以类似的东西copy.copy()只会复制内部指针,然后会出现同样的问题。

出于性能原因,Babeltrace(1 和 2)迭代器不能倒退(更多关于这一点的内容如下)。

我看到的唯一解决方案是制作您自己的事件记录复制功能,将必要的内容保留在您自己类的另一个实例中。毕竟,您可能只需要事件记录的名称、时间戳和一些一级字段。

但是 Babeltrace 2 正是您要寻找的,特别是因为我们不再维护 Babeltrace 1(除了关键/安全错误修复)。

Babeltrace 2 提供了丰富且一致的 C API,其中许多对象都有引用计数,因此可以随心所欲地存在。Babeltrace 2 Python 绑定包装了这个 C API,以便您可以从相同的功能中受益。

虽然 C API 文档是完整的,但不幸的是 Python 绑定还没有。但是,我们有这个,它至少显示了一些示例来帮助您入门。

关于您的评论:

因为看起来事件是一种可以向后走的链表

你不能。这是为了适应某些跟踪格式的限制,特别是CTF(LTTng 使用的格式)。CTF 数据包是一系列序列化的二进制事件记录:要解码事件记录N,您需要先解码事件记录N - 1 ,依此类推。一个 CTF 数据包可以包含数千个这样的连续事件记录,CTF 数据流可以包含数千个数据包,一个 CTF 跟踪可以包含许多数据流。知道了这一点,就没有合理的方法来存储所有编码的 CTF 事件记录的偏移量,这样您就可以在没有大量对象副本的情况下向后迭代。

但是,您可以使用 Babeltrace 2 做的是保留您需要的特定事件记录对象,而无需任何副本。

将来,我们想要一种复制消息迭代器的方法,复制其所有状态以及在幕后继续所需的内容。这将使保留“检查点迭代器”成为可能,以便在由于某种原因无法一次执行分析时可以返回到以前的事件记录。

请注意,您也可以让消息迭代器寻找特定的时间戳,但截至该日期,ctf插件中尚未实现“快速”寻找(迭代器寻找消息序列的开头,然后继续前进,直到达到请求的时间戳,即效率不高)。

于 2021-12-16T14:24:28.197 回答