rcpp_framework/modules/drogon/trantor/utils/Logger.cc

188 lines
4.4 KiB
C++
Raw Normal View History

2021-06-17 14:43:29 +02:00
/**
*
* Logger.cc
* An Tao
*
* Public header file in trantor lib.
*
* Copyright 2018, An Tao. All rights reserved.
* Use of this source code is governed by a BSD-style license
* that can be found in the License file.
*
*
*/
#include <stdio.h>
#include <trantor/utils/Logger.h>
2021-06-17 14:43:29 +02:00
#include <thread>
#ifndef _WIN32
#include <sys/syscall.h>
#include <unistd.h>
2021-06-17 14:43:29 +02:00
#else
#include <sstream>
#endif
#ifdef __FreeBSD__
#include <pthread_np.h>
#endif
namespace trantor {
2021-06-17 14:43:29 +02:00
// helper class for known string length at compile time
class T {
public:
T(const char *str, unsigned len) :
str_(str), len_(len) {
assert(strlen(str) == len_);
}
2021-06-17 14:43:29 +02:00
const char *str_;
const unsigned len_;
2021-06-17 14:43:29 +02:00
};
const char *strerror_tl(int savedErrno) {
2021-06-17 14:43:29 +02:00
#ifndef _MSC_VER
return strerror(savedErrno);
2021-06-17 14:43:29 +02:00
#else
static thread_local char errMsg[64];
(void)strerror_s<sizeof errMsg>(errMsg, savedErrno);
return errMsg;
2021-06-17 14:43:29 +02:00
#endif
}
inline LogStream &operator<<(LogStream &s, T v) {
s.append(v.str_, v.len_);
return s;
2021-06-17 14:43:29 +02:00
}
inline LogStream &operator<<(LogStream &s, const Logger::SourceFile &v) {
s.append(v.data_, v.size_);
return s;
2021-06-17 14:43:29 +02:00
}
} // namespace trantor
2021-06-17 14:43:29 +02:00
using namespace trantor;
static thread_local uint64_t lastSecond_{ 0 };
static thread_local char lastTimeString_[32] = { 0 };
2021-06-17 14:43:29 +02:00
#ifdef __linux__
static thread_local pid_t threadId_{ 0 };
2021-06-17 14:43:29 +02:00
#else
static thread_local uint64_t threadId_{ 0 };
2021-06-17 14:43:29 +02:00
#endif
// static thread_local LogStream logStream_;
void Logger::formatTime() {
uint64_t now = static_cast<uint64_t>(date_.secondsSinceEpoch());
uint64_t microSec =
static_cast<uint64_t>(date_.microSecondsSinceEpoch() -
date_.roundSecond().microSecondsSinceEpoch());
if (now != lastSecond_) {
lastSecond_ = now;
2021-06-17 14:43:29 +02:00
#ifndef _MSC_VER
strncpy(lastTimeString_,
date_.toFormattedString(false).c_str(),
sizeof(lastTimeString_) - 1);
2021-06-17 14:43:29 +02:00
#else
strncpy_s<sizeof lastTimeString_>(
lastTimeString_,
date_.toFormattedString(false).c_str(),
sizeof(lastTimeString_) - 1);
2021-06-17 14:43:29 +02:00
#endif
}
logStream_ << T(lastTimeString_, 17);
char tmp[32];
snprintf(tmp,
sizeof(tmp),
".%06llu UTC ",
static_cast<long long unsigned int>(microSec));
logStream_ << T(tmp, 12);
2021-06-17 14:43:29 +02:00
#ifdef __linux__
if (threadId_ == 0)
threadId_ = static_cast<pid_t>(::syscall(SYS_gettid));
2021-06-17 14:43:29 +02:00
#elif defined __FreeBSD__
if (threadId_ == 0) {
threadId_ = pthread_getthreadid_np();
}
2021-06-17 14:43:29 +02:00
#elif defined __OpenBSD__
if (threadId_ == 0) {
threadId_ = getthrid();
}
2021-06-17 14:43:29 +02:00
#elif defined _WIN32
if (threadId_ == 0) {
std::stringstream ss;
ss << std::this_thread::get_id();
threadId_ = std::stoull(ss.str());
}
2021-06-17 14:43:29 +02:00
#else
if (threadId_ == 0) {
pthread_threadid_np(NULL, &threadId_);
}
2021-06-17 14:43:29 +02:00
#endif
logStream_ << threadId_;
2021-06-17 14:43:29 +02:00
}
static const char *logLevelStr[Logger::LogLevel::kNumberOfLogLevels] = {
" TRACE ",
" DEBUG ",
" INFO ",
" WARN ",
" ERROR ",
" FATAL ",
2021-06-17 14:43:29 +02:00
};
Logger::Logger(SourceFile file, int line) :
sourceFile_(file), fileLine_(line), level_(kInfo) {
formatTime();
logStream_ << T(logLevelStr[level_], 7);
2021-06-17 14:43:29 +02:00
}
Logger::Logger(SourceFile file, int line, LogLevel level) :
sourceFile_(file), fileLine_(line), level_(level) {
formatTime();
logStream_ << T(logLevelStr[level_], 7);
2021-06-17 14:43:29 +02:00
}
Logger::Logger(SourceFile file, int line, LogLevel level, const char *func) :
sourceFile_(file), fileLine_(line), level_(level) {
formatTime();
logStream_ << T(logLevelStr[level_], 7) << "[" << func << "] ";
2021-06-17 14:43:29 +02:00
}
Logger::Logger(SourceFile file, int line, bool) :
sourceFile_(file), fileLine_(line), level_(kFatal) {
formatTime();
logStream_ << T(logLevelStr[level_], 7);
if (errno != 0) {
logStream_ << strerror_tl(errno) << " (errno=" << errno << ") ";
}
2021-06-17 14:43:29 +02:00
}
RawLogger::~RawLogger() {
if (index_ < 0) {
auto &oFunc = Logger::outputFunc_();
if (!oFunc)
return;
oFunc(logStream_.bufferData(), logStream_.bufferLength());
} else {
auto &oFunc = Logger::outputFunc_(index_);
if (!oFunc)
return;
oFunc(logStream_.bufferData(), logStream_.bufferLength());
}
2021-06-17 14:43:29 +02:00
}
Logger::~Logger() {
logStream_ << T(" - ", 3) << sourceFile_ << ':' << fileLine_ << '\n';
if (index_ < 0) {
auto &oFunc = Logger::outputFunc_();
if (!oFunc)
return;
oFunc(logStream_.bufferData(), logStream_.bufferLength());
if (level_ >= kError)
Logger::flushFunc_()();
} else {
auto &oFunc = Logger::outputFunc_(index_);
if (!oFunc)
return;
oFunc(logStream_.bufferData(), logStream_.bufferLength());
if (level_ >= kError)
Logger::flushFunc_(index_)();
}
2021-06-17 14:43:29 +02:00
// logStream_.resetBuffer();
2021-06-17 14:43:29 +02:00
}
LogStream &Logger::stream() {
return logStream_;
2021-06-17 14:43:29 +02:00
}