tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Making syslog output pretty and smaller binaries



Hi List!

There seems to be a fair bit of code in our tree which outputs to both
syslog and stdout/stderr via printf/perror/warnx, etc.
I'll make the assumption that is because syslog output via LOG_PERROR
isn't pretty. It also only goes to stderr.
Also, there are cases where you want to run a daemon in the foreground
for debugging and as such you don't really want messages to appear in
the system logs.

To help reduce this duplication of output function and make our binaries
smaller, I propose extend syslog as follows:
   LOG_POUT  - output only the formattted message to stdout
               if pri > LOG_ERR, otherwise stderr
   LOG_NOLOG - don't log to syslog or console
               assume LOG_PERROR or LOG_POUT is present

Comments welcome, sample patch attached for review.

Roy
Index: lib/libc/gen/syslog.3
===================================================================
RCS file: /cvsroot/src/lib/libc/gen/syslog.3,v
retrieving revision 1.29
diff -p -u -r1.29 syslog.3
--- lib/libc/gen/syslog.3	25 Jul 2011 19:42:50 -0000	1.29
+++ lib/libc/gen/syslog.3	6 Oct 2016 14:32:42 -0000
@@ -30,7 +30,7 @@
 .\"
 .\"     @(#)syslog.3	8.1 (Berkeley) 6/4/93
 .\"
-.Dd May 3, 2010
+.Dd October 6, 2016
 .Dt SYSLOG 3
 .Os
 .Sh NAME
@@ -302,6 +302,18 @@ Log the process id with each message: us
 instantiations of daemons.
 (This PID is placed within brackets
 between the ident and the message.)
+.It Dv LOG_POUT
+Write the message to standard output if priority is greater than
+.Dv LOG_ERR ,
+otherwise standard error.
+The message is also written to the system log.
+.It Dv LOG_NOLOG
+The message is not written to the system log.
+Either
+.Dv LOG_PERROR
+or
+.Dv LOG_POUT
+should be set.
 .El
 .Pp
 The
@@ -484,6 +496,10 @@ The async-signal-safe functions appeared
 .Nx 4.0 .
 The syslog-protocol functions appeared in
 .Nx 5.0 .
+The
+.Fa logopt
+options LOG_POUT and LOG_NOLOG appeared in
+.Nx 8.0 .
 .Sh CAVEATS
 It is important never to pass a string with user-supplied data as a
 format without using
Index: lib/libc/gen/syslog.c
===================================================================
RCS file: /cvsroot/src/lib/libc/gen/syslog.c,v
retrieving revision 1.55
diff -p -u -r1.55 syslog.c
--- lib/libc/gen/syslog.c	26 Oct 2015 11:44:30 -0000	1.55
+++ lib/libc/gen/syslog.c	6 Oct 2016 14:32:43 -0000
@@ -230,7 +230,7 @@ vsyslogp_r(int pri, struct syslog_data *
 
 	pri &= ~LOG_SIGNAL_SAFE;
 
-#define INTERNALLOG	LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID
+#define INTERNALLOG	LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID|LOG_POUT|LOG_NOLOG
 	/* Check for invalid bits. */
 	if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) {
 		syslog_r(INTERNALLOG | signal_safe, data,
@@ -317,7 +317,7 @@ vsyslogp_r(int pri, struct syslog_data *
 	if (data == &sdata)
 		mutex_unlock(&syslog_mutex);
 
-	if (data->log_stat & (LOG_PERROR|LOG_CONS)) {
+	if (data->log_stat & (LOG_PERROR|LOG_POUT|LOG_CONS)) {
 		iovcnt = 0;
 		iov[iovcnt].iov_base = p;
 		iov[iovcnt].iov_len = prlen - 1;
@@ -362,7 +362,7 @@ vsyslogp_r(int pri, struct syslog_data *
 	} else
 		strlcat(fmt_cat, "-", FMT_LEN);
 
-	if (data->log_stat & (LOG_PERROR|LOG_CONS))
+	if (data->log_stat & (LOG_PERROR|LOG_POUT|LOG_CONS))
 		msgsdlen = strlen(fmt_cat) + 1;
 	else
 		msgsdlen = 0;	/* XXX: GCC */
@@ -409,7 +409,7 @@ vsyslogp_r(int pri, struct syslog_data *
 	else
 		prlen = vsnprintf(p, tbuf_left, fmt_cpy, ap);
 
-	if (data->log_stat & (LOG_PERROR|LOG_CONS)) {
+	if (data->log_stat & (LOG_PERROR|LOG_POUT|LOG_CONS)) {
 		iov[iovcnt].iov_base = p + msgsdlen;
 		iov[iovcnt].iov_len = prlen - msgsdlen;
 		iovcnt++;
@@ -418,13 +418,28 @@ vsyslogp_r(int pri, struct syslog_data *
 	DEC();
 	cnt = p - tbuf;
 
-	/* Output to stderr if requested. */
-	if (data->log_stat & LOG_PERROR) {
+	/* Output if requested. */
+	if (data->log_stat & LOG_POUT) {
+		/* Only output the message. */
+		struct iovec oiov[2];
+		int f;
+
+		oiov[0] = iov[iovcnt - 1];
+		oiov[1].iov_base = __UNCONST(CRLF + 1);
+		oiov[1].iov_len = 1;
+
+		f = LOG_PRI(pri) <= LOG_ERR ? STDERR_FILENO : STDOUT_FILENO;
+		(void)writev(f, oiov, 2);
+	} else if (data->log_stat & LOG_PERROR) {
+		/* Output program[pid] and the message. */
 		iov[iovcnt].iov_base = __UNCONST(CRLF + 1);
 		iov[iovcnt].iov_len = 1;
 		(void)writev(STDERR_FILENO, iov, iovcnt + 1);
 	}
 
+	if (data->log_stat & LOG_NOLOG)
+		goto out;
+
 	/* Get connected, output the message to the local logger. */
 	if (data == &sdata)
 		mutex_lock(&syslog_mutex);
@@ -465,6 +480,7 @@ vsyslogp_r(int pri, struct syslog_data *
 		(void)close(fd);
 	}
 
+out:
 	if (data == &sdata)
 		mutex_unlock(&syslog_mutex);
 
Index: sys/sys/syslog.h
===================================================================
RCS file: /cvsroot/src/sys/sys/syslog.h,v
retrieving revision 1.38
diff -p -u -r1.38 syslog.h
--- sys/sys/syslog.h	15 Oct 2015 06:15:22 -0000	1.38
+++ sys/sys/syslog.h	6 Oct 2016 14:32:43 -0000
@@ -168,6 +168,8 @@ CODE facilitynames[] = {
 #define	LOG_NDELAY	0x08	/* don't delay open */
 #define	LOG_NOWAIT	0x10	/* don't wait for console forks: DEPRECATED */
 #define	LOG_PERROR	0x20	/* log to stderr as well */
+#define	LOG_POUT	0x40	/* log to stdout or stderr if >=LOG_ERR */
+#define	LOG_NOLOG	0x80	/* don't log - needs LOG_PERROR or LOG_POUT */
 
 #ifndef _KERNEL
 


Home | Main Index | Thread Index | Old Index