* Node telemetry * Add genesis block * Don't checkif at the end of the stream with UDP to support compatibility with different message versions * Add single request and optional blocking * Formatting * Use nano locks * Fix clang build * Out of date comments * Update some names of classes/functions/variables * Fix for disconnected peer channels & some cleanup * Remove unnecessary lock requirement in active_transactions::lock. (#2475) * Remove unnecessarry lock requirement in active_transactions::lock. This also removes some code-smell around passing in a bool to determine if the lock should actually be acquired. * Using a timeout counter in line with other test idioms. * Confirmation solicitor revamp (#2472) * Optional minimum version when querying representatives from crawler * Revamping confirmation_solicitor to mimick previous active_transactions behavior * Use a time-based approach to throttle confirmation requests and block flooding * Addressing Wesley review * Remove unusued node.hpp include (thanks wes) * Simplify logic by using unordered_map::operator[] which calls the default constructor if not found * Split solicitor add into broadcast+add and bring back the logic to active_transactions This brings back rate-limitting logic and modifying election variables to active_transactions only. Timings are also slightly adjusted: - Only 2 requests required before starting to flood blocks - Timings for test network * Rename flag * Only broadcast OR request confirmation in the same loop for the same election * Enclose lambda in clang-format off * Beta network reset #2 (#2476) * Delete rep_weights_beta.bin * New genesis * Change header_magic_number to one never used before * use v1.1 for actions-aws-cli (#2486) * The start of CLI tests (#2403) * The start of CLI tests * Add needed header file after merge * Serg review comments * Websocket bootstrap subscription (#2471) * Bootstrap attempt ID * Websocket bootstrap subscription * Change processed blocks factor for requeued pulls (#2437) From `processed blocks / 10000` to `processed blocks / 4096` for better processing of largest chains in case of failures * Upgrade confirmation height table to include cemented frontier (#2481) * Upgrade confirmation height table to include cemented frontier * Stein review comments * Add //clang-format block around lambda * Update comment (thanks Gui) * Upgrade to v17 instead * Update comments * Request aggregator (#2485) * Request aggregator Adds a class that runs in a new thread to pool confirmation requests by endpoint. This allows a reduction of bandwidth, vote generation, and moves some vote generation out of the I/O threads. * Use a constant for confirm_ack_hashes_max * Small code simplification * Use const transaction * Disable clang-format for lambdas * Add missing deadlines and update deadline before poll block * Use a scoped lock_guard pattern and initialize start in-class * Misc. fixes and documentation * use clang-format-8 (#2490) There is some funkiness with clang-format-9 and lambdas that are not honored * Formatting fix so clangformat 8 applies cleanly (#2491) * Support multiple work peers in the same host (#2477) * Correct check for peers when creating work * Support multiple work peers in the same address * Send cancels despite errors to account for non-conforming implementations * Add tests using a fake work peer, acting as good, malicious or slow * Comment * Formatting * Fix multiple response error in RPC * Formatting * Add extra error handling when specifying port and not address with the RPC (and vice versa) * Formatting * Serg comments * Formatting * Mask not needed * Missed file check in for mask removal * Fix test failures * Gui suggestions * Formatting * Fix assert with test on Windows and some cleanup * Lower number of nodes in node_telemetry.many_nodes when using sanitizers Co-authored-by: clemahieu <clemahieu@gmail.com> Co-authored-by: Guilherme Lawless <guilherme.lawless@gmail.com> Co-authored-by: Russel Waters <vaelstrom@gmail.com> Co-authored-by: Sergey Kroshnin <sergiysw@gmail.com> Co-authored-by: cryptocode <stein@nano.org>
373 lines
15 KiB
C++
373 lines
15 KiB
C++
#include <nano/lib/config.hpp>
|
|
#include <nano/lib/jsonconfig.hpp>
|
|
#include <nano/lib/logger_mt.hpp>
|
|
#include <nano/lib/tomlconfig.hpp>
|
|
#include <nano/node/logging.hpp>
|
|
|
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
|
#include <boost/log/expressions.hpp>
|
|
#include <boost/log/utility/setup/common_attributes.hpp>
|
|
#include <boost/log/utility/setup/console.hpp>
|
|
#include <boost/log/utility/setup/file.hpp>
|
|
|
|
#ifdef BOOST_WINDOWS
|
|
#include <boost/log/sinks/event_log_backend.hpp>
|
|
#else
|
|
#define BOOST_LOG_USE_NATIVE_SYSLOG
|
|
#include <boost/log/sinks/syslog_backend.hpp>
|
|
#endif
|
|
|
|
BOOST_LOG_ATTRIBUTE_KEYWORD (severity, "Severity", nano::severity_level)
|
|
|
|
boost::shared_ptr<boost::log::sinks::synchronous_sink<boost::log::sinks::text_file_backend>> nano::logging::file_sink;
|
|
std::atomic_flag nano::logging::logging_already_added ATOMIC_FLAG_INIT;
|
|
|
|
void nano::logging::init (boost::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_level, severity_tag> ("Severity") << boost::log::expressions::smessage;
|
|
auto format_with_timestamp = boost::log::expressions::stream << "[" << boost::log::expressions::attr<boost::posix_time::ptime> ("TimeStamp") << "]: " << boost::log::expressions::attr<severity_level, severity_tag> ("Severity") << boost::log::expressions::smessage;
|
|
|
|
if (log_to_cerr ())
|
|
{
|
|
boost::log::add_console_log (std::cerr, boost::log::keywords::format = format_with_timestamp);
|
|
}
|
|
|
|
nano::network_constants network_constants;
|
|
if (!network_constants.is_test_network ())
|
|
{
|
|
#ifdef BOOST_WINDOWS
|
|
if (nano::event_log_reg_entry_exists () || nano::is_windows_elevated ())
|
|
{
|
|
static auto event_sink = boost::make_shared<boost::log::sinks::synchronous_sink<boost::log::sinks::simple_event_log_backend>> (boost::log::keywords::log_name = "Nano", boost::log::keywords::log_source = "Nano");
|
|
event_sink->set_formatter (format);
|
|
|
|
// Currently only mapping sys log errors
|
|
boost::log::sinks::event_log::custom_event_type_mapping<nano::severity_level> mapping ("Severity");
|
|
mapping[nano::severity_level::error] = boost::log::sinks::event_log::error;
|
|
event_sink->locked_backend ()->set_event_type_mapper (mapping);
|
|
|
|
// Only allow messages or error or greater severity to the event log
|
|
event_sink->set_filter (severity >= nano::severity_level::error);
|
|
boost::log::core::get ()->add_sink (event_sink);
|
|
}
|
|
#else
|
|
static auto sys_sink = boost::make_shared<boost::log::sinks::synchronous_sink<boost::log::sinks::syslog_backend>> (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<nano::severity_level> 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
|
|
}
|
|
|
|
auto path = application_path_a / "log";
|
|
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);
|
|
}
|
|
}
|
|
|
|
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 ();
|
|
}
|
|
}
|
|
|
|
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 ("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 ("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 ("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 ("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");
|
|
|
|
return toml.get_error ();
|
|
}
|
|
|
|
nano::error nano::logging::deserialize_toml (nano::tomlconfig & toml)
|
|
{
|
|
toml.get<bool> ("ledger", ledger_logging_value);
|
|
toml.get<bool> ("ledger_duplicate", ledger_duplicate_logging_value);
|
|
toml.get<bool> ("vote", vote_logging_value);
|
|
toml.get<bool> ("network", network_logging_value);
|
|
toml.get<bool> ("network_timeout", network_timeout_logging_value);
|
|
toml.get<bool> ("network_message", network_message_logging_value);
|
|
toml.get<bool> ("network_publish", network_publish_logging_value);
|
|
toml.get<bool> ("network_packet", network_packet_logging_value);
|
|
toml.get<bool> ("network_keepalive", network_keepalive_logging_value);
|
|
toml.get<bool> ("network_node_id_handshake", network_node_id_handshake_logging_value);
|
|
toml.get<bool> ("network_telemetry_logging", network_telemetry_logging_value);
|
|
toml.get<bool> ("node_lifetime_tracing", node_lifetime_tracing_value);
|
|
toml.get<bool> ("insufficient_work", insufficient_work_logging_value);
|
|
toml.get<bool> ("log_ipc", log_ipc_value);
|
|
toml.get<bool> ("bulk_pull", bulk_pull_logging_value);
|
|
toml.get<bool> ("work_generation_time", work_generation_time_value);
|
|
toml.get<bool> ("upnp_details", upnp_details_logging_value);
|
|
toml.get<bool> ("timing", timing_logging_value);
|
|
toml.get<bool> ("active_update", active_update_value);
|
|
toml.get<bool> ("log_to_cerr", log_to_cerr_value);
|
|
toml.get<bool> ("flush", flush);
|
|
toml.get<bool> ("single_line_record", single_line_record_value);
|
|
toml.get<uintmax_t> ("max_size", max_size);
|
|
toml.get<uintmax_t> ("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);
|
|
|
|
return toml.get_error ();
|
|
}
|
|
|
|
nano::error nano::logging::serialize_json (nano::jsonconfig & json) const
|
|
{
|
|
json.put ("version", json_version ());
|
|
json.put ("ledger", ledger_logging_value);
|
|
json.put ("ledger_duplicate", ledger_duplicate_logging_value);
|
|
json.put ("vote", vote_logging_value);
|
|
json.put ("network", network_logging_value);
|
|
json.put ("network_timeout", network_timeout_logging_value);
|
|
json.put ("network_message", network_message_logging_value);
|
|
json.put ("network_publish", network_publish_logging_value);
|
|
json.put ("network_packet", network_packet_logging_value);
|
|
json.put ("network_keepalive", network_keepalive_logging_value);
|
|
json.put ("network_node_id_handshake", network_node_id_handshake_logging_value);
|
|
json.put ("network_telemetry_logging", network_telemetry_logging_value);
|
|
json.put ("node_lifetime_tracing", node_lifetime_tracing_value);
|
|
json.put ("insufficient_work", insufficient_work_logging_value);
|
|
json.put ("log_ipc", log_ipc_value);
|
|
json.put ("bulk_pull", bulk_pull_logging_value);
|
|
json.put ("work_generation_time", work_generation_time_value);
|
|
json.put ("upnp_details", upnp_details_logging_value);
|
|
json.put ("timing", timing_logging_value);
|
|
json.put ("log_to_cerr", log_to_cerr_value);
|
|
json.put ("max_size", max_size);
|
|
json.put ("rotation_size", rotation_size);
|
|
json.put ("flush", flush);
|
|
json.put ("min_time_between_output", min_time_between_log_output.count ());
|
|
json.put ("single_line_record", single_line_record_value);
|
|
return json.get_error ();
|
|
}
|
|
|
|
bool nano::logging::upgrade_json (unsigned version_a, nano::jsonconfig & json)
|
|
{
|
|
json.put ("version", json_version ());
|
|
switch (version_a)
|
|
{
|
|
case 1:
|
|
json.put ("vote", vote_logging_value);
|
|
case 2:
|
|
json.put ("rotation_size", rotation_size);
|
|
json.put ("flush", true);
|
|
case 3:
|
|
json.put ("network_node_id_handshake", false);
|
|
case 4:
|
|
json.put ("upnp_details", "false");
|
|
json.put ("timing", "false");
|
|
case 5:
|
|
uintmax_t config_max_size;
|
|
json.get<uintmax_t> ("max_size", config_max_size);
|
|
max_size = std::max (max_size, config_max_size);
|
|
json.put ("max_size", max_size);
|
|
json.put ("log_ipc", true);
|
|
case 6:
|
|
json.put ("min_time_between_output", min_time_between_log_output.count ());
|
|
json.put ("network_timeout", network_timeout_logging_value);
|
|
json.erase ("log_rpc");
|
|
break;
|
|
case 7:
|
|
json.put ("single_line_record", single_line_record_value);
|
|
case 8:
|
|
break;
|
|
default:
|
|
throw std::runtime_error ("Unknown logging_config version");
|
|
break;
|
|
}
|
|
return version_a < json_version ();
|
|
}
|
|
|
|
nano::error nano::logging::deserialize_json (bool & upgraded_a, nano::jsonconfig & json)
|
|
{
|
|
int version_l{ 1 };
|
|
if (!json.has_key ("version"))
|
|
{
|
|
json.put ("version", version_l);
|
|
|
|
auto work_peers_l (json.get_optional_child ("work_peers"));
|
|
if (!work_peers_l)
|
|
{
|
|
nano::jsonconfig peers;
|
|
json.put_child ("work_peers", peers);
|
|
}
|
|
upgraded_a = true;
|
|
}
|
|
else
|
|
{
|
|
json.get_required<int> ("version", version_l);
|
|
}
|
|
|
|
upgraded_a |= upgrade_json (version_l, json);
|
|
json.get<bool> ("ledger", ledger_logging_value);
|
|
json.get<bool> ("ledger_duplicate", ledger_duplicate_logging_value);
|
|
json.get<bool> ("vote", vote_logging_value);
|
|
json.get<bool> ("network", network_logging_value);
|
|
json.get<bool> ("network_timeout", network_timeout_logging_value);
|
|
json.get<bool> ("network_message", network_message_logging_value);
|
|
json.get<bool> ("network_publish", network_publish_logging_value);
|
|
json.get<bool> ("network_packet", network_packet_logging_value);
|
|
json.get<bool> ("network_keepalive", network_keepalive_logging_value);
|
|
json.get<bool> ("network_node_id_handshake", network_node_id_handshake_logging_value);
|
|
json.get<bool> ("node_lifetime_tracing", node_lifetime_tracing_value);
|
|
json.get<bool> ("insufficient_work", insufficient_work_logging_value);
|
|
json.get<bool> ("log_ipc", log_ipc_value);
|
|
json.get<bool> ("bulk_pull", bulk_pull_logging_value);
|
|
json.get<bool> ("work_generation_time", work_generation_time_value);
|
|
json.get<bool> ("upnp_details", upnp_details_logging_value);
|
|
json.get<bool> ("timing", timing_logging_value);
|
|
json.get<bool> ("log_to_cerr", log_to_cerr_value);
|
|
json.get<bool> ("flush", flush);
|
|
json.get<bool> ("single_line_record", single_line_record_value);
|
|
json.get<uintmax_t> ("max_size", max_size);
|
|
json.get<uintmax_t> ("rotation_size", rotation_size);
|
|
uintmax_t min_time_between_log_output_raw;
|
|
json.get<uintmax_t> ("min_time_between_output", min_time_between_log_output_raw);
|
|
min_time_between_log_output = std::chrono::milliseconds (min_time_between_log_output_raw);
|
|
return json.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::vote_logging () const
|
|
{
|
|
return vote_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::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::log_to_cerr () const
|
|
{
|
|
return log_to_cerr_value;
|
|
}
|
|
|
|
bool nano::logging::single_line_record () const
|
|
{
|
|
return single_line_record_value;
|
|
}
|