*/
#include <folly/experimental/logging/LogLevel.h>
+#include <array>
#include <cctype>
#include <ostream>
namespace folly {
+namespace {
+struct NumberedLevelInfo {
+ LogLevel min;
+ LogLevel max;
+ StringPiece lowerPrefix;
+ StringPiece upperPrefix;
+};
+
+constexpr std::array<NumberedLevelInfo, 2> numberedLogLevels = {
+ NumberedLevelInfo{LogLevel::DBG, LogLevel::DBG0, "dbg", "DBG"},
+ NumberedLevelInfo{LogLevel::INFO, LogLevel::INFO0, "info", "INFO"},
+};
+} // namespace
+
LogLevel stringToLogLevel(StringPiece name) {
string lowerNameStr;
lowerNameStr.reserve(name.size());
return LogLevel::MAX_LEVEL;
}
- if (lowerName.startsWith("dbg")) {
- auto remainder = lowerName.subpiece(3);
+ for (const auto& info : numberedLogLevels) {
+ if (!lowerName.startsWith(info.lowerPrefix)) {
+ continue;
+ }
+ auto remainder = lowerName.subpiece(info.lowerPrefix.size());
auto level = folly::tryTo<int>(remainder).value_or(-1);
- if (level < 0 || level > 100) {
- throw std::range_error("invalid dbg logger level: " + name.str());
+ if (level < 0 ||
+ static_cast<unsigned int>(level) > (static_cast<uint32_t>(info.max) -
+ static_cast<uint32_t>(info.min))) {
+ throw std::range_error(to<string>(
+ "invalid ", info.lowerPrefix, " logger level: ", name.str()));
}
- return LogLevel::DBG0 - level;
+ return info.max - level;
}
// Try as an plain integer if all else fails
return "FATAL";
}
- if (static_cast<uint32_t>(level) <= static_cast<uint32_t>(LogLevel::DBG0) &&
- static_cast<uint32_t>(level) > static_cast<uint32_t>(LogLevel::DBG)) {
- auto num =
- static_cast<uint32_t>(LogLevel::DBG0) - static_cast<uint32_t>(level);
- return folly::to<string>("DBG", num);
+ for (const auto& info : numberedLogLevels) {
+ if (static_cast<uint32_t>(level) <= static_cast<uint32_t>(info.max) &&
+ static_cast<uint32_t>(level) > static_cast<uint32_t>(info.min)) {
+ auto num = static_cast<uint32_t>(info.max) - static_cast<uint32_t>(level);
+ return folly::to<string>(info.upperPrefix, num);
+ }
}
+
return folly::to<string>("LogLevel(", static_cast<uint32_t>(level), ")");
}
*
* Higher levels are more important than lower ones.
*
- * However, the numbers in the DBG* level names are reversed, and can be
- * thought of as debug verbosity levels. Increasing DBG* numbers mean
- * increasing level of verbosity. DBG0 is the least verbose debug level,
- * DBG1 is one level higher of verbosity, etc.
+ * However, the numbers in the DBG* and INFO* level names are reversed, and can
+ * be thought of as debug verbosity levels. Increasing DBG* numbers mean
+ * increasing level of verbosity. DBG0 is the least verbose debug level, DBG1
+ * is one level higher of verbosity, etc.
*/
enum class LogLevel : uint32_t {
UNINITIALIZED = 0,
//
// This is named "DBG" rather than "DEBUG" since some open source projects
// define "DEBUG" as a preprocessor macro.
- DBG = 900,
-
- DBG0 = 1000,
- DBG1 = 999,
- DBG2 = 998,
- DBG3 = 997,
- DBG4 = 996,
- DBG5 = 995,
- DBG6 = 994,
- DBG7 = 993,
- DBG8 = 992,
- DBG9 = 991,
+ DBG = 1000,
+
+ // Fine-grained debug log levels.
+ DBG0 = 1999,
+ DBG1 = 1998,
+ DBG2 = 1997,
+ DBG3 = 1996,
+ DBG4 = 1995,
+ DBG5 = 1994,
+ DBG6 = 1993,
+ DBG7 = 1992,
+ DBG8 = 1991,
+ DBG9 = 1990,
INFO = 2000,
+ // Fine-grained info log levels.
+ INFO0 = 2999,
+ INFO1 = 2998,
+ INFO2 = 2997,
+ INFO3 = 2996,
+ INFO4 = 2995,
+ INFO5 = 2994,
+ INFO6 = 2993,
+ INFO7 = 2992,
+ INFO8 = 2991,
+ INFO9 = 2990,
+
WARN = 3000,
WARNING = 3000,
EXPECT_EQ(LogLevel::DBG5, stringToLogLevel("dbg5"));
EXPECT_EQ(LogLevel::DBG5, stringToLogLevel("DBG5"));
EXPECT_EQ(LogLevel::DBG9, stringToLogLevel("DBG9"));
- EXPECT_EQ(LogLevel::DBG + 1, stringToLogLevel("DBG99"));
- EXPECT_EQ(LogLevel::DBG, stringToLogLevel("900"));
- EXPECT_EQ(LogLevel::DBG, stringToLogLevel("LogLevel(900)"));
+ EXPECT_EQ(LogLevel::DBG + 1, stringToLogLevel("DBG998"));
+ EXPECT_EQ(LogLevel::DBG, stringToLogLevel("DBG999"));
+ EXPECT_EQ(LogLevel::DBG, stringToLogLevel("1000"));
+ EXPECT_EQ(LogLevel::DBG, stringToLogLevel("LogLevel(1000)"));
+
+ EXPECT_EQ(LogLevel::INFO0, stringToLogLevel("info0"));
+ EXPECT_EQ(LogLevel::INFO5, stringToLogLevel("INFO5"));
+ EXPECT_EQ(LogLevel::INFO5, stringToLogLevel("INFO5"));
+ EXPECT_EQ(LogLevel::INFO9, stringToLogLevel("info9"));
+ EXPECT_EQ(LogLevel::INFO + 1, stringToLogLevel("Info998"));
+ EXPECT_EQ(LogLevel::INFO, stringToLogLevel("INFO999"));
+ EXPECT_EQ(LogLevel::INFO, stringToLogLevel("2000"));
+ EXPECT_EQ(LogLevel::INFO6, stringToLogLevel("LogLevel(2993)"));
EXPECT_THROW(stringToLogLevel("foobar"), std::range_error);
EXPECT_THROW(stringToLogLevel("dbgx"), std::range_error);
EXPECT_EQ("DBG2", logLevelToString(LogLevel::DBG2));
EXPECT_EQ("DBG5", logLevelToString(LogLevel::DBG5));
EXPECT_EQ("DBG9", logLevelToString(LogLevel::DBG9));
- EXPECT_EQ("DBG97", logLevelToString(static_cast<LogLevel>(903)));
+ EXPECT_EQ("DBG96", logLevelToString(static_cast<LogLevel>(1903)));
EXPECT_EQ("DBG64", logLevelToString(LogLevel::DBG4 - 60));
- EXPECT_EQ("LogLevel(1234)", logLevelToString(static_cast<LogLevel>(1234)));
+ EXPECT_EQ("INFO0", logLevelToString(LogLevel::INFO0));
+ EXPECT_EQ("INFO2", logLevelToString(LogLevel::INFO2));
+ EXPECT_EQ("INFO5", logLevelToString(LogLevel::INFO5));
+ EXPECT_EQ("INFO9", logLevelToString(LogLevel::INFO9));
+ EXPECT_EQ("INFO86", logLevelToString(static_cast<LogLevel>(2913)));
+ EXPECT_EQ("INFO57", logLevelToString(LogLevel::INFO7 - 50));
+
+ EXPECT_EQ("LogLevel(123)", logLevelToString(static_cast<LogLevel>(123)));
}
TEST(LogLevel, toStringAndBack) {