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 */
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)