summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Burrows <Daniel Burrows Daniel_Burrows@alumni.brown.edu>2010-05-25 00:36:16 -0700
committerDaniel Burrows <Daniel Burrows Daniel_Burrows@alumni.brown.edu>2010-05-25 00:36:16 -0700
commitce774ca21fb572579e02e39f900bc531e682d239 (patch)
treefa4ed777dabdebf24d0e93acd58dfdfc51050fb5 /src
parent335f355d491fb507486d00f6c86f321c7f8bc095 (diff)
downloadaptitude-ce774ca21fb572579e02e39f900bc531e682d239.tar.gz
Redesign the logging interface so that test logging systems can be created.
Since some test code registers itself with the global logging system, I want to be able to create local instances of the logging system in order to verify that it behaves as expected.
Diffstat (limited to 'src')
-rw-r--r--src/generic/util/logging.cc78
-rw-r--r--src/generic/util/logging.h41
2 files changed, 97 insertions, 22 deletions
diff --git a/src/generic/util/logging.cc b/src/generic/util/logging.cc
index ab94384c..4aa7c99b 100644
--- a/src/generic/util/logging.cc
+++ b/src/generic/util/logging.cc
@@ -25,6 +25,7 @@
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/mem_fun.hpp>
+#include <boost/weak_ptr.hpp>
#include <cwidget/generic/threads/threads.h>
@@ -40,6 +41,7 @@ using boost::multi_index::indexed_by;
using boost::multi_index::tag;
using boost::optional;
using boost::shared_ptr;
+using boost::weak_ptr;
using cwidget::threads::mutex;
namespace aptitude
@@ -73,16 +75,22 @@ namespace aptitude
const shared_ptr<Logger::Impl> parent;
+ // We carry a weak pointer to the parent logging system, so
+ // that we can call back into it even if it's not the global
+ // instance.
+ const weak_ptr<LoggingSystem::Impl> loggingSystemWeak;
+
sigc::signal<void, const char *, int, log_level, LoggerPtr, std::string>
signal_message_logged;
static log_level getDefaultLevel() { return ERROR_LEVEL; }
- friend class Logger::LoggingSystem;
+ friend class LoggingSystem;
public:
Impl(const std::string &_category,
- const shared_ptr<Logger::Impl> &_parent);
+ const shared_ptr<Logger::Impl> &_parent,
+ const shared_ptr<LoggingSystem::Impl> &_loggingSystem);
void log(const char *sourceFilename,
int sourceLineNumber,
@@ -105,12 +113,14 @@ namespace aptitude
};
Logger::Impl::Impl(const std::string &_category,
- const shared_ptr<Logger::Impl> &_parent)
+ const shared_ptr<Logger::Impl> &_parent,
+ const shared_ptr<LoggingSystem::Impl> &_loggingSystem)
: Logger(_parent.get() == NULL
? getDefaultLevel()
: _parent->effectiveLevel),
category(_category),
- parent(_parent)
+ parent(_parent),
+ loggingSystemWeak(_loggingSystem)
{
}
@@ -136,12 +146,22 @@ namespace aptitude
return parent;
}
+ LoggingSystem::LoggingSystem()
+ {
+ }
+
+ LoggingSystem::~LoggingSystem()
+ {
+ }
+
/** \brief Wrapper for the state of the logging system.
*
* A singleton class is used to better encapsulate the state
* and to handle lifetime issues properly.
*/
- class Logger::LoggingSystem
+ class LoggingSystem::Impl
+ : public LoggingSystem,
+ public enable_shared_from_this<LoggingSystem::Impl>
{
class by_category_tag;
class by_parent_tag;
@@ -200,11 +220,7 @@ namespace aptitude
recursiveSetEffectiveLevel(*it, effectiveLevel);
}
- LoggingSystem()
- {
- }
-
- LoggingSystem(const LoggingSystem &);
+ Impl(const Impl &);
// Like getLogger, but
// 1. Returns a Logger::Impl instead of a Logger;
@@ -213,6 +229,10 @@ namespace aptitude
shared_ptr<Logger::Impl> doGetLogger(const std::string &category);
public:
+ Impl()
+ {
+ }
+
void setLevel(const shared_ptr<Logger::Impl> &category,
const optional<log_level> &level);
@@ -223,16 +243,23 @@ namespace aptitude
log_level logLevel,
const std::string &msg);
- static LoggingSystem &get()
+ /** \brief Get the implicit global logging system. */
+ static Impl &get()
{
- static LoggingSystem system;
+ static boost::shared_ptr<Impl> system = boost::make_shared<Impl>();
+
+ return *system;
+ }
- return system;
+ /** \brief Create a new logging system. */
+ static shared_ptr<Impl> create()
+ {
+ return make_shared<Impl>();
}
};
- void Logger::LoggingSystem::setLevel(const shared_ptr<Logger::Impl> &category,
- const optional<log_level> &level)
+ void LoggingSystem::Impl::setLevel(const shared_ptr<Logger::Impl> &category,
+ const optional<log_level> &level)
{
mutex::lock l(loggers_mutex);
@@ -259,7 +286,7 @@ namespace aptitude
recursiveSetEffectiveLevel(category, newEffectiveLevel);
}
- LoggerPtr Logger::LoggingSystem::getLogger(const std::string &category)
+ LoggerPtr LoggingSystem::Impl::getLogger(const std::string &category)
{
mutex::lock l(loggers_mutex);
@@ -267,7 +294,7 @@ namespace aptitude
}
shared_ptr<Logger::Impl>
- Logger::LoggingSystem::doGetLogger(const std::string &category)
+ LoggingSystem::Impl::doGetLogger(const std::string &category)
{
by_category_index &by_category = loggers.get<by_category_tag>();
@@ -296,16 +323,20 @@ namespace aptitude
}
shared_ptr<Logger::Impl> rval =
- make_shared<Logger::Impl>(category, parent);
+ make_shared<Logger::Impl>(category, parent, shared_from_this());
loggers.insert(rval);
return rval;
}
- void Logger::Impl::setLevel(const optional <log_level> &value)
+ void Logger::Impl::setLevel(const optional<log_level> &value)
{
- LoggingSystem::get().setLevel(shared_from_this(), value);
+ boost::shared_ptr<LoggingSystem::Impl> loggingSystem =
+ loggingSystemWeak.lock();
+
+ if(loggingSystem.get() != NULL)
+ loggingSystem->setLevel(shared_from_this(), value);
}
sigc::connection
@@ -332,7 +363,12 @@ namespace aptitude
LoggerPtr Logger::getLogger(const std::string &category)
{
- return LoggingSystem::get().getLogger(category);
+ return LoggingSystem::Impl::get().getLogger(category);
+ }
+
+ boost::shared_ptr<LoggingSystem> createLoggingSystem()
+ {
+ return LoggingSystem::Impl::create();
}
}
}
diff --git a/src/generic/util/logging.h b/src/generic/util/logging.h
index bcf0c927..e6fcb339 100644
--- a/src/generic/util/logging.h
+++ b/src/generic/util/logging.h
@@ -65,6 +65,8 @@ namespace aptitude
class Logger;
typedef boost::shared_ptr<Logger> LoggerPtr;
+ class LoggingSystem;
+
/** \brief A logger is used to log messages in a particular
* category in conjunction with the LOG_*() macros below.
*/
@@ -78,9 +80,9 @@ namespace aptitude
log_level effectiveLevel;
class Impl;
- class LoggingSystem;
Logger(log_level _effectiveLevel);
+ Logger(const Logger &);
// Logger is really just an interface to the hidden
// LoggingSystem singleton. For organizational reasons and to
@@ -193,6 +195,43 @@ namespace aptitude
#define LOG_WARN(logger, msg) LOG_LEVEL(::aptitude::util::logging::WARN_LEVEL, msg)
#define LOG_ERROR(logger, msg) LOG_LEVEL(::aptitude::util::logging::ERROR_LEVEL, msg)
#define LOG_FATAL(logger, msg) LOG_LEVEL(::aptitude::util::logging::FATAL_LEVEL, msg)
+
+ /** \brief Represents the entire logging system.
+ *
+ * This class is exposed primarily for use with tests: to test
+ * the logging system itself, you really need to be able to
+ * create a local one that no-one else will mess with.
+ *
+ * That said, this is a representation of an entire logging
+ * system. It keeps track of which loggers are available and
+ * provides a routine for creating them that's equivalent to
+ * Logger::getLogger.
+ */
+ class LoggingSystem
+ {
+ class Impl;
+ friend class Logger;
+
+ LoggingSystem();
+ LoggingSystem(const LoggingSystem &);
+
+ friend boost::shared_ptr<LoggingSystem> createLoggingSystem();
+
+ public:
+ virtual ~LoggingSystem();
+
+ /** \brief Retrieve a logger for the given category.
+ *
+ * The returned logger is the only logger for that category
+ * within this logging system, but will be distinct from
+ * loggers created in any other logging system (including the
+ * global one managed by Logger::getLogger).
+ */
+ virtual LoggerPtr getLogger(const std::string &category) = 0;
+ };
+
+ /** \brief Create a new, local logging system. */
+ boost::shared_ptr<LoggingSystem> createLoggingSystem();
}
}
}