From 47f0c97f8e7ec27dc371f05fdcab460373521920 Mon Sep 17 00:00:00 2001 From: Marian Krivos Date: Mon, 22 Aug 2011 17:08:27 +0000 Subject: [PATCH] trunk/branch integration: Logger() --- Foundation/include/Poco/Logger.h | 281 ++++++++++++++++++++++++++++++- 1 file changed, 272 insertions(+), 9 deletions(-) diff --git a/Foundation/include/Poco/Logger.h b/Foundation/include/Poco/Logger.h index f48b461da..721e247aa 100644 --- a/Foundation/include/Poco/Logger.h +++ b/Foundation/include/Poco/Logger.h @@ -9,7 +9,7 @@ // // Definition of the Logger class. // -// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// Copyright (c) 2004-2010, Applied Informatics Software Engineering GmbH. // and Contributors. // // Permission is hereby granted, free of charge, to any person or organization @@ -43,6 +43,7 @@ #include "Poco/Foundation.h" #include "Poco/Channel.h" #include "Poco/Message.h" +#include "Poco/Format.h" #include #include #include @@ -85,6 +86,19 @@ class Foundation_API Logger: public Channel /// set up at application startup and never changed afterwards. Nevertheless, /// there are methods to simultaneously change the level and channel of all /// loggers in a certain hierarchy. + /// + /// There are also convenience macros available that wrap the actual + /// logging statement into a check whether the Logger's log level + /// is sufficient to actually log the message. This allows to increase + /// the application performance if many complex log statements + /// are used. The macros also add the source file path and line + /// number into the log message so that it is available to formatters. + /// Variants of these macros that allow message formatting with Poco::format() + /// are also available. Up to four arguments are supported. + /// + /// Examples: + /// poco_warning(logger, "This is a warning"); + /// poco_information_f2(logger, "An informational message with args: %d, %d", 1, 2); { public: const std::string& name() const; @@ -129,6 +143,13 @@ public: void log(const Exception& exc); /// Logs the given exception with priority PRIO_ERROR. + + void log(const Exception& exc, const char* file, int line); + /// Logs the given exception with priority PRIO_ERROR. + /// + /// File must be a static string, such as the value of + /// the __FILE__ macro. The string is not copied + /// internally for performance reasons. void fatal(const std::string& msg); /// If the Logger's log level is at least PRIO_FATAL, @@ -136,47 +157,127 @@ public: /// and the given message text and sends it /// to the attached channel. + void fatal(const std::string& msg, const char* file, int line); + /// If the Logger's log level is at least PRIO_FATAL, + /// creates a Message with priority PRIO_FATAL + /// and the given message text and sends it + /// to the attached channel. + /// + /// File must be a static string, such as the value of + /// the __FILE__ macro. The string is not copied + /// internally for performance reasons. + void critical(const std::string& msg); /// If the Logger's log level is at least PRIO_CRITICAL, /// creates a Message with priority PRIO_CRITICAL /// and the given message text and sends it /// to the attached channel. + void critical(const std::string& msg, const char* file, int line); + /// If the Logger's log level is at least PRIO_CRITICAL, + /// creates a Message with priority PRIO_CRITICAL + /// and the given message text and sends it + /// to the attached channel. + /// + /// File must be a static string, such as the value of + /// the __FILE__ macro. The string is not copied + /// internally for performance reasons. + void error(const std::string& msg); /// If the Logger's log level is at least PRIO_ERROR, /// creates a Message with priority PRIO_ERROR /// and the given message text and sends it /// to the attached channel. + void error(const std::string& msg, const char* file, int line); + /// If the Logger's log level is at least PRIO_ERROR, + /// creates a Message with priority PRIO_ERROR + /// and the given message text and sends it + /// to the attached channel. + /// + /// File must be a static string, such as the value of + /// the __FILE__ macro. The string is not copied + /// internally for performance reasons. + void warning(const std::string& msg); /// If the Logger's log level is at least PRIO_WARNING, /// creates a Message with priority PRIO_WARNING /// and the given message text and sends it /// to the attached channel. + void warning(const std::string& msg, const char* file, int line); + /// If the Logger's log level is at least PRIO_WARNING, + /// creates a Message with priority PRIO_WARNING + /// and the given message text and sends it + /// to the attached channel. + /// + /// File must be a static string, such as the value of + /// the __FILE__ macro. The string is not copied + /// internally for performance reasons. + void notice(const std::string& msg); /// If the Logger's log level is at least PRIO_NOTICE, /// creates a Message with priority PRIO_NOTICE /// and the given message text and sends it /// to the attached channel. + void notice(const std::string& msg, const char* file, int line); + /// If the Logger's log level is at least PRIO_NOTICE, + /// creates a Message with priority PRIO_NOTICE + /// and the given message text and sends it + /// to the attached channel. + /// + /// File must be a static string, such as the value of + /// the __FILE__ macro. The string is not copied + /// internally for performance reasons. + void information(const std::string& msg); /// If the Logger's log level is at least PRIO_INFORMATION, /// creates a Message with priority PRIO_INFORMATION /// and the given message text and sends it /// to the attached channel. + void information(const std::string& msg, const char* file, int line); + /// If the Logger's log level is at least PRIO_INFORMATION, + /// creates a Message with priority PRIO_INFORMATION + /// and the given message text and sends it + /// to the attached channel. + /// + /// File must be a static string, such as the value of + /// the __FILE__ macro. The string is not copied + /// internally for performance reasons. + void debug(const std::string& msg); /// If the Logger's log level is at least PRIO_DEBUG, /// creates a Message with priority PRIO_DEBUG /// and the given message text and sends it /// to the attached channel. + void debug(const std::string& msg, const char* file, int line); + /// If the Logger's log level is at least PRIO_DEBUG, + /// creates a Message with priority PRIO_DEBUG + /// and the given message text and sends it + /// to the attached channel. + /// + /// File must be a static string, such as the value of + /// the __FILE__ macro. The string is not copied + /// internally for performance reasons. + void trace(const std::string& msg); /// If the Logger's log level is at least PRIO_TRACE, /// creates a Message with priority PRIO_TRACE /// and the given message text and sends it /// to the attached channel. + + void trace(const std::string& msg, const char* file, int line); + /// If the Logger's log level is at least PRIO_TRACE, + /// creates a Message with priority PRIO_TRACE + /// and the given message text and sends it + /// to the attached channel. + /// + /// File must be a static string, such as the value of + /// the __FILE__ macro. The string is not copied + /// internally for performance reasons. void dump(const std::string& msg, const void* buffer, std::size_t length, Message::Priority prio = Message::PRIO_DEBUG); /// Logs the given message, followed by the data in buffer. @@ -298,6 +399,7 @@ protected: ~Logger(); void log(const std::string& text, Message::Priority prio); + void log(const std::string& text, Message::Priority prio, const char* file, int line); static std::string format(const std::string& fmt, int argc, std::string argv[]); static void formatDump(std::string& message, const void* buffer, std::size_t length); @@ -323,32 +425,136 @@ private: // convenience macros // #define poco_fatal(logger, msg) \ - if ((logger).fatal()) (logger).fatal(msg); else (void) 0 + if ((logger).fatal()) (logger).fatal(msg, __FILE__, __LINE__); else (void) 0 + +#define poco_fatal_f1(logger, fmt, arg1) \ + if ((logger).fatal()) (logger).fatal(Poco::format((fmt), arg1), __FILE__, __LINE__); else (void) 0 + +#define poco_fatal_f2(logger, fmt, arg1, arg2) \ + if ((logger).fatal()) (logger).fatal(Poco::format((fmt), (arg1), (arg2)), __FILE__, __LINE__); else (void) 0 + +#define poco_fatal_f3(logger, fmt, arg1, arg2, arg3) \ + if ((logger).fatal()) (logger).fatal(Poco::format((fmt), (arg1), (arg2), (arg3)), __FILE__, __LINE__); else (void) 0 + +#define poco_fatal_f4(logger, fmt, arg1, arg2, arg3, arg4) \ + if ((logger).fatal()) (logger).fatal(Poco::format((fmt), (arg1), (arg2), (arg3), (arg4)), __FILE__, __LINE__); else (void) 0 #define poco_critical(logger, msg) \ - if ((logger).critical()) (logger).critical(msg); else (void) 0 + if ((logger).critical()) (logger).critical(msg, __FILE__, __LINE__); else (void) 0 + +#define poco_critical_f1(logger, fmt, arg1) \ + if ((logger).critical()) (logger).critical(Poco::format((fmt), (arg1)), __FILE__, __LINE__); else (void) 0 + +#define poco_critical_f2(logger, fmt, arg1, arg2) \ + if ((logger).critical()) (logger).critical(Poco::format((fmt), (arg1), (arg2)), __FILE__, __LINE__); else (void) 0 + +#define poco_critical_f3(logger, fmt, arg1, arg2, arg3) \ + if ((logger).critical()) (logger).critical(Poco::format((fmt), (arg1), (arg2), (arg3)), __FILE__, __LINE__); else (void) 0 + +#define poco_critical_f4(logger, fmt, arg1, arg2, arg3, arg4) \ + if ((logger).critical()) (logger).critical(Poco::format((fmt), (arg1), (arg2), (arg3), (arg4)), __FILE__, __LINE__); else (void) 0 #define poco_error(logger, msg) \ - if ((logger).error()) (logger).error(msg); else (void) 0 + if ((logger).error()) (logger).error(msg, __FILE__, __LINE__); else (void) 0 + +#define poco_error_f1(logger, fmt, arg1) \ + if ((logger).error()) (logger).error(Poco::format((fmt), (arg1)), __FILE__, __LINE__); else (void) 0 + +#define poco_error_f2(logger, fmt, arg1, arg2) \ + if ((logger).error()) (logger).error(Poco::format((fmt), (arg1), (arg2)), __FILE__, __LINE__); else (void) 0 + +#define poco_error_f3(logger, fmt, arg1, arg2, arg3) \ + if ((logger).error()) (logger).error(Poco::format((fmt), (arg1), (arg2), (arg3)), __FILE__, __LINE__); else (void) 0 + +#define poco_error_f4(logger, fmt, arg1, arg2, arg3, arg4) \ + if ((logger).error()) (logger).error(Poco::format((fmt), (arg1), (arg2), (arg3), (arg4)), __FILE__, __LINE__); else (void) 0 #define poco_warning(logger, msg) \ - if ((logger).warning()) (logger).warning(msg); else (void) 0 + if ((logger).warning()) (logger).warning(msg, __FILE__, __LINE__); else (void) 0 + +#define poco_warning_f1(logger, fmt, arg1) \ + if ((logger).warning()) (logger).warning(Poco::format((fmt), (arg1)), __FILE__, __LINE__); else (void) 0 + +#define poco_warning_f2(logger, fmt, arg1, arg2) \ + if ((logger).warning()) (logger).warning(Poco::format((fmt), (arg1), (arg2)), __FILE__, __LINE__); else (void) 0 + +#define poco_warning_f3(logger, fmt, arg1, arg2, arg3) \ + if ((logger).warning()) (logger).warning(Poco::format((fmt), (arg1), (arg2), (arg3)), __FILE__, __LINE__); else (void) 0 + +#define poco_warning_f4(logger, fmt, arg1, arg2, arg3, arg4) \ + if ((logger).warning()) (logger).warning(Poco::format((fmt), (arg1), (arg2), (arg3), (arg4)), __FILE__, __LINE__); else (void) 0 #define poco_notice(logger, msg) \ - if ((logger).notice()) (logger).notice(msg); else (void) 0 + if ((logger).notice()) (logger).notice(msg, __FILE__, __LINE__); else (void) 0 + +#define poco_notice_f1(logger, fmt, arg1) \ + if ((logger).notice()) (logger).notice(Poco::format((fmt), (arg1)), __FILE__, __LINE__); else (void) 0 + +#define poco_notice_f2(logger, fmt, arg1, arg2) \ + if ((logger).notice()) (logger).notice(Poco::format((fmt), (arg1), (arg2)), __FILE__, __LINE__); else (void) 0 + +#define poco_notice_f3(logger, fmt, arg1, arg2, arg3) \ + if ((logger).notice()) (logger).notice(Poco::format((fmt), (arg1), (arg2), (arg3)), __FILE__, __LINE__); else (void) 0 + +#define poco_notice_f4(logger, fmt, arg1, arg2, arg3, arg4) \ + if ((logger).notice()) (logger).notice(Poco::format((fmt), (arg1), (arg2), (arg3), (arg4)), __FILE__, __LINE__); else (void) 0 #define poco_information(logger, msg) \ - if ((logger).information()) (logger).information(msg); else (void) 0 + if ((logger).information()) (logger).information(msg, __FILE__, __LINE__); else (void) 0 + +#define poco_information_f1(logger, fmt, arg1) \ + if ((logger).information()) (logger).information(Poco::format((fmt), (arg1)), __FILE__, __LINE__); else (void) 0 + +#define poco_information_f2(logger, fmt, arg1, arg2) \ + if ((logger).information()) (logger).information(Poco::format((fmt), (arg1), (arg2)), __FILE__, __LINE__); else (void) 0 + +#define poco_information_f3(logger, fmt, arg1, arg2, arg3) \ + if ((logger).information()) (logger).information(Poco::format((fmt), (arg1), (arg2), (arg3)), __FILE__, __LINE__); else (void) 0 + +#define poco_information_f4(logger, fmt, arg1, arg2, arg3, arg4) \ + if ((logger).information()) (logger).information(Poco::format((fmt), (arg1), (arg2), (arg3), (arg4)), __FILE__, __LINE__); else (void) 0 #if defined(_DEBUG) #define poco_debug(logger, msg) \ - if ((logger).debug()) (logger).debug(msg); else (void) 0 + if ((logger).debug()) (logger).debug(msg, __FILE__, __LINE__); else (void) 0 + + #define poco_debug_f1(logger, fmt, arg1) \ + if ((logger).debug()) (logger).debug(Poco::format((fmt), (arg1)), __FILE__, __LINE__); else (void) 0 + + #define poco_debug_f2(logger, fmt, arg1, arg2) \ + if ((logger).debug()) (logger).debug(Poco::format((fmt), (arg1), (arg2)), __FILE__, __LINE__); else (void) 0 + + #define poco_debug_f3(logger, fmt, arg1, arg2, arg3) \ + if ((logger).debug()) (logger).debug(Poco::format((fmt), (arg1), (arg2), (arg3)), __FILE__, __LINE__); else (void) 0 + + #define poco_debug_f4(logger, fmt, arg1, arg2, arg3, arg4) \ + if ((logger).debug()) (logger).debug(Poco::format((fmt), (arg1), (arg2), (arg3), (arg4)), __FILE__, __LINE__); else (void) 0 #define poco_trace(logger, msg) \ - if ((logger).trace()) (logger).trace(msg); else (void) 0 + if ((logger).trace()) (logger).trace(msg, __FILE__, __LINE__); else (void) 0 + + #define poco_trace_f1(logger, fmt, arg1) \ + if ((logger).trace()) (logger).trace(Poco::format((fmt), (arg1)), __FILE__, __LINE__); else (void) 0 + + #define poco_trace_f2(logger, fmt, arg1, arg2) \ + if ((logger).trace()) (logger).trace(Poco::format((fmt), (arg1), (arg2)), __FILE__, __LINE__); else (void) 0 + + #define poco_trace_f3(logger, fmt, arg1, arg2, arg3) \ + if ((logger).trace()) (logger).trace(Poco::format((fmt), (arg1), (arg2), (arg3)), __FILE__, __LINE__); else (void) 0 + + #define poco_trace_f4(logger, fmt, arg1, arg2, arg3, arg4) \ + if ((logger).trace()) (logger).trace(Poco::format((fmt), (arg1), (arg2), (arg3), (arg4)), __FILE__, __LINE__); else (void) 0 #else #define poco_debug(logger, msg) + #define poco_debug_f1(logger, fmt, arg1) + #define poco_debug_f2(logger, fmt, arg1, arg2) + #define poco_debug_f3(logger, fmt, arg1, arg2, arg3) + #define poco_debug_f4(logger, fmt, arg1, arg2, arg3, arg4) #define poco_trace(logger, msg) + #define poco_trace_f1(logger, fmt, arg1) + #define poco_trace_f2(logger, fmt, arg1, arg2) + #define poco_trace_f3(logger, fmt, arg1, arg2, arg3) + #define poco_trace_f4(logger, fmt, arg1, arg2, arg3, arg4) #endif @@ -376,54 +582,111 @@ inline void Logger::log(const std::string& text, Message::Priority prio) } +inline void Logger::log(const std::string& text, Message::Priority prio, const char* file, int line) +{ + if (_level >= prio && _pChannel) + { + _pChannel->log(Message(_name, text, prio, file, line)); + } +} + + inline void Logger::fatal(const std::string& msg) { log(msg, Message::PRIO_FATAL); } +inline void Logger::fatal(const std::string& msg, const char* file, int line) +{ + log(msg, Message::PRIO_FATAL, file, line); +} + + inline void Logger::critical(const std::string& msg) { log(msg, Message::PRIO_CRITICAL); } +inline void Logger::critical(const std::string& msg, const char* file, int line) +{ + log(msg, Message::PRIO_CRITICAL, file, line); +} + + inline void Logger::error(const std::string& msg) { log(msg, Message::PRIO_ERROR); } +inline void Logger::error(const std::string& msg, const char* file, int line) +{ + log(msg, Message::PRIO_ERROR, file, line); +} + + inline void Logger::warning(const std::string& msg) { log(msg, Message::PRIO_WARNING); } +inline void Logger::warning(const std::string& msg, const char* file, int line) +{ + log(msg, Message::PRIO_WARNING, file, line); +} + + inline void Logger::notice(const std::string& msg) { log(msg, Message::PRIO_NOTICE); } +inline void Logger::notice(const std::string& msg, const char* file, int line) +{ + log(msg, Message::PRIO_NOTICE, file, line); +} + + inline void Logger::information(const std::string& msg) { log(msg, Message::PRIO_INFORMATION); } +inline void Logger::information(const std::string& msg, const char* file, int line) +{ + log(msg, Message::PRIO_INFORMATION, file, line); +} + + inline void Logger::debug(const std::string& msg) { log(msg, Message::PRIO_DEBUG); } +inline void Logger::debug(const std::string& msg, const char* file, int line) +{ + log(msg, Message::PRIO_DEBUG, file, line); +} + + inline void Logger::trace(const std::string& msg) { log(msg, Message::PRIO_TRACE); } +inline void Logger::trace(const std::string& msg, const char* file, int line) +{ + log(msg, Message::PRIO_TRACE, file, line); +} + + inline bool Logger::is(int level) const { return _level >= level;