proxygen
LogLevel.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include <folly/logging/LogLevel.h>
17 
18 #include <array>
19 #include <cctype>
20 #include <ostream>
21 
22 #include <folly/Conv.h>
23 
24 using std::string;
25 
26 namespace folly {
27 
28 namespace {
29 struct NumberedLevelInfo {
34 };
35 
36 constexpr std::array<NumberedLevelInfo, 2> numberedLogLevels = {{
37  NumberedLevelInfo{LogLevel::DBG, LogLevel::DBG0, "dbg", "DBG"},
38  NumberedLevelInfo{LogLevel::INFO, LogLevel::INFO0, "info", "INFO"},
39 }};
40 } // namespace
41 
43  string lowerNameStr;
44  lowerNameStr.reserve(name.size());
45  for (char c : name) {
46  lowerNameStr.push_back(static_cast<char>(std::tolower(c)));
47  }
48  StringPiece lowerName{lowerNameStr};
49 
50  // If the string is of the form "LogLevel::foo" or "LogLevel(foo)"
51  // strip it down just to "foo". This makes sure we can process both
52  // the "LogLevel::WARN" and "LogLevel(1234)" formats produced by
53  // logLevelToString().
54  constexpr StringPiece lowercasePrefix{"loglevel::"};
55  constexpr StringPiece wrapperPrefix{"loglevel("};
56  if (lowerName.startsWith(lowercasePrefix)) {
57  lowerName.advance(lowercasePrefix.size());
58  } else if (lowerName.startsWith(wrapperPrefix) && lowerName.endsWith(")")) {
59  lowerName.advance(wrapperPrefix.size());
60  lowerName.subtract(1);
61  }
62 
63  if (lowerName == "uninitialized") {
65  } else if (lowerName == "none") {
66  return LogLevel::NONE;
67  } else if (lowerName == "debug" || lowerName == "dbg") {
68  return LogLevel::DBG;
69  } else if (lowerName == "info") {
70  return LogLevel::INFO;
71  } else if (lowerName == "warn" || lowerName == "warning") {
72  return LogLevel::WARN;
73  } else if (lowerName == "error" || lowerName == "err") {
74  return LogLevel::ERR;
75  } else if (lowerName == "critical") {
76  return LogLevel::CRITICAL;
77  } else if (lowerName == "dfatal") {
78  return LogLevel::DFATAL;
79  } else if (lowerName == "fatal") {
80  return LogLevel::FATAL;
81  } else if (lowerName == "max" || lowerName == "max_level") {
82  return LogLevel::MAX_LEVEL;
83  }
84 
85  for (const auto& info : numberedLogLevels) {
86  if (!lowerName.startsWith(info.lowerPrefix)) {
87  continue;
88  }
89  auto remainder = lowerName.subpiece(info.lowerPrefix.size());
90  auto level = folly::tryTo<int>(remainder).value_or(-1);
91  if (level < 0 ||
92  static_cast<unsigned int>(level) > (static_cast<uint32_t>(info.max) -
93  static_cast<uint32_t>(info.min))) {
94  throw std::range_error(to<string>(
95  "invalid ", info.lowerPrefix, " logger level: ", name.str()));
96  }
97  return info.max - level;
98  }
99 
100  // Try as an plain integer if all else fails
101  try {
102  auto level = folly::to<uint32_t>(lowerName);
103  return static_cast<LogLevel>(level);
104  } catch (const std::exception&) {
105  throw std::range_error("invalid logger level: " + name.str());
106  }
107 }
108 
109 string logLevelToString(LogLevel level) {
110  if (level == LogLevel::UNINITIALIZED) {
111  return "UNINITIALIZED";
112  } else if (level == LogLevel::NONE) {
113  return "NONE";
114  } else if (level == LogLevel::DBG) {
115  return "DEBUG";
116  } else if (level == LogLevel::INFO) {
117  return "INFO";
118  } else if (level == LogLevel::WARN) {
119  return "WARN";
120  } else if (level == LogLevel::ERR) {
121  return "ERR";
122  } else if (level == LogLevel::CRITICAL) {
123  return "CRITICAL";
124  } else if (level == LogLevel::DFATAL) {
125  return "DFATAL";
126  } else if (level == LogLevel::FATAL) {
127  return "FATAL";
128  }
129 
130  for (const auto& info : numberedLogLevels) {
131  if (static_cast<uint32_t>(level) <= static_cast<uint32_t>(info.max) &&
132  static_cast<uint32_t>(level) > static_cast<uint32_t>(info.min)) {
133  auto num = static_cast<uint32_t>(info.max) - static_cast<uint32_t>(level);
134  return folly::to<string>(info.upperPrefix, num);
135  }
136  }
137 
138  return folly::to<string>("LogLevel(", static_cast<uint32_t>(level), ")");
139 }
140 
141 std::ostream& operator<<(std::ostream& os, LogLevel level) {
142  os << logLevelToString(level);
143  return os;
144 }
145 } // namespace folly
def info()
Definition: deadlock.py:447
LogLevel max
Definition: LogLevel.cpp:31
void advance(size_type n)
Definition: Range.h:672
constexpr size_type size() const
Definition: Range.h:431
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
LogLevel stringToLogLevel(StringPiece name)
Definition: LogLevel.cpp:42
string logLevelToString(LogLevel level)
Definition: LogLevel.cpp:109
const char * name
Definition: http_parser.c:437
LogLevel min
Definition: LogLevel.cpp:30
StringPiece upperPrefix
Definition: LogLevel.cpp:33
LogLevel
Definition: LogLevel.h:38
const char * string
Definition: Conv.cpp:212
Range< const char * > StringPiece
char c
StringPiece lowerPrefix
Definition: LogLevel.cpp:32
std::ostream & operator<<(std::ostream &out, dynamic const &d)
Definition: dynamic-inl.h:1158