Changeset 221388 in webkit
- Timestamp:
- Aug 30, 2017 12:06:49 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/PAL/ChangeLog
r221381 r221388 1 2017-08-30 Eric Carlson <eric.carlson@apple.com> 2 3 Add Logger observer and helper class 4 https://bugs.webkit.org/show_bug.cgi?id=176106 5 6 Reviewed by Andy Estes. 7 8 * pal/Logger.h: 9 (PAL::LogArgument::toString): Add new variants. 10 (PAL::Logger::Observer::~Observer): 11 (PAL::Logger::logAlways const): Constify. 12 (PAL::Logger::error const): Ditto. 13 (PAL::Logger::warning const): Ditto. 14 (PAL::Logger::notice const): Ditto. 15 (PAL::Logger::info const): Ditto. 16 (PAL::Logger::debug const): Ditto. 17 (PAL::Logger::willLog const): Ditto. 18 (PAL::Logger::MethodAndPointer::MethodAndPointer): Add class name, make object pointer const. 19 (PAL::Logger::addObserver): New. 20 (PAL::Logger::removeObserver): New. 21 (PAL::Logger::Logger): 22 (PAL::Logger::log): 23 (PAL::Logger::observers): 24 (PAL::LogHelper::willLog const): 25 (PAL::LogArgument<Logger::MethodAndPointer>::toString): 26 1 27 2017-08-30 Andy Estes <aestes@apple.com> 2 28 -
trunk/Source/WebCore/PAL/pal/Logger.h
r221288 r221388 38 38 template<typename T> 39 39 struct LogArgument { 40 template<typename U = T> static typename std::enable_if<std::is_same<U, bool>::value, String>::type toString(bool argument) { return argument ? ASCIILiteral("true") : ASCIILiteral("false"); } 40 41 template<typename U = T> static typename std::enable_if<std::is_same<U, int>::value, String>::type toString(int argument) { return String::number(argument); } 41 42 template<typename U = T> static typename std::enable_if<std::is_same<U, float>::value, String>::type toString(float argument) { return String::number(argument); } 42 43 template<typename U = T> static typename std::enable_if<std::is_same<U, double>::value, String>::type toString(double argument) { return String::number(argument); } 43 template<typename U = T> static typename std::enable_if<std::is_same<U, String>::value, String>::type toString(String argument) { return argument; } 44 template<typename U = T> static typename std::enable_if<std::is_same<typename std::remove_reference<U>::type, AtomicString>::value, String>::type toString(AtomicString argument) { return argument.string(); } 45 template<typename U = T> static typename std::enable_if<std::is_same<typename std::remove_reference<U>::type, String>::value, String>::type toString(String argument) { return argument; } 44 46 template<typename U = T> static typename std::enable_if<std::is_same<U, const char*>::value, String>::type toString(const char* argument) { return String(argument); } 45 47 template<size_t length> static String toString(const char (&argument)[length]) { return String(argument); } … … 49 51 WTF_MAKE_NONCOPYABLE(Logger); 50 52 public: 53 54 class Observer { 55 public: 56 virtual ~Observer() { } 57 virtual void didLogMessage(const WTFLogChannel&, const String&) = 0; 58 }; 59 51 60 static Ref<Logger> create(const void* owner) 52 61 { … … 55 64 56 65 template<typename... Arguments> 57 inline void logAlways(WTFLogChannel& channel, const Arguments&... arguments) 66 inline void logAlways(WTFLogChannel& channel, const Arguments&... arguments) const 58 67 { 59 68 #if RELEASE_LOG_DISABLED … … 70 79 71 80 template<typename... Arguments> 72 inline void error(WTFLogChannel& channel, const Arguments&... arguments) 81 inline void error(WTFLogChannel& channel, const Arguments&... arguments) const 73 82 { 74 83 if (!willLog(channel, WTFLogLevelError)) … … 79 88 80 89 template<typename... Arguments> 81 inline void warning(WTFLogChannel& channel, const Arguments&... arguments) 90 inline void warning(WTFLogChannel& channel, const Arguments&... arguments) const 82 91 { 83 92 if (!willLog(channel, WTFLogLevelWarning)) … … 88 97 89 98 template<typename... Arguments> 90 inline void notice(WTFLogChannel& channel, const Arguments&... arguments) 99 inline void notice(WTFLogChannel& channel, const Arguments&... arguments) const 91 100 { 92 101 if (!willLog(channel, WTFLogLevelNotice)) … … 97 106 98 107 template<typename... Arguments> 99 inline void info(WTFLogChannel& channel, const Arguments&... arguments) 108 inline void info(WTFLogChannel& channel, const Arguments&... arguments) const 100 109 { 101 110 if (!willLog(channel, WTFLogLevelInfo)) … … 106 115 107 116 template<typename... Arguments> 108 inline void debug(WTFLogChannel& channel, const Arguments&... arguments) 117 inline void debug(WTFLogChannel& channel, const Arguments&... arguments) const 109 118 { 110 119 if (!willLog(channel, WTFLogLevelDebug)) … … 114 123 } 115 124 116 inline bool willLog( WTFLogChannel& channel, WTFLogLevel level) const125 inline bool willLog(const WTFLogChannel& channel, WTFLogLevel level) const 117 126 { 118 127 if (level != WTFLogLevelAlways && level > channel.level) … … 134 143 135 144 struct MethodAndPointer { 136 MethodAndPointer(const char* methodName, void* objectPtr)137 : methodName (methodName)138 , objectPtr (reinterpret_cast<uintptr_t>(objectPtr))145 MethodAndPointer(const char* methodName, const void* objectPtr) 146 : methodName { methodName } 147 , objectPtr { reinterpret_cast<uintptr_t>(objectPtr) } 139 148 { 140 149 } 141 150 142 const char* methodName; 143 uintptr_t objectPtr; 151 MethodAndPointer(const char* className, const char* methodName, const void* objectPtr) 152 : className { className } 153 , methodName { methodName } 154 , objectPtr { reinterpret_cast<uintptr_t>(objectPtr) } 155 { 156 } 157 158 const char* className { nullptr }; 159 const char* methodName { nullptr }; 160 const uintptr_t objectPtr { 0 }; 144 161 }; 145 162 163 static inline void addObserver(Observer& observer) 164 { 165 observers().append(observer); 166 } 167 static inline void removeObserver(Observer& observer) 168 { 169 observers().removeFirstMatching([&observer](auto anObserver) { 170 return &anObserver.get() == &observer; 171 }); 172 } 173 146 174 private: 147 Logger(const void* owner) { m_owner = owner; } 175 Logger(const void* owner) 176 : m_owner { owner } 177 { 178 } 148 179 149 180 template<typename... Argument> 150 181 static inline void log(WTFLogChannel& channel, const Argument&... arguments) 151 182 { 152 String string= makeString(LogArgument<Argument>::toString(arguments)...);183 String logMessage = makeString(LogArgument<Argument>::toString(arguments)...); 153 184 154 185 #if RELEASE_LOG_DISABLED 155 WTFLog(&channel, "%s", string.utf8().data());186 WTFLog(&channel, "%s", logMessage.utf8().data()); 156 187 #else 157 os_log(channel.osLogChannel, "%{public}s", string.utf8().data());188 os_log(channel.osLogChannel, "%{public}s", logMessage.utf8().data()); 158 189 #endif 190 191 for (Observer& observer : observers()) 192 observer.didLogMessage(channel, logMessage); 193 } 194 195 static Vector<std::reference_wrapper<Observer>>& observers() 196 { 197 static NeverDestroyed<Vector<std::reference_wrapper<Observer>>> observers; 198 return observers; 159 199 } 160 200 161 201 const void* m_owner; 162 202 bool m_enabled { true }; 203 }; 204 205 class LogHelper { 206 public: 207 virtual ~LogHelper() = default; 208 209 virtual const Logger& logger() const = 0; 210 virtual const char* className() const = 0; 211 virtual WTFLogChannel& logChannel() const = 0; 212 213 inline bool willLog(WTFLogLevel level) const { return logger().willLog(logChannel(), level); } 214 215 #define ALWAYS_LOG(...) logger().logAlways(logChannel(), Logger::MethodAndPointer(className(), __func__, this), ##__VA_ARGS__) 216 #define ERROR_LOG(...) logger().error(logChannel(), Logger::MethodAndPointer(className(), __func__, this), ##__VA_ARGS__) 217 #define WARNING_LOG(...) logger().warning(logChannel(), Logger::MethodAndPointer(className(), __func__, this), ##__VA_ARGS__) 218 #define NOTICE_LOG(...) logger().notice(logChannel(), Logger::MethodAndPointer(className(), __func__, this), ##__VA_ARGS__) 219 #define INFO_LOG(...) logger().info(logChannel(), Logger::MethodAndPointer(className(), __func__, this), ##__VA_ARGS__) 220 #define DEBUG_LOG(...) logger().debug(logChannel(), Logger::MethodAndPointer(className(), __func__, this), ##__VA_ARGS__) 221 163 222 }; 164 223 … … 168 227 { 169 228 StringBuilder builder; 229 230 if (value.className) { 231 builder.append(value.className); 232 builder.appendLiteral("::"); 233 } 170 234 builder.append(value.methodName); 171 235 builder.appendLiteral("(0x"); … … 177 241 178 242 } // namespace PAL 179 -
trunk/Tools/ChangeLog
r221380 r221388 1 2017-08-30 Eric Carlson <eric.carlson@apple.com> 2 3 Add Logger observer and helper class 4 https://bugs.webkit.org/show_bug.cgi?id=176106 5 6 Reviewed by Andy Estes. 7 8 * TestWebKitAPI/Tests/WebCore/Logging.cpp: 9 (TestWebKitAPI::LoggingTest::LoggingTest): 10 (TestWebKitAPI::LoggingTest::Logger::create): 11 (TestWebKitAPI::TEST_F): 12 (TestWebKitAPI::LogObserver::log): 13 (TestWebKitAPI::LogObserver::channel const): 14 1 15 2017-08-29 Filip Pizlo <fpizlo@apple.com> 2 16 -
trunk/Tools/TestWebKitAPI/Tests/WebCore/Logging.cpp
r221288 r221388 56 56 namespace TestWebKitAPI { 57 57 58 class LoggingTest : public testing::Test {58 class LoggingTest : public testing::Test, public LogHelper { 59 59 public: 60 LoggingTest() 61 : m_logger { Logger::create(this) } 62 { 63 } 64 60 65 void SetUp() final 61 66 { … … 95 100 } 96 101 102 const Logger& logger() const final { return m_logger.get(); } 103 const char* className() const final { return "LoggingTest"; } 104 WTFLogChannel& logChannel() const final { return TestChannel1; } 105 97 106 private: 107 108 Ref<Logger> m_logger; 98 109 int m_descriptors[2]; 99 110 FILE* m_stderr; … … 268 279 269 280 WTFSetLogChannelLevel(&TestChannel1, WTFLogLevelError); 281 EXPECT_TRUE(logger->willLog(TestChannel1, WTFLogLevelError)); 270 282 logger->error(TestChannel1, "You're using coconuts!"); 271 283 EXPECT_TRUE(output().contains("You're using coconuts!", false)); … … 303 315 304 316 logger->setEnabled(this, false); 317 EXPECT_FALSE(logger->willLog(TestChannel1, WTFLogLevelError)); 318 EXPECT_FALSE(logger->willLog(TestChannel1, WTFLogLevelWarning)); 319 EXPECT_FALSE(logger->willLog(TestChannel1, WTFLogLevelNotice)); 320 EXPECT_FALSE(logger->willLog(TestChannel1, WTFLogLevelInfo)); 321 EXPECT_FALSE(logger->willLog(TestChannel1, WTFLogLevelDebug)); 305 322 EXPECT_FALSE(logger->enabled()); 306 323 logger->logAlways(TestChannel1, "You've got two empty halves of coconuts"); 307 324 EXPECT_EQ(0u, output().length()); 308 } 325 326 logger->setEnabled(this, true); 327 AtomicString string1("AtomicString", AtomicString::ConstructFromLiteral); 328 const AtomicString string2("const AtomicString", AtomicString::ConstructFromLiteral); 329 logger->logAlways(TestChannel1, string1, " and ", string2); 330 EXPECT_TRUE(output().contains("AtomicString and const AtomicString", false)); 331 332 String string3("String"); 333 const String string4("const String"); 334 logger->logAlways(TestChannel1, string3, " and ", string4); 335 EXPECT_TRUE(output().contains("String and const String", false)); 336 } 337 338 TEST_F(LoggingTest, LogHelper) 339 { 340 EXPECT_TRUE(logger().enabled()); 341 342 StringBuilder builder; 343 builder.appendLiteral("LoggingTest::TestBody(0x"); 344 appendUnsigned64AsHex(reinterpret_cast<uintptr_t>(this), builder); 345 builder.appendLiteral(")"); 346 String signature = builder.toString(); 347 348 ALWAYS_LOG(); 349 EXPECT_TRUE(this->output().contains(signature, false)); 350 351 ALWAYS_LOG("Welcome back", " my friends", " to the show", " that never ends"); 352 String result = this->output(); 353 EXPECT_TRUE(result.contains(signature, false)); 354 EXPECT_TRUE(result.contains("to the show that never", false)); 355 356 WTFSetLogChannelLevel(&TestChannel1, WTFLogLevelWarning); 357 EXPECT_TRUE(willLog(WTFLogLevelWarning)); 358 359 ERROR_LOG("We're so glad you could attend"); 360 EXPECT_TRUE(output().contains("We're so glad you could attend", false)); 361 362 WARNING_LOG("Come inside! ", "Come inside!"); 363 EXPECT_TRUE(output().contains("Come inside! Come inside!", false)); 364 365 NOTICE_LOG("There behind a glass is a real blade of grass"); 366 EXPECT_EQ(0u, output().length()); 367 368 INFO_LOG("be careful as you pass."); 369 EXPECT_EQ(0u, output().length()); 370 371 DEBUG_LOG("Move along! Move along!"); 372 EXPECT_EQ(0u, output().length()); 373 } 374 375 class LogObserver : public Logger::Observer { 376 public: 377 LogObserver() = default; 378 379 String log() 380 { 381 String log = m_logBuffer.toString(); 382 m_logBuffer.clear(); 383 384 return log; 385 } 386 387 WTFLogChannel channel() const { return m_lastChannel; } 388 389 private: 390 void didLogMessage(const WTFLogChannel& channel, const String& logMessage) final 391 { 392 m_logBuffer.append(logMessage); 393 m_lastChannel = channel; 394 } 395 396 StringBuilder m_logBuffer; 397 WTFLogChannel m_lastChannel; 398 }; 399 400 TEST_F(LoggingTest, LogObserver) 401 { 402 LogObserver observer; 403 404 EXPECT_TRUE(logger().enabled()); 405 406 logger().addObserver(observer); 407 ALWAYS_LOG("testing 1, 2, 3"); 408 EXPECT_TRUE(this->output().contains("testing 1, 2, 3", false)); 409 EXPECT_TRUE(observer.log().contains("testing 1, 2, 3", false)); 410 EXPECT_STREQ(observer.channel().name, logChannel().name); 411 412 logger().removeObserver(observer); 413 ALWAYS_LOG("testing ", 1, ", ", 2, ", 3"); 414 EXPECT_TRUE(this->output().contains("testing 1, 2, 3", false)); 415 EXPECT_EQ(0u, observer.log().length()); 416 } 417 309 418 #endif 310 419
Note: See TracChangeset
for help on using the changeset viewer.