Store log files in node data path
This commit is contained in:
parent
de28085281
commit
8e7542052d
10 changed files with 44 additions and 52 deletions
|
@ -19,7 +19,7 @@ void force_nano_dev_network ();
|
|||
|
||||
GTEST_API_ int main (int argc, char ** argv)
|
||||
{
|
||||
nano::nlogger::initialize_for_tests (nano::load_log_config (nano::log_config::tests_default ()));
|
||||
nano::nlogger::initialize_for_tests (nano::log_config::tests_default ());
|
||||
nano::set_file_descriptor_limit (OPEN_FILE_DESCRIPTORS_LIMIT);
|
||||
nano::force_nano_dev_network ();
|
||||
nano::node_singleton_memory_pool_purge_guard memory_pool_cleanup_guard;
|
||||
|
|
|
@ -386,40 +386,29 @@ nano::tomlconfig nano::load_toml_file (const std::filesystem::path & config_file
|
|||
}
|
||||
config_overrides_stream << std::endl;
|
||||
|
||||
auto try_load_toml = [&config_overrides_stream] (auto toml_config_path) -> std::optional<nano::tomlconfig> {
|
||||
// Make sure we don't create an empty toml file if it doesn't exist. Running without a toml file is the default.
|
||||
if (std::filesystem::exists (toml_config_path))
|
||||
// Make sure we don't create an empty toml file if it doesn't exist. Running without a toml file is the default.
|
||||
auto toml_config_path = data_path / config_filename;
|
||||
if (std::filesystem::exists (toml_config_path))
|
||||
{
|
||||
nano::tomlconfig toml;
|
||||
auto error = toml.read (config_overrides_stream, toml_config_path);
|
||||
if (error)
|
||||
{
|
||||
nano::tomlconfig toml;
|
||||
auto error = toml.read (config_overrides_stream, toml_config_path);
|
||||
if (error)
|
||||
{
|
||||
throw std::runtime_error (error.get_message ());
|
||||
}
|
||||
return toml;
|
||||
throw std::runtime_error (error.get_message ());
|
||||
}
|
||||
return std::nullopt;
|
||||
};
|
||||
|
||||
// First try to load config from the current working directory, then from the node data directory
|
||||
if (auto toml = try_load_toml (config_filename); toml)
|
||||
{
|
||||
nano::default_logger ().info (nano::log::type::config, "Config for `{}` loaded from current working directory", config_filename.string ());
|
||||
return *toml;
|
||||
nano::default_logger ().info (nano::log::type::config, "Config for `{}` loaded from node data directory: ", config_filename.string (), toml_config_path.string ());
|
||||
return toml;
|
||||
}
|
||||
if (auto toml = try_load_toml (data_path / config_filename); toml)
|
||||
else
|
||||
{
|
||||
nano::default_logger ().info (nano::log::type::config, "Config for `{}` loaded from node data directory ({})", config_filename.string (), data_path.string ());
|
||||
return *toml;
|
||||
// If no config was found, return an empty config with overrides applied
|
||||
nano::tomlconfig toml;
|
||||
auto error = toml.read (config_overrides_stream);
|
||||
if (error)
|
||||
{
|
||||
throw std::runtime_error (error.get_message ());
|
||||
}
|
||||
nano::default_logger ().info (nano::log::type::config, "Config for `{}` not found, using default configuration", config_filename.string ());
|
||||
return toml;
|
||||
}
|
||||
|
||||
// If no config was found, return an empty config with overrides applied
|
||||
nano::tomlconfig toml;
|
||||
auto error = toml.read (config_overrides_stream);
|
||||
if (error)
|
||||
{
|
||||
throw std::runtime_error (error.get_message ());
|
||||
}
|
||||
nano::default_logger ().info (nano::log::type::config, "Config for `{}` not found, using default configuration", config_filename.string ());
|
||||
return toml;
|
||||
}
|
||||
|
|
|
@ -34,10 +34,10 @@ std::function<std::string (nano::log::type tag, std::string identifier)> nano::n
|
|||
return std::string{ to_string (tag) };
|
||||
} };
|
||||
|
||||
void nano::nlogger::initialize (nano::log_config config)
|
||||
void nano::nlogger::initialize (nano::log_config fallback, std::filesystem::path data_path, std::vector<std::string> const & config_overrides)
|
||||
{
|
||||
initialize_common (config);
|
||||
|
||||
auto config = nano::load_log_config (std::move (fallback), data_path, config_overrides);
|
||||
initialize_common (config, data_path);
|
||||
global_initialized = true;
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,7 @@ namespace
|
|||
/// Takes a qualified identifier in the form `node_identifier::tag` and splits it into a pair of `identifier` and `tag`
|
||||
/// It is a limitation of spldlog that we cannot attach additional data to the logger, so we have to encode the node identifier in the logger name
|
||||
/// @returns <node identifier, tag>
|
||||
|
||||
std::pair<std::string_view, std::string_view> split_qualified_identifier (std::string_view qualified_identifier)
|
||||
{
|
||||
auto pos = qualified_identifier.find ("::");
|
||||
|
@ -94,15 +95,17 @@ public:
|
|||
};
|
||||
}
|
||||
|
||||
void nano::nlogger::initialize_for_tests (nano::log_config config)
|
||||
void nano::nlogger::initialize_for_tests (nano::log_config fallback)
|
||||
{
|
||||
initialize_common (config);
|
||||
auto config = nano::load_log_config (std::move (fallback), /* load log config from current workdir */ {});
|
||||
initialize_common (config, /* store log file in current workdir */ {});
|
||||
|
||||
// Use tag and identifier as the logger name, since multiple nodes may be running in the same process
|
||||
global_name_formatter = [] (nano::log::type tag, std::string identifier) {
|
||||
return fmt::format ("{}::{}", identifier, to_string (tag));
|
||||
};
|
||||
|
||||
// Setup formatter to include information about node identifier `[%i]` and tag `[%n]`
|
||||
auto formatter = std::make_unique<spdlog::pattern_formatter> ();
|
||||
formatter->add_flag<identifier_formatter_flag> ('i');
|
||||
formatter->add_flag<tag_formatter_flag> ('n');
|
||||
|
@ -110,14 +113,13 @@ void nano::nlogger::initialize_for_tests (nano::log_config config)
|
|||
|
||||
for (auto & sink : global_sinks)
|
||||
{
|
||||
// Make deep copy of formatter for each sink
|
||||
sink->set_formatter (formatter->clone ());
|
||||
}
|
||||
|
||||
global_initialized = true;
|
||||
}
|
||||
|
||||
void nano::nlogger::initialize_common (nano::log_config const & config)
|
||||
void nano::nlogger::initialize_common (nano::log_config const & config, std::filesystem::path data_path)
|
||||
{
|
||||
global_config = config;
|
||||
|
||||
|
@ -160,8 +162,8 @@ void nano::nlogger::initialize_common (nano::log_config const & config)
|
|||
auto filename = fmt::format ("log_{:%Y-%m-%d_%H-%M}-{:%S}", fmt::localtime (time), now.time_since_epoch ());
|
||||
std::replace (filename.begin (), filename.end (), '.', '_'); // Replace millisecond dot separator with underscore
|
||||
|
||||
std::filesystem::path log_path{ "log" };
|
||||
log_path /= filename + ".log";
|
||||
std::filesystem::path log_path{ data_path / "log" / (filename + ".log") };
|
||||
log_path = std::filesystem::absolute (log_path);
|
||||
|
||||
std::cerr << "Logging to file: " << log_path.string () << std::endl;
|
||||
|
||||
|
@ -170,12 +172,12 @@ void nano::nlogger::initialize_common (nano::log_config const & config)
|
|||
{
|
||||
// TODO: Maybe show a warning to the user about possibly unlimited log file size
|
||||
|
||||
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt> (log_path, true);
|
||||
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt> (log_path.string (), true);
|
||||
global_sinks.push_back (file_sink);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt> (log_path, config.file.max_size, config.file.rotation_count);
|
||||
auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt> (log_path.string (), config.file.max_size, config.file.rotation_count);
|
||||
global_sinks.push_back (file_sink);
|
||||
}
|
||||
}
|
||||
|
@ -287,6 +289,7 @@ nano::log_config nano::log_config::tests_default ()
|
|||
{
|
||||
log_config config{};
|
||||
config.default_level = nano::log::level::off;
|
||||
config.file.enable = false;
|
||||
return config;
|
||||
}
|
||||
|
||||
|
|
|
@ -76,8 +76,8 @@ public:
|
|||
nlogger (nlogger const &) = delete;
|
||||
|
||||
public:
|
||||
static void initialize (nano::log_config);
|
||||
static void initialize_for_tests (nano::log_config);
|
||||
static void initialize (nano::log_config fallback, std::filesystem::path data_path = {}, std::vector<std::string> const & config_overrides = std::vector<std::string> ());
|
||||
static void initialize_for_tests (nano::log_config fallback);
|
||||
static void flush ();
|
||||
|
||||
private:
|
||||
|
@ -86,7 +86,7 @@ private:
|
|||
static std::vector<spdlog::sink_ptr> global_sinks;
|
||||
static std::function<std::string (nano::log::type tag, std::string identifier)> global_name_formatter;
|
||||
|
||||
static void initialize_common (nano::log_config const &);
|
||||
static void initialize_common (nano::log_config const &, std::filesystem::path data_path);
|
||||
|
||||
public:
|
||||
template <class... Args>
|
||||
|
|
|
@ -491,7 +491,7 @@ account_info account_info_rpc (boost::asio::io_context & ioc, tcp::resolver::res
|
|||
/** This launches a node and fires a lot of send/recieve RPC requests at it (configurable), then other nodes are tested to make sure they observe these blocks as well. */
|
||||
int main (int argc, char * const * argv)
|
||||
{
|
||||
nano::nlogger::initialize_for_tests (nano::load_log_config (nano::log_config::tests_default ()));
|
||||
nano::nlogger::initialize_for_tests (nano::log_config::tests_default ());
|
||||
nano::force_nano_dev_network ();
|
||||
|
||||
boost::program_options::options_description description ("Command line options");
|
||||
|
|
|
@ -63,7 +63,7 @@ constexpr std::size_t OPEN_FILE_DESCRIPTORS_LIMIT = 16384;
|
|||
|
||||
void nano::daemon::run (std::filesystem::path const & data_path, nano::node_flags const & flags)
|
||||
{
|
||||
nano::nlogger::initialize (nano::load_log_config (nano::log_config::daemon_default (), data_path, flags.config_overrides));
|
||||
nano::nlogger::initialize (nano::log_config::daemon_default (), data_path, flags.config_overrides);
|
||||
|
||||
nlogger.info (nano::log::type::daemon, "Daemon started");
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ nano::error read_wallet_config (nano::wallet_config & config_a, std::filesystem:
|
|||
|
||||
int run_wallet (QApplication & application, int argc, char * const * argv, std::filesystem::path const & data_path, nano::node_flags const & flags)
|
||||
{
|
||||
nano::nlogger::initialize (nano::load_log_config (nano::log_config::daemon_default (), data_path, flags.config_overrides));
|
||||
nano::nlogger::initialize (nano::log_config::daemon_default (), data_path, flags.config_overrides);
|
||||
|
||||
nlogger.info (nano::log::type::daemon_wallet, "Daemon started (wallet)");
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ void force_nano_dev_network ();
|
|||
|
||||
int main (int argc, char ** argv)
|
||||
{
|
||||
nano::nlogger::initialize_for_tests (nano::load_log_config (nano::log_config::tests_default ()));
|
||||
nano::nlogger::initialize_for_tests (nano::log_config::tests_default ());
|
||||
nano::force_nano_dev_network ();
|
||||
nano::node_singleton_memory_pool_purge_guard memory_pool_cleanup_guard;
|
||||
QApplication application (argc, argv);
|
||||
|
|
|
@ -15,7 +15,7 @@ void force_nano_dev_network ();
|
|||
|
||||
int main (int argc, char ** argv)
|
||||
{
|
||||
nano::nlogger::initialize_for_tests (nano::load_log_config (nano::log_config::tests_default ()));
|
||||
nano::nlogger::initialize_for_tests (nano::log_config::tests_default ());
|
||||
nano::force_nano_dev_network ();
|
||||
nano::set_use_memory_pools (false);
|
||||
nano::node_singleton_memory_pool_purge_guard cleanup_guard;
|
||||
|
|
|
@ -14,7 +14,7 @@ void force_nano_dev_network ();
|
|||
|
||||
int main (int argc, char ** argv)
|
||||
{
|
||||
nano::nlogger::initialize_for_tests (nano::load_log_config (nano::log_config::tests_default ()));
|
||||
nano::nlogger::initialize_for_tests (nano::log_config::tests_default ());
|
||||
nano::force_nano_dev_network ();
|
||||
nano::node_singleton_memory_pool_purge_guard memory_pool_cleanup_guard;
|
||||
testing::InitGoogleTest (&argc, argv);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue