Metric SQL 用户手册
本手册面向用户,系统地介绍了 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
运算符支持两种形式的模式:
(开发中)
带有元字符的 SQL 风格模式,如%
(匹配零个或多个任意字符)和_
(匹配一个任意字符)。元字符可以用反斜杠(/
)转义以表示%
和_
字符本身。- 正则表达式字面量,如
/.../
和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 目前有一些限制:
order by
子句中只允许一列。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. 保留所有权利。
本文档为专有文档,包含机密信息。未经版权持有者书面许可,禁止在任何时候重新分发本文档。