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"); |