]>
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> | |
11 | #include <string> | |
12 | ||
13 | #include "port/port.h" | |
14 | #include "port/util_logger.h" | |
15 | #include "util/filename.h" | |
16 | #include "util/mutexlock.h" | |
17 | #include "util/sync_point.h" | |
18 | ||
19 | namespace rocksdb { | |
20 | ||
21 | #ifndef ROCKSDB_LITE | |
22 | // Rolls the log file by size and/or time | |
23 | class AutoRollLogger : public Logger { | |
24 | public: | |
25 | AutoRollLogger(Env* env, const std::string& dbname, | |
26 | const std::string& db_log_dir, size_t log_max_size, | |
27 | size_t log_file_time_to_roll, | |
28 | const InfoLogLevel log_level = InfoLogLevel::INFO_LEVEL) | |
29 | : Logger(log_level), | |
30 | dbname_(dbname), | |
31 | db_log_dir_(db_log_dir), | |
32 | env_(env), | |
33 | status_(Status::OK()), | |
34 | kMaxLogFileSize(log_max_size), | |
35 | kLogFileTimeToRoll(log_file_time_to_roll), | |
36 | cached_now(static_cast<uint64_t>(env_->NowMicros() * 1e-6)), | |
37 | ctime_(cached_now), | |
38 | cached_now_access_count(0), | |
39 | call_NowMicros_every_N_records_(100), | |
40 | mutex_() { | |
41 | env->GetAbsolutePath(dbname, &db_absolute_path_); | |
42 | log_fname_ = InfoLogFileName(dbname_, db_absolute_path_, db_log_dir_); | |
43 | RollLogFile(); | |
44 | ResetLogger(); | |
45 | } | |
46 | ||
47 | using Logger::Logv; | |
48 | void Logv(const char* format, va_list ap) override; | |
49 | ||
50 | // Write a header entry to the log. All header information will be written | |
51 | // again every time the log rolls over. | |
52 | virtual void LogHeader(const char* format, va_list ap) override; | |
53 | ||
54 | // check if the logger has encountered any problem. | |
55 | Status GetStatus() { | |
56 | return status_; | |
57 | } | |
58 | ||
59 | size_t GetLogFileSize() const override { | |
60 | std::shared_ptr<Logger> logger; | |
61 | { | |
62 | MutexLock l(&mutex_); | |
63 | // pin down the current logger_ instance before releasing the mutex. | |
64 | logger = logger_; | |
65 | } | |
66 | return logger->GetLogFileSize(); | |
67 | } | |
68 | ||
69 | void Flush() override { | |
70 | std::shared_ptr<Logger> logger; | |
71 | { | |
72 | MutexLock l(&mutex_); | |
73 | // pin down the current logger_ instance before releasing the mutex. | |
74 | logger = logger_; | |
75 | } | |
76 | TEST_SYNC_POINT("AutoRollLogger::Flush:PinnedLogger"); | |
77 | if (logger) { | |
78 | logger->Flush(); | |
79 | } | |
80 | } | |
81 | ||
82 | virtual ~AutoRollLogger() { | |
11fdf7f2 TL |
83 | if (logger_ && !closed_) { |
84 | logger_->Close(); | |
85 | } | |
7c673cae FG |
86 | } |
87 | ||
88 | void SetCallNowMicrosEveryNRecords(uint64_t call_NowMicros_every_N_records) { | |
89 | call_NowMicros_every_N_records_ = call_NowMicros_every_N_records; | |
90 | } | |
91 | ||
92 | // Expose the log file path for testing purpose | |
93 | std::string TEST_log_fname() const { | |
94 | return log_fname_; | |
95 | } | |
96 | ||
97 | uint64_t TEST_ctime() const { return ctime_; } | |
98 | ||
11fdf7f2 TL |
99 | protected: |
100 | // Implementation of Close() | |
101 | virtual Status CloseImpl() override { | |
102 | if (logger_) { | |
103 | return logger_->Close(); | |
104 | } else { | |
105 | return Status::OK(); | |
106 | } | |
107 | } | |
108 | ||
7c673cae FG |
109 | private: |
110 | bool LogExpired(); | |
111 | Status ResetLogger(); | |
112 | void RollLogFile(); | |
113 | // Log message to logger without rolling | |
114 | void LogInternal(const char* format, ...); | |
115 | // Serialize the va_list to a string | |
116 | std::string ValistToString(const char* format, va_list args) const; | |
117 | // Write the logs marked as headers to the new log file | |
118 | void WriteHeaderInfo(); | |
7c673cae FG |
119 | std::string log_fname_; // Current active info log's file name. |
120 | std::string dbname_; | |
121 | std::string db_log_dir_; | |
122 | std::string db_absolute_path_; | |
123 | Env* env_; | |
124 | std::shared_ptr<Logger> logger_; | |
125 | // current status of the logger | |
126 | Status status_; | |
127 | const size_t kMaxLogFileSize; | |
128 | const size_t kLogFileTimeToRoll; | |
129 | // header information | |
130 | std::list<std::string> headers_; | |
131 | // to avoid frequent env->NowMicros() calls, we cached the current time | |
132 | uint64_t cached_now; | |
133 | uint64_t ctime_; | |
134 | uint64_t cached_now_access_count; | |
135 | uint64_t call_NowMicros_every_N_records_; | |
136 | mutable port::Mutex mutex_; | |
137 | }; | |
138 | #endif // !ROCKSDB_LITE | |
139 | ||
140 | // Facade to craete logger automatically | |
141 | Status CreateLoggerFromOptions(const std::string& dbname, | |
142 | const DBOptions& options, | |
143 | std::shared_ptr<Logger>* logger); | |
144 | ||
145 | } // namespace rocksdb |