MADARA  3.4.1
Logger.cpp
Go to the documentation of this file.
1 #include "Logger.h"
2 #include <stdio.h>
3 #include <stdarg.h>
4 #include <time.h>
6 #include <boost/lexical_cast.hpp>
7 #include <iomanip>
8 
9 #if 0
10 thread_local int madara::logger::Logger::thread_level_(
12 
13 thread_local std::string madara::logger::Logger::thread_name_("");
14 
15 thread_local double madara::logger::Logger::thread_hertz_(
17 #endif
18 
19 madara::logger::Logger::Logger(bool log_to_terminal)
20  : mutex_(),
21  level_(LOG_ERROR),
22  term_added_(log_to_terminal),
23  syslog_added_(false),
24  tag_("madara"),
25  timestamp_format_("")
26 {
27  if (log_to_terminal)
28  {
29  add_term();
30  }
31 }
32 
34 {
35  clear();
36 }
37 
39  const std::string in_str, const std::string ts_str)
40 {
41  std::string ret_str(in_str);
42  ret_str.replace(ret_str.find(ts_str), ts_str.length(), ts_str);
43  return ret_str;
44 }
45 
47  const std::string& buf, const std::string& ts_str)
48 {
49  bool done = false;
50  std::size_t found = 0;
51  std::size_t offset = 0;
52  std::string ret_string = buf;
53  const int MGT_DIGIT_PRECISION = 6;
54 
55  while (!done)
56  {
68  found = ret_string.find(ts_str.c_str(), found + offset, ts_str.length());
69  if (found == std::string::npos)
70  {
71  done = true;
72  continue;
73  }
74 
75  offset = 1;
76  if (ts_str == MADARA_GET_TIME_MGT_)
77  {
80  double mgt_time = madara::utility::get_time() / (double)1000000000;
81 
83  std::stringstream mgt_str;
84 
87  mgt_str << std::setprecision(MGT_DIGIT_PRECISION) << std::fixed
88  << mgt_time;
89  ret_string.replace(
90  ret_string.find(ts_str), ts_str.length(), mgt_str.str());
91  continue;
92  }
93  else if (ts_str == MADARA_THREAD_NAME_)
94  {
95  // insert thread name into message buffer copy
96 #if 0
97  ret_string.replace(ret_string.find(ts_str), ts_str.length(),
98  madara::logger::Logger::get_thread_name());
99 #else
100  ret_string.replace(
101  ret_string.find(ts_str), ts_str.length(), "<DISABLED>");
102 #endif
103  continue;
104  }
105  else if (ts_str == MADARA_THREAD_HERTZ_)
106  {
107  // insert thread hertz value into message buffer copy
108 #if 0
109  std::string hzstr = boost::lexical_cast<std::string>(
110  madara::logger::Logger::get_thread_hertz());
111  ret_string.replace(ret_string.find(ts_str), ts_str.length(), hzstr);
112 #else
113  ret_string.replace(
114  ret_string.find(ts_str), ts_str.length(), "<DISABLED>");
115 #endif
116  continue;
117  }
118  }
119 
120  return ret_string;
121 }
122 
123 void madara::logger::Logger::log(int level, const char* message, ...)
124 {
126  level <= get_thread_level()) ||
127  level <= level_)
128  {
129  va_list argptr;
130  va_start(argptr, message);
131 
134  char buffer[10240];
135  char* begin = (char*)buffer;
136  size_t remaining_buffer = sizeof(buffer);
137 
138  if (this->timestamp_format_.size() > 0)
139  {
147  std::string mad_str = message;
148  mad_str = search_and_insert_custom_tstamp(mad_str, MADARA_GET_TIME_MGT_);
149  mad_str = search_and_insert_custom_tstamp(mad_str, MADARA_THREAD_NAME_);
150  mad_str = search_and_insert_custom_tstamp(mad_str, MADARA_THREAD_HERTZ_);
151 
152  char custom_buffer[10240];
153  std::strcpy(custom_buffer, mad_str.c_str());
154 
162  time_t raw_time;
163  struct tm* time_info;
164 
165  time(&raw_time);
166  time_info = localtime(&raw_time);
167 
168  mad_str = search_and_insert_custom_tstamp(
169  timestamp_format_, MADARA_GET_TIME_MGT_);
170  mad_str = search_and_insert_custom_tstamp(mad_str, MADARA_THREAD_NAME_);
171  mad_str = search_and_insert_custom_tstamp(mad_str, MADARA_THREAD_HERTZ_);
172 
177  size_t chars_written =
178  strftime(begin, remaining_buffer, mad_str.c_str(), time_info);
179 
180  remaining_buffer -= chars_written;
181  begin += chars_written;
182  vsnprintf(begin, remaining_buffer, custom_buffer, argptr);
183  }
184  else
185  {
186  vsnprintf(begin, remaining_buffer, message, argptr);
187  }
188 
189  va_end(argptr);
190 
191  MADARA_GUARD_TYPE guard(mutex_);
192 
193 #ifdef _MADARA_ANDROID_
194  if (this->term_added_ || this->syslog_added_)
195  {
196  if (level == LOG_ERROR)
197  {
198  __android_log_write(ANDROID_LOG_ERROR, tag_.c_str(), buffer);
199  }
200  else if (level == LOG_WARNING)
201  {
202  __android_log_write(ANDROID_LOG_WARN, tag_.c_str(), buffer);
203  }
204  else
205  {
206  __android_log_write(ANDROID_LOG_INFO, tag_.c_str(), buffer);
207  }
208  }
209 #else // end if _USING_ANDROID_
210  if (this->term_added_ || this->syslog_added_)
211  {
212  fprintf(stderr, "%s", buffer);
213  }
214 #endif
215 
216  int file_num = 0;
217  for (FileVectors::iterator i = files_.begin(); i != files_.end(); ++i)
218  {
219  if (level >= LOG_DETAILED)
220  {
221  fprintf(stderr, "Logger::log: writing to file num %d", file_num);
222 
223  // file_num is only important if logging is detailed
224  ++file_num;
225  }
226  fprintf(*i, "%s", buffer);
227  }
228  }
229 }
static int get_thread_level(void)
Fetches thread local storage value for thread level.
Definition: Logger.inl:85
void add_term(void)
Adds terminal to logger outputs.
Definition: Logger.inl:104
~Logger()
Destructor.
Definition: Logger.cpp:33
Logger(bool log_to_stderr=true)
Constructor.
Definition: Logger.cpp:19
std::string strip_custom_tstamp(const std::string in_str, const std::string ts_str)
Set thread local storage value for hertz.
Definition: Logger.cpp:38
std::string search_and_insert_custom_tstamp(const std::string &buf, const std::string &ts_str)
Set thread local storage value for hertz.
Definition: Logger.cpp:46
void log(int level, const char *message,...)
Logs a message to all available loggers.
Definition: Logger.cpp:123
constexpr string_t string
const int TLS_THREAD_LEVEL_DEFAULT
Definition: Logger.h:156
const double TLS_THREAD_HZ_DEFAULT
Definition: Logger.h:157
int64_t get_time(void)
Returns a time of day in nanoseconds If simtime feature is enabled, this may be simulation time inste...
Definition: Utility.inl:265