Index: doc/src/sgml/func.sgml =================================================================== RCS file: /projects/cvsroot/pgsql-server/doc/src/sgml/func.sgml,v retrieving revision 1.206 diff -u -r1.206 func.sgml --- doc/src/sgml/func.sgml 2 Jun 2004 21:34:49 -0000 1.206 +++ doc/src/sgml/func.sgml 11 Jun 2004 17:58:35 -0000 @@ -7308,6 +7308,53 @@ columns do not have OIDs of their own. + + pg_logfile + + + pg_logfile_length + + + The functions shown in + deal with the server log file if configured with log_destination + file. + previously stored with the COMMENT command. A + null value is returned if no comment could be found matching the + specified parameters. + + + + Server Logfile Functions + + + Name Return Type Description + + + + + pg_logfile(size_int4, offset_int4) + cstring + get a part of the server log file + + + pg_logfile_length() + int4 + return the current length of the server log file + + + +
+ +The pg_logfile function will return the + contents of the server log file, limited by the size + parameter. If size is NULL, a server internal limit (currently + 50000) is applied. The position parameter determines the + starting position of the server log chunk to be returned. A + positive number or 0 will be counted from the start of the file, + a negative number from the end; if NULL, -size is assumed + (i.e. the tail of the log file). + + Index: doc/src/sgml/runtime.sgml =================================================================== RCS file: /projects/cvsroot/pgsql-server/doc/src/sgml/runtime.sgml,v retrieving revision 1.266 diff -u -r1.266 runtime.sgml --- doc/src/sgml/runtime.sgml 10 Jun 2004 22:26:17 -0000 1.266 +++ doc/src/sgml/runtime.sgml 11 Jun 2004 17:58:46 -0000 @@ -1721,14 +1721,25 @@ PostgreSQL supports several methods - for loggning, including stderr and - syslog. On Windows, - eventlog is also supported. Set this + for logging, including stderr, + file and syslog. + On Windows, eventlog is also supported. Set this option to a list of desired log destinations separated by a comma. The default is to log to stderr only. This option must be set at server start. + + + + log_filename (string) + + + This option sets the target filename for the log destination + file option. It may be specified as absolute + path or relative to the cluster directory. + + Index: src/backend/postmaster/postmaster.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/postmaster/postmaster.c,v retrieving revision 1.403 diff -u -r1.403 postmaster.c --- src/backend/postmaster/postmaster.c 11 Jun 2004 03:54:43 -0000 1.403 +++ src/backend/postmaster/postmaster.c 11 Jun 2004 17:58:52 -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: src/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 --- src/backend/storage/ipc/ipc.c 12 Dec 2003 18:45:09 -0000 1.87 +++ src/backend/storage/ipc/ipc.c 11 Jun 2004 17:58:52 -0000 @@ -111,6 +111,8 @@ on_proc_exit_list[on_proc_exit_index].arg); elog(DEBUG3, "exit(%d)", code); + + LogFileClose(); exit(code); } Index: src/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 --- src/backend/utils/adt/misc.c 2 Jun 2004 21:29:29 -0000 1.34 +++ src/backend/utils/adt/misc.c 11 Jun 2004 17:58:58 -0000 @@ -103,3 +103,70 @@ { PG_RETURN_INT32(pg_signal_backend(PG_GETARG_INT32(0),SIGINT)); } + +extern FILE *logfile; // in elog.c + +Datum pg_logfile_length(PG_FUNCTION_ARGS) +{ + if (logfile) + { + fflush(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, "rb"); + if (f) + { + if (logfile) + fflush(logfile); + + 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: src/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 --- src/backend/utils/error/elog.c 3 Jun 2004 02:08:04 -0000 1.140 +++ src/backend/utils/error/elog.c 11 Jun 2004 17:59:01 -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, "ab"); + + 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: src/backend/utils/misc/guc.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/utils/misc/guc.c,v retrieving revision 1.211 diff -u -r1.211 guc.c --- src/backend/utils/misc/guc.c 11 Jun 2004 03:54:54 -0000 1.211 +++ src/backend/utils/misc/guc.c 11 Jun 2004 17:59:09 -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 { @@ -4779,6 +4791,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: src/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 --- src/backend/utils/misc/postgresql.conf.sample 7 Apr 2004 05:05:50 -0000 1.113 +++ src/backend/utils/misc/postgresql.conf.sample 11 Jun 2004 17:59:10 -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 = 'postgresql.log' #syslog_facility = 'LOCAL0' #syslog_ident = 'postgres' Index: src/include/catalog/pg_proc.h =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/include/catalog/pg_proc.h,v retrieving revision 1.335 diff -u -r1.335 pg_proc.h --- src/include/catalog/pg_proc.h 6 Jun 2004 19:07:00 -0000 1.335 +++ src/include/catalog/pg_proc.h 11 Jun 2004 17:59:25 -0000 @@ -3588,6 +3588,15 @@ 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 = 2546( int2array_int2vector_eq PGNSP PGUID 12 f f t f i 2 16 "1005 22" _null_ int2array_int2vector_eq - _null_ )); +DESCR("int2array int2vector equal"); + +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: src/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 --- src/include/utils/builtins.h 2 Jun 2004 21:29:29 -0000 1.241 +++ src/include/utils/builtins.h 11 Jun 2004 17:59:27 -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: src/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 --- src/include/utils/elog.h 5 Apr 2004 03:02:10 -0000 1.68 +++ src/include/utils/elog.h 11 Jun 2004 17:59:28 -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 */