From b8934971516d69086cf693a1a51acf649930ee64 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Thu, 4 Jan 2007 18:02:32 +0000 Subject: syslogd: stop doing open/fstat/lseek/close on _every_ write (still doing it if more than a second passed in between). Costs ~40 bytes. --- sysklogd/syslogd.c | 117 +++++++++++++++++++++++++++++------------------------ 1 file changed, 65 insertions(+), 52 deletions(-) (limited to 'sysklogd') diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index f4644f218..7edce7a0a 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c @@ -29,6 +29,7 @@ static char *dev_log_name; /* Path for the file where all log messages are written */ static const char *logFilePath = "/var/log/messages"; +static int logFD = -1; /* interval between marks in seconds */ static int markInterval = 20 * 60; @@ -41,9 +42,11 @@ static char localHostName[64]; #if ENABLE_FEATURE_ROTATE_LOGFILE /* max size of message file before being rotated */ -static int logFileSize = 200 * 1024; +static unsigned logFileSize = 200 * 1024; /* number of rotated message files */ -static int logFileRotate = 1; +static unsigned logFileRotate = 1; +static unsigned curFileSize; +static smallint isRegular; #endif #if ENABLE_FEATURE_REMOTE_LOG @@ -256,7 +259,10 @@ void log_to_shmem(const char *msg); /* Print a message to the log file. */ static void log_locally(char *msg) { - int fd, len = strlen(msg); + static time_t last; + + struct flock fl; + int len = strlen(msg); #if ENABLE_FEATURE_IPC_SYSLOG if ((option_mask32 & OPT_circularlog) && shbuf) { @@ -264,62 +270,69 @@ static void log_locally(char *msg) return; } #endif - - again: - fd = device_open(logFilePath, O_WRONLY | O_CREAT + if (logFD >= 0) { + time_t cur; + time(&cur); + if (last != cur) { + last = cur; /* reopen log file every second */ + close(logFD); + goto reopen; + } + } else { + struct stat statf; + reopen: + logFD = device_open(logFilePath, O_WRONLY | O_CREAT | O_NOCTTY | O_APPEND | O_NONBLOCK); - if (fd >= 0) { - struct flock fl; + if (logFD < 0) { + /* cannot open logfile? - print to /dev/console then */ + int fd = device_open(_PATH_CONSOLE, O_WRONLY | O_NOCTTY | O_NONBLOCK); + if (fd < 0) + fd = 2; /* then stderr, dammit */ + full_write(fd, msg, len); + if (fd != 2) + close(fd); + return; + } +#if ENABLE_FEATURE_ROTATE_LOGFILE + isRegular = (fstat(logFD, &statf) == 0 && (statf.st_mode & S_IFREG)); + /* bug (mostly harmless): can wrap around if file > 4gb */ + curFileSize = statf.st_size; +#endif + } - fl.l_whence = SEEK_SET; - fl.l_start = 0; - fl.l_len = 1; - fl.l_type = F_WRLCK; - fcntl(fd, F_SETLKW, &fl); + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 1; + fl.l_type = F_WRLCK; + fcntl(logFD, F_SETLKW, &fl); #if ENABLE_FEATURE_ROTATE_LOGFILE - if (logFileSize) { - struct stat statf; - int r = fstat(fd, &statf); - if (!r && (statf.st_mode & S_IFREG) - && (lseek(fd, 0, SEEK_END) > logFileSize) - ) { - if (logFileRotate) { /* always 0..99 */ - int i = strlen(logFilePath) + 3 + 1; - char oldFile[i]; - char newFile[i]; - i = logFileRotate - 1; - /* rename: f.8 -> f.9; f.7 -> f.8; ... */ - while (1) { - sprintf(newFile, "%s.%d", logFilePath, i); - if (i == 0) break; - sprintf(oldFile, "%s.%d", logFilePath, --i); - rename(oldFile, newFile); - } - /* newFile == "f.0" now */ - rename(logFilePath, newFile); - fl.l_type = F_UNLCK; - fcntl(fd, F_SETLKW, &fl); - close(fd); - goto again; - } - ftruncate(fd, 0); + if (logFileSize && isRegular && curFileSize > logFileSize) { + if (logFileRotate) { /* always 0..99 */ + int i = strlen(logFilePath) + 3 + 1; + char oldFile[i]; + char newFile[i]; + i = logFileRotate - 1; + /* rename: f.8 -> f.9; f.7 -> f.8; ... */ + while (1) { + sprintf(newFile, "%s.%d", logFilePath, i); + if (i == 0) break; + sprintf(oldFile, "%s.%d", logFilePath, --i); + rename(oldFile, newFile); } + /* newFile == "f.0" now */ + rename(logFilePath, newFile); + fl.l_type = F_UNLCK; + fcntl(logFD, F_SETLKW, &fl); + close(logFD); + goto reopen; } -#endif - full_write(fd, msg, len); - fl.l_type = F_UNLCK; - fcntl(fd, F_SETLKW, &fl); - close(fd); - } else { - /* cannot open logfile? - print to /dev/console then */ - fd = device_open(_PATH_CONSOLE, O_WRONLY | O_NOCTTY | O_NONBLOCK); - if (fd < 0) - fd = 2; /* then stderr, dammit */ - full_write(fd, msg, len); - if (fd != 2) - close(fd); + ftruncate(logFD, 0); } +#endif + curFileSize += full_write(logFD, msg, len); + fl.l_type = F_UNLCK; + fcntl(logFD, F_SETLKW, &fl); } static void parse_fac_prio_20(int pri, char *res20) -- cgit v1.2.3