Author: chug
Date: Thu May 17 20:07:28 2012
New Revision: 1339836

URL: http://svn.apache.org/viewvc?rev=1339836&view=rev
Log:
QPID-3902 Add formal message categories to C++ Broker log messages

Facilities are defined to issue a log message of any category from 
source module.

Log messages issued with QPID_LOG macro are compiled to use the 
Undefined category.

This checkin version uses a lookup to autogenerate a category for
Undefined log messages.

In practice a 'qpidd -t' trace of a connection appears as shown.


2012-05-17 16:01:37 [IO] info Listening to: 0.0.0.0:5672
2012-05-17 16:01:37 [IO] debug Listened to: 5672
2012-05-17 16:01:37 [IO] info Listening to: [::]:5672
2012-05-17 16:01:37 [IO] debug Listened to: 5672
2012-05-17 16:01:37 [IO] notice Listening on TCP/TCP6 port 5672
2012-05-17 16:01:37 [Management] debug ManagementAgent added package 
org.apache.qpid.acl
2012-05-17 16:01:37 [Management] debug SEND PackageInd 
package=org.apache.qpid.acl to=schema.package
2012-05-17 16:01:37 [Management] debug ManagementAgent added class 
org.apache.qpid.acl:acl
2012-05-17 16:01:37 [Management] debug ManagementAgent added class 
org.apache.qpid.acl:allow
2012-05-17 16:01:37 [Management] debug ManagementAgent added class 
org.apache.qpid.acl:deny
2012-05-17 16:01:37 [Management] debug ManagementAgent added class 
org.apache.qpid.acl:connectionDeny
2012-05-17 16:01:37 [Management] debug ManagementAgent added class 
org.apache.qpid.acl:fileLoaded
2012-05-17 16:01:37 [Management] debug ManagementAgent added class 
org.apache.qpid.acl:fileLoadFailed
2012-05-17 16:01:37 [Management] debug Management object (V1) added: 
org.apache.qpid.acl:acl:org.apache.qpid.broker:broker:amqp-broker
2012-05-17 16:01:37 [Security] notice ACL: Read file 
"/home/chug/svn/qpid/cpp/src/tests/policy.acl"
2012-05-17 16:01:37 [Security] debug ACL: Group list: 0 groups found:
2012-05-17 16:01:37 [Security] debug ACL: name list: 1 names found:
2012-05-17 16:01:37 [Security] debug ACL:  *
2012-05-17 16:01:37 [Security] debug ACL: Rule list: 1 ACL rules found:
2012-05-17 16:01:37 [Security] debug ACL:    1 allow [*] *
2012-05-17 16:01:37 [Security] debug ACL: Load Rules
2012-05-17 16:01:37 [Security] debug ACL: Processing  1 allow [*] *
2012-05-17 16:01:37 [Security] debug ACL: FoundMode allow
2012-05-17 16:01:37 [Management] debug SEND raiseEvent (v1) 
class=org.apache.qpid.acl.fileLoaded
2012-05-17 16:01:37 [Management] debug SEND raiseEvent (v2) 
class=org.apache.qpid.acl.fileLoaded
2012-05-17 16:01:37 [Security] info ACL Plugin loaded
2012-05-17 16:01:37 [Broker] notice Broker running
2012-05-17 16:01:42 [IO] debug RECV [[::1]:5672-[::1]:53468]: INIT(0-10)
2012-05-17 16:01:42 [Security] debug SASL: No Authentication Performed
2012-05-17 16:01:42 [Broker] debug LinkRegistry::notifyConnection(); 
key=[::1]:5672-[::1]:53468
2012-05-17 16:01:42 [Security] trace ACL ConnectionCounter connection 
IP:[::1]:5672-[::1]:53468, userId:
2012-05-17 16:01:42 [Management] debug Management object (V1) added: 
org.apache.qpid.broker:connection:[::1]:5672-[::1]:53468
2012-05-17 16:01:42 [Amqp] trace SENT [[::1]:5672-[::1]:53468]: INIT(0-10)
2012-05-17 16:01:42 [Amqp] trace SENT [[::1]:5672-[::1]:53468]: Frame[BEbe; 
channel=0; {ConnectionStartBody: 
server-properties={qpid.federation_tag:V2:36:str16(5787d304-441c-4266-9702-11ecc9a521bc)};
 mechanisms=str16{V2:9:str16(ANONYMOUS), V2:5:str16(PLAIN)}; 
locales=str16{V2:5:str16(en_US)}; }]
2012-05-17 16:01:42 [Amqp] trace RECV [[::1]:5672-[::1]:53468]: Frame[BEbe; 
channel=0; {ConnectionStartOkBody: 
client-properties={platform:V2:5:str16(posix),product:V2:18:str16(qpid python 
client),qpid.client_pid:F8:int64(28802),qpid.client_ppid:F8:int64(1994),qpid.client_process:V2:9:str16(qpid-tool),version:V2:11:str16(development)};
 mechanism=ANONYMOUS; }]
2012-05-17 16:01:42 [Management] debug SEND raiseEvent (v1) 
class=org.apache.qpid.broker.clientConnect
2012-05-17 16:01:42 [Management] debug SEND raiseEvent (v2) 
class=org.apache.qpid.broker.clientConnect
2012-05-17 16:01:42 [Amqp] trace SENT [[::1]:5672-[::1]:53468]: Frame[BEbe; 
channel=0; {ConnectionTuneBody: channel-max=32767; max-frame-size=65535; 
heartbeat-min=0; heartbeat-max=120; }]
2012-05-17 16:01:42 [Amqp] trace RECV [[::1]:5672-[::1]:53468]: Frame[BEbe; 
channel=0; {ConnectionTuneOkBody: }]
2012-05-17 16:01:42 [Amqp] trace RECV [[::1]:5672-[::1]:53468]: Frame[BEbe; 
channel=0; {ConnectionOpenBody: }]
2012-05-17 16:01:42 [Security] trace ACL ConnectionCounter Opened 
IP:[::1]:5672-[::1]:53468, userId:anonymous
2012-05-17 16:01:42 [Amqp] trace SENT [[::1]:5672-[::1]:53468]: Frame[BEbe; 
channel=0; {ConnectionOpenOkBody: 
known-hosts=str16{V2:49:str16(amqp:tcp:10.16.185.91:5672,tcp:192.168.122.1:5672)};
 }]
2012-05-17 16:01:42 [Amqp] trace RECV [[::1]:5672-[::1]:53468]: Frame[BEbe; 
channel=1; {SessionAttachBody: name=ummmm.28802.1; }]
2012-05-17 16:01:42 [Broker] debug SessionState::SessionState 
anonymous.ummmm.28802.1: 0x7ffff0044960
2012-05-17 16:01:42 [Management] debug Management object (V1) added: 
org.apache.qpid.broker:session:ummmm.28802.1
2012-05-17 16:01:42 [Broker] debug anonymous.ummmm.28802.1: attached on broker.
2012-05-17 16:01:42 [Amqp] debug Attached channel 1 to anonymous.ummmm.28802.1
2012-05-17 16:01:42 [Broker] debug anonymous.ummmm.28802.1: ready to send, 
activating output.




Modified:
    qpid/branches/qpid-3902/qpid/cpp/include/qpid/log/Logger.h
    qpid/branches/qpid-3902/qpid/cpp/include/qpid/log/Options.h
    qpid/branches/qpid-3902/qpid/cpp/include/qpid/log/Selector.h
    qpid/branches/qpid-3902/qpid/cpp/include/qpid/log/Statement.h
    qpid/branches/qpid-3902/qpid/cpp/src/qpid/log/Logger.cpp
    qpid/branches/qpid-3902/qpid/cpp/src/qpid/log/Options.cpp
    qpid/branches/qpid-3902/qpid/cpp/src/qpid/log/Selector.cpp
    qpid/branches/qpid-3902/qpid/cpp/src/qpid/log/Statement.cpp
    qpid/branches/qpid-3902/qpid/cpp/src/tests/logging.cpp

