diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index bbddbe59039d09d3fa87ee2e06ce563f41c52266..d3f09f6376948fc61cb05e8b026eb69078cfb916 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -1,4 +1,4 @@ -<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.112 2007/02/16 16:37:29 tgl Exp $ --> +<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.113 2007/03/02 23:37:22 tgl Exp $ --> <chapter Id="runtime-config"> <title>Server Configuration</title> @@ -2507,9 +2507,10 @@ SELECT * FROM parent WHERE key = 2400; <literal>DEBUG2</literal>, <literal>DEBUG1</literal>, <literal>INFO</literal>, <literal>NOTICE</literal>, <literal>WARNING</literal>, <literal>ERROR</literal>, + <literal>LOG</literal>, <literal>FATAL</literal>, and <literal>PANIC</literal>. The default is <literal>ERROR</literal>, which means statements - causing errors, fatal errors, or panics will be logged. + causing errors, log messages, fatal errors, or panics will be logged. To effectively turn off logging of failing statements, set this parameter to <literal>PANIC</literal>. Only superusers can change this setting. diff --git a/doc/src/sgml/sources.sgml b/doc/src/sgml/sources.sgml index 873ba6b2f257f1d0ae84400c27e700a403cbbb9d..5d9043a16a7b72ce008e4d66b2981a01d9dd5b15 100644 --- a/doc/src/sgml/sources.sgml +++ b/doc/src/sgml/sources.sgml @@ -1,4 +1,4 @@ -<!-- $PostgreSQL: pgsql/doc/src/sgml/sources.sgml,v 2.27 2007/02/01 22:06:14 tgl Exp $ --> +<!-- $PostgreSQL: pgsql/doc/src/sgml/sources.sgml,v 2.28 2007/03/02 23:37:22 tgl Exp $ --> <chapter id="source"> <title>PostgreSQL Coding Conventions</title> @@ -206,6 +206,14 @@ ereport(ERROR, socket-related system call. </para> </listitem> + <listitem> + <para> + <function>errhidestmt(bool hide_stmt)</function> can be called to specify + suppression of the <literal>STATEMENT:</> portion of a message in the + postmaster log. Generally this is appropriate if the message text + includes the current statement already. + </para> + </listitem> </itemizedlist> </para> diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 1c40a8752e953e34e2f23924b679676ebf4bbacf..afb6b4db0a1e8ffbe7bceb973da8e14351bdf9f3 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.525 2007/02/20 17:32:16 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.526 2007/03/02 23:37:22 tgl Exp $ * * NOTES * this is the "main" module of the postgres backend and @@ -823,6 +823,7 @@ exec_simple_query(const char *query_string) { ereport(LOG, (errmsg("statement: %s", query_string), + errhidestmt(true), errdetail_execute(parsetree_list))); was_logged = true; } @@ -1020,12 +1021,14 @@ exec_simple_query(const char *query_string) { case 1: ereport(LOG, - (errmsg("duration: %s ms", msec_str))); + (errmsg("duration: %s ms", msec_str), + errhidestmt(true))); break; case 2: ereport(LOG, (errmsg("duration: %s ms statement: %s", msec_str, query_string), + errhidestmt(true), errdetail_execute(parsetree_list))); break; } @@ -1281,14 +1284,16 @@ exec_parse_message(const char *query_string, /* string to execute */ { case 1: ereport(LOG, - (errmsg("duration: %s ms", msec_str))); + (errmsg("duration: %s ms", msec_str), + errhidestmt(true))); break; case 2: ereport(LOG, (errmsg("duration: %s ms parse %s: %s", msec_str, *stmt_name ? stmt_name : "<unnamed>", - query_string))); + query_string), + errhidestmt(true))); break; } @@ -1635,7 +1640,8 @@ exec_bind_message(StringInfo input_message) { case 1: ereport(LOG, - (errmsg("duration: %s ms", msec_str))); + (errmsg("duration: %s ms", msec_str), + errhidestmt(true))); break; case 2: ereport(LOG, @@ -1645,6 +1651,7 @@ exec_bind_message(StringInfo input_message) *portal_name ? "/" : "", *portal_name ? portal_name : "", pstmt->query_string ? pstmt->query_string : "<source not stored>"), + errhidestmt(true), errdetail_params(params))); break; } @@ -1778,6 +1785,7 @@ exec_execute_message(const char *portal_name, long max_rows) *portal_name ? portal_name : "", sourceText ? ": " : "", sourceText ? sourceText : ""), + errhidestmt(true), errdetail_params(portalParams))); was_logged = true; } @@ -1846,7 +1854,8 @@ exec_execute_message(const char *portal_name, long max_rows) { case 1: ereport(LOG, - (errmsg("duration: %s ms", msec_str))); + (errmsg("duration: %s ms", msec_str), + errhidestmt(true))); break; case 2: ereport(LOG, @@ -1860,6 +1869,7 @@ exec_execute_message(const char *portal_name, long max_rows) *portal_name ? portal_name : "", sourceText ? ": " : "", sourceText ? sourceText : ""), + errhidestmt(true), errdetail_params(portalParams))); break; } diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index 3700c4ecdc08741e1777b0d6ad3d5c3e78fe0f47..c76d817bb1464c122a99696ea5853867e6622406 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -42,7 +42,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.182 2007/02/11 11:59:26 mha Exp $ + * $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.183 2007/03/02 23:37:23 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -731,6 +731,25 @@ errcontext(const char *fmt,...) } +/* + * errhidestmt --- optionally suppress STATEMENT: field of log entry + * + * This should be called if the message text already includes the statement. + */ +int +errhidestmt(bool hide_stmt) +{ + ErrorData *edata = &errordata[errordata_stack_depth]; + + /* we don't bother incrementing recursion_depth */ + CHECK_STACK_DEPTH(); + + edata->hide_stmt = hide_stmt; + + return 0; /* return value does not matter */ +} + + /* * errfunction --- add reporting function name to the current error * @@ -1629,7 +1648,9 @@ send_message_to_server_log(ErrorData *edata) /* * If the user wants the query that generated this error logged, do it. */ - if (edata->elevel >= log_min_error_statement && debug_query_string != NULL) + if (is_log_level_output(edata->elevel, log_min_error_statement) && + debug_query_string != NULL && + !edata->hide_stmt) { log_line_prefix(&buf); appendStringInfoString(&buf, _("STATEMENT: ")); @@ -2046,7 +2067,7 @@ write_stderr(const char *fmt,...) vsnprintf(errbuf, sizeof(errbuf), fmt, ap); - write_eventlog(EVENTLOG_ERROR_TYPE, errbuf); + write_eventlog(ERROR, errbuf); } else /* Not running as service, write to stderr */ @@ -2055,13 +2076,18 @@ write_stderr(const char *fmt,...) va_end(ap); } + +/* + * is_log_level_output -- is elevel logically >= log_min_level? + * + * We use this for tests that should consider LOG to sort out-of-order, + * between ERROR and FATAL. Generally this is the right thing for testing + * whether a message should go to the postmaster log, whereas a simple >= + * test is correct for testing whether the message should go to the client. + */ static bool is_log_level_output(int elevel, int log_min_level) { - /* - * Complicated because LOG is sorted out-of-order here, between - * ERROR and FATAL. - */ if (elevel == LOG || elevel == COMMERROR) { if (log_min_level == LOG || log_min_level <= ERROR) diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index 703f5cbaa3324b01fae40dd6d8ffa35cf712fc62..77a86f0020b3b5551cb7c0a5aa61c46c23ffbb70 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -262,7 +262,7 @@ # - When to Log - -#client_min_messages = notice # Values, in order of decreasing detail: +#client_min_messages = notice # Values in order of decreasing detail: # debug5 # debug4 # debug3 @@ -273,7 +273,7 @@ # warning # error -#log_min_messages = notice # Values, in order of decreasing detail: +#log_min_messages = notice # Values in order of decreasing detail: # debug5 # debug4 # debug3 @@ -289,7 +289,7 @@ #log_error_verbosity = default # terse, default, or verbose messages -#log_min_error_statement = error # Values in order of increasing severity: +#log_min_error_statement = error # Values in order of decreasing detail: # debug5 # debug4 # debug3 @@ -299,11 +299,14 @@ # notice # warning # error + # log # fatal # panic (effectively off) #log_min_duration_statement = -1 # -1 is disabled, 0 logs all statements - # and their durations. + # and their durations, > 0 logs only + # statements running at least N msec. + #silent_mode = off # DO NOT USE without syslog or # redirect_stderr diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h index 8d835d30ef5c8bf5e148a3a9754145a14efb5d48..86fd4deb9eab74a5a5481ca3a0decd6d122784f4 100644 --- a/src/include/utils/elog.h +++ b/src/include/utils/elog.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/utils/elog.h,v 1.83 2007/01/05 22:19:59 momjian Exp $ + * $PostgreSQL: pgsql/src/include/utils/elog.h,v 1.84 2007/03/02 23:37:23 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -137,6 +137,8 @@ errcontext(const char *fmt,...) the supplied arguments. */ __attribute__((format(printf, 1, 2))); +extern int errhidestmt(bool hide_stmt); + extern int errfunction(const char *funcname); extern int errposition(int cursorpos); @@ -240,6 +242,7 @@ typedef struct ErrorData bool output_to_server; /* will report to server log? */ bool output_to_client; /* will report to client? */ bool show_funcname; /* true to force funcname inclusion */ + bool hide_stmt; /* true to prevent STATEMENT: inclusion */ const char *filename; /* __FILE__ of ereport() call */ int lineno; /* __LINE__ of ereport() call */ const char *funcname; /* __func__ of ereport() call */