syslogd: start using bb_common_bufsiz1 instead of stack/malloc
logger: optimize, also use bb_common_bufsiz1 (~40 bytes) tested to eat arbitrarily-sized input at high speed - ok
This commit is contained in:
parent
b893497151
commit
a0e2a0a192
@ -3009,19 +3009,19 @@
|
|||||||
"System logging utility.\n" \
|
"System logging utility.\n" \
|
||||||
"Note that this version of syslogd ignores /etc/syslog.conf." \
|
"Note that this version of syslogd ignores /etc/syslog.conf." \
|
||||||
"\n\nOptions:" \
|
"\n\nOptions:" \
|
||||||
"\n -m MIN Minutes between MARK lines (default=20, 0=off)" \
|
"\n -m MIN Minutes between MARK lines (default=20, 0=off)" \
|
||||||
"\n -n Run as a foreground process" \
|
"\n -n Run as a foreground process" \
|
||||||
"\n -O FILE Use an alternate log file (default=/var/log/messages)" \
|
"\n -O FILE Use an alternate log file (default=/var/log/messages)" \
|
||||||
"\n -l n Sets the local log level of messages to n" \
|
"\n -l n Sets the local log level of messages to n" \
|
||||||
"\n -S Make logging output smaller" \
|
"\n -S Make logging output smaller" \
|
||||||
USE_FEATURE_ROTATE_LOGFILE( \
|
USE_FEATURE_ROTATE_LOGFILE( \
|
||||||
"\n -s SIZE Max size (KB) before rotate (default=200KB, 0=off)" \
|
"\n -s SIZE Max size (KB) before rotate (default=200KB, 0=off)" \
|
||||||
"\n -b NUM Number of rotated logs to keep (default=1, max=99, 0=purge)") \
|
"\n -b NUM Number of rotated logs to keep (default=1, max=99, 0=purge)") \
|
||||||
USE_FEATURE_REMOTE_LOG( \
|
USE_FEATURE_REMOTE_LOG( \
|
||||||
"\n -R HOST[:PORT] Log to IP or hostname on PORT (default PORT=514/UDP)" \
|
"\n -R HOST[:PORT] Log to IP or hostname on PORT (default PORT=514/UDP)" \
|
||||||
"\n -L Log locally and via network logging (default is network only)") \
|
"\n -L Log locally and via network logging (default is network only)") \
|
||||||
USE_FEATURE_IPC_SYSLOG( \
|
USE_FEATURE_IPC_SYSLOG( \
|
||||||
"\n -C[size(KiB)] Log to a circular buffer (read the buffer using logread)")
|
"\n -C[size(KiB)] Log to a shared mem buffer (read the buffer using logread)")
|
||||||
/* NB: -Csize shouldn't have space (because size is optional) */
|
/* NB: -Csize shouldn't have space (because size is optional) */
|
||||||
#define syslogd_example_usage \
|
#define syslogd_example_usage \
|
||||||
"$ syslogd -R masterlog:514\n" \
|
"$ syslogd -R masterlog:514\n" \
|
||||||
|
@ -8,13 +8,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "busybox.h"
|
#include "busybox.h"
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#if !defined CONFIG_SYSLOGD
|
#if !defined CONFIG_SYSLOGD
|
||||||
|
|
||||||
@ -93,49 +86,40 @@ int logger_main(int argc, char **argv)
|
|||||||
char *opt_p, *opt_t;
|
char *opt_p, *opt_t;
|
||||||
int pri = LOG_USER | LOG_NOTICE;
|
int pri = LOG_USER | LOG_NOTICE;
|
||||||
int option = 0;
|
int option = 0;
|
||||||
int c, i;
|
char name[80];
|
||||||
char buf[1024], name[128];
|
|
||||||
|
|
||||||
/* Fill out the name string early (may be overwritten later) */
|
/* Fill out the name string early (may be overwritten later) */
|
||||||
bb_getpwuid(name, geteuid(), sizeof(name));
|
bb_getpwuid(name, geteuid(), sizeof(name));
|
||||||
|
|
||||||
/* Parse any options */
|
/* Parse any options */
|
||||||
opt = getopt32(argc, argv, "p:st:", &opt_p, &opt_t);
|
opt = getopt32(argc, argv, "p:st:", &opt_p, &opt_t);
|
||||||
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
if (opt & 0x1) pri = pencode(opt_p); // -p
|
if (opt & 0x1) pri = pencode(opt_p); // -p
|
||||||
if (opt & 0x2) option |= LOG_PERROR; // -s
|
if (opt & 0x2) option |= LOG_PERROR; // -s
|
||||||
if (opt & 0x4) safe_strncpy(name, opt_t, sizeof(name)); // -t
|
if (opt & 0x4) safe_strncpy(name, opt_t, sizeof(name)); // -t
|
||||||
|
|
||||||
openlog(name, option, 0);
|
openlog(name, option, 0);
|
||||||
if (optind == argc) {
|
if (!argc) {
|
||||||
do {
|
while (fgets(bb_common_bufsiz1, BUFSIZ, stdin)) {
|
||||||
/* read from stdin */
|
if (bb_common_bufsiz1[0]
|
||||||
i = 0;
|
&& NOT_LONE_CHAR(bb_common_bufsiz1, '\n')
|
||||||
while ((c = getc(stdin)) != EOF && c != '\n' &&
|
) {
|
||||||
i < (sizeof(buf)-1)) {
|
/* Neither "" nor "\n" */
|
||||||
buf[i++] = c;
|
syslog(pri, "%s", bb_common_bufsiz1);
|
||||||
}
|
}
|
||||||
if (i > 0) {
|
}
|
||||||
buf[i++] = '\0';
|
|
||||||
syslog(pri, "%s", buf);
|
|
||||||
}
|
|
||||||
} while (c != EOF);
|
|
||||||
} else {
|
} else {
|
||||||
char *message = NULL;
|
char *message = NULL;
|
||||||
int len = argc - optind; /* for the space between the args
|
int len = 1; /* for NUL */
|
||||||
and '\0' */
|
int pos = 0;
|
||||||
opt = len;
|
do {
|
||||||
argv += optind;
|
len += strlen(*argv) + 1;
|
||||||
for (i = 0; i < opt; i++) {
|
|
||||||
len += strlen(*argv);
|
|
||||||
message = xrealloc(message, len);
|
message = xrealloc(message, len);
|
||||||
if(!i)
|
sprintf(message + pos, " %s", *argv),
|
||||||
message[0] = '\0';
|
pos = len;
|
||||||
else
|
} while (*++argv);
|
||||||
strcat(message, " ");
|
syslog(pri, "%s", message + 1); /* skip leading " " */
|
||||||
strcat(message, *argv);
|
|
||||||
argv++;
|
|
||||||
}
|
|
||||||
syslog(pri, "%s", message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
closelog();
|
closelog();
|
||||||
|
@ -56,13 +56,23 @@ static int remoteFD = -1;
|
|||||||
static struct sockaddr_in remoteAddr;
|
static struct sockaddr_in remoteAddr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* We are using bb_common_bufsiz1 for buffering: */
|
||||||
/* NB: we may need 2x this amount on stack... */
|
enum { MAX_READ = (BUFSIZ/6) & ~0xf };
|
||||||
enum { MAX_READ = 1024 };
|
/* We recv into this... (size: MAX_READ ~== BUFSIZ/6) */
|
||||||
|
#define RECVBUF bb_common_bufsiz1
|
||||||
|
/* ...then copy here, escaping control chars */
|
||||||
|
/* (can grow x2 + 1 max ~== BUFSIZ/3) */
|
||||||
|
#define PARSEBUF (bb_common_bufsiz1 + MAX_READ)
|
||||||
|
/* ...then sprintf into this, adding timestamp (15 chars),
|
||||||
|
* host (64), fac.prio (20) to the message */
|
||||||
|
/* (growth by: 15 + 64 + 20 + delims = ~110) */
|
||||||
|
#define PRINTBUF (bb_common_bufsiz1 + 3*MAX_READ + 0x10)
|
||||||
|
/* totals: BUFSIZ/6 + BUFSIZ/3 + BUFSIZ/3 = BUFSIZ - BUFSIZ/6
|
||||||
|
* -- we have BUFSIZ/6 extra at the ent of PRINTBUF
|
||||||
|
* which covers needed ~110 extra bytes (and much more) */
|
||||||
|
|
||||||
|
|
||||||
/* options */
|
/* Options */
|
||||||
/* Correct regardless of combination of CONFIG_xxx */
|
|
||||||
enum {
|
enum {
|
||||||
OPTBIT_mark = 0, // -m
|
OPTBIT_mark = 0, // -m
|
||||||
OPTBIT_nofork, // -n
|
OPTBIT_nofork, // -n
|
||||||
@ -175,11 +185,12 @@ static void ipcsyslog_init(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write message to buffer */
|
/* Write message to shared mem buffer */
|
||||||
static void log_to_shmem(const char *msg, int len)
|
static void log_to_shmem(const char *msg, int len)
|
||||||
{
|
{
|
||||||
static /*const*/ struct sembuf SMwup[1] = { {1, -1, IPC_NOWAIT} };
|
/* Why libc insists on these being rw? */
|
||||||
static /*const*/ struct sembuf SMwdn[3] = { {0, 0}, {1, 0}, {1, +1} };
|
static struct sembuf SMwup[1] = { {1, -1, IPC_NOWAIT} };
|
||||||
|
static struct sembuf SMwdn[3] = { {0, 0}, {1, 0}, {1, +1} };
|
||||||
|
|
||||||
int old_tail, new_tail;
|
int old_tail, new_tail;
|
||||||
char *c;
|
char *c;
|
||||||
@ -362,9 +373,9 @@ static void parse_fac_prio_20(int pri, char *res20)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* len parameter is used only for "is there a timestamp?" check
|
/* len parameter is used only for "is there a timestamp?" check.
|
||||||
* NB: some callers cheat and supply 0 when they know
|
* NB: some callers cheat and supply 0 when they know
|
||||||
* that there is no timestamp, short-cutting the test */
|
* that there is no timestamp, short-cutting the test. */
|
||||||
static void timestamp_and_log(int pri, char *msg, int len)
|
static void timestamp_and_log(int pri, char *msg, int len)
|
||||||
{
|
{
|
||||||
time_t now;
|
time_t now;
|
||||||
@ -385,31 +396,29 @@ static void timestamp_and_log(int pri, char *msg, int len)
|
|||||||
if (!ENABLE_FEATURE_REMOTE_LOG || (option_mask32 & OPT_locallog)) {
|
if (!ENABLE_FEATURE_REMOTE_LOG || (option_mask32 & OPT_locallog)) {
|
||||||
if (LOG_PRI(pri) < logLevel) {
|
if (LOG_PRI(pri) < logLevel) {
|
||||||
if (option_mask32 & OPT_small)
|
if (option_mask32 & OPT_small)
|
||||||
msg = xasprintf("%s %s\n", timestamp, msg);
|
sprintf(PRINTBUF, "%s %s\n", timestamp, msg);
|
||||||
else {
|
else {
|
||||||
char res[20];
|
char res[20];
|
||||||
parse_fac_prio_20(pri, res);
|
parse_fac_prio_20(pri, res);
|
||||||
msg = xasprintf("%s %s %s %s\n", timestamp, localHostName, res, msg);
|
sprintf(PRINTBUF, "%s %s %s %s\n", timestamp, localHostName, res, msg);
|
||||||
}
|
}
|
||||||
log_locally(msg);
|
log_locally(PRINTBUF);
|
||||||
free(msg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void split_escape_and_log(char *tmpbuf, int len)
|
static void split_escape_and_log(char *tmpbuf, int len)
|
||||||
{
|
{
|
||||||
char line[len * 2 + 1]; /* gcc' cheap alloca */
|
|
||||||
char *p = tmpbuf;
|
char *p = tmpbuf;
|
||||||
|
|
||||||
tmpbuf += len;
|
tmpbuf += len;
|
||||||
while (p < tmpbuf) {
|
while (p < tmpbuf) {
|
||||||
char c;
|
char c;
|
||||||
char *q = line;
|
char *q = PARSEBUF;
|
||||||
int pri = (LOG_USER | LOG_NOTICE);
|
int pri = (LOG_USER | LOG_NOTICE);
|
||||||
|
|
||||||
if (*p == '<') {
|
if (*p == '<') {
|
||||||
/* Parse the magic priority number. */
|
/* Parse the magic priority number */
|
||||||
pri = bb_strtou(p + 1, &p, 10);
|
pri = bb_strtou(p + 1, &p, 10);
|
||||||
if (*p == '>') p++;
|
if (*p == '>') p++;
|
||||||
if (pri & ~(LOG_FACMASK | LOG_PRIMASK)) {
|
if (pri & ~(LOG_FACMASK | LOG_PRIMASK)) {
|
||||||
@ -427,8 +436,8 @@ static void split_escape_and_log(char *tmpbuf, int len)
|
|||||||
*q++ = c;
|
*q++ = c;
|
||||||
}
|
}
|
||||||
*q = '\0';
|
*q = '\0';
|
||||||
/* now log it */
|
/* Now log it */
|
||||||
timestamp_and_log(pri, line, q - line);
|
timestamp_and_log(pri, PARSEBUF, q - PARSEBUF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -509,11 +518,10 @@ static void do_syslogd(void)
|
|||||||
|
|
||||||
if (FD_ISSET(sock_fd, &fds)) {
|
if (FD_ISSET(sock_fd, &fds)) {
|
||||||
int i;
|
int i;
|
||||||
#define tmpbuf bb_common_bufsiz1
|
i = recv(sock_fd, RECVBUF, MAX_READ - 1, 0);
|
||||||
i = recv(sock_fd, tmpbuf, MAX_READ, 0);
|
|
||||||
if (i <= 0)
|
if (i <= 0)
|
||||||
bb_perror_msg_and_die("UNIX socket error");
|
bb_perror_msg_and_die("UNIX socket error");
|
||||||
/* TODO: maybe supress duplicates? */
|
/* TODO: maybe suppress duplicates? */
|
||||||
#if ENABLE_FEATURE_REMOTE_LOG
|
#if ENABLE_FEATURE_REMOTE_LOG
|
||||||
/* We are not modifying log messages in any way before send */
|
/* We are not modifying log messages in any way before send */
|
||||||
/* Remote site cannot trust _us_ anyway and need to do validation again */
|
/* Remote site cannot trust _us_ anyway and need to do validation again */
|
||||||
@ -523,15 +531,14 @@ static void do_syslogd(void)
|
|||||||
}
|
}
|
||||||
if (-1 != remoteFD) {
|
if (-1 != remoteFD) {
|
||||||
/* send message to remote logger, ignore possible error */
|
/* send message to remote logger, ignore possible error */
|
||||||
sendto(remoteFD, tmpbuf, i, MSG_DONTWAIT,
|
sendto(remoteFD, RECVBUF, i, MSG_DONTWAIT,
|
||||||
(struct sockaddr *) &remoteAddr,
|
(struct sockaddr *) &remoteAddr,
|
||||||
sizeof(remoteAddr));
|
sizeof(remoteAddr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
tmpbuf[i] = '\0';
|
RECVBUF[i] = '\0';
|
||||||
split_escape_and_log(tmpbuf, i);
|
split_escape_and_log(RECVBUF, i);
|
||||||
#undef tmpbuf
|
|
||||||
} /* FD_ISSET() */
|
} /* FD_ISSET() */
|
||||||
} /* for */
|
} /* for */
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user