diff options
-rw-r--r-- | config.tests/unix/journald/journald.c | 48 | ||||
-rw-r--r-- | config.tests/unix/journald/journald.pro | 6 | ||||
-rwxr-xr-x | configure | 29 | ||||
-rw-r--r-- | src/corelib/global/global.pri | 6 | ||||
-rw-r--r-- | src/corelib/global/qlogging.cpp | 48 |
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 @@ -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) { |