diff options
author | Sami Kerola | 2014-02-21 20:25:30 +0100 |
---|---|---|
committer | Karel Zak | 2014-03-04 13:44:21 +0100 |
commit | 4b670c01dff7e5106d924a1267c23961b6926b6f (patch) | |
tree | 42d62bfb27695ee725571add9c5750d917bd6208 /misc-utils/logger.c | |
parent | hexdump: color unit may now be longer than the corresponding format unit (diff) | |
download | kernel-qcow2-util-linux-4b670c01dff7e5106d924a1267c23961b6926b6f.tar.gz kernel-qcow2-util-linux-4b670c01dff7e5106d924a1267c23961b6926b6f.tar.xz kernel-qcow2-util-linux-4b670c01dff7e5106d924a1267c23961b6926b6f.zip |
logger: allow user to send structured journald messages
This feature is hopefully mostly used to give MESSAGE_ID labels for
messages coming from scripts, making search of messages easy. The
logger(1) manual page update should give enough information how to use
--journald option.
[kzak@redhat.com: - add missing #ifdefs
- use xalloc.h]
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'misc-utils/logger.c')
-rw-r--r-- | misc-utils/logger.c | 71 |
1 files changed, 69 insertions, 2 deletions
diff --git a/misc-utils/logger.c b/misc-utils/logger.c index 07176470e..c07bfac89 100644 --- a/misc-utils/logger.c +++ b/misc-utils/logger.c @@ -54,10 +54,15 @@ #include "closestream.h" #include "nls.h" #include "strutils.h" +#include "xalloc.h" #define SYSLOG_NAMES #include <syslog.h> +#ifdef HAVE_JOURNALD +# include <systemd/sd-journal.h> +#endif + enum { TYPE_UDP = (1 << 1), TYPE_TCP = (1 << 2), @@ -65,7 +70,8 @@ enum { }; enum { - OPT_PRIO_PREFIX = CHAR_MAX + 1 + OPT_PRIO_PREFIX = CHAR_MAX + 1, + OPT_JOURNALD }; @@ -204,6 +210,40 @@ static int inet_socket(const char *servername, const char *port, return fd; } +#ifdef HAVE_JOURNALD +static int journald_entry(FILE *fp) +{ + struct iovec *iovec; + char *buf = NULL; + ssize_t sz; + int n, lines, vectors = 8, ret; + size_t dummy = 0; + + iovec = xmalloc(vectors * sizeof(struct iovec)); + for (lines = 0; /* nothing */ ; lines++) { + buf = NULL; + sz = getline(&buf, &dummy, fp); + if (sz == -1) + break; + if (0 < sz && buf[sz - 1] == '\n') { + sz--; + buf[sz] = '\0'; + } + if (lines == vectors) { + vectors *= 2; + iovec = xrealloc(iovec, vectors * sizeof(struct iovec)); + } + iovec[lines].iov_base = buf; + iovec[lines].iov_len = sz; + } + ret = sd_journal_sendv(iovec, lines); + for (n = 0; n < lines; n++) + free(iovec[n].iov_base); + free(iovec); + return ret; +} +#endif + static void mysyslog(int fd, int logflags, int pri, char *tag, char *msg) { char buf[1000], pid[30], *cp, *tp; @@ -249,6 +289,9 @@ static void __attribute__ ((__noreturn__)) usage(FILE *out) fputs(_(" -s, --stderr output message to standard error as well\n"), out); fputs(_(" -t, --tag <tag> mark every line with this tag\n"), out); fputs(_(" -u, --socket <socket> write to this Unix socket\n"), out); +#ifdef HAVE_JOURNALD + fputs(_(" --journald[=<file>] write journald entry\n"), out); +#endif fputs(USAGE_SEPARATOR, out); fputs(USAGE_HELP, out); @@ -272,7 +315,9 @@ int main(int argc, char **argv) char *server = NULL; char *port = NULL; int LogSock = -1, socket_type = ALL_TYPES; - +#ifdef HAVE_JOURNALD + FILE *jfd = NULL; +#endif static const struct option longopts[] = { { "id", no_argument, 0, 'i' }, { "stderr", no_argument, 0, 's' }, @@ -287,6 +332,9 @@ int main(int argc, char **argv) { "version", no_argument, 0, 'V' }, { "help", no_argument, 0, 'h' }, { "prio-prefix", no_argument, 0, OPT_PRIO_PREFIX }, +#ifdef HAVE_JOURNALD + { "journald", optional_argument, 0, OPT_JOURNALD }, +#endif { NULL, 0, 0, 0 } }; @@ -342,6 +390,17 @@ int main(int argc, char **argv) case OPT_PRIO_PREFIX: prio_prefix = 1; break; +#ifdef HAVE_JOURNALD + case OPT_JOURNALD: + if (optarg) { + jfd = fopen(optarg, "r"); + if (!jfd) + err(EXIT_FAILURE, _("cannot open %s"), + optarg); + } else + jfd = stdin; + break; +#endif case '?': default: usage(stderr); @@ -351,6 +410,14 @@ int main(int argc, char **argv) argv += optind; /* setup for logging */ +#ifdef HAVE_JOURNALD + if (jfd) { + int ret = journald_entry(jfd); + if (stdin != jfd) + fclose(jfd); + return ret ? EXIT_FAILURE : EXIT_SUCCESS; + } +#endif if (server) LogSock = inet_socket(server, port, socket_type); else if (usock) |