2 * Copyright 2004-present Facebook, Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 #include <folly/experimental/logging/LogCategory.h>
17 #include <folly/experimental/logging/LogHandler.h>
18 #include <folly/experimental/logging/LogMessage.h>
19 #include <folly/experimental/logging/LoggerDB.h>
20 #include <folly/experimental/logging/test/TestLogHandler.h>
21 #include <folly/experimental/logging/test/XlogHeader1.h>
22 #include <folly/experimental/logging/test/XlogHeader2.h>
23 #include <folly/experimental/logging/xlog.h>
24 #include <folly/portability/GTest.h>
25 #include <folly/test/TestUtils.h>
27 using namespace folly;
28 using std::make_shared;
30 XLOG_SET_CATEGORY_NAME("xlog_test.main_file");
32 // Note that the XLOG* macros always use the main LoggerDB singleton.
33 // There is no way to get them to use a test LoggerDB during unit tests.
35 // Therefore any configuration we do here affects the main log category
36 // settings for the entire program. Fortunately all of the other unit tests do
37 // use testing LoggerDB objects.
39 TEST(Xlog, xlogName) {
40 EXPECT_EQ("xlog_test.main_file", XLOG_GET_CATEGORY_NAME());
41 EXPECT_EQ("xlog_test.main_file", XLOG_GET_CATEGORY()->getName());
45 auto handler = make_shared<TestLogHandler>();
46 LoggerDB::get()->getCategory("xlog_test")->addHandler(handler);
47 auto& messages = handler->getMessages();
49 // info messages are not enabled initially.
50 EXPECT_FALSE(XLOG_IS_ON(INFO));
51 EXPECT_TRUE(XLOG_IS_ON(ERR));
52 XLOG(INFO, "testing 1");
53 EXPECT_EQ(0, messages.size());
56 // Increase the log level, then log a message.
57 LoggerDB::get()->setLevel("xlog_test.main_file", LogLevel::DBG1);
59 XLOG(DBG1, "testing: ", 1, 2, 3);
60 ASSERT_EQ(1, messages.size());
61 EXPECT_EQ("testing: 123", messages[0].first.getMessage());
62 EXPECT_TRUE(messages[0].first.getFileName().endsWith("XlogTest.cpp"))
63 << "unexpected file name: " << messages[0].first.getFileName();
64 EXPECT_EQ(LogLevel::DBG1, messages[0].first.getLevel());
65 EXPECT_EQ("xlog_test.main_file", messages[0].first.getCategory()->getName());
66 EXPECT_EQ("xlog_test", messages[0].second->getName());
69 XLOGF(WARN, "number: {:>3d}; string: {}", 12, "foo");
70 ASSERT_EQ(1, messages.size());
71 EXPECT_EQ("number: 12; string: foo", messages[0].first.getMessage());
72 EXPECT_TRUE(messages[0].first.getFileName().endsWith("XlogTest.cpp"))
73 << "unexpected file name: " << messages[0].first.getFileName();
74 EXPECT_EQ(LogLevel::WARN, messages[0].first.getLevel());
75 EXPECT_EQ("xlog_test.main_file", messages[0].first.getCategory()->getName());
76 EXPECT_EQ("xlog_test", messages[0].second->getName());
79 XLOG(DBG2, "this log check should not pass");
80 EXPECT_EQ(0, messages.size());
83 // Test stream arguments to XLOG()
84 XLOG(INFO) << "stream test: " << 1 << ", two, " << 3;
85 ASSERT_EQ(1, messages.size());
86 EXPECT_EQ("stream test: 1, two, 3", messages[0].first.getMessage());
87 EXPECT_TRUE(messages[0].first.getFileName().endsWith("XlogTest.cpp"))
88 << "unexpected file name: " << messages[0].first.getFileName();
89 EXPECT_EQ(LogLevel::INFO, messages[0].first.getLevel());
90 EXPECT_EQ("xlog_test.main_file", messages[0].first.getCategory()->getName());
91 EXPECT_EQ("xlog_test", messages[0].second->getName());
95 TEST(Xlog, perFileCategoryHandling) {
96 using namespace logging_test;
98 auto handler = make_shared<TestLogHandler>();
100 ->getCategory("folly.experimental.logging.test")
101 ->addHandler(handler);
102 LoggerDB::get()->setLevel("folly.experimental.logging.test", LogLevel::DBG9);
103 auto& messages = handler->getMessages();
105 // Use the simple helper function in XlogHeader2
106 testXlogHdrFunction("factor", 99);
107 ASSERT_EQ(1, messages.size());
108 EXPECT_EQ("test: factor=99", messages[0].first.getMessage());
109 EXPECT_TRUE(messages[0].first.getFileName().endsWith("XlogHeader2.h"))
110 << "unexpected file name: " << messages[0].first.getFileName();
111 EXPECT_EQ(LogLevel::DBG3, messages[0].first.getLevel());
113 "folly.experimental.logging.test.XlogHeader2",
114 messages[0].first.getCategory()->getName());
115 EXPECT_EQ("folly.experimental.logging.test", messages[0].second->getName());
118 // Test the loop function from XlogHeader1
119 testXlogHdrLoop(3, "hello world");
120 ASSERT_EQ(5, messages.size());
121 EXPECT_EQ("starting: hello world", messages[0].first.getMessage());
122 EXPECT_TRUE(messages[0].first.getFileName().endsWith("XlogHeader1.h"))
123 << "unexpected file name: " << messages[0].first.getFileName();
124 EXPECT_EQ(LogLevel::DBG1, messages[0].first.getLevel());
126 "folly.experimental.logging.test.XlogHeader1",
127 messages[0].first.getCategory()->getName());
128 EXPECT_EQ("folly.experimental.logging.test", messages[0].second->getName());
130 EXPECT_EQ("test: hello world", messages[1].first.getMessage());
131 EXPECT_EQ("test: hello world", messages[2].first.getMessage());
132 EXPECT_EQ("test: hello world", messages[3].first.getMessage());
133 EXPECT_EQ("finished: hello world", messages[4].first.getMessage());
134 EXPECT_EQ(LogLevel::DBG5, messages[1].first.getLevel());
135 EXPECT_EQ(LogLevel::DBG5, messages[2].first.getLevel());
136 EXPECT_EQ(LogLevel::DBG5, messages[3].first.getLevel());
137 EXPECT_EQ(LogLevel::DBG1, messages[4].first.getLevel());
140 // Reduce the log level so that the messages inside the loop
141 // should not be logged.
142 LoggerDB::get()->setLevel("folly.experimental.logging.test", LogLevel::DBG2);
143 testXlogHdrLoop(300, "hello world");
144 ASSERT_EQ(2, messages.size());
145 EXPECT_EQ("starting: hello world", messages[0].first.getMessage());
146 EXPECT_EQ("finished: hello world", messages[1].first.getMessage());
149 // Call the helpers function in XlogFile1.cpp and XlogFile2.cpp and makes
150 // sure their categories are reported correctly.
151 testXlogFile1Dbg1("foobar 1234");
152 ASSERT_EQ(1, messages.size());
153 EXPECT_EQ("file1: foobar 1234", messages[0].first.getMessage());
155 "folly.experimental.logging.test.XlogFile1",
156 messages[0].first.getCategory()->getName());
159 testXlogFile2Dbg1("hello world");
160 ASSERT_EQ(1, messages.size());
161 EXPECT_EQ("file2: hello world", messages[0].first.getMessage());
163 "folly.experimental.logging.test.XlogFile2",
164 messages[0].first.getCategory()->getName());
167 // Adjust the log level and make sure the changes take effect for the .cpp
169 LoggerDB::get()->setLevel("folly.experimental.logging.test", LogLevel::INFO);
170 testXlogFile1Dbg1("log check should fail now");
171 testXlogFile2Dbg1("this should fail too");
172 EXPECT_EQ(0, messages.size());
175 LoggerDB::get()->setLevel(
176 "folly.experimental.logging.test.XlogFile1", LogLevel::DBG1);
177 testXlogFile1Dbg1("this log check should pass now");
178 testXlogFile2Dbg1("but this one should still fail");
179 ASSERT_EQ(1, messages.size());
181 "file1: this log check should pass now", messages[0].first.getMessage());
183 "folly.experimental.logging.test.XlogFile1",
184 messages[0].first.getCategory()->getName());