summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2015-03-06 15:50:34 +0100
committerKarel Zak <kzak@redhat.com>2015-03-12 10:20:19 +0100
commit2a3b435d8ba7c6a5c26193102663d74abb74fcdb (patch)
treef5f74c3f96ed2c0d055ceb923dd1a6409fe01549
parent393600eb84533b09e765266b65c20eda12656ec6 (diff)
downloadutil-linux-2a3b435d8ba7c6a5c26193102663d74abb74fcdb.tar.gz
logger: permit to send messages larger than 1024 characters
This is an important capability that has been specified in RFC5424. However, messages larger than 1024 chars are being accepted for years now by at least rsyslog and syslog-ng. This patch adds the option --size to permit setting a new max size, with 1024 being the default. Note that the size limit is only approximative, as we do not take the header size in account (RFC talks about total message length). [[kzak@redhat.com: - add 'S' to getopt_long(), - rename --message-size to --size - add the option to bash-completion] Signed-off-by: Karel Zak <kzak@redhat.com>
-rw-r--r--bash-completion/logger2
-rw-r--r--misc-utils/logger.115
-rw-r--r--misc-utils/logger.c23
3 files changed, 32 insertions, 8 deletions
diff --git a/bash-completion/logger b/bash-completion/logger
index 0a66af309..593a67824 100644
--- a/bash-completion/logger
+++ b/bash-completion/logger
@@ -37,7 +37,7 @@ _logger_module()
esac
case $cur in
-*)
- OPTS="--journald --udp --id --file --help --server --port --priority --rfc3164 --rfc5424 --stderr --tag --socket --version"
+ OPTS="--journald --udp --id --file --help --server --port --priority --rfc3164 --rfc5424 --stderr --tag --size --socket --version"
COMPREPLY=( $(compgen -W "${OPTS[*]}" -- $cur) )
return 0
;;
diff --git a/misc-utils/logger.1 b/misc-utils/logger.1
index e05e99f2a..b73f46a9a 100644
--- a/misc-utils/logger.1
+++ b/misc-utils/logger.1
@@ -86,6 +86,21 @@ execution of
will display MESSAGE field. Use
.B journalctl --output json-pretty
to see rest of the fields.
+.TP
+.BR \-\--size " \fIsize
+Sets the maximum permitted message size to \fIsize\fR. The default
+is 1KiB characters, which is the limit traditionally used and specified
+in RFC 3164. With RFC 5424, this limit has become flexible. A good assumption
+is that RFC 5424 receivers can at least process 4KiB messages.
+
+Most receivers accept larger than 1KiB message over any type of syslog
+protocol. As such, the \fB\-\-size\fR option affects logger in
+all cases (not only when \fB\-\-rfc5424\fR was used).
+
+Note: the message size limit is not totally strict. It limits only
+the user data, the size of the syslog header is not considered. While
+this can lead to some truncation at the receiver level, a consistent limit
+based on the user data size is generally wanted.
.TP
.BR \-n , " \-\-server " \fIserver
diff --git a/misc-utils/logger.c b/misc-utils/logger.c
index 24cbb3b0b..3740c2e84 100644
--- a/misc-utils/logger.c
+++ b/misc-utils/logger.c
@@ -102,6 +102,7 @@ struct logger_ctl {
char *server;
char *port;
int socket_type;
+ size_t max_message_size;
void (*syslogfp)(const struct logger_ctl *ctl, const char *msg);
unsigned int
unix_socket_errors:1, /* whether to report or not errors */
@@ -374,7 +375,7 @@ static void syslog_rfc3164(const struct logger_ctl *ctl, const char *msg)
if (dot)
*dot = '\0';
- len = xasprintf(&buf, "<%d>%.15s %s %.200s%s: %.400s",
+ len = xasprintf(&buf, "<%d>%.15s %s %.200s%s: %s",
ctl->pri, rfc3164_current_time(), hostname, cp, pid, msg);
write_output(ctl, buf, len);
@@ -522,9 +523,9 @@ static void logger_open(struct logger_ctl *ctl)
static void logger_command_line(const struct logger_ctl *ctl, char **argv)
{
- char buf[4096];
+ char *const buf = xmalloc(ctl->max_message_size + 1);
char *p = buf;
- const char *endp = buf + sizeof(buf) - 2;
+ const char *endp = buf + ctl->max_message_size - 1;
size_t len;
while (*argv) {
@@ -533,7 +534,8 @@ static void logger_command_line(const struct logger_ctl *ctl, char **argv)
ctl->syslogfp(ctl, buf);
p = buf;
}
- if (sizeof(buf) - 1 < len) {
+ if (ctl->max_message_size < len) {
+ (*argv)[ctl->max_message_size] = '\0'; /* truncate */
ctl->syslogfp(ctl, *argv++);
continue;
}
@@ -550,9 +552,9 @@ static void logger_stdin(struct logger_ctl *ctl)
{
char *msg;
int default_priority = ctl->pri;
- char buf[1024];
+ char *const buf = xmalloc(ctl->max_message_size + 2);
- while (fgets(buf, sizeof(buf), stdin) != NULL) {
+ while (fgets(buf, ctl->max_message_size+2, stdin) != NULL) {
int len = strlen(buf);
/* some glibc versions are buggy, they add an additional
@@ -588,6 +590,7 @@ static void __attribute__ ((__noreturn__)) usage(FILE *out)
fputs(_(" -p, --priority <prio> mark given message with this priority\n"), out);
fputs(_(" --prio-prefix look for a prefix on every line read from stdin\n"), out);
fputs(_(" -s, --stderr output message to standard error as well\n"), out);
+ fputs(_(" -S, --size <size> maximum size for a single message\n"), out);
fputs(_(" -t, --tag <tag> mark every line with this tag\n"), out);
fputs(_(" -n, --server <name> write to this remote syslog server\n"), out);
fputs(_(" -P, --port <number> use this UDP port\n"), out);
@@ -630,6 +633,7 @@ int main(int argc, char **argv)
.server = NULL,
.port = NULL,
.socket_type = ALL_TYPES,
+ .max_message_size = 1024,
.rfc5424_time = 1,
.rfc5424_tq = 1,
.rfc5424_host = 1,
@@ -657,6 +661,7 @@ int main(int argc, char **argv)
{ "prio-prefix", no_argument, 0, OPT_PRIO_PREFIX },
{ "rfc3164", no_argument, 0, OPT_RFC3164 },
{ "rfc5424", optional_argument, 0, OPT_RFC5424 },
+ { "size", required_argument, 0, 'S' },
#ifdef HAVE_LIBSYSTEMD
{ "journald", optional_argument, 0, OPT_JOURNALD },
#endif
@@ -668,7 +673,7 @@ int main(int argc, char **argv)
textdomain(PACKAGE);
atexit(close_stdout);
- while ((ch = getopt_long(argc, argv, "f:ip:st:u:dTn:P:Vh",
+ while ((ch = getopt_long(argc, argv, "f:ip:S:st:u:dTn:P:Vh",
longopts, NULL)) != -1) {
switch (ch) {
case 'f': /* file to log */
@@ -701,6 +706,10 @@ int main(int argc, char **argv)
case 'u': /* unix socket */
ctl.unix_socket = optarg;
break;
+ case 'S': /* max message size */
+ ctl.max_message_size = strtosize_or_err(optarg,
+ _("failed to parse message size"));
+ break;
case 'd':
ctl.socket_type = TYPE_UDP;
break;