feat merge master
Some checks failed
linux-mips64-gcc / linux-gcc-mips64el (Debug) (push) Waiting to run
linux-mips64-gcc / linux-gcc-mips64el (Release) (push) Waiting to run
linux-riscv64-gcc / linux-gcc-riscv64 (Debug) (push) Waiting to run
linux-riscv64-gcc / linux-gcc-riscv64 (Release) (push) Waiting to run
linux-x64-clang / linux-clang (Debug) (push) Waiting to run
linux-x64-clang / linux-clang (Release) (push) Waiting to run
linux-x64-gcc / linux-gcc (Debug) (push) Waiting to run
linux-x64-gcc / linux-gcc (Release) (push) Waiting to run
linux-x86-gcc / linux-gcc (Debug) (push) Waiting to run
linux-x86-gcc / linux-gcc (Release) (push) Waiting to run
android / build (push) Failing after 8s
linux-aarch64-cpu-gcc / linux-gcc-aarch64 (Debug) (push) Failing after 8s
linux-aarch64-cpu-gcc / linux-gcc-aarch64 (Release) (push) Failing after 8s
linux-arm-gcc / linux-gcc-arm (Debug) (push) Failing after 8s
linux-arm-gcc / linux-gcc-arm (Release) (push) Failing after 7s
linux-arm-gcc / linux-gcc-armhf (Debug) (push) Failing after 8s
linux-arm-gcc / linux-gcc-armhf (Release) (push) Failing after 8s
linux-mips-gcc / linux-gcc-mipsel (Debug) (push) Failing after 10s
linux-mips-gcc / linux-gcc-mipsel (Release) (push) Has been cancelled
android / build (pull_request) Failing after 19s
linux-aarch64-cpu-gcc / linux-gcc-aarch64 (Debug) (pull_request) Failing after 34m8s
linux-aarch64-cpu-gcc / linux-gcc-aarch64 (Release) (pull_request) Failing after 37m55s
linux-arm-gcc / linux-gcc-arm (Debug) (pull_request) Failing after 1m20s
linux-arm-gcc / linux-gcc-arm (Release) (pull_request) Failing after 21s
linux-arm-gcc / linux-gcc-armhf (Debug) (pull_request) Failing after 23m4s
linux-arm-gcc / linux-gcc-armhf (Release) (pull_request) Failing after 17m19s
linux-mips-gcc / linux-gcc-mipsel (Debug) (pull_request) Failing after 8m59s
linux-mips-gcc / linux-gcc-mipsel (Release) (pull_request) Failing after 2h45m58s
linux-mips64-gcc / linux-gcc-mips64el (Debug) (pull_request) Has been cancelled
linux-mips64-gcc / linux-gcc-mips64el (Release) (pull_request) Has been cancelled
linux-riscv64-gcc / linux-gcc-riscv64 (Debug) (pull_request) Has been cancelled
linux-riscv64-gcc / linux-gcc-riscv64 (Release) (pull_request) Has been cancelled
linux-x64-clang / linux-clang (Debug) (pull_request) Has been cancelled
linux-x64-clang / linux-clang (Release) (pull_request) Has been cancelled
linux-x64-gcc / linux-gcc (Debug) (pull_request) Has been cancelled
linux-x64-gcc / linux-gcc (Release) (pull_request) Has been cancelled
linux-x86-gcc / linux-gcc (Debug) (pull_request) Has been cancelled
linux-x86-gcc / linux-gcc (Release) (pull_request) Has been cancelled

This commit is contained in:
tqcq 2024-09-02 13:44:40 +08:00
parent 635db57230
commit fa04f9c23a
15 changed files with 958 additions and 729 deletions

View File

@ -2128,7 +2128,7 @@ nsel_DISABLE_MSVC_WARNINGS(26409)
: make_unexpected(detail::invoke(std::forward<F>(f), std::move(error())));
}
#endif
#endif// nsel_P2505R >= 3
#endif// nsel_P2505R >= 3 \
// unwrap()
// template <class U, class E>

View File

@ -174,7 +174,6 @@ private:
{"1s", 1}
};
for (auto &&item : m) {}
}
return result;
}

View File

