summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2022-12-02 17:53:27 +0100
committerGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2022-12-05 04:15:39 +0100
commiteb63f2eb0522531d133e96707f828dfc686698f4 (patch)
tree6c785847e2fe9bde2336bdca75aac21c09348257 /src/corelib
parent33e682f9af81902b36afa1aef1c4ecdcd2ed95a2 (diff)
QMessageLogger: make qFatal categorized and streamable
There is no technical reason why qFatal shouldn't support categorized logging, nor have a streaming version. There is perhaps an API issue, that is, a streaming syntax may encourage users to do "too much": qFatal() << gatherLogs() << saveDatabase() << ...; and that sounds like a bad idea in case the application is in an unrecoverable state that requires immedate terminatation (indeed, through qFatal). I'd err on the side of providing the extra convenience. This commits adds overloads of QMessageLogger::fatal to support categorized logging (note that fatal messages cannot be disabled), the relative qCFatal macro, as well as overloads for streaming. [ChangeLog][QtCore][QMessageLogger] QMessageLogger::fatal now supports categorized logging, for instance using the qCFatal(category) macro. Moreover, qFatal() and qCFatal() now support streaming of values to be printed in the fatal message. Change-Id: Ia57f25f5c85fca97e5fcf27eaa760dbde09cba0e Fixes: QTBUG-8298 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/global/qlogging.cpp95
-rw-r--r--src/corelib/global/qlogging.h26
-rw-r--r--src/corelib/io/qloggingcategory.h1
3 files changed, 116 insertions, 6 deletions
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 1ce55c3f14..213273ed67 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -862,6 +862,56 @@ QDebug QMessageLogger::critical(QMessageLogger::CategoryFunction catFunc) const
#endif
#undef qFatal
+
+/*!
+ Logs a fatal message specified with format \a msg for the context \a cat.
+ Additional parameters, specified by \a msg, may be used.
+
+ \since 6.5
+ \sa qCFatal()
+*/
+void QMessageLogger::fatal(const QLoggingCategory &cat, const char *msg, ...) const noexcept
+{
+ QMessageLogContext ctxt;
+ ctxt.copyContextFrom(context);
+ ctxt.category = cat.categoryName();
+
+ QString message;
+
+ va_list ap;
+ va_start(ap, msg); // use variable arg list
+ QT_TERMINATE_ON_EXCEPTION(message = qt_message(QtFatalMsg, ctxt, msg, ap));
+ va_end(ap);
+
+ qt_message_fatal(QtCriticalMsg, ctxt, message);
+}
+
+/*!
+ Logs a fatal message specified with format \a msg for the context returned
+ by \a catFunc. Additional parameters, specified by \a msg, may be used.
+
+ \since 6.5
+ \sa qCFatal()
+*/
+void QMessageLogger::fatal(QMessageLogger::CategoryFunction catFunc,
+ const char *msg, ...) const noexcept
+{
+ const QLoggingCategory &cat = (*catFunc)();
+
+ QMessageLogContext ctxt;
+ ctxt.copyContextFrom(context);
+ ctxt.category = cat.categoryName();
+
+ QString message;
+
+ va_list ap;
+ va_start(ap, msg); // use variable arg list
+ QT_TERMINATE_ON_EXCEPTION(message = qt_message(QtFatalMsg, ctxt, msg, ap));
+ va_end(ap);
+
+ qt_message_fatal(QtFatalMsg, ctxt, message);
+}
+
/*!
Logs a fatal message specified with format \a msg. Additional
parameters, specified by \a msg, may be used.
@@ -880,6 +930,51 @@ void QMessageLogger::fatal(const char *msg, ...) const noexcept
qt_message_fatal(QtFatalMsg, context, message);
}
+#ifndef QT_NO_DEBUG_STREAM
+/*!
+ Logs a fatal message using a QDebug stream.
+
+ \since 6.5
+
+ \sa qFatal(), QDebug
+*/
+QDebug QMessageLogger::fatal() const
+{
+ QDebug dbg = QDebug(QtFatalMsg);
+ QMessageLogContext &ctxt = dbg.stream->context;
+ ctxt.copyContextFrom(context);
+ return dbg;
+}
+
+/*!
+ Logs a fatal message into category \a cat using a QDebug stream.
+
+ \since 6.5
+ \sa qCFatal(), QDebug
+*/
+QDebug QMessageLogger::fatal(const QLoggingCategory &cat) const
+{
+ QDebug dbg = QDebug(QtFatalMsg);
+
+ QMessageLogContext &ctxt = dbg.stream->context;
+ ctxt.copyContextFrom(context);
+ ctxt.category = cat.categoryName();
+
+ return dbg;
+}
+
+/*!
+ Logs a fatal message into category returned by \a catFunc using a QDebug stream.
+
+ \since 6.5
+ \sa qCFatal(), QDebug
+*/
+QDebug QMessageLogger::fatal(QMessageLogger::CategoryFunction catFunc) const
+{
+ return fatal((*catFunc)());
+}
+#endif // QT_NO_DEBUG_STREAM
+
/*!
\internal
*/
diff --git a/src/corelib/global/qlogging.h b/src/corelib/global/qlogging.h
index 5111daefd3..ea1c68b168 100644
--- a/src/corelib/global/qlogging.h
+++ b/src/corelib/global/qlogging.h
@@ -54,6 +54,12 @@ private:
class QLoggingCategory;
+#ifdef Q_CC_MSVC
+# define QT_MESSAGE_LOGGER_NORETURN
+#else
+# define QT_MESSAGE_LOGGER_NORETURN Q_NORETURN
+#endif
+
class Q_CORE_EXPORT QMessageLogger
{
Q_DISABLE_COPY(QMessageLogger)
@@ -72,6 +78,8 @@ public:
void warning(const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(2, 3);
Q_DECL_COLD_FUNCTION
void critical(const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(2, 3);
+ QT_MESSAGE_LOGGER_NORETURN Q_DECL_COLD_FUNCTION
+ void fatal(const char *msg, ...) const noexcept Q_ATTRIBUTE_FORMAT_PRINTF(2, 3);
typedef const QLoggingCategory &(*CategoryFunction)();
@@ -87,12 +95,10 @@ public:
void critical(const QLoggingCategory &cat, const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(3, 4);
Q_DECL_COLD_FUNCTION
void critical(CategoryFunction catFunc, const char *msg, ...) const Q_ATTRIBUTE_FORMAT_PRINTF(3, 4);
-
-#ifndef Q_CC_MSVC
- Q_NORETURN
-#endif
- Q_DECL_COLD_FUNCTION
- void fatal(const char *msg, ...) const noexcept Q_ATTRIBUTE_FORMAT_PRINTF(2, 3);
+ QT_MESSAGE_LOGGER_NORETURN Q_DECL_COLD_FUNCTION
+ void fatal(const QLoggingCategory &cat, const char *msg, ...) const noexcept Q_ATTRIBUTE_FORMAT_PRINTF(3, 4);
+ QT_MESSAGE_LOGGER_NORETURN Q_DECL_COLD_FUNCTION
+ void fatal(CategoryFunction catFunc, const char *msg, ...) const noexcept Q_ATTRIBUTE_FORMAT_PRINTF(3, 4);
#ifndef QT_NO_DEBUG_STREAM
QDebug debug() const;
@@ -113,6 +119,12 @@ public:
QDebug critical(const QLoggingCategory &cat) const;
Q_DECL_COLD_FUNCTION
QDebug critical(CategoryFunction catFunc) const;
+ Q_DECL_COLD_FUNCTION
+ QDebug fatal() const;
+ Q_DECL_COLD_FUNCTION
+ QDebug fatal(const QLoggingCategory &cat) const;
+ Q_DECL_COLD_FUNCTION
+ QDebug fatal(CategoryFunction catFunc) const;
QNoDebug noDebug() const noexcept;
#endif // QT_NO_DEBUG_STREAM
@@ -121,6 +133,8 @@ private:
QMessageLogContext context;
};
+#undef QT_MESSAGE_LOGGER_NORETURN
+
#if !defined(QT_MESSAGELOGCONTEXT) && !defined(QT_NO_MESSAGELOGCONTEXT)
# if defined(QT_NO_DEBUG)
# define QT_NO_MESSAGELOGCONTEXT
diff --git a/src/corelib/io/qloggingcategory.h b/src/corelib/io/qloggingcategory.h
index f990d8d0c4..c9b32a7227 100644
--- a/src/corelib/io/qloggingcategory.h
+++ b/src/corelib/io/qloggingcategory.h
@@ -125,6 +125,7 @@ template <> const bool QLoggingCategoryMacroHolder<QtWarningMsg>::IsOutputEnable
#define qCInfo(category, ...) QT_MESSAGE_LOGGER_COMMON(category, QtInfoMsg).info(__VA_ARGS__)
#define qCWarning(category, ...) QT_MESSAGE_LOGGER_COMMON(category, QtWarningMsg).warning(__VA_ARGS__)
#define qCCritical(category, ...) QT_MESSAGE_LOGGER_COMMON(category, QtCriticalMsg).critical(__VA_ARGS__)
+#define qCFatal(category, ...) QT_MESSAGE_LOGGER_COMMON(category, QtFatalMsg).fatal(__VA_ARGS__)
QT_END_NAMESPACE