2016-02-09 23:12:00 +00:00
|
|
|
// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
|
2017-07-15 23:03:42 +00:00
|
|
|
// 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).
|
2014-03-10 05:01:13 +00:00
|
|
|
|
2019-06-01 00:19:43 +00:00
|
|
|
#include "logging/log_buffer.h"
|
2014-03-10 05:01:13 +00:00
|
|
|
|
2015-07-07 23:58:20 +00:00
|
|
|
#include "port/sys_time.h"
|
|
|
|
#include "port/port.h"
|
2014-03-10 05:01:13 +00:00
|
|
|
|
2020-02-20 20:07:53 +00:00
|
|
|
namespace ROCKSDB_NAMESPACE {
|
2014-03-10 05:01:13 +00:00
|
|
|
|
|
|
|
LogBuffer::LogBuffer(const InfoLogLevel log_level,
|
|
|
|
Logger*info_log)
|
|
|
|
: log_level_(log_level), info_log_(info_log) {}
|
|
|
|
|
2014-09-23 20:43:03 +00:00
|
|
|
void LogBuffer::AddLogToBuffer(size_t max_log_size, const char* format,
|
|
|
|
va_list ap) {
|
2014-03-10 05:01:13 +00:00
|
|
|
if (!info_log_ || log_level_ < info_log_->GetInfoLogLevel()) {
|
|
|
|
// Skip the level because of its level.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-09-23 20:43:03 +00:00
|
|
|
char* alloc_mem = arena_.AllocateAligned(max_log_size);
|
2014-03-10 05:01:13 +00:00
|
|
|
BufferedLog* buffered_log = new (alloc_mem) BufferedLog();
|
|
|
|
char* p = buffered_log->message;
|
2014-09-23 20:43:03 +00:00
|
|
|
char* limit = alloc_mem + max_log_size - 1;
|
2014-03-10 05:01:13 +00:00
|
|
|
|
|
|
|
// store the time
|
2022-05-25 01:20:17 +00:00
|
|
|
port::GetTimeOfDay(&(buffered_log->now_tv), nullptr);
|
2014-03-10 05:01:13 +00:00
|
|
|
|
|
|
|
// Print the message
|
|
|
|
if (p < limit) {
|
|
|
|
va_list backup_ap;
|
|
|
|
va_copy(backup_ap, ap);
|
2014-03-21 17:26:02 +00:00
|
|
|
auto n = vsnprintf(p, limit - p, format, backup_ap);
|
2015-07-01 23:13:49 +00:00
|
|
|
#ifndef OS_WIN
|
|
|
|
// MS reports -1 when the buffer is too short
|
2014-03-21 17:26:02 +00:00
|
|
|
assert(n >= 0);
|
2015-07-01 23:13:49 +00:00
|
|
|
#endif
|
|
|
|
if (n > 0) {
|
|
|
|
p += n;
|
|
|
|
} else {
|
|
|
|
p = limit;
|
|
|
|
}
|
2014-03-10 05:01:13 +00:00
|
|
|
va_end(backup_ap);
|
|
|
|
}
|
|
|
|
|
2014-03-21 17:26:02 +00:00
|
|
|
if (p > limit) {
|
|
|
|
p = limit;
|
|
|
|
}
|
|
|
|
|
2014-03-10 05:01:13 +00:00
|
|
|
// 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;
|
2022-05-25 01:20:17 +00:00
|
|
|
if (port::LocalTimeR(&seconds, &t) != nullptr) {
|
2017-05-05 23:09:24 +00:00
|
|
|
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);
|
|
|
|
}
|
2014-03-10 05:01:13 +00:00
|
|
|
}
|
|
|
|
logs_.clear();
|
|
|
|
}
|
|
|
|
|
2014-09-23 20:43:03 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-10 05:01:13 +00:00
|
|
|
void LogToBuffer(LogBuffer* log_buffer, const char* format, ...) {
|
|
|
|
if (log_buffer != nullptr) {
|
|
|
|
va_list ap;
|
|
|
|
va_start(ap, format);
|
2020-01-06 18:15:00 +00:00
|
|
|
log_buffer->AddLogToBuffer(LogBuffer::kDefaultMaxLogSize, format, ap);
|
2014-03-10 05:01:13 +00:00
|
|
|
va_end(ap);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-20 20:07:53 +00:00
|
|
|
} // namespace ROCKSDB_NAMESPACE
|