Sentry 监控 - Snuba 数据中台架构(编写和测试 Snuba 查询)

安全 应用安全 中台
为了构建 Snuba 查询,第一步是能够知道您应该查询哪个数据集,您应该选择哪些实体以及每个实体的 schema 是什么。

[[436990]]

本文转载自微信公众号「黑客下午茶」,作者为少 。转载本文请联系黑客下午茶公众号。

探索 Snuba 数据模型

为了构建 Snuba 查询,第一步是能够知道您应该查询哪个数据集,您应该选择哪些实体以及每个实体的 schema 是什么。

有关数据集和实体的介绍,请参阅 Snuba 数据模型部分。

  • https://getsentry.github.io/snuba/architecture/datamodel.html

数据集可以在这个模块中找到。每个数据集都是一个引用实体的类。

  • https://github.com/getsentry/snuba/blob/master/snuba/datasets/factory.py

系统中的实体列表可以通过 snuba entity 命令找到:

  1. snuba entities list 

会返回如下内容:

  1. Declared Entities: 
  2. discover 
  3. errors 
  4. events 
  5. groups 
  6. groupassignee 
  7. groupedmessage 
  8. ..... 

一旦我们找到了我们感兴趣的实体,我们就需要了解在该实体上声明的 schema 和 relationship。相同的命令描述了一个实体:

  1. snuba entities describe groupedmessage 

会返回:

  1. Entity groupedmessage 
  2.     Entity schema 
  3.     -------------------------------- 
  4.     offset UInt64 
  5.     record_deleted UInt8 
  6.     project_id UInt64 
  7.     id UInt64 
  8.     status Nullable(UInt8) 
  9.     last_seen Nullable(DateTime) 
  10.     first_seen Nullable(DateTime) 
  11.     active_at Nullable(DateTime) 
  12.     first_release_id Nullable(UInt64) 
  13.  
  14.     Relationships 
  15.     -------------------------------- 
  16.         groups 
  17.         -------------------------------- 
  18.         Destination: events 
  19.         Type: LEFT 
  20.             Join keys 
  21.             -------------------------------- 
  22.             project_id = LEFT.project_id 
  23.             id = LEFT.group_id 

它提供列的列表及其类型以及与数据模型中定义的其他实体的关系。

准备对 Snuba 的查询

Snuba 查询语言称为 SnQL。它记录在 SnQL 查询语言部分。所以本节不赘述。

  • https://getsentry.github.io/snuba/language/snql.html

有一个 python sdk 可用于构建 Snuba 查询,它可以用于任何 Python 客户端,包括 Sentry。snuba-sdk。

  • https://github.com/getsentry/snuba-sdk

查询表示为一个 Query 对象,如:

  1. query = Query( 
  2.     dataset="discover"
  3.     match=Entity("events"), 
  4.     select=[ 
  5.         Column("title"), 
  6.         Function("uniq", [Column("event_id")], "uniq_events"), 
  7.     ], 
  8.     groupby=[Column("title")], 
  9.     where=[ 
  10.         Condition(Column("timestamp"), Op.GT, datetime.datetime(2021, 1, 1)), 
  11.         Condition(Column("project_id"), Op.INFunction("tuple", [1, 2, 3])), 
  12.     ], 
  13.     limit=Limit(10), 
  14.     offset=Offset(0), 
  15.     granularity=Granularity(3600), 

有关如何构建查询的更多详细信息,请参见 sdk 文档。

  • https://getsentry.github.io/snuba-sdk/

一旦查询对象准备就绪,它就可以发送到 Snuba。

使用 Sentry 向 Snuba 发送查询

查询 Snuba 时最常见的用例是通过 Sentry。本节说明如何在 Sentry 代码库中构建查询并将其发送到 Snuba。

Sentry 导入了上述的 Snuba sdk。这是构建 Snuba 查询的推荐方法。

一旦创建了 Query 对象,Sentry 提供的 Snuba client api 就可以并且应该用于将查询发送到 Snuba。

api 在这个模块中。它负责缓存、重试并允许批量查询。

  • https://github.com/getsentry/sentry/blob/master/src/sentry/utils/snuba.py#L667

该方法返回一个字典,其中包含响应中的数据和其他元数据:

  1.     "data": [ 
  2.         { 
  3.             "title""very bad"
  4.             "uniq_events": 2 
  5.         } 
  6.     ], 
  7.     "meta": [ 
  8.         { 
  9.             "name""title"
  10.             "type""String" 
  11.         }, 
  12.         { 
  13.             "name""uniq_events"
  14.             "type""UInt64" 
  15.         } 
  16.     ], 
  17.     "timing": { 
  18.         ... details ... 
  19.     } 

data 部分是一个列表,每行一个字典。meta 包含响应中包含的列的列表,其数据类型由 Clickhouse 推断。

通过 Web UI 发送测试查询

Snuba 具有可用于发送查询的最小 Web UI。您可以在本地运行 Snuba, 并且可以通过 http://localhost:1218/[DATASET NAME]/snql 访问 Web UI。

应该在 query 属性中提供 SnQL 查询,并且响应的结构与上一节中讨论的相同。

通过 curl 发送查询

Web UI 仅将 payload 作为 POST 发送。因此,使用 curl 或任何其他 HTTP 客户端可以实现相同的结果。

请求和响应格式

请求格式在上面截图中可见:

  • query 包含字符串形式的 SnQL 查询。
  • dataset 是数据集名称(如果尚未在 url 中指定。
  • debug 使 Snuba 在响应中提供详尽的统计信息,包括 Clickhouse 查询。
  • consistent 强制 Clickhouse 查询以单线程模式执行,并且如果 Clickhouse 表被复制,它将强制 Snuba 始终命中同一个节点。可以保证顺序一致性,因为这是消费者默认写入的节点。这是通过设置为 in_order 的负载平衡 Clickhouse 属性实现的。
    • https://clickhouse.tech/docs/en/operations/settings/settings/#load_balancing-in_order
  • turbo 为 TURBO_SAMPLE_RATE Snuba 设置中定义的查询设置采样率。它还可以防止 Snuba 将 FINAL 模式应用于 Clickhouse 查询,以防在替换后需要保证正确的结果。

Snuba 可以使用 4 个 http code 进行响应。200 表示成功的查询,如果查询无法正确验证,则为 400。500 通常意味着与 Clickhouse 相关的问题(从超时到连接问题),尽管 Snuba 仍然无法提前识别一些无效查询。Snuba 有一个内部速率限制器,所以 429 也是一个可能的返回码。

成功查询的响应格式与上面讨论的相同。完整版本如下所示(在 debug 模式下)

  1.     "data": [], 
  2.     "meta": [ 
  3.         { 
  4.             "name""title"
  5.             "type""String" 
  6.         } 
  7.     ], 
  8.     "timing": { 
  9.         "timestamp": 1621038379, 
  10.         "duration_ms": 95, 
  11.         "marks_ms": { 
  12.             "cache_get": 1, 
  13.             "cache_set": 4, 
  14.             "execute": 39, 
  15.             "get_configs": 0, 
  16.             "prepare_query": 10, 
  17.             "rate_limit": 4, 
  18.             "validate_schema": 34 
  19.         } 
  20.     }, 
  21.     "stats": { 
  22.         "clickhouse_table""errors_local"
  23.         "final"false
  24.         "referrer""http://localhost:1218/events/snql"
  25.         "sample"null
  26.         "project_rate": 0, 
  27.         "project_concurrent": 1, 
  28.         "global_rate": 0, 
  29.         "global_concurrent": 1, 
  30.         "consistent"false
  31.         "result_rows": 0, 
  32.         "result_cols": 1, 
  33.         "query_id""f09f3f9e1c632f395792c6a4bfe7c4fe" 
  34.     }, 
  35.     "sql""SELECT (title AS _snuba_title) FROM errors_local PREWHERE equals((project_id AS _snuba_project_id), 1) WHERE equals(deleted, 0) AND greaterOrEquals((timestamp AS _snuba_timestamp), toDateTime('2021-05-01T00:00:00', 'Universal')) AND less(_snuba_timestamp, toDateTime('2021-05-11T00:00:00', 'Universal')) LIMIT 1000 OFFSET 0" 

timing 部分包含查询的时间戳和持续时间。有趣的是,持续时间被分解为几个阶段:marks_ms。

sql 元素是 Clickhouse 查询。

stats 字典包含以下 key

  • clickhouse_table 是 snuba 在查询处理过程中选取的表。
  • final 表示 Snuba 是否决定向 Clickhouse 发送 FINAL 查询,这会迫使 Clickhouse 立即应用相关的合并(Merge Tree)。细节
  • https://clickhouse.tech/docs/en/sql-reference/statements/select/from/#select-from-final
  • sample 是应用的采样率。
  • project_rate 是查询时 Snuba 每秒收到的特定项目的请求数。
  • project_concurrent 是查询时涉及特定项目的并发查询数。
  • global_rate 与 project_rate 相同,但不专注于一个项目。
  • global_concurrent 与 project_concurrent 相同,但不专注于一个项目。
  • query_id 是此查询的唯一标识符。

查询验证问题通常采用以下格式:

  1.     "error": { 
  2.         "type""invalid_query"
  3.         "message""missing >= condition on column timestamp for entity events" 
  4.     } 

 

Clickhouse 错误将具有类似的结构。type 字段将显示 clickhouse,该消息将包含有关异常的详细信息。与查询验证错误相反,在 Clickhouse 错误的情况下,实际执行了查询,因此存在为成功查询描述的所有时间和统计信息。

 

责任编辑:武晓燕 来源: 黑客下午茶
相关推荐

2021-11-27 23:54:44

监控Snuba数据

2021-10-11 19:36:08

监控Sentry架构

2021-10-09 23:33:55

监控

2021-10-09 00:00:40

Sentr 监控架构

2021-12-01 23:59:45

监控Snuba数据中台

2023-02-13 11:43:15

云原生中间件负载均衡

2021-09-16 23:33:41

大数据Sentry监控

2023-04-21 13:15:01

2022-03-15 21:38:29

sentry微服务监控

2021-09-14 23:50:17

Sentry后端监控

2021-09-27 19:41:31

监控Sentry Alerts

2021-09-26 16:20:04

Sentry Dashboards 数据可视化

2019-12-12 10:22:16

大数据平台大数据安全大数据

2021-04-22 08:45:38

架构交易中台

2021-09-13 05:00:09

监控Trends 性能

2021-09-11 21:02:24

监控Sentry Web性能

2021-09-09 12:28:50

Sentry Web性能监控

2021-09-29 07:47:49

Sentry 监控Environment事件数据

2010-07-23 15:30:18

2022-04-13 20:25:16

中台业务架构
点赞
收藏

51CTO技术栈公众号