syslogd: stop doing open/fstat/lseek/close on _every_ write

(still doing it if more than a second passed in between).
Costs ~40 bytes.
This commit is contained in:
Denis Vlasenko 2007-01-04 18:02:32 +00:00
parent a9b60e93ee
commit b893497151

View File

@ -29,6 +29,7 @@ static char *dev_log_name;
/* Path for the file where all log messages are written */ /* Path for the file where all log messages are written */
static const char *logFilePath = "/var/log/messages"; static const char *logFilePath = "/var/log/messages";
static int logFD = -1;
/* interval between marks in seconds */ /* interval between marks in seconds */
static int markInterval = 20 * 60; static int markInterval = 20 * 60;
@ -41,9 +42,11 @@ static char localHostName[64];
#if ENABLE_FEATURE_ROTATE_LOGFILE #if ENABLE_FEATURE_ROTATE_LOGFILE
/* max size of message file before being rotated */ /* max size of message file before being rotated */
static int logFileSize = 200 * 1024; static unsigned logFileSize = 200 * 1024;
/* number of rotated message files */ /* number of rotated message files */
static int logFileRotate = 1; static unsigned logFileRotate = 1;
static unsigned curFileSize;
static smallint isRegular;
#endif #endif
#if ENABLE_FEATURE_REMOTE_LOG #if ENABLE_FEATURE_REMOTE_LOG
@ -256,7 +259,10 @@ void log_to_shmem(const char *msg);
/* Print a message to the log file. */ /* Print a message to the log file. */
static void log_locally(char *msg) 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 ENABLE_FEATURE_IPC_SYSLOG
if ((option_mask32 & OPT_circularlog) && shbuf) { if ((option_mask32 & OPT_circularlog) && shbuf) {
@ -264,62 +270,69 @@ static void log_locally(char *msg)
return; return;
} }
#endif #endif
if (logFD >= 0) {
again: time_t cur;
fd = device_open(logFilePath, O_WRONLY | O_CREAT 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); | O_NOCTTY | O_APPEND | O_NONBLOCK);
if (fd >= 0) { if (logFD < 0) {
struct flock fl; /* 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_whence = SEEK_SET;
fl.l_start = 0; fl.l_start = 0;
fl.l_len = 1; fl.l_len = 1;
fl.l_type = F_WRLCK; fl.l_type = F_WRLCK;
fcntl(fd, F_SETLKW, &fl); fcntl(logFD, F_SETLKW, &fl);
#if ENABLE_FEATURE_ROTATE_LOGFILE #if ENABLE_FEATURE_ROTATE_LOGFILE
if (logFileSize) { if (logFileSize && isRegular && curFileSize > logFileSize) {
struct stat statf; if (logFileRotate) { /* always 0..99 */
int r = fstat(fd, &statf); int i = strlen(logFilePath) + 3 + 1;
if (!r && (statf.st_mode & S_IFREG) char oldFile[i];
&& (lseek(fd, 0, SEEK_END) > logFileSize) char newFile[i];
) { i = logFileRotate - 1;
if (logFileRotate) { /* always 0..99 */ /* rename: f.8 -> f.9; f.7 -> f.8; ... */
int i = strlen(logFilePath) + 3 + 1; while (1) {
char oldFile[i]; sprintf(newFile, "%s.%d", logFilePath, i);
char newFile[i]; if (i == 0) break;
i = logFileRotate - 1; sprintf(oldFile, "%s.%d", logFilePath, --i);
/* rename: f.8 -> f.9; f.7 -> f.8; ... */ rename(oldFile, newFile);
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);
} }
/* newFile == "f.0" now */
rename(logFilePath, newFile);
fl.l_type = F_UNLCK;
fcntl(logFD, F_SETLKW, &fl);
close(logFD);
goto reopen;
} }
#endif ftruncate(logFD, 0);
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);
} }
#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) static void parse_fac_prio_20(int pri, char *res20)