Compare commits
2 Commits
76595be62a
...
ea3dfc9ca8
Author | SHA1 | Date | |
---|---|---|---|
|
ea3dfc9ca8 | ||
|
1e1bb8e7d0 |
@ -88,7 +88,7 @@ add_subdirectory("third_party/googletest")
|
||||
add_subdirectory("third_party/gflags")
|
||||
set(GFLAGS_USE_TARGET_NAMESPACE ON)
|
||||
set(gflags_DIR "${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags")
|
||||
add_subdirectory("third_party/glog")
|
||||
# add_subdirectory("third_party/glog")
|
||||
# add_subdirectory("third_party/context")
|
||||
|
||||
set(CURL_DISABLE_TESTS ON)
|
||||
@ -166,6 +166,7 @@ set(TILE_SRCS
|
||||
"tile/base/internal/thread_pool.cc"
|
||||
"tile/base/internal/time_keeper.cc"
|
||||
"tile/base/internal/time_keeper.h"
|
||||
"tile/base/logging/splitter_sink.cc"
|
||||
"tile/base/net/endpoint.cc"
|
||||
"tile/base/object_pool/disabled.cc"
|
||||
"tile/base/object_pool/global.cc"
|
||||
@ -216,7 +217,7 @@ if((NOT TILE_HAVE_GETIFADDRS) OR (NOT TILE_HAVE_FREEIFADDRS))
|
||||
list(APPEND TILE_SRCS "tile/base/net/detail/android/ifaddrs.c")
|
||||
endif()
|
||||
|
||||
add_library(tile OBJECT ${TILE_SRCS})
|
||||
add_library(tile SHARED ${TILE_SRCS})
|
||||
set_target_properties(tile PROPERTIES VERSION ${PROJECT_VERSION}
|
||||
target_precompile_headers(tile PUBLIC inja/inja.h)
|
||||
target_precompile_headers(tile PUBLIC inja/string_view.h)
|
||||
@ -229,8 +230,8 @@ target_include_directories(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/third_party/mustache.hpp"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/third_party/fmt/include"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/third_party/glog"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/third_party/glog/src"
|
||||
# "${CMAKE_CURRENT_BINARY_DIR}/third_party/glog"
|
||||
# "${CMAKE_CURRENT_SOURCE_DIR}/third_party/glog/src"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
${THIRD_PARTY_INCLUDE_DIRS}
|
||||
RPIVATE
|
||||
@ -240,7 +241,7 @@ target_link_libraries(
|
||||
tile
|
||||
PUBLIC # -Wl,--start-group
|
||||
# nova_context
|
||||
zlib gflags::gflags glog::glog
|
||||
zlib gflags::gflags # glog::glog
|
||||
jsoncpp_static
|
||||
# -Wl,--end-group
|
||||
libcurl fmt)
|
||||
@ -301,6 +302,7 @@ function(add_test_group prefix group_name)
|
||||
# convert to relative path message(STATUS "${prefix} -> ${TEST_FILE}")
|
||||
file(RELATIVE_PATH TEST_NAME "${prefix}" "${SRC_FILE}")
|
||||
string(REPLACE "/" "_" TEST_NAME "${TEST_NAME}")
|
||||
string(REPLACE "_test.cc" "_test" TEST_NAME "${TEST_NAME}")
|
||||
# if group_name is not empty, add suffix _
|
||||
if (NOT group_name STREQUAL "")
|
||||
set(TEST_NAME "${group_name}_${TEST_NAME}")
|
||||
|
@ -171,6 +171,7 @@ private:
|
||||
std::unordered_map<std::string, T> m = {{"1s", 1}};
|
||||
for (auto &&item : m) {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void LinkToParent(Slice rel_path, ExposedVarGroup *parent) {
|
||||
|
@ -1,57 +1,27 @@
|
||||
#include "tile/base/internal/logging.h"
|
||||
|
||||
#include "glog/logging.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
|
||||
namespace tile {
|
||||
bool VLogIsOn(int n) { return true; }
|
||||
class LogMessage::Impl {
|
||||
public:
|
||||
Impl(const char *file, int line, int severity) : lm_(file, line, severity) {}
|
||||
std::ostream &stream() { return lm_.stream(); }
|
||||
|
||||
private:
|
||||
google::LogMessage lm_;
|
||||
};
|
||||
|
||||
class LogMessageFatal::Impl {
|
||||
public:
|
||||
Impl(const char *file, int line) : lm_(file, line) {}
|
||||
std::ostream &stream() { return lm_.stream(); }
|
||||
|
||||
private:
|
||||
google::LogMessageFatal lm_;
|
||||
};
|
||||
|
||||
LogMessage::LogMessage(const char *file, int line, int severity)
|
||||
: impl_(new Impl(file, line, severity)) {}
|
||||
LogMessage::~LogMessage() = default;
|
||||
std::ostream &LogMessage::stream() { return impl_->stream(); }
|
||||
|
||||
LogMessageFatal::LogMessageFatal(const char *file, int line)
|
||||
: impl_(new Impl(file, line)) {}
|
||||
LogMessageFatal::~LogMessageFatal() = default;
|
||||
std::ostream &LogMessageFatal::stream() { return impl_->stream(); }
|
||||
|
||||
} // namespace tile
|
||||
#include <set>
|
||||
|
||||
namespace tile {
|
||||
namespace internal {
|
||||
namespace logging {
|
||||
|
||||
namespace {
|
||||
std::vector<PrefixAppender *> *GetProviers() {
|
||||
static std::vector<PrefixAppender *> providers;
|
||||
return &providers;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace details {
|
||||
std::string DescribeFormatArguments(const std::vector<std::string> &args) {
|
||||
return fmt::format("{}", fmt::join(args.begin(), args.end(), ", "));
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
|
||||
void InstallPrefixProvider(PrefixAppender *writer) {
|
||||
GetProviers()->push_back(writer);
|
||||
}
|
||||
@ -67,7 +37,172 @@ void WritePrefixTo(std::string *to) {
|
||||
} // namespace logging
|
||||
} // namespace internal
|
||||
} // namespace tile
|
||||
|
||||
namespace tile {
|
||||
static std::mutex g_sink_mutex;
|
||||
static std::set<LogSink *> g_sinks;
|
||||
|
||||
static uint64_t g_num_messages[TILE_MAX_LOG_SEVERITY + 1];
|
||||
std::mutex g_log_mutex;
|
||||
|
||||
class OStreamWrapper : public std::streambuf {
|
||||
public:
|
||||
OStreamWrapper(std::ostream &ostream) : ostream_(ostream) {}
|
||||
|
||||
int_type overflow(int_type c) override { return c; }
|
||||
|
||||
private:
|
||||
std::ostream &ostream_;
|
||||
};
|
||||
|
||||
bool VLogIsOn(int n) { return true; }
|
||||
|
||||
class LogMessage::Impl {
|
||||
public:
|
||||
Impl(const char *file, int line)
|
||||
: stream_(message_text_, LogMessage::kMaxLogMessageLen, 0) {
|
||||
Init(file, line, TILE_INFO, &LogMessage::Impl::SendToLog);
|
||||
}
|
||||
Impl(const char *file, int line, LogSeverity severity)
|
||||
: stream_(message_text_, LogMessage::kMaxLogMessageLen, 0) {
|
||||
Init(file, line, severity, &LogMessage::Impl::SendToLog);
|
||||
}
|
||||
Impl(const char *file, int line, LogSeverity severity, LogSink *sink,
|
||||
bool also_send_to_log)
|
||||
: stream_(message_text_, LogMessage::kMaxLogMessageLen, 0) {
|
||||
Init(file, line, severity,
|
||||
also_send_to_log ? &LogMessage::Impl::SendToSinkAndLog
|
||||
: &LogMessage::Impl::SendToSink);
|
||||
sink_ = sink;
|
||||
}
|
||||
~Impl() { Flush(); }
|
||||
std::ostream &stream() { return stream_; }
|
||||
void Flush() {
|
||||
if (has_been_flushed_) {
|
||||
return;
|
||||
}
|
||||
|
||||
num_chars_to_log_ = stream_.pcount();
|
||||
bool append_newline = message_text_[num_chars_to_log_ - 1] != '\n';
|
||||
char original_final_char = '\0';
|
||||
|
||||
if (append_newline) {
|
||||
original_final_char = message_text_[num_chars_to_log_];
|
||||
message_text_[num_chars_to_log_++] = '\n';
|
||||
}
|
||||
message_text_[num_chars_to_log_] = '\0';
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> _{g_log_mutex};
|
||||
(this->*(send_method_))();
|
||||
++g_num_messages[severity_];
|
||||
WaitForSinks();
|
||||
if (sink_) {
|
||||
sink_->WaitTillSent();
|
||||
}
|
||||
}
|
||||
|
||||
if (append_newline) {
|
||||
message_text_[num_chars_to_log_ - 1] = original_final_char;
|
||||
}
|
||||
|
||||
if (preserved_errno_ != 0) {
|
||||
errno = preserved_errno_;
|
||||
}
|
||||
has_been_flushed_ = true;
|
||||
|
||||
if (severity_ == TILE_FATAL) {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
LogSeverity severity() const noexcept { return severity_; }
|
||||
int line() const noexcept { return line_; }
|
||||
const char *fullname() const noexcept { return file_; }
|
||||
const char *basename() const noexcept { return file_; }
|
||||
const LogMessageTime &time() const noexcept { return time_; }
|
||||
int preserved_errno() const { return preserved_errno_; }
|
||||
|
||||
private:
|
||||
void Init(const char *file, int line, LogSeverity severity,
|
||||
void (LogMessage::Impl::*send_method)()) {
|
||||
has_been_flushed_ = false;
|
||||
file_ = file;
|
||||
line_ = line;
|
||||
severity_ = severity;
|
||||
send_method_ = send_method;
|
||||
sink_ = nullptr;
|
||||
const auto now = std::chrono::system_clock::now();
|
||||
time_ = LogMessageTime(now);
|
||||
thread_id_ = std::this_thread::get_id();
|
||||
preserved_errno_ = errno;
|
||||
}
|
||||
|
||||
void SendToSink() {
|
||||
if (sink_) {
|
||||
sink_->send(severity_, fullname(), basename(), line(), time(),
|
||||
message_text_ + num_prefix_chars_,
|
||||
num_chars_to_log_ - num_prefix_chars_ - 1);
|
||||
}
|
||||
}
|
||||
void SendToLog() {
|
||||
LogToSinks(severity_, fullname(), basename(), line(), time(),
|
||||
message_text_ + num_prefix_chars_,
|
||||
num_chars_to_log_ - num_prefix_chars_ - 1);
|
||||
}
|
||||
void SendToSinkAndLog() {
|
||||
SendToSink();
|
||||
SendToLog();
|
||||
}
|
||||
|
||||
private:
|
||||
char message_text_[LogMessage::kMaxLogMessageLen + 1];
|
||||
LogMessage::LogStream stream_;
|
||||
|
||||
bool has_been_flushed_;
|
||||
|
||||
const char *file_;
|
||||
int line_;
|
||||
LogSeverity severity_;
|
||||
void (LogMessage::Impl::*send_method_)();
|
||||
|
||||
LogSink *sink_;
|
||||
LogMessageTime time_;
|
||||
std::thread::id thread_id_;
|
||||
int preserved_errno_;
|
||||
|
||||
size_t num_prefix_chars_;
|
||||
size_t num_chars_to_log_;
|
||||
};
|
||||
|
||||
LogMessage::LogMessage(const char *file, int line)
|
||||
: impl_(new Impl(file, line)) {}
|
||||
LogMessage::LogMessage(const char *file, int line, LogSeverity severity)
|
||||
: impl_(new Impl(file, line, severity)) {}
|
||||
LogMessage::LogMessage(const char *file, int line, LogSeverity severity,
|
||||
LogSink *sink, bool also_send_to_log)
|
||||
: impl_(new Impl(file, line, severity, sink, also_send_to_log)) {}
|
||||
|
||||
LogMessage::~LogMessage() {}
|
||||
|
||||
std::ostream &LogMessage::stream() { return impl_->stream(); }
|
||||
void LogMessage::Flush() { impl_->Flush(); }
|
||||
|
||||
LogSeverity LogMessage::severity() const noexcept { return impl_->severity(); }
|
||||
int LogMessage::line() const noexcept { return impl_->line(); }
|
||||
const char *LogMessage::fullname() const noexcept { return impl_->fullname(); }
|
||||
const char *LogMessage::basename() const noexcept { return impl_->basename(); }
|
||||
const LogMessageTime &LogMessage::time() const noexcept {
|
||||
return impl_->time();
|
||||
}
|
||||
int LogMessage::preserved_errno() const { return impl_->preserved_errno(); }
|
||||
|
||||
LogMessageFatal::LogMessageFatal(const char *file, int line)
|
||||
: LogMessage(file, line, TILE_FATAL) {}
|
||||
|
||||
LogMessageFatal::~LogMessageFatal() {}
|
||||
|
||||
std::ostream &LogMessageFatal::stream() { return LogMessage::stream(); }
|
||||
|
||||
LogMessageTime::LogMessageTime()
|
||||
: time_struct_(), timestamp_(0), usecs_(0), gmtoffset_(0) {}
|
||||
@ -79,12 +214,21 @@ LogMessageTime::LogMessageTime(std::tm t) {
|
||||
|
||||
LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime now) {
|
||||
std::tm t;
|
||||
if (FLAGS_log_utc_time)
|
||||
if (true)
|
||||
gmtime_r(×tamp, &t);
|
||||
else
|
||||
localtime_r(×tamp, &t);
|
||||
init(t, timestamp, now);
|
||||
}
|
||||
LogMessageTime::LogMessageTime(std::chrono::system_clock::time_point tp) {
|
||||
std::time_t timestamp = std::chrono::system_clock::to_time_t(tp);
|
||||
std::tm t;
|
||||
if (true)
|
||||
gmtime_r(×tamp, &t);
|
||||
else
|
||||
localtime_r(×tamp, &t);
|
||||
init(t, timestamp, 0);
|
||||
}
|
||||
|
||||
void LogMessageTime::init(const std::tm &t, std::time_t timestamp,
|
||||
WallTime now) {
|
||||
@ -98,7 +242,7 @@ void LogMessageTime::init(const std::tm &t, std::time_t timestamp,
|
||||
void LogMessageTime::CalcGmtOffset() {
|
||||
std::tm gmt_struct;
|
||||
int isDst = 0;
|
||||
if (FLAGS_log_utc_time) {
|
||||
if (true) {
|
||||
localtime_r(×tamp_, &gmt_struct);
|
||||
isDst = gmt_struct.tm_isdst;
|
||||
gmt_struct = time_struct_;
|
||||
@ -124,64 +268,60 @@ void LogSink::send(LogSeverity severity, const char *full_filename,
|
||||
// do nothing
|
||||
}
|
||||
void LogSink::WaitTillSent() {}
|
||||
|
||||
std::string LogSink::ToString(LogSeverity severity, const char *file, int line,
|
||||
const LogMessageTime &logmsgtime,
|
||||
const char *message, size_t message_len) {
|
||||
return google::LogSink::ToString(severity, file, line, logmsgtime.tm(),
|
||||
message, message_len);
|
||||
// return google::LogSink::ToString(severity, file, line, logmsgtime.tm(),
|
||||
// message, message_len);
|
||||
|
||||
std::stringstream ss;
|
||||
ss.write(message, message_len);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
class LogSinkWrapper : public google::LogSink {
|
||||
public:
|
||||
LogSinkWrapper(tile::LogSink *dest) : dest_(dest) {}
|
||||
~LogSinkWrapper() override {}
|
||||
void send(LogSeverity severity, const char *full_filename,
|
||||
const char *base_filename, int line,
|
||||
const google::LogMessageTime &logmsgtime, const char *message,
|
||||
size_t message_len) override {
|
||||
dest_->send(severity, full_filename, base_filename, line, logmsgtime.tm(),
|
||||
message, message_len);
|
||||
}
|
||||
|
||||
void WaitTillSent() override { dest_->WaitTillSent(); }
|
||||
|
||||
private:
|
||||
tile::LogSink *dest_;
|
||||
};
|
||||
|
||||
struct LogSinkPair {
|
||||
struct LogSinWrapper *wrapper;
|
||||
LogSink *sink;
|
||||
};
|
||||
|
||||
static std::map<LogSink *, LogSinkWrapper *> sink_registry;
|
||||
static std::mutex sink_registry_mutex;
|
||||
|
||||
void AddLogSink(LogSink *dest) {
|
||||
std::lock_guard<std::mutex> lock(sink_registry_mutex);
|
||||
if (sink_registry.find(dest) != sink_registry.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto wrapper = new LogSinkWrapper(dest);
|
||||
sink_registry[dest] = wrapper;
|
||||
google::AddLogSink(wrapper);
|
||||
std::lock_guard<std::mutex> _(g_sink_mutex);
|
||||
g_sinks.insert(dest);
|
||||
}
|
||||
|
||||
void RemoveLogSink(LogSink *dest) {
|
||||
std::lock_guard<std::mutex> lock(sink_registry_mutex);
|
||||
auto iter = sink_registry.find(dest);
|
||||
if (iter != sink_registry.end()) {
|
||||
google::RemoveLogSink(iter->second);
|
||||
sink_registry.erase(iter);
|
||||
delete iter->second;
|
||||
std::lock_guard<std::mutex> _(g_sink_mutex);
|
||||
g_sinks.erase(dest);
|
||||
}
|
||||
|
||||
void SetStderrLogging(LogSeverity min_severity) {}
|
||||
void LogToStderr() {}
|
||||
void LogToSinks(LogSeverity severity, const char *full_filename,
|
||||
const char *base_filename, int line, const LogMessageTime &time,
|
||||
const char *message, size_t message_len) {
|
||||
std::lock_guard<std::mutex> _(g_sink_mutex);
|
||||
for (auto &&sink : g_sinks) {
|
||||
sink->send(severity, full_filename, base_filename, line, time, message,
|
||||
message_len);
|
||||
}
|
||||
}
|
||||
void SetStderrLogging(LogSeverity min_severity) {
|
||||
google::SetStderrLogging(min_severity);
|
||||
void WaitForSinks() {
|
||||
std::lock_guard<std::mutex> _(g_sink_mutex);
|
||||
for (auto &&sink : g_sinks) {
|
||||
sink->WaitTillSent();
|
||||
}
|
||||
}
|
||||
void LogToStderr() { google::LogToStderr(); }
|
||||
|
||||
const char *GetLogSeverityName(LogSeverity severity) {
|
||||
return google::GetLogSeverityName(severity);
|
||||
const static std::map<LogSeverity, const char *> severity_names = {
|
||||
{TILE_INFO, "INFO"},
|
||||
{TILE_WARNING, "WARNING"},
|
||||
{TILE_ERROR, "ERROR"},
|
||||
{TILE_FATAL, "FATAL"},
|
||||
};
|
||||
|
||||
auto iter = severity_names.find(severity);
|
||||
if (iter != severity_names.end()) {
|
||||
return iter->second;
|
||||
} else {
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace tile
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <ctime>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
@ -17,31 +18,98 @@
|
||||
#include <type_traits>
|
||||
|
||||
namespace tile {
|
||||
typedef int LogSeverity;
|
||||
const int TILE_INFO = 0, TILE_WARNING = 1, TILE_ERROR = 2, TILE_FATAL = 3;
|
||||
// typedef int LogSeverity;
|
||||
// const int TILE_INFO = 0, TILE_WARNING = 1, TILE_ERROR = 2, TILE_FATAL = 3;
|
||||
enum LogSeverity {
|
||||
TILE_INFO = 0,
|
||||
TILE_WARNING = 1,
|
||||
TILE_ERROR = 2,
|
||||
TILE_FATAL = 3,
|
||||
TILE_MAX_LOG_SEVERITY = TILE_FATAL
|
||||
};
|
||||
|
||||
bool VLogIsOn(int n);
|
||||
|
||||
class LogStreamBuf : public std::streambuf {
|
||||
public:
|
||||
LogStreamBuf(char *buf, int len) { setp(buf, buf + len - 2); }
|
||||
|
||||
int_type overflow(int_type ch) { return ch; }
|
||||
size_t pcount() const { return static_cast<size_t>(pptr() - pbase()); }
|
||||
char *pbase() const { return std::streambuf::pbase(); }
|
||||
};
|
||||
|
||||
class LogSink;
|
||||
class LogMessageTime;
|
||||
class LogMessage {
|
||||
public:
|
||||
LogMessage(const char *file, int line, int severity);
|
||||
class LogStream : public std::ostream {
|
||||
public:
|
||||
LogStream(char *buf, int len, int64_t ctr)
|
||||
: std::ostream(nullptr), streambuf_(buf, len), ctr_(ctr), self_(this) {
|
||||
rdbuf(&streambuf_);
|
||||
}
|
||||
|
||||
LogStream(LogStream &other) noexcept
|
||||
: std::ostream(nullptr), streambuf_(std::move(other.streambuf_)),
|
||||
ctr_(internal::Exchange(other.ctr_, 0)), self_(this) {
|
||||
rdbuf(&streambuf_);
|
||||
}
|
||||
|
||||
LogStream &operator=(LogStream &&other) noexcept {
|
||||
streambuf_ = std::move(other.streambuf_);
|
||||
ctr_ = internal::Exchange(other.ctr_, 0);
|
||||
self_ = this;
|
||||
rdbuf(&streambuf_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
int64_t ctr() const { return ctr_; }
|
||||
void set_ctr(int64_t ctr) { ctr_ = ctr; }
|
||||
|
||||
LogStream *self() { return self_; }
|
||||
|
||||
size_t pcount() const { return streambuf_.pcount(); }
|
||||
char *pbase() const { return streambuf_.pbase(); }
|
||||
char *str() const { return pbase(); }
|
||||
|
||||
LogStream(const LogStream &) = delete;
|
||||
LogStream &operator=(const LogStream &) = delete;
|
||||
|
||||
private:
|
||||
LogStreamBuf streambuf_;
|
||||
int64_t ctr_;
|
||||
LogStream *self_;
|
||||
};
|
||||
|
||||
public:
|
||||
static const size_t kMaxLogMessageLen = 30000;
|
||||
LogMessage(const char *file, int line);
|
||||
LogMessage(const char *file, int line, LogSeverity severity);
|
||||
LogMessage(const char *file, int line, LogSeverity severity, LogSink *sink,
|
||||
bool also_send_to_log = true);
|
||||
|
||||
~LogMessage();
|
||||
std::ostream &stream();
|
||||
void Flush();
|
||||
|
||||
LogSeverity severity() const noexcept;
|
||||
int line() const noexcept;
|
||||
const char *fullname() const noexcept;
|
||||
const char *basename() const noexcept;
|
||||
const LogMessageTime &time() const noexcept;
|
||||
int preserved_errno() const;
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> impl_;
|
||||
};
|
||||
|
||||
class LogMessageFatal {
|
||||
class LogMessageFatal : public LogMessage {
|
||||
public:
|
||||
LogMessageFatal(const char *file, int line);
|
||||
~LogMessageFatal();
|
||||
std::ostream &stream();
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> impl_;
|
||||
};
|
||||
|
||||
class LogMessageVoidify {
|
||||
@ -599,6 +667,7 @@ struct LogMessageTime {
|
||||
LogMessageTime();
|
||||
LogMessageTime(std::tm t);
|
||||
LogMessageTime(std::time_t timestamp, WallTime now);
|
||||
LogMessageTime(std::chrono::system_clock::time_point tp);
|
||||
|
||||
const time_t ×tamp() const { return timestamp_; }
|
||||
const int &sec() const { return time_struct_.tm_sec; }
|
||||
@ -637,15 +706,14 @@ public:
|
||||
size_t message_len);
|
||||
};
|
||||
|
||||
class FileLogSink : public LogSink {
|
||||
public:
|
||||
FileLogSink(const std::string &file_path_template);
|
||||
};
|
||||
|
||||
void AddLogSink(LogSink *dest);
|
||||
void RemoveLogSink(LogSink *dest);
|
||||
void SetStderrLogging(LogSeverity min_severity);
|
||||
void LogToStderr();
|
||||
void LogToSinks(LogSeverity severity, const char *full_filename,
|
||||
const char *base_filename, int line, const LogMessageTime &time,
|
||||
const char *message, size_t message_len);
|
||||
void WaitForSinks();
|
||||
const char *GetLogSeverityName(LogSeverity severity);
|
||||
|
||||
} // namespace tile
|
||||
|
187
tile/base/internal/logging_glog.cc
Normal file
187
tile/base/internal/logging_glog.cc
Normal file
@ -0,0 +1,187 @@
|
||||
#include "tile/base/internal/logging.h"
|
||||
|
||||
#include "glog/logging.h"
|
||||
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
|
||||
namespace tile {
|
||||
bool VLogIsOn(int n) { return true; }
|
||||
class LogMessage::Impl {
|
||||
public:
|
||||
Impl(const char *file, int line, int severity) : lm_(file, line, severity) {}
|
||||
std::ostream &stream() { return lm_.stream(); }
|
||||
|
||||
private:
|
||||
google::LogMessage lm_;
|
||||
};
|
||||
|
||||
class LogMessageFatal::Impl {
|
||||
public:
|
||||
Impl(const char *file, int line) : lm_(file, line) {}
|
||||
std::ostream &stream() { return lm_.stream(); }
|
||||
|
||||
private:
|
||||
google::LogMessageFatal lm_;
|
||||
};
|
||||
|
||||
LogMessage::LogMessage(const char *file, int line, int severity)
|
||||
: impl_(new Impl(file, line, severity)) {}
|
||||
LogMessage::~LogMessage() = default;
|
||||
std::ostream &LogMessage::stream() { return impl_->stream(); }
|
||||
|
||||
LogMessageFatal::LogMessageFatal(const char *file, int line)
|
||||
: impl_(new Impl(file, line)) {}
|
||||
LogMessageFatal::~LogMessageFatal() = default;
|
||||
std::ostream &LogMessageFatal::stream() { return impl_->stream(); }
|
||||
|
||||
} // namespace tile
|
||||
|
||||
namespace tile {
|
||||
namespace internal {
|
||||
namespace logging {
|
||||
namespace {
|
||||
std::vector<PrefixAppender *> *GetProviers() {
|
||||
static std::vector<PrefixAppender *> providers;
|
||||
return &providers;
|
||||
}
|
||||
} // namespace
|
||||
namespace details {
|
||||
std::string DescribeFormatArguments(const std::vector<std::string> &args) {
|
||||
return fmt::format("{}", fmt::join(args.begin(), args.end(), ", "));
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
void InstallPrefixProvider(PrefixAppender *writer) {
|
||||
GetProviers()->push_back(writer);
|
||||
}
|
||||
void WritePrefixTo(std::string *to) {
|
||||
for (auto &&appender : *GetProviers()) {
|
||||
auto was = to->size();
|
||||
appender(to);
|
||||
if (to->size() != was) {
|
||||
to->push_back(' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace logging
|
||||
} // namespace internal
|
||||
} // namespace tile
|
||||
namespace tile {
|
||||
|
||||
LogMessageTime::LogMessageTime()
|
||||
: time_struct_(), timestamp_(0), usecs_(0), gmtoffset_(0) {}
|
||||
|
||||
LogMessageTime::LogMessageTime(std::tm t) {
|
||||
std::time_t timestamp = std::mktime(&t);
|
||||
init(t, timestamp, 0);
|
||||
}
|
||||
|
||||
LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime now) {
|
||||
std::tm t;
|
||||
if (FLAGS_log_utc_time)
|
||||
gmtime_r(×tamp, &t);
|
||||
else
|
||||
localtime_r(×tamp, &t);
|
||||
init(t, timestamp, now);
|
||||
}
|
||||
|
||||
void LogMessageTime::init(const std::tm &t, std::time_t timestamp,
|
||||
WallTime now) {
|
||||
time_struct_ = t;
|
||||
timestamp_ = timestamp;
|
||||
usecs_ = static_cast<std::int32_t>((now - timestamp) * 1000000);
|
||||
|
||||
CalcGmtOffset();
|
||||
}
|
||||
|
||||
void LogMessageTime::CalcGmtOffset() {
|
||||
std::tm gmt_struct;
|
||||
int isDst = 0;
|
||||
if (FLAGS_log_utc_time) {
|
||||
localtime_r(×tamp_, &gmt_struct);
|
||||
isDst = gmt_struct.tm_isdst;
|
||||
gmt_struct = time_struct_;
|
||||
} else {
|
||||
isDst = time_struct_.tm_isdst;
|
||||
gmtime_r(×tamp_, &gmt_struct);
|
||||
}
|
||||
|
||||
time_t gmt_sec = mktime(&gmt_struct);
|
||||
const long hour_secs = 3600;
|
||||
// If the Daylight Saving Time(isDst) is active subtract an hour from the
|
||||
// current timestamp.
|
||||
gmtoffset_ =
|
||||
static_cast<long int>(timestamp_ - gmt_sec + (isDst ? hour_secs : 0));
|
||||
}
|
||||
|
||||
LogSink::~LogSink() {}
|
||||
void LogSink::send(LogSeverity severity, const char *full_filename,
|
||||
const char *base_filename, int line,
|
||||
const LogMessageTime &logmsgtime, const char *message,
|
||||
size_t message_len) {
|
||||
|
||||
// do nothing
|
||||
}
|
||||
void LogSink::WaitTillSent() {}
|
||||
std::string LogSink::ToString(LogSeverity severity, const char *file, int line,
|
||||
const LogMessageTime &logmsgtime,
|
||||
const char *message, size_t message_len) {
|
||||
return google::LogSink::ToString(severity, file, line, logmsgtime.tm(),
|
||||
message, message_len);
|
||||
}
|
||||
|
||||
class LogSinkWrapper : public google::LogSink {
|
||||
public:
|
||||
LogSinkWrapper(tile::LogSink *dest) : dest_(dest) {}
|
||||
~LogSinkWrapper() override {}
|
||||
void send(LogSeverity severity, const char *full_filename,
|
||||
const char *base_filename, int line,
|
||||
const google::LogMessageTime &logmsgtime, const char *message,
|
||||
size_t message_len) override {
|
||||
dest_->send(severity, full_filename, base_filename, line, logmsgtime.tm(),
|
||||
message, message_len);
|
||||
}
|
||||
|
||||
void WaitTillSent() override { dest_->WaitTillSent(); }
|
||||
|
||||
private:
|
||||
tile::LogSink *dest_;
|
||||
};
|
||||
|
||||
struct LogSinkPair {
|
||||
struct LogSinWrapper *wrapper;
|
||||
LogSink *sink;
|
||||
};
|
||||
|
||||
static std::map<LogSink *, LogSinkWrapper *> sink_registry;
|
||||
static std::mutex sink_registry_mutex;
|
||||
|
||||
void AddLogSink(LogSink *dest) {
|
||||
std::lock_guard<std::mutex> lock(sink_registry_mutex);
|
||||
if (sink_registry.find(dest) != sink_registry.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto wrapper = new LogSinkWrapper(dest);
|
||||
sink_registry[dest] = wrapper;
|
||||
google::AddLogSink(wrapper);
|
||||
}
|
||||
|
||||
void RemoveLogSink(LogSink *dest) {
|
||||
std::lock_guard<std::mutex> lock(sink_registry_mutex);
|
||||
auto iter = sink_registry.find(dest);
|
||||
if (iter != sink_registry.end()) {
|
||||
google::RemoveLogSink(iter->second);
|
||||
sink_registry.erase(iter);
|
||||
delete iter->second;
|
||||
}
|
||||
}
|
||||
void SetStderrLogging(LogSeverity min_severity) {
|
||||
google::SetStderrLogging(min_severity);
|
||||
}
|
||||
void LogToStderr() { google::LogToStderr(); }
|
||||
const char *GetLogSeverityName(LogSeverity severity) {
|
||||
return google::GetLogSeverityName(severity);
|
||||
}
|
||||
} // namespace tile
|
@ -4,6 +4,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "tile/base/internal/logging.h"
|
||||
#include "tile/base/logging/splitter_sink.h"
|
||||
|
||||
// #define TILE_VLOG(n, ...)
|
||||
|
||||
|
53
tile/base/logging/splitter_sink.cc
Normal file
53
tile/base/logging/splitter_sink.cc
Normal file
@ -0,0 +1,53 @@
|
||||
#include "tile/base/logging/splitter_sink.h"
|
||||
#include <cassert>
|
||||
|
||||
namespace tile {
|
||||
SplitterSink::SplitterSink() {}
|
||||
SplitterSink::SplitterSink(
|
||||
std::initializer_list<std::shared_ptr<LogSink>> init_list) {
|
||||
std::lock_guard<std::mutex> _(sinks_mutex_);
|
||||
for (auto &sink : init_list) {
|
||||
sinks_.insert(sink);
|
||||
}
|
||||
}
|
||||
SplitterSink::~SplitterSink() {}
|
||||
void SplitterSink::send(LogSeverity severity, const char *full_filename,
|
||||
const char *base_filename, int line,
|
||||
const LogMessageTime &logmsgtime, const char *message,
|
||||
size_t message_len) {
|
||||
assert(!doing_ && "SplitterSink::send() should not be called recursively");
|
||||
std::lock_guard<std::mutex> _(sinks_mutex_);
|
||||
doing_ = true;
|
||||
for (auto &sink : sinks_) {
|
||||
sink->send(severity, full_filename, base_filename, line, logmsgtime,
|
||||
message, message_len);
|
||||
}
|
||||
doing_ = false;
|
||||
}
|
||||
|
||||
void SplitterSink::WaitTillSent() {
|
||||
assert(!doing_ && "SplitterSink::send() should not be called recursively");
|
||||
std::lock_guard<std::mutex> _(sinks_mutex_);
|
||||
doing_ = true;
|
||||
for (auto &sink : sinks_) {
|
||||
sink->WaitTillSent();
|
||||
}
|
||||
doing_ = false;
|
||||
}
|
||||
|
||||
void SplitterSink::AddSink(std::shared_ptr<LogSink> sink) {
|
||||
std::lock_guard<std::mutex> _(sinks_mutex_);
|
||||
sinks_.insert(sink);
|
||||
}
|
||||
|
||||
void SplitterSink::RemoveSink(std::shared_ptr<LogSink> sink) {
|
||||
std::lock_guard<std::mutex> _(sinks_mutex_);
|
||||
sinks_.erase(sink);
|
||||
}
|
||||
|
||||
void SplitterSink::ClearSinks() {
|
||||
std::lock_guard<std::mutex> _(sinks_mutex_);
|
||||
sinks_.clear();
|
||||
}
|
||||
|
||||
} // namespace tile
|
28
tile/base/logging/splitter_sink.h
Normal file
28
tile/base/logging/splitter_sink.h
Normal file
@ -0,0 +1,28 @@
|
||||
#include "tile/base/internal/logging.h"
|
||||
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
|
||||
namespace tile {
|
||||
class SplitterSink : public LogSink {
|
||||
public:
|
||||
SplitterSink();
|
||||
SplitterSink(std::initializer_list<std::shared_ptr<LogSink>> init_list);
|
||||
~SplitterSink() override;
|
||||
|
||||
void send(LogSeverity severity, const char *full_filename,
|
||||
const char *base_filename, int line,
|
||||
const LogMessageTime &logmsgtime, const char *message,
|
||||
size_t message_len) override;
|
||||
void WaitTillSent() override;
|
||||
|
||||
void AddSink(std::shared_ptr<LogSink> sink);
|
||||
void RemoveSink(std::shared_ptr<LogSink> sink);
|
||||
void ClearSinks();
|
||||
|
||||
private:
|
||||
std::set<std::shared_ptr<LogSink>> sinks_;
|
||||
std::mutex sinks_mutex_;
|
||||
bool doing_ = false;
|
||||
};
|
||||
} // namespace tile
|
15
tile/init.cc
15
tile/init.cc
@ -13,8 +13,8 @@
|
||||
#include "tile/net/internal/http_engine.h"
|
||||
|
||||
#include "gflags/gflags.h"
|
||||
#include "glog/logging.h"
|
||||
#include "glog/raw_logging.h"
|
||||
// #include "glog/logging.h"
|
||||
// #include "glog/raw_logging.h"
|
||||
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
@ -33,7 +33,8 @@ std::atomic<bool> g_quit_siganl{false};
|
||||
void QuitSignalHandler(int sig) {
|
||||
auto old = g_quit_siganl.exchange(true, std::memory_order_relaxed);
|
||||
if (old && FLAGS_tile_abort_on_double_quit_signal) {
|
||||
RAW_LOG(FATAL, "Double quit signal received. Crashing the program");
|
||||
// TODO: Add TILE_RAW_LOG
|
||||
// RAW_LOG(FATAL, "Double quit signal received. Crashing the program");
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,9 +50,9 @@ void InstallQuitSignalHandler() {
|
||||
|
||||
int Start(int argc, char **argv, std::function<int(int, char **)> cb,
|
||||
bool single_thread, bool enable_crash_catch) {
|
||||
// glog
|
||||
if (enable_crash_catch) {
|
||||
google::InstallFailureSignalHandler();
|
||||
// TODO: Add InstallFailureSignalHandler
|
||||
// google::InstallFailureSignalHandler();
|
||||
}
|
||||
|
||||
// Init gflags
|
||||
@ -59,8 +60,8 @@ int Start(int argc, char **argv, std::function<int(int, char **)> cb,
|
||||
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||
detail::ApplyFlagOverrider();
|
||||
|
||||
// Init Glog
|
||||
google::InitGoogleLogging(argv[0]);
|
||||
// TODO: Add Init log level
|
||||
// google::InitGoogleLogging(argv[0]);
|
||||
|
||||
TILE_LOG_INFO("Tile started. version: {}", TILE_VERSION);
|
||||
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include "benchmark/benchmark.h"
|
||||
|
||||
#include "gflags/gflags.h"
|
||||
#include "glog/logging.h"
|
||||
#include "tile/base/logging.h"
|
||||
#include "tile/init.h"
|
||||
|
||||
@ -11,29 +10,27 @@ namespace tile {
|
||||
namespace testing {
|
||||
|
||||
namespace {
|
||||
int
|
||||
StartBenchmark(int argc, char **argv)
|
||||
{
|
||||
::benchmark::Initialize(&argc, argv);
|
||||
if (::benchmark::ReportUnrecognizedArguments(argc, argv)) { return 1; }
|
||||
::benchmark::RunSpecifiedBenchmarks();
|
||||
::benchmark::Shutdown();
|
||||
return 0;
|
||||
int StartBenchmark(int argc, char **argv) {
|
||||
::benchmark::Initialize(&argc, argv);
|
||||
if (::benchmark::ReportUnrecognizedArguments(argc, argv)) {
|
||||
return 1;
|
||||
}
|
||||
::benchmark::RunSpecifiedBenchmarks();
|
||||
::benchmark::Shutdown();
|
||||
return 0;
|
||||
}
|
||||
}// namespace
|
||||
} // namespace
|
||||
|
||||
int
|
||||
InitAndRunAllBenchmarks(int *argc, char **argv)
|
||||
{
|
||||
int InitAndRunAllBenchmarks(int *argc, char **argv) {
|
||||
|
||||
// if (gflags::GetCommandLineFlagInfoOrDie("logtostderr").is_default) {
|
||||
// FLAGS_logtostderr = true;
|
||||
// }
|
||||
// if (gflags::GetCommandLineFlagInfoOrDie("logtostderr").is_default) {
|
||||
// FLAGS_logtostderr = true;
|
||||
// }
|
||||
|
||||
return Start(*argc, argv, StartBenchmark, true);
|
||||
return Start(*argc, argv, StartBenchmark, true);
|
||||
}
|
||||
|
||||
}// namespace testing
|
||||
}// namespace tile
|
||||
} // namespace testing
|
||||
} // namespace tile
|
||||
|
||||
TILE_BENCHMARK_MAIN
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "tile/testing/main.h"
|
||||
|
||||
#include "gflags/gflags.h"
|
||||
#include "glog/logging.h"
|
||||
// #include "glog/logging.h"
|
||||
#include "tile/init.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user