Date: Tue, 9 Oct 2001 00:27:05 +0900 (JST) From: Toshihiko ARAI <toshi@jp.FreeBSD.org> To: freebsd-hackers@FreeBSD.org Subject: [patch] extension of newsyslog Message-ID: <200110081527.f98FR5A56224.toshi@jp.FreeBSD.org>
index | next in thread | raw e-mail
Hello,
I add script call features to newsyslog. This adds a one field to
newsyslog.conf. When newsyslog processed log file, this can execute
arbitrary program.
Situation to assume:
* For the log file which cannot use signal.
* Cases to do statistical application for log file.
A sample entry of newsylog.conf:
# logfilename [owner:group] mode count size when [ZB] [/pid_file] [sig_num] [/program]
/var/log/foo.log bar:baz 640 1 100 * Z - - /etc/foo.sh
'-' is usable as a filler of null field.
I used similar enhanced function from the past. I think that you can
apply this patch for 5-current. In addition, I can prepare a patch
for 4-stable if it is necessary.
I ask for testing and a review of the following patches.
Thanks.
--
Toshihiko ARAI
Index: newsyslog.8
===================================================================
RCS file: /home/ncvs/src/usr.sbin/newsyslog/newsyslog.8,v
retrieving revision 1.32
diff -u -r1.32 newsyslog.8
--- newsyslog.8 2001/07/30 15:17:17 1.32
+++ newsyslog.8 2001/09/30 08:54:07
@@ -76,7 +76,7 @@
Each line of the file contains information about a particular log file
that should be handled by
.Nm .
-Each line has five mandatory fields and four optional fields, with
+Each line has five mandatory fields and five optional fields, with
whitespace separating each field. Blank lines or lines beginning with
``#'' are ignored. The fields of the configuration file are as
follows:
@@ -294,12 +294,28 @@
.Ar signal_number
is sent the process id contained in this
file. This field must start with "/" in order to be recognized
-properly.
+properly. Same as
+.Ar flags
+field, you can use "-" for null field.
.It Ar signal_number
This optional field specifies
-the signal number will be sent to the daemon process.
+the signal number or signal name will be sent to the daemon process.
By default
-a SIGHUP will be sent.
+a SIGHUP will be sent. Same as
+.Ar flags
+field, you can use "-" for null field.
+.It Ar path_to_program
+This optional field specifies
+the path name of a script for postprocessing of log file.
+This field must be specified with full path.
+And a file must be execute permission by specified
+.Ar owner
+and
+.Ar group .
+When
+.Ar path_to_program
+is called, new log file is given to the first argument, and old
+log file is given to the second argument.
.El
.Sh OPTIONS
The following options can be used with
Index: newsyslog.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/newsyslog/newsyslog.c,v
retrieving revision 1.37
diff -u -r1.37 newsyslog.c
--- newsyslog.c 2001/07/31 16:25:55 1.37
+++ newsyslog.c 2001/10/08 14:09:19
@@ -38,6 +38,7 @@
#include <ctype.h>
#include <err.h>
+#include <errno.h>
#include <fcntl.h>
#include <grp.h>
#include <paths.h>
@@ -73,6 +74,7 @@
struct conf_entry {
char *log; /* Name of the log */
char *pid_file; /* PID file */
+ char *prog; /* Program for postprocessing */
int uid; /* Owner of log */
int gid; /* Group of log */
int numlogs; /* Number of logs to keep */
@@ -106,11 +108,13 @@
static void do_entry(struct conf_entry * ent);
static void PRS(int argc, char **argv);
static void usage(void);
-static void dotrim(char *log, const char *pid_file, int numdays, int falgs,
- int perm, int owner_uid, int group_gid, int sig);
+static void dotrim(char *log, const char *pid_file, const char *prog,
+ int numdays, int falgs, int perm, int owner_uid,
+ int group_gid, int sig);
static int log_trim(char *log);
static void compress_log(char *log);
static void bzcompress_log(char *log);
+static int post_prog(const char *prog, char *log, int owner_uid, int group_gid);
static int sizefile(char *file);
static int age_old_log(char *file);
static pid_t get_pid(const char *pid_file);
@@ -119,6 +123,7 @@
int group_gid);
static void createdir(char *dirpart);
static time_t parseDWM(char *s);
+static int signame_to_signum(char *sig);
int
main(int argc, char **argv)
@@ -200,7 +205,7 @@
else
pid_file = NULL;
}
- dotrim(ent->log, pid_file, ent->numlogs,
+ dotrim(ent->log, pid_file, ent->prog, ent->numlogs,
ent->flags, ent->permissions, ent->uid, ent->gid,
ent->sig);
} else {
@@ -460,34 +465,52 @@
if (q && *q) {
if (*q == '/')
working->pid_file = strdup(q);
- else if (isdigit(*q))
+ else if (isalnum(*q))
goto got_sig;
- else
- errx(1,
- "illegal pid file or signal number in config file:\n%s",
+ else if (*q != '-')
+ errx(1, "illegal pid file in config file:\n%s",
errline);
}
+
if (eol)
q = NULL;
else {
q = parse = sob(++parse); /* Optional field */
- *(parse = son(parse)) = '\0';
+ parse = son(parse);
+ if (!*parse)
+ eol = 1;
+ *parse = '\0';
}
+ got_sig:
working->sig = SIGHUP;
if (q && *q) {
- if (isdigit(*q)) {
- got_sig:
+ if (isdigit(*q))
working->sig = atoi(q);
- } else {
- err_sig:
+ else if (*q != '-')
+ working->sig = signame_to_signum(q);
+ if (working->sig < 1 || working->sig >= NSIG)
errx(1,
"illegal signal number in config file:\n%s",
errline);
- }
- if (working->sig < 1 || working->sig >= NSIG)
- goto err_sig;
}
+
+ if (eol)
+ q = NULL;
+ else {
+ q = parse = sob(++parse); /* Optional field */
+ *(parse = son(parse)) = '\0';
+ }
+
+ working->prog = NULL;
+ if (q && *q) {
+ if (*q == '/')
+ working->prog = strdup(q);
+ else if (*q != '-')
+ errx(1,
+ "illegal program file in config file:\n%s",
+ errline);
+ }
free(errline);
}
if (working)
@@ -506,14 +529,14 @@
}
static void
-dotrim(char *log, const char *pid_file, int numdays, int flags, int perm,
- int owner_uid, int group_gid, int sig)
+dotrim(char *log, const char *pid_file, const char *prog, int numdays,
+ int flags, int perm, int owner_uid, int group_gid, int sig)
{
char dirpart[MAXPATHLEN], namepart[MAXPATHLEN];
char file1[MAXPATHLEN], file2[MAXPATHLEN];
char zfile1[MAXPATHLEN], zfile2[MAXPATHLEN];
char jfile1[MAXPATHLEN];
- int notified, need_notification, fd, _numdays;
+ int notified, need_notification, pstat, fd, _numdays;
struct stat st;
pid_t pid;
@@ -660,7 +683,7 @@
(void) chmod(log, perm);
pid = 0;
- need_notification = notified = 0;
+ need_notification = notified = pstat = 0;
if (pid_file != NULL) {
need_notification = 1;
pid = get_pid(pid_file);
@@ -677,11 +700,29 @@
printf("daemon pid %d notified\n", (int) pid);
}
}
+ if (prog != NULL) {
+ if (need_notification && !notified)
+ warnx("don't run %s because signal is not notified",
+ prog);
+ else if (noaction)
+ printf("Exec %s %s %s.0\n", prog, log, log);
+ else {
+ pstat = post_prog(prog, log, owner_uid, group_gid);
+ if (pstat != 0)
+ warnx("%s returned exit status %d",
+ prog, WEXITSTATUS(pstat));
+ else if (verbose)
+ printf("exec %s done\n", prog);
+ }
+ }
if ((flags & CE_COMPACT) || (flags & CE_BZCOMPACT)) {
if (need_notification && !notified)
warnx(
"log %s not compressed because daemon not notified",
log);
+ else if (pstat != 0)
+ warnx("log %s is not compressed because %s failed",
+ log, prog);
else if (noaction)
printf("Compress %s.0\n", log);
else {
@@ -756,6 +797,32 @@
}
}
+/* Program run for postprocessing of log file */
+static int
+post_prog(const char *prog, char *log, int owner_uid, int group_gid)
+{
+ pid_t pid;
+ int pstat;
+
+ pid = vfork();
+ if (pid < 0)
+ err(1, "can't vfork");
+ else if (pid == 0) {
+ char tmp[MAXPATHLEN];
+
+ (void) snprintf(tmp, sizeof(tmp), "%s.0", log);
+ if (group_gid != NONE)
+ setgid(group_gid);
+ if (owner_uid != NONE)
+ setuid(owner_uid);
+ (void) execl(prog, prog, log, tmp, NULL);
+ warn("can't exec %s", prog);
+ _exit(1);
+ }
+ while (waitpid(pid, &pstat, 0) == -1 && errno == EINTR);
+ return pstat;
+}
+
/* Return size in kilobytes of a file */
static int
sizefile(char *file)
@@ -1100,3 +1167,19 @@
}
return mktime(&tm);
}
+
+/* Convert a signal name into signal number */
+static int
+signame_to_signum(char *sig)
+{
+ int n;
+
+ if (!strncasecmp(sig, "sig", (size_t)3))
+ sig += 3;
+ for (n = 1; n < NSIG; n++) {
+ if (!strcasecmp(sys_signame[n], sig))
+ return (n);
+ }
+ return (-1);
+}
+
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200110081527.f98FR5A56224.toshi>