Modified: qpid/branches/qpid-3902/qpid/cpp/include/qpid/log/Logger.h
URL: 
http://svn.apache.org/viewvc/qpid/branches/qpid-3902/qpid/cpp/include/qpid/log/Logger.h?rev=1339836&r1=1339835&r2=1339836&view=diff
==============================================================================
--- qpid/branches/qpid-3902/qpid/cpp/include/qpid/log/Logger.h (original)
+++ qpid/branches/qpid-3902/qpid/cpp/include/qpid/log/Logger.h Thu May 17 
20:07:28 2012
@@ -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.

Modified: qpid/branches/qpid-3902/qpid/cpp/include/qpid/log/Options.h
URL: 
http://svn.apache.org/viewvc/qpid/branches/qpid-3902/qpid/cpp/include/qpid/log/Options.h?rev=1339836&r1=1339835&r2=1339836&view=diff
==============================================================================
--- qpid/branches/qpid-3902/qpid/cpp/include/qpid/log/Options.h (original)
+++ qpid/branches/qpid-3902/qpid/cpp/include/qpid/log/Options.h Thu May 17 
20:07:28 2012
@@ -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;

Modified: qpid/branches/qpid-3902/qpid/cpp/include/qpid/log/Selector.h
URL: 
http://svn.apache.org/viewvc/qpid/branches/qpid-3902/qpid/cpp/include/qpid/log/Selector.h?rev=1339836&r1=1339835&r2=1339836&view=diff
==============================================================================
--- qpid/branches/qpid-3902/qpid/cpp/include/qpid/log/Selector.h (original)
+++ qpid/branches/qpid-3902/qpid/cpp/include/qpid/log/Selector.h Thu May 17 
20:07:28 2012
@@ -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];
 };
 
 

Modified: qpid/branches/qpid-3902/qpid/cpp/include/qpid/log/Statement.h
URL: 
http://svn.apache.org/viewvc/qpid/branches/qpid-3902/qpid/cpp/include/qpid/log/Statement.h?rev=1339836&r1=1339835&r2=1339836&view=diff
==============================================================================
--- qpid/branches/qpid-3902/qpid/cpp/include/qpid/log/Statement.h (original)
+++ qpid/branches/qpid-3902/qpid/cpp/include/qpid/log/Statement.h Thu May 17 
20:07:28 2012
@@ -55,15 +55,61 @@ struct LevelTraits {
     static const char* name(Level);
 };
 
