diff options
author | Daniel Burrows <Daniel Burrows Daniel_Burrows@alumni.brown.edu> | 2010-05-25 00:36:16 -0700 |
---|---|---|
committer | Daniel Burrows <Daniel Burrows Daniel_Burrows@alumni.brown.edu> | 2010-05-25 00:36:16 -0700 |
commit | ce774ca21fb572579e02e39f900bc531e682d239 (patch) | |
tree | fa4ed777dabdebf24d0e93acd58dfdfc51050fb5 /src | |
parent | 335f355d491fb507486d00f6c86f321c7f8bc095 (diff) | |
download | aptitude-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.cc | 78 | ||||
-rw-r--r-- | src/generic/util/logging.h | 41 |
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(); } } } |