Implement forced log file rotation upon SIGUSR2
This commit is contained in:
parent
23a6d81ea2
commit
949e80f150
@ -483,6 +483,10 @@ SIGTERM.
|
|||||||
.It USR1
|
.It USR1
|
||||||
In debug mode this switches debugging on/off. In normal operation
|
In debug mode this switches debugging on/off. In normal operation
|
||||||
it is ignored.
|
it is ignored.
|
||||||
|
.It USR2
|
||||||
|
.Nm
|
||||||
|
will rotate all files for which rotation is configured when receiving
|
||||||
|
this signal.
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
For convenience the PID is by default stored in
|
For convenience the PID is by default stored in
|
||||||
|
121
src/syslogd.c
121
src/syslogd.c
@ -103,6 +103,7 @@ char ctty[] = _PATH_CONSOLE;
|
|||||||
|
|
||||||
static volatile sig_atomic_t debugging_on;
|
static volatile sig_atomic_t debugging_on;
|
||||||
static volatile sig_atomic_t restart;
|
static volatile sig_atomic_t restart;
|
||||||
|
static volatile sig_atomic_t rotate_signal;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Intervals at which we flush out "message repeated" messages,
|
* Intervals at which we flush out "message repeated" messages,
|
||||||
@ -169,6 +170,9 @@ static void parsemsg(const char *from, char *msg);
|
|||||||
static int opensys(const char *file);
|
static int opensys(const char *file);
|
||||||
static void printsys(char *msg);
|
static void printsys(char *msg);
|
||||||
static void logmsg(struct buf_msg *buffer);
|
static void logmsg(struct buf_msg *buffer);
|
||||||
|
static void logrotate(struct filed *f);
|
||||||
|
static void rotate_file(struct filed *f);
|
||||||
|
static void rotate_all_files(void);
|
||||||
static void fprintlog_first(struct filed *f, struct buf_msg *buffer);
|
static void fprintlog_first(struct filed *f, struct buf_msg *buffer);
|
||||||
static void fprintlog_successive(struct filed *f, int flags);
|
static void fprintlog_successive(struct filed *f, int flags);
|
||||||
void endtty();
|
void endtty();
|
||||||
@ -192,6 +196,7 @@ static void notifier_add(struct notifiers *newn, const char *program);
|
|||||||
static void notifier_invoke(const char *logfile);
|
static void notifier_invoke(const char *logfile);
|
||||||
static void notifier_free_all(void);
|
static void notifier_free_all(void);
|
||||||
void reload(int);
|
void reload(int);
|
||||||
|
static void signal_rotate(int sig);
|
||||||
static int validate(struct sockaddr *sa, const char *hname);
|
static int validate(struct sockaddr *sa, const char *hname);
|
||||||
static int waitdaemon(int);
|
static int waitdaemon(int);
|
||||||
static void timedout(int);
|
static void timedout(int);
|
||||||
@ -589,6 +594,12 @@ no_klogd:
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rotate_signal > 0) {
|
||||||
|
rotate_signal = 0;
|
||||||
|
logit("\nReceived SIGUSR2, forcing log rotation.\n");
|
||||||
|
rotate_all_files();
|
||||||
|
}
|
||||||
|
|
||||||
if (rc < 0 && errno != EINTR)
|
if (rc < 0 && errno != EINTR)
|
||||||
ERR("select()");
|
ERR("select()");
|
||||||
|
|
||||||
@ -1560,7 +1571,7 @@ static void logmsg(struct buf_msg *buffer)
|
|||||||
sigprocmask(SIG_UNBLOCK, &mask, NULL);
|
sigprocmask(SIG_UNBLOCK, &mask, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void logrotate(struct filed *f)
|
static void logrotate(struct filed *f)
|
||||||
{
|
{
|
||||||
struct stat statf;
|
struct stat statf;
|
||||||
|
|
||||||
@ -1571,52 +1582,66 @@ void logrotate(struct filed *f)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
/* bug (mostly harmless): can wrap around if file > 4gb */
|
/* bug (mostly harmless): can wrap around if file > 4gb */
|
||||||
if (S_ISREG(statf.st_mode) && statf.st_size > f->f_rotatesz) {
|
if (S_ISREG(statf.st_mode) && statf.st_size > f->f_rotatesz)
|
||||||
if (f->f_rotatecount > 0) { /* always 0..999 */
|
rotate_file(f);
|
||||||
int len = strlen(f->f_un.f_fname) + 10 + 5;
|
}
|
||||||
int i;
|
|
||||||
char oldFile[len];
|
|
||||||
char newFile[len];
|
|
||||||
|
|
||||||
/* First age zipped log files */
|
static void rotate_file(struct filed *f)
|
||||||
for (i = f->f_rotatecount; i > 1; i--) {
|
{
|
||||||
snprintf(oldFile, len, "%s.%d.gz", f->f_un.f_fname, i - 1);
|
if (f->f_rotatecount > 0) { /* always 0..999 */
|
||||||
snprintf(newFile, len, "%s.%d.gz", f->f_un.f_fname, i);
|
int len = strlen(f->f_un.f_fname) + 10 + 5;
|
||||||
|
int i;
|
||||||
|
char oldFile[len];
|
||||||
|
char newFile[len];
|
||||||
|
|
||||||
/* ignore errors - file might be missing */
|
/* First age zipped log files */
|
||||||
(void)rename(oldFile, newFile);
|
for (i = f->f_rotatecount; i > 1; i--) {
|
||||||
}
|
snprintf(oldFile, len, "%s.%d.gz", f->f_un.f_fname, i - 1);
|
||||||
|
snprintf(newFile, len, "%s.%d.gz", f->f_un.f_fname, i);
|
||||||
|
|
||||||
/* rename: f.8 -> f.9; f.7 -> f.8; ... */
|
/* ignore errors - file might be missing */
|
||||||
for (i = 1; i > 0; i--) {
|
(void)rename(oldFile, newFile);
|
||||||
snprintf(oldFile, len, "%s.%d", f->f_un.f_fname, i - 1);
|
|
||||||
snprintf(newFile, len, "%s.%d", f->f_un.f_fname, i);
|
|
||||||
|
|
||||||
if (!rename(oldFile, newFile) && i > 0) {
|
|
||||||
size_t clen = 18 + strlen(newFile) + 1;
|
|
||||||
char cmd[clen];
|
|
||||||
|
|
||||||
snprintf(cmd, sizeof(cmd), "gzip -f %s", newFile);
|
|
||||||
system(cmd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* newFile == "f.0" now */
|
|
||||||
snprintf(newFile, len, "%s.0", f->f_un.f_fname);
|
|
||||||
(void)rename(f->f_un.f_fname, newFile);
|
|
||||||
close(f->f_file);
|
|
||||||
|
|
||||||
f->f_file = open(f->f_un.f_fname, O_CREATE | O_NONBLOCK | O_NOCTTY, 0644);
|
|
||||||
if (f->f_file < 0) {
|
|
||||||
f->f_type = F_UNUSED;
|
|
||||||
ERR("Failed re-opening log file %s after rotation", f->f_un.f_fname);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!SIMPLEQ_EMPTY(¬head))
|
|
||||||
notifier_invoke(f->f_un.f_fname);
|
|
||||||
}
|
}
|
||||||
ftruncate(f->f_file, 0);
|
|
||||||
|
/* rename: f.8 -> f.9; f.7 -> f.8; ... */
|
||||||
|
for (i = 1; i > 0; i--) {
|
||||||
|
snprintf(oldFile, len, "%s.%d", f->f_un.f_fname, i - 1);
|
||||||
|
snprintf(newFile, len, "%s.%d", f->f_un.f_fname, i);
|
||||||
|
|
||||||
|
if (!rename(oldFile, newFile) && i > 0) {
|
||||||
|
size_t clen = 18 + strlen(newFile) + 1;
|
||||||
|
char cmd[clen];
|
||||||
|
|
||||||
|
snprintf(cmd, sizeof(cmd), "gzip -f %s", newFile);
|
||||||
|
system(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* newFile == "f.0" now */
|
||||||
|
snprintf(newFile, len, "%s.0", f->f_un.f_fname);
|
||||||
|
(void)rename(f->f_un.f_fname, newFile);
|
||||||
|
close(f->f_file);
|
||||||
|
|
||||||
|
f->f_file = open(f->f_un.f_fname, O_CREATE | O_NONBLOCK | O_NOCTTY, 0644);
|
||||||
|
if (f->f_file < 0) {
|
||||||
|
f->f_type = F_UNUSED;
|
||||||
|
ERR("Failed re-opening log file %s after rotation", f->f_un.f_fname);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SIMPLEQ_EMPTY(¬head))
|
||||||
|
notifier_invoke(f->f_un.f_fname);
|
||||||
|
}
|
||||||
|
ftruncate(f->f_file, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rotate_all_files(void)
|
||||||
|
{
|
||||||
|
struct filed *f;
|
||||||
|
|
||||||
|
SIMPLEQ_FOREACH(f, &fhead, f_link) {
|
||||||
|
if (f->f_type == F_FILE && f->f_rotatesz)
|
||||||
|
rotate_file(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2443,6 +2468,7 @@ static void signal_init(void)
|
|||||||
SIGNAL(SIGINT, Debug ? die : SIG_IGN);
|
SIGNAL(SIGINT, Debug ? die : SIG_IGN);
|
||||||
SIGNAL(SIGQUIT, Debug ? die : SIG_IGN);
|
SIGNAL(SIGQUIT, Debug ? die : SIG_IGN);
|
||||||
SIGNAL(SIGUSR1, Debug ? debug_switch : SIG_IGN);
|
SIGNAL(SIGUSR1, Debug ? debug_switch : SIG_IGN);
|
||||||
|
SIGNAL(SIGUSR2, signal_rotate);
|
||||||
SIGNAL(SIGXFSZ, SIG_IGN);
|
SIGNAL(SIGXFSZ, SIG_IGN);
|
||||||
SIGNAL(SIGHUP, reload);
|
SIGNAL(SIGHUP, reload);
|
||||||
SIGNAL(SIGCHLD, reapchild);
|
SIGNAL(SIGCHLD, reapchild);
|
||||||
@ -3445,6 +3471,15 @@ void reload(int signo)
|
|||||||
restart++;
|
restart++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SIGUSR2: forced rotation for so-configured files as soon as possible.
|
||||||
|
*/
|
||||||
|
static void signal_rotate(int sig)
|
||||||
|
{
|
||||||
|
(void)sig;
|
||||||
|
rotate_signal++;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Local Variables:
|
* Local Variables:
|
||||||
* indent-tabs-mode: t
|
* indent-tabs-mode: t
|
||||||
|
Loading…
Reference in New Issue
Block a user