_messageProcessor(0),
_coreAccountModel(new CoreAccountModel(this)),
_coreConnection(new CoreConnection(this)),
- _connected(false),
- _debugLog(&_debugLogBuffer)
+ _connected(false)
{
_signalProxy->synchronize(_ircListHelper);
}
coreAccountModel()->save();
emit passwordChanged(success);
}
-
-
-#if QT_VERSION < 0x050000
-void Client::logMessage(QtMsgType type, const char *msg)
-{
- fprintf(stderr, "%s\n", msg);
- fflush(stderr);
- if (type == QtFatalMsg) {
- Quassel::logFatalMessage(msg);
- }
- else {
- QString msgString = QString("%1\n").arg(msg);
-
- //Check to see if there is an instance around, else we risk recursions
- //when calling instance() and creating new ones.
- if (!instanceExists())
- return;
-
- instance()->_debugLog << msgString;
- emit instance()->logUpdated(msgString);
- }
-}
-#else
-void Client::logMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg)
-{
- Q_UNUSED(context);
-
- fprintf(stderr, "%s\n", msg.toLocal8Bit().constData());
- fflush(stderr);
- if (type == QtFatalMsg) {
- Quassel::logFatalMessage(msg.toLocal8Bit().constData());
- }
- else {
- QString msgString = QString("%1\n").arg(msg);
-
- //Check to see if there is an instance around, else we risk recursions
- //when calling instance() and creating new ones.
- if (!instanceExists())
- return;
-
- instance()->_debugLog << msgString;
- emit instance()->logUpdated(msgString);
- }
-}
-#endif
emit showIgnoreList(ignoreRule);
}
-#if QT_VERSION < 0x050000
- static void logMessage(QtMsgType type, const char *msg);
-#else
- static void logMessage(QtMsgType, const QMessageLogContext&, const QString&);
-#endif
- static inline const QString &debugLog() { return instance()->_debugLogBuffer; }
-
void displayChannelList(NetworkId networkId) {
emit showChannelList(networkId);
}
void requestCreateNetwork(const NetworkInfo &info, const QStringList &persistentChannels = QStringList());
void requestRemoveNetwork(NetworkId);
- void logUpdated(const QString &msg);
-
//! Emitted when a buffer has been marked as read
/** This is currently triggered by setting lastSeenMsg, either local or remote,
* or by bringing the window to front.
bool _connected;
- QString _debugLogBuffer;
- QTextStream _debugLog;
-
QList<QPair<BufferInfo, QString> > _userInputBuffer;
friend class CoreConnection;
#include "client.h"
#include "clientsettings.h"
-#include "logger.h"
+#include "logmessage.h"
#include "peerfactory.h"
#if QT_VERSION < 0x050000
irclisthelper.cpp
ircuser.cpp
logger.cpp
+ logmessage.cpp
message.cpp
messageevent.cpp
network.cpp
#include "basichandler.h"
+#include <QDebug>
#include <QMetaMethod>
-#include "logger.h"
-
BasicHandler::BasicHandler(QObject *parent)
: QObject(parent),
_defaultHandler(-1),
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
-#include <QFile>
-#include <QTextStream>
-#include <QDateTime>
+#include <iostream>
#ifdef HAVE_SYSLOG
# include <syslog.h>
#endif
+#include <QByteArray>
+#include <QDateTime>
+#include <QDebug>
+#include <QFile>
+
#include "logger.h"
#include "quassel.h"
-Logger::~Logger()
+namespace {
+
+QByteArray msgWithTime(const Logger::LogEntry &msg)
{
- log();
+ return (msg.timeStamp.toString("yyyy-MM-dd hh:mm:ss ") + msg.message + "\n").toUtf8();
+};
+
}
-void Logger::log()
+Logger::Logger(QObject *parent)
+ : QObject(parent)
{
- if (_logLevel < Quassel::logLevel())
- return;
+ static bool registered = []() {
+ qRegisterMetaType<LogEntry>();
+ return true;
+ }();
+ Q_UNUSED(registered)
- switch (_logLevel) {
- case Quassel::DebugLevel:
- _buffer.prepend("Debug: ");
- break;
- case Quassel::InfoLevel:
- _buffer.prepend("Info: ");
- break;
- case Quassel::WarningLevel:
- _buffer.prepend("Warning: ");
- break;
- case Quassel::ErrorLevel:
- _buffer.prepend("Error: ");
- break;
- default:
- break;
- }
+ connect(this, SIGNAL(messageLogged(Logger::LogEntry)), this, SLOT(onMessageLogged(Logger::LogEntry)));
-#ifdef HAVE_SYSLOG
- if (Quassel::logToSyslog()) {
- int prio;
- switch (_logLevel) {
- case Quassel::DebugLevel:
- prio = LOG_DEBUG;
- break;
- case Quassel::InfoLevel:
- prio = LOG_INFO;
- break;
- case Quassel::WarningLevel:
- prio = LOG_WARNING;
- break;
- case Quassel::ErrorLevel:
- prio = LOG_ERR;
- break;
- default:
- prio = LOG_INFO;
- break;
+#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();
}
- syslog(prio|LOG_USER, "%s", qPrintable(_buffer));
}
-#endif
+}
+
- // if we neither use syslog nor have a logfile we log to stdout
+std::vector<Logger::LogEntry> Logger::messages() const
+{
+ return _messages;
+}
+
+
+bool Logger::setup(bool keepMessages)
+{
+ _keepMessages = keepMessages;
- if (Quassel::logFile() || !Quassel::logToSyslog()) {
- _buffer.prepend(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss "));
+ // Set maximum level for output (we still store/announce all messages for client-side filtering)
+ if (Quassel::isOptionSet("loglevel")) {
+ QString level = Quassel::optionValue("loglevel").toLower();
+ if (level == "debug")
+ _outputLevel = LogLevel::Debug;
+ else if (level == "info")
+ _outputLevel = LogLevel::Info;
+ else if (level == "warning")
+ _outputLevel = LogLevel::Warning;
+ else if (level == "error")
+ _outputLevel = LogLevel::Error;
+ else {
+ qCritical() << qPrintable(tr("Invalid log level %1; supported are Debug|Info|Warning|Error").arg(level));
+ return false;
+ }
+ }
- QTextStream out(stdout);
- if (Quassel::logFile() && Quassel::logFile()->isOpen()) {
- _buffer.remove(QChar('\n'));
- out.setDevice(Quassel::logFile());
+ QString logfilename = Quassel::optionValue("logfile");
+ if (!logfilename.isEmpty()) {
+ _logFile.setFileName(logfilename);
+ if (!_logFile.open(QFile::Append|QFile::Unbuffered|QFile::Text)) {
+ qCritical() << qPrintable(tr("Could not open log file \"%1\": %2").arg(logfilename, _logFile.errorString()));
+ }
+ }
+ if (!_logFile.isOpen()) {
+ if (!_logFile.open(stderr, QFile::WriteOnly|QFile::Unbuffered|QFile::Text)) {
+ qCritical() << qPrintable(tr("Cannot write to stderr: %1").arg(_logFile.errorString()));
}
+ }
+
+#ifdef HAVE_SYSLOG
+ _syslogEnabled = Quassel::isOptionSet("syslog");
+#endif
+
+ _initialized = true;
- out << _buffer << endl;
+ // Now that we've setup our logging backends, output pending messages
+ for (auto &&message : _messages) {
+ outputMessage(message);
}
+ if (!_keepMessages) {
+ _messages.clear();
+ }
+
+ return true;
}
#if QT_VERSION < 0x050000
-void Logger::logMessage(QtMsgType type, const char *msg)
+void Logger::messageHandler(QtMsgType type, const char *message)
+#else
+void Logger::messageHandler(QtMsgType type, const QMessageLogContext &, const QString &message)
+#endif
+{
+ Quassel::instance()->logger()->handleMessage(type, message);
+}
+
+
+void Logger::handleMessage(QtMsgType type, const QString &msg)
{
switch (type) {
case QtDebugMsg:
- Logger(Quassel::DebugLevel) << msg;
+ handleMessage(LogLevel::Debug, msg);
break;
+#if QT_VERSION >= 0x050500
+ case QtInfoMsg:
+ handleMessage(LogLevel::Info, msg);
+ break;
+#endif
case QtWarningMsg:
- Logger(Quassel::WarningLevel) << msg;
+ handleMessage(LogLevel::Warning, msg);
break;
case QtCriticalMsg:
- Logger(Quassel::ErrorLevel) << msg;
+ handleMessage(LogLevel::Error, msg);
break;
case QtFatalMsg:
- Logger(Quassel::ErrorLevel) << msg;
- Quassel::logFatalMessage(msg);
- return;
+ handleMessage(LogLevel::Fatal, msg);
+ break;
}
}
-#else
-void Logger::logMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg)
+
+
+void Logger::handleMessage(LogLevel level, const QString &msg)
{
- Q_UNUSED(context)
+ QString logString;
- switch (type) {
- case QtDebugMsg:
- Logger(Quassel::DebugLevel) << msg.toLocal8Bit().constData();
+ switch (level) {
+ case LogLevel::Debug:
+ logString = "[Debug] ";
break;
-#if QT_VERSION >= 0x050500
- case QtInfoMsg:
- Logger(Quassel::InfoLevel) << msg.toLocal8Bit().constData();
+ case LogLevel::Info:
+ logString = "[Info ] ";
break;
-#endif
- case QtWarningMsg:
- Logger(Quassel::WarningLevel) << msg.toLocal8Bit().constData();
+ case LogLevel::Warning:
+ logString = "[Warn ] ";
break;
- case QtCriticalMsg:
- Logger(Quassel::ErrorLevel) << msg.toLocal8Bit().constData();
+ case LogLevel::Error:
+ logString = "[Error] ";
+ break;
+ case LogLevel::Fatal:
+ logString = "[FATAL] ";
break;
- case QtFatalMsg:
- Logger(Quassel::ErrorLevel) << msg.toLocal8Bit().constData();
- Quassel::logFatalMessage(msg.toLocal8Bit().constData());
- return;
}
+
+ // Use signal connection to make this method thread-safe
+ emit messageLogged({QDateTime::currentDateTime(), level, logString += msg});
}
+
+
+void Logger::onMessageLogged(const LogEntry &message)
+{
+ if (_keepMessages) {
+ _messages.push_back(message);
+ }
+
+ // If setup() wasn't called yet, just store the message - will be output later
+ if (_initialized) {
+ outputMessage(message);
+ }
+}
+
+
+void Logger::outputMessage(const LogEntry &message)
+{
+ if (message.logLevel < _outputLevel) {
+ return;
+ }
+
+#ifdef HAVE_SYSLOG
+ if (_syslogEnabled) {
+ int prio{LOG_INFO};
+ switch (message.logLevel) {
+ case LogLevel::Debug:
+ prio = LOG_DEBUG;
+ break;
+ case LogLevel::Info:
+ prio = LOG_INFO;
+ break;
+ case LogLevel::Warning:
+ prio = LOG_WARNING;
+ break;
+ case LogLevel::Error:
+ prio = LOG_ERR;
+ break;
+ case LogLevel::Fatal:
+ prio = LOG_CRIT;
+ }
+ syslog(prio|LOG_USER, "%s", qPrintable(message.message));
+ }
#endif
+
+ if (!_logFile.fileName().isEmpty() || !_syslogEnabled) {
+ _logFile.write(msgWithTime(message));
+ }
+
+#ifndef Q_OS_MAC
+ // For fatal messages, write log to dump file
+ if (message.logLevel == LogLevel::Fatal) {
+ QFile dumpFile{Quassel::instance()->coreDumpFileName()};
+ if (dumpFile.open(QIODevice::Append)) {
+ dumpFile.write(msgWithTime(message));
+ dumpFile.close();
+ }
+ }
+#endif
+
+}
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
-#ifndef LOGGER_H
-#define LOGGER_H
+#pragma once
-#include <QStringList>
-#include <QTextStream>
+#include <vector>
-#include "quassel.h"
-#include "types.h"
+#include <QDateTime>
+#include <QFile>
+#include <QMetaType>
+#include <QObject>
+#include <QString>
-class Logger
+/**
+ * The Logger class encapsulates the various configured logging backends.
+ */
+class Logger : public QObject
{
+ Q_OBJECT
+
public:
- inline Logger(Quassel::LogLevel level) : _stream(&_buffer, QIODevice::WriteOnly), _logLevel(level) {}
- ~Logger();
+ Logger(QObject *parent = nullptr);
+ ~Logger() override;
+
+ enum class LogLevel {
+ Debug,
+ Info,
+ Warning,
+ Error,
+ Fatal
+ };
+
+ struct LogEntry {
+ QDateTime timeStamp;
+ LogLevel logLevel;
+ QString message;
+ };
+
+ /**
+ * Initial setup, to be called ones command line options are available.
+ *
+ * Sets up the log file if appropriate. Outputs the log messages already accumulated since
+ * construction. If @c keepMessages is false, deletes the accumulated messages afterwards,
+ * and won't store further ones.
+ *
+ * @param keepMessages Whether messages should be kept
+ * @returns true, if initialization was successful
+ */
+ bool setup(bool keepMessages);
+
+ /**
+ * Accesses the stores log messages, e.g. for consumption by DebugLogWidget.
+ *
+ * @returns The accumuates log messages
+ */
+ std::vector<Logger::LogEntry> messages() const;
#if QT_VERSION < 0x050000
- static void logMessage(QtMsgType type, const char *msg);
+ static void messageHandler(QtMsgType type, const char *message);
#else
- static void logMessage(QtMsgType, const QMessageLogContext&, const QString&);
+ static void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &message);
#endif
- template<typename T>
- inline Logger &operator<<(const T &value) { _stream << value << " "; return *this; }
- inline Logger &operator<<(const QStringList &t) { _stream << t.join(" ") << " "; return *this; }
- inline Logger &operator<<(bool t) { _stream << (t ? "true" : "false") << " "; return *this; }
-
-private:
- void log();
- QTextStream _stream;
- QString _buffer;
- Quassel::LogLevel _logLevel;
-};
+ /**
+ * Takes the given message with the given log level, formats it and emits the @a messageLogged() signal.
+ *
+ * @note This method is thread-safe.
+ *
+ * @param logLevel The log leve of the message
+ * @param message The message
+ */
+ void handleMessage(LogLevel logLevel, const QString &message);
+signals:
+ /**
+ * Emitted whenever a message was logged.
+ *
+ * @param message The message that was logged
+ */
+ void messageLogged(const Logger::LogEntry &message);
-class quInfo : public Logger
-{
-public:
- inline quInfo() : Logger(Quassel::InfoLevel) {}
-};
+private slots:
+ void onMessageLogged(const Logger::LogEntry &message);
+private:
+ void handleMessage(QtMsgType type, const QString &message);
+ void outputMessage(const LogEntry &message);
-class quWarning : public Logger
-{
-public:
- inline quWarning() : Logger(Quassel::WarningLevel) {}
-};
-
+private:
+ LogLevel _outputLevel{LogLevel::Info};
+ QFile _logFile;
+ bool _syslogEnabled{false};
-class quError : public Logger
-{
-public:
- inline quError() : Logger(Quassel::ErrorLevel) {}
+ std::vector<LogEntry> _messages;
+ bool _keepMessages{true};
+ bool _initialized{false};
};
-
-#endif
+Q_DECLARE_METATYPE(Logger::LogEntry)
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2005-2018 by the Quassel Project *
+ * devel@quassel-irc.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) version 3. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include "logmessage.h"
+
+#include <QFile>
+#include <QTextStream>
+#include <QDateTime>
+
+#include "quassel.h"
+
+LogMessage::LogMessage(Logger::LogLevel level)
+ : _stream(&_buffer, QIODevice::WriteOnly)
+ , _logLevel(level)
+{
+}
+
+
+LogMessage::~LogMessage()
+{
+ Quassel::instance()->logger()->handleMessage(_logLevel, _buffer);
+}
+
+
+LogMessage &LogMessage::operator<<(const QStringList &t)
+{
+ _stream << t.join(" ") << " ";
+ return *this;
+}
+
+
+LogMessage &LogMessage::operator<<(bool t) {
+ _stream << (t ? "true" : "false") << " ";
+ return *this;
+}
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2005-2018 by the Quassel Project *
+ * devel@quassel-irc.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) version 3. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#pragma once
+
+#include <QStringList>
+#include <QTextStream>
+
+#include "logger.h"
+#include "types.h"
+
+/**
+ * Class encapsulating a single log message.
+ *
+ * Very similar in concept to qDebug() and friends.
+ */
+class LogMessage
+{
+public:
+ LogMessage(Logger::LogLevel level);
+ ~LogMessage();
+
+ template<typename T>
+ LogMessage &operator<<(const T &value) {
+ _stream << value << " ";
+ return *this;
+ }
+
+ LogMessage &operator<<(const QStringList &t);
+ LogMessage &operator<<(bool t);
+
+private:
+ QTextStream _stream;
+ QString _buffer;
+ Logger::LogLevel _logLevel;
+};
+
+
+// The only reason for LogMessage and the helpers below to exist is the fact that Qt versions
+// prior to 5.5 did not support the Info level.
+// Once we can rely on Qt 5.5, they will be removed and replaced by the native Qt functions.
+
+/**
+ * Creates an info-level log message.
+ *
+ * @sa qInfo
+ */
+class quInfo : public LogMessage
+{
+public:
+ quInfo() : LogMessage(Logger::LogLevel::Info) {}
+};
+
+
+/**
+ * Creates a warning-level log message.
+ *
+ * @sa qWarning
+ */
+class quWarning : public LogMessage
+{
+public:
+ quWarning() : LogMessage(Logger::LogLevel::Warning) {}
+};
+
+
+/**
+ * Creates an error-level log message.
+ *
+ * @sa qCritical
+ */
+class quError : public LogMessage
+{
+public:
+ quError() : LogMessage(Logger::LogLevel::Error) {}
+};
umask(S_IRWXG | S_IRWXO);
#endif
+ // Instantiate early, so log messages are handled
+ Quassel::instance();
+
#if QT_VERSION < 0x050000
// All our source files are in UTF-8, and Qt5 even requires that
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
#include "bufferinfo.h"
#include "identity.h"
#include "logger.h"
+#include "logmessage.h"
#include "message.h"
#include "network.h"
#include "peer.h"
Quassel::Quassel()
+ : _logger{new Logger{this}}
{
}
return false;
}
- // Set up logging
- if (isOptionSet("loglevel")) {
- QString level = optionValue("loglevel").toLower();
-
- if (level == "debug")
- setLogLevel(DebugLevel);
- else if (level == "info")
- setLogLevel(InfoLevel);
- else if (level == "warning")
- setLogLevel(WarningLevel);
- else if (level == "error")
- setLogLevel(ErrorLevel);
- else {
- qWarning() << qPrintable(tr("Invalid log level %1; supported are Debug|Info|Warning|Error").arg(level));
- return false;
- }
- }
-
- QString logfilename = optionValue("logfile");
- if (!logfilename.isEmpty()) {
- instance()->_logFile.reset(new QFile{logfilename});
- if (!logFile()->open(QIODevice::Append | QIODevice::Text)) {
- qWarning() << qPrintable(tr("Could not open log file \"%1\": %2").arg(logfilename, logFile()->errorString()));
- instance()->_logFile.reset();
- }
- }
-#ifdef HAVE_SYSLOG
- instance()->_logToSyslog = isOptionSet("syslog");
-#endif
+ // Don't keep a debug log on the core
+ return instance()->logger()->setup(runMode() != RunMode::CoreOnly);
+}
-#if QT_VERSION < 0x050000
- qInstallMsgHandler(Logger::logMessage);
-#else
- qInstallMessageHandler(Logger::logMessage);
-#endif
- return true;
+void Quassel::destroy()
+{
}
-void Quassel::destroy()
+Logger *Quassel::logger() const
{
- if (logFile()) {
- logFile()->close();
- instance()->_logFile.reset();
- }
+ return _logger;
}
}
-Quassel::LogLevel Quassel::logLevel()
-{
- return instance()->_logLevel;
-}
-
-
-void Quassel::setLogLevel(LogLevel logLevel)
-{
- instance()->_logLevel = logLevel;
-}
-
-
-QFile *Quassel::logFile() {
- return instance()->_logFile.get();
-}
-
-
-bool Quassel::logToSyslog()
-{
- return instance()->_logToSyslog;
-}
-
-
-void Quassel::logFatalMessage(const char *msg)
-{
-#ifdef Q_OS_MAC
- Q_UNUSED(msg)
-#else
- QFile dumpFile(instance()->coreDumpFileName());
- dumpFile.open(QIODevice::Append);
- QTextStream dumpStream(&dumpFile);
-
- dumpStream << "Fatal: " << msg << '\n';
- dumpStream.flush();
- dumpFile.close();
-#endif
-}
-
-
const QString &Quassel::coreDumpFileName()
{
if (_coreDumpFileName.isEmpty()) {
class QFile;
+class Logger;
+
class Quassel : public QObject
{
// TODO Qt5: Use Q_GADGET
static Quassel *instance();
+ /**
+ * Provides access to the Logger instance.
+ *
+ * @returns The Logger instance
+ */
+ Logger *logger() const;
+
static void setupBuildInfo();
static const BuildInfo &buildInfo();
static RunMode runMode();
static QString optionValue(const QString &option);
static bool isOptionSet(const QString &option);
- enum LogLevel {
- DebugLevel,
- InfoLevel,
- WarningLevel,
- ErrorLevel
- };
-
- static LogLevel logLevel();
- static void setLogLevel(LogLevel logLevel);
- static QFile *logFile();
- static bool logToSyslog();
-
- static void logFatalMessage(const char *msg);
-
using ReloadHandler = std::function<bool()>;
static void registerReloadHandler(ReloadHandler handler);
static void registerQuitHandler(QuitHandler quitHandler);
+ const QString &coreDumpFileName();
+
+signals:
+ void messageLogged(const QDateTime &timeStamp, const QString &msg);
+
protected:
static bool init();
static void destroy();
void setupEnvironment();
void registerMetaTypes();
- const QString &coreDumpFileName();
-
/**
* Requests a reload of relevant runtime configuration.
*
QStringList _dataDirPaths;
QString _translationDirPath;
- LogLevel _logLevel{InfoLevel};
- bool _logToSyslog{false};
- std::unique_ptr<QFile> _logFile;
-
std::shared_ptr<AbstractCliParser> _cliParser;
+ Logger *_logger;
+
std::vector<ReloadHandler> _reloadHandlers;
std::vector<QuitHandler> _quitHandlers;
};
***************************************************************************/
#include "abstractsqlstorage.h"
-#include "quassel.h"
-
-#include "logger.h"
#include <QMutexLocker>
#include <QSqlDriver>
#include <QSqlField>
#include <QSqlQuery>
+#include "logmessage.h"
+#include "quassel.h"
+
int AbstractSqlStorage::_nextConnectionId = 0;
AbstractSqlStorage::AbstractSqlStorage(QObject *parent)
: Storage(parent),
*/
#include "cipher.h"
-#include "logger.h"
+#include "logmessage.h"
Cipher::Cipher()
{
#include "coreauthhandler.h"
#include "coresession.h"
#include "coresettings.h"
-#include "logger.h"
#include "internalpeer.h"
+#include "logmessage.h"
#include "network.h"
#include "postgresqlstorage.h"
#include "quassel.h"
#endif
#include "core.h"
-#include "logger.h"
+#include "logmessage.h"
using namespace Protocol;
#include "corebasichandler.h"
#include "util.h"
-#include "logger.h"
+#include "logmessage.h"
CoreBasicHandler::CoreBasicHandler(CoreNetwork *parent)
: BasicHandler(parent),
#include "ircchannel.h"
#include "ircparser.h"
#include "ircuser.h"
-#include "logger.h"
+#include "logmessage.h"
#include "messageevent.h"
#include "remotepeer.h"
#include "storage.h"
#include "ctcpevent.h"
#include "ircevent.h"
#include "ircuser.h"
-#include "logger.h"
+#include "logmessage.h"
#include "messageevent.h"
#include "netsplit.h"
#include "quassel.h"
#include "corenetwork.h"
#include "identserver.h"
-#include "logger.h"
+#include "logmessage.h"
IdentServer::IdentServer(QObject *parent)
: QObject(parent)
#include "ldapauthenticator.h"
-#include "logger.h"
+#include "logmessage.h"
#include "network.h"
#include "quassel.h"
#include <QtSql>
-#include "logger.h"
+#include "logmessage.h"
#include "network.h"
#include "quassel.h"
#include "sqlauthenticator.h"
-#include "logger.h"
+#include "logmessage.h"
#include "network.h"
#include "quassel.h"
#include <QtSql>
-#include "logger.h"
+#include "logmessage.h"
#include "network.h"
#include "quassel.h"
#include <QDateTime>
-#include "logger.h"
#include "quassel.h"
+#include "logmessage.h"
#ifdef HAVE_SSL
#include "debuglogwidget.h"
-#include "client.h"
+#include "quassel.h"
DebugLogWidget::DebugLogWidget(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
setAttribute(Qt::WA_DeleteOnClose, true);
- ui.textEdit->setPlainText(Client::debugLog());
- connect(Client::instance(), SIGNAL(logUpdated(const QString &)), this, SLOT(logUpdated(const QString &)));
+
ui.textEdit->setReadOnly(true);
+
+ connect(Quassel::instance()->logger(), SIGNAL(messageLogged(Logger::LogEntry)), SLOT(logUpdated(Logger::LogEntry)));
+
+ QString content;
+ for (auto &&message : Quassel::instance()->logger()->messages()) {
+ content += toString(message);
+ }
+ ui.textEdit->setPlainText(content);
+
+}
+
+
+QString DebugLogWidget::toString(const Logger::LogEntry &msg)
+{
+ return msg.timeStamp.toString("yyyy-MM-dd hh:mm:ss ") + msg.message + "\n";
}
-void DebugLogWidget::logUpdated(const QString &msg)
+void DebugLogWidget::logUpdated(const Logger::LogEntry &msg)
{
ui.textEdit->moveCursor(QTextCursor::End);
- ui.textEdit->insertPlainText(msg);
+ ui.textEdit->insertPlainText(toString(msg));
ui.textEdit->moveCursor(QTextCursor::End);
}
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
-#ifndef DEBUGLOGWIDGET_H
-#define DEBUGLOGWIDGET_H
+#pragma once
+
+#include <QString>
+#include <QWidget>
+
+#include "logger.h"
#include "ui_debuglogwidget.h"
DebugLogWidget(QWidget *parent = 0);
private slots:
- void logUpdated(const QString &msg);
+ void logUpdated(const Logger::LogEntry &msg);
+
+private:
+ QString toString(const Logger::LogEntry &msg);
private:
Ui::DebugLogWidget ui;
};
-
-
-#endif //DEBUGLOGWIDGET_H
void MainWin::on_actionDebugLog_triggered()
{
- DebugLogWidget *logWidget = new DebugLogWidget(0);
+ DebugLogWidget *logWidget = new DebugLogWidget(nullptr); // will be deleted on close
logWidget->show();
}
#include <tuple>
#include <vector>
-#include <QStringList>
+#include <QList>
+#include <QObject>
+#include <QString>
#if QT_VERSION >= 0x050000
# include <QTemporaryDir>
inline static QtUiStyle *style();
inline static MainWin *mainWindow();
+ QString debugLog() const;
+
static bool haveSystemTray();
/* Notifications */
Quassel::setRunMode(Quassel::ClientOnly);
-#if QT_VERSION < 0x050000
- qInstallMsgHandler(Client::logMessage);
-#else
- qInstallMessageHandler(Client::logMessage);
+#if QT_VERSION >= 0x050000
connect(this, &QGuiApplication::commitDataRequest, this, &QtUiApplication::commitData, Qt::DirectConnection);
connect(this, &QGuiApplication::saveStateRequest, this, &QtUiApplication::saveState, Qt::DirectConnection);
#endif