[PATCH] syslogd: support external logrotate command

Joshua Judson Rosen jrosen at harvestai.com
Tue May 20 22:09:50 UTC 2014


Hrm. Apparently there's a bug, not in this patch, that prevents external rotation
from working correctly: the "Reopen log file every second" logic in syslogd
doesn't reopen _all_ files, just the first one written in that second.

On 2014-05-20 01:08, Joshua Judson Rosen wrote:
> Configurable at build time.
>
> Invoke "syslogd -c logrotate" to call out to "logrotate"
> when it's time to rotate log-files.
>
> Signed-off-by: Joshua Judson Rosen <jrosen at harvestai.com>
> ---
>   sysklogd/Config.src |    9 +++++++++
>   sysklogd/syslogd.c  |   32 +++++++++++++++++++++++++++++++-
>   2 files changed, 40 insertions(+), 1 deletion(-)
>
> diff --git a/sysklogd/Config.src b/sysklogd/Config.src
> index fd8d408..7938f6f 100644
> --- a/sysklogd/Config.src
> +++ b/sysklogd/Config.src
> @@ -41,6 +41,15 @@ config FEATURE_ROTATE_LOGFILE
>   	  This enables syslogd to rotate the message files
>   	  on his own. No need to use an external rotatescript.
>
> +config FEATURE_LOGROTATE_CMD
> +	bool "Support calling an external logrotate command"
> +	default n
> +	depends on FEATURE_ROTATE_LOGFILE
> +	help
> +	  This adds a "-c" option to syslogd, to specify
> +	  an external command to call in order to rotate
> +	  logs when they pass the rotation-threshold.
> +
>   config FEATURE_LOGROTATE_TIMESTAMPS
>   	bool "Suffix rotated logfile names with timestamps"
>   	default n
> diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c
> index d9cf289..689b036 100644
> --- a/sysklogd/syslogd.c
> +++ b/sysklogd/syslogd.c
> @@ -25,6 +25,9 @@
>   //usage:     "\n	-l N		Log only messages more urgent than prio N (1-8)"
>   //usage:     "\n	-S		Smaller output"
>   //usage:	IF_FEATURE_ROTATE_LOGFILE(
> +//usage:	IF_FEATURE_LOGROTATE_CMD(
> +//usage:     "\n	-c COMMAND	Call out to shell to run COMMAND to rotate logs"
> +//usage:	)
>   //usage:     "\n	-s SIZE		Max size (KB) before rotation (default:200KB, 0=off)"
>   //usage:     "\n	-b N		N rotated logs to keep (default:1, max=99, 0=purge)"
>   //usage:	)
> @@ -82,6 +85,10 @@
>   #include <unistd.h>
>   #endif
>
> +#if ENABLE_FEATURE_LOGROTATE_CMD
> +#include <stdlib.h>
> +#endif
> +
>   #define DEBUG 0
>
>   /* MARK code is not very useful, is bloat, and broken:
> @@ -142,6 +149,10 @@ IF_FEATURE_ROTATE_LOGFILE( \
>   	unsigned logFileSize;                   \
>   	/* number of rotated message files */   \
>   	unsigned logFileRotate;                 \
> +IF_FEATURE_LOGROTATE_CMD( \
> +	/* external logrotate command */        \
> +	const char *logrotateCmd;               \
> +) \
>   ) \
>   IF_FEATURE_IPC_SYSLOG( \
>   	int shmid; /* ipc shared memory id */   \
> @@ -198,6 +209,9 @@ static const struct init_globals init_data = {
>   #if ENABLE_FEATURE_ROTATE_LOGFILE
>   	.logFileSize = 200 * 1024,
>   	.logFileRotate = 1,
> +#if ENABLE_FEATURE_LOGROTATE_CMD
> +	.logrotateCmd = NULL,
> +#endif
>   #endif
>   #if ENABLE_FEATURE_IPC_SYSLOG
>   	.shmid = -1,
> @@ -221,6 +235,7 @@ enum {
>   	OPTBIT_outfile, // -O
>   	OPTBIT_loglevel, // -l
>   	OPTBIT_small, // -S
> +	IF_FEATURE_LOGROTATE_CMD( OPTBIT_rotatecmd  ,)  // -c
>   	IF_FEATURE_ROTATE_LOGFILE(OPTBIT_filesize   ,)	// -s
>   	IF_FEATURE_ROTATE_LOGFILE(OPTBIT_rotatecnt  ,)	// -b
>   	IF_FEATURE_REMOTE_LOG(    OPTBIT_remotelog  ,)	// -R
> @@ -235,6 +250,7 @@ enum {
>   	OPT_outfile     = 1 << OPTBIT_outfile ,
>   	OPT_loglevel    = 1 << OPTBIT_loglevel,
>   	OPT_small       = 1 << OPTBIT_small   ,
> +	OPT_rotatecmd   = IF_FEATURE_LOGROTATE_CMD( (1 << OPTBIT_rotatecmd  )) + 0,
>   	OPT_filesize    = IF_FEATURE_ROTATE_LOGFILE((1 << OPTBIT_filesize   )) + 0,
>   	OPT_rotatecnt   = IF_FEATURE_ROTATE_LOGFILE((1 << OPTBIT_rotatecnt  )) + 0,
>   	OPT_remotelog   = IF_FEATURE_REMOTE_LOG(    (1 << OPTBIT_remotelog  )) + 0,
> @@ -246,6 +262,7 @@ enum {
>
>   };
>   #define OPTION_STR "m:nO:l:S" \
> +	IF_FEATURE_LOGROTATE_CMD( "c:" )  \
>   	IF_FEATURE_ROTATE_LOGFILE("s:" ) \
>   	IF_FEATURE_ROTATE_LOGFILE("b:" ) \
>   	IF_FEATURE_REMOTE_LOG(    "R:" ) \
> @@ -255,11 +272,13 @@ enum {
>   	IF_FEATURE_SYSLOGD_CFG(   "f:" ) \
>   	IF_FEATURE_KMSG_SYSLOG(   "K"  )
>   #define OPTION_DECL *opt_m, *opt_l \
> +	IF_FEATURE_LOGROTATE_CMD( ,*opt_c = NULL) \
>   	IF_FEATURE_ROTATE_LOGFILE(,*opt_s) \
>   	IF_FEATURE_ROTATE_LOGFILE(,*opt_b) \
>   	IF_FEATURE_IPC_SYSLOG(    ,*opt_C = NULL) \
>   	IF_FEATURE_SYSLOGD_CFG(   ,*opt_f = NULL)
>   #define OPTION_PARAM &opt_m, &(G.logFile.path), &opt_l \
> +	IF_FEATURE_LOGROTATE_CMD( ,&(G.logrotateCmd)) \
>   	IF_FEATURE_ROTATE_LOGFILE(,&opt_s) \
>   	IF_FEATURE_ROTATE_LOGFILE(,&opt_b) \
>   	IF_FEATURE_REMOTE_LOG(    ,&remoteAddrList) \
> @@ -639,7 +658,18 @@ static void log_locally(time_t now, char *msg, logFile_t *log_file)
>
>   #if ENABLE_FEATURE_ROTATE_LOGFILE
>   	if (G.logFileSize && log_file->isRegular && log_file->size > G.logFileSize) {
> -		if (G.logFileRotate) { /* always 0..99 */
> +		IF_FEATURE_LOGROTATE_CMD(
> +		if (G.logrotateCmd) {
> +			system(G.logrotateCmd);
> +
> +			/* Note the unlink(), below, saves us from
> +			 * getting into an infinite loop in the case that
> +			 * this "rotate" command actually doesn't do its job
> +			 * (and note that this precludes the command from
> +			 * intentionally leaving/inserting content in
> +			 * the new file).
> +			 */
> +		} else) if (G.logFileRotate) { /* always 0..99 */
>   			int oldname_len = strlen(log_file->path);
>   #if ENABLE_FEATURE_LOGROTATE_TIMESTAMPS
>   			int i = oldname_len + 1 + 4 + 2 + 2 + 2 + 2 + 2    + 1;
>

-- 
"'tis an ill wind that blows no minds."


More information about the busybox mailing list