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 }
else if(0==res)
time_t time
Definition: blockchain.cpp:93
Thread-safe Configuration repository.
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...
static void setDefaultConfigurations(const Configurations &configurations, bool reconfigureExistingLoggers=false)
Sets default configurations. This configuration is used for future (and conditionally for existing) l...
static void addFlag(LoggingFlag flag)
Adds logging flag used internally.
#define MERROR(x)
Definition: misc_log_ex.h:73
void mlog_set_log(const char *log)
Definition: mlog.cpp:288
#define MLOG_BASE_FORMAT
Definition: mlog.cpp:49
const char * name
@ CreateLoggerAutomatically
Creates logger automatically when not available.
@ HierarchicalLogging
Enables hierarchical logging.
@ StrictLogFileSizeCheck
Enables strict file rolling.
@ DisableApplicationAbortOnFatalLog
Allows to disable application abortion when logged using FATAL level.
@ ColoredTerminalOutput
Make terminal output colorful for supported terminals.
@ Filename
Determines log file (full path) to write logs to for correponding level and logger.
@ MaxLogFileSize
Specifies log file max size.
@ Format
Determines format of logging corresponding level and logger.
@ ToStandardOutput
Whether or not to write corresponding level and logger log to standard output. By standard output mea...
@ ToFile
Whether or not to write corresponding log to log file.
std::string to_string(t_connection_type type)
::std::string string
Definition: gtest-port.h:1097
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_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 & get_current_module_name()
Definition: string_tools.h:227
std::string & get_current_module_folder()
Definition: string_tools.h:233
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 }
static void setCategories(const char *categories, bool clear=true)
Sets categories as specified (on the fly)
std::string mlog_get_categories()
Definition: mlog.cpp:276
#define MLOG_LOG(x)
Definition: mlog.cpp:51
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 }
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 }
Here is the caller graph for this function: