117 #ifndef GSLAM_MINIGLOG_GLOG_LOGGING_H_ 118 #define GSLAM_MINIGLOG_GLOG_LOGGING_H_ 121 # include <android/log.h> 141 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) 143 #elif defined(__CYGWIN__) || defined(__CYGWIN32__) 145 #elif defined(linux) || defined(__linux) || defined(__linux__) 149 #elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) 151 #elif defined(__FreeBSD__) 153 #elif defined(__NetBSD__) 155 #elif defined(__OpenBSD__) 161 #if defined(OS_LINUX) 163 #elif defined(OS_WINDOWS) 168 #if defined(_MSC_VER) 169 # define GSLAM_EXPORT __declspec(dllexport) 170 #elif defined(_MSC_VER) && 0 171 # define GSLAM_EXPORT __declspec(dllimport) 173 # define GSLAM_EXPORT __attribute__ ((visibility("default"))) 184 const int FATAL = -3;
185 const int ERROR = -2;
186 const int WARNING = -1;
193 typedef int LogSeverity;
195 const int GLOG_INFO = 0, GLOG_WARNING = 1, GLOG_ERROR = 2, GLOG_FATAL = 3,
198 const char*
const LogSeverityNames[NUM_SEVERITIES] = {
199 "INFO",
"WARNING",
"ERROR",
"FATAL" 204 inline void get_timeinfo(
struct tm& ti)
209 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) 211 localtime_s(&ti, &rawtime);
214 localtime_r(&rawtime, &ti);
219 inline int64_t GetTID()
222 #if defined(OS_LINUX) 224 #elif defined(OS_WINDOWS) 225 return GetCurrentThreadId();
239 virtual void send(LogSeverity severity,
240 const char* full_filename,
241 const char* base_filename,
243 const struct tm* tm_time,
245 size_t message_len) = 0;
246 virtual void WaitTillSent() = 0;
248 static std::string ToString(LogSeverity severity,
const char* file,
int line,
249 const struct ::tm* tm_time,
250 const char* message,
size_t message_len) {
251 std::ostringstream stream(std::string(message, message_len));
260 stream << LogSeverityNames[severity+NUM_SEVERITIES-1][0]
261 << std::setw(2) << 1+tm_time->tm_mon
262 << std::setw(2) << tm_time->tm_mday
264 << std::setw(2) << tm_time->tm_hour <<
':' 265 << std::setw(2) << tm_time->tm_min <<
':' 266 << std::setw(2) << tm_time->tm_sec <<
'.' 267 << std::setw(6) << usecs
269 << std::setfill(
' ') << std::setw(5) << GetTID() << std::setfill(
'0')
271 << file <<
':' << line <<
"] ";
273 stream << std::string(message, message_len);
278 inline std::shared_ptr<std::set<LogSink *> >& getLogSinksGlobal()
280 static std::shared_ptr<std::set<LogSink *> > sink(
new std::set<LogSink *>());
284 inline void InitGoogleLogging(
char *argv) {
289 inline void AddLogSink(
LogSink *sink) {
291 getLogSinksGlobal()->insert(sink);
293 inline void RemoveLogSink(
LogSink *sink) {
294 getLogSinksGlobal()->erase(sink);
302 LogFileSink(LogSeverity severity,
const char* base_filename)
304 m_severity = severity;
305 m_baseFileName = base_filename;
310 sprintf(fname,
"%s%04d%02d%02d-%02d%02d%02d",
312 ti.tm_year+1900, ti.tm_mon+1, ti.tm_mday,
313 ti.tm_hour, ti.tm_min, ti.tm_sec);
314 m_logFileName = fname;
316 m_logFile = fopen(fname,
"wt+");
328 virtual void send(LogSeverity severity,
329 const char* full_filename,
330 const char* base_filename,
332 const struct tm* tm_time,
336 if( severity >= m_severity && m_logFile )
338 std::string ls = LogSink::ToString(severity, base_filename, line, tm_time, message, message_len);
339 fwrite(ls.c_str(), ls.size(), 1, m_logFile);
343 virtual void WaitTillSent()
349 LogSeverity m_severity;
350 const char* m_baseFileName;
351 std::string m_logFileName;
358 typedef std::map<LogSeverity, LogFileSink*> LogSinkMap;
360 inline LogSinkMap& getLogSinkMapGlobal()
362 static std::shared_ptr<LogSinkMap > logSinkMap(
new LogSinkMap());
363 return (*logSinkMap);
367 inline void SetLogDestination(LogSeverity severity,
368 const char* base_filename)
370 LogSinkMap& g_logSinks = getLogSinkMapGlobal();
372 LogSinkMap::iterator it = g_logSinks.find(severity);
373 if( it == g_logSinks.end() )
375 if( strlen(base_filename) == 0 )
return;
379 g_logSinks[severity] = logFile;
389 RemoveLogSink(logFile);
390 g_logSinks.erase(it);
395 if( strlen(base_filename) > 0 )
397 logFile =
new LogFileSink(severity, base_filename);
398 g_logSinks[severity] = logFile;
418 MessageLogger(
const char *file,
int line,
const char *tag,
int severity)
419 : file_(file), line_(line), tag_(tag), severity_(severity) {
420 StripBasename(std::string(file), &filename_only_);
428 static const int android_log_levels[] = {
438 const int kMaxVerboseLevel = 2;
439 int android_level_index = std::min(std::max(FATAL, severity_),
440 kMaxVerboseLevel) - FATAL;
441 int android_log_level = android_log_levels[android_level_index];
444 __android_log_write(android_log_level, tag_.c_str(), stream_.str().c_str());
447 if (severity_ == FATAL) {
448 __android_log_write(ANDROID_LOG_FATAL,
454 std::cerr << filename_only_ <<
":" << line_ <<
" " << stream_.str();
457 LogToSinks(severity_);
462 if (severity_ == FATAL) {
468 std::stringstream &stream() {
return stream_; }
471 void LogToSinks(
int severity) {
473 GSLAM::get_timeinfo(timeinfo);
475 std::set<GSLAM::LogSink*>::iterator iter;
477 for (iter = GSLAM::getLogSinksGlobal()->begin();
478 iter != GSLAM::getLogSinksGlobal()->end(); ++iter) {
479 (*iter)->send(severity, file_.c_str(), filename_only_.c_str(), line_,
480 &timeinfo, stream_.str().c_str(), stream_.str().size());
484 void WaitForSinks() {
486 std::set<GSLAM::LogSink *>::iterator iter;
489 for (iter = GSLAM::getLogSinksGlobal()->begin();
490 iter != GSLAM::getLogSinksGlobal()->end(); ++iter) {
491 (*iter)->WaitTillSent();
495 void StripBasename(
const std::string &full_path, std::string *filename) {
497 const char kSeparator =
'/';
498 size_t pos = full_path.rfind(kSeparator);
499 if (pos != std::string::npos) {
500 *filename = full_path.substr(pos + 1, std::string::npos);
502 *filename = full_path;
507 std::string filename_only_;
510 std::stringstream stream_;
524 void operator&(
const std::ostream &s) { }
528 #define LOG_IF(severity, condition) \ 529 !(condition) ? (void) 0 : LoggerVoidify() & \ 530 MessageLogger((char *)__FILE__, __LINE__, "native", severity).stream() 533 #define LOG_IF_FALSE(severity, condition) LOG_IF(severity, !(condition)) 539 # define LOG(n) LOG_IF(n, n <= MAX_LOG_LEVEL) 540 # define VLOG(n) LOG_IF(n, n <= MAX_LOG_LEVEL) 541 # define LG LOG_IF(INFO, INFO <= MAX_LOG_LEVEL) 542 # define VLOG_IF(n, condition) LOG_IF(n, (n <= MAX_LOG_LEVEL) && condition) 544 # define LOG(n) MessageLogger((char *)__FILE__, __LINE__, "native", n).stream() // NOLINT 545 # define VLOG(n) MessageLogger((char *)__FILE__, __LINE__, "native", n).stream() // NOLINT 546 # define LG MessageLogger((char *)__FILE__, __LINE__, "native", INFO).stream() // NOLINT 547 # define VLOG_IF(n, condition) LOG_IF(n, condition) 551 #ifndef MAX_LOG_LEVEL 552 # define VLOG_IS_ON(x) (1) 554 # define VLOG_IS_ON(x) (x <= MAX_LOG_LEVEL) 560 # define DLOG(severity) true ? (void) 0 : LoggerVoidify() & \ 561 MessageLogger((char *)__FILE__, __LINE__, "native", severity).stream() 567 void LogMessageFatal(
const char *file,
int line,
const T &message) {
568 MessageLogger((
char *)__FILE__, __LINE__,
"native", FATAL).stream()
575 #define CHECK(condition) LOG_IF_FALSE(FATAL, condition) \ 576 << "Check failed: " #condition " " 580 # define DCHECK(condition) LOG_IF_FALSE(FATAL, condition) \ 581 << "Check failed: " #condition " " 584 # define DCHECK(condition) if (false) LOG_IF_FALSE(FATAL, condition) \ 585 << "Check failed: " #condition " " 592 #define CHECK_OP(val1, val2, op) LOG_IF_FALSE(FATAL, ((val1) op (val2))) \ 593 << "Check failed: " #val1 " " #op " " #val2 " " 596 #define CHECK_EQ(val1, val2) CHECK_OP(val1, val2, ==) 597 #define CHECK_NE(val1, val2) CHECK_OP(val1, val2, !=) 598 #define CHECK_LE(val1, val2) CHECK_OP(val1, val2, <=) 599 #define CHECK_LT(val1, val2) CHECK_OP(val1, val2, <) 600 #define CHECK_GE(val1, val2) CHECK_OP(val1, val2, >=) 601 #define CHECK_GT(val1, val2) CHECK_OP(val1, val2, >) 605 # define DCHECK_EQ(val1, val2) CHECK_OP(val1, val2, ==) 606 # define DCHECK_NE(val1, val2) CHECK_OP(val1, val2, !=) 607 # define DCHECK_LE(val1, val2) CHECK_OP(val1, val2, <=) 608 # define DCHECK_LT(val1, val2) CHECK_OP(val1, val2, <) 609 # define DCHECK_GE(val1, val2) CHECK_OP(val1, val2, >=) 610 # define DCHECK_GT(val1, val2) CHECK_OP(val1, val2, >) 613 # define DCHECK_EQ(val1, val2) if (false) CHECK_OP(val1, val2, ==) 614 # define DCHECK_NE(val1, val2) if (false) CHECK_OP(val1, val2, !=) 615 # define DCHECK_LE(val1, val2) if (false) CHECK_OP(val1, val2, <=) 616 # define DCHECK_LT(val1, val2) if (false) CHECK_OP(val1, val2, <) 617 # define DCHECK_GE(val1, val2) if (false) CHECK_OP(val1, val2, >=) 618 # define DCHECK_GT(val1, val2) if (false) CHECK_OP(val1, val2, >) 625 template <
typename T>
626 T& CheckNotNullCommon(
const char *file,
int line,
const char *names, T& t) {
628 LogMessageFatal(file, line, std::string(names));
633 template <
typename T>
634 T* CheckNotNull(
const char *file,
int line,
const char *names, T* t) {
635 return CheckNotNullCommon(file, line, names, t);
638 template <
typename T>
639 T& CheckNotNull(
const char *file,
int line,
const char *names, T& t) {
640 return CheckNotNullCommon(file, line, names, t);
644 #define CHECK_NOTNULL(val) \ 645 CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val)) 649 #define DCHECK_NOTNULL(val) \ 650 CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val)) 653 #define DCHECK_NOTNULL(val) if (false)\ 654 CheckNotNull(__FILE__, __LINE__, "'" #val "' Must be non NULL", (val)) 657 #endif // GSLAM_MINIGLOG_GLOG_LOGGING_H_