Metric SQL 用户手册

本手册面向用户,系统地介绍了 Metrics SQL 语言的语法与使用方式。 为了方便起见,在本文档中我们使用 msql 来表示 Ops 语言。 有问题的示例代码会在每行开头标记问号 ?。

本手册面向用户,系统地介绍了 Metrics SQL 语言的语法与使用方式。

目录

约定

为了方便起见,在本文档中我们使用 msql 来表示 Ops 语言。

有问题的示例代码会在每行开头标记问号 ?。例如:

? select *;

描述

Metrics SQL 语言受 SQL 语言启发,但从未打算与 SQL 标准或某些 SQL 方言 100% 兼容。尽管如此,Metrics SQL 代码可能看起来与 SQL 代码非常相似。

Metrics SQL 语言作为 OpenResty Edge 平台的一部分提供。它是为 OpenResty Edge 快速创建新动态指标的一种方式。

返回目录

程序布局

Metrics SQL 程序由多个用分号分隔的语句组成。目前只允许单个 select 查询语句,但这在将来可能会改变。下面是一个例子:

select uri, host, count(*)
from reqs group by uri, host limit 10;

最后一个语句的尾随分号可以省略。

返回目录

词法结构

整数

整数可以表示为十进制或十六进制字面量,如:

-3
519
0xdeadbeef

返回目录

浮点数

浮点数可以表示如下:

3.1415926
2e8
4.2E2

返回目录

字符串字面量

字符串字面量用单引号括起来,就像标准 SQL 语言一样,如:

'hello, world!'

此外,我们支持以下特殊转义序列来指定特殊字符:

\a          响铃,ascii 码 0x07
\b          退格,ascii 码 0x08
\f          换页,ascii 码 0x0c
\n          换行
\r          回车
\t          制表符
\v          垂直制表符
\\          反斜杠 (\)
\'          单引号字符 (')
\"          双引号字符 (")
\<newline>  换行字符,就像 \n

下面是使用转义序列的例子:

'hello\nworld\t!'

返回目录

正则表达式字面量

正则表达式字面量是表示用于模式匹配的正则表达式的一种方式(与 like 二元运算符一起使用)。正则表达式字面量,比如 /[0-9]+/,可以用不同的分隔符括起来,如:

/[0-9]+/

rx/[0-9]+/

rx{[0-9]+}

rx([0-9]+)

rx[[0-9]+]

rx'[0-9]+'

rx"[0-9]+"

rx![0-9]+!

您可以选择最佳分隔符来最小化正则表达式模式本身内部必要的转义。

目前只允许 Perl 兼容正则表达式和 POSIX 正则表达式语法的通用子集,但不包括反向引用语法(如 \1、\2 等)。我们可能在将来取消这个限制。

支持使用括号的子匹配捕获。

返回目录

布尔字面量

Metrics SQL 中的布尔字面量就是 true 和 false,就像在 SQL 中一样。

返回目录

空值

特殊的 null 关键字表示空值(类似于 SQL 中的 null 值)。

Metrics SQL 通常不涉及空值,因此这个字面量很少使用。包含它只是为了完整性。

返回目录

表

表名必须始终以其完全限定形式指定,除非用户给出别名(如在 from 子句中使用 as ALIAS 语法)。

Metrics SQL 目前支持一个内置表 reqs。详见"内置表"部分。

返回目录

列

当没有歧义时,列名可以用其裸名称表示,如 uri 和 host,或者用带表名的完全限定形式,如:

select uri, count(*)
from reqs group by uri

其中 uri 列使用完全限定形式 reqs.uri 指定。

列也可以通过用户别名间接引用(如在 select 列表中使用 as ALIAS 语法)。

返回目录

运算符和表达式

Metrics SQL 支持许多类似 SQL 的运算符和表达式类型,并有一些自己的补充。

所有运算符的优先级表如下:

3    一元 !
4    - (一元减号), + (一元加号)
5    || (字符串连接)
7    *, /, %
8    二元 -, +
12    = (比较), >=, >, <=, <, <>, !=, is, like, in, prefix, suffix, contains
13    between
14    not
15    and
17    or
19    left join, inner join
20    , (交叉连接)

通常可以使用括号 (...) 来组合优先级较低的运算符。

not ... 变体如 not between 和 is not 未在运算符优先级表中列出。

返回目录

算术表达式

Metrics SQL 支持以下二元算术运算符:加法(+)、减法(-)、乘法(*)、除法(/)和取模(%)。

它还支持一元算术运算符 - 和 +。

返回目录

字符串连接

支持 SQL 风格的字符串连接运算符 ||。

返回目录

关系表达式

Metrics SQL 支持大多数常见的 SQL 风格关系运算符:

  • =(等于)
  • != 或 <>(不等于)
  • <=
  • <
  • >
  • >=
  • between ... and(开发中)
  • in (value...)(开发中)
  • like 和 not like
  • is 或 is not(开发中)

