diff options
author | Charles E. Rolke <chug@apache.org> | 2012-05-17 20:07:28 +0000 |
---|---|---|
committer | Charles E. Rolke <chug@apache.org> | 2012-05-17 20:07:28 +0000 |
commit | 219e068084f926dc0bd3847818fedc3b87fedae2 (patch) | |
tree | 609daff4169f24337b169dd3053797e3753fbf8d | |
parent | f63ed524a7bf4d6dac49617b87d30380478d0547 (diff) | |
download | qpid-python-219e068084f926dc0bd3847818fedc3b87fedae2.tar.gz |
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.
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/qpid-3902@1339836 13f79535-47bb-0310-9956-ffa450edef68
-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 | 111 | ||||
-rw-r--r-- | qpid/cpp/src/qpid/log/Logger.cpp | 7 | ||||
-rw-r--r-- | qpid/cpp/src/qpid/log/Options.cpp | 18 | ||||
-rw-r--r-- | qpid/cpp/src/qpid/log/Selector.cpp | 31 | ||||
-rw-r--r-- | qpid/cpp/src/qpid/log/Statement.cpp | 93 | ||||
-rw-r--r-- | qpid/cpp/src/tests/logging.cpp | 2 |
9 files changed, 271 insertions, 22 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..94e38d721b 100644 --- a/qpid/cpp/include/qpid/log/Statement.h +++ b/qpid/cpp/include/qpid/log/Statement.h @@ -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 diff --git a/qpid/cpp/src/qpid/log/Logger.cpp b/qpid/cpp/src/qpid/log/Logger.cpp index 800881c077..7c2e807ca9 100644 --- a/qpid/cpp/src/qpid/log/Logger.cpp +++ b/qpid/cpp/src/qpid/log/Logger.cpp @@ -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, const std::string& msg) { 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; } diff --git a/qpid/cpp/src/qpid/log/Options.cpp b/qpid/cpp/src/qpid/log/Options.cpp index 1259244297..10422bbb1e 100644 --- a/qpid/cpp/src/qpid/log/Options.cpp +++ b/qpid/cpp/src/qpid/log/Options.cpp @@ -39,6 +39,7 @@ Options::Options(const std::string& argv0_, const std::string& name_) : source(false), function(false), hiresTs(false), + category(true), trace(false), sinkOptions (SinkOptions::create(argv0_)) { @@ -49,15 +50,23 @@ Options::Options(const std::string& argv0_, const std::string& name_) : 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& argv0_, const std::string& name_) : ("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 Options& x) { 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 diff --git a/qpid/cpp/src/qpid/log/Selector.cpp b/qpid/cpp/src/qpid/log/Selector.cpp index a4bc580470..8757486d88 100644 --- a/qpid/cpp/src/qpid/log/Selector.cpp +++ b/qpid/cpp/src/qpid/log/Selector.cpp @@ -37,18 +37,29 @@ void Selector::enable(const string& enableStr) { 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, const char* function) { 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 diff --git a/qpid/cpp/src/qpid/log/Statement.cpp b/qpid/cpp/src/qpid/log/Statement.cpp index 09d1c9449f..2347b2b4cb 100644 --- a/qpid/cpp/src/qpid/log/Statement.cpp +++ b/qpid/cpp/src/qpid/log/Statement.cpp @@ -54,6 +54,72 @@ void Statement::log(const std::string& message) { 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(Statement& s) : statement(s) { // 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 diff --git a/qpid/cpp/src/tests/logging.cpp b/qpid/cpp/src/tests/logging.cpp index 5d5bb1feef..47e601ed05 100644 --- a/qpid/cpp/src/tests/logging.cpp +++ b/qpid/cpp/src/tests/logging.cpp @@ -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; } |