summaryrefslogtreecommitdiffstats
path: root/src/corelib/global/qlogging.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/global/qlogging.cpp')
-rw-r--r--src/corelib/global/qlogging.cpp212
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}".