like 运算符支持两种形式的模式:

  1. (开发中) 带有元字符的 SQL 风格模式,如 %(匹配零个或多个任意字符)和 _(匹配一个任意字符)。元字符可以用反斜杠(/)转义以表示 % 和 _ 字符本身。
  2. 正则表达式字面量,如 /.../ 和 rx{...}。

此外,Metrics SQL 支持以下字符串匹配运算符,分别测试右侧字符串是否是左侧字符串的前缀、子字符串或后缀:

  • prefix
  • contains
  • suffix

返回目录

逻辑表达式

支持以下 SQL 风格逻辑运算符:

  • 二元 and
  • 二元 or
  • 一元 not

返回目录

子查询

Metrics SQL 目前不支持子查询,尽管 Metrics SQL 编译器可以很好地解析它们。

返回目录

Select 查询语句

此语句包含一个带有以下一个或多个子句的单个 select 查询。注意 select 子句始终是必需的。

返回目录

Select 子句

支持 SQL 风格的 select 子句。下面是一些例子:

select host, count(*) from reqs group by host;

聚合函数和转换函数可以出现在 select 列表中。关系表达式、算术表达式和字符串连接表达式也可以。目前不允许逻辑表达式。我们可能在将来取消这个限制。

每个选定的值可以在值表达式后面带一个可选的别名,就像在标准 SQL 中一样,如:

select avg(active_conns) as active from http;

聚合函数如 sum()、avg()、min()、max() 和 count() 也可以在选定的值表达式中使用,如:

select count(*), sum(latency_s)
from reqs;

转换函数如 hist_log() 也可以在选定的值表达式中使用,如:

select count(*), hist_log(latency_ms) as latency
from reqs group by latency;

返回目录

From 子句

from 子句也类似于标准 SQL 语言。可以指定单个表,如:

select uri, count(*)
from reqs group by uri;

返回目录

Where 子句

where 子句与标准 SQL 语言相同。可以在这里指定逻辑表达式作为搜索条件。下面是一个例子:

select count(*)
from reqs
where uri prefix '/css/';

返回目录

Group By 子句

group by 子句类似于标准 SQL 语言,如:

select count(*) as cnt, host
from reqs
group by host
order by cnt desc
limit 10;

返回目录

Order By 子句

order by 子句类似于标准 SQL 语言。Metrics SQL 目前有一些限制:

  1. order by 子句中只允许一列。
  2. order by 列只能是列名或 count() 聚合函数。

下面是一个例子:

select count(*), host
from reqs
group by host
order by count(*) desc;

也可以在 order by 子句中引用选定值表达式的别名(如果有的话),如:

select count(*) cnt, host
from reqs
group by host
order by cnt desc;

返回目录

Limit 子句

limit 子句类似于标准 SQL 语言。下面是一个例子:

select *
from reqs
limit 10;

返回目录

Offset 子句(开发中)

offset 子句语法类似于 PostgreSQL 提供的 PL/SQL 语言。下面是一个例子:

select *
from reqs
offset 1
limit 10;

这将跳过第一行,只输出第 2 到第 10 行。

返回目录

内置表

下面是 Metrics SQL 编译器当前支持的内置表的详细列表。我们正在快速添加新表和新列。

返回目录

reqs

此表用于检查 nginx(主)请求。这里排除了 Nginx 子请求。

