Re: [HACKERS] serverlog function (log_destination file) - Mailing list pgsql-patches
From | Bruce Momjian |
---|---|
Subject | Re: [HACKERS] serverlog function (log_destination file) |
Date | |
Msg-id | 200406100410.i5A4Ach14360@candle.pha.pa.us Whole thread Raw |
In response to | Re: [HACKERS] serverlog function (log_destination file) (Andreas Pflug <pgadmin@pse-consulting.de>) |
Responses |
Re: [HACKERS] serverlog function (log_destination file)
|
List | pgsql-patches |
Looks good to me. The only issue I saw was that the default file name mentioned in postgresql.conf doesn't match the actual default. Is this ready to be added to the patch queue? --------------------------------------------------------------------------- Andreas Pflug wrote: > Magnus Hagander wrote: > > >Specifically about the logs, I still think there is a lot of value to > >being able to read the logs remotely even if you can't restart > >postmaster. > > > Since I believe that retrieving the logs easily without server file > access is a feature that's welcomed by many users, here's my proposal. > > The attached diff will > - add a guc-variable log_filename > - extend log_destination to accept the keyword 'file' > - elog to that file if configured > - provide two functions pg_logfile_length() and pg_logfile to obtain the > contents. > > int4 pg_logfile_length() > cstring pg_logfile(int4 size, int4 position) > size (may be null meaning max) is the chunk size (max: currently 50000) > position (may be null meaning -size) is the start position; positive > counting from log file start, negative from end. > > > Regards, > Andreas > > Index: backend/postmaster/postmaster.c > =================================================================== > RCS file: /projects/cvsroot/pgsql-server/src/backend/postmaster/postmaster.c,v > retrieving revision 1.402 > diff -u -r1.402 postmaster.c > --- backend/postmaster/postmaster.c 3 Jun 2004 02:08:03 -0000 1.402 > +++ backend/postmaster/postmaster.c 8 Jun 2004 18:07:30 -0000 > @@ -532,6 +532,9 @@ > /* If timezone is not set, determine what the OS uses */ > pg_timezone_initialize(); > > + /* open alternate logfile, if any */ > + LogFileOpen(); > + > #ifdef EXEC_BACKEND > write_nondefault_variables(PGC_POSTMASTER); > #endif > Index: backend/storage/ipc/ipc.c > =================================================================== > RCS file: /projects/cvsroot/pgsql-server/src/backend/storage/ipc/ipc.c,v > retrieving revision 1.87 > diff -u -r1.87 ipc.c > --- backend/storage/ipc/ipc.c 12 Dec 2003 18:45:09 -0000 1.87 > +++ backend/storage/ipc/ipc.c 8 Jun 2004 18:07:31 -0000 > @@ -111,6 +111,8 @@ > on_proc_exit_list[on_proc_exit_index].arg); > > elog(DEBUG3, "exit(%d)", code); > + > + LogFileClose(); > exit(code); > } > > Index: backend/utils/adt/misc.c > =================================================================== > RCS file: /projects/cvsroot/pgsql-server/src/backend/utils/adt/misc.c,v > retrieving revision 1.34 > diff -u -r1.34 misc.c > --- backend/utils/adt/misc.c 2 Jun 2004 21:29:29 -0000 1.34 > +++ backend/utils/adt/misc.c 8 Jun 2004 18:07:36 -0000 > @@ -103,3 +103,64 @@ > { > PG_RETURN_INT32(pg_signal_backend(PG_GETARG_INT32(0),SIGINT)); > } > + > +Datum pg_logfile_length(PG_FUNCTION_ARGS) > +{ > + extern FILE *logfile; // in elog.c > + > + if (logfile) > + PG_RETURN_INT32(ftell(logfile)); > + PG_RETURN_INT32(0); > +} > + > + > +#define MAXLOGFILECHUNK 50000 > +Datum pg_logfile(PG_FUNCTION_ARGS) > +{ > + size_t size=MAXLOGFILECHUNK; > + char *buf=0; > + size_t nbytes; > + > + char *filename = LogFileName(); > + if (filename) > + { > + if (!PG_ARGISNULL(0)) > + size = PG_GETARG_INT32(0); > + if (size > MAXLOGFILECHUNK) > + { > + size = MAXLOGFILECHUNK; > + ereport(WARNING, > + (errcode(ERRCODE_OUT_OF_MEMORY), > + errmsg("Maximum size is %d.", MAXLOGFILECHUNK))); > + } > + > + FILE *f=fopen(filename, "r"); > + if (f) > + { > + if (PG_ARGISNULL(1)) > + fseek(f, -size, SEEK_END); > + else > + { > + long pos = PG_GETARG_INT32(1); > + if (pos >= 0) > + fseek(f, pos, SEEK_SET); > + else > + fseek(f, pos, SEEK_END); > + } > + buf = palloc(size+1); > + nbytes = fread(buf, 1, size, f); > + buf[nbytes] = 0; > + > + fclose(f); > + } > + else > + { > + ereport(WARNING, > + (errcode(ERRCODE_NO_DATA), > + errmsg("Could not open log file %s.", filename))); > + } > + free(filename); > + } > + > + PG_RETURN_CSTRING(buf); > +} > Index: backend/utils/error/elog.c > =================================================================== > RCS file: /projects/cvsroot/pgsql-server/src/backend/utils/error/elog.c,v > retrieving revision 1.140 > diff -u -r1.140 elog.c > --- backend/utils/error/elog.c 3 Jun 2004 02:08:04 -0000 1.140 > +++ backend/utils/error/elog.c 8 Jun 2004 18:07:39 -0000 > @@ -71,8 +71,10 @@ > PGErrorVerbosity Log_error_verbosity = PGERROR_VERBOSE; > char *Log_line_prefix = NULL; /* format for extra log line info */ > unsigned int Log_destination = LOG_DESTINATION_STDERR; > +char *Log_filename = NULL; > > bool in_fatal_exit = false; > +FILE *logfile = NULL; > > #ifdef HAVE_SYSLOG > char *Syslog_facility; /* openlog() parameters */ > @@ -936,6 +938,69 @@ > > > /* > + * Name of configured log file, or NULL > + * must be freed after usage > + */ > +char* > +LogFileName(void) > +{ > + if (Log_filename && (Log_destination & LOG_DESTINATION_FILE)) > + { > + if (is_absolute_path(Log_filename)) > + return strdup(Log_filename); > + else > + { > + char *buf = malloc(strlen(DataDir) + strlen(Log_filename) +2); > + if (!buf) > + ereport(FATAL, > + (errcode(ERRCODE_OUT_OF_MEMORY), > + errmsg("out of memory"))); > + > + sprintf(buf, "%s/%s", DataDir, Log_filename); > + > + return buf; > + } > + } > + return NULL; > +} > + > + > +/* > + * Open log file, if configured. > + */ > +void > +LogFileOpen(void) > +{ > + char *filename = LogFileName(); > + > + if (filename) > + { > + LogFileClose(); > + > + logfile = fopen(filename, "at"); > + > + if (!logfile) > + ereport(WARNING, > + (errcode(ERRCODE_CONFIG_FILE_ERROR), > + errmsg("could not open log file %s", filename))); > + > + free(filename); > + } > +} > + > + > +/* > + * Close log file, if open. > + */ > +void > +LogFileClose(void) > +{ > + if (logfile) > + fclose(logfile); > + logfile = NULL; > +} > + > +/* > * Initialization of error output file > */ > void > @@ -1445,6 +1510,11 @@ > if ((Log_destination & LOG_DESTINATION_STDERR) || whereToSendOutput == Debug) > { > fprintf(stderr, "%s", buf.data); > + } > + > + if (logfile && (Log_destination & LOG_DESTINATION_FILE)) > + { > + fprintf(logfile, "%s", buf.data); > } > > pfree(buf.data); > Index: backend/utils/misc/guc.c > =================================================================== > RCS file: /projects/cvsroot/pgsql-server/src/backend/utils/misc/guc.c,v > retrieving revision 1.210 > diff -u -r1.210 guc.c > --- backend/utils/misc/guc.c 30 May 2004 23:40:38 -0000 1.210 > +++ backend/utils/misc/guc.c 8 Jun 2004 18:07:47 -0000 > @@ -76,6 +76,8 @@ > static const char *assign_log_destination(const char *value, > bool doit, GucSource source); > > +extern char *Log_filename; > + > #ifdef HAVE_SYSLOG > extern char *Syslog_facility; > extern char *Syslog_ident; > @@ -1644,13 +1646,23 @@ > { > {"log_destination", PGC_POSTMASTER, LOGGING_WHERE, > gettext_noop("Sets the target for log output."), > - gettext_noop("Valid values are combinations of stderr, syslog " > + gettext_noop("Valid values are combinations of stderr, file, syslog " > "and eventlog, depending on platform."), > GUC_LIST_INPUT | GUC_REPORT > }, > &log_destination_string, > "stderr", assign_log_destination, NULL > }, > + { > + {"log_filename", PGC_POSTMASTER, LOGGING_WHERE, > + gettext_noop("Sets the target filename for log output."), > + gettext_noop("May be specified as relative to the cluster directory " > + "or as absolute path."), > + GUC_LIST_INPUT | GUC_REPORT > + }, > + &Log_filename, > + "postgresql.log", NULL, NULL > + }, > > #ifdef HAVE_SYSLOG > { > @@ -4775,6 +4787,8 @@ > > if (pg_strcasecmp(tok,"stderr") == 0) > newlogdest |= LOG_DESTINATION_STDERR; > + else if (pg_strcasecmp(tok,"file") == 0) > + newlogdest |= LOG_DESTINATION_FILE; > #ifdef HAVE_SYSLOG > else if (pg_strcasecmp(tok,"syslog") == 0) > newlogdest |= LOG_DESTINATION_SYSLOG; > Index: backend/utils/misc/postgresql.conf.sample > =================================================================== > RCS file: /projects/cvsroot/pgsql-server/src/backend/utils/misc/postgresql.conf.sample,v > retrieving revision 1.113 > diff -u -r1.113 postgresql.conf.sample > --- backend/utils/misc/postgresql.conf.sample 7 Apr 2004 05:05:50 -0000 1.113 > +++ backend/utils/misc/postgresql.conf.sample 8 Jun 2004 18:07:48 -0000 > @@ -147,9 +147,10 @@ > > # - Where to Log - > > -#log_destination = 'stderr' # Valid values are combinations of stderr, > +#log_destination = 'stderr' # Valid values are combinations of stderr, file, > # syslog and eventlog, depending on > # platform. > +#log_filename = 'pgsql.log' > #syslog_facility = 'LOCAL0' > #syslog_ident = 'postgres' > > Index: include/catalog/pg_proc.h > =================================================================== > RCS file: /projects/cvsroot/pgsql-server/src/include/catalog/pg_proc.h,v > retrieving revision 1.334 > diff -u -r1.334 pg_proc.h > --- include/catalog/pg_proc.h 2 Jun 2004 21:29:29 -0000 1.334 > +++ include/catalog/pg_proc.h 8 Jun 2004 18:08:03 -0000 > @@ -3588,6 +3588,12 @@ > DATA(insert OID = 2243 ( bit_or PGNSP PGUID 12 t f f f i 1 1560 "1560" _null_ aggregate_dummy- _null_)); > DESCR("bitwise-or bit aggregate"); > > +DATA(insert OID = 2550( pg_logfile_length PGNSP PGUID 12 f f f f v 0 23 "" _null_ pg_logfile_length - _null_)); > +DESCR("length of log file"); > +DATA(insert OID = 2551( pg_logfile PGNSP PGUID 12 f f f f v 2 2275 "23 23" _null_ pg_logfile -_null_ )); > +DESCR("return log file contents"); > + > + > /* > * Symbolic values for provolatile column: these indicate whether the result > * of a function is dependent *only* on the values of its explicit arguments, > Index: include/utils/builtins.h > =================================================================== > RCS file: /projects/cvsroot/pgsql-server/src/include/utils/builtins.h,v > retrieving revision 1.241 > diff -u -r1.241 builtins.h > --- include/utils/builtins.h 2 Jun 2004 21:29:29 -0000 1.241 > +++ include/utils/builtins.h 8 Jun 2004 18:08:05 -0000 > @@ -356,6 +356,8 @@ > extern Datum current_database(PG_FUNCTION_ARGS); > extern Datum pg_terminate_backend(PG_FUNCTION_ARGS); > extern Datum pg_cancel_backend(PG_FUNCTION_ARGS); > +extern Datum pg_logfile_length(PG_FUNCTION_ARGS); > +extern Datum pg_logfile(PG_FUNCTION_ARGS); > > /* not_in.c */ > extern Datum int4notin(PG_FUNCTION_ARGS); > Index: include/utils/elog.h > =================================================================== > RCS file: /projects/cvsroot/pgsql-server/src/include/utils/elog.h,v > retrieving revision 1.68 > diff -u -r1.68 elog.h > --- include/utils/elog.h 5 Apr 2004 03:02:10 -0000 1.68 > +++ include/utils/elog.h 8 Jun 2004 18:08:06 -0000 > @@ -182,8 +182,12 @@ > #define LOG_DESTINATION_STDERR 1 > #define LOG_DESTINATION_SYSLOG 2 > #define LOG_DESTINATION_EVENTLOG 4 > +#define LOG_DESTINATION_FILE 8 > > /* Other exported functions */ > extern void DebugFileOpen(void); > +extern char *LogFileName(void); > +extern void LogFileOpen(void); > +extern void LogFileClose(void); > > #endif /* ELOG_H */ > > ---------------------------(end of broadcast)--------------------------- > TIP 7: don't forget to increase your free space map settings -- Bruce Momjian | http://candle.pha.pa.us pgman@candle.pha.pa.us | (610) 359-1001 + If your life is a hard drive, | 13 Roberts Road + Christ can be your backup. | Newtown Square, Pennsylvania 19073
pgsql-patches by date: