Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 1f98e11

Browse files
eulertoCommitfest Bot
authored and
Commitfest Bot
committed
log_min_messages per backend type
Change log_min_messages from a single element to a comma-separated list of elements. Each element is backendtype:loglevel. The backendtype are archiver, autovacuum (includes launcher and workers), backend, bgworker, bgwriter, checkpointer, logger, slotsyncworker, walreceiver, walsender, walsummarizer and walwriter. It should be part of this list a single log level that is applied as a final step to the backend types that are not informed. The old syntax (a single log level) is still accepted for backward compatibility. In this case, it means the informed log level is applied for the backend types that are not informed. The default log level is the same (WARNING) for all backend types.
1 parent 36e5fda commit 1f98e11

File tree

12 files changed

+352
-25
lines changed

12 files changed

+352
-25
lines changed

doc/src/sgml/config.sgml

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6999,7 +6999,7 @@ local0.* /var/log/postgresql
69996999
<variablelist>
70007000

70017001
<varlistentry id="guc-log-min-messages" xreflabel="log_min_messages">
7002-
<term><varname>log_min_messages</varname> (<type>enum</type>)
7002+
<term><varname>log_min_messages</varname> (<type>string</type>)
70037003
<indexterm>
70047004
<primary><varname>log_min_messages</varname> configuration parameter</primary>
70057005
</indexterm>
@@ -7008,14 +7008,26 @@ local0.* /var/log/postgresql
70087008
<para>
70097009
Controls which <link linkend="runtime-config-severity-levels">message
70107010
levels</link> are written to the server log.
7011-
Valid values are <literal>DEBUG5</literal>, <literal>DEBUG4</literal>,
7012-
<literal>DEBUG3</literal>, <literal>DEBUG2</literal>, <literal>DEBUG1</literal>,
7013-
<literal>INFO</literal>, <literal>NOTICE</literal>, <literal>WARNING</literal>,
7014-
<literal>ERROR</literal>, <literal>LOG</literal>, <literal>FATAL</literal>, and
7015-
<literal>PANIC</literal>. Each level includes all the levels that
7016-
follow it. The later the level, the fewer messages are sent
7017-
to the log. The default is <literal>WARNING</literal>. Note that
7018-
<literal>LOG</literal> has a different rank here than in
7011+
Valid values are a comma-separated list of <literal>backendtype:level</literal>
7012+
and a single <literal>level</literal>. The list allows it to use
7013+
different levels per backend type.
7014+
Valid <literal>backendtype</literal> values are <literal>archiver</literal>,
7015+
<literal>autovacuum</literal>, <literal>backend</literal>,
7016+
<literal>bgworker</literal>, <literal>bgwriter</literal>,
7017+
<literal>checkpointer</literal>, <literal>logger</literal>,
7018+
<literal>slotsyncworker</literal>, <literal>walreceiver</literal>,
7019+
<literal>walsender</literal>, <literal>walsummarizer</literal>, and
7020+
<literal>walwriter</literal>.
7021+
Valid <literal>LEVEL</literal> values are <literal>DEBUG5</literal>,
7022+
<literal>DEBUG4</literal>, <literal>DEBUG3</literal>, <literal>DEBUG2</literal>,
7023+
<literal>DEBUG1</literal>, <literal>INFO</literal>, <literal>NOTICE</literal>,
7024+
<literal>WARNING</literal>, <literal>ERROR</literal>, <literal>LOG</literal>,
7025+
<literal>FATAL</literal>, and <literal>PANIC</literal>. Each level includes
7026+
all the levels that follow it. The later the level, the fewer messages are sent
7027+
to the log. The single <literal>LEVEL</literal> is mandatory and it is
7028+
assigned to the backend types that are not specified in the list. The
7029+
default is <literal>WARNING</literal> for all backend types.
7030+
Note that <literal>LOG</literal> has a different rank here than in
70197031
<xref linkend="guc-client-min-messages"/>.
70207032
Only superusers and users with the appropriate <literal>SET</literal>
70217033
privilege can change this setting.

