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/printf.h>
17 #include <folly/experimental/logging/test/TestLogHandler.h>
18 #include <folly/portability/GTest.h>
20 using namespace folly;
21 using std::make_shared;
23 TEST(PrintfTest, printfStyleMacros) {
24 LoggerDB db{LoggerDB::TESTING};
25 Logger logger{&db, "test"};
26 auto* category = logger.getCategory();
28 auto handler = make_shared<TestLogHandler>();
29 category->addHandler(handler);
30 category->setLevel(LogLevel::DBG, true);
32 Logger foo{&db, "test.foo.bar"};
33 Logger foobar{&db, "test.foo.bar"};
34 Logger footest{&db, "test.foo.test"};
35 Logger footest1234{&db, "test.foo.test.1234"};
36 Logger other{&db, "test.other"};
37 db.setLevel("test", LogLevel::ERR);
38 db.setLevel("test.foo", LogLevel::DBG2);
39 db.setLevel("test.foo.test", LogLevel::DBG7);
41 auto& messages = handler->getMessages();
43 // test.other's effective level should be ERR, so a warning
44 // message to it should be discarded
45 FB_LOGC(other, WARN, "this should be discarded: %d", 5);
46 ASSERT_EQ(0, messages.size());
48 // Disabled log messages should not evaluate their arguments
49 bool argumentEvaluated = false;
51 argumentEvaluated = true;
54 FB_LOGC(foobar, DBG3, "discarded message: %d", getValue());
55 EXPECT_FALSE(argumentEvaluated);
57 FB_LOGC(foobar, DBG1, "this message should pass: %d", getValue());
58 ASSERT_EQ(1, messages.size());
59 EXPECT_EQ("this message should pass: 5", messages[0].first.getMessage());
60 EXPECT_TRUE(argumentEvaluated);
63 // The FB_LOGC() macro should work even if the format string does not contain
64 // any format sequences. Ideally people would just use FB_LOG() if they
65 // aren't actually formatting anything, but making FB_LOGC() work in this
66 // scenario still makes it easier for people to switch legacy printf-style
68 FB_LOGC(foobar, DBG1, "no actual format arguments");
69 ASSERT_EQ(1, messages.size());
70 EXPECT_EQ("no actual format arguments", messages[0].first.getMessage());
73 // Similar checks with XLOGC()
74 auto* xlogCategory = XLOG_GET_CATEGORY();
75 xlogCategory->addHandler(handler);
76 xlogCategory->setLevel(LogLevel::DBG5, true);
78 argumentEvaluated = false;
79 XLOGC(DBG9, "failing log check: %d", getValue());
80 EXPECT_FALSE(argumentEvaluated);
82 XLOGC(DBG5, "passing log: %03d", getValue());
83 ASSERT_EQ(1, messages.size());
84 EXPECT_EQ("passing log: 005", messages[0].first.getMessage());
85 EXPECT_TRUE(argumentEvaluated);
88 XLOGC(DBG1, "no xlog format arguments");
89 ASSERT_EQ(1, messages.size());
90 EXPECT_EQ("no xlog format arguments", messages[0].first.getMessage());
93 // Errors attempting to format the message should not throw
94 FB_LOGC(footest1234, ERR, "width overflow: %999999999999999999999d", 5);
95 ASSERT_EQ(1, messages.size());
97 "error formatting printf-style log message: "
98 "width overflow: %999999999999999999999d",
99 messages[0].first.getMessage());