feat/update_config #10
@ -2128,7 +2128,7 @@ nsel_DISABLE_MSVC_WARNINGS(26409)
|
|||||||
: make_unexpected(detail::invoke(std::forward<F>(f), std::move(error())));
|
: make_unexpected(detail::invoke(std::forward<F>(f), std::move(error())));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif// nsel_P2505R >= 3
|
#endif// nsel_P2505R >= 3 \
|
||||||
// unwrap()
|
// unwrap()
|
||||||
|
|
||||||
// template <class U, class E>
|
// template <class U, class E>
|
||||||
|
@ -174,7 +174,6 @@ private:
|
|||||||
{"1s", 1}
|
{"1s", 1}
|
||||||
};
|
};
|
||||||
for (auto &&item : m) {}
|
for (auto &&item : m) {}
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ GetProviers()
|
|||||||
static std::vector<PrefixAppender *> providers;
|
static std::vector<PrefixAppender *> providers;
|
||||||
return &providers;
|
return &providers;
|
||||||
}
|
}
|
||||||
} // namespace
|
}// namespace
|
||||||
|
|
||||||
namespace details {
|
namespace details {
|
||||||
std::string
|
std::string
|
||||||
@ -24,9 +24,11 @@ DescribeFormatArguments(const std::vector<std::string> &args)
|
|||||||
{
|
{
|
||||||
return fmt::format("{}", fmt::join(args.begin(), args.end(), ", "));
|
return fmt::format("{}", fmt::join(args.begin(), args.end(), ", "));
|
||||||
}
|
}
|
||||||
} // namespace details
|
}// namespace details
|
||||||
|
|
||||||
void InstallPrefixProvider(PrefixAppender *writer) {
|
void
|
||||||
|
InstallPrefixProvider(PrefixAppender *writer)
|
||||||
|
{
|
||||||
GetProviers()->push_back(writer);
|
GetProviers()->push_back(writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,9 +41,9 @@ WritePrefixTo(std::string *to)
|
|||||||
if (to->size() != was) { to->push_back(' '); }
|
if (to->size() != was) { to->push_back(' '); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace logging
|
}// namespace logging
|
||||||
} // namespace internal
|
}// namespace internal
|
||||||
} // namespace tile
|
}// namespace tile
|
||||||
|
|
||||||
namespace tile {
|
namespace tile {
|
||||||
static std::mutex g_sink_mutex;
|
static std::mutex g_sink_mutex;
|
||||||
@ -61,32 +63,39 @@ private:
|
|||||||
std::ostream &ostream_;
|
std::ostream &ostream_;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool VLogIsOn(int n) { return true; }
|
bool
|
||||||
|
VLogIsOn(int n)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
class LogMessage::Impl {
|
class LogMessage::Impl {
|
||||||
public:
|
public:
|
||||||
Impl(const char *file, int line)
|
Impl(const char *file, int line) : stream_(message_text_, LogMessage::kMaxLogMessageLen, 0)
|
||||||
: stream_(message_text_, LogMessage::kMaxLogMessageLen, 0) {
|
{
|
||||||
Init(file, line, TILE_INFO, &LogMessage::Impl::SendToLog);
|
Init(file, line, TILE_INFO, &LogMessage::Impl::SendToLog);
|
||||||
}
|
}
|
||||||
Impl(const char *file, int line, LogSeverity severity)
|
|
||||||
: stream_(message_text_, LogMessage::kMaxLogMessageLen, 0) {
|
Impl(const char *file, int line, LogSeverity severity) : stream_(message_text_, LogMessage::kMaxLogMessageLen, 0)
|
||||||
|
{
|
||||||
Init(file, line, severity, &LogMessage::Impl::SendToLog);
|
Init(file, line, severity, &LogMessage::Impl::SendToLog);
|
||||||
}
|
}
|
||||||
Impl(const char *file, int line, LogSeverity severity, LogSink *sink,
|
|
||||||
bool also_send_to_log)
|
Impl(const char *file, int line, LogSeverity severity, LogSink *sink, bool also_send_to_log)
|
||||||
: stream_(message_text_, LogMessage::kMaxLogMessageLen, 0) {
|
: stream_(message_text_, LogMessage::kMaxLogMessageLen, 0)
|
||||||
|
{
|
||||||
Init(file, line, severity,
|
Init(file, line, severity,
|
||||||
also_send_to_log ? &LogMessage::Impl::SendToSinkAndLog
|
also_send_to_log ? &LogMessage::Impl::SendToSinkAndLog : &LogMessage::Impl::SendToSink);
|
||||||
: &LogMessage::Impl::SendToSink);
|
|
||||||
sink_ = sink;
|
sink_ = sink;
|
||||||
}
|
}
|
||||||
|
|
||||||
~Impl() { Flush(); }
|
~Impl() { Flush(); }
|
||||||
|
|
||||||
std::ostream &stream() { return stream_; }
|
std::ostream &stream() { return stream_; }
|
||||||
void Flush() {
|
|
||||||
if (has_been_flushed_) {
|
void Flush()
|
||||||
return;
|
{
|
||||||
}
|
if (has_been_flushed_) { return; }
|
||||||
|
|
||||||
num_chars_to_log_ = stream_.pcount();
|
num_chars_to_log_ = stream_.pcount();
|
||||||
const bool append_newline = message_text_[num_chars_to_log_ - 1] != '\n';
|
const bool append_newline = message_text_[num_chars_to_log_ - 1] != '\n';
|
||||||
@ -103,35 +112,32 @@ public:
|
|||||||
(this->*(send_method_))();
|
(this->*(send_method_))();
|
||||||
++g_num_messages[severity_];
|
++g_num_messages[severity_];
|
||||||
WaitForSinks();
|
WaitForSinks();
|
||||||
if (sink_) {
|
if (sink_) { sink_->Flush(); }
|
||||||
sink_->Flush();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (append_newline) {
|
if (append_newline) { message_text_[num_chars_to_log_ - 1] = original_final_char; }
|
||||||
message_text_[num_chars_to_log_ - 1] = original_final_char;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (preserved_errno_ != 0) {
|
if (preserved_errno_ != 0) { errno = preserved_errno_; }
|
||||||
errno = preserved_errno_;
|
|
||||||
}
|
|
||||||
has_been_flushed_ = true;
|
has_been_flushed_ = true;
|
||||||
|
|
||||||
if (severity_ == TILE_FATAL) {
|
if (severity_ == TILE_FATAL) { assert(false); }
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LogSeverity severity() const noexcept { return severity_; }
|
LogSeverity severity() const noexcept { return severity_; }
|
||||||
|
|
||||||
int line() const noexcept { return line_; }
|
int line() const noexcept { return line_; }
|
||||||
|
|
||||||
const char *fullname() const noexcept { return file_; }
|
const char *fullname() const noexcept { return file_; }
|
||||||
|
|
||||||
const char *basename() const noexcept { return file_; }
|
const char *basename() const noexcept { return file_; }
|
||||||
|
|
||||||
const LogMessageTime &time() const noexcept { return time_; }
|
const LogMessageTime &time() const noexcept { return time_; }
|
||||||
|
|
||||||
int preserved_errno() const { return preserved_errno_; }
|
int preserved_errno() const { return preserved_errno_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Init(const char *file, int line, LogSeverity severity,
|
void Init(const char *file, int line, LogSeverity severity, void (LogMessage::Impl::*send_method)())
|
||||||
void (LogMessage::Impl::*send_method)()) {
|
{
|
||||||
has_been_flushed_ = false;
|
has_been_flushed_ = false;
|
||||||
file_ = file;
|
file_ = file;
|
||||||
line_ = line;
|
line_ = line;
|
||||||
@ -144,23 +150,25 @@ private:
|
|||||||
preserved_errno_ = errno;
|
preserved_errno_ = errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendToSink() {
|
void SendToSink()
|
||||||
|
{
|
||||||
if (sink_) {
|
if (sink_) {
|
||||||
sink_->Send(severity_, fullname(), basename(), line(), time(),
|
sink_->Send(severity_, fullname(), basename(), line(), time(), message_text_ + num_prefix_chars_,
|
||||||
message_text_ + num_prefix_chars_,
|
num_chars_to_log_ - num_prefix_chars_ - 1);
|
||||||
num_chars_to_log_ - num_prefix_chars_);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void SendToLog() {
|
|
||||||
|
void SendToLog()
|
||||||
|
{
|
||||||
if (g_sink_count.load(std::memory_order_relaxed) == 0) {
|
if (g_sink_count.load(std::memory_order_relaxed) == 0) {
|
||||||
ColoredWriteToStdout(severity_, message_text_ + num_prefix_chars_,
|
ColoredWriteToStdout(severity_, message_text_ + num_prefix_chars_, num_chars_to_log_ - num_chars_to_log_);
|
||||||
num_chars_to_log_ - num_chars_to_log_);
|
|
||||||
}
|
}
|
||||||
LogToSinks(severity_, fullname(), basename(), line(), time(),
|
LogToSinks(severity_, fullname(), basename(), line(), time(), message_text_ + num_prefix_chars_,
|
||||||
message_text_ + num_prefix_chars_,
|
num_chars_to_log_ - num_prefix_chars_ - 1);
|
||||||
num_chars_to_log_ - num_prefix_chars_);
|
|
||||||
}
|
}
|
||||||
void SendToSinkAndLog() {
|
|
||||||
|
void SendToSinkAndLog()
|
||||||
|
{
|
||||||
SendToSink();
|
SendToSink();
|
||||||
SendToLog();
|
SendToLog();
|
||||||
}
|
}
|
||||||
@ -185,44 +193,84 @@ private:
|
|||||||
size_t num_chars_to_log_;
|
size_t num_chars_to_log_;
|
||||||
};
|
};
|
||||||
|
|
||||||
LogMessage::LogMessage(const char *file, int line)
|
LogMessage::LogMessage(const char *file, int line) : impl_(new Impl(file, line)) {}
|
||||||
: impl_(new Impl(file, line)) {}
|
|
||||||
LogMessage::LogMessage(const char *file, int line, LogSeverity severity)
|
LogMessage::LogMessage(const char *file, int line, LogSeverity severity) : impl_(new Impl(file, line, severity)) {}
|
||||||
: impl_(new Impl(file, line, severity)) {}
|
|
||||||
LogMessage::LogMessage(const char *file, int line, LogSeverity severity,
|
LogMessage::LogMessage(const char *file, int line, LogSeverity severity, LogSink *sink, bool also_send_to_log)
|
||||||
LogSink *sink, bool also_send_to_log)
|
: impl_(new Impl(file, line, severity, sink, also_send_to_log))
|
||||||
: impl_(new Impl(file, line, severity, sink, also_send_to_log)) {}
|
{}
|
||||||
|
|
||||||
LogMessage::~LogMessage() {}
|
LogMessage::~LogMessage() {}
|
||||||
|
|
||||||
std::ostream &LogMessage::stream() { return impl_->stream(); }
|
std::ostream &
|
||||||
void LogMessage::Flush() { impl_->Flush(); }
|
LogMessage::stream()
|
||||||
|
{
|
||||||
|
return impl_->stream();
|
||||||
|
}
|
||||||
|
|
||||||
LogSeverity LogMessage::severity() const noexcept { return impl_->severity(); }
|
void
|
||||||
int LogMessage::line() const noexcept { return impl_->line(); }
|
LogMessage::Flush()
|
||||||
const char *LogMessage::fullname() const noexcept { return impl_->fullname(); }
|
{
|
||||||
const char *LogMessage::basename() const noexcept { return impl_->basename(); }
|
impl_->Flush();
|
||||||
const LogMessageTime &LogMessage::time() const noexcept {
|
}
|
||||||
|
|
||||||
|
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();
|
return impl_->time();
|
||||||
}
|
}
|
||||||
int LogMessage::preserved_errno() const { return impl_->preserved_errno(); }
|
|
||||||
|
|
||||||
LogMessageFatal::LogMessageFatal(const char *file, int line)
|
int
|
||||||
: LogMessage(file, line, TILE_FATAL) {}
|
LogMessage::preserved_errno() const
|
||||||
|
{
|
||||||
|
return impl_->preserved_errno();
|
||||||
|
}
|
||||||
|
|
||||||
|
LogMessageFatal::LogMessageFatal(const char *file, int line) : LogMessage(file, line, TILE_FATAL) {}
|
||||||
|
|
||||||
LogMessageFatal::~LogMessageFatal() {}
|
LogMessageFatal::~LogMessageFatal() {}
|
||||||
|
|
||||||
std::ostream &LogMessageFatal::stream() { return LogMessage::stream(); }
|
std::ostream &
|
||||||
|
LogMessageFatal::stream()
|
||||||
|
{
|
||||||
|
return LogMessage::stream();
|
||||||
|
}
|
||||||
|
|
||||||
LogMessageTime::LogMessageTime() : time_struct_(), timestamp_(0), usecs_(0), gmtoffset_(0) {}
|
LogMessageTime::LogMessageTime() : time_struct_(), timestamp_(0), usecs_(0), gmtoffset_(0) {}
|
||||||
|
|
||||||
LogMessageTime::LogMessageTime(std::tm t) : use_localtime_(true) {
|
LogMessageTime::LogMessageTime(std::tm t) : use_localtime_(true)
|
||||||
|
{
|
||||||
std::time_t timestamp = std::mktime(&t);
|
std::time_t timestamp = std::mktime(&t);
|
||||||
init(t, timestamp, 0);
|
init(t, timestamp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime now)
|
LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime now) : use_localtime_(false)
|
||||||
: use_localtime_(false) {
|
{
|
||||||
std::tm t;
|
std::tm t;
|
||||||
if (use_localtime_) {
|
if (use_localtime_) {
|
||||||
localtime_r(×tamp, &t);
|
localtime_r(×tamp, &t);
|
||||||
@ -232,8 +280,9 @@ LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime now)
|
|||||||
|
|
||||||
init(t, timestamp, now);
|
init(t, timestamp, now);
|
||||||
}
|
}
|
||||||
LogMessageTime::LogMessageTime(std::chrono::system_clock::time_point tp)
|
|
||||||
: use_localtime_(false) {
|
LogMessageTime::LogMessageTime(std::chrono::system_clock::time_point tp) : use_localtime_(false)
|
||||||
|
{
|
||||||
std::time_t timestamp = std::chrono::system_clock::to_time_t(tp);
|
std::time_t timestamp = std::chrono::system_clock::to_time_t(tp);
|
||||||
std::tm t;
|
std::tm t;
|
||||||
if (use_localtime_) {
|
if (use_localtime_) {
|
||||||
@ -243,14 +292,12 @@ LogMessageTime::LogMessageTime(std::chrono::system_clock::time_point tp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
init(t, timestamp, 0);
|
init(t, timestamp, 0);
|
||||||
usecs_ = std::chrono::duration_cast<std::chrono::microseconds>(
|
usecs_ = std::chrono::duration_cast<std::chrono::microseconds>(tp.time_since_epoch()).count() % 1000000;
|
||||||
tp.time_since_epoch())
|
|
||||||
.count() %
|
|
||||||
1000000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogMessageTime::init(const std::tm &t, std::time_t timestamp,
|
void
|
||||||
WallTime now) {
|
LogMessageTime::init(const std::tm &t, std::time_t timestamp, WallTime now)
|
||||||
|
{
|
||||||
time_struct_ = t;
|
time_struct_ = t;
|
||||||
timestamp_ = timestamp;
|
timestamp_ = timestamp;
|
||||||
if (now < timestamp) {
|
if (now < timestamp) {
|
||||||
@ -262,7 +309,9 @@ void LogMessageTime::init(const std::tm &t, std::time_t timestamp,
|
|||||||
CalcGmtOffset();
|
CalcGmtOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogMessageTime::CalcGmtOffset() {
|
void
|
||||||
|
LogMessageTime::CalcGmtOffset()
|
||||||
|
{
|
||||||
std::tm gmt_struct;
|
std::tm gmt_struct;
|
||||||
int isDst = 0;
|
int isDst = 0;
|
||||||
if (true) {
|
if (true) {
|
||||||
@ -282,14 +331,15 @@ void LogMessageTime::CalcGmtOffset() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LogSink::~LogSink() {}
|
LogSink::~LogSink() {}
|
||||||
bool LogSink::ShouldLog(LogSeverity severity) { return true; }
|
|
||||||
void LogSink::Send(LogSeverity severity, const char *full_filename,
|
bool
|
||||||
const char *base_filename, int line,
|
LogSink::ShouldLog(LogSeverity severity)
|
||||||
const LogMessageTime &logmsgtime, const char *message,
|
{
|
||||||
size_t message_len) {
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
LogSink::send(LogSeverity severity,
|
LogSink::Send(LogSeverity severity,
|
||||||
const char *full_filename,
|
const char *full_filename,
|
||||||
const char *base_filename,
|
const char *base_filename,
|
||||||
int line,
|
int line,
|
||||||
@ -300,18 +350,24 @@ LogSink::send(LogSeverity severity,
|
|||||||
|
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
void LogSink::Flush() {}
|
|
||||||
|
|
||||||
std::string LogSink::ToString(LogSeverity severity, const char *file,
|
void
|
||||||
const char *base_filename, int line,
|
LogSink::Flush()
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
LogSink::ToString(LogSeverity severity,
|
||||||
|
const char *file,
|
||||||
|
const char *base_filename,
|
||||||
|
int line,
|
||||||
const LogMessageTime &logmsgtime,
|
const LogMessageTime &logmsgtime,
|
||||||
const char *message, size_t message_len) {
|
const char *message,
|
||||||
|
size_t message_len)
|
||||||
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
char date_time[64];
|
char date_time[64];
|
||||||
sprintf(date_time, "%4d-%02d-%02dT%02d:%02d:%02d.%06d",
|
sprintf(date_time, "%4d-%02d-%02dT%02d:%02d:%02d.%06d", logmsgtime.year() + 1900, logmsgtime.month(),
|
||||||
logmsgtime.year() + 1900, logmsgtime.month(), logmsgtime.day(),
|
logmsgtime.day(), logmsgtime.hour(), logmsgtime.min(), logmsgtime.sec(), logmsgtime.usec());
|
||||||
logmsgtime.hour(), logmsgtime.min(), logmsgtime.sec(),
|
|
||||||
logmsgtime.usec());
|
|
||||||
|
|
||||||
ss << date_time;
|
ss << date_time;
|
||||||
|
|
||||||
@ -333,63 +389,83 @@ std::string LogSink::ToString(LogSeverity severity, const char *file,
|
|||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ColoredWriteToStderrOrStdout(FILE *output, LogSeverity severity,
|
static void
|
||||||
const char *message, size_t len) {
|
ColoredWriteToStderrOrStdout(FILE *output, LogSeverity severity, const char *message, size_t len)
|
||||||
|
{
|
||||||
fwrite(message, len, 1, output);
|
fwrite(message, len, 1, output);
|
||||||
fflush(output);
|
fflush(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColoredWriteToStdout(LogSeverity severity, const char *message,
|
void
|
||||||
size_t len) {
|
ColoredWriteToStdout(LogSeverity severity, const char *message, size_t len)
|
||||||
|
{
|
||||||
FILE *output = stdout;
|
FILE *output = stdout;
|
||||||
if (severity >= TILE_FATAL) {
|
if (severity >= TILE_FATAL) { output = stderr; }
|
||||||
output = stderr;
|
|
||||||
}
|
|
||||||
ColoredWriteToStderrOrStdout(output, severity, message, len);
|
ColoredWriteToStderrOrStdout(output, severity, message, len);
|
||||||
}
|
}
|
||||||
void ColoredWriteToStderr(LogSeverity severity, const char *message,
|
|
||||||
size_t len) {
|
void
|
||||||
|
ColoredWriteToStderr(LogSeverity severity, const char *message, size_t len)
|
||||||
|
{
|
||||||
ColoredWriteToStderrOrStdout(stderr, severity, message, len);
|
ColoredWriteToStderrOrStdout(stderr, severity, message, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddLogSink(LogSink::Ptr dest) {
|
void
|
||||||
|
AddLogSink(LogSink::Ptr dest)
|
||||||
|
{
|
||||||
std::lock_guard<std::mutex> _(g_sink_mutex);
|
std::lock_guard<std::mutex> _(g_sink_mutex);
|
||||||
g_sinks.insert(dest);
|
g_sinks.insert(dest);
|
||||||
g_sink_count.fetch_add(1);
|
g_sink_count.fetch_add(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoveLogSink(LogSink::Ptr dest) {
|
void
|
||||||
|
RemoveLogSink(LogSink::Ptr dest)
|
||||||
|
{
|
||||||
std::lock_guard<std::mutex> _(g_sink_mutex);
|
std::lock_guard<std::mutex> _(g_sink_mutex);
|
||||||
g_sinks.erase(dest);
|
g_sinks.erase(dest);
|
||||||
g_sink_count.fetch_sub(1);
|
g_sink_count.fetch_sub(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetStderrLogging(LogSeverity min_severity) {}
|
void
|
||||||
void LogToStderr() {}
|
SetStderrLogging(LogSeverity min_severity)
|
||||||
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
|
||||||
|
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);
|
std::lock_guard<std::mutex> _(g_sink_mutex);
|
||||||
for (auto &&sink : g_sinks) {
|
for (auto &&sink : g_sinks) {
|
||||||
if (sink->ShouldLog(severity)) {
|
if (sink->ShouldLog(severity)) {
|
||||||
sink->Send(severity, full_filename, base_filename, line, time, message,
|
sink->Send(severity, full_filename, base_filename, line, time, message, message_len);
|
||||||
message_len);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void WaitForSinks() {
|
|
||||||
std::lock_guard<std::mutex> _(g_sink_mutex);
|
|
||||||
for (auto &&sink : g_sinks) {
|
|
||||||
sink->Flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *GetLogSeverityName(LogSeverity severity) {
|
void
|
||||||
|
WaitForSinks()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> _(g_sink_mutex);
|
||||||
|
for (auto &&sink : g_sinks) { sink->Flush(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
GetLogSeverityName(LogSeverity severity)
|
||||||
|
{
|
||||||
const static std::map<LogSeverity, const char *> severity_names = {
|
const static std::map<LogSeverity, const char *> severity_names = {
|
||||||
{TILE_INFO, "INFO"},
|
{TILE_INFO, "INFO" },
|
||||||
{TILE_WARNING, "WARNING"},
|
{TILE_WARNING, "WARNING"},
|
||||||
{TILE_ERROR, "ERROR"},
|
{TILE_ERROR, "ERROR" },
|
||||||
{TILE_FATAL, "FATAL"},
|
{TILE_FATAL, "FATAL" },
|
||||||
};
|
};
|
||||||
|
|
||||||
auto iter = severity_names.find(severity);
|
auto iter = severity_names.find(severity);
|
||||||
@ -400,4 +476,4 @@ const char *GetLogSeverityName(LogSeverity severity) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace tile
|
}// namespace tile
|
||||||
|
@ -35,28 +35,35 @@ public:
|
|||||||
LogStreamBuf(char *buf, int len) { setp(buf, buf + len - 2); }
|
LogStreamBuf(char *buf, int len) { setp(buf, buf + len - 2); }
|
||||||
|
|
||||||
int_type overflow(int_type ch) { return ch; }
|
int_type overflow(int_type ch) { return ch; }
|
||||||
|
|
||||||
size_t pcount() const { return static_cast<size_t>(pptr() - pbase()); }
|
size_t pcount() const { return static_cast<size_t>(pptr() - pbase()); }
|
||||||
|
|
||||||
char *pbase() const { return std::streambuf::pbase(); }
|
char *pbase() const { return std::streambuf::pbase(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class LogSink;
|
class LogSink;
|
||||||
class LogMessageTime;
|
class LogMessageTime;
|
||||||
|
|
||||||
class LogMessage {
|
class LogMessage {
|
||||||
public:
|
public:
|
||||||
class LogStream : public std::ostream {
|
class LogStream : public std::ostream {
|
||||||
public:
|
public:
|
||||||
LogStream(char *buf, int len, int64_t ctr)
|
LogStream(char *buf, int len, int64_t ctr) : std::ostream(nullptr), streambuf_(buf, len), ctr_(ctr), self_(this)
|
||||||
: std::ostream(nullptr), streambuf_(buf, len), ctr_(ctr), self_(this) {
|
{
|
||||||
rdbuf(&streambuf_);
|
rdbuf(&streambuf_);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogStream(LogStream &other) noexcept
|
LogStream(LogStream &other) noexcept
|
||||||
: std::ostream(nullptr), streambuf_(std::move(other.streambuf_)),
|
: std::ostream(nullptr),
|
||||||
ctr_(internal::Exchange(other.ctr_, 0)), self_(this) {
|
streambuf_(std::move(other.streambuf_)),
|
||||||
|
ctr_(internal::Exchange(other.ctr_, 0)),
|
||||||
|
self_(this)
|
||||||
|
{
|
||||||
rdbuf(&streambuf_);
|
rdbuf(&streambuf_);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogStream &operator=(LogStream &&other) noexcept {
|
LogStream &operator=(LogStream &&other) noexcept
|
||||||
|
{
|
||||||
streambuf_ = std::move(other.streambuf_);
|
streambuf_ = std::move(other.streambuf_);
|
||||||
ctr_ = internal::Exchange(other.ctr_, 0);
|
ctr_ = internal::Exchange(other.ctr_, 0);
|
||||||
self_ = this;
|
self_ = this;
|
||||||
@ -65,12 +72,15 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int64_t ctr() const { return ctr_; }
|
int64_t ctr() const { return ctr_; }
|
||||||
|
|
||||||
void set_ctr(int64_t ctr) { ctr_ = ctr; }
|
void set_ctr(int64_t ctr) { ctr_ = ctr; }
|
||||||
|
|
||||||
LogStream *self() { return self_; }
|
LogStream *self() { return self_; }
|
||||||
|
|
||||||
size_t pcount() const { return streambuf_.pcount(); }
|
size_t pcount() const { return streambuf_.pcount(); }
|
||||||
|
|
||||||
char *pbase() const { return streambuf_.pbase(); }
|
char *pbase() const { return streambuf_.pbase(); }
|
||||||
|
|
||||||
char *str() const { return pbase(); }
|
char *str() const { return pbase(); }
|
||||||
|
|
||||||
LogStream(const LogStream &) = delete;
|
LogStream(const LogStream &) = delete;
|
||||||
@ -86,8 +96,7 @@ public:
|
|||||||
static const size_t kMaxLogMessageLen = 30000;
|
static const size_t kMaxLogMessageLen = 30000;
|
||||||
LogMessage(const char *file, int line);
|
LogMessage(const char *file, int line);
|
||||||
LogMessage(const char *file, int line, LogSeverity severity);
|
LogMessage(const char *file, int line, LogSeverity severity);
|
||||||
LogMessage(const char *file, int line, LogSeverity severity, LogSink *sink,
|
LogMessage(const char *file, int line, LogSeverity severity, LogSink *sink, bool also_send_to_log = true);
|
||||||
bool also_send_to_log = true);
|
|
||||||
|
|
||||||
~LogMessage();
|
~LogMessage();
|
||||||
std::ostream &stream();
|
std::ostream &stream();
|
||||||
@ -550,6 +559,7 @@ FormatLog(const char *file, int line, Ts &&...args) noexcept
|
|||||||
|
|
||||||
namespace tile {
|
namespace tile {
|
||||||
typedef double WallTime;
|
typedef double WallTime;
|
||||||
|
|
||||||
struct LogMessageTime {
|
struct LogMessageTime {
|
||||||
LogMessageTime();
|
LogMessageTime();
|
||||||
LogMessageTime(std::tm t);
|
LogMessageTime(std::tm t);
|
||||||
@ -557,23 +567,36 @@ struct LogMessageTime {
|
|||||||
LogMessageTime(std::chrono::system_clock::time_point tp);
|
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; }
|
||||||
|
|
||||||
const int32_t &usec() const { return usecs_; }
|
const int32_t &usec() const { return usecs_; }
|
||||||
const int &(min)() const { return time_struct_.tm_min; }
|
|
||||||
|
const int &(min) () const { return time_struct_.tm_min; }
|
||||||
|
|
||||||
const int &hour() const { return time_struct_.tm_hour; }
|
const int &hour() const { return time_struct_.tm_hour; }
|
||||||
|
|
||||||
const int &day() const { return time_struct_.tm_mday; }
|
const int &day() const { return time_struct_.tm_mday; }
|
||||||
|
|
||||||
const int &month() const { return time_struct_.tm_mon; }
|
const int &month() const { return time_struct_.tm_mon; }
|
||||||
|
|
||||||
const int &year() const { return time_struct_.tm_year; }
|
const int &year() const { return time_struct_.tm_year; }
|
||||||
|
|
||||||
const int &dayOfWeek() const { return time_struct_.tm_wday; }
|
const int &dayOfWeek() const { return time_struct_.tm_wday; }
|
||||||
|
|
||||||
const int &dayInYear() const { return time_struct_.tm_yday; }
|
const int &dayInYear() const { return time_struct_.tm_yday; }
|
||||||
|
|
||||||
const int &dst() const { return time_struct_.tm_isdst; }
|
const int &dst() const { return time_struct_.tm_isdst; }
|
||||||
|
|
||||||
const long int &gmtoff() const { return gmtoffset_; }
|
const long int &gmtoff() const { return gmtoffset_; }
|
||||||
|
|
||||||
const std::tm &tm() const { return time_struct_; }
|
const std::tm &tm() const { return time_struct_; }
|
||||||
|
|
||||||
const bool use_localtime() const { return use_localtime_; }
|
const bool use_localtime() const { return use_localtime_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init(const std::tm &t, std::time_t timestamp, WallTime now);
|
void init(const std::tm &t, std::time_t timestamp, WallTime now);
|
||||||
std::tm time_struct_; // Time of creation of LogMessage
|
std::tm time_struct_;// Time of creation of LogMessage
|
||||||
time_t timestamp_; // Time of creation of LogMessage in seconds
|
time_t timestamp_; // Time of creation of LogMessage in seconds
|
||||||
int32_t usecs_; // Time of creation of LogMessage - microseconds part
|
int32_t usecs_; // Time of creation of LogMessage - microseconds part
|
||||||
long int gmtoffset_;
|
long int gmtoffset_;
|
||||||
@ -588,28 +611,36 @@ public:
|
|||||||
|
|
||||||
virtual ~LogSink();
|
virtual ~LogSink();
|
||||||
virtual bool ShouldLog(LogSeverity severity);
|
virtual bool ShouldLog(LogSeverity severity);
|
||||||
virtual void Send(LogSeverity severity, const char *full_filename,
|
virtual void Send(LogSeverity severity,
|
||||||
const char *base_filename, int line,
|
const char *full_filename,
|
||||||
const LogMessageTime &logmsgtime, const char *message,
|
const char *base_filename,
|
||||||
|
int line,
|
||||||
|
const LogMessageTime &logmsgtime,
|
||||||
|
const char *message,
|
||||||
size_t message_len);
|
size_t message_len);
|
||||||
virtual void Flush();
|
virtual void Flush();
|
||||||
std::string ToString(LogSeverity severity, const char *file,
|
std::string ToString(LogSeverity severity,
|
||||||
const char *base_file, int line,
|
const char *file,
|
||||||
const LogMessageTime &logmsgtime, const char *message,
|
const char *base_file,
|
||||||
|
int line,
|
||||||
|
const LogMessageTime &logmsgtime,
|
||||||
|
const char *message,
|
||||||
size_t message_len);
|
size_t message_len);
|
||||||
};
|
};
|
||||||
|
|
||||||
void ColoredWriteToStdout(LogSeverity severity, const char *message,
|
void ColoredWriteToStdout(LogSeverity severity, const char *message, size_t len);
|
||||||
size_t len);
|
void ColoredWriteToStderr(LogSeverity severity, const char *message, size_t len);
|
||||||
void ColoredWriteToStderr(LogSeverity severity, const char *message,
|
|
||||||
size_t len);
|
|
||||||
void AddLogSink(LogSink::Ptr dest);
|
void AddLogSink(LogSink::Ptr dest);
|
||||||
void RemoveLogSink(LogSink::Ptr dest);
|
void RemoveLogSink(LogSink::Ptr dest);
|
||||||
void SetStderrLogging(LogSeverity min_severity);
|
void SetStderrLogging(LogSeverity min_severity);
|
||||||
void LogToStderr();
|
void LogToStderr();
|
||||||
void LogToSinks(LogSeverity severity, const char *full_filename,
|
void LogToSinks(LogSeverity severity,
|
||||||
const char *base_filename, int line, const LogMessageTime &time,
|
const char *full_filename,
|
||||||
const char *message, size_t message_len);
|
const char *base_filename,
|
||||||
|
int line,
|
||||||
|
const LogMessageTime &time,
|
||||||
|
const char *message,
|
||||||
|
size_t message_len);
|
||||||
void WaitForSinks();
|
void WaitForSinks();
|
||||||
const char *GetLogSeverityName(LogSeverity severity);
|
const char *GetLogSeverityName(LogSeverity severity);
|
||||||
|
|
||||||
|
@ -6,10 +6,16 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
namespace tile {
|
namespace tile {
|
||||||
bool VLogIsOn(int n) { return true; }
|
bool
|
||||||
|
VLogIsOn(int n)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
class LogMessage::Impl {
|
class LogMessage::Impl {
|
||||||
public:
|
public:
|
||||||
Impl(const char *file, int line, int severity) : lm_(file, line, severity) {}
|
Impl(const char *file, int line, int severity) : lm_(file, line, severity) {}
|
||||||
|
|
||||||
std::ostream &stream() { return lm_.stream(); }
|
std::ostream &stream() { return lm_.stream(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -19,65 +25,87 @@ private:
|
|||||||
class LogMessageFatal::Impl {
|
class LogMessageFatal::Impl {
|
||||||
public:
|
public:
|
||||||
Impl(const char *file, int line) : lm_(file, line) {}
|
Impl(const char *file, int line) : lm_(file, line) {}
|
||||||
|
|
||||||
std::ostream &stream() { return lm_.stream(); }
|
std::ostream &stream() { return lm_.stream(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
google::LogMessageFatal lm_;
|
google::LogMessageFatal lm_;
|
||||||
};
|
};
|
||||||
|
|
||||||
LogMessage::LogMessage(const char *file, int line, int severity)
|
LogMessage::LogMessage(const char *file, int line, int severity) : impl_(new Impl(file, line, severity)) {}
|
||||||
: impl_(new Impl(file, line, severity)) {}
|
|
||||||
LogMessage::~LogMessage() = default;
|
LogMessage::~LogMessage() = default;
|
||||||
std::ostream &LogMessage::stream() { return impl_->stream(); }
|
|
||||||
|
|
||||||
LogMessageFatal::LogMessageFatal(const char *file, int line)
|
std::ostream &
|
||||||
: impl_(new Impl(file, line)) {}
|
LogMessage::stream()
|
||||||
|
{
|
||||||
|
return impl_->stream();
|
||||||
|
}
|
||||||
|
|
||||||
|
LogMessageFatal::LogMessageFatal(const char *file, int line) : impl_(new Impl(file, line)) {}
|
||||||
|
|
||||||
LogMessageFatal::~LogMessageFatal() = default;
|
LogMessageFatal::~LogMessageFatal() = default;
|
||||||
std::ostream &LogMessageFatal::stream() { return impl_->stream(); }
|
|
||||||
|
|
||||||
} // namespace tile
|
std::ostream &
|
||||||
|
LogMessageFatal::stream()
|
||||||
|
{
|
||||||
|
return impl_->stream();
|
||||||
|
}
|
||||||
|
|
||||||
|
}// namespace tile
|
||||||
|
|
||||||
namespace tile {
|
namespace tile {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
namespace logging {
|
namespace logging {
|
||||||
namespace {
|
namespace {
|
||||||
std::vector<PrefixAppender *> *GetProviers() {
|
std::vector<PrefixAppender *> *
|
||||||
|
GetProviers()
|
||||||
|
{
|
||||||
static std::vector<PrefixAppender *> providers;
|
static std::vector<PrefixAppender *> providers;
|
||||||
return &providers;
|
return &providers;
|
||||||
}
|
}
|
||||||
} // namespace
|
}// namespace
|
||||||
|
|
||||||
namespace details {
|
namespace details {
|
||||||
std::string DescribeFormatArguments(const std::vector<std::string> &args) {
|
std::string
|
||||||
|
DescribeFormatArguments(const std::vector<std::string> &args)
|
||||||
|
{
|
||||||
return fmt::format("{}", fmt::join(args.begin(), args.end(), ", "));
|
return fmt::format("{}", fmt::join(args.begin(), args.end(), ", "));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace details
|
}// namespace details
|
||||||
void InstallPrefixProvider(PrefixAppender *writer) {
|
|
||||||
|
void
|
||||||
|
InstallPrefixProvider(PrefixAppender *writer)
|
||||||
|
{
|
||||||
GetProviers()->push_back(writer);
|
GetProviers()->push_back(writer);
|
||||||
}
|
}
|
||||||
void WritePrefixTo(std::string *to) {
|
|
||||||
|
void
|
||||||
|
WritePrefixTo(std::string *to)
|
||||||
|
{
|
||||||
for (auto &&appender : *GetProviers()) {
|
for (auto &&appender : *GetProviers()) {
|
||||||
auto was = to->size();
|
auto was = to->size();
|
||||||
appender(to);
|
appender(to);
|
||||||
if (to->size() != was) {
|
if (to->size() != was) { to->push_back(' '); }
|
||||||
to->push_back(' ');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace logging
|
}// namespace logging
|
||||||
} // namespace internal
|
}// namespace internal
|
||||||
} // namespace tile
|
}// namespace tile
|
||||||
|
|
||||||
namespace tile {
|
namespace tile {
|
||||||
|
|
||||||
LogMessageTime::LogMessageTime()
|
LogMessageTime::LogMessageTime() : time_struct_(), timestamp_(0), usecs_(0), gmtoffset_(0) {}
|
||||||
: time_struct_(), timestamp_(0), usecs_(0), gmtoffset_(0) {}
|
|
||||||
|
|
||||||
LogMessageTime::LogMessageTime(std::tm t) {
|
LogMessageTime::LogMessageTime(std::tm t)
|
||||||
|
{
|
||||||
std::time_t timestamp = std::mktime(&t);
|
std::time_t timestamp = std::mktime(&t);
|
||||||
init(t, timestamp, 0);
|
init(t, timestamp, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime now) {
|
LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime now)
|
||||||
|
{
|
||||||
std::tm t;
|
std::tm t;
|
||||||
if (FLAGS_log_utc_time)
|
if (FLAGS_log_utc_time)
|
||||||
gmtime_r(×tamp, &t);
|
gmtime_r(×tamp, &t);
|
||||||
@ -86,8 +114,9 @@ LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime now) {
|
|||||||
init(t, timestamp, now);
|
init(t, timestamp, now);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogMessageTime::init(const std::tm &t, std::time_t timestamp,
|
void
|
||||||
WallTime now) {
|
LogMessageTime::init(const std::tm &t, std::time_t timestamp, WallTime now)
|
||||||
|
{
|
||||||
time_struct_ = t;
|
time_struct_ = t;
|
||||||
timestamp_ = timestamp;
|
timestamp_ = timestamp;
|
||||||
usecs_ = static_cast<std::int32_t>((now - timestamp) * 1000000);
|
usecs_ = static_cast<std::int32_t>((now - timestamp) * 1000000);
|
||||||
@ -95,7 +124,9 @@ void LogMessageTime::init(const std::tm &t, std::time_t timestamp,
|
|||||||
CalcGmtOffset();
|
CalcGmtOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogMessageTime::CalcGmtOffset() {
|
void
|
||||||
|
LogMessageTime::CalcGmtOffset()
|
||||||
|
{
|
||||||
std::tm gmt_struct;
|
std::tm gmt_struct;
|
||||||
int isDst = 0;
|
int isDst = 0;
|
||||||
if (FLAGS_log_utc_time) {
|
if (FLAGS_log_utc_time) {
|
||||||
@ -111,36 +142,54 @@ void LogMessageTime::CalcGmtOffset() {
|
|||||||
const long hour_secs = 3600;
|
const long hour_secs = 3600;
|
||||||
// If the Daylight Saving Time(isDst) is active subtract an hour from the
|
// If the Daylight Saving Time(isDst) is active subtract an hour from the
|
||||||
// current timestamp.
|
// current timestamp.
|
||||||
gmtoffset_ =
|
gmtoffset_ = static_cast<long int>(timestamp_ - gmt_sec + (isDst ? hour_secs : 0));
|
||||||
static_cast<long int>(timestamp_ - gmt_sec + (isDst ? hour_secs : 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LogSink::~LogSink() {}
|
LogSink::~LogSink() {}
|
||||||
void LogSink::send(LogSeverity severity, const char *full_filename,
|
|
||||||
const char *base_filename, int line,
|
void
|
||||||
const LogMessageTime &logmsgtime, const char *message,
|
LogSink::send(LogSeverity severity,
|
||||||
size_t message_len) {
|
const char *full_filename,
|
||||||
|
const char *base_filename,
|
||||||
|
int line,
|
||||||
|
const LogMessageTime &logmsgtime,
|
||||||
|
const char *message,
|
||||||
|
size_t message_len)
|
||||||
|
{
|
||||||
|
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
void LogSink::WaitTillSent() {}
|
|
||||||
std::string LogSink::ToString(LogSeverity severity, const char *file, int line,
|
void
|
||||||
|
LogSink::WaitTillSent()
|
||||||
|
{}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
LogSink::ToString(LogSeverity severity,
|
||||||
|
const char *file,
|
||||||
|
int line,
|
||||||
const LogMessageTime &logmsgtime,
|
const LogMessageTime &logmsgtime,
|
||||||
const char *message, size_t message_len) {
|
const char *message,
|
||||||
return google::LogSink::ToString(severity, file, line, logmsgtime.tm(),
|
size_t message_len)
|
||||||
message, message_len);
|
{
|
||||||
|
return google::LogSink::ToString(severity, file, line, logmsgtime.tm(), message, message_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
class LogSinkWrapper : public google::LogSink {
|
class LogSinkWrapper : public google::LogSink {
|
||||||
public:
|
public:
|
||||||
LogSinkWrapper(tile::LogSink *dest) : dest_(dest) {}
|
LogSinkWrapper(tile::LogSink *dest) : dest_(dest) {}
|
||||||
|
|
||||||
~LogSinkWrapper() override {}
|
~LogSinkWrapper() override {}
|
||||||
void send(LogSeverity severity, const char *full_filename,
|
|
||||||
const char *base_filename, int line,
|
void send(LogSeverity severity,
|
||||||
const google::LogMessageTime &logmsgtime, const char *message,
|
const char *full_filename,
|
||||||
size_t message_len) override {
|
const char *base_filename,
|
||||||
dest_->send(severity, full_filename, base_filename, line, logmsgtime.tm(),
|
int line,
|
||||||
message, message_len);
|
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(); }
|
void WaitTillSent() override { dest_->WaitTillSent(); }
|
||||||
@ -157,18 +206,20 @@ struct LogSinkPair {
|
|||||||
static std::map<LogSink *, LogSinkWrapper *> sink_registry;
|
static std::map<LogSink *, LogSinkWrapper *> sink_registry;
|
||||||
static std::mutex sink_registry_mutex;
|
static std::mutex sink_registry_mutex;
|
||||||
|
|
||||||
void AddLogSink(LogSink *dest) {
|
void
|
||||||
|
AddLogSink(LogSink *dest)
|
||||||
|
{
|
||||||
std::lock_guard<std::mutex> lock(sink_registry_mutex);
|
std::lock_guard<std::mutex> lock(sink_registry_mutex);
|
||||||
if (sink_registry.find(dest) != sink_registry.end()) {
|
if (sink_registry.find(dest) != sink_registry.end()) { return; }
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto wrapper = new LogSinkWrapper(dest);
|
auto wrapper = new LogSinkWrapper(dest);
|
||||||
sink_registry[dest] = wrapper;
|
sink_registry[dest] = wrapper;
|
||||||
google::AddLogSink(wrapper);
|
google::AddLogSink(wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoveLogSink(LogSink *dest) {
|
void
|
||||||
|
RemoveLogSink(LogSink *dest)
|
||||||
|
{
|
||||||
std::lock_guard<std::mutex> lock(sink_registry_mutex);
|
std::lock_guard<std::mutex> lock(sink_registry_mutex);
|
||||||
auto iter = sink_registry.find(dest);
|
auto iter = sink_registry.find(dest);
|
||||||
if (iter != sink_registry.end()) {
|
if (iter != sink_registry.end()) {
|
||||||
@ -177,11 +228,22 @@ void RemoveLogSink(LogSink *dest) {
|
|||||||
delete iter->second;
|
delete iter->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void SetStderrLogging(LogSeverity min_severity) {
|
|
||||||
|
void
|
||||||
|
SetStderrLogging(LogSeverity min_severity)
|
||||||
|
{
|
||||||
google::SetStderrLogging(min_severity);
|
google::SetStderrLogging(min_severity);
|
||||||
}
|
}
|
||||||
void LogToStderr() { google::LogToStderr(); }
|
|
||||||
const char *GetLogSeverityName(LogSeverity severity) {
|
void
|
||||||
|
LogToStderr()
|
||||||
|
{
|
||||||
|
google::LogToStderr();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
GetLogSeverityName(LogSeverity severity)
|
||||||
|
{
|
||||||
return google::GetLogSeverityName(severity);
|
return google::GetLogSeverityName(severity);
|
||||||
}
|
}
|
||||||
} // namespace tile
|
}// namespace tile
|
||||||
|
@ -9,17 +9,31 @@
|
|||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
struct AwesomeLogSink : public tile::LogSink {
|
struct AwesomeLogSink : public tile::LogSink {
|
||||||
virtual void Send(tile::LogSeverity severity, const char *full_filename,
|
static std::shared_ptr<AwesomeLogSink> Create() { return std::make_shared<AwesomeLogSink>(); }
|
||||||
const char *base_filename, int line,
|
|
||||||
const tile::LogMessageTime &logmsgtime, const char *message,
|
virtual void Send(tile::LogSeverity severity,
|
||||||
size_t message_len) override {
|
const char *full_filename,
|
||||||
|
const char *base_filename,
|
||||||
|
int line,
|
||||||
|
const tile::LogMessageTime &logmsgtime,
|
||||||
|
const char *message,
|
||||||
|
size_t message_len) override
|
||||||
|
{
|
||||||
msgs.emplace_back(std::string(message, message_len));
|
msgs.emplace_back(std::string(message, message_len));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> msgs;
|
std::vector<std::string> msgs;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string my_prefix, my_prefix2;
|
std::string my_prefix, my_prefix2;
|
||||||
|
|
||||||
|
void
|
||||||
|
ResetLogPrefix()
|
||||||
|
{
|
||||||
|
my_prefix.clear();
|
||||||
|
my_prefix2.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
WriteLoggingPrefix(std::string *s)
|
WriteLoggingPrefix(std::string *s)
|
||||||
{
|
{
|
||||||
@ -32,7 +46,8 @@ WriteLoggingPrefix2(std::string *s)
|
|||||||
*s += my_prefix2;
|
*s += my_prefix2;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Logging, Prefix) {
|
TEST(Logging, Prefix)
|
||||||
|
{
|
||||||
auto sink = std::make_shared<AwesomeLogSink>();
|
auto sink = std::make_shared<AwesomeLogSink>();
|
||||||
tile::AddLogSink(sink);
|
tile::AddLogSink(sink);
|
||||||
tile::ScopedDeferred defered([&] { tile::RemoveLogSink(sink); });
|
tile::ScopedDeferred defered([&] { tile::RemoveLogSink(sink); });
|
||||||
@ -49,9 +64,8 @@ TEST(Logging, Prefix) {
|
|||||||
TILE_LOG_INFO("something");
|
TILE_LOG_INFO("something");
|
||||||
|
|
||||||
ASSERT_THAT(sink->msgs,
|
ASSERT_THAT(sink->msgs,
|
||||||
::testing::ElementsAre("something", "[prefix] something",
|
::testing::ElementsAre(
|
||||||
"[prefix1] something",
|
"something", "[prefix] something", "[prefix1] something", "[prefix1] [prefix2] something"));
|
||||||
"[prefix1] [prefix2] something"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Logging, CHECK)
|
TEST(Logging, CHECK)
|
||||||
@ -65,13 +79,13 @@ TEST(Logging, CHECK)
|
|||||||
ASSERT_DEATH(([] { TILE_CHECK_NE(1, 1, "CHECK_NE"); }()), "CHECK_NE");
|
ASSERT_DEATH(([] { TILE_CHECK_NE(1, 1, "CHECK_NE"); }()), "CHECK_NE");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Logging, Prefix)
|
TEST(Logging, DontPanicOnFormatFailure) { TILE_LOG_INFO("Don't panic!{}{}", 1); }
|
||||||
{
|
|
||||||
AwesomeLogSink sink;
|
|
||||||
tile::AddLogSink(&sink);
|
|
||||||
tile::ScopedDeferred defered([&] { tile::RemoveLogSink(&sink); });
|
|
||||||
|
|
||||||
auto sink = std::make_shared<AwesomeLogSink>();
|
TEST(Logging, EverySecond)
|
||||||
|
{
|
||||||
|
ResetLogPrefix();
|
||||||
|
|
||||||
|
auto sink = AwesomeLogSink::Create();
|
||||||
tile::AddLogSink(sink);
|
tile::AddLogSink(sink);
|
||||||
tile::ScopedDeferred defered([&] { tile::RemoveLogSink(sink); });
|
tile::ScopedDeferred defered([&] { tile::RemoveLogSink(sink); });
|
||||||
for (int i = 0; i < 30; i++) {
|
for (int i = 0; i < 30; i++) {
|
||||||
@ -79,25 +93,7 @@ TEST(Logging, Prefix)
|
|||||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT_THAT(sink->msgs,
|
ASSERT_THAT(sink->msgs, ::testing::ElementsAre("something", "something", "something"));
|
||||||
::testing::ElementsAre("something", "something", "something"));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(Logging, DontPanicOnFormatFailure) { TILE_LOG_INFO("Don't panic!{}{}", 1); }
|
|
||||||
|
|
||||||
TEST(Logging, EverySecond)
|
|
||||||
{
|
|
||||||
ResetLogPrefix();
|
|
||||||
|
|
||||||
AwesomeLogSink sink;
|
|
||||||
tile::AddLogSink(&sink);
|
|
||||||
tile::ScopedDeferred defered([&] { tile::RemoveLogSink(&sink); });
|
|
||||||
for (int i = 0; i < 30; i++) {
|
|
||||||
TILE_LOG_INFO_EVERY_SECOND("something");
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT_THAT(sink.msgs, ::testing::ElementsAre("something", "something", "something"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Logging, Enum)
|
TEST(Logging, Enum)
|
||||||
|
@ -1,24 +1,47 @@
|
|||||||
#include "tile/base/logging/basic_file_sink.h"
|
#include "tile/base/logging/basic_file_sink.h"
|
||||||
|
|
||||||
namespace tile {
|
namespace tile {
|
||||||
BasicFileSink::Ptr BasicFileSink::Create(const std::string &filepath) {
|
BasicFileSink::Ptr
|
||||||
|
BasicFileSink::Create(const std::string &filepath)
|
||||||
|
{
|
||||||
auto sink = std::shared_ptr<BasicFileSink>(new BasicFileSink());
|
auto sink = std::shared_ptr<BasicFileSink>(new BasicFileSink());
|
||||||
sink->set_filepath(filepath);
|
sink->set_filepath(filepath);
|
||||||
return sink;
|
return sink;
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicFileSink::BasicFileSink() {}
|
BasicFileSink::BasicFileSink() {}
|
||||||
|
|
||||||
BasicFileSink::~BasicFileSink() {}
|
BasicFileSink::~BasicFileSink() {}
|
||||||
void BasicFileSink::Send(LogSeverity severity, const char *full_filename,
|
|
||||||
const char *base_filename, int line,
|
void
|
||||||
const LogMessageTime &logmsgtime, const char *message,
|
BasicFileSink::Send(LogSeverity severity,
|
||||||
size_t message_len) {
|
const char *full_filename,
|
||||||
|
const char *base_filename,
|
||||||
|
int line,
|
||||||
|
const LogMessageTime &logmsgtime,
|
||||||
|
const char *message,
|
||||||
|
size_t message_len)
|
||||||
|
{
|
||||||
TILE_CHECK(!filepath_.empty(), "filepath is empty");
|
TILE_CHECK(!filepath_.empty(), "filepath is empty");
|
||||||
ofs_ << std::string(message, message_len) << std::endl;
|
ofs_ << std::string(message, message_len) << std::endl;
|
||||||
}
|
}
|
||||||
std::string BasicFileSink::filepath() const { return filepath_; }
|
|
||||||
void BasicFileSink::set_filepath(const std::string &filepath) {
|
std::string
|
||||||
|
BasicFileSink::filepath() const
|
||||||
|
{
|
||||||
|
return filepath_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BasicFileSink::set_filepath(const std::string &filepath)
|
||||||
|
{
|
||||||
filepath_ = filepath;
|
filepath_ = filepath;
|
||||||
ofs_.open(filepath, std::ios::out | std::ios::app);
|
ofs_.open(filepath, std::ios::out | std::ios::app);
|
||||||
}
|
}
|
||||||
void BasicFileSink::Flush() { ofs_.flush(); }
|
|
||||||
} // namespace tile
|
void
|
||||||
|
BasicFileSink::Flush()
|
||||||
|
{
|
||||||
|
ofs_.flush();
|
||||||
|
}
|
||||||
|
}// namespace tile
|
||||||
|
@ -14,9 +14,12 @@ public:
|
|||||||
static Ptr Create(const std::string &filepath);
|
static Ptr Create(const std::string &filepath);
|
||||||
|
|
||||||
~BasicFileSink() override;
|
~BasicFileSink() override;
|
||||||
void Send(LogSeverity severity, const char *full_filename,
|
void Send(LogSeverity severity,
|
||||||
const char *base_filename, int line,
|
const char *full_filename,
|
||||||
const LogMessageTime &logmsgtime, const char *message,
|
const char *base_filename,
|
||||||
|
int line,
|
||||||
|
const LogMessageTime &logmsgtime,
|
||||||
|
const char *message,
|
||||||
size_t message_len) override;
|
size_t message_len) override;
|
||||||
void Flush() override;
|
void Flush() override;
|
||||||
|
|
||||||
@ -31,6 +34,6 @@ private:
|
|||||||
std::ofstream ofs_;
|
std::ofstream ofs_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tile
|
}// namespace tile
|
||||||
|
|
||||||
#endif // TILE_BASE_LOGGING_BASIC_FILE_SINK_H
|
#endif// TILE_BASE_LOGGING_BASIC_FILE_SINK_H
|
||||||
|
@ -1,23 +1,28 @@
|
|||||||
#include "tile/base/logging/console_sink.h"
|
#include "tile/base/logging/console_sink.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
namespace tile {
|
namespace tile {
|
||||||
|
|
||||||
ConsoleSink::Ptr ConsoleSink::Create() {
|
ConsoleSink::Ptr
|
||||||
|
ConsoleSink::Create()
|
||||||
|
{
|
||||||
return std::shared_ptr<ConsoleSink>(new ConsoleSink());
|
return std::shared_ptr<ConsoleSink>(new ConsoleSink());
|
||||||
}
|
}
|
||||||
|
|
||||||
ConsoleSink::~ConsoleSink() {}
|
ConsoleSink::~ConsoleSink() {}
|
||||||
|
|
||||||
void ConsoleSink::Send(LogSeverity severity, const char *full_filename,
|
void
|
||||||
const char *base_filename, int line,
|
ConsoleSink::Send(LogSeverity severity,
|
||||||
const LogMessageTime &logmsgtime, const char *message,
|
const char *full_filename,
|
||||||
size_t message_len) {
|
const char *base_filename,
|
||||||
auto msg = ToString(severity, full_filename, base_filename, line, logmsgtime,
|
int line,
|
||||||
message, message_len);
|
const LogMessageTime &logmsgtime,
|
||||||
while (!msg.empty() && msg.back() == '\n') {
|
const char *message,
|
||||||
msg.pop_back();
|
size_t message_len)
|
||||||
}
|
{
|
||||||
|
auto msg = ToString(severity, full_filename, base_filename, line, logmsgtime, message, message_len);
|
||||||
|
while (!msg.empty() && msg.back() == '\n') { msg.pop_back(); }
|
||||||
if (severity >= TILE_FATAL) {
|
if (severity >= TILE_FATAL) {
|
||||||
fprintf(stderr, "%s\n", msg.c_str());
|
fprintf(stderr, "%s\n", msg.c_str());
|
||||||
} else {
|
} else {
|
||||||
@ -25,8 +30,10 @@ void ConsoleSink::Send(LogSeverity severity, const char *full_filename,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsoleSink::Flush() {}
|
void
|
||||||
|
ConsoleSink::Flush()
|
||||||
|
{}
|
||||||
|
|
||||||
ConsoleSink::ConsoleSink() {}
|
ConsoleSink::ConsoleSink() {}
|
||||||
|
|
||||||
} // namespace tile
|
}// namespace tile
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "tile/base/internal/logging.h"
|
#include "tile/base/internal/logging.h"
|
||||||
|
|
||||||
namespace tile {
|
namespace tile {
|
||||||
class ConsoleSink : public LogSink {
|
class ConsoleSink : public LogSink {
|
||||||
public:
|
public:
|
||||||
@ -11,15 +12,18 @@ public:
|
|||||||
static Ptr Create();
|
static Ptr Create();
|
||||||
|
|
||||||
~ConsoleSink() override;
|
~ConsoleSink() override;
|
||||||
void Send(LogSeverity severity, const char *full_filename,
|
void Send(LogSeverity severity,
|
||||||
const char *base_filename, int line,
|
const char *full_filename,
|
||||||
const LogMessageTime &logmsgtime, const char *message,
|
const char *base_filename,
|
||||||
|
int line,
|
||||||
|
const LogMessageTime &logmsgtime,
|
||||||
|
const char *message,
|
||||||
size_t message_len) override;
|
size_t message_len) override;
|
||||||
void Flush() override;
|
void Flush() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ConsoleSink();
|
ConsoleSink();
|
||||||
};
|
};
|
||||||
} // namespace tile
|
}// namespace tile
|
||||||
|
|
||||||
#endif // TILE_BASE_LOGGING_CONSOLE_SINK_H
|
#endif// TILE_BASE_LOGGING_CONSOLE_SINK_H
|
||||||
|
@ -2,62 +2,78 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
namespace tile {
|
namespace tile {
|
||||||
std::shared_ptr<SplitterSink> SplitterSink::Create() {
|
std::shared_ptr<SplitterSink>
|
||||||
|
SplitterSink::Create()
|
||||||
|
{
|
||||||
return std::shared_ptr<SplitterSink>(new SplitterSink());
|
return std::shared_ptr<SplitterSink>(new SplitterSink());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<SplitterSink> SplitterSink::Create(
|
std::shared_ptr<SplitterSink>
|
||||||
std::initializer_list<std::shared_ptr<LogSink>> init_list) {
|
SplitterSink::Create(std::initializer_list<std::shared_ptr<LogSink>> init_list)
|
||||||
|
{
|
||||||
auto sink = Create();
|
auto sink = Create();
|
||||||
for (auto &s : init_list) {
|
for (auto &s : init_list) { sink->AddSink(s); }
|
||||||
sink->AddSink(s);
|
|
||||||
}
|
|
||||||
return sink;
|
return sink;
|
||||||
}
|
}
|
||||||
|
|
||||||
SplitterSink::SplitterSink() {}
|
SplitterSink::SplitterSink() {}
|
||||||
|
|
||||||
SplitterSink::~SplitterSink() {}
|
SplitterSink::~SplitterSink() {}
|
||||||
void SplitterSink::Send(LogSeverity severity, const char *full_filename,
|
|
||||||
const char *base_filename, int line,
|
void
|
||||||
const LogMessageTime &logmsgtime, const char *message,
|
SplitterSink::Send(LogSeverity severity,
|
||||||
size_t message_len) {
|
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");
|
assert(!doing_ && "SplitterSink::send() should not be called recursively");
|
||||||
std::lock_guard<std::mutex> _(sinks_mutex_);
|
std::lock_guard<std::mutex> _(sinks_mutex_);
|
||||||
doing_ = true;
|
doing_ = true;
|
||||||
for (auto &sink : sinks_) {
|
for (auto &sink : sinks_) {
|
||||||
sink->Send(severity, full_filename, base_filename, line, logmsgtime,
|
sink->Send(severity, full_filename, base_filename, line, logmsgtime, message, message_len);
|
||||||
message, message_len);
|
|
||||||
}
|
}
|
||||||
doing_ = false;
|
doing_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SplitterSink::Flush() {
|
void
|
||||||
|
SplitterSink::Flush()
|
||||||
|
{
|
||||||
assert(!doing_ && "SplitterSink::send() should not be called recursively");
|
assert(!doing_ && "SplitterSink::send() should not be called recursively");
|
||||||
std::lock_guard<std::mutex> _(sinks_mutex_);
|
std::lock_guard<std::mutex> _(sinks_mutex_);
|
||||||
doing_ = true;
|
doing_ = true;
|
||||||
for (auto &sink : sinks_) {
|
for (auto &sink : sinks_) { sink->Flush(); }
|
||||||
sink->Flush();
|
|
||||||
}
|
|
||||||
doing_ = false;
|
doing_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SplitterSink::AddSink(std::shared_ptr<LogSink> sink) {
|
void
|
||||||
|
SplitterSink::AddSink(std::shared_ptr<LogSink> sink)
|
||||||
|
{
|
||||||
std::lock_guard<std::mutex> _(sinks_mutex_);
|
std::lock_guard<std::mutex> _(sinks_mutex_);
|
||||||
sinks_.insert(sink);
|
sinks_.insert(sink);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SplitterSink::RemoveSink(std::shared_ptr<LogSink> sink) {
|
void
|
||||||
|
SplitterSink::RemoveSink(std::shared_ptr<LogSink> sink)
|
||||||
|
{
|
||||||
std::lock_guard<std::mutex> _(sinks_mutex_);
|
std::lock_guard<std::mutex> _(sinks_mutex_);
|
||||||
sinks_.erase(sink);
|
sinks_.erase(sink);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SplitterSink::ClearSinks() {
|
void
|
||||||
|
SplitterSink::ClearSinks()
|
||||||
|
{
|
||||||
std::lock_guard<std::mutex> _(sinks_mutex_);
|
std::lock_guard<std::mutex> _(sinks_mutex_);
|
||||||
sinks_.clear();
|
sinks_.clear();
|
||||||
}
|
}
|
||||||
std::set<LogSink::Ptr> SplitterSink::sinks() {
|
|
||||||
|
std::set<LogSink::Ptr>
|
||||||
|
SplitterSink::sinks()
|
||||||
|
{
|
||||||
std::lock_guard<std::mutex> _(sinks_mutex_);
|
std::lock_guard<std::mutex> _(sinks_mutex_);
|
||||||
return sinks_;
|
return sinks_;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace tile
|
}// namespace tile
|
||||||
|
@ -16,9 +16,12 @@ public:
|
|||||||
|
|
||||||
~SplitterSink() override;
|
~SplitterSink() override;
|
||||||
|
|
||||||
void Send(LogSeverity severity, const char *full_filename,
|
void Send(LogSeverity severity,
|
||||||
const char *base_filename, int line,
|
const char *full_filename,
|
||||||
const LogMessageTime &logmsgtime, const char *message,
|
const char *base_filename,
|
||||||
|
int line,
|
||||||
|
const LogMessageTime &logmsgtime,
|
||||||
|
const char *message,
|
||||||
size_t message_len) override;
|
size_t message_len) override;
|
||||||
void Flush() override;
|
void Flush() override;
|
||||||
|
|
||||||
@ -35,6 +38,6 @@ private:
|
|||||||
std::mutex sinks_mutex_;
|
std::mutex sinks_mutex_;
|
||||||
bool doing_ = false;
|
bool doing_ = false;
|
||||||
};
|
};
|
||||||
} // namespace tile
|
}// namespace tile
|
||||||
|
|
||||||
#endif // TILE_BASE_LOGGING_SPLITTER_SINK_H
|
#endif// TILE_BASE_LOGGING_SPLITTER_SINK_H
|
||||||
|
@ -5,52 +5,56 @@ namespace tile {
|
|||||||
class SimpleSink : public LogSink {
|
class SimpleSink : public LogSink {
|
||||||
public:
|
public:
|
||||||
using Ptr = std::shared_ptr<SimpleSink>;
|
using Ptr = std::shared_ptr<SimpleSink>;
|
||||||
|
|
||||||
static Ptr Create() { return std::shared_ptr<SimpleSink>(new SimpleSink()); }
|
static Ptr Create() { return std::shared_ptr<SimpleSink>(new SimpleSink()); }
|
||||||
void Send(LogSeverity severity, const char *full_filename,
|
|
||||||
const char *base_filename, int line,
|
void Send(LogSeverity severity,
|
||||||
const LogMessageTime &logmsgtime, const char *message,
|
const char *full_filename,
|
||||||
size_t message_len) override {
|
const char *base_filename,
|
||||||
|
int line,
|
||||||
|
const LogMessageTime &logmsgtime,
|
||||||
|
const char *message,
|
||||||
|
size_t message_len) override
|
||||||
|
{
|
||||||
message_ = std::string(message, message_len);
|
message_ = std::string(message, message_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Flush() override {}
|
void Flush() override {}
|
||||||
|
|
||||||
std::string message_;
|
std::string message_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(SplitterSink, One) {
|
TEST(SplitterSink, One)
|
||||||
|
{
|
||||||
auto sink = SimpleSink::Create();
|
auto sink = SimpleSink::Create();
|
||||||
auto splitter = SplitterSink::Create({sink});
|
auto splitter = SplitterSink::Create({sink});
|
||||||
splitter->Send(LogSeverity::TILE_INFO, nullptr, nullptr, 0, LogMessageTime(),
|
splitter->Send(LogSeverity::TILE_INFO, nullptr, nullptr, 0, LogMessageTime(), "message", 7);
|
||||||
"message", 7);
|
|
||||||
ASSERT_EQ(sink->message_, "message");
|
ASSERT_EQ(sink->message_, "message");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SplitterSink, Two) {
|
TEST(SplitterSink, Two)
|
||||||
|
{
|
||||||
auto sink1 = SimpleSink::Create();
|
auto sink1 = SimpleSink::Create();
|
||||||
auto sink2 = SimpleSink::Create();
|
auto sink2 = SimpleSink::Create();
|
||||||
auto splitter = SplitterSink::Create({sink1, sink2});
|
auto splitter = SplitterSink::Create({sink1, sink2});
|
||||||
splitter->Send(LogSeverity::TILE_INFO, nullptr, nullptr, 0, LogMessageTime(),
|
splitter->Send(LogSeverity::TILE_INFO, nullptr, nullptr, 0, LogMessageTime(), "message", 7);
|
||||||
"message", 7);
|
|
||||||
ASSERT_EQ(sink1->message_, "message");
|
ASSERT_EQ(sink1->message_, "message");
|
||||||
ASSERT_EQ(sink2->message_, "message");
|
ASSERT_EQ(sink2->message_, "message");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(SplitterSink, Multi) {
|
TEST(SplitterSink, Multi)
|
||||||
|
{
|
||||||
auto splitter = SplitterSink::Create();
|
auto splitter = SplitterSink::Create();
|
||||||
for (int i = 0; i < 100; i++) {
|
for (int i = 0; i < 100; i++) { splitter->AddSink(SimpleSink::Create()); }
|
||||||
splitter->AddSink(SimpleSink::Create());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < 100; i++) {
|
for (int i = 0; i < 100; i++) {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "message" << i;
|
ss << "message" << i;
|
||||||
auto msg = ss.str();
|
auto msg = ss.str();
|
||||||
splitter->Send(LogSeverity::TILE_INFO, nullptr, nullptr, 0,
|
splitter->Send(LogSeverity::TILE_INFO, nullptr, nullptr, 0, LogMessageTime(), msg.data(), msg.size());
|
||||||
LogMessageTime(), msg.data(), msg.size());
|
|
||||||
|
|
||||||
for (auto &sink : splitter->sinks()) {
|
for (auto &sink : splitter->sinks()) { ASSERT_EQ(std::static_pointer_cast<SimpleSink>(sink)->message_, msg); }
|
||||||
ASSERT_EQ(std::static_pointer_cast<SimpleSink>(sink)->message_, msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace tile
|
}// namespace tile
|
||||||
|
@ -32,7 +32,9 @@ namespace {
|
|||||||
|
|
||||||
std::atomic<bool> g_quit_siganl{false};
|
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) {
|
||||||
// TODO: Add TILE_RAW_LOG
|
// TODO: Add TILE_RAW_LOG
|
||||||
@ -52,8 +54,9 @@ InstallQuitSignalHandler()
|
|||||||
}
|
}
|
||||||
}// namespace
|
}// namespace
|
||||||
|
|
||||||
int Start(int argc, char **argv, std::function<int(int, char **)> cb,
|
int
|
||||||
bool single_thread, bool enable_crash_catch) {
|
Start(int argc, char **argv, std::function<int(int, char **)> cb, bool single_thread, bool enable_crash_catch)
|
||||||
|
{
|
||||||
if (enable_crash_catch) {
|
if (enable_crash_catch) {
|
||||||
// TODO: Add InstallFailureSignalHandler
|
// TODO: Add InstallFailureSignalHandler
|
||||||
// google::InstallFailureSignalHandler();
|
// google::InstallFailureSignalHandler();
|
||||||
|
@ -10,18 +10,20 @@ namespace tile {
|
|||||||
namespace testing {
|
namespace testing {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
int StartBenchmark(int argc, char **argv) {
|
int
|
||||||
|
StartBenchmark(int argc, char **argv)
|
||||||
|
{
|
||||||
::benchmark::Initialize(&argc, argv);
|
::benchmark::Initialize(&argc, argv);
|
||||||
if (::benchmark::ReportUnrecognizedArguments(argc, argv)) {
|
if (::benchmark::ReportUnrecognizedArguments(argc, argv)) { return 1; }
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
::benchmark::RunSpecifiedBenchmarks();
|
::benchmark::RunSpecifiedBenchmarks();
|
||||||
::benchmark::Shutdown();
|
::benchmark::Shutdown();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} // namespace
|
}// namespace
|
||||||
|
|
||||||
int InitAndRunAllBenchmarks(int *argc, char **argv) {
|
int
|
||||||
|
InitAndRunAllBenchmarks(int *argc, char **argv)
|
||||||
|
{
|
||||||
|
|
||||||
// if (gflags::GetCommandLineFlagInfoOrDie("logtostderr").is_default) {
|
// if (gflags::GetCommandLineFlagInfoOrDie("logtostderr").is_default) {
|
||||||
// FLAGS_logtostderr = true;
|
// FLAGS_logtostderr = true;
|
||||||
@ -30,7 +32,7 @@ int InitAndRunAllBenchmarks(int *argc, char **argv) {
|
|||||||
return Start(*argc, argv, StartBenchmark, true);
|
return Start(*argc, argv, StartBenchmark, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace testing
|
}// namespace testing
|
||||||
} // namespace tile
|
}// namespace tile
|
||||||
|
|
||||||
TILE_BENCHMARK_MAIN
|
TILE_BENCHMARK_MAIN
|
||||||
|
Loading…
Reference in New Issue
Block a user