diff --git a/.gitmodules b/.gitmodules index 6f9e8c84da..c1d9a0bf26 100644 --- a/.gitmodules +++ b/.gitmodules @@ -31,3 +31,9 @@ [submodule "submodules/gtest-parallel"] path = submodules/gtest-parallel url = https://github.com/google/gtest-parallel.git +[submodule "submodules/spdlog"] + path = submodules/spdlog + url = https://github.com/gabime/spdlog.git +[submodule "submodules/fmt"] + path = submodules/fmt + url = https://github.com/fmtlib/fmt.git diff --git a/CMakeLists.txt b/CMakeLists.txt index c48e2df2a4..6218ab5fdb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -483,10 +483,6 @@ include_directories(${BOOST_LIBRARY_INCLUDES}) add_library(Boost::stacktrace ALIAS boost_stacktrace_basic) add_definitions(-DBOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED) -# Workaround for GitHub builders which do not appear to have the Windows Message -# Compiler mc.exe -add_definitions(-DBOOST_LOG_WITHOUT_EVENT_LOG) - # Workaround for missing reference errata in the boost property_tree module target_link_libraries(boost_property_tree INTERFACE Boost::any) target_link_libraries(boost_property_tree INTERFACE Boost::format) @@ -526,7 +522,8 @@ else() endif() add_subdirectory(submodules/rocksdb EXCLUDE_FROM_ALL) -include_directories(cpptoml/include) +# cpptoml +include_directories(submodules/cpptoml/include) # magic_enum include_directories(submodules/magic_enum/include) @@ -536,6 +533,16 @@ add_subdirectory(crypto/ed25519-donna) add_subdirectory(nano/ipc_flatbuffers_lib) add_subdirectory(nano/ipc_flatbuffers_test) +# fmt +add_subdirectory(submodules/fmt EXCLUDE_FROM_ALL) +include_directories(submodules/fmt/include) + +# spdlog +add_definitions(-DSPDLOG_FMT_EXTERNAL) +add_subdirectory(submodules/spdlog EXCLUDE_FROM_ALL) +include_directories(submodules/spdlog/include) + +# miniupnp set(UPNPC_BUILD_SHARED OFF CACHE BOOL "") @@ -750,6 +757,7 @@ endif() if(NANO_GUI OR RAIBLOCKS_GUI) install(FILES ${PROJECT_BINARY_DIR}/config-node.toml.sample DESTINATION .) install(FILES ${PROJECT_BINARY_DIR}/config-rpc.toml.sample DESTINATION .) + install(FILES ${PROJECT_BINARY_DIR}/config-log.toml.sample DESTINATION .) if(WIN32) set(PLATFORM_QT_PACKAGES WinExtras) else() @@ -760,7 +768,6 @@ if(NANO_GUI OR RAIBLOCKS_GUI) add_library(qt nano/qt/qt.cpp nano/qt/qt.hpp) include_directories(${CMAKE_SOURCE_DIR}/submodules) - include_directories(${CMAKE_SOURCE_DIR}/submodules/cpptoml/include) target_link_libraries( qt diff --git a/nano/core_test/CMakeLists.txt b/nano/core_test/CMakeLists.txt index 059d15acd1..623e6f2601 100644 --- a/nano/core_test/CMakeLists.txt +++ b/nano/core_test/CMakeLists.txt @@ -64,5 +64,4 @@ target_compile_definitions( target_link_libraries(core_test test_common) include_directories(${CMAKE_SOURCE_DIR}/submodules) -include_directories(${CMAKE_SOURCE_DIR}/submodules/cpptoml/include) include_directories(${CMAKE_SOURCE_DIR}/submodules/gtest/googletest/include) diff --git a/nano/core_test/block_store.cpp b/nano/core_test/block_store.cpp index 59c8092450..fe6d90c40c 100644 --- a/nano/core_test/block_store.cpp +++ b/nano/core_test/block_store.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include #include @@ -27,7 +27,7 @@ using namespace std::chrono_literals; TEST (block_store, construction) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); } @@ -102,7 +102,7 @@ TEST (block_store, sideband_serialization) TEST (block_store, add_item) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::block_builder builder; @@ -133,7 +133,7 @@ TEST (block_store, add_item) TEST (block_store, clear_successor) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::block_builder builder; @@ -180,7 +180,7 @@ TEST (block_store, clear_successor) TEST (block_store, add_nonempty_block) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::keypair key1; @@ -207,7 +207,7 @@ TEST (block_store, add_nonempty_block) TEST (block_store, add_two_items) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::keypair key1; @@ -253,7 +253,7 @@ TEST (block_store, add_two_items) TEST (block_store, add_receive) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::keypair key1; @@ -289,7 +289,7 @@ TEST (block_store, add_receive) TEST (block_store, add_pending) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::keypair key1; @@ -307,7 +307,7 @@ TEST (block_store, add_pending) TEST (block_store, pending_iterator) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); auto transaction (store->tx_begin_write ()); @@ -332,7 +332,7 @@ TEST (block_store, pending_iterator) */ TEST (block_store, pending_iterator_comparison) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::stats stats; @@ -375,7 +375,7 @@ TEST (block_store, pending_iterator_comparison) TEST (block_store, genesis) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::ledger_cache ledger_cache; @@ -403,7 +403,7 @@ TEST (block_store, genesis) TEST (block_store, empty_accounts) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); auto transaction (store->tx_begin_read ()); @@ -414,7 +414,7 @@ TEST (block_store, empty_accounts) TEST (block_store, one_block) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::block_builder builder; @@ -435,7 +435,7 @@ TEST (block_store, one_block) TEST (block_store, empty_bootstrap) { nano::test::system system{}; - nano::logger_mt logger; + nano::logger logger; nano::unchecked_map unchecked{ system.stats, false }; size_t count = 0; unchecked.for_each ([&count] (nano::unchecked_key const & key, nano::unchecked_info const & info) { @@ -446,7 +446,7 @@ TEST (block_store, empty_bootstrap) TEST (block_store, unchecked_begin_search) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::keypair key0; @@ -471,7 +471,7 @@ TEST (block_store, unchecked_begin_search) TEST (block_store, frontier_retrieval) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::account account1{}; @@ -486,7 +486,7 @@ TEST (block_store, frontier_retrieval) TEST (block_store, one_account) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::account account{}; @@ -513,7 +513,7 @@ TEST (block_store, one_account) TEST (block_store, two_block) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::block_builder builder; @@ -551,7 +551,7 @@ TEST (block_store, two_block) TEST (block_store, two_account) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::account account1 (1); @@ -593,7 +593,7 @@ TEST (block_store, two_account) TEST (block_store, latest_find) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::account account1 (1); @@ -627,7 +627,7 @@ TEST (mdb_block_store, supported_version_upgrades) } // Check that upgrading from an unsupported version is not supported auto path (nano::unique_path () / "data.ldb"); - nano::logger_mt logger; + nano::logger logger; { nano::store::lmdb::component store (logger, path, nano::dev::constants); nano::stats stats; @@ -671,10 +671,11 @@ TEST (mdb_block_store, bad_path) // Don't test this in rocksdb mode GTEST_SKIP (); } - nano::logger_mt logger; + nano::logger logger; try { auto path = nano::unique_path (); + path /= "data.ldb"; { std::ofstream stream (path.c_str ()); } @@ -696,14 +697,14 @@ TEST (block_store, DISABLED_already_open) // File can be shared std::ofstream file; file.open (path.string ().c_str ()); ASSERT_TRUE (file.is_open ()); - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, path, nano::dev::constants); ASSERT_TRUE (store->init_error ()); } TEST (block_store, roots) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::block_builder builder; @@ -745,7 +746,7 @@ TEST (block_store, roots) TEST (block_store, pending_exists) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::pending_key two (2, 0); @@ -758,7 +759,7 @@ TEST (block_store, pending_exists) TEST (block_store, latest_exists) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::account two (2); @@ -772,7 +773,7 @@ TEST (block_store, latest_exists) TEST (block_store, large_iteration) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); std::unordered_set accounts1; @@ -811,7 +812,7 @@ TEST (block_store, large_iteration) TEST (block_store, frontier) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); auto transaction (store->tx_begin_write ()); @@ -826,7 +827,7 @@ TEST (block_store, frontier) TEST (block_store, block_replace) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::block_builder builder; @@ -858,7 +859,7 @@ TEST (block_store, block_replace) TEST (block_store, block_count) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); { @@ -883,7 +884,7 @@ TEST (block_store, block_count) TEST (block_store, account_count) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); { @@ -899,7 +900,7 @@ TEST (block_store, account_count) TEST (block_store, cemented_count_cache) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); auto transaction (store->tx_begin_write ()); @@ -910,7 +911,7 @@ TEST (block_store, cemented_count_cache) TEST (block_store, block_random) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); { nano::ledger_cache ledger_cache; @@ -925,7 +926,7 @@ TEST (block_store, block_random) TEST (block_store, pruned_random) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::block_builder builder; @@ -952,7 +953,7 @@ TEST (block_store, pruned_random) TEST (block_store, state_block) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_FALSE (store->init_error ()); nano::keypair key1; @@ -999,7 +1000,7 @@ TEST (mdb_block_store, sideband_height) // Don't test this in rocksdb mode GTEST_SKIP (); } - nano::logger_mt logger; + nano::logger logger; nano::keypair key1; nano::keypair key2; nano::keypair key3; @@ -1152,7 +1153,7 @@ TEST (mdb_block_store, sideband_height) TEST (block_store, peers) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); @@ -1250,7 +1251,7 @@ TEST (block_store, endpoint_key_byte_order) TEST (block_store, online_weight) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_FALSE (store->init_error ()); { @@ -1285,7 +1286,7 @@ TEST (block_store, online_weight) TEST (block_store, pruned_blocks) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); @@ -1372,7 +1373,7 @@ TEST (mdb_block_store, upgrade_v21_v22) } auto path (nano::unique_path () / "data.ldb"); - nano::logger_mt logger; + nano::logger logger; nano::stats stats; auto const check_correct_state = [&] () { nano::store::lmdb::component store (logger, path, nano::dev::constants); @@ -1411,7 +1412,7 @@ TEST (rocksdb_block_store, upgrade_v21_v22) } auto const path = nano::unique_path () / "rocksdb"; - nano::logger_mt logger; + nano::logger logger; nano::stats stats; auto const check_correct_state = [&] () { nano::store::rocksdb::component store (logger, path, nano::dev::constants); @@ -1471,7 +1472,7 @@ TEST (mdb_block_store, upgrade_backup) }; { - nano::logger_mt logger; + nano::logger logger; nano::store::lmdb::component store (logger, path, nano::dev::constants); auto transaction (store.tx_begin_write ()); store.version.put (transaction, store.version_minimum); @@ -1479,7 +1480,7 @@ TEST (mdb_block_store, upgrade_backup) ASSERT_EQ (get_backup_path ().string (), dir.string ()); // Now do the upgrade and confirm that backup is saved - nano::logger_mt logger; + nano::logger logger; nano::store::lmdb::component store (logger, path, nano::dev::constants, nano::txn_tracking_config{}, std::chrono::seconds (5), nano::lmdb_config{}, true); ASSERT_FALSE (store.init_error ()); auto transaction (store.tx_begin_read ()); @@ -1496,7 +1497,7 @@ TEST (block_store, confirmation_height) GTEST_SKIP (); } auto path (nano::unique_path ()); - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, path, nano::dev::constants); nano::account account1{}; @@ -1542,7 +1543,7 @@ TEST (block_store, final_vote) GTEST_SKIP (); } auto path (nano::unique_path ()); - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, path, nano::dev::constants); { @@ -1567,7 +1568,7 @@ TEST (block_store, final_vote) TEST (block_store, incompatible_version) { auto path (nano::unique_path ()); - nano::logger_mt logger; + nano::logger logger; { auto store = nano::make_store (logger, path, nano::dev::constants); ASSERT_FALSE (store->init_error ()); @@ -1590,7 +1591,7 @@ TEST (block_store, incompatible_version) TEST (block_store, reset_renew_existing_transaction) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); @@ -1630,7 +1631,7 @@ TEST (block_store, reset_renew_existing_transaction) TEST (block_store, rocksdb_force_test_env_variable) { - nano::logger_mt logger; + nano::logger logger; // Set environment variable constexpr auto env_var = "TEST_USE_ROCKSDB"; @@ -1660,7 +1661,7 @@ TEST (rocksdb_block_store, tombstone_count) GTEST_SKIP (); } nano::test::system system; - nano::logger_mt logger; + nano::logger logger; auto store = std::make_unique (logger, nano::unique_path () / "rocksdb", nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::block_builder builder; diff --git a/nano/core_test/bootstrap.cpp b/nano/core_test/bootstrap.cpp index 963385d594..10198e45de 100644 --- a/nano/core_test/bootstrap.cpp +++ b/nano/core_test/bootstrap.cpp @@ -283,7 +283,7 @@ TEST (bulk_pull, count_limit) TEST (bootstrap_processor, DISABLED_process_none) { nano::test::system system (1); - auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work)); + auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work)); ASSERT_FALSE (node1->init_error ()); auto done (false); node1->bootstrap_initiator.bootstrap (system.nodes[0]->network.endpoint (), false); @@ -338,7 +338,7 @@ TEST (bootstrap_processor, process_two) ASSERT_NE (hash1, hash3); ASSERT_NE (hash2, hash3); - auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work)); + auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work)); ASSERT_FALSE (node1->init_error ()); node1->bootstrap_initiator.bootstrap (node0->network.endpoint (), false); ASSERT_NE (node1->latest (nano::dev::genesis_key.pub), node0->latest (nano::dev::genesis_key.pub)); @@ -384,7 +384,7 @@ TEST (bootstrap_processor, process_state) ASSERT_EQ (nano::process_result::progress, node0->process (*block2).code); config.peering_port = system.get_available_port (); - auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work, node_flags)); + auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work, node_flags)); ASSERT_EQ (node0->latest (nano::dev::genesis_key.pub), block2->hash ()); ASSERT_NE (node1->latest (nano::dev::genesis_key.pub), block2->hash ()); node1->bootstrap_initiator.bootstrap (node0->network.endpoint (), false); @@ -415,7 +415,7 @@ TEST (bootstrap_processor, process_new) nano::uint128_t balance2 (node1->balance (key2.pub)); ASSERT_TIMELY (10s, node1->block_confirmed (send->hash ()) && node1->block_confirmed (receive->hash ()) && node1->active.empty () && node2->active.empty ()); // All blocks should be propagated & confirmed - auto node3 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work)); + auto node3 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work)); ASSERT_FALSE (node3->init_error ()); node3->bootstrap_initiator.bootstrap (node1->network.endpoint (), false); ASSERT_TIMELY_EQ (10s, node3->balance (key2.pub), balance2); @@ -468,7 +468,7 @@ TEST (bootstrap_processor, pull_diamond) .work (*system.work.generate (send1->hash ())) .build_shared (); ASSERT_EQ (nano::process_result::progress, node0->process (*receive).code); - auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work)); + auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work)); ASSERT_FALSE (node1->init_error ()); node1->bootstrap_initiator.bootstrap (node0->network.endpoint (), false); ASSERT_TIMELY_EQ (10s, node1->balance (nano::dev::genesis_key.pub), 100); @@ -529,7 +529,7 @@ TEST (bootstrap_processor, DISABLED_push_diamond) config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; auto node0 (system.add_node (config)); nano::keypair key; - auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work)); + auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work)); ASSERT_FALSE (node1->init_error ()); auto wallet1 (node1->wallets.create (100)); wallet1->insert_adhoc (nano::dev::genesis_key.prv); @@ -662,7 +662,7 @@ TEST (bootstrap_processor, push_one) config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; auto node0 (system.add_node (config)); nano::keypair key1; - auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work)); + auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work)); auto wallet (node1->wallets.create (nano::random_wallet_id ())); ASSERT_NE (nullptr, wallet); wallet->insert_adhoc (nano::dev::genesis_key.prv); @@ -736,7 +736,7 @@ TEST (bootstrap_processor, lazy_hash) node0->block_processor.add (receive2); node0->block_processor.flush (); // Start lazy bootstrap with last block in chain known - auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work)); + auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work)); nano::test::establish_tcp (system, *node1, node0->network.endpoint ()); node1->bootstrap_initiator.bootstrap_lazy (receive2->hash (), true); { @@ -810,7 +810,7 @@ TEST (bootstrap_processor, lazy_hash_bootstrap_id) node0->block_processor.add (receive2); node0->block_processor.flush (); // Start lazy bootstrap with last block in chain known - auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work)); + auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work)); nano::test::establish_tcp (system, *node1, node0->network.endpoint ()); node1->bootstrap_initiator.bootstrap_lazy (receive2->hash (), true, "123456"); { @@ -944,7 +944,7 @@ TEST (bootstrap_processor, lazy_hash_pruning) ASSERT_EQ (5, node1->ledger.cache.block_count); ASSERT_EQ (5, node1->ledger.cache.cemented_count); // Pruning action - node1->ledger_pruning (2, false, false); + node1->ledger_pruning (2, false); ASSERT_EQ (9, node0->ledger.cache.block_count); ASSERT_EQ (0, node0->ledger.cache.pruned_count); ASSERT_EQ (5, node1->ledger.cache.block_count); @@ -1052,7 +1052,7 @@ TEST (bootstrap_processor, lazy_max_pull_count) node0->block_processor.add (change3); node0->block_processor.flush (); // Start lazy bootstrap with last block in chain known - auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work)); + auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work)); nano::test::establish_tcp (system, *node1, node0->network.endpoint ()); node1->bootstrap_initiator.bootstrap_lazy (change3->hash ()); // Check processed blocks @@ -1326,7 +1326,7 @@ TEST (bootstrap_processor, lazy_pruning_missing_block) ASSERT_EQ (5, node1->ledger.cache.block_count); ASSERT_EQ (5, node1->ledger.cache.cemented_count); // Pruning action - node1->ledger_pruning (2, false, false); + node1->ledger_pruning (2, false); ASSERT_EQ (5, node1->ledger.cache.block_count); ASSERT_EQ (1, node1->ledger.cache.pruned_count); ASSERT_TRUE (node1->ledger.block_or_pruned_exists (send1->hash ())); // true for pruned @@ -1390,7 +1390,7 @@ TEST (bootstrap_processor, lazy_cancel) .build_shared (); // Start lazy bootstrap with last block in chain known - auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work)); + auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work)); nano::test::establish_tcp (system, *node1, node0->network.endpoint ()); node1->bootstrap_initiator.bootstrap_lazy (send1->hash (), true); // Start "confirmed" block bootstrap { @@ -1465,7 +1465,7 @@ TEST (bootstrap_processor, wallet_lazy_frontier) node0->block_processor.add (receive2); node0->block_processor.flush (); // Start wallet lazy bootstrap - auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work)); + auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work)); nano::test::establish_tcp (system, *node1, node0->network.endpoint ()); auto wallet (node1->wallets.create (nano::random_wallet_id ())); ASSERT_NE (nullptr, wallet); @@ -1911,14 +1911,14 @@ TEST (frontier_req, confirmed_frontier) TEST (bulk, genesis) { nano::test::system system; - nano::node_config config (system.get_available_port (), system.logging); + nano::node_config config (system.get_available_port ()); config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; nano::node_flags node_flags; node_flags.disable_bootstrap_bulk_push_client = true; node_flags.disable_lazy_bootstrap = true; auto node1 = system.add_node (config, node_flags); system.wallet (0)->insert_adhoc (nano::dev::genesis_key.prv); - auto node2 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work)); + auto node2 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work)); ASSERT_FALSE (node2->init_error ()); nano::block_hash latest1 (node1->latest (nano::dev::genesis_key.pub)); nano::block_hash latest2 (node2->latest (nano::dev::genesis_key.pub)); @@ -1938,14 +1938,14 @@ TEST (bulk, genesis) TEST (bulk, offline_send) { nano::test::system system; - nano::node_config config (system.get_available_port (), system.logging); + nano::node_config config (system.get_available_port ()); config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; nano::node_flags node_flags; node_flags.disable_bootstrap_bulk_push_client = true; node_flags.disable_lazy_bootstrap = true; auto node1 = system.add_node (config, node_flags); system.wallet (0)->insert_adhoc (nano::dev::genesis_key.prv); - auto node2 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work)); + auto node2 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work)); ASSERT_FALSE (node2->init_error ()); node2->start (); system.nodes.push_back (node2); @@ -1980,7 +1980,7 @@ TEST (bulk, offline_send) TEST (bulk, DISABLED_genesis_pruning) { nano::test::system system; - nano::node_config config (system.get_available_port (), system.logging); + nano::node_config config (system.get_available_port ()); config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; config.enable_voting = false; // Remove after allowing pruned voting nano::node_flags node_flags; @@ -1991,7 +1991,7 @@ TEST (bulk, DISABLED_genesis_pruning) auto node1 = system.add_node (config, node_flags); system.wallet (0)->insert_adhoc (nano::dev::genesis_key.prv); node_flags.enable_pruning = false; - auto node2 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work, node_flags)); + auto node2 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work, node_flags)); ASSERT_FALSE (node2->init_error ()); nano::block_hash latest1 (node1->latest (nano::dev::genesis_key.pub)); nano::block_hash latest2 (node2->latest (nano::dev::genesis_key.pub)); @@ -2031,7 +2031,7 @@ TEST (bulk, DISABLED_genesis_pruning) election->force_confirm (); } ASSERT_TIMELY (2s, node1->active.empty () && node1->block_confirmed (send3->hash ())); - node1->ledger_pruning (2, false, false); + node1->ledger_pruning (2, false); ASSERT_EQ (2, node1->ledger.cache.pruned_count); ASSERT_EQ (4, node1->ledger.cache.block_count); ASSERT_TRUE (node1->ledger.block_or_pruned_exists (send1->hash ())); // true for pruned diff --git a/nano/core_test/bootstrap_ascending.cpp b/nano/core_test/bootstrap_ascending.cpp index f90e5d2a7c..49b8ed299d 100644 --- a/nano/core_test/bootstrap_ascending.cpp +++ b/nano/core_test/bootstrap_ascending.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -24,7 +25,7 @@ nano::block_hash random_hash () TEST (account_sets, construction) { nano::stats stats; - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_FALSE (store->init_error ()); nano::bootstrap_ascending::account_sets sets{ stats }; @@ -34,7 +35,7 @@ TEST (account_sets, empty_blocked) { nano::account account{ 1 }; nano::stats stats; - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_FALSE (store->init_error ()); nano::bootstrap_ascending::account_sets sets{ stats }; @@ -45,7 +46,7 @@ TEST (account_sets, block) { nano::account account{ 1 }; nano::stats stats; - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_FALSE (store->init_error ()); nano::bootstrap_ascending::account_sets sets{ stats }; @@ -57,7 +58,7 @@ TEST (account_sets, unblock) { nano::account account{ 1 }; nano::stats stats; - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_FALSE (store->init_error ()); nano::bootstrap_ascending::account_sets sets{ stats }; @@ -71,7 +72,7 @@ TEST (account_sets, priority_base) { nano::account account{ 1 }; nano::stats stats; - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_FALSE (store->init_error ()); nano::bootstrap_ascending::account_sets sets{ stats }; @@ -82,7 +83,7 @@ TEST (account_sets, priority_blocked) { nano::account account{ 1 }; nano::stats stats; - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_FALSE (store->init_error ()); nano::bootstrap_ascending::account_sets sets{ stats }; @@ -95,7 +96,7 @@ TEST (account_sets, priority_unblock_keep) { nano::account account{ 1 }; nano::stats stats; - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_FALSE (store->init_error ()); nano::bootstrap_ascending::account_sets sets{ stats }; @@ -113,7 +114,7 @@ TEST (account_sets, priority_up_down) { nano::account account{ 1 }; nano::stats stats; - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_FALSE (store->init_error ()); nano::bootstrap_ascending::account_sets sets{ stats }; @@ -128,7 +129,7 @@ TEST (account_sets, priority_down_sat) { nano::account account{ 1 }; nano::stats stats; - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_FALSE (store->init_error ()); nano::bootstrap_ascending::account_sets sets{ stats }; @@ -141,7 +142,7 @@ TEST (account_sets, saturate_priority) { nano::account account{ 1 }; nano::stats stats; - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_FALSE (store->init_error ()); nano::bootstrap_ascending::account_sets sets{ stats }; diff --git a/nano/core_test/confirmation_height.cpp b/nano/core_test/confirmation_height.cpp index f0db5471b6..2271e4985c 100644 --- a/nano/core_test/confirmation_height.cpp +++ b/nano/core_test/confirmation_height.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -1157,8 +1158,7 @@ TEST (confirmation_heightDeathTest, rollback_added_block) // valgrind can be noisy with death tests if (!nano::running_within_valgrind ()) { - nano::logger_mt logger; - nano::logging logging; + nano::logger logger; auto path (nano::unique_path ()); auto store = nano::make_store (logger, path, nano::dev::constants); ASSERT_TRUE (!store->init_error ()); @@ -1184,13 +1184,13 @@ TEST (confirmation_heightDeathTest, rollback_added_block) uint64_t batch_write_size = 2048; std::atomic stopped{ false }; nano::confirmation_height_unbounded unbounded_processor ( - ledger, write_database_queue, 10ms, logging, logger, stopped, batch_write_size, [] (auto const &) {}, [] (auto const &) {}, [] () { return 0; }); + ledger, write_database_queue, 10ms, logger, stopped, batch_write_size, [] (auto const &) {}, [] (auto const &) {}, [] () { return 0; }); // Processing a block which doesn't exist should bail ASSERT_DEATH_IF_SUPPORTED (unbounded_processor.process (send), ""); nano::confirmation_height_bounded bounded_processor ( - ledger, write_database_queue, 10ms, logging, logger, stopped, batch_write_size, [] (auto const &) {}, [] (auto const &) {}, [] () { return 0; }); + ledger, write_database_queue, 10ms, logger, stopped, batch_write_size, [] (auto const &) {}, [] (auto const &) {}, [] () { return 0; }); // Processing a block which doesn't exist should bail ASSERT_DEATH_IF_SUPPORTED (bounded_processor.process (send), ""); } @@ -1249,8 +1249,7 @@ TEST (confirmation_heightDeathTest, modified_chain) // valgrind can be noisy with death tests if (!nano::running_within_valgrind ()) { - nano::logging logging; - nano::logger_mt logger; + nano::logger logger; auto path (nano::unique_path ()); auto store = nano::make_store (logger, path, nano::dev::constants); ASSERT_TRUE (!store->init_error ()); @@ -1277,7 +1276,7 @@ TEST (confirmation_heightDeathTest, modified_chain) uint64_t batch_write_size = 2048; std::atomic stopped{ false }; nano::confirmation_height_bounded bounded_processor ( - ledger, write_database_queue, 10ms, logging, logger, stopped, batch_write_size, [] (auto const &) {}, [] (auto const &) {}, [] () { return 0; }); + ledger, write_database_queue, 10ms, logger, stopped, batch_write_size, [] (auto const &) {}, [] (auto const &) {}, [] () { return 0; }); { // This reads the blocks in the account, but prevents any writes from occuring yet @@ -1296,7 +1295,7 @@ TEST (confirmation_heightDeathTest, modified_chain) store->confirmation_height.put (store->tx_begin_write (), nano::dev::genesis->account (), { 1, nano::dev::genesis->hash () }); nano::confirmation_height_unbounded unbounded_processor ( - ledger, write_database_queue, 10ms, logging, logger, stopped, batch_write_size, [] (auto const &) {}, [] (auto const &) {}, [] () { return 0; }); + ledger, write_database_queue, 10ms, logger, stopped, batch_write_size, [] (auto const &) {}, [] (auto const &) {}, [] () { return 0; }); { // This reads the blocks in the account, but prevents any writes from occuring yet @@ -1327,8 +1326,7 @@ TEST (confirmation_heightDeathTest, modified_chain_account_removed) // valgrind can be noisy with death tests if (!nano::running_within_valgrind ()) { - nano::logging logging; - nano::logger_mt logger; + nano::logger logger; auto path (nano::unique_path ()); auto store = nano::make_store (logger, path, nano::dev::constants); ASSERT_TRUE (!store->init_error ()); @@ -1366,7 +1364,7 @@ TEST (confirmation_heightDeathTest, modified_chain_account_removed) uint64_t batch_write_size = 2048; std::atomic stopped{ false }; nano::confirmation_height_unbounded unbounded_processor ( - ledger, write_database_queue, 10ms, logging, logger, stopped, batch_write_size, [] (auto const &) {}, [] (auto const &) {}, [] () { return 0; }); + ledger, write_database_queue, 10ms, logger, stopped, batch_write_size, [] (auto const &) {}, [] (auto const &) {}, [] () { return 0; }); { // This reads the blocks in the account, but prevents any writes from occuring yet @@ -1386,7 +1384,7 @@ TEST (confirmation_heightDeathTest, modified_chain_account_removed) store->confirmation_height.put (store->tx_begin_write (), nano::dev::genesis->account (), { 1, nano::dev::genesis->hash () }); nano::confirmation_height_bounded bounded_processor ( - ledger, write_database_queue, 10ms, logging, logger, stopped, batch_write_size, [] (auto const &) {}, [] (auto const &) {}, [] () { return 0; }); + ledger, write_database_queue, 10ms, logger, stopped, batch_write_size, [] (auto const &) {}, [] (auto const &) {}, [] () { return 0; }); { // This reads the blocks in the account, but prevents any writes from occuring yet @@ -2039,7 +2037,7 @@ TEST (confirmation_height, unbounded_block_cache_iteration) // Don't test this in rocksdb mode GTEST_SKIP (); } - nano::logger_mt logger; + nano::logger logger; auto path (nano::unique_path ()); auto store = nano::make_store (logger, path, nano::dev::constants); ASSERT_TRUE (!store->init_error ()); @@ -2048,7 +2046,6 @@ TEST (confirmation_height, unbounded_block_cache_iteration) nano::write_database_queue write_database_queue (false); boost::latch initialized_latch{ 0 }; nano::work_pool pool{ nano::dev::network_params.network, std::numeric_limits::max () }; - nano::logging logging; nano::keypair key1; nano::block_builder builder; auto send = builder @@ -2074,7 +2071,7 @@ TEST (confirmation_height, unbounded_block_cache_iteration) ASSERT_EQ (nano::process_result::progress, ledger.process (transaction, *send1).code); } - nano::confirmation_height_processor confirmation_height_processor (ledger, write_database_queue, 10ms, logging, logger, initialized_latch, nano::confirmation_height_mode::unbounded); + nano::confirmation_height_processor confirmation_height_processor (ledger, write_database_queue, 10ms, logger, initialized_latch, nano::confirmation_height_mode::unbounded); nano::timer<> timer; timer.start (); { @@ -2103,8 +2100,7 @@ TEST (confirmation_height, unbounded_block_cache_iteration) TEST (confirmation_height, pruned_source) { - nano::logger_mt logger; - nano::logging logging; + nano::logger logger; auto path (nano::unique_path ()); auto store = nano::make_store (logger, path, nano::dev::constants); ASSERT_TRUE (!store->init_error ()); @@ -2178,7 +2174,7 @@ TEST (confirmation_height, pruned_source) std::atomic stopped{ false }; bool first_time{ true }; nano::confirmation_height_bounded bounded_processor ( - ledger, write_database_queue, 10ms, logging, logger, stopped, batch_write_size, [&] (auto const & cemented_blocks_a) { + ledger, write_database_queue, 10ms, logger, stopped, batch_write_size, [&] (auto const & cemented_blocks_a) { if (first_time) { // Prune the send diff --git a/nano/core_test/core_test_main.cc b/nano/core_test/core_test_main.cc index 6f5c4fc499..0abd1cdc3a 100644 --- a/nano/core_test/core_test_main.cc +++ b/nano/core_test/core_test_main.cc @@ -1,7 +1,7 @@ #include "gtest/gtest.h" +#include #include -#include #include #include @@ -19,13 +19,10 @@ void force_nano_dev_network (); GTEST_API_ int main (int argc, char ** argv) { - printf ("Running main() from core_test_main.cc\n"); + nano::logger::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; - // Setting up logging so that there aren't any piped to standard output. - nano::logging logging; - logging.init (nano::unique_path ()); testing::InitGoogleTest (&argc, argv); auto res = RUN_ALL_TESTS (); nano::test::cleanup_dev_directories_on_exit (); diff --git a/nano/core_test/ledger.cpp b/nano/core_test/ledger.cpp index 63e8682ed3..efe7a05ab0 100644 --- a/nano/core_test/ledger.cpp +++ b/nano/core_test/ledger.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -817,7 +818,7 @@ TEST (ledger, representation) TEST (ledger, double_open) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::stats stats; @@ -4161,7 +4162,7 @@ TEST (ledger, block_hash_account_conflict) TEST (ledger, could_fit) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::stats stats; @@ -4799,7 +4800,7 @@ TEST (ledger, dependents_confirmed) TEST (ledger, dependents_confirmed_pruning) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_FALSE (store->init_error ()); nano::stats stats; @@ -4989,7 +4990,7 @@ TEST (ledger, cache) TEST (ledger, pruning_action) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::stats stats; @@ -5073,7 +5074,7 @@ TEST (ledger, pruning_action) TEST (ledger, pruning_large_chain) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::stats stats; @@ -5128,7 +5129,7 @@ TEST (ledger, pruning_large_chain) TEST (ledger, pruning_source_rollback) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::stats stats; @@ -5216,7 +5217,7 @@ TEST (ledger, pruning_source_rollback) TEST (ledger, pruning_source_rollback_legacy) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::stats stats; @@ -5329,7 +5330,7 @@ TEST (ledger, pruning_source_rollback_legacy) TEST (ledger, pruning_process_error) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::stats stats; @@ -5376,7 +5377,7 @@ TEST (ledger, pruning_process_error) TEST (ledger, pruning_legacy_blocks) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::stats stats; @@ -5462,7 +5463,7 @@ TEST (ledger, pruning_legacy_blocks) TEST (ledger, pruning_safe_functions) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::stats stats; @@ -5523,7 +5524,7 @@ TEST (ledger, pruning_safe_functions) TEST (ledger, hash_root_random) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::stats stats; @@ -5587,7 +5588,7 @@ TEST (ledger, migrate_lmdb_to_rocksdb) { nano::test::system system{}; auto path = nano::unique_path (); - nano::logger_mt logger{}; + nano::logger logger; boost::asio::ip::address_v6 address (boost::asio::ip::make_address_v6 ("::ffff:127.0.0.1")); uint16_t port = 100; nano::store::lmdb::component store{ logger, path / "data.ldb", nano::dev::constants }; diff --git a/nano/core_test/logger.cpp b/nano/core_test/logger.cpp index 4a318b9cca..a282736058 100644 --- a/nano/core_test/logger.cpp +++ b/nano/core_test/logger.cpp @@ -1,5 +1,4 @@ -#include -#include + #include #include @@ -11,98 +10,7 @@ using namespace std::chrono_literals; -TEST (logger, changing_time_interval) -{ - auto path1 (nano::unique_path ()); - nano::logging logging; - logging.init (path1); - logging.min_time_between_log_output = 0ms; - nano::logger_mt my_logger (logging.min_time_between_log_output); - auto error (my_logger.try_log ("logger.changing_time_interval1")); - ASSERT_FALSE (error); - my_logger.min_log_delta = 20s; - error = my_logger.try_log ("logger, changing_time_interval2"); - ASSERT_TRUE (error); -} - -TEST (logger, try_log) +TEST (logger, basic) { - auto path1 (nano::unique_path ()); - std::stringstream ss; - nano::test::boost_log_cerr_redirect redirect_cerr (ss.rdbuf ()); - nano::logger_mt my_logger (100ms); - auto output1 = "logger.try_log1"; - auto error (my_logger.try_log (output1)); - ASSERT_FALSE (error); - auto output2 = "logger.try_log2"; - error = my_logger.try_log (output2); - ASSERT_TRUE (error); // Fails as it is occuring too soon - - // Sleep for a bit and then confirm - std::this_thread::sleep_for (100ms); - error = my_logger.try_log (output2); - ASSERT_FALSE (error); - - std::string str; - std::getline (ss, str, '\n'); - ASSERT_STREQ (str.c_str (), output1); - std::getline (ss, str, '\n'); - ASSERT_STREQ (str.c_str (), output2); -} - -TEST (logger, always_log) -{ - auto path1 (nano::unique_path ()); - std::stringstream ss; - nano::test::boost_log_cerr_redirect redirect_cerr (ss.rdbuf ()); - nano::logger_mt my_logger (20s); // Make time interval effectively unreachable - auto output1 = "logger.always_log1"; - auto error (my_logger.try_log (output1)); - ASSERT_FALSE (error); - - // Time is too soon after, so it won't be logged - auto output2 = "logger.always_log2"; - error = my_logger.try_log (output2); - ASSERT_TRUE (error); - - // Force it to be logged - my_logger.always_log (output2); - - std::string str; - std::getline (ss, str, '\n'); - ASSERT_STREQ (str.c_str (), output1); - std::getline (ss, str, '\n'); - ASSERT_STREQ (str.c_str (), output2); -} - -TEST (logger, stable_filename) -{ - auto path (nano::unique_path ()); - nano::logging logging; - - // Releasing allows setting up logging again - logging.release_file_sink (); - - logging.stable_log_filename = true; - logging.init (path); - - nano::logger_mt logger (logging.min_time_between_log_output); - logger.always_log ("stable1"); - - auto log_file = path / "log" / "node.log"; - -#if BOOST_VERSION >= 107000 - EXPECT_TRUE (std::filesystem::exists (log_file)); - // Try opening it again - logging.release_file_sink (); - logging.init (path); - logger.always_log ("stable2"); -#else - // When using Boost < 1.70 , behavior is reverted to not using the stable filename - EXPECT_FALSE (std::filesystem::exists (log_file)); -#endif - - // Reset the logger - logging.release_file_sink (); - nano::logging ().init (path); + // TODO } diff --git a/nano/core_test/message.cpp b/nano/core_test/message.cpp index 29e70e371c..c26e359a45 100644 --- a/nano/core_test/message.cpp +++ b/nano/core_test/message.cpp @@ -362,22 +362,6 @@ TEST (message, confirm_req_hash_batch_serialization_v2) ASSERT_TRUE (header.confirm_is_v2 ()); } -// this unit test checks that conversion of message_header to string works as expected -TEST (message, message_header_to_string) -{ - // calculate expected string - int maxver = nano::dev::network_params.network.protocol_version; - int minver = nano::dev::network_params.network.protocol_version_min; - std::stringstream ss; - ss << "NetID: 5241(dev), VerMaxUsingMin: " << maxver << "/" << maxver << "/" << minver << ", MsgType: 2(keepalive), Extensions: 0000"; - auto expected_str = ss.str (); - - // check expected vs real - nano::keepalive keepalive_msg{ nano::dev::network_params.network }; - std::string header_string = keepalive_msg.header.to_string (); - ASSERT_EQ (expected_str, header_string); -} - /** * Test that a confirm_ack can encode an empty hash set */ diff --git a/nano/core_test/network.cpp b/nano/core_test/network.cpp index 6804e7bb50..971263373c 100644 --- a/nano/core_test/network.cpp +++ b/nano/core_test/network.cpp @@ -58,7 +58,7 @@ TEST (network, construction_with_specified_port) { nano::test::system system{}; auto const port = system.get_available_port (/* do not allow 0 port */ false); - auto const node = system.add_node (nano::node_config{ port, system.logging }); + auto const node = system.add_node (nano::node_config{ port }); EXPECT_EQ (port, node->network.port); EXPECT_EQ (port, node->network.endpoint ().port ()); EXPECT_EQ (port, node->tcp_listener->endpoint ().port ()); @@ -79,7 +79,7 @@ TEST (network, send_node_id_handshake_tcp) nano::test::system system (1); auto node0 (system.nodes[0]); ASSERT_EQ (0, node0->network.size ()); - auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work)); + auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work)); node1->start (); system.nodes.push_back (node1); auto initial (node0->stats.count (nano::stat::type::message, nano::stat::detail::node_id_handshake, nano::stat::dir::in)); @@ -157,7 +157,7 @@ TEST (network, multi_keepalive) nano::test::system system (1); auto node0 = system.nodes[0]; ASSERT_EQ (0, node0->network.size ()); - auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work)); + auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work)); ASSERT_FALSE (node1->init_error ()); node1->start (); system.nodes.push_back (node1); @@ -165,7 +165,7 @@ TEST (network, multi_keepalive) ASSERT_EQ (0, node0->network.size ()); node1->network.tcp_channels.start_tcp (node0->network.endpoint ()); ASSERT_TIMELY (10s, node0->network.size () == 1 && node0->stats.count (nano::stat::type::message, nano::stat::detail::keepalive) >= 1); - auto node2 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work)); + auto node2 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work)); ASSERT_FALSE (node2->init_error ()); node2->start (); system.nodes.push_back (node2); @@ -749,7 +749,7 @@ TEST (network, peer_max_tcp_attempts) auto node = system.add_node (node_flags); for (auto i (0); i < node->network_params.network.max_peers_per_ip; ++i) { - auto node2 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work, node_flags)); + auto node2 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work, node_flags)); node2->start (); system.nodes.push_back (node2); // Start TCP attempt @@ -826,7 +826,7 @@ TEST (network, duplicate_revert_publish) nano::uint128_t digest; ASSERT_FALSE (node.network.publish_filter.apply (bytes.data (), bytes.size (), &digest)); ASSERT_TRUE (node.network.publish_filter.apply (bytes.data (), bytes.size ())); - auto other_node (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work)); + auto other_node (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work)); other_node->start (); system.nodes.push_back (other_node); auto channel = nano::test::establish_tcp (system, *other_node, node.network.endpoint ()); @@ -957,7 +957,7 @@ TEST (network, tcp_no_connect_excluded_peers) nano::test::system system (1); auto node0 (system.nodes[0]); ASSERT_EQ (0, node0->network.size ()); - auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work)); + auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work)); node1->start (); system.nodes.push_back (node1); auto endpoint1_tcp (nano::transport::map_endpoint_to_tcp (node1->network.endpoint ())); @@ -1058,7 +1058,7 @@ TEST (network, cleanup_purge) nano::test::system system (1); auto & node1 (*system.nodes[0]); - auto node2 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work)); + auto node2 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work)); node2->start (); system.nodes.push_back (node2); diff --git a/nano/core_test/node.cpp b/nano/core_test/node.cpp index 239d29d300..127ba46f90 100644 --- a/nano/core_test/node.cpp +++ b/nano/core_test/node.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -67,10 +68,8 @@ TEST (node, block_store_path_failure) nano::test::system system; auto service (std::make_shared ()); auto path (nano::unique_path ()); - nano::logging logging; - logging.init (path); nano::work_pool pool{ nano::dev::network_params.network, std::numeric_limits::max () }; - auto node (std::make_shared (*service, system.get_available_port (), path, logging, pool)); + auto node (std::make_shared (*service, system.get_available_port (), path, pool)); ASSERT_TRUE (node->wallets.items.empty ()); node->stop (); } @@ -100,7 +99,6 @@ TEST (node, password_fanout) auto path (nano::unique_path ()); nano::node_config config; config.peering_port = system.get_available_port (); - config.logging.init (path); nano::work_pool pool{ nano::dev::network_params.network, std::numeric_limits::max () }; config.password_fanout = 10; nano::node node (io_ctx, path, config, pool); @@ -266,7 +264,7 @@ TEST (node, node_receive_quorum) TEST (node, auto_bootstrap) { nano::test::system system; - nano::node_config config (system.get_available_port (), system.logging); + nano::node_config config (system.get_available_port ()); config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; nano::node_flags node_flags; node_flags.disable_bootstrap_bulk_push_client = true; @@ -278,7 +276,7 @@ TEST (node, auto_bootstrap) auto send1 (system.wallet (0)->send_action (nano::dev::genesis_key.pub, key2.pub, node0->config.receive_minimum.number ())); ASSERT_NE (nullptr, send1); ASSERT_TIMELY_EQ (10s, node0->balance (key2.pub), node0->config.receive_minimum.number ()); - auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work, node_flags)); + auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work, node_flags)); ASSERT_FALSE (node1->init_error ()); node1->start (); system.nodes.push_back (node1); @@ -298,7 +296,7 @@ TEST (node, auto_bootstrap) TEST (node, auto_bootstrap_reverse) { nano::test::system system; - nano::node_config config (system.get_available_port (), system.logging); + nano::node_config config (system.get_available_port ()); config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; nano::node_flags node_flags; node_flags.disable_bootstrap_bulk_push_client = true; @@ -307,7 +305,7 @@ TEST (node, auto_bootstrap_reverse) nano::keypair key2; system.wallet (0)->insert_adhoc (nano::dev::genesis_key.prv); system.wallet (0)->insert_adhoc (key2.prv); - auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work, node_flags)); + auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work, node_flags)); ASSERT_FALSE (node1->init_error ()); ASSERT_NE (nullptr, system.wallet (0)->send_action (nano::dev::genesis_key.pub, key2.pub, node0->config.receive_minimum.number ())); node1->start (); @@ -319,14 +317,14 @@ TEST (node, auto_bootstrap_reverse) TEST (node, auto_bootstrap_age) { nano::test::system system; - nano::node_config config (system.get_available_port (), system.logging); + nano::node_config config (system.get_available_port ()); config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; nano::node_flags node_flags; node_flags.disable_bootstrap_bulk_push_client = true; node_flags.disable_lazy_bootstrap = true; node_flags.bootstrap_interval = 1; auto node0 = system.add_node (config, node_flags); - auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work, node_flags)); + auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work, node_flags)); ASSERT_FALSE (node1->init_error ()); node1->start (); system.nodes.push_back (node1); @@ -416,7 +414,7 @@ TEST (node, search_receivable_multiple) TEST (node, search_receivable_confirmed) { nano::test::system system; - nano::node_config node_config (system.get_available_port (), system.logging); + nano::node_config node_config (system.get_available_port ()); node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; auto node = system.add_node (node_config); nano::keypair key2; @@ -450,12 +448,12 @@ TEST (node, search_receivable_confirmed) TEST (node, search_receivable_pruned) { nano::test::system system; - nano::node_config node_config (system.get_available_port (), system.logging); + nano::node_config node_config (system.get_available_port ()); node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; auto node1 = system.add_node (node_config); nano::node_flags node_flags; node_flags.enable_pruning = true; - nano::node_config config (system.get_available_port (), system.logging); + nano::node_config config (system.get_available_port ()); config.enable_voting = false; // Remove after allowing pruned voting auto node2 = system.add_node (config, node_flags); nano::keypair key2; @@ -549,9 +547,7 @@ TEST (node, confirm_locked) TEST (node_config, random_rep) { auto path (nano::unique_path ()); - nano::logging logging1; - logging1.init (path); - nano::node_config config1 (100, logging1); + nano::node_config config1 (100); auto rep (config1.random_representative ()); ASSERT_NE (config1.preconfigured_representatives.end (), std::find (config1.preconfigured_representatives.begin (), config1.preconfigured_representatives.end (), rep)); } @@ -761,7 +757,7 @@ TEST (node, fork_multi_flip) auto type = nano::transport::transport_type::tcp; nano::test::system system; nano::node_flags node_flags; - nano::node_config node_config (system.get_available_port (), system.logging); + nano::node_config node_config (system.get_available_port ()); node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; auto & node1 (*system.add_node (node_config, node_flags, type)); node_config.peering_port = system.get_available_port (); @@ -834,13 +830,13 @@ TEST (node, fork_bootstrap_flip) nano::test::system system; nano::test::system system0; nano::test::system system1; - nano::node_config config0{ system.get_available_port (), system0.logging }; + nano::node_config config0{ system.get_available_port () }; config0.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; nano::node_flags node_flags; node_flags.disable_bootstrap_bulk_push_client = true; node_flags.disable_lazy_bootstrap = true; auto & node1 = *system0.add_node (config0, node_flags); - nano::node_config config1 (system.get_available_port (), system1.logging); + nano::node_config config1 (system.get_available_port ()); auto & node2 = *system1.add_node (config1, node_flags); system0.wallet (0)->insert_adhoc (nano::dev::genesis_key.prv); nano::block_hash latest = node1.latest (nano::dev::genesis_key.pub); @@ -1246,7 +1242,7 @@ TEST (node, DISABLED_broadcast_elected) auto type = nano::transport::transport_type::tcp; nano::node_flags node_flags; nano::test::system system; - nano::node_config node_config (system.get_available_port (), system.logging); + nano::node_config node_config (system.get_available_port ()); node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; auto node0 = system.add_node (node_config, node_flags, type); node_config.peering_port = system.get_available_port (); @@ -1372,7 +1368,7 @@ TEST (node, DISABLED_broadcast_elected) TEST (node, rep_self_vote) { nano::test::system system; - nano::node_config node_config (system.get_available_port (), system.logging); + nano::node_config node_config (system.get_available_port ()); node_config.online_weight_minimum = std::numeric_limits::max (); node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; auto node0 = system.add_node (node_config); @@ -1470,10 +1466,10 @@ TEST (node, DISABLED_bootstrap_bulk_push) nano::test::system system; nano::test::system system0; nano::test::system system1; - nano::node_config config0 (system.get_available_port (), system0.logging); + nano::node_config config0 (system.get_available_port ()); config0.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; auto node0 (system0.add_node (config0)); - nano::node_config config1 (system.get_available_port (), system1.logging); + nano::node_config config1 (system.get_available_port ()); config1.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; auto node1 (system1.add_node (config1)); nano::keypair key0; @@ -1510,7 +1506,7 @@ TEST (node, DISABLED_bootstrap_bulk_push) TEST (node, bootstrap_fork_open) { nano::test::system system; - nano::node_config node_config (system.get_available_port (), system.logging); + nano::node_config node_config (system.get_available_port ()); auto node0 = system.add_node (node_config); node_config.peering_port = system.get_available_port (); auto node1 = system.add_node (node_config); @@ -1683,7 +1679,7 @@ TEST (node, rep_weight) { nano::test::system system; auto add_node = [&system] { - auto node = std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work); + auto node = std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work); node->start (); system.nodes.push_back (node); return node; @@ -1853,7 +1849,7 @@ TEST (node, rep_remove) ASSERT_TIMELY_EQ (5s, searching_node.rep_crawler.representative_count (), 0); // Add working node for genesis representative - auto node_genesis_rep = system.add_node (nano::node_config (system.get_available_port (), system.logging)); + auto node_genesis_rep = system.add_node (nano::node_config (system.get_available_port ())); system.wallet (1)->insert_adhoc (nano::dev::genesis_key.prv); auto channel_genesis_rep (searching_node.network.find_node_id (node_genesis_rep->get_node_id ())); ASSERT_NE (nullptr, channel_genesis_rep); @@ -1864,7 +1860,7 @@ TEST (node, rep_remove) ASSERT_TIMELY_EQ (10s, searching_node.rep_crawler.representative_count (), 1); // Start a node for Rep2 and wait until it is connected - auto node_rep2 (std::make_shared (system.io_ctx, nano::unique_path (), nano::node_config (system.get_available_port (), system.logging), system.work)); + auto node_rep2 (std::make_shared (system.io_ctx, nano::unique_path (), nano::node_config (system.get_available_port ()), system.work)); node_rep2->start (); searching_node.network.tcp_channels.start_tcp (node_rep2->network.endpoint ()); std::shared_ptr channel_rep2; @@ -1905,7 +1901,7 @@ TEST (node, no_voting) { nano::test::system system (1); auto & node0 (*system.nodes[0]); - nano::node_config node_config (system.get_available_port (), system.logging); + nano::node_config node_config (system.get_available_port ()); node_config.enable_voting = false; system.add_node (node_config); @@ -2229,7 +2225,7 @@ TEST (node, confirm_quorum) TEST (node, local_votes_cache) { nano::test::system system; - nano::node_config node_config (system.get_available_port (), system.logging); + nano::node_config node_config (system.get_available_port ()); node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; node_config.receive_minimum = nano::dev::constants.genesis_amount; auto & node (*system.add_node (node_config)); @@ -2317,7 +2313,7 @@ TEST (node, local_votes_cache) TEST (node, DISABLED_local_votes_cache_batch) { nano::test::system system; - nano::node_config node_config (system.get_available_port (), system.logging); + nano::node_config node_config (system.get_available_port ()); node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; auto & node (*system.add_node (node_config)); ASSERT_GE (node.network_params.voting.max_cache, 2); @@ -2390,7 +2386,7 @@ TEST (node, DISABLED_local_votes_cache_batch) TEST (node, local_votes_cache_generate_new_vote) { nano::test::system system; - nano::node_config node_config (system.get_available_port (), system.logging); + nano::node_config node_config (system.get_available_port ()); node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; auto & node (*system.add_node (node_config)); system.wallet (0)->insert_adhoc (nano::dev::genesis_key.prv); @@ -2443,7 +2439,7 @@ TEST (node, local_votes_cache_fork) node_flags.disable_lazy_bootstrap = true; node_flags.disable_legacy_bootstrap = true; node_flags.disable_wallet_bootstrap = true; - nano::node_config node_config (system.get_available_port (), system.logging); + nano::node_config node_config (system.get_available_port ()); node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; auto & node1 (*system.add_node (node_config, node_flags)); system.wallet (0)->insert_adhoc (nano::dev::genesis_key.prv); @@ -2694,7 +2690,7 @@ TEST (node, DISABLED_vote_by_hash_epoch_block_republish) TEST (node, epoch_conflict_confirm) { nano::test::system system; - nano::node_config node_config (system.get_available_port (), system.logging); + nano::node_config node_config (system.get_available_port ()); node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; auto & node0 = *system.add_node (node_config); node_config.peering_port = system.get_available_port (); @@ -3025,7 +3021,7 @@ TEST (node, block_processor_full) nano::node_flags node_flags; node_flags.force_use_write_database_queue = true; node_flags.block_processor_full_size = 3; - auto & node = *system.add_node (nano::node_config (system.get_available_port (), system.logging), node_flags); + auto & node = *system.add_node (nano::node_config (system.get_available_port ()), node_flags); nano::state_block_builder builder; auto send1 = builder.make_block () .account (nano::dev::genesis_key.pub) @@ -3070,7 +3066,7 @@ TEST (node, block_processor_half_full) nano::node_flags node_flags; node_flags.block_processor_full_size = 6; node_flags.force_use_write_database_queue = true; - auto & node = *system.add_node (nano::node_config (system.get_available_port (), system.logging), node_flags); + auto & node = *system.add_node (nano::node_config (system.get_available_port ()), node_flags); nano::state_block_builder builder; auto send1 = builder.make_block () .account (nano::dev::genesis_key.pub) @@ -3162,7 +3158,7 @@ TEST (node, peers) auto node1 (system.nodes[0]); ASSERT_TRUE (node1->network.empty ()); - auto node2 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work)); + auto node2 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work)); system.nodes.push_back (node2); auto endpoint = node1->network.endpoint (); @@ -3212,7 +3208,7 @@ TEST (node, peer_cache_restart) nano::endpoint_key endpoint_key{ endpoint.address ().to_v6 ().to_bytes (), endpoint.port () }; auto path (nano::unique_path ()); { - auto node2 (std::make_shared (system.io_ctx, system.get_available_port (), path, system.logging, system.work)); + auto node2 (std::make_shared (system.io_ctx, system.get_available_port (), path, system.work)); system.nodes.push_back (node2); auto & store = node2->store; { @@ -3232,7 +3228,7 @@ TEST (node, peer_cache_restart) { nano::node_flags node_flags; node_flags.read_only = true; - auto node3 (std::make_shared (system.io_ctx, system.get_available_port (), path, system.logging, system.work, node_flags)); + auto node3 (std::make_shared (system.io_ctx, system.get_available_port (), path, system.work, node_flags)); system.nodes.push_back (node3); // Check cached peers after restart node3->network.start (); @@ -3300,7 +3296,7 @@ TEST (node, dont_write_lock_node) std::promise write_lock_held_promise; std::promise finished_promise; std::thread ([&path, &write_lock_held_promise, &finished_promise] () { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, path, nano::dev::constants, false, true); { nano::ledger_cache ledger_cache; @@ -3337,7 +3333,7 @@ TEST (node, bidirectional_tcp) node_flags.disable_legacy_bootstrap = true; node_flags.disable_lazy_bootstrap = true; node_flags.disable_wallet_bootstrap = true; - nano::node_config node_config (system.get_available_port (), system.logging); + nano::node_config node_config (system.get_available_port ()); node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; auto node1 = system.add_node (node_config, node_flags); node_config.peering_port = system.get_available_port (); @@ -3535,7 +3531,7 @@ TEST (node, rollback_vote_self) TEST (node, rollback_gap_source) { nano::test::system system; - nano::node_config node_config (system.get_available_port (), system.logging); + nano::node_config node_config (system.get_available_port ()); node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; auto & node = *system.add_node (node_config); nano::state_block_builder builder; @@ -3603,7 +3599,7 @@ TEST (node, rollback_gap_source) TEST (node, dependency_graph) { nano::test::system system; - nano::node_config config (system.get_available_port (), system.logging); + nano::node_config config (system.get_available_port ()); config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; auto & node = *system.add_node (config); @@ -3801,7 +3797,7 @@ TEST (node, dependency_graph) TEST (node, dependency_graph_frontier) { nano::test::system system; - nano::node_config config (system.get_available_port (), system.logging); + nano::node_config config (system.get_available_port ()); config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; auto & node1 = *system.add_node (config); config.peering_port = system.get_available_port (); @@ -3968,9 +3964,9 @@ namespace nano TEST (node, deferred_dependent_elections) { nano::test::system system; - nano::node_config node_config_1{ system.get_available_port (), system.logging }; + nano::node_config node_config_1{ system.get_available_port () }; node_config_1.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; - nano::node_config node_config_2{ system.get_available_port (), system.logging }; + nano::node_config node_config_2{ system.get_available_port () }; node_config_2.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; nano::node_flags flags; flags.disable_request_loop = true; @@ -4133,7 +4129,7 @@ TEST (node, pruning_automatic) { nano::test::system system{}; - nano::node_config node_config{ system.get_available_port (), system.logging }; + nano::node_config node_config{ system.get_available_port () }; // TODO: remove after allowing pruned voting node_config.enable_voting = false; node_config.max_pruning_age = std::chrono::seconds (1); @@ -4188,7 +4184,7 @@ TEST (node, pruning_age) { nano::test::system system{}; - nano::node_config node_config{ system.get_available_port (), system.logging }; + nano::node_config node_config{ system.get_available_port () }; // TODO: remove after allowing pruned voting node_config.enable_voting = false; @@ -4230,13 +4226,13 @@ TEST (node, pruning_age) ASSERT_EQ (3, node1.ledger.cache.block_count); // Pruning with default age 1 day - node1.ledger_pruning (1, true, false); + node1.ledger_pruning (1, true); ASSERT_EQ (0, node1.ledger.cache.pruned_count); ASSERT_EQ (3, node1.ledger.cache.block_count); // Pruning with max age 0 node1.config.max_pruning_age = std::chrono::seconds{ 0 }; - node1.ledger_pruning (1, true, false); + node1.ledger_pruning (1, true); ASSERT_EQ (1, node1.ledger.cache.pruned_count); ASSERT_EQ (3, node1.ledger.cache.block_count); @@ -4251,7 +4247,7 @@ TEST (node, pruning_depth) { nano::test::system system{}; - nano::node_config node_config{ system.get_available_port (), system.logging }; + nano::node_config node_config{ system.get_available_port () }; // TODO: remove after allowing pruned voting node_config.enable_voting = false; @@ -4293,13 +4289,13 @@ TEST (node, pruning_depth) ASSERT_EQ (3, node1.ledger.cache.block_count); // Pruning with default depth (unlimited) - node1.ledger_pruning (1, true, false); + node1.ledger_pruning (1, true); ASSERT_EQ (0, node1.ledger.cache.pruned_count); ASSERT_EQ (3, node1.ledger.cache.block_count); // Pruning with max depth 1 node1.config.max_pruning_depth = 1; - node1.ledger_pruning (1, true, false); + node1.ledger_pruning (1, true); ASSERT_EQ (1, node1.ledger.cache.pruned_count); ASSERT_EQ (3, node1.ledger.cache.block_count); @@ -4310,27 +4306,27 @@ TEST (node, pruning_depth) TEST (node_config, node_id_private_key_persistence) { - nano::logger_mt logger; + nano::test::system system; // create the directory and the file auto path = nano::unique_path (); - ASSERT_TRUE (std::filesystem::create_directories (path)); + ASSERT_TRUE (std::filesystem::exists (path)); auto priv_key_filename = path / "node_id_private.key"; // check that the key generated is random when the key does not exist - nano::keypair kp1 = nano::load_or_create_node_id (path, logger); + nano::keypair kp1 = nano::load_or_create_node_id (path); std::filesystem::remove (priv_key_filename); - nano::keypair kp2 = nano::load_or_create_node_id (path, logger); + nano::keypair kp2 = nano::load_or_create_node_id (path); ASSERT_NE (kp1.prv, kp2.prv); // check that the key persists - nano::keypair kp3 = nano::load_or_create_node_id (path, logger); + nano::keypair kp3 = nano::load_or_create_node_id (path); ASSERT_EQ (kp2.prv, kp3.prv); // write the key file manually and check that right key is loaded std::ofstream ofs (priv_key_filename.string (), std::ofstream::out | std::ofstream::trunc); ofs << "3F28D035B8AA75EA53DF753BFD065CF6138E742971B2C99B84FD8FE328FED2D9" << std::flush; ofs.close (); - nano::keypair kp4 = nano::load_or_create_node_id (path, logger); + nano::keypair kp4 = nano::load_or_create_node_id (path); ASSERT_EQ (kp4.prv, nano::keypair ("3F28D035B8AA75EA53DF753BFD065CF6138E742971B2C99B84FD8FE328FED2D9").prv); } diff --git a/nano/core_test/processor_service.cpp b/nano/core_test/processor_service.cpp index 42893a97d0..406e2ed47d 100644 --- a/nano/core_test/processor_service.cpp +++ b/nano/core_test/processor_service.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -10,7 +11,7 @@ TEST (processor_service, bad_send_signature) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_FALSE (store->init_error ()); nano::stats stats; @@ -36,7 +37,7 @@ TEST (processor_service, bad_send_signature) TEST (processor_service, bad_receive_signature) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_FALSE (store->init_error ()); nano::stats stats; diff --git a/nano/core_test/toml.cpp b/nano/core_test/toml.cpp index 9d96fd367f..b28c875750 100644 --- a/nano/core_test/toml.cpp +++ b/nano/core_test/toml.cpp @@ -196,35 +196,6 @@ TEST (toml, daemon_config_deserialize_defaults) ASSERT_EQ (conf.node.backlog_scan_batch_size, defaults.node.backlog_scan_batch_size); ASSERT_EQ (conf.node.backlog_scan_frequency, defaults.node.backlog_scan_frequency); - ASSERT_EQ (conf.node.logging.bulk_pull_logging_value, defaults.node.logging.bulk_pull_logging_value); - ASSERT_EQ (conf.node.logging.flush, defaults.node.logging.flush); - ASSERT_EQ (conf.node.logging.insufficient_work_logging_value, defaults.node.logging.insufficient_work_logging_value); - ASSERT_EQ (conf.node.logging.ledger_logging_value, defaults.node.logging.ledger_logging_value); - ASSERT_EQ (conf.node.logging.ledger_duplicate_logging_value, defaults.node.logging.ledger_duplicate_logging_value); - ASSERT_EQ (conf.node.logging.log_ipc_value, defaults.node.logging.log_ipc_value); - ASSERT_EQ (conf.node.logging.log_to_cerr_value, defaults.node.logging.log_to_cerr_value); - ASSERT_EQ (conf.node.logging.max_size, defaults.node.logging.max_size); - ASSERT_EQ (conf.node.logging.min_time_between_log_output.count (), defaults.node.logging.min_time_between_log_output.count ()); - ASSERT_EQ (conf.node.logging.network_logging_value, defaults.node.logging.network_logging_value); - ASSERT_EQ (conf.node.logging.network_keepalive_logging_value, defaults.node.logging.network_keepalive_logging_value); - ASSERT_EQ (conf.node.logging.network_message_logging_value, defaults.node.logging.network_message_logging_value); - ASSERT_EQ (conf.node.logging.network_node_id_handshake_logging_value, defaults.node.logging.network_node_id_handshake_logging_value); - ASSERT_EQ (conf.node.logging.network_packet_logging_value, defaults.node.logging.network_packet_logging_value); - ASSERT_EQ (conf.node.logging.network_publish_logging_value, defaults.node.logging.network_publish_logging_value); - ASSERT_EQ (conf.node.logging.network_timeout_logging_value, defaults.node.logging.network_timeout_logging_value); - ASSERT_EQ (conf.node.logging.node_lifetime_tracing_value, defaults.node.logging.node_lifetime_tracing_value); - ASSERT_EQ (conf.node.logging.network_telemetry_logging_value, defaults.node.logging.network_telemetry_logging_value); - ASSERT_EQ (conf.node.logging.network_rejected_logging_value, defaults.node.logging.network_rejected_logging_value); - ASSERT_EQ (conf.node.logging.rotation_size, defaults.node.logging.rotation_size); - ASSERT_EQ (conf.node.logging.single_line_record_value, defaults.node.logging.single_line_record_value); - ASSERT_EQ (conf.node.logging.stable_log_filename, defaults.node.logging.stable_log_filename); - ASSERT_EQ (conf.node.logging.timing_logging_value, defaults.node.logging.timing_logging_value); - ASSERT_EQ (conf.node.logging.active_update_value, defaults.node.logging.active_update_value); - ASSERT_EQ (conf.node.logging.upnp_details_logging_value, defaults.node.logging.upnp_details_logging_value); - ASSERT_EQ (conf.node.logging.vote_logging_value, defaults.node.logging.vote_logging_value); - ASSERT_EQ (conf.node.logging.rep_crawler_logging_value, defaults.node.logging.rep_crawler_logging_value); - ASSERT_EQ (conf.node.logging.work_generation_time_value, defaults.node.logging.work_generation_time_value); - ASSERT_EQ (conf.node.websocket_config.enabled, defaults.node.websocket_config.enabled); ASSERT_EQ (conf.node.websocket_config.address, defaults.node.websocket_config.address); ASSERT_EQ (conf.node.websocket_config.port, defaults.node.websocket_config.port); @@ -642,35 +613,6 @@ TEST (toml, daemon_config_deserialize_no_defaults) ASSERT_NE (conf.node.backlog_scan_batch_size, defaults.node.backlog_scan_batch_size); ASSERT_NE (conf.node.backlog_scan_frequency, defaults.node.backlog_scan_frequency); - ASSERT_NE (conf.node.logging.bulk_pull_logging_value, defaults.node.logging.bulk_pull_logging_value); - ASSERT_NE (conf.node.logging.flush, defaults.node.logging.flush); - ASSERT_NE (conf.node.logging.insufficient_work_logging_value, defaults.node.logging.insufficient_work_logging_value); - ASSERT_NE (conf.node.logging.ledger_logging_value, defaults.node.logging.ledger_logging_value); - ASSERT_NE (conf.node.logging.ledger_duplicate_logging_value, defaults.node.logging.ledger_duplicate_logging_value); - ASSERT_NE (conf.node.logging.log_ipc_value, defaults.node.logging.log_ipc_value); - ASSERT_NE (conf.node.logging.log_to_cerr_value, defaults.node.logging.log_to_cerr_value); - ASSERT_NE (conf.node.logging.max_size, defaults.node.logging.max_size); - ASSERT_NE (conf.node.logging.min_time_between_log_output.count (), defaults.node.logging.min_time_between_log_output.count ()); - ASSERT_NE (conf.node.logging.network_logging_value, defaults.node.logging.network_logging_value); - ASSERT_NE (conf.node.logging.network_keepalive_logging_value, defaults.node.logging.network_keepalive_logging_value); - ASSERT_NE (conf.node.logging.network_message_logging_value, defaults.node.logging.network_message_logging_value); - ASSERT_NE (conf.node.logging.network_node_id_handshake_logging_value, defaults.node.logging.network_node_id_handshake_logging_value); - ASSERT_NE (conf.node.logging.network_telemetry_logging_value, defaults.node.logging.network_telemetry_logging_value); - ASSERT_NE (conf.node.logging.network_rejected_logging_value, defaults.node.logging.network_rejected_logging_value); - ASSERT_NE (conf.node.logging.network_packet_logging_value, defaults.node.logging.network_packet_logging_value); - ASSERT_NE (conf.node.logging.network_publish_logging_value, defaults.node.logging.network_publish_logging_value); - ASSERT_NE (conf.node.logging.network_timeout_logging_value, defaults.node.logging.network_timeout_logging_value); - ASSERT_NE (conf.node.logging.node_lifetime_tracing_value, defaults.node.logging.node_lifetime_tracing_value); - ASSERT_NE (conf.node.logging.rotation_size, defaults.node.logging.rotation_size); - ASSERT_NE (conf.node.logging.single_line_record_value, defaults.node.logging.single_line_record_value); - ASSERT_NE (conf.node.logging.stable_log_filename, defaults.node.logging.stable_log_filename); - ASSERT_NE (conf.node.logging.timing_logging_value, defaults.node.logging.timing_logging_value); - ASSERT_NE (conf.node.logging.active_update_value, defaults.node.logging.active_update_value); - ASSERT_NE (conf.node.logging.upnp_details_logging_value, defaults.node.logging.upnp_details_logging_value); - ASSERT_NE (conf.node.logging.vote_logging_value, defaults.node.logging.vote_logging_value); - ASSERT_NE (conf.node.logging.rep_crawler_logging_value, defaults.node.logging.rep_crawler_logging_value); - ASSERT_NE (conf.node.logging.work_generation_time_value, defaults.node.logging.work_generation_time_value); - ASSERT_NE (conf.node.websocket_config.enabled, defaults.node.websocket_config.enabled); ASSERT_NE (conf.node.websocket_config.address, defaults.node.websocket_config.address); ASSERT_NE (conf.node.websocket_config.port, defaults.node.websocket_config.port); @@ -975,3 +917,92 @@ TEST (toml, tls_config_defaults) ASSERT_EQ (conf.server_key_passphrase, defaults.server_key_passphrase); ASSERT_EQ (conf.server_dh_path, defaults.server_dh_path); } + +TEST (toml, log_config_defaults) +{ + std::stringstream ss; + + // A config with no values + ss << R"toml()toml"; + + nano::tomlconfig toml; + toml.read (ss); + nano::log_config confg{}; + nano::log_config defaults{}; + confg.deserialize_toml (toml); + + ASSERT_FALSE (toml.get_error ()) << toml.get_error ().get_message (); + + ASSERT_EQ (confg.default_level, defaults.default_level); + ASSERT_EQ (confg.flush_level, defaults.flush_level); + ASSERT_EQ (confg.levels, defaults.levels); + ASSERT_EQ (confg.console.enable, defaults.console.enable); + ASSERT_EQ (confg.console.colors, defaults.console.colors); + ASSERT_EQ (confg.console.to_cerr, defaults.console.to_cerr); + ASSERT_EQ (confg.file.enable, defaults.file.enable); + ASSERT_EQ (confg.file.max_size, defaults.file.max_size); + ASSERT_EQ (confg.file.rotation_count, defaults.file.rotation_count); +} + +TEST (toml, log_config_no_defaults) +{ + std::stringstream ss; + + // A config file with values that differs from defaults + ss << R"toml( + [log] + default_level = "trace" + + [log.console] + colors = false + enable = false + to_cerr = true + + [log.file] + enable = false + max_size = 999 + rotation_count = 999 + + [log.levels] + active_transactions = "trace" + blockprocessor = "trace" + )toml"; + + nano::tomlconfig toml; + toml.read (ss); + nano::log_config confg{}; + nano::log_config defaults{}; + confg.deserialize_toml (toml); + + ASSERT_FALSE (toml.get_error ()) << toml.get_error ().get_message (); + + ASSERT_NE (confg.default_level, defaults.default_level); + ASSERT_NE (confg.levels, defaults.levels); + ASSERT_NE (confg.console.enable, defaults.console.enable); + ASSERT_NE (confg.console.colors, defaults.console.colors); + ASSERT_NE (confg.console.to_cerr, defaults.console.to_cerr); + ASSERT_NE (confg.file.enable, defaults.file.enable); + ASSERT_NE (confg.file.max_size, defaults.file.max_size); + ASSERT_NE (confg.file.rotation_count, defaults.file.rotation_count); +} + +TEST (toml, log_config_no_required) +{ + std::stringstream ss; + + // A config with no values, only categories + ss << R"toml( + [log] + [log.console] + [log.file] + [log.levels] + )toml"; + + nano::tomlconfig toml; + toml.read (ss); + nano::log_config confg{}; + nano::log_config defaults{}; + confg.deserialize_toml (toml); + + ASSERT_FALSE (toml.get_error ()) << toml.get_error ().get_message (); +} \ No newline at end of file diff --git a/nano/core_test/unchecked_map.cpp b/nano/core_test/unchecked_map.cpp index c9efc500a3..6823c1f72d 100644 --- a/nano/core_test/unchecked_map.cpp +++ b/nano/core_test/unchecked_map.cpp @@ -1,5 +1,4 @@ #include -#include #include #include #include diff --git a/nano/core_test/wallet.cpp b/nano/core_test/wallet.cpp index b750538b12..c27749522f 100644 --- a/nano/core_test/wallet.cpp +++ b/nano/core_test/wallet.cpp @@ -12,7 +12,7 @@ unsigned constexpr nano::wallet_store::version_current; TEST (wallet, no_special_keys_accounts) { bool init; - nano::store::lmdb::env env (init, nano::unique_path ()); + nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb"); ASSERT_FALSE (init); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; @@ -33,7 +33,7 @@ TEST (wallet, no_special_keys_accounts) TEST (wallet, no_key) { bool init; - nano::store::lmdb::env env (init, nano::unique_path ()); + nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb"); ASSERT_FALSE (init); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; @@ -48,7 +48,7 @@ TEST (wallet, no_key) TEST (wallet, fetch_locked) { bool init; - nano::store::lmdb::env env (init, nano::unique_path ()); + nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb"); ASSERT_FALSE (init); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; @@ -70,7 +70,7 @@ TEST (wallet, fetch_locked) TEST (wallet, retrieval) { bool init; - nano::store::lmdb::env env (init, nano::unique_path ()); + nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb"); ASSERT_FALSE (init); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; @@ -92,7 +92,7 @@ TEST (wallet, retrieval) TEST (wallet, empty_iteration) { bool init; - nano::store::lmdb::env env (init, nano::unique_path ()); + nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb"); ASSERT_FALSE (init); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; @@ -106,7 +106,7 @@ TEST (wallet, empty_iteration) TEST (wallet, one_item_iteration) { bool init; - nano::store::lmdb::env env (init, nano::unique_path ()); + nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb"); ASSERT_FALSE (init); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; @@ -128,7 +128,7 @@ TEST (wallet, one_item_iteration) TEST (wallet, two_item_iteration) { bool init; - nano::store::lmdb::env env (init, nano::unique_path ()); + nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb"); ASSERT_FALSE (init); nano::keypair key1; nano::keypair key2; @@ -267,7 +267,7 @@ TEST (wallet, spend_no_previous) TEST (wallet, find_none) { bool init; - nano::store::lmdb::env env (init, nano::unique_path ()); + nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb"); ASSERT_FALSE (init); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; @@ -280,7 +280,7 @@ TEST (wallet, find_none) TEST (wallet, find_existing) { bool init; - nano::store::lmdb::env env (init, nano::unique_path ()); + nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb"); ASSERT_FALSE (init); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; @@ -299,7 +299,7 @@ TEST (wallet, find_existing) TEST (wallet, rekey) { bool init; - nano::store::lmdb::env env (init, nano::unique_path ()); + nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb"); ASSERT_FALSE (init); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; @@ -371,7 +371,7 @@ TEST (account, encode_fail) TEST (wallet, hash_password) { bool init; - nano::store::lmdb::env env (init, nano::unique_path ()); + nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb"); ASSERT_FALSE (init); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; @@ -420,7 +420,7 @@ TEST (fan, change) TEST (wallet, reopen_default_password) { bool init; - nano::store::lmdb::env env (init, nano::unique_path ()); + nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb"); auto transaction (env.tx_begin_write ()); ASSERT_FALSE (init); nano::kdf kdf{ nano::dev::network_params.kdf_work }; @@ -456,7 +456,7 @@ TEST (wallet, reopen_default_password) TEST (wallet, representative) { auto error (false); - nano::store::lmdb::env env (error, nano::unique_path ()); + nano::store::lmdb::env env (error, nano::unique_path () / "wallet.ldb"); ASSERT_FALSE (error); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; @@ -477,7 +477,7 @@ TEST (wallet, representative) TEST (wallet, serialize_json_empty) { auto error (false); - nano::store::lmdb::env env (error, nano::unique_path ()); + nano::store::lmdb::env env (error, nano::unique_path () / "wallet.ldb"); ASSERT_FALSE (error); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; @@ -502,7 +502,7 @@ TEST (wallet, serialize_json_empty) TEST (wallet, serialize_json_one) { auto error (false); - nano::store::lmdb::env env (error, nano::unique_path ()); + nano::store::lmdb::env env (error, nano::unique_path () / "wallet.ldb"); ASSERT_FALSE (error); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; @@ -531,7 +531,7 @@ TEST (wallet, serialize_json_one) TEST (wallet, serialize_json_password) { auto error (false); - nano::store::lmdb::env env (error, nano::unique_path ()); + nano::store::lmdb::env env (error, nano::unique_path () / "wallet.ldb"); ASSERT_FALSE (error); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; @@ -564,7 +564,7 @@ TEST (wallet, serialize_json_password) TEST (wallet_store, move) { auto error (false); - nano::store::lmdb::env env (error, nano::unique_path ()); + nano::store::lmdb::env env (error, nano::unique_path () / "wallet.ldb"); ASSERT_FALSE (error); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; @@ -722,7 +722,7 @@ TEST (wallet, insert_locked) TEST (wallet, deterministic_keys) { bool init; - nano::store::lmdb::env env (init, nano::unique_path ()); + nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb"); ASSERT_FALSE (init); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; @@ -765,7 +765,7 @@ TEST (wallet, deterministic_keys) TEST (wallet, reseed) { bool init; - nano::store::lmdb::env env (init, nano::unique_path ()); + nano::store::lmdb::env env (init, nano::unique_path () / "wallet.ldb"); ASSERT_FALSE (init); auto transaction (env.tx_begin_write ()); nano::kdf kdf{ nano::dev::network_params.kdf_work }; diff --git a/nano/core_test/work_pool.cpp b/nano/core_test/work_pool.cpp index 99fafac728..59ada8938c 100644 --- a/nano/core_test/work_pool.cpp +++ b/nano/core_test/work_pool.cpp @@ -1,9 +1,8 @@ #include #include -#include +#include #include #include -#include #include #include #include @@ -90,9 +89,7 @@ TEST (work, cancel_many) TEST (work, opencl) { - nano::logging logging; - logging.init (nano::unique_path ()); - nano::logger_mt logger; + nano::logger logger; bool error (false); nano::opencl_environment environment (error); ASSERT_TRUE (!error || !nano::opencl_loaded); diff --git a/nano/lib/CMakeLists.txt b/nano/lib/CMakeLists.txt index d56f55e8f7..84fa0e1a6a 100644 --- a/nano/lib/CMakeLists.txt +++ b/nano/lib/CMakeLists.txt @@ -50,7 +50,10 @@ add_library( lmdbconfig.cpp locks.hpp locks.cpp - logger_mt.hpp + logging.hpp + logging.cpp + logging_enums.hpp + logging_enums.cpp memory.hpp memory.cpp numbers.hpp @@ -100,7 +103,6 @@ add_library( work.cpp) include_directories(${CMAKE_SOURCE_DIR}/submodules) -include_directories(${CMAKE_SOURCE_DIR}/submodules/cpptoml/include) include_directories( ${CMAKE_SOURCE_DIR}/submodules/nano-pow-server/deps/cpptoml/include) @@ -111,12 +113,12 @@ target_link_libraries( blake2 ${CRYPTOPP_LIBRARY} ${CMAKE_DL_LIBS} + fmt::fmt + spdlog::spdlog Boost::iostreams Boost::asio Boost::circular_buffer Boost::dll - Boost::log_setup - Boost::log Boost::multiprecision Boost::program_options Boost::stacktrace) diff --git a/nano/lib/blocks.cpp b/nano/lib/blocks.cpp index 15881b3e50..7a77dfc3b7 100644 --- a/nano/lib/blocks.cpp +++ b/nano/lib/blocks.cpp @@ -11,6 +11,7 @@ #include #include +#include /** Compare blocks, first by type, then content. This is an optimization over dynamic_cast, which is very slow on some platforms. */ namespace @@ -1864,3 +1865,8 @@ bool nano::block_sideband::deserialize (nano::stream & stream_a, nano::block_typ return result; } + +std::string_view nano::to_string (nano::block_type type) +{ + return magic_enum::enum_name (type); +} diff --git a/nano/lib/blocks.hpp b/nano/lib/blocks.hpp index 5a9ab168bc..acc44601d5 100644 --- a/nano/lib/blocks.hpp +++ b/nano/lib/blocks.hpp @@ -29,6 +29,9 @@ enum class block_type : uint8_t change = 5, state = 6 }; + +std::string_view to_string (block_type); + class block_details { static_assert (std::is_same::type, uint8_t> (), "Epoch enum is not the proper type"); diff --git a/nano/lib/config.cpp b/nano/lib/config.cpp index 13273e1096..7f40e3b039 100644 --- a/nano/lib/config.cpp +++ b/nano/lib/config.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -355,3 +356,60 @@ uint32_t nano::test_scan_wallet_reps_delay () auto test_env = nano::get_env_or_default ("NANO_TEST_WALLET_SCAN_REPS_DELAY", "900000"); // 15 minutes by default return boost::lexical_cast (test_env); } + +std::string_view nano::to_string (nano::networks network) +{ + switch (network) + { + case nano::networks::invalid: + return "invalid"; + case nano::networks::nano_beta_network: + return "beta"; + case nano::networks::nano_dev_network: + return "dev"; + case nano::networks::nano_live_network: + return "live"; + case nano::networks::nano_test_network: + return "test"; + // default case intentionally omitted to cause warnings for unhandled enums + } + + return "n/a"; +} + +// Using std::cerr here, since logging may not be initialized yet +nano::tomlconfig nano::load_toml_file (const std::filesystem::path & config_filename, const std::filesystem::path & data_path, const std::vector & config_overrides) +{ + std::stringstream config_overrides_stream; + for (auto const & entry : config_overrides) + { + config_overrides_stream << entry << std::endl; + } + config_overrides_stream << std::endl; + + // 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) + { + throw std::runtime_error (error.get_message ()); + } + std::cerr << "Config file `" << config_filename.string () << "` loaded from node data directory: " << toml_config_path.string () << std::endl; + return toml; + } + else + { + // 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 ()); + } + std::cerr << "Config file `" << config_filename.string () << "` not found, using default configuration" << std::endl; + return toml; + } +} diff --git a/nano/lib/config.hpp b/nano/lib/config.hpp index db8ef89752..5db3296c78 100644 --- a/nano/lib/config.hpp +++ b/nano/lib/config.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include #include @@ -127,6 +129,8 @@ enum class networks : uint16_t nano_test_network = 0x5258, // 'R', 'X' }; +std::string_view to_string (nano::networks); + enum class work_version { unspecified, @@ -404,4 +408,28 @@ bool is_sanitizer_build (); /** Set the active network to the dev network */ void force_nano_dev_network (); + +/** + * Attempt to read a configuration file from specified directory. Returns empty tomlconfig if nothing is found. + * @throws std::runtime_error with error code if the file or overrides are not valid toml + */ +nano::tomlconfig load_toml_file (const std::filesystem::path & config_filename, const std::filesystem::path & data_path, const std::vector & config_overrides); + +/** + * Attempt to read a configuration file from specified directory. Returns fallback config if nothing is found. + * @throws std::runtime_error with error code if the file or overrides are not valid toml or deserialization fails + */ +template +T load_config_file (T fallback, const std::filesystem::path & config_filename, const std::filesystem::path & data_path, const std::vector & config_overrides) +{ + auto toml = load_toml_file (config_filename, data_path, config_overrides); + + T config = fallback; + auto error = config.deserialize_toml (toml); + if (error) + { + throw std::runtime_error (error.get_message ()); + } + return config; +} } diff --git a/nano/lib/logger_mt.hpp b/nano/lib/logger_mt.hpp deleted file mode 100644 index 9afd47842a..0000000000 --- a/nano/lib/logger_mt.hpp +++ /dev/null @@ -1,139 +0,0 @@ -#pragma once - -#include -#include - -#include -#include -#include - -#include -#include -#include - -namespace nano -{ -enum class severity_level -{ - normal = 0, - error -}; -} - -// Attribute value tag type -struct severity_tag; - -inline boost::log::formatting_ostream & operator<< (boost::log::formatting_ostream & strm, boost::log::to_log_manip const & manip) -{ - // Needs to match order in the severity_level enum - static std::array strings = { - "", - "Error: " - }; - - nano::severity_level level = manip.get (); - debug_assert (static_cast (level) < strings.size ()); - strm << strings[static_cast (level)]; - return strm; -} - -namespace nano -{ -// A wrapper around a boost logger object to allow minimum -// time spaced output to prevent logging happening too quickly. -class logger_mt -{ -private: - void add_to_stream (boost::log::record_ostream & stream) - { - } - - template - void add_to_stream (boost::log::record_ostream & stream, const LogItem & first_log_item, LogItems &&... remainder_log_items) - { - stream << first_log_item; - add_to_stream (stream, remainder_log_items...); - } - - template - void output (nano::severity_level severity_level, LogItems &&... log_items) - { - boost::log::record rec = boost_logger_mt.open_record (boost::log::keywords::severity = severity_level); - if (rec) - { - boost::log::record_ostream strm (rec); - add_to_stream (strm, std::forward (log_items)...); - strm.flush (); - boost_logger_mt.push_record (std::move (rec)); - } - } - -public: - logger_mt () = default; - - /** - * @param min_log_delta_a The minimum time between successive output - */ - explicit logger_mt (std::chrono::milliseconds const & min_log_delta_a) : - min_log_delta (min_log_delta_a) - { - } - - /* - * @param log_items A collection of objects with overloaded operator<< to be output to the log file - * @params severity_level The severity level that this log message should have. - */ - template - void always_log (nano::severity_level severity_level, LogItems &&... log_items) - { - output (severity_level, std::forward (log_items)...); - } - - /* - * @param log_items A collection of objects with overloaded operator<< to be output to the log file. - */ - template - void always_log (LogItems &&... log_items) - { - always_log (nano::severity_level::normal, std::forward (log_items)...); - } - - /* - * @param log_items Output to the log file if the last write was over min_log_delta time ago. - * @params severity_level The severity level that this log message should have. - * @return true if nothing was logged - */ - template - bool try_log (nano::severity_level severity_level, LogItems &&... log_items) - { - auto error (true); - auto time_now = std::chrono::steady_clock::now (); - nano::unique_lock lk (last_log_time_mutex); - if (((time_now - last_log_time) > min_log_delta) || last_log_time == std::chrono::steady_clock::time_point{}) - { - last_log_time = time_now; - lk.unlock (); - output (severity_level, std::forward (log_items)...); - error = false; - } - return error; - } - - /* - * @param log_items Output to the log file if the last write was over min_log_delta time ago. - * @return true if nothing was logged - */ - template - bool try_log (LogItems &&... log_items) - { - return try_log (nano::severity_level::normal, std::forward (log_items)...); - } - - std::chrono::milliseconds min_log_delta{ 0 }; - -private: - nano::mutex last_log_time_mutex; - std::chrono::steady_clock::time_point last_log_time; - boost::log::sources::severity_logger_mt boost_logger_mt; -}; -} diff --git a/nano/lib/logging.cpp b/nano/lib/logging.cpp new file mode 100644 index 0000000000..4147ea5a3e --- /dev/null +++ b/nano/lib/logging.cpp @@ -0,0 +1,519 @@ +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +nano::logger & nano::default_logger () +{ + static nano::logger logger{ "default" }; + return logger; +} + +/* + * logger + */ + +bool nano::logger::global_initialized{ false }; +nano::log_config nano::logger::global_config{}; +std::vector nano::logger::global_sinks{}; + +// By default, use only the tag as the logger name, since only one node is running in the process +std::function nano::logger::global_name_formatter{ [] (auto tag, auto identifier) { + return std::string{ to_string (tag) }; +} }; + +void nano::logger::initialize (nano::log_config fallback, std::optional data_path, std::vector const & config_overrides) +{ + // Only load log config from file if data_path is available (i.e. not running in cli mode) + nano::log_config config = data_path ? nano::load_log_config (fallback, *data_path, config_overrides) : fallback; + initialize_common (config, data_path); + global_initialized = true; +} + +// Custom log formatter flags +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 + +std::pair split_qualified_identifier (std::string_view qualified_identifier) +{ + auto pos = qualified_identifier.find ("::"); + debug_assert (pos != std::string_view::npos); // This should never happen, since the default logger name formatter always adds the tag + if (pos == std::string_view::npos) + { + return { std::string_view{}, qualified_identifier }; + } + else + { + return { qualified_identifier.substr (0, pos), qualified_identifier.substr (pos + 2) }; + } +} + +class identifier_formatter_flag : public spdlog::custom_flag_formatter +{ +public: + void format (const spdlog::details::log_msg & msg, const std::tm & tm, spdlog::memory_buf_t & dest) override + { + // Extract identifier and tag from logger name + auto [identifier, tag] = split_qualified_identifier (std::string_view (msg.logger_name.data (), msg.logger_name.size ())); + dest.append (identifier.data (), identifier.data () + identifier.size ()); + } + + std::unique_ptr clone () const override + { + return spdlog::details::make_unique (); + } +}; + +class tag_formatter_flag : public spdlog::custom_flag_formatter +{ +public: + void format (const spdlog::details::log_msg & msg, const std::tm & tm, spdlog::memory_buf_t & dest) override + { + // Extract identifier and tag from logger name + auto [identifier, tag] = split_qualified_identifier (std::string_view (msg.logger_name.data (), msg.logger_name.size ())); + dest.append (tag.data (), tag.data () + tag.size ()); + } + + std::unique_ptr clone () const override + { + return spdlog::details::make_unique (); + } +}; +} + +void nano::logger::initialize_for_tests (nano::log_config fallback) +{ + auto config = nano::load_log_config (std::move (fallback), /* load log config from current workdir */ std::filesystem::current_path ()); + initialize_common (config, /* store log file in current workdir */ std::filesystem::current_path ()); + + // 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 (); + formatter->add_flag ('i'); + formatter->add_flag ('n'); + formatter->set_pattern ("[%Y-%m-%d %H:%M:%S.%e] [%i] [%n] [%l] %v"); + + for (auto & sink : global_sinks) + { + sink->set_formatter (formatter->clone ()); + } + + global_initialized = true; +} + +// Using std::cerr here, since logging may not be initialized yet +void nano::logger::initialize_common (nano::log_config const & config, std::optional data_path) +{ + global_config = config; + + spdlog::set_automatic_registration (false); + spdlog::set_level (to_spdlog_level (config.default_level)); + + global_sinks.clear (); + + // Console setup + if (config.console.enable) + { + if (!config.console.to_cerr) + { + // Only use colors if not writing to cerr + if (config.console.colors) + { + auto console_sink = std::make_shared (); + global_sinks.push_back (console_sink); + } + else + { + auto console_sink = std::make_shared (); + global_sinks.push_back (console_sink); + } + } + else + { + if (config.console.colors) + { + std::cerr << "WARNING: Logging to cerr is enabled, console colors will be disabled" << std::endl; + } + + auto cerr_sink = std::make_shared (); + global_sinks.push_back (cerr_sink); + } + } + + // File setup + if (config.file.enable) + { + // In cases where data_path is not available, file logging should always be disabled + release_assert (data_path); + + auto now = std::chrono::system_clock::now (); + auto time = std::chrono::system_clock::to_time_t (now); + + 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{ data_path.value () / "log" / (filename + ".log") }; + log_path = std::filesystem::absolute (log_path); + + std::cerr << "Logging to file: " << log_path.string () << std::endl; + + // If either max_size or rotation_count is 0, then disable file rotation + if (config.file.max_size == 0 || config.file.rotation_count == 0) + { + std::cerr << "WARNING: Log file rotation is disabled, log file size may grow without bound" << std::endl; + + auto file_sink = std::make_shared (log_path.string (), true); + global_sinks.push_back (file_sink); + } + else + { + auto file_sink = std::make_shared (log_path.string (), config.file.max_size, config.file.rotation_count); + global_sinks.push_back (file_sink); + } + } +} + +void nano::logger::flush () +{ + for (auto & sink : global_sinks) + { + sink->flush (); + } +} + +/* + * logger + */ + +nano::logger::logger (std::string identifier) : + identifier{ std::move (identifier) } +{ + release_assert (global_initialized, "logging should be initialized before creating a logger"); +} + +nano::logger::~logger () +{ + flush (); +} + +spdlog::logger & nano::logger::get_logger (nano::log::type tag) +{ + // This is a two-step process to avoid exclusively locking the mutex in the common case + { + std::shared_lock lock{ mutex }; + + if (auto it = spd_loggers.find (tag); it != spd_loggers.end ()) + { + return *it->second; + } + } + // Not found, create a new logger + { + std::unique_lock lock{ mutex }; + + auto [it, inserted] = spd_loggers.emplace (tag, make_logger (tag)); + return *it->second; + } +} + +std::shared_ptr nano::logger::make_logger (nano::log::type tag) +{ + auto const & config = global_config; + auto const & sinks = global_sinks; + + auto name = global_name_formatter (tag, identifier); + auto spd_logger = std::make_shared (name, sinks.begin (), sinks.end ()); + + if (auto it = config.levels.find ({ tag, nano::log::detail::all }); it != config.levels.end ()) + { + spd_logger->set_level (to_spdlog_level (it->second)); + } + else + { + spd_logger->set_level (to_spdlog_level (config.default_level)); + } + + spd_logger->flush_on (to_spdlog_level (config.flush_level)); + + return spd_logger; +} + +spdlog::level::level_enum nano::logger::to_spdlog_level (nano::log::level level) +{ + switch (level) + { + case nano::log::level::off: + return spdlog::level::off; + case nano::log::level::critical: + return spdlog::level::critical; + case nano::log::level::error: + return spdlog::level::err; + case nano::log::level::warn: + return spdlog::level::warn; + case nano::log::level::info: + return spdlog::level::info; + case nano::log::level::debug: + return spdlog::level::debug; + case nano::log::level::trace: + return spdlog::level::trace; + } + debug_assert (false, "Invalid log level"); + return spdlog::level::off; +} + +/* + * logging config presets + */ + +nano::log_config nano::log_config::cli_default () +{ + log_config config{}; + config.default_level = nano::log::level::critical; + config.console.to_cerr = true; // Use cerr to avoid interference with CLI output that goes to stdout + config.file.enable = false; + return config; +} + +nano::log_config nano::log_config::daemon_default () +{ + log_config config{}; + config.default_level = nano::log::level::info; + return config; +} + +nano::log_config nano::log_config::tests_default () +{ + log_config config{}; + config.default_level = nano::log::level::off; + config.file.enable = false; + return config; +} + +nano::log_config nano::log_config::sample_config () +{ + log_config config{}; + config.default_level = nano::log::level::info; + config.levels = default_levels (nano::log::level::info); // Populate with default levels + return config; +} + +/* + * logging config + */ + +nano::error nano::log_config::serialize_toml (nano::tomlconfig & toml) const +{ + nano::tomlconfig config_toml; + serialize (config_toml); + toml.put_child ("log", config_toml); + + return toml.get_error (); +} + +nano::error nano::log_config::deserialize_toml (nano::tomlconfig & toml) +{ + try + { + auto logging_l = toml.get_optional_child ("log"); + if (logging_l) + { + deserialize (*logging_l); + } + } + catch (std::invalid_argument const & ex) + { + toml.get_error ().set (ex.what ()); + } + + return toml.get_error (); +} + +void nano::log_config::serialize (nano::tomlconfig & toml) const +{ + toml.put ("default_level", std::string{ to_string (default_level) }); + + nano::tomlconfig console_config; + console_config.put ("enable", console.enable); + console_config.put ("to_cerr", console.to_cerr); + console_config.put ("colors", console.colors); + toml.put_child ("console", console_config); + + nano::tomlconfig file_config; + file_config.put ("enable", file.enable); + file_config.put ("max_size", file.max_size); + file_config.put ("rotation_count", file.rotation_count); + toml.put_child ("file", file_config); + + nano::tomlconfig levels_config; + for (auto const & [logger_id, level] : levels) + { + auto logger_name = to_string (logger_id.first); + levels_config.put (std::string{ logger_name }, std::string{ to_string (level) }); + } + toml.put_child ("levels", levels_config); +} + +void nano::log_config::deserialize (nano::tomlconfig & toml) +{ + if (toml.has_key ("default_level")) + { + auto default_level_l = toml.get ("default_level"); + default_level = nano::log::parse_level (default_level_l); + } + + if (toml.has_key ("console")) + { + auto console_config = toml.get_required_child ("console"); + console_config.get ("enable", console.enable); + console_config.get ("to_cerr", console.to_cerr); + console_config.get ("colors", console.colors); + } + + if (toml.has_key ("file")) + { + auto file_config = toml.get_required_child ("file"); + file_config.get ("enable", file.enable); + file_config.get ("max_size", file.max_size); + file_config.get ("rotation_count", file.rotation_count); + } + + if (toml.has_key ("levels")) + { + auto levels_config = toml.get_required_child ("levels"); + for (auto & level : levels_config.get_values ()) + { + try + { + auto & [name_str, level_str] = level; + auto logger_level = nano::log::parse_level (level_str); + auto logger_id = parse_logger_id (name_str); + + levels[logger_id] = logger_level; + } + catch (std::invalid_argument const & ex) + { + // Ignore but warn about invalid logger names + std::cerr << "Problem processing log config: " << ex.what () << std::endl; + } + } + } +} + +/** + * Parse `logger_name[:logger_detail]` into a pair of `log::type` and `log::detail` + * @throw std::invalid_argument if `logger_name` or `logger_detail` are invalid + */ +nano::log_config::logger_id_t nano::log_config::parse_logger_id (const std::string & logger_name) +{ + auto pos = logger_name.find ("::"); + if (pos == std::string::npos) + { + return { nano::log::parse_type (logger_name), nano::log::detail::all }; + } + else + { + auto logger_type = logger_name.substr (0, pos); + auto logger_detail = logger_name.substr (pos + 1); + + return { nano::log::parse_type (logger_type), nano::log::parse_detail (logger_detail) }; + } +} + +std::map nano::log_config::default_levels (nano::log::level default_level) +{ + std::map result; + for (auto const & type : nano::log::all_types ()) + { + result.emplace (std::make_pair (type, nano::log::detail::all), default_level); + } + return result; +} + +/* + * config loading + */ + +// Using std::cerr here, since logging may not be initialized yet +nano::log_config nano::load_log_config (nano::log_config fallback, const std::filesystem::path & data_path, const std::vector & config_overrides) +{ + const std::string config_filename = "config-log.toml"; + try + { + auto config = nano::load_config_file (fallback, config_filename, data_path, config_overrides); + + // Parse default log level from environment variable, e.g. "NANO_LOG=debug" + auto env_level = nano::get_env ("NANO_LOG"); + if (env_level) + { + try + { + config.default_level = nano::log::parse_level (*env_level); + + std::cerr << "Using default log level from NANO_LOG environment variable: " << *env_level << std::endl; + } + catch (std::invalid_argument const & ex) + { + std::cerr << "Invalid log level from NANO_LOG environment variable: " << ex.what () << std::endl; + } + } + + // Parse per logger levels from environment variable, e.g. "NANO_LOG_LEVELS=ledger=debug,node=trace" + auto env_levels = nano::get_env ("NANO_LOG_LEVELS"); + if (env_levels) + { + std::map levels; + for (auto const & env_level_str : nano::util::split (*env_levels, ',')) + { + try + { + // Split 'logger_name=level' into a pair of 'logger_name' and 'level' + auto arr = nano::util::split (env_level_str, '='); + if (arr.size () != 2) + { + throw std::invalid_argument ("Invalid entry: " + env_level_str); + } + + auto name_str = arr[0]; + auto level_str = arr[1]; + + auto logger_id = nano::log_config::parse_logger_id (name_str); + auto logger_level = nano::log::parse_level (level_str); + + levels[logger_id] = logger_level; + + std::cerr << "Using logger log level from NANO_LOG_LEVELS environment variable: " << name_str << "=" << level_str << std::endl; + } + catch (std::invalid_argument const & ex) + { + std::cerr << "Invalid log level from NANO_LOG_LEVELS environment variable: " << ex.what () << std::endl; + } + } + + // Merge with existing levels + for (auto const & [logger_id, level] : levels) + { + config.levels[logger_id] = level; + } + } + + return config; + } + catch (std::runtime_error const & ex) + { + std::cerr << "Unable to load log config. Using defaults. Error: " << ex.what () << std::endl; + } + return fallback; +} \ No newline at end of file diff --git a/nano/lib/logging.hpp b/nano/lib/logging.hpp new file mode 100644 index 0000000000..55f08ad64f --- /dev/null +++ b/nano/lib/logging.hpp @@ -0,0 +1,141 @@ +#pragma once + +#include +#include + +#include +#include +#include +#include + +#include + +namespace nano +{ +class log_config final +{ +public: + nano::error serialize_toml (nano::tomlconfig &) const; + nano::error deserialize_toml (nano::tomlconfig &); + +private: + void serialize (nano::tomlconfig &) const; + void deserialize (nano::tomlconfig &); + +public: + nano::log::level default_level{ nano::log::level::info }; + nano::log::level flush_level{ nano::log::level::error }; + + using logger_id_t = std::pair; + std::map levels; + + struct console_config + { + bool enable{ true }; + bool colors{ true }; + bool to_cerr{ false }; + }; + + struct file_config + { + bool enable{ true }; + std::size_t max_size{ 32 * 1024 * 1024 }; + std::size_t rotation_count{ 4 }; + }; + + console_config console; + file_config file; + +public: // Predefined defaults + static log_config cli_default (); + static log_config daemon_default (); + static log_config tests_default (); + static log_config sample_config (); // For auto-generated sample config files + + static logger_id_t parse_logger_id (std::string const &); + +private: + /// Returns placeholder log levels for all loggers + static std::map default_levels (nano::log::level); +}; + +nano::log_config load_log_config (nano::log_config fallback, std::filesystem::path const & data_path, std::vector const & config_overrides = {}); + +class logger final +{ +public: + explicit logger (std::string identifier = ""); + ~logger (); + + // Disallow copies + logger (logger const &) = delete; + +public: + static void initialize (nano::log_config fallback, std::optional data_path = std::nullopt, std::vector const & config_overrides = std::vector ()); + static void initialize_for_tests (nano::log_config fallback); + static void flush (); + +private: + static bool global_initialized; + static nano::log_config global_config; + static std::vector global_sinks; + static std::function global_name_formatter; + + static void initialize_common (nano::log_config const &, std::optional data_path); + +public: + template + void log (nano::log::level level, nano::log::type tag, spdlog::format_string_t fmt, Args &&... args) + { + get_logger (tag).log (to_spdlog_level (level), fmt, std::forward (args)...); + } + + template + void debug (nano::log::type tag, spdlog::format_string_t fmt, Args &&... args) + { + get_logger (tag).debug (fmt, std::forward (args)...); + } + + template + void info (nano::log::type tag, spdlog::format_string_t fmt, Args &&... args) + { + get_logger (tag).info (fmt, std::forward (args)...); + } + + template + void warn (nano::log::type tag, spdlog::format_string_t fmt, Args &&... args) + { + get_logger (tag).warn (fmt, std::forward (args)...); + } + + template + void error (nano::log::type tag, spdlog::format_string_t fmt, Args &&... args) + { + get_logger (tag).error (fmt, std::forward (args)...); + } + + template + void critical (nano::log::type tag, spdlog::format_string_t fmt, Args &&... args) + { + get_logger (tag).critical (fmt, std::forward (args)...); + } + +private: + const std::string identifier; + + std::unordered_map> spd_loggers; + std::shared_mutex mutex; + +private: + spdlog::logger & get_logger (nano::log::type tag); + std::shared_ptr make_logger (nano::log::type tag); + + static spdlog::level::level_enum to_spdlog_level (nano::log::level); +}; + +/** + * Returns a logger instance that can be used before node specific logging is available. + * Should only be used for logging that happens during startup and initialization, since it won't contain node specific identifier. + */ +nano::logger & default_logger (); +} \ No newline at end of file diff --git a/nano/lib/logging_enums.cpp b/nano/lib/logging_enums.cpp new file mode 100644 index 0000000000..b1a55f4485 --- /dev/null +++ b/nano/lib/logging_enums.cpp @@ -0,0 +1,91 @@ +#define MAGIC_ENUM_RANGE_MIN 0 +#define MAGIC_ENUM_RANGE_MAX 256 + +#include +#include + +#include + +std::string_view nano::log::to_string (nano::log::type tag) +{ + return magic_enum::enum_name (tag); +} + +std::string_view nano::log::to_string (nano::log::detail detail) +{ + return magic_enum::enum_name (detail); +} + +std::string_view nano::log::to_string (nano::log::level level) +{ + return magic_enum::enum_name (level); +} + +const std::vector & nano::log::all_levels () +{ + static std::vector all = [] () { + std::vector result; + for (auto const & lvl : magic_enum::enum_values ()) + { + result.push_back (lvl); + } + return result; + }(); + return all; +} + +const std::vector & nano::log::all_types () +{ + static std::vector all = [] () { + std::vector result; + for (auto const & lvl : magic_enum::enum_values ()) + { + result.push_back (lvl); + } + return result; + }(); + return all; +} + +nano::log::level nano::log::parse_level (std::string_view name) +{ + auto value = magic_enum::enum_cast (name); + if (value.has_value ()) + { + return value.value (); + } + else + { + auto all_levels_str = nano::util::join (nano::log::all_levels (), ", ", [] (auto const & lvl) { + return to_string (lvl); + }); + + throw std::invalid_argument ("Invalid log level: " + std::string (name) + ". Must be one of: " + all_levels_str); + } +} + +nano::log::type nano::log::parse_type (std::string_view name) +{ + auto value = magic_enum::enum_cast (name); + if (value.has_value ()) + { + return value.value (); + } + else + { + throw std::invalid_argument ("Invalid log type: " + std::string (name)); + } +} + +nano::log::detail nano::log::parse_detail (std::string_view name) +{ + auto value = magic_enum::enum_cast (name); + if (value.has_value ()) + { + return value.value (); + } + else + { + throw std::invalid_argument ("Invalid log detail: " + std::string (name)); + } +} \ No newline at end of file diff --git a/nano/lib/logging_enums.hpp b/nano/lib/logging_enums.hpp new file mode 100644 index 0000000000..a0e5306256 --- /dev/null +++ b/nano/lib/logging_enums.hpp @@ -0,0 +1,142 @@ +#pragma once + +#include +#include +#include + +namespace nano::log +{ +enum class level +{ + trace, + debug, + info, + warn, + error, + critical, + off, +}; + +enum class type +{ + all = 0, // reserved + + generic, + init, + config, + logging, + node, + node_wrapper, + daemon, + daemon_rpc, + daemon_wallet, + wallet, + qt, + rpc, + rpc_connection, + rpc_callbacks, + rpc_request, + ipc, + ipc_server, + websocket, + tls, + active_transactions, + election, + blockprocessor, + network, + channel, + socket, + socket_server, + tcp, + tcp_server, + tcp_listener, + prunning, + conf_processor_bounded, + conf_processor_unbounded, + distributed_work, + epoch_upgrader, + opencl_work, + upnp, + repcrawler, + lmdb, + rocksdb, + txn_tracker, + gap_cache, + vote_processor, + bulk_pull_client, + bulk_pull_server, + bulk_pull_account_client, + bulk_pull_account_server, + bulk_push_client, + bulk_push_server, + frontier_req_client, + frontier_req_server, + bootstrap, + bootstrap_lazy, + bootstrap_legacy, +}; + +enum class detail +{ + all = 0, // reserved + + // node + process_confirmed, + + // active_transactions + active_started, + active_stopped, + + // election + election_confirmed, + election_expired, + + // blockprocessor + block_processed, + + // vote_processor + vote_processed, + + // network + message_received, + message_sent, + message_dropped, + + // bulk pull/push + pulled_block, + sending_block, + sending_pending, + sending_frontier, + requesting_account_or_head, + requesting_pending, + +}; + +// TODO: Additionally categorize logs by categories which can be enabled/disabled independently +enum class category +{ + all = 0, // reserved + + work_generation, + // ... +}; +} + +namespace nano::log +{ +std::string_view to_string (nano::log::type); +std::string_view to_string (nano::log::detail); +std::string_view to_string (nano::log::level); + +/// @throw std::invalid_argument if the input string does not match a log::level +nano::log::level parse_level (std::string_view); + +/// @throw std::invalid_argument if the input string does not match a log::type +nano::log::type parse_type (std::string_view); + +/// @throw std::invalid_argument if the input string does not match a log::detail +nano::log::detail parse_detail (std::string_view); + +std::vector const & all_levels (); +std::vector const & all_types (); +} diff --git a/nano/lib/numbers.cpp b/nano/lib/numbers.cpp index 65cb8ac86d..f33d6f3cb3 100644 --- a/nano/lib/numbers.cpp +++ b/nano/lib/numbers.cpp @@ -894,6 +894,27 @@ std::string nano::to_string (double const value_a, int const precision_a) return stream.str (); } +std::ostream & nano::operator<< (std::ostream & os, const uint128_union & val) +{ + // TODO: Replace with streaming implementation + os << val.to_string (); + return os; +} + +std::ostream & nano::operator<< (std::ostream & os, const uint256_union & val) +{ + // TODO: Replace with streaming implementation + os << val.to_string (); + return os; +} + +std::ostream & nano::operator<< (std::ostream & os, const uint512_union & val) +{ + // TODO: Replace with streaming implementation + os << val.to_string (); + return os; +} + #ifdef _WIN32 #pragma warning(push) #pragma warning(disable : 4146) // warning C4146: unary minus operator applied to unsigned type, result still unsigned diff --git a/nano/lib/numbers.hpp b/nano/lib/numbers.hpp index d73310d1b4..3021524c4c 100644 --- a/nano/lib/numbers.hpp +++ b/nano/lib/numbers.hpp @@ -4,6 +4,7 @@ #include #include +#include namespace nano { @@ -61,6 +62,7 @@ class amount : public uint128_union using uint128_union::uint128_union; }; class raw_key; + class uint256_union { public: @@ -265,6 +267,11 @@ std::string to_string_hex (uint64_t const); std::string to_string_hex (uint16_t const); bool from_string_hex (std::string const &, uint64_t &); +/* Printing adapters */ +std::ostream & operator<< (std::ostream & os, const uint128_union & val); +std::ostream & operator<< (std::ostream & os, const uint256_union & val); +std::ostream & operator<< (std::ostream & os, const uint512_union & val); + /** * Convert a double to string in fixed format * @param precision_a (optional) use a specific precision (default is the maximum) diff --git a/nano/lib/stats_enums.hpp b/nano/lib/stats_enums.hpp index 7473d85c66..ff9ef58190 100644 --- a/nano/lib/stats_enums.hpp +++ b/nano/lib/stats_enums.hpp @@ -21,6 +21,8 @@ enum class type : uint8_t http_callback, ipc, tcp, + channel, + socket, confirmation_height, confirmation_observer, drop, @@ -311,7 +313,7 @@ enum class dir : uint8_t namespace nano { -std::string_view to_string (stat::type type); -std::string_view to_string (stat::detail detail); -std::string_view to_string (stat::dir dir); +std::string_view to_string (stat::type); +std::string_view to_string (stat::detail); +std::string_view to_string (stat::dir); } diff --git a/nano/lib/tlsconfig.cpp b/nano/lib/tlsconfig.cpp index 064fce24d8..9af33384b4 100644 --- a/nano/lib/tlsconfig.cpp +++ b/nano/lib/tlsconfig.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include @@ -138,7 +138,7 @@ namespace } #endif -nano::error read_tls_config_toml (std::filesystem::path const & data_path_a, nano::tls_config & config_a, nano::logger_mt & logger_a, std::vector const & config_overrides) +nano::error read_tls_config_toml (std::filesystem::path const & data_path_a, nano::tls_config & config_a, nano::logger & logger, std::vector const & config_overrides) { nano::error error; auto toml_config_path = nano::get_tls_toml_config_path (data_path_a); @@ -176,9 +176,7 @@ nano::error read_tls_config_toml (std::filesystem::path const & data_path_a, nan #ifdef NANO_SECURE_RPC load_certs (config_a, logger_a); #else - auto msg ("https or wss is enabled in the TLS configuration, but the node is not built with NANO_SECURE_RPC"); - std::cerr << msg << std::endl; - logger_a.always_log (msg); + logger.critical (nano::log::type::tls, "HTTPS or WSS is enabled in the TLS configuration, but the node is not built with NANO_SECURE_RPC"); std::exit (1); #endif } diff --git a/nano/lib/tlsconfig.hpp b/nano/lib/tlsconfig.hpp index 3afc605327..bae2a9f9b2 100644 --- a/nano/lib/tlsconfig.hpp +++ b/nano/lib/tlsconfig.hpp @@ -13,7 +13,7 @@ namespace nano { -class logger_mt; +class logger; class jsonconfig; class tomlconfig; @@ -54,5 +54,5 @@ class tls_config final #endif }; -nano::error read_tls_config_toml (std::filesystem::path const & data_path_a, nano::tls_config & config_a, nano::logger_mt & logger_a, std::vector const & config_overrides = std::vector ()); +nano::error read_tls_config_toml (std::filesystem::path const & data_path_a, nano::tls_config & config_a, nano::logger &, std::vector const & config_overrides = std::vector ()); } diff --git a/nano/lib/tomlconfig.hpp b/nano/lib/tomlconfig.hpp index e04af3bc05..140e1b0ab9 100644 --- a/nano/lib/tomlconfig.hpp +++ b/nano/lib/tomlconfig.hpp @@ -171,6 +171,19 @@ class tomlconfig : public nano::configbase return *this; } + template + std::vector> get_values () + { + std::vector> result; + for (auto & entry : *tree) + { + T target{}; + get_config (true, entry.first, target, target); + result.push_back ({ entry.first, target }); + } + return result; + } + protected: template ::value>> tomlconfig & get_config (bool optional, std::string const & key, T & target, T default_value = T ()) diff --git a/nano/lib/utility.hpp b/nano/lib/utility.hpp index 7155ca4760..331c0534ab 100644 --- a/nano/lib/utility.hpp +++ b/nano/lib/utility.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -10,6 +11,7 @@ #include #include #include +#include #include #include @@ -210,3 +212,54 @@ bool elapsed (nano::clock::time_point const & last, Duration duration) return elapsed (last, duration, nano::clock::now ()); } } + +namespace nano::util +{ +/** + * Joins elements with specified delimiter while transforming those elements via specified transform function + */ +template +std::string join (InputIt first, InputIt last, std::string_view delimiter, Func transform) +{ + bool start = true; + std::stringstream ss; + while (first != last) + { + if (start) + { + start = false; + } + else + { + ss << delimiter << " "; + } + ss << transform (*first); + ++first; + } + return ss.str (); +} + +template +std::string join (Container const & container, std::string_view delimiter, Func transform) +{ + return join (container.begin (), container.end (), delimiter, transform); +} + +inline std::vector split (const std::string & str, char delimiter) +{ + std::stringstream ss{ str }; + std::vector result; + std::string item; + while (std::getline (ss, item, delimiter)) + { + result.push_back (item); + } + return result; +} + +template +std::string to_str (T const & val) +{ + return boost::lexical_cast (val); +} +} \ No newline at end of file diff --git a/nano/load_test/CMakeLists.txt b/nano/load_test/CMakeLists.txt index 71a99cc371..0864ac6cfe 100644 --- a/nano/load_test/CMakeLists.txt +++ b/nano/load_test/CMakeLists.txt @@ -3,5 +3,4 @@ add_executable(load_test entry.cpp) target_link_libraries(load_test test_common Boost::process) include_directories(${CMAKE_SOURCE_DIR}/submodules) -include_directories(${CMAKE_SOURCE_DIR}/submodules/cpptoml/include) include_directories(${CMAKE_SOURCE_DIR}/submodules/gtest/googletest/include) diff --git a/nano/load_test/entry.cpp b/nano/load_test/entry.cpp index db0ecc5f47..e41e376abc 100644 --- a/nano/load_test/entry.cpp +++ b/nano/load_test/entry.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -490,6 +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::logger::initialize_for_tests (nano::log_config::tests_default ()); nano::force_nano_dev_network (); boost::program_options::options_description description ("Command line options"); diff --git a/nano/nano_node/CMakeLists.txt b/nano/nano_node/CMakeLists.txt index 5da26671ee..48d42d3586 100644 --- a/nano/nano_node/CMakeLists.txt +++ b/nano/nano_node/CMakeLists.txt @@ -18,7 +18,9 @@ add_custom_command( COMMAND nano_node --generate_config node > ${PROJECT_BINARY_DIR}/config-node.toml.sample COMMAND nano_node --generate_config rpc > - ${PROJECT_BINARY_DIR}/config-rpc.toml.sample) + ${PROJECT_BINARY_DIR}/config-rpc.toml.sample + COMMAND nano_node --generate_config log > + ${PROJECT_BINARY_DIR}/config-log.toml.sample) if((NANO_GUI OR RAIBLOCKS_GUI) AND NOT APPLE) if(WIN32) diff --git a/nano/nano_node/daemon.cpp b/nano/nano_node/daemon.cpp index 6344fd8e21..fed22d3bcf 100644 --- a/nano/nano_node/daemon.cpp +++ b/nano/nano_node/daemon.cpp @@ -20,6 +20,8 @@ #include #include +#include + namespace { void nano_abort_signal_handler (int signum) @@ -59,27 +61,31 @@ volatile sig_atomic_t sig_int_or_term = 0; constexpr std::size_t OPEN_FILE_DESCRIPTORS_LIMIT = 16384; } -void nano_daemon::daemon::run (std::filesystem::path const & data_path, nano::node_flags const & flags) +void nano::daemon::run (std::filesystem::path const & data_path, nano::node_flags const & flags) { + nano::logger::initialize (nano::log_config::daemon_default (), data_path, flags.config_overrides); + + logger.info (nano::log::type::daemon, "Daemon started"); + install_abort_signal_handler (); std::filesystem::create_directories (data_path); boost::system::error_code error_chmod; nano::set_secure_perm_directory (data_path, error_chmod); + std::unique_ptr runner; nano::network_params network_params{ nano::network_constants::active_network }; nano::daemon_config config{ data_path, network_params }; auto error = nano::read_node_config_toml (data_path, config, flags.config_overrides); + nano::set_use_memory_pools (config.node.use_memory_pools); + if (!error) { error = nano::flags_config_conflicts (flags, config.node); } if (!error) { - config.node.logging.init (data_path); - nano::logger_mt logger{ config.node.logging.min_time_between_log_output }; - auto tls_config (std::make_shared ()); error = nano::read_tls_config_toml (data_path, *tls_config, logger); if (error) @@ -100,23 +106,18 @@ void nano_daemon::daemon::run (std::filesystem::path const & data_path, nano::no : std::function (nano::work_version const, nano::root const &, uint64_t, std::atomic &)> (nullptr)); try { - // This avoid a blank prompt during any node initialization delays - auto initialization_text = "Starting up Nano node..."; - std::cout << initialization_text << std::endl; - logger.always_log (initialization_text); + // This avoids a blank prompt during any node initialization delays + logger.info (nano::log::type::daemon, "Starting up Nano node..."); // Print info about number of logical cores detected, those are used to decide how many IO, worker and signature checker threads to spawn - logger.always_log (boost::format ("Hardware concurrency: %1% ( configured: %2% )") % std::thread::hardware_concurrency () % nano::hardware_concurrency ()); + logger.info (nano::log::type::daemon, "Hardware concurrency: {} ( configured: {} )", std::thread::hardware_concurrency (), nano::hardware_concurrency ()); nano::set_file_descriptor_limit (OPEN_FILE_DESCRIPTORS_LIMIT); auto const file_descriptor_limit = nano::get_file_descriptor_limit (); + logger.info (nano::log::type::daemon, "File descriptors limit: {}", file_descriptor_limit); if (file_descriptor_limit < OPEN_FILE_DESCRIPTORS_LIMIT) { - logger.always_log (boost::format ("WARNING: open file descriptors limit is %1%, lower than the %2% recommended. Node was unable to change it.") % file_descriptor_limit % OPEN_FILE_DESCRIPTORS_LIMIT); - } - else - { - logger.always_log (boost::format ("Open file descriptors limit is %1%") % file_descriptor_limit); + logger.warn (nano::log::type::daemon, "File descriptors limit is lower than the {} recommended. Node was unable to change it.", OPEN_FILE_DESCRIPTORS_LIMIT); } // for the daemon start up, if the user hasn't specified a port in @@ -133,18 +134,15 @@ void nano_daemon::daemon::run (std::filesystem::path const & data_path, nano::no auto network_label = node->network_params.network.get_current_network_as_string (); std::time_t dateTime = std::time (nullptr); - std::cout << "Network: " << network_label << ", version: " << NANO_VERSION_STRING << "\n" - << "Path: " << node->application_path.string () << "\n" - << "Build Info: " << BUILD_INFO << "\n" - << "Database backend: " << node->store.vendor_get () << "\n" - << "Start time: " << std::put_time (std::gmtime (&dateTime), "%c UTC") << std::endl; + logger.info (nano::log::type::daemon, "Network: {}", network_label); + logger.info (nano::log::type::daemon, "Version: {}", NANO_VERSION_STRING); + logger.info (nano::log::type::daemon, "Data path: '{}'", node->application_path.string ()); + logger.info (nano::log::type::daemon, "Build info: {}", BUILD_INFO); + logger.info (nano::log::type::daemon, "Database backend: {}", node->store.vendor_get ()); + logger.info (nano::log::type::daemon, "Start time: {:%c} UTC", fmt::gmtime (dateTime)); - auto voting (node->wallets.reps ().voting); - if (voting > 1) - { - std::cout << "Voting with more than one representative can limit performance: " << voting << " representatives are configured" << std::endl; - } node->start (); + nano::ipc::ipc_server ipc_server (*node, config.rpc); std::unique_ptr rpc_process; std::unique_ptr rpc; @@ -187,7 +185,9 @@ void nano_daemon::daemon::run (std::filesystem::path const & data_path, nano::no } debug_assert (!nano::signal_handler_impl); - nano::signal_handler_impl = [&io_ctx] () { + nano::signal_handler_impl = [this, &io_ctx] () { + logger.warn (nano::log::type::daemon, "Interrupt signal received, stopping..."); + io_ctx.stop (); sig_int_or_term = 1; }; @@ -219,16 +219,18 @@ void nano_daemon::daemon::run (std::filesystem::path const & data_path, nano::no } else { - std::cerr << "Error initializing node\n"; + logger.critical (nano::log::type::daemon, "Error initializing node"); } } catch (std::runtime_error const & e) { - std::cerr << "Error while running node (" << e.what () << ")\n"; + logger.critical (nano::log::type::daemon, "Error while running node: {}", e.what ()); } } else { - std::cerr << "Error deserializing config: " << error.get_message () << std::endl; + logger.critical (nano::log::type::daemon, "Error deserializing config: {}", error.get_message ()); } + + logger.info (nano::log::type::daemon, "Daemon exiting"); } diff --git a/nano/nano_node/daemon.hpp b/nano/nano_node/daemon.hpp index d56a26c907..8fcc69787c 100644 --- a/nano/nano_node/daemon.hpp +++ b/nano/nano_node/daemon.hpp @@ -1,11 +1,13 @@ +#include + namespace nano { class node_flags; -} -namespace nano_daemon -{ + class daemon { + nano::logger logger{ "daemon" }; + public: void run (std::filesystem::path const &, nano::node_flags const & flags); }; diff --git a/nano/nano_node/entry.cpp b/nano/nano_node/entry.cpp index 250428f542..e77751762e 100644 --- a/nano/nano_node/entry.cpp +++ b/nano/nano_node/entry.cpp @@ -53,8 +53,11 @@ class address_library_pair int main (int argc, char * const * argv) { - nano::set_umask (); + nano::set_umask (); // Make sure the process umask is set before any files are created + nano::logger::initialize (nano::log_config::cli_default ()); + nano::node_singleton_memory_pool_purge_guard memory_pool_cleanup_guard; + boost::program_options::options_description description ("Command line options"); // clang-format off description.add_options () @@ -138,7 +141,7 @@ int main (int argc, char * const * argv) { if (vm.count ("daemon") > 0) { - nano_daemon::daemon daemon; + nano::daemon daemon; nano::node_flags flags; auto flags_ec = nano::update_flags (flags, vm); if (flags_ec) @@ -281,14 +284,14 @@ int main (int argc, char * const * argv) { if (sample.diff > log_threshold) { - node->logger.always_log (sample.get_entry ()); + std::cout << '\t' << sample.get_entry () << '\n'; } } for (auto const & newcomer : newcomers) { if (newcomer.second > log_threshold) { - node->logger.always_log (newcomer_entry (newcomer)); + std::cout << '\t' << newcomer_entry (newcomer) << '\n'; } } } @@ -610,7 +613,7 @@ int main (int argc, char * const * argv) error |= device >= environment.platforms[platform].devices.size (); if (!error) { - nano::logger_mt logger; + nano::logger logger; nano::opencl_config config (platform, device, threads); auto opencl (nano::opencl_work::create (true, config, logger, network_params.work)); nano::work_pool work_pool{ network_params.network, 0, std::chrono::nanoseconds (0), opencl ? [&opencl] (nano::work_version const version_a, nano::root const & root_a, uint64_t difficulty_a, std::atomic &) { @@ -1121,10 +1124,8 @@ int main (int argc, char * const * argv) boost::asio::io_context io_ctx1; boost::asio::io_context io_ctx2; nano::work_pool work{ network_params.network, std::numeric_limits::max () }; - nano::logging logging; auto path1 (nano::unique_path ()); auto path2 (nano::unique_path ()); - logging.init (path1); std::vector config_overrides; auto config (vm.find ("config")); if (config != vm.end ()) @@ -1871,7 +1872,7 @@ int main (int argc, char * const * argv) nano::update_flags (node_flags, vm); nano::inactive_node inactive_node (data_path, node_flags); auto node = inactive_node.node; - node->ledger_pruning (node_flags.block_processor_batch_size != 0 ? node_flags.block_processor_batch_size : 16 * 1024, true, true); + node->ledger_pruning (node_flags.block_processor_batch_size != 0 ? node_flags.block_processor_batch_size : 16 * 1024, true); } else if (vm.count ("debug_stacktrace")) { @@ -1879,15 +1880,12 @@ int main (int argc, char * const * argv) } else if (vm.count ("debug_sys_logging")) { -#ifdef BOOST_WINDOWS - if (!nano::event_log_reg_entry_exists () && !nano::is_windows_elevated ()) - { - std::cerr << "The event log requires the HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\EventLog\\Nano\\Nano registry entry, run again as administator to create it.\n"; - return 1; - } -#endif auto inactive_node = nano::default_inactive_node (data_path, vm); - inactive_node->node->logger.always_log (nano::severity_level::error, "Testing system logger"); + inactive_node->node->logger.critical ({}, "Testing system logger (CRITICAL)"); + inactive_node->node->logger.error ({}, "Testing system logger (ERROR)"); + inactive_node->node->logger.warn ({}, "Testing system logger (WARN)"); + inactive_node->node->logger.info ({}, "Testing system logger (INFO)"); + inactive_node->node->logger.debug ({}, "Testing system logger (DEBUG)"); } else if (vm.count ("debug_account_versions")) { diff --git a/nano/nano_rpc/entry.cpp b/nano/nano_rpc/entry.cpp index 415beb9f5f..65e1de81e9 100644 --- a/nano/nano_rpc/entry.cpp +++ b/nano/nano_rpc/entry.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -11,34 +12,24 @@ #include #include -#include -#include +#include #include namespace { -void logging_init (std::filesystem::path const & application_path_a) -{ - static std::atomic_flag logging_already_added = ATOMIC_FLAG_INIT; - if (!logging_already_added.test_and_set ()) - { - boost::log::add_common_attributes (); - auto path = application_path_a / "log"; - - uintmax_t max_size{ 128 * 1024 * 1024 }; - uintmax_t rotation_size{ 4 * 1024 * 1024 }; - bool flush{ true }; - boost::log::add_file_log (boost::log::keywords::target = path, boost::log::keywords::file_name = path / "rpc_log_%Y-%m-%d_%H-%M-%S.%N.log", boost::log::keywords::rotation_size = rotation_size, boost::log::keywords::auto_flush = flush, boost::log::keywords::scan_method = boost::log::sinks::file::scan_method::scan_matching, boost::log::keywords::max_size = max_size, boost::log::keywords::format = "[%TimeStamp%]: %Message%"); - } -} - volatile sig_atomic_t sig_int_or_term = 0; +nano::logger logger{ "rpc_daemon" }; + void run (std::filesystem::path const & data_path, std::vector const & config_overrides) { + logger.info (nano::log::type::daemon_rpc, "Daemon started (RPC)"); + std::filesystem::create_directories (data_path); + boost::system::error_code error_chmod; nano::set_secure_perm_directory (data_path, error_chmod); + std::unique_ptr runner; nano::network_params network_params{ nano::network_constants::active_network }; @@ -46,14 +37,11 @@ void run (std::filesystem::path const & data_path, std::vector cons auto error = nano::read_rpc_config_toml (data_path, rpc_config, config_overrides); if (!error) { - logging_init (data_path); - nano::logger_mt logger; - auto tls_config (std::make_shared ()); error = nano::read_tls_config_toml (data_path, *tls_config, logger); if (error) { - std::cerr << error.get_message () << std::endl; + logger.critical (nano::log::type::daemon, "Error reading RPC TLS config: {}", error.get_message ()); std::exit (1); } else @@ -88,19 +76,22 @@ void run (std::filesystem::path const & data_path, std::vector cons } catch (std::runtime_error const & e) { - std::cerr << "Error while running rpc (" << e.what () << ")\n"; + logger.critical (nano::log::type::daemon, "Error while running RPC: {}", e.what ()); } } else { - std::cerr << "Error deserializing config: " << error.get_message () << std::endl; + logger.critical (nano::log::type::daemon, "Error deserializing config: {}", error.get_message ()); } + + logger.info (nano::log::type::daemon_rpc, "Daemon stopped (RPC)"); } } int main (int argc, char * const * argv) { - nano::set_umask (); + nano::set_umask (); // Make sure the process umask is set before any files are created + nano::logger::initialize (nano::log_config::cli_default ()); boost::program_options::options_description description ("Command line options"); diff --git a/nano/nano_wallet/entry.cpp b/nano/nano_wallet/entry.cpp index 440e5ddf80..ec15e6fb98 100644 --- a/nano/nano_wallet/entry.cpp +++ b/nano/nano_wallet/entry.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -25,13 +26,18 @@ namespace { +nano::logger logger{ "wallet_daemon" }; + void show_error (std::string const & message_a) { + logger.critical (nano::log::type::daemon, "{}", message_a); + QMessageBox message (QMessageBox::Critical, "Error starting Nano", message_a.c_str ()); message.setModal (true); message.show (); message.exec (); } + void show_help (std::string const & message_a) { QMessageBox message (QMessageBox::NoIcon, "Help", "see launch options "); @@ -68,6 +74,10 @@ 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::logger::initialize (nano::log_config::daemon_default (), data_path, flags.config_overrides); + + logger.info (nano::log::type::daemon_wallet, "Daemon started (wallet)"); + int result (0); nano_qt::eventloop_processor processor; boost::system::error_code error_chmod; @@ -99,9 +109,6 @@ int run_wallet (QApplication & application, int argc, char * const * argv, std:: { nano::set_use_memory_pools (config.node.use_memory_pools); - config.node.logging.init (data_path); - nano::logger_mt logger{ config.node.logging.min_time_between_log_output }; - auto tls_config (std::make_shared ()); error = nano::read_tls_config_toml (data_path, *tls_config, logger); if (error) @@ -231,12 +238,17 @@ int run_wallet (QApplication & application, int argc, char * const * argv, std:: splash->hide (); show_error ("Error deserializing config: " + error.get_message ()); } + + logger.info (nano::log::type::daemon_wallet, "Daemon exiting (wallet)"); + return result; } int main (int argc, char * const * argv) { - nano::set_umask (); + nano::set_umask (); // Make sure the process umask is set before any files are created + nano::logger::initialize (nano::log_config::cli_default ()); + nano::node_singleton_memory_pool_purge_guard memory_pool_cleanup_guard; QApplication application (argc, const_cast (argv)); diff --git a/nano/node/CMakeLists.txt b/nano/node/CMakeLists.txt index b4de400f8f..7918388016 100644 --- a/nano/node/CMakeLists.txt +++ b/nano/node/CMakeLists.txt @@ -110,8 +110,6 @@ add_library( ipc/ipc_server.cpp json_handler.hpp json_handler.cpp - logging.hpp - logging.cpp make_store.hpp make_store.cpp network.hpp @@ -204,8 +202,6 @@ target_link_libraries( argon2 lmdb Boost::beast - Boost::log_setup - Boost::log Boost::program_options Boost::stacktrace Boost::system @@ -223,6 +219,5 @@ target_compile_definitions( add_dependencies(node ipc_flatbuffers_lib) include_directories(${CMAKE_SOURCE_DIR}/submodules) -include_directories(${CMAKE_SOURCE_DIR}/submodules/cpptoml/include) include_directories( ${CMAKE_SOURCE_DIR}/submodules/nano-pow-server/deps/cpptoml/include) diff --git a/nano/node/active_transactions.cpp b/nano/node/active_transactions.cpp index f3581f5b56..29cdbf3c91 100644 --- a/nano/node/active_transactions.cpp +++ b/nano/node/active_transactions.cpp @@ -300,11 +300,6 @@ void nano::active_transactions::request_confirm (nano::unique_lock solicitor.flush (); lock_a.lock (); - - if (node.config.logging.timing_logging ()) - { - node.logger.try_log (boost::str (boost::format ("Processed %1% elections (%2% were already confirmed) in %3% %4%") % this_loop_target_l % (this_loop_target_l - unconfirmed_count_l) % elapsed.value ().count () % elapsed.unit ())); - } } void nano::active_transactions::cleanup_election (nano::unique_lock & lock_a, std::shared_ptr election) @@ -313,7 +308,6 @@ void nano::active_transactions::cleanup_election (nano::unique_lock debug_assert (lock_a.owns_lock ()); debug_assert (!election->confirmed () || recently_confirmed.exists (election->qualified_root)); - node.stats.inc (completion_type (*election), nano::to_stat_detail (election->behavior ())); // Keep track of election count by election type debug_assert (count_by_behavior[election->behavior ()] > 0); count_by_behavior[election->behavior ()]--; @@ -325,10 +319,15 @@ void nano::active_transactions::cleanup_election (nano::unique_lock (void)erased; debug_assert (erased == 1); } + roots.get ().erase (roots.get ().find (election->qualified_root)); lock_a.unlock (); + + node.stats.inc (completion_type (*election), nano::to_stat_detail (election->behavior ())); + vacancy_update (); + for (auto const & [hash, block] : blocks_l) { // Notify observers about dropped elections & blocks lost confirmed elections @@ -343,11 +342,6 @@ void nano::active_transactions::cleanup_election (nano::unique_lock node.network.publish_filter.clear (block); } } - - if (node.config.logging.election_result_logging ()) - { - node.logger.try_log (boost::str (boost::format ("Election erased for root %1%, confirmed: %2$b") % election->qualified_root.to_string () % election->confirmed ())); - } } nano::stat::type nano::active_transactions::completion_type (nano::election const & election) const diff --git a/nano/node/blockprocessor.cpp b/nano/node/blockprocessor.cpp index 6d843fea54..e696b5966b 100644 --- a/nano/node/blockprocessor.cpp +++ b/nano/node/blockprocessor.cpp @@ -112,19 +112,17 @@ void nano::block_processor::rollback_competitor (store::write_transaction const if (successor != nullptr && successor->hash () != hash) { // Replace our block with the winner and roll back any dependent blocks - if (node.config.logging.ledger_rollback_logging ()) - { - node.logger.always_log (boost::str (boost::format ("Rolling back %1% and replacing with %2%") % successor->hash ().to_string () % hash.to_string ())); - } + node.logger.debug (nano::log::type::blockprocessor, "Rolling back: {} and replacing with: {}", successor->hash ().to_string (), hash.to_string ()); + std::vector> rollback_list; if (node.ledger.rollback (transaction, successor->hash (), rollback_list)) { node.stats.inc (nano::stat::type::ledger, nano::stat::detail::rollback_failed); - node.logger.always_log (nano::severity_level::error, boost::str (boost::format ("Failed to roll back %1% because it or a successor was confirmed") % successor->hash ().to_string ())); + node.logger.error (nano::log::type::blockprocessor, "Failed to roll back: {} because it or a successor was confirmed", successor->hash ().to_string ()); } - else if (node.config.logging.ledger_rollback_logging ()) + else { - node.logger.always_log (boost::str (boost::format ("%1% blocks rolled back") % rollback_list.size ())); + node.logger.debug (nano::log::type::blockprocessor, "Blocks rolled back: {}", rollback_list.size ()); } // Deleting from votes cache, stop active transaction for (auto & i : rollback_list) @@ -176,7 +174,7 @@ bool nano::block_processor::should_log () auto now (std::chrono::steady_clock::now ()); if (next_log < now) { - next_log = now + (node.config.logging.timing_logging () ? std::chrono::seconds (2) : std::chrono::seconds (15)); + next_log = now + std::chrono::seconds (15); result = true; } return result; @@ -218,10 +216,12 @@ auto nano::block_processor::process_batch (nano::unique_lock & lock auto store_batch_reached = [&number_of_blocks_processed, max = node.store.max_block_write_batch_num ()] { return number_of_blocks_processed >= max; }; while (have_blocks_ready () && (!deadline_reached () || !processor_batch_reached ()) && !store_batch_reached ()) { + // TODO: Cleaner periodical logging if ((blocks.size () + forced.size () > 64) && should_log ()) { - node.logger.always_log (boost::str (boost::format ("%1% blocks (+ %2% forced) in processing queue") % blocks.size () % forced.size ())); + node.logger.debug (nano::log::type::blockprocessor, "{} blocks (+ {} forced) in processing queue", blocks.size (), forced.size ()); } + std::shared_ptr block; nano::block_hash hash (0); bool force (false); @@ -251,10 +251,11 @@ auto nano::block_processor::process_batch (nano::unique_lock & lock } lock_a.unlock (); - if (node.config.logging.timing_logging () && number_of_blocks_processed != 0 && timer_l.stop () > std::chrono::milliseconds (100)) + if (number_of_blocks_processed != 0 && timer_l.stop () > std::chrono::milliseconds (100)) { - node.logger.always_log (boost::str (boost::format ("Processed %1% blocks (%2% blocks were forced) in %3% %4%") % number_of_blocks_processed % number_of_forced_processed % timer_l.value ().count () % timer_l.unit ())); + node.logger.debug (nano::log::type::blockprocessor, "Processed {} blocks ({} forced) in {} {}", number_of_blocks_processed, number_of_forced_processed, timer_l.value ().count (), timer_l.unit ()); } + return processed; } @@ -263,16 +264,13 @@ nano::process_return nano::block_processor::process_one (store::write_transactio nano::process_return result; auto hash (block->hash ()); result = node.ledger.process (transaction_a, *block); + + node.stats.inc (nano::stat::type::blockprocessor, to_stat_detail (result.code)); + switch (result.code) { case nano::process_result::progress: { - if (node.config.logging.ledger_logging ()) - { - std::string block_string; - block->serialize_json (block_string, node.config.logging.single_line_record ()); - node.logger.try_log (boost::str (boost::format ("Processing block %1%: %2%") % hash.to_string () % block_string)); - } queue_unchecked (transaction_a, hash); /* For send blocks check epoch open unchecked (gap pending). For state blocks check only send subtype and only if block epoch is not last epoch. @@ -287,120 +285,65 @@ nano::process_return nano::block_processor::process_one (store::write_transactio } case nano::process_result::gap_previous: { - if (node.config.logging.ledger_logging ()) - { - node.logger.try_log (boost::str (boost::format ("Gap previous for: %1%") % hash.to_string ())); - } node.unchecked.put (block->previous (), block); node.stats.inc (nano::stat::type::ledger, nano::stat::detail::gap_previous); break; } case nano::process_result::gap_source: { - if (node.config.logging.ledger_logging ()) - { - node.logger.try_log (boost::str (boost::format ("Gap source for: %1%") % hash.to_string ())); - } node.unchecked.put (node.ledger.block_source (transaction_a, *block), block); node.stats.inc (nano::stat::type::ledger, nano::stat::detail::gap_source); break; } case nano::process_result::gap_epoch_open_pending: { - if (node.config.logging.ledger_logging ()) - { - node.logger.try_log (boost::str (boost::format ("Gap pending entries for epoch open: %1%") % hash.to_string ())); - } node.unchecked.put (block->account (), block); // Specific unchecked key starting with epoch open block account public key node.stats.inc (nano::stat::type::ledger, nano::stat::detail::gap_source); break; } case nano::process_result::old: { - if (node.config.logging.ledger_duplicate_logging ()) - { - node.logger.try_log (boost::str (boost::format ("Old for: %1%") % hash.to_string ())); - } node.stats.inc (nano::stat::type::ledger, nano::stat::detail::old); break; } case nano::process_result::bad_signature: { - if (node.config.logging.ledger_logging ()) - { - node.logger.try_log (boost::str (boost::format ("Bad signature for: %1%") % hash.to_string ())); - } break; } case nano::process_result::negative_spend: { - if (node.config.logging.ledger_logging ()) - { - node.logger.try_log (boost::str (boost::format ("Negative spend for: %1%") % hash.to_string ())); - } break; } case nano::process_result::unreceivable: { - if (node.config.logging.ledger_logging ()) - { - node.logger.try_log (boost::str (boost::format ("Unreceivable for: %1%") % hash.to_string ())); - } break; } case nano::process_result::fork: { node.stats.inc (nano::stat::type::ledger, nano::stat::detail::fork); - if (node.config.logging.ledger_logging ()) - { - node.logger.try_log (boost::str (boost::format ("Fork for: %1% root: %2%") % hash.to_string () % block->root ().to_string ())); - } break; } case nano::process_result::opened_burn_account: { - if (node.config.logging.ledger_logging ()) - { - node.logger.try_log (boost::str (boost::format ("Rejecting open block for burn account: %1%") % hash.to_string ())); - } break; } case nano::process_result::balance_mismatch: { - if (node.config.logging.ledger_logging ()) - { - node.logger.try_log (boost::str (boost::format ("Balance mismatch for: %1%") % hash.to_string ())); - } break; } case nano::process_result::representative_mismatch: { - if (node.config.logging.ledger_logging ()) - { - node.logger.try_log (boost::str (boost::format ("Representative mismatch for: %1%") % hash.to_string ())); - } break; } case nano::process_result::block_position: { - if (node.config.logging.ledger_logging ()) - { - node.logger.try_log (boost::str (boost::format ("Block %1% cannot follow predecessor %2%") % hash.to_string () % block->previous ().to_string ())); - } break; } case nano::process_result::insufficient_work: { - if (node.config.logging.ledger_logging ()) - { - node.logger.try_log (boost::str (boost::format ("Insufficient work for %1% : %2% (difficulty %3%)") % hash.to_string () % nano::to_string_hex (block->block_work ()) % nano::to_string_hex (node.network_params.work.difficulty (*block)))); - } break; } } - - node.stats.inc (nano::stat::type::blockprocessor, nano::to_stat_detail (result.code)); - return result; } diff --git a/nano/node/blockprocessor.hpp b/nano/node/blockprocessor.hpp index 5e87663897..fc6c7172a0 100644 --- a/nano/node/blockprocessor.hpp +++ b/nano/node/blockprocessor.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include diff --git a/nano/node/bootstrap/bootstrap_attempt.cpp b/nano/node/bootstrap/bootstrap_attempt.cpp index 4656ad5f4f..8d892db2e2 100644 --- a/nano/node/bootstrap/bootstrap_attempt.cpp +++ b/nano/node/bootstrap/bootstrap_attempt.cpp @@ -20,7 +20,8 @@ nano::bootstrap_attempt::bootstrap_attempt (std::shared_ptr const & id = nano::hardened_constants::get ().random_128.to_string (); } - node_a->logger.always_log (boost::str (boost::format ("Starting %1% bootstrap attempt with ID %2%") % mode_text () % id)); + node_a->logger.debug (nano::log::type::bootstrap, "Starting bootstrap attempt with ID: {} (mode: {})", mode_text (), id); + node_a->bootstrap_initiator.notify_listeners (true); if (node_a->websocket.server) { @@ -36,7 +37,9 @@ nano::bootstrap_attempt::~bootstrap_attempt () { return; } - node->logger.always_log (boost::str (boost::format ("Exiting %1% bootstrap attempt with ID %2%") % mode_text () % id)); + + node->logger.debug (nano::log::type::bootstrap, "Exiting bootstrap attempt with ID: {} (mode: {})", mode_text (), id); + node->bootstrap_initiator.notify_listeners (false); if (node->websocket.server) { diff --git a/nano/node/bootstrap/bootstrap_bulk_pull.cpp b/nano/node/bootstrap/bootstrap_bulk_pull.cpp index 5c0daa4602..33fb6717a2 100644 --- a/nano/node/bootstrap/bootstrap_bulk_pull.cpp +++ b/nano/node/bootstrap/bootstrap_bulk_pull.cpp @@ -46,10 +46,8 @@ nano::bulk_pull_client::~bulk_pull_client () } pull.processed += pull_blocks - unexpected_count; node->bootstrap_initiator.connections->requeue_pull (pull, network_error); - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Bulk pull end block is not expected %1% for account %2% or head block %3%") % pull.end.to_string () % pull.account_or_head.to_account () % pull.account_or_head.to_string ())); - } + + node->logger.debug (nano::log::type::bulk_pull_client, "Bulk pull end block is not expected {} for account {} or head block {}", pull.end.to_string (), pull.account_or_head.to_account (), pull.account_or_head.to_string ()); } else { @@ -82,14 +80,11 @@ void nano::bulk_pull_client::request () req.count = pull.count; req.set_count_present (pull.count != 0); - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Requesting account %1% or head block %2% from %3%. %4% accounts in queue") % pull.account_or_head.to_account () % pull.account_or_head.to_string () % connection->channel->to_string () % attempt->pulling)); - } - else if (node->config.logging.network_logging () && attempt->should_log ()) + if (attempt->should_log ()) { - node->logger.always_log (boost::str (boost::format ("%1% accounts in pull queue") % attempt->pulling)); + node->logger.debug (nano::log::type::bulk_pull_client, "Accounts in pull queue: {}", attempt->pulling.load ()); } + auto this_l (shared_from_this ()); connection->channel->send ( req, [this_l] (boost::system::error_code const & ec, std::size_t size_a) { @@ -104,10 +99,7 @@ void nano::bulk_pull_client::request () } else { - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Error sending bulk pull request to %1%: to %2%") % ec.message () % this_l->connection->channel->to_string ())); - } + node->logger.debug (nano::log::type::bulk_pull_client, "Error sending bulk pull request to: {} ({})", this_l->connection->channel->to_string (), ec.message ()); node->stats.inc (nano::stat::type::bootstrap, nano::stat::detail::bulk_pull_request_failure, nano::stat::dir::in); } }, @@ -168,20 +160,12 @@ void nano::bulk_pull_client::received_block (boost::system::error_code ec, std:: } if (node->network_params.work.validate_entry (*block)) { - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Insufficient work for bulk pull block: %1%") % block->hash ().to_string ())); - } - node->stats.inc_detail_only (nano::stat::type::error, nano::stat::detail::insufficient_work); + node->logger.debug (nano::log::type::bulk_pull_client, "Insufficient work for bulk pull block: {}", block->hash ().to_string ()); + node->stats.inc (nano::stat::type::error, nano::stat::detail::insufficient_work); return; } auto hash = block->hash (); - if (node->config.logging.bulk_pull_logging ()) - { - std::string block_l; - block->serialize_json (block_l, node->config.logging.single_line_record ()); - node->logger.try_log (boost::str (boost::format ("Pulled block %1% %2%") % hash.to_string () % block_l)); - } + // Is block expected? bool block_expected (false); // Unconfirmed head is used only for lazy destinations if legacy bootstrap is not available, see nano::bootstrap_attempt::lazy_destinations_increment (...) @@ -247,14 +231,12 @@ void nano::bulk_pull_account_client::request () req.account = account; req.minimum_amount = node->config.receive_minimum; req.flags = nano::bulk_pull_account_flags::pending_hash_and_amount; - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Requesting pending for account %1% from %2%. %3% accounts in queue") % req.account.to_account () % connection->channel->to_string () % attempt->wallet_size ())); - } - else if (node->config.logging.network_logging () && attempt->should_log ()) + + if (attempt->should_log ()) { - node->logger.always_log (boost::str (boost::format ("%1% accounts in pull queue") % attempt->wallet_size ())); + node->logger.debug (nano::log::type::bulk_pull_account_client, "Accounts in pull queue: {}", attempt->wallet_size ()); } + auto this_l (shared_from_this ()); connection->channel->send ( req, [this_l] (boost::system::error_code const & ec, std::size_t size_a) { @@ -269,12 +251,10 @@ void nano::bulk_pull_account_client::request () } else { - this_l->attempt->requeue_pending (this_l->account); - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Error starting bulk pull request to %1%: to %2%") % ec.message () % this_l->connection->channel->to_string ())); - } + node->logger.debug (nano::log::type::bulk_pull_account_client, "Error starting bulk pull request to: {} ({})", this_l->connection->channel->to_string (), ec.message ()); node->stats.inc (nano::stat::type::bootstrap, nano::stat::detail::bulk_pull_error_starting_request, nano::stat::dir::in); + + this_l->attempt->requeue_pending (this_l->account); } }, nano::transport::buffer_drop_policy::no_limiter_drop); @@ -334,20 +314,16 @@ void nano::bulk_pull_account_client::receive_pending () } else { + node->logger.debug (nano::log::type::bulk_pull_account_client, "Error while receiving bulk pull account frontier: {}", ec.message ()); + this_l->attempt->requeue_pending (this_l->account); - if (node->config.logging.network_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Error while receiving bulk pull account frontier %1%") % ec.message ())); - } } } else { + node->logger.debug (nano::log::type::bulk_pull_account_client, "Invalid size: Expected {}, got: {}", size_l, size_a); + this_l->attempt->requeue_pending (this_l->account); - if (node->config.logging.network_message_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Invalid size: expected %1%, got %2%") % size_l % size_a)); - } } }); } @@ -379,19 +355,14 @@ void nano::bulk_pull_server::set_current_end () auto transaction (node->store.tx_begin_read ()); if (!node->store.block.exists (transaction, request->end)) { - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Bulk pull end block doesn't exist: %1%, sending everything") % request->end.to_string ())); - } + node->logger.debug (nano::log::type::bulk_pull_server, "Bulk pull end block doesn't exist: {}, sending everything", request->end.to_string ()); + request->end.clear (); } if (node->store.block.exists (transaction, request->start.as_block_hash ())) { - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Bulk pull request for block hash: %1%") % request->start.to_string ())); - } + node->logger.debug (nano::log::type::bulk_pull_server, "Bulk pull request for block hash: {}", request->start.to_string ()); current = ascending () ? node->store.block.successor (transaction, request->start.as_block_hash ()) : request->start.as_block_hash (); include_start = true; @@ -401,10 +372,8 @@ void nano::bulk_pull_server::set_current_end () auto info = node->ledger.account_info (transaction, request->start.as_account ()); if (!info) { - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Request for unknown account: %1%") % request->start.to_account ())); - } + node->logger.debug (nano::log::type::bulk_pull_server, "Request for unknown account: {}", request->start.to_account ()); + current = request->end; } else @@ -415,10 +384,8 @@ void nano::bulk_pull_server::set_current_end () auto account (node->ledger.account (transaction, request->end)); if (account != request->start.as_account ()) { - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Request for block that is not on account chain: %1% not on %2%") % request->end.to_string () % request->start.to_account ())); - } + node->logger.debug (nano::log::type::bulk_pull_server, "Request for block that is not on account chain: {} not on {}", request->end.to_string (), request->start.to_account ()); + current = request->end; } } @@ -451,10 +418,7 @@ void nano::bulk_pull_server::send_next () nano::vectorstream stream (send_buffer); nano::serialize_block (stream, *block); } - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Sending block: %1%") % block->hash ().to_string ())); - } + connection->socket->async_write (nano::shared_const_buffer (std::move (send_buffer)), [this_l = shared_from_this ()] (boost::system::error_code const & ec, std::size_t size_a) { this_l->sent_action (ec, size_a); }); @@ -556,10 +520,7 @@ void nano::bulk_pull_server::sent_action (boost::system::error_code const & ec, } else { - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Unable to bulk send block: %1%") % ec.message ())); - } + node->logger.debug (nano::log::type::bulk_pull_server, "Unable to bulk send block: {}", ec.message ()); } } @@ -572,10 +533,9 @@ void nano::bulk_pull_server::send_finished () } nano::shared_const_buffer send_buffer (static_cast (nano::block_type::not_a_block)); auto this_l (shared_from_this ()); - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log ("Bulk sending finished"); - } + + node->logger.debug (nano::log::type::bulk_pull_server, "Bulk sending finished"); + connection->socket->async_write (send_buffer, [this_l] (boost::system::error_code const & ec, std::size_t size_a) { this_l->no_block_sent (ec, size_a); }); @@ -595,10 +555,7 @@ void nano::bulk_pull_server::no_block_sent (boost::system::error_code const & ec } else { - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log ("Unable to send not-a-block"); - } + node->logger.debug (nano::log::type::bulk_pull_server, "Unable to bulk send not-a-block: {}", ec.message ()); } } @@ -650,13 +607,9 @@ void nano::bulk_pull_account_server::set_params () } else { - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Invalid bulk_pull_account flags supplied %1%") % static_cast (request->flags))); - } + node->logger.debug (nano::log::type::bulk_pull_account_server, "Invalid bulk_pull_account flags supplied: {}", static_cast (request->flags)); invalid_request = true; - return; } @@ -729,23 +682,11 @@ void nano::bulk_pull_account_server::send_next_block () if (pending_address_only) { nano::vectorstream output_stream (send_buffer); - - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Sending address: %1%") % block_info->source.to_string ())); - } - write (output_stream, block_info->source.bytes); } else { nano::vectorstream output_stream (send_buffer); - - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Sending block: %1%") % block_info_key->hash.to_string ())); - } - write (output_stream, block_info_key->hash.bytes); write (output_stream, block_info->amount.bytes); @@ -768,10 +709,7 @@ void nano::bulk_pull_account_server::send_next_block () /* * Otherwise, finalize the connection */ - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Done sending blocks"))); - } + node->logger.debug (nano::log::type::bulk_pull_account_server, "Done sending blocks"); send_finished (); } @@ -876,10 +814,7 @@ void nano::bulk_pull_account_server::sent_action (boost::system::error_code cons } else { - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Unable to bulk send block: %1%") % ec.message ())); - } + node->logger.debug (nano::log::type::bulk_pull_account_server, "Unable to bulk send block: {}", ec.message ()); } } @@ -916,13 +851,9 @@ void nano::bulk_pull_account_server::send_finished () } } - auto this_l (shared_from_this ()); - - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log ("Bulk sending for an account finished"); - } + node->logger.debug (nano::log::type::bulk_pull_account_server, "Bulk sending for an account finished"); + auto this_l (shared_from_this ()); connection->socket->async_write (nano::shared_const_buffer (std::move (send_buffer)), [this_l] (boost::system::error_code const & ec, std::size_t size_a) { this_l->complete (ec, size_a); }); @@ -957,10 +888,7 @@ void nano::bulk_pull_account_server::complete (boost::system::error_code const & } else { - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log ("Unable to pending-as-zero"); - } + node->logger.debug (nano::log::type::bulk_pull_account_server, "Unable to pending-as-zero: {}", ec.message ()); } } diff --git a/nano/node/bootstrap/bootstrap_bulk_push.cpp b/nano/node/bootstrap/bootstrap_bulk_push.cpp index dd1fc76f3c..5ff069ba12 100644 --- a/nano/node/bootstrap/bootstrap_bulk_push.cpp +++ b/nano/node/bootstrap/bootstrap_bulk_push.cpp @@ -38,10 +38,7 @@ void nano::bulk_push_client::start () } else { - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Unable to send bulk_push request: %1%") % ec.message ())); - } + node->logger.debug (nano::log::type::bulk_push_client, "Unable to send bulk push request: {}", ec.message ()); } }, nano::transport::buffer_drop_policy::no_limiter_drop); @@ -71,10 +68,7 @@ void nano::bulk_push_client::push () } else { - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log ("Bulk pushing range ", current_target.first.to_string (), " down to ", current_target.second.to_string ()); - } + node->logger.debug (nano::log::type::bulk_push_client, "Bulk pushing range: [{}:{}]", current_target.first.to_string (), current_target.second.to_string ()); } } } @@ -124,10 +118,7 @@ void nano::bulk_push_client::push_block (nano::block const & block_a) } else { - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Error sending block during bulk push: %1%") % ec.message ())); - } + node->logger.debug (nano::log::type::bulk_push_client, "Error sending block during bulk push: {}", ec.message ()); } }); } @@ -171,10 +162,7 @@ void nano::bulk_push_server::receive () } if (node->bootstrap_initiator.in_progress ()) { - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log ("Aborting bulk_push because a bootstrap attempt is in progress"); - } + node->logger.debug (nano::log::type::bulk_push_server, "Aborting bulk push because a bootstrap attempt is in progress"); } else { @@ -191,10 +179,7 @@ void nano::bulk_push_server::receive () } else { - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Error receiving block type: %1%") % ec.message ())); - } + node->logger.debug (nano::log::type::bulk_push_server, "Error receiving block type: {}", ec.message ()); } }); } @@ -258,10 +243,7 @@ void nano::bulk_push_server::received_type () } default: { - if (node->config.logging.network_packet_logging ()) - { - node->logger.try_log ("Unknown type received as block type"); - } + node->logger.debug (nano::log::type::bulk_push_server, "Unknown type received as block type"); break; } } @@ -282,11 +264,8 @@ void nano::bulk_push_server::received_block (boost::system::error_code const & e { if (node->network_params.work.validate_entry (*block)) { - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Insufficient work for bulk push block: %1%") % block->hash ().to_string ())); - } - node->stats.inc_detail_only (nano::stat::type::error, nano::stat::detail::insufficient_work); + node->logger.debug (nano::log::type::bulk_push_server, "Insufficient work for bulk push block: {}", block->hash ().to_string ()); + node->stats.inc (nano::stat::type::error, nano::stat::detail::insufficient_work); return; } node->process_active (std::move (block)); @@ -294,10 +273,7 @@ void nano::bulk_push_server::received_block (boost::system::error_code const & e } else { - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log ("Error deserializing block received from pull request"); - } + node->logger.debug (nano::log::type::bulk_push_server, "Error deserializing block received from pull request"); } } } diff --git a/nano/node/bootstrap/bootstrap_connections.cpp b/nano/node/bootstrap/bootstrap_connections.cpp index 6287add5a3..ccb47c06a6 100644 --- a/nano/node/bootstrap/bootstrap_connections.cpp +++ b/nano/node/bootstrap/bootstrap_connections.cpp @@ -91,7 +91,8 @@ std::shared_ptr nano::bootstrap_connections::connection } if (result == nullptr && connections_count == 0 && new_connections_empty && attempt_a != nullptr) { - node.logger.try_log (boost::str (boost::format ("Bootstrap attempt stopped because there are no peers"))); + node.logger.debug (nano::log::type::bootstrap, "Bootstrap attempt stopped because there are no peers"); + lock.unlock (); attempt_a->stop (); } @@ -157,29 +158,24 @@ void nano::bootstrap_connections::connect_client (nano::tcp_endpoint const & end [this_l, socket, endpoint_a, push_front] (boost::system::error_code const & ec) { if (!ec) { - if (this_l->node.config.logging.bulk_pull_logging ()) - { - this_l->node.logger.try_log (boost::str (boost::format ("Connection established to %1%") % endpoint_a)); - } + this_l->node.logger.debug (nano::log::type::bootstrap, "Connection established to: {}", nano::util::to_str (endpoint_a)); + auto client (std::make_shared (this_l->node.shared (), std::make_shared (*this_l->node.shared (), socket), socket)); this_l->pool_connection (client, true, push_front); } else { - if (this_l->node.config.logging.network_logging ()) + switch (ec.value ()) { - switch (ec.value ()) - { - default: - this_l->node.logger.try_log (boost::str (boost::format ("Error initiating bootstrap connection to %1%: %2%") % endpoint_a % ec.message ())); - break; - case boost::system::errc::connection_refused: - case boost::system::errc::operation_canceled: - case boost::system::errc::timed_out: - case 995: // Windows The I/O operation has been aborted because of either a thread exit or an application request - case 10061: // Windows No connection could be made because the target machine actively refused it - break; - } + default: + this_l->node.logger.debug (nano::log::type::bootstrap, "Error initiating bootstrap connection to: {} ({})", nano::util::to_str (endpoint_a), ec.message ()); + break; + case boost::system::errc::connection_refused: + case boost::system::errc::operation_canceled: + case boost::system::errc::timed_out: + case 995: // Windows The I/O operation has been aborted because of either a thread exit or an application request + case 10061: // Windows No connection could be made because the target machine actively refused it + break; } } --this_l->connections_count; @@ -236,10 +232,12 @@ void nano::bootstrap_connections::populate_connections (bool repeat) // This is ~1.5kilobits/sec. if (elapsed_sec > nano::bootstrap_limits::bootstrap_minimum_termination_time_sec && blocks_per_sec < nano::bootstrap_limits::bootstrap_minimum_blocks_per_sec) { - if (node.config.logging.bulk_pull_logging ()) - { - node.logger.try_log (boost::str (boost::format ("Stopping slow peer %1% (elapsed sec %2%s > %3%s and %4% blocks per second < %5%)") % client->channel->to_string () % elapsed_sec % nano::bootstrap_limits::bootstrap_minimum_termination_time_sec % blocks_per_sec % nano::bootstrap_limits::bootstrap_minimum_blocks_per_sec)); - } + node.logger.debug (nano::log::type::bootstrap, "Stopping slow peer {} (elapsed sec {} > {} and {} blocks per second < {})", + client->channel->to_string (), + elapsed_sec, + nano::bootstrap_limits::bootstrap_minimum_termination_time_sec, + blocks_per_sec, + nano::bootstrap_limits::bootstrap_minimum_blocks_per_sec); client->stop (true); new_clients.pop_back (); @@ -259,29 +257,27 @@ void nano::bootstrap_connections::populate_connections (bool repeat) // 4 -> 1, 8 -> 2, 16 -> 4, arbitrary, but seems to work well. auto drop = (int)roundf (sqrtf ((float)target - 2.0f)); - if (node.config.logging.bulk_pull_logging ()) - { - node.logger.try_log (boost::str (boost::format ("Dropping %1% bulk pull peers, target connections %2%") % drop % target)); - } + node.logger.debug (nano::log::type::bootstrap, "Dropping {} bulk pull peers, target connections {}", drop, target); for (int i = 0; i < drop; i++) { auto client = sorted_connections.top (); - if (node.config.logging.bulk_pull_logging ()) - { - node.logger.try_log (boost::str (boost::format ("Dropping peer with block rate %1%, block count %2% (%3%) ") % client->block_rate % client->block_count % client->channel->to_string ())); - } + node.logger.debug (nano::log::type::bootstrap, "Dropping peer with block rate {} and block count {} ({})", + client->block_rate.load (), + client->block_count.load (), + client->channel->to_string ()); client->stop (false); sorted_connections.pop (); } } - if (node.config.logging.bulk_pull_logging ()) - { - node.logger.try_log (boost::str (boost::format ("Bulk pull connections: %1%, rate: %2% blocks/sec, bootstrap attempts %3%, remaining pulls: %4%") % connections_count.load () % (int)rate_sum % attempts_count % num_pulls)); - } + node.logger.debug (nano::log::type::bootstrap, "Bulk pull connections: {}, rate: {} blocks/sec, bootstrap attempts {}, remaining pulls: {}", + connections_count.load (), + (int)rate_sum, + attempts_count, + num_pulls); if (connections_count < target && (attempts_count != 0 || new_connections_empty) && !stopped) { @@ -423,11 +419,13 @@ void nano::bootstrap_connections::requeue_pull (nano::pull_info const & pull_a, } else { - if (node.config.logging.bulk_pull_logging ()) - { - node.logger.try_log (boost::str (boost::format ("Failed to pull account %1% or head block %2% down to %3% after %4% attempts and %5% blocks processed") % pull.account_or_head.to_account () % pull.account_or_head.to_string () % pull.end.to_string () % pull.attempts % pull.processed)); - } node.stats.inc (nano::stat::type::bootstrap, nano::stat::detail::bulk_pull_failed_account, nano::stat::dir::in); + node.logger.debug (nano::log::type::bootstrap, "Failed to pull account {} or head block {} down to {} after {} attempts and {} blocks processed", + pull.account_or_head.to_account (), + pull.account_or_head.to_string (), + pull.end.to_string (), + pull.attempts, + pull.processed); if (lazy && pull.processed > 0) { diff --git a/nano/node/bootstrap/bootstrap_frontier.cpp b/nano/node/bootstrap/bootstrap_frontier.cpp index 6b8766fc24..7a9d580361 100644 --- a/nano/node/bootstrap/bootstrap_frontier.cpp +++ b/nano/node/bootstrap/bootstrap_frontier.cpp @@ -42,10 +42,7 @@ void nano::frontier_req_client::run (nano::account const & start_account_a, uint } else { - if (node->config.logging.network_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Error while sending bootstrap request %1%") % ec.message ())); - } + node->logger.debug (nano::log::type::frontier_req_client, "Error while sending bootstrap request: {}", ec.message ()); } }, nano::transport::buffer_drop_policy::no_limiter_drop); @@ -76,10 +73,7 @@ void nano::frontier_req_client::receive_frontier () } else { - if (node->config.logging.network_message_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Invalid size: expected %1%, got %2%") % nano::frontier_req_client::size_frontier % size_a)); - } + node->logger.debug (nano::log::type::frontier_req_client, "Invalid size: expected {}, got {}", nano::frontier_req_client::size_frontier, size_a); } }); } @@ -137,14 +131,17 @@ void nano::frontier_req_client::received_frontier (boost::system::error_code con double age_factor = (frontiers_age == std::numeric_limits::max ()) ? 1.0 : 1.5; // Allow slower frontiers receive for requests with age if (elapsed_sec > nano::bootstrap_limits::bootstrap_connection_warmup_time_sec && blocks_per_sec * age_factor < nano::bootstrap_limits::bootstrap_minimum_frontier_blocks_per_sec) { - node->logger.try_log (boost::str (boost::format ("Aborting frontier req because it was too slow: %1% frontiers per second, last %2%") % blocks_per_sec % account.to_account ())); + node->logger.debug (nano::log::type::frontier_req_client, "Aborting frontier req because it was too slow: {} frontiers per second, last {}", blocks_per_sec, account.to_account ()); + promise.set_value (true); return; } + if (attempt->should_log ()) { - node->logger.always_log (boost::str (boost::format ("Received %1% frontiers from %2%") % std::to_string (count) % connection->channel->to_string ())); + node->logger.debug (nano::log::type::frontier_req_client, "Received {} frontiers from {}", count, connection->channel->to_string ()); } + if (!account.is_zero () && count <= count_limit) { last_account = account; @@ -203,10 +200,8 @@ void nano::frontier_req_client::received_frontier (boost::system::error_code con } // Prevent new frontier_req requests attempt->set_start_account (std::numeric_limits::max ()); - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log ("Bulk push cost: ", bulk_push_cost); - } + + node->logger.debug (nano::log::type::frontier_req_client, "Bulk push cost: {}", bulk_push_cost); } else { @@ -225,10 +220,7 @@ void nano::frontier_req_client::received_frontier (boost::system::error_code con } else { - if (node->config.logging.network_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Error while receiving frontier %1%") % ec.message ())); - } + node->logger.debug (nano::log::type::frontier_req_client, "Error while receiving frontier: {}", ec.message ()); } } @@ -291,11 +283,8 @@ void nano::frontier_req_server::send_next () debug_assert (!current.is_zero ()); debug_assert (!frontier.is_zero ()); } + auto this_l (shared_from_this ()); - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Sending frontier for %1% %2%") % current.to_account () % frontier.to_string ())); - } next (); connection->socket->async_write (nano::shared_const_buffer (std::move (send_buffer)), [this_l] (boost::system::error_code const & ec, std::size_t size_a) { this_l->sent_action (ec, size_a); @@ -321,11 +310,10 @@ void nano::frontier_req_server::send_finished () write (stream, zero.bytes); write (stream, zero.bytes); } + + node->logger.debug (nano::log::type::frontier_req_server, "Frontier sending finished"); + auto this_l (shared_from_this ()); - if (node->config.logging.network_logging ()) - { - node->logger.try_log ("Frontier sending finished"); - } connection->socket->async_write (nano::shared_const_buffer (std::move (send_buffer)), [this_l] (boost::system::error_code const & ec, std::size_t size_a) { this_l->no_block_sent (ec, size_a); }); @@ -344,10 +332,7 @@ void nano::frontier_req_server::no_block_sent (boost::system::error_code const & } else { - if (node->config.logging.network_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Error sending frontier finish: %1%") % ec.message ())); - } + node->logger.debug (nano::log::type::frontier_req_server, "Error sending frontier finish: {}", ec.message ()); } } @@ -368,10 +353,7 @@ void nano::frontier_req_server::sent_action (boost::system::error_code const & e } else { - if (node->config.logging.network_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Error sending frontier pair: %1%") % ec.message ())); - } + node->logger.debug (nano::log::type::frontier_req_server, "Error sending frontier pair: {}", ec.message ()); } } diff --git a/nano/node/bootstrap/bootstrap_lazy.cpp b/nano/node/bootstrap/bootstrap_lazy.cpp index 28e5cf6ad0..0d3dbc9408 100644 --- a/nano/node/bootstrap/bootstrap_lazy.cpp +++ b/nano/node/bootstrap/bootstrap_lazy.cpp @@ -250,11 +250,11 @@ void nano::bootstrap_attempt_lazy::run () } if (!stopped) { - node->logger.try_log ("Completed lazy pulls"); + node->logger.debug (nano::log::type::bootstrap_lazy, "Completed lazy pulls"); } if (lazy_has_expired ()) { - node->logger.try_log (boost::str (boost::format ("Lazy bootstrap attempt ID %1% expired") % id)); + node->logger.debug (nano::log::type::bootstrap_lazy, "Lazy bootstrap attempt ID {} expired", id); } lock.unlock (); stop (); @@ -613,7 +613,7 @@ void nano::bootstrap_attempt_wallet::run () } if (!stopped) { - node->logger.try_log ("Completed wallet lazy pulls"); + node->logger.info (nano::log::type::bootstrap_lazy, "Completed wallet lazy pulls"); } lock.unlock (); stop (); diff --git a/nano/node/bootstrap/bootstrap_legacy.cpp b/nano/node/bootstrap/bootstrap_legacy.cpp index 481d6df85b..25605c91b5 100644 --- a/nano/node/bootstrap/bootstrap_legacy.cpp +++ b/nano/node/bootstrap/bootstrap_legacy.cpp @@ -88,14 +88,6 @@ void nano::bootstrap_attempt_legacy::request_push (nano::unique_lockconfig.logging.network_logging ()) - { - node->logger.try_log ("Exiting bulk push client"); - if (error) - { - node->logger.try_log ("Bulk push client failed"); - } - } } void nano::bootstrap_attempt_legacy::add_frontier (nano::pull_info const & pull_a) @@ -186,16 +178,13 @@ bool nano::bootstrap_attempt_legacy::request_frontier (nano::unique_lockconfig.logging.network_logging ()) + if (!result) { - if (!result) - { - node->logger.try_log (boost::str (boost::format ("Completed frontier request, %1% out of sync accounts according to %2%") % account_count % connection_l->channel->to_string ())); - } - else - { - node->stats.inc (nano::stat::type::error, nano::stat::detail::frontier_req, nano::stat::dir::out); - } + node->logger.debug (nano::log::type::bootstrap_legacy, "Completed frontier request, {} out of sync accounts according to {}", account_count.load (), connection_l->channel->to_string ()); + } + else + { + node->stats.inc (nano::stat::type::error, nano::stat::detail::frontier_req, nano::stat::dir::out); } } return result; @@ -233,25 +222,24 @@ void nano::bootstrap_attempt_legacy::run () // clang-format off condition.wait (lock, [&stopped = stopped, &pulling = pulling] { return stopped || pulling == 0; }); } + // Flushing may resolve forks which can add more pulls - node->logger.try_log ("Flushing unchecked blocks"); lock.unlock (); node->block_processor.flush (); lock.lock (); + if (start_account.number () != std::numeric_limits::max ()) { - node->logger.try_log (boost::str (boost::format ("Finished flushing unchecked blocks, requesting new frontiers after %1%") % start_account.to_account ())); + node->logger.debug(nano::log::type::bootstrap_legacy, "Requesting new frontiers after: {}", start_account.to_account ()); + // Requesting new frontiers run_start (lock); } - else - { - node->logger.try_log ("Finished flushing unchecked blocks"); - } } if (!stopped) { - node->logger.try_log ("Completed legacy pulls"); + node->logger.debug(nano::log::type::bootstrap_legacy, "Completed legacy pulls"); + if (!node->flags.disable_bootstrap_bulk_push_client) { request_push (lock); diff --git a/nano/node/cli.cpp b/nano/node/cli.cpp index 721edd67ff..ce9369fc14 100644 --- a/nano/node/cli.cpp +++ b/nano/node/cli.cpp @@ -58,7 +58,7 @@ void nano::add_node_options (boost::program_options::options_description & descr ("rebuild_database", "Rebuild LMDB database with vacuum for best compaction") ("migrate_database_lmdb_to_rocksdb", "Migrates LMDB database to RocksDB") ("diagnostics", "Run internal diagnostics") - ("generate_config", boost::program_options::value (), "Write configuration to stdout, populated with defaults suitable for this system. Pass the configuration type node, rpc or tls. See also use_defaults.") + ("generate_config", boost::program_options::value (), "Write configuration to stdout, populated with defaults suitable for this system. Pass the configuration type node, rpc or log. See also use_defaults.") ("key_create", "Generates a adhoc random keypair and prints it to stdout") ("key_expand", "Derive public key and account number from ") ("wallet_add_adhoc", "Insert in to ") @@ -254,6 +254,9 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map if (vm.count ("initialize")) { + // TODO: --config flag overrides are not taken into account here + nano::logger::initialize (nano::log_config::daemon_default (), data_path); + auto node_flags = nano::inactive_node_flag_defaults (); node_flags.read_only = false; nano::update_flags (node_flags, vm); @@ -671,6 +674,12 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map nano::rpc_config config{ nano::dev::network_params.network }; config.serialize_toml (toml); } + else if (type == "log") + { + valid_type = true; + nano::log_config config = nano::log_config::sample_config (); + config.serialize_toml (toml); + } else if (type == "tls") { valid_type = true; @@ -730,7 +739,7 @@ std::error_code nano::handle_node_options (boost::program_options::variables_map environment.dump (std::cout); std::stringstream stream; environment.dump (stream); - inactive_node->node->logger.always_log (stream.str ()); + std::cout << stream.str () << std::endl; } else { diff --git a/nano/node/confirmation_height_bounded.cpp b/nano/node/confirmation_height_bounded.cpp index a2301f891d..9136dc7c5d 100644 --- a/nano/node/confirmation_height_bounded.cpp +++ b/nano/node/confirmation_height_bounded.cpp @@ -1,7 +1,5 @@ -#include #include #include -#include #include #include #include @@ -12,11 +10,10 @@ #include -nano::confirmation_height_bounded::confirmation_height_bounded (nano::ledger & ledger_a, nano::write_database_queue & write_database_queue_a, std::chrono::milliseconds batch_separate_pending_min_time_a, nano::logging const & logging_a, nano::logger_mt & logger_a, std::atomic & stopped_a, uint64_t & batch_write_size_a, std::function> const &)> const & notify_observers_callback_a, std::function const & notify_block_already_cemented_observers_callback_a, std::function const & awaiting_processing_size_callback_a) : +nano::confirmation_height_bounded::confirmation_height_bounded (nano::ledger & ledger_a, nano::write_database_queue & write_database_queue_a, std::chrono::milliseconds batch_separate_pending_min_time_a, nano::logger & logger_a, std::atomic & stopped_a, uint64_t & batch_write_size_a, std::function> const &)> const & notify_observers_callback_a, std::function const & notify_block_already_cemented_observers_callback_a, std::function const & awaiting_processing_size_callback_a) : ledger (ledger_a), write_database_queue (write_database_queue_a), batch_separate_pending_min_time (batch_separate_pending_min_time_a), - logging (logging_a), logger (logger_a), stopped (stopped_a), batch_write_size (batch_write_size_a), @@ -101,9 +98,8 @@ void nano::confirmation_height_bounded::process (std::shared_ptr or } else { - auto error_str = (boost::format ("Ledger mismatch trying to set confirmation height for block %1% (bounded processor)") % current.to_string ()).str (); - logger.always_log (error_str); - std::cerr << error_str << std::endl; + logger.critical (nano::log::type::conf_processor_bounded, "Ledger mismatch trying to set confirmation height for block {} (bounded processor)", current.to_string ()); + release_assert (block); } } @@ -433,9 +429,8 @@ void nano::confirmation_height_bounded::cement_blocks (nano::write_guard & scope { if (!block) { - auto error_str = (boost::format ("Failed to write confirmation height for block %1% (bounded processor)") % new_cemented_frontier.to_string ()).str (); - logger.always_log (error_str); - std::cerr << error_str << std::endl; + logger.critical (nano::log::type::conf_processor_bounded, "Failed to write confirmation height for block {} (bounded processor)", new_cemented_frontier.to_string ()); + // Undo any blocks about to be cemented from this account for this pending write. cemented_blocks.erase (cemented_blocks.end () - num_blocks_iterated, cemented_blocks.end ()); error = true; @@ -455,10 +450,6 @@ void nano::confirmation_height_bounded::cement_blocks (nano::write_guard & scope total_blocks_cemented += num_blocks_cemented; write_confirmation_height (num_blocks_cemented, start_height + total_blocks_cemented - 1, new_cemented_frontier); transaction.commit (); - if (logging.timing_logging ()) - { - logger.always_log (boost::str (boost::format ("Cemented %1% blocks in %2% %3% (bounded processor)") % cemented_blocks.size () % time_spent_cementing % cemented_batch_timer.unit ())); - } // Update the maximum amount of blocks to write next time based on the time it took to cement this batch. if (time_spent_cementing > maximum_batch_write_time) @@ -521,11 +512,8 @@ void nano::confirmation_height_bounded::cement_blocks (nano::write_guard & scope --pending_writes_size; } } - auto time_spent_cementing = cemented_batch_timer.since_start ().count (); - if (logging.timing_logging () && time_spent_cementing > 50) - { - logger.always_log (boost::str (boost::format ("Cemented %1% blocks in %2% %3% (bounded processor)") % cemented_blocks.size () % time_spent_cementing % cemented_batch_timer.unit ())); - } + + auto time_spent_cementing = cemented_batch_timer.since_start (); // Scope guard could have been released earlier (0 cemented_blocks would indicate that) if (scoped_write_guard_a.is_owned () && !cemented_blocks.empty ()) @@ -537,7 +525,8 @@ void nano::confirmation_height_bounded::cement_blocks (nano::write_guard & scope // Bail if there was an error. This indicates that there was a fatal issue with the ledger // (the blocks probably got rolled back when they shouldn't have). release_assert (!error); - if (time_spent_cementing > maximum_batch_write_time) + + if (time_spent_cementing.count () > maximum_batch_write_time) { // Reduce (unless we have hit a floor) batch_write_size = std::max (minimum_batch_write_size, batch_write_size - amount_to_change); diff --git a/nano/node/confirmation_height_bounded.hpp b/nano/node/confirmation_height_bounded.hpp index c176b41686..a5052b1452 100644 --- a/nano/node/confirmation_height_bounded.hpp +++ b/nano/node/confirmation_height_bounded.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -11,15 +12,14 @@ namespace nano { class ledger; -class logging; -class logger_mt; class write_database_queue; class write_guard; class confirmation_height_bounded final { public: - confirmation_height_bounded (nano::ledger &, nano::write_database_queue &, std::chrono::milliseconds batch_separate_pending_min_time, nano::logging const &, nano::logger_mt &, std::atomic & stopped, uint64_t & batch_write_size, std::function> const &)> const & cemented_callback, std::function const & already_cemented_callback, std::function const & awaiting_processing_size_query); + confirmation_height_bounded (nano::ledger &, nano::write_database_queue &, std::chrono::milliseconds batch_separate_pending_min_time, nano::logger &, std::atomic & stopped, uint64_t & batch_write_size, std::function> const &)> const & cemented_callback, std::function const & already_cemented_callback, std::function const & awaiting_processing_size_query); + bool pending_empty () const; void clear_process_vars (); void process (std::shared_ptr original_block); @@ -121,8 +121,7 @@ class confirmation_height_bounded final nano::ledger & ledger; nano::write_database_queue & write_database_queue; std::chrono::milliseconds batch_separate_pending_min_time; - nano::logging const & logging; - nano::logger_mt & logger; + nano::logger & logger; std::atomic & stopped; uint64_t & batch_write_size; std::function> const &)> notify_observers_callback; diff --git a/nano/node/confirmation_height_processor.cpp b/nano/node/confirmation_height_processor.cpp index 6cf9772999..4b9d9d82a6 100644 --- a/nano/node/confirmation_height_processor.cpp +++ b/nano/node/confirmation_height_processor.cpp @@ -1,4 +1,3 @@ -#include #include #include #include @@ -9,16 +8,16 @@ #include -nano::confirmation_height_processor::confirmation_height_processor (nano::ledger & ledger_a, nano::write_database_queue & write_database_queue_a, std::chrono::milliseconds batch_separate_pending_min_time_a, nano::logging const & logging_a, nano::logger_mt & logger_a, boost::latch & latch, confirmation_height_mode mode_a) : +nano::confirmation_height_processor::confirmation_height_processor (nano::ledger & ledger_a, nano::write_database_queue & write_database_queue_a, std::chrono::milliseconds batch_separate_pending_min_time_a, nano::logger & logger_a, boost::latch & latch, confirmation_height_mode mode_a) : ledger (ledger_a), write_database_queue (write_database_queue_a), unbounded_processor ( - ledger_a, write_database_queue_a, batch_separate_pending_min_time_a, logging_a, logger_a, stopped, batch_write_size, + ledger_a, write_database_queue_a, batch_separate_pending_min_time_a, logger_a, stopped, batch_write_size, /* cemented_callback */ [this] (auto & cemented_blocks) { this->notify_cemented (cemented_blocks); }, /* already cemented_callback */ [this] (auto const & block_hash_a) { this->notify_already_cemented (block_hash_a); }, /* awaiting_processing_size_query */ [this] () { return this->awaiting_processing_size (); }), bounded_processor ( - ledger_a, write_database_queue_a, batch_separate_pending_min_time_a, logging_a, logger_a, stopped, batch_write_size, + ledger_a, write_database_queue_a, batch_separate_pending_min_time_a, logger_a, stopped, batch_write_size, /* cemented_callback */ [this] (auto & cemented_blocks) { this->notify_cemented (cemented_blocks); }, /* already cemented_callback */ [this] (auto const & block_hash_a) { this->notify_already_cemented (block_hash_a); }, /* awaiting_processing_size_query */ [this] () { return this->awaiting_processing_size (); }), diff --git a/nano/node/confirmation_height_processor.hpp b/nano/node/confirmation_height_processor.hpp index 88f2d1a15b..d31267833f 100644 --- a/nano/node/confirmation_height_processor.hpp +++ b/nano/node/confirmation_height_processor.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -24,14 +25,14 @@ class latch; namespace nano { class ledger; -class logger_mt; class write_database_queue; class confirmation_height_processor final { public: - confirmation_height_processor (nano::ledger &, nano::write_database_queue &, std::chrono::milliseconds, nano::logging const &, nano::logger_mt &, boost::latch & initialized_latch, confirmation_height_mode = confirmation_height_mode::automatic); + confirmation_height_processor (nano::ledger &, nano::write_database_queue &, std::chrono::milliseconds, nano::logger &, boost::latch & initialized_latch, confirmation_height_mode = confirmation_height_mode::automatic); ~confirmation_height_processor (); + void pause (); void unpause (); void stop (); diff --git a/nano/node/confirmation_height_unbounded.cpp b/nano/node/confirmation_height_unbounded.cpp index 9a458b9c8c..8f50f39dcb 100644 --- a/nano/node/confirmation_height_unbounded.cpp +++ b/nano/node/confirmation_height_unbounded.cpp @@ -1,7 +1,5 @@ -#include #include #include -#include #include #include #include @@ -12,11 +10,10 @@ #include -nano::confirmation_height_unbounded::confirmation_height_unbounded (nano::ledger & ledger_a, nano::write_database_queue & write_database_queue_a, std::chrono::milliseconds batch_separate_pending_min_time_a, nano::logging const & logging_a, nano::logger_mt & logger_a, std::atomic & stopped_a, uint64_t & batch_write_size_a, std::function> const &)> const & notify_observers_callback_a, std::function const & notify_block_already_cemented_observers_callback_a, std::function const & awaiting_processing_size_callback_a) : +nano::confirmation_height_unbounded::confirmation_height_unbounded (nano::ledger & ledger_a, nano::write_database_queue & write_database_queue_a, std::chrono::milliseconds batch_separate_pending_min_time_a, nano::logger & logger_a, std::atomic & stopped_a, uint64_t & batch_write_size_a, std::function> const &)> const & notify_observers_callback_a, std::function const & notify_block_already_cemented_observers_callback_a, std::function const & awaiting_processing_size_callback_a) : ledger (ledger_a), write_database_queue (write_database_queue_a), batch_separate_pending_min_time (batch_separate_pending_min_time_a), - logging (logging_a), logger (logger_a), stopped (stopped_a), batch_write_size (batch_write_size_a), @@ -77,9 +74,7 @@ void nano::confirmation_height_unbounded::process (std::shared_ptr } if (!block) { - auto error_str = (boost::format ("Ledger mismatch trying to set confirmation height for block %1% (unbounded processor)") % current.to_string ()).str (); - logger.always_log (error_str); - std::cerr << error_str << std::endl; + logger.critical (nano::log::type::conf_processor_unbounded, "Ledger mismatch trying to set confirmation height for block {} (unbounded processor)", current.to_string ()); } release_assert (block); @@ -395,9 +390,8 @@ void nano::confirmation_height_unbounded::cement_blocks (nano::write_guard & sco } else { - auto error_str = (boost::format ("Failed to write confirmation height for block %1% (unbounded processor)") % pending.hash.to_string ()).str (); - logger.always_log (error_str); - std::cerr << error_str << std::endl; + logger.critical (nano::log::type::conf_processor_unbounded, "Failed to write confirmation height for block {} (unbounded processor)", pending.hash.to_string ()); + error = true; break; } @@ -424,10 +418,6 @@ void nano::confirmation_height_unbounded::cement_blocks (nano::write_guard & sco } auto time_spent_cementing = cemented_batch_timer.since_start ().count (); - if (logging.timing_logging () && time_spent_cementing > 50) - { - logger.always_log (boost::str (boost::format ("Cemented %1% blocks in %2% %3% (unbounded processor)") % cemented_blocks.size () % time_spent_cementing % cemented_batch_timer.unit ())); - } scoped_write_guard_a.release (); notify_observers_callback (cemented_blocks); diff --git a/nano/node/confirmation_height_unbounded.hpp b/nano/node/confirmation_height_unbounded.hpp index 0af353e69a..ea3e7e52a1 100644 --- a/nano/node/confirmation_height_unbounded.hpp +++ b/nano/node/confirmation_height_unbounded.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -12,15 +13,14 @@ namespace nano { class ledger; -class logging; -class logger_mt; class write_database_queue; class write_guard; class confirmation_height_unbounded final { public: - confirmation_height_unbounded (nano::ledger &, nano::write_database_queue &, std::chrono::milliseconds batch_separate_pending_min_time, nano::logging const &, nano::logger_mt &, std::atomic & stopped, uint64_t & batch_write_size, std::function> const &)> const & cemented_callback, std::function const & already_cemented_callback, std::function const & awaiting_processing_size_query); + confirmation_height_unbounded (nano::ledger &, nano::write_database_queue &, std::chrono::milliseconds batch_separate_pending_min_time, nano::logger &, std::atomic & stopped, uint64_t & batch_write_size, std::function> const &)> const & cemented_callback, std::function const & already_cemented_callback, std::function const & awaiting_processing_size_query); + bool pending_empty () const; void clear_process_vars (); void process (std::shared_ptr original_block); @@ -98,10 +98,9 @@ class confirmation_height_unbounded final nano::ledger & ledger; nano::write_database_queue & write_database_queue; std::chrono::milliseconds batch_separate_pending_min_time; - nano::logger_mt & logger; + nano::logger & logger; std::atomic & stopped; uint64_t & batch_write_size; - nano::logging const & logging; std::function> const &)> notify_observers_callback; std::function notify_block_already_cemented_observers_callback; diff --git a/nano/node/distributed_work.cpp b/nano/node/distributed_work.cpp index b710c41552..7d1849fb9b 100644 --- a/nano/node/distributed_work.cpp +++ b/nano/node/distributed_work.cpp @@ -94,7 +94,8 @@ void nano::distributed_work::start () } else { - this_l->node.logger.try_log (boost::str (boost::format ("Error resolving work peer: %1%:%2%: %3%") % peer.first % peer.second % ec.message ())); + this_l->node.logger.error (nano::log::type::distributed_work, "Error resolving work peer: {}:{} ({})", peer.first, peer.second, ec.message ()); + this_l->failure (); } }); @@ -166,7 +167,11 @@ void nano::distributed_work::do_request (nano::tcp_endpoint const & endpoint_a) } else if (ec) { - this_l->node.logger.try_log (boost::str (boost::format ("Work peer responded with an error %1% %2%: %3%") % connection->endpoint.address () % connection->endpoint.port () % connection->response.result ())); + this_l->node.logger.error (nano::log::type::distributed_work, "Work peer responded with an error {}:{} ({})", + nano::util::to_str (connection->endpoint.address ()), + connection->endpoint.port (), + ec.message ()); + this_l->add_bad_peer (connection->endpoint); this_l->failure (); } @@ -180,7 +185,11 @@ void nano::distributed_work::do_request (nano::tcp_endpoint const & endpoint_a) } else if (ec && ec != boost::system::errc::operation_canceled) { - this_l->node.logger.try_log (boost::str (boost::format ("Unable to write to work_peer %1% %2%: %3% (%4%)") % connection->endpoint.address () % connection->endpoint.port () % ec.message () % ec.value ())); + this_l->node.logger.error (nano::log::type::distributed_work, "Unable to write to work peer {}:{} ({})", + nano::util::to_str (connection->endpoint.address ()), + connection->endpoint.port (), + ec.message ()); + this_l->add_bad_peer (connection->endpoint); this_l->failure (); } @@ -188,7 +197,11 @@ void nano::distributed_work::do_request (nano::tcp_endpoint const & endpoint_a) } else if (ec && ec != boost::system::errc::operation_canceled) { - this_l->node.logger.try_log (boost::str (boost::format ("Unable to connect to work_peer %1% %2%: %3% (%4%)") % connection->endpoint.address () % connection->endpoint.port () % ec.message () % ec.value ())); + this_l->node.logger.error (nano::log::type::distributed_work, "Unable to connect to work peer {}:{} ({})", + nano::util::to_str (connection->endpoint.address ()), + connection->endpoint.port (), + ec.message ()); + this_l->add_bad_peer (connection->endpoint); this_l->failure (); } @@ -219,7 +232,10 @@ void nano::distributed_work::do_cancel (nano::tcp_endpoint const & endpoint_a) [this_l, peer_cancel, cancelling_l] (boost::system::error_code const & ec, std::size_t bytes_transferred) { if (ec && ec != boost::system::errc::operation_canceled) { - this_l->node.logger.try_log (boost::str (boost::format ("Unable to send work_cancel to work_peer %1% %2%: %3% (%4%)") % cancelling_l->endpoint.address () % cancelling_l->endpoint.port () % ec.message () % ec.value ())); + this_l->node.logger.error (nano::log::type::distributed_work, "Unable to send work cancel to work peer {}:{} ({})", + nano::util::to_str (cancelling_l->endpoint.address ()), + cancelling_l->endpoint.port (), + ec.message ()); } })); } @@ -247,17 +263,28 @@ void nano::distributed_work::success (std::string const & body_a, nano::tcp_endp } else { - node.logger.try_log (boost::str (boost::format ("Incorrect work response from %1%:%2% for root %3% with diffuculty %4%: %5%") % endpoint_a.address () % endpoint_a.port () % request.root.to_string () % nano::to_string_hex (request.difficulty) % work_text)); + node.logger.error (nano::log::type::distributed_work, "Incorrect work response from {}:{} for root {} with diffuculty {}: {}", + nano::util::to_str (endpoint_a.address ()), + endpoint_a.port (), + request.root.to_string (), + nano::to_string_hex (request.difficulty), + work_text); } } else { - node.logger.try_log (boost::str (boost::format ("Work response from %1%:%2% wasn't a number: %3%") % endpoint_a.address () % endpoint_a.port () % work_text)); + node.logger.error (nano::log::type::distributed_work, "Work response from {}:{} wasn't a number: {}", + nano::util::to_str (endpoint_a.address ()), + endpoint_a.port (), + work_text); } } catch (...) { - node.logger.try_log (boost::str (boost::format ("Work response from %1%:%2% wasn't parsable: %3%") % endpoint_a.address () % endpoint_a.port () % body_a)); + node.logger.error (nano::log::type::distributed_work, "Work response from {}:{} wasn't parsable: {}", + nano::util::to_str (endpoint_a.address ()), + endpoint_a.port (), + body_a); } if (error) { @@ -290,12 +317,18 @@ void nano::distributed_work::stop_once (bool const local_stop_a) connection_l->socket.close (ec); if (ec) { - this_l->node.logger.try_log (boost::str (boost::format ("Error closing socket with work_peer %1% %2%: %3%") % connection_l->endpoint.address () % connection_l->endpoint.port () % ec.message () % ec.value ())); + this_l->node.logger.error (nano::log::type::distributed_work, "Error closing socket with work peer: {}:{} ({})", + nano::util::to_str (connection_l->endpoint.address ()), + connection_l->endpoint.port (), + ec.message ()); } } else { - this_l->node.logger.try_log (boost::str (boost::format ("Error cancelling operation with work_peer %1% %2%: %3%") % connection_l->endpoint.address () % connection_l->endpoint.port () % ec.message () % ec.value ())); + this_l->node.logger.error (nano::log::type::distributed_work, "Error cancelling operation with work peer: {}:{} ({})", + nano::util::to_str (connection_l->endpoint.address ()), + connection_l->endpoint.port (), + ec.message ()); } } })); @@ -310,6 +343,13 @@ void nano::distributed_work::set_once (uint64_t const work_a, std::string const if (!finished.exchange (true)) { elapsed.stop (); + + node.logger.info (nano::log::type::distributed_work, "Work generation for {}, with a threshold difficulty of {} (multiplier {}x) complete: {} ms", + request.root.to_string (), + nano::to_string_hex (request.difficulty), + nano::to_string (nano::difficulty::to_multiplier (request.difficulty, node.default_difficulty (request.version)), 2), + elapsed.value ().count ()); + status = work_generation_status::success; if (request.callback) { @@ -317,12 +357,6 @@ void nano::distributed_work::set_once (uint64_t const work_a, std::string const } winner = source_a; work_result = work_a; - if (node.config.logging.work_generation_time ()) - { - boost::format unformatted_l ("Work generation for %1%, with a threshold difficulty of %2% (multiplier %3%x) complete: %4% ms"); - auto multiplier_text_l (nano::to_string (nano::difficulty::to_multiplier (request.difficulty, node.default_difficulty (request.version)), 2)); - node.logger.try_log (boost::str (unformatted_l % request.root.to_string () % nano::to_string_hex (request.difficulty) % multiplier_text_l % elapsed.value ().count ())); - } } } @@ -331,16 +365,17 @@ void nano::distributed_work::cancel () if (!finished.exchange (true)) { elapsed.stop (); + + node.logger.info (nano::log::type::distributed_work, "Work generation for {} was cancelled after {} ms", + request.root.to_string (), + elapsed.value ().count ()); + status = work_generation_status::cancelled; if (request.callback) { request.callback (boost::none); } stop_once (true); - if (node.config.logging.work_generation_time ()) - { - node.logger.try_log (boost::str (boost::format ("Work generation for %1% was cancelled after %2% ms") % request.root.to_string () % elapsed.value ().count ())); - } } } @@ -359,11 +394,12 @@ void nano::distributed_work::handle_failure () node.unresponsive_work_peers = true; if (!local_generation_started && !finished.exchange (true)) { + node.logger.info (nano::log::type::distributed_work, "Work peer(s) failed to generate work for root {}, retrying... (backoff: {}s)", + request.root.to_string (), + backoff.count ()); + status = work_generation_status::failure_peers; - if (backoff == std::chrono::seconds (1) && node.config.logging.work_generation_time ()) - { - node.logger.always_log ("Work peer(s) failed to generate work for root ", request.root.to_string (), ", retrying..."); - } + auto now (std::chrono::steady_clock::now ()); std::weak_ptr node_weak (node.shared ()); auto next_backoff (std::min (backoff * 2, std::chrono::seconds (5 * 60))); diff --git a/nano/node/election.cpp b/nano/node/election.cpp index 93c681c706..ab4aab345c 100644 --- a/nano/node/election.cpp +++ b/nano/node/election.cpp @@ -250,10 +250,6 @@ bool nano::election::transition_time (nano::confirmation_solicitor & solicitor_a if (!state_change (state_m, nano::election::state_t::expired_unconfirmed)) { result = true; // Return true to indicate this election should be cleaned up - if (node.config.logging.election_expiration_tally_logging ()) - { - log_votes (tally_impl (), "Election expired: "); - } status.type = nano::election_status_type::stopped; } } @@ -375,10 +371,6 @@ void nano::election::confirm_if_quorum (nano::unique_lock & lock_a) } if (!node.ledger.cache.final_votes_confirmation_canary.load () || final_weight >= node.online_reps.delta ()) { - if (node.config.logging.vote_logging () || (node.config.logging.election_fork_tally_logging () && last_blocks.size () > 1)) - { - log_votes (tally_l); - } confirm_once (lock_a, nano::election_status_type::active_confirmed_quorum); } } @@ -419,25 +411,6 @@ nano::election_status nano::election::set_status_type (nano::election_status_typ return status_l; } -void nano::election::log_votes (nano::tally_t const & tally_a, std::string const & prefix_a) const -{ - std::stringstream tally; - std::string line_end (node.config.logging.single_line_record () ? "\t" : "\n"); - tally << boost::str (boost::format ("%1%%2%Vote tally for root %3%, final weight:%4%") % prefix_a % line_end % root.to_string () % final_weight); - for (auto i (tally_a.begin ()), n (tally_a.end ()); i != n; ++i) - { - tally << boost::str (boost::format ("%1%Block %2% weight %3%") % line_end % i->second->hash ().to_string () % i->first.convert_to ()); - } - for (auto i (last_votes.begin ()), n (last_votes.end ()); i != n; ++i) - { - if (i->first != nullptr) - { - tally << boost::str (boost::format ("%1%%2% %3% %4%") % line_end % i->first.to_account () % std::to_string (i->second.timestamp) % i->second.hash.to_string ()); - } - } - node.logger.try_log (tally.str ()); -} - std::shared_ptr nano::election::find (nano::block_hash const & hash_a) const { std::shared_ptr result; diff --git a/nano/node/election.hpp b/nano/node/election.hpp index b49f946540..8c025f654a 100644 --- a/nano/node/election.hpp +++ b/nano/node/election.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -62,6 +63,9 @@ enum class election_behavior nano::stat::detail to_stat_detail (nano::election_behavior); +// map of vote weight per block, ordered greater first +using tally_t = std::map, std::greater>; + struct election_extended_status final { nano::election_status status; @@ -120,7 +124,6 @@ class election final : public std::enable_shared_from_this std::shared_ptr winner () const; std::atomic confirmation_request_count{ 0 }; - void log_votes (nano::tally_t const &, std::string const & = "") const; nano::tally_t tally () const; bool have_quorum (nano::tally_t const &) const; diff --git a/nano/node/epoch_upgrader.cpp b/nano/node/epoch_upgrader.cpp index a731bb4da8..df30195032 100644 --- a/nano/node/epoch_upgrader.cpp +++ b/nano/node/epoch_upgrader.cpp @@ -2,7 +2,7 @@ #include #include -nano::epoch_upgrader::epoch_upgrader (nano::node & node_a, nano::ledger & ledger_a, nano::store::component & store_a, nano::network_params & network_params_a, nano::logger_mt & logger_a) : +nano::epoch_upgrader::epoch_upgrader (nano::node & node_a, nano::ledger & ledger_a, nano::store::component & store_a, nano::network_params & network_params_a, nano::logger & logger_a) : node{ node_a }, ledger{ ledger_a }, store{ store_a }, @@ -59,7 +59,12 @@ void nano::epoch_upgrader::upgrade_impl (nano::raw_key const & prv_a, nano::epoc else { bool fork (result == nano::process_result::fork); - logger.always_log (boost::str (boost::format ("Failed to upgrade account %1%. Valid signature: %2%. Valid work: %3%. Block processor fork: %4%") % account_a.to_account () % valid_signature % valid_work % fork)); + + logger.error (nano::log::type::epoch_upgrader, "Failed to upgrade account {} (valid signature: {}, valid work: {}, fork: {})", + account_a.to_account (), + valid_signature, + valid_work, + fork); } }; @@ -181,12 +186,16 @@ void nano::epoch_upgrader::upgrade_impl (nano::raw_key const & prv_a, nano::epoc if (!accounts_list.empty ()) { - logger.always_log (boost::str (boost::format ("%1% accounts were upgraded to new epoch, %2% remain...") % total_upgraded_accounts % (accounts_list.size () - upgraded_accounts))); + logger.info (nano::log::type::epoch_upgrader, "{} accounts were upgraded to new epoch, {} remain...", + total_upgraded_accounts, + accounts_list.size () - upgraded_accounts); + accounts_list.clear (); } else { - logger.always_log (boost::str (boost::format ("%1% total accounts were upgraded to new epoch") % total_upgraded_accounts)); + logger.info (nano::log::type::epoch_upgrader, "{} total accounts were upgraded to new epoch", total_upgraded_accounts); + finished_accounts = true; } } @@ -284,11 +293,12 @@ void nano::epoch_upgrader::upgrade_impl (nano::raw_key const & prv_a, nano::epoc // Repeat if some pending accounts were upgraded if (upgraded_pending != 0) { - logger.always_log (boost::str (boost::format ("%1% unopened accounts with pending blocks were upgraded to new epoch...") % total_upgraded_pending)); + logger.info (nano::log::type::epoch_upgrader, "{} unopened accounts with pending blocks were upgraded to new epoch...", total_upgraded_pending); } else { - logger.always_log (boost::str (boost::format ("%1% total unopened accounts with pending blocks were upgraded to new epoch") % total_upgraded_pending)); + logger.info (nano::log::type::epoch_upgrader, "{} total unopened accounts with pending blocks were upgraded to new epoch", total_upgraded_pending); + finished_pending = true; } } @@ -296,5 +306,5 @@ void nano::epoch_upgrader::upgrade_impl (nano::raw_key const & prv_a, nano::epoc finished_upgrade = (total_upgraded_accounts == 0) && (total_upgraded_pending == 0); } - logger.always_log ("Epoch upgrade is completed"); + logger.info (nano::log::type::epoch_upgrader, "Epoch upgrade is completed"); } diff --git a/nano/node/epoch_upgrader.hpp b/nano/node/epoch_upgrader.hpp index ab0499fb14..d9bccad98e 100644 --- a/nano/node/epoch_upgrader.hpp +++ b/nano/node/epoch_upgrader.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -15,12 +16,11 @@ namespace store class component; } class network_params; -class logger_mt; class epoch_upgrader final { public: - epoch_upgrader (nano::node &, nano::ledger &, nano::store::component &, nano::network_params &, nano::logger_mt &); + epoch_upgrader (nano::node &, nano::ledger &, nano::store::component &, nano::network_params &, nano::logger &); bool start (nano::raw_key const & prv, nano::epoch epoch, uint64_t count_limit, uint64_t threads); void stop (); @@ -30,7 +30,7 @@ class epoch_upgrader final nano::ledger & ledger; nano::store::component & store; nano::network_params & network_params; - nano::logger_mt & logger; + nano::logger & logger; private: void upgrade_impl (nano::raw_key const & prv, nano::epoch epoch, uint64_t count_limit, uint64_t threads); diff --git a/nano/node/gap_cache.cpp b/nano/node/gap_cache.cpp index 0153455810..1ef81dd598 100644 --- a/nano/node/gap_cache.cpp +++ b/nano/node/gap_cache.cpp @@ -100,7 +100,7 @@ void nano::gap_cache::bootstrap_start (nano::block_hash const & hash_a) { if (!node_l->bootstrap_initiator.in_progress ()) { - node_l->logger.try_log (boost::str (boost::format ("Missing block %1% which has enough votes to warrant lazy bootstrapping it") % hash_a.to_string ())); + node_l->logger.debug (nano::log::type::gap_cache, "Block {} has enough votes to warrant lazy bootstrapping it", hash_a.to_string ()); } if (!node_l->flags.disable_lazy_bootstrap) { diff --git a/nano/node/ipc/ipc_broker.cpp b/nano/node/ipc/ipc_broker.cpp index 5176b3b131..15ba718cca 100644 --- a/nano/node/ipc/ipc_broker.cpp +++ b/nano/node/ipc/ipc_broker.cpp @@ -65,13 +65,13 @@ void nano::ipc::broker::start () } catch (nano::error const & err) { - this_l->node.logger.always_log ("IPC: could not broadcast message: ", err.get_message ()); + this_l->node.logger.error (nano::log::type::ipc, "Could not broadcast message: {}", err.get_message ()); } }); } template -void subscribe_or_unsubscribe (nano::logger_mt & logger, COLL & subscriber_collection, std::weak_ptr const & subscriber_a, TOPIC_TYPE topic_a) +void subscribe_or_unsubscribe (nano::logger & logger, COLL & subscriber_collection, std::weak_ptr const & subscriber_a, TOPIC_TYPE topic_a) { // Evict subscribers from dead sessions. Also remove current subscriber if unsubscribing. subscriber_collection.erase (std::remove_if (subscriber_collection.begin (), subscriber_collection.end (), @@ -85,7 +85,7 @@ void subscribe_or_unsubscribe (nano::logger_mt & logger, COLL & subscriber_colle remove = topic_a->unsubscribe && subscriber_l->get_id () == calling_subscriber_l->get_id (); if (remove) { - logger.always_log ("IPC: unsubscription from subscriber #", calling_subscriber_l->get_id ()); + logger.info (nano::log::type::ipc, "Subscriber ubsubscribed #{}", calling_subscriber_l->get_id ()); } } } diff --git a/nano/node/ipc/ipc_server.cpp b/nano/node/ipc/ipc_server.cpp index 9eaf1e7509..ab5b39ef02 100644 --- a/nano/node/ipc/ipc_server.cpp +++ b/nano/node/ipc/ipc_server.cpp @@ -23,8 +23,6 @@ #include -using namespace boost::log; - namespace { /** @@ -39,10 +37,7 @@ class session final : public nano::ipc::socket_base, public std::enable_shared_f server (server_a), node (server_a.node), session_id (server_a.id_dispenser.fetch_add (1)), io_ctx (io_ctx_a), strand (io_ctx_a.get_executor ()), socket (io_ctx_a), config_transport (config_transport_a) { - if (node.config.logging.log_ipc ()) - { - node.logger.always_log ("IPC: created session with id: ", session_id.load ()); - } + node.logger.debug (nano::log::type::ipc, "Creating session with id: ", session_id.load ()); } ~session () @@ -234,10 +229,7 @@ class session final : public nano::ipc::socket_base, public std::enable_shared_f this_l->timer_cancel (); if (ec == boost::asio::error::broken_pipe || ec == boost::asio::error::connection_aborted || ec == boost::asio::error::connection_reset || ec == boost::asio::error::connection_refused) { - if (this_l->node.config.logging.log_ipc ()) - { - this_l->node.logger.always_log (boost::str (boost::format ("IPC: error reading %1% ") % ec.message ())); - } + this_l->node.logger.error (nano::log::type::ipc, "Error reading: ", ec.message ()); } else if (bytes_transferred_a > 0) { @@ -260,10 +252,11 @@ class session final : public nano::ipc::socket_base, public std::enable_shared_f auto buffer (std::make_shared> ()); buffer->insert (buffer->end (), reinterpret_cast (&big), reinterpret_cast (&big) + sizeof (std::uint32_t)); buffer->insert (buffer->end (), body.begin (), body.end ()); - if (this_l->node.config.logging.log_ipc ()) - { - this_l->node.logger.always_log (boost::str (boost::format ("IPC/RPC request %1% completed in: %2% %3%") % request_id_l % this_l->session_timer.stop ().count () % this_l->session_timer.unit ())); - } + + this_l->node.logger.debug (nano::log::type::ipc, "IPC/RPC request {} completed in: {} {}", + request_id_l, + this_l->session_timer.stop ().count (), + this_l->session_timer.unit ()); this_l->timer_start (std::chrono::seconds (this_l->config_transport.io_timeout)); this_l->queued_write (boost::asio::buffer (buffer->data (), buffer->size ()), [this_l, buffer] (boost::system::error_code const & error_a, std::size_t size_a) { @@ -272,9 +265,9 @@ class session final : public nano::ipc::socket_base, public std::enable_shared_f { this_l->read_next_request (); } - else if (this_l->node.config.logging.log_ipc ()) + else { - this_l->node.logger.always_log ("IPC: Write failed: ", error_a.message ()); + this_l->node.logger.error (nano::log::type::ipc, "Write failed: ", error_a.message ()); } }); @@ -307,10 +300,7 @@ class session final : public nano::ipc::socket_base, public std::enable_shared_f this_l->active_encoding = static_cast (encoding); if (this_l->buffer[nano::ipc::preamble_offset::lead] != 'N' || this_l->buffer[nano::ipc::preamble_offset::reserved_1] != 0 || this_l->buffer[nano::ipc::preamble_offset::reserved_2] != 0) { - if (this_l->node.config.logging.log_ipc ()) - { - this_l->node.logger.always_log ("IPC: Invalid preamble"); - } + this_l->node.logger.error (nano::log::type::ipc, "Invalid preamble"); } else if (encoding == static_cast (nano::ipc::payload_encoding::json_v1) || encoding == static_cast (nano::ipc::payload_encoding::json_v1_unsafe)) { @@ -344,10 +334,9 @@ class session final : public nano::ipc::socket_base, public std::enable_shared_f if (encoding == static_cast (nano::ipc::payload_encoding::flatbuffers_json)) { this_l->flatbuffers_handler->process_json (this_l->buffer.data (), this_l->buffer_size, [this_l] (std::shared_ptr const & body) { - if (this_l->node.config.logging.log_ipc ()) - { - this_l->node.logger.always_log (boost::str (boost::format ("IPC/Flatbuffer request completed in: %1% %2%") % this_l->session_timer.stop ().count () % this_l->session_timer.unit ())); - } + this_l->node.logger.debug (nano::log::type::ipc, "IPC/Flatbuffer request completed in: {} {}", + this_l->session_timer.stop ().count (), + this_l->session_timer.unit ()); auto big_endian_length = std::make_shared (boost::endian::native_to_big (static_cast (body->size ()))); boost::array buffers = { @@ -360,9 +349,9 @@ class session final : public nano::ipc::socket_base, public std::enable_shared_f { this_l->read_next_request (); } - else if (this_l->node.config.logging.log_ipc ()) + else { - this_l->node.logger.always_log ("IPC: Write failed: ", error_a.message ()); + this_l->node.logger.error (nano::log::type::ipc, "Write failed: {}", error_a.message ()); } }); }); @@ -370,10 +359,9 @@ class session final : public nano::ipc::socket_base, public std::enable_shared_f else { this_l->flatbuffers_handler->process (this_l->buffer.data (), this_l->buffer_size, [this_l] (std::shared_ptr const & fbb) { - if (this_l->node.config.logging.log_ipc ()) - { - this_l->node.logger.always_log (boost::str (boost::format ("IPC/Flatbuffer request completed in: %1% %2%") % this_l->session_timer.stop ().count () % this_l->session_timer.unit ())); - } + this_l->node.logger.debug (nano::log::type::ipc, "IPC/Flatbuffer request completed in: {} {}", + this_l->session_timer.stop ().count (), + this_l->session_timer.unit ()); auto big_endian_length = std::make_shared (boost::endian::native_to_big (static_cast (fbb->GetSize ()))); boost::array buffers = { @@ -386,9 +374,9 @@ class session final : public nano::ipc::socket_base, public std::enable_shared_f { this_l->read_next_request (); } - else if (this_l->node.config.logging.log_ipc ()) + else { - this_l->node.logger.always_log ("IPC: Write failed: ", error_a.message ()); + this_l->node.logger.error (nano::log::type::ipc, "Write failed: {}", error_a.message ()); } }); }); @@ -396,9 +384,9 @@ class session final : public nano::ipc::socket_base, public std::enable_shared_f }); }); } - else if (this_l->node.config.logging.log_ipc ()) + else { - this_l->node.logger.always_log ("IPC: Unsupported payload encoding"); + this_l->node.logger.error (nano::log::type::ipc, "Unsupported payload encoding"); } }); } @@ -523,7 +511,7 @@ class socket_transport : public nano::ipc::transport } else { - node->logger.always_log ("IPC: acceptor error: ", ec.message ()); + node->logger.error (nano::log::type::ipc, "Acceptor error: ", ec.message ()); } if (ec != boost::asio::error::operation_aborted && acceptor->is_open ()) @@ -532,7 +520,7 @@ class socket_transport : public nano::ipc::transport } else { - node->logger.always_log ("IPC: shutting down"); + node->logger.info (nano::log::type::ipc, "Shutting down"); } }); } @@ -625,7 +613,7 @@ nano::ipc::ipc_server::ipc_server (nano::node & node_a, nano::node_rpc_config co boost::asio::local::stream_protocol::endpoint ep{ node_a.config.ipc_config.transport_domain.path }; transports.push_back (std::make_shared (*this, ep, node_a.config.ipc_config.transport_domain, threads)); #else - node.logger.always_log ("IPC: Domain sockets are not supported on this platform"); + node.logger.error (nano::log::type::ipc_server, "Domain sockets are not supported on this platform"); #endif } @@ -635,7 +623,7 @@ nano::ipc::ipc_server::ipc_server (nano::node & node_a, nano::node_rpc_config co transports.push_back (std::make_shared (*this, boost::asio::ip::tcp::endpoint (boost::asio::ip::tcp::v6 (), node_a.config.ipc_config.transport_tcp.port), node_a.config.ipc_config.transport_tcp, threads)); } - node.logger.always_log ("IPC: server started"); + node.logger.debug (nano::log::type::ipc_server, "Server started"); if (!transports.empty ()) { @@ -644,13 +632,13 @@ nano::ipc::ipc_server::ipc_server (nano::node & node_a, nano::node_rpc_config co } catch (std::runtime_error const & ex) { - node.logger.always_log ("IPC: ", ex.what ()); + node.logger.error (nano::log::type::ipc_server, "Error: {}", ex.what ()); } } nano::ipc::ipc_server::~ipc_server () { - node.logger.always_log ("IPC: server stopped"); + node.logger.debug (nano::log::type::ipc_server, "Server stopped"); } void nano::ipc::ipc_server::stop () @@ -690,9 +678,7 @@ nano::error nano::ipc::ipc_server::reload_access_config () nano::error access_config_error (nano::ipc::read_access_config_toml (node.application_path, access)); if (access_config_error) { - auto error (boost::str (boost::format ("IPC: invalid access configuration file: %1%") % access_config_error.get_message ())); - std::cerr << error << std::endl; - node.logger.always_log (error); + node.logger.error (nano::log::type::ipc_server, "Invalid access configuration file: {}", access_config_error.get_message ()); } return access_config_error; } diff --git a/nano/node/json_handler.cpp b/nano/node/json_handler.cpp index 3e6683da74..58af00f1c5 100644 --- a/nano/node/json_handler.cpp +++ b/nano/node/json_handler.cpp @@ -2955,7 +2955,7 @@ void nano::json_handler::password_change () rpc_l->response_l.put ("changed", error ? "0" : "1"); if (!error) { - rpc_l->node.logger.try_log ("Wallet password changed"); + rpc_l->node.logger.warn (nano::log::type::rpc, "Wallet password changed"); } } } @@ -4773,7 +4773,8 @@ void nano::json_handler::wallet_lock () empty.clear (); wallet->store.password.value_set (empty); response_l.put ("locked", "1"); - node.logger.try_log ("Wallet locked"); + + node.logger.warn (nano::log::type::rpc, "Wallet locked"); } response_errors (); } diff --git a/nano/node/logging.cpp b/nano/node/logging.cpp deleted file mode 100644 index 5dcfb9f816..0000000000 --- a/nano/node/logging.cpp +++ /dev/null @@ -1,344 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#ifdef BOOST_WINDOWS -#else -#define BOOST_LOG_USE_NATIVE_SYSLOG -#include -#endif - -BOOST_LOG_ATTRIBUTE_KEYWORD (severity, "Severity", nano::severity_level) - -boost::shared_ptr> nano::logging::file_sink; -std::atomic_flag nano::logging::logging_already_added ATOMIC_FLAG_INIT; - -void nano::logging::init (std::filesystem::path const & application_path_a) -{ - if (!logging_already_added.test_and_set ()) - { - boost::log::add_common_attributes (); - auto format = boost::log::expressions::stream << boost::log::expressions::attr ("Severity") << boost::log::expressions::smessage; - auto format_with_timestamp = boost::log::expressions::stream << "[" << boost::log::expressions::attr ("TimeStamp") << "]: " << boost::log::expressions::attr ("Severity") << boost::log::expressions::smessage; - - if (log_to_cerr ()) - { - boost::log::add_console_log (std::cerr, boost::log::keywords::format = format_with_timestamp); - } - -#ifdef BOOST_WINDOWS -#else - static auto sys_sink = boost::make_shared> (boost::log::keywords::facility = boost::log::sinks::syslog::user, boost::log::keywords::use_impl = boost::log::sinks::syslog::impl_types::native); - sys_sink->set_formatter (format); - - // Currently only mapping sys log errors - boost::log::sinks::syslog::custom_severity_mapping mapping ("Severity"); - mapping[nano::severity_level::error] = boost::log::sinks::syslog::error; - sys_sink->locked_backend ()->set_severity_mapper (mapping); - - // Only allow messages or error or greater severity to the sys log - sys_sink->set_filter (severity >= nano::severity_level::error); - boost::log::core::get ()->add_sink (sys_sink); -#endif - -//clang-format off -#if BOOST_VERSION < 107000 - if (stable_log_filename) - { - stable_log_filename = false; - std::cerr << "The stable_log_filename config setting is only available when building with Boost 1.70 or later. Reverting to old behavior." << std::endl; - } -#endif - - auto path = application_path_a / "log"; - if (stable_log_filename) - { -#if BOOST_VERSION >= 107000 - auto const file_name = path / "node.log"; - // Logging to node.log and node_ instead of log_.log is deliberate. This way, - // existing log monitoring scripts expecting the old logfile structure will fail immediately instead - // of reading only rotated files with old entries. - file_sink = boost::log::add_file_log (boost::log::keywords::target = path, - boost::log::keywords::file_name = file_name, - boost::log::keywords::target_file_name = path / "node_%Y-%m-%d_%H-%M-%S.%N.log", - boost::log::keywords::open_mode = std::ios_base::out | std::ios_base::app, // append to node.log if it exists - boost::log::keywords::enable_final_rotation = false, // for stable log filenames, don't rotate on destruction - boost::log::keywords::rotation_size = rotation_size, // max file size in bytes before rotation - boost::log::keywords::auto_flush = flush, - boost::log::keywords::scan_method = boost::log::sinks::file::scan_method::scan_matching, - boost::log::keywords::max_size = max_size, // max total size in bytes of all log files - boost::log::keywords::format = format_with_timestamp); - - if (!std::filesystem::exists (file_name)) - { - // Create temp stream to first create the file - std::ofstream stream (file_name.string ()); - } - - // Set permissions before opening otherwise Windows only has read permissions - nano::set_secure_perm_file (file_name); - -#else - debug_assert (false); -#endif - } - else - { - file_sink = boost::log::add_file_log (boost::log::keywords::target = path, - boost::log::keywords::file_name = path / "log_%Y-%m-%d_%H-%M-%S.%N.log", - boost::log::keywords::rotation_size = rotation_size, - boost::log::keywords::auto_flush = flush, - boost::log::keywords::scan_method = boost::log::sinks::file::scan_method::scan_matching, - boost::log::keywords::max_size = max_size, - boost::log::keywords::format = format_with_timestamp); - } - - struct exception_handler - { - void operator() (std::exception const & e) const - { - std::cerr << "Logging exception: " << e.what () << std::endl; - } - }; - - boost::log::core::get ()->set_exception_handler (boost::log::make_exception_handler (exception_handler ())); - } - //clang-format on -} - -void nano::logging::release_file_sink () -{ - if (logging_already_added.test_and_set ()) - { - boost::log::core::get ()->remove_sink (nano::logging::file_sink); - nano::logging::file_sink.reset (); - logging_already_added.clear (); - } -} - -nano::error nano::logging::serialize_toml (nano::tomlconfig & toml) const -{ - toml.put ("ledger", ledger_logging_value, "Log ledger related messages.\ntype:bool"); - toml.put ("ledger_duplicate", ledger_duplicate_logging_value, "Log when a duplicate block is attempted inserted into the ledger.\ntype:bool"); - toml.put ("ledger_rollback", election_fork_tally_logging_value, "Log when a block is replaced in the ledger.\ntype:bool"); - toml.put ("vote", vote_logging_value, "Vote logging. Enabling this option leads to a high volume.\nof log messages which may affect node performance.\ntype:bool"); - toml.put ("rep_crawler", rep_crawler_logging_value, "Rep crawler logging. Enabling this option leads to a high volume.\nof log messages which may affect node performance.\ntype:bool"); - toml.put ("election_expiration", election_expiration_tally_logging_value, "Log election tally on expiration.\ntype:bool"); - toml.put ("election_fork", election_fork_tally_logging_value, "Log election tally when more than one block is seen.\ntype:bool"); - toml.put ("network", network_logging_value, "Log network related messages.\ntype:bool"); - toml.put ("network_timeout", network_timeout_logging_value, "Log TCP timeouts.\ntype:bool"); - toml.put ("network_message", network_message_logging_value, "Log network errors and message details.\ntype:bool"); - toml.put ("network_publish", network_publish_logging_value, "Log publish related network messages.\ntype:bool"); - toml.put ("network_packet", network_packet_logging_value, "Log network packet activity.\ntype:bool"); - toml.put ("network_keepalive", network_keepalive_logging_value, "Log keepalive related messages.\ntype:bool"); - toml.put ("network_node_id_handshake", network_node_id_handshake_logging_value, "Log node-id handshake related messages.\ntype:bool"); - toml.put ("network_telemetry", network_telemetry_logging_value, "Log telemetry related messages.\ntype:bool"); - toml.put ("network_rejected", network_rejected_logging_value, "Log message when a connection is rejected.\ntype:bool"); - toml.put ("node_lifetime_tracing", node_lifetime_tracing_value, "Log node startup and shutdown messages.\ntype:bool"); - toml.put ("insufficient_work", insufficient_work_logging_value, "Log if insufficient work is detected.\ntype:bool"); - toml.put ("log_ipc", log_ipc_value, "Log IPC related activity.\ntype:bool"); - toml.put ("bulk_pull", bulk_pull_logging_value, "Log bulk pull errors and messages.\ntype:bool"); - toml.put ("work_generation_time", work_generation_time_value, "Log work generation timing information.\ntype:bool"); - toml.put ("upnp_details", upnp_details_logging_value, "Log UPNP discovery details..\nWarning: this may include information.\nabout discovered devices, such as product identification. Please review before sharing logs.\ntype:bool"); - toml.put ("timing", timing_logging_value, "Log detailed timing information for various node operations.\ntype:bool"); - toml.put ("active_update", active_update_value, "Log when a block is updated while in active transactions.\ntype:bool"); - toml.put ("election_result", election_result_logging_value, "Log election result when cleaning up election from active election container.\ntype:bool"); - toml.put ("log_to_cerr", log_to_cerr_value, "Log to standard error in addition to the log file. Not recommended for production systems.\ntype:bool"); - toml.put ("max_size", max_size, "Maximum log file size in bytes.\ntype:uint64"); - toml.put ("rotation_size", rotation_size, "Log file rotation size in character count.\ntype:uint64"); - toml.put ("flush", flush, "If enabled, immediately flush new entries to log file.\nWarning: this may negatively affect logging performance.\ntype:bool"); - toml.put ("min_time_between_output", min_time_between_log_output.count (), "Minimum time that must pass for low priority entries to be logged.\nWarning: decreasing this value may result in a very large amount of logs.\ntype:milliseconds"); - toml.put ("single_line_record", single_line_record_value, "Keep log entries on single lines.\ntype:bool"); - toml.put ("stable_log_filename", stable_log_filename, "Append to log/node.log without a timestamp in the filename.\nThe file is not emptied on startup if it exists, but appended to.\ntype:bool"); - - return toml.get_error (); -} - -nano::error nano::logging::deserialize_toml (nano::tomlconfig & toml) -{ - toml.get ("ledger", ledger_logging_value); - toml.get ("ledger_duplicate", ledger_duplicate_logging_value); - toml.get ("ledger_rollback", ledger_rollback_logging_value); - toml.get ("vote", vote_logging_value); - toml.get ("rep_crawler", rep_crawler_logging_value); - toml.get ("election_expiration", election_expiration_tally_logging_value); - toml.get ("election_fork", election_fork_tally_logging_value); - toml.get ("network", network_logging_value); - toml.get ("network_timeout", network_timeout_logging_value); - toml.get ("network_message", network_message_logging_value); - toml.get ("network_publish", network_publish_logging_value); - toml.get ("network_packet", network_packet_logging_value); - toml.get ("network_keepalive", network_keepalive_logging_value); - toml.get ("network_node_id_handshake", network_node_id_handshake_logging_value); - toml.get ("network_telemetry_logging", network_telemetry_logging_value); - toml.get ("network_rejected_logging", network_rejected_logging_value); - toml.get ("node_lifetime_tracing", node_lifetime_tracing_value); - toml.get ("insufficient_work", insufficient_work_logging_value); - toml.get ("log_ipc", log_ipc_value); - toml.get ("bulk_pull", bulk_pull_logging_value); - toml.get ("work_generation_time", work_generation_time_value); - toml.get ("upnp_details", upnp_details_logging_value); - toml.get ("timing", timing_logging_value); - toml.get ("active_update", active_update_value); - toml.get ("election_result", election_result_logging_value); - toml.get ("log_to_cerr", log_to_cerr_value); - toml.get ("flush", flush); - toml.get ("single_line_record", single_line_record_value); - toml.get ("max_size", max_size); - toml.get ("rotation_size", rotation_size); - auto min_time_between_log_output_l = min_time_between_log_output.count (); - toml.get ("min_time_between_output", min_time_between_log_output_l); - min_time_between_log_output = std::chrono::milliseconds (min_time_between_log_output_l); - toml.get ("stable_log_filename", stable_log_filename); - - return toml.get_error (); -} - -bool nano::logging::ledger_logging () const -{ - return ledger_logging_value; -} - -bool nano::logging::ledger_duplicate_logging () const -{ - return ledger_logging () && ledger_duplicate_logging_value; -} - -bool nano::logging::ledger_rollback_logging () const -{ - return ledger_rollback_logging_value; -} - -bool nano::logging::vote_logging () const -{ - return vote_logging_value; -} - -bool nano::logging::rep_crawler_logging () const -{ - return rep_crawler_logging_value; -} - -bool nano::logging::election_expiration_tally_logging () const -{ - return election_expiration_tally_logging_value; -} - -bool nano::logging::election_fork_tally_logging () const -{ - return election_fork_tally_logging_value; -} - -bool nano::logging::network_logging () const -{ - return network_logging_value; -} - -bool nano::logging::network_timeout_logging () const -{ - return network_logging () && network_timeout_logging_value; -} - -bool nano::logging::network_message_logging () const -{ - return network_logging () && network_message_logging_value; -} - -bool nano::logging::network_publish_logging () const -{ - return network_logging () && network_publish_logging_value; -} - -bool nano::logging::network_packet_logging () const -{ - return network_logging () && network_packet_logging_value; -} - -bool nano::logging::network_keepalive_logging () const -{ - return network_logging () && network_keepalive_logging_value; -} - -bool nano::logging::network_node_id_handshake_logging () const -{ - return network_logging () && network_node_id_handshake_logging_value; -} - -bool nano::logging::network_telemetry_logging () const -{ - return network_logging () && network_telemetry_logging_value; -} - -bool nano::logging::network_rejected_logging () const -{ - return network_logging () && network_rejected_logging_value; -} - -bool nano::logging::node_lifetime_tracing () const -{ - return node_lifetime_tracing_value; -} - -bool nano::logging::insufficient_work_logging () const -{ - return network_logging () && insufficient_work_logging_value; -} - -bool nano::logging::log_ipc () const -{ - return network_logging () && log_ipc_value; -} - -bool nano::logging::bulk_pull_logging () const -{ - return network_logging () && bulk_pull_logging_value; -} - -bool nano::logging::callback_logging () const -{ - return network_logging (); -} - -bool nano::logging::work_generation_time () const -{ - return work_generation_time_value; -} - -bool nano::logging::upnp_details_logging () const -{ - return upnp_details_logging_value; -} - -bool nano::logging::timing_logging () const -{ - return timing_logging_value; -} - -bool nano::logging::active_update_logging () const -{ - return active_update_value; -} - -bool nano::logging::election_result_logging () const -{ - return election_result_logging_value; -} - -bool nano::logging::log_to_cerr () const -{ - return log_to_cerr_value; -} - -bool nano::logging::single_line_record () const -{ - return single_line_record_value; -} diff --git a/nano/node/logging.hpp b/nano/node/logging.hpp deleted file mode 100644 index e8f206a51e..0000000000 --- a/nano/node/logging.hpp +++ /dev/null @@ -1,105 +0,0 @@ -#pragma once - -#include - -#include -#include - -#include -#include -#include - -#define FATAL_LOG_PREFIX "FATAL ERROR: " - -namespace boost -{ -BOOST_LOG_OPEN_NAMESPACE -namespace sinks -{ - class text_file_backend; - - template - class synchronous_sink; -} - -BOOST_LOG_CLOSE_NAMESPACE - -} - -namespace nano -{ -class tomlconfig; -class logging final -{ -public: - nano::error serialize_toml (nano::tomlconfig &) const; - nano::error deserialize_toml (nano::tomlconfig &); - bool ledger_logging () const; - bool ledger_duplicate_logging () const; - bool ledger_rollback_logging () const; - bool vote_logging () const; - bool rep_crawler_logging () const; - bool election_fork_tally_logging () const; - bool election_expiration_tally_logging () const; - bool network_logging () const; - bool network_timeout_logging () const; - bool network_message_logging () const; - bool network_publish_logging () const; - bool network_packet_logging () const; - bool network_keepalive_logging () const; - bool network_node_id_handshake_logging () const; - bool network_telemetry_logging () const; - bool network_rejected_logging () const; - bool node_lifetime_tracing () const; - bool insufficient_work_logging () const; - bool upnp_details_logging () const; - bool timing_logging () const; - bool log_ipc () const; - bool bulk_pull_logging () const; - bool callback_logging () const; - bool work_generation_time () const; - bool active_update_logging () const; - bool election_result_logging () const; - bool log_to_cerr () const; - bool single_line_record () const; - void init (std::filesystem::path const &); - - bool ledger_logging_value{ false }; - bool ledger_duplicate_logging_value{ false }; - bool ledger_rollback_logging_value{ false }; - bool vote_logging_value{ false }; - bool rep_crawler_logging_value{ false }; - bool election_fork_tally_logging_value{ false }; - bool election_expiration_tally_logging_value{ false }; - bool network_logging_value{ true }; - bool network_timeout_logging_value{ false }; - bool network_message_logging_value{ false }; - bool network_publish_logging_value{ false }; - bool network_packet_logging_value{ false }; - bool network_keepalive_logging_value{ false }; - bool network_node_id_handshake_logging_value{ false }; - bool network_telemetry_logging_value{ false }; - bool network_rejected_logging_value{ false }; - bool node_lifetime_tracing_value{ false }; - bool insufficient_work_logging_value{ true }; - bool log_ipc_value{ true }; - bool bulk_pull_logging_value{ false }; - bool work_generation_time_value{ true }; - bool upnp_details_logging_value{ false }; - bool timing_logging_value{ false }; - bool active_update_value{ false }; - bool election_result_logging_value{ false }; - bool log_to_cerr_value{ false }; - bool flush{ true }; - uintmax_t max_size{ 128 * 1024 * 1024 }; - uintmax_t rotation_size{ 4 * 1024 * 1024 }; - bool stable_log_filename{ false }; - std::chrono::milliseconds min_time_between_log_output{ 5 }; - bool single_line_record_value{ false }; - static void release_file_sink (); - -private: - static boost::shared_ptr> file_sink; - static std::atomic_flag logging_already_added; -}; -} diff --git a/nano/node/make_store.cpp b/nano/node/make_store.cpp index 7f24c649cf..c3c8c28105 100644 --- a/nano/node/make_store.cpp +++ b/nano/node/make_store.cpp @@ -2,7 +2,7 @@ #include #include -std::unique_ptr nano::make_store (nano::logger_mt & logger, std::filesystem::path const & path, nano::ledger_constants & constants, bool read_only, bool add_db_postfix, nano::rocksdb_config const & rocksdb_config, nano::txn_tracking_config const & txn_tracking_config_a, std::chrono::milliseconds block_processor_batch_max_time_a, nano::lmdb_config const & lmdb_config_a, bool backup_before_upgrade) +std::unique_ptr nano::make_store (nano::logger & logger, std::filesystem::path const & path, nano::ledger_constants & constants, bool read_only, bool add_db_postfix, nano::rocksdb_config const & rocksdb_config, nano::txn_tracking_config const & txn_tracking_config_a, std::chrono::milliseconds block_processor_batch_max_time_a, nano::lmdb_config const & lmdb_config_a, bool backup_before_upgrade) { if (rocksdb_config.enable) { diff --git a/nano/node/make_store.hpp b/nano/node/make_store.hpp index 1e7bdd2dc1..5f5b5f9372 100644 --- a/nano/node/make_store.hpp +++ b/nano/node/make_store.hpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include @@ -22,5 +22,5 @@ class component; namespace nano { -std::unique_ptr make_store (nano::logger_mt & logger, std::filesystem::path const & path, nano::ledger_constants & constants, bool open_read_only = false, bool add_db_postfix = true, nano::rocksdb_config const & rocksdb_config = nano::rocksdb_config{}, nano::txn_tracking_config const & txn_tracking_config_a = nano::txn_tracking_config{}, std::chrono::milliseconds block_processor_batch_max_time_a = std::chrono::milliseconds (5000), nano::lmdb_config const & lmdb_config_a = nano::lmdb_config{}, bool backup_before_upgrade = false); +std::unique_ptr make_store (nano::logger &, std::filesystem::path const & path, nano::ledger_constants & constants, bool open_read_only = false, bool add_db_postfix = true, nano::rocksdb_config const & rocksdb_config = nano::rocksdb_config{}, nano::txn_tracking_config const & txn_tracking_config_a = nano::txn_tracking_config{}, std::chrono::milliseconds block_processor_batch_max_time_a = std::chrono::milliseconds (5000), nano::lmdb_config const & lmdb_config_a = nano::lmdb_config{}, bool backup_before_upgrade = false); } diff --git a/nano/node/messages.cpp b/nano/node/messages.cpp index 3b6079b432..0631dcddfa 100644 --- a/nano/node/messages.cpp +++ b/nano/node/messages.cpp @@ -82,86 +82,6 @@ bool nano::message_header::deserialize (nano::stream & stream_a) return error; } -std::string nano::to_string (nano::message_type type) -{ - switch (type) - { - case nano::message_type::invalid: - return "invalid"; - case nano::message_type::not_a_type: - return "not_a_type"; - case nano::message_type::keepalive: - return "keepalive"; - case nano::message_type::publish: - return "publish"; - case nano::message_type::confirm_req: - return "confirm_req"; - case nano::message_type::confirm_ack: - return "confirm_ack"; - case nano::message_type::bulk_pull: - return "bulk_pull"; - case nano::message_type::bulk_push: - return "bulk_push"; - case nano::message_type::frontier_req: - return "frontier_req"; - case nano::message_type::node_id_handshake: - return "node_id_handshake"; - case nano::message_type::bulk_pull_account: - return "bulk_pull_account"; - case nano::message_type::telemetry_req: - return "telemetry_req"; - case nano::message_type::telemetry_ack: - return "telemetry_ack"; - case nano::message_type::asc_pull_req: - return "asc_pull_req"; - case nano::message_type::asc_pull_ack: - return "asc_pull_ack"; - // default case intentionally omitted to cause warnings for unhandled enums - } - - return "n/a"; -} - -nano::stat::detail nano::to_stat_detail (nano::message_type type) -{ - switch (type) - { - case nano::message_type::invalid: - return nano::stat::detail::invalid; - case nano::message_type::not_a_type: - return nano::stat::detail::not_a_type; - case nano::message_type::keepalive: - return nano::stat::detail::keepalive; - case nano::message_type::publish: - return nano::stat::detail::publish; - case nano::message_type::confirm_req: - return nano::stat::detail::confirm_req; - case nano::message_type::confirm_ack: - return nano::stat::detail::confirm_ack; - case nano::message_type::bulk_pull: - return nano::stat::detail::bulk_pull; - case nano::message_type::bulk_push: - return nano::stat::detail::bulk_push; - case nano::message_type::frontier_req: - return nano::stat::detail::frontier_req; - case nano::message_type::node_id_handshake: - return nano::stat::detail::node_id_handshake; - case nano::message_type::bulk_pull_account: - return nano::stat::detail::bulk_pull_account; - case nano::message_type::telemetry_req: - return nano::stat::detail::telemetry_req; - case nano::message_type::telemetry_ack: - return nano::stat::detail::telemetry_ack; - case nano::message_type::asc_pull_req: - return nano::stat::detail::asc_pull_req; - case nano::message_type::asc_pull_ack: - return nano::stat::detail::asc_pull_ack; - // default case intentionally omitted to cause warnings for unhandled enums - } - debug_assert (false); - return {}; -} - std::string nano::message_header::to_string () const { // Cast to uint16_t to get integer value since uint8_t is treated as an unsigned char in string formatting. @@ -169,11 +89,11 @@ std::string nano::message_header::to_string () const uint16_t version_max_l = static_cast (version_max); uint16_t version_using_l = static_cast (version_using); uint16_t version_min_l = static_cast (version_min); - std::string type_text = nano::to_string (type); + auto type_text = nano::to_string (type); std::stringstream stream; - stream << boost::format ("NetID: %1%(%2%), ") % nano::to_string_hex (static_cast (network)) % nano::network::to_string (network); + stream << boost::format ("NetID: %1%(%2%), ") % nano::to_string_hex (static_cast (network)) % nano::to_string (network); stream << boost::format ("VerMaxUsingMin: %1%/%2%/%3%, ") % version_max_l % version_using_l % version_min_l; stream << boost::format ("MsgType: %1%(%2%), ") % type_l % type_text; stream << boost::format ("Extensions: %1%") % nano::to_string_hex (static_cast (extensions.to_ulong ())); @@ -2068,3 +1988,87 @@ void nano::asc_pull_ack::frontiers_payload::deserialize (nano::stream & stream) current = deserialize_frontier (stream); } } + +/* + * + */ + +std::string_view nano::to_string (nano::message_type type) +{ + switch (type) + { + case nano::message_type::invalid: + return "invalid"; + case nano::message_type::not_a_type: + return "not_a_type"; + case nano::message_type::keepalive: + return "keepalive"; + case nano::message_type::publish: + return "publish"; + case nano::message_type::confirm_req: + return "confirm_req"; + case nano::message_type::confirm_ack: + return "confirm_ack"; + case nano::message_type::bulk_pull: + return "bulk_pull"; + case nano::message_type::bulk_push: + return "bulk_push"; + case nano::message_type::frontier_req: + return "frontier_req"; + case nano::message_type::node_id_handshake: + return "node_id_handshake"; + case nano::message_type::bulk_pull_account: + return "bulk_pull_account"; + case nano::message_type::telemetry_req: + return "telemetry_req"; + case nano::message_type::telemetry_ack: + return "telemetry_ack"; + case nano::message_type::asc_pull_req: + return "asc_pull_req"; + case nano::message_type::asc_pull_ack: + return "asc_pull_ack"; + // default case intentionally omitted to cause warnings for unhandled enums + } + + return "n/a"; +} + +nano::stat::detail nano::to_stat_detail (nano::message_type type) +{ + switch (type) + { + case nano::message_type::invalid: + return nano::stat::detail::invalid; + case nano::message_type::not_a_type: + return nano::stat::detail::not_a_type; + case nano::message_type::keepalive: + return nano::stat::detail::keepalive; + case nano::message_type::publish: + return nano::stat::detail::publish; + case nano::message_type::confirm_req: + return nano::stat::detail::confirm_req; + case nano::message_type::confirm_ack: + return nano::stat::detail::confirm_ack; + case nano::message_type::bulk_pull: + return nano::stat::detail::bulk_pull; + case nano::message_type::bulk_push: + return nano::stat::detail::bulk_push; + case nano::message_type::frontier_req: + return nano::stat::detail::frontier_req; + case nano::message_type::node_id_handshake: + return nano::stat::detail::node_id_handshake; + case nano::message_type::bulk_pull_account: + return nano::stat::detail::bulk_pull_account; + case nano::message_type::telemetry_req: + return nano::stat::detail::telemetry_req; + case nano::message_type::telemetry_ack: + return nano::stat::detail::telemetry_ack; + case nano::message_type::asc_pull_req: + return nano::stat::detail::asc_pull_req; + case nano::message_type::asc_pull_ack: + return nano::stat::detail::asc_pull_ack; + // default case intentionally omitted to cause warnings for unhandled enums + } + debug_assert (false); + return {}; +} diff --git a/nano/node/messages.hpp b/nano/node/messages.hpp index 5c22118695..d662054bdb 100644 --- a/nano/node/messages.hpp +++ b/nano/node/messages.hpp @@ -44,8 +44,8 @@ enum class message_type : uint8_t asc_pull_ack = 0x0f, }; -std::string to_string (message_type); -stat::detail to_stat_detail (message_type); +std::string_view to_string (nano::message_type); +stat::detail to_stat_detail (nano::message_type); enum class bulk_pull_account_flags : uint8_t { diff --git a/nano/node/network.cpp b/nano/node/network.cpp index a9c1974399..d02026deac 100644 --- a/nano/node/network.cpp +++ b/nano/node/network.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -27,10 +28,9 @@ nano::network::network (nano::node & node_a, uint16_t port_a) : port (port_a), disconnect_observer ([] () {}) { - // TCP for (std::size_t i = 0; i < node.config.network_threads && !node.flags.disable_tcp_realtime; ++i) { - packet_processing_threads.emplace_back (nano::thread_attributes::get_default (), [this] () { + packet_processing_threads.emplace_back (nano::thread_attributes::get_default (), [this, i] () { nano::thread_role::set (nano::thread_role::name::packet_processing); try { @@ -38,28 +38,24 @@ nano::network::network (nano::node & node_a, uint16_t port_a) : } catch (boost::system::error_code & ec) { - this->node.logger.always_log (FATAL_LOG_PREFIX, ec.message ()); + node.logger.critical (nano::log::type::network, "Error: {}", ec.message ()); release_assert (false); } catch (std::error_code & ec) { - this->node.logger.always_log (FATAL_LOG_PREFIX, ec.message ()); + node.logger.critical (nano::log::type::network, "Error: {}", ec.message ()); release_assert (false); } catch (std::runtime_error & err) { - this->node.logger.always_log (FATAL_LOG_PREFIX, err.what ()); + node.logger.critical (nano::log::type::network, "Error: {}", err.what ()); release_assert (false); } catch (...) { - this->node.logger.always_log (FATAL_LOG_PREFIX, "Unknown exception"); + node.logger.critical (nano::log::type::network, "Unknown error"); release_assert (false); } - if (this->node.config.logging.network_packet_logging ()) - { - this->node.logger.try_log ("Exiting TCP packet processing thread"); - } }); } } @@ -131,10 +127,11 @@ void nano::network::send_node_id_handshake (std::shared_ptrget_endpoint () % (query ? query->cookie.to_string () : std::string ("[none]")) % (respond_to ? respond_to->to_string () : std::string ("[none]")) % (response ? response->signature.to_string () : std::string ("[none]")))); - } + node.logger.debug (nano::log::type::network, "Node ID handshake sent to: {} (query: {}, respond to: {}, signature: {})", + nano::util::to_str (channel_a->get_endpoint ()), + (query ? query->cookie.to_string () : ""), + (respond_to ? respond_to->to_string () : ""), + (response ? response->signature.to_string () : "")); channel_a->send (message); } @@ -260,10 +257,6 @@ void nano::network::broadcast_confirm_req (std::shared_ptr const & void nano::network::broadcast_confirm_req_base (std::shared_ptr const & block_a, std::shared_ptr>> const & endpoints_a, unsigned delay_a, bool resumption) { std::size_t const max_reps = 10; - if (!resumption && node.config.logging.network_logging ()) - { - node.logger.try_log (boost::str (boost::format ("Broadcasting confirm req for block %1% to %2% representatives") % block_a->hash ().to_string () % endpoints_a->size ())); - } auto count (0); while (!endpoints_a->empty () && count < max_reps) { @@ -288,11 +281,6 @@ void nano::network::broadcast_confirm_req_base (std::shared_ptr con void nano::network::broadcast_confirm_req_batched_many (std::unordered_map, std::deque>> request_bundle_a, std::function callback_a, unsigned delay_a, bool resumption_a) { - if (!resumption_a && node.config.logging.network_logging ()) - { - node.logger.try_log (boost::str (boost::format ("Broadcasting batch confirm req to %1% representatives") % request_bundle_a.size ())); - } - for (auto i (request_bundle_a.begin ()), n (request_bundle_a.end ()); i != n;) { std::vector> roots_hashes_l; @@ -365,18 +353,13 @@ class network_message_visitor : public nano::message_visitor { public: network_message_visitor (nano::node & node_a, std::shared_ptr const & channel_a) : - node (node_a), - channel (channel_a) + node{ node_a }, + channel{ channel_a } { } void keepalive (nano::keepalive const & message_a) override { - if (node.config.logging.network_keepalive_logging ()) - { - node.logger.try_log (boost::str (boost::format ("Received keepalive message from %1%") % channel->to_string ())); - } - node.network.merge_peers (message_a.peers); // Check for special node port data @@ -393,11 +376,6 @@ class network_message_visitor : public nano::message_visitor void publish (nano::publish const & message_a) override { - if (node.config.logging.network_message_logging ()) - { - node.logger.try_log (boost::str (boost::format ("Publish message from %1% for %2%") % channel->to_string () % message_a.block->hash ().to_string ())); - } - if (!node.block_processor.full ()) { node.process_active (message_a.block); @@ -411,14 +389,6 @@ class network_message_visitor : public nano::message_visitor void confirm_req (nano::confirm_req const & message_a) override { - if (node.config.logging.network_message_logging ()) - { - if (!message_a.roots_hashes.empty ()) - { - node.logger.try_log (boost::str (boost::format ("Confirm_req message from %1% for hashes:roots %2%") % channel->to_string () % message_a.roots_string ())); - } - } - // Don't load nodes with disabled voting if (node.config.enable_voting && node.wallets.reps ().voting > 0) { @@ -431,11 +401,6 @@ class network_message_visitor : public nano::message_visitor void confirm_ack (nano::confirm_ack const & message_a) override { - if (node.config.logging.network_message_logging ()) - { - node.logger.try_log (boost::str (boost::format ("Received confirm_ack message from %1% for %2% timestamp %3%") % channel->to_string () % message_a.vote->hashes_string () % std::to_string (message_a.vote->timestamp ()))); - } - if (!message_a.vote->account.is_zero ()) { node.vote_processor.vote (message_a.vote, channel); @@ -469,11 +434,6 @@ class network_message_visitor : public nano::message_visitor void telemetry_req (nano::telemetry_req const & message_a) override { - if (node.config.logging.network_telemetry_logging ()) - { - node.logger.try_log (boost::str (boost::format ("Telemetry_req message from %1%") % channel->to_string ())); - } - // Send an empty telemetry_ack if we do not want, just to acknowledge that we have received the message to // remove any timeouts on the server side waiting for a message. nano::telemetry_ack telemetry_ack{ node.network_params.network }; @@ -487,11 +447,6 @@ class network_message_visitor : public nano::message_visitor void telemetry_ack (nano::telemetry_ack const & message_a) override { - if (node.config.logging.network_telemetry_logging ()) - { - node.logger.try_log (boost::str (boost::format ("Received telemetry_ack message from %1%") % channel->to_string ())); - } - node.telemetry.process (message_a, channel); } @@ -515,7 +470,7 @@ void nano::network::process_message (nano::message const & message, std::shared_ { node.stats.inc (nano::stat::type::message, nano::to_stat_detail (message.header.type), nano::stat::dir::in); - network_message_visitor visitor (node, channel); + network_message_visitor visitor{ node, channel }; message.visit (visitor); } @@ -998,23 +953,3 @@ std::unique_ptr nano::syn_cookies::collect_conta composite->add_component (std::make_unique (container_info{ "syn_cookies_per_ip", syn_cookies_per_ip_count, sizeof (decltype (cookies_per_ip)::value_type) })); return composite; } - -std::string nano::network::to_string (nano::networks network) -{ - switch (network) - { - case nano::networks::invalid: - return "invalid"; - case nano::networks::nano_beta_network: - return "beta"; - case nano::networks::nano_dev_network: - return "dev"; - case nano::networks::nano_live_network: - return "live"; - case nano::networks::nano_test_network: - return "test"; - // default case intentionally omitted to cause warnings for unhandled enums - } - - return "n/a"; -} diff --git a/nano/node/network.hpp b/nano/node/network.hpp index 56f6f23b86..f0785d9441 100644 --- a/nano/node/network.hpp +++ b/nano/node/network.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -133,8 +134,6 @@ class network final std::optional prepare_handshake_query (nano::endpoint const & remote_endpoint); nano::node_id_handshake::response_payload prepare_handshake_response (nano::node_id_handshake::query_payload const & query, bool v2) const; - static std::string to_string (nano::networks); - private: void process_message (nano::message const &, std::shared_ptr const &); @@ -158,5 +157,6 @@ class network final static std::size_t const confirm_req_hashes_max = 7; static std::size_t const confirm_ack_hashes_max = 12; }; + std::unique_ptr collect_container_info (network & network, std::string const & name); } diff --git a/nano/node/node.cpp b/nano/node/node.cpp index 2ec288a875..52ab7f1afd 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -84,7 +84,7 @@ void nano::node::keepalive (std::string const & address_a, uint16_t port_a) } else { - node_l->logger.try_log (boost::str (boost::format ("Error resolving address: %1%:%2%: %3%") % address_a % port_a % ec.message ())); + node_l->logger.error (nano::log::type::node, "Error resolving address for keepalive: {}:{} ({})", address_a, port_a, ec.message ()); } }); } @@ -103,13 +103,14 @@ std::unique_ptr nano::collect_container_info (re return composite; } -nano::keypair nano::load_or_create_node_id (std::filesystem::path const & application_path, nano::logger_mt & logger) +nano::keypair nano::load_or_create_node_id (std::filesystem::path const & application_path) { auto node_private_key_path = application_path / "node_id_private.key"; std::ifstream ifs (node_private_key_path.c_str ()); if (ifs.good ()) { - logger.always_log (boost::str (boost::format ("%1% exists, reading node id from it") % node_private_key_path.string ())); + nano::default_logger ().info (nano::log::type::init, "Reading node id from: '{}'", node_private_key_path.string ()); + std::string node_private_key; ifs >> node_private_key; release_assert (node_private_key.size () == 64); @@ -119,7 +120,8 @@ nano::keypair nano::load_or_create_node_id (std::filesystem::path const & applic else { // no node_id found, generate new one - logger.always_log (boost::str (boost::format ("%1% does not exist, creating a new node_id") % node_private_key_path.string ())); + nano::default_logger ().info (nano::log::type::init, "Generating a new node id, saving to: '{}'", node_private_key_path.string ()); + nano::keypair kp; std::ofstream ofs (node_private_key_path.c_str (), std::ofstream::out | std::ofstream::trunc); ofs << kp.prv.to_string () << std::endl @@ -130,24 +132,25 @@ nano::keypair nano::load_or_create_node_id (std::filesystem::path const & applic } } -nano::node::node (boost::asio::io_context & io_ctx_a, uint16_t peering_port_a, std::filesystem::path const & application_path_a, nano::logging const & logging_a, nano::work_pool & work_a, nano::node_flags flags_a, unsigned seq) : - node (io_ctx_a, application_path_a, nano::node_config (peering_port_a, logging_a), work_a, flags_a, seq) +nano::node::node (boost::asio::io_context & io_ctx_a, uint16_t peering_port_a, std::filesystem::path const & application_path_a, nano::work_pool & work_a, nano::node_flags flags_a, unsigned seq) : + node (io_ctx_a, application_path_a, nano::node_config (peering_port_a), work_a, flags_a, seq) { } nano::node::node (boost::asio::io_context & io_ctx_a, std::filesystem::path const & application_path_a, nano::node_config const & config_a, nano::work_pool & work_a, nano::node_flags flags_a, unsigned seq) : + node_id{ load_or_create_node_id (application_path_a) }, write_database_queue (!flags_a.force_use_write_database_queue && (config_a.rocksdb_config.enable)), io_ctx (io_ctx_a), node_initialized_latch (1), config (config_a), network_params{ config.network_params }, + logger{ make_logger_identifier (node_id) }, stats (config.stats_config), workers{ config.background_threads, nano::thread_role::name::worker }, bootstrap_workers{ config.bootstrap_serving_threads, nano::thread_role::name::bootstrap_worker }, flags (flags_a), work (work_a), distributed_work (*this), - logger (config_a.logging.min_time_between_log_output), store_impl (nano::make_store (logger, application_path_a, network_params.ledger, flags.read_only, true, config_a.rocksdb_config, config_a.diagnostics_config.txn_tracking, config_a.block_processor_batch_max_time, config_a.lmdb_config, config_a.backup_before_upgrade)), store (*store_impl), unchecked{ stats, flags.disable_block_processor_unchecked_deletion }, @@ -180,7 +183,7 @@ nano::node::node (boost::asio::io_context & io_ctx_a, std::filesystem::path cons online_reps (ledger, config), history{ config.network_params.voting }, vote_uniquer{}, - confirmation_height_processor (ledger, write_database_queue, config.conf_height_processor_batch_min_time, config.logging, logger, node_initialized_latch, flags.confirmation_height_processor_mode), + confirmation_height_processor (ledger, write_database_queue, config.conf_height_processor_batch_min_time, logger, node_initialized_latch, flags.confirmation_height_processor_mode), vote_cache{ config.vote_cache, stats }, generator{ config, ledger, wallets, vote_processor, history, network, stats, /* non-final */ false }, final_generator{ config, ledger, wallets, vote_processor, history, network, stats, /* final */ true }, @@ -200,6 +203,8 @@ nano::node::node (boost::asio::io_context & io_ctx_a, std::filesystem::path cons gap_tracker{ gap_cache }, process_live_dispatcher{ ledger, scheduler.priority, vote_cache, websocket } { + logger.debug (nano::log::type::node, "Constructing node..."); + block_broadcast.connect (block_processor); block_publisher.connect (block_processor); gap_tracker.connect (block_processor); @@ -288,10 +293,7 @@ nano::node::node (boost::asio::io_context & io_ctx_a, std::filesystem::path cons } else { - if (node_l->config.logging.callback_logging ()) - { - node_l->logger.always_log (boost::str (boost::format ("Error resolving callback: %1%:%2%: %3%") % address % port % ec.message ())); - } + node_l->logger.error (nano::log::type::rpc_callbacks, "Error resolving callback: {}:{} ({})", address, port, ec.message ()); node_l->stats.inc (nano::stat::type::error, nano::stat::detail::http_callback, nano::stat::dir::out); } }); @@ -338,26 +340,25 @@ nano::node::node (boost::asio::io_context & io_ctx_a, std::filesystem::path cons this->distributed_work.cancel (root_a); }); - logger.always_log ("Node starting, version: ", NANO_VERSION_STRING); - logger.always_log ("Build information: ", BUILD_INFO); - logger.always_log ("Database backend: ", store.vendor_get ()); - auto const network_label = network_params.network.get_current_network_as_string (); - logger.always_log ("Active network: ", network_label); - logger.always_log (boost::str (boost::format ("Work pool running %1% threads %2%") % work.threads.size () % (work.opencl ? "(1 for OpenCL)" : ""))); - logger.always_log (boost::str (boost::format ("%1% work peers configured") % config.work_peers.size ())); - if (!work_generation_enabled ()) - { - logger.always_log ("Work generation is disabled"); - } + logger.info (nano::log::type::node, "Node starting, version: {}", NANO_VERSION_STRING); + logger.info (nano::log::type::node, "Build information: {}", BUILD_INFO); + logger.info (nano::log::type::node, "Active network: {}", network_label); + logger.info (nano::log::type::node, "Database backend: {}", store.vendor_get ()); + logger.info (nano::log::type::node, "Data path: {}", application_path.string ()); + logger.info (nano::log::type::node, "Work pool threads: {} ({})", work.threads.size (), (work.opencl ? "OpenCL" : "CPU")); + logger.info (nano::log::type::node, "Work peers: {}", config.work_peers.size ()); + logger.info (nano::log::type::node, "Node ID: {}", node_id.pub.to_node_id ()); - if (config.logging.node_lifetime_tracing ()) + if (!work_generation_enabled ()) { - logger.always_log ("Constructing node"); + logger.info (nano::log::type::node, "Work generation is disabled"); } - logger.always_log (boost::str (boost::format ("Outbound Voting Bandwidth limited to %1% bytes per second, burst ratio %2%") % config.bandwidth_limit % config.bandwidth_limit_burst_ratio)); + logger.info (nano::log::type::node, "Outbound bandwidth limit: {} bytes/s, burst ratio: {}", + config.bandwidth_limit, + config.bandwidth_limit_burst_ratio); // First do a pass with a read to see if any writing needs doing, this saves needing to open a write lock (and potentially blocking) auto is_initialized (false); @@ -375,59 +376,69 @@ nano::node::node (boost::asio::io_context & io_ctx_a, std::filesystem::path cons if (!ledger.block_or_pruned_exists (config.network_params.ledger.genesis->hash ())) { - std::stringstream ss; - ss << "Genesis block not found. This commonly indicates a configuration issue, check that the --network or --data_path command line arguments are correct, " - "and also the ledger backend node config option. If using a read-only CLI command a ledger must already exist, start the node with --daemon first."; + logger.critical (nano::log::type::node, "Genesis block not found. This commonly indicates a configuration issue, check that the --network or --data_path command line arguments are correct, and also the ledger backend node config option. If using a read-only CLI command a ledger must already exist, start the node with --daemon first."); + if (network_params.network.is_beta_network ()) { - ss << " Beta network may have reset, try clearing database files"; + logger.critical (nano::log::type::node, "Beta network may have reset, try clearing database files"); } - auto const str = ss.str (); - logger.always_log (str); - std::cerr << str << std::endl; std::exit (1); } if (config.enable_voting) { - std::ostringstream stream; - stream << "Voting is enabled, more system resources will be used"; - auto voting (wallets.reps ().voting); - if (voting > 0) + auto reps = wallets.reps (); + logger.info (nano::log::type::node, "Voting is enabled, more system resources will be used, local representatives: {}", reps.accounts.size ()); + for (auto const & account : reps.accounts) { - stream << ". " << voting << " representative(s) are configured"; - if (voting > 1) - { - stream << ". Voting with more than one representative can limit performance"; - } + logger.info (nano::log::type::node, "Local representative: {}", account.to_account ()); + } + if (reps.accounts.size () > 1) + { + logger.warn (nano::log::type::node, "Voting with more than one representative can limit performance"); } - logger.always_log (stream.str ()); } - node_id = nano::load_or_create_node_id (application_path, logger); - logger.always_log ("Node ID: ", node_id.pub.to_node_id ()); - if ((network_params.network.is_live_network () || network_params.network.is_beta_network ()) && !flags.inactive_node) { auto const bootstrap_weights = get_bootstrap_weights (); + ledger.bootstrap_weight_max_blocks = bootstrap_weights.first; + + logger.info (nano::log::type::node, "Initial bootstrap height: {}", ledger.bootstrap_weight_max_blocks); + logger.info (nano::log::type::node, "Current ledger height: {}", ledger.cache.block_count.load ()); + // Use bootstrap weights if initial bootstrap is not completed const bool use_bootstrap_weight = ledger.cache.block_count < bootstrap_weights.first; if (use_bootstrap_weight) { + logger.info (nano::log::type::node, "Using predefined representative weights, since block count is less than bootstrap threshold"); + ledger.bootstrap_weights = bootstrap_weights.second; - for (auto const & rep : ledger.bootstrap_weights) + + logger.info (nano::log::type::node, "************************************ Bootstrap weights ************************************"); + + // Sort the weights + std::vector> sorted_weights (ledger.bootstrap_weights.begin (), ledger.bootstrap_weights.end ()); + std::sort (sorted_weights.begin (), sorted_weights.end (), [] (auto const & entry1, auto const & entry2) { + return entry1.second > entry2.second; + }); + + for (auto const & rep : sorted_weights) { - logger.always_log ("Using bootstrap rep weight: ", rep.first.to_account (), " -> ", nano::uint128_union (rep.second).format_balance (Mxrb_ratio, 0, true), " XRB"); + logger.info (nano::log::type::node, "Using bootstrap rep weight: {} -> {}", + rep.first.to_account (), + nano::uint128_union (rep.second).format_balance (Mxrb_ratio, 0, true)); } + + logger.info (nano::log::type::node, "************************************ ================= ************************************"); } - ledger.bootstrap_weight_max_blocks = bootstrap_weights.first; // Drop unchecked blocks if initial bootstrap is completed if (!flags.disable_unchecked_drop && !use_bootstrap_weight && !flags.read_only) { + logger.info (nano::log::type::node, "Dropping unchecked blocks..."); unchecked.clear (); - logger.always_log ("Dropping unchecked blocks"); } } @@ -437,16 +448,12 @@ nano::node::node (boost::asio::io_context & io_ctx_a, std::filesystem::path cons { if (config.enable_voting && !flags.inactive_node) { - std::string str = "Incompatibility detected between config node.enable_voting and existing pruned blocks"; - logger.always_log (str); - std::cerr << str << std::endl; + logger.critical (nano::log::type::node, "Incompatibility detected between config node.enable_voting and existing pruned blocks"); std::exit (1); } else if (!flags.enable_pruning && !flags.inactive_node) { - std::string str = "To start node with existing pruned blocks use launch flag --enable_pruning"; - logger.always_log (str); - std::cerr << str << std::endl; + logger.critical (nano::log::type::node, "To start node with existing pruned blocks use launch flag --enable_pruning"); std::exit (1); } } @@ -456,13 +463,11 @@ nano::node::node (boost::asio::io_context & io_ctx_a, std::filesystem::path cons nano::node::~node () { - if (config.logging.node_lifetime_tracing ()) - { - logger.always_log ("Destructing node"); - } + logger.debug (nano::log::type::node, "Destructing node..."); stop (); } +// TODO: Move to a separate class void nano::node::do_rpc_callback (boost::asio::ip::tcp::resolver::iterator i_a, std::string const & address, uint16_t port, std::shared_ptr const & target, std::shared_ptr const & body, std::shared_ptr const & resolver) { if (i_a != boost::asio::ip::tcp::resolver::iterator{}) @@ -494,41 +499,30 @@ void nano::node::do_rpc_callback (boost::asio::ip::tcp::resolver::iterator i_a, } else { - if (node_l->config.logging.callback_logging ()) - { - node_l->logger.try_log (boost::str (boost::format ("Callback to %1%:%2% failed with status: %3%") % address % port % resp->result ())); - } + node_l->logger.error (nano::log::type::rpc_callbacks, "Callback to {}:{} failed [status: {}]", address, port, nano::util::to_str (resp->result ())); node_l->stats.inc (nano::stat::type::error, nano::stat::detail::http_callback, nano::stat::dir::out); } } else { - if (node_l->config.logging.callback_logging ()) - { - node_l->logger.try_log (boost::str (boost::format ("Unable complete callback: %1%:%2%: %3%") % address % port % ec.message ())); - } + node_l->logger.error (nano::log::type::rpc_callbacks, "Unable to complete callback: {}:{} ({})", address, port, ec.message ()); node_l->stats.inc (nano::stat::type::error, nano::stat::detail::http_callback, nano::stat::dir::out); }; }); } else { - if (node_l->config.logging.callback_logging ()) - { - node_l->logger.try_log (boost::str (boost::format ("Unable to send callback: %1%:%2%: %3%") % address % port % ec.message ())); - } + node_l->logger.error (nano::log::type::rpc_callbacks, "Unable to send callback: {}:{} ({})", address, port, ec.message ()); node_l->stats.inc (nano::stat::type::error, nano::stat::detail::http_callback, nano::stat::dir::out); } }); } else { - if (node_l->config.logging.callback_logging ()) - { - node_l->logger.try_log (boost::str (boost::format ("Unable to connect to callback address: %1%:%2%: %3%") % address % port % ec.message ())); - } + node_l->logger.error (nano::log::type::rpc_callbacks, "Unable to connect to callback address: {}:{} ({})", address, port, ec.message ()); node_l->stats.inc (nano::stat::type::error, nano::stat::detail::http_callback, nano::stat::dir::out); ++i_a; + node_l->do_rpc_callback (i_a, address, port, target, body, resolver); } }); @@ -655,7 +649,7 @@ void nano::node::start () network.port = tcp_listener->endpoint ().port (); } - logger.always_log (boost::str (boost::format ("Node started with peering port `%1%`.") % network.port)); + logger.info (nano::log::type::node, "Node peering port: {}", network.port.load ()); } if (!flags.disable_backup) @@ -702,7 +696,7 @@ void nano::node::stop () return; } - logger.always_log ("Node stopping"); + logger.info (nano::log::type::node, "Node stopping..."); // Cancels ongoing work generation tasks, which may be blocking other threads // No tasks may wait for work generation in I/O threads, or termination signal capturing will be unable to call node::stop() @@ -811,7 +805,7 @@ void nano::node::long_inactivity_cleanup () { store.online_weight.clear (transaction); store.peer.clear (transaction); - logger.always_log ("Removed records of peers and online weight after a long period of inactivity"); + logger.info (nano::log::type::node, "Removed records of peers and online weight after a long period of inactivity"); } } @@ -975,7 +969,7 @@ void nano::node::unchecked_cleanup () } if (!cleaning_list.empty ()) { - logger.always_log (boost::str (boost::format ("Deleting %1% old unchecked blocks") % cleaning_list.size ())); + logger.info (nano::log::type::node, "Deleting {} old unchecked blocks", cleaning_list.size ()); } // Delete old unchecked keys in batches while (!cleaning_list.empty ()) @@ -1056,7 +1050,7 @@ bool nano::node::collect_ledger_pruning_targets (std::deque & return !finish_transaction || last_account_a.is_zero (); } -void nano::node::ledger_pruning (uint64_t const batch_size_a, bool bootstrap_weight_reached_a, bool log_to_cout_a) +void nano::node::ledger_pruning (uint64_t const batch_size_a, bool bootstrap_weight_reached_a) { uint64_t const max_depth (config.max_pruning_depth != 0 ? config.max_pruning_depth : std::numeric_limits::max ()); uint64_t const cutoff_time (bootstrap_weight_reached_a ? nano::seconds_since_epoch () - config.max_pruning_age.count () : std::numeric_limits::max ()); @@ -1086,32 +1080,18 @@ void nano::node::ledger_pruning (uint64_t const batch_size_a, bool bootstrap_wei pruning_targets.pop_front (); } pruned_count += transaction_write_count; - auto log_message (boost::str (boost::format ("%1% blocks pruned") % pruned_count)); - if (!log_to_cout_a) - { - logger.try_log (log_message); - } - else - { - std::cout << log_message << std::endl; - } + + logger.debug (nano::log::type::prunning, "Pruned blocks: {}", pruned_count); } } - auto const log_message (boost::str (boost::format ("Total recently pruned block count: %1%") % pruned_count)); - if (!log_to_cout_a) - { - logger.always_log (log_message); - } - else - { - std::cout << log_message << std::endl; - } + + logger.debug (nano::log::type::prunning, "Total recently pruned block count: {}", pruned_count); } void nano::node::ongoing_ledger_pruning () { auto bootstrap_weight_reached (ledger.cache.block_count >= ledger.bootstrap_weight_max_blocks); - ledger_pruning (flags.block_processor_batch_size != 0 ? flags.block_processor_batch_size : 2 * 1024, bootstrap_weight_reached, false); + ledger_pruning (flags.block_processor_batch_size != 0 ? flags.block_processor_batch_size : 2 * 1024, bootstrap_weight_reached); auto const ledger_pruning_interval (bootstrap_weight_reached ? config.max_pruning_age : std::min (config.max_pruning_age, std::chrono::seconds (15 * 60))); auto this_l (shared ()); workers.add_timed_task (std::chrono::steady_clock::now () + ledger_pruning_interval, [this_l] () { @@ -1238,7 +1218,7 @@ void nano::node::add_initial_peers () { if (flags.disable_add_initial_peers) { - logger.always_log ("Skipping add_initial_peers because disable_add_initial_peers is set"); + logger.warn (nano::log::type::node, "Not adding initial peers because `disable_add_initial_peers` flag is set"); return; } @@ -1318,12 +1298,12 @@ void nano::node::receive_confirmed (store::transaction const & block_transaction { if (!ledger.block_or_pruned_exists (block_transaction_a, hash_a)) { - logger.try_log (boost::str (boost::format ("Confirmed block is missing: %1%") % hash_a.to_string ())); - debug_assert (false && "Confirmed block is missing"); + logger.warn (nano::log::type::node, "Confirmed block is missing: {}", hash_a.to_string ()); + debug_assert (false, "Confirmed block is missing"); } else { - logger.try_log (boost::str (boost::format ("Block %1% has already been received") % hash_a.to_string ())); + logger.warn (nano::log::type::node, "Block has already been received: {}", hash_a.to_string ()); } } } @@ -1495,6 +1475,12 @@ nano::telemetry_data nano::node::local_telemetry () const return telemetry_data; } +std::string nano::node::make_logger_identifier (const nano::keypair & node_id) +{ + // Node identifier consists of first 10 characters of node id + return node_id.pub.to_node_id ().substr (0, 10); +} + /* * node_wrapper */ @@ -1504,13 +1490,14 @@ nano::node_wrapper::node_wrapper (std::filesystem::path const & path_a, std::fil io_context (std::make_shared ()), work{ network_params.network, 1 } { - boost::system::error_code error_chmod; - /* * @warning May throw a filesystem exception */ std::filesystem::create_directories (path_a); + + boost::system::error_code error_chmod; nano::set_secure_perm_directory (path_a, error_chmod); + nano::daemon_config daemon_config{ path_a, network_params }; auto error = nano::read_node_config_toml (config_path_a, daemon_config, node_flags_a.config_overrides); if (error) @@ -1527,8 +1514,6 @@ nano::node_wrapper::node_wrapper (std::filesystem::path const & path_a, std::fil auto & node_config = daemon_config.node; node_config.peering_port = 24000; - node_config.logging.max_size = std::numeric_limits::max (); - node_config.logging.init (path_a); node = std::make_shared (*io_context, path_a, node_config, work, node_flags_a); } diff --git a/nano/node/node.hpp b/nano/node/node.hpp index 4e7b567444..65d85830f0 100644 --- a/nano/node/node.hpp +++ b/nano/node/node.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include #include @@ -69,7 +70,7 @@ outbound_bandwidth_limiter::config outbound_bandwidth_limiter_config (node_confi class node final : public std::enable_shared_from_this { public: - node (boost::asio::io_context &, uint16_t, std::filesystem::path const &, nano::logging const &, nano::work_pool &, nano::node_flags = nano::node_flags (), unsigned seq = 0); + node (boost::asio::io_context &, uint16_t, std::filesystem::path const &, nano::work_pool &, nano::node_flags = nano::node_flags (), unsigned seq = 0); node (boost::asio::io_context &, std::filesystem::path const &, nano::node_config const &, nano::work_pool &, nano::node_flags = nano::node_flags (), unsigned seq = 0); ~node (); @@ -106,7 +107,7 @@ class node final : public std::enable_shared_from_this void bootstrap_wallet (); void unchecked_cleanup (); bool collect_ledger_pruning_targets (std::deque &, nano::account &, uint64_t const, uint64_t const, uint64_t const); - void ledger_pruning (uint64_t const, bool, bool); + void ledger_pruning (uint64_t const, bool); void ongoing_ledger_pruning (); int price (nano::uint128_t const &, int); // The default difficulty updates to base only when the first epoch_2 block is processed @@ -139,18 +140,19 @@ class node final : public std::enable_shared_from_this nano::telemetry_data local_telemetry () const; public: + const nano::keypair node_id; nano::write_database_queue write_database_queue; boost::asio::io_context & io_ctx; boost::latch node_initialized_latch; nano::node_config config; nano::network_params & network_params; + nano::logger logger; nano::stats stats; nano::thread_pool workers; nano::thread_pool bootstrap_workers; nano::node_flags flags; nano::work_pool & work; nano::distributed_work_factory distributed_work; - nano::logger_mt logger; std::unique_ptr store_impl; nano::store::component & store; nano::unchecked_map unchecked; @@ -174,7 +176,6 @@ class node final : public std::enable_shared_from_this nano::block_processor block_processor; nano::block_arrival block_arrival; nano::local_vote_history history; - nano::keypair node_id; nano::block_uniquer block_uniquer; nano::vote_uniquer vote_uniquer; nano::confirmation_height_processor confirmation_height_processor; @@ -226,9 +227,12 @@ class node final : public std::enable_shared_from_this private: void long_inactivity_cleanup (); + + static std::string make_logger_identifier (nano::keypair const & node_id); }; -nano::keypair load_or_create_node_id (std::filesystem::path const & application_path, nano::logger_mt & logger); +nano::keypair load_or_create_node_id (std::filesystem::path const & application_path); + std::unique_ptr collect_container_info (node & node, std::string const & name); nano::node_flags const & inactive_node_flag_defaults (); diff --git a/nano/node/nodeconfig.cpp b/nano/node/nodeconfig.cpp index 2453c2c24d..61179c685c 100644 --- a/nano/node/nodeconfig.cpp +++ b/nano/node/nodeconfig.cpp @@ -21,15 +21,14 @@ std::string const default_test_peer_network = nano::get_env_or_default ("NANO_DE } nano::node_config::node_config (nano::network_params & network_params) : - node_config (std::nullopt, nano::logging (), network_params) + node_config (std::nullopt, network_params) { } -nano::node_config::node_config (const std::optional & peering_port_a, nano::logging const & logging_a, nano::network_params & network_params) : +nano::node_config::node_config (const std::optional & peering_port_a, nano::network_params & network_params) : network_params{ network_params }, peering_port{ peering_port_a }, hinted_scheduler{ network_params.network }, - logging{ logging_a }, websocket_config{ network_params.network }, ipc_config{ network_params.network }, external_address{ boost::asio::ip::address_v6{}.to_string () } @@ -168,10 +167,6 @@ nano::error nano::node_config::serialize_toml (nano::tomlconfig & toml) const callback_l.put ("target", callback_target, "Callback target path.\ntype:string,uri"); toml.put_child ("httpcallback", callback_l); - nano::tomlconfig logging_l; - logging.serialize_toml (logging_l); - toml.put_child ("logging", logging_l); - nano::tomlconfig websocket_l; websocket_config.serialize_toml (websocket_l); toml.put_child ("websocket", websocket_l); @@ -223,12 +218,6 @@ nano::error nano::node_config::deserialize_toml (nano::tomlconfig & toml) callback_l.get ("target", callback_target); } - if (toml.has_key ("logging")) - { - auto logging_l (toml.get_required_child ("logging")); - logging.deserialize_toml (logging_l); - } - if (toml.has_key ("websocket")) { auto websocket_config_l (toml.get_required_child ("websocket")); diff --git a/nano/node/nodeconfig.hpp b/nano/node/nodeconfig.hpp index 0cc4116270..c4f8a9693b 100644 --- a/nano/node/nodeconfig.hpp +++ b/nano/node/nodeconfig.hpp @@ -4,12 +4,12 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include #include @@ -39,18 +39,18 @@ class node_config { public: node_config (nano::network_params & network_params = nano::dev::network_params); - node_config (const std::optional &, nano::logging const &, nano::network_params & network_params = nano::dev::network_params); + node_config (const std::optional &, nano::network_params & network_params = nano::dev::network_params); nano::error serialize_toml (nano::tomlconfig &) const; nano::error deserialize_toml (nano::tomlconfig &); bool upgrade_json (unsigned, nano::jsonconfig &); nano::account random_representative () const; + nano::network_params network_params; std::optional peering_port{}; nano::scheduler::optimistic_config optimistic_scheduler; nano::scheduler::hinted_config hinted_scheduler; - nano::logging logging; std::vector> work_peers; std::vector> secondary_work_peers{ { "127.0.0.1", 8076 } }; /* Default of nano-pow-server */ std::vector preconfigured_peers; diff --git a/nano/node/openclwork.cpp b/nano/node/openclwork.cpp index 8389a19fb3..1e8907797d 100644 --- a/nano/node/openclwork.cpp +++ b/nano/node/openclwork.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -249,7 +250,7 @@ void nano::opencl_environment::dump (std::ostream & stream) } } -nano::opencl_work::opencl_work (bool & error_a, nano::opencl_config const & config_a, nano::opencl_environment & environment_a, nano::logger_mt & logger_a, nano::work_thresholds & work) : +nano::opencl_work::opencl_work (bool & error_a, nano::opencl_config const & config_a, nano::opencl_environment & environment_a, nano::logger & logger_a, nano::work_thresholds & work) : config (config_a), context (0), attempt_buffer (0), @@ -343,85 +344,85 @@ nano::opencl_work::opencl_work (bool & error_a, nano::opencl_config const & conf } else { - logger.always_log (boost::str (boost::format ("Bind argument 3 error %1%") % arg3_error)); + logger.error (nano::log::type::opencl_work, "Bind argument 3 error: {}", arg3_error); } } else { - logger.always_log (boost::str (boost::format ("Bind argument 2 error %1%") % arg2_error)); + logger.error (nano::log::type::opencl_work, "Bind argument 2 error: {}", arg2_error); } } else { - logger.always_log (boost::str (boost::format ("Bind argument 1 error %1%") % arg1_error)); + logger.error (nano::log::type::opencl_work, "Bind argument 1 error: {}", arg1_error); } } else { - logger.always_log (boost::str (boost::format ("Bind argument 0 error %1%") % arg0_error)); + logger.error (nano::log::type::opencl_work, "Bind argument 0 error: {}", arg0_error); } } else { - logger.always_log (boost::str (boost::format ("Create kernel error %1%") % kernel_error)); + logger.error (nano::log::type::opencl_work, "Create kernel error: {}", kernel_error); } } else { - logger.always_log (boost::str (boost::format ("Build program error %1%") % clBuildProgramError)); + logger.error (nano::log::type::opencl_work, "Build program error: {}", clBuildProgramError); for (auto i (selected_devices.begin ()), n (selected_devices.end ()); i != n; ++i) { std::size_t log_size (0); clGetProgramBuildInfo (program, *i, CL_PROGRAM_BUILD_LOG, 0, nullptr, &log_size); std::vector log (log_size); clGetProgramBuildInfo (program, *i, CL_PROGRAM_BUILD_LOG, log.size (), log.data (), nullptr); - logger.always_log (log.data ()); + logger.info (nano::log::type::opencl_work, "Device log: {}", log.data ()); } } } else { - logger.always_log (boost::str (boost::format ("Create program error %1%") % program_error)); + logger.error (nano::log::type::opencl_work, "Create program error: {}", program_error); } } else { - logger.always_log (boost::str (boost::format ("Difficulty buffer error %1%") % difficulty_error)); + logger.error (nano::log::type::opencl_work, "Difficulty buffer error: {}", difficulty_error); } } else { - logger.always_log (boost::str (boost::format ("Item buffer error %1%") % item_error)); + logger.error (nano::log::type::opencl_work, "Item buffer error: {}", item_error); } } else { - logger.always_log (boost::str (boost::format ("Result buffer error %1%") % result_error)); + logger.error (nano::log::type::opencl_work, "Result buffer error: {}", result_error); } } else { - logger.always_log (boost::str (boost::format ("Attempt buffer error %1%") % attempt_error)); + logger.error (nano::log::type::opencl_work, "Attempt buffer error: {}", attempt_error); } } else { - logger.always_log (boost::str (boost::format ("Unable to create command queue %1%") % queue_error)); + logger.error (nano::log::type::opencl_work, "Unable to create command queue: {}", queue_error); } } else { - logger.always_log (boost::str (boost::format ("Unable to create context %1%") % createContextError)); + logger.error (nano::log::type::opencl_work, "Unable to create context: {}", createContextError); } } else { - logger.always_log (boost::str (boost::format ("Requested device %1%, and only have %2%") % config.device % platform.devices.size ())); + logger.error (nano::log::type::opencl_work, "Requested device {} and only have {}", config.device, platform.devices.size ()); } } else { - logger.always_log (boost::str (boost::format ("Requested platform %1% and only have %2%") % config.platform % environment_a.platforms.size ())); + logger.error (nano::log::type::opencl_work, "Requested platform {} and only have {}", config.platform, environment_a.platforms.size ()); } } @@ -480,37 +481,37 @@ boost::optional nano::opencl_work::generate_work (nano::work_version c else { error = true; - logger.always_log (boost::str (boost::format ("Error finishing queue %1%") % finishError)); + logger.error (nano::log::type::opencl_work, "Error finishing queue: {}", finishError); } } else { error = true; - logger.always_log (boost::str (boost::format ("Error reading result %1%") % read_error1)); + logger.error (nano::log::type::opencl_work, "Error reading result: {}", read_error1); } } else { error = true; - logger.always_log (boost::str (boost::format ("Error enqueueing kernel %1%") % enqueue_error)); + logger.error (nano::log::type::opencl_work, "Error enqueueing kernel: {}", enqueue_error); } } else { error = true; - logger.always_log (boost::str (boost::format ("Error writing item %1%") % write_error3)); + logger.error (nano::log::type::opencl_work, "Error writing difficulty: {}", write_error3); } } else { error = true; - logger.always_log (boost::str (boost::format ("Error writing item %1%") % write_error2)); + logger.error (nano::log::type::opencl_work, "Error writing item: {}", write_error2); } } else { error = true; - logger.always_log (boost::str (boost::format ("Error writing attempt %1%") % write_error1)); + logger.error (nano::log::type::opencl_work, "Error writing attempt: {}", write_error1); } } boost::optional value; @@ -521,16 +522,18 @@ boost::optional nano::opencl_work::generate_work (nano::work_version c return value; } -std::unique_ptr nano::opencl_work::create (bool create_a, nano::opencl_config const & config_a, nano::logger_mt & logger_a, nano::work_thresholds & work) +std::unique_ptr nano::opencl_work::create (bool create_a, nano::opencl_config const & config_a, nano::logger & logger_a, nano::work_thresholds & work) { std::unique_ptr result; if (create_a) { auto error (false); + nano::opencl_environment environment (error); std::stringstream stream; environment.dump (stream); - logger_a.always_log (stream.str ()); + logger_a.info (nano::log::type::opencl_work, "OpenCL environment: {}", stream.str ()); + if (!error) { result.reset (new nano::opencl_work (error, config_a, environment, logger_a, work)); diff --git a/nano/node/openclwork.hpp b/nano/node/openclwork.hpp index 2f452e092e..15173c1dcc 100644 --- a/nano/node/openclwork.hpp +++ b/nano/node/openclwork.hpp @@ -21,7 +21,7 @@ namespace nano { extern bool opencl_loaded; -class logger_mt; +class logger; class opencl_platform { public: @@ -40,11 +40,11 @@ class work_pool; class opencl_work { public: - opencl_work (bool &, nano::opencl_config const &, nano::opencl_environment &, nano::logger_mt &, nano::work_thresholds & work); + opencl_work (bool &, nano::opencl_config const &, nano::opencl_environment &, nano::logger &, nano::work_thresholds & work); ~opencl_work (); boost::optional generate_work (nano::work_version const, nano::root const &, uint64_t const); boost::optional generate_work (nano::work_version const, nano::root const &, uint64_t const, std::atomic &); - static std::unique_ptr create (bool, nano::opencl_config const &, nano::logger_mt &, nano::work_thresholds & work); + static std::unique_ptr create (bool, nano::opencl_config const &, nano::logger &, nano::work_thresholds & work); nano::opencl_config const & config; nano::mutex mutex; cl_context context; @@ -56,7 +56,7 @@ class opencl_work cl_kernel kernel; cl_command_queue queue; nano::xorshift1024star rand; - nano::logger_mt & logger; + nano::logger & logger; nano::work_thresholds & work; }; } diff --git a/nano/node/portmapping.cpp b/nano/node/portmapping.cpp index 690b7ce907..e8d01e847f 100644 --- a/nano/node/portmapping.cpp +++ b/nano/node/portmapping.cpp @@ -60,17 +60,19 @@ void nano::port_mapping::refresh_devices () std::array local_address_l; local_address_l.fill (0); auto igd_error_l (UPNP_GetValidIGD (upnp_l.devices, &upnp_l.urls, &upnp_l.data, local_address_l.data (), sizeof (local_address_l))); - if (check_count % 15 == 0 || node.config.logging.upnp_details_logging ()) + + // Bump logging level periodically + node.logger.log ((check_count % 15 == 0) ? nano::log::level::info : nano::log::level::debug, + nano::log::type::upnp, "UPnP local address {}, discovery: {}, IGD search: {}", + local_address_l.data (), + discover_error_l, + igd_error_l); + + for (auto i (upnp_l.devices); i != nullptr; i = i->pNext) { - node.logger.always_log (boost::str (boost::format ("UPnP local address: %1%, discovery: %2%, IGD search: %3%") % local_address_l.data () % discover_error_l % igd_error_l)); - if (node.config.logging.upnp_details_logging ()) - { - for (auto i (upnp_l.devices); i != nullptr; i = i->pNext) - { - node.logger.always_log (boost::str (boost::format ("UPnP device url: %1% st: %2% usn: %3%") % i->descURL % i->st % i->usn)); - } - } + node.logger.debug (nano::log::type::upnp, "UPnP device url: {}, st: {}, usn: {}", i->descURL, i->st, i->usn); } + // Update port mapping nano::lock_guard guard_l (mutex); upnp = std::move (upnp_l); @@ -114,14 +116,23 @@ void nano::port_mapping::refresh_mapping () if (add_port_mapping_error_l == UPNPCOMMAND_SUCCESS) { protocol.external_port = static_cast (std::atoi (config_port_l.data ())); - auto fmt = boost::format ("UPnP %1% %2%:%3% mapped to %4%") % protocol.name % protocol.external_address % config_port_l % node_port_l; - node.logger.always_log (boost::str (fmt)); + + node.logger.info (nano::log::type::upnp, "UPnP {} {}:{} mapped to: {}", + protocol.name, + protocol.external_address.to_string (), + config_port_l, + node_port_l); } else { protocol.external_port = 0; - auto fmt = boost::format ("UPnP %1% %2%:%3% FAILED") % protocol.name % add_port_mapping_error_l % strupnperror (add_port_mapping_error_l); - node.logger.always_log (boost::str (fmt)); + + node.logger.warn (nano::log::type::upnp, "UPnP {} {}:{} failed: {} ({})", + protocol.name, + protocol.external_address.to_string (), + config_port_l, + add_port_mapping_error_l, + strupnperror (add_port_mapping_error_l)); } } } @@ -149,12 +160,19 @@ bool nano::port_mapping::check_lost_or_old_mapping () if (verify_port_mapping_error_l != UPNPCOMMAND_SUCCESS) { result_l = true; - node.logger.always_log (boost::str (boost::format ("UPNP_GetSpecificPortMappingEntry failed %1%: %2%") % verify_port_mapping_error_l % strupnperror (verify_port_mapping_error_l))); + + node.logger.warn (nano::log::type::upnp, "UPnP get specific port mapping failed: {} ({})", + verify_port_mapping_error_l, + strupnperror (verify_port_mapping_error_l)); } if (!recent_lease) { result_l = true; - node.logger.always_log (boost::str (boost::format ("UPnP leasing time getting old, remaining time: %1%, lease time: %2%, below the threshold: %3%") % remaining_from_port_mapping % lease_duration % lease_duration_divided_by_two)); + + node.logger.info (nano::log::type::upnp, "UPnP lease time getting old, remaining time: {}, lease time: {}, below the threshold: {}", + remaining_from_port_mapping, + lease_duration, + lease_duration_divided_by_two); } std::array external_address_l; external_address_l.fill (0); @@ -168,12 +186,19 @@ bool nano::port_mapping::check_lost_or_old_mapping () else { protocol.external_address = boost::asio::ip::address_v4::any (); - node.logger.always_log (boost::str (boost::format ("UPNP_GetExternalIPAddress failed %1%: %2%") % verify_port_mapping_error_l % strupnperror (verify_port_mapping_error_l))); - } - if (node.config.logging.upnp_details_logging ()) - { - node.logger.always_log (boost::str (boost::format ("UPnP %1% mapping verification response: %2%, external ip response: %3%, external ip: %4%, internal ip: %5%, remaining lease: %6%") % protocol.name % verify_port_mapping_error_l % external_ip_error_l % external_address_l.data () % address.to_string () % remaining_mapping_duration_l.data ())); + + node.logger.warn (nano::log::type::upnp, "UPnP get external ip address failed: {} ({})", + external_ip_error_l, + strupnperror (external_ip_error_l)); } + + node.logger.debug (nano::log::type::upnp, "UPnP {} mapping verification response: {}, external ip response: {}, external ip: {}, internal ip: {}, remaining lease: {}", + protocol.name, + verify_port_mapping_error_l, + external_ip_error_l, + external_address_l.data (), + address.to_string (), + remaining_mapping_duration_l.data ()); } return result_l; } @@ -194,15 +219,14 @@ void nano::port_mapping::check_mapping_loop () } else { - node.logger.always_log (boost::str (boost::format ("UPnP No need to refresh the mapping"))); + node.logger.info (nano::log::type::upnp, "UPnP No need to refresh the mapping"); } } else { - if (check_count < 10 || node.config.logging.upnp_details_logging ()) - { - node.logger.always_log (boost::str (boost::format ("UPnP No IGD devices found"))); - } + // Bump logging level periodically + node.logger.log ((check_count % 15 == 0) ? nano::log::level::info : nano::log::level::debug, + nano::log::type::upnp, "UPnP No IGD devices found"); } // Check for new devices or after health_check_period @@ -225,11 +249,17 @@ void nano::port_mapping::stop () auto delete_error_l (UPNP_DeletePortMapping (upnp.urls.controlURL, upnp.data.first.servicetype, std::to_string (protocol.external_port).c_str (), protocol.name, address.to_string ().c_str ())); if (delete_error_l) { - node.logger.always_log (boost::str (boost::format ("UPnP shutdown %1% port mapping response: %2%") % protocol.name % delete_error_l)); + node.logger.warn (nano::log::type::upnp, "UPnP shutdown {} port mapping failed: {} ({})", + protocol.name, + delete_error_l, + strupnperror (delete_error_l)); } else { - node.logger.always_log (boost::str (boost::format ("UPnP shutdown %1% port mapping successful: %2%:%3%") % protocol.name % protocol.external_address % protocol.external_port)); + node.logger.info (nano::log::type::upnp, "UPnP shutdown {} port mapping successful: {}:{}", + protocol.name, + protocol.external_address.to_string (), + protocol.external_port); } } } diff --git a/nano/node/repcrawler.cpp b/nano/node/repcrawler.cpp index 0d637b1483..8d7bb5ceee 100644 --- a/nano/node/repcrawler.cpp +++ b/nano/node/repcrawler.cpp @@ -45,20 +45,18 @@ void nano::rep_crawler::validate () if (channel->get_type () == nano::transport::transport_type::loopback) { - if (node.config.logging.rep_crawler_logging ()) - { - node.logger.try_log (boost::str (boost::format ("rep_crawler ignoring vote from loopback channel %1%") % channel->to_string ())); - } + node.logger.debug (nano::log::type::repcrawler, "Ignoring vote from loopback channel: {}", channel->to_string ()); + continue; } nano::uint128_t rep_weight = node.ledger.weight (vote->account); if (rep_weight < minimum) { - if (node.config.logging.rep_crawler_logging ()) - { - node.logger.try_log (boost::str (boost::format ("rep_crawler ignoring vote from account %1% with too little voting weight %2%") % vote->account.to_account () % rep_weight)); - } + node.logger.debug (nano::log::type::repcrawler, "Ignoring vote from account {} with too little voting weight: {}", + vote->account.to_account (), + nano::util::to_str (rep_weight)); + continue; } @@ -95,12 +93,11 @@ void nano::rep_crawler::validate () if (inserted) { - node.logger.try_log (boost::str (boost::format ("Found representative %1% at %2%") % vote->account.to_account () % channel->to_string ())); + node.logger.info (nano::log::type::repcrawler, "Found representative {} at {}", vote->account.to_account (), channel->to_string ()); } - if (updated) { - node.logger.try_log (boost::str (boost::format ("Updated representative %1% at %2% (was at: %3%)") % vote->account.to_account () % channel->to_string () % prev_channel->to_string ())); + node.logger.warn (nano::log::type::repcrawler, "Updated representative {} at {} (was at: {})", vote->account.to_account (), channel->to_string (), prev_channel->to_string ()); } } } diff --git a/nano/node/transport/channel.cpp b/nano/node/transport/channel.cpp index 39037b734b..4649726786 100644 --- a/nano/node/transport/channel.cpp +++ b/nano/node/transport/channel.cpp @@ -22,23 +22,20 @@ void nano::transport::channel::send (nano::message & message_a, std::function #include +#include + nano::transport::message_deserializer::message_deserializer (nano::network_constants const & network_constants_a, nano::network_filter & publish_filter_a, nano::block_uniquer & block_uniquer_a, nano::vote_uniquer & vote_uniquer_a, read_query read_op) : read_buffer{ std::make_shared> () }, @@ -380,8 +382,10 @@ std::unique_ptr nano::transport::message_deserializer::deser return {}; } -nano::stat::detail nano::transport::message_deserializer::to_stat_detail (parse_status status) +nano::stat::detail nano::to_stat_detail (nano::transport::message_deserializer::parse_status status) { + using parse_status = nano::transport::message_deserializer::parse_status; + // Keep additional `break` for readability switch (status) { @@ -449,74 +453,7 @@ nano::stat::detail nano::transport::message_deserializer::to_stat_detail (parse_ return {}; } -std::string nano::transport::message_deserializer::to_string (parse_status status) +std::string_view nano::to_string (nano::transport::message_deserializer::parse_status status) { - // Keep additional `break` for readability - switch (status) - { - case parse_status::none: - return "none"; - break; - case parse_status::success: - return "success"; - break; - case parse_status::insufficient_work: - return "insufficient_work"; - break; - case parse_status::invalid_header: - return "invalid_header"; - break; - case parse_status::invalid_message_type: - return "invalid_message_type"; - break; - case parse_status::invalid_keepalive_message: - return "invalid_keepalive_message"; - break; - case parse_status::invalid_publish_message: - return "invalid_publish_message"; - break; - case parse_status::invalid_confirm_req_message: - return "invalid_confirm_req_message"; - break; - case parse_status::invalid_confirm_ack_message: - return "invalid_confirm_ack_message"; - break; - case parse_status::invalid_node_id_handshake_message: - return "invalid_node_id_handshake_message"; - break; - case parse_status::invalid_telemetry_req_message: - return "invalid_telemetry_req_message"; - break; - case parse_status::invalid_telemetry_ack_message: - return "invalid_telemetry_ack_message"; - break; - case parse_status::invalid_bulk_pull_message: - return "invalid_bulk_pull_message"; - break; - case parse_status::invalid_bulk_pull_account_message: - return "invalid_bulk_pull_account_message"; - break; - case parse_status::invalid_frontier_req_message: - return "invalid_frontier_req_message"; - break; - case parse_status::invalid_asc_pull_req_message: - return "invalid_asc_pull_req_message"; - break; - case parse_status::invalid_asc_pull_ack_message: - return "invalid_asc_pull_ack_message"; - break; - case parse_status::invalid_network: - return "invalid_network"; - break; - case parse_status::outdated_version: - return "outdated_version"; - break; - case parse_status::duplicate_publish_message: - return "duplicate_publish_message"; - break; - case parse_status::message_size_too_big: - return "message_size_too_big"; - break; - } - return "n/a"; + return magic_enum::enum_name (status); } diff --git a/nano/node/transport/message_deserializer.hpp b/nano/node/transport/message_deserializer.hpp index 0a85454e51..9a2fbc21c6 100644 --- a/nano/node/transport/message_deserializer.hpp +++ b/nano/node/transport/message_deserializer.hpp @@ -89,11 +89,9 @@ namespace transport nano::block_uniquer & block_uniquer_m; nano::vote_uniquer & vote_uniquer_m; read_query read_op; - - public: - static stat::detail to_stat_detail (parse_status); - static std::string to_string (parse_status); }; - } + +nano::stat::detail to_stat_detail (nano::transport::message_deserializer::parse_status); +std::string_view to_string (nano::transport::message_deserializer::parse_status); } diff --git a/nano/node/transport/socket.cpp b/nano/node/transport/socket.cpp index 21fbc4de44..609bb75220 100644 --- a/nano/node/transport/socket.cpp +++ b/nano/node/transport/socket.cpp @@ -54,6 +54,7 @@ void nano::transport::socket::async_connect (nano::tcp_endpoint const & endpoint this_l->tcp_socket.async_connect (endpoint_a, boost::asio::bind_executor (this_l->strand, [this_l, callback = std::move (callback_a), endpoint_a] (boost::system::error_code const & ec) { + this_l->remote = endpoint_a; if (ec) { this_l->node.stats.inc (nano::stat::type::tcp, nano::stat::detail::tcp_connect_error, nano::stat::dir::in); @@ -62,9 +63,13 @@ void nano::transport::socket::async_connect (nano::tcp_endpoint const & endpoint else { this_l->set_last_completion (); + { + // Best effort attempt to get endpoint address + boost::system::error_code ec; + this_l->local = this_l->tcp_socket.local_endpoint (ec); + } + this_l->node.observers.socket_connected.notify (*this_l); } - this_l->remote = endpoint_a; - this_l->node.observers.socket_connected.notify (*this_l); callback (ec); })); } @@ -241,23 +246,22 @@ void nano::transport::socket::ongoing_checkup () if (this_l->endpoint_type () == endpoint_type_t::server && (now - this_l->last_receive_time_or_init) > static_cast (this_l->silent_connection_tolerance_time.count ())) { this_l->node.stats.inc (nano::stat::type::tcp, nano::stat::detail::tcp_silent_connection_drop, nano::stat::dir::in); + condition_to_disconnect = true; } // if there is no activity for timeout seconds then disconnect if ((now - this_l->last_completion_time_or_init) > this_l->timeout) { - this_l->node.stats.inc (nano::stat::type::tcp, nano::stat::detail::tcp_io_timeout_drop, - this_l->endpoint_type () == endpoint_type_t::server ? nano::stat::dir::in : nano::stat::dir::out); + this_l->node.stats.inc (nano::stat::type::tcp, nano::stat::detail::tcp_io_timeout_drop, this_l->endpoint_type () == endpoint_type_t::server ? nano::stat::dir::in : nano::stat::dir::out); + condition_to_disconnect = true; } if (condition_to_disconnect) { - if (this_l->node.config.logging.network_timeout_logging ()) - { - this_l->node.logger.try_log (boost::str (boost::format ("Disconnecting from %1% due to timeout") % this_l->remote)); - } + this_l->node.logger.debug (nano::log::type::tcp_server, "Closing socket due to timeout ({})", nano::util::to_str (this_l->remote)); + this_l->timed_out = true; this_l->close (); } @@ -330,19 +334,21 @@ void nano::transport::socket::close_internal () if (ec) { - node.logger.try_log ("Failed to close socket gracefully: ", ec.message ()); - node.stats.inc (nano::stat::type::bootstrap, nano::stat::detail::error_socket_close); + node.stats.inc (nano::stat::type::socket, nano::stat::detail::error_socket_close); + node.logger.error (nano::log::type::socket, "Failed to close socket gracefully: {} ({})", ec.message (), nano::util::to_str (remote)); } } nano::tcp_endpoint nano::transport::socket::remote_endpoint () const { + // Using cached value to avoid calling tcp_socket.remote_endpoint() which may be invalid (throw) after closing the socket return remote; } nano::tcp_endpoint nano::transport::socket::local_endpoint () const { - return tcp_socket.local_endpoint (); + // Using cached value to avoid calling tcp_socket.local_endpoint() which may be invalid (throw) after closing the socket + return local; } /* diff --git a/nano/node/transport/socket.hpp b/nano/node/transport/socket.hpp index b2593b1ba2..0ac01400fc 100644 --- a/nano/node/transport/socket.hpp +++ b/nano/node/transport/socket.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -157,6 +158,7 @@ class socket final : public std::enable_shared_from_thisnetwork.prepare_handshake_query (endpoint_a); nano::node_id_handshake message{ node_l->network_params.network, query }; - if (node_l->config.logging.network_node_id_handshake_logging ()) - { - node_l->logger.try_log (boost::str (boost::format ("Node ID handshake request sent with node ID %1% to %2%: query %3%") % node_l->node_id.pub.to_node_id () % endpoint_a % (query ? query->cookie.to_string () : "not set"))); - } + node_l->logger.debug (nano::log::type::tcp, "Handshake sent to: {} (query: {})", + nano::util::to_str (endpoint_a), + (query ? query->cookie.to_string () : "")); channel->set_endpoint (); std::shared_ptr> receive_buffer (std::make_shared> ()); @@ -572,30 +571,25 @@ void nano::transport::tcp_channels::start_tcp (nano::endpoint const & endpoint_a } else { + node_l->logger.debug (nano::log::type::tcp, "Error sending handshake to: {} ({})", nano::util::to_str (endpoint_a), ec.message ()); + if (auto socket_l = channel->socket.lock ()) { socket_l->close (); } - if (node_l->config.logging.network_node_id_handshake_logging ()) - { - node_l->logger.try_log (boost::str (boost::format ("Error sending node_id_handshake to %1%: %2%") % endpoint_a % ec.message ())); - } } } }); } else { - if (node_l->config.logging.network_logging ()) + if (ec) { - if (ec) - { - node_l->logger.try_log (boost::str (boost::format ("Error connecting to %1%: %2%") % endpoint_a % ec.message ())); - } - else - { - node_l->logger.try_log (boost::str (boost::format ("Error connecting to %1%") % endpoint_a)); - } + node_l->logger.debug (nano::log::type::tcp, "Error connecting to: {} ({})", nano::util::to_str (endpoint_a), ec.message ()); + } + else + { + node_l->logger.debug (nano::log::type::tcp, "Error connecting to: {}", nano::util::to_str (endpoint_a)); } } } @@ -633,10 +627,8 @@ void nano::transport::tcp_channels::start_tcp_receive_node_id (std::shared_ptrconfig.logging.network_node_id_handshake_logging ()) - { - node_l->logger.try_log (boost::str (boost::format ("Error reading node_id_handshake from %1%: %2%") % endpoint_a % ec.message ())); - } + node_l->logger.debug (nano::log::type::tcp, "Error reading handshake from: {} ({})", nano::util::to_str (endpoint_a), ec.message ()); + cleanup_node_id_handshake_socket (endpoint_a); return; } @@ -646,10 +638,8 @@ void nano::transport::tcp_channels::start_tcp_receive_node_id (std::shared_ptrtype () != nano::message_type::node_id_handshake) { - if (node_l->config.logging.network_node_id_handshake_logging ()) - { - node_l->logger.try_log (boost::str (boost::format ("Error reading node_id_handshake message header from %1%") % endpoint_a)); - } + node_l->logger.debug (nano::log::type::tcp, "Error reading handshake header from: {} ({})", nano::util::to_str (endpoint_a), ec.message ()); + cleanup_node_id_handshake_socket (endpoint_a); return; } @@ -678,10 +668,8 @@ void nano::transport::tcp_channels::start_tcp_receive_node_id (std::shared_ptrconfig.logging.network_node_id_handshake_logging ()) - { - node_l->logger.try_log (boost::str (boost::format ("Error reading node_id_handshake from %1%") % endpoint_a)); - } + node_l->logger.debug (nano::log::type::tcp, "Error reading handshake payload from: {} ({})", nano::util::to_str (endpoint_a), ec.message ()); + cleanup_node_id_handshake_socket (endpoint_a); return; } @@ -714,10 +702,9 @@ void nano::transport::tcp_channels::start_tcp_receive_node_id (std::shared_ptrnetwork.prepare_handshake_response (*handshake.query, handshake.is_v2 ()); nano::node_id_handshake handshake_response (node_l->network_params.network, std::nullopt, response); - if (node_l->config.logging.network_node_id_handshake_logging ()) - { - node_l->logger.try_log (boost::str (boost::format ("Node ID handshake response sent with node ID %1% to %2%: query %3%") % node_l->node_id.pub.to_node_id () % endpoint_a % handshake.query->cookie.to_string ())); - } + node_l->logger.debug (nano::log::type::tcp, "Handshake response sent to {} (query: {})", + nano::util::to_str (endpoint_a), + handshake.query->cookie.to_string ()); channel_a->send (handshake_response, [node_w, channel_a, endpoint_a, cleanup_node_id_handshake_socket] (boost::system::error_code const & ec, std::size_t size_a) { auto node_l = node_w.lock (); @@ -727,10 +714,8 @@ void nano::transport::tcp_channels::start_tcp_receive_node_id (std::shared_ptrconfig.logging.network_node_id_handshake_logging ()) - { - node_l->logger.try_log (boost::str (boost::format ("Error sending node_id_handshake to %1%: %2%") % endpoint_a % ec.message ())); - } + node_l->logger.debug (nano::log::type::tcp, "Error sending handshake response to: {} ({})", nano::util::to_str (endpoint_a), ec.message ()); + cleanup_node_id_handshake_socket (endpoint_a); return; } diff --git a/nano/node/transport/tcp_server.cpp b/nano/node/transport/tcp_server.cpp index 57222dc365..9d02482b11 100644 --- a/nano/node/transport/tcp_server.cpp +++ b/nano/node/transport/tcp_server.cpp @@ -56,7 +56,7 @@ void nano::transport::tcp_listener::start (std::functionacceptor.is_open ()) { - this_l->node.logger.always_log ("Network: Acceptor is not open"); + this_l->node.logger.error (nano::log::type::tcp_listener, "Acceptor is not open"); return; } @@ -138,20 +138,18 @@ void nano::transport::tcp_listener::on_connection (std::functionconnections_per_address.size () >= this_l->max_inbound_connections) { - this_l->node.logger.try_log ("Network: max_inbound_connections reached, unable to open new connection"); this_l->node.stats.inc (nano::stat::type::tcp, nano::stat::detail::tcp_accept_failure, nano::stat::dir::in); + this_l->node.logger.debug (nano::log::type::tcp_listener, "Max connections reached ({}), unable to open new connection", this_l->connections_per_address.size ()); + this_l->on_connection_requeue_delayed (std::move (cbk)); return; } if (this_l->limit_reached_for_incoming_ip_connections (new_connection)) { - auto const remote_ip_address = new_connection->remote_endpoint ().address (); - auto const log_message = boost::str ( - boost::format ("Network: max connections per IP (max_peers_per_ip) was reached for %1%, unable to open new connection") - % remote_ip_address.to_string ()); - this_l->node.logger.try_log (log_message); this_l->node.stats.inc (nano::stat::type::tcp, nano::stat::detail::tcp_max_per_ip, nano::stat::dir::in); + this_l->node.logger.debug (nano::log::type::tcp_listener, "Max connections per IP reached ({}), unable to open new connection", new_connection->remote_endpoint ().address ().to_string ()); + this_l->on_connection_requeue_delayed (std::move (cbk)); return; } @@ -161,18 +159,24 @@ void nano::transport::tcp_listener::on_connection (std::functionremote_endpoint ().address (); debug_assert (remote_ip_address.is_v6 ()); auto const remote_subnet = socket_functions::get_ipv6_subnet_address (remote_ip_address.to_v6 (), this_l->node.network_params.network.max_peers_per_subnetwork); - auto const log_message = boost::str ( - boost::format ("Network: max connections per subnetwork (max_peers_per_subnetwork) was reached for subnetwork %1% (remote IP: %2%), unable to open new connection") - % remote_subnet.canonical ().to_string () - % remote_ip_address.to_string ()); - this_l->node.logger.try_log (log_message); + this_l->node.stats.inc (nano::stat::type::tcp, nano::stat::detail::tcp_max_per_subnetwork, nano::stat::dir::in); + this_l->node.logger.debug (nano::log::type::tcp_listener, "Max connections per subnetwork reached (subnetwork: {}, ip: {}), unable to open new connection", + remote_subnet.canonical ().to_string (), + remote_ip_address.to_string ()); + this_l->on_connection_requeue_delayed (std::move (cbk)); return; } if (!ec_a) { + { + // Best effort attempt to get endpoint addresses + boost::system::error_code ec; + new_connection->local = new_connection->tcp_socket.local_endpoint (ec); + } + // Make sure the new connection doesn't idle. Note that in most cases, the callback is going to start // an IO operation immediately, which will start a timer. new_connection->start (); @@ -185,13 +189,13 @@ void nano::transport::tcp_listener::on_connection (std::functionon_connection (std::move (cbk)); return; } - this_l->node.logger.always_log ("Network: Stopping to accept connections"); + this_l->node.logger.warn (nano::log::type::tcp_listener, "Stopping to accept new connections"); return; } // accept error - this_l->node.logger.try_log ("Network: Unable to accept connection: ", ec_a.message ()); this_l->node.stats.inc (nano::stat::type::tcp, nano::stat::detail::tcp_accept_failure, nano::stat::dir::in); + this_l->node.logger.error (nano::log::type::tcp_listener, "Unable to accept connection: {} ({})", ec_a.message (), new_connection->remote_endpoint ().address ().to_string ()); if (is_temporary_error (ec_a)) { @@ -208,7 +212,7 @@ void nano::transport::tcp_listener::on_connection (std::functionnode.logger.always_log ("Network: Stopping to accept connections"); + this_l->node.logger.warn (nano::log::type::tcp_listener, "Stopping to accept new connections"); })); })); } @@ -250,10 +254,7 @@ void nano::transport::tcp_listener::accept_action (boost::system::error_code con else { node.stats.inc (nano::stat::type::tcp, nano::stat::detail::tcp_excluded); - if (node.config.logging.network_rejected_logging ()) - { - node.logger.try_log ("Rejected connection from excluded peer ", socket_a->remote_endpoint ()); - } + node.logger.debug (nano::log::type::tcp_server, "Rejected connection from excluded peer: {}", nano::util::to_str (socket_a->remote_endpoint ())); } } @@ -304,10 +305,8 @@ nano::transport::tcp_server::~tcp_server () { return; } - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log ("Exiting incoming TCP/bootstrap server"); - } + + node->logger.debug (nano::log::type::tcp_server, "Exiting TCP server ({})", nano::util::to_str (remote_endpoint)); if (socket->type () == nano::transport::socket::type_t::bootstrap) { @@ -340,6 +339,12 @@ void nano::transport::tcp_server::start () remote_endpoint = socket->remote_endpoint (); debug_assert (remote_endpoint.port () != 0); } + + if (auto node_l = node.lock (); node_l) + { + node_l->logger.debug (nano::log::type::tcp_server, "Starting TCP server ({})", nano::util::to_str (remote_endpoint)); + } + receive_message (); } @@ -367,7 +372,12 @@ void nano::transport::tcp_server::receive_message () if (ec) { // IO error or critical error when deserializing message - node->stats.inc (nano::stat::type::error, nano::transport::message_deserializer::to_stat_detail (this_l->message_deserializer->status)); + node->stats.inc (nano::stat::type::error, nano::to_stat_detail (this_l->message_deserializer->status)); + node->logger.debug (nano::log::type::tcp_server, "Error reading message: {}, status: {} ({})", + ec.message (), + nano::to_string (this_l->message_deserializer->status), + nano::util::to_str (this_l->remote_endpoint)); + this_l->stop (); } else @@ -393,11 +403,19 @@ void nano::transport::tcp_server::received_message (std::unique_ptrstatus != transport::message_deserializer::parse_status::success); - node->stats.inc (nano::stat::type::error, nano::transport::message_deserializer::to_stat_detail (message_deserializer->status)); + + node->stats.inc (nano::stat::type::error, nano::to_stat_detail (message_deserializer->status)); if (message_deserializer->status == transport::message_deserializer::parse_status::duplicate_publish_message) { node->stats.inc (nano::stat::type::filter, nano::stat::detail::duplicate_publish); } + else + { + // Avoid too much noise about `duplicate_publish_message` errors + node->logger.debug (nano::log::type::tcp_server, "Error deserializing message: {} ({})", + nano::to_string (message_deserializer->status), + nano::util::to_str (remote_endpoint)); + } } if (should_continue) @@ -448,6 +466,10 @@ bool nano::transport::tcp_server::process_message (std::unique_ptrlogger.debug (nano::log::type::tcp_server, "Neither handshake nor bootstrap received when in handshake mode: {} ({})", + nano::to_string (message->header.type), + nano::util::to_str (remote_endpoint)); + return true; } } @@ -500,10 +522,8 @@ void nano::transport::tcp_server::handshake_message_visitor::node_id_handshake ( } if (node->flags.disable_tcp_realtime) { - if (node->config.logging.network_node_id_handshake_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Disabled realtime TCP for handshake %1%") % server->remote_endpoint)); - } + node->logger.debug (nano::log::type::tcp_server, "Handshake attempted with disabled realtime TCP ({})", nano::util::to_str (server->remote_endpoint)); + // Stop invalid handshake server->stop (); return; @@ -511,10 +531,8 @@ void nano::transport::tcp_server::handshake_message_visitor::node_id_handshake ( if (message.query && server->handshake_query_received) { - if (node->config.logging.network_node_id_handshake_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Detected multiple node_id_handshake query from %1%") % server->remote_endpoint)); - } + node->logger.debug (nano::log::type::tcp_server, "Detected multiple handshake queries ({})", nano::util::to_str (server->remote_endpoint)); + // Stop invalid handshake server->stop (); return; @@ -522,10 +540,7 @@ void nano::transport::tcp_server::handshake_message_visitor::node_id_handshake ( server->handshake_query_received = true; - if (node->config.logging.network_node_id_handshake_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Received node_id_handshake message from %1%") % server->remote_endpoint)); - } + node->logger.debug (nano::log::type::tcp_server, "Handshake query received ({})", nano::util::to_str (server->remote_endpoint)); if (message.query) { @@ -569,10 +584,8 @@ void nano::transport::tcp_server::send_handshake_response (nano::node_id_handsha } if (ec) { - if (node->config.logging.network_node_id_handshake_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Error sending node_id_handshake to %1%: %2%") % this_l->remote_endpoint % ec.message ())); - } + node->logger.debug (nano::log::type::tcp_server, "Error sending handshake response: {} ({})", ec.message (), nano::util::to_str (this_l->remote_endpoint)); + // Stop invalid handshake this_l->stop (); } @@ -692,11 +705,6 @@ void nano::transport::tcp_server::bootstrap_message_visitor::bulk_pull (const na return; } - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Received bulk pull for %1% down to %2%, maximum of %3% from %4%") % message.start.to_string () % message.end.to_string () % message.count % server->remote_endpoint)); - } - node->bootstrap_workers.push_task ([server = server, message = message] () { // TODO: Add completion callback to bulk pull server // TODO: There should be no need to re-copy message as unique pointer, refactor those bulk/frontier pull/push servers @@ -719,11 +727,6 @@ void nano::transport::tcp_server::bootstrap_message_visitor::bulk_pull_account ( return; } - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Received bulk pull account for %1% with a minimum amount of %2%") % message.account.to_account () % nano::amount (message.minimum_amount).format_balance (nano::Mxrb_ratio, 10, true))); - } - node->bootstrap_workers.push_task ([server = server, message = message] () { // TODO: Add completion callback to bulk pull server // TODO: There should be no need to re-copy message as unique pointer, refactor those bulk/frontier pull/push servers @@ -757,10 +760,6 @@ void nano::transport::tcp_server::bootstrap_message_visitor::frontier_req (const { return; } - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log (boost::str (boost::format ("Received frontier request for %1% with age %2%") % message.start.to_string () % message.age)); - } node->bootstrap_workers.push_task ([server = server, message = message] () { // TODO: There should be no need to re-copy message as unique pointer, refactor those bulk/frontier pull/push servers @@ -782,10 +781,8 @@ void nano::transport::tcp_server::timeout () } if (socket->has_timed_out ()) { - if (node->config.logging.bulk_pull_logging ()) - { - node->logger.try_log ("Closing incoming tcp / bootstrap server by timeout"); - } + node->logger.debug (nano::log::type::tcp_server, "Closing TCP server due to timeout ({})", nano::util::to_str (remote_endpoint)); + { nano::lock_guard lock{ node->tcp_listener->mutex }; node->tcp_listener->connections.erase (this); @@ -820,6 +817,9 @@ bool nano::transport::tcp_server::to_bootstrap_connection () ++node->tcp_listener->bootstrap_count; socket->type_set (nano::transport::socket::type_t::bootstrap); + + node->logger.debug (nano::log::type::tcp_server, "Switched to bootstrap mode ({})", nano::util::to_str (remote_endpoint)); + return true; } @@ -835,6 +835,9 @@ bool nano::transport::tcp_server::to_realtime_connection (nano::account const & remote_node_id = node_id; ++node->tcp_listener->realtime_count; socket->type_set (nano::transport::socket::type_t::realtime); + + node->logger.debug (nano::log::type::tcp_server, "Switched to realtime mode ({})", nano::util::to_str (remote_endpoint)); + return true; } return false; diff --git a/nano/node/vote_processor.cpp b/nano/node/vote_processor.cpp index 76a32d59df..0885da8332 100644 --- a/nano/node/vote_processor.cpp +++ b/nano/node/vote_processor.cpp @@ -1,4 +1,4 @@ -#include + #include #include #include @@ -15,7 +15,7 @@ #include using namespace std::chrono_literals; -nano::vote_processor::vote_processor (nano::active_transactions & active_a, nano::node_observers & observers_a, nano::stats & stats_a, nano::node_config & config_a, nano::node_flags & flags_a, nano::logger_mt & logger_a, nano::online_reps & online_reps_a, nano::rep_crawler & rep_crawler_a, nano::ledger & ledger_a, nano::network_params & network_params_a) : +nano::vote_processor::vote_processor (nano::active_transactions & active_a, nano::node_observers & observers_a, nano::stats & stats_a, nano::node_config & config_a, nano::node_flags & flags_a, nano::logger & logger_a, nano::online_reps & online_reps_a, nano::rep_crawler & rep_crawler_a, nano::ledger & ledger_a, nano::network_params & network_params_a) : active (active_a), observers (observers_a), stats (stats_a), @@ -62,7 +62,8 @@ void nano::vote_processor::process_loop () condition.notify_all (); log_this_iteration = false; - if (config.logging.network_logging () && votes_l.size () > 50) + // TODO: This is a temporary measure to prevent spamming the logs until we can implement a better solution + if (votes_l.size () > 1024 * 4) { /* * Only log the timing information for this iteration if @@ -76,8 +77,12 @@ void nano::vote_processor::process_loop () if (log_this_iteration && elapsed.stop () > std::chrono::milliseconds (100)) { - logger.try_log (boost::str (boost::format ("Processed %1% votes in %2% milliseconds (rate of %3% votes per second)") % votes_l.size () % elapsed.value ().count () % ((votes_l.size () * 1000ULL) / elapsed.value ().count ()))); + logger.debug (nano::log::type::vote_processor, "Processed {} votes in {} milliseconds (rate of {} votes per second)", + votes_l.size (), + elapsed.value ().count (), + ((votes_l.size () * 1000ULL) / elapsed.value ().count ())); } + lock.lock (); } else @@ -168,10 +173,7 @@ nano::vote_code nano::vote_processor::vote_blocking (std::shared_ptr stats.inc (nano::stat::type::vote, nano::stat::detail::vote_indeterminate); break; } - if (config.logging.vote_logging ()) - { - logger.try_log (boost::str (boost::format ("Vote from: %1% timestamp: %2% duration %3%ms block(s): %4% status: %5%") % vote_a->account.to_account () % std::to_string (vote_a->timestamp ()) % std::to_string (vote_a->duration ().count ()) % vote_a->hashes_string () % status)); - } + return result; } @@ -197,7 +199,7 @@ void nano::vote_processor::flush () }); if (!success) { - logger.always_log ("WARNING: vote_processor::flush timeout while waiting for flush"); + logger.error (nano::log::type::vote_processor, "Flush timeout"); debug_assert (false && "vote_processor::flush timeout while waiting for flush"); } } diff --git a/nano/node/vote_processor.hpp b/nano/node/vote_processor.hpp index 4ee3c6f0ea..dbcacc41c3 100644 --- a/nano/node/vote_processor.hpp +++ b/nano/node/vote_processor.hpp @@ -20,7 +20,7 @@ namespace store class node_observers; class stats; class node_config; -class logger_mt; +class logger; class online_reps; class rep_crawler; class ledger; @@ -36,7 +36,7 @@ namespace transport class vote_processor final { public: - vote_processor (nano::active_transactions & active_a, nano::node_observers & observers_a, nano::stats & stats_a, nano::node_config & config_a, nano::node_flags & flags_a, nano::logger_mt & logger_a, nano::online_reps & online_reps_a, nano::rep_crawler & rep_crawler_a, nano::ledger & ledger_a, nano::network_params & network_params_a); + vote_processor (nano::active_transactions & active_a, nano::node_observers & observers_a, nano::stats & stats_a, nano::node_config & config_a, nano::node_flags & flags_a, nano::logger &, nano::online_reps & online_reps_a, nano::rep_crawler & rep_crawler_a, nano::ledger & ledger_a, nano::network_params & network_params_a); /** Returns false if the vote was processed */ bool vote (std::shared_ptr const &, std::shared_ptr const &); @@ -60,7 +60,7 @@ class vote_processor final nano::node_observers & observers; nano::stats & stats; nano::node_config & config; - nano::logger_mt & logger; + nano::logger & logger; nano::online_reps & online_reps; nano::rep_crawler & rep_crawler; nano::ledger & ledger; diff --git a/nano/node/wallet.cpp b/nano/node/wallet.cpp index f2e05c6cd2..3f29a80a0e 100644 --- a/nano/node/wallet.cpp +++ b/nano/node/wallet.cpp @@ -699,16 +699,17 @@ bool nano::wallet::enter_password (store::transaction const & transaction_a, std auto result (store.attempt_password (transaction_a, password_a)); if (!result) { + wallets.node.logger.info (nano::log::type::wallet, "Wallet unlocked"); + auto this_l = shared_from_this (); wallets.node.wallets.queue_wallet_action (nano::wallets::high_priority, this_l, [this_l] (nano::wallet & wallet) { // Wallets must survive node lifetime this_l->search_receivable (this_l->wallets.tx_begin_read ()); }); - wallets.node.logger.try_log ("Wallet unlocked"); } else { - wallets.node.logger.try_log ("Invalid password, wallet locked"); + wallets.node.logger.warn (nano::log::type::wallet, "Invalid password, wallet locked"); } lock_observer (result, password_a.empty ()); return result; @@ -865,7 +866,7 @@ std::shared_ptr nano::wallet::receive_action (nano::block_hash cons } else { - wallets.node.logger.try_log ("Unable to receive, wallet locked"); + wallets.node.logger.warn (nano::log::type::wallet, "Unable to receive, wallet locked"); } } else @@ -880,8 +881,8 @@ std::shared_ptr nano::wallet::receive_action (nano::block_hash cons } else { - wallets.node.logger.try_log (boost::str (boost::format ("Not receiving block %1% due to minimum receive threshold") % send_hash_a.to_string ())); // Someone sent us something below the threshold of receiving + wallets.node.logger.warn (nano::log::type::wallet, "Not receiving block {} due to minimum receive threshold", send_hash_a.to_string ()); } if (block != nullptr) { @@ -1043,7 +1044,10 @@ bool nano::wallet::action_complete (std::shared_ptr const & block_a auto required_difficulty{ wallets.node.network_params.work.threshold (block_a->work_version (), details_a) }; if (wallets.node.network_params.work.difficulty (*block_a) < required_difficulty) { - wallets.node.logger.try_log (boost::str (boost::format ("Cached or provided work for block %1% account %2% is invalid, regenerating") % block_a->hash ().to_string () % account_a.to_account ())); + wallets.node.logger.info (nano::log::type::wallet, "Cached or provided work for block {} account {} is invalid, regenerating...", + block_a->hash ().to_string (), + account_a.to_account ()); + debug_assert (required_difficulty <= wallets.node.max_work_generate_difficulty (block_a->work_version ())); error = !wallets.node.work_generate_blocking (*block_a, required_difficulty).is_initialized (); } @@ -1139,7 +1143,7 @@ void nano::wallet::work_update (store::transaction const & transaction_a, nano:: } else { - wallets.node.logger.try_log ("Cached work no longer valid, discarding"); + wallets.node.logger.warn (nano::log::type::wallet, "Cached work no longer valid, discarding"); } } @@ -1168,7 +1172,8 @@ bool nano::wallet::search_receivable (store::transaction const & wallet_transact auto result (!store.valid_password (wallet_transaction_a)); if (!result) { - wallets.node.logger.try_log ("Beginning receivable block search"); + wallets.node.logger.info (nano::log::type::wallet, "Beginning receivable block search"); + for (auto i (store.begin (wallet_transaction_a)), n (store.end ()); i != n; ++i) { auto block_transaction (wallets.node.store.tx_begin_read ()); @@ -1184,7 +1189,8 @@ bool nano::wallet::search_receivable (store::transaction const & wallet_transact auto amount (pending.amount.number ()); if (wallets.node.config.receive_minimum.number () <= amount) { - wallets.node.logger.try_log (boost::str (boost::format ("Found a receivable block %1% for account %2%") % hash.to_string () % pending.source.to_account ())); + wallets.node.logger.info (nano::log::type::wallet, "Found a receivable block {} for account {}", hash.to_string (), pending.source.to_account ()); + if (wallets.node.ledger.block_confirmed (block_transaction, hash)) { auto representative = store.representative (wallet_transaction_a); @@ -1204,11 +1210,12 @@ bool nano::wallet::search_receivable (store::transaction const & wallet_transact } } } - wallets.node.logger.try_log ("Receivable block search phase completed"); + + wallets.node.logger.info (nano::log::type::wallet, "Receivable block search phase complete"); } else { - wallets.node.logger.try_log ("Stopping search, wallet is locked"); + wallets.node.logger.warn (nano::log::type::wallet, "Stopping search, wallet is locked"); } return result; } @@ -1300,7 +1307,7 @@ void nano::wallet::work_cache_blocking (nano::account const & account_a, nano::r } else if (!wallets.node.stopped) { - wallets.node.logger.try_log (boost::str (boost::format ("Could not precache work for root %1% due to work generation failure") % root_a.to_string ())); + wallets.node.logger.warn (nano::log::type::wallet, "Could not precache work for root {} due to work generation failure", root_a.to_string ()); } } } @@ -1556,11 +1563,13 @@ void nano::wallets::foreach_representative (std::functionfirst.to_string ())); + + node.logger.warn (nano::log::type::wallet, "Representative locked inside wallet: {}", i->first.to_string ()); } } } diff --git a/nano/node/websocket.cpp b/nano/node/websocket.cpp index fd436c6b14..c2b3af2f98 100644 --- a/nano/node/websocket.cpp +++ b/nano/node/websocket.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -14,12 +15,13 @@ #include #include -nano::websocket::confirmation_options::confirmation_options (nano::wallets & wallets_a) : - wallets (wallets_a) +nano::websocket::confirmation_options::confirmation_options (nano::wallets & wallets_a, nano::logger & logger_a) : + wallets (wallets_a), + logger (logger_a) { } -nano::websocket::confirmation_options::confirmation_options (boost::property_tree::ptree const & options_a, nano::wallets & wallets_a, nano::logger_mt & logger_a) : +nano::websocket::confirmation_options::confirmation_options (boost::property_tree::ptree const & options_a, nano::wallets & wallets_a, nano::logger & logger_a) : wallets (wallets_a), logger (logger_a) { @@ -62,7 +64,7 @@ nano::websocket::confirmation_options::confirmation_options (boost::property_tre if (!include_block) { - logger_a.always_log ("Websocket: Filtering option \"all_local_accounts\" requires that \"include_block\" is set to true to be effective"); + logger.warn (nano::log::type::websocket, "Filtering option \"all_local_accounts\" requires that \"include_block\" is set to true to be effective"); } } auto accounts_l (options_a.get_child_optional ("accounts")); @@ -79,13 +81,13 @@ nano::websocket::confirmation_options::confirmation_options (boost::property_tre } else { - logger_a.always_log ("Websocket: invalid account provided for filtering blocks: ", account_l.second.data ()); + logger.warn (nano::log::type::websocket, "Invalid account provided for filtering blocks: ", account_l.second.data ()); } } if (!include_block) { - logger_a.always_log ("Websocket: Filtering option \"accounts\" requires that \"include_block\" is set to true to be effective"); + logger.warn (nano::log::type::websocket, "Filtering option \"accounts\" requires that \"include_block\" is set to true to be effective"); } } check_filter_empty (); @@ -158,9 +160,9 @@ bool nano::websocket::confirmation_options::update (boost::property_tree::ptree this->accounts.erase (encoded_l); } } - else if (this->logger.is_initialized ()) + else { - this->logger->always_log ("Websocket: invalid account provided for filtering blocks: ", account_l.second.data ()); + logger.warn (nano::log::type::websocket, "Invalid account provided for filtering blocks: ", account_l.second.data ()); } } }; @@ -186,13 +188,13 @@ bool nano::websocket::confirmation_options::update (boost::property_tree::ptree void nano::websocket::confirmation_options::check_filter_empty () const { // Warn the user if the options resulted in an empty filter - if (logger.is_initialized () && has_account_filtering_options && !all_local_accounts && accounts.empty ()) + if (has_account_filtering_options && !all_local_accounts && accounts.empty ()) { - logger->always_log ("Websocket: provided options resulted in an empty block confirmation filter"); + logger.warn (nano::log::type::websocket, "Provided options resulted in an empty account confirmation filter"); } } -nano::websocket::vote_options::vote_options (boost::property_tree::ptree const & options_a, nano::logger_mt & logger_a) +nano::websocket::vote_options::vote_options (boost::property_tree::ptree const & options_a, nano::logger & logger) { include_replays = options_a.get ("include_replays", false); include_indeterminate = options_a.get ("include_indeterminate", false); @@ -209,13 +211,13 @@ nano::websocket::vote_options::vote_options (boost::property_tree::ptree const & } else { - logger_a.always_log ("Websocket: invalid account given to filter votes: ", representative_l.second.data ()); + logger.warn (nano::log::type::websocket, "Invalid account provided for filtering votes: ", representative_l.second.data ()); } } // Warn the user if the option will be ignored if (representatives.empty ()) { - logger_a.always_log ("Websocket: account filter for votes is empty, no messages will be filtered"); + logger.warn (nano::log::type::websocket, "Account filter for votes is empty, no messages will be filtered"); } } } @@ -240,15 +242,25 @@ bool nano::websocket::vote_options::should_filter (nano::websocket::message cons nano::websocket::session::session (nano::websocket::listener & listener_a, socket_type socket_a, boost::asio::ssl::context & ctx_a) : ws_listener (listener_a), ws (std::move (socket_a), ctx_a) { - ws_listener.get_logger ().try_log ("Websocket: secure session started"); } #endif -nano::websocket::session::session (nano::websocket::listener & listener_a, socket_type socket_a) : - ws_listener (listener_a), ws (std::move (socket_a)) +nano::websocket::session::session (nano::websocket::listener & listener_a, socket_type socket_a, nano::logger & logger_a) : + ws_listener (listener_a), + ws (std::move (socket_a)), + logger (logger_a) { - ws_listener.get_logger ().try_log ("Websocket: session started"); + { + // Best effort attempt to get endpoint addresses + boost::system::error_code ec; + remote = ws.get_socket ().remote_endpoint (ec); + debug_assert (!ec); + local = ws.get_socket ().local_endpoint (ec); + debug_assert (!ec); + } + + logger.info (nano::log::type::websocket, "Session started ({})", nano::util::to_str (remote)); } nano::websocket::session::~session () @@ -273,14 +285,14 @@ void nano::websocket::session::handshake () } else { - this_l->ws_listener.get_logger ().always_log ("Websocket: handshake failed: ", ec.message ()); + this_l->logger.error (nano::log::type::websocket, "Handshake failed: {} ({})", ec.message (), nano::util::to_str (this_l->remote)); } }); } void nano::websocket::session::close () { - ws_listener.get_logger ().try_log ("Websocket: session closing"); + logger.info (nano::log::type::websocket, "Session closing ({})", nano::util::to_str (remote)); auto this_l (shared_from_this ()); boost::asio::dispatch (ws.get_strand (), @@ -356,12 +368,12 @@ void nano::websocket::session::read () } catch (boost::property_tree::json_parser::json_parser_error const & ex) { - this_l->ws_listener.get_logger ().try_log ("Websocket: json parsing failed: ", ex.what ()); + this_l->logger.error (nano::log::type::websocket, "JSON parsing failed: {} ({})", ex.what (), nano::util::to_str (this_l->remote)); } } else if (ec != boost::asio::error::eof) { - this_l->ws_listener.get_logger ().try_log ("Websocket: read failed: ", ec.message ()); + this_l->logger.error (nano::log::type::websocket, "Read failed: {} ({})", ec.message (), nano::util::to_str (this_l->remote)); } }); }); @@ -483,11 +495,11 @@ void nano::websocket::session::handle_message (boost::property_tree::ptree const std::unique_ptr options_l{ nullptr }; if (options_text_l && topic_l == nano::websocket::topic::confirmation) { - options_l = std::make_unique (options_text_l.get (), ws_listener.get_wallets (), ws_listener.get_logger ()); + options_l = std::make_unique (options_text_l.get (), ws_listener.get_wallets (), logger); } else if (options_text_l && topic_l == nano::websocket::topic::vote) { - options_l = std::make_unique (options_text_l.get (), ws_listener.get_logger ()); + options_l = std::make_unique (options_text_l.get (), logger); } else { @@ -496,13 +508,15 @@ void nano::websocket::session::handle_message (boost::property_tree::ptree const auto existing (subscriptions.find (topic_l)); if (existing != subscriptions.end ()) { + logger.info (nano::log::type::websocket, "Updated subscription to topic: {} ({})", from_topic (topic_l), nano::util::to_str (remote)); + existing->second = std::move (options_l); - ws_listener.get_logger ().always_log ("Websocket: updated subscription to topic: ", from_topic (topic_l)); } else { + logger.info (nano::log::type::websocket, "New subscription to topic: {} ({})", from_topic (topic_l), nano::util::to_str (remote)); + subscriptions.emplace (topic_l, std::move (options_l)); - ws_listener.get_logger ().always_log ("Websocket: new subscription to topic: ", from_topic (topic_l)); ws_listener.increase_subscriber_count (topic_l); } action_succeeded = true; @@ -525,7 +539,8 @@ void nano::websocket::session::handle_message (boost::property_tree::ptree const nano::lock_guard lk (subscriptions_mutex); if (subscriptions.erase (topic_l)) { - ws_listener.get_logger ().always_log ("Websocket: removed subscription to topic: ", from_topic (topic_l)); + logger.info (nano::log::type::websocket, "Removed subscription to topic: {} ({})", from_topic (topic_l), nano::util::to_str (remote)); + ws_listener.decrease_subscriber_count (topic_l); } action_succeeded = true; @@ -559,7 +574,7 @@ void nano::websocket::listener::stop () sessions.clear (); } -nano::websocket::listener::listener (std::shared_ptr const & tls_config_a, nano::logger_mt & logger_a, nano::wallets & wallets_a, boost::asio::io_context & io_ctx_a, boost::asio::ip::tcp::endpoint endpoint_a) : +nano::websocket::listener::listener (std::shared_ptr const & tls_config_a, nano::logger & logger_a, nano::wallets & wallets_a, boost::asio::io_context & io_ctx_a, boost::asio::ip::tcp::endpoint endpoint_a) : tls_config (tls_config_a), logger (logger_a), wallets (wallets_a), @@ -579,7 +594,7 @@ nano::websocket::listener::listener (std::shared_ptr const & t } catch (std::exception const & ex) { - logger.always_log ("Websocket: listen failed: ", ex.what ()); + logger.error (nano::log::type::websocket, "Listen failed: {}", ex.what ()); } } @@ -604,7 +619,7 @@ void nano::websocket::listener::on_accept (boost::system::error_code ec) { if (ec) { - logger.always_log ("Websocket: accept failed: ", ec.message ()); + logger.error (nano::log::type::websocket, "Accept failed: {}", ec.message ()); } else { @@ -618,7 +633,7 @@ void nano::websocket::listener::on_accept (boost::system::error_code ec) } else { - session = std::make_shared (*this, std::move (socket)); + session = std::make_shared (*this, std::move (socket), logger); } sessions_mutex.lock (); @@ -650,7 +665,7 @@ void nano::websocket::listener::broadcast_confirmation (std::shared_ptrsubscriptions.find (nano::websocket::topic::confirmation)); if (subscription != session_ptr->subscriptions.end ()) { - nano::websocket::confirmation_options default_options (wallets); + nano::websocket::confirmation_options default_options (wallets, logger); auto conf_options (dynamic_cast (subscription->second.get ())); if (conf_options == nullptr) { @@ -967,7 +982,7 @@ std::string nano::websocket::message::to_string () const * websocket_server */ -nano::websocket_server::websocket_server (nano::websocket::config & config_a, nano::node_observers & observers_a, nano::wallets & wallets_a, nano::ledger & ledger_a, boost::asio::io_context & io_ctx_a, nano::logger_mt & logger_a) : +nano::websocket_server::websocket_server (nano::websocket::config & config_a, nano::node_observers & observers_a, nano::wallets & wallets_a, nano::ledger & ledger_a, boost::asio::io_context & io_ctx_a, nano::logger & logger_a) : config{ config_a }, observers{ observers_a }, wallets{ wallets_a }, diff --git a/nano/node/websocket.hpp b/nano/node/websocket.hpp index 9d197dcfb6..6bb7426a0b 100644 --- a/nano/node/websocket.hpp +++ b/nano/node/websocket.hpp @@ -21,7 +21,7 @@ namespace nano { class wallets; -class logger_mt; +class logger; class vote; class election_status; class telemetry_data; @@ -142,8 +142,8 @@ namespace websocket class confirmation_options final : public options { public: - confirmation_options (nano::wallets & wallets_a); - confirmation_options (boost::property_tree::ptree const & options_a, nano::wallets & wallets_a, nano::logger_mt & logger_a); + confirmation_options (nano::wallets & wallets_a, nano::logger &); + confirmation_options (boost::property_tree::ptree const & options_a, nano::wallets & wallets_a, nano::logger &); /** * Checks if a message should be filtered for given block confirmation options. @@ -195,7 +195,8 @@ namespace websocket void check_filter_empty () const; nano::wallets & wallets; - boost::optional logger; + nano::logger & logger; + bool include_election_info{ false }; bool include_election_info_with_votes{ false }; bool include_sideband_info{ false }; @@ -214,7 +215,7 @@ namespace websocket class vote_options final : public options { public: - vote_options (boost::property_tree::ptree const & options_a, nano::logger_mt & logger_a); + vote_options (boost::property_tree::ptree const & options_a, nano::logger &); /** * Checks if a message should be filtered for given vote received options. @@ -240,7 +241,7 @@ namespace websocket explicit session (nano::websocket::listener & listener_a, socket_type socket_a, boost::asio::ssl::context & ctx_a); #endif /** Constructor that takes ownership over \p socket_a */ - explicit session (nano::websocket::listener & listener_a, socket_type socket_a); + explicit session (nano::websocket::listener & listener_a, socket_type socket_a, nano::logger &); ~session (); @@ -261,11 +262,17 @@ namespace websocket nano::websocket::listener & ws_listener; /** Websocket stream, supporting both plain and tls connections */ nano::websocket::stream ws; + nano::logger & logger; + /** Buffer for received messages */ boost::beast::multi_buffer read_buffer; /** Outgoing messages. The send queue is protected by accessing it only through the strand */ std::deque send_queue; + /** Cache remote & local endpoints to make them available after the socket is closed */ + socket_type::endpoint_type remote; + socket_type::endpoint_type local; + /** Hash functor for topic enums */ struct topic_hash { @@ -291,7 +298,7 @@ namespace websocket class listener final : public std::enable_shared_from_this { public: - listener (std::shared_ptr const & tls_config_a, nano::logger_mt & logger_a, nano::wallets & wallets_a, boost::asio::io_context & io_ctx_a, boost::asio::ip::tcp::endpoint endpoint_a); + listener (std::shared_ptr const & tls_config_a, nano::logger &, nano::wallets & wallets_a, boost::asio::io_context & io_ctx_a, boost::asio::ip::tcp::endpoint endpoint_a); /** Start accepting connections */ void run (); @@ -307,11 +314,6 @@ namespace websocket /** Broadcast \p message to all session subscribing to the message topic. */ void broadcast (nano::websocket::message message_a); - nano::logger_mt & get_logger () const - { - return logger; - } - std::uint16_t listening_port () { return acceptor.local_endpoint ().port (); @@ -346,7 +348,7 @@ namespace websocket void decrease_subscriber_count (nano::websocket::topic const & topic_a); std::shared_ptr tls_config; - nano::logger_mt & logger; + nano::logger & logger; nano::wallets & wallets; boost::asio::ip::tcp::acceptor acceptor; socket_type socket; @@ -363,7 +365,7 @@ namespace websocket class websocket_server { public: - websocket_server (nano::websocket::config &, nano::node_observers &, nano::wallets &, nano::ledger &, boost::asio::io_context &, nano::logger_mt &); + websocket_server (nano::websocket::config &, nano::node_observers &, nano::wallets &, nano::ledger &, boost::asio::io_context &, nano::logger &); void start (); void stop (); @@ -374,7 +376,7 @@ class websocket_server nano::wallets & wallets; nano::ledger & ledger; boost::asio::io_context & io_ctx; - nano::logger_mt & logger; + nano::logger & logger; public: // TODO: Encapsulate, this is public just because existing code needs it diff --git a/nano/node/websocket_stream.cpp b/nano/node/websocket_stream.cpp index 74d5eaf8a3..d680e999d2 100644 --- a/nano/node/websocket_stream.cpp +++ b/nano/node/websocket_stream.cpp @@ -67,6 +67,11 @@ class stream_wrapper : public nano::websocket::websocket_stream_concept return strand; } + socket_type & get_socket () override + { + return ws.next_layer (); + } + void close (boost::beast::websocket::close_reason const & reason_a, boost::system::error_code & ec_a) override { ws.close (reason_a, ec_a); @@ -105,6 +110,11 @@ nano::websocket::stream::stream (socket_type socket_a) return impl->get_strand (); } +[[nodiscard]] socket_type & nano::websocket::stream::get_socket () +{ + return impl->get_socket (); +} + void nano::websocket::stream::handshake (std::function callback_a) { impl->handshake (callback_a); diff --git a/nano/node/websocket_stream.hpp b/nano/node/websocket_stream.hpp index 03e21490ce..5a5cb86c45 100644 --- a/nano/node/websocket_stream.hpp +++ b/nano/node/websocket_stream.hpp @@ -32,6 +32,7 @@ class websocket_stream_concept public: virtual ~websocket_stream_concept () = default; virtual boost::asio::strand & get_strand () = 0; + virtual socket_type & get_socket () = 0; virtual void handshake (std::function callback_a) = 0; virtual void close (boost::beast::websocket::close_reason const & reason_a, boost::system::error_code & ec_a) = 0; virtual void async_write (nano::shared_const_buffer const & buffer_a, std::function callback_a) = 0; @@ -51,6 +52,7 @@ class stream final : public websocket_stream_concept stream (socket_type socket_a); [[nodiscard]] boost::asio::strand & get_strand () override; + [[nodiscard]] socket_type & get_socket () override; void handshake (std::function callback_a) override; void close (boost::beast::websocket::close_reason const & reason_a, boost::system::error_code & ec_a) override; void async_write (nano::shared_const_buffer const & buffer_a, std::function callback_a) override; diff --git a/nano/qt/qt.cpp b/nano/qt/qt.cpp index 2c8b6cfb1b..2b83d7d61a 100644 --- a/nano/qt/qt.cpp +++ b/nano/qt/qt.cpp @@ -1546,7 +1546,7 @@ nano_qt::settings::settings (nano_qt::wallet & wallet_a) : retype_password->setPlaceholderText ("Retype password"); show_button_success (*change); change->setText ("Password was changed"); - this->wallet.node.logger.try_log ("Wallet password changed"); + this->wallet.node.logger.warn (nano::log::type::qt, "Wallet password changed"); update_locked (false, false); this->wallet.node.workers.add_timed_task (std::chrono::steady_clock::now () + std::chrono::seconds (5), [this] () { this->wallet.application.postEvent (&this->wallet.processor, new eventloop_event ([this] () { @@ -1639,7 +1639,7 @@ nano_qt::settings::settings (nano_qt::wallet & wallet_a) : this->wallet.wallet_m->store.password.value_set (empty); update_locked (true, true); lock_toggle->setText ("Unlock"); - this->wallet.node.logger.try_log ("Wallet locked"); + this->wallet.node.logger.warn (nano::log::type::qt, "Wallet locked"); password->setEnabled (1); } else diff --git a/nano/qt_test/entry.cpp b/nano/qt_test/entry.cpp index 0352439ec6..e8976178c4 100644 --- a/nano/qt_test/entry.cpp +++ b/nano/qt_test/entry.cpp @@ -1,8 +1,10 @@ +#include #include #include #include + QApplication * test_application = nullptr; namespace nano { @@ -15,6 +17,7 @@ void force_nano_dev_network (); int main (int argc, char ** argv) { + nano::logger::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); diff --git a/nano/qt_test/qt.cpp b/nano/qt_test/qt.cpp index f7b1b41ae3..b7b6621ae3 100644 --- a/nano/qt_test/qt.cpp +++ b/nano/qt_test/qt.cpp @@ -522,7 +522,8 @@ TEST (history, short_text) account = system.account (transaction, 0); } auto wallet (std::make_shared (*test_application, processor, *system.nodes[0], system.wallet (0), account)); - auto store = nano::make_store (system.nodes[0]->logger, nano::unique_path (), nano::dev::constants); + nano::logger logger; + auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::ledger ledger (*store, system.nodes[0]->stats, nano::dev::constants); { @@ -559,7 +560,8 @@ TEST (history, pruned_source) account = system.account (transaction, 0); } auto wallet (std::make_shared (*test_application, processor, *system.nodes[0], system.wallet (0), account)); - auto store = nano::make_store (system.nodes[0]->logger, nano::unique_path (), nano::dev::constants); + nano::logger logger; + auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_TRUE (!store->init_error ()); nano::ledger ledger (*store, system.nodes[0]->stats, nano::dev::constants); ledger.pruning = true; @@ -683,7 +685,7 @@ TEST (wallet, import) system.wallet (0)->store.serialize_json (transaction, json); } system.wallet (1)->insert_adhoc (key2.prv); - auto path (nano::unique_path ()); + auto path{ nano::unique_path () / "wallet.json" }; { std::ofstream stream; stream.open (path.string ().c_str ()); diff --git a/nano/rpc/rpc.cpp b/nano/rpc/rpc.cpp index 18c0e5a227..687c9b316e 100644 --- a/nano/rpc/rpc.cpp +++ b/nano/rpc/rpc.cpp @@ -15,7 +15,6 @@ nano::rpc::rpc (boost::asio::io_context & io_ctx_a, nano::rpc_config config_a, nano::rpc_handler_interface & rpc_handler_interface_a) : config (std::move (config_a)), acceptor (io_ctx_a), - logger (std::chrono::milliseconds (0)), io_ctx (io_ctx_a), rpc_handler_interface (rpc_handler_interface_a) { @@ -33,13 +32,13 @@ nano::rpc::~rpc () void nano::rpc::start () { auto endpoint (boost::asio::ip::tcp::endpoint (boost::asio::ip::make_address_v6 (config.address), config.port)); + bool const is_loopback = (endpoint.address ().is_loopback () || (endpoint.address ().to_v6 ().is_v4_mapped () && boost::asio::ip::make_address_v4 (boost::asio::ip::v4_mapped, endpoint.address ().to_v6 ()).is_loopback ())); if (!is_loopback && config.enable_control) { - auto warning = boost::str (boost::format ("WARNING: control-level RPCs are enabled on non-local address %1%, potentially allowing wallet access outside local computer") % endpoint.address ().to_string ()); - std::cout << warning << std::endl; - logger.always_log (warning); + logger.warn (nano::log::type::rpc, "WARNING: Control-level RPCs are enabled on non-local address {}, potentially allowing wallet access outside local computer", endpoint.address ().to_string ()); } + acceptor.open (endpoint.protocol ()); acceptor.set_option (boost::asio::ip::tcp::acceptor::reuse_address (true)); @@ -47,7 +46,7 @@ void nano::rpc::start () acceptor.bind (endpoint, ec); if (ec) { - logger.always_log (boost::str (boost::format ("Error while binding for RPC on port %1%: %2%") % endpoint.port () % ec.message ())); + logger.critical (nano::log::type::rpc, "Error while binding for RPC on port: {} ({})", endpoint.port (), ec.message ()); throw std::runtime_error (ec.message ()); } acceptor.listen (); @@ -68,7 +67,7 @@ void nano::rpc::accept () } else { - logger.always_log (boost::str (boost::format ("Error accepting RPC connections: %1% (%2%)") % ec.message () % ec.value ())); + logger.error (nano::log::type::rpc, "Error accepting RPC connection: {}", ec.message ()); } })); } diff --git a/nano/rpc/rpc.hpp b/nano/rpc/rpc.hpp index 40c096f37c..99f66b260a 100644 --- a/nano/rpc/rpc.hpp +++ b/nano/rpc/rpc.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include #include @@ -31,9 +31,9 @@ class rpc return acceptor.local_endpoint ().port (); } + nano::logger logger{ "rpc" }; nano::rpc_config config; boost::asio::ip::tcp::acceptor acceptor; - nano::logger_mt logger; boost::asio::io_context & io_ctx; nano::rpc_handler_interface & rpc_handler_interface; bool stopped{ false }; diff --git a/nano/rpc/rpc_connection.cpp b/nano/rpc/rpc_connection.cpp index f4d96be45b..d7c71562c1 100644 --- a/nano/rpc/rpc_connection.cpp +++ b/nano/rpc/rpc_connection.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include #include @@ -14,7 +13,7 @@ #endif #include -nano::rpc_connection::rpc_connection (nano::rpc_config const & rpc_config, boost::asio::io_context & io_ctx, nano::logger_mt & logger, nano::rpc_handler_interface & rpc_handler_interface) : +nano::rpc_connection::rpc_connection (nano::rpc_config const & rpc_config, boost::asio::io_context & io_ctx, nano::logger & logger, nano::rpc_handler_interface & rpc_handler_interface) : socket (io_ctx), strand (io_ctx.get_executor ()), io_ctx (io_ctx), @@ -84,7 +83,7 @@ void nano::rpc_connection::read (STREAM_TYPE & stream) } else { - this_l->logger.always_log ("RPC header error: ", ec.message ()); + this_l->logger.error (nano::log::type::rpc_connection, "RPC header error: ", ec.message ()); // Respond with the reason for the invalid header auto response_handler ([this_l, &stream] (std::string const & tree_a) { @@ -123,12 +122,9 @@ void nano::rpc_connection::parse_request (STREAM_TYPE & stream, std::shared_ptr< this_l->write_completion_handler (this_l); })); - std::stringstream ss; - if (this_l->rpc_config.rpc_logging.log_rpc) - { - ss << "RPC request " << request_id << " completed in: " << std::chrono::duration_cast (std::chrono::steady_clock::now () - start).count () << " microseconds"; - this_l->logger.always_log (ss.str ().c_str ()); - } + // Bump logging level if RPC request logging is enabled + this_l->logger.log (this_l->rpc_config.rpc_logging.log_rpc ? nano::log::level::info : nano::log::level::debug, + nano::log::type::rpc_request, "RPC request {} completed in {} microseconds", request_id, std::chrono::duration_cast (std::chrono::steady_clock::now () - start).count ()); }); std::string api_path_l = "/api/v2"; @@ -168,7 +164,7 @@ void nano::rpc_connection::parse_request (STREAM_TYPE & stream, std::shared_ptr< } else { - this_l->logger.always_log ("RPC read error: ", ec.message ()); + this_l->logger.error (nano::log::type::rpc_connection, "RPC read error: ", ec.message ()); } })); } diff --git a/nano/rpc/rpc_connection.hpp b/nano/rpc/rpc_connection.hpp index 3226e28064..960e0b31fa 100644 --- a/nano/rpc/rpc_connection.hpp +++ b/nano/rpc/rpc_connection.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include @@ -18,14 +19,13 @@ using socket_type = boost::asio::basic_stream_socket { public: - rpc_connection (nano::rpc_config const & rpc_config, boost::asio::io_context & io_ctx, nano::logger_mt & logger, nano::rpc_handler_interface & rpc_handler_interface_a); + rpc_connection (nano::rpc_config const & rpc_config, boost::asio::io_context & io_ctx, nano::logger &, nano::rpc_handler_interface & rpc_handler_interface_a); virtual ~rpc_connection () = default; virtual void parse_connection (); virtual void write_completion_handler (std::shared_ptr const & rpc_connection); @@ -38,7 +38,7 @@ class rpc_connection : public std::enable_shared_from_this boost::asio::strand strand; std::atomic_flag responded; boost::asio::io_context & io_ctx; - nano::logger_mt & logger; + nano::logger & logger; nano::rpc_config const & rpc_config; nano::rpc_handler_interface & rpc_handler_interface; diff --git a/nano/rpc/rpc_handler.cpp b/nano/rpc/rpc_handler.cpp index 7148d45d63..241c46c47c 100644 --- a/nano/rpc/rpc_handler.cpp +++ b/nano/rpc/rpc_handler.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include #include #include @@ -18,7 +17,7 @@ std::unordered_set rpc_control_impl_set = create_rpc_control_impls std::string filter_request (boost::property_tree::ptree tree_a); } -nano::rpc_handler::rpc_handler (nano::rpc_config const & rpc_config, std::string const & body_a, std::string const & request_id_a, std::function const & response_a, nano::rpc_handler_interface & rpc_handler_interface_a, nano::logger_mt & logger) : +nano::rpc_handler::rpc_handler (nano::rpc_config const & rpc_config, std::string const & body_a, std::string const & request_id_a, std::function const & response_a, nano::rpc_handler_interface & rpc_handler_interface_a, nano::logger & logger) : body (body_a), request_id (request_id_a), response (response_a), @@ -62,13 +61,10 @@ void nano::rpc_handler::process_request (nano::rpc_handler_request_params const } auto action = request.get ("action"); - if (rpc_config.rpc_logging.log_rpc) - { - // Creating same string via stringstream as using it directly is generating a TSAN warning - std::stringstream ss; - ss << request_id; - logger.always_log (ss.str (), " ", filter_request (request)); - } + + // Bump logging level if RPC request logging is enabled + logger.log (rpc_config.rpc_logging.log_rpc ? nano::log::level::info : nano::log::level::debug, + nano::log::type::rpc_request, "Request {} : {}", request_id, filter_request (request)); // Check if this is a RPC command which requires RPC enabled control std::error_code rpc_control_disabled_ec = nano::error_rpc::rpc_control_disabled; diff --git a/nano/rpc/rpc_handler.hpp b/nano/rpc/rpc_handler.hpp index 2e919f303a..55a979fa07 100644 --- a/nano/rpc/rpc_handler.hpp +++ b/nano/rpc/rpc_handler.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include #include @@ -9,13 +11,12 @@ namespace nano { class rpc_config; class rpc_handler_interface; -class logger_mt; class rpc_handler_request_params; class rpc_handler : public std::enable_shared_from_this { public: - rpc_handler (nano::rpc_config const & rpc_config, std::string const & body_a, std::string const & request_id_a, std::function const & response_a, nano::rpc_handler_interface & rpc_handler_interface_a, nano::logger_mt & logger); + rpc_handler (nano::rpc_config const & rpc_config, std::string const & body_a, std::string const & request_id_a, std::function const & response_a, nano::rpc_handler_interface & rpc_handler_interface_a, nano::logger &); void process_request (nano::rpc_handler_request_params const & request_params); private: @@ -25,6 +26,6 @@ class rpc_handler : public std::enable_shared_from_this std::function response; nano::rpc_config const & rpc_config; nano::rpc_handler_interface & rpc_handler_interface; - nano::logger_mt & logger; + nano::logger & logger; }; } diff --git a/nano/rpc/rpc_secure.cpp b/nano/rpc/rpc_secure.cpp index 3f596a7cba..9640e28c2f 100644 --- a/nano/rpc/rpc_secure.cpp +++ b/nano/rpc/rpc_secure.cpp @@ -27,7 +27,7 @@ void nano::rpc_secure::accept () } else { - logger.always_log (boost::str (boost::format ("Error accepting RPC connections: %1%") % ec)); + logger.error (nano::log::type::rpc, "Error accepting RPC connection: {}", ec.message ()); } })); } diff --git a/nano/rpc_test/entry.cpp b/nano/rpc_test/entry.cpp index 530f146c98..2a94b7d9e7 100644 --- a/nano/rpc_test/entry.cpp +++ b/nano/rpc_test/entry.cpp @@ -1,7 +1,9 @@ +#include #include #include #include + namespace nano { namespace test @@ -13,6 +15,7 @@ void force_nano_dev_network (); int main (int argc, char ** argv) { + nano::logger::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; diff --git a/nano/rpc_test/rpc.cpp b/nano/rpc_test/rpc.cpp index 056d05a1b7..fff4b0d3ac 100644 --- a/nano/rpc_test/rpc.cpp +++ b/nano/rpc_test/rpc.cpp @@ -1677,7 +1677,7 @@ TEST (rpc, keepalive) { nano::test::system system; auto node0 = add_ipc_enabled_node (system); - auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work)); + auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work)); node1->start (); system.nodes.push_back (node1); auto const rpc_ctx = add_rpc (system, node0); @@ -5376,7 +5376,6 @@ TEST (rpc, block_confirm_confirmed) config.callback_address = "localhost"; config.callback_port = system.get_available_port (); config.callback_target = "/"; - config.logging.init (path); auto node = add_ipc_enabled_node (system, config); { auto transaction (node->store.tx_begin_read ()); diff --git a/nano/secure/common.cpp b/nano/secure/common.cpp index 35b5ad68f9..525083669d 100644 --- a/nano/secure/common.cpp +++ b/nano/secure/common.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include diff --git a/nano/secure/ledger.cpp b/nano/secure/ledger.cpp index e7c7f1abf9..0fc1ecd604 100644 --- a/nano/secure/ledger.cpp +++ b/nano/secure/ledger.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -1558,7 +1559,7 @@ bool nano::ledger::migrate_lmdb_to_rocksdb (std::filesystem::path const & data_p auto rockdb_data_path = data_path_a / "rocksdb"; std::filesystem::remove_all (rockdb_data_path); - nano::logger_mt logger; + nano::logger logger; auto error (false); // Open rocksdb database diff --git a/nano/secure/ledger.hpp b/nano/secure/ledger.hpp index c1e2b11817..6cabac2eee 100644 --- a/nano/secure/ledger.hpp +++ b/nano/secure/ledger.hpp @@ -17,9 +17,6 @@ namespace nano { class stats; -// map of vote weight per block, ordered greater first -using tally_t = std::map, std::greater>; - class uncemented_info { public: diff --git a/nano/secure/utility.cpp b/nano/secure/utility.cpp index 19c5836294..0ed99eb9b1 100644 --- a/nano/secure/utility.cpp +++ b/nano/secure/utility.cpp @@ -46,6 +46,9 @@ std::filesystem::path nano::unique_path (nano::networks network) } auto result = working_path (network) / random_string; + + std::filesystem::create_directories (result); + all_unique_paths.push_back (result); return result; } @@ -60,15 +63,6 @@ void nano::remove_temporary_directories () { std::cerr << "Could not remove temporary directory: " << ec.message () << std::endl; } - - // lmdb creates a -lock suffixed file for its MDB_NOSUBDIR databases - auto lockfile = path; - lockfile += "-lock"; - std::filesystem::remove (lockfile, ec); - if (ec) - { - std::cerr << "Could not remove temporary lock file: " << ec.message () << std::endl; - } } } diff --git a/nano/secure/vote.cpp b/nano/secure/vote.cpp index 2f19c9748e..208aca4de1 100644 --- a/nano/secure/vote.cpp +++ b/nano/secure/vote.cpp @@ -165,13 +165,9 @@ std::string nano::vote::to_json () const std::string nano::vote::hashes_string () const { - std::string result; - for (auto const & hash : hashes) - { - result += hash.to_string (); - result += ", "; - } - return result; + return nano::util::join (hashes, ",", [] (auto const & hash) { + return hash.to_string (); + }); } uint64_t nano::vote::packed_timestamp (uint64_t timestamp, uint8_t duration) @@ -184,13 +180,4 @@ uint64_t nano::vote::packed_timestamp (uint64_t timestamp, uint8_t duration) bool nano::vote::is_final_timestamp (uint64_t timestamp) { return timestamp == std::numeric_limits::max (); -} - -/* - * iterate_vote_blocks_as_hash - */ - -nano::block_hash nano::iterate_vote_blocks_as_hash::operator() (nano::block_hash const & item) const -{ - return item; -} +} \ No newline at end of file diff --git a/nano/secure/vote.hpp b/nano/secure/vote.hpp index 35d7308a13..d7c9b62b32 100644 --- a/nano/secure/vote.hpp +++ b/nano/secure/vote.hpp @@ -12,14 +12,6 @@ namespace nano { -using vote_blocks_vec_iter = std::vector::const_iterator; -class iterate_vote_blocks_as_hash final -{ -public: - iterate_vote_blocks_as_hash () = default; - nano::block_hash operator() (nano::block_hash const & item) const; -}; - class vote final { public: @@ -43,9 +35,6 @@ class vote final bool operator== (nano::vote const &) const; bool operator!= (nano::vote const &) const; - boost::transform_iterator begin () const; - boost::transform_iterator end () const; - void serialize_json (boost::property_tree::ptree & tree) const; std::string to_json () const; std::string hashes_string () const; diff --git a/nano/slow_test/entry.cpp b/nano/slow_test/entry.cpp index cc8fd2e18e..0b9a0ca758 100644 --- a/nano/slow_test/entry.cpp +++ b/nano/slow_test/entry.cpp @@ -1,6 +1,8 @@ +#include #include #include + namespace nano { namespace test @@ -12,6 +14,7 @@ void force_nano_dev_network (); int main (int argc, char ** argv) { + nano::logger::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); diff --git a/nano/slow_test/node.cpp b/nano/slow_test/node.cpp index 2bb0075c01..4310968dae 100644 --- a/nano/slow_test/node.cpp +++ b/nano/slow_test/node.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -88,7 +89,7 @@ TEST (system, receive_while_synchronizing) uint32_t count (1000); system.generate_mass_activity (count, *system.nodes[0]); nano::keypair key; - auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.logging, system.work)); + auto node1 (std::make_shared (system.io_ctx, system.get_available_port (), nano::unique_path (), system.work)); ASSERT_FALSE (node1->init_error ()); auto wallet (node1->wallets.create (1)); wallet->insert_adhoc (nano::dev::genesis_key.prv); // For voting @@ -116,7 +117,7 @@ TEST (system, receive_while_synchronizing) TEST (ledger, deep_account_compute) { - nano::logger_mt logger; + nano::logger logger; auto store = nano::make_store (logger, nano::unique_path (), nano::dev::constants); ASSERT_FALSE (store->init_error ()); nano::stats stats; @@ -536,7 +537,7 @@ TEST (store, vote_load) */ TEST (store, pruned_load) { - nano::logger_mt logger; + nano::logger logger; auto path (nano::unique_path ()); constexpr auto num_pruned = 2000000; auto const expected_result = num_pruned / 2; @@ -1222,8 +1223,7 @@ TEST (confirmation_height, many_accounts_send_receive_self_no_elections) // Don't test this in rocksdb mode return; } - nano::logger_mt logger; - nano::logging logging; + nano::logger logger; auto path (nano::unique_path ()); auto store = nano::make_store (logger, path, nano::dev::constants); ASSERT_TRUE (!store->init_error ()); @@ -1235,7 +1235,7 @@ TEST (confirmation_height, many_accounts_send_receive_self_no_elections) boost::latch initialized_latch{ 0 }; nano::block_hash block_hash_being_processed{ 0 }; - nano::confirmation_height_processor confirmation_height_processor{ ledger, write_database_queue, 10ms, logging, logger, initialized_latch, confirmation_height_mode::automatic }; + nano::confirmation_height_processor confirmation_height_processor{ ledger, write_database_queue, 10ms, logger, initialized_latch, confirmation_height_mode::automatic }; auto const num_accounts = 100000; @@ -2123,7 +2123,7 @@ TEST (node, wallet_create_block_confirm_conflicts) { nano::test::system system; nano::block_builder builder; - nano::node_config node_config (system.get_available_port (), system.logging); + nano::node_config node_config (system.get_available_port ()); node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; auto node = system.add_node (node_config); auto const num_blocks = 10000; diff --git a/nano/store/CMakeLists.txt b/nano/store/CMakeLists.txt index 427e038082..a992ba59bc 100644 --- a/nano/store/CMakeLists.txt +++ b/nano/store/CMakeLists.txt @@ -97,11 +97,10 @@ add_library( target_link_libraries( nano_store + nano_lib Boost::circular_buffer Boost::endian Boost::iostreams - Boost::log_setup - Boost::log Boost::multiprecision Boost::pool Boost::stacktrace diff --git a/nano/store/lmdb/lmdb.cpp b/nano/store/lmdb/lmdb.cpp index 8834c38d01..4dd9e64407 100644 --- a/nano/store/lmdb/lmdb.cpp +++ b/nano/store/lmdb/lmdb.cpp @@ -12,7 +12,7 @@ #include -nano::store::lmdb::component::component (nano::logger_mt & logger_a, std::filesystem::path const & path_a, nano::ledger_constants & constants, nano::txn_tracking_config const & txn_tracking_config_a, std::chrono::milliseconds block_processor_batch_max_time_a, nano::lmdb_config const & lmdb_config_a, bool backup_before_upgrade_a) : +nano::store::lmdb::component::component (nano::logger & logger_a, std::filesystem::path const & path_a, nano::ledger_constants & constants, nano::txn_tracking_config const & txn_tracking_config_a, std::chrono::milliseconds block_processor_batch_max_time_a, nano::lmdb_config const & lmdb_config_a, bool backup_before_upgrade_a) : // clang-format off nano::store::component{ block_store, @@ -37,7 +37,7 @@ nano::store::lmdb::component::component (nano::logger_mt & logger_a, std::filesy confirmation_height_store{ *this }, final_vote_store{ *this }, version_store{ *this }, - logger (logger_a), + logger{ logger_a }, env (error, path_a, nano::store::lmdb::env::options::make ().set_config (lmdb_config_a).set_use_no_mem_init (true)), mdb_txn_tracker (logger_a, txn_tracking_config_a, block_processor_batch_max_time_a), txn_tracking_enabled (txn_tracking_config_a.enable) @@ -66,10 +66,11 @@ nano::store::lmdb::component::component (nano::logger_mt & logger_a, std::filesy { if (!is_fresh_db) { - logger.always_log ("Upgrade in progress..."); + logger.info (nano::log::type::lmdb, "Upgrade in progress..."); + if (backup_before_upgrade_a) { - create_backup_file (env, path_a, logger_a); + create_backup_file (env, path_a, logger); } } auto needs_vacuuming = false; @@ -84,9 +85,18 @@ nano::store::lmdb::component::component (nano::logger_mt & logger_a, std::filesy if (needs_vacuuming) { - logger.always_log ("Preparing vacuum..."); + logger.info (nano::log::type::lmdb, "Ledger vaccum in progress..."); + auto vacuum_success = vacuum_after_upgrade (path_a, lmdb_config_a); - logger.always_log (vacuum_success ? "Vacuum succeeded." : "Failed to vacuum. (Optional) Ensure enough disk space is available for a copy of the database and try to vacuum after shutting down the node"); + if (vacuum_success) + { + logger.info (nano::log::type::lmdb, "Ledger vacuum completed"); + } + else + { + logger.error (nano::log::type::lmdb, "Ledger vaccum failed"); + logger.error (nano::log::type::lmdb, "(Optional) Please ensure enough disk space is available for a copy of the database and try to vacuum after shutting down the node"); + } } } else @@ -202,7 +212,7 @@ bool nano::store::lmdb::component::do_upgrades (store::write_transaction & trans auto version_l = version.get (transaction_a); if (version_l < version_minimum) { - logger.always_log (boost::str (boost::format ("The version of the ledger (%1%) is lower than the minimum (%2%) which is supported for upgrades. Either upgrade to a v19, v20 or v21 node first or delete the ledger.") % version_l % version_minimum)); + logger.critical (nano::log::type::lmdb, "The version of the ledger ({}) is lower than the minimum ({}) which is supported for upgrades. Either upgrade a node first or delete the ledger.", version_l, version_minimum); return true; } switch (version_l) @@ -213,7 +223,7 @@ bool nano::store::lmdb::component::do_upgrades (store::write_transaction & trans case 22: break; default: - logger.always_log (boost::str (boost::format ("The version of the ledger (%1%) is too high for this node") % version_l)); + logger.critical (nano::log::type::lmdb, "The version of the ledger ({}) is too high for this node", version_l); error = true; break; } @@ -222,16 +232,18 @@ bool nano::store::lmdb::component::do_upgrades (store::write_transaction & trans void nano::store::lmdb::component::upgrade_v21_to_v22 (store::write_transaction const & transaction_a) { - logger.always_log ("Preparing v21 to v22 database upgrade..."); + logger.info (nano::log::type::lmdb, "Upgrading database from v21 to v22..."); + MDB_dbi unchecked_handle{ 0 }; release_assert (!mdb_dbi_open (env.tx (transaction_a), "unchecked", MDB_CREATE, &unchecked_handle)); release_assert (!mdb_drop (env.tx (transaction_a), unchecked_handle, 1)); // del = 1, to delete it from the environment and close the DB handle. version.put (transaction_a, 22); - logger.always_log ("Finished removing unchecked table"); + + logger.info (nano::log::type::lmdb, "Upgrading database from v21 to v22 completed"); } /** Takes a filepath, appends '_backup_' to the end (but before any extension) and saves that file in the same directory */ -void nano::store::lmdb::component::create_backup_file (nano::store::lmdb::env & env_a, std::filesystem::path const & filepath_a, nano::logger_mt & logger_a) +void nano::store::lmdb::component::create_backup_file (nano::store::lmdb::env & env_a, std::filesystem::path const & filepath_a, nano::logger & logger) { auto extension = filepath_a.extension (); auto filename_without_extension = filepath_a.filename ().replace_extension (""); @@ -242,22 +254,18 @@ void nano::store::lmdb::component::create_backup_file (nano::store::lmdb::env & backup_filename += std::to_string (std::chrono::system_clock::now ().time_since_epoch ().count ()); backup_filename += extension; auto backup_filepath = backup_path / backup_filename; - auto start_message (boost::str (boost::format ("Performing %1% backup before database upgrade...") % filepath_a.filename ())); - logger_a.always_log (start_message); - std::cout << start_message << std::endl; + + logger.info (nano::log::type::lmdb, "Performing {} backup before database upgrade...", filepath_a.filename ().string ()); + auto error (mdb_env_copy (env_a, backup_filepath.string ().c_str ())); if (error) { - auto error_message (boost::str (boost::format ("%1% backup failed") % filepath_a.filename ())); - logger_a.always_log (error_message); - std::cerr << error_message << std::endl; + logger.critical (nano::log::type::lmdb, "Database backup failed"); std::exit (1); } else { - auto success_message (boost::str (boost::format ("Backup created: %1%") % backup_filename)); - logger_a.always_log (success_message); - std::cout << success_message << std::endl; + logger.info (nano::log::type::lmdb, "Database backup completed. Backup can be found at: {}", backup_filepath.string ()); } } diff --git a/nano/store/lmdb/lmdb.hpp b/nano/store/lmdb/lmdb.hpp index 91822f7f95..a1f5dda6cf 100644 --- a/nano/store/lmdb/lmdb.hpp +++ b/nano/store/lmdb/lmdb.hpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include #include @@ -63,7 +63,7 @@ class component : public nano::store::component friend class nano::store::lmdb::version; public: - component (nano::logger_mt &, std::filesystem::path const &, nano::ledger_constants & constants, nano::txn_tracking_config const & txn_tracking_config_a = nano::txn_tracking_config{}, std::chrono::milliseconds block_processor_batch_max_time_a = std::chrono::milliseconds (5000), nano::lmdb_config const & lmdb_config_a = nano::lmdb_config{}, bool backup_before_upgrade = false); + component (nano::logger &, std::filesystem::path const &, nano::ledger_constants & constants, nano::txn_tracking_config const & txn_tracking_config_a = nano::txn_tracking_config{}, std::chrono::milliseconds block_processor_batch_max_time_a = std::chrono::milliseconds (5000), nano::lmdb_config const & lmdb_config_a = nano::lmdb_config{}, bool backup_before_upgrade = false); store::write_transaction tx_begin_write (std::vector const & tables_requiring_lock = {}, std::vector const & tables_no_lock = {}) override; store::read_transaction tx_begin_read () const override; @@ -71,14 +71,14 @@ class component : public nano::store::component void serialize_mdb_tracker (boost::property_tree::ptree &, std::chrono::milliseconds, std::chrono::milliseconds) override; - static void create_backup_file (nano::store::lmdb::env &, std::filesystem::path const &, nano::logger_mt &); + static void create_backup_file (nano::store::lmdb::env &, std::filesystem::path const &, nano::logger &); void serialize_memory_stats (boost::property_tree::ptree &) override; unsigned max_block_write_batch_num () const override; private: - nano::logger_mt & logger; + nano::logger & logger; bool error{ false }; public: diff --git a/nano/store/lmdb/lmdb_env.cpp b/nano/store/lmdb/lmdb_env.cpp index 9e627c7676..e66511da4c 100644 --- a/nano/store/lmdb/lmdb_env.cpp +++ b/nano/store/lmdb/lmdb_env.cpp @@ -8,6 +8,8 @@ nano::store::lmdb::env::env (bool & error_a, std::filesystem::path const & path_ void nano::store::lmdb::env::init (bool & error_a, std::filesystem::path const & path_a, nano::store::lmdb::env::options options_a) { + debug_assert (path_a.extension () == ".ldb", "invalid filename extension for lmdb database file"); + boost::system::error_code error_mkdir, error_chmod; if (path_a.has_parent_path ()) { diff --git a/nano/store/lmdb/transaction.cpp b/nano/store/lmdb/transaction.cpp index a01698c09d..2460539cfb 100644 --- a/nano/store/lmdb/transaction.cpp +++ b/nano/store/lmdb/transaction.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include @@ -116,7 +116,7 @@ bool nano::store::lmdb::write_transaction_impl::contains (nano::tables table_a) return true; } -nano::mdb_txn_tracker::mdb_txn_tracker (nano::logger_mt & logger_a, nano::txn_tracking_config const & txn_tracking_config_a, std::chrono::milliseconds block_processor_batch_max_time_a) : +nano::mdb_txn_tracker::mdb_txn_tracker (nano::logger & logger_a, nano::txn_tracking_config const & txn_tracking_config_a, std::chrono::milliseconds block_processor_batch_max_time_a) : logger (logger_a), txn_tracking_config (txn_tracking_config_a), block_processor_batch_max_time (block_processor_batch_max_time_a) @@ -194,7 +194,12 @@ void nano::mdb_txn_tracker::log_if_held_long_enough (nano::mdb_txn_stats const & if (!should_ignore && ((is_write && time_open >= txn_tracking_config.min_write_txn_time) || (!is_write && time_open >= txn_tracking_config.min_read_txn_time))) { debug_assert (mdb_txn_stats.stacktrace); - logger.always_log (boost::str (boost::format ("%1%ms %2% held on thread %3%\n%4%") % mdb_txn_stats.timer.since_start ().count () % (is_write ? "write lock" : "read") % mdb_txn_stats.thread_name % *mdb_txn_stats.stacktrace)); + + logger.warn (nano::log::type::txn_tracker, "{}ms {} held on thread {}\n{}", + time_open.count (), + is_write ? "write lock" : "read", + mdb_txn_stats.thread_name, + nano::util::to_str (*mdb_txn_stats.stacktrace)); } } diff --git a/nano/store/lmdb/transaction_impl.hpp b/nano/store/lmdb/transaction_impl.hpp index 001fd896a3..06a4e1d414 100644 --- a/nano/store/lmdb/transaction_impl.hpp +++ b/nano/store/lmdb/transaction_impl.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -11,10 +12,6 @@ #include -namespace nano -{ -class logger_mt; -} namespace nano::store::lmdb { class env; @@ -75,7 +72,7 @@ class mdb_txn_stats class mdb_txn_tracker { public: - mdb_txn_tracker (nano::logger_mt & logger_a, nano::txn_tracking_config const & txn_tracking_config_a, std::chrono::milliseconds block_processor_batch_max_time_a); + mdb_txn_tracker (nano::logger &, nano::txn_tracking_config const & txn_tracking_config_a, std::chrono::milliseconds block_processor_batch_max_time_a); void serialize_json (boost::property_tree::ptree & json, std::chrono::milliseconds min_read_time, std::chrono::milliseconds min_write_time); void add (store::transaction_impl const * transaction_impl); void erase (store::transaction_impl const * transaction_impl); @@ -83,7 +80,7 @@ class mdb_txn_tracker private: nano::mutex mutex; std::vector stats; - nano::logger_mt & logger; + nano::logger & logger; nano::txn_tracking_config txn_tracking_config; std::chrono::milliseconds block_processor_batch_max_time; diff --git a/nano/store/rocksdb/rocksdb.cpp b/nano/store/rocksdb/rocksdb.cpp index 054fec0a82..099972583c 100644 --- a/nano/store/rocksdb/rocksdb.cpp +++ b/nano/store/rocksdb/rocksdb.cpp @@ -34,7 +34,7 @@ class event_listener : public rocksdb::EventListener }; } -nano::store::rocksdb::component::component (nano::logger_mt & logger_a, std::filesystem::path const & path_a, nano::ledger_constants & constants, nano::rocksdb_config const & rocksdb_config_a, bool open_read_only_a) : +nano::store::rocksdb::component::component (nano::logger & logger_a, std::filesystem::path const & path_a, nano::ledger_constants & constants, nano::rocksdb_config const & rocksdb_config_a, bool open_read_only_a) : // clang-format off nano::store::component{ block_store, @@ -95,14 +95,16 @@ nano::store::rocksdb::component::component (nano::logger_mt & logger_a, std::fil auto version_l = version.get (transaction); if (version_l > version_current) { + logger.critical (nano::log::type::rocksdb, "The version of the ledger ({}) is too high for this node", version_l); + error = true; - logger.always_log (boost::str (boost::format ("The version of the ledger (%1%) is too high for this node") % version_l)); return; } else if (version_l < version_minimum) { + logger.critical (nano::log::type::rocksdb, "The version of the ledger ({}) is lower than the minimum ({}) which is supported for upgrades. Either upgrade a node first or delete the ledger.", version_l, version_minimum); + error = true; - logger.always_log (boost::str (boost::format ("The version of the ledger (%1%) is lower than the minimum (%2%) which is supported for upgrades. Either upgrade to a v19, v20 or v21 node first or delete the ledger.") % version_l % version_minimum)); return; } is_fully_upgraded = (version_l == version_current); @@ -149,7 +151,8 @@ nano::store::rocksdb::component::component (nano::logger_mt & logger_a, std::fil open (error, path_a, open_read_only_a, options, get_current_column_families (path_a.string (), options)); if (!error) { - logger.always_log ("Upgrade in progress..."); + logger.info (nano::log::type::rocksdb, "Upgrade in progress..."); + auto transaction = tx_begin_write (); error |= do_upgrades (transaction); } @@ -240,7 +243,7 @@ bool nano::store::rocksdb::component::do_upgrades (store::write_transaction cons case 22: break; default: - logger.always_log (boost::str (boost::format ("The version of the ledger (%1%) is too high for this node") % version_l)); + logger.critical (nano::log::type::rocksdb, "The version of the ledger ({}) is too high for this node", version_l); error_l = true; break; } @@ -249,7 +252,8 @@ bool nano::store::rocksdb::component::do_upgrades (store::write_transaction cons void nano::store::rocksdb::component::upgrade_v21_to_v22 (store::write_transaction const & transaction_a) { - logger.always_log ("Preparing v21 to v22 database upgrade..."); + logger.info (nano::log::type::rocksdb, "Upgrading database from v21 to v22..."); + if (column_family_exists ("unchecked")) { auto const unchecked_handle = get_column_family ("unchecked"); @@ -264,9 +268,12 @@ void nano::store::rocksdb::component::upgrade_v21_to_v22 (store::write_transacti } return false; }); + logger.debug (nano::log::type::rocksdb, "Finished removing unchecked table"); } + version.put (transaction_a, 22); - logger.always_log ("Finished removing unchecked table"); + + logger.info (nano::log::type::rocksdb, "Upgrading database from v21 to v22 completed"); } void nano::store::rocksdb::component::generate_tombstone_map () diff --git a/nano/store/rocksdb/rocksdb.hpp b/nano/store/rocksdb/rocksdb.hpp index 9490ed9522..1c51bbbb05 100644 --- a/nano/store/rocksdb/rocksdb.hpp +++ b/nano/store/rocksdb/rocksdb.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include #include #include @@ -36,8 +36,8 @@ namespace nano::store::rocksdb class rocksdb_block_store_upgrade_v21_v22_Test; /** - * rocksdb implementation of the block store - */ + * rocksdb implementation of the block store + */ class component : public nano::store::component { private: @@ -64,7 +64,7 @@ class component : public nano::store::component friend class nano::store::rocksdb::pruned; friend class nano::store::rocksdb::version; - explicit component (nano::logger_mt &, std::filesystem::path const &, nano::ledger_constants & constants, nano::rocksdb_config const & = nano::rocksdb_config{}, bool open_read_only = false); + explicit component (nano::logger &, std::filesystem::path const &, nano::ledger_constants & constants, nano::rocksdb_config const & = nano::rocksdb_config{}, bool open_read_only = false); store::write_transaction tx_begin_write (std::vector const & tables_requiring_lock = {}, std::vector const & tables_no_lock = {}) override; store::read_transaction tx_begin_read () const override; @@ -103,7 +103,7 @@ class component : public nano::store::component private: bool error{ false }; - nano::logger_mt & logger; + nano::logger & logger; nano::ledger_constants & constants; // Optimistic transactions are used in write mode ::rocksdb::OptimisticTransactionDB * optimistic_db = nullptr; diff --git a/nano/test_common/CMakeLists.txt b/nano/test_common/CMakeLists.txt index 337d34211d..6271377f45 100644 --- a/nano/test_common/CMakeLists.txt +++ b/nano/test_common/CMakeLists.txt @@ -15,7 +15,7 @@ add_library( testutil.hpp testutil.cpp) -target_link_libraries(test_common node gtest Boost::log_setup Boost::log) +target_link_libraries(test_common node gtest) include_directories(${CMAKE_SOURCE_DIR}/submodules) include_directories(${CMAKE_SOURCE_DIR}/submodules/gtest/googletest/include) diff --git a/nano/test_common/ledger.hpp b/nano/test_common/ledger.hpp index 6d64e170e4..6b12c258a2 100644 --- a/nano/test_common/ledger.hpp +++ b/nano/test_common/ledger.hpp @@ -1,6 +1,5 @@ #pragma once -#include #include #include @@ -26,7 +25,7 @@ namespace test std::deque> const & blocks () const; private: - nano::logger_mt logger; + nano::logger logger; std::unique_ptr store_m; nano::stats stats_m; nano::ledger ledger_m; diff --git a/nano/test_common/network.cpp b/nano/test_common/network.cpp index 3241afca61..1d584ac185 100644 --- a/nano/test_common/network.cpp +++ b/nano/test_common/network.cpp @@ -26,7 +26,7 @@ std::shared_ptr nano::test::establish_tcp (nano::t std::shared_ptr nano::test::add_outer_node (nano::test::system & system_a, nano::node_flags flags_a) { - auto outer_node = std::make_shared (system_a.io_ctx, system_a.get_available_port (), nano::unique_path (), system_a.logging, system_a.work, flags_a); + auto outer_node = std::make_shared (system_a.io_ctx, system_a.get_available_port (), nano::unique_path (), system_a.work, flags_a); outer_node->start (); system_a.nodes.push_back (outer_node); return outer_node; diff --git a/nano/test_common/system.cpp b/nano/test_common/system.cpp index b0f2ff1dfc..eff5f455b5 100644 --- a/nano/test_common/system.cpp +++ b/nano/test_common/system.cpp @@ -132,7 +132,6 @@ nano::test::system::system () { deadline_scaling_factor = std::stod (scale_str); } - logging.init (nano::unique_path ()); } nano::test::system::system (uint16_t count_a, nano::transport::transport_type type_a, nano::node_flags flags_a) : @@ -563,7 +562,7 @@ void nano::test::system::stop () nano::node_config nano::test::system::default_config () { - nano::node_config config{ get_available_port (), logging }; + nano::node_config config{ get_available_port () }; return config; } @@ -619,10 +618,9 @@ uint16_t nano::test::system::get_available_port (bool can_be_zero) } } +// Makes sure everything is cleaned up void nano::test::cleanup_dev_directories_on_exit () { - // Makes sure everything is cleaned up - nano::logging::release_file_sink (); // Clean up tmp directories created by the tests. Since it's sometimes useful to // see log files after test failures, an environment variable is supported to // retain the files. diff --git a/nano/test_common/system.hpp b/nano/test_common/system.hpp index e03532ccef..8e0cf19bc3 100644 --- a/nano/test_common/system.hpp +++ b/nano/test_common/system.hpp @@ -66,8 +66,8 @@ namespace test public: boost::asio::io_context io_ctx; std::vector> nodes; - nano::logging logging; nano::stats stats; + nano::logger logger{ "tests" }; nano::work_pool work{ nano::dev::network_params.network, std::max (nano::hardware_concurrency (), 1u) }; std::chrono::time_point> deadline{ std::chrono::steady_clock::time_point::max () }; double deadline_scaling_factor{ 1.0 }; diff --git a/nano/test_common/testutil.hpp b/nano/test_common/testutil.hpp index 3203fdfb3e..766d6da64d 100644 --- a/nano/test_common/testutil.hpp +++ b/nano/test_common/testutil.hpp @@ -7,8 +7,6 @@ #include #include -#include -#include #include #include @@ -136,54 +134,6 @@ namespace test { class system; - class stringstream_mt_sink : public boost::iostreams::sink - { - public: - stringstream_mt_sink () = default; - stringstream_mt_sink (stringstream_mt_sink const & sink) - { - nano::lock_guard guard{ mutex }; - ss << sink.ss.str (); - } - - std::streamsize write (char const * string_to_write, std::streamsize size) - { - nano::lock_guard guard{ mutex }; - ss << std::string (string_to_write, size); - return size; - } - - std::string str () - { - nano::lock_guard guard{ mutex }; - return ss.str (); - } - - private: - mutable nano::mutex mutex; - std::stringstream ss; - }; - - class boost_log_cerr_redirect - { - public: - boost_log_cerr_redirect (std::streambuf * new_buffer) : - old (std::cerr.rdbuf (new_buffer)) - { - console_sink = (boost::log::add_console_log (std::cerr, boost::log::keywords::format = "%Message%")); - } - - ~boost_log_cerr_redirect () - { - std::cerr.rdbuf (old); - boost::log::core::get ()->remove_sink (console_sink); - } - - private: - std::streambuf * old; - boost::shared_ptr> console_sink; - }; - class cout_redirect { public: diff --git a/submodules/fmt b/submodules/fmt new file mode 160000 index 0000000000..a0b8a92e3d --- /dev/null +++ b/submodules/fmt @@ -0,0 +1 @@ +Subproject commit a0b8a92e3d1532361c2f7feb63babc5c18d00ef2 diff --git a/submodules/spdlog b/submodules/spdlog new file mode 160000 index 0000000000..7e635fca68 --- /dev/null +++ b/submodules/spdlog @@ -0,0 +1 @@ +Subproject commit 7e635fca68d014934b4af8a1cf874f63989352b7