Commit 59f59178 authored by Adam Simpkins's avatar Adam Simpkins Committed by Facebook Github Bot

logging: add numbered INFO* log level values

Summary:
Define INFO0 through INFO9 levels for users that want to have finer-grained
control over info log messages.

This also renumbers the DBG log levels slightly so that there are exactly 1000
levels between each major log level step.  This renumbering change should not
affect any code behavior, since these level values are primarily used in memory
and aren't saved persistently anywhere.

Reviewed By: yfeldblum

Differential Revision: D6690466

fbshipit-source-id: acd499cff6830a1d1b579f295bd4b2bac93b5ada
parent 24d6b776
......@@ -15,6 +15,7 @@
*/
#include <folly/experimental/logging/LogLevel.h>
#include <array>
#include <cctype>
#include <ostream>
......@@ -24,6 +25,20 @@ using std::string;
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());
......@@ -67,13 +82,19 @@ LogLevel stringToLogLevel(StringPiece name) {
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
......@@ -106,12 +127,14 @@ string logLevelToString(LogLevel level) {
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), ")");
}
......
......@@ -30,10 +30,10 @@ namespace folly {
*
* 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,
......@@ -49,20 +49,33 @@ enum class LogLevel : uint32_t {
//
// 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,
......
......@@ -71,9 +71,19 @@ TEST(LogLevel, fromString) {
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);
......@@ -100,10 +110,17 @@ TEST(LogLevel, toString) {
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) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment