X-Git-Url: http://git.code-monkey.de/?a=blobdiff_plain;f=src%2Flog.c;h=91ec5b023ed40e0de5d8e407553114fc0f9d78f7;hb=HEAD;hp=f4a0ea117233f9e8bdd7a97dc35861a6d3eaae8c;hpb=46d18f60766f997d0ca37c5937f58c0c06477932;p=umurmur.git diff --git a/src/log.c b/src/log.c index f4a0ea1..91ec5b0 100644 --- a/src/log.c +++ b/src/log.c @@ -1,5 +1,5 @@ -/* Copyright (C) 2009-2010, Martin Johansson - Copyright (C) 2005-2010, Thorvald Natvig +/* Copyright (C) 2009-2014, Martin Johansson + Copyright (C) 2005-2014, Thorvald Natvig All rights reserved. @@ -34,108 +34,227 @@ #include #include #include +#include +#include #include "log.h" +#include "conf.h" +#include "util.h" -#define BUFSIZE 254 +#define STRSIZE 254 -static bool_t termprint; +static bool_t termprint, init; +static FILE *logfile; + +static void openlogfile(const char *logfilename) +{ + int fd, flags; + logfile = fopen(logfilename, "a"); + if (logfile == NULL) { + Log_fatal("Failed to open log file '%s' for writing: %s\n", logfilename, strerror(errno)); + } + + /* Set the stream as line buffered */ + if (setvbuf(logfile, NULL, _IOLBF, 0) < 0) + Log_fatal("setvbuf() failed: %s\n", strerror(errno)); + + /* XXX - Is it neccessary/appropriate that logging to file is non-blocking? + * If not, there's a risk that execution blocks, meaning that voice blocks + * as well since uMurmur is single threaded by design. OTOH, what could + * cause a block? If the disk causes blocking, it is probably br0ken, but + * the log could be on a nfs or smb share, so let's set it up as + * non-blocking and we'll see what happens. + */ + fd = fileno(logfile); + flags = fcntl(fd, F_GETFL, 0); + fcntl(fd, F_SETFL, flags | O_NONBLOCK); +} + +static char *timestring(void) +{ + static char timebuf[32]; + time_t t; + struct tm *timespec; + + t= time(NULL); + timespec = localtime(&t); + strftime(timebuf, 32, "%b %e %T", timespec); + return timebuf; +} void Log_init(bool_t terminal) { + const char *logfilename; + termprint = terminal; - if (!termprint) - openlog("uMurmurd", LOG_PID, LOG_DAEMON); + if (termprint) + return; + + logfilename = getStrConf(LOGFILE); + if (logfilename != NULL) { + openlogfile(logfilename); + } + else openlog("uMurmurd", LOG_PID, LOG_DAEMON); + init = true; } void Log_free() { - if (!termprint) + if (termprint) + return; + else if (logfile) + fclose(logfile); + else closelog(); } - + +void Log_reset() +{ + const char *logfilename; + + if (logfile) { + logfilename = getStrConf(LOGFILE); + fclose(logfile); + openlogfile(logfilename); + } +} void logthis(const char *logstring, ...) { va_list argp; - char buf[BUFSIZE + 2]; - + char buf[STRSIZE + 1]; + va_start(argp, logstring); - vsnprintf(&buf[0], BUFSIZE, logstring, argp); + vsnprintf(&buf[0], STRSIZE, logstring, argp); va_end(argp); - strcat(buf, "\n"); + if (termprint) - fprintf(stderr, "%s", buf); /* XXX - other targets for logging */ + fprintf(stderr, "%s\n", buf); + else if (logfile) + fprintf(logfile, "%s %s\n", timestring(), buf); else - syslog(LOG_INFO, buf); + syslog(LOG_INFO, "%s", buf); } void Log_warn(const char *logstring, ...) { va_list argp; - char buf[BUFSIZE + 2]; + char buf[STRSIZE + 1]; int offset = 0; - + + if (termprint || logfile) + offset = sprintf(buf, "WARN: "); + va_start(argp, logstring); - offset = sprintf(buf, "WARN: "); - vsnprintf(&buf[offset], BUFSIZE - offset, logstring, argp); + vsnprintf(&buf[offset], STRSIZE - offset, logstring, argp); va_end(argp); - strcat(buf, "\n"); + if (termprint) - fprintf(stderr, "%s", buf); /* XXX - other targets for logging */ + fprintf(stderr, "%s\n", buf); + else if (logfile) + fprintf(logfile, "%s %s\n", timestring(), buf); else - syslog(LOG_WARNING, buf); + syslog(LOG_WARNING, "%s", buf); } void Log_info(const char *logstring, ...) { va_list argp; - char buf[BUFSIZE + 2]; + char buf[STRSIZE + 1]; int offset = 0; - + + if (termprint || logfile) + offset = sprintf(buf, "INFO: "); + va_start(argp, logstring); - offset = sprintf(buf, "INFO: "); - vsnprintf(&buf[offset], BUFSIZE - offset, logstring, argp); + vsnprintf(&buf[offset], STRSIZE - offset, logstring, argp); va_end(argp); - strcat(buf, "\n"); + if (termprint) - fprintf(stderr, "%s", buf); /* XXX - other targets for logging */ + fprintf(stderr, "%s\n", buf); + else if (logfile) + fprintf(logfile, "%s %s\n", timestring(), buf); else - syslog(LOG_INFO, buf); + syslog(LOG_INFO, "%s", buf); +} + +void Log_info_client(client_t *client, const char *logstring, ...) +{ + va_list argp; + char buf[STRSIZE + 1]; + int offset = 0; + + if (termprint || logfile) + offset = sprintf(buf, "INFO: "); + + va_start(argp, logstring); + offset += vsnprintf(&buf[offset], STRSIZE - offset, logstring, argp); + va_end(argp); + + char *clientAddressString = Util_clientAddressToString(client); + offset += snprintf(&buf[offset], STRSIZE - offset, " - [%d] %s@%s:%d", + client->sessionId, + client->username == NULL ? "" : client->username, + clientAddressString, + Util_clientAddressToPortTCP(client)); + free(clientAddressString); + + if (termprint) + fprintf(stderr, "%s\n", buf); + else if (logfile) + fprintf(logfile, "%s %s\n", timestring(), buf); + else + syslog(LOG_INFO, "%s", buf); } #ifdef DEBUG void Log_debug(const char *logstring, ...) { va_list argp; - char buf[BUFSIZE + 2]; + char buf[STRSIZE + 1]; int offset = 0; - + + if (termprint || logfile) + offset = sprintf(buf, "DEBUG: "); + va_start(argp, logstring); - offset = sprintf(buf, "DEBUG: "); - vsnprintf(&buf[offset], BUFSIZE - offset, logstring, argp); + vsnprintf(&buf[offset], STRSIZE - offset, logstring, argp); va_end(argp); - strcat(buf, "\n"); if (termprint) - fprintf(stderr, "%s", buf); /* XXX - other targets for logging */ + fprintf(stderr, "%s\n", buf); + else if (logfile) + fprintf(logfile, "%s %s\n", timestring(), buf); else - syslog(LOG_DEBUG, buf); + syslog(LOG_DEBUG, "%s", buf); } #endif void Log_fatal(const char *logstring, ...) { va_list argp; - char buf[BUFSIZE + 2]; + char buf[STRSIZE + 1]; int offset = 0; + + if (termprint || logfile) + offset = sprintf(buf, "FATAL: "); + va_start(argp, logstring); - offset = sprintf(buf, "FATAL: "); - vsnprintf(&buf[offset], BUFSIZE - offset, logstring, argp); + vsnprintf(&buf[offset], STRSIZE - offset, logstring, argp); va_end(argp); - strcat(buf, "\n"); + if (termprint) - fprintf(stderr, "%s", buf); /* XXX - other targets for logging */ - else - syslog(LOG_CRIT, buf); + fprintf(stderr, "%s\n", buf); + else if (logfile) + fprintf(logfile, "%s %s\n", timestring(), buf); + else { /* If logging subsystem is not initialized, fall back to stderr + + * syslog logging for fatal errors. + */ + if (!init) { + openlog("uMurmurd", LOG_PID, LOG_DAEMON); + fprintf(stderr, "%s\n", buf); + } + syslog(LOG_CRIT, "%s", buf); + } + exit(1); }