auto_roll_logger.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
  2. // This source code is licensed under both the GPLv2 (found in the
  3. // COPYING file in the root directory) and Apache 2.0 License
  4. // (found in the LICENSE.Apache file in the root directory).
  5. //
  6. // Logger implementation that can be shared by all environments
  7. // where enough posix functionality is available.
  8. #pragma once
  9. #include <list>
  10. #include <queue>
  11. #include <string>
  12. #include "file/filename.h"
  13. #include "port/port.h"
  14. #include "port/util_logger.h"
  15. #include "test_util/sync_point.h"
  16. #include "util/mutexlock.h"
  17. namespace ROCKSDB_NAMESPACE {
  18. class FileSystem;
  19. class SystemClock;
  20. // Rolls the log file by size and/or time
  21. class AutoRollLogger : public Logger {
  22. public:
  23. AutoRollLogger(const std::shared_ptr<FileSystem>& fs,
  24. const std::shared_ptr<SystemClock>& clock,
  25. const std::string& dbname, const std::string& db_log_dir,
  26. size_t log_max_size, size_t log_file_time_to_roll,
  27. size_t keep_log_file_num,
  28. const InfoLogLevel log_level = InfoLogLevel::INFO_LEVEL);
  29. using Logger::Logv;
  30. void Logv(const char* format, va_list ap) override;
  31. // Write a header entry to the log. All header information will be written
  32. // again every time the log rolls over.
  33. void LogHeader(const char* format, va_list ap) override;
  34. // check if the logger has encountered any problem.
  35. Status GetStatus() { return status_; }
  36. size_t GetLogFileSize() const override {
  37. std::shared_ptr<Logger> logger;
  38. {
  39. MutexLock l(&mutex_);
  40. if (!logger_) {
  41. return 0;
  42. }
  43. // pin down the current logger_ instance before releasing the mutex.
  44. logger = logger_;
  45. }
  46. return logger->GetLogFileSize();
  47. }
  48. void Flush() override {
  49. std::shared_ptr<Logger> logger;
  50. {
  51. MutexLock l(&mutex_);
  52. // pin down the current logger_ instance before releasing the mutex.
  53. logger = logger_;
  54. }
  55. TEST_SYNC_POINT("AutoRollLogger::Flush:PinnedLogger");
  56. if (logger) {
  57. logger->Flush();
  58. }
  59. }
  60. virtual ~AutoRollLogger() {
  61. if (logger_ && !closed_) {
  62. logger_->Close().PermitUncheckedError();
  63. }
  64. status_.PermitUncheckedError();
  65. }
  66. using Logger::GetInfoLogLevel;
  67. InfoLogLevel GetInfoLogLevel() const override {
  68. MutexLock l(&mutex_);
  69. if (!logger_) {
  70. return Logger::GetInfoLogLevel();
  71. }
  72. return logger_->GetInfoLogLevel();
  73. }
  74. using Logger::SetInfoLogLevel;
  75. void SetInfoLogLevel(const InfoLogLevel log_level) override {
  76. MutexLock lock(&mutex_);
  77. Logger::SetInfoLogLevel(log_level);
  78. if (logger_) {
  79. logger_->SetInfoLogLevel(log_level);
  80. }
  81. }
  82. void SetCallNowMicrosEveryNRecords(uint64_t call_NowMicros_every_N_records) {
  83. call_NowMicros_every_N_records_ = call_NowMicros_every_N_records;
  84. }
  85. // Expose the log file path for testing purpose
  86. std::string TEST_log_fname() const { return log_fname_; }
  87. uint64_t TEST_ctime() const { return ctime_; }
  88. Logger* TEST_inner_logger() const { return logger_.get(); }
  89. protected:
  90. // Implementation of Close()
  91. Status CloseImpl() override {
  92. if (logger_) {
  93. return logger_->Close();
  94. } else {
  95. return Status::OK();
  96. }
  97. }
  98. private:
  99. bool LogExpired();
  100. Status ResetLogger();
  101. void RollLogFile();
  102. // Read all names of old log files into old_log_files_
  103. // If there is any error, put the error code in status_
  104. void GetExistingFiles();
  105. // Delete old log files if it excceeds the limit.
  106. Status TrimOldLogFiles();
  107. // Log message to logger without rolling
  108. void LogInternal(const char* format, ...);
  109. // Serialize the va_list to a string
  110. std::string ValistToString(const char* format, va_list args) const;
  111. // Write the logs marked as headers to the new log file
  112. void WriteHeaderInfo();
  113. std::string log_fname_; // Current active info log's file name.
  114. std::string dbname_;
  115. std::string db_log_dir_;
  116. std::string db_absolute_path_;
  117. std::shared_ptr<FileSystem> fs_;
  118. std::shared_ptr<SystemClock> clock_;
  119. std::shared_ptr<Logger> logger_;
  120. // current status of the logger
  121. Status status_;
  122. const size_t kMaxLogFileSize;
  123. const size_t kLogFileTimeToRoll;
  124. const size_t kKeepLogFileNum;
  125. // header information
  126. std::list<std::string> headers_;
  127. // List of all existing info log files. Used for enforcing number of
  128. // info log files.
  129. // Full path is stored here. It consumes signifianctly more memory
  130. // than only storing file name. Can optimize if it causes a problem.
  131. std::queue<std::string> old_log_files_;
  132. // to avoid frequent clock->NowMicros() calls, we cached the current time
  133. uint64_t cached_now;
  134. uint64_t ctime_;
  135. uint64_t cached_now_access_count;
  136. uint64_t call_NowMicros_every_N_records_;
  137. IOOptions io_options_;
  138. IODebugContext io_context_;
  139. mutable port::Mutex mutex_;
  140. };
  141. // Facade to craete logger automatically
  142. Status CreateLoggerFromOptions(const std::string& dbname,
  143. const DBOptions& options,
  144. std::shared_ptr<Logger>* logger);
  145. } // namespace ROCKSDB_NAMESPACE