Hi čt 6. 6. 2019 v 10:48 odesílatel Gilles Darold <gil...@darold.net> napsal:
> Le 06/06/2019 à 10:38, Pavel Stehule a écrit : > > Hi > > > > I like the idea of sampling slow statements via > > log_statement_sample_rate. But I miss some parameter that can ensure > > so every query executed over this limit is logged. > > > > Can we introduce new option > > > > log_statement_sampling_limit > > > > The query with execution time over this limit is logged every time. > > > > What do you think about this? > > > > Regards > > > > Pavel > > > +1, log_min_duration_statement is modulated by log_statement_sample_rate > that mean that there is no more way to log all statements over a certain > duration limit. log_statement_sampling_limit might probably always be > upper than log_min_duration_statement. > Here is a patch Regards Pavel > > -- > Gilles Darold > http://www.darold.net/ > >
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 84341a30e5..690f54f731 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -5903,6 +5903,21 @@ local0.* /var/log/postgresql </listitem> </varlistentry> + <varlistentry id="guc-log-statement-sample-limit" xreflabel="log_statement_sample_limit"> + <term><varname>log_statement_sample_limit</varname> (<type>integer</type>) + <indexterm> + <primary><varname>log_statement_sample_limit</varname> configuration parameter</primary> + </indexterm> + </term> + <listitem> + <para> + Only if query duration is less than this value, the log sampling is active. + When <varname>log_statement_sample_limit</varname> is <literal>-1</literal> + then log sampling is without limit. + </para> + </listitem> + </varlistentry> + <varlistentry id="guc-log-transaction-sample-rate" xreflabel="log_transaction_sample_rate"> <term><varname>log_transaction_sample_rate</varname> (<type>real</type>) <indexterm> diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 44a59e1d4f..2d8cc7d411 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -2193,7 +2193,9 @@ check_log_statement(List *stmt_list) /* * check_log_duration * Determine whether current command's duration should be logged. - * If log_statement_sample_rate < 1.0, log only a sample. + * If log_statement_sample_rate < 1.0, log only a sample and duration + * is less than log_statement_sample_limit. log_statement_sample_limit + * is used only if this value is different than -1. * We also check if this statement in this transaction must be logged * (regardless of its duration). * @@ -2217,6 +2219,7 @@ check_log_duration(char *msec_str, bool was_logged) int usecs; int msecs; bool exceeded; + bool every_time; bool in_sample; TimestampDifference(GetCurrentStatementStartTimestamp(), @@ -2234,6 +2237,15 @@ check_log_duration(char *msec_str, bool was_logged) (secs > log_min_duration_statement / 1000 || secs * 1000 + msecs >= log_min_duration_statement))); + /* + * When log_statement_sample_limit is exceeded, then query is + * logged every time. + */ + every_time = (log_statement_sample_limit == 0 || + (log_statement_sample_limit > 0 && + (secs > log_statement_sample_limit / 1000 || + secs * 1000 + msecs >= log_statement_sample_limit))); + /* * Do not log if log_statement_sample_rate = 0. Log a sample if * log_statement_sample_rate <= 1 and avoid unnecessary random() call @@ -2245,7 +2257,7 @@ check_log_duration(char *msec_str, bool was_logged) (log_statement_sample_rate == 1 || random() <= log_statement_sample_rate * MAX_RANDOM_VALUE); - if ((exceeded && in_sample) || log_duration || xact_is_sampled) + if ((exceeded && (in_sample || every_time)) || log_duration || xact_is_sampled) { snprintf(msec_str, 32, "%ld.%03d", secs * 1000 + msecs, usecs % 1000); diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 1208eb9a68..b0c7d9df0e 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -510,6 +510,7 @@ int log_min_error_statement = ERROR; int log_min_messages = WARNING; int client_min_messages = NOTICE; int log_min_duration_statement = -1; +int log_statement_sample_limit = -1; int log_temp_files = -1; double log_statement_sample_rate = 1.0; double log_xact_sample_rate = 0; @@ -2715,6 +2716,19 @@ static struct config_int ConfigureNamesInt[] = NULL, NULL, NULL }, + { + {"log_statement_sample_limit", PGC_SUSET, LOGGING_WHEN, + gettext_noop("Sets the maximum execution time for sampling " + "logged statements."), + gettext_noop("Zero effective disables sampling. " + "-1 use sampling every time (without limit)."), + GUC_UNIT_MS + }, + &log_statement_sample_limit, + -1, -1, INT_MAX, + NULL, NULL, NULL + }, + { {"log_autovacuum_min_duration", PGC_SIGHUP, LOGGING_WHAT, gettext_noop("Sets the minimum execution time above which " diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h index e709177c37..8f0c2c59d4 100644 --- a/src/include/utils/guc.h +++ b/src/include/utils/guc.h @@ -252,6 +252,7 @@ extern int log_min_error_statement; extern PGDLLIMPORT int log_min_messages; extern PGDLLIMPORT int client_min_messages; extern int log_min_duration_statement; +extern int log_statement_sample_limit; extern int log_temp_files; extern double log_statement_sample_rate; extern double log_xact_sample_rate;