mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-24 12:08:50 +03:00
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.
This commit is contained in:
parent
9b751fe6d8
commit
80f7683a57
4 changed files with 96 additions and 22 deletions
|
@ -31,7 +31,27 @@ Displays help including Qt specific options.
|
|||
Displays version information.
|
||||
|
||||
*--debug*::
|
||||
Enables debug output.
|
||||
Alias for _--log-level trace_.
|
||||
|
||||
*-l*, *--log-level* _<level>_::
|
||||
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_
|
||||
+
|
||||
Log levels can also be set in the NHEKO_LOG_LEVEL environment variable, using
|
||||
the same syntax. It will be overridden by this command line option.
|
||||
|
||||
*-L*, *--log-type* _<type>_::
|
||||
Set the log output type. A comma-separated list is allowed. The default is _file,stderr_.
|
||||
+
|
||||
types: _file_ _stderr_ _none_
|
||||
+
|
||||
The log type can also be set in the NHEKO_LOG_TYPE environment variable,
|
||||
which will be overridden by this command line option.
|
||||
|
||||
*-p* _<profile>_, *--profile* _<profile>_::
|
||||
Creates a unique profile, which allows you to log into several accounts at the
|
||||
|
|
|
@ -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;
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
53
src/main.cpp
53
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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue