aboutsummaryrefslogtreecommitdiffstats
path: root/src/geniviextras/qdltregistration.cpp
diff options
context:
space:
mode:
authorDominik Holland <dominik.holland@qt.io>2019-10-10 17:21:37 +0200
committerDominik Holland <dominik.holland@qt.io>2019-10-10 18:29:50 +0200
commit9338ef08af7803f0d39830830547b44bb3373e34 (patch)
tree34db1d6dcfa7ad83cbaa21333b647d29104b0de3 /src/geniviextras/qdltregistration.cpp
parent2df528532d293327599f1c5107415ddb34035c5c (diff)
geniviextras: Add better handling for long messages
DLT silently drops too long messages and produces empty lines instead. This changes introduces a behavior enum which helps to configure geniviextras to truncate or split the long messages. Change-Id: I325c8e8da25c9456ee56d29bce0779b016c01917 Fixes: AUTOSUITE-1187 Reviewed-by: Robert Griebl <robert.griebl@qt.io>
Diffstat (limited to 'src/geniviextras/qdltregistration.cpp')
-rw-r--r--src/geniviextras/qdltregistration.cpp99
1 files changed, 98 insertions, 1 deletions
diff --git a/src/geniviextras/qdltregistration.cpp b/src/geniviextras/qdltregistration.cpp
index 47abe21..14b2130 100644
--- a/src/geniviextras/qdltregistration.cpp
+++ b/src/geniviextras/qdltregistration.cpp
@@ -73,10 +73,47 @@ QDltRegistration *globalDltRegistration()
QT_END_NAMESPACE
+// helper functions to split or truncate a utf8 correctly (not between a composed character)
+namespace QtGeniviExtrasPrivate {
+
+ static constexpr int MAX_MSG_LEN = DLT_USER_BUF_MAX_SIZE - 10;
+
+ QByteArray utf8_mid(const QByteArray &buffer, int position, int len)
+ {
+ int max = qMin(position + len, buffer.size());
+ int end = max;
+ // move from the maximum length backwards so we don't cut in-between a multi-byte char
+ for (; end > position && end < buffer.size(); --end) {
+ if ((buffer[end] & 0xC0) != 0x80)
+ break;
+ }
+ // if we can't find a good position for a split (e.g. a invalid utf-8 string) take the max
+ // len for the split
+ if (end == position)
+ end = max;
+ return buffer.mid(position, end - position);
+ }
+
+ QVector<QByteArray> utf8_split(const QByteArray &buffer, int len)
+ {
+ QVector<QByteArray> split;
+ int position = 0;
+ do {
+ const QByteArray mid = utf8_mid(buffer, position, len);
+ split.append(mid);
+ position += mid.size();
+ } while (position < buffer.size());
+
+ return split;
+ }
+}
+
+
QDltRegistrationPrivate::QDltRegistrationPrivate(QDltRegistration *parent)
: q_ptr(parent)
, m_dltAppRegistered(false)
, m_registerOnFirstUse(false)
+ , m_longMessageBehavior(QDltRegistration::LongMessageBehavior::Truncate)
{
}
@@ -249,6 +286,31 @@ DltLogLevelType QDltRegistrationPrivate::severity2dltLevel(QtMsgType type)
types of a QLoggingCategory whenever the log level of a dlt context changes.
*/
+/*!
+ \enum QDltRegistration::LongMessageBehavior
+
+ This enum type describes the available options for long messages.
+
+ \value Truncate Truncate the message to the maximum size.
+ \value Split Split the message into several smaller ones.
+ \value Pass Pass the message as is to DLT. This option has the least performance impact, but
+ DLT might ignore the message if it is too long and produce just an empty line instead.
+
+ \since 5.12.4
+*/
+
+/*!
+ \property QDltRegistration::longMessageBehavior
+ \brief Defines the handling of messages that are too long for DLT to handle correctly
+
+ DLT defines that a message has a maximum size of about 1k (The real value depends on the DLT
+ version used).
+
+ The default behavior is to truncate the message to the maximum supported length.
+
+ \since 5.12.4
+*/
+
QDltRegistration::QDltRegistration(QObject *parent)
: QObject(parent)
, d_ptr(new QDltRegistrationPrivate(this))
@@ -370,6 +432,18 @@ void QDltRegistration::registerUnregisteredContexts()
}
}
+void QDltRegistration::setLongMessageBehavior(QDltRegistration::LongMessageBehavior config)
+{
+ Q_D(QDltRegistration);
+ d->m_longMessageBehavior = config;
+}
+
+QDltRegistration::LongMessageBehavior QDltRegistration::longMessageBehavior() const
+{
+ Q_D(const QDltRegistration);
+ return d->m_longMessageBehavior;
+}
+
/*!
Unregisters the application with the dlt-daemon.
The registered application as well as all registered dlt context will be deleted.
@@ -408,7 +482,30 @@ void QDltRegistration::messageHandler(QtMsgType msgType, const QMessageLogContex
DltLogLevelType logLevel = globalDltRegistration()->d_ptr->severity2dltLevel(msgType);
- DLT_LOG(*dltCtx, logLevel, DLT_STRING(qPrintable(qFormatLogMessage(msgType, msgCtx, msg))));
+ const QByteArray fullMessage = qFormatLogMessage(msgType, msgCtx, msg).toUtf8();
+
+ if (Q_UNLIKELY(fullMessage.size() > QtGeniviExtrasPrivate::MAX_MSG_LEN)) {
+#if GENIVIEXTRAS_DEBUG
+ std::cout << "LOG MESSAGE TOO LONG" << std::endl;
+#endif
+ if (globalDltRegistration()->longMessageBehavior() == LongMessageBehavior::Truncate) {
+#if GENIVIEXTRAS_DEBUG
+ std::cout << "TRUNCATE" << std::endl;
+#endif
+ DLT_LOG(*dltCtx, logLevel, DLT_UTF8(QtGeniviExtrasPrivate::utf8_mid(fullMessage, 0, QtGeniviExtrasPrivate::MAX_MSG_LEN)));
+ return;
+ } else if (globalDltRegistration()->longMessageBehavior() == LongMessageBehavior::Split) {
+#if GENIVIEXTRAS_DEBUG
+ std::cout << "SPLIT" << std::endl;
+#endif
+ const QVector<QByteArray> split = QtGeniviExtrasPrivate::utf8_split(fullMessage, QtGeniviExtrasPrivate::MAX_MSG_LEN);
+ for (const QByteArray &m : split)
+ DLT_LOG(*dltCtx, logLevel, DLT_UTF8(m));
+ return;
+ }
+ }
+
+ DLT_LOG(*dltCtx, logLevel, DLT_UTF8(fullMessage));
}
/*!