diff --git a/src/Logging.cpp b/src/Logging.cpp index 9ae94f088..801225507 100644 --- a/src/Logging.cpp +++ b/src/Logging.cpp @@ -6,6 +6,8 @@ #include "Logging.h" #include "config/nheko.h" +#include "spdlog/spdlog.h" +#include "spdlog/cfg/helpers.h" #include "spdlog/sinks/rotating_file_sink.h" #include "spdlog/sinks/stdout_color_sinks.h" #include @@ -61,19 +63,20 @@ qmlMessageHandler(QtMsgType type, const QMessageLogContext &context, const QStri } namespace nhlog { -bool enable_debug_log_from_commandline = false; void -init(const std::string &file_path) +init(const std::string &level, const std::string &path, bool to_stderr) { - auto file_sink = std::make_shared( - file_path, MAX_FILE_SIZE, MAX_LOG_FILES); - - auto console_sink = std::make_shared(); - std::vector sinks; - sinks.push_back(file_sink); - sinks.push_back(console_sink); + if (!path.empty()) { + auto file_sink = std::make_shared( + path, MAX_FILE_SIZE, MAX_LOG_FILES); + sinks.push_back(file_sink); + } + if (to_stderr) { + auto console_sink = std::make_shared(); + sinks.push_back(console_sink); + } mtx::utils::log::log()->sinks() = sinks; net_logger = std::make_shared("net", std::begin(sinks), std::end(sinks)); @@ -82,7 +85,7 @@ init(const std::string &file_path) crypto_logger = std::make_shared("crypto", std::begin(sinks), std::end(sinks)); qml_logger = std::make_shared("qml", std::begin(sinks), std::end(sinks)); - if (nheko::enable_debug_log || enable_debug_log_from_commandline) { + if (nheko::enable_debug_log) { db_logger->set_level(spdlog::level::trace); ui_logger->set_level(spdlog::level::trace); crypto_logger->set_level(spdlog::level::trace); @@ -91,6 +94,20 @@ init(const std::string &file_path) mtx::utils::log::log()->set_level(spdlog::level::trace); } + spdlog::register_logger(net_logger); + spdlog::register_logger(ui_logger); + spdlog::register_logger(db_logger); + spdlog::register_logger(crypto_logger); + spdlog::register_logger(qml_logger); + + auto envlevel = qEnvironmentVariable("NHEKO_LOG_LEVEL").toStdString(); + if (!envlevel.empty()) { + spdlog::cfg::helpers::load_levels(envlevel); + } + if (!level.empty()) { + spdlog::cfg::helpers::load_levels(level); + } + qInstallMessageHandler(qmlMessageHandler); } diff --git a/src/Logging.h b/src/Logging.h index 4a5109a62..21b4585be 100644 --- a/src/Logging.h +++ b/src/Logging.h @@ -6,11 +6,12 @@ #pragma once #include +#include #include namespace nhlog { void -init(const std::string &file); +init(const std::string &level, const std::string &path, bool to_stderr); std::shared_ptr ui(); @@ -27,5 +28,4 @@ crypto(); std::shared_ptr qml(); -extern bool enable_debug_log_from_commandline; } diff --git a/src/main.cpp b/src/main.cpp index 47ebba27d..3367e9b46 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -202,8 +202,19 @@ main(int argc, char *argv[]) QCommandLineParser parser; parser.addHelpOption(); parser.addVersionOption(); - QCommandLineOption debugOption(QStringLiteral("debug"), QStringLiteral("Enable debug output")); + QCommandLineOption logLevel(QStringLiteral("loglevel"), + QStringLiteral("Set the log level, or a = list like \"warn,ui=off\". " + "levels:{trace,debug,info,warning,error,critical,off} " + "components:{crypto,db,net,qml,ui}"), + QStringLiteral("loglevel")); + parser.addOption(logLevel); + QCommandLineOption debugOption(QStringLiteral("debug"), + QStringLiteral("Alias for \"--loglevel trace\".")); parser.addOption(debugOption); + QCommandLineOption noLog(QStringLiteral("nolog"), QStringLiteral("No log file output.")); + parser.addOption(noLog); + QCommandLineOption noStderr(QStringLiteral("nostderr"), QStringLiteral("No stderr output.")); + parser.addOption(noStderr); // This option is not actually parsed via Qt due to the need to parse it before the app // name is set. It only exists to keep Qt from complaining about the --profile/-p @@ -254,13 +265,13 @@ main(int argc, char *argv[]) } #endif - if (parser.isSet(debugOption)) - nhlog::enable_debug_log_from_commandline = true; - try { - nhlog::init(QStringLiteral("%1/nheko.log") - .arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)) - .toStdString()); + std::string level = (parser.isSet(debugOption) ? "trace," : "") + + parser.value(logLevel).toStdString(); + std::string path = parser.isSet(noLog) ? "" : + QDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)) + .filePath("nheko.log").toStdString(); + nhlog::init(level, path, !parser.isSet(noStderr)); } catch (const spdlog::spdlog_ex &ex) { std::cout << "Log initialization failed: " << ex.what() << std::endl; std::exit(1);