proxygen
LogCategory.h
Go to the documentation of this file.
1 /*
2  * Copyright 2017-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include <atomic>
19 #include <cstdint>
20 #include <list>
21 #include <string>
22 
23 #include <folly/Range.h>
24 #include <folly/Synchronized.h>
25 #include <folly/logging/LogLevel.h>
26 
27 namespace folly {
28 
29 class LoggerDB;
30 class LogHandler;
31 class LogMessage;
32 
41 class LogCategory {
42  public:
48  explicit LogCategory(LoggerDB* db);
49 
62 
66  const std::string& getName() const {
67  return name_;
68  }
69 
73  LogLevel getLevel() const {
74  return static_cast<LogLevel>(
75  level_.load(std::memory_order_acquire) & ~FLAG_INHERIT);
76  }
77 
81  std::pair<LogLevel, bool> getLevelInfo() const {
82  auto value = level_.load(std::memory_order_acquire);
83  return {static_cast<LogLevel>(value & ~FLAG_INHERIT),
84  bool(value & FLAG_INHERIT)};
85  }
86 
96  return effectiveLevel_.load(std::memory_order_acquire);
97  }
98 
107  return effectiveLevel_.load(std::memory_order_relaxed);
108  }
109 
114  bool logCheck(LogLevel level) const {
115  // We load the effective level using std::memory_order_relaxed.
116  //
117  // We want to make log checks as lightweight as possible. It's fine if we
118  // don't immediately respond to changes made to the log level from other
119  // threads. We can wait until some other operation triggers a memory
120  // barrier before we honor the new log level setting. No other memory
121  // accesses depend on the log level value. Callers should not rely on all
122  // other threads to immediately stop logging as soon as they decrease the
123  // log level for a given category.
124  return effectiveLevel_.load(std::memory_order_relaxed) <= level;
125  }
126 
139  void setLevel(LogLevel level, bool inherit = true);
140 
148  LoggerDB* getDB() const {
149  return db_;
150  }
151 
155  void addHandler(std::shared_ptr<LogHandler> handler);
156 
160  void clearHandlers();
161 
165  std::vector<std::shared_ptr<LogHandler>> getHandlers() const;
166 
170  void replaceHandlers(std::vector<std::shared_ptr<LogHandler>> handlers);
171 
183  void updateHandlers(const std::unordered_map<
184  std::shared_ptr<LogHandler>,
185  std::shared_ptr<LogHandler>>& handlerMap);
186 
187  /* Internal methods for use by other parts of the logging library code */
188 
198  void admitMessage(const LogMessage& message) const;
199 
207  void setLevelLocked(LogLevel level, bool inherit);
208 
219  void registerXlogLevel(std::atomic<LogLevel>* levelPtr);
220 
221  private:
222  enum : uint32_t { FLAG_INHERIT = 0x80000000 };
223 
224  // FLAG_INHERIT is the stored in the uppermost bit of the LogLevel field.
225  // assert that it does not conflict with valid LogLevel values.
226  static_assert(
227  static_cast<uint32_t>(LogLevel::MAX_LEVEL) < FLAG_INHERIT,
228  "The FLAG_INHERIT bit must not be set in any valid LogLevel value");
229 
230  // Forbidden copy constructor and assignment operator
231  LogCategory(LogCategory const&) = delete;
232  LogCategory& operator=(LogCategory const&) = delete;
233  // Disallow moving LogCategory objects as well.
234  // LogCategory objects store pointers to their parent and siblings,
235  // so we cannot allow moving categories to other locations.
236  LogCategory(LogCategory&&) = delete;
237  LogCategory& operator=(LogCategory&&) = delete;
238 
239  void processMessage(const LogMessage& message) const;
240  void updateEffectiveLevel(LogLevel newEffectiveLevel);
241  void parentLevelUpdated(LogLevel parentEffectiveLevel);
242 
246  std::atomic<LogLevel> effectiveLevel_{LogLevel::MAX_LEVEL};
247 
254  std::atomic<uint32_t> level_{0};
255 
262  LogCategory* const parent_{nullptr};
263 
268 
273 
280  LoggerDB* const db_{nullptr};
281 
290 
298  std::vector<std::atomic<LogLevel>*> xlogLevels_;
299 };
300 } // namespace folly
folly::Synchronized< std::vector< std::shared_ptr< LogHandler > > > handlers_
Definition: LogCategory.h:272
Definition: test.c:42
LogCategory(LoggerDB *db)
Definition: LogCategory.cpp:32
std::atomic< uint32_t > level_
Definition: LogCategory.h:254
void processMessage(const LogMessage &message) const
Definition: LogCategory.cpp:74
std::vector< std::atomic< LogLevel > * > xlogLevels_
Definition: LogCategory.h:298
void setLevelLocked(LogLevel level, bool inherit)
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
LoggerDB *const db_
Definition: LogCategory.h:280
void handler(int, siginfo_t *, void *)
LogCategory * firstChild_
Definition: LogCategory.h:288
const char * name
Definition: http_parser.c:437
std::pair< LogLevel, bool > getLevelInfo() const
Definition: LogCategory.h:81
const std::string name_
Definition: LogCategory.h:267
void setLevel(LogLevel level, bool inherit=true)
const std::string & getName() const
Definition: LogCategory.h:66
LogLevel getEffectiveLevelRelaxed() const
Definition: LogCategory.h:106
LogLevel getLevel() const
Definition: LogCategory.h:73
LogLevel
Definition: LogLevel.h:38
LogCategory & operator=(LogCategory const &)=delete
void updateHandlers(const std::unordered_map< std::shared_ptr< LogHandler >, std::shared_ptr< LogHandler >> &handlerMap)
const char * string
Definition: Conv.cpp:212
bool logCheck(LogLevel level) const
Definition: LogCategory.h:114
uint64_t value(const typename LockFreeRingBuffer< T, Atom >::Cursor &rbcursor)
std::vector< std::shared_ptr< LogHandler > > getHandlers() const
LogLevel getEffectiveLevel() const
Definition: LogCategory.h:95
void replaceHandlers(std::vector< std::shared_ptr< LogHandler >> handlers)
LoggerDB * getDB() const
Definition: LogCategory.h:148
std::atomic< LogLevel > effectiveLevel_
Definition: LogCategory.h:246
LogCategory *const parent_
Definition: LogCategory.h:262
LogCategory * nextSibling_
Definition: LogCategory.h:289
void addHandler(std::shared_ptr< LogHandler > handler)
void updateEffectiveLevel(LogLevel newEffectiveLevel)
void admitMessage(const LogMessage &message) const
Definition: LogCategory.cpp:49
void parentLevelUpdated(LogLevel parentEffectiveLevel)
folly::Function< void()> parent
Definition: AtFork.cpp:34
void registerXlogLevel(std::atomic< LogLevel > *levelPtr)