5 * th9x - http://code.google.com/p/th9x
6 * er9x - http://code.google.com/p/er9x
7 * gruvin9x - http://code.google.com/p/gruvin9x
9 * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
21 #ifndef APPDEBUGMESSAGEHANDLER_H
22 #define APPDEBUGMESSAGEHANDLER_H
27 #include <QApplication>
30 #include <QMessageLogContext>
32 #include <QRegularExpression>
36 * Custom debug/message handler class to work in conjunction with qDebug() family of functions.
37 * Formats all stderr output generated by the application in a consistent manner.
38 * It can also be used by other event listeners to intercept messages they may be interested in (connect to messageOutput() signal).
40 * Include this header to use qInfo() safely with Qt < v5.5 (qInfo becomes alias for qDebug).
42 * Note that the default message format can still be overriden by setting QT_MESSAGE_PATTERN environment variable at _runtime_.
43 * see: https://doc.qt.io/qt-5/qtglobal.html#qSetMessagePattern
45 * This is an app-wide "global" thread-safe singleton class, use it with AppDebugMessageHandler::instance().
46 * For example, at start of application:
48 * QApplication app(argc, argv);
49 * AppDebugMessageHandler::instance()->installAppMessageHandler();
51 * To connect to a signal:
53 * connect(AppDebugMessageHandler::instance(), &AppDebugMessageHandler::messageOutput, this, &DebugOutput::onAppDebugMessage);
55 * This singleton will self-destruct upon QApplication termination.
59 #if defined(QT_DEBUG) || defined(DEBUG)
60 #define APP_DBG_HANDLER_IS_DBG_BUILD 1
62 #define APP_DBG_HANDLER_IS_DBG_BUILD 0
65 // Enable/disable this custom handler handler entirely
66 #ifndef APP_DBG_HANDLER_ENABLE
67 #define APP_DBG_HANDLER_ENABLE 1
70 // Default log level (can also be set with setAppDebugOutputLevel()):
71 // 0 = debug+; 1 = info+; 2 = warn+; 3 = critical+; 4 = fatal only
72 #ifndef APP_DBG_HANDLER_DEFAULT_LEVEL
73 #define APP_DBG_HANDLER_DEFAULT_LEVEL 0
76 // Include source file path/name in output (filtered with APP_DBG_HANDLER_SRC_PATH)
77 #ifndef APP_DBG_HANDLER_SHOW_SRC_PATH
78 #define APP_DBG_HANDLER_SHOW_SRC_PATH APP_DBG_HANDLER_IS_DBG_BUILD
81 // Show just the function Class::name vs. full declaration with return and param types
82 #ifndef APP_DBG_HANDLER_SHOW_FUNCTION_DECL
83 #define APP_DBG_HANDLER_SHOW_FUNCTION_DECL 0
86 // base path for source file name filter, everything after this is kept; RegEx, non-greedy
87 #ifndef APP_DBG_HANDLER_SRC_PATH
88 #define APP_DBG_HANDLER_SRC_PATH ".*src"
91 // Make sure to include this header if using qInfo()
92 #if (QT_VERSION < QT_VERSION_CHECK(5, 5, 0))
93 #if defined(QT_NO_INFO_OUTPUT)
94 #define qInfo QT_NO_QDEBUG_MACRO
98 #define QtInfoMsg QtMsgType(4)
101 class AppDebugMessageHandler
: public QObject
106 // This class implements the singleton design pattern and is therefore publicly accessible only through instance().
107 static AppDebugMessageHandler
* instance();
108 AppDebugMessageHandler(AppDebugMessageHandler
const &) = delete;
109 void operator = (AppDebugMessageHandler
const &) = delete;
111 void setAppDebugOutputLevel(const quint8
& appDebugOutputLevel
);
112 void setShowSourcePath(bool showSourcePath
);
113 void setShowFunctionDeclarations(bool showFunctionDeclarations
);
114 void addOutputDevice(QIODevice
* device
);
115 void removeOutputDevice(QIODevice
* device
);
117 void installAppMessageHandler();
118 void messageHandler(QtMsgType type
, const QMessageLogContext
& context
, const QString
& msg
);
121 // This class implements the singleton design pattern and therefore has only a private constructor.
122 explicit AppDebugMessageHandler(QObject
* parent
= Q_NULLPTR
);
123 ~AppDebugMessageHandler() { }
125 QtMessageHandler m_defaultHandler
;
126 QRegularExpression m_srcPathFilter
;
127 QRegularExpression m_functionFilter
;
128 quint8 m_appDebugOutputLevel
;
129 QVector
<QIODevice
*> m_outputDevices
;
130 bool m_showSourcePath
;
131 bool m_showFunctionDeclarations
;
134 void messageOutput(quint8 level
, const QString
& msg
);
137 // Message handler which is installed using qInstallMessageHandler. This needs to be global.
138 // Use AppDebugMessageHandler::instance()->installAppMessageHandler();
139 // instead of installing this function directly (it will verify this handler is enabled, etc).
140 void g_appDebugMessageHandler(QtMsgType
, const QMessageLogContext
&, const QString
&);
142 #endif // APPDEBUGMESSAGEHANDLER_H