diff --git a/client/client.pro b/client/client.pro index f365cbec..85f70c68 100644 --- a/client/client.pro +++ b/client/client.pro @@ -84,9 +84,6 @@ HEADERS += \ utilities.h \ vpnconnection.h \ protocols/vpnprotocol.h \ - logger.h \ - loghandler.h \ - loglevel.h \ constants.h \ platforms/ios/QRCodeReaderBase.h @@ -144,8 +141,6 @@ SOURCES += \ utilities.cpp \ vpnconnection.cpp \ protocols/vpnprotocol.cpp \ - logger.cpp \ - loghandler.cpp \ platforms/ios/QRCodeReaderBase.cpp RESOURCES += \ diff --git a/client/logger.cpp b/client/logger.cpp deleted file mode 100644 index 06a7c6c8..00000000 --- a/client/logger.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "logger.h" -#include "loghandler.h" - -Logger::Logger(const QString& module, const QString& className) - : Logger(QStringList({module}), className) {} - -Logger::Logger(const QStringList& modules, const QString& className) - : m_modules(modules), m_className(className) {} - -Logger::Log Logger::error() { return Log(this, LogLevel::Error); } -Logger::Log Logger::warning() { return Log(this, LogLevel::Warning); } -Logger::Log Logger::info() { return Log(this, LogLevel::Info); } -Logger::Log Logger::debug() { return Log(this, LogLevel::Debug); } - -Logger::Log::Log(Logger* logger, LogLevel logLevel) - : m_logger(logger), m_logLevel(logLevel), m_data(new Data()) {} - -Logger::Log::~Log() { - LogHandler::messageHandler(m_logLevel, m_logger->modules(), - m_logger->className(), m_data->m_buffer.trimmed()); - delete m_data; -} - -#define CREATE_LOG_OP_REF(x) \ - Logger::Log& Logger::Log::operator<<(x t) { \ - m_data->m_ts << t << ' '; \ - return *this; \ - } - -CREATE_LOG_OP_REF(uint64_t); -CREATE_LOG_OP_REF(const char*); -CREATE_LOG_OP_REF(const QString&); -CREATE_LOG_OP_REF(const QByteArray&); -CREATE_LOG_OP_REF(void*); - -#undef CREATE_LOG_OP_REF - -Logger::Log& Logger::Log::operator<<(const QStringList& t) { - m_data->m_ts << '[' << t.join(",") << ']' << ' '; - return *this; -} - -Logger::Log& Logger::Log::operator<<(QTextStreamFunction t) { - m_data->m_ts << t; - return *this; -} - -// static -QString Logger::sensitive(const QString& input) { -#ifdef QT_DEBUG - return input; -#else - return QString(input.length(), 'X'); -#endif -} diff --git a/client/logger.h b/client/logger.h deleted file mode 100644 index 19aeb6f3..00000000 --- a/client/logger.h +++ /dev/null @@ -1,90 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef LOGGER_H -#define LOGGER_H - -#include "loglevel.h" - -#include -#include -#include -#include - -constexpr const char* LOG_CAPTIVEPORTAL = "captiveportal"; -constexpr const char* LOG_CONTROLLER = "controller"; -constexpr const char* LOG_IAP = "iap"; -constexpr const char* LOG_INSPECTOR = "inspector"; -constexpr const char* LOG_MAIN = "main"; -constexpr const char* LOG_MODEL = "model"; -constexpr const char* LOG_NETWORKING = "networking"; -constexpr const char* LOG_SERVER = "server"; - -#if defined(MVPN_LINUX) || defined(MVPN_ANDROID) -constexpr const char* LOG_LINUX = "linux"; -#endif - -#ifdef MVPN_WINDOWS -constexpr const char* LOG_WINDOWS = "windows"; -#endif - -#if __APPLE__ || defined(MVPN_WASM) -constexpr const char* LOG_MACOS = "macos"; -constexpr const char* LOG_IOS = "ios"; -#endif - -#if defined(MVPN_ANDROID) || defined(UNIT_TEST) -constexpr const char* LOG_ANDROID = "android"; -#endif - -class Logger { - public: - Logger(const QString& module, const QString& className); - Logger(const QStringList& modules, const QString& className); - - const QStringList& modules() const { return m_modules; } - const QString& className() const { return m_className; } - - class Log { - public: - Log(Logger* logger, LogLevel level); - ~Log(); - - Log& operator<<(uint64_t t); - Log& operator<<(const char* t); - Log& operator<<(const QString& t); - Log& operator<<(const QStringList& t); - Log& operator<<(const QByteArray& t); - Log& operator<<(QTextStreamFunction t); - Log& operator<<(void* t); - - private: - Logger* m_logger; - LogLevel m_logLevel; - - struct Data { - Data() : m_ts(&m_buffer, QIODevice::WriteOnly) {} - - QString m_buffer; - QTextStream m_ts; - }; - - Data* m_data; - }; - - Log error(); - Log warning(); - Log info(); - Log debug(); - - // Use this to log sensitive data such as IP address, session tokens, and so - // on. - QString sensitive(const QString& input); - - private: - QStringList m_modules; - QString m_className; -}; - -#endif // LOGGER_H diff --git a/client/loghandler.cpp b/client/loghandler.cpp deleted file mode 100644 index 1302f1ca..00000000 --- a/client/loghandler.cpp +++ /dev/null @@ -1,345 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "loghandler.h" -#include "constants.h" -#include "logger.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef MVPN_ANDROID -# include -#endif - -constexpr qint64 LOG_MAX_FILE_SIZE = 204800; -constexpr const char* LOG_FILENAME = "mozillavpn.txt"; - -namespace { -QMutex s_mutex; -QString s_location = - QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); -LogHandler* s_instance = nullptr; - -LogLevel qtTypeToLogLevel(QtMsgType type) { - switch (type) { - case QtDebugMsg: - return Debug; - case QtInfoMsg: - return Info; - case QtWarningMsg: - return Warning; - case QtCriticalMsg: - [[fallthrough]]; - case QtFatalMsg: - return Error; - default: - return Debug; - } -} - -} // namespace - -// static -LogHandler* LogHandler::instance() { - QMutexLocker lock(&s_mutex); - return maybeCreate(lock); -} - -// static -void LogHandler::messageQTHandler(QtMsgType type, - const QMessageLogContext& context, - const QString& message) { - QMutexLocker lock(&s_mutex); - maybeCreate(lock)->addLog(Log(qtTypeToLogLevel(type), context.file, - context.function, context.line, message), - lock); -} - -// static -void LogHandler::messageHandler(LogLevel logLevel, const QStringList& modules, - const QString& className, - const QString& message) { - QMutexLocker lock(&s_mutex); - maybeCreate(lock)->addLog(Log(logLevel, modules, className, message), lock); -} - -// static -LogHandler* LogHandler::maybeCreate(const QMutexLocker& proofOfLock) { - if (!s_instance) { - LogLevel minLogLevel = Debug; // TODO: in prod, we should log >= warning - QStringList modules; - QProcessEnvironment pe = QProcessEnvironment::systemEnvironment(); - if (pe.contains("MOZVPN_LEVEL")) { - QString level = pe.value("MOZVPN_LEVEL"); - if (level == "info") - minLogLevel = Info; - else if (level == "warning") - minLogLevel = Warning; - else if (level == "error") - minLogLevel = Error; - } - - if (pe.contains("MOZVPN_LOG")) { - QStringList parts = pe.value("MOZVPN_LOG").split(","); - for (const QString& part : parts) { - modules.append(part.trimmed()); - } - } - - s_instance = new LogHandler(minLogLevel, modules, proofOfLock); - } - - return s_instance; -} - -// static -void LogHandler::prettyOutput(QTextStream& out, const LogHandler::Log& log) { - out << "[" << log.m_dateTime.toString("dd.MM.yyyy hh:mm:ss.zzz") << "] "; - - switch (log.m_logLevel) { - case Debug: - out << "Debug: "; - break; - case Info: - out << "Info: "; - break; - case Warning: - out << "Warning: "; - break; - case Error: - out << "Error: "; - break; - default: - out << "?!?: "; - break; - } - - if (log.m_fromQT) { - out << log.m_message; - - if (!log.m_file.isEmpty() || !log.m_function.isEmpty()) { - out << " ("; - - if (!log.m_file.isEmpty()) { - int pos = log.m_file.lastIndexOf("/"); - out << log.m_file.right(log.m_file.length() - pos - 1); - - if (log.m_line >= 0) { - out << ":" << log.m_line; - } - - if (!log.m_function.isEmpty()) { - out << ", "; - } - } - - if (!log.m_function.isEmpty()) { - out << log.m_function; - } - - out << ")"; - } - } else { - out << "(" << log.m_modules.join("|") << " - " << log.m_className << ") " - << log.m_message; - } - - out << Qt::endl; -} - -// static -void LogHandler::enableDebug() { - QMutexLocker lock(&s_mutex); - maybeCreate(lock)->m_showDebug = true; -} - -LogHandler::LogHandler(LogLevel minLogLevel, const QStringList& modules, - const QMutexLocker& proofOfLock) - : m_minLogLevel(minLogLevel), m_modules(modules) { - Q_UNUSED(proofOfLock); - -#if defined(QT_DEBUG) || defined(MVPN_WASM) - m_showDebug = true; -#endif - - if (!s_location.isEmpty()) { - openLogFile(proofOfLock); - } -} - -void LogHandler::addLog(const Log& log, const QMutexLocker& proofOfLock) { - if (!matchLogLevel(log, proofOfLock)) { - return; - } - - if (!matchModule(log, proofOfLock)) { - return; - } - - if (m_output) { - prettyOutput(*m_output, log); - } - - if ((log.m_logLevel != LogLevel::Debug) || m_showDebug) { - QTextStream out(stderr); - prettyOutput(out, log); - } - - QByteArray buffer; - { - QTextStream out(&buffer); - prettyOutput(out, log); - } - - emit logEntryAdded(buffer); - -#if defined(MVPN_ANDROID) && defined(QT_DEBUG) - const char* str = buffer.constData(); - if (str) { - __android_log_write(ANDROID_LOG_DEBUG, "mozillavpn", str); - } -#endif -} - -bool LogHandler::matchModule(const Log& log, - const QMutexLocker& proofOfLock) const { - Q_UNUSED(proofOfLock); - - // Let's include QT logs always. - if (log.m_fromQT) { - return true; - } - - // If no modules has been specified, let's include all. - if (m_modules.isEmpty()) { - return true; - } - - for (const QString& module : log.m_modules) { - if (m_modules.contains(module)) { - return true; - } - } - - return false; -} - -bool LogHandler::matchLogLevel(const Log& log, - const QMutexLocker& proofOfLock) const { - Q_UNUSED(proofOfLock); - return log.m_logLevel >= m_minLogLevel; -} - -// static -void LogHandler::writeLogs(QTextStream& out) { - QMutexLocker lock(&s_mutex); - - if (!s_instance || !s_instance->m_logFile) { - return; - } - - QString logFileName = s_instance->m_logFile->fileName(); - s_instance->closeLogFile(lock); - - { - QFile file(logFileName); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - return; - } - - out << file.readAll(); - } - - s_instance->openLogFile(lock); -} - -// static -void LogHandler::cleanupLogs() { - QMutexLocker lock(&s_mutex); - cleanupLogFile(lock); -} - -// static -void LogHandler::cleanupLogFile(const QMutexLocker& proofOfLock) { - if (!s_instance || !s_instance->m_logFile) { - return; - } - - QString logFileName = s_instance->m_logFile->fileName(); - s_instance->closeLogFile(proofOfLock); - - { - QFile file(logFileName); - file.remove(); - } - - s_instance->openLogFile(proofOfLock); -} - -// static -void LogHandler::setLocation(const QString& path) { - QMutexLocker lock(&s_mutex); - s_location = path; - - if (s_instance && s_instance->m_logFile) { - cleanupLogFile(lock); - } -} - -void LogHandler::openLogFile(const QMutexLocker& proofOfLock) { - Q_UNUSED(proofOfLock); - Q_ASSERT(!m_logFile); - Q_ASSERT(!m_output); - - QDir appDataLocation(s_location); - if (!appDataLocation.exists()) { - QDir tmp(s_location); - tmp.cdUp(); - if (!tmp.exists()) { - return; - } - if (!tmp.mkdir(appDataLocation.dirName())) { - return; - } - } - - QString logFileName = appDataLocation.filePath(LOG_FILENAME); - m_logFile = new QFile(logFileName); - if (m_logFile->size() > LOG_MAX_FILE_SIZE) { - m_logFile->remove(); - } - - if (!m_logFile->open(QIODevice::WriteOnly | QIODevice::Append | - QIODevice::Text)) { - delete m_logFile; - m_logFile = nullptr; - return; - } - - m_output = new QTextStream(m_logFile); - - addLog(Log(Debug, QStringList{LOG_MAIN}, "LogHandler", - QString("Log file: %1").arg(logFileName)), - proofOfLock); -} - -void LogHandler::closeLogFile(const QMutexLocker& proofOfLock) { - Q_UNUSED(proofOfLock); - - if (m_logFile) { - delete m_output; - m_output = nullptr; - - delete m_logFile; - m_logFile = nullptr; - } -} diff --git a/client/loghandler.h b/client/loghandler.h deleted file mode 100644 index d853a808..00000000 --- a/client/loghandler.h +++ /dev/null @@ -1,102 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef LOGHANDLER_H -#define LOGHANDLER_H - -#include "loglevel.h" - -#include -#include -#include -#include - -class QFile; -class QTextStream; - -class LogHandler final : public QObject { - Q_OBJECT - - public: - struct Log { - Log() = default; - - Log(LogLevel logLevel, const QStringList& modules, const QString& className, - const QString& message) - : m_logLevel(logLevel), - m_dateTime(QDateTime::currentDateTime()), - m_modules(modules), - m_className(className), - m_message(message), - m_fromQT(false) {} - - Log(LogLevel logLevel, const QString& file, const QString& function, - uint32_t line, const QString& message) - : m_logLevel(logLevel), - m_dateTime(QDateTime::currentDateTime()), - m_file(file), - m_function(function), - m_message(message), - m_line(line), - m_fromQT(true) {} - - LogLevel m_logLevel = LogLevel::Debug; - QDateTime m_dateTime; - QString m_file; - QString m_function; - QStringList m_modules; - QString m_className; - QString m_message; - int32_t m_line = -1; - bool m_fromQT = false; - }; - - static LogHandler* instance(); - - static void messageQTHandler(QtMsgType type, - const QMessageLogContext& context, - const QString& message); - - static void messageHandler(LogLevel logLevel, const QStringList& modules, - const QString& className, const QString& message); - - static void prettyOutput(QTextStream& out, const LogHandler::Log& log); - - static void writeLogs(QTextStream& out); - - static void cleanupLogs(); - - static void setLocation(const QString& path); - - static void enableDebug(); - - signals: - void logEntryAdded(const QByteArray& log); - - private: - LogHandler(LogLevel m_minLogLevel, const QStringList& modules, - const QMutexLocker& proofOfLock); - - static LogHandler* maybeCreate(const QMutexLocker& proofOfLock); - - void addLog(const Log& log, const QMutexLocker& proofOfLock); - - bool matchLogLevel(const Log& log, const QMutexLocker& proofOfLock) const; - bool matchModule(const Log& log, const QMutexLocker& proofOfLock) const; - - void openLogFile(const QMutexLocker& proofOfLock); - - void closeLogFile(const QMutexLocker& proofOfLock); - - static void cleanupLogFile(const QMutexLocker& proofOfLock); - - const LogLevel m_minLogLevel; - const QStringList m_modules; - bool m_showDebug = false; - - QFile* m_logFile = nullptr; - QTextStream* m_output = nullptr; -}; - -#endif // LOGHANDLER_H diff --git a/client/loglevel.h b/client/loglevel.h deleted file mode 100644 index 0bdec85b..00000000 --- a/client/loglevel.h +++ /dev/null @@ -1,15 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef LOGLEVEL_H -#define LOGLEVEL_H - -enum LogLevel { - Debug, - Info, - Warning, - Error, -}; - -#endif // LOGLEVEL_H