可观测性
可观测性允许根据系统生成的日志、指标和跟踪等数据来衡量系统的当前状态。
日志
PostgREST 将基本请求信息记录到 stdout
,包括可用的已认证用户、请求的 IP 地址和用户代理、请求的 URL 和 HTTP 响应状态。
127.0.0.1 - user [26/Jul/2021:01:56:38 -0500] "GET /clients HTTP/1.1" 200 - "" "curl/7.64.0"
127.0.0.1 - anonymous [26/Jul/2021:01:56:48 -0500] "GET /unexistent HTTP/1.1" 404 - "" "curl/7.64.0"
有关服务器本身的诊断信息,PostgREST 将记录到 stderr
06/May/2024:08:16:11 -0500: Starting PostgREST 12.1...
06/May/2024:08:16:11 -0500: Attempting to connect to the database...
06/May/2024:08:16:11 -0500: Successfully connected to PostgreSQL 14.10 (Ubuntu 14.10-0ubuntu0.22.04.1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0, 64-bit
06/May/2024:08:16:11 -0500: Listening on port 3000
06/May/2024:08:16:11 -0500: Listening for notifications on the "pgrst" channel
06/May/2024:08:16:11 -0500: Config reloaded
06/May/2024:08:16:11 -0500: Schema cache queried in 3.8 milliseconds
06/May/2024:08:16:11 -0500: Schema cache loaded 15 Relations, 8 Relationships, 8 Functions, 0 Domain Representations, 4 Media Type Handlers
06/May/2024:14:11:27 -0500: Received a config reload message on the "pgrst" channel
06/May/2024:14:11:27 -0500: Config reloaded
数据库日志
目前 PostgREST 不会记录针对底层数据库执行的 SQL 命令。
要查找 SQL 操作,您可以查看数据库日志。默认情况下,PostgreSQL 不会保留这些日志,因此您需要进行以下配置更改。
在您的 PostgreSQL 数据目录中找到 postgresql.conf
(要找到它,请执行命令 show data_directory;
)。要么在整个文件中找到这些设置并将它们更改为以下值,要么将此代码块追加到配置文件的末尾。
# send logs where the collector can access them
log_destination = "stderr"
# collect stderr output to log files
logging_collector = on
# save logs in pg_log/ under the pg data directory
log_directory = "pg_log"
# (optional) new log file per day
log_filename = "postgresql-%Y-%m-%d.log"
# log every kind of SQL statement
log_statement = "all"
重新启动数据库并实时查看日志文件,以了解 HTTP 请求是如何转换为 SQL 命令的。
注意
在 Docker 上,您可以使用自定义的 init.sh
来启用日志。
#!/bin/sh
echo "log_statement = 'all'" >> /var/lib/postgresql/data/postgresql.conf
之后,您可以启动容器并使用 docker logs
检查日志。
docker run -v "$(pwd)/init.sh":"/docker-entrypoint-initdb.d/init.sh" -d postgres
docker logs -f <container-id>
指标
管理服务器 端点上的 metrics
端点以 Prometheus 文本格式 提供指标。
curl "http://localhost:3001/metrics"
# HELP pgrst_schema_cache_query_time_seconds The query time in seconds of the last schema cache load
# TYPE pgrst_schema_cache_query_time_seconds gauge
pgrst_schema_cache_query_time_seconds 1.5937927e-2
# HELP pgrst_schema_cache_loads_total The total number of times the schema cache was loaded
# TYPE pgrst_schema_cache_loads_total counter
pgrst_schema_cache_loads_total 1.0
...
模式缓存指标
与 模式缓存 相关的指标。
pgrst_schema_cache_query_time_seconds
类型 |
Gauge |
上次模式缓存加载的查询时间(以秒为单位)。
pgrst_schema_cache_loads_total
类型 |
计数器 |
标签 |
|
架构缓存加载的总次数。
连接池指标
与连接池相关的指标。
pgrst_db_pool_timeouts_total
类型 |
计数器 |
池连接超时总数。
pgrst_db_pool_available
类型 |
Gauge |
池中可用的连接。
pgrst_db_pool_waiting
类型 |
Gauge |
等待获取池连接的请求
pgrst_db_pool_max
类型 |
Gauge |
最大池连接数。
跟踪
服务器版本头
调试问题时,验证正在运行的 PostgREST 版本非常重要。为此,您可以查看每个请求返回的 Server
HTTP 响应头。
HEAD /users HTTP/1.1
Server: postgrest/11.0.1
跟踪头
您可以通过设置 server-trace-header 来启用跟踪 HTTP 请求。在请求中指定要设置的头,服务器将在响应中包含它。
server-trace-header = "X-Request-Id"
curl "http://localhost:3000/users" \
-H "X-Request-Id: 123"
HTTP/1.1 200 OK
X-Request-Id: 123
服务器计时头
您可以通过设置 server-timing-enabled 为 on 来启用 Server-Timing 头。此头将传达请求-响应周期中不同阶段的指标。
curl "http://localhost:3000/users" -i
HTTP/1.1 200 OK
Server-Timing: jwt;dur=14.9, parse;dur=71.1, plan;dur=109.0, transaction;dur=353.2, response;dur=4.4
所有持续时间 (
dur
) 都是以毫秒为单位。在
jwt
阶段,基于 JWT 的用户模拟 完成。此持续时间可以通过 JWT 缓存 来降低。在
parse
阶段,URL 语法 被解析。The
transaction
stage corresponds to the database transaction. See Transactions.The
response
stage is where the response status and headers are computed.
注意
We’re working on lowering the duration of the parse
and plan
stages on https://github.com/PostgREST/postgrest/issues/2816.
执行计划
您可以通过添加 Accept: application/vnd.pgrst.plan
头部来获取请求的 EXPLAIN 执行计划。这由 db-plan-enabled(默认情况下为 false)启用。
curl "http://localhost:3000/users?select=name&order=id" \
-H "Accept: application/vnd.pgrst.plan"
Aggregate (cost=73.65..73.68 rows=1 width=112)
-> Index Scan using users_pkey on users (cost=0.15..60.90 rows=850 width=36)
计划的输出默认情况下以 text
格式生成,但您可以使用 +json
后缀将其更改为 JSON。
curl "http://localhost:3000/users?select=name&order=id" \
-H "Accept: application/vnd.pgrst.plan+json"
[
{
"Plan": {
"Node Type": "Aggregate",
"Strategy": "Plain",
"Partial Mode": "Simple",
"Parallel Aware": false,
"Async Capable": false,
"Startup Cost": 73.65,
"Total Cost": 73.68,
"Plan Rows": 1,
"Plan Width": 112,
"Plans": [
{
"Node Type": "Index Scan",
"Parent Relationship": "Outer",
"Parallel Aware": false,
"Async Capable": false,
"Scan Direction": "Forward",
"Index Name": "users_pkey",
"Relation Name": "users",
"Alias": "users",
"Startup Cost": 0.15,
"Total Cost": 60.90,
"Plan Rows": 850,
"Plan Width": 36
}
]
}
}
]
默认情况下,假设该计划生成资源的 JSON 表示形式(application/json
),但您可以通过将它们添加到 for
参数中来获取 PostgREST 支持的不同表示形式 的计划。例如,要获取 text/xml
的计划,您将使用 Accept: application/vnd.pgrst.plan; for="text/xml
。
其他可用参数是 analyze
、verbose
、settings
、buffers
和 wal
,它们对应于 EXPLAIN 命令选项。例如,要使用 analyze
和 wal
参数,您将像 Accept: application/vnd.pgrst.plan; options=analyze|wal
那样添加它们。
请注意,与 EXPLAIN 命令类似,使用 analyze
选项时,更改将被提交。为了避免这种情况,您可以使用 db-tx-end 和 Prefer: tx=rollback
头部。
保护执行计划
建议仅在测试环境中激活 db-plan-enabled,因为它会暴露内部数据库细节。但是,如果您选择在生产环境中使用它,您可以添加一个 db-pre-request 来过滤可以使用此功能的请求。
例如,要仅允许来自特定 IP 地址的请求获取执行计划
-- Assuming a proxy(Nginx, Cloudflare, etc) passes an "X-Forwarded-For" header(https://mdn.org.cn/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)
create or replace function filter_plan_requests()
returns void as $$
declare
headers json := current_setting('request.headers', true)::json;
client_ip text := coalesce(headers->>'x-forwarded-for', '');
accept text := coalesce(headers->>'accept', '');
begin
if accept like 'application/vnd.pgrst.plan%' and client_ip != '144.96.121.73' then
raise insufficient_privilege using
message = 'Not allowed to use application/vnd.pgrst.plan';
end if;
end; $$ language plpgsql;
-- set this function on your postgrest.conf
-- db-pre-request = filter_plan_requests