Electroneum
mlog.cpp File Reference
#include <time.h>
#include <atomic>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#include "string_tools.h"
#include "misc_os_dependent.h"
#include "misc_log_ex.h"
Include dependency graph for mlog.cpp:

Go to the source code of this file.

Namespaces

 epee
 

Macros

#define _MLOG_H_
 
#define ELECTRONEUM_DEFAULT_LOG_CATEGORY   "logging"
 
#define MLOG_BASE_FORMAT   "%datetime{%Y-%M-%d %H:%m:%s.%g}\t%thread\t%level\t%logger\t%loc\t%msg"
 
#define MLOG_LOG(x)   CINFO(el::base::Writer,el::base::DispatchAction::FileOnlyLog,ELECTRONEUM_DEFAULT_LOG_CATEGORY) << x
 

Functions

std::string mlog_get_default_log_path (const char *default_filename)
 
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)
 
void mlog_set_categories (const char *categories)
 
std::string mlog_get_categories ()
 
void mlog_set_log_level (int level)
 
void mlog_set_log (const char *log)
 
bool epee::is_stdout_a_tty ()
 
void epee::set_console_color (int color, bool bright)
 
void epee::reset_console_color ()
 

Macro Definition Documentation

◆ _MLOG_H_

#define _MLOG_H_

Definition at line 29 of file mlog.cpp.

◆ ELECTRONEUM_DEFAULT_LOG_CATEGORY

#define ELECTRONEUM_DEFAULT_LOG_CATEGORY   "logging"

Definition at line 47 of file mlog.cpp.

◆ MLOG_BASE_FORMAT

#define MLOG_BASE_FORMAT   "%datetime{%Y-%M-%d %H:%m:%s.%g}\t%thread\t%level\t%logger\t%loc\t%msg"

Definition at line 49 of file mlog.cpp.

◆ MLOG_LOG

Definition at line 51 of file mlog.cpp.

Function Documentation

◆ mlog_configure()

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 
)

Definition at line 148 of file mlog.cpp.

149 {
153  const char *log_format = getenv("ELECTRONEUM_LOG_FORMAT");
154  if (!log_format)
155  log_format = MLOG_BASE_FORMAT;
157  c.setGlobally(el::ConfigurationType::ToStandardOutput, console ? "true" : "false");
160 
166  el::Helpers::installPreRollOutCallback([filename_base, max_log_files](const char *name, size_t){
167  std::string rname = generate_log_filename(filename_base.c_str());
168  int ret = rename(name, rname.c_str());
169  if (ret < 0)
170  {
171  // can't log a failure, but don't do the file removal below
172  return;
173  }
174  if (max_log_files != 0)
175  {
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)
181  {
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)
184  {
185  found_files.push_back(iter->path());
186  }
187  }
188  if (found_files.size() >= max_log_files)
189  {
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);
193  if (ec)
194  {
195  MERROR("Failed to get timestamp from " << a << ": " << ec);
196  ta = std::time(nullptr);
197  }
198  std::time_t tb = boost::filesystem::last_write_time(boost::filesystem::path(b), ec);
199  if (ec)
200  {
201  MERROR("Failed to get timestamp from " << b << ": " << ec);
202  tb = std::time(nullptr);
203  }
204  static_assert(std::is_integral<time_t>(), "bad time_t");
205  return ta < tb;
206  });
207  for (size_t i = 0; i <= found_files.size() - max_log_files; ++i)
208  {
209  try
210  {
211  boost::system::error_code ec;
212  boost::filesystem::remove(found_files[i], ec);
213  if (ec)
214  {
215  MERROR("Failed to remove " << found_files[i] << ": " << ec);
216  }
217  }
218  catch (const std::exception &e)
219  {
220  MERROR("Failed to remove " << found_files[i] << ": " << e.what());
221  }
222  }
223  }
224  }
225  });
226  mlog_set_common_prefix();
227  const char *electroneum_log = getenv("ELECTRONEUM_LOGS");
228  if (!electroneum_log)
229  {
230  electroneum_log = get_default_categories(0);
231  }
232  mlog_set_log(electroneum_log);
233 #ifdef WIN32
234  EnableVTMode();
235 #endif
236 }
#define MERROR(x)
Definition: misc_log_ex.h:73
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)
Definition: mlog.cpp:288
::std::string string
Definition: gtest-port.h:1097
static void addFlag(LoggingFlag flag)
Adds logging flag used internally.
#define MLOG_BASE_FORMAT
Definition: mlog.cpp:49
const char * name
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 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...
time_t time
Definition: blockchain.cpp:93
Make terminal output colorful for supported terminals.
Enables strict file rolling.
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1124
Whether or not to write corresponding log to log file.
std::string to_string(t_connection_type type)
Whether or not to write corresponding level and logger log to standard output. By standard output mea...
Enables hierarchical logging.
Specifies log file max size.
Allows to disable application abortion when logged using FATAL level.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mlog_get_categories()

