feat: allow logging the SQL query to stderr
- Logs the main SQL query when `log-query=main-query`. - Only logs at the current `log-level`.
This commit is contained in:
@@ -308,6 +308,23 @@
|
||||
pdSchema: public
|
||||
pdVolatility: Volatile
|
||||
|
||||
- - qiName: root
|
||||
qiSchema: public
|
||||
- - pdDescription: null
|
||||
pdFuncSettings: []
|
||||
pdHasVariadic: false
|
||||
pdName: root
|
||||
pdParams: []
|
||||
pdReturnType:
|
||||
contents:
|
||||
contents:
|
||||
qiName: json
|
||||
qiSchema: pg_catalog
|
||||
tag: Scalar
|
||||
tag: Single
|
||||
pdSchema: public
|
||||
pdVolatility: Volatile
|
||||
|
||||
- - qiName: uses_prepared_statements
|
||||
qiSchema: public
|
||||
- - pdDescription: null
|
||||
|
||||
@@ -10,6 +10,18 @@
|
||||
tableSchema: public
|
||||
tableUpdatable: true
|
||||
|
||||
- - qiName: infinite_recursion
|
||||
qiSchema: public
|
||||
- tableColumns: {}
|
||||
tableDeletable: false
|
||||
tableDescription: null
|
||||
tableInsertable: false
|
||||
tableIsView: true
|
||||
tableName: infinite_recursion
|
||||
tablePKCols: []
|
||||
tableSchema: public
|
||||
tableUpdatable: false
|
||||
|
||||
- - qiName: cats
|
||||
qiSchema: public
|
||||
- tableColumns:
|
||||
|
||||
@@ -25,6 +25,7 @@ jwt-secret = ""
|
||||
jwt-secret-is-base64 = true
|
||||
jwt-cache-max-lifetime = 0
|
||||
log-level = "error"
|
||||
log-query = "disabled"
|
||||
openapi-mode = "follow-privileges"
|
||||
openapi-security-active = false
|
||||
openapi-server-proxy-uri = ""
|
||||
|
||||
@@ -25,6 +25,7 @@ jwt-secret = ""
|
||||
jwt-secret-is-base64 = true
|
||||
jwt-cache-max-lifetime = 0
|
||||
log-level = "error"
|
||||
log-query = "disabled"
|
||||
openapi-mode = "follow-privileges"
|
||||
openapi-security-active = false
|
||||
openapi-server-proxy-uri = ""
|
||||
|
||||
@@ -25,6 +25,7 @@ jwt-secret = ""
|
||||
jwt-secret-is-base64 = true
|
||||
jwt-cache-max-lifetime = 0
|
||||
log-level = "error"
|
||||
log-query = "disabled"
|
||||
openapi-mode = "follow-privileges"
|
||||
openapi-security-active = false
|
||||
openapi-server-proxy-uri = ""
|
||||
|
||||
@@ -25,6 +25,7 @@ jwt-secret = ""
|
||||
jwt-secret-is-base64 = false
|
||||
jwt-cache-max-lifetime = 0
|
||||
log-level = "error"
|
||||
log-query = "disabled"
|
||||
openapi-mode = "follow-privileges"
|
||||
openapi-security-active = false
|
||||
openapi-server-proxy-uri = ""
|
||||
|
||||
@@ -25,6 +25,7 @@ jwt-secret = ""
|
||||
jwt-secret-is-base64 = false
|
||||
jwt-cache-max-lifetime = 0
|
||||
log-level = "error"
|
||||
log-query = "disabled"
|
||||
openapi-mode = "follow-privileges"
|
||||
openapi-security-active = false
|
||||
openapi-server-proxy-uri = ""
|
||||
|
||||
@@ -25,6 +25,7 @@ jwt-secret = ""
|
||||
jwt-secret-is-base64 = false
|
||||
jwt-cache-max-lifetime = 0
|
||||
log-level = "error"
|
||||
log-query = "disabled"
|
||||
openapi-mode = "follow-privileges"
|
||||
openapi-security-active = false
|
||||
openapi-server-proxy-uri = ""
|
||||
|
||||
@@ -25,6 +25,7 @@ jwt-secret = ""
|
||||
jwt-secret-is-base64 = false
|
||||
jwt-cache-max-lifetime = 0
|
||||
log-level = "error"
|
||||
log-query = "disabled"
|
||||
openapi-mode = "follow-privileges"
|
||||
openapi-security-active = false
|
||||
openapi-server-proxy-uri = ""
|
||||
|
||||
@@ -25,6 +25,7 @@ jwt-secret = ""
|
||||
jwt-secret-is-base64 = false
|
||||
jwt-cache-max-lifetime = 0
|
||||
log-level = "error"
|
||||
log-query = "disabled"
|
||||
openapi-mode = "follow-privileges"
|
||||
openapi-security-active = false
|
||||
openapi-server-proxy-uri = ""
|
||||
|
||||
@@ -25,6 +25,7 @@ jwt-secret = ""
|
||||
jwt-secret-is-base64 = false
|
||||
jwt-cache-max-lifetime = 0
|
||||
log-level = "error"
|
||||
log-query = "disabled"
|
||||
openapi-mode = "follow-privileges"
|
||||
openapi-security-active = false
|
||||
openapi-server-proxy-uri = ""
|
||||
|
||||
@@ -25,6 +25,7 @@ jwt-secret = "ODERREALLYREALLYREALLYREALLYVERYSAFE"
|
||||
jwt-secret-is-base64 = false
|
||||
jwt-cache-max-lifetime = 7200
|
||||
log-level = "info"
|
||||
log-query = "main-query"
|
||||
openapi-mode = "disabled"
|
||||
openapi-security-active = false
|
||||
openapi-server-proxy-uri = "https://otherexample.org/api"
|
||||
|
||||
@@ -25,6 +25,7 @@ jwt-secret = "OVERRIDE=REALLY=REALLY=REALLY=REALLY=VERY=SAFE"
|
||||
jwt-secret-is-base64 = false
|
||||
jwt-cache-max-lifetime = 3600
|
||||
log-level = "info"
|
||||
log-query = "main-query"
|
||||
openapi-mode = "ignore-privileges"
|
||||
openapi-security-active = true
|
||||
openapi-server-proxy-uri = "https://example.org/api"
|
||||
|
||||
@@ -25,6 +25,7 @@ jwt-secret = "c2VjdXJpdHl0aHJvdWdob2JzY3VyaXR5aW5iYXNlNjQ="
|
||||
jwt-secret-is-base64 = true
|
||||
jwt-cache-max-lifetime = 86400
|
||||
log-level = "info"
|
||||
log-query = "main-query"
|
||||
openapi-mode = "ignore-privileges"
|
||||
openapi-security-active = true
|
||||
openapi-server-proxy-uri = "https://postgrest.org"
|
||||
|
||||
@@ -25,6 +25,7 @@ jwt-secret = ""
|
||||
jwt-secret-is-base64 = false
|
||||
jwt-cache-max-lifetime = 0
|
||||
log-level = "error"
|
||||
log-query = "disabled"
|
||||
openapi-mode = "follow-privileges"
|
||||
openapi-security-active = false
|
||||
openapi-server-proxy-uri = ""
|
||||
|
||||
@@ -28,6 +28,7 @@ PGRST_JWT_SECRET: c2VjdXJpdHl0aHJvdWdob2JzY3VyaXR5aW5iYXNlNjQ=
|
||||
PGRST_JWT_SECRET_IS_BASE64: true
|
||||
PGRST_JWT_CACHE_MAX_LIFETIME: 86400
|
||||
PGRST_LOG_LEVEL: info
|
||||
PGRST_LOG_QUERY: 'main-query'
|
||||
PGRST_OPENAPI_MODE: 'ignore-privileges'
|
||||
PGRST_OPENAPI_SECURITY_ACTIVE: true
|
||||
PGRST_OPENAPI_SERVER_PROXY_URI: 'https://postgrest.org'
|
||||
|
||||
@@ -25,6 +25,7 @@ jwt-secret = "c2VjdXJpdHl0aHJvdWdob2JzY3VyaXR5aW5iYXNlNjQ="
|
||||
jwt-secret-is-base64 = true
|
||||
jwt-cache-max-lifetime = 86400
|
||||
log-level = "info"
|
||||
log-query = "main-query"
|
||||
openapi-mode = "ignore-privileges"
|
||||
openapi-security-active = true
|
||||
openapi-server-proxy-uri = "https://postgrest.org"
|
||||
|
||||
@@ -47,6 +47,7 @@ ALTER ROLE db_config_authenticator SET pgrst.db_pool_max_idletime = 'ignored';
|
||||
ALTER ROLE db_config_authenticator SET pgrst.db_pool_max_lifetime = 'ignored';
|
||||
ALTER ROLE db_config_authenticator SET pgrst.db_uri = 'postgresql://ignored';
|
||||
ALTER ROLE db_config_authenticator SET pgrst.log_level = 'ignored';
|
||||
ALTER ROLE db_config_authenticator SET pgrst.log_query = 'ignored';
|
||||
ALTER ROLE db_config_authenticator SET pgrst.server_host = 'ignored';
|
||||
ALTER ROLE db_config_authenticator SET pgrst.server_port = 'ignored';
|
||||
ALTER ROLE db_config_authenticator SET pgrst.server_unix_socket = 'ignored';
|
||||
|
||||
@@ -243,3 +243,13 @@ end $_$ volatile security definer language plpgsql ;
|
||||
create function test.get_current_schema() returns text as $$
|
||||
select current_schema()::text;
|
||||
$$ language sql;
|
||||
|
||||
create or replace function root() returns json as $_$
|
||||
select '{"swagger": "2.0"}'::json;
|
||||
$_$ language sql;
|
||||
|
||||
create view infinite_recursion as
|
||||
select * from projects;
|
||||
|
||||
create or replace view infinite_recursion as
|
||||
select * from infinite_recursion;
|
||||
|
||||
@@ -980,6 +980,66 @@ def test_log_level(level, defaultenv):
|
||||
assert len(output) == 7
|
||||
|
||||
|
||||
@pytest.mark.parametrize("level", ["crit", "error", "warn", "info", "debug"])
|
||||
def test_log_query(level, defaultenv):
|
||||
"log_query=true should log the SQL query according to the log_level"
|
||||
|
||||
env = {
|
||||
**defaultenv,
|
||||
"PGRST_LOG_LEVEL": level,
|
||||
"PGRST_LOG_QUERY": "main-query",
|
||||
# The root path can only log SQL when a function is set in db-root-spec
|
||||
"PGRST_DB_ROOT_SPEC": "root",
|
||||
}
|
||||
|
||||
with run(env=env) as postgrest:
|
||||
response = postgrest.session.get("/")
|
||||
assert response.status_code == 200
|
||||
|
||||
response = postgrest.session.get("/projects")
|
||||
assert response.status_code == 200
|
||||
|
||||
response = postgrest.session.get("/unknown")
|
||||
assert response.status_code == 404
|
||||
|
||||
response = postgrest.session.get("/infinite_recursion")
|
||||
assert response.status_code == 500
|
||||
|
||||
root_2xx_regx = r'.+: WITH pgrst_source AS.+SELECT "public"\."root"\(\) pgrst_scalar.+_postgrest_t'
|
||||
get_2xx_regx = r'.+: WITH pgrst_source AS.+SELECT "public"\."projects"\.\* FROM "public"\."projects".+_postgrest_t'
|
||||
unknown_4xx_regx = r'.+: WITH pgrst_source AS.+SELECT "public"\."unknown"\.\* FROM "public"\."unknown".+_postgrest_t'
|
||||
infinite_recursion_5xx_regx = r'.+: WITH pgrst_source AS.+SELECT "public"\."infinite_recursion"\.\* FROM "public"\."infinite_recursion".+_postgrest_t'
|
||||
|
||||
if level == "crit":
|
||||
output = postgrest.read_stdout(nlines=1)
|
||||
assert len(output) == 0
|
||||
elif level == "error":
|
||||
output = postgrest.read_stdout(nlines=4)
|
||||
assert re.match(infinite_recursion_5xx_regx, output[1])
|
||||
assert len(output) == 3
|
||||
elif level == "warn":
|
||||
output = postgrest.read_stdout(nlines=6)
|
||||
assert re.match(unknown_4xx_regx, output[0])
|
||||
assert re.match(infinite_recursion_5xx_regx, output[3])
|
||||
assert len(output) == 5
|
||||
elif level == "info":
|
||||
output = postgrest.read_stdout(nlines=10)
|
||||
assert re.match(root_2xx_regx, output[0])
|
||||
assert re.match(get_2xx_regx, output[2])
|
||||
assert re.match(unknown_4xx_regx, output[4])
|
||||
assert re.match(infinite_recursion_5xx_regx, output[7])
|
||||
assert len(output) == 9
|
||||
elif level == "debug":
|
||||
output_ok = postgrest.read_stdout(nlines=8)
|
||||
assert re.match(root_2xx_regx, output_ok[2])
|
||||
assert re.match(get_2xx_regx, output_ok[6])
|
||||
assert len(output_ok) == 8
|
||||
output_err = postgrest.read_stdout(nlines=10)
|
||||
assert re.match(unknown_4xx_regx, output_err[2])
|
||||
assert re.match(infinite_recursion_5xx_regx, output_err[7])
|
||||
assert len(output_err) == 9
|
||||
|
||||
|
||||
def test_no_pool_connection_required_on_bad_http_logic(defaultenv):
|
||||
"no pool connection should be consumed for failing on invalid http logic"
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ import Data.String (String)
|
||||
import PostgREST.Config (AppConfig (..),
|
||||
JSPathExp (..),
|
||||
LogLevel (..),
|
||||
LogQuery (..),
|
||||
OpenAPIMode (..),
|
||||
parseSecret)
|
||||
import PostgREST.SchemaCache.Identifiers (QualifiedIdentifier (..))
|
||||
@@ -138,6 +139,7 @@ baseCfg = let secret = encodeUtf8 "reallyreallyreallyreallyverysafe" in
|
||||
, configJwtSecretIsBase64 = False
|
||||
, configJwtCacheMaxLifetime = 0
|
||||
, configLogLevel = LogCrit
|
||||
, configLogQuery = LogQueryDisabled
|
||||
, configOpenApiMode = OAFollowPriv
|
||||
, configOpenApiSecurityActive = False
|
||||
, configOpenApiServerProxyUri = Nothing
|
||||
|
||||
Reference in New Issue
Block a user