QLogging: deduplicate the calls to qFormatLogMessage()

Lift it up from inside of each of the message sinks and instead perform
the formatting in qDefaultMessageHandler(). This necessitated having a
trait indicating whether the sink takes formatted output or not
(currently, only the Apple backend is unformatted).

Change-Id: Ifa1111900d6945ea8e05fffd177e155db9a599cc
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Thiago Macieira 2023-08-22 17:04:58 -07:00
parent 039ea9b40f
commit d614067ea0

View File

@ -1340,16 +1340,15 @@ void QMessagePattern::setPattern(const QString &pattern)
// make sure the function has "Message" in the name so the function is removed // make sure the function has "Message" in the name so the function is removed
/* /*
A typical backtrace in debug mode looks like: A typical backtrace in debug mode looks like:
#0 backtraceFramesForLogMessage (frameCount=5) at qlogging.cpp:1296 #0 backtraceFramesForLogMessage (frameCount=0) at qlogging.cpp:1398
#1 formatBacktraceForLogMessage (backtraceParams=..., function=0x4040b8 "virtual void MyClass::myFunction(int)") at qlogging.cpp:1344 #1 formatBacktraceForLogMessage (backtraceParams=..., function=0x5555555580b0 "virtual void MyClass::myFunction(int)") at qlogging.cpp:1525
#2 qFormatLogMessage (type=QtDebugMsg, context=..., str=...) at qlogging.cpp:1452 #2 qFormatLogMessage (type=QtDebugMsg, context=..., str=...) at qlogging.cpp:1637
#3 stderr_message_handler (type=QtDebugMsg, context=..., message=...) at qlogging.cpp:1744 #3 qDefaultMessageHandler (type=QtDebugMsg, context=..., message=...) at qlogging.cpp:1992
#4 qDefaultMessageHandler (type=QtDebugMsg, context=..., message=...) at qlogging.cpp:1795 #4 qt_message_print (msgType=QtDebugMsg, context=..., message=...) at qlogging.cpp:2038
#5 qt_message_print (msgType=QtDebugMsg, context=..., message=...) at qlogging.cpp:1840 #5 qt_message_output (msgType=QtDebugMsg, context=..., message=...) at qlogging.cpp:2077
#6 qt_message_output (msgType=QtDebugMsg, context=..., message=...) at qlogging.cpp:1891 #6 QDebug::~QDebug (this=0x7fffffffd9b8, __in_chrg=<optimized out>) at qdebug.cpp:166
#7 QDebug::~QDebug (this=<optimized out>, __in_chrg=<optimized out>) at qdebug.h:111
*/ */
static constexpr int TypicalBacktraceFrameCount = 8; static constexpr int TypicalBacktraceFrameCount = 7;
# if defined(Q_CC_GNU) && !defined(Q_CC_CLANG) # if defined(Q_CC_GNU) && !defined(Q_CC_CLANG)
// force skipping the frame pointer, to save the backtrace() function some work // force skipping the frame pointer, to save the backtrace() function some work
@ -1653,12 +1652,13 @@ Q_CONSTINIT static QBasicAtomicPointer<void (QtMsgType, const QMessageLogContext
#define QT_LOG_CODE 9000 #define QT_LOG_CODE 9000
#endif #endif
static bool slog2_default_handler(QtMsgType type, const QMessageLogContext &context, const QString &message) static bool slog2_default_handler(QtMsgType type, const QMessageLogContext &,
const QString &message)
{ {
if (shouldLogToStderr()) if (shouldLogToStderr())
return false; // Leave logging up to stderr handler return false; // Leave logging up to stderr handler
QString formattedMessage = qFormatLogMessage(type, context, message); QString formattedMessage = message;
formattedMessage.append(u'\n'); formattedMessage.append(u'\n');
if (slog2_set_default_buffer((slog2_buffer_t)-1) == 0) { if (slog2_set_default_buffer((slog2_buffer_t)-1) == 0) {
slog2_buffer_set_config_t buffer_config; slog2_buffer_set_config_t buffer_config;
@ -1709,13 +1709,11 @@ static bool slog2_default_handler(QtMsgType type, const QMessageLogContext &cont
#if QT_CONFIG(journald) #if QT_CONFIG(journald)
static bool systemd_default_message_handler(QtMsgType type, static bool systemd_default_message_handler(QtMsgType type,
const QMessageLogContext &context, const QMessageLogContext &context,
const QString &message) const QString &formattedMessage)
{ {
if (shouldLogToStderr()) if (shouldLogToStderr())
return false; // Leave logging up to stderr handler return false; // Leave logging up to stderr handler
QString formattedMessage = qFormatLogMessage(type, context, message);
int priority = LOG_INFO; // Informational int priority = LOG_INFO; // Informational
switch (type) { switch (type) {
case QtDebugMsg: case QtDebugMsg:
@ -1748,13 +1746,12 @@ static bool systemd_default_message_handler(QtMsgType type,
#endif #endif
#if QT_CONFIG(syslog) #if QT_CONFIG(syslog)
static bool syslog_default_message_handler(QtMsgType type, const QMessageLogContext &context, const QString &message) static bool syslog_default_message_handler(QtMsgType type, const QMessageLogContext &context,
const QString &formattedMessage)
{ {
if (shouldLogToStderr()) if (shouldLogToStderr())
return false; // Leave logging up to stderr handler return false; // Leave logging up to stderr handler
QString formattedMessage = qFormatLogMessage(type, context, message);
int priority = LOG_INFO; // Informational int priority = LOG_INFO; // Informational
switch (type) { switch (type) {
case QtDebugMsg: case QtDebugMsg:
@ -1783,13 +1780,11 @@ static bool syslog_default_message_handler(QtMsgType type, const QMessageLogCont
#ifdef Q_OS_ANDROID #ifdef Q_OS_ANDROID
static bool android_default_message_handler(QtMsgType type, static bool android_default_message_handler(QtMsgType type,
const QMessageLogContext &context, const QMessageLogContext &context,
const QString &message) const QString &formattedMessage)
{ {
if (shouldLogToStderr()) if (shouldLogToStderr())
return false; // Leave logging up to stderr handler return false; // Leave logging up to stderr handler
QString formattedMessage = qFormatLogMessage(type, context, message);
android_LogPriority priority = ANDROID_LOG_DEBUG; android_LogPriority priority = ANDROID_LOG_DEBUG;
switch (type) { switch (type) {
case QtDebugMsg: case QtDebugMsg:
@ -1841,12 +1836,12 @@ static void win_outputDebugString_helper(const QString &message)
} }
} }
static bool win_message_handler(QtMsgType type, const QMessageLogContext &context, const QString &message) static bool win_message_handler(QtMsgType, const QMessageLogContext &,
const QString &formattedMessage)
{ {
if (shouldLogToStderr()) if (shouldLogToStderr())
return false; // Leave logging up to stderr handler return false; // Leave logging up to stderr handler
const QString formattedMessage = qFormatLogMessage(type, context, message).append(u'\n');
win_outputDebugString_helper(formattedMessage); win_outputDebugString_helper(formattedMessage);
return true; // Prevent further output to stderr return true; // Prevent further output to stderr
@ -1855,15 +1850,14 @@ static bool win_message_handler(QtMsgType type, const QMessageLogContext &contex
#ifdef Q_OS_WASM #ifdef Q_OS_WASM
static bool wasm_default_message_handler(QtMsgType type, static bool wasm_default_message_handler(QtMsgType type,
const QMessageLogContext &context, const QMessageLogContext &,
const QString &message) const QString &formattedMessage)
{ {
if (shouldLogToStderr()) if (shouldLogToStderr())
return false; // Leave logging up to stderr handler return false; // Leave logging up to stderr handler
QString formattedMessage = qFormatLogMessage(type, context, message);
int emOutputFlags = EM_LOG_CONSOLE; int emOutputFlags = EM_LOG_CONSOLE;
QByteArray localMsg = message.toLocal8Bit(); QByteArray localMsg = formattedMessage.toLocal8Bit();
switch (type) { switch (type) {
case QtDebugMsg: case QtDebugMsg:
break; break;
@ -1888,21 +1882,30 @@ static bool wasm_default_message_handler(QtMsgType type,
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
static void stderr_message_handler(QtMsgType type, const QMessageLogContext &context, const QString &message) static void stderr_message_handler(QtMsgType type, const QMessageLogContext &context,
const QString &formattedMessage)
{ {
QString formattedMessage = qFormatLogMessage(type, context, message); Q_UNUSED(type);
Q_UNUSED(context);
// print nothing if message pattern didn't apply / was empty. // print nothing if message pattern didn't apply / was empty.
// (still print empty lines, e.g. because message itself was empty) // (still print empty lines, e.g. because message itself was empty)
if (formattedMessage.isNull()) if (formattedMessage.isNull())
return; return;
fprintf(stderr, "%s\n", formattedMessage.toLocal8Bit().constData()); fprintf(stderr, "%s\n", formattedMessage.toLocal8Bit().constData());
fflush(stderr); fflush(stderr);
} }
using SystemMessageSink = bool(QtMsgType, const QMessageLogContext &, const QString &); namespace {
static constexpr SystemMessageSink *systemMessageSink = struct SystemMessageSink
{
using Fn = bool(QtMsgType, const QMessageLogContext &, const QString &);
Fn *sink;
bool messageIsUnformatted = false;
};
}
static constexpr SystemMessageSink systemMessageSink = {
#if defined(QT_BOOTSTRAPPED) #if defined(QT_BOOTSTRAPPED)
nullptr nullptr
#elif defined(Q_OS_WIN) #elif defined(Q_OS_WIN)
@ -1916,13 +1919,13 @@ static constexpr SystemMessageSink *systemMessageSink =
#elif defined(Q_OS_ANDROID) #elif defined(Q_OS_ANDROID)
android_default_message_handler android_default_message_handler
#elif defined(QT_USE_APPLE_UNIFIED_LOGGING) #elif defined(QT_USE_APPLE_UNIFIED_LOGGING)
AppleUnifiedLogger::messageHandler AppleUnifiedLogger::messageHandler, true
#elif defined Q_OS_WASM #elif defined Q_OS_WASM
wasm_default_message_handler wasm_default_message_handler
#else #else
nullptr nullptr
#endif #endif
; };
/*! /*!
\internal \internal
@ -1934,13 +1937,18 @@ static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &con
// optionally formatting the message if the latter, and returns true if the sink // optionally formatting the message if the latter, and returns true if the sink
// handled stderr output as well, which will shortcut our default stderr output. // handled stderr output as well, which will shortcut our default stderr output.
if (systemMessageSink.messageIsUnformatted) {
if (systemMessageSink.sink(type, context, message))
return;
}
QString formattedMessage = qFormatLogMessage(type, context, message);
QT_WARNING_PUSH QT_WARNING_PUSH
QT_WARNING_DISABLE_GCC("-Waddress") // "the address of ~~ will never be NULL QT_WARNING_DISABLE_GCC("-Waddress") // "the address of ~~ will never be NULL
if (systemMessageSink && systemMessageSink(type, context, message)) if (systemMessageSink.sink && systemMessageSink.sink(type, context, formattedMessage))
return; return;
QT_WARNING_POP QT_WARNING_POP
stderr_message_handler(type, context, formattedMessage);
stderr_message_handler(type, context, message);
} }
#if defined(Q_COMPILER_THREAD_LOCAL) #if defined(Q_COMPILER_THREAD_LOCAL)