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. Signed-off-by: Sami Kerola <kerolasa@xxxxxx> --- bash-completion/logger | 4 +-- configure.ac | 16 ++++++++++++ misc-utils/Makemodule.am | 4 +++ misc-utils/logger.1 | 29 ++++++++++++++++++++- misc-utils/logger.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 115 insertions(+), 4 deletions(-) diff --git a/bash-completion/logger b/bash-completion/logger index 963abc7..6b4c7df 100644 --- a/bash-completion/logger +++ b/bash-completion/logger @@ -5,7 +5,7 @@ _logger_module() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" case $prev in - '-f'|'--file') + '-f'|'--file'|'--journald') local IFS=$'\n' compopt -o filenames COMPREPLY=( $(compgen -f -- $cur) ) @@ -37,7 +37,7 @@ _logger_module() esac case $cur in -*) - OPTS="--udp --id --file --help --server --port --priority --stderr --tag --socket --version" + OPTS="--journald --udp --id --file --help --server --port --priority --stderr --tag --socket --version" COMPREPLY=( $(compgen -W "${OPTS[*]}" -- $cur) ) return 0 ;; diff --git a/configure.ac b/configure.ac index e742801..2e47bac 100644 --- a/configure.ac +++ b/configure.ac @@ -716,6 +716,7 @@ AS_IF([test "x$enable_most_builds" = xyes], [ enable_newgrp=yes enable_reset=yes enable_socket_activation=yes + enable_journald=yes enable_tunelp=yes enable_vipw=yes enable_write=yes @@ -1414,6 +1415,21 @@ AS_IF([test "x$with_systemdsystemunitdir" != "xno"], [ ]) +AC_ARG_ENABLE([journald], + AS_HELP_STRING([--enable-journald], [add journald support to logger]), + [], [enable_journald=no] +) +have_journald=no +AS_IF([test "x$enable_journald" = xyes], [ + PKG_CHECK_MODULES([SYSTEMD_JOURNAL], [libsystemd-journal], [], [ + AC_MSG_ERROR([cannot find libsystemd-journal support]) + ]) + have_journald=yes + AC_DEFINE([HAVE_JOURNALD], [1], [Define if journald is available]) +]) +AM_CONDITIONAL([HAVE_JOURNALD], [test "x$have_journald" = xyes]) + + AC_ARG_WITH([smack], AS_HELP_STRING([--with-smack], [build with SMACK support]), [], [with_smack=no] diff --git a/misc-utils/Makemodule.am b/misc-utils/Makemodule.am index d30229d..05407de 100644 --- a/misc-utils/Makemodule.am +++ b/misc-utils/Makemodule.am @@ -20,6 +20,10 @@ endif usrbin_exec_PROGRAMS += logger dist_man_MANS += misc-utils/logger.1 logger_SOURCES = misc-utils/logger.c lib/strutils.c +if HAVE_JOURNALD +logger_LDADD = $(SYSTEMD_JOURNAL_LIBS) +logger_CFLAGS = $(SYSTEMD_JOURNAL_CFLAGS) +endif usrbin_exec_PROGRAMS += look dist_man_MANS += misc-utils/look.1 diff --git a/misc-utils/logger.1 b/misc-utils/logger.1 index c7c3de0..08cf907 100644 --- a/misc-utils/logger.1 +++ b/misc-utils/logger.1 @@ -122,6 +122,31 @@ Write to the specified .I socket instead of to the builtin syslog routines. .TP +\fB\-\-journald\fR [\fIfile\fR] +Write systemd journal entry. The entry is read from +.I stdin +or input +.IR file . +Each new line must begin with a field that is accepted by journald, see +.IR systemd.journal-fields (7) +for details. Use of MESSAGE_ID field is generally good idea, as they +make finding entries easy. +.IP +.nf +$ printf "%s\\n%s\\n%s\\n" MESSAGE_ID=86184c3b1aa444f58ebe7b30fec1438b DOGS=bark "CARAVAN=goes on" | logger --journald +$ logger --journald=entry.txt +.fi +.IP +Notice that +.B \-\-journald +will ignore values of other options, such as priority. If priority is +needed it must be within input, and use PRIORITY field. The simple +execution of +.B journalctl +will display MESSAGE field. Use +.B journalctl --output json-pretty +to see rest of the fields. +.TP \fB\-V\fR, \fB\-\-version\fR Display version information and exit. .TP @@ -169,7 +194,9 @@ logger \-p local0.notice \-t HOSTIDM \-f /dev/idmc logger \-n loghost.example.com System rebooted .SH SEE ALSO .BR syslog (3), -.BR syslogd (8) +.BR syslogd (8), +.BR journalctl (1), +.BR systemd.journal-fields (7) .SH STANDARDS The .B logger diff --git a/misc-utils/logger.c b/misc-utils/logger.c index 0717647..b4a25ce 100644 --- a/misc-utils/logger.c +++ b/misc-utils/logger.c @@ -58,6 +58,10 @@ #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 +69,8 @@ enum { }; enum { - OPT_PRIO_PREFIX = CHAR_MAX + 1 + OPT_PRIO_PREFIX = CHAR_MAX + 1, + OPT_JOURNALD }; @@ -204,6 +209,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 = malloc(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 = realloc(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 +288,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,6 +314,7 @@ int main(int argc, char **argv) char *server = NULL; char *port = NULL; int LogSock = -1, socket_type = ALL_TYPES; + FILE *jfd = NULL; static const struct option longopts[] = { { "id", no_argument, 0, 'i' }, @@ -287,6 +330,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 +388,16 @@ int main(int argc, char **argv) case OPT_PRIO_PREFIX: prio_prefix = 1; break; + case OPT_JOURNALD: + if (optarg) { + jfd = fopen(optarg, "r"); + if (!jfd) + err(EXIT_FAILURE, _("cannot open %s"), + optarg); + } else { + jfd = stdin; + } + break; case '?': default: usage(stderr); @@ -351,6 +407,14 @@ int main(int argc, char **argv) argv += optind; /* setup for logging */ + if (jfd) { + int ret = journald_entry(jfd); + if (stdin != jfd) + fclose(jfd); + if (ret == 0) + return EXIT_SUCCESS; + return EXIT_FAILURE; + } if (server) LogSock = inet_socket(server, port, socket_type); else if (usock) -- 1.9.0 -- To unsubscribe from this list: send the line "unsubscribe util-linux" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html