#include "message_handler.h" #include <QDateTime> #include <cstring> #define OUTPUT_LEN (20) static bool installedMsgHandler = false; static QtMsgType debugLevel = QtInfoMsg; QtMsgType getDebugLevel() { return debugLevel; } void setDebugLevel(QtMsgType newDebugLevel) { debugLevel = newDebugLevel; } bool messageHandlerInstalled() { return installedMsgHandler; } QtMessageHandler atbInstallMessageHandler(QtMessageHandler handler) { installedMsgHandler = (handler != 0); static QtMessageHandler prevHandler = nullptr; if (handler) { prevHandler = qInstallMessageHandler(handler); return prevHandler; } else { return qInstallMessageHandler(prevHandler); } } /// /// \brief Print message according to given debug level. /// /// \note Install this function using qInstallMsgHandler(). /// /// int main(int argc, char **argv) { /// installMsgHandler(atbDebugOutput); /// QApplication app(argc, argv); /// ... /// return app.exec(); /// } /// #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) void atbDebugOutput(QtMsgType type, const char *msg) { switch (type) { case QtDebugMsg: { if (debugLevel <= QtDebugMsg) { fprintf(stderr, "%*.*s Debug: %s\n", OUTPUT_LEN, OUTPUT_LEN, QDateTime::currentDateTime().toString(Qt::ISODate).toStdString().c_str(), msg); } } break; case QtInfoMsg: { if (debugLevel <= QtInfoMsg) { fprintf(stderr, "%*.*s Info: %s\n", OUTPUT_LEN, OUTPUT_LEN, QDateTime::currentDateTime().toString(Qt::ISODate).toStdString().c_str(), msg); } } break; case QtWarningMsg: { if (debugLevel <= QtWarningMsg) { fprintf(stderr, "%*.*s Warning: %s\n", OUTPUT_LEN, OUTPUT_LEN, QDateTime::currentDateTime().toString(Qt::ISODate).toStdString().c_str(), msg); } } break; case QtCriticalMsg: { if (debugLevel <= QtCriticalMsg) { fprintf(stderr, "%*.*s Critical: %s\n", OUTPUT_LEN, OUTPUT_LEN, QDateTime::currentDateTime().toString(Qt::ISODate).toStdString().c_str(), msg); } } break; case QtFatalMsg: { if (debugLevel <= QtFatalMsg) { fprintf(stderr, "%*.*s Fatal: %s\n", OUTPUT_LEN, OUTPUT_LEN, QDateTime::currentDateTime().toString(Qt::ISODate).toStdString().c_str(), msg); } // abort(); } break; default: { fprintf(stderr, "%*.*s No ErrorLevel defined! %s\n", OUTPUT_LEN, OUTPUT_LEN, QDateTime::currentDateTime().toString(Qt::ISODate).toStdString().c_str(), msg); } } } #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0) void atbDebugOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) { static constexpr const char *format = "dd.MM.yyyy hh:mm:ss"; QByteArray localMsg = msg.toLocal8Bit(); const char *file = context.file ? context.file : ""; const char *function = context.function ? context.function : ""; const char *p = std::strstr(function, "::"); if (p) { function = p + 2; } char const* output = std::strrchr(file, '/'); if (output) { file = output + 1; } qint64 const currentMSecsSinceEpoch = QDateTime::currentMSecsSinceEpoch(); int const fractional_part = currentMSecsSinceEpoch % 1000; QDateTime const datetime = QDateTime::fromMSecsSinceEpoch(currentMSecsSinceEpoch); switch (type) { case QtDebugMsg: { if (debugLevel <= QtDebugMsg) { // fprintf(stderr, "%*.*s CTX %s (%s:%u) ->\n", OUTPUT_LEN, OUTPUT_LEN, // "", function, file, context.line); //fprintf(stderr, "%*.*s.%03d DEBG %s\n", OUTPUT_LEN, OUTPUT_LEN, // datetime.toString(format).toStdString().c_str(), fractional_part, // localMsg.constData()); fprintf(stderr, "%*.*s.%03d DEBUG %s (%s:%u)\n", OUTPUT_LEN, OUTPUT_LEN, datetime.toString(format).toStdString().c_str(), fractional_part, localMsg.constData(), file, context.line); } } break; case QtInfoMsg: { if (debugLevel <= QtInfoMsg) { fprintf(stderr, "%*.*s.%03d INFO %s (%s:%u)\n", OUTPUT_LEN, OUTPUT_LEN, datetime.toString(format).toStdString().c_str(), fractional_part, localMsg.constData(), file, context.line); } } break; case QtWarningMsg: { if (debugLevel <= QtWarningMsg) { fprintf(stderr, "%*.*s.%03d WARN %s (%s:%u)\n", OUTPUT_LEN, OUTPUT_LEN, datetime.toString(format).toStdString().c_str(), fractional_part, localMsg.constData(), file, context.line); } } break; case QtCriticalMsg: { if (debugLevel <= QtCriticalMsg) { fprintf(stderr, "%*.*s.%03d CRIT %s (%s:%u)\n", OUTPUT_LEN, OUTPUT_LEN, datetime.toString(format).toStdString().c_str(), fractional_part, localMsg.constData(), file, context.line); } } break; case QtFatalMsg: { if (debugLevel <= QtFatalMsg) { fprintf(stderr, "%*.*s.%03d FATAL %s (%s:%u)\n", OUTPUT_LEN, OUTPUT_LEN, datetime.toString(format).toStdString().c_str(), fractional_part, localMsg.constData(), file, context.line); } } break; default: { fprintf(stderr, "%*.*s.%03d No ErrorLevel defined! %s\n", OUTPUT_LEN, OUTPUT_LEN, datetime.toString(format).toStdString().c_str(), fractional_part, msg.toStdString().c_str()); } } } #endif