booth/0002-Feature-alternative-logging-provider-libqb.patch
Jan Pokorný 0c140f2bb9
1.0-3.570876d.git - update per the changesets recently accepted
...by the upstream (memory/resource leaks fixes, patches previously
attached separately that make unit test pass, internal cleanups, etc.)

Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
2016-05-25 10:14:11 +02:00

374 lines
12 KiB
Diff

From c1211c0d47fb510fbd659d9165dc584a9181ec22 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= <jpokorny@redhat.com>
Date: Tue, 26 Apr 2016 16:44:48 +0200
Subject: [PATCH 2/6] Feature: alternative logging provider: libqb
---
booth.spec | 3 ++
configure.ac | 28 ++++++++++++++++-
src/Makefile.am | 8 +++++
src/alt/logging_libqb.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++
src/alt/logging_libqb.h | 70 +++++++++++++++++++++++++++++++++++++++++
src/log.h | 22 +++++++++----
src/main.c | 26 ++++++++++++---
7 files changed, 229 insertions(+), 12 deletions(-)
create mode 100644 src/alt/logging_libqb.c
create mode 100644 src/alt/logging_libqb.h
diff --git a/booth.spec b/booth.spec
index f73d2d8..cc73af2 100644
--- a/booth.spec
+++ b/booth.spec
@@ -66,6 +66,9 @@ BuildRequires: cluster-glue-libs-devel
%else
BuildRequires: libglue-devel
%endif
+%else
+# logging provider
+BuildRequires: pkgconfig(libqb)
%endif
BuildRequires: libxml2-devel
BuildRequires: zlib-devel
diff --git a/configure.ac b/configure.ac
index 1a8ed4c..32a7dd1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6,7 +6,7 @@ AC_PREREQ([2.61])
AC_INIT([booth], [1.0], [users@clusterlabs.org])
-AM_INIT_AUTOMAKE([-Wno-portability])
+AM_INIT_AUTOMAKE([-Wno-portability subdir-objects])
AC_CONFIG_SRCDIR([src/main.c])
AC_CONFIG_HEADER([src/b_config.h src/booth_config.h])
@@ -220,6 +220,31 @@ AC_ARG_WITH([glue],
[],
[with_glue=yes])
+# figure out logging provider
+logging_provider=""
+if test "x$logging_provider" = "x" && test "x$with_glue" = "xyes"; then
+ AC_CHECK_LIB([plumb], [cl_log], [logging_provider="libplumb"])
+fi
+if test "x$logging_provider" = "x" && test "x$with_glue" = "xno"; then
+ AC_CHECK_LIB([qb], [qb_log_real_], [logging_provider="libqb"])
+fi
+case "$logging_provider" in
+libplumb)
+ ;;
+libqb)
+ PKG_CHECK_MODULES([LIBQB], [libqb])
+ AC_DEFINE([LOGGING_LIBQB], [], [use libqb as a logging provider])
+ PKG_CHECK_MODULES([LIBQB1], [libqb >= 1.0],
+ [AC_DEFINE([LOGGING_LIBQB_MAJOR], [1],
+ [libqb major version lower bound])],
+ [AC_MSG_WARN([[syslog identifier will not get changed]])])
+ ;;
+*)
+ AC_MSG_ERROR([logging provider required (libplumb, or libqb when --without-glue)])
+ ;;
+esac
+AM_CONDITIONAL([LOGGING_LIBQB], [test "x$logging_provider" = "xlibqb"])
+
# OS detection
# THIS SECTION MUST DIE!
CP=cp
@@ -448,6 +473,7 @@ AC_MSG_RESULT([ System init.d directory = ${INITDDIR}])
AC_MSG_RESULT([ booth config dir = ${BOOTHSYSCONFDIR}])
AC_MSG_RESULT([ SOCKETDIR = ${SOCKETDIR}])
AC_MSG_RESULT([ Features = ${PACKAGE_FEATURES}])
+AC_MSG_RESULT([ Logging provider = ${logging_provider}])
AC_MSG_RESULT([])
AC_MSG_RESULT([$PACKAGE build info:])
AC_MSG_RESULT([ Library SONAME = ${SONAME}])
diff --git a/src/Makefile.am b/src/Makefile.am
index e7f5aa2..49c3ac4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -25,5 +25,13 @@ boothd_LDFLAGS = $(OS_DYFLAGS) -L./
boothd_LDADD = -lplumb -lplumbgpl -lm $(GLIB_LIBS) $(ZLIB_LIBS)
boothd_CFLAGS = $(GLIB_CFLAGS)
+if !LOGGING_LIBQB
+boothd_LDADD += -lplumb
+else
+boothd_LDADD += $(LIBQB_LIBS)
+boothd_SOURCES += alt/logging_libqb.c
+noinst_HEADERS += alt/logging_libqb.h
+endif
+
lint:
-splint $(INCLUDES) $(LINT_FLAGS) $(CFLAGS) *.c
diff --git a/src/alt/logging_libqb.c b/src/alt/logging_libqb.c
new file mode 100644
index 0000000..34cf97c
--- /dev/null
+++ b/src/alt/logging_libqb.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2016 Jan Pokorny <jpokorny@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This software 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <qb/qblog.h>
+
+#include "logging_libqb.h"
+
+int debug_level = 0;
+
+/* ENV_X definitions based on glue/lib/clplumbing/cl_log.c of glue project:
+ http://hg.linux-ha.org/glue */
+#define ENV_HADEBUGVAL "HA_debug"
+#define ENV_LOGFENV "HA_logfile" /* well-formed log file :-) */
+#define ENV_DEBUGFENV "HA_debugfile" /* Debug log file */
+#define ENV_LOGFACILITY "HA_logfacility"/* Facility to use for logger */
+#define ENV_SYSLOGFMT "HA_syslogmsgfmt"/* TRUE if we should use syslog message formatting */
+
+void
+alt_qb_inherit_logging_environment(void)
+{
+ char *inherit_env;
+
+ /* Don't need to free the return pointer from getenv */
+ inherit_env = getenv(ENV_HADEBUGVAL);
+ if (inherit_env != NULL && atoi(inherit_env) != 0 )
+ debug_level = atoi(inherit_env);
+
+ inherit_env = getenv(ENV_LOGFENV);
+ if (inherit_env != NULL && *inherit_env != '\0') {
+ int32_t log_fd = qb_log_file_open(inherit_env);
+ qb_log_ctl(log_fd, QB_LOG_CONF_ENABLED, QB_TRUE);
+ /* do not log debug info even if debug_level non-zero */
+ qb_log_filter_ctl(log_fd, QB_LOG_FILTER_ADD,
+ QB_LOG_FILTER_FILE, "*", LOG_INFO);
+ }
+
+ inherit_env = getenv(ENV_DEBUGFENV);
+ if (inherit_env != NULL && *inherit_env != '\0') {
+ int32_t log_fd = qb_log_file_open(inherit_env);
+ qb_log_ctl(log_fd, QB_LOG_CONF_ENABLED, QB_TRUE);
+ }
+
+ inherit_env = getenv(ENV_LOGFACILITY);
+ if (inherit_env != NULL && *inherit_env != '\0') {
+ int fac = qb_log_facility2int(inherit_env);
+ if (fac > 0)
+ qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_FACILITY, fac);
+ else
+ qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);
+ }
+
+ inherit_env = getenv(ENV_SYSLOGFMT);
+ if (inherit_env != NULL && *inherit_env != '\0'
+ && ( !strcasecmp(inherit_env, "false")
+ || !strcasecmp(inherit_env, "off")
+ || !strcasecmp(inherit_env, "no")
+ || !strcasecmp(inherit_env, "n")
+ || !strcasecmp(inherit_env, "0"))){
+ enum qb_log_target_slot i;
+ for (i = QB_LOG_TARGET_START; i < QB_LOG_TARGET_MAX; i++) {
+ if (i == QB_LOG_SYSLOG || i == QB_LOG_BLACKBOX)
+ continue;
+ qb_log_format_set(i, NULL);
+ }
+ }
+}
diff --git a/src/alt/logging_libqb.h b/src/alt/logging_libqb.h
new file mode 100644
index 0000000..76592d4
--- /dev/null
+++ b/src/alt/logging_libqb.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2016 Jan Pokorny <jpokorny@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This software 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <qb/qblog.h>
+
+#include "b_config.h"
+
+/* qb logging compat definitions */
+#if (!defined LOGGING_LIBQB_MAJOR || (LOGGING_LIBQB_MAJOR < 1))
+enum tmp_log_target_slot {
+ TMP_LOG_SYSLOG = QB_LOG_SYSLOG,
+ TMP_LOG_STDERR = QB_LOG_STDERR,
+ TMP_LOG_BLACKBOX = QB_LOG_BLACKBOX,
+ TMP_LOG_TARGET_MAX = QB_LOG_TARGET_MAX,
+};
+
+#undef QB_LOG_SYSLOG
+#undef QB_LOG_STDERR
+#undef QB_LOG_BLACKBOX
+#undef QB_LOG_TARGET_MAX
+
+enum qb_log_target_slot {
+ QB_LOG_TARGET_START,
+ QB_LOG_SYSLOG = TMP_LOG_SYSLOG,
+ QB_LOG_STDERR = TMP_LOG_STDERR,
+ QB_LOG_BLACKBOX = TMP_LOG_BLACKBOX,
+ QB_LOG_TARGET_MAX = TMP_LOG_TARGET_MAX,
+};
+
+#define QB_LOG_CTL2_S(a) (a)
+#define qb_log_ctl2(t, s, a) ((void) 0)
+#endif
+
+
+#ifndef HA_LOG_FACILITY
+/* based on glue/configure.ac of glue project: http://hg.linux-ha.org/glue */
+#define HA_LOG_FACILITY LOG_DAEMON
+#endif
+
+extern int debug_level;
+#define ANYDEBUG (debug_level)
+
+void alt_qb_inherit_logging_environment(void);
+
+#define cl_log_set_entity(ent) \
+ (void) qb_log_ctl2(QB_LOG_SYSLOG, QB_LOG_CONF_IDENT, QB_LOG_CTL2_S(ent))
+
+#define cl_log_enable_stderr(b) \
+ (void) qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, b ? QB_TRUE : QB_FALSE)
+
+#define cl_log_set_facility(f) \
+ (void) qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_FACILITY, f)
+
+#define cl_inherit_logging_environment(logqueuemax) \
+ alt_qb_inherit_logging_environment()
diff --git a/src/log.h b/src/log.h
index 0be4066..e570a8d 100644
--- a/src/log.h
+++ b/src/log.h
@@ -21,26 +21,36 @@
#ifndef _LOG_H
#define _LOG_H
+#include "b_config.h"
+
+#ifndef LOGGING_LIBQB
#include <heartbeat/glue_config.h>
#include <clplumbing/cl_log.h>
+#define priv_log(prio, ...) cl_log(prio, __VA_ARGS__)
+#else
+#include "alt/logging_libqb.h"
+#define priv_log(prio, ...) qb_log(prio, __VA_ARGS__)
+#endif
+
#include "inline-fn.h"
+
#define log_debug(fmt, args...) do { \
- if (ANYDEBUG) cl_log(LOG_DEBUG, fmt, ##args); } \
+ if (ANYDEBUG) priv_log(LOG_DEBUG, fmt, ##args); } \
while (0)
-#define log_info(fmt, args...) cl_log(LOG_INFO, fmt, ##args)
-#define log_warn(fmt, args...) cl_log(LOG_WARNING, fmt, ##args)
-#define log_error(fmt, args...) cl_log(LOG_ERR, fmt, ##args)
+#define log_info(fmt, args...) priv_log(LOG_INFO, fmt, ##args)
+#define log_warn(fmt, args...) priv_log(LOG_WARNING, fmt, ##args)
+#define log_error(fmt, args...) priv_log(LOG_ERR, fmt, ##args)
/* all tk_* macros prepend "%(tk->name): " (the caller needs to
* have the ticket named tk!)
*/
#define tk_cl_log(sev, fmt, args...) \
- cl_log(sev, "%s (%s/%d/%d): " fmt, \
+ priv_log(sev, "%s (%s/%d/%d): " fmt, \
tk->name, state_to_string(tk->state), tk->current_term, term_time_left(tk), \
##args)
#define tk_cl_log_src(sev, fmt, args...) \
- cl_log(sev, "%s:%d: %s (%s/%d/%d): " fmt, \
+ priv_log(sev, "%s:%d: %s (%s/%d/%d): " fmt, \
__FUNCTION__, __LINE__, \
tk->name, state_to_string(tk->state), tk->current_term, term_time_left(tk), \
##args)
diff --git a/src/main.c b/src/main.c
index c377392..498718b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1536,6 +1536,9 @@ int main(int argc, char *argv[], char *envp[])
{
int rv;
const char *cp;
+#ifdef LOGGING_LIBQB
+ enum qb_log_target_slot i;
+#endif
init_set_proc_title(argc, argv, envp);
get_time(&start_time);
@@ -1546,15 +1549,25 @@ int main(int argc, char *argv[], char *envp[])
cl.lockfile[0] = 0;
debug_level = 0;
- cl_log_set_entity(
- (cp = strstr(argv[0], ATTR_PROG)) && !strcmp(cp, ATTR_PROG)
+
+ cp = ((cp = strstr(argv[0], ATTR_PROG)) && !strcmp(cp, ATTR_PROG)
? ATTR_PROG
- : "booth"
- );
+ : "booth");
+#ifndef LOGGING_LIBQB
+ cl_log_set_entity(cp);
+#else
+ qb_log_init(cp, LOG_USER, LOG_DEBUG); /* prio driven by debug_level */
+ for (i = QB_LOG_TARGET_START; i < QB_LOG_TARGET_MAX; i++) {
+ if (i == QB_LOG_SYSLOG || i == QB_LOG_BLACKBOX)
+ continue;
+ qb_log_format_set(i, "%t %H %N: [%P]: %p: %b");
+ }
+ (void) qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
+ QB_LOG_FILTER_FILE, "*", LOG_DEBUG);
+#endif
cl_log_enable_stderr(TRUE);
cl_log_set_facility(0);
-
rv = read_arguments(argc, argv);
if (rv < 0)
goto out;
@@ -1581,6 +1594,9 @@ int main(int argc, char *argv[], char *envp[])
}
out:
+#ifdef LOGGING_LIBQB
+ qb_log_fini();
+#endif
/* Normalize values. 0x100 would be seen as "OK" by waitpid(). */
return (rv >= 0 && rv < 0x70) ? rv : 1;
}
--
2.4.11