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;
|
||||
}
|
||||
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->LevelFileSummary(&tmp, 0));
|
||||
|
||||
|
@ -183,10 +183,10 @@ class Version {
|
||||
// Return a human-readable short (single-line) summary of the number
|
||||
// of files per level. Uses *scratch as backing store.
|
||||
struct LevelSummaryStorage {
|
||||
char buffer[100];
|
||||
char buffer[1000];
|
||||
};
|
||||
struct FileSummaryStorage {
|
||||
char buffer[1000];
|
||||
char buffer[3000];
|
||||
};
|
||||
const char* LevelSummary(LevelSummaryStorage* scratch) const;
|
||||
// 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);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
@ -13,17 +13,17 @@ LogBuffer::LogBuffer(const InfoLogLevel log_level,
|
||||
Logger*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()) {
|
||||
// Skip the level because of its level.
|
||||
return;
|
||||
}
|
||||
|
||||
const size_t kLogSizeLimit = 512;
|
||||
char* alloc_mem = arena_.AllocateAligned(kLogSizeLimit);
|
||||
char* alloc_mem = arena_.AllocateAligned(max_log_size);
|
||||
BufferedLog* buffered_log = new (alloc_mem) BufferedLog();
|
||||
char* p = buffered_log->message;
|
||||
char* limit = alloc_mem + kLogSizeLimit - 1;
|
||||
char* limit = alloc_mem + max_log_size - 1;
|
||||
|
||||
// store the time
|
||||
gettimeofday(&(buffered_log->now_tv), nullptr);
|
||||
@ -61,11 +61,22 @@ void LogBuffer::FlushBufferToLog() {
|
||||
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) {
|
||||
va_list ap;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -21,8 +21,9 @@ class LogBuffer {
|
||||
// info_log: logger to write the logs to
|
||||
LogBuffer(const InfoLogLevel log_level, Logger* info_log);
|
||||
|
||||
// Add a log entry to the buffer.
|
||||
void AddLogToBuffer(const char* format, va_list ap);
|
||||
// Add a log entry to the buffer. Use default max_log_size.
|
||||
// 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(); }
|
||||
|
||||
@ -44,6 +45,10 @@ class LogBuffer {
|
||||
|
||||
// Add log to the LogBuffer for a delayed info logging. It can be used when
|
||||
// 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, ...);
|
||||
|
||||
} // namespace rocksdb
|
||||
|
Loading…
x
Reference in New Issue
Block a user