summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorhjk <hjk121@nokiamail.com>2013-09-19 17:15:43 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-25 18:21:45 +0200
commit466e0dff4bb686e51d0ab3f905631fcb7dd8bfef (patch)
tree79ff471a646a15e38db12cb6b460dd48ea39cfbc /src/corelib
parent774d74df91869d1178cbcdc7648994576a47f850 (diff)
Add tracing to logging framework
Change-Id: I4d5b9a24a214785019ff1238c1790ead79205b15 Reviewed-by: Leena Miettinen <riitta-leena.miettinen@digia.com> Reviewed-by: Topi Reiniƶ <topi.reinio@digia.com> Reviewed-by: Robin Burchell <robin+qt@viroteck.net> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Shawn Rutledge <shawn.rutledge@digia.com>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/doc/snippets/qtracer/ftracer.cpp180
-rw-r--r--src/corelib/doc/snippets/qtracer/main.cpp59
-rw-r--r--src/corelib/doc/snippets/qtracer/qtracer.pro2
-rw-r--r--src/corelib/global/qglobal.cpp4
-rw-r--r--src/corelib/global/qlogging.cpp1
-rw-r--r--src/corelib/global/qlogging.h2
-rw-r--r--src/corelib/io/qloggingcategory.cpp293
-rw-r--r--src/corelib/io/qloggingcategory.h74
-rw-r--r--src/corelib/io/qloggingregistry.cpp8
9 files changed, 617 insertions, 6 deletions
diff --git a/src/corelib/doc/snippets/qtracer/ftracer.cpp b/src/corelib/doc/snippets/qtracer/ftracer.cpp
new file mode 100644
index 0000000000..b12e3ed9c3
--- /dev/null
+++ b/src/corelib/doc/snippets/qtracer/ftracer.cpp
@@ -0,0 +1,180 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <QCoreApplication>
+#include <QLoggingCategory>
+
+
+//![1]
+QLoggingCategory theFooArea("foo");
+QLoggingCategory theBarArea("bar");
+QLoggingCategory theBazArea("baz");
+//![1]
+
+// Note: These locations are Ubuntu specific.
+
+// Note: To make the example work with user permissions, make sure
+// the files are user-writable and the path leading there accessible.
+
+const char traceSwitch[] = "/sys/kernel/debug/tracing/tracing_on";
+const char traceSink[] = "/sys/kernel/debug/tracing/trace_marker";
+
+// The base class only serves as a facility to share code
+// between the "single line" data logging aspect and the
+// scoped "measuring" aspect.
+
+// Both aspects and the base class could be combined into
+// a single tracer serving both purposes, but are split
+// here for clarity.
+
+// Error handling is left as an exercise.
+
+//![2]
+class MyTracerBase : public QTracer
+{
+public:
+ MyTracerBase() {
+ enable = ::open(traceSwitch, O_WRONLY);
+ marker = ::open(traceSink, O_WRONLY);
+ }
+
+ ~MyTracerBase() {
+ ::close(enable);
+ ::close(marker);
+ }
+
+protected:
+ int enable;
+ int marker;
+};
+//![2]
+
+
+//![2]
+class MyTracer : public MyTracerBase
+{
+public:
+ void start() { ::write(marker, "B", 1); }
+ void end() { ::write(marker, "E", 1); }
+};
+//![2]
+
+
+//![3]
+class MyDataLogger : public MyTracerBase
+{
+public:
+ MyDataLogger() {
+ buf[0] = 0;
+ pos = 0;
+ }
+
+ void record(int i) { pos += sprintf(buf + pos, "%d", i); }
+ void record(const char *msg) { pos += sprintf(buf + pos, "%s", msg); }
+ void end() { ::write(marker, buf, pos); pos = 0; }
+
+private:
+ char buf[100];
+ int pos;
+};
+//![3]
+
+// Simplest possible example for "measuring".
+//![4]
+int foo(int i)
+{
+ qCTraceGuard(theFooArea);
+ // Here could be some lengthy code.
+ return i * i;
+}
+//![4]
+
+// We can switch on/off tracing dynamically.
+// The tracer will be temporarily switched off at the third call
+// and re-enabled at the eighth.
+//![5]
+int bar(int i)
+{
+ static int n = 0;
+ ++n;
+ if (n == 3)
+ theBarArea.setEnabled(QtTraceMsg, false);
+ if (n == 8)
+ theBarArea.setEnabled(QtTraceMsg, true);
+
+ qCTraceGuard(theBarArea);
+ return i * i;
+}
+//![5]
+
+// An example to create "complex" log messages.
+//![6]
+int baz(int i)
+{
+ qCTrace(theBazArea) << 32 << "some stuff";
+
+ return i * i;
+}
+//![6]
+
+
+
+//![7]
+namespace {
+static struct Init
+{
+ Init() {
+ tracer.addToCategory(theFooArea);
+ tracer.addToCategory(theBarArea);
+ logger.addToCategory(theBazArea);
+ }
+
+ MyTracer tracer;
+ MyDataLogger logger;
+
+} initializer;
+}
+//![7]
diff --git a/src/corelib/doc/snippets/qtracer/main.cpp b/src/corelib/doc/snippets/qtracer/main.cpp
new file mode 100644
index 0000000000..758a2bbdb8
--- /dev/null
+++ b/src/corelib/doc/snippets/qtracer/main.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+int foo(int i);
+int bar(int i);
+int baz(int i);
+
+int main()
+{
+ int s = 0;
+ for (int i = 0; i != 10; ++i)
+ s += foo(i);
+
+ for (int i = 0; i != 10; ++i)
+ s += bar(i);
+
+ for (int i = 0; i != 10; ++i)
+ s += baz(i);
+
+ return s;
+}
+
diff --git a/src/corelib/doc/snippets/qtracer/qtracer.pro b/src/corelib/doc/snippets/qtracer/qtracer.pro
new file mode 100644
index 0000000000..254e22be76
--- /dev/null
+++ b/src/corelib/doc/snippets/qtracer/qtracer.pro
@@ -0,0 +1,2 @@
+
+SOURCES += ftracer.cpp main.cpp
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 59bdecc868..e2b1502a8e 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -717,6 +717,10 @@ Q_CORE_EXPORT void *qMemSet(void *dest, int c, size_t n);
A message generated by the qCritical() function.
\value QtFatalMsg
A message generated by the qFatal() function.
+ \value QtTraceMsg
+ Used by the qCTrace() macro. Trace events are usually passed only
+ to dedicated \a QTracer objects, and do not appear in the installed
+ message handler.
\value QtSystemMsg
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 4d564b09c3..c0709ce258 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -814,6 +814,7 @@ Q_CORE_EXPORT QString qMessageFormatString(QtMsgType type, const QMessageLogCont
case QtWarningMsg: message.append(QLatin1String("warning")); break;
case QtCriticalMsg:message.append(QLatin1String("critical")); break;
case QtFatalMsg: message.append(QLatin1String("fatal")); break;
+ case QtTraceMsg: message.append(QLatin1String("trace")); break;
}
} else if (token == fileTokenC) {
if (context.file)
diff --git a/src/corelib/global/qlogging.h b/src/corelib/global/qlogging.h
index 2b798f9ea0..68a24d0397 100644
--- a/src/corelib/global/qlogging.h
+++ b/src/corelib/global/qlogging.h
@@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE
class QDebug;
class QNoDebug;
-enum QtMsgType { QtDebugMsg, QtWarningMsg, QtCriticalMsg, QtFatalMsg, QtSystemMsg = QtCriticalMsg };
+enum QtMsgType { QtDebugMsg, QtWarningMsg, QtCriticalMsg, QtFatalMsg, QtTraceMsg, QtSystemMsg = QtCriticalMsg };
class QMessageLogContext
{
diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp
index 562cf25964..80acee6ad1 100644
--- a/src/corelib/io/qloggingcategory.cpp
+++ b/src/corelib/io/qloggingcategory.cpp
@@ -107,7 +107,8 @@ QLoggingCategory::QLoggingCategory(const char *category)
: name(0),
enabledDebug(false),
enabledWarning(true),
- enabledCritical(true)
+ enabledCritical(true),
+ enabledTrace(false)
{
bool isDefaultCategory
= (category == 0) || (strcmp(category, qtDefaultCategoryName) == 0);
@@ -122,7 +123,8 @@ QLoggingCategory::QLoggingCategory(const char *category)
}
if (QLoggingRegistry *reg = QLoggingRegistry::instance())
- reg->registerCategory(this);}
+ reg->registerCategory(this);
+}
/*!
Destructs a QLoggingCategory object
@@ -164,6 +166,7 @@ bool QLoggingCategory::isEnabled(QtMsgType msgtype) const
case QtDebugMsg: return enabledDebug;
case QtWarningMsg: return enabledWarning;
case QtCriticalMsg: return enabledCritical;
+ case QtTraceMsg: return enabledTrace;
case QtFatalMsg: return true;
default: break;
}
@@ -177,6 +180,10 @@ bool QLoggingCategory::isEnabled(QtMsgType msgtype) const
change e.g. the settings of another objects for the same category name.
\note QtFatalMsg cannot be changed. It will always return true.
+
+ Example:
+
+ \snippet qtracer/ftracer.cpp 5
*/
void QLoggingCategory::setEnabled(QtMsgType type, bool enable)
{
@@ -184,6 +191,7 @@ void QLoggingCategory::setEnabled(QtMsgType type, bool enable)
case QtDebugMsg: enabledDebug = enable; break;
case QtWarningMsg: enabledWarning = enable; break;
case QtCriticalMsg: enabledCritical = enable; break;
+ case QtTraceMsg: enabledTrace = enable; break;
case QtFatalMsg:
default: break;
}
@@ -319,12 +327,61 @@ void QLoggingCategory::setFilterRules(const QString &rules)
\snippet qloggingcategory/main.cpp 12
\note Arguments are not processed if critical output for the category is not
- enabled, so do not reply on any side effects.
+ enabled, so do not rely on any side effects.
\sa qCritical()
*/
/*!
+ \relates QLoggingCategory
+ \macro qCTrace(category)
+ \since 5.2
+
+ Returns an output stream for trace messages in the logging category
+ \a category.
+
+ The macro expands to code that first checks whether
+ \l QLoggingCategory::isEnabled() evaluates for trace output to \c{true}.
+ If so, the stream arguments are processed and sent to the tracers
+ registered with the category.
+
+ \note Arguments are not processed if trace output for the category is not
+ enabled, so do not rely on any side effects.
+
+ Example:
+
+ \snippet qtracer/ftracer.cpp 6
+
+ \sa qCTraceGuard()
+*/
+
+/*!
+ \relates QLoggingCategory
+ \macro qCTraceGuard(category)
+ \since 5.2
+
+ The macro expands to code that creates a guard object with automatic
+ storage. The guard constructor checks whether
+ \l QLoggingCategory::isEnabled() evaluates for trace output to \c{true}.
+ If so, the stream arguments are processed and the \c{start()}
+ functions of the tracers registered with the \a category are called.
+
+ The guard destructor also checks whether the category is enabled for
+ tracing and if so, the \c{end()}
+ functions of the tracers registered with the \a category are called.
+
+ \note Arguments are always processed, even if trace output for the
+ category is disabled. They will, however, in that case not be passed
+ to the \c{record()} functions of the registered tracers.
+
+ Example:
+
+ \snippet qtracer/ftracer.cpp 4
+
+ \sa qCTrace()
+*/
+
+/*!
\macro Q_DECLARE_LOGGING_CATEGORY(name)
\relates QLoggingCategory
\since 5.2
@@ -349,4 +406,234 @@ void QLoggingCategory::setFilterRules(const QString &rules)
This macro must be used outside of a class or method.
*/
+
+/*!
+ \class QTracer
+ \inmodule QtCore
+ \since 5.2
+
+ \brief The QTracer class provides an interface for handling
+ trace events associated with a logging category.
+
+ \c QTracer objects are registered with logging categories.
+ Multiple \c QTracer objects
+ can be registered with the same category, and the same
+ \c QTracer object can be registered with different categories.
+
+ If code containing \c qCTrace is executed, and the associated
+ logging category is enabled for tracing, all \c QTracer objects
+ that are registered with the category are notified.
+
+ \c QTracer objects
+*/
+
+/*!
+ \fn QTracer::QTracer()
+
+ Constructs a tracer object.
+
+ Example:
+
+ \snippet qtracer/ftracer.cpp 2
+*/
+
+/*!
+ \fn QTracer::~QTracer()
+
+ Destroys the tracer object.
+*/
+
+/*!
+ Registers this tracer for the \a category.
+
+ The tracer will later be notified of messages of type
+ \c QtTraceMsg, as long as that message type
+ is enabled in the category.
+
+ Example:
+
+ \snippet qtracer/ftracer.cpp 1
+ \codeline
+ \snippet qtracer/ftracer.cpp 7
+*/
+
+void QTracer::addToCategory(QLoggingCategory &category)
+{
+ category.tracers.append(this);
+}
+
+/*!
+ \fn void QTracer::start()
+
+ This function is invoked when a tracing activity starts,
+ typically from the constructor of a \c QTraceGuard object
+ defined by \c qCTrace() or \c qCTraceGuard().
+
+ The base implementation does nothing. \c QTracer subclasses
+ are advised to override it if needed.
+
+ \sa qCTrace(), qCTraceGuard()
+*/
+
+/*!
+ \fn void QTracer::end()
+
+ This function is invoked when a tracing activity ends,
+ typically from the destructor of a \c QTraceGuard object
+ defined by \c qCTrace() or \c qCTraceGuard().
+
+ The base implementation does nothing. It is common for
+ \c QTracer subclasses to override it to perform flushing
+ of collected data.
+
+ \sa qCTrace(), qCTraceGuard()
+*/
+
+/*!
+ \fn void QTracer::record(int data)
+
+ This function is invoked during a tracing activity to
+ pass integer \a data to the \c QTracer object.
+
+ Example:
+
+ \snippet qtracer/ftracer.cpp 3
+*/
+
+/*!
+ \fn void QTracer::record(const char *data)
+
+ This function is invoked during a tracing activity to
+ pass string \a data to the \c QTracer object.
+*/
+
+/*!
+ \fn void QTracer::record(const QVariant &data)
+
+ This function is invoked during a tracing activity to
+ pass abitrary (non-integer, non-string) \a data to
+ the \c QTracer object.
+*/
+
+/*!
+ \class QTraceGuard
+ \since 5.2
+ \inmodule QtCore
+
+ \brief The QTraceGuard class facilitates notifications to
+ \c QTracer objects.
+
+ \c QTraceGuard objects are typically implicitly created on the
+ stack when using the \c qCTrace or \c qCTraceGuard macros and
+ are associated to a \c QLoggingCategory.
+
+ The constructor of a \c QTraceGuard objects checks whether
+ its associated category is enabled, and if so, informs all
+ \c QTracer objects registered with the category that a
+ tracing activity starts.
+
+ The destructor of a \c QTraceGuard objects checks whether
+ its associated category is enabled, and if so, informs all
+ \c QTracer objects registered with the category that a
+ tracing activity ended.
+
+ A \c QTraceGuard object created by \c qCTrace will be destroyed
+ at the end of the full expression, a guard created by
+ \c qCTraceGuard at the end of the block containing the macro.
+
+ During the lifetime of a QTraceGuard object, its \c operator<<()
+ can be used to pass additional data to the active tracers.
+ The fast path handles only \c int and \c{const char *} data,
+ but it is possible to use arbitrary values wrapped in \c QVariants.
+
+ \sa QTracer
+*/
+
+/*!
+ \fn QTraceGuard::QTraceGuard(QLoggingCategory &category)
+ \internal
+
+ Constructs a trace guard object relaying to \a category.
+*/
+
+/*!
+ \fn QTraceGuard::~QTraceGuard()
+ \internal
+
+ Destroys the trace guard object.
+*/
+
+/*!
+ \internal
+
+ Calls \c start() on all registered tracers.
+*/
+
+void QTraceGuard::start()
+{
+ QLoggingCategory::Tracers &tracers = target->tracers;
+ for (int i = tracers.size(); --i >= 0; )
+ tracers.at(i)->start();
+}
+
+/*!
+ \internal
+
+ Calls \c end() on all registered tracers.
+*/
+
+void QTraceGuard::end()
+{
+ QLoggingCategory::Tracers &tracers = target->tracers;
+ for (int i = tracers.size(); --i >= 0; )
+ tracers.at(i)->end();
+}
+
+
+/*!
+ \internal
+
+ This function is called for int parameters passed to the
+ qCTrace stream.
+*/
+
+QTraceGuard &QTraceGuard::operator<<(int msg)
+{
+ QLoggingCategory::Tracers &tracers = target->tracers;
+ for (int i = tracers.size(); --i >= 0; )
+ tracers.at(i)->record(msg);
+ return *this;
+}
+
+/*!
+ \internal
+
+ This function is called for string parameters passed to the
+ qCTrace stream.
+*/
+
+QTraceGuard &QTraceGuard::operator<<(const char *msg)
+{
+ QLoggingCategory::Tracers &tracers = target->tracers;
+ for (int i = tracers.size(); --i >= 0; )
+ tracers.at(i)->record(msg);
+ return *this;
+}
+
+
+/*!
+ \internal
+
+ This function is called for QVariant parameters passed to the
+ qCTrace stream.
+*/
+
+QTraceGuard &QTraceGuard::operator<<(const QVariant &msg)
+{
+ QLoggingCategory::Tracers &tracers = target->tracers;
+ for (int i = tracers.size(); --i >= 0; )
+ tracers.at(i)->record(msg);
+ return *this;
+}
+
QT_END_NAMESPACE
diff --git a/src/corelib/io/qloggingcategory.h b/src/corelib/io/qloggingcategory.h
index 90111c96fa..23b25b5e3f 100644
--- a/src/corelib/io/qloggingcategory.h
+++ b/src/corelib/io/qloggingcategory.h
@@ -44,9 +44,13 @@
#include <QtCore/qglobal.h>
#include <QtCore/qdebug.h>
+#include <QtCore/qvector.h>
QT_BEGIN_NAMESPACE
+class QTracer;
+class QTraceGuard;
+
class Q_CORE_EXPORT QLoggingCategory
{
Q_DISABLE_COPY(QLoggingCategory)
@@ -76,13 +80,18 @@ public:
static void setFilterRules(const QString &rules);
private:
+ friend class QLoggingRegistry;
+ friend class QTraceGuard;
+ friend class QTracer;
+
const char *name;
bool enabledDebug;
bool enabledWarning;
bool enabledCritical;
-
- friend class QLoggingRegistry;
+ bool enabledTrace;
+ typedef QVector<QTracer *> Tracers;
+ Tracers tracers;
};
template <>
@@ -103,6 +112,56 @@ inline bool QLoggingCategory::isEnabled<QtCriticalMsg>() const
return enabledCritical;
}
+template <>
+inline bool QLoggingCategory::isEnabled<QtTraceMsg>() const
+{
+ return enabledTrace;
+}
+
+class Q_CORE_EXPORT QTracer
+{
+ Q_DISABLE_COPY(QTracer)
+public:
+ QTracer() {}
+ virtual ~QTracer() {}
+
+ void addToCategory(QLoggingCategory &category);
+
+ virtual void start() {}
+ virtual void end() {}
+ virtual void record(int) {}
+ virtual void record(const char *) {}
+ virtual void record(const QVariant &) {}
+};
+
+class Q_CORE_EXPORT QTraceGuard
+{
+ Q_DISABLE_COPY(QTraceGuard)
+public:
+ QTraceGuard(QLoggingCategory &category)
+ {
+ target = category.isEnabled<QtTraceMsg>() ? &category : 0;
+ if (target)
+ start();
+ }
+
+ ~QTraceGuard()
+ {
+ if (target)
+ end();
+ }
+
+ QTraceGuard &operator<<(int msg);
+ QTraceGuard &operator<<(const char *msg);
+ QTraceGuard &operator<<(const QVariant &msg);
+
+private:
+ void start();
+ void end();
+
+ QLoggingCategory *target;
+};
+
#define Q_DECLARE_LOGGING_CATEGORY(name) \
extern QLoggingCategory &name();
@@ -123,6 +182,17 @@ inline bool QLoggingCategory::isEnabled<QtCriticalMsg>() const
#define qCCritical(category) \
for (bool enabled = category().isEnabled<QtCriticalMsg>(); enabled; enabled = false) \
QMessageLogger(__FILE__, __LINE__, Q_FUNC_INFO, category().categoryName()).critical()
+#define qCTrace(category) \
+ for (bool enabled = category.isEnabled<QtTraceMsg>(); enabled; enabled = false) \
+ QTraceGuard(category)
+
+
+#define Q_TRACE_GUARD_NAME_HELPER(line) qTraceGuard ## line
+#define Q_TRACE_GUARD_NAME(line) Q_TRACE_GUARD_NAME_HELPER(line)
+
+#define qCTraceGuard(category) \
+ QTraceGuard Q_TRACE_GUARD_NAME(__LINE__)(category);
+
#if defined(QT_NO_DEBUG_OUTPUT)
# undef qCDebug
diff --git a/src/corelib/io/qloggingregistry.cpp b/src/corelib/io/qloggingregistry.cpp
index a82e6f65f4..885b51709d 100644
--- a/src/corelib/io/qloggingregistry.cpp
+++ b/src/corelib/io/qloggingregistry.cpp
@@ -86,6 +86,9 @@ int QLoggingRule::pass(const QString &categoryName, QtMsgType msgType) const
case QtCriticalMsg:
fullCategory += QLatin1String(".critical");
break;
+ case QtTraceMsg:
+ fullCategory += QLatin1String(".trace");
+ break;
default:
break;
}
@@ -288,6 +291,7 @@ void QLoggingRegistry::defaultCategoryFilter(QLoggingCategory *cat)
bool debug = (cat->categoryName() == qtDefaultCategoryName);
bool warning = true;
bool critical = true;
+ bool trace = true;
QString categoryName = QLatin1String(cat->categoryName());
QLoggingRegistry *reg = QLoggingRegistry::instance();
@@ -301,11 +305,15 @@ void QLoggingRegistry::defaultCategoryFilter(QLoggingCategory *cat)
filterpass = item.pass(categoryName, QtCriticalMsg);
if (filterpass != 0)
critical = (filterpass > 0);
+ filterpass = item.pass(categoryName, QtTraceMsg);
+ if (filterpass != 0)
+ trace = (filterpass > 0);
}
cat->setEnabled(QtDebugMsg, debug);
cat->setEnabled(QtWarningMsg, warning);
cat->setEnabled(QtCriticalMsg, critical);
+ cat->setEnabled(QtTraceMsg, trace);
}