mirror of
https://salsa.debian.org/ha-team/libqb
synced 2025-12-30 18:22:35 +00:00
Feature: allow changing the identifier for syslog (+tests)
Original "qb_log_ctl" interface had to be extended for passing read-only
strings (new parameter), resulting in new "qb_log_ctl2" function, which
is what qb_log_ctl calls into with the new parameter set to NULL.
This ensures backward compatibility.
A new QB_LOG_CONF_IDENT configuration directive for the mentioned
interface is added with a goal to set new internal identifier
that is, notably, used for syslog sink. This allows for switching
the identification without a need to reinitialize logging subsystem,
akin to changing target logging facility.
Also a brand new concept of testing syslog sink in particular is
introduced (finally). During initial trial&error stage, it used
LD_PRELOAD hack but it seems that libtool is sophisticated enough
that no such extra intervention is needed and the desired symbol
resolution Just Works (tm). However, the technique is highly
non-portable (there is even a warning about that from libtool,
which is partially on purpose as the _syslog_override.so should
rather be explicit it is by no mean a regular library) and hence
the syslog tests have to be enabled with explicit
./configure --enable-syslog-tests
rather than possibly break on untested platforms (far too many).
The concept can be extended upon, but initially, just the new
feature is being tested.
Post-review: thanks Chrissie for a suggestion how to deal with
extract-arg-and-forget in a less intrusive way (no defines).
This commit is contained in:
parent
242a07ebc2
commit
642f74de61
12
configure.ac
12
configure.ac
@ -434,6 +434,12 @@ AC_ARG_ENABLE([slow-tests],
|
||||
[ --enable-slow-tests : build and run slow tests. ],
|
||||
[ default="no" ])
|
||||
|
||||
if test x"$with_check" = xyes; then
|
||||
AC_ARG_ENABLE([syslog-tests],
|
||||
[ --enable-syslog-tests : build and run syslog tests. ],
|
||||
[ default="no" ])
|
||||
fi
|
||||
|
||||
AC_ARG_WITH([socket-dir],
|
||||
[ --with-socket-dir=DIR : socket dir. ],
|
||||
[ SOCKETDIR="$withval" ],
|
||||
@ -514,6 +520,12 @@ if test "x${enable_slow_tests}" = xyes ; then
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_SLOW_TESTS, [test "x${enable_slow_tests}" = xyes])
|
||||
AC_SUBST(HAVE_SLOW_TESTS)
|
||||
if test "x${enable_syslog_tests}" = xyes ; then
|
||||
AC_DEFINE([HAVE_SYSLOG_TESTS], 1,[have syslog tests])
|
||||
AC_MSG_NOTICE([Enabling syslog tests])
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_SYSLOG_TESTS, [test "x${enable_syslog_tests}" = xyes])
|
||||
AC_SUBST(HAVE_SYSLOG_TESTS)
|
||||
|
||||
# --- callsite sections ---
|
||||
if test "x${GCC}" = xyes; then
|
||||
|
||||
@ -420,6 +420,7 @@ enum qb_log_conf {
|
||||
QB_LOG_CONF_STATE_GET,
|
||||
QB_LOG_CONF_FILE_SYNC,
|
||||
QB_LOG_CONF_EXTENDED,
|
||||
QB_LOG_CONF_IDENT,
|
||||
};
|
||||
|
||||
enum qb_log_filter_type {
|
||||
@ -504,6 +505,30 @@ void qb_log_callsites_dump(void);
|
||||
*/
|
||||
int32_t qb_log_ctl(int32_t target, enum qb_log_conf conf_type, int32_t arg);
|
||||
|
||||
typedef union {
|
||||
int32_t i32;
|
||||
const char *s;
|
||||
} qb_log_ctl2_arg_t;
|
||||
|
||||
/**
|
||||
* Extension of main logging control function accepting also strings.
|
||||
*
|
||||
* @param arg for QB_LOG_CONF_IDENT, 's' member as new identifier to openlog(),
|
||||
* for all original qb_log_ctl-compatible configuration directives,
|
||||
* 'i32' member is assumed (although a preferred way is to use
|
||||
* that original function directly as it allows for more type safety)
|
||||
* @see qb_log_ctl
|
||||
*
|
||||
* @note You can use <tt>QB_LOG_CTL2_I32</tt> and <tt>QB_LOG_CTL2_S</tt>
|
||||
* macros for a convenient on-the-fly construction of the object
|
||||
* to be passed as an <tt>arg</tt> argument.
|
||||
*/
|
||||
int32_t qb_log_ctl2(int32_t target, enum qb_log_conf conf_type,
|
||||
qb_log_ctl2_arg_t arg);
|
||||
|
||||
#define QB_LOG_CTL2_I32(a) ((qb_log_ctl2_arg_t) { .i32 = (a) })
|
||||
#define QB_LOG_CTL2_S(a) ((qb_log_ctl2_arg_t) { .s = (a) })
|
||||
|
||||
/**
|
||||
* This allows you modify the 'tags' and 'targets' callsite fields at runtime.
|
||||
*/
|
||||
|
||||
34
lib/log.c
34
lib/log.c
@ -1060,11 +1060,15 @@ _log_target_disable(struct qb_log_target *t)
|
||||
}
|
||||
|
||||
int32_t
|
||||
qb_log_ctl(int32_t t, enum qb_log_conf c, int32_t arg)
|
||||
qb_log_ctl2(int32_t t, enum qb_log_conf c, qb_log_ctl2_arg_t arg_not4directuse)
|
||||
{
|
||||
int32_t rc = 0;
|
||||
int32_t need_reload = QB_FALSE;
|
||||
|
||||
/* extract the constants and do not touch the origin anymore */
|
||||
const int32_t arg_i32 = arg_not4directuse.i32;
|
||||
const char * const arg_s = arg_not4directuse.s;
|
||||
|
||||
if (!logger_inited) {
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -1074,7 +1078,7 @@ qb_log_ctl(int32_t t, enum qb_log_conf c, int32_t arg)
|
||||
}
|
||||
switch (c) {
|
||||
case QB_LOG_CONF_ENABLED:
|
||||
if (arg) {
|
||||
if (arg_i32) {
|
||||
rc = _log_target_enable(&conf[t]);
|
||||
} else {
|
||||
_log_target_disable(&conf[t]);
|
||||
@ -1084,33 +1088,39 @@ qb_log_ctl(int32_t t, enum qb_log_conf c, int32_t arg)
|
||||
rc = conf[t].state;
|
||||
break;
|
||||
case QB_LOG_CONF_FACILITY:
|
||||
conf[t].facility = arg;
|
||||
conf[t].facility = arg_i32;
|
||||
if (t == QB_LOG_SYSLOG) {
|
||||
need_reload = QB_TRUE;
|
||||
}
|
||||
break;
|
||||
case QB_LOG_CONF_IDENT:
|
||||
(void)strlcpy(conf[t].name, arg_s, PATH_MAX);
|
||||
if (t == QB_LOG_SYSLOG) {
|
||||
need_reload = QB_TRUE;
|
||||
}
|
||||
break;
|
||||
case QB_LOG_CONF_FILE_SYNC:
|
||||
conf[t].file_sync = arg;
|
||||
conf[t].file_sync = arg_i32;
|
||||
break;
|
||||
case QB_LOG_CONF_PRIORITY_BUMP:
|
||||
conf[t].priority_bump = arg;
|
||||
conf[t].priority_bump = arg_i32;
|
||||
break;
|
||||
case QB_LOG_CONF_SIZE:
|
||||
if (t == QB_LOG_BLACKBOX) {
|
||||
if (arg <= 0) {
|
||||
if (arg_i32 <= 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
conf[t].size = arg;
|
||||
conf[t].size = arg_i32;
|
||||
need_reload = QB_TRUE;
|
||||
} else {
|
||||
return -ENOSYS;
|
||||
}
|
||||
break;
|
||||
case QB_LOG_CONF_THREADED:
|
||||
conf[t].threaded = arg;
|
||||
conf[t].threaded = arg_i32;
|
||||
break;
|
||||
case QB_LOG_CONF_EXTENDED:
|
||||
conf[t].extended = arg;
|
||||
conf[t].extended = arg_i32;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1123,3 +1133,9 @@ qb_log_ctl(int32_t t, enum qb_log_conf c, int32_t arg)
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int32_t
|
||||
qb_log_ctl(int32_t t, enum qb_log_conf c, int32_t arg)
|
||||
{
|
||||
return qb_log_ctl2(t, c, QB_LOG_CTL2_I32(arg));
|
||||
}
|
||||
|
||||
@ -147,6 +147,13 @@ ipc_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@
|
||||
log_test_SOURCES = check_log.c $(top_builddir)/include/qb/qblog.h
|
||||
log_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include
|
||||
log_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@
|
||||
if HAVE_SYSLOG_TESTS
|
||||
log_test_LDADD += _syslog_override.la
|
||||
|
||||
lib_LTLIBRARIES = _syslog_override.la
|
||||
_syslog_override_la_SOURCES = _syslog_override.c
|
||||
_syslog_override_la_LDFLAGS = -module
|
||||
endif
|
||||
|
||||
util_test_SOURCES = check_util.c $(top_builddir)/include/qb/qbutil.h
|
||||
util_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include
|
||||
|
||||
62
tests/_syslog_override.c
Normal file
62
tests/_syslog_override.c
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Red Hat, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Jan Pokorny <jpokorny@redhat.com>
|
||||
*
|
||||
* This file is part of libqb.
|
||||
*
|
||||
* libqb 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.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libqb 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 libqb. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "_syslog_override.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
int _syslog_opened = 0;
|
||||
int _syslog_option = 0;
|
||||
int _syslog_facility = 0;
|
||||
char _syslog_ident[PATH_MAX] = "";
|
||||
|
||||
void openlog(const char *ident, int option, int facility);
|
||||
|
||||
void
|
||||
openlog(const char *ident, int option, int facility)
|
||||
{
|
||||
_syslog_opened = 1;
|
||||
_syslog_option = option;
|
||||
_syslog_facility = facility;
|
||||
strncpy(_syslog_ident, ident, sizeof(_syslog_ident));
|
||||
}
|
||||
|
||||
void syslog(int priority, const char *format, ...);
|
||||
|
||||
void
|
||||
syslog(int priority, const char *format, ...)
|
||||
{
|
||||
_syslog_opened = 1;
|
||||
}
|
||||
|
||||
void closelog(void);
|
||||
|
||||
void
|
||||
closelog(void)
|
||||
{
|
||||
_syslog_opened = 0;
|
||||
_syslog_option = -1;
|
||||
_syslog_facility = -1;
|
||||
_syslog_ident[0] = '\0';
|
||||
}
|
||||
34
tests/_syslog_override.h
Normal file
34
tests/_syslog_override.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Red Hat, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Jan Pokorny <jpokorny@redhat.com>
|
||||
*
|
||||
* This file is part of libqb.
|
||||
*
|
||||
* libqb 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.1 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libqb 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 libqb. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef QB_SYSLOG_OVERRIDE_H_DEFINED
|
||||
#define QB_SYSLOG_OVERRIDE_H_DEFINED
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
extern int _syslog_opened;
|
||||
extern int _syslog_option;
|
||||
extern int _syslog_facility;
|
||||
extern char _syslog_ident[PATH_MAX];
|
||||
|
||||
#endif
|
||||
@ -29,6 +29,10 @@
|
||||
#include <qb/qbutil.h>
|
||||
#include <qb/qblog.h>
|
||||
|
||||
#ifdef HAVE_SYSLOG_TESTS
|
||||
#include "_syslog_override.h"
|
||||
#endif
|
||||
|
||||
extern size_t qb_vsnprintf_serialize(char *serialize, size_t max_len, const char *fmt, va_list ap);
|
||||
extern size_t qb_vsnprintf_deserialize(char *string, size_t strlen, const char *buf);
|
||||
|
||||
@ -765,6 +769,25 @@ START_TEST(test_extended_information)
|
||||
}
|
||||
END_TEST
|
||||
|
||||
#ifdef HAVE_SYSLOG_TESTS
|
||||
START_TEST(test_syslog)
|
||||
{
|
||||
qb_log_init("flip", LOG_USER, LOG_INFO);
|
||||
qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_TRUE);
|
||||
|
||||
qb_log(LOG_ERR, "first as flip");
|
||||
ck_assert_int_eq(_syslog_opened, 1);
|
||||
ck_assert_str_eq(_syslog_ident, "flip");
|
||||
|
||||
qb_log_ctl2(QB_LOG_SYSLOG, QB_LOG_CONF_IDENT, QB_LOG_CTL2_S("flop"));
|
||||
qb_log(LOG_ERR, "second as flop");
|
||||
ck_assert_str_eq(_syslog_ident, "flop");
|
||||
|
||||
qb_log_fini();
|
||||
}
|
||||
END_TEST
|
||||
#endif
|
||||
|
||||
static Suite *
|
||||
log_suite(void)
|
||||
{
|
||||
@ -812,6 +835,12 @@ log_suite(void)
|
||||
tcase_add_test(tc, test_extended_information);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
#ifdef HAVE_SYSLOG_TESTS
|
||||
tc = tcase_create("syslog");
|
||||
tcase_add_test(tc, test_syslog);
|
||||
suite_add_tcase(s, tc);
|
||||
#endif
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user