From 19dbc3463161a142537ba5c569c8e6a073a318de Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 6 Mar 2012 15:35:41 -0500 Subject: [PATCH] Add a hook for processing messages due to be sent to the server log. Use-cases for this include custom log filtering rules and custom log message transmission mechanisms (for instance, lossy log message collection, which has been discussed several times recently). As is our common practice for hooks, there's no regression test nor user-facing documentation for this, though the author did exhibit a sample module using the hook. Martin Pihlak, reviewed by Marti Raudsepp --- src/backend/utils/error/elog.c | 26 ++++++++++++++++++++++++++ src/include/utils/elog.h | 4 ++++ 2 files changed, 30 insertions(+) diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index 470081a180..239ac19882 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -95,6 +95,15 @@ sigjmp_buf *PG_exception_stack = NULL; extern bool redirection_done; +/* + * Hook for intercepting messages before they are sent to the server log. + * Note that the hook will not get called for messages that are suppressed + * by log_min_messages. Also note that logging hooks implemented in preload + * libraries will miss any log messages that are generated before the + * library is loaded. + */ +emit_log_hook_type emit_log_hook = NULL; + /* GUC parameters */ int Log_error_verbosity = PGERROR_VERBOSE; char *Log_line_prefix = NULL; /* format for extra log line info */ @@ -1276,6 +1285,23 @@ EmitErrorReport(void) CHECK_STACK_DEPTH(); oldcontext = MemoryContextSwitchTo(ErrorContext); + /* + * Call hook before sending message to log. The hook function is allowed + * to turn off edata->output_to_server, so we must recheck that afterward. + * Making any other change in the content of edata is not considered + * supported. + * + * Note: the reason why the hook can only turn off output_to_server, and + * not turn it on, is that it'd be unreliable: we will never get here at + * all if errstart() deems the message uninteresting. A hook that could + * make decisions in that direction would have to hook into errstart(), + * where it would have much less information available. emit_log_hook is + * intended for custom log filtering and custom log message transmission + * mechanisms. + */ + if (edata->output_to_server && emit_log_hook) + (*emit_log_hook) (edata); + /* Send to server log, if enabled */ if (edata->output_to_server) send_message_to_server_log(edata); diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h index fbc08df7de..7b5bcfae6f 100644 --- a/src/include/utils/elog.h +++ b/src/include/utils/elog.h @@ -334,6 +334,10 @@ extern void FlushErrorState(void); extern void ReThrowError(ErrorData *edata); extern void pg_re_throw(void) __attribute__((noreturn)); +/* Hook for intercepting messages before they are sent to the server log */ +typedef void (*emit_log_hook_type) (ErrorData *edata); +extern PGDLLIMPORT emit_log_hook_type emit_log_hook; + /* GUC-configurable parameters */