qlogging: Journal: Log thread id, suppress empty fields
The TID field can be used to differentiate the threads of a process where the message originates from. This allows to create a timeline of events when identical messages are created from multiple threads, or filter out messages from "uninteresting" threads in post-processing. The file/line/func fields are typically empty for non-debug builds, so storing these in the journal with dummy values is a waste of CPU time and storage. Use sd_journal_sendv instead of sd_journal_send, as that allows to vary the number of sent fields, and skip the ones without actual information. It is also slightly more performant, as it avoids the var-arg handling, sprintf parsing and formatting etc. done by sd_journal_send. [ChangeLog][QtCore][Logging] Qt now logs the thread id (TID) in journal, allowing separation of identical messages from multiple threads. Fixes: QTBUG-120047 Fixes: QTBUG-120048 Change-Id: Iccf3fe708dc4b896161693e13fb9012686bd1871 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
927798f5de
commit
a6070847f0
@ -1846,13 +1846,39 @@ static bool systemd_default_message_handler(QtMsgType type,
|
||||
break;
|
||||
}
|
||||
|
||||
sd_journal_send("MESSAGE=%s", message.toUtf8().constData(),
|
||||
"PRIORITY=%i", priority,
|
||||
"CODE_FUNC=%s", context.function ? context.function : "unknown",
|
||||
"CODE_LINE=%d", context.line,
|
||||
"CODE_FILE=%s", context.file ? context.file : "unknown",
|
||||
"QT_CATEGORY=%s", context.category ? context.category : "unknown",
|
||||
NULL);
|
||||
// Explicit QByteArray instead of auto, to resolve the QStringBuilder proxy
|
||||
const QByteArray messageField = "MESSAGE="_ba + message.toUtf8().constData();
|
||||
const QByteArray priorityField = "PRIORITY="_ba + QByteArray::number(priority);
|
||||
const QByteArray tidField = "TID="_ba + QByteArray::number(qlonglong(qt_gettid()));
|
||||
const QByteArray fileField = context.file
|
||||
? "CODE_FILE="_ba + context.file : QByteArray();
|
||||
const QByteArray funcField = context.function
|
||||
? "CODE_FUNC="_ba + context.function : QByteArray();
|
||||
const QByteArray lineField = context.line
|
||||
? "CODE_LINE="_ba + QByteArray::number(context.line) : QByteArray();
|
||||
const QByteArray categoryField = context.category
|
||||
? "QT_CATEGORY="_ba + context.category : QByteArray();
|
||||
|
||||
auto toIovec = [](const QByteArray &ba) {
|
||||
return iovec{const_cast<char*>(ba.data()), ba.size()};
|
||||
};
|
||||
|
||||
struct iovec fields[7] = {
|
||||
toIovec(messageField),
|
||||
toIovec(priorityField),
|
||||
toIovec(tidField),
|
||||
};
|
||||
int nFields = 3;
|
||||
if (context.file)
|
||||
fields[nFields++] = toIovec(fileField);
|
||||
if (context.function)
|
||||
fields[nFields++] = toIovec(funcField);
|
||||
if (context.line)
|
||||
fields[nFields++] = toIovec(lineField);
|
||||
if (context.category)
|
||||
fields[nFields++] = toIovec(categoryField);
|
||||
|
||||
sd_journal_sendv(fields, nFields);
|
||||
|
||||
return true; // Prevent further output to stderr
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user