/*
- * Copyright 2004-present Facebook, Inc.
+ * Copyright 2017-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <folly/experimental/logging/LogCategory.h>
#include <cstdio>
+#include <cstdlib>
+#include <folly/ConstexprMath.h>
#include <folly/ExceptionString.h>
+#include <folly/FileUtil.h>
+#include <folly/MapUtil.h>
#include <folly/experimental/logging/LogHandler.h>
#include <folly/experimental/logging/LogMessage.h>
#include <folly/experimental/logging/LogName.h>
namespace folly {
LogCategory::LogCategory(LoggerDB* db)
- : effectiveLevel_{LogLevel::ERROR},
- level_{static_cast<uint32_t>(LogLevel::ERROR)},
+ : effectiveLevel_{LogLevel::ERR},
+ level_{static_cast<uint32_t>(LogLevel::ERR)},
parent_{nullptr},
name_{},
db_{db} {}
parent_->firstChild_ = this;
}
+void LogCategory::admitMessage(const LogMessage& message) const {
+ processMessage(message);
+
+ // If this is a fatal message, flush the handlers to make sure the log
+ // message was written out, then crash.
+ if (isLogLevelFatal(message.getLevel())) {
+ auto numHandlers = db_->flushAllHandlers();
+ if (numHandlers == 0) {
+ // No log handlers were configured.
+ // Print the message to stderr, to make sure we always print the reason
+ // we are crashing somewhere.
+ auto msg = folly::to<std::string>(
+ "FATAL:",
+ message.getFileName(),
+ ":",
+ message.getLineNumber(),
+ ": ",
+ message.getMessage(),
+ "\n");
+ folly::writeFull(STDERR_FILENO, msg.data(), msg.size());
+ }
+ std::abort();
+ }
+}
+
void LogCategory::processMessage(const LogMessage& message) const {
// Make a copy of any attached LogHandlers, so we can release the handlers_
// lock before holding them.
// LogHandler destructors.
}
+std::vector<std::shared_ptr<LogHandler>> LogCategory::getHandlers() const {
+ return *(handlers_.rlock());
+}
+
+void LogCategory::replaceHandlers(
+ std::vector<std::shared_ptr<LogHandler>> handlers) {
+ return handlers_.wlock()->swap(handlers);
+}
+
+void LogCategory::updateHandlers(const std::unordered_map<
+ std::shared_ptr<LogHandler>,
+ std::shared_ptr<LogHandler>>& handlerMap) {
+ auto handlers = handlers_.wlock();
+ for (auto& entry : *handlers) {
+ auto* ptr = get_ptr(handlerMap, entry);
+ if (ptr) {
+ entry = *ptr;
+ }
+ }
+}
+
void LogCategory::setLevel(LogLevel level, bool inherit) {
// We have to set the level through LoggerDB, since we require holding
// the LoggerDB lock to iterate through our children in case our effective
//
// 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;
- }
+ level = constexpr_clamp(level, LogLevel::MIN_LEVEL, LogLevel::MAX_LEVEL);
// Make sure the inherit flag is always off for the root logger.
if (!parent_) {
void LogCategory::registerXlogLevel(std::atomic<LogLevel>* levelPtr) {
xlogLevels_.push_back(levelPtr);
}
-}
+} // namespace folly