*** ./contrib/gdlogger/gdlogger.c.orig 2015-10-22 12:03:36.910858470 +0200 --- ./contrib/gdlogger/gdlogger.c 2015-10-22 12:03:14.796733274 +0200 *************** *** 0 **** --- 1,225 ---- + /*------------------------------------------------------------------------- + * + * gdlogger.c + * + * + * Copyright (c) 2008-2012, PostgreSQL Global Development Group + * + * IDENTIFICATION + * contrib/gdlogger/gdlogger.c + * + *------------------------------------------------------------------------- + */ + #include "postgres.h" + + #include "fmgr.h" + #include "miscadmin.h" + + #include "catalog/pg_type.h" + #include "commands/dbcommands.h" + #include "storage/lwlock.h" + #include "storage/ipc.h" + #include "storage/shmem.h" + #include "storage/spin.h" + #include "utils/builtins.h" + #include "utils/elog.h" + #include "utils/guc.h" + #include "utils/lsyscache.h" + #include "utils/resowner.h" + + #include + + PG_MODULE_MAGIC; + + typedef struct + { + slock_t mutex; /* protects output to syslog */ + } gdloggerData; + + gdloggerData *logger = NULL; + + emit_log_hook_type previous_log_hook = NULL; + static shmem_startup_hook_type prev_shmem_startup_hook = NULL; + + bool initialized = false; + + void _PG_init(void); + void _PG_fini(void); + + static void gdlogger(ErrorData *edata); + static void gdlogger_shmem_startup(void); + + static FmgrInfo inet_output; + Oid inet_output_func = InvalidOid; + + /* + * Module load callback + */ + void + _PG_init(void) + { + EmitWarningsOnPlaceholders("gdlogger"); + + /* + * Request additional shared resources. (These are no-ops if we're not in + * the postmaster process.) We'll allocate or attach to the shared + * resources in pgss_shmem_startup(). + */ + RequestAddinShmemSpace(sizeof(gdloggerData)); + RequestAddinLWLocks(1); + + /* + * Install hooks. + */ + prev_shmem_startup_hook = shmem_startup_hook; + shmem_startup_hook = gdlogger_shmem_startup; + previous_log_hook = emit_log_hook; + emit_log_hook = gdlogger; + + initialized = true; + } + + static void + gdlogger_shmem_startup(void) + { + bool found; + + if (prev_shmem_startup_hook) + prev_shmem_startup_hook(); + + /* + * Create or attach to the shared memory state, including hash table + */ + LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE); + + logger = ShmemInitStruct("gdlogger", + sizeof(gdloggerData), + &found); + + if (!found) + SpinLockInit(&logger->mutex); + + LWLockRelease(AddinShmemInitLock); + } + + /* + * Module unload callback + */ + void + _PG_fini(void) + { + shmem_startup_hook = prev_shmem_startup_hook; + emit_log_hook = previous_log_hook; + previous_log_hook = NULL; + } + + /* + * puts lines to syslog + * + */ + static void + syslog_fputs(int facility, char *lines) + { + char *str = pstrdup(lines); + char *line = str; + + while (1) + { + char *ptr = line; + + while (*ptr != '\0' && *ptr != '\n') + ptr++; + + if (*ptr == '\n') + { + *ptr = '\0'; + syslog(facility, "\t %s", line); + line = ptr + 1; + } + else + { + syslog(facility, "\t %s", line); + break; + } + } + + pfree(str); + } + + /* + * change facility for slow query + * 1 -- slow query statement + * 2 -- slow query plan (result of autoexplain) + * + */ + static void + gdlogger(ErrorData *edata) + { + if (previous_log_hook) + previous_log_hook(edata); + + if (edata->message != NULL && strncmp(edata->message, "duration: ", 9) == 0) + { + ResourceOwner local_res_owner = NULL; + Datum client_addr; + char *client_addr_str = NULL; + FunctionCallInfoData fcinfo; + char *database_name; + + if (CurrentResourceOwner == NULL) + { + local_res_owner = ResourceOwnerCreate(NULL, "fakeres"); + CurrentResourceOwner = local_res_owner; + } + + if (!OidIsValid(inet_output_func)) + { + bool is_varlena; + + getTypeOutputInfo(INETOID, &inet_output_func, &is_varlena); + fmgr_info(inet_output_func, &inet_output); + } + + InitFunctionCallInfoData(fcinfo, NULL, 0, InvalidOid, NULL, NULL); + client_addr = (*inet_client_addr) (&fcinfo); + if (!fcinfo.isnull) + client_addr_str = OutputFunctionCall(&inet_output, client_addr); + + database_name = get_database_name(MyDatabaseId); + + SpinLockAcquire(&logger->mutex); + + if (strcmp(edata->filename, "auto_explain.c") == 0) + { + syslog(LOG_LOCAL2, "auto_explain database=%s client=%s appname=%s", + database_name ? database_name : "NULL", + client_addr_str ? client_addr_str : "local", + application_name); + syslog_fputs(LOG_LOCAL2, edata->message); + } + else + { + syslog(LOG_LOCAL1, "slow_query database=%s client=%s appname=%s", + database_name ? database_name : "NULL", + client_addr_str ? client_addr_str : "local", + application_name); + syslog_fputs(LOG_LOCAL1, edata->message); + } + + SpinLockRelease(&logger->mutex); + + if (local_res_owner != NULL) + { + CurrentResourceOwner = NULL; + ResourceOwnerDelete(local_res_owner); + } + + if (client_addr_str != NULL) + pfree(client_addr_str); + + if (database_name != NULL) + pfree(database_name); + + edata->output_to_server = false; + } + } *** ./contrib/gdlogger/Makefile.orig 2015-10-22 12:03:42.493890078 +0200 --- ./contrib/gdlogger/Makefile 2015-10-22 12:03:14.796733274 +0200 *************** *** 0 **** --- 1,15 ---- + # contrib/gdlogger/Makefile + + MODULE_big = gdlogger + OBJS = gdlogger.o + + ifdef USE_PGXS + PG_CONFIG = pg_config + PGXS := $(shell $(PG_CONFIG) --pgxs) + include $(PGXS) + else + subdir = contrib/gdlogger + top_builddir = ../.. + include $(top_builddir)/src/Makefile.global + include $(top_srcdir)/contrib/contrib-global.mk + endif *** ./contrib/Makefile.orig 2015-10-22 11:56:03.450690007 +0200 --- ./contrib/Makefile 2015-10-22 12:03:14.797733279 +0200 *************** *** 19,24 **** --- 19,25 ---- earthdistance \ file_fdw \ fuzzystrmatch \ + gdlogger \ hstore \ intagg \ intarray \