33 #ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING 34 #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 40 #include <boost/filesystem.hpp> 41 #include <boost/algorithm/string.hpp> 46 #undef ELECTRONEUM_DEFAULT_LOG_CATEGORY 47 #define ELECTRONEUM_DEFAULT_LOG_CATEGORY "logging" 49 #define MLOG_BASE_FORMAT "%datetime{%Y-%M-%d %H:%m:%s.%g}\t%thread\t%level\t%logger\t%loc\t%msg" 51 #define MLOG_LOG(x) CINFO(el::base::Writer,el::base::DispatchAction::FileOnlyLog,ELECTRONEUM_DEFAULT_LOG_CATEGORY) << x 55 static std::string generate_log_filename(
const char *base)
58 static unsigned int fallback_counter = 0;
61 time_t now =
time(NULL);
63 snprintf(tmp,
sizeof(tmp),
"part-%u", ++fallback_counter);
65 strftime(tmp,
sizeof(tmp),
"%Y-%m-%d-%H-%M-%S", &tm);
66 tmp[
sizeof(tmp) - 1] = 0;
77 std::string::size_type
a = default_log_file.rfind(
'.');
78 if (
a != std::string::npos )
79 default_log_file.erase(
a, default_log_file.size());
80 if ( ! default_log_file.empty() )
81 default_log_file +=
".log";
83 default_log_file = default_filename;
85 return (boost::filesystem::path(default_log_folder) / boost::filesystem::path(default_log_file)).
string();
88 static void mlog_set_common_prefix()
90 static const char *
const expected_filename =
"contrib/epee/src/mlog.cpp";
91 const char *path = __FILE__, *expected_ptr = strstr(path, expected_filename);
97 static const char *get_default_categories(
int level)
99 const char *categories =
"";
103 categories =
"*:WARNING,net:FATAL,net.http:FATAL,net.ssl:FATAL,net.p2p:FATAL,net.cn:FATAL,global:INFO,verify:FATAL,serialization:FATAL,stacktrace:INFO,logging:INFO,msgwriter:INFO";
106 categories =
"*:INFO,global:INFO,stacktrace:INFO,logging:INFO,msgwriter:INFO,perf.*:DEBUG";
109 categories =
"*:DEBUG";
112 categories =
"*:TRACE";
115 categories =
"*:TRACE";
127 HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
128 if (hOut == INVALID_HANDLE_VALUE)
134 if (!GetConsoleMode(hOut, &dwMode))
139 dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
140 if (!SetConsoleMode(hOut, dwMode))
148 void mlog_configure(
const std::string &filename_base,
bool console,
const std::size_t max_log_file_size,
const std::size_t max_log_files)
153 const char *log_format = getenv(
"ELECTRONEUM_LOG_FORMAT");
167 std::string rname = generate_log_filename(filename_base.c_str());
168 int ret = rename(
name, rname.c_str());
174 if (max_log_files != 0)
176 std::vector<boost::filesystem::path> found_files;
177 const boost::filesystem::directory_iterator end_itr;
178 const boost::filesystem::path filename_base_path(filename_base);
179 const boost::filesystem::path parent_path = filename_base_path.has_parent_path() ? filename_base_path.parent_path() :
".";
180 for (boost::filesystem::directory_iterator iter(parent_path); iter != end_itr; ++iter)
182 const std::string filename = iter->path().string();
183 if (filename.size() >= filename_base.size() && std::memcmp(filename.data(), filename_base.data(), filename_base.size()) == 0)
185 found_files.push_back(iter->path());
188 if (found_files.size() >= max_log_files)
190 std::sort(found_files.begin(), found_files.end(), [](
const boost::filesystem::path &
a,
const boost::filesystem::path &b) {
191 boost::system::error_code ec;
192 std::time_t ta = boost::filesystem::last_write_time(boost::filesystem::path(
a), ec);
195 MERROR(
"Failed to get timestamp from " <<
a <<
": " << ec);
198 std::time_t tb = boost::filesystem::last_write_time(boost::filesystem::path(b), ec);
201 MERROR(
"Failed to get timestamp from " << b <<
": " << ec);
204 static_assert(std::is_integral<time_t>(),
"bad time_t");
207 for (
size_t i = 0; i <= found_files.size() - max_log_files; ++i)
211 boost::system::error_code ec;
212 boost::filesystem::remove(found_files[i], ec);
215 MERROR(
"Failed to remove " << found_files[i] <<
": " << ec);
218 catch (
const std::exception &e)
220 MERROR(
"Failed to remove " << found_files[i] <<
": " << e.what());
226 mlog_set_common_prefix();
227 const char *electroneum_log = getenv(
"ELECTRONEUM_LOGS");
228 if (!electroneum_log)
230 electroneum_log = get_default_categories(0);
243 if (*categories ==
'+')
249 if (!new_categories.empty())
250 new_categories +=
",";
251 new_categories += categories;
254 else if (*categories ==
'-')
258 std::vector<std::string> single_categories;
259 boost::split(single_categories, categories, boost::is_any_of(
","), boost::token_compress_on);
262 size_t pos = new_categories.find(s);
263 if (pos != std::string::npos)
264 new_categories = new_categories.erase(pos, s.size());
269 new_categories = categories;
284 const char *categories = get_default_categories(level);
298 level = strtol(log, &ptr, 10);
310 else if (level >= 0 && level <= 4)
316 MERROR(
"Invalid numerical log level: " << log);
325 static std::atomic<bool> initialized(
false);
326 static std::atomic<bool> is_a_tty(
false);
328 if (!initialized.load(std::memory_order_acquire))
331 is_a_tty.store(0 != _isatty(_fileno(stdout)), std::memory_order_relaxed);
333 is_a_tty.store(0 != isatty(fileno(stdout)), std::memory_order_relaxed);
335 initialized.store(
true, std::memory_order_release);
338 return is_a_tty.load(std::memory_order_relaxed);
351 HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
352 SetConsoleTextAttribute(h_stdout, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE| (bright ? FOREGROUND_INTENSITY:0));
355 std::cout <<
"\033[1;37m";
357 std::cout <<
"\033[0m";
364 HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
365 SetConsoleTextAttribute(h_stdout, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | (bright ? FOREGROUND_INTENSITY:0));
368 std::cout <<
"\033[1;37m";
370 std::cout <<
"\033[0;37m";
377 HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
378 SetConsoleTextAttribute(h_stdout, FOREGROUND_RED | (bright ? FOREGROUND_INTENSITY:0));
381 std::cout <<
"\033[1;31m";
383 std::cout <<
"\033[0;31m";
390 HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
391 SetConsoleTextAttribute(h_stdout, FOREGROUND_GREEN | (bright ? FOREGROUND_INTENSITY:0));
394 std::cout <<
"\033[1;32m";
396 std::cout <<
"\033[0;32m";
404 HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
405 SetConsoleTextAttribute(h_stdout, FOREGROUND_BLUE | FOREGROUND_INTENSITY);
408 std::cout <<
"\033[1;34m";
410 std::cout <<
"\033[0;34m";
418 HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
419 SetConsoleTextAttribute(h_stdout, FOREGROUND_GREEN | FOREGROUND_BLUE | (bright ? FOREGROUND_INTENSITY:0));
422 std::cout <<
"\033[1;36m";
424 std::cout <<
"\033[0;36m";
432 HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
433 SetConsoleTextAttribute(h_stdout, FOREGROUND_BLUE | FOREGROUND_RED | (bright ? FOREGROUND_INTENSITY:0));
436 std::cout <<
"\033[1;35m";
438 std::cout <<
"\033[0;35m";
446 HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
447 SetConsoleTextAttribute(h_stdout, FOREGROUND_RED | FOREGROUND_GREEN | (bright ? FOREGROUND_INTENSITY:0));
450 std::cout <<
"\033[1;33m";
452 std::cout <<
"\033[0;33m";
465 HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
466 SetConsoleTextAttribute(h_stdout, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
468 std::cout <<
"\033[0m";
static void setDefaultConfigurations(const Configurations &configurations, bool reconfigureExistingLoggers=false)
Sets default configurations. This configuration is used for future (and conditionally for existing) l...
Creates logger automatically when not available.
void mlog_set_log(const char *log)
static void addFlag(LoggingFlag flag)
Adds logging flag used internally.
std::string mlog_get_categories()
Thread-safe Configuration repository.
Determines log file (full path) to write logs to for correponding level and logger.
Determines format of logging corresponding level and logger.
void reset_console_color()
void setGlobally(ConfigurationType configurationType, const std::string &value)
Sets configuration for all levels.
static void installPreRollOutCallback(const PreRollOutCallback &callback)
Installs pre rollout callback, this callback is triggered when log file is about to be rolled out (ca...
void mlog_set_log_level(int level)
bool get_gmt_time(time_t t, struct tm &tm)
static void setCategories(const char *categories, bool clear=true)
Sets categories as specified (on the fly)
Make terminal output colorful for supported terminals.
Enables strict file rolling.
void set_console_color(int color, bool bright)
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
static std::string getCategories()
Gets current categories.
Whether or not to write corresponding log to log file.
std::string to_string(t_connection_type type)
std::string mlog_get_default_log_path(const char *default_filename)
void mlog_set_categories(const char *categories)
static void setFilenameCommonPrefix(const std::string &prefix)
Sets filename common prefix.
Whether or not to write corresponding level and logger log to standard output. By standard output mea...
void mlog_configure(const std::string &filename_base, bool console, const std::size_t max_log_file_size, const std::size_t max_log_files)
Enables hierarchical logging.
Specifies log file max size.
Allows to disable application abortion when logged using FATAL level.