src/backend/commands/extension.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1145,7 +1145,7 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control,
11451145
(void) set_config_option("client_min_messages", "warning",
11461146
PGC_USERSET, PGC_S_SESSION,
11471147
GUC_ACTION_SAVE, true, 0, false);
1148-
if (log_min_messages < WARNING)
1148+
if (log_min_messages[MyBackendType] < WARNING)
11491149
(void) set_config_option_ext("log_min_messages", "warning",
11501150
PGC_SUSET, PGC_S_SESSION,
11511151
BOOTSTRAP_SUPERUSERID,

src/backend/commands/variable.c

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "utils/datetime.h"
3636
#include "utils/fmgrprotos.h"
3737
#include "utils/guc_hooks.h"
38+
#include "utils/guc_tables.h"
3839
#include "utils/snapmgr.h"
3940
#include "utils/syscache.h"
4041
#include "utils/timestamp.h"
@@ -1257,3 +1258,189 @@ check_ssl(bool *newval, void **extra, GucSource source)
12571258
#endif
12581259
return true;
12591260
}
1261+
1262+
/*
1263+
* GUC check_hook for log_min_messages
1264+
*
1265+
* The parsing consists of a comma-separated list of BACKENDTYPENAME:LEVEL
1266+
* elements. BACKENDTYPENAME is log_min_messages_backend_types. LEVEL is
1267+
* server_message_level_options. A single LEVEL element should be part of this
1268+
* list and it is applied as a final step to the backend types that are not
1269+
* specified. For backward compatibility, the old syntax is still accepted and
1270+
* it means to apply this level for all backend types.
1271+
*/
1272+
bool
1273+
check_log_min_messages(char **newval, void **extra, GucSource source)
1274+
{
1275+
char *rawstring;
1276+
List *elemlist;
1277+
ListCell *l;
1278+
int newlevels[BACKEND_NUM_TYPES];
1279+
bool assigned[BACKEND_NUM_TYPES];
1280+
int genericlevel = -1; /* -1 means not assigned */
1281+
1282+
/* Initialize the array. */
1283+
memset(newlevels, WARNING, BACKEND_NUM_TYPES * sizeof(int));
1284+
memset(assigned, false, BACKEND_NUM_TYPES * sizeof(bool));
1285+
1286+
/* Need a modifiable copy of string. */
1287+
rawstring = pstrdup(*newval);
1288+
1289+
/* Parse string into list of identifiers. */
1290+
if (!SplitGUCList(rawstring, ',', &elemlist))
1291+
{
1292+
/* syntax error in list */
1293+
GUC_check_errdetail("List syntax is invalid.");
1294+
pfree(rawstring);
1295+
list_free(elemlist);
1296+
return false;
1297+
}
1298+
1299+
/* Validate and assign log level and backend type. */
1300+
foreach(l, elemlist)
1301+
{
1302+
char *tok = (char *) lfirst(l);
1303+
char *sep;
1304+
const struct config_enum_entry *entry;
1305+
1306+
/*
1307+
* Check whether there is a backend type following the log level. If
1308+
* there is no separator, it means this log level should be applied
1309+
* for all backend types (backward compatibility).
1310+
*/
1311+
sep = strchr(tok, ':');
1312+
if (sep == NULL)
1313+
{
1314+
bool found = false;
1315+
1316+
/* Reject duplicates for generic log level. */
1317+
if (genericlevel != -1)
1318+
{
1319+
GUC_check_errdetail("Generic log level was already assigned.");
1320+
pfree(rawstring);
1321+
list_free(elemlist);
1322+
return false;
1323+
}
1324+
1325+
/* Is the log level valid? */
1326+
for (entry = server_message_level_options; entry && entry->name; entry++)
1327+
{
1328+
if (pg_strcasecmp(entry->name, tok) == 0)
1329+
{
1330+
genericlevel = entry->val;
1331+
found = true;
1332+
break;
1333+
}
1334+
}
1335+
1336+
if (!found)
1337+
{
1338+
GUC_check_errdetail("Unrecognized log level: \"%s\".", tok);
1339+
pfree(rawstring);
1340+
list_free(elemlist);
1341+
return false;
1342+
}
1343+
}
1344+
else
1345+
{
1346+
char *loglevel;
1347+
char *btype;
1348+
bool found = false;
1349+
1350+
btype = palloc((sep - tok) + 1);
1351+
memcpy(btype, tok, sep - tok);
1352+
btype[sep - tok] = '\0';
1353+
loglevel = pstrdup(sep + 1);
1354+
1355+
/* Is the log level valid? */
1356+
for (entry = server_message_level_options; entry && entry->name; entry++)
1357+
{
1358+
if (pg_strcasecmp(entry->name, loglevel) == 0)
1359+
{
1360+
found = true;
1361+
break;
1362+
}
1363+
}
1364+
1365+
if (!found)
1366+
{
1367+
GUC_check_errdetail("Unrecognized log level: \"%s\".", loglevel);
1368+
pfree(rawstring);
1369+
list_free(elemlist);
1370+
return false;
1371+
}
1372+
1373+
/*
1374+
* Is the backend type name valid? There might be multiple entries
1375+
* per backend type, don't bail out when find first occurrence.
1376+
*/
1377+
found = false;
1378+
for (int i = 0; i < BACKEND_NUM_TYPES; i++)
1379+
{
1380+
if (pg_strcasecmp(log_min_messages_backend_types[i], btype) == 0)
1381+
{
1382+
newlevels[i] = entry->val;
1383+
assigned[i] = true;
1384+
found = true;
1385+
}
1386+
}
1387+
1388+
if (!found)
1389+
{
1390+
GUC_check_errdetail("Unrecognized backend type: \"%s\".", btype);
1391+
pfree(rawstring);
1392+
list_free(elemlist);
1393+
return false;
1394+
}
1395+
}
1396+
}
1397+
1398+
/*
1399+
* Generic log level must be specified. It is a good idea to specify a
1400+
* generic log level to make it clear that it is the fallback value.
1401+
* Although, we can document it, it might confuse users that used to
1402+
* specify a single log level in prior releases.
1403+
*/
1404+
if (genericlevel == -1)
1405+
{
1406+
GUC_check_errdetail("Generic log level was not defined.");
1407+
pfree(rawstring);
1408+
list_free(elemlist);
1409+
return false;
1410+
}
1411+
1412+
/*
1413+
* Apply the generic log level (the one without a backend type) after all
1414+
* of the specific backend type have been assigned. Hence, it doesn't
1415+
* matter the order you specify the generic log level, the final result
1416+
* will be the same.
1417+
*/
1418+
for (int i = 0; i < BACKEND_NUM_TYPES; i++)
1419+
{
1420+
if (!assigned[i])
1421+
newlevels[i] = genericlevel;
1422+
}
1423+
1424+
pfree(rawstring);
1425+
list_free(elemlist);
1426+
1427+
/*
1428+
* Pass back data for assign_log_min_messages to use.
1429+
*/
1430+
*extra = guc_malloc(LOG, BACKEND_NUM_TYPES * sizeof(int));
1431+
if (!*extra)
1432+
return false;
1433+
memcpy(*extra, newlevels, BACKEND_NUM_TYPES * sizeof(int));
1434+
1435+
return true;
1436+
}
1437+
1438+
/*
1439+
* GUC assign_hook for log_min_messages
1440+
*/
1441+
void
1442+
assign_log_min_messages(const char *newval, void *extra)
1443+
{
1444+
for (int i = 0; i < BACKEND_NUM_TYPES; i++)
1445+
log_min_messages[i] = ((int *) extra)[i];
1446+
}

