mirror of
https://github.com/facebook/rocksdb.git
synced 2024-11-25 14:31:35 +00:00
af7ae912e2
Summary: There are some time-related POSIX APIs that are not available on Windows (e.g. `localtime_r`), which we have worked around by providing our own implementations in `port/sys_time.h`. This workaround actually relies on some ambiguity: on Windows, a call to `localtime_r` calls `ROCKSDB_NAMESPACE::port::localtime_r` (which is pulled into `ROCKSDB_NAMESPACE` by a using-declaration), while on other platforms it calls the global `localtime_r`. This works fine as long as there is only one candidate function; however, it breaks down when there is more than one `localtime_r` visible in a scope. The patch fixes this by introducing `ROCKSDB_NAMESPACE::port::{TimeVal, GetTimeOfDay, LocalTimeR}` to eliminate any ambiguity. Pull Request resolved: https://github.com/facebook/rocksdb/pull/10045 Test Plan: `make check` Reviewed By: riversand963 Differential Revision: D36639372 Pulled By: ltamasi fbshipit-source-id: fc13dbfa421b7c8918111a6d9e24ce77e91a7c50
93 lines
2.4 KiB
C++
93 lines
2.4 KiB
C++
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
|
// This source code is licensed under both the GPLv2 (found in the
|
|
// COPYING file in the root directory) and Apache 2.0 License
|
|
// (found in the LICENSE.Apache file in the root directory).
|
|
|
|
#include "logging/log_buffer.h"
|
|
|
|
#include "port/sys_time.h"
|
|
#include "port/port.h"
|
|
|
|
namespace ROCKSDB_NAMESPACE {
|
|
|
|
LogBuffer::LogBuffer(const InfoLogLevel log_level,
|
|
Logger*info_log)
|
|
: log_level_(log_level), info_log_(info_log) {}
|
|
|
|
void LogBuffer::AddLogToBuffer(size_t max_log_size, const char* format,
|
|
va_list ap) {
|
|
if (!info_log_ || log_level_ < info_log_->GetInfoLogLevel()) {
|
|
// Skip the level because of its level.
|
|
return;
|
|
}
|
|
|
|
char* alloc_mem = arena_.AllocateAligned(max_log_size);
|
|
BufferedLog* buffered_log = new (alloc_mem) BufferedLog();
|
|
char* p = buffered_log->message;
|
|
char* limit = alloc_mem + max_log_size - 1;
|
|
|
|
// store the time
|
|
port::GetTimeOfDay(&(buffered_log->now_tv), nullptr);
|
|
|
|
// Print the message
|
|
if (p < limit) {
|
|
va_list backup_ap;
|
|
va_copy(backup_ap, ap);
|
|
auto n = vsnprintf(p, limit - p, format, backup_ap);
|
|
#ifndef OS_WIN
|
|
// MS reports -1 when the buffer is too short
|
|
assert(n >= 0);
|
|
#endif
|
|
if (n > 0) {
|
|
p += n;
|
|
} else {
|
|
p = limit;
|
|
}
|
|
va_end(backup_ap);
|
|
}
|
|
|
|
if (p > limit) {
|
|
p = limit;
|
|
}
|
|
|
|
// Add '\0' to the end
|
|
*p = '\0';
|
|
|
|
logs_.push_back(buffered_log);
|
|
}
|
|
|
|
void LogBuffer::FlushBufferToLog() {
|
|
for (BufferedLog* log : logs_) {
|
|
const time_t seconds = log->now_tv.tv_sec;
|
|
struct tm t;
|
|
if (port::LocalTimeR(&seconds, &t) != nullptr) {
|
|
Log(log_level_, info_log_,
|
|
"(Original Log Time %04d/%02d/%02d-%02d:%02d:%02d.%06d) %s",
|
|
t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min,
|
|
t.tm_sec, static_cast<int>(log->now_tv.tv_usec), log->message);
|
|
}
|
|
}
|
|
logs_.clear();
|
|
}
|
|
|
|
void LogToBuffer(LogBuffer* log_buffer, size_t max_log_size, const char* format,
|
|
...) {
|
|
if (log_buffer != nullptr) {
|
|
va_list ap;
|
|
va_start(ap, format);
|
|
log_buffer->AddLogToBuffer(max_log_size, format, ap);
|
|
va_end(ap);
|
|
}
|
|
}
|
|
|
|
void LogToBuffer(LogBuffer* log_buffer, const char* format, ...) {
|
|
if (log_buffer != nullptr) {
|
|
va_list ap;
|
|
va_start(ap, format);
|
|
log_buffer->AddLogToBuffer(LogBuffer::kDefaultMaxLogSize, format, ap);
|
|
va_end(ap);
|
|
}
|
|
}
|
|
|
|
} // namespace ROCKSDB_NAMESPACE
|