系列

本指南将引导您完成编写和测试 Snuba 查询的过程。

探索 Snuba 数据模型

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

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

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

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

snuba entities list

会返回如下内容:

Declared Entities:
discover
errors
events
groups
groupassignee
groupedmessage
.....

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

snuba entities describe groupedmessage

会返回:

Entity groupedmessage
Entity schema
--------------------------------
offset UInt64
record_deleted UInt8
project_id UInt64
id UInt64
status Nullable(UInt8)
last_seen Nullable(DateTime)
first_seen Nullable(DateTime)
active_at Nullable(DateTime)
first_release_id Nullable(UInt64) Relationships
--------------------------------
groups
--------------------------------
Destination: events
Type: LEFT
Join keys
--------------------------------
project_id = LEFT.project_id
id = LEFT.group_id

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

准备对 Snuba 的查询

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

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

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

query = Query(
dataset="discover",
match=Entity("events"),
select=[
Column("title"),
Function("uniq", [Column("event_id")], "uniq_events"),
],
groupby=[Column("title")],
where=[
Condition(Column("timestamp"), Op.GT, datetime.datetime(2021, 1, 1)),
Condition(Column("project_id"), Op.IN, Function("tuple", [1, 2, 3])),
],
limit=Limit(10),
offset=Offset(0),
granularity=Granularity(3600),
)

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

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

使用 Sentry 向 Snuba 发送查询

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

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

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

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

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

{
"data": [
{
"title": "very bad",
"uniq_events": 2
}
],
"meta": [
{
"name": "title",
"type": "String"
},
{
"name": "uniq_events",
"type": "UInt64"
}
],
"timing": {
... details ...
}
}

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 属性实现的。
  • turbo 为 TURBO_SAMPLE_RATE Snuba 设置中定义的查询设置采样率。它还可以防止 Snuba 将 FINAL 模式应用于 Clickhouse 查询,以防在替换后需要保证正确的结果。

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

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

