From 5833d66f6540e7b34e10ddef37c2b67bd501994b Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sun, 1 Jan 2017 16:34:23 +0000 Subject: Change logging to easylogging++ This replaces the epee and data_loggers logging systems with a single one, and also adds filename:line and explicit severity levels. Categories may be defined, and logging severity set by category (or set of categories). epee style 0-4 log level maps to a sensible severity configuration. Log files now also rotate when reaching 100 MB. To select which logs to output, use the MONERO_LOGS environment variable, with a comma separated list of categories (globs are supported), with their requested severity level after a colon. If a log matches more than one such setting, the last one in the configuration string applies. A few examples: This one is (mostly) silent, only outputting fatal errors: MONERO_LOGS=*:FATAL This one is very verbose: MONERO_LOGS=*:TRACE This one is totally silent (logwise): MONERO_LOGS="" This one outputs all errors and warnings, except for the "verify" category, which prints just fatal errors (the verify category is used for logs about incoming transactions and blocks, and it is expected that some/many will fail to verify, hence we don't want the spam): MONERO_LOGS=*:WARNING,verify:FATAL Log levels are, in decreasing order of priority: FATAL, ERROR, WARNING, INFO, DEBUG, TRACE Subcategories may be added using prefixes and globs. This example will output net.p2p logs at the TRACE level, but all other net* logs only at INFO: MONERO_LOGS=*:ERROR,net*:INFO,net.p2p:TRACE Logs which are intended for the user (which Monero was using a lot through epee, but really isn't a nice way to go things) should use the "global" category. There are a few helper macros for using this category, eg: MGINFO("this shows up by default") or MGINFO_RED("this is red"), to try to keep a similar look and feel for now. Existing epee log macros still exist, and map to the new log levels, but since they're used as a "user facing" UI element as much as a logging system, they often don't map well to log severities (ie, a log level 0 log may be an error, or may be something we want the user to see, such as an important info). In those cases, I tried to use the new macros. In other cases, I left the existing macros in. When modifying logs, it is probably best to switch to the new macros with explicit levels. The --log-level options and set_log commands now also accept category settings, in addition to the epee style log levels. --- contrib/otshell_utils/CMakeLists.txt | 18 - contrib/otshell_utils/LICENCE.txt | 21 - contrib/otshell_utils/ccolor.cpp | 116 ----- contrib/otshell_utils/ccolor.hpp | 73 --- contrib/otshell_utils/lib_common1.hpp | 53 -- contrib/otshell_utils/runoptions.cpp | 69 --- contrib/otshell_utils/runoptions.hpp | 58 --- contrib/otshell_utils/utils.cpp | 806 ------------------------------- contrib/otshell_utils/utils.hpp | 532 -------------------- contrib/otshell_utils/windows_stream.cpp | 64 --- contrib/otshell_utils/windows_stream.h | 20 - 11 files changed, 1830 deletions(-) delete mode 100644 contrib/otshell_utils/CMakeLists.txt delete mode 100644 contrib/otshell_utils/LICENCE.txt delete mode 100644 contrib/otshell_utils/ccolor.cpp delete mode 100644 contrib/otshell_utils/ccolor.hpp delete mode 100644 contrib/otshell_utils/lib_common1.hpp delete mode 100644 contrib/otshell_utils/runoptions.cpp delete mode 100644 contrib/otshell_utils/runoptions.hpp delete mode 100644 contrib/otshell_utils/utils.cpp delete mode 100644 contrib/otshell_utils/utils.hpp delete mode 100644 contrib/otshell_utils/windows_stream.cpp delete mode 100644 contrib/otshell_utils/windows_stream.h (limited to 'contrib/otshell_utils') diff --git a/contrib/otshell_utils/CMakeLists.txt b/contrib/otshell_utils/CMakeLists.txt deleted file mode 100644 index 263f07c85..000000000 --- a/contrib/otshell_utils/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -cmake_minimum_required (VERSION 2.6) -project (otshell CXX) - -# Add executable - -if(APPLE AND POLICY CMP0042) - cmake_policy(SET CMP0042 NEW) -endif() - -file(GLOB otshell_utils_sources # All files in directory: - "*.h" - "*.hpp" - "*.cpp" -) - -add_library (otshell_utils ${otshell_utils_sources}) -set_target_properties (otshell_utils PROPERTIES OUTPUT_NAME "otshell_utils") -#target_link_libraries (upnpc-static ${LDLIBS}) # to add used libs diff --git a/contrib/otshell_utils/LICENCE.txt b/contrib/otshell_utils/LICENCE.txt deleted file mode 100644 index f351acf10..000000000 --- a/contrib/otshell_utils/LICENCE.txt +++ /dev/null @@ -1,21 +0,0 @@ - -This are some files also from OpenTransactions / otshell project, -developed thanks to the awesome OpenTransaction project, organization and developers :) - -Parts of code here was also developed thanks to the excellent Monero project, -thanks to Monero project, organization and developers :) - -[Some] files/code here (in external/otshell_utils) are under licence defined in -src/doc/LICENCE-otshell.txt ; -Others are from monero, with licence in src/doc/LICENCE-monero.txt ; - -For me (rfree) the licence seem compatbile so no problem, personally (as author of many parts of the code, -possibly not all) I do not worry who uses it how; I'am not a lawyer. - -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Please share :-) This licence can be used e.g. for parts of code that are usable in both open-source FOSS project -Monero and Open Transactions, to share and develop both faster. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - - diff --git a/contrib/otshell_utils/ccolor.cpp b/contrib/otshell_utils/ccolor.cpp deleted file mode 100644 index cd93e0de7..000000000 --- a/contrib/otshell_utils/ccolor.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include "ccolor.hpp" -#include - -// from http://stackoverflow.com/questions/2616906/how-do-i-output-coloured-text-to-a-linux-terminal -// from http://wiznet.gr/src/ccolor.zip -// edited by rfree - as part of https://github.com/rfree/Open-Transactions/ - -using namespace std; - -#ifdef _MSC_VER - -#define snprintf c99_snprintf - -inline int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap) { - int count = -1; - if (size != 0) - count = _vsnprintf_s(str, size, _TRUNCATE, format, ap); - if (count == -1) - count = _vscprintf(format, ap); - return count; -} - -inline int c99_snprintf(char* str, size_t size, const char* format, ...) { - int count; - va_list ap; - va_start(ap, format); - count = c99_vsnprintf(str, size, format, ap); - va_end(ap); - return count; -} -#endif // _MSC_VER - -#define CC_CONSOLE_COLOR_DEFAULT "\033[0m" -#define CC_FORECOLOR(C) "\033[" #C "m" -#define CC_BACKCOLOR(C) "\033[" #C "m" -#define CC_ATTR(A) "\033[" #A "m" - -namespace zkr -{ - enum Color - { - Black, - Red, - Green, - Yellow, - Blue, - Magenta, - Cyan, - White, - Default = 9 - }; - - enum Attributes - { - Reset, - Bright, - Dim, - Underline, - Blink, - Reverse, - Hidden - }; - - char * cc::color(int attr, int fg, int bg) - { - static const int size = 20; - static char command[size]; - - /* Command is the control command to the terminal */ - snprintf(command, size, "%c[%d;%d;%dm", 0x1B, attr, fg + 30, bg + 40); - return command; - } - - - const char *cc::console = CC_CONSOLE_COLOR_DEFAULT; - const char *cc::underline = CC_ATTR(4); - const char *cc::bold = CC_ATTR(1); - - const char *cc::fore::black = CC_FORECOLOR(30); - const char *cc::fore::blue = CC_FORECOLOR(34); - const char *cc::fore::red = CC_FORECOLOR(31); - const char *cc::fore::magenta = CC_FORECOLOR(35); - const char *cc::fore::green = CC_FORECOLOR(92); - const char *cc::fore::cyan = CC_FORECOLOR(36); - const char *cc::fore::yellow = CC_FORECOLOR(33); - const char *cc::fore::white = CC_FORECOLOR(37); - const char *cc::fore::console = CC_FORECOLOR(39); - - const char *cc::fore::lightblack = CC_FORECOLOR(90); - const char *cc::fore::lightblue = CC_FORECOLOR(94); - const char *cc::fore::lightred = CC_FORECOLOR(91); - const char *cc::fore::lightmagenta = CC_FORECOLOR(95); - const char *cc::fore::lightgreen = CC_FORECOLOR(92); - const char *cc::fore::lightcyan = CC_FORECOLOR(96); - const char *cc::fore::lightyellow = CC_FORECOLOR(93); - const char *cc::fore::lightwhite = CC_FORECOLOR(97); - - const char *cc::back::black = CC_BACKCOLOR(40); - const char *cc::back::blue = CC_BACKCOLOR(44); - const char *cc::back::red = CC_BACKCOLOR(41); - const char *cc::back::magenta = CC_BACKCOLOR(45); - const char *cc::back::green = CC_BACKCOLOR(42); - const char *cc::back::cyan = CC_BACKCOLOR(46); - const char *cc::back::yellow = CC_BACKCOLOR(43); - const char *cc::back::white = CC_BACKCOLOR(47); - const char *cc::back::console = CC_BACKCOLOR(49); - - const char *cc::back::lightblack = CC_BACKCOLOR(100); - const char *cc::back::lightblue = CC_BACKCOLOR(104); - const char *cc::back::lightred = CC_BACKCOLOR(101); - const char *cc::back::lightmagenta = CC_BACKCOLOR(105); - const char *cc::back::lightgreen = CC_BACKCOLOR(102); - const char *cc::back::lightcyan = CC_BACKCOLOR(106); - const char *cc::back::lightyellow = CC_BACKCOLOR(103); - const char *cc::back::lightwhite = CC_BACKCOLOR(107); -} diff --git a/contrib/otshell_utils/ccolor.hpp b/contrib/otshell_utils/ccolor.hpp deleted file mode 100644 index bf5a601a2..000000000 --- a/contrib/otshell_utils/ccolor.hpp +++ /dev/null @@ -1,73 +0,0 @@ -// ccolor.hpp - -// from http://stackoverflow.com/questions/2616906/how-do-i-output-coloured-text-to-a-linux-terminal -// from http://wiznet.gr/src/ccolor.zip -// edited by rfree - as part of https://github.com/rfree/Open-Transactions/ - -#ifndef INCLUDE_OT_ccolor -#define INCLUDE_OT_ccolor - -#include -#include - -namespace zkr -{ - class cc - { - public: - - class fore - { - public: - static const char *black; - static const char *blue; - static const char *red; - static const char *magenta; - static const char *green; - static const char *cyan; - static const char *yellow; - static const char *white; - static const char *console; - - static const char *lightblack; - static const char *lightblue; - static const char *lightred; - static const char *lightmagenta; - static const char *lightgreen; - static const char *lightcyan; - static const char *lightyellow; - static const char *lightwhite; - }; - - class back - { - public: - static const char *black; - static const char *blue; - static const char *red; - static const char *magenta; - static const char *green; - static const char *cyan; - static const char *yellow; - static const char *white; - static const char *console; - - static const char *lightblack; - static const char *lightblue; - static const char *lightred; - static const char *lightmagenta; - static const char *lightgreen; - static const char *lightcyan; - static const char *lightyellow; - static const char *lightwhite; - }; - - static char *color(int attr, int fg, int bg); - static const char *console; - static const char *underline; - static const char *bold; - }; -} - -#endif - diff --git a/contrib/otshell_utils/lib_common1.hpp b/contrib/otshell_utils/lib_common1.hpp deleted file mode 100644 index 2cb466beb..000000000 --- a/contrib/otshell_utils/lib_common1.hpp +++ /dev/null @@ -1,53 +0,0 @@ -/* See other files here for the LICENCE that applies here. */ - - -#ifndef INCLUDE_OT_NEWCLI_COMMON1 -#define INCLUDE_OT_NEWCLI_COMMON1 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - - -// list of thigs from libraries that we pull into namespace nOT::nNewcli -// we might still need to copy/paste it in few places to make IDEs pick it up correctly -#define INJECT_OT_COMMON_USING_NAMESPACE_COMMON_1 \ - using std::string; \ - using std::vector; \ - using std::vector; \ - using std::list; \ - using std::set; \ - using std::map; \ - using std::ostream; \ - using std::istream; \ - using std::cin; \ - using std::cerr; \ - using std::cout; \ - using std::cerr; \ - using std::endl; \ - using std::function; \ - using std::unique_ptr; \ - using std::shared_ptr; \ - using std::weak_ptr; \ - using std::enable_shared_from_this; \ - using boost::lock_guard; \ - -#endif - diff --git a/contrib/otshell_utils/runoptions.cpp b/contrib/otshell_utils/runoptions.cpp deleted file mode 100644 index ffd37eae4..000000000 --- a/contrib/otshell_utils/runoptions.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* See other files here for the LICENCE that applies here. */ -/* See header file .hpp for info */ - -#include "runoptions.hpp" - -#include "lib_common1.hpp" - -namespace nOT { - -INJECT_OT_COMMON_USING_NAMESPACE_COMMON_1 // <=== namespaces - -// (no debug - this is the default) -// +nodebug (no debug) -// +debug ...... --asdf -// +debug +debugcerr .... --asfs -// +debug +debugfile .... --asfs - -cRunOptions::cRunOptions() - : mRunMode(eRunModeCurrent), mDebug(false), mDebugSendToFile(false), mDebugSendToCerr(false) - ,mDoRunDebugshow(false) -{ } - -vector cRunOptions::ExecuteRunoptionsAndRemoveThem(const vector & args) { - vector arg_clear; // will store only the arguments that are not removed - - for (auto arg : args) { - bool thisIsRunoption=false; - - if (arg.size()>0) { - if (arg.at(0) == '+') thisIsRunoption=true; - } - - if (thisIsRunoption) Exec(arg); // *** - if (! thisIsRunoption) arg_clear.push_back(arg); - } - - Normalize(); - - return arg_clear; -} - -void cRunOptions::Exec(const string & runoption) { // eg: Exec("+debug"); - if (runoption == "+nodebug") { mDebug=false; } - else if (runoption == "+debug") { mDebug=true; } - else if (runoption == "+debugcerr") { mDebug=true; mDebugSendToCerr=true; } - else if (runoption == "+debugfile") { mDebug=true; mDebugSendToFile=true; } - else if (runoption == "+demo") { mRunMode=eRunModeDemo; } - else if (runoption == "+normal") { mRunMode=eRunModeNormal; } - else if (runoption == "+current") { mRunMode=eRunModeCurrent; } - else if (runoption == "+debugshow") { mDebug=true; mDebugSendToCerr=true; mDoRunDebugshow=true; } - else { - cerr << "Unknown runoption in Exec: '" << runoption << "'" << endl; - throw std::runtime_error("Unknown runoption"); - } - // cerr<<"debug="< ExecuteRunoptionsAndRemoveThem(const vector & args); - void Exec(const string & runoption); // eg: Exec("+debug"); - - void Normalize(); -}; - -extern cRunOptions gRunOptions; - - -} // namespace nOT - - - -#endif - diff --git a/contrib/otshell_utils/utils.cpp b/contrib/otshell_utils/utils.cpp deleted file mode 100644 index ef9b37f03..000000000 --- a/contrib/otshell_utils/utils.cpp +++ /dev/null @@ -1,806 +0,0 @@ -/// @file -/// @author rfree (current maintainer in monero.cc project) -/// @brief various general utils taken from (and relate to) otshell project, including loggiang/debug - -/* See other files here for the LICENCE that applies here. */ -/* See header file .hpp for info */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "utils.hpp" - -#include "ccolor.hpp" - -#include "lib_common1.hpp" - -#include "runoptions.hpp" - -#if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined (WIN64) - #define OS_TYPE_WINDOWS -#elif defined(__unix__) || defined(__posix) || defined(__linux) || defined(__darwin) || defined(__APPLE__) || defined(__clang__) - #define OS_TYPE_POSIX -#else - #warning "Compiler/OS platform is not recognized. Just assuming it will work as POSIX then" - #define OS_TYPE_POSIX -#endif - -#if defined(OS_TYPE_WINDOWS) - #include - #include -#elif defined(OS_TYPE_POSIX) - #include - #include - #include -#else - #error "Compiler/OS platform detection failed - not supported" -#endif - - -namespace nOT { -namespace nUtils { - -INJECT_OT_COMMON_USING_NAMESPACE_COMMON_1 // <=== namespaces - -// ==================================================================== - -// Numerical values of the debug levels - see hpp -const int _debug_level_nr_dbg3=20; -const int _debug_level_nr_dbg2=30; -const int _debug_level_nr_dbg1=40; -const int _debug_level_nr_info=50; -const int _debug_level_nr_note=60; -const int _debug_level_nr_fact=75; -const int _debug_level_nr_mark=80; -const int _debug_level_nr_warn=90; -const int _debug_level_nr_erro=100; - -// ==================================================================== - -myexception::myexception(const char * what) - : std::runtime_error(what) -{ } - -myexception::myexception(const std::string &what) - : std::runtime_error(what) -{ } - -void myexception::Report() const { - _erro("Error: " << what()); -} - -//myexception::~myexception() { } - -// ==================================================================== - -// text trimming -// http://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring -std::string & ltrim(std::string &s) { - s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun(std::isspace)))); - return s; -} - -std::string & rtrim(std::string &s) { - s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun(std::isspace))).base(), s.end()); - return s; -} - -std::string & trim(std::string &s) { - return ltrim(rtrim(s)); -} - -std::string get_current_time() { - std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); - time_t time_now = std::chrono::system_clock::to_time_t(now); - std::chrono::high_resolution_clock::duration duration = now.time_since_epoch(); - int64_t micro = std::chrono::duration_cast(duration).count(); - - // std::localtime() - This function may not be thread-safe. - #ifdef OS_TYPE_WINDOWS - struct tm * tm_pointer = std::localtime( &time_now ); // thread-safe on mingw-w64 (thread local variable) and on MSVC btw - // http://stackoverflow.com/questions/18551409/localtime-r-support-on-mingw - // tm_pointer points to thread-local data, memory is owned/managed by the system/library - #else - // linux, freebsd, have this - struct tm tm_object; // automatic storage duration http://en.cppreference.com/w/cpp/language/storage_duration - struct tm * tm_pointer = & tm_object; // just point to our data - auto x = localtime_r( &time_now , tm_pointer ); // modifies our own (this thread) data in tm_object, this is safe http://linux.die.net/man/3/localtime_r - if (x != tm_pointer) return "(internal error in get_current_time)"; // redundant check in case of broken implementation of localtime_r - #endif - // tm_pointer now points to proper time data, and that memory is automatically managed - if (!tm_pointer) return "(internal error in get_current_time - NULL)"; // redundant check in case of broken implementation of used library methods - - std::stringstream stream; - stream << std::setfill('0') - << std::setw(2) << tm_pointer->tm_year+1900 - << '-' << std::setw(2) << tm_pointer->tm_mon+1 - << '-' << std::setw(2) << tm_pointer->tm_mday - << ' ' << std::setw(2) << tm_pointer->tm_hour - << ':' << std::setw(2) << tm_pointer->tm_min - << ':' << std::setw(2) << tm_pointer->tm_sec - << '.' << std::setw(6) << (micro%1000000); // 6 because microseconds - return stream.str(); -} - -cNullstream g_nullstream; // extern a stream that does nothing (eats/discards data) - -boost::recursive_mutex gLoggerGuard; // extern -std::atomic gLoggerGuardDepth; // extern - -std::atomic & gLoggerGuardDepth_Get() { - // TODO std::once would be nicer here - - static bool once=0; - - if (!once) { // initialize it once - once=1; - gLoggerGuardDepth=0; - } - - return gLoggerGuardDepth; // global, atomic counter -} - - -// ==================================================================== - -namespace nDetail { - -const char* DbgShortenCodeFileName(const char *s) { - const char *p = s; - const char *a = s; - - bool inc=1; - while (*p) { - ++p; - if (inc && ('\0' != * p)) { a=p; inc=false; } // point to the current character (if valid) becasue previous one was slash - if ((*p)=='/') { a=p; inc=true; } // point at current slash (but set inc to try to point to next character) - } - return a; -} - -} - -// a workaround for MSVC compiler; e.g. see https://bugs.webkit.org/show_bug.cgi?format=multiple&id=125795 -#ifndef _MSC_VER -template -std::unique_ptr make_unique( Args&& ...args ) -{ - return std::unique_ptr( new T( std::forward(args)... ) ); -} -#else - using std::make_unique; -#endif -// ==================================================================== - -char cFilesystemUtils::GetDirSeparatorSys() { - // TODO nicer os detection? - #if defined(OS_TYPE_POSIX) - return '/'; - #elif defined(OS_TYPE_WINDOWS) - return '\\'; - #else - #error "Do not know how to compile this for your platform." - #endif -} - -char cFilesystemUtils::GetDirSeparatorInter() { - return '/'; -} - -string cFilesystemUtils::FileInternalToSystem(const std::string &name) { - string ret; - ret.resize(name.size()); - std::replace_copy(name.begin(), name.end(), ret.begin(), - GetDirSeparatorInter() , GetDirSeparatorSys()); - return ret; -} - -string cFilesystemUtils::FileSystemToInternal(const std::string &name) { - string ret; - ret.reserve(name.size()); - std::replace_copy(name.begin(), name.end(), ret.begin(), - GetDirSeparatorSys() , GetDirSeparatorInter()); - return ret; -} - -bool cFilesystemUtils::CreateDirTree(const std::string & dir, bool only_below) { - const bool dbg=false; - //struct stat st; - const char dirchS = cFilesystemUtils::GetDirSeparatorSys(); - const char dirchI = cFilesystemUtils::GetDirSeparatorInter(); - std::istringstream iss(dir); - string partI; // current par is in internal format (though it should not matter since it doesn't contain any slashes). eg "bar" - string sofarS=""; // sofarS - the so far created dir part is in SYSTEM format. eg "foo/bar" - if (dir.size()<1) return false; // illegal name - // dir[0] is valid from here - if ( only_below && ((dir[0]==dirchS) || (dir[0]==dirchI))) return false; // no jumping to top (on any os) - - while (getline(iss,partI,dirchI)) { // get new component eg "bar" into part - if (dbg) cout << '['< m_extra_msg; ///< any additional messages about this channel use -}; - -cDebugScopeGuard::cDebugScopeGuard() : mLevel(-1) { -} - -cDebugScopeGuard::~cDebugScopeGuard() { - if (mLevel != -1) { - gCurrentLogger.write_stream(mLevel,mChan) << mMsg << " ... end" << gCurrentLogger.endline() << std::flush; - } -} - -void cDebugScopeGuard::Assign(const string &chan, const int level, const string &msg) { - mChan=chan; - mLevel=level; - mMsg=msg; -} - -} // namespace nDetail - -// ==================================================================== - -cLogger::cLogger() : -mStream(NULL), -mStreamBrokenDebug(NULL), -mIsBroken(true), // before constructor finishes -mLevel(_debug_level_nr_warn), -mThread2Number_Biggest(0), // the CURRENT biggest value (no thread yet in map) -mPid2Number_Biggest(0) -{ - mStream = & std::cout; - mStreamBrokenDebug = & std::cerr; // the backup stream - *mStreamBrokenDebug << "Creating the logger system" << endl; - mIsBroken=false; // ok, constr. succeeded, so string is not broken now - - // this is here, because it could be using logging itself to log creation of first thread/PID etc - Thread2Number( boost::this_thread::get_id() ); // convert current id to short number, useful to reserve a number so that main thread is usually called 1 - Pid2Number( getpid() ); // add this proces ID as first one -} - -cLogger::~cLogger() { - for (auto pair : mChannels) { - std::ofstream *ptr = pair.second; - delete ptr; - pair.second=NULL; - } -} - -void cLogger::SetStreamBroken() { - SetStreamBroken("(no additional details about this problem)"); -} - -void cLogger::SetStreamBroken(const std::string &msg) { - _dbg_dbg("Stream is broken (msg: " << msg << ")"); - if (!mIsBroken) { // if not already marked as broken - _dbg_dbg("(It was not broken before)"); - std::cerr << OT_CODE_STAMP << "WARNING: due to a problem in the debug/logging system itself ("<0) output << " {p" << nicePid << "}"; - output << ' '; - return output; // <--- return - } else _dbg_dbg("Not writting: No mStream"); - } else _dbg_dbg("Not writting: Too low level level="<= mLevel="<(channel , thefile ) ); // <- created the channel mapping -} - -std::ostream & cLogger::SelectOutput(int level, const std::string & channel) noexcept { - try { - if (mIsBroken) { - _dbg_dbg("The stream is broken mIsBroken="<(fname); - mStream = & (*mOutfile); - _mark("Started new debug, to file: " << fname); -} - -void cLogger::setOutStreamFromGlobalOptions() { - if ( gRunOptions.getDebug() ) { - if ( gRunOptions.getDebugSendToFile() ) { - mOutfile = make_unique ("debuglog.txt"); - mStream = & (*mOutfile); - } - else if ( gRunOptions.getDebugSendToCerr() ) { - mStream = & std::cerr; - } - else { - mStream = & g_nullstream; - } - } - else { - mStream = & g_nullstream; - } -} - -void cLogger::setDebugLevel(int level) { - bool note_before = (mLevel > level); // report the level change before or after the change? (on higher level) - if (note_before) _note("Setting debug level to "<= 100) return cc::back::lightred + ToStr(cc::fore::lightyellow) + ToStr("ERROR ") + ToStr(cc::fore::lightyellow) + " " ; - if (level >= 90) return cc::back::lightyellow + ToStr(cc::fore::black) + ToStr("Warn ") + ToStr(cc::fore::red)+ " " ; - if (level >= 80) return cc::back::lightmagenta + ToStr(cc::fore::black) + ToStr("MARK "); //+ zkr::cc::console + ToStr(cc::fore::lightmagenta)+ " "; - if (level >= 75) return cc::back::lightyellow + ToStr(cc::fore::black) + ToStr("FACT ") + zkr::cc::console + ToStr(cc::fore::lightyellow)+ " "; - if (level >= 70) return cc::fore::green + ToStr("Note "); - if (level >= 50) return cc::fore::cyan + ToStr("info "); - if (level >= 40) return cc::fore::lightwhite + ToStr("dbg "); - if (level >= 30) return cc::fore::lightblue + ToStr("dbg "); - if (level >= 20) return cc::fore::blue + ToStr("dbg "); - - #elif defined(OS_TYPE_WINDOWS) - if (level >= 100) return ToStr("ERROR "); - if (level >= 90) return ToStr("Warn "); - if (level >= 80) return ToStr("MARK "); - if (level >= 75) return ToStr("FACT "); - if (level >= 70) return ToStr("Note "); - if (level >= 50) return ToStr("info "); - if (level >= 40) return ToStr("dbg "); - if (level >= 30) return ToStr("dbg "); - if (level >= 20) return ToStr("dbg "); - #endif - - return " "; -} - -std::string cLogger::endline() const { - #if defined(OS_TYPE_POSIX) - return ToStr("") + zkr::cc::console + ToStr("\n"); // TODO replan to avoid needles converting back and forth char*, string etc - #elif defined(OS_TYPE_WINDOWS) - return ToStr("\n"); - #endif -} - -int cLogger::Thread2Number(const boost::thread::id id) { - auto found = mThread2Number.find( id ); - if (found == mThread2Number.end()) { // new one - mThread2Number_Biggest++; - mThread2Number[id] = mThread2Number_Biggest; - _info_c("dbg/main", "This is a new thread (used in debug), thread id="<=32 && s[i] <= 126) - newStr<= ending.length()) { - return (0 == all.compare (all.length() - ending.length(), ending.length(), ending)); - } else { - return false; - } -} - - -vector WordsThatMatch(const std::string & sofar, const vector & possib) { - vector ret; - for ( auto rec : possib) { // check of possibilities - if (CheckIfBegins(sofar,rec)) { - rec = EscapeFromSpace(rec); - ret.push_back(rec); // this record matches - } - } - return ret; -} - -char GetLastChar(const std::string & str) { // TODO unicode? - auto s = str.length(); - if (s==0) throw std::runtime_error("Getting last character of empty string (" + ToStr(s) + ")" + OT_CODE_STAMP); - return str.at( s - 1); -} - -std::string GetLastCharIf(const std::string & str) { // TODO unicode? - auto s = str.length(); - if (s==0) return ""; // empty string signalizes ther is nothing to be returned - return std::string( 1 , str.at( s - 1) ); -} - -// ==================================================================== - -// ASRT - assert. Name like ASSERT() was too long, and ASS() was just... no. -// Use it like this: ASRT( x>y ); with the semicolon at end, a clever trick forces this syntax :) - -void Assert(bool result, const std::string &stamp, const std::string &condition) { - if (!result) { - _erro("Assert failed at "+stamp+": ASSERT( " << condition << ")"); - throw std::runtime_error("Assert failed at "+stamp+": ASSERT( " + condition + ")"); - } -} - -// ==================================================================== -// advanced string - -const std::string GetMultiline(string endLine) { - std::string result(""); // Taken from OT_CLI_ReadUntilEOF - while (true) { - std::string input_line(""); - if (std::getline(std::cin, input_line, '\n')) - { - input_line += "\n"; - if (input_line[0] == '~') - break; - result += input_line; - } - if (std::cin.eof() ) - { - std::cin.clear(); - break; - } - if (std::cin.fail() ) - { - std::cin.clear(); - break; - } - if (std::cin.bad()) - { - std::cin.clear(); - break; - } - } - return result; -} - -vector SplitString(const string & str){ - std::istringstream iss(str); - vector vec { std::istream_iterator{iss}, std::istream_iterator{} }; - return vec; -} - -bool checkPrefix(const string & str, char prefix) { - if (str.at(0) == prefix) - return true; - return false; -} - -// ==================================================================== -// operation on files - - -#ifdef __unix - -void cEnvUtils::GetTmpTextFile() { - // TODO make this name configurable (depending on project) - char filename[] = "/tmp/otshellutils_text.XXXXXX"; - fd = mkstemp(filename); - if (fd == -1) { - _erro("Can't create the file: " << filename); - return; - } - mFilename = filename; -} - -void cEnvUtils::CloseFile() { - close(fd); - unlink( mFilename.c_str() ); -} - -void cEnvUtils::OpenEditor() { - char* editor = std::getenv("OT_EDITOR"); //TODO Read editor from configuration file - if (editor == NULL) - editor = std::getenv("VISUAL"); - if (editor == NULL) - editor = std::getenv("EDITOR"); - - string command; - if (editor != NULL) - command = ToStr(editor) + " " + mFilename; - else - command = "/usr/bin/editor " + mFilename; - _dbg3("Opening editor with command: " << command); - if ( system( command.c_str() ) == -1 ) - _erro("Cannot execute system command: " << command); -} - -const string cEnvUtils::ReadFromTmpFile() { - std::ifstream ifs(mFilename); - string msg((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); - return msg; -} - -const string cEnvUtils::Compose() { - GetTmpTextFile(); - OpenEditor(); - string input = ReadFromTmpFile(); - CloseFile(); - return input; -} - -#endif - -const string cEnvUtils::ReadFromFile(const string path) { - std::ifstream ifs(path); - string msg((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); - return msg; -} - -void hintingToTxt(std::fstream & file, string command, vector &commands) { - if(file.good()) { - file< lightColors; - using namespace zkr; - lightColors.push_back(cc::fore::lightblue); - lightColors.push_back(cc::fore::lightred); - lightColors.push_back(cc::fore::lightmagenta); - lightColors.push_back(cc::fore::lightgreen); - lightColors.push_back(cc::fore::lightcyan); - lightColors.push_back(cc::fore::lightyellow); - lightColors.push_back(cc::fore::lightwhite); - - int sum=0; - - for (auto ch : hash) sum+=ch; - auto color = sum%(lightColors.size()-1); - - return lightColors.at( color ); -} - - -// ==================================================================== -// algorthms - - -} // namespace nUtil - - -} // namespace OT - -// global namespace - -const extern int _dbg_ignore = 0; // see description in .hpp - -std::string GetObjectName() { - //static std::string * name=nullptr; - //if (!name) name = new std::string("(global)"); - return ""; -} - -// ==================================================================== - -nOT::nUtils::cLogger gCurrentLogger; - diff --git a/contrib/otshell_utils/utils.hpp b/contrib/otshell_utils/utils.hpp deleted file mode 100644 index 98508b565..000000000 --- a/contrib/otshell_utils/utils.hpp +++ /dev/null @@ -1,532 +0,0 @@ -/// @file -/// @author rfree (current maintainer in monero.cc project) -/// @brief various general utils taken from (and relate to) otshell project, including loggiang/debug - -/* See other files here for the LICENCE that applies here. */ - -#include "ccolor.hpp" -#ifndef INCLUDE_OT_NEWCLI_UTILS -#define INCLUDE_OT_NEWCLI_UTILS - -#include "lib_common1.hpp" -#ifdef __unix - #include -#endif - -#if defined(_WIN32) - #include"windows_stream.h" -#endif - -#ifndef CFG_WITH_TERMCOLORS - //#error "You requested to turn off terminal colors (CFG_WITH_TERMCOLORS), however currently they are hardcoded (this option to turn them off is not yet implemented)." -#endif - -///Macros related to automatic deduction of class name etc; -#define MAKE_CLASS_NAME(NAME) private: static std::string GetObjectName() { return #NAME; } -#define MAKE_STRUCT_NAME(NAME) private: static std::string GetObjectName() { return #NAME; } public: - -// define this to debug the debug system itself: -// #define opt_debug_debug - -#ifdef opt_debug_debug - #define _dbg_dbg(X) do { std::cerr<<"_dbg_dbg: " << OT_CODE_STAMP << " {thread=" << boost::this_thread::get_id()<<"} " \ - << " {pid="< -std::string ToStr(const T & obj) { - std::ostringstream oss; - oss << obj; - return oss.str(); -} - -struct cNullstream : std::ostream { - cNullstream() : std::ios(0), std::ostream(0) {} -}; -extern cNullstream g_nullstream; // a stream that does nothing (eats/discards data) -// ========== debug ========== -// _dbg_ignore is moved to global namespace (on purpose) - -// TODO make _dbg_ignore thread-safe everywhere - -extern boost::recursive_mutex gLoggerGuard; // the mutex guarding logging/debugging code e.g. protecting streams, files, etc - -std::atomic & gLoggerGuardDepth_Get(); // getter for the global singleton of counter (it guarantees initializing it to 0). This counter shows the current recursion (re-entrant) level of debug macros. - -// TODO more debug of the debug system: -// detect lock() error e.g. recursive limit -// detect stream e.g. operator<< error - -#define _debug_level(LEVEL,VAR) do { if (_dbg_ignore< LEVEL) { \ - _dbg_dbg("WRITE DEBUG: LEVEL="< mutex_guard( nOT::nUtils::gLoggerGuard ); \ - part=1; \ - try { \ - ++nOT::nUtils::gLoggerGuardDepth_Get(); \ -/* int counter = nOT::nUtils::gLoggerGuardDepth_Get(); if (counter!=1) gCurrentLogger.write_stream(100,"")<<"DEBUG-ERROR: recursion, counter="< mutex_guard( nOT::nUtils::gLoggerGuard ); \ - part=1; \ - try { \ - ++nOT::nUtils::gLoggerGuardDepth_Get(); \ - std::ostringstream oss; \ - oss << nOT::nUtils::get_current_time() << ' ' << OT_CODE_STAMP << ' ' << VAR << gCurrentLogger.endline() << std::flush; \ - std::string as_string = oss.str(); \ - _dbg_dbg("START will write to log LEVEL="< mOutfile; - std::ostream * mStream; ///< pointing only! can point to our own mOutfile, or maye to global null stream - std::ostream * mStreamBrokenDebug; ///< pointing only! this is a pointer to some stream that should be used when normal debugging is broken eg std::cerr - bool mIsBroken; ///< is the debugging system broken (this should be set when internal problems occur and should cause fallback to std::cerr) - - std::map< std::string , std::ofstream * > mChannels; // the ofstream objects are owned by this class - - int mLevel; ///< current debug level - - std::ostream & SelectOutput(int level, const std::string & channel) noexcept; ///< returns a proper stream for this level and channel (always usable string) - void OpenNewChannel(const std::string & channel) noexcept; ///< tries to prepare this channel. does NOT guarantee to created mChannels[] entry! - void OpenNewChannel_(const std::string & channel); ///< internal function, will throw in case of problems - std::string GetLogBaseDir() const; - - std::map< boost::thread::id , int > mThread2Number; ///< change long thread IDs into a short nice number to show - int mThread2Number_Biggest; ///< current biggest value held there (biggest key) - works as growing-only counter basically - int Thread2Number(const boost::thread::id id); ///< convert the system's thread id into a nice short our id; make one if new thread - - std::map< t_anypid , int > mPid2Number; ///< change long proces PID into a short nice number to show - int mPid2Number_Biggest; ///< current biggest value held there (biggest key) - works as growing-only counter basically - int Pid2Number(const t_anypid id); ///< convert the system's PID id into a nice short our id; make one if new thread -}; - - - -// ==================================================================== -// vector debug - -template -std::string vectorToStr(const T & v) { - std::ostringstream oss; - for(auto rec: v) { - oss << rec <<","; - } - return oss.str(); -} - -template -void DisplayVector(std::ostream & out, const std::vector &v, const std::string &delim=" ") { - std::copy( v.begin(), v.end(), std::ostream_iterator(out, delim.c_str()) ); -} - -template -void EndlDisplayVector(std::ostream & out, const std::vector &v, const std::string &delim=" ") { - out << std::endl; - DisplayVector(out,v,delim); -} - -template -void DisplayVectorEndl(std::ostream & out, const std::vector &v, const std::string &delim=" ") { - DisplayVector(out,v,delim); - out << std::endl; -} - -template -void DbgDisplayVector(const std::vector &v, const std::string &delim=" ") { - std::cerr << "["; - std::copy( v.begin(), v.end(), std::ostream_iterator(std::cerr, delim.c_str()) ); - std::cerr << "]"; -} - -string stringToColor(const string &hash); -template -void DisplayMap(std::ostream & out, const std::map &m, const std::string &delim=" ") { - auto *no_color = zkr::cc::fore::console; - for(auto var : m) { - out << stringToColor(var.first) << var.first << delim << var.second << no_color << endl; - } - -} - -template -void EndlDisplayMap(std::ostream & out, const std::map &m, const std::string &delim=" ") { - out << endl; - for(auto var : m) { - out << var.first << delim << var.second << endl; - } -} - -template -void DbgDisplayMap(const std::map &m, const std::string &delim=" ") { - for(auto var : m) { - std::cerr << var.first << delim << var.second << endl; - } -} - - -template -void DbgDisplayVectorEndl(const std::vector &v, const std::string &delim=" ") { - DbgDisplayVector(v,delim); - std::cerr << std::endl; -} - -void DisplayStringEndl(std::ostream & out, const std::string text); - -bool CheckIfBegins(const std::string & beggining, const std::string & all); -bool CheckIfEnds (std::string const & ending, std::string const & all); -std::string SpaceFromEscape(const std::string &s); -std::string EscapeFromSpace(const std::string &s); -vector WordsThatMatch(const std::string & sofar, const vector & possib); -char GetLastChar(const std::string & str); -std::string GetLastCharIf(const std::string & str); // TODO unicode? -std::string EscapeString(const std::string &s); - - -template -std::string DbgVector(const std::vector &v, const std::string &delim="|") { - std::ostringstream oss; - oss << "["; - bool first=true; - for(auto vElement : v) { if (!first) oss<(oss, delim.c_str()) ); - return oss.str(); -} - -template -std::ostream & operator<<(std::ostream & os, const map< T, vector > & obj){ - os << "["; - for(auto const & elem : obj) { - os << " [" << elem.first << "=" << DbgVector(elem.second) << "] "; - } - os << "]"; - return os; -} - -template -std::string DbgMap(const map & map) { - std::ostringstream oss; - oss << map; - return oss.str(); -} - -// ==================================================================== -// assert - -// ASRT - assert. Name like ASSERT() was too long, and ASS() was just... no. -// Use it like this: ASRT( x>y ); with the semicolon at end, a clever trick forces this syntax :) -#define ASRT(x) do { if (!(x)) nOT::nUtils::Assert(false, OT_CODE_STAMP, #x); } while(0) - -void Assert(bool result, const std::string &stamp, const std::string &condition); - -// ==================================================================== -// advanced string - -const std::string GetMultiline(string endLine = "~"); -vector SplitString(const string & str); - -bool checkPrefix(const string & str, char prefix = '^'); - -// ==================================================================== -// nUse utils - -enum class eSubjectType {Account, Asset, User, Server, Unknown}; - -string SubjectType2String(const eSubjectType & type); -eSubjectType String2SubjectType(const string & type); - -// ==================================================================== -// operation on files - -/// @brief tools related to filesystem -/// @author rfree (maintainer) -class cFilesystemUtils { // if we do not want to use boost in given project (or we could optionally write boost here later) - public: - static bool CreateDirTree(const std::string & dir, bool only_below=false); - static char GetDirSeparatorSys(); /// < eg '/' or '\' - static char GetDirSeparatorInter(); /// < internal is '/' - static string FileInternalToSystem(const std::string &name); ///< converts from internal file name string to system file name string - static string FileSystemToInternal(const std::string &name); ///< converts from system file name string to internal file name string -}; - - -/// @brief utils to e.g. edit a file from console -/// @author rfree (maintainer) -class cEnvUtils { - int fd; - string mFilename; - - void GetTmpTextFile(); - void CloseFile(); - void OpenEditor(); - const string ReadFromTmpFile(); -public: - const string Compose(); - const string ReadFromFile(const string path); -}; -void hintingToTxt(std::fstream & file, string command, vector &commands); -void generateQuestions (std::fstream & file, string command); -void generateAnswers (std::fstream & file, string command, vector &completions); - -// ==================================================================== - -namespace nOper { // nOT::nUtils::nOper -// cool shortcut operators, like vector + vecotr operator working same as string (appending) -// isolated to namespace because it's unorthodox ide to implement this - -using namespace std; - -// TODO use && and move? -template -vector operator+(const vector &a, const vector &b) { - vector ret = a; - ret.insert( ret.end() , b.begin(), b.end() ); - return ret; -} - -template -vector operator+(const T &a, const vector &b) { - vector ret(1,a); - ret.insert( ret.end() , b.begin(), b.end() ); - return ret; -} - -template -vector operator+(const vector &a, const T &b) { - vector b_vector(1,a); - return a + b_vector; -} - -template -vector& operator+=(vector &a, const vector &b) { - a.insert( a.end() , b.begin(), b.end() ); - return a; -} - -// map -template -map operator+(const map &a, const map &b) { - map ret = a; - for (const auto & elem : b) { - ret.insert(elem); - } - return ret; -} - - -} // nOT::nUtils::nOper - -// ==================================================================== - -// ==================================================================== - -// Algorithms - -// ==================================================================== -// ==================================================================== - - -/** -@brief Special type that on creation will be initialized to have value INIT given as template argument. -Might be usefull e.g. to express in the declaration of class what will be the default value of member variable -See also http://www.boost.org/doc/libs/1_56_0/libs/utility/value_init.htm -Probably not needed when using boost in your project. -*/ -template -class value_init { - private: - T data; - public: - value_init(); - - T& operator=(const T& v) { data=v; return *this; } - operator T const &() const { return data; } - operator T&() { return data; } -}; - -template -value_init::value_init() : data(INIT) { } - -} // namespace nUtils - -} // namespace nOT - - -// global namespace -extern nOT::nUtils::cLogger gCurrentLogger; ///< The current main logger. Usually do not use it directly, instead use macros like _dbg1 etc - -std::string GetObjectName(); ///< Method to return name of current object; To use in debug; Can be shadowed in your classes. (Might be not used currently) - -const extern int _dbg_ignore; ///< the global _dbg_ignore, but local code (blocks, classes etc) you could shadow it in your code blocks, -// to override debug compile-time setting for given block/class, e.g. to disable debug in one of your methods or increase it there. -// Or to make it runtime by providing a class normal member and editing it in runtime - -#define OT_CODE_STAMP ( nOT::nUtils::ToStr("[") + nOT::nUtils::nDetail::DbgShortenCodeFileName(__FILE__) + nOT::nUtils::ToStr("+") + nOT::nUtils::ToStr(__LINE__) + nOT::nUtils::ToStr(" ") + (GetObjectName()) + nOT::nUtils::ToStr("::") + nOT::nUtils::ToStr(__FUNCTION__) + nOT::nUtils::ToStr("]")) - - - - -#endif - diff --git a/contrib/otshell_utils/windows_stream.cpp b/contrib/otshell_utils/windows_stream.cpp deleted file mode 100644 index 59d8b12a3..000000000 --- a/contrib/otshell_utils/windows_stream.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#if defined(_WIN32) -#include "windows_stream.h" -#include - -windows_stream::windows_stream(unsigned int pLevel) - : - mLevel(pLevel) -{ -} - -std::ostream& operator << (std::ostream &stream, windows_stream const& object) -{ - HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE); - - if (object.mLevel >= 100) - { - SetConsoleTextAttribute(h_stdout, FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_INTENSITY); - return stream; - } - if (object.mLevel >= 90) - { - SetConsoleTextAttribute(h_stdout, FOREGROUND_RED | FOREGROUND_INTENSITY | BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY); - return stream; - } - if (object.mLevel >= 80) - { - SetConsoleTextAttribute(h_stdout, BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY); - return stream; - } - if (object.mLevel >= 75) - { - SetConsoleTextAttribute(h_stdout, BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_INTENSITY); - return stream; - } - if (object.mLevel >= 70) - { - SetConsoleTextAttribute(h_stdout, FOREGROUND_GREEN | FOREGROUND_INTENSITY); - return stream; - } - if (object.mLevel >= 50) - { - SetConsoleTextAttribute(h_stdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY); - return stream; - } - if (object.mLevel >= 40) - { - SetConsoleTextAttribute(h_stdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY); - return stream; - } - if (object.mLevel >= 30) - { - SetConsoleTextAttribute(h_stdout, FOREGROUND_BLUE | FOREGROUND_INTENSITY); - return stream; - } - if (object.mLevel >= 20) - { - SetConsoleTextAttribute(h_stdout, FOREGROUND_BLUE); - return stream; - } - - return stream; -} - -#endif diff --git a/contrib/otshell_utils/windows_stream.h b/contrib/otshell_utils/windows_stream.h deleted file mode 100644 index 859e7ee50..000000000 --- a/contrib/otshell_utils/windows_stream.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef WINDOWS_STREAM_H -#define WINDOWS_STREAM_H - -#if defined(_WIN32) - -#include -#include - -class windows_stream -{ -public: - windows_stream(unsigned int pLevel); - friend std::ostream& operator<<(std::ostream &stream, windows_stream const& object); -private: - unsigned int mLevel = 0; -}; - -#endif // _WIN32 - -#endif // WINDOWS_STREAM_H -- cgit v1.2.3