summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorForest <forestix@sonic.net>2022-08-23 12:47:52 -0700
committerForest <forestix@sonic.net>2022-09-10 18:28:44 -0700
commit80f7683a577357e59ec9ca557b79bbfb03b489e2 (patch)
tree40bb5e3ea1470fbe1827cdbc305b58ff1105439a /src
parentBump mtxclient to released version (diff)
downloadnheko-80f7683a577357e59ec9ca557b79bbfb03b489e2.tar.xz
Control logging via command line and environment variables
Nheko is very chatty in its log output, generating log noise (which
complicates diagnostics) and needless disk writes (which affect power
consumption and SSD life).  This patch introduces command line options
and environment variables to control log levels and output type.

The old --debug command line option still works, at least for now.
It is overridden by the new command line options when they are used.

Partially addresses #665.
Diffstat (limited to 'src')
-rw-r--r--src/Logging.cpp34
-rw-r--r--src/Logging.h9
-rw-r--r--src/main.cpp53
3 files changed, 75 insertions, 21 deletions
diff --git a/src/Logging.cpp b/src/Logging.cpp

index 9ae94f08..cd72e395 100644 --- a/src/Logging.cpp +++ b/src/Logging.cpp
@@ -6,8 +6,10 @@ #include "Logging.h" #include "config/nheko.h" +#include "spdlog/cfg/helpers.h" #include "spdlog/sinks/rotating_file_sink.h" #include "spdlog/sinks/stdout_color_sinks.h" +#include "spdlog/spdlog.h" #include <iostream> #include <QString> @@ -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 QString &level, const QString &path, bool to_stderr) { - auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>( - file_path, MAX_FILE_SIZE, MAX_LOG_FILES); - - auto console_sink = std::make_shared<spdlog::sinks::stderr_color_sink_mt>(); - std::vector<spdlog::sink_ptr> sinks; - sinks.push_back(file_sink); - sinks.push_back(console_sink); + if (!path.isEmpty()) { + auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>( + path.toStdString(), MAX_FILE_SIZE, MAX_LOG_FILES); + sinks.push_back(file_sink); + } + if (to_stderr) { + auto console_sink = std::make_shared<spdlog::sinks::stderr_color_sink_mt>(); + sinks.push_back(console_sink); + } mtx::utils::log::log()->sinks() = sinks; net_logger = std::make_shared<spdlog::logger>("net", std::begin(sinks), std::end(sinks)); @@ -82,7 +85,7 @@ init(const std::string &file_path) crypto_logger = std::make_shared<spdlog::logger>("crypto", std::begin(sinks), std::end(sinks)); qml_logger = std::make_shared<spdlog::logger>("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,17 @@ 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); + // We assume the mtxclient library will register its own logger. + + if (!level.isEmpty()) { + spdlog::cfg::helpers::load_levels(level.toStdString()); + } + qInstallMessageHandler(qmlMessageHandler); } diff --git a/src/Logging.h b/src/Logging.h
index 4a5109a6..23ff8236 100644 --- a/src/Logging.h +++ b/src/Logging.h
@@ -6,11 +6,15 @@ #pragma once #include <memory> -#include <spdlog/logger.h> +#include <string> + +#include <QString> + +#include "spdlog/logger.h" namespace nhlog { void -init(const std::string &file); +init(const QString &level, const QString &path, bool to_stderr); std::shared_ptr<spdlog::logger> ui(); @@ -27,5 +31,4 @@ crypto(); std::shared_ptr<spdlog::logger> qml(); -extern bool enable_debug_log_from_commandline; } diff --git a/src/main.cpp b/src/main.cpp
index 47ebba27..f76d8ca6 100644 --- a/src/main.cpp +++ b/src/main.cpp
@@ -202,8 +202,24 @@ main(int argc, char *argv[]) QCommandLineParser parser; parser.addHelpOption(); parser.addVersionOption(); - QCommandLineOption debugOption(QStringLiteral("debug"), QStringLiteral("Enable debug output")); + QCommandLineOption debugOption(QStringLiteral("debug"), + QObject::tr("Alias for '--log-level trace'.")); parser.addOption(debugOption); + QCommandLineOption logLevel( + QStringList() << QStringLiteral("l") << QStringLiteral("log-level"), + QObject::tr("Set the global log level, or a comma-separated list of <component>=<level> " + "pairs, or both. For example, to set the default log level to 'warn' but " + "disable logging for the 'ui' component, pass 'warn,ui=off'. " + "levels:{trace,debug,info,warning,error,critical,off} " + "components:{crypto,db,mtx,net,qml,ui}"), + QObject::tr("level")); + parser.addOption(logLevel); + QCommandLineOption logType( + QStringList() << QStringLiteral("L") << QStringLiteral("log-type"), + QObject::tr("Set the log output type. A comma-separated list is allowed. " + "The default is 'file,stderr'. types:{file,stderr,none}"), + QObject::tr("type")); + parser.addOption(logType); // 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,15 +270,36 @@ 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()); + QString level; + if (parser.isSet(logLevel)) { + level = parser.value(logLevel); + } else if (parser.isSet(debugOption)) { + level = "trace"; + } else { + level = qEnvironmentVariable("NHEKO_LOG_LEVEL"); + } + + QStringList targets = + (parser.isSet(logType) ? parser.value(logType) + : qEnvironmentVariable("NHEKO_LOG_TYPE", "file,stderr")) + .split(',', Qt::SkipEmptyParts); + targets.removeAll("none"); + bool to_stderr = bool(targets.removeAll("stderr")); + QString path = targets.removeAll("file") + ? QDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)) + .filePath("nheko.log") + : QLatin1String(""); + if (!targets.isEmpty()) { + std::cerr << "Invalid log type '" << targets.first().toStdString().c_str() << "'" + << std::endl; + std::exit(1); + } + + nhlog::init(level, path, to_stderr); + } catch (const spdlog::spdlog_ex &ex) { - std::cout << "Log initialization failed: " << ex.what() << std::endl; + std::cerr << "Log initialization failed: " << ex.what() << std::endl; std::exit(1); }