diff options
| author | Charles E. Rolke <chug@apache.org> | 2012-06-11 20:53:47 +0000 |
|---|---|---|
| committer | Charles E. Rolke <chug@apache.org> | 2012-06-11 20:53:47 +0000 |
| commit | 35f30ce23af989b23b57a50f2c4b97bf486b1d64 (patch) | |
| tree | 73a844c4a53d4873cb15cd661f9a3880823220ab /qpid/cpp/include | |
| parent | a72e355e7458497c0f993e1259e09167af113f01 (diff) | |
| download | qpid-python-35f30ce23af989b23b57a50f2c4b97bf486b1d64.tar.gz | |
QPID-3902 C++ Broker add log categories
svn merge --reintegrate from branch qpid/branches/qpid-3902/qpid
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1349006 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/cpp/include')
| -rw-r--r-- | qpid/cpp/include/qpid/log/Logger.h | 2 | ||||
| -rw-r--r-- | qpid/cpp/include/qpid/log/Options.h | 2 | ||||
| -rw-r--r-- | qpid/cpp/include/qpid/log/Selector.h | 27 | ||||
| -rw-r--r-- | qpid/cpp/include/qpid/log/Statement.h | 166 |
4 files changed, 189 insertions, 8 deletions
diff --git a/qpid/cpp/include/qpid/log/Logger.h b/qpid/cpp/include/qpid/log/Logger.h index d255b7e150..9464fa52dd 100644 --- a/qpid/cpp/include/qpid/log/Logger.h +++ b/qpid/cpp/include/qpid/log/Logger.h @@ -36,7 +36,7 @@ namespace log { class QPID_COMMON_CLASS_EXTERN Logger : private boost::noncopyable { public: /** Flags indicating what to include in the log output */ - enum FormatFlag { FILE=1, LINE=2, FUNCTION=4, LEVEL=8, TIME=16, THREAD=32, HIRES=64}; + enum FormatFlag { FILE=1, LINE=2, FUNCTION=4, LEVEL=8, TIME=16, THREAD=32, HIRES=64, CATEGORY=128}; /** * Logging output sink. diff --git a/qpid/cpp/include/qpid/log/Options.h b/qpid/cpp/include/qpid/log/Options.h index 17cbfde9bc..819f2c85f1 100644 --- a/qpid/cpp/include/qpid/log/Options.h +++ b/qpid/cpp/include/qpid/log/Options.h @@ -39,7 +39,7 @@ struct Options : public qpid::Options { std::string argv0; std::string name; std::vector<std::string> selectors; - bool time, level, thread, source, function, hiresTs; + bool time, level, thread, source, function, hiresTs, category; bool trace; std::string prefix; std::auto_ptr<SinkOptions> sinkOptions; diff --git a/qpid/cpp/include/qpid/log/Selector.h b/qpid/cpp/include/qpid/log/Selector.h index 061152d7e2..498d4a7342 100644 --- a/qpid/cpp/include/qpid/log/Selector.h +++ b/qpid/cpp/include/qpid/log/Selector.h @@ -35,17 +35,24 @@ struct Options; class Selector { public: /** Empty selector selects nothing */ - Selector() {} + Selector() { + reset(); + } /** Set selector from Options */ QPID_COMMON_EXTERN Selector(const Options&); /** Equavlient to: Selector s; s.enable(l, s) */ Selector(Level l, const std::string& s=std::string()) { + reset(); enable(l,s); } - Selector(const std::string& enableStr) { enable(enableStr); } + Selector(const std::string& enableStr) { + reset(); + enable(enableStr); + } + /** * Enable messages with level in levels where the file * name contains substring. Empty string matches all. @@ -54,14 +61,30 @@ class Selector { substrings[level].push_back(substring); } + /** + * Enable messages at this level for this category + */ + void enable(Level level, Category category) { + catFlags[level][category] = true; + } + /** Enable based on a 'level[+]:file' string */ QPID_COMMON_EXTERN void enable(const std::string& enableStr); /** True if level is enabled for file. */ QPID_COMMON_EXTERN bool isEnabled(Level level, const char* function); + QPID_COMMON_EXTERN bool isEnabled(Level level, const char* function, Category category); + + /** Reset the category enable flags */ + QPID_COMMON_EXTERN void reset() { + for (int lt = 0; lt < LevelTraits::COUNT; ++lt) + for (int ct = 0; ct < CategoryTraits::COUNT; ++ct) + catFlags[lt][ct] = false; + } private: std::vector<std::string> substrings[LevelTraits::COUNT]; + bool catFlags[LevelTraits::COUNT][CategoryTraits::COUNT]; }; diff --git a/qpid/cpp/include/qpid/log/Statement.h b/qpid/cpp/include/qpid/log/Statement.h index 7b3ab60b81..610bfa077a 100644 --- a/qpid/cpp/include/qpid/log/Statement.h +++ b/qpid/cpp/include/qpid/log/Statement.h @@ -22,6 +22,7 @@ #include "qpid/Msg.h" #include "qpid/CommonImportExport.h" #include <boost/current_function.hpp> +#include <list> namespace qpid { namespace log { @@ -55,15 +56,115 @@ struct LevelTraits { static const char* name(Level); }; -/** POD struct representing a logging statement in source code. */ +/** Formal message categories + * https://issues.apache.org/jira/browse/QPID-3902 + * + * Category Source code directory + * -------- --------------------- + * Security acl ssl gssapi sasl cyrus + * Broker broker + * Management agent console qmf + * Amqp amqp_0_10 framing + * System log sys types xml thread mutex fork pipe time ... + * HA cluster ha replication + * Messaging messaging client + * Store store + * IO tcp rdma AsynchIO socket epoll + * Test + * Unspecified + */ +enum Category { security, broker, management, amqp, system, ha, messaging, + store, io, test, unspecified }; +struct CategoryTraits { + static const int COUNT=unspecified+1; + + /** Test if given name is a Category name + */ + static bool isCategory(const std::string& name); + + /** Get category from string name + * @exception if name invalid. + */ + static Category category(const char* name); + + /** Get category from string name. + * @exception if name invalid. + */ + static Category category(const std::string& name) { + return category(name.c_str()); + } + + /** String name of category */ + static const char* name(Category); +}; + + +class CategoryFileNameHints { +public: + CategoryFileNameHints(){ + hintList.push_back(std::make_pair("AsynchIo", io)); + hintList.push_back(std::make_pair("TCP", io)); + hintList.push_back(std::make_pair("epoll", io)); + hintList.push_back(std::make_pair("Pollable", io)); + hintList.push_back(std::make_pair("Socket", io)); + + hintList.push_back(std::make_pair("Sasl", security)); + hintList.push_back(std::make_pair("Ssl", security)); + hintList.push_back(std::make_pair("Acl", security)); + hintList.push_back(std::make_pair("acl", security)); + hintList.push_back(std::make_pair("cyrus", security)); + + hintList.push_back(std::make_pair("amqp_", amqp)); + hintList.push_back(std::make_pair("framing", amqp)); + + hintList.push_back(std::make_pair("management", management)); + hintList.push_back(std::make_pair("qmf", management)); + hintList.push_back(std::make_pair("console", management)); + hintList.push_back(std::make_pair("Management", management)); + + hintList.push_back(std::make_pair("cluster", ha)); + hintList.push_back(std::make_pair("qpid/ha", ha)); + hintList.push_back(std::make_pair("qpid\\ha", ha)); + hintList.push_back(std::make_pair("replication", ha)); + hintList.push_back(std::make_pair("ClusterSafe", ha)); + + hintList.push_back(std::make_pair("broker", broker)); + hintList.push_back(std::make_pair("SessionState",broker)); + hintList.push_back(std::make_pair("DataDir", broker)); + hintList.push_back(std::make_pair("qpidd", broker)); + hintList.push_back(std::make_pair("xml", broker)); + hintList.push_back(std::make_pair("QpidBroker", broker)); + + hintList.push_back(std::make_pair("store", store)); + + hintList.push_back(std::make_pair("assert", system)); + hintList.push_back(std::make_pair("Exception", system)); + hintList.push_back(std::make_pair("sys", system)); + hintList.push_back(std::make_pair("SCM", system)); + + hintList.push_back(std::make_pair("tests", test)); + + hintList.push_back(std::make_pair("messaging", messaging)); + hintList.push_back(std::make_pair("types", messaging)); + } + + static Category categoryOf(const char*const fName); + +private: + std::list<std::pair<const char* const, Category> > hintList; +}; + + /** POD struct representing a logging statement in source code. */ struct Statement { bool enabled; const char* file; int line; const char* function; Level level; + Category category; QPID_COMMON_EXTERN void log(const std::string& message); + QPID_COMMON_EXTERN static void categorize(Statement& s); struct Initializer { QPID_COMMON_EXTERN Initializer(Statement& s); @@ -72,8 +173,14 @@ struct Statement { }; ///@internal static initializer for a Statement. -#define QPID_LOG_STATEMENT_INIT(level) \ - { 0, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, (::qpid::log::level) } +#define QPID_LOG_STATEMENT_INIT_CAT(LEVEL, CATEGORY) \ +{ 0, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, (::qpid::log::LEVEL), \ +(::qpid::log::CATEGORY) } + + +///@internal static initializer for a Statement with unspecified category +#define QPID_LOG_STATEMENT_INIT(LEVEL) \ +QPID_LOG_STATEMENT_INIT_CAT ( LEVEL , unspecified ) /** * Like QPID_LOG but computes an additional boolean test expression @@ -96,13 +203,26 @@ struct Statement { } while(0) /** + * Line QPID_LOG_IF but with the additional specification of a category. + * @param CATEGORY message category. + */ +#define QPID_LOG_IF_CAT(LEVEL, CATEGORY, TEST, MESSAGE) \ + do { \ + using ::qpid::log::Statement; \ + static Statement stmt_= QPID_LOG_STATEMENT_INIT_CAT(LEVEL, CATEGORY); \ + static Statement::Initializer init_(stmt_); \ + if (stmt_.enabled && (TEST)) \ + stmt_.log(::qpid::Msg() << MESSAGE); \ + } while(0) + +/** * FLAG must be a boolean variable. Assigns FLAG to true iff logging * is enabled for LEVEL in the calling context. Use when extra * support code is needed to generate log messages, to ensure that it * is only run if the logging level is enabled. * e.g. * bool logWarning; - * QPID_LOG_TEST(LEVEL, logWarning); + * QPID_LOG_TEST(warning, logWarning); * if (logWarning) { do stuff needed for warning log messages } */ #define QPID_LOG_TEST(LEVEL, FLAG) \ @@ -113,12 +233,31 @@ struct Statement { FLAG = stmt_.enabled; \ } while(0) + /** + * FLAG must be a boolean variable. Assigns FLAG to true iff logging + * is enabled for LEVEL in the calling context. Use when extra + * support code is needed to generate log messages, to ensure that it + * is only run if the logging level is enabled. + * e.g. + * bool logWarning; + * QPID_LOG_TEST_CAT(warning, System, logWarning); + * if (logWarning) { do stuff needed for warning log messages } + */ + #define QPID_LOG_TEST_CAT(LEVEL, CATEGORY, FLAG) \ + do { \ + using ::qpid::log::Statement; \ + static Statement stmt_= QPID_LOG_STATEMENT_INIT_CAT(LEVEL, CATEGORY); \ + static Statement::Initializer init_(stmt_); \ + FLAG = stmt_.enabled; \ + } while(0) + /** * Macro for log statements. Example of use: * @code * QPID_LOG(debug, "There are " << foocount << " foos in the bar."); * QPID_LOG(error, boost::format("Dohickey %s exploded") % dohicky.name()); * @endcode + * Using QPID_LOG implies a category of Unspecified. * * You can subscribe to log messages by level, by component, by filename * or a combination @see Configuration. @@ -130,6 +269,25 @@ struct Statement { */ #define QPID_LOG(LEVEL, MESSAGE) QPID_LOG_IF(LEVEL, true, MESSAGE); +/** + * Macro for log statements. Example of use: + * @code + * QPID_LOG_CAT(debug, System, "There are " << foocount << " foos in the bar."); + * QPID_LOG_CAT(error, System, boost::format("Dohickey %s exploded") % dohicky.name()); + * @endcode + * Using QPID_LOG_CAT requires the specification of a category. + * + * You can subscribe to log messages by level, by component, by filename + * or a combination @see Configuration. + * + *@param LEVEL severity Level for message, should be one of: + * debug, info, notice, warning, error, critical. NB no qpid::log:: prefix. + *@param CATEGORY basic Category for the message. + *@param MESSAGE any object with an @eostream operator<<, or a sequence + * like of ostreamable objects separated by @e<<. + */ +#define QPID_LOG_CAT(LEVEL, CATEGORY, MESSAGE) QPID_LOG_IF_CAT(LEVEL, CATEGORY, true, MESSAGE); + }} // namespace qpid::log |
