Enlarge log size cap when printing file summary
Summary: Now the file summary is too small for printing. Enlarge it. To enable it, allow to pass a size to log buffer. Test Plan: Add a unit test. make all check Reviewers: ljin, yhchiang Reviewed By: yhchiang Subscribers: leveldb Differential Revision: https://reviews.facebook.net/D21723
This commit is contained in:
parent
7cc1ed7f08
commit
cdaf44f9ae
@ -575,7 +575,7 @@ Compaction* UniversalCompactionPicker::PickCompaction(Version* version,
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
Version::FileSummaryStorage tmp;
|
Version::FileSummaryStorage tmp;
|
||||||
LogToBuffer(log_buffer, "[%s] Universal: candidate files(%zu): %s\n",
|
LogToBuffer(log_buffer, 3072, "[%s] Universal: candidate files(%zu): %s\n",
|
||||||
version->cfd_->GetName().c_str(), version->files_[level].size(),
|
version->cfd_->GetName().c_str(), version->files_[level].size(),
|
||||||
version->LevelFileSummary(&tmp, 0));
|
version->LevelFileSummary(&tmp, 0));
|
||||||
|
|
||||||
|
@ -183,10 +183,10 @@ class Version {
|
|||||||
// Return a human-readable short (single-line) summary of the number
|
// Return a human-readable short (single-line) summary of the number
|
||||||
// of files per level. Uses *scratch as backing store.
|
// of files per level. Uses *scratch as backing store.
|
||||||
struct LevelSummaryStorage {
|
struct LevelSummaryStorage {
|
||||||
char buffer[100];
|
char buffer[1000];
|
||||||
};
|
};
|
||||||
struct FileSummaryStorage {
|
struct FileSummaryStorage {
|
||||||
char buffer[1000];
|
char buffer[3000];
|
||||||
};
|
};
|
||||||
const char* LevelSummary(LevelSummaryStorage* scratch) const;
|
const char* LevelSummary(LevelSummaryStorage* scratch) const;
|
||||||
// Return a human-readable short (single-line) summary of files
|
// Return a human-readable short (single-line) summary of files
|
||||||
|
@ -768,6 +768,41 @@ TEST(EnvPosixTest, LogBufferTest) {
|
|||||||
ASSERT_EQ(10, test_logger.char_x_count);
|
ASSERT_EQ(10, test_logger.char_x_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TestLogger2 : public Logger {
|
||||||
|
public:
|
||||||
|
explicit TestLogger2(size_t max_log_size) : max_log_size_(max_log_size) {}
|
||||||
|
virtual void Logv(const char* format, va_list ap) override {
|
||||||
|
char new_format[2000];
|
||||||
|
std::fill_n(new_format, sizeof(new_format), '2');
|
||||||
|
{
|
||||||
|
va_list backup_ap;
|
||||||
|
va_copy(backup_ap, ap);
|
||||||
|
int n = vsnprintf(new_format, sizeof(new_format) - 1, format, backup_ap);
|
||||||
|
// 48 bytes for extra information + bytes allocated
|
||||||
|
ASSERT_TRUE(
|
||||||
|
n <= 48 + static_cast<int>(max_log_size_ - sizeof(struct timeval)));
|
||||||
|
ASSERT_TRUE(n > static_cast<int>(max_log_size_ - sizeof(struct timeval)));
|
||||||
|
va_end(backup_ap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size_t max_log_size_;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST(EnvPosixTest, LogBufferMaxSizeTest) {
|
||||||
|
char bytes9000[9000];
|
||||||
|
std::fill_n(bytes9000, sizeof(bytes9000), '1');
|
||||||
|
bytes9000[sizeof(bytes9000) - 1] = '\0';
|
||||||
|
|
||||||
|
for (size_t max_log_size = 256; max_log_size <= 1024;
|
||||||
|
max_log_size += 1024 - 256) {
|
||||||
|
TestLogger2 test_logger(max_log_size);
|
||||||
|
test_logger.SetInfoLogLevel(InfoLogLevel::INFO_LEVEL);
|
||||||
|
LogBuffer log_buffer(InfoLogLevel::INFO_LEVEL, &test_logger);
|
||||||
|
LogToBuffer(&log_buffer, max_log_size, "%s", bytes9000);
|
||||||
|
log_buffer.FlushBufferToLog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace rocksdb
|
} // namespace rocksdb
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
@ -13,17 +13,17 @@ LogBuffer::LogBuffer(const InfoLogLevel log_level,
|
|||||||
Logger*info_log)
|
Logger*info_log)
|
||||||
: log_level_(log_level), info_log_(info_log) {}
|
: log_level_(log_level), info_log_(info_log) {}
|
||||||
|
|
||||||
void LogBuffer::AddLogToBuffer(const char* format, va_list ap) {
|
void LogBuffer::AddLogToBuffer(size_t max_log_size, const char* format,
|
||||||
|
va_list ap) {
|
||||||
if (!info_log_ || log_level_ < info_log_->GetInfoLogLevel()) {
|
if (!info_log_ || log_level_ < info_log_->GetInfoLogLevel()) {
|
||||||
// Skip the level because of its level.
|
// Skip the level because of its level.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t kLogSizeLimit = 512;
|
char* alloc_mem = arena_.AllocateAligned(max_log_size);
|
||||||
char* alloc_mem = arena_.AllocateAligned(kLogSizeLimit);
|
|
||||||
BufferedLog* buffered_log = new (alloc_mem) BufferedLog();
|
BufferedLog* buffered_log = new (alloc_mem) BufferedLog();
|
||||||
char* p = buffered_log->message;
|
char* p = buffered_log->message;
|
||||||
char* limit = alloc_mem + kLogSizeLimit - 1;
|
char* limit = alloc_mem + max_log_size - 1;
|
||||||
|
|
||||||
// store the time
|
// store the time
|
||||||
gettimeofday(&(buffered_log->now_tv), nullptr);
|
gettimeofday(&(buffered_log->now_tv), nullptr);
|
||||||
@ -61,11 +61,22 @@ void LogBuffer::FlushBufferToLog() {
|
|||||||
logs_.clear();
|
logs_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogToBuffer(LogBuffer* log_buffer, const char* format, ...) {
|
void LogToBuffer(LogBuffer* log_buffer, size_t max_log_size, const char* format,
|
||||||
|
...) {
|
||||||
if (log_buffer != nullptr) {
|
if (log_buffer != nullptr) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
log_buffer->AddLogToBuffer(format, ap);
|
log_buffer->AddLogToBuffer(max_log_size, format, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LogToBuffer(LogBuffer* log_buffer, const char* format, ...) {
|
||||||
|
const size_t kDefaultMaxLogSize = 512;
|
||||||
|
if (log_buffer != nullptr) {
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, format);
|
||||||
|
log_buffer->AddLogToBuffer(kDefaultMaxLogSize, format, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,9 @@ class LogBuffer {
|
|||||||
// info_log: logger to write the logs to
|
// info_log: logger to write the logs to
|
||||||
LogBuffer(const InfoLogLevel log_level, Logger* info_log);
|
LogBuffer(const InfoLogLevel log_level, Logger* info_log);
|
||||||
|
|
||||||
// Add a log entry to the buffer.
|
// Add a log entry to the buffer. Use default max_log_size.
|
||||||
void AddLogToBuffer(const char* format, va_list ap);
|
// max_log_size indicates maximize log size, including some metadata.
|
||||||
|
void AddLogToBuffer(size_t max_log_size, const char* format, va_list ap);
|
||||||
|
|
||||||
size_t IsEmpty() const { return logs_.empty(); }
|
size_t IsEmpty() const { return logs_.empty(); }
|
||||||
|
|
||||||
@ -44,6 +45,10 @@ class LogBuffer {
|
|||||||
|
|
||||||
// Add log to the LogBuffer for a delayed info logging. It can be used when
|
// Add log to the LogBuffer for a delayed info logging. It can be used when
|
||||||
// we want to add some logs inside a mutex.
|
// we want to add some logs inside a mutex.
|
||||||
|
// max_log_size indicates maximize log size, including some metadata.
|
||||||
|
extern void LogToBuffer(LogBuffer* log_buffer, size_t max_log_size,
|
||||||
|
const char* format, ...);
|
||||||
|
// Same as previous function, but with default max log size.
|
||||||
extern void LogToBuffer(LogBuffer* log_buffer, const char* format, ...);
|
extern void LogToBuffer(LogBuffer* log_buffer, const char* format, ...);
|
||||||
|
|
||||||
} // namespace rocksdb
|
} // namespace rocksdb
|
||||||
|
Loading…
x
Reference in New Issue
Block a user