diff options
author | Colin Walters <walters@verbum.org> | 2016-06-14 13:12:21 -0400 |
---|---|---|
committer | Atomic Bot <atomic-devel@projectatomic.io> | 2016-06-21 18:24:17 +0000 |
commit | 9e2763106be01044caa541314d3fe185cc73361d (patch) | |
tree | 66b07e037eb38f0880e5205814726d3d95c880fc | |
parent | 4819b44189cbdde189a2693e081be39483838e78 (diff) | |
download | ostree-9e2763106be01044caa541314d3fe185cc73361d.tar.gz |
lib: Use sd_journal directly (optionally)
This was the last caller of libgsystem that isn't
`gs_file_get_path_cached()`. I think the use case ostree has where
the same code can be called via command line and via a shared library
*and* via a daemon is rather unusual, so let's just copy the code for
logging from libgsystem into here.
For example rpm-ostree hard depends on a daemon mode, so it'll just
use `sd_journal` directly.
Closes: #341
Approved by: jlebon
-rw-r--r-- | Makefile-libostree.am | 5 | ||||
-rw-r--r-- | Makefile-ostree.am | 2 | ||||
-rw-r--r-- | Makefile-otutil.am | 6 | ||||
-rw-r--r-- | configure.ac | 12 | ||||
-rw-r--r-- | src/libostree/ostree-sysroot-deploy.c | 6 | ||||
-rw-r--r-- | src/libotutil/ot-log-utils.c | 163 | ||||
-rw-r--r-- | src/libotutil/ot-log-utils.h | 31 | ||||
-rw-r--r-- | src/libotutil/otutil.h | 1 |
8 files changed, 216 insertions, 10 deletions
diff --git a/Makefile-libostree.am b/Makefile-libostree.am index d6b83528..8c2fd297 100644 --- a/Makefile-libostree.am +++ b/Makefile-libostree.am @@ -156,6 +156,11 @@ libostree_1_la_CFLAGS += $(OT_DEP_LIBARCHIVE_CFLAGS) libostree_1_la_LIBADD += $(OT_DEP_LIBARCHIVE_LIBS) endif +if BUILDOPT_LIBSYSTEMD +libostree_1_la_CFLAGS += $(LIBSYSTEMD_CFLAGS) +libostree_1_la_LIBADD += $(LIBSYSTEMD_LIBS) +endif + if USE_LIBSOUP libostree_1_la_SOURCES += \ src/libostree/ostree-fetcher.h \ diff --git a/Makefile-ostree.am b/Makefile-ostree.am index 0ef5c4ee..33875dc4 100644 --- a/Makefile-ostree.am +++ b/Makefile-ostree.am @@ -99,7 +99,7 @@ ostree_bin_shared_cflags = $(AM_CFLAGS) -I$(srcdir)/src/libotutil -I$(srcdir)/sr ostree_bin_shared_ldadd = libglnx.la libbsdiff.la libotutil.la libostree-kernel-args.la libostree-1.la ostree_CFLAGS = $(ostree_bin_shared_cflags) $(OT_INTERNAL_GIO_UNIX_CFLAGS) -I$(srcdir)/libglnx -ostree_LDADD = $(ostree_bin_shared_ldadd) $(OT_INTERNAL_GIO_UNIX_LIBS) +ostree_LDADD = $(ostree_bin_shared_ldadd) $(OT_INTERNAL_GIO_UNIX_LIBS) $(LIBSYSTEMD_LIBS) if USE_LIBSOUP ostree_SOURCES += \ diff --git a/Makefile-otutil.am b/Makefile-otutil.am index efcb04b7..ee892a70 100644 --- a/Makefile-otutil.am +++ b/Makefile-otutil.am @@ -36,6 +36,8 @@ libotutil_la_SOURCES = \ src/libotutil/ot-variant-utils.h \ src/libotutil/ot-gio-utils.c \ src/libotutil/ot-gio-utils.h \ + src/libotutil/ot-log-utils.c \ + src/libotutil/ot-log-utils.h \ src/libotutil/ot-gpg-utils.c \ src/libotutil/ot-gpg-utils.h \ src/libotutil/otutil.c \ @@ -43,5 +45,5 @@ libotutil_la_SOURCES = \ src/libotutil/ot-tool-util.c \ src/libotutil/ot-tool-util.h \ $(NULL) -libotutil_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/libglnx -I$(srcdir)/src/libotutil -DLOCALEDIR=\"$(datadir)/locale\" $(OT_INTERNAL_GIO_UNIX_CFLAGS) $(OT_INTERNAL_GPGME_CFLAGS) -libotutil_la_LIBADD = $(OT_INTERNAL_GIO_UNIX_LIBS) $(OT_INTERNAL_GPGME_LIBS) +libotutil_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/libglnx -I$(srcdir)/src/libotutil -DLOCALEDIR=\"$(datadir)/locale\" $(OT_INTERNAL_GIO_UNIX_CFLAGS) $(OT_INTERNAL_GPGME_CFLAGS) $(LIBSYSTEMD_CFLAGS) +libotutil_la_LIBADD = $(OT_INTERNAL_GIO_UNIX_LIBS) $(OT_INTERNAL_GPGME_LIBS) $(LIBSYSTEMD_LIBS) diff --git a/configure.ac b/configure.ac index 18f9f277..d28c410a 100644 --- a/configure.ac +++ b/configure.ac @@ -251,7 +251,13 @@ AC_ARG_WITH(mkinitcpio, [with_mkinitcpio=no]) AM_CONDITIONAL(BUILDOPT_MKINITCPIO, test x$with_mkinitcpio = xyes) -AS_IF([test "x$with_dracut" = "xyes" || test "x$with_dracut" = "xyesbutnoconf" || test "x$with_mkinitcpio" = "xyes"], [ +dnl We have separate checks for libsystemd and the unit dir for historical reasons +PKG_CHECK_MODULES([LIBSYSTEMD], [libsystemd], [have_libsystemd=yes], [have_libsystemd=no]) +AM_CONDITIONAL(BUILDOPT_LIBSYSTEMD, test x$have_libsystemd = xyes) +AM_COND_IF(BUILDOPT_LIBSYSTEMD, + AC_DEFINE([HAVE_LIBSYSTEMD], 1, [Define if we have libsystemd])) + +AS_IF([test "x$have_libsystemd" = "xyes"], [ with_systemd=yes AC_ARG_WITH([systemdsystemunitdir], AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [Directory for systemd service files]), @@ -309,6 +315,7 @@ echo " libsoup (retrieve remote HTTP repositories): $with_soup libsoup TLS client certs: $have_libsoup_client_certs SELinux: $with_selinux + systemd: $have_libsystemd libmount: $with_libmount libarchive (parse tar files directly): $with_libarchive static deltas: yes (always enabled now) @@ -322,7 +329,4 @@ AS_IF([test x$with_builtin_grub2_mkconfig = xyes], [ ], [ echo " grub2-mkconfig path: $GRUB2_MKCONFIG" ]) -AS_IF([test "x$with_systemd" = "xyes"], [ - echo " systemd unit dir: $with_systemdsystemunitdir" -]) echo "" diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c index 4616bab1..cc1a1faa 100644 --- a/src/libostree/ostree-sysroot-deploy.c +++ b/src/libostree/ostree-sysroot-deploy.c @@ -473,7 +473,7 @@ merge_etc_changes (GFile *orig_etc, goto out; } - gs_log_structured_print_id_v (OSTREE_CONFIGMERGE_ID, + ot_log_structured_print_id_v (OSTREE_CONFIGMERGE_ID, "Copying /etc changes: %u modified, %u removed, %u added", modified->len, removed->len, @@ -773,7 +773,7 @@ selinux_relabel_var_if_needed (OstreeSysroot *sysroot, if (!g_file_query_exists (deployment_var_labeled, NULL)) { - gs_log_structured_print_id_v (OSTREE_VARRELABEL_ID, + ot_log_structured_print_id_v (OSTREE_VARRELABEL_ID, "Relabeling /var (no stamp file '%s' found)", gs_file_get_path_cached (deployment_var_labeled)); @@ -1927,7 +1927,7 @@ ostree_sysroot_write_deployments (OstreeSysroot *self, } } - gs_log_structured_print_id_v (OSTREE_DEPLOYMENT_COMPLETE_ID, + ot_log_structured_print_id_v (OSTREE_DEPLOYMENT_COMPLETE_ID, "%s; bootconfig swap: %s deployment count change: %i", (bootloader_is_atomic ? "Transaction complete" : "Bootloader updated"), requires_new_bootversion ? "yes" : "no", diff --git a/src/libotutil/ot-log-utils.c b/src/libotutil/ot-log-utils.c new file mode 100644 index 00000000..e1ce1690 --- /dev/null +++ b/src/libotutil/ot-log-utils.c @@ -0,0 +1,163 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2016 Colin Walters <walters@verbum.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Colin Walters <walters@verbum.org> + */ + +#include "config.h" + +#include <gio/gio.h> + +#include <string.h> + +#include "otutil.h" +#include "libglnx.h" + +#ifdef HAVE_LIBSYSTEMD +#define SD_JOURNAL_SUPPRESS_LOCATION +#include <systemd/sd-journal.h> +#endif +#include <glib-unix.h> + +/** + * ot_log_structured: + * @message: Text message to send + * @keys: (allow-none) (array zero-terminated=1) (element-type utf8): Optional structured data + * + * Log structured data in an operating-system specific fashion. The + * parameter @opts should be an array of UTF-8 KEY=VALUE strings. + * This function does not support binary data. See + * http://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html + * for more information about fields that can be used on a systemd + * system. + */ +static void +ot_log_structured (const char *message, + const char *const *keys) +{ +#ifdef HAVE_LIBSYSTEMD + const char *const*iter; + g_autofree char *msgkey = NULL; + guint i, n_opts; + struct iovec *iovs; + + for (n_opts = 0, iter = keys; *iter; iter++, n_opts++) + ; + + n_opts++; /* Add one for MESSAGE= */ + iovs = g_alloca (sizeof (struct iovec) * n_opts); + + for (i = 0, iter = keys; *iter; iter++, i++) { + iovs[i].iov_base = (char*)keys[i]; + iovs[i].iov_len = strlen (keys[i]); + } + g_assert(i == n_opts-1); + msgkey = g_strconcat ("MESSAGE=", message, NULL); + iovs[i].iov_base = msgkey; + iovs[i].iov_len = strlen (msgkey); + + // The code location isn't useful since we're wrapping + sd_journal_sendv (iovs, n_opts); +#else + g_print ("%s\n", message); +#endif +} + +/** + * ot_stdout_is_journal: + * + * Use this function when you want your code to behave differently + * depeneding on whether your program was started as a systemd unit, + * or e.g. interactively at a terminal. + * + * Returns: %TRUE if stdout is (probably) connnected to the systemd journal + */ +static gboolean +ot_stdout_is_journal (void) +{ + static gsize initialized; + static gboolean stdout_is_socket; + + if (g_once_init_enter (&initialized)) + { + guint64 pid = (guint64) getpid (); + g_autofree char *fdpath = g_strdup_printf ("/proc/%" G_GUINT64_FORMAT "/fd/1", pid); + char buf[1024]; + ssize_t bytes_read; + + if ((bytes_read = readlink (fdpath, buf, sizeof(buf) - 1)) != -1) + { + buf[bytes_read] = '\0'; + stdout_is_socket = g_str_has_prefix (buf, "socket:"); + } + else + stdout_is_socket = FALSE; + + g_once_init_leave (&initialized, TRUE); + } + + return stdout_is_socket; +} + +/** + * gs_log_structured_print: + * @message: A message to log + * @keys: (allow-none) (array zero-terminated=1) (element-type utf8): Optional structured data + * + * Like gs_log_structured(), but also print to standard output (if it + * is not already connected to the system log). + */ +static void +ot_log_structured_print (const char *message, + const char *const *keys) +{ + ot_log_structured (message, keys); + +#ifdef HAVE_LIBSYSTEMD + if (!ot_stdout_is_journal ()) + g_print ("%s\n", message); +#endif +} + +/** + * ot_log_structured_print_id_v: + * @message_id: A unique MESSAGE_ID + * @format: A format string + * + * The provided @message_id is a unique MESSAGE_ID (see <ulink url="http://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html"> for more information). + * + * This function otherwise acts as ot_log_structured_print(), taking + * @format as a format string. + */ +void +ot_log_structured_print_id_v (const char *message_id, + const char *format, + ...) +{ + const char *key0 = glnx_strjoina ("MESSAGE_ID=", message_id); + const char *keys[] = { key0, NULL }; + g_autofree char *msg = NULL; + va_list args; + + va_start (args, format); + msg = g_strdup_vprintf (format, args); + va_end (args); + + ot_log_structured_print (msg, (const char *const *)keys); +} diff --git a/src/libotutil/ot-log-utils.h b/src/libotutil/ot-log-utils.h new file mode 100644 index 00000000..5e0502ab --- /dev/null +++ b/src/libotutil/ot-log-utils.h @@ -0,0 +1,31 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2016 Colin Walters <walters@verbum.org>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#pragma once + +#include "ot-unix-utils.h" + +G_BEGIN_DECLS + +void ot_log_structured_print_id_v (const char *message_id, + const char *format, + ...); + +G_END_DECLS diff --git a/src/libotutil/otutil.h b/src/libotutil/otutil.h index 754f9253..6790d8ff 100644 --- a/src/libotutil/otutil.h +++ b/src/libotutil/otutil.h @@ -47,5 +47,6 @@ #include <ot-spawn-utils.h> #include <ot-checksum-utils.h> #include <ot-gpg-utils.h> +#include <ot-log-utils.h> void ot_ptrarray_add_many (GPtrArray *a, ...) G_GNUC_NULL_TERMINATED; |