探针 (API)
通用探测 REST API
以下信息介绍了尽可能多的 API,以便熟悉 Apstra API 约定的人员了解如何使用 IBA。正式的 API 文档是为 API 文档本身保留的。
我们将逐步介绍用于简介中描述的示例工作流的 API,并通过特定示例演示其一般功能。
创建探测器
要创建探测器,操作员使用以下形式开机自检 /api/blueprints/<blueprint_id>/probes
:
{ "label": "server_tx_bytes", "description": "Server traffic imbalance", "tags": ["server", "imbalance"], "disabled": false, "processors": [ { "name": "server_tx_bytes", "outputs": { "out": "server_tx_bytes_output" }, "properties": { "counter_type": "tx_bytes", "graph_query": "node('system', name='sys').out('hosted_interfaces').node('interface', name='intf').out('link').node('link', link_type='ethernet', speed=not_none()).in_('link').node('interface', name='dst_intf').in_('hosted_interfaces').node('system', name='dst_node', role='server').ensure_different('intf', 'dst_intf')", "interface": "intf.if_name", "system_id": "sys.system_id" }, "type": "if_counter" }, { "inputs": { "in": "server_tx_bytes_output" }, "name": "std", "outputs": { "out": "std_dev_output" }, "properties": { "ddof": 0, "group_by": [] }, "type": "std_dev" }, { "inputs": { "in": "std_dev_output" }, "name": "server_imbalance", "outputs": { "out": "std_dev_output_in_range" }, "properties": { "range": { "max": 100 } }, "type": "range_check" }, { "inputs": { "in": "std_dev_output_in_range" }, "name": "server_imbalance_anomaly", "outputs": { "out": "server_traffic_imbalanced" }, "type": "anomaly" } ], "stages": [ { "name": "server_tx_bytes_output", "description": "Collect server tx_bytes", "tags": ["traffic counter"], "units": "Bps" } ] }
如上所示,终结点将获得探测元数据的输入、处理器实例列表和输出阶段列表。
探测器元数据由以下字段组成:
label | 人类可读的探针标签;必填 |
description | 探头的可选描述, |
tags | 带有探测标签的字符串列表;选 |
disabled | 指示是否应禁用探测器的可选布尔值。禁用的探测器不提供任何数据,也不会消耗任何资源。默认情况下,探测器未处于禁用状态。 |
每个处理器实例都包含一个实例名称(由用户定义)、处理器类型(从平台和参考设计定义的目录中选择)和 inputs
/或 outputs
。每个处理器中的所有附加字段都特定于该类型的处理器,在子字段中指定 properties
,并且可以通过我们的自省 API 进行自省来学习;我们稍后将介绍此 API /api/blueprints/<blueprint_id>/telemetry/processors
。
匹配我们的工作示例,我们将遍历上面示例中处理器列表中的每个条目。
在第一个条目中,我们有一个类型的if_counter
处理器实例,我们命名 server_tx_bytes
.它接受一个名为图形查询的graph_query
查询作为输入。然后,它还有另外两个名为 interface
和 system_id
的字段。这三个字段共同表示我们要为系统中每个面向服务器的端口收集一个(第一次时间导数)计数器。对于 指定的graph_query
查询的每个匹配项,我们通过获取结果路径中节点的sys
字段(如处理器字段中指定system_id
)来提取system_id,并通过获取if_name
结果路径中节点的intf
字段(如处理器字段中指定interface
)来system_id
提取接口名称。系统ID和接口的组合用于识别网络中的接口,其tx_bytes计数器(由 指定counter_type
)放入该处理器的输出中。该处理器的输出类型为“数字集”(NS);稍后将详尽讨论阶段类型。该处理器没有输入,因此我们不提供input
字段。它有一个输出,标记为out
(由if_counter处理器类型定义);我们将该输出映射到标记为 server_tx_bytes_output
的阶段。
第二个处理器的类型是,并将我们之前server_tx_bytes_output
创建的阶段作为输入;有关该ddof
字段的含义,std_dev
请参阅特定于处理器的文档。另请参阅特定于处理器的文档,了解该group_by
字段的完整含义。现在group_by
只要说,在这种情况下告诉我们从输入NS构造一个输出“数字”(N)就足够了;也就是说,这个处理器输出一个数字 - 许多输入数字中的每一个的标准偏差。此输出名为“std_dev_output”。
第三个处理器的类型 range_check
并作为输入 std_dev_output
。它检查输入是否超出 - range
在这种情况下,如果输入大于 100(我们选择此任意值来指示服务器定向流量何时不平衡)。该处理器有一个 我们选择标记 std_dev_output_in_range
的单个输出 .此输出(由range_check处理器类型定义)的类型为 DS(离散状态),可以采用 true
或 的值 false
,指示值是否超出范围。
我们的最终处理器是类型 anomaly
并作为输入 std_dev_output_in_range
。当输入处于该 true
状态时,它会引发 Apstra 异常。该处理器有一个 我们选择标记 server_traffic_imbalanced
的单个输出 .此输出(由异常处理器类型定义)的类型为 DS(离散状态),可以采用 true
或 的值 false
,指示是否引发异常。在此示例中,我们不会对此异常状态数据进行任何进一步处理,但这并不排除其一般可能性。
最后,我们有一个 stages
领域。这是输出阶段子集的列表,每个阶段由引用阶段标签的字段指示 name
。此列表旨在向无法从 DAG 本身推断的每个输出阶段添加元数据。目前,支持的字段包括:
description | 带有阶段描述的字符串, |
tags | 为舞台制作一组标签的字符串列表, |
units | 用于描述阶段数据的单位的字符串。 |
所有这些字段都是可选的。
通过 REST API 从该阶段获取数据时,将返回此阶段元数据,并由 GUI 在可视化中使用。
HTTP POST 可以发送到 /api/blueprints/<blueprint_id>/probes
。在这里,我们进行 POST 探测器配置,如“用于创建探测器的 POST”图中所示,以创建新探测器。POST 到此端点将返回一个 UUID,就像 Apstra 中的大多数其他创建端点一样,可用于进一步的操作。
在 2.3 版更改: 若要获取可预测的探测 ID 而不是上述 UUID,可以通过向请求正文添加“id”属性来指定它。
{ "id": "my_tx_bytes_probe", "label": "server_tx_bytes", "processors": [], "rest_of_the": "request_body" }
在 2.3 版更改: 以前,阶段定义内联到处理器定义中,如下所示:
{ "label": "test probe", "processors": [ { "name": "testproc", "outputs": {"out": "test_stage"}, "stages": [{"name": "out", "units": "pps"}] } ] }
这不再有效,阶段名称应引用阶段标签而不是内部阶段名称。所以上面的示例应该是这样的:
{ "stages": [{"name": "test_stage", "units": "pps"}] }
附加说明:建议不要将阶段定义内联到处理器定义中,而是将其作为独立元素放置,如上面的 POST 示例所示。
HTTP DELETE 可以发送到 /api/blueprints/<blueprint_id>/probes/<probe_id>
删除其 probe_id
指定的探测的位置。
可以发送 /api/blueprints/<blueprint_id>/probes/<probe_id>
HTTP GET 以检索探测器在发布时的配置。它将包含比创建探测器时指定的字段更多的字段:
id | 使用探测器的 ID(如果在创建时未指定,则为 UUID), |
state | 与探头的实际状态;可能的值为正在配置的探测器为“创建”,对于成功配置的探测器为“操作”,如果探测器配置失败,则为“错误”。 |
last_error | 包含处于“错误”状态的探测器的最新错误的详细错误说明。它具有以下子字段:
|
可以通过向 发出 /api/blueprints/<blueprint_id>/probes/<probe_id>/messages
HTTP GET 请求来获取探测消息的完整列表。
消息按“时间戳”字段排序,最早的先到。
此外,可以发送 /api/blueprints/<blueprint_id>/probes
HTTP GET 以检索蓝图 <blueprint_id>
的所有探测。
2.3
用于探测的 HTTP PATCH 和 PUT 方法从 Apstra 版本 2.3 开始可用。
可以将 HTTP PATCH 发送到以 /api/blueprints/<blueprint_id>/probes/<probe_id>
更新探测元数据或者禁用或启用探测。
{ "label": "new server_tx_bytes", "description": "some better probe description", "tags": ["production"], "stages": [ { "name": "server_tx_bytes", "description": "updated stage description", "tags": ["server traffic"], "units": "bps" } ] }
此示例更新使用上面列出的 POST 请求创建的探测器的探测器元数据。此处的所有字段都是可选的,未指定的值保持不变。
每个阶段实例也是可选的,即仅更新指定的阶段,未指定的阶段保持不变。
标签集合是完全更新的,即如果它是 tags: ["a", "b"]
并且指定 tags: ["c"]
了 PATCH 有效负载,那么生成的集合将看起来像 tags: ["c"]
(NOT tags: ["a", "b", "c"]
)。
使用PATCH,无法更改探头的处理器和平台集。请进一步阅读允许这样做的PUT说明。
可以将 HTTP PUT 发送到 /api/blueprints/<blueprint_id>/probes/<probe_id>
以替换探测。
这与 POST 非常相似,不同之处在于它用有效负载中指定的新配置替换了探测 <probe_id>
的旧配置。此请求的有效负载格式与 POST 相同,但 id
不允许。
检查探针
阶段是通过在各种处理器的输入和输出中命名来隐式创建的。您可以检查探头的各个阶段。用于读取特定阶段的 API 是 /api/blueprints/<blueprint_id>/probes/<probe_id>/stages/<stage_name>
每个阶段都有一个类型。这是生成处理器和该处理器的输入级的功能。类型是:数字(N);数字时间序列 (NTS),数字集 (NS);数字集时间序列 (NSTS);文本 (T);文本时间序列 (TTS);文本集 (TS);文本集时间序列 (TSTS);离散状态 (DS);离散状态时间序列 (DSTS);离散状态集 (DSS);离散集时间序列 (DSSTS)
NS就是:一组数字。
同样,DSS 是一组离散状态变量。DSS(和 DSSTS)阶段的部分规范是离散状态变量可以采用的可能值。
文本集是一组字符串。
NSTS 是一组以数字作为值的时间序列。例如,此集合的成员将是:(时间 = 0 秒,值 = 3)、(时间 = 3 秒,值 = 5)、(时间 = 6 秒,值 = 23)等等。
DSTS 与 NSTS 相同,只是值是离散状态。
TSTS 与 NSTS 相同,只是值是字符串。
数字 (N)、离散状态 (DS) 和文本 (T) 只是数字集、离散状态集和保证长度为 1 的文本集。
NTS、DSTS 和 TS 与上述相同,但属于时间序列,而不是单个值。
让我们考虑第一阶段 - “server_tx_bytes”。此阶段包含系统中每个面向服务器的端口的tx_bytes计数器。我们可以从网址中获取它 /api/blueprints/<blueprint_id>/probes/<probe_id>/stages/server_tx_bytes_output
我们得到的响应形式如下:
{ "properties": [ "interface", "system_id" ], "type": "ns", "units": "bytes_per_second", "values": [ { "properties": { "interface": "intf1", "system_id": "spine1" }, "value": 22 }, { "properties": { "interface": "intf2", "system_id": "spine1" }, "value": 23 }, { "properties": { "interface": "intf1", "system_id": "spine3" }, "value": 24 } ] }
从运行示例中我们知道,“server_tx_bytes”阶段包含网络中每个面向服务器的接口的tx_bytes值。看上面的例子,我们可以看到这个阶段的类型是“ns”,表示NS或数字集。如前所述,分阶段的数据与上下文相关联。这意味着阶段集合中的每个元素都与一组键值对相关联。在每个阶段,每个数据(或等效地,集合中的项目)的键都是相同的。这些键列在给定阶段的“属性”字段中,通常是生成处理器的功能。“值”中的每个项目为阶段的每个属性分配一个值,并提供一个值(“数字集”中的“数字”)。此数据在此阶段的含义是,主干 1 的 intf1 上的tx_bytes为 22,主干 1 的 intf2 上的为 23,主干 3 的 intf1 上的为每秒 24 字节。
请注意,已按照运行示例中的指定为此阶段设置了“单位”。
要查询探测中的第二阶段,请向 std 端点 /api/blueprints/<blueprint_id>/probes/<probe_id>/stages/std_dev_output
发送 HTTP GET 。
{ "type": "n", "units": "", "value": 1 }
这个阶段是一个数字。它没有上下文,只有一个值。在我们的示例中,这是所有脊柱的标准偏差。
我们探测器的倒数第二级可以在端点 /api/blueprints/<blueprint_id>/probes/<probe_id>/stages/server_traffic_imbalanced
处查询。
{ "possible_values": [ "true", "false" ], "type": "ds", "units": "", "value": false }
如图所示,此阶段通过指示所有面向服务器的端口之间的 tx_bytes 标准偏差是否大于 100,来指示服务器流量是不平衡(“真”)还是不不平衡(“假”)。请注意,“possible_values”字段描述了离散状态“值”可以采用的所有值。
也可以通过 查询 /api/blueprints/<blueprint_id>/probes/<probe_id>/processors/<processor_name>
探测器的所有处理器。通过执行此类查询,您可以发现用于创建所述处理器的配置。
查询探测异常
示例处理器的最后阶段会引发 Apstra 异常(并将其输出设置为“true”),当面向服务器的接口之间的 tx_bytes 标准偏差大于 100 时。
您可以通过标准异常 API 查询探测异常,网址为 /api/blueprints/<bluprint_id>/anomalies?type=probe
。
下面是示例探测将引发的异常的 JSON 形式(对于此示例,我们不关心的数据使用省略号):
{ "actual": { "value_int": 101 }, "anomaly_type": "probe", "expected": { "value_int": 100 }, "id": "...", "identity": { "anomaly_type": "probe", "probe_id": "efb2bf7f-d8cc-4a55-8e9b-9381e4dba61f", "properties": {}, "stage_id": "server_traffic_imbalanced" }, "last_modified_at": "...", "severity": "critical" }
如上面的示例所示,标识包含引发异常且需要操作员进一步检查的阶段的probe_id和名称。在给定阶段中,如果阶段的类型是基于集的类型,则异常的“属性”字段将使用集中导致异常的特定项目的属性填充。这就提出了一个重要的观点,即只要每个异常都在集合中的不同项目上,就可以在单个阶段引发多个异常。在我们的示例中,由于所讨论的阶段是 NS 类型,因此未设置“属性”字段。
自省处理器
操作员可用的处理器集是平台和参考设计的功能。Apstra 为操作员提供了一个 API,用于列出所有可用的处理器,了解它们采用的参数,并了解它们需要哪些输入和产生哪些输出。
有问题的 API 可在 中找到 /api/blueprints/<blueprint_id>/telemetry/processors
。
它生成处理器说明的列表。在以下示例中,我们显示了std_dev处理器的说明。
{ "description": "Standard Deviation Processor.\n\n Groups as described by group_by, then calculates std deviation and\n outputs one standard deviation for each group. Output is NS.\n Input is an NS or NSTS.\n ", "inputs": { "in": { "required": true, "types": [ { "keys": [], "possible_values": null, "type": "ns" }, { "keys": [], "possible_values": null, "type": "nsts" } ] } }, "outputs": { "out": { "required": true, "types": [ { "keys": [], "possible_values": null, "type": "ns" } ] } }, "label": "Standard Deviation", "name": "std_dev", "schema": { "additionalProperties": false, "properties": { "ddof": { "default": 0, "description": "Standard deviation correction value, is used to correct divisor (N - ddof) in calculations, e.g. ddof=0 - uncorrected sample standard deviation, ddof=1 - corrected sample standard deviation.", "title": "ddof", "type": "integer" }, "enable_streaming": { "default": false, "type": "boolean" }, "group_by": { "default": [ "system_id" ], "items": { "type": "string" }, "type": "array" } }, "type": "object" } }
如上所示,有一个基于字符串的说明,即类型处理器类型的名称(在探测配置中提供给 REST API)。特定于给定探测器的参数集在“架构”中描述。
必须特别注意“投入”和“产出”。即使这些在“架构”部分中,它们也存在于每种类型的处理器上。每个处理器可以采用零个或多个输入级,并且必须输出一个或多个级。可选阶段的“必需”设置为 false。这些变量中描述了它们采用的阶段的名称(相对于处理器的特定实例)。我们可以看到,“std_dev”处理器接受一个名为“in”的单个输入和一个名为“out”的单个输出。这反映在我们在前面示例中对它的用法中。
有一个特殊的输入名称: *
。例如:
"inputs": { "*": { "required": true, "types": [ { "keys": [], "possible_values": null, "type": "ns" }, { "keys": [], "possible_values": [], "type": "dss" }, { "keys": [], "possible_values": null, "type": "ts" } ] } }
这意味着处理器接受具有任意名称的指定类型的一个或多个输入。
在 3.0 中更改: 以前,输入和输出部分未指定是否需要特定的输入或输出,因此格式已从以下内容更改:
此语法已弃用且无效。
"inputs": { "in": [ { "data_type": "ns", "keys": [ "system_id" ], "value_map": null, "value_type": "int64" } ... ] }
流数据
任何探测器中的任何处理器实例都可以配置为在 Apstra 流输出的“perfmon”通道中流式传输其输出级。如果任何处理器的配置中属性“enable_streaming”设置为“true”,则其输出级的所有数据流。
对于非基于时间序列的阶段,只要其值发生变化,每个阶段都会生成一条消息。对于基于时间序列的阶段,每当向时间序列创建新条目时,每个阶段都会生成一条消息。对于基于集的阶段,集中的每个项目都将根据前面的两个规则生成一条消息。
生成的每条消息都有一个值、一个时间戳和一组键值对。该值是不言自明的。时间戳是非基于时间序列的阶段的值更改的时间,是基于时间序列的阶段的新条目的时间戳。键值对对应于我们之前在阶段的“值”部分中观察到的“属性”字段,从而提供了上下文。
下面我们有来自 IBA 的消息格式,它封装在 PerfMon 消息中(反过来又封装在 AosMessage 中)。上下文的键值对被放入“属性”重复字段(“name”作为键,“value”作为值),而值被放入“value”字段中。“probe_id”和“stage_name”是它们出现的样子。blueprint_id被放入封装的AosMessage的“origin_name”。同样,时间戳被放入通用的“时间戳”字段中。
message ProbeProperty { required string name = 5; required string value = 6; } message ProbeMessage { repeated ProbeProperty property = 1; oneof value { int64 int64_value = 2; float float_value = 3; string string_value = 4; } required string probe_id = 5; required string stage_name = 6; }