src/backend/utils/error/elog.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ is_log_level_output(int elevel, int log_min_level)
235235
static inline bool
236236
should_output_to_server(int elevel)
237237
{
238-
return is_log_level_output(elevel, log_min_messages);
238+
return is_log_level_output(elevel, log_min_messages[MyBackendType]);
239239
}
240240

241241
/*

src/backend/utils/misc/guc_tables.c

Lines changed: 68 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ static const struct config_enum_entry client_message_level_options[] = {
146146
{NULL, 0, false}
147147
};
148148

149-
static const struct config_enum_entry server_message_level_options[] = {
149+
const struct config_enum_entry server_message_level_options[] = {
150150
{"debug5", DEBUG5, false},
151151
{"debug4", DEBUG4, false},
152152
{"debug3", DEBUG3, false},
@@ -536,7 +536,6 @@ static bool default_with_oids = false;
536536
bool current_role_is_superuser;
537537

538538
int log_min_error_statement = ERROR;
539-
int log_min_messages = WARNING;
540539
int client_min_messages = NOTICE;
541540
int log_min_duration_sample = -1;
542541
int log_min_duration_statement = -1;
@@ -594,6 +593,7 @@ static char *server_version_string;
594593
static int server_version_num;
595594
static char *debug_io_direct_string;
596595
static char *restrict_nonsystem_relation_kind_string;
596+
static char *log_min_messages_string;
597597

598598
#ifdef HAVE_SYSLOG
599599
#define DEFAULT_SYSLOG_FACILITY LOG_LOCAL0
@@ -638,6 +638,60 @@ char *role_string;
638638
/* should be static, but guc.c needs to get at this */
639639
bool in_hot_standby_guc;
640640

