Commit bdf8ef69 authored by Tom Lane's avatar Tom Lane

Create a built-in log rotation program, so that we no longer have to

recommend that people go get Apache's rotatelogs program.  Additional
benefits are that configuration is done through GUC, rather than
externally, and that the postmaster can monitor the log rotator and
restart it after failure (though we certainly hope that won't happen
often).
Andreas Pflug, some rework by Tom Lane.
parent b4cd416a
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/maintenance.sgml,v 1.36 2004/07/24 19:51:22 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/maintenance.sgml,v 1.37 2004/08/05 23:32:10 tgl Exp $
--> -->
<chapter id="maintenance"> <chapter id="maintenance">
...@@ -445,22 +445,52 @@ VACUUM ...@@ -445,22 +445,52 @@ VACUUM
</para> </para>
<para> <para>
If you simply direct the <systemitem>stderr</> of the <command>postmaster</command> into a If you simply direct the <systemitem>stderr</> of the
file, the only way to truncate the log file is to stop and restart <command>postmaster</command> into a
file, you will have log output, but
the only way to truncate the log file is to stop and restart
the <command>postmaster</command>. This may be OK if you are using the <command>postmaster</command>. This may be OK if you are using
<productname>PostgreSQL</productname> in a development environment, <productname>PostgreSQL</productname> in a development environment,
but few production servers would find this behavior acceptable. but few production servers would find this behavior acceptable.
</para> </para>
<para> <para>
The simplest production-grade approach to managing log output is to A better approach is to send the <command>postmaster</>'s
<systemitem>stderr</> output to some type of log rotation program.
There is a built-in log rotation program, which you can use by
setting the configuration parameter <literal>redirect_stderr</> to
<literal>true</> in <filename>postgresql.conf</>. The control
parameters for this program are described in <xref
linkend="runtime-config-logging-where">.
</para>
<para>
Alternatively, you might prefer to use an external log rotation
program, if you have one that you are already using with other
server software. For example, the <application>rotatelogs</application>
tool included in the <productname>Apache</productname> distribution
can be used with <productname>PostgreSQL</productname>. To do this,
just pipe the <command>postmaster</>'s
<systemitem>stderr</> output to the desired program.
If you start the server with
<command>pg_ctl</>, then <systemitem>stderr</>
is already redirected to <systemitem>stdout</>, so you just need a
pipe command:
<programlisting>
pg_ctl start | rotatelogs /var/log/pgsql_log 86400
</programlisting>
</para>
<para>
Another production-grade approach to managing log output is to
send it all to <application>syslog</> and let send it all to <application>syslog</> and let
<application>syslog</> deal with file rotation. To do this, set the <application>syslog</> deal with file rotation. To do this, set the
configuration parameter <literal>log_destination</> to 'syslog' (to log to configuration parameter <literal>log_destination</> to <literal>syslog</>
<application>syslog</> only) in <filename>postgresql.conf</>. Then (to log to <application>syslog</> only) in
you can send a <literal>SIGHUP</literal> signal to the <filename>postgresql.conf</>. Then you can send a <literal>SIGHUP</literal>
<application>syslog</> daemon whenever you want to force it to signal to the <application>syslog</> daemon whenever you want to force it
start writing a new log file. If you want to automate log to start writing a new log file. If you want to automate log
rotation, the <application>logrotate</application> program can be rotation, the <application>logrotate</application> program can be
configured to work with log files from configured to work with log files from
<application>syslog</application>. <application>syslog</application>.
...@@ -471,27 +501,15 @@ VACUUM ...@@ -471,27 +501,15 @@ VACUUM
particularly with large log messages; it may truncate or drop messages particularly with large log messages; it may truncate or drop messages
just when you need them the most. Also, on <productname>linux</>, just when you need them the most. Also, on <productname>linux</>,
<application>syslog</> will sync each message to disk, yielding poor <application>syslog</> will sync each message to disk, yielding poor
performance. Use a <literal>-</> at the start of the file name performance. (You can use a <literal>-</> at the start of the file name
in the <application>syslog</> config file to disable this behavior. in the <application>syslog</> config file to disable this behavior.)
</para> </para>
<para> <para>
You may find it more useful to pipe the Note that all the solutions described above take care of starting new
<systemitem>stderr</> of the <command>postmaster</> to some type of log files at configurable intervals, but they do not handle deletion
log rotation program. If you start the server with of old, no-longer-interesting log files. You will also want to set
<command>pg_ctl</>, then the <systemitem>stderr</> of the <command>postmaster</command> up a batch job to periodically delete old log files.
is already redirected to <systemitem>stdout</>, so you just need a
pipe command:
<programlisting>
pg_ctl start | rotatelogs /var/log/pgsql_log 86400
</programlisting>
The <productname>PostgreSQL</> distribution doesn't include a
suitable log rotation program, but there are many available on the
Internet. For example, the <application>rotatelogs</application>
tool included in the <productname>Apache</productname> distribution
can be used with <productname>PostgreSQL</productname>.
</para> </para>
</sect1> </sect1>
</chapter> </chapter>
......
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.271 2004/08/03 23:42:59 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.272 2004/08/05 23:32:10 tgl Exp $
--> -->
<Chapter Id="runtime"> <Chapter Id="runtime">
...@@ -1800,15 +1800,91 @@ SET ENABLE_SEQSCAN TO OFF; ...@@ -1800,15 +1800,91 @@ SET ENABLE_SEQSCAN TO OFF;
option to a list of desired log destinations separated by option to a list of desired log destinations separated by
commas. The default is to log to <systemitem>stderr</systemitem> commas. The default is to log to <systemitem>stderr</systemitem>
only. only.
This option can only be set at server start or in the
<filename>postgresql.conf</filename> configuration file.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry id="guc-redirect-stderr" xreflabel="redirect_stderr">
<term><varname>redirect_stderr</varname> (<type>boolean</type>)</term>
<listitem>
<para>
This option allows messages sent to <application>stderr</> to be
captured and redirected into log files.
This option, in combination with logging to <application>stderr</>,
is often more useful than
logging to <application>syslog</>, since some types of messages
may not appear in <application>syslog</> output (a common example
is dynamic-linker failure messages).
This option can only be set at server start.
</para>
</listitem>
</varlistentry>
<varlistentry id="guc-log-directory" xreflabel="log_directory">
<term><varname>log_directory</varname> (<type>string</type>)</term>
<listitem>
<para>
When <varname>redirect_stderr</> is enabled, this option
determines the directory in which log files will be created.
It may be specified as an absolute path, or relative to the
cluster data directory.
This option can only be set at server start or in the
<filename>postgresql.conf</filename> configuration file.
</para>
</listitem>
</varlistentry>
<varlistentry id="guc-log-filename-prefix" xreflabel="log_filename_prefix">
<term><varname>log_filename_prefix</varname> (<type>string</type>)</term>
<listitem>
<para>
When <varname>redirect_stderr</> is enabled, this option
sets the prefix of the file names of the created log files.
The postmaster PID and the current time are appended to this
prefix to form an exact log file name.
This option can only be set at server start or in the
<filename>postgresql.conf</filename> configuration file.
</para>
</listitem>
</varlistentry>
<varlistentry id="guc-log-rotation-age" xreflabel="log_rotation_age">
<term><varname>log_rotation_age</varname> (<type>integer</type>)</term>
<listitem>
<para>
When <varname>redirect_stderr</> is enabled, this option
determines the maximum lifetime of an individual log file.
After this many minutes have elapsed, a new log file will
be created. Set to zero to disable time-based creation of
new log files.
This option can only be set at server start or in the
<filename>postgresql.conf</filename> configuration file.
</para>
</listitem>
</varlistentry>
<varlistentry id="guc-log-rotation-size" xreflabel="log_rotation_size">
<term><varname>log_rotation_size</varname> (<type>integer</type>)</term>
<listitem>
<para>
When <varname>redirect_stderr</> is enabled, this option
determines the maximum size of an individual log file.
After this many kilobytes have been emitted into a log file,
a new log file will be created. Set to zero to disable size-based
creation of new log files.
This option can only be set at server start or in the
<filename>postgresql.conf</filename> configuration file.
</para>
</listitem>
</varlistentry>
<varlistentry id="guc-syslog-facility" xreflabel="syslog_facility"> <varlistentry id="guc-syslog-facility" xreflabel="syslog_facility">
<term><varname>syslog_facility</varname> (<type>string</type>)</term> <term><varname>syslog_facility</varname> (<type>string</type>)</term>
<listitem> <listitem>
<para> <para>
If logging to <application>syslog</> is enabled, this option When logging to <application>syslog</> is enabled, this option
determines the <application>syslog</application> determines the <application>syslog</application>
<quote>facility</quote> to be used. You may choose <quote>facility</quote> to be used. You may choose
from <literal>LOCAL0</>, <literal>LOCAL1</>, from <literal>LOCAL0</>, <literal>LOCAL1</>,
...@@ -1826,7 +1902,7 @@ SET ENABLE_SEQSCAN TO OFF; ...@@ -1826,7 +1902,7 @@ SET ENABLE_SEQSCAN TO OFF;
<term><varname>syslog_ident</varname> (<type>string</type>)</term> <term><varname>syslog_ident</varname> (<type>string</type>)</term>
<listitem> <listitem>
<para> <para>
If logging to <application>syslog</> is enabled, this option When logging to <application>syslog</> is enabled, this option
determines the program name used to identify determines the program name used to identify
<productname>PostgreSQL</productname> messages in <productname>PostgreSQL</productname> messages in
<application>syslog</application> logs. The default is <application>syslog</application> logs. The default is
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# Makefile for src/backend/postmaster # Makefile for src/backend/postmaster
# #
# IDENTIFICATION # IDENTIFICATION
# $PostgreSQL: pgsql/src/backend/postmaster/Makefile,v 1.18 2004/07/21 20:34:46 momjian Exp $ # $PostgreSQL: pgsql/src/backend/postmaster/Makefile,v 1.19 2004/08/05 23:32:10 tgl Exp $
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
...@@ -12,7 +12,7 @@ subdir = src/backend/postmaster ...@@ -12,7 +12,7 @@ subdir = src/backend/postmaster
top_builddir = ../../.. top_builddir = ../../..
include $(top_builddir)/src/Makefile.global include $(top_builddir)/src/Makefile.global
OBJS = postmaster.o bgwriter.o pgstat.o pgarch.o OBJS = postmaster.o bgwriter.o pgstat.o pgarch.o syslogger.o
all: SUBSYS.o all: SUBSYS.o
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/pgarch.c,v 1.4 2004/08/03 20:32:33 tgl Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/pgarch.c,v 1.5 2004/08/05 23:32:10 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -172,7 +172,7 @@ pgarch_start(void) ...@@ -172,7 +172,7 @@ pgarch_start(void)
beos_backend_startup(); beos_backend_startup();
#endif #endif
/* Close the postmaster's sockets */ /* Close the postmaster's sockets */
ClosePostmasterPorts(); ClosePostmasterPorts(false);
/* Drop our connection to postmaster's shared memory, as well */ /* Drop our connection to postmaster's shared memory, as well */
PGSharedMemoryDetach(); PGSharedMemoryDetach();
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
* *
* Copyright (c) 2001-2003, PostgreSQL Global Development Group * Copyright (c) 2001-2003, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.77 2004/07/01 00:50:36 tgl Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.78 2004/08/05 23:32:10 tgl Exp $
* ---------- * ----------
*/ */
#include "postgres.h" #include "postgres.h"
...@@ -611,7 +611,7 @@ pgstat_start(void) ...@@ -611,7 +611,7 @@ pgstat_start(void)
beos_backend_startup(); beos_backend_startup();
#endif #endif
/* Close the postmaster's sockets */ /* Close the postmaster's sockets */
ClosePostmasterPorts(); ClosePostmasterPorts(false);
/* Drop our connection to postmaster's shared memory, as well */ /* Drop our connection to postmaster's shared memory, as well */
PGSharedMemoryDetach(); PGSharedMemoryDetach();
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.419 2004/08/04 20:09:47 tgl Exp $ * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.420 2004/08/05 23:32:10 tgl Exp $
* *
* NOTES * NOTES
* *
...@@ -104,6 +104,7 @@ ...@@ -104,6 +104,7 @@
#include "nodes/nodes.h" #include "nodes/nodes.h"
#include "postmaster/postmaster.h" #include "postmaster/postmaster.h"
#include "postmaster/pgarch.h" #include "postmaster/pgarch.h"
#include "postmaster/syslogger.h"
#include "storage/fd.h" #include "storage/fd.h"
#include "storage/ipc.h" #include "storage/ipc.h"
#include "storage/pg_shmem.h" #include "storage/pg_shmem.h"
...@@ -199,7 +200,8 @@ char *preload_libraries_string = NULL; ...@@ -199,7 +200,8 @@ char *preload_libraries_string = NULL;
static pid_t StartupPID = 0, static pid_t StartupPID = 0,
BgWriterPID = 0, BgWriterPID = 0,
PgArchPID = 0, PgArchPID = 0,
PgStatPID = 0; PgStatPID = 0,
SysLoggerPID = 0;
/* Startup/shutdown state */ /* Startup/shutdown state */
#define NoShutdown 0 #define NoShutdown 0
...@@ -828,7 +830,7 @@ PostmasterMain(int argc, char *argv[]) ...@@ -828,7 +830,7 @@ PostmasterMain(int argc, char *argv[])
* CAUTION: when changing this list, check for side-effects on the signal * CAUTION: when changing this list, check for side-effects on the signal
* handling setup of child processes. See tcop/postgres.c, * handling setup of child processes. See tcop/postgres.c,
* bootstrap/bootstrap.c, postmaster/bgwriter.c, postmaster/pgarch.c, * bootstrap/bootstrap.c, postmaster/bgwriter.c, postmaster/pgarch.c,
* and postmaster/pgstat.c. * postmaster/pgstat.c, and postmaster/syslogger.c.
*/ */
pqinitmask(); pqinitmask();
PG_SETMASK(&BlockSig); PG_SETMASK(&BlockSig);
...@@ -850,6 +852,11 @@ PostmasterMain(int argc, char *argv[]) ...@@ -850,6 +852,11 @@ PostmasterMain(int argc, char *argv[])
pqsignal(SIGXFSZ, SIG_IGN); /* ignored */ pqsignal(SIGXFSZ, SIG_IGN); /* ignored */
#endif #endif
/*
* If enabled, start up syslogger collection subprocess
*/
SysLoggerPID = SysLogger_Start();
/* /*
* Reset whereToSendOutput from Debug (its starting state) to None. * Reset whereToSendOutput from Debug (its starting state) to None.
* This stops ereport from sending log messages to stderr unless * This stops ereport from sending log messages to stderr unless
...@@ -933,8 +940,8 @@ checkDataDir(const char *checkdir) ...@@ -933,8 +940,8 @@ checkDataDir(const char *checkdir)
{ {
write_stderr("%s does not know where to find the database system data.\n" write_stderr("%s does not know where to find the database system data.\n"
"You must specify the directory that contains the database system\n" "You must specify the directory that contains the database system\n"
"or configuration files by either specifying the -D invocation option\n" "either by specifying the -D invocation option or by setting the\n"
"or by setting the PGDATA environment variable.\n", "PGDATA environment variable.\n",
progname); progname);
ExitPostmaster(2); ExitPostmaster(2);
} }
...@@ -944,12 +951,12 @@ checkDataDir(const char *checkdir) ...@@ -944,12 +951,12 @@ checkDataDir(const char *checkdir)
if (errno == ENOENT) if (errno == ENOENT)
ereport(FATAL, ereport(FATAL,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("data or configuration location \"%s\" does not exist", errmsg("data directory \"%s\" does not exist",
checkdir))); checkdir)));
else else
ereport(FATAL, ereport(FATAL,
(errcode_for_file_access(), (errcode_for_file_access(),
errmsg("could not read permissions of \"%s\": %m", errmsg("could not read permissions of directory \"%s\": %m",
checkdir))); checkdir)));
} }
...@@ -1050,7 +1057,7 @@ pmdaemonize(void) ...@@ -1050,7 +1057,7 @@ pmdaemonize(void)
ExitPostmaster(1); ExitPostmaster(1);
} }
#endif #endif
i = open(NULL_DEV, O_RDWR | PG_BINARY); i = open(NULL_DEV, O_RDWR);
dup2(i, 0); dup2(i, 0);
dup2(i, 1); dup2(i, 1);
dup2(i, 2); dup2(i, 2);
...@@ -1207,6 +1214,10 @@ ServerLoop(void) ...@@ -1207,6 +1214,10 @@ ServerLoop(void)
} }
} }
/* If we have lost the system logger, try to start a new one */
if (SysLoggerPID == 0 && Redirect_stderr)
SysLoggerPID = SysLogger_Start();
/* /*
* If no background writer process is running, and we are not in * If no background writer process is running, and we are not in
* a state that prevents it, start one. It doesn't matter if this * a state that prevents it, start one. It doesn't matter if this
...@@ -1714,9 +1725,12 @@ ConnFree(Port *conn) ...@@ -1714,9 +1725,12 @@ ConnFree(Port *conn)
* This is called during child process startup to release file descriptors * This is called during child process startup to release file descriptors
* that are not needed by that child process. The postmaster still has * that are not needed by that child process. The postmaster still has
* them open, of course. * them open, of course.
*
* Note: we pass am_syslogger as a boolean because we don't want to set
* the global variable yet when this is called.
*/ */
void void
ClosePostmasterPorts(void) ClosePostmasterPorts(bool am_syslogger)
{ {
int i; int i;
...@@ -1729,6 +1743,20 @@ ClosePostmasterPorts(void) ...@@ -1729,6 +1743,20 @@ ClosePostmasterPorts(void)
ListenSocket[i] = -1; ListenSocket[i] = -1;
} }
} }
/* If using syslogger, close the read side of the pipe */
if (!am_syslogger)
{
#ifndef WIN32
if (syslogPipe[0] >= 0)
close(syslogPipe[0]);
syslogPipe[0] = -1;
#else
if (syslogPipe[0])
CloseHandle(syslogPipe[0]);
syslogPipe[0] = 0;
#endif
}
} }
...@@ -1770,6 +1798,8 @@ SIGHUP_handler(SIGNAL_ARGS) ...@@ -1770,6 +1798,8 @@ SIGHUP_handler(SIGNAL_ARGS)
kill(BgWriterPID, SIGHUP); kill(BgWriterPID, SIGHUP);
if (PgArchPID != 0) if (PgArchPID != 0)
kill(PgArchPID, SIGHUP); kill(PgArchPID, SIGHUP);
if (SysLoggerPID != 0)
kill(SysLoggerPID, SIGHUP);
/* PgStatPID does not currently need SIGHUP */ /* PgStatPID does not currently need SIGHUP */
load_hba(); load_hba();
load_ident(); load_ident();
...@@ -2063,6 +2093,18 @@ reaper(SIGNAL_ARGS) ...@@ -2063,6 +2093,18 @@ reaper(SIGNAL_ARGS)
continue; continue;
} }
/* Was it the system logger? try to start a new one */
if (SysLoggerPID != 0 && pid == SysLoggerPID)
{
SysLoggerPID = 0;
/* for safety's sake, launch new logger *first* */
SysLoggerPID = SysLogger_Start();
if (exitstatus != 0)
LogChildExit(LOG, gettext("system logger process"),
pid, exitstatus);
continue;
}
/* /*
* Else do standard backend child cleanup. * Else do standard backend child cleanup.
*/ */
...@@ -2258,6 +2300,8 @@ HandleChildCrash(int pid, int exitstatus, const char *procname) ...@@ -2258,6 +2300,8 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
kill(PgStatPID, SIGQUIT); kill(PgStatPID, SIGQUIT);
} }
/* We do NOT restart the syslogger */
FatalError = true; FatalError = true;
} }
...@@ -2528,7 +2572,7 @@ BackendRun(Port *port) ...@@ -2528,7 +2572,7 @@ BackendRun(Port *port)
* Let's clean up ourselves as the postmaster child, and close the * Let's clean up ourselves as the postmaster child, and close the
* postmaster's listen sockets * postmaster's listen sockets
*/ */
ClosePostmasterPorts(); ClosePostmasterPorts(false);
/* We don't want the postmaster's proc_exit() handlers */ /* We don't want the postmaster's proc_exit() handlers */
on_exit_reset(); on_exit_reset();
...@@ -2921,7 +2965,7 @@ SubPostmasterMain(int argc, char *argv[]) ...@@ -2921,7 +2965,7 @@ SubPostmasterMain(int argc, char *argv[])
if (strcmp(argv[1], "-forkboot") == 0) if (strcmp(argv[1], "-forkboot") == 0)
{ {
/* Close the postmaster's sockets */ /* Close the postmaster's sockets */
ClosePostmasterPorts(); ClosePostmasterPorts(false);
/* Attach process to shared segments */ /* Attach process to shared segments */
CreateSharedMemoryAndSemaphores(false, MaxBackends, 0); CreateSharedMemoryAndSemaphores(false, MaxBackends, 0);
...@@ -2932,7 +2976,7 @@ SubPostmasterMain(int argc, char *argv[]) ...@@ -2932,7 +2976,7 @@ SubPostmasterMain(int argc, char *argv[])
if (strcmp(argv[1], "-forkarch") == 0) if (strcmp(argv[1], "-forkarch") == 0)
{ {
/* Close the postmaster's sockets */ /* Close the postmaster's sockets */
ClosePostmasterPorts(); ClosePostmasterPorts(false);
/* Do not want to attach to shared memory */ /* Do not want to attach to shared memory */
...@@ -2942,7 +2986,7 @@ SubPostmasterMain(int argc, char *argv[]) ...@@ -2942,7 +2986,7 @@ SubPostmasterMain(int argc, char *argv[])
if (strcmp(argv[1], "-forkbuf") == 0) if (strcmp(argv[1], "-forkbuf") == 0)
{ {
/* Close the postmaster's sockets */ /* Close the postmaster's sockets */
ClosePostmasterPorts(); ClosePostmasterPorts(false);
/* Do not want to attach to shared memory */ /* Do not want to attach to shared memory */
...@@ -2961,6 +3005,16 @@ SubPostmasterMain(int argc, char *argv[]) ...@@ -2961,6 +3005,16 @@ SubPostmasterMain(int argc, char *argv[])
PgstatCollectorMain(argc, argv); PgstatCollectorMain(argc, argv);
proc_exit(0); proc_exit(0);
} }
if (strcmp(argv[1], "-forklog") == 0)
{
/* Close the postmaster's sockets */
ClosePostmasterPorts(true);
/* Do not want to attach to shared memory */
SysLoggerMain(argc, argv);
proc_exit(0);
}
return 1; /* shouldn't get here */ return 1; /* shouldn't get here */
} }
...@@ -3017,7 +3071,7 @@ sigusr1_handler(SIGNAL_ARGS) ...@@ -3017,7 +3071,7 @@ sigusr1_handler(SIGNAL_ARGS)
if (Shutdown <= SmartShutdown) if (Shutdown <= SmartShutdown)
SignalChildren(SIGUSR1); SignalChildren(SIGUSR1);
} }
if (PgArchPID != 0 && Shutdown == NoShutdown) if (PgArchPID != 0 && Shutdown == NoShutdown)
{ {
if (CheckPostmasterSignal(PMSIGNAL_WAKEN_ARCHIVER)) if (CheckPostmasterSignal(PMSIGNAL_WAKEN_ARCHIVER))
...@@ -3214,7 +3268,7 @@ StartChildProcess(int xlop) ...@@ -3214,7 +3268,7 @@ StartChildProcess(int xlop)
IsUnderPostmaster = true; /* we are a postmaster subprocess now */ IsUnderPostmaster = true; /* we are a postmaster subprocess now */
/* Close the postmaster's sockets */ /* Close the postmaster's sockets */
ClosePostmasterPorts(); ClosePostmasterPorts(false);
/* Lose the postmaster's on-exit routines and port connections */ /* Lose the postmaster's on-exit routines and port connections */
on_exit_reset(); on_exit_reset();
...@@ -3400,6 +3454,9 @@ write_backend_variables(char *filename, Port *port) ...@@ -3400,6 +3454,9 @@ write_backend_variables(char *filename, Port *port)
write_var(PostmasterHandle, fp); write_var(PostmasterHandle, fp);
#endif #endif
write_var(syslogPipe[0], fp);
write_var(syslogPipe[1], fp);
StrNCpy(str_buf, my_exec_path, MAXPGPATH); StrNCpy(str_buf, my_exec_path, MAXPGPATH);
write_array_var(str_buf, fp); write_array_var(str_buf, fp);
...@@ -3471,6 +3528,9 @@ read_backend_variables(char *filename, Port *port) ...@@ -3471,6 +3528,9 @@ read_backend_variables(char *filename, Port *port)
read_var(PostmasterHandle, fp); read_var(PostmasterHandle, fp);
#endif #endif
read_var(syslogPipe[0], fp);
read_var(syslogPipe[1], fp);
read_array_var(str_buf, fp); read_array_var(str_buf, fp);
StrNCpy(my_exec_path, str_buf, MAXPGPATH); StrNCpy(my_exec_path, str_buf, MAXPGPATH);
......
This diff is collapsed.
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.145 2004/08/04 20:58:46 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.146 2004/08/05 23:32:11 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -57,6 +57,7 @@ ...@@ -57,6 +57,7 @@
#include "mb/pg_wchar.h" #include "mb/pg_wchar.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "postmaster/postmaster.h" #include "postmaster/postmaster.h"
#include "postmaster/syslogger.h"
#include "storage/ipc.h" #include "storage/ipc.h"
#include "tcop/tcopprot.h" #include "tcop/tcopprot.h"
#include "utils/memutils.h" #include "utils/memutils.h"
...@@ -71,7 +72,7 @@ sigjmp_buf *PG_exception_stack = NULL; ...@@ -71,7 +72,7 @@ sigjmp_buf *PG_exception_stack = NULL;
/* GUC parameters */ /* GUC parameters */
PGErrorVerbosity Log_error_verbosity = PGERROR_VERBOSE; PGErrorVerbosity Log_error_verbosity = PGERROR_VERBOSE;
char *Log_line_prefix = NULL; /* format for extra log line info */ char *Log_line_prefix = NULL; /* format for extra log line info */
unsigned int Log_destination = LOG_DESTINATION_STDERR; int Log_destination = LOG_DESTINATION_STDERR;
#ifdef HAVE_SYSLOG #ifdef HAVE_SYSLOG
char *Syslog_facility; /* openlog() parameters */ char *Syslog_facility; /* openlog() parameters */
...@@ -1589,6 +1590,10 @@ send_message_to_server_log(ErrorData *edata) ...@@ -1589,6 +1590,10 @@ send_message_to_server_log(ErrorData *edata)
fprintf(stderr, "%s", buf.data); fprintf(stderr, "%s", buf.data);
} }
/* If in the syslogger process, try to write messages direct to file */
if (am_syslogger)
write_syslogger_file(buf.data, buf.len);
pfree(buf.data); pfree(buf.data);
} }
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>. * Written by Peter Eisentraut <peter_e@gmx.net>.
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.225 2004/07/28 14:23:29 tgl Exp $ * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.226 2004/08/05 23:32:12 tgl Exp $
* *
*-------------------------------------------------------------------- *--------------------------------------------------------------------
*/ */
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include "parser/parse_expr.h" #include "parser/parse_expr.h"
#include "parser/parse_relation.h" #include "parser/parse_relation.h"
#include "postmaster/bgwriter.h" #include "postmaster/bgwriter.h"
#include "postmaster/syslogger.h"
#include "postmaster/postmaster.h" #include "postmaster/postmaster.h"
#include "storage/bufmgr.h" #include "storage/bufmgr.h"
#include "storage/fd.h" #include "storage/fd.h"
...@@ -801,19 +802,13 @@ static struct config_bool ConfigureNamesBool[] = ...@@ -801,19 +802,13 @@ static struct config_bool ConfigureNamesBool[] =
&default_with_oids, &default_with_oids,
true, NULL, NULL true, NULL, NULL
}, },
{ {
{"integer_datetimes", PGC_INTERNAL, COMPILE_OPTIONS, {"redirect_stderr", PGC_POSTMASTER, LOGGING_WHERE,
gettext_noop("Datetimes are integer based"), gettext_noop("Start a subprocess to capture stderr output into log files"),
NULL, NULL
GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
}, },
&integer_datetimes, &Redirect_stderr,
#ifdef HAVE_INT64_TIMESTAMP
true, NULL, NULL
#else
false, NULL, NULL false, NULL, NULL
#endif
}, },
#ifdef WAL_DEBUG #ifdef WAL_DEBUG
...@@ -828,6 +823,20 @@ static struct config_bool ConfigureNamesBool[] = ...@@ -828,6 +823,20 @@ static struct config_bool ConfigureNamesBool[] =
}, },
#endif #endif
{
{"integer_datetimes", PGC_INTERNAL, COMPILE_OPTIONS,
gettext_noop("Datetimes are integer based"),
NULL,
GUC_NOT_IN_SAMPLE | GUC_DISALLOW_IN_FILE
},
&integer_datetimes,
#ifdef HAVE_INT64_TIMESTAMP
true, NULL, NULL
#else
false, NULL, NULL
#endif
},
/* End-of-list marker */ /* End-of-list marker */
{ {
{NULL, 0, 0, NULL, NULL}, NULL, false, NULL, NULL {NULL, 0, 0, NULL, NULL}, NULL, false, NULL, NULL
...@@ -1245,6 +1254,24 @@ static struct config_int ConfigureNamesInt[] = ...@@ -1245,6 +1254,24 @@ static struct config_int ConfigureNamesInt[] =
100, 1, 1000, NULL, NULL 100, 1, 1000, NULL, NULL
}, },
{
{"log_rotation_age", PGC_SIGHUP, LOGGING_WHERE,
gettext_noop("Automatic logfile rotation will occur after N minutes"),
NULL
},
&Log_RotationAge,
24*60, 0, INT_MAX, NULL, NULL
},
{
{"log_rotation_size", PGC_SIGHUP, LOGGING_WHERE,
gettext_noop("Automatic logfile rotation will occur after N kilobytes"),
NULL
},
&Log_RotationSize,
10*1024, 0, INT_MAX, NULL, NULL
},
{ {
{"max_function_args", PGC_INTERNAL, COMPILE_OPTIONS, {"max_function_args", PGC_INTERNAL, COMPILE_OPTIONS,
gettext_noop("Shows the maximum number of function arguments"), gettext_noop("Shows the maximum number of function arguments"),
...@@ -1634,6 +1661,23 @@ static struct config_string ConfigureNamesString[] = ...@@ -1634,6 +1661,23 @@ static struct config_string ConfigureNamesString[] =
&log_destination_string, &log_destination_string,
"stderr", assign_log_destination, NULL "stderr", assign_log_destination, NULL
}, },
{
{"log_directory", PGC_SIGHUP, LOGGING_WHERE,
gettext_noop("Sets the destination directory for logfiles."),
gettext_noop("May be specified as relative to the cluster directory "
"or as absolute path.")
},
&Log_directory,
"pg_log", NULL, NULL
},
{
{"log_filename_prefix", PGC_SIGHUP, LOGGING_WHERE,
gettext_noop("Prefix for file names created in the log_directory."),
NULL
},
&Log_filename_prefix,
"postgresql-", NULL, NULL
},
#ifdef HAVE_SYSLOG #ifdef HAVE_SYSLOG
{ {
...@@ -5055,7 +5099,7 @@ assign_log_destination(const char *value, bool doit, GucSource source) ...@@ -5055,7 +5099,7 @@ assign_log_destination(const char *value, bool doit, GucSource source)
char *rawstring; char *rawstring;
List *elemlist; List *elemlist;
ListCell *l; ListCell *l;
unsigned int newlogdest = 0; int newlogdest = 0;
/* Need a modifiable copy of string */ /* Need a modifiable copy of string */
rawstring = pstrdup(value); rawstring = pstrdup(value);
......
...@@ -170,9 +170,23 @@ ...@@ -170,9 +170,23 @@
#log_destination = 'stderr' # Valid values are combinations of stderr, #log_destination = 'stderr' # Valid values are combinations of stderr,
# syslog and eventlog, depending on # syslog and eventlog, depending on
# platform. # platform.
# This is relevant when logging to stderr:
#redirect_stderr = false # Enable capturing of stderr into log files.
# These are only relevant if redirect_stderr is true:
#log_directory = 'pg_log' # Directory where logfiles are written.
# May be specified absolute or relative to PGDATA
#log_filename_prefix = 'postgresql_' # Prefix for logfile names.
#log_rotation_age = 1440 # Automatic rotation of logfiles will happen after
# so many minutes. 0 to disable.
#log_rotation_size = 10240 # Automatic rotation of logfiles will happen after
# so many kilobytes of log output. 0 to disable.
# These are relevant when logging to syslog:
#syslog_facility = 'LOCAL0' #syslog_facility = 'LOCAL0'
#syslog_ident = 'postgres' #syslog_ident = 'postgres'
# - When to Log - # - When to Log -
#client_min_messages = notice # Values, in order of decreasing detail: #client_min_messages = notice # Values, in order of decreasing detail:
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/postmaster/postmaster.h,v 1.4 2004/07/21 20:34:48 momjian Exp $ * $PostgreSQL: pgsql/src/include/postmaster/postmaster.h,v 1.5 2004/08/05 23:32:12 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -36,7 +36,7 @@ extern HANDLE PostmasterHandle; ...@@ -36,7 +36,7 @@ extern HANDLE PostmasterHandle;
extern int PostmasterMain(int argc, char *argv[]); extern int PostmasterMain(int argc, char *argv[]);
extern void ClosePostmasterPorts(void); extern void ClosePostmasterPorts(bool am_syslogger);
#ifdef EXEC_BACKEND #ifdef EXEC_BACKEND
extern pid_t postmaster_forkexec(int argc, char *argv[]); extern pid_t postmaster_forkexec(int argc, char *argv[]);
extern int SubPostmasterMain(int argc, char *argv[]); extern int SubPostmasterMain(int argc, char *argv[]);
......
/*-------------------------------------------------------------------------
*
* syslogger.h
* Exports from postmaster/syslogger.c.
*
* Copyright (c) 2004, PostgreSQL Global Development Group
*
* $PostgreSQL: pgsql/src/include/postmaster/syslogger.h,v 1.1 2004/08/05 23:32:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef _SYSLOGGER_H
#define _SYSLOGGER_H
/* GUC options */
extern bool Redirect_stderr;
extern int Log_RotationAge;
extern int Log_RotationSize;
extern char *Log_directory;
extern char *Log_filename_prefix;
extern bool am_syslogger;
#ifndef WIN32
extern int syslogPipe[2];
#else
extern HANDLE syslogPipe[2];
#endif
extern int SysLogger_Start(void);
extern void write_syslogger_file(const char *buffer, int count);
#ifdef EXEC_BACKEND
extern void SysLoggerMain(int argc, char *argv[]);
#endif
#endif /* _SYSLOGGER_H */
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/utils/elog.h,v 1.72 2004/07/31 23:04:55 tgl Exp $ * $PostgreSQL: pgsql/src/include/utils/elog.h,v 1.73 2004/08/05 23:32:13 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -272,7 +272,7 @@ typedef enum ...@@ -272,7 +272,7 @@ typedef enum
extern PGErrorVerbosity Log_error_verbosity; extern PGErrorVerbosity Log_error_verbosity;
extern char *Log_line_prefix; extern char *Log_line_prefix;
extern unsigned int Log_destination; extern int Log_destination;
/* Log destination bitmap */ /* Log destination bitmap */
#define LOG_DESTINATION_STDERR 1 #define LOG_DESTINATION_STDERR 1
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment