summaryrefslogtreecommitdiff
path: root/qpid/cpp/include
diff options
context:
space:
mode:
authorCharles E. Rolke <chug@apache.org>2012-06-11 20:53:47 +0000
committerCharles E. Rolke <chug@apache.org>2012-06-11 20:53:47 +0000
commit35f30ce23af989b23b57a50f2c4b97bf486b1d64 (patch)
tree73a844c4a53d4873cb15cd661f9a3880823220ab /qpid/cpp/include
parenta72e355e7458497c0f993e1259e09167af113f01 (diff)
downloadqpid-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.h2
-rw-r--r--qpid/cpp/include/qpid/log/Options.h2
-rw-r--r--qpid/cpp/include/qpid/log/Selector.h27
-rw-r--r--qpid/cpp/include/qpid/log/Statement.h166
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