Hi,
Here is the rewritten patch that add syslog support to PgPool with all
your great suggestions applied.
This patch has been created from the current cvs HEAD branch.
This patch also modify the comment about logdir configuraion directive.
"Logging directory" has been change into "PgPool status file logging
directory"
Feel free to apply or remove it. It just seems to me that 'logdir' =>
"Logging directory" is very confusing and false as this directive is
only used to save the pgpool_status file. It will certainly be better to
rename this directive, but for the moment just changing the comment help
a lot for understanding and preserve backward compatibility.
Regards,
Le 26/12/2010 04:30, Tatsuo Ishii a écrit :
>> Here are some comments after trying this patch.
>>
>> First, I splitted the patch in two patches, so to have one patch per
>> functionality. You'll find the first one, syslog, attached.
>>
>> Le 21/12/2010 15:11, Gilles Darold a écrit :
>>> [...]
>>> Syslog patch :
>>>
>>> It adds two configuration directives : "logsyslog = true|false" and
>>> "logfacility = 'LOCAL0'"
>>>
>> I would much prefer to have the same name than PostgreSQL options. No
>> logsyslog, but a log_destination which accepts stderr and syslog. No
>> logfacility, but syslog_facility.
> Me too.
>
>>> If 'logsyslog' is enabled, messages are sent to syslog (through
>>> pool_error.c) just after the call of pool_get_config() in main.c.
>>>
>>> Syslog ident it hard coded to "pgpool".
>>>
>> It shouldn't be hardcoded. I would better have a syslog_ident parameter.
> Right.
>
>>> Connection to syslog is closed from pool_shmem_exit() in
>>> pool_shmem.c because this is the only method always called at exit.
>>> A better place should be in main.c but it has to be repeated so many
>>> time so that I choose this lazy place :-)
>>>
>> Seems enough for me.
> I think so too.
>
>>> Samples configuration files has been patched too.
>>>
>> Apart from the options name, and the missing option, I have a big issue
>> with the FACILITY variable. Where do you initialize it? AFAICT, nowhere.
>>
>> BTW, there is no reason to set only INIT_CONFIG for the facility
>> parameter. I should be INIT_CONFIG|RELOAD_CONFIG.
>>
>> So, all in all, I like this patch but it still needs some work. Gilles,
>> could you work on the few issues I talked about? and send another patch
>> (and this time only on syslog). If you can't, I'll do it.
>>
>> Now, I'll work on your second patch.
>>
>> Thanks.
>>
>>
>> --
>> Guillaume
>> http://www.postgresql.fr
>> http://dalibo.com
--
Gilles Darold
Administrateur de bases de données
http://dalibo.com - http://dalibo.org
diff -r -u pgpool-II/main.c pgpool-II-syslog/main.c
--- pgpool-II/main.c 2010-11-12 06:47:01.000000000 +0100
+++ pgpool-II-syslog/main.c 2010-12-27 09:07:22.922532860 +0100
@@ -314,6 +314,17 @@
}
/*
+ * Open syslog connection if required
+ */
+ if (!strcmp(pool_config->log_destination, "syslog")) {
+ openlog(pool_config->syslog_ident, LOG_PID|LOG_NDELAY|LOG_NOWAIT, pool_config->syslog_facility);
+ /* set a flag to allow pool_error.c to begin writing to syslog
+ instead of stdout now that pool_get_config() is done */
+ pool_config->logsyslog = 1;
+ }
+
+
+ /*
* Locate pool_passwd
*/
if (strcmp("", pool_config->pool_passwd))
diff -r -u pgpool-II/pgpool.conf.sample pgpool-II-syslog/pgpool.conf.sample
--- pgpool-II/pgpool.conf.sample 2010-10-30 13:12:42.000000000 +0200
+++ pgpool-II-syslog/pgpool.conf.sample 2010-12-27 09:11:48.918532813 +0100
@@ -53,9 +53,18 @@
# 0 means no timeout.
authentication_timeout = 60
-# Logging directory
+# PgPool status file logging directory
logdir = '/tmp'
+# Where to Log. Valid values are stderr and syslog. Default to stderr.
+log_destination = 'stderr'
+
+# Select syslog local facility for logging. Default: LOCAL0
+syslog_facility = 'LOCAL0'
+
+# Set the syslog program ident string. Default to 'pgpool'
+syslog_ident = 'pgpool'
+
# pid file name
pid_file_name = '/var/run/pgpool/pgpool.pid'
diff -r -u pgpool-II/pgpool.conf.sample-master-slave pgpool-II-syslog/pgpool.conf.sample-master-slave
--- pgpool-II/pgpool.conf.sample-master-slave 2010-10-30 13:12:43.000000000 +0200
+++ pgpool-II-syslog/pgpool.conf.sample-master-slave 2010-12-27 09:11:29.126532627 +0100
@@ -53,9 +53,18 @@
# 0 means no timeout.
authentication_timeout = 60
-# Logging directory
+# PgPool status file logging directory
logdir = '/tmp'
+# Where to Log. Valid values are stderr and syslog. Default to stderr.
+log_destination = 'stderr'
+
+# Select syslog local facility for logging. Default: LOCAL0
+syslog_facility = 'LOCAL0'
+
+# Set the syslog program ident string. Default to 'pgpool'
+syslog_ident = 'pgpool'
+
# pid file name
pid_file_name = '/var/run/pgpool/pgpool.pid'
diff -r -u pgpool-II/pgpool.conf.sample-replication pgpool-II-syslog/pgpool.conf.sample-replication
--- pgpool-II/pgpool.conf.sample-replication 2010-10-30 13:12:43.000000000 +0200
+++ pgpool-II-syslog/pgpool.conf.sample-replication 2010-12-27 09:11:15.306032795 +0100
@@ -53,9 +53,18 @@
# 0 means no timeout.
authentication_timeout = 60
-# Logging directory
+# PgPool status file logging directory
logdir = '/tmp'
+# Where to Log. Valid values are stderr and syslog. Default to stderr.
+log_destination = 'stderr'
+
+# Select syslog local facility for logging. Default: LOCAL0
+syslog_facility = 'LOCAL0'
+
+# Set the syslog program ident string. Default to 'pgpool'
+syslog_ident = 'pgpool'
+
# pid file name
pid_file_name = '/var/run/pgpool/pgpool.pid'
diff -r -u pgpool-II/pgpool.conf.sample-stream pgpool-II-syslog/pgpool.conf.sample-stream
--- pgpool-II/pgpool.conf.sample-stream 2010-10-30 13:12:43.000000000 +0200
+++ pgpool-II-syslog/pgpool.conf.sample-stream 2010-12-27 09:10:55.582532933 +0100
@@ -53,9 +53,18 @@
# 0 means no timeout.
authentication_timeout = 60
-# Logging directory
+# PgPool status file logging directory
logdir = '/tmp'
+# Where to Log. Valid values are stderr and syslog. Default to stderr.
+log_destination = 'stderr'
+
+# Select syslog local facility for logging. Default: LOCAL0
+syslog_facility = 'LOCAL0'
+
+# Set the syslog program ident string. Default to 'pgpool'
+syslog_ident = 'pgpool'
+
# pid file name
pid_file_name = '/var/run/pgpool/pgpool.pid'
diff -r -u pgpool-II/pool_config.c pgpool-II-syslog/pool_config.c
--- pgpool-II/pool_config.c 2010-12-26 01:58:36.000000000 +0100
+++ pgpool-II-syslog/pool_config.c 2010-12-27 09:19:00.518032845 +0100
@@ -1871,6 +1871,10 @@
pool_config->child_max_connections = 0;
pool_config->authentication_timeout = 60;
pool_config->logdir = DEFAULT_LOGDIR;
+ pool_config->log_destination = "stderr";
+ pool_config->logsyslog = 0;
+ pool_config->syslog_facility = LOG_LOCAL0;
+ pool_config->syslog_ident = DEFAULT_SYSLOG_IDENT;
pool_config->pid_file_name = DEFAULT_PID_FILE_NAME;
pool_config->log_statement = 0;
pool_config->log_per_node_statement = 0;
@@ -2303,6 +2307,61 @@
}
pool_config->logdir = str;
}
+ else if (!strcmp(key, "log_destination") &&
+ CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
+ {
+ char *str;
+
+ if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
+ {
+ PARSE_ERROR();
+ fclose(fd);
+ return(-1);
+ }
+ str = extract_string(yytext, token);
+ if (str == NULL)
+ {
+ fclose(fd);
+ return(-1);
+ }
+ pool_config->log_destination = str;
+ }
+ else if (!strcmp(key, "syslog_facility") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
+ {
+ char *str;
+
+ if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
+ {
+ PARSE_ERROR();
+ fclose(fd);
+ return(-1);
+ }
+ str = extract_string(yytext, token);
+ if (str == NULL)
+ {
+ fclose(fd);
+ return(-1);
+ }
+ pool_config->syslog_facility = set_syslog_facility(str);
+ }
+ else if (!strcmp(key, "syslog_ident") && CHECK_CONTEXT(INIT_CONFIG, context))
+ {
+ char *str;
+
+ if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
+ {
+ PARSE_ERROR();
+ fclose(fd);
+ return(-1);
+ }
+ str = extract_string(yytext, token);
+ if (str == NULL)
+ {
+ fclose(fd);
+ return(-1);
+ }
+ pool_config->syslog_ident = str;
+ }
else if (!strcmp(key, "pid_file_name") && CHECK_CONTEXT(INIT_CONFIG, context))
{
char *str;
@@ -3634,4 +3693,42 @@
}
#endif
+/* Use to set the syslog facility level if logsyslog is activated */
+int set_syslog_facility(char *value)
+{
+ int facility = LOG_LOCAL0;
+
+ if (value == NULL)
+ return facility;
+
+ if (strncmp(value, "LOCAL", 5) == 0 && strlen(value) == 6) {
+ switch (value[5]) {
+ case '0':
+ facility = LOG_LOCAL0;
+ break;
+ case '1':
+ facility = LOG_LOCAL1;
+ break;
+ case '2':
+ facility = LOG_LOCAL2;
+ break;
+ case '3':
+ facility = LOG_LOCAL3;
+ break;
+ case '4':
+ facility = LOG_LOCAL4;
+ break;
+ case '5':
+ facility = LOG_LOCAL5;
+ break;
+ case '6':
+ facility = LOG_LOCAL6;
+ break;
+ case '7':
+ facility = LOG_LOCAL7;
+ break;
+ }
+ }
+ return facility;
+}
diff -r -u pgpool-II/pool_config.h pgpool-II-syslog/pool_config.h
--- pgpool-II/pool_config.h 2010-12-26 01:58:36.000000000 +0100
+++ pgpool-II-syslog/pool_config.h 2010-12-27 09:23:14.986033285 +0100
@@ -66,6 +66,9 @@
int authentication_timeout; /* maximum time in seconds to complete client authentication */
int max_pool; /* max # of connection pool per child */
char *logdir; /* logging directory */
+ char *log_destination; /* log destination: stderr or syslog */
+ int syslog_facility; /* syslog facility: LOCAL0, LOCAL1, ... */
+ char *syslog_ident; /* syslog ident string: pgpool */
char *pid_file_name; /* pid file name */
char *backend_socket_dir; /* Unix domain socket directory for the PostgreSQL server */
int replication_mode; /* replication mode */
@@ -157,6 +160,7 @@
int num_reset_queries; /* number of queries in reset_query_list */
int num_white_function_list; /* number of functions in white_function_list */
int num_black_function_list; /* number of functions in black_function_list */
+ int logsyslog; /* flag used to start logging to syslog */
/* ssl configuration */
int ssl; /* if non 0, activate ssl support (frontend+backend) */
@@ -182,6 +186,9 @@
extern int pool_get_config(char *confpath, POOL_CONFIG_CONTEXT context);
extern int eval_logical(char *str);
+/* method use for syslog support */
+extern int set_syslog_facility (char *);
+
/* methods used for regexp support */
extern int add_regex_pattern(char *type, char *s);
extern int growPatternArray (RegPattern item);
diff -r -u pgpool-II/pool_config.l pgpool-II-syslog/pool_config.l
--- pgpool-II/pool_config.l 2010-12-26 01:58:36.000000000 +0100
+++ pgpool-II-syslog/pool_config.l 2010-12-27 09:35:13.426532765 +0100
@@ -146,6 +146,10 @@
pool_config->child_max_connections = 0;
pool_config->authentication_timeout = 60;
pool_config->logdir = DEFAULT_LOGDIR;
+ pool_config->logsyslog = 0;
+ pool_config->log_destination = "stderr";
+ pool_config->syslog_facility = LOG_LOCAL0;
+ pool_config->syslog_ident = "pgpool";
pool_config->pid_file_name = DEFAULT_PID_FILE_NAME;
pool_config->log_statement = 0;
pool_config->log_per_node_statement = 0;
@@ -578,6 +582,63 @@
}
pool_config->logdir = str;
}
+ else if (!strcmp(key, "log_destination") &&
+ CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
+ {
+ char *str;
+
+ if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
+ {
+ PARSE_ERROR();
+ fclose(fd);
+ return(-1);
+ }
+ str = extract_string(yytext, token);
+ if (str == NULL)
+ {
+ fclose(fd);
+ return(-1);
+ }
+ pool_config->log_destination = str;
+
+ }
+ else if (!strcmp(key, "syslog_facility") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
+ {
+ char *str;
+
+ if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
+ {
+ PARSE_ERROR();
+ fclose(fd);
+ return(-1);
+ }
+ str = extract_string(yytext, token);
+ if (str == NULL)
+ {
+ fclose(fd);
+ return(-1);
+ }
+ pool_config->syslog_facility = set_syslog_facility(str);
+ }
+ else if (!strcmp(key, "syslog_ident") &&
+ CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
+ {
+ char *str;
+
+ if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
+ {
+ PARSE_ERROR();
+ fclose(fd);
+ return(-1);
+ }
+ str = extract_string(yytext, token);
+ if (str == NULL)
+ {
+ fclose(fd);
+ return(-1);
+ }
+ pool_config->syslog_ident = str;
+ }
else if (!strcmp(key, "pid_file_name") && CHECK_CONTEXT(INIT_CONFIG, context))
{
char *str;
@@ -1917,3 +1978,42 @@
}
#endif
+/* Use to set the syslog facility level if logsyslog is activated */
+int set_syslog_facility(char *value)
+{
+ int facility = LOG_LOCAL0;
+
+ if (value == NULL)
+ return facility;
+
+ if (strncmp(value, "LOCAL", 5) == 0 && strlen(value) == 6) {
+ switch (value[5]) {
+ case '0':
+ facility = LOG_LOCAL0;
+ break;
+ case '1':
+ facility = LOG_LOCAL1;
+ break;
+ case '2':
+ facility = LOG_LOCAL2;
+ break;
+ case '3':
+ facility = LOG_LOCAL3;
+ break;
+ case '4':
+ facility = LOG_LOCAL4;
+ break;
+ case '5':
+ facility = LOG_LOCAL5;
+ break;
+ case '6':
+ facility = LOG_LOCAL6;
+ break;
+ case '7':
+ facility = LOG_LOCAL7;
+ break;
+ }
+ }
+ return facility;
+}
+
diff -r -u pgpool-II/pool_error.c pgpool-II-syslog/pool_error.c
--- pgpool-II/pool_error.c 2010-08-10 17:08:32.000000000 +0200
+++ pgpool-II-syslog/pool_error.c 2010-12-27 09:37:36.498532942 +0100
@@ -50,6 +50,13 @@
#else
int oldmask;
#endif
+ /* Write error message to syslog */
+ if (pool_config->logsyslog == 1) {
+ va_start(ap, fmt);
+ vsyslog(pool_config->syslog_facility | LOG_ERR, fmt, ap);
+ va_end(ap);
+ return;
+ }
POOL_SETMASK2(&BlockSig, &oldmask);
@@ -105,6 +112,13 @@
if (pool_config->debug_level <= 0)
return;
}
+ /* Write debug message to syslog */
+ if (pool_config->logsyslog == 1) {
+ va_start(ap, fmt);
+ vsyslog(pool_config->syslog_facility | LOG_DEBUG, fmt, ap);
+ va_end(ap);
+ return;
+ }
POOL_SETMASK2(&BlockSig, &oldmask);
@@ -149,6 +163,13 @@
#else
int oldmask;
#endif
+ /* Write log message to syslog */
+ if (pool_config->logsyslog == 1) {
+ va_start(ap, fmt);
+ vsyslog(pool_config->syslog_facility | LOG_NOTICE, fmt, ap);
+ va_end(ap);
+ return;
+ }
POOL_SETMASK2(&BlockSig, &oldmask);
diff -r -u pgpool-II/pool.h pgpool-II-syslog/pool.h
--- pgpool-II/pool.h 2010-11-12 09:09:32.000000000 +0100
+++ pgpool-II-syslog/pool.h 2010-12-27 09:39:30.838532865 +0100
@@ -43,6 +43,8 @@
#include <openssl/err.h>
#endif
+#include <syslog.h>
+
/* undef this if you have problems with non blocking accept() */
#define NONE_BLOCK
@@ -69,6 +71,9 @@
/* status file name */
#define STATUS_FILE_NAME "pgpool_status"
+/* default string used to identify pgpool on syslog output */
+#define DEFAULT_SYSLOG_IDENT "pgpool"
+
typedef enum {
POOL_CONTINUE = 0,
POOL_IDLE,
diff -r -u pgpool-II/pool_process_reporting.c pgpool-II-syslog/pool_process_reporting.c
--- pgpool-II/pool_process_reporting.c 2010-11-28 15:57:17.000000000 +0100
+++ pgpool-II-syslog/pool_process_reporting.c 2010-12-27 09:42:17.738532851 +0100
@@ -173,7 +173,22 @@
strncpy(status[i].name, "logdir", POOLCONFIG_MAXNAMELEN);
snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->logdir);
- strncpy(status[i].desc, "logging directory", POOLCONFIG_MAXDESCLEN);
+ strncpy(status[i].desc, "PgPool status file logging directory", POOLCONFIG_MAXDESCLEN);
+ i++;
+
+ strncpy(status[i].name, "log_destination", POOLCONFIG_MAXNAMELEN);
+ snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->log_destination);
+ strncpy(status[i].desc, "logging destination", POOLCONFIG_MAXDESCLEN);
+ i++;
+
+ strncpy(status[i].name, "syslog_facility", POOLCONFIG_MAXNAMELEN);
+ snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "LOCAL%d", (pool_config->syslog_facility/8) - 16);
+ strncpy(status[i].desc, "syslog local faclity", POOLCONFIG_MAXDESCLEN);
+ i++;
+
+ strncpy(status[i].name, "syslog_ident", POOLCONFIG_MAXNAMELEN);
+ snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->syslog_ident);
+ strncpy(status[i].desc, "syslog program ident string", POOLCONFIG_MAXDESCLEN);
i++;
strncpy(status[i].name, "pid_file_name", POOLCONFIG_MAXNAMELEN);
diff -r -u pgpool-II/pool_shmem.c pgpool-II-syslog/pool_shmem.c
--- pgpool-II/pool_shmem.c 2009-08-22 06:04:21.000000000 +0200
+++ pgpool-II-syslog/pool_shmem.c 2010-12-27 09:42:48.686532623 +0100
@@ -127,6 +127,8 @@
pool_shmem_exit(int code)
{
shmem_exit(code);
+ /* Close syslog connection here as this function is always called on exit */
+ closelog();
}
/*
_______________________________________________
Pgpool-hackers mailing list
[email protected]
http://pgfoundry.org/mailman/listinfo/pgpool-hackers