parent_->firstChild_ = this;
}
-void LogCategory::processMessage(const LogMessage& message) {
+void LogCategory::processMessage(const LogMessage& message) const {
// Make a copy of any attached LogHandlers, so we can release the handlers_
// lock before holding them.
//
for (size_t n = 0; n < numHandlers; ++n) {
try {
- handlers[n]->log(message, this);
+ handlers[n]->handleMessage(message, this);
} catch (const std::exception& ex) {
- // If a LogHandler throws an exception, complain about this fact on
- // stderr to avoid swallowing the error information completely. We
- // don't propagate the exception up to our caller: most code does not
- // prepare for log statements to throw. We also want to continue
- // trying to log the message to any other handlers attached to ourself
- // or one of our parent categories.
- fprintf(
- stderr,
- "WARNING: log handler for category %s threw an error: %s\n",
- name_.c_str(),
- folly::exceptionStr(ex).c_str());
+ // Use LoggerDB::internalWarning() to report the error, but continue
+ // trying to log the message to any other handlers attached to ourself or
+ // one of our parent categories.
+ LoggerDB::internalWarning(
+ __FILE__,
+ __LINE__,
+ "log handler for category \"",
+ name_,
+ "\" threw an error: ",
+ folly::exceptionStr(ex));
}
}
}
void LogCategory::setLevelLocked(LogLevel level, bool inherit) {
- // Truncate to LogLevel::MAX_LEVEL to make sure it does not conflict
- // with our flag bits.
+ // Clamp the value to MIN_LEVEL and MAX_LEVEL.
+ //
+ // This makes sure that UNINITIALIZED is always less than any valid level
+ // value, and that level values cannot conflict with our flag bits.
if (level > LogLevel::MAX_LEVEL) {
level = LogLevel::MAX_LEVEL;
+ } else if (level < LogLevel::MIN_LEVEL) {
+ level = LogLevel::MIN_LEVEL;
}
+
// Make sure the inherit flag is always off for the root logger.
if (!parent_) {
inherit = false;
return;
}
+ // Update all of the values in xlogLevels_
+ for (auto* levelPtr : xlogLevels_) {
+ levelPtr->store(newEffectiveLevel, std::memory_order_release);
+ }
+
// Update all children loggers
LogCategory* child = firstChild_;
while (child != nullptr) {
auto newEffectiveLevel = std::min(myLevel, parentEffectiveLevel);
updateEffectiveLevel(newEffectiveLevel);
}
+
+void LogCategory::registerXlogLevel(std::atomic<LogLevel>* levelPtr) {
+ xlogLevels_.push_back(levelPtr);
+}
}