@ -26,7 +26,9 @@ DescribeFormatArguments(const std::vector<std::string> &args)
}
}// namespace details
void InstallPrefixProvider(PrefixAppender *writer) {
void
InstallPrefixProvider(PrefixAppender *writer)
{
GetProviers()->push_back(writer);
}
@ -61,32 +63,39 @@ private:
std::ostream &ostream_;
};
bool VLogIsOn(int n) { return true; }
bool
VLogIsOn(int n)
{
return true;
}
class LogMessage::Impl {
public:
Impl(const char *file, int line)
: stream_(message_text_, LogMessage::kMaxLogMessageLen, 0) {
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) {
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) {
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);
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;
}
void Flush()
{
if (has_been_flushed_) { return; }
num_chars_to_log_ = stream_.pcount();
const bool append_newline = message_text_[num_chars_to_log_ - 1] != '\n';
@ -103,35 +112,32 @@ public:
(this->*(send_method_))();
++g_num_messages[severity_];
WaitForSinks();
if (sink_) {
sink_->Flush();
}
if (sink_) { sink_->Flush(); }
}
if (append_newline) {
message_text_[num_chars_to_log_ - 1] = original_final_char;
}
if (append_newline) { message_text_[num_chars_to_log_ - 1] = original_final_char; }
if (preserved_errno_ != 0) {
errno = preserved_errno_;
}
if (preserved_errno_ != 0) { errno = preserved_errno_; }
has_been_flushed_ = true;
if (severity_ == TILE_FATAL) {
assert(false);
}
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)()) {
void Init(const char *file, int line, LogSeverity severity, void (LogMessage::Impl::*send_method)())
{
has_been_flushed_ = false;
file_ = file;
line_ = line;
@ -144,23 +150,25 @@ private:
preserved_errno_ = errno;
}
void SendToSink() {
void SendToSink()
{
if (sink_) {
sink_->Send(severity_, fullname(), basename(), line(), time(),
message_text_ + num_prefix_chars_,
num_chars_to_log_ - num_prefix_chars_);
sink_->Send(severity_, fullname(), basename(), line(), time(), message_text_ + num_prefix_chars_,
num_chars_to_log_ - num_prefix_chars_ - 1);
}
}
void SendToLog() {
void SendToLog()
{
if (g_sink_count.load(std::memory_order_relaxed) == 0) {
ColoredWriteToStdout(severity_, message_text_ + num_prefix_chars_,
num_chars_to_log_ - num_chars_to_log_);
ColoredWriteToStdout(severity_, message_text_ + num_prefix_chars_, num_chars_to_log_ - num_chars_to_log_);
}
LogToSinks(severity_, fullname(), basename(), line(), time(),
message_text_ + num_prefix_chars_,
num_chars_to_log_ - num_prefix_chars_);
LogToSinks(severity_, fullname(), basename(), line(), time(), message_text_ + num_prefix_chars_,
num_chars_to_log_ - num_prefix_chars_ - 1);
}
void SendToSinkAndLog() {
void SendToSinkAndLog()
{
SendToSink();
SendToLog();
}
@ -185,44 +193,84 @@ private:
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(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(); }
std::ostream &
LogMessage::stream()
{
return impl_->stream();
}
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 {
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) {}
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(); }
std::ostream &
LogMessageFatal::stream()
{
return LogMessage::stream();
}
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);
init(t, timestamp, 0);
}
LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime now)
: use_localtime_(false) {
LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime now) : use_localtime_(false)
{
std::tm t;
if (use_localtime_) {
localtime_r(&timestamp, &t);
@ -232,8 +280,9 @@ LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime 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::tm t;
if (use_localtime_) {
@ -243,14 +292,12 @@ LogMessageTime::LogMessageTime(std::chrono::system_clock::time_point tp)
}
init(t, timestamp, 0);
usecs_ = std::chrono::duration_cast<std::chrono::microseconds>(
tp.time_since_epoch())
.count() %
1000000;
usecs_ = std::chrono::duration_cast<std::chrono::microseconds>(tp.time_since_epoch()).count() % 1000000;
}
void LogMessageTime::init(const std::tm &t, std::time_t timestamp,
WallTime now) {
void
LogMessageTime::init(const std::tm &t, std::time_t timestamp, WallTime now)
{
time_struct_ = t;
timestamp_ = timestamp;
if (now < timestamp) {
@ -262,7 +309,9 @@ void LogMessageTime::init(const std::tm &t, std::time_t timestamp,
CalcGmtOffset();
}
void LogMessageTime::CalcGmtOffset() {
void
LogMessageTime::CalcGmtOffset()
{
std::tm gmt_struct;
int isDst = 0;
if (true) {
@ -282,14 +331,15 @@ void LogMessageTime::CalcGmtOffset() {
}
LogSink::~LogSink() {}
bool LogSink::ShouldLog(LogSeverity severity) { return true; }
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) {
bool
LogSink::ShouldLog(LogSeverity severity)
{
return true;
}
void
LogSink::send(LogSeverity severity,
LogSink::Send(LogSeverity severity,
const char *full_filename,
const char *base_filename,
int line,
@ -300,18 +350,24 @@ LogSink::send(LogSeverity severity,
// do nothing
}
void LogSink::Flush() {}
std::string LogSink::ToString(LogSeverity severity, const char *file,
const char *base_filename, int line,
void
LogSink::Flush()
{}
std::string
LogSink::ToString(LogSeverity severity,
const char *file,
const char *base_filename,
int line,
const LogMessageTime &logmsgtime,
const char *message, size_t message_len) {
const char *message,
size_t message_len)
{
std::stringstream ss;
char date_time[64];
sprintf(date_time, "%4d-%02d-%02dT%02d:%02d:%02d.%06d",
logmsgtime.year() + 1900, logmsgtime.month(), logmsgtime.day(),
logmsgtime.hour(), logmsgtime.min(), logmsgtime.sec(),
logmsgtime.usec());
sprintf(date_time, "%4d-%02d-%02dT%02d:%02d:%02d.%06d", logmsgtime.year() + 1900, logmsgtime.month(),
logmsgtime.day(), logmsgtime.hour(), logmsgtime.min(), logmsgtime.sec(), logmsgtime.usec());
ss << date_time;
@ -333,58 +389,78 @@ std::string LogSink::ToString(LogSeverity severity, const char *file,
return ss.str();
}
static void ColoredWriteToStderrOrStdout(FILE *output, LogSeverity severity,
const char *message, size_t len) {
static void
ColoredWriteToStderrOrStdout(FILE *output, LogSeverity severity, const char *message, size_t len)
{
fwrite(message, len, 1, output);
fflush(output);
}
void ColoredWriteToStdout(LogSeverity severity, const char *message,
size_t len) {
void
ColoredWriteToStdout(LogSeverity severity, const char *message, size_t len)
{
FILE *output = stdout;
if (severity >= TILE_FATAL) {
output = stderr;
}
if (severity >= TILE_FATAL) { output = stderr; }
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);
}
void AddLogSink(LogSink::Ptr dest) {
void
AddLogSink(LogSink::Ptr dest)
{
std::lock_guard<std::mutex> _(g_sink_mutex);
g_sinks.insert(dest);
g_sink_count.fetch_add(1);
}
void RemoveLogSink(LogSink::Ptr dest) {
void
RemoveLogSink(LogSink::Ptr dest)
{
std::lock_guard<std::mutex> _(g_sink_mutex);
g_sinks.erase(dest);
g_sink_count.fetch_sub(1);
}
void SetStderrLogging(LogSeverity min_severity) {}
void LogToStderr() {}
void LogToSinks(LogSeverity severity, const char *full_filename,
const char *base_filename, int line, const LogMessageTime &time,
const char *message, size_t message_len) {
void
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) {
if (sink->ShouldLog(severity)) {
sink->Send(severity, full_filename, base_filename, line, time, message,
message_len);
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->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 = {
{TILE_INFO, "INFO" },
{TILE_WARNING, "WARNING"},

View File

@ -35,28 +35,35 @@ public:
LogStreamBuf(char *buf, int len) { setp(buf, buf + len - 2); }
int_type overflow(int_type ch) { return ch; }
size_t pcount() const { return static_cast<size_t>(pptr() - pbase()); }
char *pbase() const { return std::streambuf::pbase(); }
};
class LogSink;
class LogMessageTime;
class LogMessage {
public:
class LogStream : public std::ostream {
public:
LogStream(char *buf, int len, int64_t ctr)
: std::ostream(nullptr), streambuf_(buf, len), ctr_(ctr), self_(this) {
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) {
: std::ostream(nullptr),
streambuf_(std::move(other.streambuf_)),
ctr_(internal::Exchange(other.ctr_, 0)),
self_(this)
{
rdbuf(&streambuf_);
}
LogStream &operator=(LogStream &&other) noexcept {
LogStream &operator=(LogStream &&other) noexcept
{
streambuf_ = std::move(other.streambuf_);
ctr_ = internal::Exchange(other.ctr_, 0);
self_ = this;
@ -65,12 +72,15 @@ public:
}
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;
@ -86,8 +96,7 @@ 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(const char *file, int line, LogSeverity severity, LogSink *sink, bool also_send_to_log = true);
~LogMessage();
std::ostream &stream();
@ -550,6 +559,7 @@ FormatLog(const char *file, int line, Ts &&...args) noexcept
namespace tile {
typedef double WallTime;
struct LogMessageTime {
LogMessageTime();
LogMessageTime(std::tm t);
@ -557,18 +567,31 @@ struct LogMessageTime {
LogMessageTime(std::chrono::system_clock::time_point tp);
const time_t &timestamp() const { return timestamp_; }
const int &sec() const { return time_struct_.tm_sec; }
const int32_t &usec() const { return usecs_; }
const int &(min) () const { return time_struct_.tm_min; }
const int &hour() const { return time_struct_.tm_hour; }
const int &day() const { return time_struct_.tm_mday; }
const int &month() const { return time_struct_.tm_mon; }
const int &year() const { return time_struct_.tm_year; }
const int &dayOfWeek() const { return time_struct_.tm_wday; }
const int &dayInYear() const { return time_struct_.tm_yday; }
const int &dst() const { return time_struct_.tm_isdst; }
const long int &gmtoff() const { return gmtoffset_; }
const std::tm &tm() const { return time_struct_; }
const bool use_localtime() const { return use_localtime_; }
private:
@ -588,28 +611,36 @@ public:
virtual ~LogSink();
virtual bool ShouldLog(LogSeverity severity);
virtual void Send(LogSeverity severity, const char *full_filename,
const char *base_filename, int line,
const LogMessageTime &logmsgtime, const char *message,
virtual void Send(LogSeverity severity,
const char *full_filename,
const char *base_filename,
int line,
const LogMessageTime &logmsgtime,
const char *message,
size_t message_len);
virtual void Flush();
std::string ToString(LogSeverity severity, const char *file,
const char *base_file, int line,
const LogMessageTime &logmsgtime, const char *message,
std::string ToString(LogSeverity severity,
const char *file,
const char *base_file,
int line,
const LogMessageTime &logmsgtime,
const char *message,
size_t message_len);
};
void ColoredWriteToStdout(LogSeverity severity, const char *message,
size_t len);
void ColoredWriteToStderr(LogSeverity severity, const char *message,
size_t len);
void ColoredWriteToStdout(LogSeverity severity, const char *message, size_t len);
void ColoredWriteToStderr(LogSeverity severity, const char *message, size_t len);
void AddLogSink(LogSink::Ptr dest);
void RemoveLogSink(LogSink::Ptr dest);
void SetStderrLogging(LogSeverity min_severity);
void LogToStderr();
void LogToSinks(LogSeverity severity, const char *full_filename,
const char *base_filename, int line, const LogMessageTime &time,
const char *message, size_t message_len);
void 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);

View File

@ -6,10 +6,16 @@
#include <mutex>
namespace tile {
bool VLogIsOn(int n) { return true; }
bool
VLogIsOn(int n)
{
return true;
}
class LogMessage::Impl {
public:
Impl(const char *file, int line, int severity) : lm_(file, line, severity) {}
std::ostream &stream() { return lm_.stream(); }
private:
@ -19,21 +25,32 @@ private:
class LogMessageFatal::Impl {
public:
Impl(const char *file, int line) : lm_(file, line) {}
std::ostream &stream() { return lm_.stream(); }
private:
google::LogMessageFatal lm_;
};
LogMessage::LogMessage(const char *file, int line, int severity)
: impl_(new Impl(file, line, severity)) {}
LogMessage::~LogMessage() = default;
std::ostream &LogMessage::stream() { return impl_->stream(); }
LogMessage::LogMessage(const char *file, int line, int severity) : impl_(new Impl(file, line, severity)) {}
LogMessage::~LogMessage() = default;
std::ostream &
LogMessage::stream()
{
return impl_->stream();
}
LogMessageFatal::LogMessageFatal(const char *file, int line) : impl_(new Impl(file, line)) {}
LogMessageFatal::LogMessageFatal(const char *file, int line)
: impl_(new Impl(file, line)) {}
LogMessageFatal::~LogMessageFatal() = default;
std::ostream &LogMessageFatal::stream() { return impl_->stream(); }
std::ostream &
LogMessageFatal::stream()
{
return impl_->stream();
}
}// namespace tile
@ -41,43 +58,54 @@ namespace tile {
namespace internal {
namespace logging {
namespace {
std::vector<PrefixAppender *> *GetProviers() {
std::vector<PrefixAppender *> *
GetProviers()
{
static std::vector<PrefixAppender *> providers;
return &providers;
}
}// namespace
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(), ", "));
}
}// namespace details
void InstallPrefixProvider(PrefixAppender *writer) {
void
InstallPrefixProvider(PrefixAppender *writer)
{
GetProviers()->push_back(writer);
}
void WritePrefixTo(std::string *to) {
void
WritePrefixTo(std::string *to)
{
for (auto &&appender : *GetProviers()) {
auto was = to->size();
appender(to);
if (to->size() != was) {
to->push_back(' ');
}
if (to->size() != was) { to->push_back(' '); }
}
}
}// namespace logging
}// namespace internal
}// namespace tile
namespace tile {
LogMessageTime::LogMessageTime()
: time_struct_(), timestamp_(0), usecs_(0), gmtoffset_(0) {}
LogMessageTime::LogMessageTime() : 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);
init(t, timestamp, 0);
}
LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime now) {
LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime now)
{
std::tm t;
if (FLAGS_log_utc_time)
gmtime_r(&timestamp, &t);
@ -86,8 +114,9 @@ LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime now) {
init(t, timestamp, now);
}
void LogMessageTime::init(const std::tm &t, std::time_t timestamp,
WallTime now) {
void
LogMessageTime::init(const std::tm &t, std::time_t timestamp, WallTime now)
{
time_struct_ = t;
timestamp_ = timestamp;
usecs_ = static_cast<std::int32_t>((now - timestamp) * 1000000);
@ -95,7 +124,9 @@ void LogMessageTime::init(const std::tm &t, std::time_t timestamp,
CalcGmtOffset();
}
void LogMessageTime::CalcGmtOffset() {
void
LogMessageTime::CalcGmtOffset()
{
std::tm gmt_struct;
int isDst = 0;
if (FLAGS_log_utc_time) {
@ -111,36 +142,54 @@ void LogMessageTime::CalcGmtOffset() {
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));
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) {
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,
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);
const char *message,
size_t message_len)
{
return google::LogSink::ToString(severity, file, line, logmsgtime.tm(), message, message_len);
}
class LogSinkWrapper : public google::LogSink {
public:
LogSinkWrapper(tile::LogSink *dest) : dest_(dest) {}
~LogSinkWrapper() override {}
void send(LogSeverity severity, const char *full_filename,
const char *base_filename, int line,
const google::LogMessageTime &logmsgtime, const char *message,
size_t message_len) override {
dest_->send(severity, full_filename, base_filename, line, logmsgtime.tm(),
message, message_len);
void send(LogSeverity severity,
const char *full_filename,
const char *base_filename,
int line,
const google::LogMessageTime &logmsgtime,
const char *message,
size_t message_len) override
{
dest_->send(severity, full_filename, base_filename, line, logmsgtime.tm(), message, message_len);
}
void WaitTillSent() override { dest_->WaitTillSent(); }
@ -157,18 +206,20 @@ struct LogSinkPair {
static std::map<LogSink *, LogSinkWrapper *> sink_registry;
static std::mutex sink_registry_mutex;
void AddLogSink(LogSink *dest) {
void
AddLogSink(LogSink *dest)
{
std::lock_guard<std::mutex> lock(sink_registry_mutex);
if (sink_registry.find(dest) != sink_registry.end()) {
return;
}
if (sink_registry.find(dest) != sink_registry.end()) { return; }
auto wrapper = new LogSinkWrapper(dest);
sink_registry[dest] = wrapper;
google::AddLogSink(wrapper);
}
void RemoveLogSink(LogSink *dest) {
void
RemoveLogSink(LogSink *dest)
{
std::lock_guard<std::mutex> lock(sink_registry_mutex);
auto iter = sink_registry.find(dest);
if (iter != sink_registry.end()) {
@ -177,11 +228,22 @@ void RemoveLogSink(LogSink *dest) {
delete iter->second;
}
}
void SetStderrLogging(LogSeverity min_severity) {
void
SetStderrLogging(LogSeverity 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);
}
}// namespace tile

View File

@ -9,17 +9,31 @@
#include <thread>
struct AwesomeLogSink : public tile::LogSink {
virtual void Send(tile::LogSeverity severity, const char *full_filename,
const char *base_filename, int line,
const tile::LogMessageTime &logmsgtime, const char *message,
size_t message_len) override {
static std::shared_ptr<AwesomeLogSink> Create() { return std::make_shared<AwesomeLogSink>(); }
virtual void Send(tile::LogSeverity severity,
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));
}
std::vector<std::string> msgs;
};
std::string my_prefix, my_prefix2;
void
ResetLogPrefix()
{
my_prefix.clear();
my_prefix2.clear();
}
void
WriteLoggingPrefix(std::string *s)
{
@ -32,7 +46,8 @@ WriteLoggingPrefix2(std::string *s)
*s += my_prefix2;
}
TEST(Logging, Prefix) {
TEST(Logging, Prefix)
{
auto sink = std::make_shared<AwesomeLogSink>();
tile::AddLogSink(sink);
tile::ScopedDeferred defered([&] { tile::RemoveLogSink(sink); });
@ -49,9 +64,8 @@ TEST(Logging, Prefix) {
TILE_LOG_INFO("something");
ASSERT_THAT(sink->msgs,
::testing::ElementsAre("something", "[prefix] something",
"[prefix1] something",
"[prefix1] [prefix2] something"));
::testing::ElementsAre(
"something", "[prefix] something", "[prefix1] something", "[prefix1] [prefix2] something"));
}
TEST(Logging, CHECK)
@ -65,13 +79,13 @@ TEST(Logging, CHECK)
ASSERT_DEATH(([] { TILE_CHECK_NE(1, 1, "CHECK_NE"); }()), "CHECK_NE");
}
TEST(Logging, Prefix)
{
AwesomeLogSink sink;
tile::AddLogSink(&sink);
tile::ScopedDeferred defered([&] { tile::RemoveLogSink(&sink); });
TEST(Logging, DontPanicOnFormatFailure) { TILE_LOG_INFO("Don't panic!{}{}", 1); }
auto sink = std::make_shared<AwesomeLogSink>();
TEST(Logging, EverySecond)
{
ResetLogPrefix();
auto sink = AwesomeLogSink::Create();
tile::AddLogSink(sink);
tile::ScopedDeferred defered([&] { tile::RemoveLogSink(sink); });
for (int i = 0; i < 30; i++) {
@ -79,25 +93,7 @@ TEST(Logging, Prefix)
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
ASSERT_THAT(sink->msgs,
::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"));
ASSERT_THAT(sink->msgs, ::testing::ElementsAre("something", "something", "something"));
}
TEST(Logging, Enum)

View File

@ -1,24 +1,47 @@
#include "tile/base/logging/basic_file_sink.h"
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());
sink->set_filepath(filepath);
return sink;
}
BasicFileSink::BasicFileSink() {}
BasicFileSink::~BasicFileSink() {}
void BasicFileSink::Send(LogSeverity severity, const char *full_filename,
const char *base_filename, int line,
const LogMessageTime &logmsgtime, const char *message,
size_t message_len) {
void
BasicFileSink::Send(LogSeverity severity,
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");
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;
ofs_.open(filepath, std::ios::out | std::ios::app);
}
void BasicFileSink::Flush() { ofs_.flush(); }
void
BasicFileSink::Flush()
{
ofs_.flush();
}
}// namespace tile

View File

@ -14,9 +14,12 @@ public:
static Ptr Create(const std::string &filepath);
~BasicFileSink() override;
void Send(LogSeverity severity, const char *full_filename,
const char *base_filename, int line,
const LogMessageTime &logmsgtime, const char *message,
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 Flush() override;

View File

@ -1,23 +1,28 @@
#include "tile/base/logging/console_sink.h"
#include <stdio.h>
namespace tile {
ConsoleSink::Ptr ConsoleSink::Create() {
ConsoleSink::Ptr
ConsoleSink::Create()
{
return std::shared_ptr<ConsoleSink>(new ConsoleSink());
}
ConsoleSink::~ConsoleSink() {}
void ConsoleSink::Send(LogSeverity severity, const char *full_filename,
const char *base_filename, int line,
const LogMessageTime &logmsgtime, const char *message,
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();
}
void
ConsoleSink::Send(LogSeverity severity,
const char *full_filename,
const char *base_filename,
int line,
const LogMessageTime &logmsgtime,
const char *message,
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) {
fprintf(stderr, "%s\n", msg.c_str());
} else {
@ -25,7 +30,9 @@ void ConsoleSink::Send(LogSeverity severity, const char *full_filename,
}
}
void ConsoleSink::Flush() {}
void
ConsoleSink::Flush()
{}
ConsoleSink::ConsoleSink() {}

View File

@ -4,6 +4,7 @@
#pragma once
#include "tile/base/internal/logging.h"
namespace tile {
class ConsoleSink : public LogSink {
public:
@ -11,9 +12,12 @@ public:
static Ptr Create();
~ConsoleSink() override;
void Send(LogSeverity severity, const char *full_filename,
const char *base_filename, int line,
const LogMessageTime &logmsgtime, const char *message,
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 Flush() override;

View File

@ -2,60 +2,76 @@
#include <cassert>
namespace tile {
std::shared_ptr<SplitterSink> SplitterSink::Create() {
std::shared_ptr<SplitterSink>
SplitterSink::Create()
{
return std::shared_ptr<SplitterSink>(new SplitterSink());
}
std::shared_ptr<SplitterSink> SplitterSink::Create(
std::initializer_list<std::shared_ptr<LogSink>> init_list) {
std::shared_ptr<SplitterSink>
SplitterSink::Create(std::initializer_list<std::shared_ptr<LogSink>> init_list)
{
auto sink = Create();
for (auto &s : init_list) {
sink->AddSink(s);
}
for (auto &s : init_list) { sink->AddSink(s); }
return sink;
}
SplitterSink::SplitterSink() {}
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) {
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);
sink->Send(severity, full_filename, base_filename, line, logmsgtime, message, message_len);
}
doing_ = false;
}
void SplitterSink::Flush() {
void
SplitterSink::Flush()
{
assert(!doing_ && "SplitterSink::send() should not be called recursively");
std::lock_guard<std::mutex> _(sinks_mutex_);
doing_ = true;
for (auto &sink : sinks_) {
sink->Flush();
}
for (auto &sink : sinks_) { sink->Flush(); }
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_);
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_);
sinks_.erase(sink);
}
void SplitterSink::ClearSinks() {
void
SplitterSink::ClearSinks()
{
std::lock_guard<std::mutex> _(sinks_mutex_);
sinks_.clear();
}
std::set<LogSink::Ptr> SplitterSink::sinks() {
std::set<LogSink::Ptr>
SplitterSink::sinks()
{
std::lock_guard<std::mutex> _(sinks_mutex_);
return sinks_;
}

View File

@ -16,9 +16,12 @@ public:
~SplitterSink() override;
void Send(LogSeverity severity, const char *full_filename,
const char *base_filename, int line,
const LogMessageTime &logmsgtime, const char *message,
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 Flush() override;

View File

@ -5,51 +5,55 @@ namespace tile {
class SimpleSink : public LogSink {
public:
using Ptr = std::shared_ptr<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,
const LogMessageTime &logmsgtime, const char *message,
size_t message_len) 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
{
message_ = std::string(message, message_len);
}
void Flush() override {}
std::string message_;
};
TEST(SplitterSink, One) {
TEST(SplitterSink, One)
{
auto sink = SimpleSink::Create();
auto splitter = SplitterSink::Create({sink});
splitter->Send(LogSeverity::TILE_INFO, nullptr, nullptr, 0, LogMessageTime(),
"message", 7);
splitter->Send(LogSeverity::TILE_INFO, nullptr, nullptr, 0, LogMessageTime(), "message", 7);
ASSERT_EQ(sink->message_, "message");
}
TEST(SplitterSink, Two) {
TEST(SplitterSink, Two)
{
auto sink1 = SimpleSink::Create();
auto sink2 = SimpleSink::Create();
auto splitter = SplitterSink::Create({sink1, sink2});
splitter->Send(LogSeverity::TILE_INFO, nullptr, nullptr, 0, LogMessageTime(),
"message", 7);
splitter->Send(LogSeverity::TILE_INFO, nullptr, nullptr, 0, LogMessageTime(), "message", 7);
ASSERT_EQ(sink1->message_, "message");
ASSERT_EQ(sink2->message_, "message");
}
TEST(SplitterSink, Multi) {
TEST(SplitterSink, Multi)
{
auto splitter = SplitterSink::Create();
for (int i = 0; i < 100; i++) {
splitter->AddSink(SimpleSink::Create());
}
for (int i = 0; i < 100; i++) { splitter->AddSink(SimpleSink::Create()); }
for (int i = 0; i < 100; i++) {
std::stringstream ss;
ss << "message" << i;
auto msg = ss.str();
splitter->Send(LogSeverity::TILE_INFO, nullptr, nullptr, 0,
LogMessageTime(), msg.data(), msg.size());
splitter->Send(LogSeverity::TILE_INFO, nullptr, nullptr, 0, LogMessageTime(), msg.data(), msg.size());
for (auto &sink : splitter->sinks()) {
ASSERT_EQ(std::static_pointer_cast<SimpleSink>(sink)->message_, msg);
}
for (auto &sink : splitter->sinks()) { ASSERT_EQ(std::static_pointer_cast<SimpleSink>(sink)->message_, msg); }
}
}

View File

@ -32,7 +32,9 @@ namespace {
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);
if (old && FLAGS_tile_abort_on_double_quit_signal) {
// TODO: Add TILE_RAW_LOG
@ -52,8 +54,9 @@ InstallQuitSignalHandler()
}
}// namespace
int Start(int argc, char **argv, std::function<int(int, char **)> cb,
bool single_thread, bool enable_crash_catch) {
int
Start(int argc, char **argv, std::function<int(int, char **)> cb, bool single_thread, bool enable_crash_catch)
{
if (enable_crash_catch) {
// TODO: Add InstallFailureSignalHandler
// google::InstallFailureSignalHandler();

View File

@ -10,18 +10,20 @@ namespace tile {
namespace testing {
namespace {
int StartBenchmark(int argc, char **argv) {
int
StartBenchmark(int argc, char **argv)
{
::benchmark::Initialize(&argc, argv);
if (::benchmark::ReportUnrecognizedArguments(argc, argv)) {
return 1;
}
if (::benchmark::ReportUnrecognizedArguments(argc, argv)) { return 1; }
::benchmark::RunSpecifiedBenchmarks();
::benchmark::Shutdown();
return 0;
}
}// namespace
int InitAndRunAllBenchmarks(int *argc, char **argv) {
int
InitAndRunAllBenchmarks(int *argc, char **argv)
{
// if (gflags::GetCommandLineFlagInfoOrDie("logtostderr").is_default) {
// FLAGS_logtostderr = true;