X-Git-Url: https://tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=src%2Flogger.c;h=5de88bdeb5a9321eb09bd3182904de80ec54f0a3;hp=effcb7887b883f6259eddf4e72ef3161aa2e1e70;hb=ff306f0cdaedb50de1472e7c1fb55de922a6ca60;hpb=075e6828a7533e7daa790225f17aa6bb39703278 diff --git a/src/logger.c b/src/logger.c index effcb788..5de88bde 100644 --- a/src/logger.c +++ b/src/logger.c @@ -13,17 +13,18 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - $Id$ + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "system.h" #include "conf.h" +#include "meta.h" #include "logger.h" +#include "connection.h" +#include "control_common.h" debug_t debug_level = DEBUG_NOTHING; static logmode_t logmode = LOGMODE_STDERR; @@ -34,6 +35,7 @@ static FILE *logfile = NULL; static HANDLE loghandle = NULL; #endif static const char *logident = NULL; +bool logcontrol = false; void openlogger(const char *ident, logmode_t mode) { logident = ident; @@ -46,14 +48,18 @@ void openlogger(const char *ident, logmode_t mode) { case LOGMODE_FILE: logpid = getpid(); logfile = fopen(logfilename, "a"); - if(!logfile) + if(!logfile) { + fprintf(stderr, "Could not open log file %s: %s\n", logfilename, strerror(errno)); logmode = LOGMODE_NULL; + } break; case LOGMODE_SYSLOG: #ifdef HAVE_MINGW loghandle = RegisterEventSource(NULL, logident); - if(!loghandle) + if(!loghandle) { + fprintf(stderr, "Could not open log handle!"); logmode = LOGMODE_NULL; + } break; #else #ifdef HAVE_SYSLOG_H @@ -66,50 +72,88 @@ void openlogger(const char *ident, logmode_t mode) { } } -void logger(int priority, const char *format, ...) { +void reopenlogger() { + if(logmode != LOGMODE_FILE) + return; + + fflush(logfile); + FILE *newfile = fopen(logfilename, "a"); + if(!newfile) { + logger(DEBUG_ALWAYS, LOG_ERR, "Unable to reopen log file %s: %s", logfilename, strerror(errno)); + return; + } + fclose(logfile); + logfile = newfile; +} + +void logger(int level, int priority, const char *format, ...) { va_list ap; + int len; + char timestr[32] = ""; + char message[1024] = ""; + time_t now; + static bool suppress = false; + + // Bail out early if there is nothing to do. + if(suppress) + return; + + if(!logcontrol && (level > debug_level || logmode == LOGMODE_NULL)) + return; va_start(ap, format); + len = vsnprintf(message, sizeof message, format, ap); + va_end(ap); - switch(logmode) { - case LOGMODE_STDERR: - vfprintf(stderr, format, ap); - fprintf(stderr, "\n"); - fflush(stderr); - break; - case LOGMODE_FILE: - fprintf(logfile, "%ld %s[%ld]: ", time(NULL), logident, (long)logpid); - vfprintf(logfile, format, ap); - fprintf(logfile, "\n"); - fflush(logfile); - break; - case LOGMODE_SYSLOG: + if(len > 0 && len < sizeof message && message[len - 1] == '\n') + message[len - 1] = 0; + + if(level <= debug_level) { + switch(logmode) { + case LOGMODE_STDERR: + fprintf(stderr, "%s\n", message); + fflush(stderr); + break; + case LOGMODE_FILE: + now = time(NULL); + strftime(timestr, sizeof timestr, "%Y-%m-%d %H:%M:%S", localtime(&now)); + fprintf(logfile, "%s %s[%ld]: %s\n", timestr, logident, (long)logpid, message); + fflush(logfile); + break; + case LOGMODE_SYSLOG: #ifdef HAVE_MINGW - { - char message[4096]; - char *messages[] = {message}; - vsnprintf(message, sizeof message, format, ap); - ReportEvent(loghandle, priority, 0, 0, NULL, 1, 0, messages, NULL); - } + { + const char *messages[] = {message}; + ReportEvent(loghandle, priority, 0, 0, NULL, 1, 0, messages, NULL); + } #else #ifdef HAVE_SYSLOG_H -#ifdef HAVE_VSYSLOG - vsyslog(priority, format, ap); -#else - { - char message[4096]; - vsnprintf(message, sizeof message, format, ap); syslog(priority, "%s", message); - } -#endif - break; #endif #endif - case LOGMODE_NULL: - break; + break; + case LOGMODE_NULL: + break; + } } - va_end(ap); + if(logcontrol) { + suppress = true; + logcontrol = false; + for(list_node_t *node = connection_list->head, *next; node; node = next) { + next = node->next; + connection_t *c = node->data; + if(!c->status.log) + continue; + logcontrol = true; + if(level > (c->outcompression >= 0 ? c->outcompression : debug_level)) + continue; + int len = strlen(message); + if(send_request(c, "%d %d %d", CONTROL, REQ_LOG, len)) + send_meta(c, message, len); + } + suppress = false; + } } void closelogger(void) {