rocksdb/util/auto_split_logger.h
Chip Turner 2fdf91a4f8 Fix a number of object lifetime/ownership issues
Summary:
Replace manual memory management with std::unique_ptr in a
number of places; not exhaustive, but this fixes a few leaks with file
handles as well as clarifies semantics of the ownership of file handles
with log classes.

Test Plan: db_stress, make check

Reviewers: dhruba

Reviewed By: dhruba

CC: zshao, leveldb, heyongqiang

Differential Revision: https://reviews.facebook.net/D8043
2013-01-23 16:54:11 -08:00

83 lines
2.4 KiB
C++

// 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 UnderlyingLogger>
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_;
shared_ptr<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):
dbname_(dbname),
db_log_dir_(db_log_dir),
env_(env),
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();
}
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) {
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() ==
(size_t)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_