SWC-DB  v0.5.12 C++ documentations
SWC-DB© (Super Wide Column Database) - High Performance Scalable Database (https://github.com/kashirin-alex/swc-db)
Logger.cc
Go to the documentation of this file.
1 /*
2  * SWC-DB© Copyright since 2019 Alex Kashirin <kashirin.alex@gmail.com>
3  * License details at <https://github.com/kashirin-alex/swc-db/#license>
4  */
5 
6 
7 #include "swcdb/core/Error.h"
8 #include "swcdb/core/Logger.h"
9 #include <stdarg.h>
10 
11 
12 namespace SWC { namespace Core {
13 
16 
17 
18 namespace { //local namespace
19 
20 static SWC_CAN_INLINE
21 const char* get_name(uint8_t priority) noexcept {
22  switch(priority) {
23  case LOG_FATAL: return "FATAL";
24  case LOG_ALERT: return "ALERT";
25  case LOG_CRIT: return "CRIT";
26  case LOG_ERROR: return "ERROR";
27  case LOG_WARN: return "WARN";
28  case LOG_NOTICE: return "NOTICE";
29  case LOG_INFO: return "INFO";
30  case LOG_DEBUG: return "DEBUG";
31  default: return "NOTSET";
32  }
33 }
34 
35 }
36 
37 
38 std::string LogWriter::repr(uint8_t priority) {
39  return priority <= LOG_DEBUG ?
40  get_name(priority)
41  : "undefined logging level: " +std::to_string(priority);
42 }
43 
44 uint8_t LogWriter::from_string(const std::string& loglevel) noexcept {
45  if(Condition::str_case_eq(loglevel.c_str(), "info", loglevel.length()))
46  return LOG_INFO;
47  if(Condition::str_case_eq(loglevel.c_str(), "debug", loglevel.length()))
48  return LOG_DEBUG;
49  if(Condition::str_case_eq(loglevel.c_str(), "notice", loglevel.length()))
50  return LOG_NOTICE;
51  if(Condition::str_case_eq(loglevel.c_str(), "warn", loglevel.length()))
52  return LOG_WARN;
53  if(Condition::str_case_eq(loglevel.c_str(), "error", loglevel.length()))
54  return LOG_ERROR;
55  if(Condition::str_case_eq(loglevel.c_str(), "crit", loglevel.length()))
56  return LOG_CRIT;
57  if(Condition::str_case_eq(loglevel.c_str(), "alert", loglevel.length()))
58  return LOG_ALERT;
59  if(Condition::str_case_eq(loglevel.c_str(), "fatal", loglevel.length()))
60  return LOG_FATAL;
61  return -1;
62 }
63 
64 SWC_SHOULD_NOT_INLINE
66  : mutex(), m_name(), m_logs_path(),
67  m_file_out(stdout), //m_file_err(stderr),
68  m_priority(LOG_INFO), m_show_line_numbers(true),
69  m_daemon(false), m_next_time(0) {
70 }
71 LogWriter::~LogWriter() noexcept { }
72 
73 SWC_SHOULD_NOT_INLINE
74 void LogWriter::initialize(const std::string& name) {
76  m_name = name;
77 }
78 
79 SWC_SHOULD_NOT_INLINE
80 void LogWriter::daemon(const std::string& logs_path) {
81  errno = 0;
82 
84  m_logs_path = logs_path;
85  if(m_logs_path.back() != '/')
86  m_logs_path.append("/");
87  m_daemon = true;
88 
89  _renew_files(::time(nullptr));
90 
91  if(errno)
92  throw std::runtime_error(
93  "SWC::Core::LogWriter::initialize err="
94  + std::to_string(errno)+"("+Error::get_text(errno)+")"
95  );
96  std::fclose(stderr);
97 }
98 
99 
100 SWC_SHOULD_NOT_INLINE
101 void LogWriter::_time_and_level(uint8_t priority) {
102  auto t = ::time(nullptr);
103  if(m_daemon && m_next_time < t)
104  _renew_files(t);
105  t -= (t/86400) * 86400; // time since start of a day
106  SWC_LOG_OSTREAM << t << ' ' << get_name(priority) << ':' << ' ';
107 }
108 
109 
110 #if defined(__MINGW64__) || defined(_WIN32)
111  #define SWC_MKDIR(_path, _perms) ::mkdir(_path)
112 #else
113  #define SWC_MKDIR(_path, _perms) ::mkdir(_path, _perms)
114 #endif
115 
116 
117 void LogWriter::_renew_files(time_t secs) {
118  errno = 0;
119  m_next_time = (secs/86400)*86400;;
120  auto ltm = localtime(&m_next_time);
121  m_next_time += 86400;
122 
123  std::string filepath;
124  filepath.reserve(m_logs_path.size() + m_name.size() + 16);
125  filepath.append(m_logs_path);
126 
127  SWC_MKDIR(filepath.c_str(), 0755);
128  filepath.append(std::to_string(1900+ltm->tm_year));
129  SWC_MKDIR(filepath.c_str(), 0755);
130  filepath.append("/");
131  filepath.append(std::to_string(1+ltm->tm_mon));
132  SWC_MKDIR(filepath.c_str(), 0755);
133  filepath.append("/");
134  filepath.append(std::to_string(ltm->tm_mday));
135  SWC_MKDIR(filepath.c_str(), 0755);
136  if(errno == EEXIST)
137  errno = 0;
138  filepath.append("/");
139  filepath.append(m_name);
140  filepath.append(".log");
141 
142  if(!errno) {
143  SWC_LOG_OSTREAM << "Changing Standard Output File to="
144  << filepath << std::endl;
145  m_file_out = std::freopen(filepath.c_str(), "w", m_file_out);
146 
147  std::cerr.rdbuf(std::cout.rdbuf());
148  //std::string filepath_err(filepath+".err");
149  //std::cerr << "Changing Error Output File to=" << filepath_err << "\n";
150  //m_file_err = std::freopen(filepath_err.c_str(), "w", m_file_err);
151  }
152  /* else { fallback
153  rdbuf
154  m_file_out = std::freopen('0', "w", m_file_out);
155  m_file_err = std::freopen('1', "w", m_file_err);
156  ::fdopen(0, "wt");
157  }*/
158 }
159 #undef SWC_MKDIR
160 
161 SWC_SHOULD_NOT_INLINE
162 void LogWriter::log(uint8_t priority, const char* fmt, ...) noexcept {
163  try {
164  va_list ap;
165  va_start(ap, fmt);
166  try {
168  _time_and_level(priority);
169  vprintf(fmt, ap);
170  SWC_LOG_OSTREAM << std::endl;
171  } catch(...) { }
172  va_end(ap);
173  } catch(...) { }
174 }
175 
176 SWC_SHOULD_NOT_INLINE
177 void LogWriter::log(uint8_t priority, const char* filen, int fline,
178  const char* fmt, ...) noexcept {
179  try {
180  va_list ap;
181  va_start(ap, fmt);
182  try {
184  _time_and_level(priority);
185  if(show_line_numbers())
186  SWC_LOG_OSTREAM << '(' << filen << ':' << fline << ')' << '"';
187  vprintf(fmt, ap);
188  SWC_LOG_OSTREAM << std::endl;
189  } catch(...) { }
190  va_end(ap);
191  } catch(...) { }
192 }
193 
194 SWC_SHOULD_NOT_INLINE
195 void LogWriter::_print_prefix(uint8_t priority, const char* filen, int fline) {
196  _time_and_level(priority);
197  if(show_line_numbers())
198  SWC_LOG_OSTREAM << "(" << filen << ':' << fline << ") ";
199 }
200 
201 }}
SWC::Core::logger
LogWriter logger
Definition: Logger.cc:15
Logger.h
SWC_LOG_OSTREAM
#define SWC_LOG_OSTREAM
Definition: Logger.h:44
SWC::Core::LogWriter::daemon
void daemon(const std::string &logs_path)
Definition: Logger.cc:80
SWC::Core::LogWriter::name
constexpr SWC_CAN_INLINE const std::string & name() const noexcept
Definition: Logger.h:80
SWC::LOG_FATAL
@ LOG_FATAL
Definition: Logger.h:29
SWC::Core::LogWriter::m_logs_path
std::string m_logs_path
Definition: Logger.h:142
SWC::Error::get_text
const char * get_text(const int err) noexcept
Definition: Error.cc:173
SWC::Core::LogWriter
Definition: Logger.h:50
SWC::LOG_ALERT
@ LOG_ALERT
Definition: Logger.h:30
SWC::LOG_INFO
@ LOG_INFO
Definition: Logger.h:35
SWC::Core::LogWriter::m_name
std::string m_name
Definition: Logger.h:141
SWC::Core::MutexSptd::scope
Definition: MutexSptd.h:96
SWC::Core::LogWriter::m_next_time
time_t m_next_time
Definition: Logger.h:148
SWC::Core::LogWriter::LogWriter
LogWriter() noexcept
Definition: Logger.cc:65
SWC::Core::LogWriter::initialize
void initialize(const std::string &name)
Definition: Logger.cc:74
SWC::Core::LogWriter::m_file_out
FILE * m_file_out
Definition: Logger.h:143
SWC_CAN_INLINE
#define SWC_CAN_INLINE
Definition: Compat.h:102
SWC::LOG_DEBUG
@ LOG_DEBUG
Definition: Logger.h:36
SWC
The SWC-DB C++ namespace 'SWC'.
Definition: main.cc:12
Error.h
SWC::Core::LogWriter::_print_prefix
void _print_prefix(uint8_t priority, const char *filen, int fline)
Definition: Logger.cc:195
SWC::Core::LogWriter::m_daemon
bool m_daemon
Definition: Logger.h:147
SWC::LOG_ERROR
@ LOG_ERROR
Definition: Logger.h:32
SWC::Core::LogWriter::log
void log(uint8_t priority, const char *fmt,...) noexcept __attribute__((format(printf
Definition: Logger.cc:162
SWC::Core::LogWriter::from_string
static uint8_t SWC_PURE_FUNC from_string(const std::string &loglevel) noexcept
Definition: Logger.cc:44
SWC::LOG_CRIT
@ LOG_CRIT
Definition: Logger.h:31
SWC::Core::LogWriter::show_line_numbers
constexpr SWC_CAN_INLINE bool show_line_numbers() const noexcept
Definition: Logger.h:100
SWC::Core::LogWriter::_renew_files
void _renew_files(time_t secs)
Definition: Logger.cc:117
SWC::Core::LogWriter::~LogWriter
~LogWriter() noexcept
Definition: Logger.cc:71
SWC::LOG_NOTICE
@ LOG_NOTICE
Definition: Logger.h:34
SWC_MKDIR
#define SWC_MKDIR(_path, _perms)
Definition: Logger.cc:113
SWC::Core::LogWriter::mutex
MutexSptd mutex
Definition: Logger.h:59
SWC::Common::Files::Schema::filepath
std::string filepath(cid_t cid)
Definition: Schema.h:34
SWC::LOG_WARN
@ LOG_WARN
Definition: Logger.h:33
SWC::Core::LogWriter::_time_and_level
void _time_and_level(uint8_t priority)
Definition: Logger.cc:101
SWC::Core::to_string
SWC_CAN_INLINE std::string to_string(const BitFieldInt< T, SZ > &v)
Definition: BitFieldInt.h:263
SWC::Condition::str_case_eq
bool str_case_eq(const char *s1, const char *s2, size_t count) noexcept SWC_ATTRIBS((SWC_ATTRIB_O3))
Definition: Comparators_basic.h:257
SWC::Core::LogWriter::repr
static std::string repr(uint8_t priority)
Definition: Logger.cc:38