{
"data": [],
"meta": [
{
"name": "title",
"type": "String"
}
],
"timing": {
"timestamp": 1621038379,
"duration_ms": 95,
"marks_ms": {
"cache_get": 1,
"cache_set": 4,
"execute": 39,
"get_configs": 0,
"prepare_query": 10,
"rate_limit": 4,
"validate_schema": 34
}
},
"stats": {
"clickhouse_table": "errors_local",
"final": false,
"referrer": "http://localhost:1218/events/snql",
"sample": null,
"project_rate": 0,
"project_concurrent": 1,
"global_rate": 0,
"global_concurrent": 1,
"consistent": false,
"result_rows": 0,
"result_cols": 1,
"query_id": "f09f3f9e1c632f395792c6a4bfe7c4fe"
},
"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)。细节
  • sample 是应用的采样率。
  • project_rate 是查询时 Snuba 每秒收到的特定项目的请求数。
  • project_concurrent 是查询时涉及特定项目的并发查询数。
  • global_rate 与 project_rate 相同,但不专注于一个项目。
  • global_concurrent 与 project_concurrent 相同,但不专注于一个项目。
  • query_id 是此查询的唯一标识符。

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

{
"error": {
"type": "invalid_query",
"message": "missing >= condition on column timestamp for entity events"
}
}

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

Sentry 监控 - Snuba 数据中台架构(编写和测试 Snuba 查询)的更多相关文章

  1. Sentry 监控 - Snuba 数据中台架构(SnQL 查询语言简介)

    本文描述了 Snuba 查询语言 (SnQL). 系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒 ...

  2. Sentry 监控 - Snuba 数据中台架构(Query Processing 简介)

    系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒上手 Source Maps Sentry For ...

  3. Sentry 监控 - Snuba 数据中台架构(Data Model 简介)

    系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒上手 Source Maps Sentry For ...

  4. Sentry 监控 - Snuba 数据中台架构简介(Kafka+Clickhouse)

    系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒上手 Source Maps Sentry For ...

  5. Sentry 监控 - Snuba 数据中台本地开发环境配置实战

    系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒上手 Source Maps Sentry For ...

  6. Sentry 监控 - 私有 Docker Compose 部署与故障排除详解

    内容整理自官方开发文档 系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒上手 Source Map ...

  7. Sentry 监控 - Environments 区分不同部署环境的事件数据

    系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒上手 Source Maps Sentry For ...

  8. Sentry 监控 - 全栈开发人员的分布式跟踪 101 系列教程(第一部分)

    系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒上手 Source Maps Sentry For ...

  9. 【转】阿里架构总监一次讲透中台架构,13页PPT精华详解

    转:https://blog.csdn.net/u011323949/article/details/99542576 本文整理了阿里几位技术专家,如架构总监 谢纯良,中间件技术专家 玄难等几位大牛, ...

随机推荐

  1. Java中的基本类型和包装类

    Java中基本数据类型与包装类型有   基本类型     包装器类型   boolean Boolean char Character int Integer byte Byte short Shor ...

  2. 关于C、Java、Python程序运行耗时及内存用量

    最近没有刷题,而是在PTA找几个题目寻找有关程序输入流问题以及各种语言在运行时对计算机消耗内存的问题, 以免很多同学解题的时候发现自己做的对但是出现运行超时的问题:针对运行内存,肯定用C/C++的同学 ...

  3. 初入CTF(封神榜第一关)

    注:网址中的%20是空格的意思 1判断是否存在注入点 构造?id=1 and 1=1(不报错) 构造?id=1 and 1=2(报错或者不显示内容) 报错说明and后面的语句被识别 2判断回显字段的长 ...

  4. C++控制台应用程序一闪而过的解决方法

    Visual Studio 2017 C++控制台应用程序, 如果编译时发现黑框一闪而过,请按以下步骤操作: 右键project → 属性 → 链接器 → 系统 → 子系统,在下拉菜单中改为控制台.

  5. 函数返回值为 const 指针、const 引用

    函数返回值为 const 指针,可以使得外部在得到这个指针后,不能修改其指向的内容.返回值为 const 引用同理. class CString { private: char* str; publi ...

  6. 4.19——数组双指针——26. 删除有序数组中的重复项 & 27. 删除有序数组中的重复项II & 80. 删除有序数组中的重复项 II

    第一次做到数组双指针的题目是80: 因为python的List是可以用以下代码来删除元素的: del List[index] 所以当时的我直接用了暴力删除第三个重复元素的做法,大概代码如下: n = ...

  7. 小白自制Linux开发板 八. Linux音频驱动配置

    不知不觉小白自制开发板系列已经到第八篇了,本篇要配置的是音频驱动,也算是硬件部分的最后一片了,积攒的文章也差不多全放完了,后续更新可能会放缓,还请见谅. 对于F1C200s是自带了多媒体处理功能的,所 ...

  8. 2020年OO助教工作总结

    随着这学期课程的落幕,我一学期的OO助教工作也宣告结束.这学期我的工作主要在系统组,和OO后台的数据库打交道. 作业查重 我几乎每周都会做的例行工作,是对每周的homework进行查重管理.由于使用了 ...

  9. 在Vue前端项目中,附件展示的自定义组件开发

    在Vue前端界面中,自定义组件很重要,也很方便,我们一般是把一些通用的界面模块进行拆分,创建自己的自定义组件,这样操作可以大大降低页面的代码量,以及提高功能模块的开发效率,本篇随笔继续介绍在Vue&a ...

  10. 21.7.1 test

    \(NOI\) 模拟赛 呜呜呜 \(\cdots\cdots\) \(T1\) 类似哈夫曼编码,虽然没学过但是我依然画出了二叉树,然后尝试树形dp,并且最后还抓住了一个优化!让我兴奋地以为自己能赛时A ...