mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-22 11:00:48 +03:00
Merge pull request #1163 from foresto/log-options
Control logging via command line or environment variable
This commit is contained in:
commit
02adcfdc38
4 changed files with 96 additions and 22 deletions
|
@ -31,7 +31,27 @@ Displays help including Qt specific options.
|
||||||
Displays version information.
|
Displays version information.
|
||||||
|
|
||||||
*--debug*::
|
*--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>_::
|
*-p* _<profile>_, *--profile* _<profile>_::
|
||||||
Creates a unique profile, which allows you to log into several accounts at the
|
Creates a unique profile, which allows you to log into several accounts at the
|
||||||
|
|
|
@ -6,8 +6,10 @@
|
||||||
#include "Logging.h"
|
#include "Logging.h"
|
||||||
#include "config/nheko.h"
|
#include "config/nheko.h"
|
||||||
|
|
||||||
|
#include "spdlog/cfg/helpers.h"
|
||||||
#include "spdlog/sinks/rotating_file_sink.h"
|
#include "spdlog/sinks/rotating_file_sink.h"
|
||||||
#include "spdlog/sinks/stdout_color_sinks.h"
|
#include "spdlog/sinks/stdout_color_sinks.h"
|
||||||
|
#include "spdlog/spdlog.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
@ -61,19 +63,20 @@ qmlMessageHandler(QtMsgType type, const QMessageLogContext &context, const QStri
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace nhlog {
|
namespace nhlog {
|
||||||
bool enable_debug_log_from_commandline = false;
|
|
||||||
|
|
||||||
void
|
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;
|
std::vector<spdlog::sink_ptr> sinks;
|
||||||
sinks.push_back(file_sink);
|
if (!path.isEmpty()) {
|
||||||
sinks.push_back(console_sink);
|
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;
|
mtx::utils::log::log()->sinks() = sinks;
|
||||||
net_logger = std::make_shared<spdlog::logger>("net", std::begin(sinks), std::end(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));
|
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));
|
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);
|
db_logger->set_level(spdlog::level::trace);
|
||||||
ui_logger->set_level(spdlog::level::trace);
|
ui_logger->set_level(spdlog::level::trace);
|
||||||
crypto_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);
|
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);
|
qInstallMessageHandler(qmlMessageHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,11 +6,15 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <spdlog/logger.h>
|
#include <string>
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
#include "spdlog/logger.h"
|
||||||
|
|
||||||
namespace nhlog {
|
namespace nhlog {
|
||||||
void
|
void
|
||||||
init(const std::string &file);
|
init(const QString &level, const QString &path, bool to_stderr);
|
||||||
|
|
||||||
std::shared_ptr<spdlog::logger>
|
std::shared_ptr<spdlog::logger>
|
||||||
ui();
|
ui();
|
||||||
|
@ -27,5 +31,4 @@ crypto();
|
||||||
std::shared_ptr<spdlog::logger>
|
std::shared_ptr<spdlog::logger>
|
||||||
qml();
|
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;
|
QCommandLineParser parser;
|
||||||
parser.addHelpOption();
|
parser.addHelpOption();
|
||||||
parser.addVersionOption();
|
parser.addVersionOption();
|
||||||
QCommandLineOption debugOption(QStringLiteral("debug"), QStringLiteral("Enable debug output"));
|
QCommandLineOption debugOption(QStringLiteral("debug"),
|
||||||
|
QObject::tr("Alias for '--log-level trace'."));
|
||||||
parser.addOption(debugOption);
|
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
|
// 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
|
// 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
|
#endif
|
||||||
|
|
||||||
if (parser.isSet(debugOption))
|
|
||||||
nhlog::enable_debug_log_from_commandline = true;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
nhlog::init(QStringLiteral("%1/nheko.log")
|
QString level;
|
||||||
.arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation))
|
if (parser.isSet(logLevel)) {
|
||||||
.toStdString());
|
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) {
|
} 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);
|
std::exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue