From: Adam Simpkins Date: Thu, 30 Nov 2017 01:35:13 +0000 (-0800) Subject: logging: add a LoggerDB::getConfig() method X-Git-Tag: v2017.12.04.00~18 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=b6e14b7b1823915a6891bd2fa622bca8f4c61004;p=folly.git logging: add a LoggerDB::getConfig() method Summary: Add a method to get the current LogConfig state from the LoggerDB. Reviewed By: bolinfest Differential Revision: D6200596 fbshipit-source-id: 3bc57d498a5d25d19099d861376d71ea9f7e4039 --- diff --git a/folly/experimental/logging/LogCategory.h b/folly/experimental/logging/LogCategory.h index 4779a472..565373a7 100644 --- a/folly/experimental/logging/LogCategory.h +++ b/folly/experimental/logging/LogCategory.h @@ -75,6 +75,15 @@ class LogCategory { level_.load(std::memory_order_acquire) & ~FLAG_INHERIT); } + /** + * Get the log level and inheritance flag. + */ + std::pair getLevelInfo() const { + auto value = level_.load(std::memory_order_acquire); + return {static_cast(value & ~FLAG_INHERIT), + bool(value & FLAG_INHERIT)}; + } + /** * Get the effective level for this log category. * diff --git a/folly/experimental/logging/LoggerDB.cpp b/folly/experimental/logging/LoggerDB.cpp index fdfcdfa5..c7a32705 100644 --- a/folly/experimental/logging/LoggerDB.cpp +++ b/folly/experimental/logging/LoggerDB.cpp @@ -21,12 +21,15 @@ #include #include #include +#include #include #include #include #include #include +using std::string; + namespace folly { namespace { @@ -138,6 +141,73 @@ std::vector LoggerDB::processConfigString( return errors; } +LogConfig LoggerDB::getConfig() const { + auto handlerInfo = handlerInfo_.rlock(); + + LogConfig::HandlerConfigMap handlerConfigs; + std::unordered_map, string> handlersToName; + for (const auto& entry : handlerInfo->handlers) { + auto handler = entry.second.lock(); + if (!handler) { + continue; + } + handlersToName.emplace(handler, entry.first); + handlerConfigs.emplace(entry.first, handler->getConfig()); + } + + size_t anonymousNameIndex = 1; + auto generateAnonymousHandlerName = [&]() { + // Return a unique name of the form "anonymousHandlerN" + // Keep incrementing N until we find a name that isn't currently taken. + while (true) { + auto name = to("anonymousHandler", anonymousNameIndex); + ++anonymousNameIndex; + if (handlerInfo->handlers.find(name) == handlerInfo->handlers.end()) { + return name; + } + } + }; + + LogConfig::CategoryConfigMap categoryConfigs; + { + auto loggersByName = loggersByName_.rlock(); + for (const auto& entry : *loggersByName) { + auto* category = entry.second.get(); + auto levelInfo = category->getLevelInfo(); + auto handlers = category->getHandlers(); + + // Don't report categories that have default settings. + if (handlers.empty() && levelInfo.first == LogLevel::MAX_LEVEL && + levelInfo.second) { + continue; + } + + // Translate the handler pointers to names + std::vector handlerNames; + for (const auto& handler : handlers) { + auto iter = handlersToName.find(handler); + if (iter == handlersToName.end()) { + // This LogHandler must have been manually attached to the category, + // rather than defined with `updateConfig()` or `resetConfig()`. + // Generate a unique name to use for reporting it in the config. + auto name = generateAnonymousHandlerName(); + handlersToName.emplace(handler, name); + handlerConfigs.emplace(name, handler->getConfig()); + handlerNames.emplace_back(name); + } else { + handlerNames.emplace_back(iter->second); + } + } + + LogCategoryConfig categoryConfig( + levelInfo.first, levelInfo.second, handlerNames); + categoryConfigs.emplace(category->getName(), std::move(categoryConfig)); + } + } + + return LogConfig{std::move(handlerConfigs), std::move(categoryConfigs)}; +} + LogCategory* LoggerDB::getOrCreateCategoryLocked( LoggerNameMap& loggersByName, StringPiece name) { diff --git a/folly/experimental/logging/LoggerDB.h b/folly/experimental/logging/LoggerDB.h index c2c1d423..d65324f7 100644 --- a/folly/experimental/logging/LoggerDB.h +++ b/folly/experimental/logging/LoggerDB.h @@ -29,6 +29,7 @@ namespace folly { class LogCategory; +class LogConfig; class LogHandler; class LogHandlerFactory; enum class LogLevel : uint32_t; @@ -76,6 +77,17 @@ class LoggerDB { void setLevel(folly::StringPiece name, LogLevel level, bool inherit = true); void setLevel(LogCategory* category, LogLevel level, bool inherit = true); + /** + * Get a LogConfig object describing the current state of the LoggerDB. + * + * Note that this may not 100% accurately describe the current configuration + * if callers have manually added LogHandlers to some categories without + * using the updateConfig() or resetConfig() functions. In this case + * getConfig() will simply report these handlers as "unknown_handler" when + * returning handler names for the categories in question. + */ + LogConfig getConfig() const; + /** * Apply a configuration string specifying a series a log levels. *