31 #include <QFileDevice> 33 AppDebugMessageHandler::AppDebugMessageHandler() :
35 m_defaultHandler(nullptr)
43 defaultMessagePattern();
44 #if (QT_VERSION < QT_VERSION_CHECK(5, 4, 0)) 66 m_defaultPattern.
clear();
79 m_defaultPattern.
clear();
86 m_defaultPattern.
clear();
92 m_tsFormat = timeFormat;
93 m_defaultPattern.
clear();
99 m_msgPattern = pattern;
105 if (device && !m_outputDevices.
contains(device))
106 m_outputDevices.
append(device);
114 #if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)) 118 foreach (
QIODevice * d, m_outputDevices) {
120 m_outputDevices.
remove(i);
128 if (!m_defaultPattern.
isEmpty())
129 return m_defaultPattern;
133 msgPattern.
append(QStringLiteral(
"[%{time %1}] ").arg(m_tsFormat));
137 if (m_showSourcePath)
140 if (m_showFunctionDeclarations)
145 msgPattern.
append(
QLatin1String(
":%{line} -%{if-category} [%{category}]%{endif} %{message}"));
148 msgPattern.
append(
"%{if-fatal}\nBACKTRACE:\n%{backtrace depth=12 separator=\"\n\"}%{endif}");
151 m_defaultPattern = msgPattern;
162 #if APP_DBG_HANDLER_ENABLE 165 qInstallMessageHandler(
nullptr);
173 if (type == QtInfoMsg)
175 else if (type > QtDebugMsg)
180 if (lvl < m_appDebugOutputLevel)
183 #if defined(Q_OS_LINUX) && (QT_VERSION < QT_VERSION_CHECK(5, 3, 0)) 193 file.
replace(m_srcPathFilter,
"\\1");
195 const bool hasDevices = !m_outputDevices.
isEmpty();
202 QMessageLogContext newContext(qPrintable(file), context.line, context.function, context.category);
204 qSetMessagePattern(msgPattern);
207 #if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)) 208 msgPattern = qFormatLogMessage(type, newContext, msg);
210 msgPattern.
replace(
"%{type}", fullTypeNames().value(type,
"unknown"));
212 msgPattern.
replace(
"%{if-category} [%{category}]%{endif}",
QString(context.category));
213 msgPattern.
replace(
"%{message}", msg);
224 if (d && d->isWritable() && (!d->property(
"level").isValid() || d->property(
"level").toInt() <= lvl)) {
225 d->write(qPrintable(msgPattern +
"\n"));
226 if (
QFileDevice * fd = qobject_cast<QFileDevice *>(d))
235 if (m_defaultHandler) {
236 m_defaultHandler(type, newContext, msg);
239 fprintf(stderr,
"%s", qPrintable(msgPattern));
240 if (type == QtFatalMsg)
249 {QtDebugMsg,
tr(
"D")},
250 {QtWarningMsg,
tr(
"W")},
251 {QtCriticalMsg,
tr(
"C")},
252 {QtFatalMsg,
tr(
"F")},
258 #if (QT_VERSION < QT_VERSION_CHECK(5, 4, 0)) 263 {QtDebugMsg,
tr(
"debug")},
264 {QtWarningMsg,
tr(
"warning")},
265 {QtCriticalMsg,
tr(
"critical")},
266 {QtFatalMsg,
tr(
"fatal")},
267 {QtInfoMsg,
tr(
"info")}
void setShowTimestamp(bool showTimestamp)
static AppDebugMessageHandler * instance()
Get the singleton instance of this object. The instance is created automatically if necessary.
void messageOutput(quint8 level, const QString &msg)
Notifies when a new log massage is available.
QString & append(QChar ch)
bool showTimestamp() const
int removeAll(const T &t)
void setTimestampFormat(const QString &timeFormat)
void append(const T &value)
#define APP_DBG_HANDLER_TIMESTAMP_FORMAT
Default timestamp format (as per Qt message pattern docs for %{time ...} options).
bool showFunctionDeclarations() const
QString tr(const char *sourceText, const char *disambiguation, int n)
void installAppMessageHandler()
This function must be called to initialize this custom message handler. E.g. AppDebugMessageHandler::...
static QHash< int, QString > & shortTypeNames()
Returns a reference to the mapping of QtMsgType enum values to abbreviated names.
QString defaultMessagePattern() const
Returns the default message pattern. This format will take into account any properties set previously...
void setSourceBasePath(const QString &path=QString())
Set the base path for source file name filter, everything after this is kept. The string could be lit...
QString number(int n, int base)
bool contains(const T &value) const const
bool isEmpty() const const
void addOutputDevice(QIODevice *device)
Add a new I/O stream for receiving messages.
void g_appDebugMessageHandler(QtMsgType, const QMessageLogContext &, const QString &)
QString messagePattern() const
Returns the current message pattern in use. This will be either the one set specifically with setMess...
#define APP_DBG_HANDLER_SHOW_TIMESTAMP
Include timestamp in default message pattern.
#define APP_DBG_HANDLER_DEFAULT_LEVEL
Default log level.
void setAppDebugOutputLevel(quint8 appDebugOutputLevel)
#define APP_DBG_HANDLER_SRC_PATH
base path for source file name filter, everything after this is kept; RegEx, non-greedy
void setShowSourcePath(bool showSourcePath)
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
#define APP_DBG_HANDLER_SHOW_FUNCTION_DECL
Show full function declaration with return and attribute types instead of just the Class::Name.
void setMessagePattern(const QString &pattern=QString())
Specifies a debug message pattern to use instead of the default.
bool showSourcePath() const
void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
Handle a debug message. This is typically called by the installed global message handler callback ( g...
void setShowFunctionDeclarations(bool showFunctionDeclarations)
QString & replace(int position, int n, QChar after)
#define APP_DBG_HANDLER_SHOW_SRC_PATH
Include source file path/name in output (filtered with APP_DBG_HANDLER_SRC_PATH).
Custom debug/message handler class to work in conjunction with qDebug() family of functions.
bool isEmpty() const const
void removeOutputDevice(QIODevice *device)
Remove a previously-added I/O stream.
bool isValid() const const
quint8 appDebugOutputLevel() const
int receivers(const char *signal) const const