Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,17 @@ AC_SEARCH_LIBS([clock_gettime], [rt],,[AC_MSG_ERROR([cannot find clock_gettime()
AC_SUBST([rt_LIBS],[$LIBS])
AX_RESTORE_FLAGS

USE_JOURNAL="no"
PKG_CHECK_MODULES([SYSTEMD], [libsystemd], [have_systemd=yes],[have_systemd=no])
if test "x$enable_systemd_journal" = "xyes" ; then
if test "x$have_systemd" = "xyes" ; then
AC_DEFINE_UNQUOTED(USE_JOURNAL, 1, [Use systemd journal logging])
USE_JOURNAL="yes"
else
echo "systemd libraries not found, will just use syslog"
fi
fi

# look for testing harness "check"
PKG_CHECK_MODULES([CHECK], [check >= 0.9.4],[with_check=yes],[with_check=no])
AM_CONDITIONAL(HAVE_CHECK, test "${with_check}" = "yes")
Expand Down Expand Up @@ -538,6 +549,9 @@ AC_ARG_WITH([socket-dir],
[ SOCKETDIR="$withval" ],
[ SOCKETDIR="$localstatedir/run" ])

AC_ARG_ENABLE([systemd-journal],
[AS_HELP_STRING([--enable-systemd-journal],[Allow use of systemd journal instead of syslog])])

AC_ARG_WITH([force-sockets-config-file],
[AS_HELP_STRING([--with-force-sockets-config-file=FILE],[config file to force IPC to use filesystem sockets (Linux & Cygwin only) @<:@SYSCONFDIR/libqb/force-filesystem-sockets@:>@])],
[ FORCESOCKETSFILE="$withval" ],
Expand Down Expand Up @@ -701,7 +715,6 @@ AC_SUBST([FORCESOCKETSFILE])
AC_DEFINE_UNQUOTED([SOCKETDIR], "$(eval echo ${SOCKETDIR})", [Socket directory])
AC_DEFINE_UNQUOTED([LOCALSTATEDIR], "$(eval echo ${localstatedir})", [localstate directory])
AC_DEFINE_UNQUOTED([PACKAGE_FEATURES], "${PACKAGE_FEATURES}", [quarterback built-in features])

AC_DEFINE_UNQUOTED([FORCESOCKETSFILE], "$(eval echo ${FORCESOCKETSFILE})", [for sockets config file])

# version parsing (for qbconfig.h)
Expand Down Expand Up @@ -763,6 +776,7 @@ AC_MSG_RESULT([ State information = ${localstatedir}])
AC_MSG_RESULT([ System configuration = ${sysconfdir}])
AC_MSG_RESULT([ SOCKETDIR = ${SOCKETDIR}])
AC_MSG_RESULT([ Features = ${PACKAGE_FEATURES}])
AC_MSG_RESULT([ Use systemd journal = ${USE_JOURNAL}])
AC_MSG_RESULT([])
AC_MSG_RESULT([$PACKAGE build info:])
AC_MSG_RESULT([ Optimization = ${OPT_CFLAGS}])
Expand Down
1 change: 1 addition & 0 deletions include/qb/qblog.h
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ enum qb_log_conf {
QB_LOG_CONF_IDENT,
QB_LOG_CONF_MAX_LINE_LEN,
QB_LOG_CONF_ELLIPSIS,
QB_LOG_CONF_USE_JOURNAL,
};

enum qb_log_filter_type {
Expand Down
4 changes: 2 additions & 2 deletions lib/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ EXTRA_libqb_la_DEPENDENCIES = qblog_script.ld qblog_script.la
EXTRA_DIST = qblog_script.ld.in qblog_script.la.in qblog_script_noop.ld

libqb_la_SOURCES = $(source_to_lint) unix.c
libqb_la_CFLAGS = $(PTHREAD_CFLAGS)
libqb_la_LIBADD = $(LTLIBOBJS) $(dlopen_LIBS) $(PTHREAD_LIBS) $(socket_LIBS) $(rt_LIBS)
libqb_la_CFLAGS = $(PTHREAD_CFLAGS) $(SYSTEMD_CFLAGS)
libqb_la_LIBADD = $(LTLIBOBJS) $(dlopen_LIBS) $(PTHREAD_LIBS) $(socket_LIBS) $(rt_LIBS) $(SYSTEMD_LIBS)

AM_LDFLAGS = $(LDFLAGS_COPY:-Bsymbolic-functions=)

Expand Down
2 changes: 1 addition & 1 deletion lib/libqb.pc.in
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ Version: @PACKAGE_VERSION@
Description: libqb
Requires:
Libs: -L${libdir} -lqb
Libs.private: @LIBS@
Libs.private: @LIBS@ @SYSTEMD_LIBS@
Cflags: -I${includedir}
11 changes: 11 additions & 0 deletions lib/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -1134,6 +1134,17 @@ qb_log_ctl2(int32_t t, enum qb_log_conf c, qb_log_ctl2_arg_t arg_not4directuse)
case QB_LOG_CONF_ELLIPSIS:
conf[t].ellipsis = arg_i32;
break;
case QB_LOG_CONF_USE_JOURNAL:
#ifdef USE_JOURNAL
if (t == QB_LOG_SYSLOG) {
conf[t].use_journal = arg_i32;
} else {
rc = -EINVAL;
}
#else
rc = -EOPNOTSUPP;
#endif
break;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current code silently ignores this operation if USE_JOURNAL is not defined. Wouldn't it be better to return some error instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. commit added (with test)


default:
rc = -EINVAL;
Expand Down
1 change: 1 addition & 0 deletions lib/log_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ struct qb_log_target {
int32_t file_sync;
int32_t debug;
int32_t extended;
int32_t use_journal;
size_t size;
size_t max_line_length;
int32_t ellipsis;
Expand Down
38 changes: 33 additions & 5 deletions lib/log_syslog.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@
#ifdef HAVE_SYSLOG_H
#include <syslog.h>
#endif /* HAVE_SYSLOG_H */
#ifdef USE_JOURNAL
#define SD_JOURNAL_SUPPRESS_LOCATION
#include <systemd/sd-journal.h>
#endif

#include "log_int.h"

static void
Expand Down Expand Up @@ -57,7 +62,21 @@ _syslog_logger(int32_t target,
if (final_priority < LOG_EMERG) {
final_priority = LOG_EMERG;
}
syslog(final_priority, "%s", output_buffer);
#ifdef USE_JOURNAL
if (t->use_journal) {
sd_journal_send("PRIORITY=%d", final_priority,
"CODE_LINE=%d", cs->lineno,
"CODE_FILE=%s", cs->filename,
"CODE_FUNC=%s", cs->function,
"SYSLOG_IDENTIFIER=%s", t->name,
"MESSAGE=%s", output_buffer,
NULL);
} else {
#endif
syslog(final_priority, "%s", output_buffer);
#ifdef USE_JOURNAL
}
#endif
if (t->max_line_length > QB_LOG_MAX_LEN) {
free(output_buffer);
}
Expand All @@ -66,15 +85,22 @@ _syslog_logger(int32_t target,
static void
_syslog_close(int32_t target)
{
closelog();
struct qb_log_target *t = qb_log_target_get(target);

if (!t->use_journal) {
closelog();
}
}

static void
_syslog_reload(int32_t target)
{
struct qb_log_target *t = qb_log_target_get(target);
closelog();
openlog(t->name, LOG_PID, t->facility);

if (!t->use_journal) {
closelog();
openlog(t->name, LOG_PID, t->facility);
}
}

int32_t
Expand All @@ -84,6 +110,8 @@ qb_log_syslog_open(struct qb_log_target *t)
t->reload = _syslog_reload;
t->close = _syslog_close;

openlog(t->name, LOG_PID, t->facility);
if (!t->use_journal) {
openlog(t->name, LOG_PID, t->facility);
}
return 0;
}
64 changes: 64 additions & 0 deletions tests/check_log.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
#include <qb/qbutil.h>
#include <qb/qblog.h>

#ifdef USE_JOURNAL
#include <systemd/sd-journal.h>
#endif

#include "_syslog_override.h"

extern size_t qb_vsnprintf_serialize(char *serialize, size_t max_len, const char *fmt, va_list ap);
Expand Down Expand Up @@ -976,8 +980,55 @@ START_TEST(test_zero_tags)
}
END_TEST

#ifdef USE_JOURNAL
START_TEST(test_journal)
{
int rc;
const char *msg;
size_t len;
pid_t log_pid;
sd_journal *jnl;
int count = 0;

qb_log_init("check_log", LOG_USER, LOG_DEBUG);
qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_TRUE);
rc = qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_USE_JOURNAL, 1);
ck_assert_int_eq(rc, 0);
qb_log(LOG_ERR, "Test message 1 from libqb");

qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_TRUE);
rc = qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_USE_JOURNAL, 1);
ck_assert_int_eq(rc, -EINVAL);
sleep(1);

/* Check it reached the journal */
rc = sd_journal_open(&jnl, 0);
ck_assert_int_eq(rc, 0);
rc = sd_journal_seek_tail(jnl);
ck_assert_int_eq(rc, 0);
SD_JOURNAL_FOREACH_BACKWARDS(jnl) {
rc = sd_journal_get_data(jnl, "_PID", (const void **)&msg, &len);
ck_assert_int_eq(rc, 0);
sscanf(msg, "_PID=%d", &log_pid);
fprintf(stderr, "PID message = '%s' - pid = %d (pid=%d, parent=%d)\n", msg, log_pid, getpid(), getppid());
if (log_pid == getpid()) {
rc = sd_journal_get_data(jnl, "MESSAGE", (const void **)&msg, &len);
ck_assert_int_eq(rc, 0);
break;
}
if (++count > 20) {
break;
}
}
sd_journal_close(jnl);
ck_assert_int_lt(count, 20);
}
END_TEST
#else
START_TEST(test_syslog)
{
int rc;

qb_log_init("flip", LOG_USER, LOG_INFO);
qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_TRUE);

Expand All @@ -989,9 +1040,14 @@ START_TEST(test_syslog)
qb_log(LOG_ERR, "second as flop");
ck_assert_str_eq(_syslog_ident, "flop");

/* This test only runs if USE_JOURNAL is undefined, so should always fail */
rc = qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_USE_JOURNAL, 1);
ck_assert_int_eq(rc, -EOPNOTSUPP);

qb_log_fini();
}
END_TEST
#endif

static Suite *
log_suite(void)
Expand All @@ -1015,7 +1071,15 @@ log_suite(void)
#endif
add_tcase(s, tc, test_extended_information);
add_tcase(s, tc, test_zero_tags);
/*
* You can still use syslog and journal in a normal application,
* but the syslog_override code doesn't work when -lsystemd is present
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this some load order problem?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried moving the link order around with no luck. TBH I don't care enough to spend time on it as it's only a test program. If you do, then I'm happy to take patches ;-)

#ifdef USE_JOURNAL
add_tcase(s, tc, test_journal);
#else
add_tcase(s, tc, test_syslog);
#endif

return s;
}
Expand Down