proxygen
LogCategoryTest.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  */
17 
18 #include <folly/Conv.h>
19 #include <folly/logging/Logger.h>
20 #include <folly/logging/LoggerDB.h>
23 
24 using namespace folly;
25 using std::make_shared;
26 using std::shared_ptr;
27 using std::string;
28 
29 TEST(LogCategory, effectiveLevel) {
31  Logger foo{&db, "foo"};
32  Logger foo2{&db, "..foo.."};
33  EXPECT_EQ(foo.getCategory(), foo2.getCategory());
34 
35  EXPECT_EQ(kDefaultLogLevel, db.getCategory("")->getLevel());
36  EXPECT_EQ(kDefaultLogLevel, db.getCategory("")->getEffectiveLevel());
37 
38  EXPECT_EQ(LogLevel::MAX_LEVEL, db.getCategory("foo.bar")->getLevel());
39  EXPECT_EQ(kDefaultLogLevel, db.getCategory("foo.bar")->getEffectiveLevel());
40 
41  db.setLevel(".foo", LogLevel::DBG0);
42  EXPECT_EQ(LogLevel::MAX_LEVEL, db.getCategory("foo.bar")->getLevel());
43  EXPECT_EQ(LogLevel::DBG0, db.getCategory("foo.bar")->getEffectiveLevel());
44 
45  db.setLevel(".", LogLevel::DBG0);
46  EXPECT_EQ(LogLevel::MAX_LEVEL, db.getCategory("foo.bar")->getLevel());
47  EXPECT_EQ(LogLevel::DBG0, db.getCategory("foo.bar")->getEffectiveLevel());
48 
49  // Test a newly created category under .foo
50  EXPECT_EQ(LogLevel::MAX_LEVEL, db.getCategory("foo.test.1234")->getLevel());
51  EXPECT_EQ(
52  LogLevel::DBG0, db.getCategory("foo.test.1234")->getEffectiveLevel());
53 
54  // Test a category that does not inherit its parent's log level
55  auto noinherit = db.getCategory("foo.test.noinherit");
56  EXPECT_EQ(LogLevel::MAX_LEVEL, noinherit->getLevel());
57  EXPECT_EQ(LogLevel::DBG0, noinherit->getEffectiveLevel());
58  noinherit->setLevel(LogLevel::CRITICAL, false);
59  EXPECT_EQ(LogLevel::CRITICAL, noinherit->getEffectiveLevel());
60 
61  // Modify the root logger's level
62  db.setLevel(".", LogLevel::ERR);
63  EXPECT_EQ(LogLevel::MAX_LEVEL, db.getCategory("foo.test.1234")->getLevel());
64  EXPECT_EQ(
65  LogLevel::DBG0, db.getCategory("foo.test.1234")->getEffectiveLevel());
66  EXPECT_EQ(LogLevel::MAX_LEVEL, db.getCategory("foo.test")->getLevel());
67  EXPECT_EQ(LogLevel::DBG0, db.getCategory("foo.test")->getEffectiveLevel());
68  EXPECT_EQ(LogLevel::DBG0, db.getCategory("foo")->getLevel());
69  EXPECT_EQ(LogLevel::DBG0, db.getCategory("foo")->getEffectiveLevel());
70  EXPECT_EQ(
71  LogLevel::CRITICAL, db.getCategory("foo.test.noinherit")->getLevel());
72  EXPECT_EQ(
74  db.getCategory("foo.test.noinherit")->getEffectiveLevel());
75 
76  EXPECT_EQ(LogLevel::MAX_LEVEL, db.getCategory("bar.foo.test")->getLevel());
77  EXPECT_EQ(LogLevel::ERR, db.getCategory("bar.foo.test")->getEffectiveLevel());
78 }
79 
80 void testNumHandlers(size_t numHandlers) {
81  SCOPED_TRACE(folly::to<string>("num_handlers= ", numHandlers));
83  db.setLevel("", LogLevel::DBG);
84 
85  // Create the requested number of handlers for the foo.bar category
86  Logger foobar{&db, "foo.bar"};
87  std::vector<shared_ptr<TestLogHandler>> handlers;
88  for (size_t n = 0; n < numHandlers; ++n) {
89  handlers.emplace_back(make_shared<TestLogHandler>());
90  foobar.getCategory()->addHandler(handlers.back());
91  }
92 
93  // Add a handler to the root category, to confirm that messages are
94  // propagated up to the root correctly.
95  auto rootHandler = make_shared<TestLogHandler>();
96  auto rootCategory = db.getCategory("");
97  rootCategory->addHandler(rootHandler);
98 
99  // Log a message to a child of the foobar category
100  Logger childLogger{&db, "foo.bar.child"};
101  FB_LOG(childLogger, WARN, "beware");
102 
103  // Make sure the message showed up at all of the handlers
104  for (const auto& handler : handlers) {
105  auto& messages = handler->getMessages();
106  ASSERT_EQ(1, messages.size());
107  EXPECT_EQ("beware", messages[0].first.getMessage());
108  EXPECT_EQ(LogLevel::WARN, messages[0].first.getLevel());
109  EXPECT_EQ(childLogger.getCategory(), messages[0].first.getCategory());
110  EXPECT_EQ(foobar.getCategory(), messages[0].second);
111  }
112  {
113  auto& messages = rootHandler->getMessages();
114  ASSERT_EQ(1, messages.size());
115  EXPECT_EQ("beware", messages[0].first.getMessage());
116  EXPECT_EQ(LogLevel::WARN, messages[0].first.getLevel());
117  EXPECT_EQ(childLogger.getCategory(), messages[0].first.getCategory());
118  EXPECT_EQ(rootCategory, messages[0].second);
119  }
120 
121  // Now log a message directly to foobar
122  FB_LOG(foobar, DBG1, "just testing");
123  for (const auto& handler : handlers) {
124  auto& messages = handler->getMessages();
125  ASSERT_EQ(2, messages.size());
126  EXPECT_EQ("just testing", messages[1].first.getMessage());
127  EXPECT_EQ(LogLevel::DBG1, messages[1].first.getLevel());
128  EXPECT_EQ(foobar.getCategory(), messages[1].first.getCategory());
129  EXPECT_EQ(foobar.getCategory(), messages[1].second);
130  }
131  {
132  auto& messages = rootHandler->getMessages();
133  ASSERT_EQ(2, messages.size());
134  EXPECT_EQ("just testing", messages[1].first.getMessage());
135  EXPECT_EQ(LogLevel::DBG1, messages[1].first.getLevel());
136  EXPECT_EQ(foobar.getCategory(), messages[1].first.getCategory());
137  EXPECT_EQ(rootCategory, messages[1].second);
138  }
139 
140  // Log a message to a sibling of foobar
141  Logger siblingLogger{&db, "foo.sibling"};
142  FB_LOG(siblingLogger, ERR, "oh noes");
143  for (const auto& handler : handlers) {
144  auto& messages = handler->getMessages();
145  EXPECT_EQ(2, messages.size());
146  }
147  {
148  auto& messages = rootHandler->getMessages();
149  ASSERT_EQ(3, messages.size());
150  EXPECT_EQ("oh noes", messages[2].first.getMessage());
151  EXPECT_EQ(LogLevel::ERR, messages[2].first.getLevel());
152  EXPECT_EQ(siblingLogger.getCategory(), messages[2].first.getCategory());
153  EXPECT_EQ(rootCategory, messages[2].second);
154  }
155 }
156 
157 TEST(LogCategory, numHandlers) {
158  // The LogCategory code behaves differently when there are 5 or fewer
159  // LogHandlers attached to a category vs when ther are more.
160  //
161  // Test with fewer than 5 handlers.
162  testNumHandlers(1);
163  testNumHandlers(2);
164 
165  // Test with exactly 5 handlers, as well as one fewer and one more, just
166  // to make sure we catch any corner cases.
167  testNumHandlers(4);
168  testNumHandlers(5);
169  testNumHandlers(6);
170 
171  // Test with significantly more than 5 handlers.
172  testNumHandlers(15);
173 }
static struct message messages[5]
Definition: test.c:75
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
FOLLY_NOINLINE void foo2()
#define SCOPED_TRACE(message)
Definition: gtest.h:2115
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
#define FB_LOG(logger, level,...)
Definition: Logger.h:34
void handler(int, siginfo_t *, void *)
void testNumHandlers(size_t numHandlers)
constexpr LogLevel kDefaultLogLevel
Definition: LogLevel.h:102
const char * string
Definition: Conv.cpp:212
TEST(SequencedExecutor, CPUThreadPoolExecutor)
constexpr detail::First first
Definition: Base-inl.h:2553