<!--
-$PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.28 2005/10/13 22:55:19 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.29 2005/10/14 20:53:55 tgl Exp $
-->
<chapter Id="runtime-config">
<title>Run-time Configuration</title>
the default is <literal>LOCAL0</>. See also the
documentation of your system's
<application>syslog</application> daemon.
- This option can only be set at server start.
+ This option can only be set at server start or in the
+ <filename>postgresql.conf</filename> configuration file.
</para>
</listitem>
</varlistentry>
<productname>PostgreSQL</productname> messages in
<application>syslog</application> logs. The default is
<literal>postgres</literal>.
- This option can only be set at server start.
+ This option can only be set at server start or in the
+ <filename>postgresql.conf</filename> configuration file.
</para>
</listitem>
</varlistentry>
<varname>log_statement</> to be logged. When using this option,
if you are not using <application>syslog</>, it is recommended
that you log the PID or session ID using <varname>log_line_prefix</>
- so that you can link the statement to the
- duration using the process ID or session ID. The default is
+ so that you can link the statement message to the later
+ duration message using the process ID or session ID. The default is
<literal>off</>. Only superusers can change this setting.
</para>
</listitem>
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.163 2005/10/14 16:41:02 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.164 2005/10/14 20:53:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
int Log_destination = LOG_DESTINATION_STDERR;
#ifdef HAVE_SYSLOG
-char *Syslog_facility; /* openlog() parameters */
-char *Syslog_ident;
+static bool openlog_done = false;
+static char *syslog_ident = NULL;
+static int syslog_facility = LOG_LOCAL0;
static void write_syslog(int level, const char *line);
#endif
#ifdef HAVE_SYSLOG
+/*
+ * Set or update the parameters for syslog logging
+ */
+void
+set_syslog_parameters(const char *ident, int facility)
+{
+ /*
+ * guc.c is likely to call us repeatedly with same parameters, so
+ * don't thrash the syslog connection unnecessarily. Also, we do not
+ * re-open the connection until needed, since this routine will get called
+ * whether or not Log_destination actually mentions syslog.
+ *
+ * Note that we make our own copy of the ident string rather than relying
+ * on guc.c's. This may be overly paranoid, but it ensures that we cannot
+ * accidentally free a string that syslog is still using.
+ */
+ if (syslog_ident == NULL || strcmp(syslog_ident, ident) != 0 ||
+ syslog_facility != facility)
+ {
+ if (openlog_done)
+ {
+ closelog();
+ openlog_done = false;
+ }
+ if (syslog_ident)
+ free(syslog_ident);
+ syslog_ident = strdup(ident);
+ /* if the strdup fails, we will cope in write_syslog() */
+ syslog_facility = facility;
+ }
+}
+
+
#ifndef PG_SYSLOG_LIMIT
#define PG_SYSLOG_LIMIT 128
#endif
static void
write_syslog(int level, const char *line)
{
- static bool openlog_done = false;
static unsigned long seq = 0;
int len;
+ /* Open syslog connection if not done yet */
if (!openlog_done)
{
- int syslog_fac;
- char *syslog_ident;
-
- if (pg_strcasecmp(Syslog_facility, "LOCAL0") == 0)
- syslog_fac = LOG_LOCAL0;
- else if (pg_strcasecmp(Syslog_facility, "LOCAL1") == 0)
- syslog_fac = LOG_LOCAL1;
- else if (pg_strcasecmp(Syslog_facility, "LOCAL2") == 0)
- syslog_fac = LOG_LOCAL2;
- else if (pg_strcasecmp(Syslog_facility, "LOCAL3") == 0)
- syslog_fac = LOG_LOCAL3;
- else if (pg_strcasecmp(Syslog_facility, "LOCAL4") == 0)
- syslog_fac = LOG_LOCAL4;
- else if (pg_strcasecmp(Syslog_facility, "LOCAL5") == 0)
- syslog_fac = LOG_LOCAL5;
- else if (pg_strcasecmp(Syslog_facility, "LOCAL6") == 0)
- syslog_fac = LOG_LOCAL6;
- else if (pg_strcasecmp(Syslog_facility, "LOCAL7") == 0)
- syslog_fac = LOG_LOCAL7;
- else
- syslog_fac = LOG_LOCAL0;
- /*
- * openlog() usually just stores the passed char pointer as-is,
- * so we must give it a string that will be unchanged for the life of
- * the process. The Syslog_ident GUC variable does not meet this
- * requirement, so strdup() it. This isn't a memory leak because
- * this code is executed at most once per process.
- */
- syslog_ident = strdup(Syslog_ident);
- if (syslog_ident == NULL) /* out of memory already!? */
- syslog_ident = "postgres";
-
- openlog(syslog_ident, LOG_PID | LOG_NDELAY | LOG_NOWAIT, syslog_fac);
+ openlog(syslog_ident ? syslog_ident : "postgres",
+ LOG_PID | LOG_NDELAY | LOG_NOWAIT,
+ syslog_facility);
openlog_done = true;
}
* Written by Peter Eisentraut <peter_e@gmx.net>.
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.291 2005/10/08 20:08:19 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.292 2005/10/14 20:53:56 tgl Exp $
*
*--------------------------------------------------------------------
*/
#include <limits.h>
#include <unistd.h>
#include <sys/stat.h>
+#ifdef HAVE_SYSLOG
+#include <syslog.h>
+#endif
#include "utils/guc.h"
#include "utils/guc_tables.h"
bool doit, GucSource source);
#ifdef HAVE_SYSLOG
-extern char *Syslog_facility;
-extern char *Syslog_ident;
+static int syslog_facility = LOG_LOCAL0;
-static const char *assign_facility(const char *facility,
+static const char *assign_syslog_facility(const char *facility,
+ bool doit, GucSource source);
+static const char *assign_syslog_ident(const char *ident,
bool doit, GucSource source);
#endif
static char *log_statement_str;
static char *log_min_error_statement_str;
static char *log_destination_string;
+static char *syslog_facility_str;
+static char *syslog_ident_str;
static bool phony_autocommit;
static bool session_auth_is_superuser;
static double phony_random_seed;
#ifdef HAVE_SYSLOG
{
- {"syslog_facility", PGC_POSTMASTER, LOGGING_WHERE,
+ {"syslog_facility", PGC_SIGHUP, LOGGING_WHERE,
gettext_noop("Sets the syslog \"facility\" to be used when syslog enabled."),
gettext_noop("Valid values are LOCAL0, LOCAL1, LOCAL2, LOCAL3, "
"LOCAL4, LOCAL5, LOCAL6, LOCAL7.")
},
- &Syslog_facility,
- "LOCAL0", assign_facility, NULL
+ &syslog_facility_str,
+ "LOCAL0", assign_syslog_facility, NULL
},
{
- {"syslog_ident", PGC_POSTMASTER, LOGGING_WHERE,
- gettext_noop("Sets the program name used to identify PostgreSQL messages "
- "in syslog."),
+ {"syslog_ident", PGC_SIGHUP, LOGGING_WHERE,
+ gettext_noop("Sets the program name used to identify PostgreSQL "
+ "messages in syslog."),
NULL
},
- &Syslog_ident,
- "postgres", NULL, NULL
+ &syslog_ident_str,
+ "postgres", assign_syslog_ident, NULL
},
#endif
#ifdef HAVE_SYSLOG
static const char *
-assign_facility(const char *facility, bool doit, GucSource source)
+assign_syslog_facility(const char *facility, bool doit, GucSource source)
{
+ int syslog_fac;
+
if (pg_strcasecmp(facility, "LOCAL0") == 0)
- return facility;
- if (pg_strcasecmp(facility, "LOCAL1") == 0)
- return facility;
- if (pg_strcasecmp(facility, "LOCAL2") == 0)
- return facility;
- if (pg_strcasecmp(facility, "LOCAL3") == 0)
- return facility;
- if (pg_strcasecmp(facility, "LOCAL4") == 0)
- return facility;
- if (pg_strcasecmp(facility, "LOCAL5") == 0)
- return facility;
- if (pg_strcasecmp(facility, "LOCAL6") == 0)
- return facility;
- if (pg_strcasecmp(facility, "LOCAL7") == 0)
- return facility;
- return NULL;
+ syslog_fac = LOG_LOCAL0;
+ else if (pg_strcasecmp(facility, "LOCAL1") == 0)
+ syslog_fac = LOG_LOCAL1;
+ else if (pg_strcasecmp(facility, "LOCAL2") == 0)
+ syslog_fac = LOG_LOCAL2;
+ else if (pg_strcasecmp(facility, "LOCAL3") == 0)
+ syslog_fac = LOG_LOCAL3;
+ else if (pg_strcasecmp(facility, "LOCAL4") == 0)
+ syslog_fac = LOG_LOCAL4;
+ else if (pg_strcasecmp(facility, "LOCAL5") == 0)
+ syslog_fac = LOG_LOCAL5;
+ else if (pg_strcasecmp(facility, "LOCAL6") == 0)
+ syslog_fac = LOG_LOCAL6;
+ else if (pg_strcasecmp(facility, "LOCAL7") == 0)
+ syslog_fac = LOG_LOCAL7;
+ else
+ return NULL; /* reject */
+
+ if (doit)
+ {
+ syslog_facility = syslog_fac;
+ set_syslog_parameters(syslog_ident_str ? syslog_ident_str : "postgres",
+ syslog_facility);
+ }
+
+ return facility;
}
-#endif
+
+static const char *
+assign_syslog_ident(const char *ident, bool doit, GucSource source)
+{
+ if (doit)
+ set_syslog_parameters(ident, syslog_facility);
+
+ return ident;
+}
+
+#endif /* HAVE_SYSLOG */
static const char *
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/elog.h,v 1.79 2005/06/10 16:23:10 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/utils/elog.h,v 1.80 2005/10/14 20:53:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
/* Other exported functions */
extern void DebugFileOpen(void);
extern char *unpack_sql_state(int sql_state);
+#ifdef HAVE_SYSLOG
+extern void set_syslog_parameters(const char *ident, int facility);
+#endif
/*
* Write errors to stderr (or by equal means when stderr is