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:
parent
a9b60e93ee
commit
b893497151
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user