Merge pull request #46 from sdaoden/rotate
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
commit
0b3d379001
@ -483,6 +483,10 @@ SIGTERM.
|
||||
.It USR1
|
||||
In debug mode this switches debugging on/off. In normal operation
|
||||
it is ignored.
|
||||
.It USR2
|
||||
.Nm
|
||||
will rotate all files for which rotation is configured when receiving
|
||||
this signal.
|
||||
.El
|
||||
.Pp
|
||||
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 restart;
|
||||
static volatile sig_atomic_t rotate_signal;
|
||||
|
||||
/*
|
||||
* 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 void printsys(char *msg);
|
||||
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_successive(struct filed *f, int flags);
|
||||
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_free_all(void);
|
||||
void reload(int);
|
||||
static void signal_rotate(int sig);
|
||||
static int validate(struct sockaddr *sa, const char *hname);
|
||||
static int waitdaemon(int);
|
||||
static void timedout(int);
|
||||
@ -589,6 +594,12 @@ no_klogd:
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rotate_signal > 0) {
|
||||
rotate_signal = 0;
|
||||
logit("\nReceived SIGUSR2, forcing log rotation.\n");
|
||||
rotate_all_files();
|
||||
}
|
||||
|
||||
if (rc < 0 && errno != EINTR)
|
||||
ERR("select()");
|
||||
|
||||
@ -1560,7 +1571,7 @@ static void logmsg(struct buf_msg *buffer)
|
||||
sigprocmask(SIG_UNBLOCK, &mask, NULL);
|
||||
}
|
||||
|
||||
void logrotate(struct filed *f)
|
||||
static void logrotate(struct filed *f)
|
||||
{
|
||||
struct stat statf;
|
||||
|
||||
@ -1571,52 +1582,66 @@ void logrotate(struct filed *f)
|
||||
return;
|
||||
|
||||
/* bug (mostly harmless): can wrap around if file > 4gb */
|
||||
if (S_ISREG(statf.st_mode) && statf.st_size > f->f_rotatesz) {
|
||||
if (f->f_rotatecount > 0) { /* always 0..999 */
|
||||
int len = strlen(f->f_un.f_fname) + 10 + 5;
|
||||
int i;
|
||||
char oldFile[len];
|
||||
char newFile[len];
|
||||
if (S_ISREG(statf.st_mode) && statf.st_size > f->f_rotatesz)
|
||||
rotate_file(f);
|
||||
}
|
||||
|
||||
/* First age zipped log files */
|
||||
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);
|
||||
static void rotate_file(struct filed *f)
|
||||
{
|
||||
if (f->f_rotatecount > 0) { /* always 0..999 */
|
||||
int len = strlen(f->f_un.f_fname) + 10 + 5;
|
||||
int i;
|
||||
char oldFile[len];
|
||||
char newFile[len];
|
||||
|
||||
/* ignore errors - file might be missing */
|
||||
(void)rename(oldFile, newFile);
|
||||
}
|
||||
/* First age zipped log files */
|
||||
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; ... */
|
||||
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);
|
||||
/* ignore errors - file might be missing */
|
||||
(void)rename(oldFile, newFile);
|
||||
}
|
||||
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(SIGQUIT, Debug ? die : SIG_IGN);
|
||||
SIGNAL(SIGUSR1, Debug ? debug_switch : SIG_IGN);
|
||||
SIGNAL(SIGUSR2, signal_rotate);
|
||||
SIGNAL(SIGXFSZ, SIG_IGN);
|
||||
SIGNAL(SIGHUP, reload);
|
||||
SIGNAL(SIGCHLD, reapchild);
|
||||
@ -3445,6 +3471,15 @@ void reload(int signo)
|
||||
restart++;
|
||||
}
|
||||
|
||||
/*
|
||||
* SIGUSR2: forced rotation for so-configured files as soon as possible.
|
||||
*/
|
||||
static void signal_rotate(int sig)
|
||||
{
|
||||
(void)sig;
|
||||
rotate_signal++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Local Variables:
|
||||
* indent-tabs-mode: t
|
||||
|
@ -1,5 +1,6 @@
|
||||
EXTRA_DIST = lib.sh opts.sh
|
||||
EXTRA_DIST += api.sh local.sh unicode.sh remote.sh fwd.sh mark.sh notify.sh
|
||||
EXTRA_DIST += api.sh local.sh unicode.sh remote.sh fwd.sh mark.sh \
|
||||
notify.sh rotate_all.sh
|
||||
CLEANFILES = *~ *.trs *.log
|
||||
TEST_EXTENSIONS = .sh
|
||||
TESTS_ENVIRONMENT= unshare -mrun
|
||||
@ -18,5 +19,6 @@ TESTS += api.sh
|
||||
TESTS += fwd.sh
|
||||
TESTS += mark.sh
|
||||
TESTS += notify.sh
|
||||
TESTS += rotate_all.sh
|
||||
|
||||
programs: $(check_PROGRAMS)
|
||||
|
95
test/rotate_all.sh
Executable file
95
test/rotate_all.sh
Executable file
@ -0,0 +1,95 @@
|
||||
#!/bin/sh
|
||||
set -x
|
||||
|
||||
if [ x"${srcdir}" = x ]; then
|
||||
srcdir=.
|
||||
fi
|
||||
. ${srcdir}/lib.sh
|
||||
|
||||
[ -x ../src/logger ] || SKIP 'logger missing'
|
||||
command -v zgrep >/dev/null 2>&1 || SKIP 'zgrep(1) missing'
|
||||
|
||||
NOT1=${DIR}/${NM}-1.sh
|
||||
NOT1STAMP=${DIR}/${NM}-1.stamp
|
||||
NOT2=${DIR}/${NM}-2.sh
|
||||
NOT2STAMP=${DIR}/${NM}-2.stamp
|
||||
|
||||
printf '#!/bin/sh -\necho script 1: $* >> '${NOT1STAMP}'\n' > ${NOT1}
|
||||
chmod 0755 ${NOT1}
|
||||
|
||||
cat <<EOF > ${CONFD}/rotate_all.conf
|
||||
notify ${NOT1}
|
||||
*.* -${LOG} ;rotate=10k:2,RFC5424
|
||||
*.* -${LOG}X ;rotate=10k:2,RFC5424
|
||||
EOF
|
||||
|
||||
setup
|
||||
|
||||
rm -f ${NOT1STAMP}
|
||||
../src/logger -u ${SOCK} notrotall-1
|
||||
|
||||
kill -USR2 `cat ${PID}`
|
||||
sleep 3
|
||||
if [ -f ${LOG}.0 ] && [ -f ${LOG}X.0 ] &&
|
||||
grep notrotall-1 ${LOG}.0 &&
|
||||
grep notrotall-1 ${LOG}X.0; then
|
||||
:
|
||||
else
|
||||
FAIL 'Missing log entries, I.'
|
||||
fi
|
||||
if [ -f ${NOT1STAMP} ] && grep 'script 1' ${NOT1STAMP} &&
|
||||
grep ${LOG} ${NOT1STAMP} && grep ${LOG}X ${NOT1STAMP}; then
|
||||
:
|
||||
else
|
||||
FAIL 'Notifier did not run, I.'
|
||||
fi
|
||||
|
||||
rm -f ${NOT1STAMP}
|
||||
../src/logger -u ${SOCK} notrotall-2
|
||||
|
||||
kill -USR2 `cat ${PID}`
|
||||
sleep 3
|
||||
if [ -f ${LOG}.0 ] && [ -f ${LOG}X.0 ] &&
|
||||
[ -f ${LOG}.1.gz ] && [ -f ${LOG}X.1.gz ] &&
|
||||
grep notrotall-2 ${LOG}.0 &&
|
||||
grep notrotall-2 ${LOG}X.0 &&
|
||||
zgrep notrotall-1 ${LOG}.1.gz &&
|
||||
zgrep notrotall-1 ${LOG}X.1.gz; then
|
||||
:
|
||||
else
|
||||
FAIL 'Missing log entries, II.'
|
||||
fi
|
||||
if [ -f ${NOT1STAMP} ] && grep 'script 1' ${NOT1STAMP} &&
|
||||
grep ${LOG} ${NOT1STAMP} && grep ${LOG}X ${NOT1STAMP}; then
|
||||
:
|
||||
else
|
||||
FAIL 'Notifier did not run, II.'
|
||||
fi
|
||||
|
||||
cp $NOT1STAMP /tmp/
|
||||
rm -f ${NOT1STAMP}
|
||||
../src/logger -u ${SOCK} notrotall-3
|
||||
|
||||
kill -USR2 `cat ${PID}`
|
||||
sleep 3
|
||||
if [ -f ${LOG}.0 ] && [ -f ${LOG}X.0 ] &&
|
||||
[ -f ${LOG}.1.gz ] && [ -f ${LOG}X.1.gz ] &&
|
||||
[ -f ${LOG}.2.gz ] && [ -f ${LOG}X.2.gz ] &&
|
||||
grep notrotall-3 ${LOG}.0 &&
|
||||
grep notrotall-3 ${LOG}X.0 &&
|
||||
zgrep notrotall-2 ${LOG}.1.gz &&
|
||||
zgrep notrotall-2 ${LOG}X.1.gz &&
|
||||
zgrep notrotall-1 ${LOG}.2.gz &&
|
||||
zgrep notrotall-1 ${LOG}X.2.gz; then
|
||||
:
|
||||
else
|
||||
FAIL 'Missing log entries, III.'
|
||||
fi
|
||||
if [ -f ${NOT1STAMP} ] && grep 'script 1' ${NOT1STAMP} &&
|
||||
grep ${LOG} ${NOT1STAMP} && grep ${LOG}X ${NOT1STAMP}; then
|
||||
:
|
||||
else
|
||||
FAIL 'Notifier did not run, III.'
|
||||
fi
|
||||
|
||||
OK
|
Loading…
Reference in New Issue
Block a user