diff options
author | Alan Conway <aconway@apache.org> | 2008-06-02 20:52:40 +0000 |
---|---|---|
committer | Alan Conway <aconway@apache.org> | 2008-06-02 20:52:40 +0000 |
commit | 6c5f69a0e6e62fc220f3b4198dad1f202552e2ad (patch) | |
tree | 80b6a3ff24a6fe91adc36f3e83044ee44b00ac5a /cpp | |
parent | 1322ce3cf402f3bb74c2a411dcbdfd3779ed6d3b (diff) | |
download | qpid-python-6c5f69a0e6e62fc220f3b4198dad1f202552e2ad.tar.gz |
Added --syslog-name, --syslog-facility options.
git-svn-id: https://svn.apache.org/repos/asf/incubator/qpid/trunk/qpid@662558 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/src/qpid/client/Connection.cpp | 3 | ||||
-rw-r--r-- | cpp/src/qpid/client/ConnectionSettings.cpp | 7 | ||||
-rw-r--r-- | cpp/src/qpid/client/ConnectionSettings.h | 6 | ||||
-rw-r--r-- | cpp/src/qpid/log/Logger.cpp | 29 | ||||
-rw-r--r-- | cpp/src/qpid/log/Logger.h | 7 | ||||
-rw-r--r-- | cpp/src/qpid/log/Options.cpp | 112 | ||||
-rw-r--r-- | cpp/src/qpid/log/Options.h | 17 | ||||
-rw-r--r-- | cpp/src/qpidd.cpp | 11 | ||||
-rw-r--r-- | cpp/src/tests/TestOptions.h | 2 | ||||
-rw-r--r-- | cpp/src/tests/logging.cpp | 18 |
10 files changed, 152 insertions, 60 deletions
diff --git a/cpp/src/qpid/client/Connection.cpp b/cpp/src/qpid/client/Connection.cpp index c108c3c86a..6994c7a400 100644 --- a/cpp/src/qpid/client/Connection.cpp +++ b/cpp/src/qpid/client/Connection.cpp @@ -53,7 +53,8 @@ void Connection::open( const std::string& vhost, uint16_t maxFrameSize) { - ConnectionSettings settings; + // FIXME aconway 2008-06-02: refactor ConnectionSettings to separate out command line parsing. + ConnectionSettings settings(""); settings.host = host; settings.port = port; settings.username = uid; diff --git a/cpp/src/qpid/client/ConnectionSettings.cpp b/cpp/src/qpid/client/ConnectionSettings.cpp index 998e1c4636..26a11c3b9d 100644 --- a/cpp/src/qpid/client/ConnectionSettings.cpp +++ b/cpp/src/qpid/client/ConnectionSettings.cpp @@ -29,7 +29,7 @@ namespace qpid { namespace client { -ConnectionSettings::ConnectionSettings() : +ConnectionSettings::ConnectionSettings(const std::string& argv0) : Options("Connection Settings"), host("localhost"), port(TcpAddress::DEFAULT_PORT), @@ -42,7 +42,8 @@ ConnectionSettings::ConnectionSettings() : maxChannels(32767), maxFrameSize(65535), bounds(2), - tcpNoDelay(false) + tcpNoDelay(false), + log(argv0) { addOptions() ("broker,b", optValue(host, "HOST"), "Broker host to connect to") @@ -65,7 +66,7 @@ ConnectionSettings::~ConnectionSettings() {} void ConnectionSettings::parse(int argc, char** argv) { qpid::Options::parse(argc, argv); - qpid::log::Logger::instance().configure(log, argv[0]); + qpid::log::Logger::instance().configure(log); } diff --git a/cpp/src/qpid/client/ConnectionSettings.h b/cpp/src/qpid/client/ConnectionSettings.h index 8db5c0578c..d35b8bc0e7 100644 --- a/cpp/src/qpid/client/ConnectionSettings.h +++ b/cpp/src/qpid/client/ConnectionSettings.h @@ -37,9 +37,9 @@ namespace client { * Used to hold seetings for a connection (and parse these from * command line options etc if desired). */ -struct ConnectionSettings : qpid::Options, qpid::sys::Socket::Configuration -{ - ConnectionSettings(); +struct ConnectionSettings : qpid::Options, qpid::sys::Socket::Configuration { + // FIXME aconway 2008-06-02: separate option parsing from settings as subclass. + ConnectionSettings(const std::string& argv0=std::string()); virtual ~ConnectionSettings(); /** diff --git a/cpp/src/qpid/log/Logger.cpp b/cpp/src/qpid/log/Logger.cpp index f2f86e62fc..84096f7e58 100644 --- a/cpp/src/qpid/log/Logger.cpp +++ b/cpp/src/qpid/log/Logger.cpp @@ -63,8 +63,8 @@ struct OstreamOutput : public Logger::Output { }; struct SyslogOutput : public Logger::Output { - SyslogOutput(const std::string& name, int facility_=LOG_USER) - : progName(name), facility(facility_) + SyslogOutput(const Options& opts) + : name(opts.syslogName), facility(opts.syslogFacility.value) { ::openlog(name.c_str(), LOG_PID, facility); } @@ -78,7 +78,7 @@ struct SyslogOutput : public Logger::Output { syslog(LevelTraits::priority(s.level), "%s", m.c_str()); } - std::string progName; + std::string name; int facility; }; @@ -90,9 +90,9 @@ Logger::Logger() : flags(0) { // Initialize myself from env variables so all programs // (e.g. tests) can use logging even if they don't parse // command line args. - Options opts; + Options opts(""); opts.parse(0, 0); - configure(opts,""); + configure(opts); } Logger::~Logger() {} @@ -161,17 +161,17 @@ void Logger::output(std::ostream& out) { output(make_auto_ptr<Output>(new OstreamOutput(out))); } -void Logger::syslog(const std::string& progName) { - output(make_auto_ptr<Output>(new SyslogOutput(progName))); +void Logger::syslog(const Options& opts) { + output(make_auto_ptr<Output>(new SyslogOutput(opts))); } -void Logger::output(const std::string& name) { +void Logger::output(const std::string& name, const Options& opts) { if (name=="stderr") output(clog); else if (name=="stdout") output(cout); else if (name=="syslog") - syslog(syslogName); + syslog(opts); else output(make_auto_ptr<Output>(new OstreamOutput(name))); } @@ -209,21 +209,16 @@ void Logger::add(Statement& s) { statements.insert(&s); } -void Logger::configure(const Options& opts, const std::string& prog) -{ +void Logger::configure(const Options& opts) { clear(); Options o(opts); if (o.trace) o.selectors.push_back("trace+"); - { - ScopedLock l(lock); - syslogName=prog; - } format(o); select(Selector(o)); - void (Logger::* outputFn)(const std::string&) = &Logger::output; + void (Logger::* outputFn)(const std::string&, const Options&) = &Logger::output; for_each(o.outputs.begin(), o.outputs.end(), - boost::bind(outputFn, this, _1)); + boost::bind(outputFn, this, _1, boost::cref(o))); } }} // namespace qpid::log diff --git a/cpp/src/qpid/log/Logger.h b/cpp/src/qpid/log/Logger.h index 7851c65406..657c8848a0 100644 --- a/cpp/src/qpid/log/Logger.h +++ b/cpp/src/qpid/log/Logger.h @@ -62,7 +62,7 @@ class Logger : private boost::noncopyable { int format(const Options&); /** Configure logger from Options */ - void configure(const Options& o, const std::string& progname); + void configure(const Options& o); /** Add a statement. */ void add(Statement& s); @@ -79,13 +79,13 @@ class Logger : private boost::noncopyable { void output(std::ostream&); /** Add syslog to outputs. */ - void syslog(const std::string& programName); + void syslog(const Options&); /** Add an output. *@param name a file name or one of the special tokens: *stdout, stderr, syslog. */ - void output(const std::string& name); + void output(const std::string& name, const Options&); /** Add an output destination for messages */ void output(std::auto_ptr<Output> out); @@ -100,7 +100,6 @@ class Logger : private boost::noncopyable { sys::Mutex lock; inline void enable_unlocked(Statement* s); - std::string syslogName; Statements statements; Outputs outputs; Selector selector; diff --git a/cpp/src/qpid/log/Options.cpp b/cpp/src/qpid/log/Options.cpp index dd296f3a93..0fb7fb4cbb 100644 --- a/cpp/src/qpid/log/Options.cpp +++ b/cpp/src/qpid/log/Options.cpp @@ -19,14 +19,100 @@ #include "Options.h" #include "Statement.h" #include "qpid/Options.h" +#include <map> +#include <string> +#include <algorithm> +#include <syslog.h> namespace qpid { namespace log { using namespace std; -Options::Options(const std::string& name) : qpid::Options(name), - time(true), level(true), thread(false), source(false), function(false), trace(false) +namespace { + +class SyslogFacilities { + public: + typedef map<string, int> ByName; + typedef map<int, string> ByValue; + + SyslogFacilities() { + struct NameValue { const char* name; int value; }; + NameValue nameValue[] = { + { "AUTH", LOG_AUTH }, + { "AUTHPRIV", LOG_AUTHPRIV }, + { "CRON", LOG_CRON }, + { "DAEMON", LOG_DAEMON }, + { "FTP", LOG_FTP }, + { "KERN", LOG_KERN }, + { "LOCAL0", LOG_LOCAL0 }, + { "LOCAL1", LOG_LOCAL1 }, + { "LOCAL2", LOG_LOCAL2 }, + { "LOCAL3", LOG_LOCAL3 }, + { "LOCAL4", LOG_LOCAL4 }, + { "LOCAL5", LOG_LOCAL5 }, + { "LOCAL6", LOG_LOCAL6 }, + { "LOCAL7", LOG_LOCAL7 }, + { "LPR", LOG_LPR }, + { "MAIL", LOG_MAIL }, + { "NEWS", LOG_NEWS }, + { "SYSLOG", LOG_SYSLOG }, + { "USER", LOG_USER }, + { "UUCP", LOG_UUCP } + }; + for (size_t i = 0; i < sizeof(nameValue)/sizeof(nameValue[0]); ++i) { + byName.insert(ByName::value_type(nameValue[i].name, nameValue[i].value)); + // Recognise with and without LOG_ prefix e.g.: AUTH and LOG_AUTH + byName.insert(ByName::value_type(string("LOG_")+nameValue[i].name, nameValue[i].value)); + byValue.insert(ByValue::value_type(nameValue[i].value, string("LOG_")+nameValue[i].name)); + } + }; + + int value(const string& name) const { + string key(name); + transform(key.begin(), key.end(), key.begin(), ::toupper); + ByName::const_iterator i = byName.find(key); + if (i == byName.end()) + throw Exception("Not a valid syslog facility: " + name); + return i->second; + } + + string name(int value) const { + ByValue::const_iterator i = byValue.find(value); + if (i == byValue.end()) + throw Exception("Not a valid syslog value: " + value); + return i->second; + } + + private: + ByName byName; + ByValue byValue; +}; + +} + +ostream& operator<<(ostream& o, const SyslogFacility& f) { + return o << SyslogFacilities().name(f.value); +} + +istream& operator>>(istream& i, SyslogFacility& f) { + std::string name; + i >> name; + f.value = SyslogFacilities().value(name); + return i; +} + +namespace { +std::string basename(const std::string path) { + size_t i = path.find_last_of('/'); + return path.substr((i == std::string::npos) ? 0 : i+1); +} +} + +Options::Options(const std::string& argv0, const std::string& name) : + qpid::Options(name), + time(true), level(true), thread(false), source(false), function(false), trace(false), + syslogName(basename(argv0)), syslogFacility(LOG_DAEMON) { outputs.push_back("stderr"); selectors.push_back("error+"); @@ -35,9 +121,9 @@ Options::Options(const std::string& name) : qpid::Options(name), levels << LevelTraits::name(Level(0)); for (int i = 1; i < LevelTraits::COUNT; ++i) levels << " " << LevelTraits::name(Level(i)); + addOptions() - ("log-output", optValue(outputs, "FILE"), - "Send log output to FILE. " + ("log-output", optValue(outputs, "FILE"), "Send log output to FILE. " "FILE can be a file name or one of the special values:\n" "stderr, stdout, syslog") ("trace,t", optValue(trace), "Enables all logging" ) @@ -51,16 +137,14 @@ Options::Options(const std::string& name) : qpid::Options(name), "\t'--log-enable debug:framing' " "logs debug messages from the framing namespace. " "This option can be used multiple times").c_str()) - ("log-time", optValue(time, "yes|no"), - "Include time in log messages") - ("log-level", optValue(level,"yes|no"), - "Include severity level in log messages") - ("log-source", optValue(source,"yes|no"), - "Include source file:line in log messages") - ("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-time", optValue(time, "yes|no"), "Include time in log messages") + ("log-level", optValue(level,"yes|no"), "Include severity level in log messages") + ("log-source", optValue(source,"yes|no"), "Include source file:line in log messages") + ("log-thread", optValue(thread,"yes|no"), "Include thread ID in log messages") + ("log-function", optValue(function,"yes|no"), "Include function signature in log messages") + ("syslog-name", optValue(syslogName, "NAME"), "Name to use in syslog messages") + ("syslog-facility", optValue(syslogFacility,"LOG_XXX"), "Facility to use in syslog messages") + ; } }} // namespace qpid::log diff --git a/cpp/src/qpid/log/Options.h b/cpp/src/qpid/log/Options.h index 441c6e8a8d..25db7f3474 100644 --- a/cpp/src/qpid/log/Options.h +++ b/cpp/src/qpid/log/Options.h @@ -19,19 +19,32 @@ * */ #include "qpid/Options.h" - +#include <iosfwd> namespace qpid { namespace log { +/** Provides << and >> operators to convert syslog facility values to/from strings. */ +struct SyslogFacility { + int value; + SyslogFacility(int i=0) : value(i) {} +}; + +std::ostream& operator<<(std::ostream&, const SyslogFacility&); +std::istream& operator>>(std::istream&, SyslogFacility&); + /** Logging options for config parser. */ struct Options : public qpid::Options { - Options(const std::string& name="Logging options"); + /** Pass argv[0] for use in syslog output */ + Options(const std::string& argv0, + const std::string& name="Logging options"); std::vector<std::string> selectors; std::vector<std::string> outputs; bool time, level, thread, source, function; bool trace; + std::string syslogName; + SyslogFacility syslogFacility; }; diff --git a/cpp/src/qpidd.cpp b/cpp/src/qpidd.cpp index 08b907cbe2..338c5d51f7 100644 --- a/cpp/src/qpidd.cpp +++ b/cpp/src/qpidd.cpp @@ -79,7 +79,7 @@ struct QpiddOptions : public qpid::Options { DaemonOptions daemon; qpid::log::Options log; - QpiddOptions() : qpid::Options("Options"), common("", "/etc/qpidd.conf") { + QpiddOptions(const char* argv0) : qpid::Options("Options"), common("", "/etc/qpidd.conf"), log(argv0) { add(common); add(module); add(broker); @@ -109,7 +109,7 @@ struct BootstrapOptions : public qpid::Options { ModuleOptions module; qpid::log::Options log; - BootstrapOptions() : qpid::Options("Options"), common("", "/etc/qpidd.conf") { + BootstrapOptions(const char* argv0) : qpid::Options("Options"), common("", "/etc/qpidd.conf"), log(argv0) { add(common); add(module); add(log); @@ -181,14 +181,13 @@ int main(int argc, char* argv[]) try { { - BootstrapOptions bootOptions; + BootstrapOptions bootOptions(argv[0]); string defaultPath (bootOptions.module.loadDir); - // Parse only the common, load, and log options to see which modules need // to be loaded. Once the modules are loaded, the command line will // be re-parsed with all of the module-supplied options. bootOptions.parse (argc, argv, bootOptions.common.config, true); - qpid::log::Logger::instance().configure(bootOptions.log, argv[0]); + qpid::log::Logger::instance().configure(bootOptions.log); for (vector<string>::iterator iter = bootOptions.module.load.begin(); iter != bootOptions.module.load.end(); @@ -202,7 +201,7 @@ int main(int argc, char* argv[]) } // Parse options - options.reset(new QpiddOptions()); + options.reset(new QpiddOptions(argv[0])); options->parse(argc, argv, options->common.config); // Options that just print information. diff --git a/cpp/src/tests/TestOptions.h b/cpp/src/tests/TestOptions.h index b34acaec4e..3013ffa773 100644 --- a/cpp/src/tests/TestOptions.h +++ b/cpp/src/tests/TestOptions.h @@ -52,7 +52,7 @@ struct TestOptions : public qpid::Options msg << *this << std::endl << std::endl << e.what() << std::endl; throw qpid::Options::Exception(msg.str()); } - qpid::log::Logger::instance().configure(con.log, argv[0]); + qpid::log::Logger::instance().configure(con.log); if (help) { std::ostringstream msg; msg << *this << std::endl << std::endl << helpText << std::endl; diff --git a/cpp/src/tests/logging.cpp b/cpp/src/tests/logging.cpp index 700586539f..6b0315da04 100644 --- a/cpp/src/tests/logging.cpp +++ b/cpp/src/tests/logging.cpp @@ -265,7 +265,7 @@ QPID_AUTO_TEST_CASE(testOptionsParse) { "--log-thread", "true", "--log-function", "YES" }; - qpid::log::Options opts; + qpid::log::Options opts(""); opts.parse(ARGC(argv), const_cast<char**>(argv)); vector<string> expect=list_of("error+:foo")("debug:bar")("info"); BOOST_CHECK_EQUAL(expect, opts.selectors); @@ -278,7 +278,7 @@ QPID_AUTO_TEST_CASE(testOptionsParse) { } QPID_AUTO_TEST_CASE(testOptionsDefault) { - Options opts; + Options opts(""); vector<string> expect=list_of("stderr"); BOOST_CHECK_EQUAL(expect, opts.outputs); expect=list_of("error+"); @@ -294,7 +294,7 @@ QPID_AUTO_TEST_CASE(testSelectorFromOptions) { "--log-enable", "debug:bar", "--log-enable", "info" }; - qpid::log::Options opts; + qpid::log::Options opts(""); opts.parse(ARGC(argv), const_cast<char**>(argv)); vector<string> expect=list_of("error+:foo")("debug:bar")("info"); BOOST_CHECK_EQUAL(expect, opts.selectors); @@ -309,7 +309,7 @@ QPID_AUTO_TEST_CASE(testSelectorFromOptions) { QPID_AUTO_TEST_CASE(testOptionsFormat) { Logger l; { - Options opts; + Options opts(""); BOOST_CHECK_EQUAL(Logger::TIME|Logger::LEVEL, l.format(opts)); const char* argv[]={ 0, @@ -323,7 +323,7 @@ QPID_AUTO_TEST_CASE(testOptionsFormat) { Logger::FILE|Logger::LINE|Logger::THREAD, l.format(opts)); } { - Options opts; // Clear. + Options opts(""); // Clear. const char* argv[]={ 0, "--log-level", "no", @@ -341,7 +341,7 @@ QPID_AUTO_TEST_CASE(testOptionsFormat) { QPID_AUTO_TEST_CASE(testLoggerConfigure) { Logger& l=Logger::instance(); l.clear(); - Options opts; + Options opts("test"); const char* argv[]={ 0, "--log-time", "no", @@ -350,7 +350,7 @@ QPID_AUTO_TEST_CASE(testLoggerConfigure) { "--log-enable", "critical" }; opts.parse(ARGC(argv), const_cast<char**>(argv)); - l.configure(opts, "test"); + l.configure(opts); QPID_LOG(critical, "foo"); int srcline=__LINE__; ifstream log("logging.tmp"); string line; @@ -364,11 +364,11 @@ QPID_AUTO_TEST_CASE(testLoggerConfigure) { QPID_AUTO_TEST_CASE(testQuoteNonPrintable) { Logger& l=Logger::instance(); l.clear(); - Options opts; + Options opts("test"); opts.outputs.clear(); opts.outputs.push_back("logging.tmp"); opts.time=false; - l.configure(opts, "test"); + l.configure(opts); char s[] = "null\0tab\tspace newline\nret\r\x80\x99\xff"; string str(s, sizeof(s)); QPID_LOG(critical, str); |