它有以下列:

  • args

    HTTP 请求的 URI 查询字符串。

  • host

    HTTP 请求的主机名。

  • latency_ms

    表示请求延迟(毫秒)的整数,如 120。

  • latency_s

    表示请求延迟(秒)的浮点数,如 0.32。

  • keepalive

    布尔值,表示当前请求是否为当前 TCP 连接启用 HTTP keep-alive。

  • method

    HTTP 请求的方法字符串。

  • scheme

    当前 HTTP 请求的协议字符串,如 http 和 https。

  • uri

    HTTP 请求 URI(不包括任何查询字符串)。

  • raw_uri

    HTTP 原始请求 URI(包括查询字符串)。

  • client_ip

    字符串。IP 地址(IPv4 或 IPv6 或 unix socket 文件路径)。

  • req_size

    整数。整个请求大小(包括头部和正文)的字节数。

  • req_body_size

    整数。请求正文大小的字节数。

  • resp_size

    整数。整个响应大小(包括头部和正文)的字节数(如果涉及压缩,则为压缩后的大小)。

  • resp_body_size

    整数。响应正文大小的字节数。

  • total_size

    整数。下游请求的总大小,包括 req_size 和 resp_size。

  • server_city

    字符串。基于服务器 IP 地址查询地理信息数据获得的城市名称

  • server_province

    字符串。基于服务器 IP 地址查询地理信息数据获得的省份名称

  • server_country

    字符串。基于服务器 IP 地址查询地理信息数据获得的国家名称

  • server_continent

    字符串。基于服务器 IP 地址查询地理信息数据获得的大洲名称

  • server_isp

    字符串。基于服务器 IP 地址查询地理信息数据获得的 ISP 名称

  • server_latitude

    字符串。基于服务器 IP 地址查询地理信息数据获得的纬度

  • server_longtitude

    字符串。基于服务器 IP 地址查询地理信息数据获得的经度

  • server_port

    整数。当前请求访问的服务器端口。

  • status

    整数。HTTP 响应状态码(如 502 和 200)或内部 nginx 错误码(如果没有有意义的 HTTP 状态码可用)。

  • status_class

    字符串。分类后的 HTTP 响应状态码,如 2xx/3xx/4xx/5xx。

  • is_ssl

    布尔值。当前请求是否使用 SSL 或 TLS。

  • tls_ver

    数字。TLS 协议版本号,如 1.2 和 1.3。

  • ssl_ver

    数字。SSL 协议版本号,如 2 和 3。

  • resp_is_chunked

    布尔值。响应正文是否使用分块编码。

  • req_is_chunked

    布尔值。请求正文是否使用分块编码。

  • http_ver

    数字。HTTP 协议版本(0.9、1.0、1.1、2.0)。

  • is_websocket

    布尔值。当前请求是否已升级到 WebSocket 协议。

  • resp_is_compressed

    布尔值。当前请求的响应正文是否被压缩(通过 gzip 或其他编码)。

  • mime_type

    字符串。应该是像 application/javascript 这样的值。应排除任何尾随参数,如 ; charset=utf-8。

  • uses_lua

    布尔值。当前请求是否在任何请求处理阶段使用任何 Lua 代码处理程序(如 log_by_lua、rewrite_by_lua 等)。

  • for_static_file

    布尔值。当前请求是否使用静态文件模块来提供当前机器文件系统上的静态文件。

  • has_upstream

    布尔值。当前请求是否使用代理(即使用 nginx upstream 模块)。

  • uses_error_page

    布尔值。当前请求是否提供错误页面。

  • uri_changes

    整数。在请求处理阶段完成的 URI 更改次数(对应 r->uri_changes)。

  • uri_changed

    布尔值。当前请求的 URI 是否曾被请求处理阶段更改(对应 r->uri_changed)。

  • is_pipelined

    布尔值。当前请求是否是管道请求(即 C 层面的 r->pipeline)。

  • resp_header_only

    布尔值。当前响应是否只有头部(r->header_only)。

  • location

    字符串。最后服务当前请求的 nginx location 名称。

  • user_agent

    字符串。User-Agent 字符串。

  • conn_is_reused

    布尔值。当前请求是否重用了由较早请求创建的连接。

  • upstream_addr

    字符串。用于连接到上游服务器的最后一个上游地址。

  • upstream_cache_status

    字符串。上游缓存状态。 如果没有上游则为空字符串,否则为以下之一:MISS BYPASS EXPIRED STALE UPDATING REVALIDATED HIT

  • is_upstream_cache_status_hit

    字符串。当前请求的缓存状态为 HIT,表示请求的内容在缓存中找到且有效,响应直接从缓存提供。此变量于 25.6.20-1 版本首次引入。

  • is_upstream_cache_status_miss

    字符串。当前请求的缓存状态为 MISS,表示请求的内容在缓存中未找到,需要从上游服务器获取。此变量于 25.6.20-1 版本首次引入。

  • is_upstream_cache_status_bypass

    字符串。当前请求的缓存状态为 BYPASS,表示缓存被绕过,请求直接转发到上游服务器而不使用缓存。此变量于 25.6.20-1 版本首次引入。

  • is_upstream_cache_status_expired

    字符串。当前请求的缓存状态为 EXPIRED,表示缓存内容已过期,需要从上游服务器重新获取。此变量于 25.6.20-1 版本首次引入。

  • is_upstream_cache_status_stale

    字符串。当前请求的缓存状态为 STALE,表示缓存内容已过期但仍可用,通常在上游服务器不可用时返回。此变量于 25.6.20-1 版本首次引入。

  • is_upstream_cache_status_updating

    字符串。当前请求的缓存状态为 UPDATING,表示缓存正在更新,当前请求使用旧的缓存内容提供服务。此变量于 25.6.20-1 版本首次引入。

  • is_upstream_cache_status_revalidated

    字符串。当前请求的缓存状态为 REVALIDATED,表示缓存内容已与上游服务器重新验证并确认仍然有效。此变量于 25.6.20-1 版本首次引入。

  • upstream_byte_sent

    整数。发送到上游服务器的字节数。多个上游服务器的值将相加。

  • upstream_byte_received

    整数。从上游服务器接收的字节数。多个上游服务器的值将相加。

  • upstream_byte_total

    整数。发送到上游服务器和从上游服务器接收的字节数。多个上游服务器的值将相加。

  • upstream_body_length

    整数。从上游服务器获得的响应长度。多个上游服务器的值将相加。

  • upstream_header_timer_ms

    整数。从上游服务器接收响应头部所花费的时间;时间以毫秒分辨率保存。多个响应的时间相加。

  • upstream_connect_timer_ms

    整数。与上游服务器建立连接所花费的时间;时间以毫秒分辨率保存。在 SSL 情况下,包括握手所花费的时间。多个连接的时间相加。

  • upstream_resp_timer_ms

    整数。从上游服务器接收响应所花费的时间;时间以毫秒分辨率保存。多个响应的时间相加。

  • client_city

    字符串。基于客户端 IP 地址查询地理信息数据获得的城市名称

  • client_province

    字符串。基于客户端 IP 地址查询地理信息数据获得的省份名称

  • client_country

    字符串。基于客户端 IP 地址查询地理信息数据获得的国家名称

  • client_continent

    字符串。基于客户端 IP 地址查询地理信息数据获得的大洲名称

  • client_isp

    字符串。基于客户端 IP 地址查询地理信息数据获得的 ISP 名称

  • client_latitude

    字符串。基于客户端 IP 地址查询地理信息数据获得的纬度

  • client_longtitude

    字符串。基于客户端 IP 地址查询地理信息数据获得的经度

  • is_status_2xx

    布尔值。当前请求的响应状态是否在 200 到 299 之间。

  • is_status_3xx

    布尔值。当前请求的响应状态是否在 300 到 399 之间。

  • is_status_4xx

    布尔值。当前请求的响应状态是否在 400 到 499 之间。

  • is_status_5xx

    布尔值。当前请求的响应状态是否在 500 到 599 之间。

  • is_status_other

    布尔值。当前请求的响应状态是否小于 200 或大于 599。

  • is_upstream_status_2xx

    布尔值。当前请求的响应状态是否在 200 到 299 之间。

  • is_upstream_status_3xx

    布尔值。上游的响应状态是否在 300 到 399 之间。

  • is_upstream_status_4xx

    布尔值。上游的响应状态是否在 400 到 499 之间。

  • is_upstream_status_5xx

    布尔值。上游的响应状态是否在 500 到 599 之间。

  • is_upstream_status_other

    布尔值。上游的响应状态是否小于 200 或大于 599。

  • is_status_400

    布尔值。响应状态是否为 400。

  • is_status_403

    布尔值。响应状态是否为 403。

  • is_status_404

    布尔值。响应状态是否为 404。

  • is_status_412

    布尔值。响应状态是否为 412。

  • is_status_429

    布尔值。响应状态是否为 429。

  • is_status_500

    布尔值。响应状态是否为 500。

  • is_status_502

    布尔值。响应状态是否为 502。

  • is_status_503

    布尔值。响应状态是否为 503。

  • is_status_504

    布尔值。响应状态是否为 504。

  • is_upstream_status_400

    布尔值。上游的响应状态是否为 400。

  • is_upstream_status_403

    布尔值。上游的响应状态是否为 403。

  • is_upstream_status_404

    布尔值。上游的响应状态是否为 404。

  • is_upstream_status_412

    布尔值。上游的响应状态是否为 412。

  • is_upstream_status_429

    布尔值。上游的响应状态是否为 429。

  • is_upstream_status_500

    布尔值。上游的响应状态是否为 500。

  • is_upstream_status_502

    布尔值。上游的响应状态是否为 502。

  • is_upstream_status_503

    布尔值。上游的响应状态是否为 503。

  • is_upstream_status_504

    布尔值。上游的响应状态是否为 504。

HTTP

此表主要用于统计连接数。

它有以下列:

  • active_conns

    当前活跃客户端连接数,包括等待连接。

  • waiting_conns

    当前等待请求的空闲客户端连接数。

  • writing_conns

    当前 openresty edge 正在向客户端写回响应的连接数。

  • reading_conns

    当前 openresty edge 正在读取请求头部的连接数。

返回目录

示例

示例一:统计统计命中率 TOP 10 的域名

select host, sum(is_upstream_cache_status_hit) / count(*) * 100 as cache_hit_ratio_percent
from reqs
where upstream_cache_status != ''
group by host
order by cache_hit_ratio_percent desc
limit 10

返回目录

作者

章亦春 yichun@openresty.com,OpenResty Inc.

返回目录

版权和许可

版权所有 (C) 2020-2021 OpenResty Inc. 保留所有权利。

本文档为专有文档,包含机密信息。未经版权持有者书面许可,禁止在任何时候重新分发本文档。

返回目录