summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/qpid/client/Connection.cpp3
-rw-r--r--cpp/src/qpid/client/ConnectionSettings.cpp7
-rw-r--r--cpp/src/qpid/client/ConnectionSettings.h6
-rw-r--r--cpp/src/qpid/log/Logger.cpp29
-rw-r--r--cpp/src/qpid/log/Logger.h7
-rw-r--r--cpp/src/qpid/log/Options.cpp112
-rw-r--r--cpp/src/qpid/log/Options.h17
-rw-r--r--cpp/src/qpidd.cpp11
-rw-r--r--cpp/src/tests/TestOptions.h2
-rw-r--r--cpp/src/tests/logging.cpp18
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);