Permalink
Browse files

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>
  • Loading branch information...
1 parent 3bf7ede commit 4b670c01dff7e5106d924a1267c23961b6926b6f @kerolasa kerolasa committed with Feb 21, 2014
Showing with 119 additions and 5 deletions.
  1. +2 −2 bash-completion/logger
  2. +16 −0 configure.ac
  3. +4 −0 misc-utils/Makemodule.am
  4. +28 −1 misc-utils/logger.1
  5. +69 −2 misc-utils/logger.c
View
@@ -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
;;
View
@@ -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]
View
@@ -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
View
@@ -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
View
@@ -54,18 +54,24 @@
#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),
ALL_TYPES = TYPE_UDP | TYPE_TCP
};
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)

0 comments on commit 4b670c0

Please sign in to comment.