[Sheepdog] [PATCH] support specifying output log file
FUJITA Tomonori
fujita.tomonori at lab.ntt.co.jp
Wed Apr 7 05:41:36 CEST 2010
On Tue, 6 Apr 2010 14:12:11 +0900
MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp> wrote:
> When running more than one collies in the same machine, it is
> confusing to send all the output to the syslog.
>
> You can specify the output file with -o option.
>
> $ collie -o /tmp/sdog /store
> (log messages are sent to /tmp/sdog)
>
> $ script/start-sheepdog -n=3 -o=/tmp/sdog- -d=/store
> (log messages are sent to /tmp/sdog-0, /tmp/sdog-1, and /tmp/sdog-2)
>
> Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
> ---
> collie/collie.c | 14 ++++++++++++--
> include/logger.h | 3 ++-
> lib/logger.c | 21 +++++++++++++++++----
> script/start-sheepdog | 15 +++++++++++----
> 4 files changed, 42 insertions(+), 11 deletions(-)
>
> diff --git a/collie/collie.c b/collie/collie.c
> index 8367487..0acc2d2 100644
> --- a/collie/collie.c
> +++ b/collie/collie.c
> @@ -25,12 +25,13 @@ static struct option const long_options[] = {
> {"port", required_argument, 0, 'p'},
> {"foreground", no_argument, 0, 'f'},
> {"loglevel", required_argument, 0, 'l'},
> + {"outfile", required_argument, 0, 'o'},
> {"debug", no_argument, 0, 'd'},
> {"help", no_argument, 0, 'h'},
> {0, 0, 0, 0},
> };
>
> -static char *short_options = "p:fl:dh";
> +static char *short_options = "p:fl:o:dh";
>
> static void usage(int status)
> {
> @@ -44,6 +45,7 @@ Sheepdog Daemon, version %s\n\
> -p, --port specify the listen port number\n\
> -f, --foreground make the program run in the foreground\n\
> -l, --loglevel specify the message level printed by default\n\
> + -o, --outfile location for output (defaults to the system log)\n\
> -d, --debug print debug messages\n\
> -h, --help display this help and exit\n\
> ", SD_VERSION);
> @@ -60,6 +62,7 @@ int main(int argc, char **argv)
> char *dir = DEFAULT_OBJECT_DIR;
> int is_daemon = 1;
> int log_level = LOG_INFO;
> + char *out_file = NULL;
>
> while ((ch = getopt_long(argc, argv, short_options, long_options,
> &longindex)) >= 0) {
> @@ -72,6 +75,12 @@ int main(int argc, char **argv)
> break;
> case 'l':
> log_level = atoi(optarg);
> + break;
> + case 'o':
> + out_file = optarg;
> + if (strcmp(out_file, "syslog") == 0)
> + out_file = NULL;
I don't think we need this. There is no point to provide two different
ways to do the same thing.
I also think that it's better to avoid syslog by default.
anyway, here's a patch that addresses the above issues.
diff --git a/collie/collie.c b/collie/collie.c
index 669e894..0ae56c2 100644
--- a/collie/collie.c
+++ b/collie/collie.c
@@ -25,12 +25,13 @@ static struct option const long_options[] = {
{"port", required_argument, 0, 'p'},
{"foreground", no_argument, 0, 'f'},
{"loglevel", required_argument, 0, 'l'},
+ {"outfile", required_argument, 0, 'o'},
{"debug", no_argument, 0, 'd'},
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0},
};
-static char *short_options = "p:fl:dh";
+static char *short_options = "p:fl:o:dh";
static void usage(int status)
{
@@ -44,6 +45,7 @@ Sheepdog Daemon, version %s\n\
-p, --port specify the listen port number\n\
-f, --foreground make the program run in the foreground\n\
-l, --loglevel specify the message level printed by default\n\
+ -o, --outfile location for output (defaults to the system log)\n\
-d, --debug print debug messages\n\
-h, --help display this help and exit\n\
", SD_VERSION);
@@ -60,6 +62,7 @@ int main(int argc, char **argv)
char *dir = DEFAULT_OBJECT_DIR;
int is_daemon = 1;
int log_level = LOG_INFO;
+ char *out_file = NULL;
while ((ch = getopt_long(argc, argv, short_options, long_options,
&longindex)) >= 0) {
@@ -72,6 +75,10 @@ int main(int argc, char **argv)
break;
case 'l':
log_level = atoi(optarg);
+ break;
+ case 'o':
+ out_file = optarg;
+ break;
case 'd':
/* removed soon. use loglevel instead */
log_level = LOG_DEBUG;
@@ -88,7 +95,8 @@ int main(int argc, char **argv)
if (optind != argc)
dir = argv[optind];
- ret = log_init(program_name, LOG_SPACE_SIZE, is_daemon, log_level);
+ ret = log_init(program_name, LOG_SPACE_SIZE, is_daemon, log_level,
+ out_file);
if (ret)
exit(1);
diff --git a/include/logger.h b/include/logger.h
index 7fa4cf1..6b4a399 100644
--- a/include/logger.h
+++ b/include/logger.h
@@ -55,9 +55,10 @@ struct logarea {
char *buff;
int semid;
union semun semarg;
+ int fd;
};
-extern int log_init(char * progname, int size, int daemon, int level);
+extern int log_init(char * progname, int size, int daemon, int level, char *outfile);
extern void log_close (void);
extern void dump_logmsg (void *);
extern void log_write(int prio, const char *func, int line, const char *fmt, ...)
diff --git a/lib/logger.c b/lib/logger.c
index 817fd0e..afcace0 100644
--- a/lib/logger.c
+++ b/lib/logger.c
@@ -26,6 +26,7 @@
#include <syslog.h>
#include <signal.h>
#include <errno.h>
+#include <time.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/stat.h>
@@ -132,6 +133,8 @@ static int logarea_init (int size)
static void free_logarea (void)
{
+ if (la->fd >= 0)
+ close(la->fd);
semctl(la->semid, 0, IPC_RMID, la->semarg);
shmdt(la->buff);
shmdt(la->start);
@@ -176,6 +179,18 @@ static int log_enqueue(int prio, const char *func, int line, const char *fmt,
}
p = buff;
+
+ if (la->fd != -1) {
+ time_t t;
+ struct tm *tmp;
+
+ t = time(NULL);
+ tmp = localtime(&t);
+
+ strftime(p, MAX_MSG_SIZE, "%b %2d %I:%M:%S ", tmp);
+ p += strlen(p);
+ }
+
snprintf(p, MAX_MSG_SIZE, "%s(%d) ", func, line);
p += strlen(p);
@@ -260,7 +275,10 @@ static void log_syslog (void * buff)
{
struct logmsg * msg = (struct logmsg *)buff;
- syslog(msg->prio, "%s", (char *)&msg->str);
+ if (la->fd >= 0)
+ write(la->fd, (char *)&msg->str, strlen((char *)&msg->str));
+ else
+ syslog(msg->prio, "%s", (char *)&msg->str);
}
static void dolog(int prio, const char *func, int line, const char *fmt, va_list ap)
@@ -342,7 +360,7 @@ static void log_flush(void)
}
}
-int log_init(char *program_name, int size, int daemon, int level)
+int log_init(char *program_name, int size, int daemon, int level, char *outfile)
{
log_level = level;
@@ -354,8 +372,15 @@ int log_init(char *program_name, int size, int daemon, int level)
struct sigaction sa_new;
int fd;
- openlog(log_name, 0, LOG_DAEMON);
- setlogmask (LOG_UPTO (LOG_DEBUG));
+ if (outfile) {
+ fd = open(outfile, O_CREAT | O_RDWR | O_APPEND, 0644);
+ if (fd < 0)
+ syslog(LOG_ERR, "failed to open %s\n", outfile);
+ } else {
+ fd = -1;
+ openlog(log_name, 0, LOG_DAEMON);
+ setlogmask (LOG_UPTO (LOG_DEBUG));
+ }
if (logarea_init(size)) {
syslog(LOG_ERR, "failed to initialize the logger\n");
@@ -363,6 +388,7 @@ int log_init(char *program_name, int size, int daemon, int level)
}
la->active = 1;
+ la->fd = fd;
pid = fork();
if (pid < 0) {
syslog(LOG_ERR, "fail to fork the logger\n");
More information about the sheepdog
mailing list