可观性#
日志记录#
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
。
12/Jun/2021:17:47:39 -0500: Starting PostgREST 11.1.0...
12/Jun/2021:17:47:39 -0500: Attempting to connect to the database...
12/Jun/2021:17:47:39 -0500: Listening on port 3000
12/Jun/2021:17:47:39 -0500: Connection successful
12/Jun/2021:17:47:39 -0500: Config re-loaded
12/Jun/2021:17:47:40 -0500: Schema cache loaded
备注
当在SSH会话中运行它时,您必须将其与标准输出分离,否则它将在会话关闭时终止。最简单的方法是将输出重定向到日志文件或系统日志:
ssh foo@example.com \
'postgrest foo.conf </dev/null >/var/log/postgrest.log 2>&1 &'
# another option is to pipe the output into "logger -t postgrest"
目前,PostgREST不记录针对底层数据库执行的SQL命令。
数据库日志#
要找到SQL操作,您可以查看数据库日志。默认情况下,PostgreSQL不会保留这些日志,因此您需要进行以下配置更改。
发现 postgresql.conf
在您的PostgreSQL数据目录中(要找到它,请发出以下命令 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>
服务器版本#
在调试问题时,验证正在运行的PostgREST版本很重要。有三种方法可以做到这一点:
寻找
Server
在每个请求上返回的HTTP响应头。
HEAD /users HTTP/1.1
Server: postgrest/11.0.1
查询
application_name
在……上面 pg_stat_activity 。
select distinct application_name
from pg_stat_activity
where application_name ilike '%postgrest%';
application_name
------------------------------
PostgREST 11.1.0
重要
服务器设置 fallback_application_name 设置为此查询工作所需的连接URI。覆盖值集的步骤
application_name
在连接字符串上。仅当版本是有效的URI时才会设置 (RFC 3986 )。这意味着任何特殊字符都必须经过urlended编码。
如果连接字符串位于中,则不会设置版本 keyword/value format 。
这个
stderr
日志还包含版本,如上所述 日志记录 。
跟踪标头#
您可以通过设置启用跟踪HTTP请求 服务器跟踪标头 。在请求中指定Set标头,服务器会将其包含在响应中。
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 通过设置表头 启用服务器计时 在……上面。此标头传达请求-响应周期中不同阶段的指标。
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语法 是被解析的。这个
transaction
阶段对应于数据库事务。看见 交易记录 。这个
response
阶段是计算响应状态和标头的地方。
备注
我们正在努力降低持续时间 parse
和 plan
PostgREST/postgrest#2816.上的阶段
执行计划#
你可以拿到 EXPLAIN execution plan 通过添加请求的 Accept: application/vnd.pgrst.plan
标题。这可通过以下方式实现 数据库-计划已启用 (默认情况下为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
后缀。
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
),但您可以获取 different representations that PostgREST supports 通过将它们添加到 for
参数。例如,要获得一个 text/xml
,您将使用 Accept: application/vnd.pgrst.plan; for="text/xml
。
其他可用参数包括 analyze
, verbose
, settings
, buffers
和 wal
,它们对应于 EXPLAIN command options 。要使用 analyze
和 wal
参数,例如,您可以将它们添加为 Accept: application/vnd.pgrst.plan; options=analyze|wal
。
注意,与EXPLAIN命令类似,更改将在使用 analyze
选择。要避免这种情况,您可以使用 DB-TX-END 以及 Prefer: tx=rollback
标题。
确保执行计划的安全#
建议仅激活 数据库-计划已启用 因为它揭示了内部数据库的详细信息。但是,如果选择在生产中使用它,则可以添加一个 数据库-请求前 以筛选可以使用此功能的请求。
例如,要仅允许来自IP地址的请求获取执行计划:
-- Assuming a proxy(Nginx, Cloudflare, etc) passes an "X-Forwarded-For" header(https://developer.mozilla.org/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