+namespace {
+
+QByteArray msgWithTime(const Logger::LogEntry &msg)
+{
+ QString levelString;
+
+ switch (msg.logLevel) {
+ case Logger::LogLevel::Debug:
+ levelString = "[Debug] ";
+ break;
+ case Logger::LogLevel::Info:
+ levelString = "[Info ] ";
+ break;
+ case Logger::LogLevel::Warning:
+ levelString = "[Warn ] ";
+ break;
+ case Logger::LogLevel::Error:
+ levelString = "[Error] ";
+ break;
+ case Logger::LogLevel::Fatal:
+ levelString = "[FATAL] ";
+ break;
+ }
+
+ return (msg.timeStamp.toString("yyyy-MM-dd hh:mm:ss ") + levelString + msg.message + "\n").toUtf8();
+};
+
+}
+
+
+Logger::Logger(QObject *parent)
+ : QObject(parent)
+{
+ static bool registered = []() {
+ qRegisterMetaType<LogEntry>();
+ return true;
+ }();
+ Q_UNUSED(registered)
+
+ connect(this, SIGNAL(messageLogged(Logger::LogEntry)), this, SLOT(onMessageLogged(Logger::LogEntry)));
+
+#if QT_VERSION < 0x050000
+ qInstallMsgHandler(Logger::messageHandler);
+#else
+ qInstallMessageHandler(Logger::messageHandler);
+#endif
+}
+
+
+Logger::~Logger()
+{
+ // If we're not initialized yet, output pending messages so they don't get lost
+ if (!_initialized) {
+ for (auto &&message : _messages) {
+ std::cerr << msgWithTime(message).constData();
+ }
+ }
+}
+
+
+std::vector<Logger::LogEntry> Logger::messages() const
+{
+ return _messages;
+}
+
+
+bool Logger::setup(bool keepMessages)
+{
+ _keepMessages = keepMessages;