feat: use chrono (#1020)
This commit is contained in:
parent
4244cec140
commit
70285fddc7
39
COPYING
39
COPYING
@ -1,4 +1,4 @@
|
||||
Copyright (c) 2008, Google Inc.
|
||||
Copyright (c) 2024, Google Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
@ -26,40 +26,3 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
A function gettimeofday in utilities.cc is based on
|
||||
|
||||
http://www.google.com/codesearch/p?hl=en#dR3YEbitojA/COPYING&q=GetSystemTimeAsFileTime%20license:bsd
|
||||
|
||||
The license of this code is:
|
||||
|
||||
Copyright (c) 2003-2008, Jouni Malinen <j@w1.fi> and contributors
|
||||
All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name(s) of the above-listed copyright holder(s) nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
@ -97,12 +97,9 @@ typedef std::uint32_t uint32;
|
||||
typedef std::int64_t int64;
|
||||
typedef std::uint64_t uint64;
|
||||
|
||||
typedef double WallTime;
|
||||
|
||||
struct GLOG_EXPORT LogMessageTime {
|
||||
LogMessageTime();
|
||||
LogMessageTime(std::tm t);
|
||||
LogMessageTime(std::time_t timestamp, WallTime now);
|
||||
explicit LogMessageTime(std::chrono::system_clock::time_point now);
|
||||
|
||||
const time_t& timestamp() const { return timestamp_; }
|
||||
const int& sec() const { return time_struct_.tm_sec; }
|
||||
@ -119,7 +116,8 @@ struct GLOG_EXPORT LogMessageTime {
|
||||
const std::tm& tm() const { return time_struct_; }
|
||||
|
||||
private:
|
||||
void init(const std::tm& t, std::time_t timestamp, WallTime now);
|
||||
void init(const std::tm& t, std::time_t timestamp,
|
||||
std::chrono::system_clock::time_point now);
|
||||
std::tm time_struct_; // Time of creation of LogMessage
|
||||
time_t timestamp_; // Time of creation of LogMessage in seconds
|
||||
int32_t usecs_; // Time of creation of LogMessage - microseconds part
|
||||
|
||||
@ -27,6 +27,8 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <chrono>
|
||||
#include <system_error>
|
||||
#define _GNU_SOURCE 1 // needed for O_NOFOLLOW and pread()/pwrite()
|
||||
|
||||
#include "glog/logging.h"
|
||||
@ -483,8 +485,9 @@ class LogFileObject : public base::Logger {
|
||||
uint32 dropped_mem_length_{0};
|
||||
uint32 file_length_{0};
|
||||
unsigned int rollover_attempt_;
|
||||
int64 next_flush_time_{0}; // cycle count at which to flush log
|
||||
WallTime start_time_;
|
||||
std::chrono::system_clock::time_point
|
||||
next_flush_time_; // cycle count at which to flush log
|
||||
std::chrono::system_clock::time_point start_time_;
|
||||
|
||||
// Actually create a logfile using the value of base_filename_ and the
|
||||
// optional argument time_pid_string
|
||||
@ -522,7 +525,8 @@ class LogCleaner {
|
||||
|
||||
bool enabled_{false};
|
||||
unsigned int overdue_days_{7};
|
||||
int64 next_cleanup_time_{0}; // cycle count at which to clean overdue log
|
||||
std::chrono::system_clock::time_point
|
||||
next_cleanup_time_; // cycle count at which to clean overdue log
|
||||
};
|
||||
|
||||
LogCleaner log_cleaner;
|
||||
@ -977,14 +981,14 @@ const char possible_dir_delim[] = {'\\', '/'};
|
||||
const char possible_dir_delim[] = {'/'};
|
||||
#endif
|
||||
|
||||
string PrettyDuration(int secs) {
|
||||
string PrettyDuration(const std::chrono::duration<int>& secs) {
|
||||
std::stringstream result;
|
||||
int mins = secs / 60;
|
||||
int mins = secs.count() / 60;
|
||||
int hours = mins / 60;
|
||||
mins = mins % 60;
|
||||
secs = secs % 60;
|
||||
int s = secs.count() % 60;
|
||||
result.fill('0');
|
||||
result << hours << ':' << setw(2) << mins << ':' << setw(2) << secs;
|
||||
result << hours << ':' << setw(2) << mins << ':' << setw(2) << s;
|
||||
return result.str();
|
||||
}
|
||||
|
||||
@ -993,12 +997,9 @@ LogFileObject::LogFileObject(LogSeverity severity, const char* base_filename)
|
||||
base_filename_((base_filename != nullptr) ? base_filename : ""),
|
||||
symlink_basename_(glog_internal_namespace_::ProgramInvocationShortName()),
|
||||
filename_extension_(),
|
||||
|
||||
severity_(severity),
|
||||
|
||||
rollover_attempt_(kRolloverAttemptFrequency - 1),
|
||||
|
||||
start_time_(WallTime_Now()) {
|
||||
start_time_(std::chrono::system_clock::now()) {
|
||||
assert(severity >= 0);
|
||||
assert(severity < NUM_SEVERITIES);
|
||||
}
|
||||
@ -1054,9 +1055,10 @@ void LogFileObject::FlushUnlocked() {
|
||||
bytes_since_flush_ = 0;
|
||||
}
|
||||
// Figure out when we are due for another flush.
|
||||
const int64 next =
|
||||
(FLAGS_logbufsecs * static_cast<int64>(1000000)); // in usec
|
||||
next_flush_time_ = CycleClock_Now() + UsecToCycles(next);
|
||||
next_flush_time_ =
|
||||
std::chrono::system_clock::now() +
|
||||
std::chrono::duration_cast<std::chrono::system_clock::duration>(
|
||||
std::chrono::duration<int32>{FLAGS_logbufsecs});
|
||||
}
|
||||
|
||||
bool LogFileObject::CreateLogfile(const string& time_pid_string) {
|
||||
@ -1279,9 +1281,11 @@ void LogFileObject::Write(bool force_flush, time_t timestamp,
|
||||
const char* const date_time_format = FLAGS_log_year_in_prefix
|
||||
? "yyyymmdd hh:mm:ss.uuuuuu"
|
||||
: "mmdd hh:mm:ss.uuuuuu";
|
||||
file_header_stream << "Running duration (h:mm:ss): "
|
||||
file_header_stream
|
||||
<< "Running duration (h:mm:ss): "
|
||||
<< PrettyDuration(
|
||||
static_cast<int>(WallTime_Now() - start_time_))
|
||||
std::chrono::duration_cast<std::chrono::duration<int>>(
|
||||
std::chrono::system_clock::now() - start_time_))
|
||||
<< '\n'
|
||||
<< "Log line format: [IWEF]" << date_time_format << " "
|
||||
<< "threadid file:line] msg" << '\n';
|
||||
@ -1312,7 +1316,7 @@ void LogFileObject::Write(bool force_flush, time_t timestamp,
|
||||
bytes_since_flush_ += message_len;
|
||||
}
|
||||
} else {
|
||||
if (CycleClock_Now() >= next_flush_time_) {
|
||||
if (std::chrono::system_clock::now() >= next_flush_time_) {
|
||||
stop_writing = false; // check to see if disk has free space.
|
||||
}
|
||||
return; // no need to flush
|
||||
@ -1321,7 +1325,7 @@ void LogFileObject::Write(bool force_flush, time_t timestamp,
|
||||
// See important msgs *now*. Also, flush logs at least every 10^6 chars,
|
||||
// or every "FLAGS_logbufsecs" seconds.
|
||||
if (force_flush || (bytes_since_flush_ >= 1000000) ||
|
||||
(CycleClock_Now() >= next_flush_time_)) {
|
||||
(std::chrono::system_clock::now() >= next_flush_time_)) {
|
||||
FlushUnlocked();
|
||||
#ifdef GLOG_OS_LINUX
|
||||
// Only consider files >= 3MiB
|
||||
@ -1364,8 +1368,10 @@ void LogCleaner::Enable(unsigned int overdue_days) {
|
||||
void LogCleaner::Disable() { enabled_ = false; }
|
||||
|
||||
void LogCleaner::UpdateCleanUpTime() {
|
||||
const int64 next = (FLAGS_logcleansecs * 1000000); // in usec
|
||||
next_cleanup_time_ = CycleClock_Now() + UsecToCycles(next);
|
||||
next_cleanup_time_ =
|
||||
std::chrono::system_clock::now() +
|
||||
std::chrono::duration_cast<std::chrono::system_clock::duration>(
|
||||
std::chrono::duration<int32>{FLAGS_logcleansecs});
|
||||
}
|
||||
|
||||
void LogCleaner::Run(bool base_filename_selected, const string& base_filename,
|
||||
@ -1374,7 +1380,7 @@ void LogCleaner::Run(bool base_filename_selected, const string& base_filename,
|
||||
assert(!base_filename_selected || !base_filename.empty());
|
||||
|
||||
// avoid scanning logs too frequently
|
||||
if (CycleClock_Now() < next_cleanup_time_) {
|
||||
if (std::chrono::system_clock::now() < next_cleanup_time_) {
|
||||
return;
|
||||
}
|
||||
UpdateCleanUpTime();
|
||||
@ -1659,9 +1665,9 @@ void LogMessage::Init(const char* file, int line, LogSeverity severity,
|
||||
data_->send_method_ = send_method;
|
||||
data_->sink_ = nullptr;
|
||||
data_->outvec_ = nullptr;
|
||||
WallTime now = WallTime_Now();
|
||||
auto timestamp_now = static_cast<time_t>(now);
|
||||
logmsgtime_ = LogMessageTime(timestamp_now, now);
|
||||
|
||||
auto now = std::chrono::system_clock::now();
|
||||
logmsgtime_ = LogMessageTime(now);
|
||||
|
||||
data_->num_chars_to_log_ = 0;
|
||||
data_->num_chars_to_syslog_ = 0;
|
||||
@ -2701,12 +2707,8 @@ void DisableLogCleaner() { log_cleaner.Disable(); }
|
||||
LogMessageTime::LogMessageTime()
|
||||
: time_struct_(), timestamp_(0), usecs_(0), gmtoffset_(0) {}
|
||||
|
||||
LogMessageTime::LogMessageTime(std::tm t) {
|
||||
std::time_t timestamp = std::mktime(&t);
|
||||
init(t, timestamp, 0);
|
||||
}
|
||||
|
||||
LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime now) {
|
||||
LogMessageTime::LogMessageTime(std::chrono::system_clock::time_point now) {
|
||||
std::time_t timestamp = std::chrono::system_clock::to_time_t(now);
|
||||
std::tm t;
|
||||
if (FLAGS_log_utc_time) {
|
||||
gmtime_r(×tamp, &t);
|
||||
@ -2717,10 +2719,12 @@ LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime now) {
|
||||
}
|
||||
|
||||
void LogMessageTime::init(const std::tm& t, std::time_t timestamp,
|
||||
WallTime now) {
|
||||
std::chrono::system_clock::time_point now) {
|
||||
time_struct_ = t;
|
||||
timestamp_ = timestamp;
|
||||
usecs_ = static_cast<int32>((now - timestamp) * 1000000);
|
||||
usecs_ = std::chrono::duration_cast<std::chrono::duration<int32, std::micro>>(
|
||||
now - std::chrono::system_clock::from_time_t(timestamp))
|
||||
.count();
|
||||
|
||||
CalcGmtOffset();
|
||||
}
|
||||
|
||||
@ -194,52 +194,6 @@ const char* ProgramInvocationShortName() {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef GLOG_OS_WINDOWS
|
||||
struct timeval {
|
||||
long tv_sec, tv_usec;
|
||||
};
|
||||
|
||||
// Based on:
|
||||
// http://www.google.com/codesearch/p?hl=en#dR3YEbitojA/os_win32.c&q=GetSystemTimeAsFileTime%20license:bsd
|
||||
// See COPYING for copyright information.
|
||||
static int gettimeofday(struct timeval* tv, void* /*tz*/) {
|
||||
# ifdef __GNUC__
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wlong-long"
|
||||
# endif
|
||||
# define EPOCHFILETIME (116444736000000000ULL)
|
||||
FILETIME ft;
|
||||
ULARGE_INTEGER li;
|
||||
uint64 tt;
|
||||
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
li.LowPart = ft.dwLowDateTime;
|
||||
li.HighPart = ft.dwHighDateTime;
|
||||
tt = (li.QuadPart - EPOCHFILETIME) / 10;
|
||||
tv->tv_sec = tt / 1000000;
|
||||
tv->tv_usec = tt % 1000000;
|
||||
# ifdef __GNUC__
|
||||
# pragma GCC diagnostic pop
|
||||
# endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int64 CycleClock_Now() {
|
||||
// TODO(hamaji): temporary impementation - it might be too slow.
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, nullptr);
|
||||
return static_cast<int64>(tv.tv_sec) * 1000000 + tv.tv_usec;
|
||||
}
|
||||
|
||||
int64 UsecToCycles(int64 usec) { return usec; }
|
||||
|
||||
WallTime WallTime_Now() {
|
||||
// Now, cycle clock is retuning microseconds since the epoch.
|
||||
return CycleClock_Now() * 0.000001;
|
||||
}
|
||||
|
||||
static int32 g_main_thread_pid = getpid();
|
||||
int32 GetMainThreadPid() { return g_main_thread_pid; }
|
||||
|
||||
|
||||
@ -164,11 +164,6 @@ namespace glog_internal_namespace_ {
|
||||
|
||||
const char* ProgramInvocationShortName();
|
||||
|
||||
int64 CycleClock_Now();
|
||||
|
||||
int64 UsecToCycles(int64 usec);
|
||||
WallTime WallTime_Now();
|
||||
|
||||
int32 GetMainThreadPid();
|
||||
bool PidHasChanged();
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user