From 8965c8d0b9fadce5250502af2e57125d2a418e8c Mon Sep 17 00:00:00 2001 From: Kai Liu Date: Fri, 26 Oct 2012 15:23:50 -0700 Subject: [PATCH] Add the missing util/auto_split_logger.h Summary: Test Plan: Reviewers: CC: Task ID: 1803577 Blame Rev: --- util/auto_split_logger.h | 81 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 util/auto_split_logger.h diff --git a/util/auto_split_logger.h b/util/auto_split_logger.h new file mode 100644 index 000000000..89429b0b4 --- /dev/null +++ b/util/auto_split_logger.h @@ -0,0 +1,81 @@ +// Copyright (c) 2011 The LevelDB Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. See the AUTHORS file for names of contributors. +// +// Logger implementation that can be shared by all environments +// where enough posix functionality is available. + +#ifndef STORAGE_LEVELDB_UTIL_SPLIT_LOGGER_LOGGER_H_ +#define STORAGE_LEVELDB_UTIL_SPLIT_LOGGER_LOGGER_H_ + +#include "util/posix_logger.h" +#include "db/filename.h" + +namespace leveldb { + +// AutoSplitLogger can automatically create a new log file +// if the file size exceeds the limit. +// +// The template parameter "UnderlyingLogger" can be any Logger class +// that has the method "GetLogFileSize()" and "ResetFile()" +template +class AutoSplitLogger : public Logger { + private: + std::string log_fname_; // Current active info log's file name. + std::string dbname_; + std::string db_log_dir_; + std::string db_absolute_path_; + Env* env_; + UnderlyingLogger* logger_; + const size_t MAX_LOG_FILE_SIZE; + Status status_; + + public: + AutoSplitLogger(Env* env, const std::string& dbname, + const std::string& db_log_dir, size_t log_max_size): + env_(env), dbname_(dbname), db_log_dir_(db_log_dir), + MAX_LOG_FILE_SIZE(log_max_size), status_(Status::OK()) { + env->GetAbsolutePath(dbname, &db_absolute_path_); + log_fname_ = InfoLogFileName(dbname_, db_absolute_path_, db_log_dir_); + InitLogger(); + } + ~AutoSplitLogger() { delete logger_; } + + virtual void Logv(const char* format, va_list ap) { + assert(GetStatus().ok()); + + logger_->Logv(format, ap); + // Check if the log file should be splitted. + if (logger_->GetLogFileSize() > MAX_LOG_FILE_SIZE) { + delete logger_; + std::string old_fname = OldInfoLogFileName( + dbname_, env_->NowMicros(), db_absolute_path_, db_log_dir_); + env_->RenameFile(log_fname_, old_fname); + InitLogger(); + } + } + + // check if the logger has any problem. + Status GetStatus() { + return status_; + } + + private: + Status InitLogger() { + status_ = env_->NewLogger(log_fname_, &logger_); + if (!status_.ok()) { + logger_ = NULL; + } + if (logger_->GetLogFileSize() == + Logger::DO_NOT_SUPPORT_GET_LOG_FILE_SIZE) { + status_ = Status::NotSupported( + "The underlying logger doesn't support GetLogFileSize()"); + } + return status_; + } + +}; // class AutoSplitLogger + +} // namespace leveldb + +#endif // STORAGE_LEVELDB_UTIL_SPLIT_LOGGER_LOGGER_H_