feat update
This commit is contained in:
parent
1e1bb8e7d0
commit
ea3dfc9ca8
@ -88,7 +88,7 @@ add_subdirectory("third_party/googletest")
|
|||||||
add_subdirectory("third_party/gflags")
|
add_subdirectory("third_party/gflags")
|
||||||
set(GFLAGS_USE_TARGET_NAMESPACE ON)
|
set(GFLAGS_USE_TARGET_NAMESPACE ON)
|
||||||
set(gflags_DIR "${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags")
|
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")
|
# add_subdirectory("third_party/context")
|
||||||
|
|
||||||
set(CURL_DISABLE_TESTS ON)
|
set(CURL_DISABLE_TESTS ON)
|
||||||
@ -161,11 +161,12 @@ set(TILE_SRCS
|
|||||||
"tile/base/internal/curl.h"
|
"tile/base/internal/curl.h"
|
||||||
"tile/base/internal/early_init.h"
|
"tile/base/internal/early_init.h"
|
||||||
"tile/base/internal/index_alloc.cc"
|
"tile/base/internal/index_alloc.cc"
|
||||||
"tile/base/internal/logging_glog.cc"
|
"tile/base/internal/logging.cc"
|
||||||
"tile/base/internal/logging.h"
|
"tile/base/internal/logging.h"
|
||||||
"tile/base/internal/thread_pool.cc"
|
"tile/base/internal/thread_pool.cc"
|
||||||
"tile/base/internal/time_keeper.cc"
|
"tile/base/internal/time_keeper.cc"
|
||||||
"tile/base/internal/time_keeper.h"
|
"tile/base/internal/time_keeper.h"
|
||||||
|
"tile/base/logging/splitter_sink.cc"
|
||||||
"tile/base/net/endpoint.cc"
|
"tile/base/net/endpoint.cc"
|
||||||
"tile/base/object_pool/disabled.cc"
|
"tile/base/object_pool/disabled.cc"
|
||||||
"tile/base/object_pool/global.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")
|
list(APPEND TILE_SRCS "tile/base/net/detail/android/ifaddrs.c")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_library(tile OBJECT ${TILE_SRCS})
|
add_library(tile SHARED ${TILE_SRCS})
|
||||||
set_target_properties(tile PROPERTIES VERSION ${PROJECT_VERSION}
|
set_target_properties(tile PROPERTIES VERSION ${PROJECT_VERSION}
|
||||||
target_precompile_headers(tile PUBLIC inja/inja.h)
|
target_precompile_headers(tile PUBLIC inja/inja.h)
|
||||||
target_precompile_headers(tile PUBLIC inja/string_view.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_SOURCE_DIR}/third_party/mustache.hpp"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}"
|
"${CMAKE_CURRENT_BINARY_DIR}"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/third_party/fmt/include"
|
"${CMAKE_CURRENT_SOURCE_DIR}/third_party/fmt/include"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/third_party/glog"
|
# "${CMAKE_CURRENT_BINARY_DIR}/third_party/glog"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/third_party/glog/src"
|
# "${CMAKE_CURRENT_SOURCE_DIR}/third_party/glog/src"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||||
${THIRD_PARTY_INCLUDE_DIRS}
|
${THIRD_PARTY_INCLUDE_DIRS}
|
||||||
RPIVATE
|
RPIVATE
|
||||||
@ -240,7 +241,7 @@ target_link_libraries(
|
|||||||
tile
|
tile
|
||||||
PUBLIC # -Wl,--start-group
|
PUBLIC # -Wl,--start-group
|
||||||
# nova_context
|
# nova_context
|
||||||
zlib gflags::gflags glog::glog
|
zlib gflags::gflags # glog::glog
|
||||||
jsoncpp_static
|
jsoncpp_static
|
||||||
# -Wl,--end-group
|
# -Wl,--end-group
|
||||||
libcurl fmt)
|
libcurl fmt)
|
||||||
@ -301,6 +302,7 @@ function(add_test_group prefix group_name)
|
|||||||
# convert to relative path message(STATUS "${prefix} -> ${TEST_FILE}")
|
# convert to relative path message(STATUS "${prefix} -> ${TEST_FILE}")
|
||||||
file(RELATIVE_PATH TEST_NAME "${prefix}" "${SRC_FILE}")
|
file(RELATIVE_PATH TEST_NAME "${prefix}" "${SRC_FILE}")
|
||||||
string(REPLACE "/" "_" TEST_NAME "${TEST_NAME}")
|
string(REPLACE "/" "_" TEST_NAME "${TEST_NAME}")
|
||||||
|
string(REPLACE "_test.cc" "_test" TEST_NAME "${TEST_NAME}")
|
||||||
# if group_name is not empty, add suffix _
|
# if group_name is not empty, add suffix _
|
||||||
if (NOT group_name STREQUAL "")
|
if (NOT group_name STREQUAL "")
|
||||||
set(TEST_NAME "${group_name}_${TEST_NAME}")
|
set(TEST_NAME "${group_name}_${TEST_NAME}")
|
||||||
|
@ -171,6 +171,7 @@ private:
|
|||||||
std::unordered_map<std::string, T> m = {{"1s", 1}};
|
std::unordered_map<std::string, T> m = {{"1s", 1}};
|
||||||
for (auto &&item : m) {
|
for (auto &&item : m) {
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinkToParent(Slice rel_path, ExposedVarGroup *parent) {
|
void LinkToParent(Slice rel_path, ExposedVarGroup *parent) {
|
||||||
|
327
tile/base/internal/logging.cc
Normal file
327
tile/base/internal/logging.cc
Normal file
@ -0,0 +1,327 @@
|
|||||||
|
#include "tile/base/internal/logging.h"
|
||||||
|
#include <cassert>
|
||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
#include <mutex>
|
||||||
|
#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);
|
||||||
|
}
|
||||||
|
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 {
|
||||||
|
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) {}
|
||||||
|
|
||||||
|
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 (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) {
|
||||||
|
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 (true) {
|
||||||
|
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);
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
ss.write(message, message_len);
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddLogSink(LogSink *dest) {
|
||||||
|
std::lock_guard<std::mutex> _(g_sink_mutex);
|
||||||
|
g_sinks.insert(dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoveLogSink(LogSink *dest) {
|
||||||
|
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 WaitForSinks() {
|
||||||
|
std::lock_guard<std::mutex> _(g_sink_mutex);
|
||||||
|
for (auto &&sink : g_sinks) {
|
||||||
|
sink->WaitTillSent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *GetLogSeverityName(LogSeverity 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 <cstdint>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
#include <set>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -17,31 +18,98 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
namespace tile {
|
namespace tile {
|
||||||
typedef int LogSeverity;
|
// typedef int LogSeverity;
|
||||||
const int TILE_INFO = 0, TILE_WARNING = 1, TILE_ERROR = 2, TILE_FATAL = 3;
|
// 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);
|
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 {
|
class LogMessage {
|
||||||
public:
|
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();
|
~LogMessage();
|
||||||
std::ostream &stream();
|
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:
|
private:
|
||||||
class Impl;
|
class Impl;
|
||||||
std::unique_ptr<Impl> impl_;
|
std::unique_ptr<Impl> impl_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class LogMessageFatal {
|
class LogMessageFatal : public LogMessage {
|
||||||
public:
|
public:
|
||||||
LogMessageFatal(const char *file, int line);
|
LogMessageFatal(const char *file, int line);
|
||||||
~LogMessageFatal();
|
~LogMessageFatal();
|
||||||
std::ostream &stream();
|
std::ostream &stream();
|
||||||
|
|
||||||
private:
|
|
||||||
class Impl;
|
|
||||||
std::unique_ptr<Impl> impl_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class LogMessageVoidify {
|
class LogMessageVoidify {
|
||||||
@ -599,6 +667,7 @@ struct LogMessageTime {
|
|||||||
LogMessageTime();
|
LogMessageTime();
|
||||||
LogMessageTime(std::tm t);
|
LogMessageTime(std::tm t);
|
||||||
LogMessageTime(std::time_t timestamp, WallTime now);
|
LogMessageTime(std::time_t timestamp, WallTime now);
|
||||||
|
LogMessageTime(std::chrono::system_clock::time_point tp);
|
||||||
|
|
||||||
const time_t ×tamp() const { return timestamp_; }
|
const time_t ×tamp() const { return timestamp_; }
|
||||||
const int &sec() const { return time_struct_.tm_sec; }
|
const int &sec() const { return time_struct_.tm_sec; }
|
||||||
@ -637,15 +706,14 @@ public:
|
|||||||
size_t message_len);
|
size_t message_len);
|
||||||
};
|
};
|
||||||
|
|
||||||
class FileLogSink : public LogSink {
|
|
||||||
public:
|
|
||||||
FileLogSink(const std::string &file_path_template);
|
|
||||||
};
|
|
||||||
|
|
||||||
void AddLogSink(LogSink *dest);
|
void AddLogSink(LogSink *dest);
|
||||||
void RemoveLogSink(LogSink *dest);
|
void RemoveLogSink(LogSink *dest);
|
||||||
void SetStderrLogging(LogSeverity min_severity);
|
void SetStderrLogging(LogSeverity min_severity);
|
||||||
void LogToStderr();
|
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);
|
const char *GetLogSeverityName(LogSeverity severity);
|
||||||
|
|
||||||
} // namespace tile
|
} // namespace tile
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "tile/base/internal/logging.h"
|
#include "tile/base/internal/logging.h"
|
||||||
|
#include "tile/base/logging/splitter_sink.h"
|
||||||
|
|
||||||
// #define TILE_VLOG(n, ...)
|
// #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 "tile/net/internal/http_engine.h"
|
||||||
|
|
||||||
#include "gflags/gflags.h"
|
#include "gflags/gflags.h"
|
||||||
#include "glog/logging.h"
|
// #include "glog/logging.h"
|
||||||
#include "glog/raw_logging.h"
|
// #include "glog/raw_logging.h"
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
@ -33,7 +33,8 @@ std::atomic<bool> g_quit_siganl{false};
|
|||||||
void QuitSignalHandler(int sig) {
|
void QuitSignalHandler(int sig) {
|
||||||
auto old = g_quit_siganl.exchange(true, std::memory_order_relaxed);
|
auto old = g_quit_siganl.exchange(true, std::memory_order_relaxed);
|
||||||
if (old && FLAGS_tile_abort_on_double_quit_signal) {
|
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,
|
int Start(int argc, char **argv, std::function<int(int, char **)> cb,
|
||||||
bool single_thread, bool enable_crash_catch) {
|
bool single_thread, bool enable_crash_catch) {
|
||||||
// glog
|
|
||||||
if (enable_crash_catch) {
|
if (enable_crash_catch) {
|
||||||
google::InstallFailureSignalHandler();
|
// TODO: Add InstallFailureSignalHandler
|
||||||
|
// google::InstallFailureSignalHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init gflags
|
// Init gflags
|
||||||
@ -59,8 +60,8 @@ int Start(int argc, char **argv, std::function<int(int, char **)> cb,
|
|||||||
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||||
detail::ApplyFlagOverrider();
|
detail::ApplyFlagOverrider();
|
||||||
|
|
||||||
// Init Glog
|
// TODO: Add Init log level
|
||||||
google::InitGoogleLogging(argv[0]);
|
// google::InitGoogleLogging(argv[0]);
|
||||||
|
|
||||||
TILE_LOG_INFO("Tile started. version: {}", TILE_VERSION);
|
TILE_LOG_INFO("Tile started. version: {}", TILE_VERSION);
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
#include "benchmark/benchmark.h"
|
#include "benchmark/benchmark.h"
|
||||||
|
|
||||||
#include "gflags/gflags.h"
|
#include "gflags/gflags.h"
|
||||||
#include "glog/logging.h"
|
|
||||||
#include "tile/base/logging.h"
|
#include "tile/base/logging.h"
|
||||||
#include "tile/init.h"
|
#include "tile/init.h"
|
||||||
|
|
||||||
@ -11,20 +10,18 @@ namespace tile {
|
|||||||
namespace testing {
|
namespace testing {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
int
|
int StartBenchmark(int argc, char **argv) {
|
||||||
StartBenchmark(int argc, char **argv)
|
|
||||||
{
|
|
||||||
::benchmark::Initialize(&argc, argv);
|
::benchmark::Initialize(&argc, argv);
|
||||||
if (::benchmark::ReportUnrecognizedArguments(argc, argv)) { return 1; }
|
if (::benchmark::ReportUnrecognizedArguments(argc, argv)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
::benchmark::RunSpecifiedBenchmarks();
|
::benchmark::RunSpecifiedBenchmarks();
|
||||||
::benchmark::Shutdown();
|
::benchmark::Shutdown();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
int
|
int InitAndRunAllBenchmarks(int *argc, char **argv) {
|
||||||
InitAndRunAllBenchmarks(int *argc, char **argv)
|
|
||||||
{
|
|
||||||
|
|
||||||
// if (gflags::GetCommandLineFlagInfoOrDie("logtostderr").is_default) {
|
// if (gflags::GetCommandLineFlagInfoOrDie("logtostderr").is_default) {
|
||||||
// FLAGS_logtostderr = true;
|
// FLAGS_logtostderr = true;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#include "tile/testing/main.h"
|
#include "tile/testing/main.h"
|
||||||
|
|
||||||
#include "gflags/gflags.h"
|
#include "gflags/gflags.h"
|
||||||
#include "glog/logging.h"
|
// #include "glog/logging.h"
|
||||||
#include "tile/init.h"
|
#include "tile/init.h"
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user