std::string mlog_get_categories ( )

Definition at line 276 of file mlog.cpp.

277 {
279 }
static std::string getCategories()
Gets current categories.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mlog_get_default_log_path()

std::string mlog_get_default_log_path ( const char *  default_filename)

Definition at line 72 of file mlog.cpp.

73 {
76  std::string default_log_file = process_name;
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";
82  else
83  default_log_file = default_filename;
84 
85  return (boost::filesystem::path(default_log_folder) / boost::filesystem::path(default_log_file)).string();
86 }
::std::string string
Definition: gtest-port.h:1097
std::string & get_current_module_name()
Definition: string_tools.h:227
std::string & get_current_module_folder()
Definition: string_tools.h:233
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1124
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mlog_set_categories()

void mlog_set_categories ( const char *  categories)

Definition at line 238 of file mlog.cpp.

239 {
240  std::string new_categories;
241  if (*categories)
242  {
243  if (*categories == '+')
244  {
245  ++categories;
246  new_categories = mlog_get_categories();
247  if (*categories)
248  {
249  if (!new_categories.empty())
250  new_categories += ",";
251  new_categories += categories;
252  }
253  }
254  else if (*categories == '-')
255  {
256  ++categories;
257  new_categories = mlog_get_categories();
258  std::vector<std::string> single_categories;
259  boost::split(single_categories, categories, boost::is_any_of(","), boost::token_compress_on);
260  for (const std::string &s: single_categories)
261  {
262  size_t pos = new_categories.find(s);
263  if (pos != std::string::npos)
264  new_categories = new_categories.erase(pos, s.size());
265  }
266  }
267  else
268  {
269  new_categories = categories;
270  }
271  }
272  el::Loggers::setCategories(new_categories.c_str(), true);
273  MLOG_LOG("New log categories: " << el::Loggers::getCategories());
274 }
::std::string string
Definition: gtest-port.h:1097
std::string mlog_get_categories()
Definition: mlog.cpp:276
#define MLOG_LOG(x)
Definition: mlog.cpp:51
static void setCategories(const char *categories, bool clear=true)
Sets categories as specified (on the fly)
static std::string getCategories()
Gets current categories.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mlog_set_log()

void mlog_set_log ( const char *  log)

Definition at line 288 of file mlog.cpp.

289 {
290  long level;
291  char *ptr = NULL;
292 
293  if (!*log)
294  {
295  mlog_set_categories(log);
296  return;
297  }
298  level = strtol(log, &ptr, 10);
299  if (ptr && *ptr)
300  {
301  // we can have a default level, eg, 2,foo:ERROR
302  if (*ptr == ',') {
303  std::string new_categories = std::string(get_default_categories(level)) + ptr;
304  mlog_set_categories(new_categories.c_str());
305  }
306  else {
307  mlog_set_categories(log);
308  }
309  }
310  else if (level >= 0 && level <= 4)
311  {
312  mlog_set_log_level(level);
313  }
314  else
315  {
316  MERROR("Invalid numerical log level: " << log);
317  }
318 }
#define MERROR(x)
Definition: misc_log_ex.h:73
::std::string string
Definition: gtest-port.h:1097
void mlog_set_log_level(int level)
Definition: mlog.cpp:282
void mlog_set_categories(const char *categories)
Definition: mlog.cpp:238
Here is the caller graph for this function:

◆ mlog_set_log_level()

void mlog_set_log_level ( int  level)

Definition at line 282 of file mlog.cpp.

283 {
284  const char *categories = get_default_categories(level);
285  mlog_set_categories(categories);
286 }
void mlog_set_categories(const char *categories)
Definition: mlog.cpp:238
Here is the caller graph for this function: