You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by sh...@apache.org on 2008/10/16 00:33:35 UTC
svn commit: r705083 - in /incubator/qpid/trunk/qpid/cpp: docs/man/ src/
src/qpid/ src/qpid/log/ src/qpid/log/posix/ src/tests/
Author: shuston
Date: Wed Oct 15 15:33:34 2008
New Revision: 705083
URL: http://svn.apache.org/viewvc?rev=705083&view=rev
Log:
Split logging options into portable options and sink-related options that are platform-specific. Re-did sink options for Posix as discussed on qpid-dev (no more --log-output, but more specific --log-to-<target> options. Allows addition of Windows options without further reorg of Posix code.
Added:
incubator/qpid/trunk/qpid/cpp/src/qpid/log/OstreamOutput.cpp
incubator/qpid/trunk/qpid/cpp/src/qpid/log/OstreamOutput.h
incubator/qpid/trunk/qpid/cpp/src/qpid/log/SinkOptions.h
incubator/qpid/trunk/qpid/cpp/src/qpid/log/posix/
incubator/qpid/trunk/qpid/cpp/src/qpid/log/posix/SinkOptions.cpp
incubator/qpid/trunk/qpid/cpp/src/qpid/log/posix/SinkOptions.h
Modified:
incubator/qpid/trunk/qpid/cpp/docs/man/qpidd.x
incubator/qpid/trunk/qpid/cpp/src/Makefile.am
incubator/qpid/trunk/qpid/cpp/src/qpid/Plugin.h
incubator/qpid/trunk/qpid/cpp/src/qpid/log/Logger.cpp
incubator/qpid/trunk/qpid/cpp/src/qpid/log/Logger.h
incubator/qpid/trunk/qpid/cpp/src/qpid/log/Options.cpp
incubator/qpid/trunk/qpid/cpp/src/qpid/log/Options.h
incubator/qpid/trunk/qpid/cpp/src/qpidd.cpp
incubator/qpid/trunk/qpid/cpp/src/tests/logging.cpp
incubator/qpid/trunk/qpid/cpp/src/tests/start_broker
incubator/qpid/trunk/qpid/cpp/src/tests/start_cluster
incubator/qpid/trunk/qpid/cpp/src/tests/start_cluster_hosts
Modified: incubator/qpid/trunk/qpid/cpp/docs/man/qpidd.x
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/docs/man/qpidd.x?rev=705083&r1=705082&r2=705083&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/docs/man/qpidd.x (original)
+++ incubator/qpid/trunk/qpid/cpp/docs/man/qpidd.x Wed Oct 15 15:33:34 2008
@@ -28,8 +28,8 @@
# My qpidd configuration file.
port=6000
max-connections=10
- log-output=stdout
- log-output=/tmp/qpidd.log
+ log-to-stdout=yes
+ log-to-file=/tmp/qpidd.log
[ENVIRONMENT]
.I QPID_<option>
@@ -41,6 +41,6 @@
export QPID_PORT=6000
export QPID_MAX_CONNECTIONS=10
- export QPID_LOG_OUTPUT=/tmp/qpidd.log
+ export QPID_LOG_TO_FILE=/tmp/qpidd.log
Modified: incubator/qpid/trunk/qpid/cpp/src/Makefile.am
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/Makefile.am?rev=705083&r1=705082&r2=705083&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/Makefile.am (original)
+++ incubator/qpid/trunk/qpid/cpp/src/Makefile.am Wed Oct 15 15:33:34 2008
@@ -68,6 +68,7 @@
qpidd_SOURCES = qpidd.cpp
posix_plat_src = \
+ qpid/log/posix/SinkOptions.cpp \
qpid/sys/posix/IOHandle.cpp \
qpid/sys/posix/Socket.cpp \
qpid/sys/posix/AsynchIO.cpp \
@@ -83,6 +84,7 @@
qpid/sys/posix/PollableCondition.cpp
posix_plat_hdr = \
+ qpid/log/posix/SinkOptions.h \
qpid/sys/posix/check.h \
qpid/sys/posix/Condition.h \
qpid/sys/posix/PrivatePosix.h \
@@ -117,15 +119,6 @@
include qmf.mk
include xml.mk
-# The logger library uses boost::date_time to format time.
-# We have to disable the unused parameters warning to get around
-# unused parameters in boost::date_time headers. So we build it
-# in a convenience library to link into libqpid_common.
-#
-noinst_LTLIBRARIES=libLogger.la # libqpidamqp_0_10.la
-libLogger_la_SOURCES=qpid/log/Logger.cpp qpid/log/Logger.h
-libLogger_la_CXXFLAGS=$(AM_CXXFLAGS) -Wno-unused-parameter
-
if RDMA
# RDMA (Infiniband) protocol code
@@ -222,19 +215,28 @@
-lboost_program_options \
-lboost_filesystem \
-luuid \
- libLogger.la \
$(LIB_DLOPEN) \
$(LIB_CLOCK_GETTIME)
libqpidcommon_la_SOURCES = \
$(rgen_framing_srcs) \
$(platform_src) \
- qpid/amqp_0_10/SessionHandler.h \
- qpid/amqp_0_10/SessionHandler.cpp \
+ qpid/assert.cpp qpid/assert.h \
+ qpid/pointer_to_other.h \
+ qpid/DataDir.cpp \
+ qpid/Exception.cpp \
+ qpid/Options.cpp \
+ qpid/Plugin.cpp \
+ qpid/RefCountedBuffer.h \
+ qpid/RefCountedBuffer.cpp \
qpid/Serializer.h \
qpid/SessionState.h \
qpid/SessionState.cpp \
qpid/SessionId.cpp \
+ qpid/StringUtils.cpp \
+ qpid/Url.cpp \
+ qpid/amqp_0_10/SessionHandler.h \
+ qpid/amqp_0_10/SessionHandler.cpp \
qpid/framing/AccumulatedAck.cpp \
qpid/framing/AMQBody.cpp \
qpid/framing/AMQMethodBody.cpp \
@@ -262,11 +264,11 @@
qpid/framing/Blob.cpp \
qpid/framing/MaxMethodBodySize.h \
qpid/framing/TransferContent.cpp \
- qpid/assert.cpp qpid/assert.h \
- qpid/Exception.cpp \
- qpid/Plugin.cpp \
- qpid/StringUtils.cpp \
- qpid/Url.cpp \
+ qpid/log/Logger.cpp \
+ qpid/log/Options.cpp \
+ qpid/log/OstreamOutput.cpp \
+ qpid/log/Selector.cpp \
+ qpid/log/Statement.cpp \
qpid/management/Manageable.cpp \
qpid/management/ManagementObject.cpp \
qpid/sys/AggregateOutput.cpp \
@@ -275,15 +277,7 @@
qpid/sys/PollableCondition.h \
qpid/sys/PollableQueue.h \
qpid/sys/Runnable.cpp \
- qpid/sys/Shlib.cpp \
- qpid/DataDir.cpp \
- qpid/Options.cpp \
- qpid/log/Options.cpp \
- qpid/RefCountedBuffer.h \
- qpid/RefCountedBuffer.cpp \
- qpid/log/Selector.cpp \
- qpid/log/Statement.cpp \
- qpid/pointer_to_other.h
+ qpid/sys/Shlib.cpp
libqpidbroker_la_LIBADD = libqpidcommon.la -luuid
if HAVE_SASL
@@ -578,7 +572,9 @@
qpid/log/Helpers.h \
qpid/log/Options.h \
qpid/log/Logger.h \
+ qpid/log/OstreamOutput.h \
qpid/log/Selector.h \
+ qpid/log/SinkOptions.h \
qpid/log/Statement.h \
qpid/management/Args.h \
qpid/management/Manageable.h \
Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/Plugin.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/Plugin.h?rev=705083&r1=705082&r2=705083&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/Plugin.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/Plugin.h Wed Oct 15 15:33:34 2008
@@ -28,7 +28,7 @@
/**@file Generic plug-in framework. */
namespace qpid {
-class Options;
+struct Options;
/**
* Plug-in base class.
Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/log/Logger.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/log/Logger.cpp?rev=705083&r1=705082&r2=705083&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/log/Logger.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/log/Logger.cpp Wed Oct 15 15:33:34 2008
@@ -17,18 +17,17 @@
*/
#include "Logger.h"
+#include "Options.h"
+#include "SinkOptions.h"
#include "qpid/memory.h"
#include "qpid/sys/Thread.h"
#include <boost/pool/detail/singleton.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
-#include <boost/scoped_ptr.hpp>
#include <algorithm>
#include <sstream>
-#include <fstream>
#include <iomanip>
#include <stdexcept>
-#include <syslog.h>
#include <time.h>
@@ -43,45 +42,6 @@
s->enabled=selector.isEnabled(s->level, s->function);
}
-struct OstreamOutput : public Logger::Output {
- OstreamOutput(std::ostream& o) : out(&o) {}
-
- OstreamOutput(const string& file)
- : out(new ofstream(file.c_str(), ios_base::out | ios_base::app)),
- mine(out)
- {
- if (!out->good())
- throw std::runtime_error("Can't open log file: "+file);
- }
-
- void log(const Statement&, const std::string& m) {
- *out << m << flush;
- }
-
- ostream* out;
- boost::scoped_ptr<ostream> mine;
-};
-
-struct SyslogOutput : public Logger::Output {
- SyslogOutput(const Options& opts)
- : name(opts.syslogName), facility(opts.syslogFacility.value)
- {
- ::openlog(name.c_str(), LOG_PID, facility);
- }
-
- ~SyslogOutput() {
- ::closelog();
- }
-
- void log(const Statement& s, const std::string& m)
- {
- syslog(LevelTraits::priority(s.level), "%s", m.c_str());
- }
-
- std::string name;
- int facility;
-};
-
Logger& Logger::instance() {
return boost::details::pool::singleton_default<Logger>::instance();
}
@@ -158,25 +118,6 @@
outputs.push_back(out.release());
}
-void Logger::output(std::ostream& out) {
- output(make_auto_ptr<Output>(new OstreamOutput(out)));
-}
-
-void Logger::syslog(const Options& opts) {
- output(make_auto_ptr<Output>(new SyslogOutput(opts)));
-}
-
-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(opts);
- else
- output(make_auto_ptr<Output>(new OstreamOutput(name)));
-}
-
void Logger::clear() {
select(Selector()); // locked
format(0); // locked
@@ -218,10 +159,8 @@
o.selectors.push_back("trace+");
format(o);
select(Selector(o));
- void (Logger::* outputFn)(const std::string&, const Options&) = &Logger::output;
- for_each(o.outputs.begin(), o.outputs.end(),
- boost::bind(outputFn, this, _1, boost::cref(o)));
setPrefix(opts.prefix);
+ options.sinkOptions->setup(this);
}
void Logger::setPrefix(const std::string& p) { prefix = p; }
Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/log/Logger.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/log/Logger.h?rev=705083&r1=705082&r2=705083&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/log/Logger.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/log/Logger.h Wed Oct 15 15:33:34 2008
@@ -26,15 +26,25 @@
* Central logging agent.
*
* Thread safe, singleton.
+ *
+ * The Logger provides all needed functionality for selecting and
+ * formatting logging output. The actual outputting of log records
+ * is handled by Logger::Output-derived classes instantiated by the
+ * platform's sink-related options.
*/
class 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};
- /** Interface for log output destination.
- *
- * Implementations must be thread safe.
+ /**
+ * Logging output sink.
+ *
+ * The Output sink provides an interface to direct logging output to.
+ * Logging sinks are primarily platform-specific as provided for on
+ * each platform.
+ *
+ * Implementations of Output must be thread safe.
*/
class Output {
public:
@@ -43,7 +53,7 @@
/** Receives the statemnt of origin and formatted message to log. */
virtual void log(const Statement&, const std::string&) =0;
};
-
+
static Logger& instance();
Logger();
@@ -69,25 +79,8 @@
/** Log a message. */
void log(const Statement&, const std::string&);
- /** Add an ostream to outputs.
- *
- * The ostream must not be destroyed while the Logger might
- * still be using it. This is the case for std streams cout,
- * cerr, clog.
- */
- void output(std::ostream&);
-
- /** Add syslog to outputs. */
- 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, const Options&);
-
/** Add an output destination for messages */
- void output(std::auto_ptr<Output> out);
+ void output(std::auto_ptr<Output> out);
/** Set a prefix for all messages */
void setPrefix(const std::string& prefix);
Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/log/Options.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/log/Options.cpp?rev=705083&r1=705082&r2=705083&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/log/Options.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/log/Options.cpp Wed Oct 15 15:33:34 2008
@@ -17,115 +17,38 @@
*/
#include "Options.h"
+#include "SinkOptions.h"
#include "Statement.h"
#include "qpid/Options.h"
#include <map>
#include <string>
#include <algorithm>
-#include <syslog.h>
namespace qpid {
namespace log {
using namespace std;
-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)
+Options::Options(const std::string& argv0_, const std::string& name_) :
+ qpid::Options(name_),
+ argv0(argv0_),
+ name(name_),
+ time(true),
+ level(true),
+ thread(false),
+ source(false),
+ function(false),
+ trace(false),
+ sinkOptions (SinkOptions::create(argv0_))
{
- outputs.push_back("stderr");
selectors.push_back("error+");
ostringstream levels;
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. "
- "FILE can be a file name or one of the special values:\n"
- "stderr, stdout, syslog")
("trace,t", optValue(trace), "Enables all logging" )
("log-enable", optValue(selectors, "RULE"),
("Enables logging for selected levels and components. "
@@ -143,24 +66,40 @@
("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-prefix", optValue(prefix,"STRING"), "Prefix to append to all 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")
;
+ add(*sinkOptions);
+}
+
+Options::Options(const Options &o) :
+ qpid::Options(o.name),
+ argv0(o.argv0),
+ name(o.name),
+ selectors(o.selectors),
+ time(o.time),
+ level(o.level),
+ thread(o.thread),
+ source(o.source),
+ function(o.function),
+ trace(o.trace),
+ prefix(o.prefix),
+ sinkOptions (SinkOptions::create(o.argv0))
+{
+ *sinkOptions = *o.sinkOptions;
}
Options& Options::operator=(const Options& x) {
if (this != &x) {
+ argv0 = x.argv0;
+ name = x.name;
selectors = x.selectors;
- outputs = x.outputs;
time = x.time;
level= x.level;
thread = x.thread;
source = x.source;
function = x.function;
trace = x.trace;
- syslogName = x.syslogName;
- syslogFacility = x.syslogFacility;
prefix = x.prefix;
+ *sinkOptions = *x.sinkOptions;
}
return *this;
}
Modified: incubator/qpid/trunk/qpid/cpp/src/qpid/log/Options.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/log/Options.h?rev=705083&r1=705082&r2=705083&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/log/Options.h (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/log/Options.h Wed Oct 15 15:33:34 2008
@@ -1,5 +1,5 @@
-#ifndef OPTIONS_H
-#define OPTIONS_H
+#ifndef QPID_LOG_OPTIONS_H
+#define QPID_LOG_OPTIONS_H
/*
*
@@ -19,40 +19,31 @@
*
*/
#include "qpid/Options.h"
+#include "SinkOptions.h"
#include <iosfwd>
+#include <memory>
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 {
/** Pass argv[0] for use in syslog output */
- Options(const std::string& argv0=std::string(),
- const std::string& name="Logging options");
+ Options(const std::string& argv0_=std::string(),
+ const std::string& name_="Logging options");
+ Options(const Options &);
Options& operator=(const Options&);
+ std::string argv0;
+ std::string name;
std::vector<std::string> selectors;
- std::vector<std::string> outputs;
bool time, level, thread, source, function;
bool trace;
- std::string syslogName;
- SyslogFacility syslogFacility;
std::string prefix;
+ std::auto_ptr<SinkOptions> sinkOptions;
};
-
}} // namespace qpid::log
-
-
-#endif /*!OPTIONS_H*/
+#endif /*!QPID_LOG_OPTIONS_H*/
Added: incubator/qpid/trunk/qpid/cpp/src/qpid/log/OstreamOutput.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/log/OstreamOutput.cpp?rev=705083&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/log/OstreamOutput.cpp (added)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/log/OstreamOutput.cpp Wed Oct 15 15:33:34 2008
@@ -0,0 +1,41 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "OstreamOutput.h"
+#include <stdexcept>
+
+using namespace std;
+
+namespace qpid {
+namespace log {
+
+OstreamOutput::OstreamOutput(std::ostream& o) : out(&o) {}
+
+OstreamOutput::OstreamOutput(const std::string& file)
+ : out(new ofstream(file.c_str(), ios_base::out | ios_base::app)),
+ mine(out)
+{
+ if (!out->good())
+ throw std::runtime_error("Can't open log file: "+file);
+}
+
+void OstreamOutput::log(const Statement&, const std::string& m) {
+ *out << m << flush;
+}
+
+}} // namespace qpid::log
Added: incubator/qpid/trunk/qpid/cpp/src/qpid/log/OstreamOutput.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/log/OstreamOutput.h?rev=705083&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/log/OstreamOutput.h (added)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/log/OstreamOutput.h Wed Oct 15 15:33:34 2008
@@ -0,0 +1,41 @@
+#ifndef QPID_LOG_OSTREAMOUTPUT_H
+#define QPID_LOG_OSTREAMOUTPUT_H
+
+/*
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "Logger.h"
+#include <boost/scoped_ptr.hpp>
+#include <fstream>
+#include <ostream>
+
+namespace qpid {
+namespace log {
+
+/**
+ * OstreamOutput is a reusable logging sink that directs logging to a C++
+ * ostream.
+ */
+class OstreamOutput : public qpid::log::Logger::Output {
+public:
+ OstreamOutput(std::ostream& o);
+ OstreamOutput(const std::string& file);
+
+ virtual void log(const Statement&, const std::string& m);
+
+private:
+ std::ostream* out;
+ boost::scoped_ptr<std::ostream> mine;
+};
+
+}} // namespace qpid::log
+
+#endif /*!QPID_LOG_OSTREAMOUTPUT_H*/
Added: incubator/qpid/trunk/qpid/cpp/src/qpid/log/SinkOptions.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/log/SinkOptions.h?rev=705083&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/log/SinkOptions.h (added)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/log/SinkOptions.h Wed Oct 15 15:33:34 2008
@@ -0,0 +1,64 @@
+#ifndef QPID_LOG_SINKOPTIONS_H
+#define QPID_LOG_SINKOPTIONS_H
+
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "qpid/Options.h"
+#include <string>
+
+namespace qpid {
+namespace log {
+
+class Logger;
+
+/**
+ * Logging sink options.
+ *
+ * Most logging sink options will be platform-specific, even if some are
+ * duplicated. The range of platforms to which this code may be ported
+ * can't be assumed to all have C++ iostreams or files. Thus, this class
+ * is primarily for implementing in a platform-specific way.
+ */
+struct SinkOptions : public qpid::Options {
+
+ // Create a platform's SinkOptions. Pass argv0 as the program name,
+ // useful for syslog-type logging.
+ static SinkOptions *create(const std::string& argv0=std::string());
+
+ SinkOptions(const std::string& name="Logging sink options")
+ : qpid::Options(name)
+ {}
+ virtual ~SinkOptions() {}
+
+ virtual SinkOptions& operator=(const SinkOptions&) = 0;
+
+ // This allows the caller to indicate that there's no normal outputs
+ // available. For example, when running as a daemon. In these cases, the
+ // platform's "syslog"-type output should replace the default stderr
+ // unless some other sink has been selected.
+ virtual void detached(void) = 0;
+
+ // The Logger acting on these options calls setup() to request any
+ // Sinks be set up and fed back to the logger.
+ virtual void setup(Logger *logger) = 0;
+};
+
+}} // namespace qpid::log
+
+#endif /*!QPID_LOG_OPTIONS_H*/
Added: incubator/qpid/trunk/qpid/cpp/src/qpid/log/posix/SinkOptions.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/log/posix/SinkOptions.cpp?rev=705083&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/log/posix/SinkOptions.cpp (added)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/log/posix/SinkOptions.cpp Wed Oct 15 15:33:34 2008
@@ -0,0 +1,211 @@
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "SinkOptions.h"
+#include "qpid/log/SinkOptions.h"
+#include "qpid/log/Logger.h"
+#include "qpid/log/OstreamOutput.h"
+#include "qpid/memory.h"
+#include "qpid/Exception.h"
+#include <iostream>
+#include <map>
+#include <string>
+#include <syslog.h>
+
+using std::string;
+using qpid::Exception;
+
+namespace {
+
+// SyslogFacilities maps from syslog values to the text equivalents.
+class SyslogFacilities {
+public:
+ typedef std::map<string, int> ByName;
+ typedef std::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;
+};
+
+// 'priorities' maps qpid log levels to syslog priorities. They are in
+// order of qpid log levels and must map to:
+// "trace", "debug", "info", "notice", "warning", "error", "critical"
+static int priorities[qpid::log::LevelTraits::COUNT] = {
+ LOG_DEBUG, LOG_DEBUG, LOG_INFO, LOG_NOTICE,
+ LOG_WARNING, LOG_ERR, LOG_CRIT
+};
+
+std::string basename(const std::string path) {
+ size_t i = path.find_last_of('/');
+ return path.substr((i == std::string::npos) ? 0 : i+1);
+}
+
+} // namespace
+
+namespace qpid {
+namespace log {
+namespace posix {
+
+std::ostream& operator<<(std::ostream& o, const SyslogFacility& f) {
+ return o << SyslogFacilities().name(f.value);
+}
+
+std::istream& operator>>(std::istream& i, SyslogFacility& f) {
+ std::string name;
+ i >> name;
+ f.value = SyslogFacilities().value(name);
+ return i;
+}
+
+class SyslogOutput : public qpid::log::Logger::Output {
+public:
+ SyslogOutput(const std::string& logName, const SyslogFacility& logFacility)
+ : name(logName), facility(logFacility.value)
+ {
+ ::openlog(name.c_str(), LOG_PID, facility);
+ }
+
+ virtual ~SyslogOutput() {
+ ::closelog();
+ }
+
+ virtual void log(const Statement& s, const std::string& m)
+ {
+ syslog(priorities[s.level], "%s", m.c_str());
+ }
+
+private:
+ std::string name;
+ int facility;
+};
+
+SinkOptions::SinkOptions(const std::string& argv0)
+ : qpid::log::SinkOptions(),
+ logToStderr(true),
+ logToStdout(false),
+ logToSyslog(false),
+ syslogName(basename(argv0)),
+ syslogFacility(LOG_DAEMON) {
+
+ addOptions()
+ ("log-to-stderr", optValue(logToStderr, "yes|no"), "Send logging output to stderr")
+ ("log-to-stdout", optValue(logToStdout, "yes|no"), "Send logging output to stdout")
+ ("log-to-file", optValue(logFile, "FILE"), "Send log output to FILE.")
+ ("log-to-syslog", optValue(logToSyslog, "yes|no"), "Send logging output to syslog;\n\tcustomize using --syslog-name and --syslog-facility")
+ ("syslog-name", optValue(syslogName, "NAME"), "Name to use in syslog messages")
+ ("syslog-facility", optValue(syslogFacility,"LOG_XXX"), "Facility to use in syslog messages")
+ ;
+
+}
+
+qpid::log::SinkOptions& SinkOptions::operator=(const qpid::log::SinkOptions& rhs) {
+ const SinkOptions *prhs = dynamic_cast<const SinkOptions*>(&rhs);
+ if (this != prhs) {
+ logToStderr = prhs->logToStderr;
+ logToStdout = prhs->logToStdout;
+ logToSyslog = prhs->logToSyslog;
+ logFile = prhs->logFile;
+ syslogName = prhs->syslogName;
+ syslogFacility.value = prhs->syslogFacility.value;
+ }
+ return *this;
+}
+
+void SinkOptions::detached(void) {
+ if (logToStderr && !logToStdout && !logToSyslog) {
+ logToStderr = false;
+ logToSyslog = true;
+ }
+}
+
+// The Logger acting on these options calls setup() to request any
+// Sinks be set up and fed back to the logger.
+void SinkOptions::setup(qpid::log::Logger *logger) {
+ if (logToStderr)
+ logger->output(make_auto_ptr<qpid::log::Logger::Output>
+ (new qpid::log::OstreamOutput(std::clog)));
+ if (logToStdout)
+ logger->output(make_auto_ptr<qpid::log::Logger::Output>
+ (new qpid::log::OstreamOutput(std::cout)));
+
+ if (logFile.length() > 0)
+ logger->output(make_auto_ptr<qpid::log::Logger::Output>
+ (new qpid::log::OstreamOutput(logFile)));
+
+ if (logToSyslog)
+ logger->output(make_auto_ptr<qpid::log::Logger::Output>
+ (new SyslogOutput(syslogName, syslogFacility)));
+
+}
+
+} // namespace qpid::log::posix
+
+SinkOptions* SinkOptions::create(const std::string& argv0) {
+ return new qpid::log::posix::SinkOptions (argv0);
+}
+
+}} // namespace qpid::log
Added: incubator/qpid/trunk/qpid/cpp/src/qpid/log/posix/SinkOptions.h
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpid/log/posix/SinkOptions.h?rev=705083&view=auto
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpid/log/posix/SinkOptions.h (added)
+++ incubator/qpid/trunk/qpid/cpp/src/qpid/log/posix/SinkOptions.h Wed Oct 15 15:33:34 2008
@@ -0,0 +1,64 @@
+#ifndef QPID_LOG_POSIX_SINKOPTIONS_H
+#define QPID_LOG_POSIX_SINKOPTIONS_H
+
+/*
+ *
+ * Copyright (c) 2006 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "qpid/log/SinkOptions.h"
+#include <string>
+
+namespace qpid {
+namespace log {
+namespace posix {
+
+/**
+ * Provides a type that can be passed to << and >> operators to convert
+ * syslog facility values to/from strings.
+ */
+struct SyslogFacility {
+ int value;
+ SyslogFacility(int i=0) : value(i) {}
+};
+
+struct SinkOptions : public qpid::log::SinkOptions {
+ SinkOptions(const std::string& argv0);
+ virtual ~SinkOptions() {}
+
+ virtual qpid::log::SinkOptions& operator=(const qpid::log::SinkOptions& rhs);
+
+ // This allows the caller to indicate that there's no normal outputs
+ // available. For example, when running as a daemon. In these cases, the
+ // platform's "syslog"-type output should replace the default stderr
+ // unless some other sink has been selected.
+ virtual void detached(void);
+
+ // The Logger acting on these options calls setup() to request any
+ // Sinks be set up and fed back to the logger.
+ virtual void setup(qpid::log::Logger *logger);
+
+ bool logToStderr;
+ bool logToStdout;
+ bool logToSyslog;
+ std::string logFile;
+ std::string syslogName;
+ SyslogFacility syslogFacility;
+};
+
+}}} // namespace qpid::log::posix
+
+#endif /*!QPID_LOG_POSIX_SINKOPTIONS_H*/
Modified: incubator/qpid/trunk/qpid/cpp/src/qpidd.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/qpidd.cpp?rev=705083&r1=705082&r2=705083&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/qpidd.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/qpidd.cpp Wed Oct 15 15:33:34 2008
@@ -229,10 +229,8 @@
// Starting the broker.
if (options->daemon.daemon) {
// For daemon mode replace default stderr with syslog.
- if (options->log.outputs.size() == 1 && options->log.outputs[0] == "stderr") {
- options->log.outputs[0] = "syslog";
- qpid::log::Logger::instance().configure(options->log);
- }
+ options->log.sinkOptions->detached();
+ qpid::log::Logger::instance().configure(options->log);
// Fork the daemon
QpiddDaemon d(options->daemon.piddir);
d.fork(); // Broker is stared in QpiddDaemon::child()
Modified: incubator/qpid/trunk/qpid/cpp/src/tests/logging.cpp
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/tests/logging.cpp?rev=705083&r1=705082&r2=705083&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/tests/logging.cpp (original)
+++ incubator/qpid/trunk/qpid/cpp/src/tests/logging.cpp Wed Oct 15 15:33:34 2008
@@ -19,8 +19,13 @@
#include "test_tools.h"
#include "qpid/log/Logger.h"
#include "qpid/log/Options.h"
+#include "qpid/log/OstreamOutput.h"
#include "qpid/memory.h"
#include "qpid/Options.h"
+#if defined (_WIN32)
+#else
+# include "qpid/log/posix/SinkOptions.h"
+#endif
#include <boost/test/floating_point_comparison.hpp>
#include <boost/format.hpp>
@@ -179,7 +184,7 @@
ScopedSuppressLogging ls(l);
l.select(Selector(error));
ostringstream os;
- l.output(os);
+ l.output(qpid::make_auto_ptr<Logger::Output>(new OstreamOutput(os)));
QPID_LOG(error, "foo");
QPID_LOG(error, "bar");
QPID_LOG(error, "baz");
@@ -257,19 +262,22 @@
"--log-enable", "error+:foo",
"--log-enable", "debug:bar",
"--log-enable", "info",
- "--log-output", "x",
- "--log-output", "y",
+ "--log-to-stderr", "no",
+ "--log-to-file", "logout",
"--log-level", "yes",
"--log-source", "1",
"--log-thread", "true",
"--log-function", "YES"
};
qpid::log::Options opts("");
+ qpid::log::posix::SinkOptions sinks("test");
opts.parse(ARGC(argv), const_cast<char**>(argv));
+ sinks = *opts.sinkOptions;
vector<string> expect=list_of("error+:foo")("debug:bar")("info");
BOOST_CHECK_EQUAL(expect, opts.selectors);
- expect=list_of("x")("y");
- BOOST_CHECK_EQUAL(expect, opts.outputs);
+ BOOST_CHECK(!sinks.logToStderr);
+ BOOST_CHECK(!sinks.logToStdout);
+ BOOST_CHECK(sinks.logFile == "logout");
BOOST_CHECK(opts.level);
BOOST_CHECK(opts.source);
BOOST_CHECK(opts.function);
@@ -278,9 +286,12 @@
QPID_AUTO_TEST_CASE(testOptionsDefault) {
Options opts("");
- vector<string> expect=list_of("stderr");
- BOOST_CHECK_EQUAL(expect, opts.outputs);
- expect=list_of("error+");
+ qpid::log::posix::SinkOptions sinks("test");
+ sinks = *opts.sinkOptions;
+ BOOST_CHECK(sinks.logToStderr);
+ BOOST_CHECK(!sinks.logToStdout);
+ BOOST_CHECK(sinks.logFile.length() == 0);
+ vector<string> expect=list_of("error+");
BOOST_CHECK_EQUAL(expect, opts.selectors);
BOOST_CHECK(opts.time && opts.level);
BOOST_CHECK(!(opts.source || opts.function || opts.thread));
@@ -313,7 +324,8 @@
0,
"--log-time", "no",
"--log-source", "yes",
- "--log-output", "logging.tmp",
+ "--log-to-stderr", "no",
+ "--log-to-file", "logging.tmp",
"--log-enable", "critical"
};
opts.parse(ARGC(argv), const_cast<char**>(argv));
@@ -332,10 +344,13 @@
Logger& l=Logger::instance();
ScopedSuppressLogging ls(l);
Options opts("test");
- opts.outputs.clear();
- opts.outputs.push_back("logging.tmp");
opts.time=false;
+ qpid::log::posix::SinkOptions *sinks =
+ dynamic_cast<qpid::log::posix::SinkOptions *>(opts.sinkOptions.get());
+ sinks->logToStderr = false;
+ sinks->logFile = "logging.tmp";
l.configure(opts);
+
char s[] = "null\0tab\tspace newline\nret\r\x80\x99\xff";
string str(s, sizeof(s));
QPID_LOG(critical, str);
Modified: incubator/qpid/trunk/qpid/cpp/src/tests/start_broker
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/tests/start_broker?rev=705083&r1=705082&r2=705083&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/tests/start_broker (original)
+++ incubator/qpid/trunk/qpid/cpp/src/tests/start_broker Wed Oct 15 15:33:34 2008
@@ -1,4 +1,4 @@
#!/bin/sh
# Start a test broker.
srcdir=`dirname $0`
-exec $srcdir/run_test ../qpidd --auth=no --no-module-dir --daemon --port=0 --log-output qpidd.log "$@" > qpidd.port
+exec $srcdir/run_test ../qpidd --auth=no --no-module-dir --daemon --port=0 --log-to-file qpidd.log "$@" > qpidd.port
Modified: incubator/qpid/trunk/qpid/cpp/src/tests/start_cluster
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/tests/start_cluster?rev=705083&r1=705082&r2=705083&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/tests/start_cluster (original)
+++ incubator/qpid/trunk/qpid/cpp/src/tests/start_cluster Wed Oct 15 15:33:34 2008
@@ -16,10 +16,10 @@
if test "$SIZE" = "one"; then # Special case of singleton cluster, use default port.
../qpidd -q
- with_ais_group ../qpidd $OPTS --log-output=cluster.log || exit 1
+ with_ais_group ../qpidd $OPTS --log-to-file=cluster.log || exit 1
else
for (( i=0; i<SIZE; ++i )); do
- PORT=`with_ais_group ../qpidd -p0 --log-output=cluster$i.log $OPTS` || exit 1
+ PORT=`with_ais_group ../qpidd -p0 --log-to-file=cluster$i.log $OPTS` || exit 1
echo $PORT >> cluster.ports
done
fi
Modified: incubator/qpid/trunk/qpid/cpp/src/tests/start_cluster_hosts
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/cpp/src/tests/start_cluster_hosts?rev=705083&r1=705082&r2=705083&view=diff
==============================================================================
--- incubator/qpid/trunk/qpid/cpp/src/tests/start_cluster_hosts (original)
+++ incubator/qpid/trunk/qpid/cpp/src/tests/start_cluster_hosts Wed Oct 15 15:33:34 2008
@@ -37,7 +37,7 @@
test -z "$CLUSTER" && { echo Must specify at least one host; exit 1; }
-OPTS="-d $PORTOPT --load-module $LIBQPIDCLUSTER --cluster-name=$NAME --no-data-dir --auth=no --log-output=syslog --log-enable=info+"
+OPTS="-d $PORTOPT --load-module $LIBQPIDCLUSTER --cluster-name=$NAME --no-data-dir --auth=no --log-to-syslog --log-enable=info+"
num=0
for h in $CLUSTER; do