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