summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config.tests/unix/journald/journald.c48
-rw-r--r--config.tests/unix/journald/journald.pro6
-rwxr-xr-xconfigure29
-rw-r--r--src/corelib/global/global.pri6
-rw-r--r--src/corelib/global/qlogging.cpp48
5 files changed, 137 insertions, 0 deletions
diff --git a/config.tests/unix/journald/journald.c b/config.tests/unix/journald/journald.c
new file mode 100644
index 0000000000..470d526e68
--- /dev/null
+++ b/config.tests/unix/journald/journald.c
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Jolla Ltd, author: <robin.burchell@jollamobile.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the config.tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <systemd/sd-journal.h>
+
+int main(int argc, char **argv)
+{
+ sd_journal_print_with_location(LOG_INFO, "CODE_FILE=foo.c", "CODE_LINE=0", "unknown_function", "test message");
+ return 0;
+}
diff --git a/config.tests/unix/journald/journald.pro b/config.tests/unix/journald/journald.pro
new file mode 100644
index 0000000000..2bb50ceb71
--- /dev/null
+++ b/config.tests/unix/journald/journald.pro
@@ -0,0 +1,6 @@
+SOURCES = journald.c
+
+CONFIG += link_pkgconfig
+PKGCONFIG_PRIVATE += libsystemd-journal
+
+CONFIG -= qt
diff --git a/configure b/configure
index cb4ea3f0eb..f745c122f5 100755
--- a/configure
+++ b/configure
@@ -596,6 +596,7 @@ CFG_XINERAMA=runtime
CFG_XFIXES=runtime
CFG_ZLIB=auto
CFG_MTDEV=auto
+CFG_JOURNALD=no
CFG_SQLITE=qt
CFG_GIF=auto
CFG_PNG=yes
@@ -1590,6 +1591,13 @@ while [ "$#" -gt 0 ]; do
UNKNOWN_OPT=yes
fi
;;
+ journald)
+ if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then
+ CFG_JOURNALD="$VAL"
+ else
+ UNKNOWN_OPT=yes
+ fi
+ ;;
sqlite)
if [ "$VAL" = "system" ]; then
CFG_SQLITE=system
@@ -2307,6 +2315,9 @@ Third Party Libraries:
-no-mtdev ......... Do not compile mtdev support.
+ -mtdev ............. Enable mtdev support.
+ + -no-journald ....... Do not send logging output to journald.
+ -journald .......... Send logging output to journald.
+
-no-gif ............ Do not compile GIF reading support.
-no-libpng ......... Do not compile PNG support.
@@ -4416,6 +4427,23 @@ if [ "$CFG_MTDEV" = "no" ]; then
QMakeVar add DEFINES QT_NO_MTDEV
fi
+if [ "$CFG_JOURNALD" != "no" ]; then
+ if compileTest unix/journald "journald"; then
+ CFG_JOURNALD=yes
+ QMAKE_CONFIG="$QMAKE_CONFIG journald"
+ else
+ if [ "$CFG_JOURNALD" != "auto" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then
+ echo "journald support cannot be enabled due to functionality tests!"
+ echo " Turn on verbose messaging (-v) to $0 to see the final report."
+ echo " If you believe this message is in error you may use the continue"
+ echo " switch (-continue) to $0 to continue."
+ exit 101
+ else
+ CFG_JOURNALD=no
+ fi
+ fi
+fi
+
if [ "$CFG_LARGEFILE" = "auto" ]; then
#Large files should be enabled for all Linux systems
CFG_LARGEFILE=yes
@@ -6724,6 +6752,7 @@ report_support_plugin " JPEG ................." "$CFG_JPEG" "$CFG_LIBJPEG" Qt
report_support_plugin " PNG .................." "$CFG_PNG" "$CFG_LIBPNG" QtGui
report_support " Glib ..................." "$CFG_GLIB"
report_support " GTK theme .............." "$CFG_QGTKSTYLE"
+report_support " journald ..............." "$CFG_JOURNALD"
report_support " Large File ............." "$CFG_LARGEFILE"
report_support " mtdev .................." "$CFG_MTDEV" yes "system library"
report_support " Networking:"
diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri
index fd031469f6..789f500cab 100644
--- a/src/corelib/global/global.pri
+++ b/src/corelib/global/global.pri
@@ -51,3 +51,9 @@ slog2 {
LIBS_PRIVATE += -lslog2
DEFINES += QT_USE_SLOG2
}
+
+journald {
+ CONFIG += link_pkgconfig
+ PKGCONFIG_PRIVATE += libsystemd-journal
+ DEFINES += QT_USE_JOURNALD
+}
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 076582373e..23d046acf0 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -63,6 +63,11 @@
#include <android/log.h>
#endif
+#if defined(QT_USE_JOURNALD) && !defined(QT_BOOTSTRAPPED)
+# include <systemd/sd-journal.h>
+# include <unistd.h>
+#endif
+
#include <stdio.h>
QT_BEGIN_NAMESPACE
@@ -866,6 +871,37 @@ Q_CORE_EXPORT QtMsgHandler qInstallMsgHandler(QtMsgHandler);
static QtMsgHandler msgHandler = 0; // pointer to debug handler (without context)
static QtMessageHandler messageHandler = 0; // pointer to debug handler (with context)
+#if defined(QT_USE_JOURNALD) && !defined(QT_BOOTSTRAPPED)
+static void systemd_default_message_handler(QtMsgType type,
+ const QMessageLogContext &context,
+ const QString &message)
+{
+ int priority = LOG_INFO; // Informational
+ switch (type) {
+ case QtDebugMsg:
+ priority = LOG_DEBUG; // Debug-level messages
+ break;
+ case QtWarningMsg:
+ priority = LOG_WARNING; // Warning conditions
+ break;
+ case QtCriticalMsg:
+ priority = LOG_CRIT; // Critical conditions
+ break;
+ case QtFatalMsg:
+ priority = LOG_ALERT; // Action must be taken immediately
+ break;
+ }
+
+ char filebuf[PATH_MAX + sizeof("CODE_FILE=")];
+ snprintf(filebuf, sizeof(filebuf), "CODE_FILE=%s", context.file ? context.file : "unknown");
+
+ char linebuf[20];
+ snprintf(linebuf, sizeof(linebuf), "CODE_LINE=%d", context.line);
+
+ sd_journal_print_with_location(priority, filebuf, linebuf, context.function ? context.function : "unknown", "%s", message.toUtf8().constData());
+}
+#endif
+
#ifdef Q_OS_ANDROID
static void android_default_message_handler(QtMsgType type,
const QMessageLogContext &context,
@@ -902,6 +938,18 @@ static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &con
#if defined(QT_USE_SLOG2)
slog2_default_handler(type, logMessage.toLocal8Bit().constData());
+#elif defined(QT_USE_JOURNALD) && !defined(QT_BOOTSTRAPPED)
+ // We use isatty to catch the obvious case of someone running something interactively.
+ // We also support an environment variable for Qt Creator use, or more complicated cases like subprocesses.
+ static bool logToConsole = isatty(fileno(stdin)) || !qEnvironmentVariableIsEmpty("QT_NO_JOURNALD_LOG");
+ if (Q_LIKELY(!logToConsole)) {
+ // remove trailing \n, systemd appears to want them newline-less
+ logMessage.chop(1);
+ systemd_default_message_handler(type, context, logMessage);
+ } else {
+ fprintf(stderr, "%s", logMessage.toUtf8().constData());
+ fflush(stderr);
+ }
#elif defined(Q_OS_ANDROID)
static bool logToAndroid = qEnvironmentVariableIsEmpty("QT_ANDROID_PLAIN_LOG");
if (logToAndroid) {