|
|
|
@ -28,6 +28,7 @@ static bool auto_explain_log_buffers = false; |
|
|
|
|
static bool auto_explain_log_triggers = false; |
|
|
|
|
static bool auto_explain_log_timing = true; |
|
|
|
|
static int auto_explain_log_format = EXPLAIN_FORMAT_TEXT; |
|
|
|
|
static int auto_explain_log_level = LOG; |
|
|
|
|
static bool auto_explain_log_nested_statements = false; |
|
|
|
|
static double auto_explain_sample_rate = 1; |
|
|
|
|
|
|
|
|
@ -39,6 +40,20 @@ static const struct config_enum_entry format_options[] = { |
|
|
|
|
{NULL, 0, false} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
static const struct config_enum_entry loglevel_options[] = { |
|
|
|
|
{"debug5", DEBUG5, false}, |
|
|
|
|
{"debug4", DEBUG4, false}, |
|
|
|
|
{"debug3", DEBUG3, false}, |
|
|
|
|
{"debug2", DEBUG2, false}, |
|
|
|
|
{"debug1", DEBUG1, false}, |
|
|
|
|
{"debug", DEBUG2, true}, |
|
|
|
|
{"info", INFO, false}, |
|
|
|
|
{"notice", NOTICE, false}, |
|
|
|
|
{"warning", WARNING, false}, |
|
|
|
|
{"log", LOG, false}, |
|
|
|
|
{NULL, 0, false} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/* Current nesting depth of ExecutorRun calls */ |
|
|
|
|
static int nesting_level = 0; |
|
|
|
|
|
|
|
|
@ -141,6 +156,18 @@ _PG_init(void) |
|
|
|
|
NULL, |
|
|
|
|
NULL); |
|
|
|
|
|
|
|
|
|
DefineCustomEnumVariable("auto_explain.log_level", |
|
|
|
|
"Log level for the plan.", |
|
|
|
|
NULL, |
|
|
|
|
&auto_explain_log_level, |
|
|
|
|
LOG, |
|
|
|
|
loglevel_options, |
|
|
|
|
PGC_SUSET, |
|
|
|
|
0, |
|
|
|
|
NULL, |
|
|
|
|
NULL, |
|
|
|
|
NULL); |
|
|
|
|
|
|
|
|
|
DefineCustomBoolVariable("auto_explain.log_nested_statements", |
|
|
|
|
"Log nested statements.", |
|
|
|
|
NULL, |
|
|
|
@ -353,7 +380,7 @@ explain_ExecutorEnd(QueryDesc *queryDesc) |
|
|
|
|
* reported. This isn't ideal but trying to do it here would |
|
|
|
|
* often result in duplication. |
|
|
|
|
*/ |
|
|
|
|
ereport(LOG, |
|
|
|
|
ereport(auto_explain_log_level, |
|
|
|
|
(errmsg("duration: %.3f ms plan:\n%s", |
|
|
|
|
msec, es->str->data), |
|
|
|
|
errhidestmt(true))); |
|
|
|
|