-/** POD struct representing a logging statement in source code. */
+/** Add 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);
+};
+
+
+ /** 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);
+    QPID_COMMON_EXTERN static Category categoryOf(const char* const function);
 
     struct Initializer {
         QPID_COMMON_EXTERN Initializer(Statement& s);
@@ -72,8 +118,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 +148,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 +178,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 +214,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
 
 

Modified: qpid/branches/qpid-3902/qpid/cpp/src/qpid/log/Logger.cpp
URL: 
http://svn.apache.org/viewvc/qpid/branches/qpid-3902/qpid/cpp/src/qpid/log/Logger.cpp?rev=1339836&r1=1339835&r2=1339836&view=diff
==============================================================================
--- qpid/branches/qpid-3902/qpid/cpp/src/qpid/log/Logger.cpp (original)
+++ qpid/branches/qpid-3902/qpid/cpp/src/qpid/log/Logger.cpp Thu May 17 
20:07:28 2012
@@ -47,7 +47,7 @@ using namespace std;
 typedef sys::Mutex::ScopedLock ScopedLock;
 
 inline void Logger::enable_unlocked(Statement* s) {
-    s->enabled=selector.isEnabled(s->level, s->function);
+    s->enabled=selector.isEnabled(s->level, s->function, s->category);
 }
 
 Logger& Logger::instance() {
@@ -95,6 +95,8 @@ void Logger::log(const Statement& s, con
         else
             qpid::sys::outputFormattedNow(os);
     }
+    if (flags&CATEGORY)
+        os << "[" << CategoryTraits::name(s.category) << "] ";
     if (flags&LEVEL)
         os << LevelTraits::name(s.level) << " ";
     if (flags&THREAD)
@@ -144,7 +146,8 @@ int Logger::format(const Options& opts) 
         bitIf(opts.source, (FILE|LINE)) |
         bitIf(opts.function, FUNCTION) |
         bitIf(opts.thread, THREAD) |
-        bitIf(opts.hiresTs, HIRES);
+        bitIf(opts.hiresTs, HIRES) |
+        bitIf(opts.category, CATEGORY);
     format(flags);
     return flags;
 }

Modified: qpid/branches/qpid-3902/qpid/cpp/src/qpid/log/Options.cpp
URL: 
http://svn.apache.org/viewvc/qpid/branches/qpid-3902/qpid/cpp/src/qpid/log/Options.cpp?rev=1339836&r1=1339835&r2=1339836&view=diff
==============================================================================
--- qpid/branches/qpid-3902/qpid/cpp/src/qpid/log/Options.cpp (original)
+++ qpid/branches/qpid-3902/qpid/cpp/src/qpid/log/Options.cpp Thu May 17 
20:07:28 2012
@@ -39,6 +39,7 @@ Options::Options(const std::string& argv
     source(false),
     function(false),
     hiresTs(false),
+    category(true),
     trace(false),
     sinkOptions (SinkOptions::create(argv0_))
 {
@@ -49,15 +50,23 @@ Options::Options(const std::string& argv
     for (int i = 1; i < LevelTraits::COUNT; ++i)
         levels << " " << LevelTraits::name(Level(i));
 
+    ostringstream categories;
+    categories << CategoryTraits::name(Category(0));
+    for (int i = 1; i < CategoryTraits::COUNT; ++i)
+        categories << " " << CategoryTraits::name(Category(i));
+
     addOptions()
         ("trace,t", optValue(trace), "Enables all logging" )
         ("log-enable", optValue(selectors, "RULE"),
-         ("Enables logging for selected levels and components. " 
+         ("Enables logging for selected levels and components. "
           "RULE is in the form 'LEVEL[+][:PATTERN]' "
-          "Levels are one of: \n\t "+levels.str()+"\n"
+          "LEVEL is one of: \n\t "+levels.str()+"\n"
+          "PATTERN is a function name or a catogory: \n\t 
"+categories.str()+"\n"
           "For example:\n"
           "\t'--log-enable warning+' "
           "logs all warning, error and critical messages.\n"
+          "\t'--log-enable trace+:Broker' "
+          "logs all category 'Broker' messages.\n"
           "\t'--log-enable debug:framing' "
           "logs debug messages from the framing namespace. "
           "This option can be used multiple times").c_str())
@@ -67,6 +76,7 @@ Options::Options(const std::string& argv
         ("log-thread", optValue(thread,"yes|no"), "Include thread ID in log 
messages")
         ("log-function", optValue(function,"yes|no"), "Include function 
signature in log messages")
         ("log-hires-timestamp", optValue(hiresTs,"yes|no"), "Use hi-resolution 
timestamps in log messages")
+        ("log-category", optValue(category,"yes|no"), "Include category in log 
messages")
         ("log-prefix", optValue(prefix,"STRING"), "Prefix to append to all log 
messages")
         ;
     add(*sinkOptions);
@@ -83,6 +93,7 @@ Options::Options(const Options &o) :
     source(o.source),
     function(o.function),
     hiresTs(o.hiresTs),
+    category(o.category),
     trace(o.trace),
     prefix(o.prefix),
     sinkOptions (SinkOptions::create(o.argv0))
@@ -101,11 +112,12 @@ Options& Options::operator=(const Option
         source = x.source;
         function = x.function;
         hiresTs = x.hiresTs;
+        category = x.category;
         trace = x.trace;
         prefix = x.prefix;
         *sinkOptions = *x.sinkOptions;
     }
     return *this;
 }
-        
+
 }} // namespace qpid::log

Modified: qpid/branches/qpid-3902/qpid/cpp/src/qpid/log/Selector.cpp
URL: 
http://svn.apache.org/viewvc/qpid/branches/qpid-3902/qpid/cpp/src/qpid/log/Selector.cpp?rev=1339836&r1=1339835&r2=1339836&view=diff
==============================================================================
--- qpid/branches/qpid-3902/qpid/cpp/src/qpid/log/Selector.cpp (original)
+++ qpid/branches/qpid-3902/qpid/cpp/src/qpid/log/Selector.cpp Thu May 17 
20:07:28 2012
@@ -37,18 +37,29 @@ void Selector::enable(const string& enab
         level=enableStr.substr(0,c);
         pattern=enableStr.substr(c+1);
     }
+    bool isCat = CategoryTraits::isCategory(pattern);
     if (!level.empty() && level[level.size()-1]=='+') {
         for (int i =  LevelTraits::level(level.substr(0,level.size()-1));
              i < LevelTraits::COUNT;
-             ++i)
-            enable(Level(i), pattern);
+             ++i) {
+            if (isCat) {
+                enable(Level(i), CategoryTraits::category(pattern));
+            } else {
+                enable(Level(i), pattern);
+            }
+        }
     }
     else {
-        enable(LevelTraits::level(level), pattern);
+        if (isCat) {
+            enable(LevelTraits::level(level), 
CategoryTraits::category(pattern));
+        } else {
+            enable(LevelTraits::level(level), pattern);
+        }
     }
 }
 
 Selector::Selector(const Options& opt){
+    reset();
     for_each(opt.selectors.begin(), opt.selectors.end(),
              boost::bind(&Selector::enable, this, _1));
 }
@@ -58,11 +69,17 @@ bool Selector::isEnabled(Level level, co
     for (std::vector<std::string>::iterator i=substrings[level].begin();
          i != substrings[level].end();
          ++i)
-    {
-        if (std::search(function, functionEnd, i->begin(), i->end()) != 
functionEnd)
-            return true;
-    }
+        {
+            if (std::search(function, functionEnd, i->begin(), i->end()) != 
functionEnd)
+                return true;
+        }
     return false;
 }
 
+bool Selector::isEnabled(Level level, const char* function, Category category) 
{
+    if (catFlags[level][category])
+        return true;
+    return isEnabled(level, function);
+}
+
 }} // namespace qpid::log

Modified: qpid/branches/qpid-3902/qpid/cpp/src/qpid/log/Statement.cpp
URL: 
http://svn.apache.org/viewvc/qpid/branches/qpid-3902/qpid/cpp/src/qpid/log/Statement.cpp?rev=1339836&r1=1339835&r2=1339836&view=diff
==============================================================================
--- qpid/branches/qpid-3902/qpid/cpp/src/qpid/log/Statement.cpp (original)
+++ qpid/branches/qpid-3902/qpid/cpp/src/qpid/log/Statement.cpp Thu May 17 
20:07:28 2012
@@ -54,6 +54,72 @@ void Statement::log(const std::string& m
     Logger::instance().log(*this, quote(message));
 }
 
+#define test(STR, CAT)           \
+if (strstr(fName, (STR)) != 0) {\
+    return (::qpid::log::CAT); \
+}
+//    std::cout << "File: " << fName << " categorized as " << 
CategoryTraits::name(::qpid::log::CAT) << std::endl;
+
+Category Statement::categoryOf(const char*const fName) {
+    test("AsynchIO",    io);
+    test("TCP",         io);
+    test("epoll",       io);
+    test("Pollable",    io);
+    test("Socket",      io);
+
+    test("Sasl",        security);
+    test("Ssl",         security);
+    test("Acl",         security);
+    test("acl",         security);
+    test("cyrus",       security);
+
+    test("amqp_",       amqp);
+    test("framing",     amqp);
+
+    test("management",  management);
+    test("qmf",         management);
+    test("console",     management);
+
+    test("cluster",     ha);
+    test("qpid/ha",     ha);
+    test("qpid\\ha",    ha);
+    test("replication", ha);
+    test("ClusterSafe", ha);
+
+    test("broker",      broker);
+    test("SessionState",broker);
+    test("DataDir",     broker);
+    test("qpidd",       broker);
+
+    test("store",       store);
+
+    test("assert",      system);
+    test("Exception",   system);
+    test("sys",         system);
+    test("SCM",         system);
+
+    test("tests",       test);
+
+    test("messaging",   messaging);
+    test("types",       messaging);
+
+    std::cout << "Unspecified file:" << fName << std::endl;
+    return unspecified;
+}
+
+
+void Statement::categorize(Statement& s) {
+    // given a statement and it's category
+    // if the category is Unspecified then try to find a
+    // better category based on the path/file function name.
+    if (s.category == log::unspecified) {
+        s.category = categoryOf(s.file);
+    } else {
+        // already has a category so leave it alone
+    }
+}
+
+
 Statement::Initializer::Initializer(Statement& s) : statement(s) {
     // QPID-3891
     // From the given BOOST_CURRENT_FUNCTION name extract only the
@@ -99,16 +165,22 @@ Statement::Initializer::Initializer(Stat
         // no function-name pointer to process
     }
 
+    Statement::categorize(s);
     Logger::instance().add(s);
 }
 
+
 namespace {
 const char* names[LevelTraits::COUNT] = {
     "trace", "debug", "info", "notice", "warning", "error", "critical"
 };
 
-} // namespace
+const char* catNames[CategoryTraits::COUNT] = {
+    "Security", "Broker", "Management", "Amqp", "System", "HA", "Messaging",
+    "Store", "IO", "Test", "Unspecified"
+};
 
+} // namespace
 Level LevelTraits::level(const char* name) {
     for (int i =0; i < LevelTraits::COUNT; ++i) {
         if (strcmp(names[i], name)==0)
@@ -121,4 +193,23 @@ const char* LevelTraits::name(Level l) {
     return names[l];
 }
 
+bool CategoryTraits::isCategory(const std::string& name) {
+    for (int i =0; i < CategoryTraits::COUNT; ++i) {
+        if (strcmp(catNames[i], name.c_str())==0)
+            return true;
+    }
+    return false;
+}
+
+Category CategoryTraits::category(const char* name) {
+    for (int i =0; i < CategoryTraits::COUNT; ++i) {
+        if (strcmp(catNames[i], name)==0)
+            return Category(i);
+    }
+    throw std::runtime_error(std::string("Invalid log category name: ")+name);
+}
+
+const char* CategoryTraits::name(Category c) {
+    return catNames[c];
+}
 }} // namespace qpid::log

Modified: qpid/branches/qpid-3902/qpid/cpp/src/tests/logging.cpp
URL: 
http://svn.apache.org/viewvc/qpid/branches/qpid-3902/qpid/cpp/src/tests/logging.cpp?rev=1339836&r1=1339835&r2=1339836&view=diff
==============================================================================
--- qpid/branches/qpid-3902/qpid/cpp/src/tests/logging.cpp (original)
+++ qpid/branches/qpid-3902/qpid/cpp/src/tests/logging.cpp Thu May 17 20:07:28 
2012
@@ -258,7 +258,7 @@ QPID_AUTO_TEST_CASE(testOverhead) {
 Statement statement(
     Level level, const char* file="", int line=0, const char* fn=0)
 {
-    Statement s={0, file, line, fn, level};
+    Statement s={0, file, line, fn, level, ::qpid::log::unspecified};
     return s;
 }
 



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@qpid.apache.org
For additional commands, e-mail: commits-h...@qpid.apache.org

Reply via email to