feat(logger): use chrono (#1039)

This commit is contained in:
Sergiu Deitsch 2024-01-05 23:07:49 +01:00 committed by GitHub
parent f88544adf5
commit eb72e4c181
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 148 additions and 102 deletions

View File

@ -83,29 +83,40 @@ struct GLOG_EXPORT LogMessageTime {
LogMessageTime(); LogMessageTime();
explicit LogMessageTime(std::chrono::system_clock::time_point now); explicit LogMessageTime(std::chrono::system_clock::time_point now);
const time_t& timestamp() const { return timestamp_; } [[deprecated("Use LogMessageTime::when() instead.")]] std::time_t timestamp()
const int& sec() const { return time_struct_.tm_sec; } const noexcept {
const int32_t& usec() const { return usecs_; } return std::chrono::system_clock::to_time_t(when());
const int&(min)() const { return time_struct_.tm_min; } }
const int& hour() const { return time_struct_.tm_hour; } const std::chrono::system_clock::time_point& when() const noexcept {
const int& day() const { return time_struct_.tm_mday; } return timestamp_;
const int& month() const { return time_struct_.tm_mon; } }
const int& year() const { return time_struct_.tm_year; } int sec() const noexcept { return tm_.tm_sec; }
const int& dayOfWeek() const { return time_struct_.tm_wday; } long usec() const noexcept { return usecs_.count(); }
const int& dayInYear() const { return time_struct_.tm_yday; } int(min)() const noexcept { return tm_.tm_min; }
const int& dst() const { return time_struct_.tm_isdst; } int hour() const noexcept { return tm_.tm_hour; }
const long int& gmtoff() const { return gmtoffset_; } int day() const noexcept { return tm_.tm_mday; }
const std::tm& tm() const { return time_struct_; } int month() const noexcept { return tm_.tm_mon; }
int year() const noexcept { return tm_.tm_year; }
int dayOfWeek() const noexcept { return tm_.tm_wday; }
int dayInYear() const noexcept { return tm_.tm_yday; }
int dst() const noexcept { return tm_.tm_isdst; }
[[deprecated("Use LogMessageTime::gmtoffset() instead.")]] long gmtoff()
const noexcept {
return gmtoffset_.count();
}
std::chrono::seconds gmtoffset() const noexcept { return gmtoffset_; }
const std::tm& tm() const noexcept { return tm_; }
private: private:
void init(const std::tm& t, std::time_t timestamp, void init(const std::tm& t, std::time_t timestamp,
std::chrono::system_clock::time_point now); std::chrono::system_clock::time_point now);
std::tm time_struct_; // Time of creation of LogMessage void CalcGmtOffset(std::time_t t);
time_t timestamp_; // Time of creation of LogMessage in seconds
int32_t usecs_; // Time of creation of LogMessage - microseconds part
long int gmtoffset_;
void CalcGmtOffset(); std::tm tm_{}; // Time of creation of LogMessage
std::chrono::system_clock::time_point
timestamp_; // Time of creation of LogMessage in seconds
std::chrono::microseconds usecs_;
std::chrono::seconds gmtoffset_;
}; };
struct LogMessageInfo { struct LogMessageInfo {
@ -347,7 +358,7 @@ typedef void (*CustomPrefixCallback)(std::ostream& s, const LogMessageInfo& l,
// timestamps from different machines. // timestamps from different machines.
// Log messages below the GOOGLE_STRIP_LOG level will be compiled away for // Log messages below the GOOGLE_STRIP_LOG level will be compiled away for
// security reasons. See LOG(severtiy) below. // security reasons. See LOG(severity) below.
// A few definitions of macros that don't generate much code. Since // A few definitions of macros that don't generate much code. Since
// LOG(INFO) and its ilk are used all over our code, it's // LOG(INFO) and its ilk are used all over our code, it's
@ -1304,7 +1315,12 @@ class GLOG_EXPORT LogMessage {
// Must be called without the log_mutex held. (L < log_mutex) // Must be called without the log_mutex held. (L < log_mutex)
static int64 num_messages(int severity); static int64 num_messages(int severity);
const LogMessageTime& getLogMessageTime() const; [[deprecated("Use LogMessage::time() instead.")]] const LogMessageTime&
getLogMessageTime() const {
return time();
}
const LogMessageTime& time() const;
struct LogMessageData; struct LogMessageData;
@ -1331,7 +1347,7 @@ class GLOG_EXPORT LogMessage {
// LogMessage uses less stack space. // LogMessage uses less stack space.
LogMessageData* allocated_; LogMessageData* allocated_;
LogMessageData* data_; LogMessageData* data_;
LogMessageTime logmsgtime_; LogMessageTime time_;
friend class LogDestination; friend class LogDestination;
@ -1567,8 +1583,15 @@ class GLOG_EXPORT Logger {
// appropriate by the higher level logging facility. For example, // appropriate by the higher level logging facility. For example,
// textual log messages already contain timestamps, and the // textual log messages already contain timestamps, and the
// file:linenumber header. // file:linenumber header.
virtual void Write(bool force_flush, time_t timestamp, const char* message, [[deprecated(
size_t message_len) = 0; "Logger::Write accepting a std::time_t timestamp is provided for "
"compatibility purposes only. New code should implement the "
"std::chrono::system_clock::time_point overload.")]] virtual void
Write(bool force_flush, time_t timestamp, const char* message,
size_t message_len);
virtual void Write(bool force_flush,
const std::chrono::system_clock::time_point& timestamp,
const char* message, size_t message_len);
// Flush any buffered messages // Flush any buffered messages
virtual void Flush() = 0; virtual void Flush() = 0;

View File

@ -342,6 +342,28 @@ static bool SendEmailInternal(const char* dest, const char* subject,
base::Logger::~Logger() = default; base::Logger::~Logger() = default;
void base::Logger::Write(bool /*force_flush*/, time_t /*timestamp*/,
const char* /*message*/, size_t /*message_len*/) {}
void base::Logger::Write(bool force_flush,
const std::chrono::system_clock::time_point& timestamp,
const char* message, size_t message_len) {
#if defined(__GNUG__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#elif defined(_MSC_VER)
# pragma warning(push)
# pragma warning(disable : 4996)
#endif // __GNUG__
return Write(force_flush, std::chrono::system_clock::to_time_t(timestamp),
message, message_len);
#if defined(__GNUG__)
# pragma GCC diagnostic pop
#elif defined(_MSC_VER)
# pragma warning(pop)
#endif // __GNUG__
}
namespace { namespace {
constexpr std::intmax_t kSecondsInDay = 60 * 60 * 24; constexpr std::intmax_t kSecondsInDay = 60 * 60 * 24;
@ -359,7 +381,8 @@ class LogFileObject : public base::Logger {
~LogFileObject() override; ~LogFileObject() override;
void Write(bool force_flush, // Should we force a flush here? void Write(bool force_flush, // Should we force a flush here?
time_t timestamp, // Timestamp for this entry const std::chrono::system_clock::time_point&
timestamp, // Timestamp for this entry
const char* message, size_t message_len) override; const char* message, size_t message_len) override;
// Configuration options // Configuration options
@ -506,12 +529,16 @@ class LogDestination {
size_t len); size_t len);
// Take a log message of a particular severity and log it to a file // Take a log message of a particular severity and log it to a file
// iff the base filename is not "" (which means "don't log to me") // iff the base filename is not "" (which means "don't log to me")
static void MaybeLogToLogfile(LogSeverity severity, time_t timestamp, static void MaybeLogToLogfile(
LogSeverity severity,
const std::chrono::system_clock::time_point& timestamp,
const char* message, size_t len); const char* message, size_t len);
// Take a log message of a particular severity and log it to the file // Take a log message of a particular severity and log it to the file
// for that severity and also for all files with severity less than // for that severity and also for all files with severity less than
// this severity. // this severity.
static void LogToAllLogfiles(LogSeverity severity, time_t timestamp, static void LogToAllLogfiles(
LogSeverity severity,
const std::chrono::system_clock::time_point& timestamp,
const char* message, size_t len); const char* message, size_t len);
// Send logging info to all registered sinks. // Send logging info to all registered sinks.
@ -804,17 +831,19 @@ inline void LogDestination::MaybeLogToEmail(LogSeverity severity,
} }
} }
inline void LogDestination::MaybeLogToLogfile(LogSeverity severity, inline void LogDestination::MaybeLogToLogfile(
time_t timestamp, LogSeverity severity,
const char* message, size_t len) { const std::chrono::system_clock::time_point& timestamp, const char* message,
size_t len) {
const bool should_flush = severity > FLAGS_logbuflevel; const bool should_flush = severity > FLAGS_logbuflevel;
LogDestination* destination = log_destination(severity); LogDestination* destination = log_destination(severity);
destination->logger_->Write(should_flush, timestamp, message, len); destination->logger_->Write(should_flush, timestamp, message, len);
} }
inline void LogDestination::LogToAllLogfiles(LogSeverity severity, inline void LogDestination::LogToAllLogfiles(
time_t timestamp, LogSeverity severity,
const char* message, size_t len) { const std::chrono::system_clock::time_point& timestamp, const char* message,
size_t len) {
if (FLAGS_logtostdout) { // global flag: never log to file if (FLAGS_logtostdout) { // global flag: never log to file
ColoredWriteToStdout(severity, message, len); ColoredWriteToStdout(severity, message, len);
} else if (FLAGS_logtostderr) { // global flag: never log to file } else if (FLAGS_logtostderr) { // global flag: never log to file
@ -1077,7 +1106,8 @@ bool LogFileObject::CreateLogfile(const string& time_pid_string) {
return true; // Everything worked return true; // Everything worked
} }
void LogFileObject::Write(bool force_flush, time_t timestamp, void LogFileObject::Write(
bool force_flush, const std::chrono::system_clock::time_point& timestamp,
const char* message, size_t message_len) { const char* message, size_t message_len) {
std::lock_guard<std::mutex> l{mutex_}; std::lock_guard<std::mutex> l{mutex_};
@ -1086,9 +1116,7 @@ void LogFileObject::Write(bool force_flush, time_t timestamp,
return; return;
} }
const auto now = std::chrono::system_clock::now(); auto cleanupLogs = [this, current_time = timestamp] {
auto cleanupLogs = [this, current_time = now] {
if (log_cleaner.enabled()) { if (log_cleaner.enabled()) {
log_cleaner.Run(current_time, base_filename_selected_, base_filename_, log_cleaner.Run(current_time, base_filename_selected_, base_filename_,
filename_extension_); filename_extension_);
@ -1114,10 +1142,12 @@ void LogFileObject::Write(bool force_flush, time_t timestamp,
rollover_attempt_ = 0; rollover_attempt_ = 0;
struct ::tm tm_time; struct ::tm tm_time;
std::time_t t = std::chrono::system_clock::to_time_t(timestamp);
if (FLAGS_log_utc_time) { if (FLAGS_log_utc_time) {
gmtime_r(&timestamp, &tm_time); gmtime_r(&t, &tm_time);
} else { } else {
localtime_r(&timestamp, &tm_time); localtime_r(&t, &tm_time);
} }
// The logfile's filename will have the date/time & pid in it // The logfile's filename will have the date/time & pid in it
@ -1208,7 +1238,7 @@ void LogFileObject::Write(bool force_flush, time_t timestamp,
<< "Running duration (h:mm:ss): " << "Running duration (h:mm:ss): "
<< PrettyDuration( << PrettyDuration(
std::chrono::duration_cast<std::chrono::duration<int>>( std::chrono::duration_cast<std::chrono::duration<int>>(
now - start_time_)) timestamp - start_time_))
<< '\n' << '\n'
<< "Log line format: [IWEF]" << date_time_format << " " << "Log line format: [IWEF]" << date_time_format << " "
<< "threadid file:line] msg" << '\n'; << "threadid file:line] msg" << '\n';
@ -1239,7 +1269,7 @@ void LogFileObject::Write(bool force_flush, time_t timestamp,
bytes_since_flush_ += message_len; bytes_since_flush_ += message_len;
} }
} else { } else {
if (now >= next_flush_time_) { if (timestamp >= next_flush_time_) {
stop_writing = false; // check to see if disk has free space. stop_writing = false; // check to see if disk has free space.
} }
return; // no need to flush return; // no need to flush
@ -1248,8 +1278,8 @@ void LogFileObject::Write(bool force_flush, time_t timestamp,
// See important msgs *now*. Also, flush logs at least every 10^6 chars, // See important msgs *now*. Also, flush logs at least every 10^6 chars,
// or every "FLAGS_logbufsecs" seconds. // or every "FLAGS_logbufsecs" seconds.
if (force_flush || (bytes_since_flush_ >= 1000000) || if (force_flush || (bytes_since_flush_ >= 1000000) ||
(now >= next_flush_time_)) { (timestamp >= next_flush_time_)) {
FlushUnlocked(now); FlushUnlocked(timestamp);
#ifdef GLOG_OS_LINUX #ifdef GLOG_OS_LINUX
// Only consider files >= 3MiB // Only consider files >= 3MiB
if (FLAGS_drop_log_memory && file_length_ >= (3U << 20U)) { if (FLAGS_drop_log_memory && file_length_ >= (3U << 20U)) {
@ -1587,8 +1617,8 @@ void LogMessage::Init(const char* file, int line, LogSeverity severity,
data_->sink_ = nullptr; data_->sink_ = nullptr;
data_->outvec_ = nullptr; data_->outvec_ = nullptr;
auto now = std::chrono::system_clock::now(); const auto now = std::chrono::system_clock::now();
logmsgtime_ = LogMessageTime(now); time_ = LogMessageTime(now);
data_->num_chars_to_log_ = 0; data_->num_chars_to_log_ = 0;
data_->num_chars_to_syslog_ = 0; data_->num_chars_to_syslog_ = 0;
@ -1607,20 +1637,19 @@ void LogMessage::Init(const char* file, int line, LogSeverity severity,
if (custom_prefix_callback == nullptr) { if (custom_prefix_callback == nullptr) {
stream() << LogSeverityNames[severity][0]; stream() << LogSeverityNames[severity][0];
if (FLAGS_log_year_in_prefix) { if (FLAGS_log_year_in_prefix) {
stream() << setw(4) << 1900 + logmsgtime_.year(); stream() << setw(4) << 1900 + time_.year();
} }
stream() << setw(2) << 1 + logmsgtime_.month() << setw(2) stream() << setw(2) << 1 + time_.month() << setw(2) << time_.day() << ' '
<< logmsgtime_.day() << ' ' << setw(2) << logmsgtime_.hour() << setw(2) << time_.hour() << ':' << setw(2) << time_.min()
<< ':' << setw(2) << logmsgtime_.min() << ':' << setw(2) << ':' << setw(2) << time_.sec() << "." << setw(6)
<< logmsgtime_.sec() << "." << setw(6) << logmsgtime_.usec() << time_.usec() << ' ' << setfill(' ') << setw(5)
<< ' ' << setfill(' ') << setw(5) << std::this_thread::get_id() << std::this_thread::get_id() << setfill('0') << ' '
<< setfill('0') << ' ' << data_->basename_ << ':' << data_->line_ << data_->basename_ << ':' << data_->line_ << "] ";
<< "] ";
} else { } else {
custom_prefix_callback( custom_prefix_callback(
stream(), stream(),
LogMessageInfo(LogSeverityNames[severity], data_->basename_, LogMessageInfo(LogSeverityNames[severity], data_->basename_,
data_->line_, std::this_thread::get_id(), logmsgtime_), data_->line_, std::this_thread::get_id(), time_),
custom_prefix_callback_data); custom_prefix_callback_data);
stream() << " "; stream() << " ";
} }
@ -1641,9 +1670,7 @@ void LogMessage::Init(const char* file, int line, LogSeverity severity,
} }
} }
const LogMessageTime& LogMessage::getLogMessageTime() const { const LogMessageTime& LogMessage::time() const { return time_; }
return logmsgtime_;
}
LogMessage::~LogMessage() { LogMessage::~LogMessage() {
Flush(); Flush();
@ -1722,7 +1749,7 @@ void LogMessage::Flush() {
// Copy of first FATAL log message so that we can print it out again // Copy of first FATAL log message so that we can print it out again
// after all the stack traces. To preserve legacy behavior, we don't // after all the stack traces. To preserve legacy behavior, we don't
// use fatal_msg_data_exclusive. // use fatal_msg_data_exclusive.
static time_t fatal_time; static std::chrono::system_clock::time_point fatal_time;
static char fatal_message[256]; static char fatal_message[256];
void ReprintFatalMessage() { void ReprintFatalMessage() {
@ -1769,11 +1796,11 @@ void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
// this could be protected by a flag if necessary. // this could be protected by a flag if necessary.
LogDestination::LogToSinks( LogDestination::LogToSinks(
data_->severity_, data_->fullname_, data_->basename_, data_->line_, data_->severity_, data_->fullname_, data_->basename_, data_->line_,
logmsgtime_, data_->message_text_ + data_->num_prefix_chars_, time_, data_->message_text_ + data_->num_prefix_chars_,
(data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1)); (data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1));
} else { } else {
// log this message to all log files of severity <= severity_ // log this message to all log files of severity <= severity_
LogDestination::LogToAllLogfiles(data_->severity_, logmsgtime_.timestamp(), LogDestination::LogToAllLogfiles(data_->severity_, time_.when(),
data_->message_text_, data_->message_text_,
data_->num_chars_to_log_); data_->num_chars_to_log_);
@ -1784,7 +1811,7 @@ void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
data_->num_chars_to_log_); data_->num_chars_to_log_);
LogDestination::LogToSinks( LogDestination::LogToSinks(
data_->severity_, data_->fullname_, data_->basename_, data_->line_, data_->severity_, data_->fullname_, data_->basename_, data_->line_,
logmsgtime_, data_->message_text_ + data_->num_prefix_chars_, time_, data_->message_text_ + data_->num_prefix_chars_,
(data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1)); (data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1));
// NOTE: -1 removes trailing \n // NOTE: -1 removes trailing \n
} }
@ -1804,13 +1831,14 @@ void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
min(data_->num_chars_to_log_, sizeof(fatal_message) - 1); min(data_->num_chars_to_log_, sizeof(fatal_message) - 1);
memcpy(fatal_message, data_->message_text_, copy); memcpy(fatal_message, data_->message_text_, copy);
fatal_message[copy] = '\0'; fatal_message[copy] = '\0';
fatal_time = logmsgtime_.timestamp(); fatal_time = time_.when();
} }
if (!FLAGS_logtostderr && !FLAGS_logtostdout) { if (!FLAGS_logtostderr && !FLAGS_logtostdout) {
for (auto& log_destination : LogDestination::log_destinations_) { for (auto& log_destination : LogDestination::log_destinations_) {
if (log_destination) { if (log_destination) {
log_destination->logger_->Write(true, 0, "", 0); log_destination->logger_->Write(
true, std::chrono::system_clock::time_point{}, "", 0);
} }
} }
} }
@ -1880,7 +1908,7 @@ void LogMessage::SendToSink() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
""); "");
data_->sink_->send( data_->sink_->send(
data_->severity_, data_->fullname_, data_->basename_, data_->line_, data_->severity_, data_->fullname_, data_->basename_, data_->line_,
logmsgtime_, data_->message_text_ + data_->num_prefix_chars_, time_, data_->message_text_ + data_->num_prefix_chars_,
(data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1)); (data_->num_chars_to_log_ - data_->num_prefix_chars_ - 1));
} }
} }
@ -2005,20 +2033,20 @@ void LogSink::send(LogSeverity severity, const char* full_filename,
const char* base_filename, int line, const char* base_filename, int line,
const LogMessageTime& time, const char* message, const LogMessageTime& time, const char* message,
size_t message_len) { size_t message_len) {
#if defined(__GNUC__) #if defined(__GNUG__)
# pragma GCC diagnostic push # pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations" # pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
# pragma warning(push) # pragma warning(push)
# pragma warning(disable : 4996) # pragma warning(disable : 4996)
#endif // __GNUC__ #endif // __GNUG__
send(severity, full_filename, base_filename, line, &time.tm(), message, send(severity, full_filename, base_filename, line, &time.tm(), message,
message_len); message_len);
#if defined(__GNUC__) #if defined(__GNUG__)
# pragma GCC diagnostic pop # pragma GCC diagnostic pop
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
# pragma warning(pop) # pragma warning(pop)
#endif // __GNUC__ #endif // __GNUG__
} }
void LogSink::send(LogSeverity severity, const char* full_filename, void LogSink::send(LogSeverity severity, const char* full_filename,
@ -2649,49 +2677,41 @@ void EnableLogCleaner(const std::chrono::minutes& overdue) {
void DisableLogCleaner() { log_cleaner.Disable(); } void DisableLogCleaner() { log_cleaner.Disable(); }
LogMessageTime::LogMessageTime() LogMessageTime::LogMessageTime() = default;
: time_struct_(), timestamp_(0), usecs_(0), gmtoffset_(0) {}
LogMessageTime::LogMessageTime(std::chrono::system_clock::time_point now) { LogMessageTime::LogMessageTime(std::chrono::system_clock::time_point now)
: timestamp_{now} {
std::time_t timestamp = std::chrono::system_clock::to_time_t(now); std::time_t timestamp = std::chrono::system_clock::to_time_t(now);
std::tm t;
if (FLAGS_log_utc_time) { if (FLAGS_log_utc_time) {
gmtime_r(&timestamp, &t); gmtime_r(&timestamp, &tm_);
} else { } else {
localtime_r(&timestamp, &t); localtime_r(&timestamp, &tm_);
} }
init(t, timestamp, now); usecs_ = std::chrono::duration_cast<std::chrono::microseconds>(
now - std::chrono::system_clock::from_time_t(timestamp));
CalcGmtOffset(timestamp);
} }
void LogMessageTime::init(const std::tm& t, std::time_t timestamp, void LogMessageTime::CalcGmtOffset(std::time_t t) {
std::chrono::system_clock::time_point now) {
time_struct_ = t;
timestamp_ = timestamp;
usecs_ = std::chrono::duration_cast<std::chrono::duration<int32, std::micro>>(
now - std::chrono::system_clock::from_time_t(timestamp))
.count();
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) {
localtime_r(&timestamp_, &gmt_struct); localtime_r(&t, &gmt_struct);
isDst = gmt_struct.tm_isdst; isDst = gmt_struct.tm_isdst;
gmt_struct = time_struct_; gmt_struct = tm_;
} else { } else {
isDst = time_struct_.tm_isdst; isDst = tm_.tm_isdst;
gmtime_r(&timestamp_, &gmt_struct); gmtime_r(&t, &gmt_struct);
} }
time_t gmt_sec = mktime(&gmt_struct); time_t gmt_sec = mktime(&gmt_struct);
const long hour_secs = 3600;
// If the Daylight Saving Time(isDst) is active subtract an hour from the // If the Daylight Saving Time(isDst) is active subtract an hour from the
// current timestamp. // current timestamp.
gmtoffset_ = using namespace std::chrono_literals;
static_cast<long int>(timestamp_ - gmt_sec + (isDst ? hour_secs : 0)); gmtoffset_ = std::chrono::duration_cast<std::chrono::seconds>(
timestamp_ - std::chrono::system_clock::from_time_t(gmt_sec) +
(isDst ? 1h : 0h));
} }
} // namespace google } // namespace google

View File

@ -937,7 +937,8 @@ struct MyLogger : public base::Logger {
~MyLogger() override { *set_on_destruction_ = true; } ~MyLogger() override { *set_on_destruction_ = true; }
void Write(bool /* should_flush */, time_t /* timestamp */, void Write(bool /* should_flush */,
const std::chrono::system_clock::time_point& /* timestamp */,
const char* message, size_t length) override { const char* message, size_t length) override {
data.append(message, length); data.append(message, length);
} }
@ -1070,8 +1071,9 @@ struct RecordDeletionLogger : public base::Logger {
*set_on_destruction_ = false; *set_on_destruction_ = false;
} }
~RecordDeletionLogger() override { *set_on_destruction_ = true; } ~RecordDeletionLogger() override { *set_on_destruction_ = true; }
void Write(bool force_flush, time_t timestamp, const char* message, void Write(bool force_flush,
size_t length) override { const std::chrono::system_clock::time_point& timestamp,
const char* message, size_t length) override {
wrapped_logger_->Write(force_flush, timestamp, message, length); wrapped_logger_->Write(force_flush, timestamp, message, length);
} }
void Flush() override { wrapped_logger_->Flush(); } void Flush() override { wrapped_logger_->Flush(); }
@ -1535,10 +1537,11 @@ TEST(LogMsgTime, gmtoff) {
* */ * */
google::LogMessage log_obj(__FILE__, __LINE__); google::LogMessage log_obj(__FILE__, __LINE__);
long int nGmtOff = log_obj.getLogMessageTime().gmtoff(); std::chrono::seconds nGmtOff = log_obj.time().gmtoffset();
// GMT offset ranges from UTC-12:00 to UTC+14:00 // GMT offset ranges from UTC-12:00 to UTC+14:00
const long utc_min_offset = -43200; using namespace std::chrono_literals;
const long utc_max_offset = 50400; const std::chrono::hours utc_min_offset = -12h;
const std::chrono::hours utc_max_offset = 14h;
EXPECT_TRUE((nGmtOff >= utc_min_offset) && (nGmtOff <= utc_max_offset)); EXPECT_TRUE((nGmtOff >= utc_min_offset) && (nGmtOff <= utc_max_offset));
} }