From 01b6f4150921cde1cc4853875f0aac5aa0bfb116 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Sun, 15 Mar 2020 06:14:08 +0100 Subject: [PATCH] implemented get logs/truncate logs in plain_wallet --- contrib/epee/include/file_io_utils.h | 3 +- contrib/epee/include/misc_log_ex.h | 113 ++++++++++++++-- src/common/command_line.cpp | 2 +- src/common/command_line.h | 19 +++ src/gui/qt-daemon/main.cpp | 5 + src/wallet/plain_wallet_api.cpp | 29 +++- src/wallet/plain_wallet_api.h | 2 + src/wallet/wallets_manager.cpp | 20 +-- .../core_concurrency_test.cpp | 6 +- tests/functional_tests/plain_wallet_tests.cpp | 128 +++++++++--------- 10 files changed, 241 insertions(+), 86 deletions(-) diff --git a/contrib/epee/include/file_io_utils.h b/contrib/epee/include/file_io_utils.h index b79db5b5..08e3fd81 100644 --- a/contrib/epee/include/file_io_utils.h +++ b/contrib/epee/include/file_io_utils.h @@ -48,10 +48,11 @@ #endif #ifndef WIN32 +#include #include #endif -#include "include_base_utils.h" +//#include "include_base_utils.h" #include "string_coding.h" namespace epee diff --git a/contrib/epee/include/misc_log_ex.h b/contrib/epee/include/misc_log_ex.h index 6cb4f406..46241df4 100644 --- a/contrib/epee/include/misc_log_ex.h +++ b/contrib/epee/include/misc_log_ex.h @@ -69,7 +69,7 @@ DISABLE_VS_WARNINGS(4100) #include "syncobj.h" #include "sync_locked_object.h" #include "string_coding.h" - +#include "file_io_utils.h" #define LOG_LEVEL_SILENT -1 #define LOG_LEVEL_0 0 @@ -290,6 +290,8 @@ namespace log_space virtual bool set_max_logfile_size(uint64_t max_size){return true;}; virtual bool set_log_rotate_cmd(const std::string& cmd){return true;}; + virtual bool truncate_log_files() { return true; } + virtual std::string copy_logs_to_buffer() { return ""; } }; /************************************************************************/ @@ -629,7 +631,7 @@ namespace log_space class file_output_stream : public ibase_log_stream { public: - typedef std::map named_log_streams; + typedef std::map > named_log_streams; file_output_stream( const std::string& default_log_file_name, const std::string& log_path ) { @@ -643,12 +645,12 @@ namespace log_space { for(named_log_streams::iterator it = m_log_file_names.begin(); it!=m_log_file_names.end(); it++) { - if ( it->second->is_open() ) + if ( it->second.first->is_open() ) { - it->second->flush(); - it->second->close(); + it->second.first->flush(); + it->second.first->close(); } - delete it->second; + delete it->second.first; } } private: @@ -666,12 +668,14 @@ namespace log_space //log_space::rotate_log_file((m_default_log_path + "\\" + pstream_name).c_str()); boost::system::error_code ec; boost::filesystem::create_directories(m_default_log_path_w, ec); - boost::filesystem::ofstream* pstream = (m_log_file_names[pstream_name] = new boost::filesystem::ofstream); + boost::filesystem::ofstream* pstream = new boost::filesystem::ofstream; + std::wstring target_path = m_default_log_path_w + L"/" + epee::string_encoding::utf8_to_wstring(pstream_name); pstream->open( target_path.c_str(), std::ios_base::out | std::ios::app /*ios_base::trunc */); if(pstream->fail()) return NULL; + m_log_file_names[pstream_name] = std::pair(pstream, target_path); return pstream; } @@ -687,6 +691,51 @@ namespace log_space return true; } + bool truncate_log_files() + { + for (named_log_streams::iterator it = m_log_file_names.begin(); it != m_log_file_names.end(); it++) + { + std::wstring target_path = it->second.second; + //close and delete current stream + if (it->second.first->is_open()) + { + it->second.first->flush(); + it->second.first->close(); + } + delete it->second.first; + it->second.first = nullptr; + //reopen it with truncate + boost::filesystem::ofstream* pstream = new boost::filesystem::ofstream; + pstream->open(target_path.c_str(), std::ios_base::out | std::ios::trunc ); + if (pstream->fail()) + { + throw std::runtime_error("Unexpected error: failed to re-open log stream on truncate"); + } + it->second.first = pstream; + } + return true; + } + + std::string copy_logs_to_buffer() + { + std::stringstream res; + + for (named_log_streams::iterator it = m_log_file_names.begin(); it != m_log_file_names.end(); it++) + { + std::wstring target_path = it->second.second; + res << "[" << epee::string_encoding::convert_to_ansii(target_path) << "]" << ENDL; + std::string res_buf; + if (!epee::file_io_utils::load_file_to_string(target_path, res_buf)) + { + res << "ERROR"; + } + else + { + res << res_buf; + } + } + return res.str(); + } virtual bool out_buffer( const char* buffer, int buffer_len, int log_level, int color, const char* plog_name = NULL ) @@ -698,7 +747,7 @@ namespace log_space if(it == m_log_file_names.end()) m_target_file_stream = add_new_stream_and_open(plog_name); else - m_target_file_stream = it->second; + m_target_file_stream = it->second.first; } if(!m_target_file_stream || !m_target_file_stream->is_open()) return false;//TODO: add assert here @@ -796,6 +845,22 @@ namespace log_space return true; } + bool truncate_log_files() + { + for (streams_container::iterator it = m_log_streams.begin(); it != m_log_streams.end(); it++) + it->first->truncate_log_files(); + return true; + } + + std::string copy_logs_to_buffer() + { + std::string res; + for (streams_container::iterator it = m_log_streams.begin(); it != m_log_streams.end(); it++) + res += it->first->copy_logs_to_buffer(); + return res; + } + + bool do_log_message(const std::string& rlog_mes, int log_level, int color, const char* plog_name = NULL) { std::string str_mess = rlog_mes; @@ -967,6 +1032,21 @@ namespace log_space return true; } + std::string copy_logs_to_buffer() + { + FAST_CRITICAL_REGION_BEGIN(m_critical_sec); + return m_log_target.copy_logs_to_buffer(); + FAST_CRITICAL_REGION_END(); + } + + + bool truncate_log_files() + { + FAST_CRITICAL_REGION_BEGIN(m_critical_sec); + return m_log_target.truncate_log_files(); + FAST_CRITICAL_REGION_END(); + } + bool take_away_journal(std::list& journal) { FAST_CRITICAL_REGION_BEGIN(m_critical_sec); @@ -1254,6 +1334,23 @@ namespace log_space return plogger->set_log_rotate_cmd(cmd); } + + static std::string copy_logs_to_buffer() + { + logger* plogger = get_or_create_instance(); + if (!plogger) return false; + return plogger->copy_logs_to_buffer(); + } + + + static bool truncate_log_files() + { + logger* plogger = get_or_create_instance(); + if (!plogger) return false; + return plogger->truncate_log_files(); + } + + static bool add_logger( int type, const char* pdefault_file_name, const char* pdefault_log_folder, int log_level_limit = LOG_LEVEL_4) { diff --git a/src/common/command_line.cpp b/src/common/command_line.cpp index 4926e345..c714ea63 100644 --- a/src/common/command_line.cpp +++ b/src/common/command_line.cpp @@ -12,7 +12,7 @@ namespace command_line { const arg_descriptor arg_help = {"help", "Produce help message"}; const arg_descriptor arg_version = {"version", "Output version information"}; - const arg_descriptor arg_data_dir = {"data-dir", "Specify data directory"}; + const arg_descriptor arg_data_dir = {"data-dir", "Specify data directory", ""}; const arg_descriptor arg_config_file = { "config-file", "Specify configuration file", std::string(CURRENCY_NAME_SHORT ".conf") }; const arg_descriptor arg_os_version = { "os-version", "" }; diff --git a/src/common/command_line.h b/src/common/command_line.h index bbd871d6..4971bb13 100644 --- a/src/common/command_line.h +++ b/src/common/command_line.h @@ -23,6 +23,25 @@ namespace command_line struct arg_descriptor { typedef T value_type; + arg_descriptor(const char* _name, const char* _description): + name(_name), + description(_description), + not_use_default(true), + default_value(T()) + {} + arg_descriptor(const char* _name, const char* _description, const T& default_val) : + name(_name), + description(_description), + not_use_default(false), + default_value(default_val) + {} + arg_descriptor(const char* _name, const char* _description, const T& default_val, bool not_use_default) : + name(_name), + description(_description), + default_value(default_val), + not_use_default(not_use_default) + {} + const char* name; const char* description; diff --git a/src/gui/qt-daemon/main.cpp b/src/gui/qt-daemon/main.cpp index 28e7a564..94efe369 100644 --- a/src/gui/qt-daemon/main.cpp +++ b/src/gui/qt-daemon/main.cpp @@ -60,6 +60,11 @@ int main(int argc, char *argv[]) #endif #endif + log_space::get_set_log_detalisation_level(true, LOG_LEVEL_0); + log_space::get_set_need_thread_id(true, true); + log_space::log_singletone::enable_channels("core,currency_protocol,tx_pool,p2p,wallet"); + + QApplication app(argc, argv); MainWindow viewer; if (!viewer.init_backend(argc, argv)) diff --git a/src/wallet/plain_wallet_api.cpp b/src/wallet/plain_wallet_api.cpp index 9ee8b9b3..c4f55a39 100644 --- a/src/wallet/plain_wallet_api.cpp +++ b/src/wallet/plain_wallet_api.cpp @@ -3,6 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include #include "plain_wallet_api.h" #include "plain_wallet_api_impl.h" #include "currency_core/currency_config.h" @@ -17,7 +18,7 @@ #elif ANDROID_BUILD #define HOME_FOLDER "files" #else - #define HOME_FOLDER "" + #define HOME_FOLDER "logs" #endif #define WALLETS_FOLDER_NAME "wallets" #define APP_CONFIG_FOLDER "app_config" @@ -41,7 +42,7 @@ namespace plain_wallet std::string get_bundle_root_dir() { #ifdef WIN32 - return ""; + return boost::dll::program_location().parent_path().string(); #elif IOS_BUILD char* env = getenv("HOME"); return env ? env : ""; @@ -79,6 +80,9 @@ namespace plain_wallet { std::string log_dir = get_bundle_root_dir(); log_dir += "/" HOME_FOLDER; + + log_space::get_set_need_thread_id(true, true); + log_space::log_singletone::enable_channels("core,currency_protocol,tx_pool,p2p,wallet"); epee::log_space::get_set_log_detalisation_level(true, log_level); epee::log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL); epee::log_space::log_singletone::add_logger(LOGGER_FILE, "plain_wallet.log", log_dir.c_str()); @@ -108,11 +112,13 @@ namespace plain_wallet initialize_logs(log_level); std::string argss_1 = std::string("--remote-node=") + ip + ":" + port; - char * args[3]; + std::string argss_2 = std::string("--disable-logs-init"); + char * args[4]; args[0] = "stub"; args[1] = const_cast(argss_1.c_str()); - args[2] = nullptr; - if (!gwm.init(2, args, nullptr)) + args[2] = const_cast(argss_2.c_str()); + args[3] = nullptr; + if (!gwm.init(3, args, nullptr)) { LOG_ERROR("Failed to init wallets_manager"); return GENERAL_INTERNAL_ERRROR_INIT; @@ -176,6 +182,19 @@ namespace plain_wallet } + std::string get_logs_buffer() + { + return epee::log_space::log_singletone::copy_logs_to_buffer(); + } + + std::string truncate_log() + { + epee::log_space::log_singletone::truncate_log_files(); + epee::json_rpc::response ok_response = AUTO_VAL_INIT(ok_response); + ok_response.result.return_code = API_RETURN_CODE_OK; + return epee::serialization::store_t_to_json(ok_response); + } + std::string get_version() { diff --git a/src/wallet/plain_wallet_api.h b/src/wallet/plain_wallet_api.h index abc96f0d..5f05e8b7 100644 --- a/src/wallet/plain_wallet_api.h +++ b/src/wallet/plain_wallet_api.h @@ -17,6 +17,8 @@ namespace plain_wallet std::string get_appconfig(); std::string set_appconfig(const std::string& conf_str); + std::string get_logs_buffer(); + std::string truncate_log(); std::string open(const std::string& path, const std::string& password); std::string restore(const std::string& seed, const std::string& path, const std::string& password); diff --git a/src/wallet/wallets_manager.cpp b/src/wallet/wallets_manager.cpp index 780ea0f2..302754ea 100644 --- a/src/wallet/wallets_manager.cpp +++ b/src/wallet/wallets_manager.cpp @@ -67,6 +67,9 @@ const command_line::arg_descriptor arg_enable_gui_debug_mode = { "gui-debu const command_line::arg_descriptor arg_qt_remote_debugging_port = { "remote-debugging-port", "Specify port for Qt remote debugging", 30333, true }; const command_line::arg_descriptor arg_remote_node = { "remote-node", "Switch GUI to work with remote node instead of local daemon", "", true }; const command_line::arg_descriptor arg_enable_qt_logs = { "enable-qt-logs", "Forward Qt log messages into main log", false, true }; +const command_line::arg_descriptor arg_disable_logs_init("disable-logs-init", "Disable log initialization in GUI"); +//const command_line::arg_descriptor arg_disable_logs_init = { "disable-logs-init", "Disable log initialization in GUI" }; + void wallet_lock_time_watching_policy::watch_lock_time(uint64_t lock_time) { @@ -100,10 +103,6 @@ bool wallets_manager::init(int argc, char* argv[], view::i_view* pview_handler) dsi.pos_difficulty = dsi.pow_difficulty = "---"; m_pview->update_daemon_status(dsi); - log_space::get_set_log_detalisation_level(true, LOG_LEVEL_0); - log_space::get_set_need_thread_id(true, true); - log_space::log_singletone::enable_channels("core,currency_protocol,tx_pool,p2p,wallet"); - tools::signal_handler::install_fatal([](int sig_number, void* address) { LOG_ERROR("\n\nFATAL ERROR\nsig: " << sig_number << ", address: " << address); std::fflush(nullptr); // all open output streams are flushed @@ -142,6 +141,8 @@ bool wallets_manager::init(int argc, char* argv[], view::i_view* pview_handler) command_line::add_arg(desc_cmd_sett, arg_qt_remote_debugging_port); command_line::add_arg(desc_cmd_sett, arg_remote_node); command_line::add_arg(desc_cmd_sett, arg_enable_qt_logs); + command_line::add_arg(desc_cmd_sett, arg_disable_logs_init); + #ifndef MOBILE_WALLET_BUILD currency::core::init_options(desc_cmd_sett); @@ -228,10 +229,6 @@ bool wallets_manager::init(int argc, char* argv[], view::i_view* pview_handler) path_to_html = command_line::get_arg(m_vm, arg_html_folder); } - log_space::log_singletone::add_logger(LOGGER_FILE, log_file_name.c_str(), log_dir.c_str()); - LOG_PRINT_L0(CURRENCY_NAME << " v" << PROJECT_VERSION_LONG); - LOG_PRINT("Module folder: " << argv[0], LOG_LEVEL_0); - if (command_line::has_arg(m_vm, arg_remote_node)) { m_remote_node_mode = true; @@ -242,6 +239,13 @@ bool wallets_manager::init(int argc, char* argv[], view::i_view* pview_handler) m_rpc_proxy->set_connection_addr(command_line::get_arg(m_vm, arg_remote_node)); } + if(!command_line::has_arg(m_vm, arg_disable_logs_init)) + { + log_space::log_singletone::add_logger(LOGGER_FILE, log_file_name.c_str(), log_dir.c_str()); + LOG_PRINT_L0(CURRENCY_NAME << " v" << PROJECT_VERSION_LONG); + LOG_PRINT("Module folder: " << argv[0], LOG_LEVEL_0); + } + m_qt_logs_enbaled = command_line::get_arg(m_vm, arg_enable_qt_logs); m_pview->init(path_to_html); diff --git a/tests/functional_tests/core_concurrency_test.cpp b/tests/functional_tests/core_concurrency_test.cpp index 52ff1b8c..55c4bdeb 100644 --- a/tests/functional_tests/core_concurrency_test.cpp +++ b/tests/functional_tests/core_concurrency_test.cpp @@ -461,7 +461,8 @@ bool core_concurrency_test(boost::program_options::variables_map& vm, size_t wth test_protocol_handler protocol_handler(c, core_listener.get()); c.set_currency_protocol(&protocol_handler); - if (!c.init(vm)) + tools::db::db_backend_selector dbbs; + if (!c.init(vm, dbbs)) { LOG_ERROR("Failed to init core"); return false; @@ -527,7 +528,8 @@ bool core_concurrency_test(boost::program_options::variables_map& vm, size_t wth test_protocol_handler protocol_handler(c, core_listener.get()); c.set_currency_protocol(&protocol_handler); - if (!c.init(vm)) + tools::db::db_backend_selector dbbs; + if (!c.init(vm, dbbs)) { LOG_ERROR("Failed to init core"); return false; diff --git a/tests/functional_tests/plain_wallet_tests.cpp b/tests/functional_tests/plain_wallet_tests.cpp index 0b626ea3..ea932417 100644 --- a/tests/functional_tests/plain_wallet_tests.cpp +++ b/tests/functional_tests/plain_wallet_tests.cpp @@ -30,77 +30,83 @@ struct try_pull_result_open_response void run_plain_wallet_api_test() { LOG_PRINT_L0("Creating instance..."); - std::string s = plain_wallet::init("195.201.107.230", "11211"); + std::string s = plain_wallet::init("195.201.107.230", "11211", 1); - LOG_PRINT_L0("Generating wallet..."); - view::open_wallet_request owr = AUTO_VAL_INIT(owr); - owr.path = "E:\\tmp\\zano_testwallet_745ss65030.zan"; - owr.pass = ""; - std::string job_id_str = plain_wallet::async_call("open", 0, epee::serialization::store_t_to_json(owr)); + std::string fres = plain_wallet::get_logs_buffer(); + std::string fres2 = plain_wallet::truncate_log(); + std::string fres3 = plain_wallet::get_logs_buffer(); - try_pull_result_open_response rsp = AUTO_VAL_INIT(rsp); - - while (true) - { - std::string res = plain_wallet::try_pull_result(1); - LOG_PRINT_L0("[try_pull_result] RESPONSE:" << ENDL << res); - - if (!epee::serialization::load_t_from_json(rsp, res)) - { - LOG_ERROR("Failed to parse try_pull_result response: " << res); - return; - } - epee::misc_utils::sleep_no_w(1000); - if(!rsp.delivered) - continue; - break; - } - +// LOG_PRINT_L0("Generating wallet..."); +// view::open_wallet_request owr = AUTO_VAL_INIT(owr); +// owr.path = "E:\\tmp\\zano_testwallet_745ss65030.zan"; +// owr.pass = ""; +// std::string job_id_str = plain_wallet::async_call("open", 0, epee::serialization::store_t_to_json(owr)); +// +// +// try_pull_result_open_response rsp = AUTO_VAL_INIT(rsp); +// +// while (true) +// { +// std::string res = plain_wallet::try_pull_result(1); +// LOG_PRINT_L0("[try_pull_result] RESPONSE:" << ENDL << res); +// +// if (!epee::serialization::load_t_from_json(rsp, res)) +// { +// LOG_ERROR("Failed to parse try_pull_result response: " << res); +// return; +// } +// epee::misc_utils::sleep_no_w(1000); +// if(!rsp.delivered) +// continue; +// break; +// } +// +// //std::string rsp = plain_wallet::open(std::string("E:\\tmp\\zano_testwallet_745ss65030.zan"), ""); //LOG_PRINT_L0("RESPONSE:" << ENDL << rsp); //epee::json_rpc::response ok_response = AUTO_VAL_INIT(ok_response); //epee::serialization::load_t_from_json(ok_response, rsp); - size_t count = 0; - while (count < 10) - { - std::string prog = plain_wallet::get_wallet_status(rsp.result.result.wallet_id); - LOG_PRINT_L0("Progress: " << ENDL << prog); - view::wallet_sync_status_info wsi = AUTO_VAL_INIT(wsi); - if (!epee::serialization::load_t_from_json(wsi, prog)) - { - LOG_ERROR("Failed to get_wallet_status()"); - return; - } - if (!wsi.is_in_long_refresh) - break; - epee::misc_utils::sleep_no_w(1000); - } - - std::string job_id_str2 = plain_wallet::async_call("close", rsp.result.result.wallet_id, ""); - try_pull_result_open_response rsp2 = AUTO_VAL_INIT(rsp2); - - while (true) - { - std::string res = plain_wallet::try_pull_result(2); - LOG_PRINT_L0("[try_pull_result] RESPONSE:" << ENDL << res); - - if (!epee::serialization::load_t_from_json(rsp2, res)) - { - LOG_ERROR("Failed to parse try_pull_result response: " << res); - return; - } - epee::misc_utils::sleep_no_w(1000); - if (!rsp2.delivered) - continue; - break; - } - - - LOG_PRINT_L0("OK"); +// size_t count = 0; +// while (count < 10) +// { +// std::string prog = plain_wallet::get_wallet_status(rsp.result.result.wallet_id); +// LOG_PRINT_L0("Progress: " << ENDL << prog); +// view::wallet_sync_status_info wsi = AUTO_VAL_INIT(wsi); +// if (!epee::serialization::load_t_from_json(wsi, prog)) +// { +// LOG_ERROR("Failed to get_wallet_status()"); +// return; +// } +// if (!wsi.is_in_long_refresh) +// break; +// epee::misc_utils::sleep_no_w(1000); +// } +// +// std::string job_id_str2 = plain_wallet::async_call("close", rsp.result.result.wallet_id, ""); +// try_pull_result_open_response rsp2 = AUTO_VAL_INIT(rsp2); +// +// while (true) +// { +// std::string res = plain_wallet::try_pull_result(2); +// LOG_PRINT_L0("[try_pull_result] RESPONSE:" << ENDL << res); +// +// if (!epee::serialization::load_t_from_json(rsp2, res)) +// { +// LOG_ERROR("Failed to parse try_pull_result response: " << res); +// return; +// } +// epee::misc_utils::sleep_no_w(1000); +// if (!rsp2.delivered) +// continue; +// break; +// } +// +// +// LOG_PRINT_L0("OK"); }