641+
/*
642+
* This must match enum BackendType! It should be static, but
643+
* commands/variable.c needs to get at this.
644+
*/
645+
int log_min_messages[] = {
646+
[B_INVALID] = WARNING,
647+
[B_BACKEND] = WARNING,
648+
[B_DEAD_END_BACKEND] = WARNING,
649+
[B_AUTOVAC_LAUNCHER] = WARNING,
650+
[B_AUTOVAC_WORKER] = WARNING,
651+
[B_BG_WORKER] = WARNING,
652+
[B_WAL_SENDER] = WARNING,
653+
[B_SLOTSYNC_WORKER] = WARNING,
654+
[B_STANDALONE_BACKEND] = WARNING,
655+
[B_ARCHIVER] = WARNING,
656+
[B_BG_WRITER] = WARNING,
657+
[B_CHECKPOINTER] = WARNING,
658+
[B_STARTUP] = WARNING,
659+
[B_WAL_RECEIVER] = WARNING,
660+
[B_WAL_SUMMARIZER] = WARNING,
661+
[B_WAL_WRITER] = WARNING,
662+
[B_LOGGER] = WARNING,
663+
};
664+
665+
StaticAssertDecl(lengthof(log_min_messages) == BACKEND_NUM_TYPES,
666+
"array length mismatch");
667+
668+
/*
669+
* This must match enum BackendType! It might be in commands/variable.c but for
670+
* convenience it is near log_min_messages.
671+
*/
672+
const char *const log_min_messages_backend_types[] = {
673+
[B_INVALID] = "backend", /* XXX same as backend? */
674+
[B_BACKEND] = "backend",
675+
[B_DEAD_END_BACKEND] = "backend", /* XXX same as backend? */
676+
[B_AUTOVAC_LAUNCHER] = "autovacuum",
677+
[B_AUTOVAC_WORKER] = "autovacuum",
678+
[B_BG_WORKER] = "bgworker",
679+
[B_WAL_SENDER] = "walsender",
680+
[B_SLOTSYNC_WORKER] = "slotsyncworker",
681+
[B_STANDALONE_BACKEND] = "backend", /* XXX same as backend? */
682+
[B_ARCHIVER] = "archiver",
683+
[B_BG_WRITER] = "bgwriter",
684+
[B_CHECKPOINTER] = "checkpointer",
685+
[B_STARTUP] = "backend", /* XXX same as backend? */
686+
[B_WAL_RECEIVER] = "walreceiver",
687+
[B_WAL_SUMMARIZER] = "walsummarizer",
688+
[B_WAL_WRITER] = "walwriter",
689+
[B_LOGGER] = "logger",
690+
};
691+
692+
StaticAssertDecl(lengthof(log_min_messages_backend_types) == BACKEND_NUM_TYPES,
693+
"array length mismatch");
694+
641695

642696
/*
643697
* Displayable names for context types (enum GucContext)
@@ -4298,6 +4352,18 @@ struct config_string ConfigureNamesString[] =
42984352
check_client_encoding, assign_client_encoding, NULL
42994353
},
43004354

4355+
{
4356+
{"log_min_messages", PGC_SUSET, LOGGING_WHEN,
4357+
gettext_noop("Sets the message levels that are logged."),
4358+
gettext_noop("Each level includes all the levels that follow it. The later"
4359+
" the level, the fewer messages are sent."),
4360+
GUC_LIST_INPUT
4361+
},
4362+
&log_min_messages_string,
4363+
"WARNING",
4364+
check_log_min_messages, assign_log_min_messages, NULL
4365+
},
4366+
43014367
{
43024368
{"log_line_prefix", PGC_SIGHUP, LOGGING_WHAT,
43034369
gettext_noop("Controls information prefixed to each log line."),
@@ -5110,17 +5176,6 @@ struct config_enum ConfigureNamesEnum[] =
51105176
NULL, NULL, NULL
51115177
},
51125178

5113-
{
5114-
{"log_min_messages", PGC_SUSET, LOGGING_WHEN,
5115-
gettext_noop("Sets the message levels that are logged."),
5116-
gettext_noop("Each level includes all the levels that follow it. The later"
5117-
" the level, the fewer messages are sent.")
5118-
},
5119-
&log_min_messages,
5120-
WARNING, server_message_level_options,
5121-
NULL, NULL, NULL
5122-
},
5123-
51245179
{
51255180
{"log_min_error_statement", PGC_SUSET, LOGGING_WHEN,
51265181
gettext_noop("Causes all statements generating error at or above this level to be logged."),

src/backend/utils/misc/postgresql.conf.sample

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,7 @@
543543
# log
544544
# fatal
545545
# panic
546+
# or a comma-separated list of backend_type:level
546547

547548
#log_min_error_statement = error # values in order of decreasing detail:
548549
# debug5

src/include/miscadmin.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,8 @@ extern void SwitchBackToLocalLatch(void);
333333
*
334334
* If you add entries, please also update the child_process_kinds array in
335335
* launch_backend.c.
336+
* XXX If you add a new backend type or change the order, update
337+
* log_min_messages because it relies on this order to work correctly.
336338
*/
337339
typedef enum BackendType
338340
{

0 commit comments

Comments
 (0)