diff options
Diffstat (limited to 'src/corelib/global/qlogging.cpp')
-rw-r--r-- | src/corelib/global/qlogging.cpp | 212 |
1 files changed, 197 insertions, 15 deletions
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 50d35a6d84..6c545bb65f 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). ** Copyright (C) 2014 Olivier Goffart <ogoffart@woboq.com> ** Copyright (C) 2014 Intel Corporation. ** Contact: http://www.qt-project.org/legal @@ -76,7 +76,8 @@ # define __has_include(x) 0 #endif -#if !defined QT_NO_REGULAREXPRESSION && !defined(QT_BOOTSTRAPPED) +#ifndef QT_BOOTSTRAPPED +#if !defined QT_NO_REGULAREXPRESSION # if (defined(__GLIBC__) && defined(__GLIBCXX__)) || (__has_include(<cxxabi.h>) && __has_include(<execinfo.h>)) # define QLOGGING_HAVE_BACKTRACE # include <qregularexpression.h> @@ -85,6 +86,38 @@ # endif #endif +#if defined(Q_OS_LINUX) && (defined(__GLIBC__) || __has_include(<sys/syscall.h>)) +# include <sys/syscall.h> +static long qt_gettid() +{ + // no error handling + // this syscall has existed since Linux 2.4.11 and cannot fail + return syscall(SYS_gettid); +} +#elif defined(Q_OS_DARWIN) +# include <pthread.h> +static int qt_gettid() +{ + // no error handling: this call cannot fail + __uint64_t tid; + pthread_threadid_np(NULL, &tid); + return tid; +} +#elif defined(Q_OS_FREEBSD_KERNEL) +# include <pthread.h> +static int qt_gettid() +{ + return pthread_getthreadid_np(); +} +#else +static QT_PREPEND_NAMESPACE(qint64) qt_gettid() +{ + QT_USE_NAMESPACE + return qintptr(QThread::currentThreadId()); +} +#endif +#endif // !QT_BOOTSTRAPPED + #include <stdio.h> QT_BEGIN_NAMESPACE @@ -168,7 +201,7 @@ Q_CORE_EXPORT bool qt_logging_to_console() \brief The QMessageLogContext class provides additional information about a log message. \since 5.0 - The class provides information about the source code location a qDebug(), qWarning(), + The class provides information about the source code location a qDebug(), qInfo(), qWarning(), qCritical() or qFatal() message was generated. \note By default, this information is recorded only in debug builds. You can overwrite @@ -184,7 +217,7 @@ Q_CORE_EXPORT bool qt_logging_to_console() \since 5.0 QMessageLogger is used to generate messages for the Qt logging framework. Usually one uses - it through qDebug(), qWarning(), qCritical, or qFatal() functions, + it through qDebug(), qInfo(), qWarning(), qCritical, or qFatal() functions, which are actually macros: For example qDebug() expands to QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO).debug() for debug builds, and QMessageLogger(0, 0, 0).debug() for release builds. @@ -193,7 +226,7 @@ Q_CORE_EXPORT bool qt_logging_to_console() \snippet code/qlogging/qlogging.cpp 1 - \sa QMessageLogContext, qDebug(), qWarning(), qCritical(), qFatal() + \sa QMessageLogContext, qDebug(), qInfo(), qWarning(), qCritical(), qFatal() */ #ifdef Q_OS_WIN @@ -244,6 +277,28 @@ void QMessageLogger::debug(const char *msg, ...) const qt_message_fatal(QtDebugMsg, context, message); } + +#undef qInfo +/*! + Logs an informational message specified with format \a msg. Additional + parameters, specified by \a msg, may be used. + + \sa qInfo() + \since 5.5 +*/ +void QMessageLogger::info(const char *msg, ...) const +{ + QString message; + + va_list ap; + va_start(ap, msg); // use variable arg list + qt_message(QtInfoMsg, context, msg, ap, message); + va_end(ap); + + if (isFatal(QtInfoMsg)) + qt_message_fatal(QtInfoMsg, context, message); +} + /*! \typedef QMessageLogger::CategoryFunction @@ -373,6 +428,110 @@ QNoDebug QMessageLogger::noDebug() const Q_DECL_NOTHROW #endif +/*! + Logs an informational message specified with format \a msg for the context \a cat. + Additional parameters, specified by \a msg, may be used. + + \since 5.5 + \sa qCInfo() +*/ +void QMessageLogger::info(const QLoggingCategory &cat, const char *msg, ...) const +{ + if (!cat.isInfoEnabled()) + return; + + QMessageLogContext ctxt; + ctxt.copy(context); + ctxt.category = cat.categoryName(); + + QString message; + + va_list ap; + va_start(ap, msg); // use variable arg list + qt_message(QtInfoMsg, ctxt, msg, ap, message); + va_end(ap); + + if (isFatal(QtInfoMsg)) + qt_message_fatal(QtInfoMsg, ctxt, message); +} + +/*! + Logs an informational message specified with format \a msg for the context returned + by \a catFunc. Additional parameters, specified by \a msg, may be used. + + \since 5.5 + \sa qCInfo() +*/ +void QMessageLogger::info(QMessageLogger::CategoryFunction catFunc, + const char *msg, ...) const +{ + const QLoggingCategory &cat = (*catFunc)(); + if (!cat.isInfoEnabled()) + return; + + QMessageLogContext ctxt; + ctxt.copy(context); + ctxt.category = cat.categoryName(); + + QString message; + + va_list ap; + va_start(ap, msg); // use variable arg list + qt_message(QtInfoMsg, ctxt, msg, ap, message); + va_end(ap); + + if (isFatal(QtInfoMsg)) + qt_message_fatal(QtInfoMsg, ctxt, message); +} + +#ifndef QT_NO_DEBUG_STREAM + +/*! + Logs an informational message using a QDebug stream. + + \since 5.5 + \sa qInfo(), QDebug +*/ +QDebug QMessageLogger::info() const +{ + QDebug dbg = QDebug(QtInfoMsg); + QMessageLogContext &ctxt = dbg.stream->context; + ctxt.copy(context); + return dbg; +} + +/*! + Logs an informational message into the category \a cat using a QDebug stream. + + \since 5.5 + \sa qCInfo(), QDebug +*/ +QDebug QMessageLogger::info(const QLoggingCategory &cat) const +{ + QDebug dbg = QDebug(QtInfoMsg); + if (!cat.isInfoEnabled()) + dbg.stream->message_output = false; + + QMessageLogContext &ctxt = dbg.stream->context; + ctxt.copy(context); + ctxt.category = cat.categoryName(); + + return dbg; +} + +/*! + Logs an informational message into category returned by \a catFunc using a QDebug stream. + + \since 5.5 + \sa qCInfo(), QDebug +*/ +QDebug QMessageLogger::info(QMessageLogger::CategoryFunction catFunc) const +{ + return info((*catFunc)()); +} + +#endif + #undef qWarning /*! Logs a warning message specified with format \a msg. Additional @@ -802,10 +961,12 @@ static const char functionTokenC[] = "%{function}"; static const char pidTokenC[] = "%{pid}"; static const char appnameTokenC[] = "%{appname}"; static const char threadidTokenC[] = "%{threadid}"; +static const char qthreadptrTokenC[] = "%{qthreadptr}"; static const char timeTokenC[] = "%{time"; //not a typo: this command has arguments static const char backtraceTokenC[] = "%{backtrace"; //ditto static const char ifCategoryTokenC[] = "%{if-category}"; static const char ifDebugTokenC[] = "%{if-debug}"; +static const char ifInfoTokenC[] = "%{if-info}"; static const char ifWarningTokenC[] = "%{if-warning}"; static const char ifCriticalTokenC[] = "%{if-critical}"; static const char ifFatalTokenC[] = "%{if-fatal}"; @@ -825,6 +986,9 @@ struct QMessagePattern { const char **literals; const char **tokens; QString timeFormat; +#ifndef QT_BOOTSTRAPPED + QElapsedTimer timer; +#endif #ifdef QLOGGING_HAVE_BACKTRACE int backtraceDepth; QString backtraceSeparator; @@ -832,10 +996,6 @@ struct QMessagePattern { bool fromEnvironment; static QBasicMutex mutex; -#ifndef QT_BOOTSTRAPPED - QElapsedTimer timer; - QDateTime startTime; -#endif }; QBasicMutex QMessagePattern::mutex; @@ -848,9 +1008,6 @@ QMessagePattern::QMessagePattern() , backtraceSeparator(QLatin1Char('|')) #endif , fromEnvironment(false) -#ifndef QT_BOOTSTRAPPED - , startTime(QDateTime::currentDateTime()) -#endif { #ifndef QT_BOOTSTRAPPED timer.start(); @@ -942,6 +1099,8 @@ void QMessagePattern::setPattern(const QString &pattern) tokens[i] = appnameTokenC; else if (lexeme == QLatin1String(threadidTokenC)) tokens[i] = threadidTokenC; + else if (lexeme == QLatin1String(qthreadptrTokenC)) + tokens[i] = qthreadptrTokenC; else if (lexeme.startsWith(QLatin1String(timeTokenC))) { tokens[i] = timeTokenC; int spaceIdx = lexeme.indexOf(QChar::fromLatin1(' ')); @@ -977,6 +1136,7 @@ void QMessagePattern::setPattern(const QString &pattern) } IF_TOKEN(ifCategoryTokenC) IF_TOKEN(ifDebugTokenC) + IF_TOKEN(ifInfoTokenC) IF_TOKEN(ifWarningTokenC) IF_TOKEN(ifCriticalTokenC) IF_TOKEN(ifFatalTokenC) @@ -1055,6 +1215,9 @@ static void slog2_default_handler(QtMsgType msgType, const char *message) //Determines the severity level switch (msgType) { case QtDebugMsg: + severity = SLOG2_DEBUG1; + break; + case QtInfoMsg: severity = SLOG2_INFO; break; case QtWarningMsg: @@ -1117,6 +1280,7 @@ QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, con } else if (token == typeTokenC) { switch (type) { case QtDebugMsg: message.append(QLatin1String("debug")); break; + case QtInfoMsg: message.append(QLatin1String("info")); break; case QtWarningMsg: message.append(QLatin1String("warning")); break; case QtCriticalMsg:message.append(QLatin1String("critical")); break; case QtFatalMsg: message.append(QLatin1String("fatal")); break; @@ -1139,6 +1303,9 @@ QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, con } else if (token == appnameTokenC) { message.append(QCoreApplication::applicationName()); } else if (token == threadidTokenC) { + // print the TID as decimal + message.append(QString::number(qt_gettid())); + } else if (token == qthreadptrTokenC) { message.append(QLatin1String("0x")); message.append(QString::number(qlonglong(QThread::currentThread()->currentThread()), 16)); #ifdef QLOGGING_HAVE_BACKTRACE @@ -1201,6 +1368,12 @@ QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, con if (pattern->timeFormat == QLatin1String("process")) { quint64 ms = pattern->timer.elapsed(); message.append(QString().sprintf("%6d.%03d", uint(ms / 1000), uint(ms % 1000))); + } else if (pattern->timeFormat == QLatin1String("boot")) { + // just print the milliseconds since the elapsed timer reference + // like the Linux kernel does + pattern->timer.elapsed(); + uint ms = pattern->timer.msecsSinceReference(); + message.append(QString().sprintf("%6d.%03d", uint(ms / 1000), uint(ms % 1000))); } else if (pattern->timeFormat.isEmpty()) { message.append(QDateTime::currentDateTime().toString(Qt::ISODate)); } else { @@ -1214,6 +1387,7 @@ QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, con } else if (token == if##LEVEL##TokenC) { \ skip = type != Qt##LEVEL##Msg; HANDLE_IF_TOKEN(Debug) + HANDLE_IF_TOKEN(Info) HANDLE_IF_TOKEN(Warning) HANDLE_IF_TOKEN(Critical) HANDLE_IF_TOKEN(Fatal) @@ -1249,6 +1423,9 @@ static void systemd_default_message_handler(QtMsgType type, case QtDebugMsg: priority = LOG_DEBUG; // Debug-level messages break; + case QtInfoMsg: + priority = LOG_INFO; // Informational conditions + break; case QtWarningMsg: priority = LOG_WARNING; // Warning conditions break; @@ -1278,6 +1455,7 @@ static void android_default_message_handler(QtMsgType type, android_LogPriority priority = ANDROID_LOG_DEBUG; switch (type) { case QtDebugMsg: priority = ANDROID_LOG_DEBUG; break; + case QtInfoMsg: priority = ANDROID_LOG_INFO; break; case QtWarningMsg: priority = ANDROID_LOG_WARN; break; case QtCriticalMsg: priority = ANDROID_LOG_ERROR; break; case QtFatalMsg: priority = ANDROID_LOG_FATAL; break; @@ -1548,9 +1726,13 @@ void qErrnoWarning(int code, const char *msg, ...) \row \li \c %{line} \li Line in source file \row \li \c %{message} \li The actual message \row \li \c %{pid} \li QCoreApplication::applicationPid() - \row \li \c %{threadid} \li ID of current thread + \row \li \c %{threadid} \li The system-wide ID of current thread (if it can be obtained) + \row \li \c %{qthreadptr} \li A pointer to the current QThread (result of QThread::currentThread()) \row \li \c %{type} \li "debug", "warning", "critical" or "fatal" \row \li \c %{time process} \li time of the message, in seconds since the process started (the token "process" is literal) + \row \li \c %{time boot} \li the time of the message, in seconds since the system boot if that + can be determined (the token "boot" is literal). If the time since boot could not be obtained, + the output is indeterminate (see QElapsedTimer::msecsSinceReference()). \row \li \c %{time [format]} \li system time when the message occurred, formatted by passing the \c format to \l QDateTime::toString(). If the format is not specified, the format of Qt::ISODate is used. @@ -1564,7 +1746,7 @@ void qErrnoWarning(int code, const char *msg, ...) tail call optimization. \endtable - You can also use conditionals on the type of the message using \c %{if-debug}, + You can also use conditionals on the type of the message using \c %{if-debug}, \c %{if-info} \c %{if-warning}, \c %{if-critical} or \c %{if-fatal} followed by an \c %{endif}. What is inside the \c %{if-*} and \c %{endif} will only be printed if the type matches. @@ -1573,7 +1755,7 @@ void qErrnoWarning(int code, const char *msg, ...) Example: \code - QT_MESSAGE_PATTERN="[%{time yyyyMMdd h:mm:ss.zzz t} %{if-debug}D%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{file}:%{line} - %{message}" + QT_MESSAGE_PATTERN="[%{time yyyyMMdd h:mm:ss.zzz t} %{if-debug}D{%endif}%{if-info}I%{endif}%{if-warning}W%{endif}%{if-critical}C%{endif}%{if-fatal}F%{endif}] %{file}:%{line} - %{message}" \endcode The default \a pattern is "%{if-category}%{category}: %{endif}%{message}". |