[asterisk-scf-commits] asterisk-scf/integration/logger.git branch "master" updated.
Commits to the Asterisk SCF project code repositories
asterisk-scf-commits at lists.digium.com
Fri Sep 24 15:40:14 CDT 2010
branch "master" has been updated
via bc8098b6d7474d80bb183c02acd0af6b30202a61 (commit)
from 2ced70031ce47fa1f4618107207b186cf0580b3a (commit)
Summary of changes:
client/src/CMakeLists.txt | 2 +
client/src/IceConfigurator.cpp | 124 ++++++++++++++++++++++++++++++++++
client/src/IceConfigurator.h | 45 ++++++++++++
client/src/Logger.cpp | 19 ++++-
client/src/LoggerFactory.cpp | 20 ++++++
client/src/logger.h | 10 +++
client/test/CMakeLists.txt | 1 +
client/test/IceConfigurator-test.cpp | 75 ++++++++++++++++++++
ice/LoggerIf.ice | 10 ++--
server/config/logging-server.conf | 3 +
server/src/CMakeLists.txt | 2 +
server/src/LoggingServer.cpp | 23 +++++--
server/src/LoggingServer.h | 4 +-
server/src/main.cpp | 52 ++++++++++++++-
14 files changed, 373 insertions(+), 17 deletions(-)
create mode 100644 client/src/IceConfigurator.cpp
create mode 100644 client/src/IceConfigurator.h
create mode 100644 client/test/IceConfigurator-test.cpp
- Log -----------------------------------------------------------------
commit bc8098b6d7474d80bb183c02acd0af6b30202a61
Author: David M. Lee <dlee at digium.com>
Date: Fri Sep 24 15:37:46 2010 -0500
Server config being pushed to clients.
diff --git a/client/src/CMakeLists.txt b/client/src/CMakeLists.txt
index 8115598..c97df57 100644
--- a/client/src/CMakeLists.txt
+++ b/client/src/CMakeLists.txt
@@ -13,9 +13,11 @@ include_directories(../../common)
hydra_component_add_file(logging-client Logger.cpp)
hydra_component_add_file(logging-client LoggerFactory.cpp)
hydra_component_add_file(logging-client LogOut.cpp)
+hydra_component_add_file(logging-client IceConfigurator.cpp)
hydra_component_add_file(logging-client IceLogger.cpp)
hydra_component_add_file(logging-client OstreamLogger.cpp)
hydra_component_add_file(logging-client logger.h)
+hydra_component_add_file(logging-client IceConfigurator.h)
hydra_component_add_file(logging-client LogOut.h)
hydra_component_add_slice(logging-client LoggerIf)
diff --git a/client/src/IceConfigurator.cpp b/client/src/IceConfigurator.cpp
new file mode 100644
index 0000000..50aff27
--- /dev/null
+++ b/client/src/IceConfigurator.cpp
@@ -0,0 +1,124 @@
+/*
+ * Asterisk Scalable Communications Framework
+ *
+ * Copyright (C) 2010 -- Digium, Inc.
+ *
+ * All rights reserved.
+ */
+
+#include <Ice/Ice.h>
+#include <IceStorm/IceStorm.h>
+
+#include "IceConfigurator.h"
+
+using namespace AsteriskSCF::System::Logging;
+
+namespace
+{
+/**
+ * For sorting SourceConfiguration's.
+ * @param lhs Left hand side.
+ * @param rhs Right hand side.
+ * @return True, if lhs < rhs.
+ */
+bool operator<(SourceConfiguration const &lhs, SourceConfiguration const &rhs)
+{
+ return lhs.name < rhs.name;
+}
+}
+
+void IceConfigurator::configured(Configuration const &logConfiguration,
+ Ice::Current const &)
+{
+ return configured(logConfiguration);
+}
+
+void IceConfigurator::configured(Configuration const &logConfiguration)
+{
+ std::vector<std::string> oldConfig = factory.getLoggerNames();
+ SourceConfigurationSeq newConfig = logConfiguration.sourceSettings;
+
+ // processing is easier if lists are sorted
+ std::sort(oldConfig.begin(), oldConfig.end());
+ std::sort(newConfig.begin(), newConfig.end());
+
+ SourceConfigurationSeq::const_iterator newConfigIter =
+ logConfiguration.sourceSettings.begin();
+ std::vector<std::string>::const_iterator oldConfigIter = oldConfig.begin();
+
+ while (newConfigIter != logConfiguration.sourceSettings.end()
+ || oldConfigIter != oldConfig.end())
+ {
+ int cmp;
+
+ if (newConfigIter == logConfiguration.sourceSettings.end())
+ {
+ // we ran out of new config; unset the rest of the old config
+ // new[end] < old
+ cmp = 1;
+ }
+ else if (oldConfigIter == oldConfig.end())
+ {
+ // we ran out of the old config; set rest of the new config
+ // new > old[end]
+ cmp = -1;
+ }
+ else
+ {
+ // compare the names
+ cmp = newConfigIter->name.compare(*oldConfigIter);
+ }
+
+ if (cmp < 0)
+ {
+ // apply a new config
+ factory.getLogger(newConfigIter->name).setLevel(
+ newConfigIter->logLevel);
+ ++newConfigIter;
+ }
+ else if (cmp == 0)
+ {
+ // change an old config
+ factory.getLogger(newConfigIter->name).setLevel(
+ newConfigIter->logLevel);
+ ++newConfigIter;
+ ++oldConfigIter;
+ }
+ else // if (cmp > 0)
+ {
+ factory.getLogger(*oldConfigIter).unsetLevel();
+ ++oldConfigIter;
+ }
+ }
+}
+
+IceConfiguratorPtr AsteriskSCF::System::Logging::createIceConfigurator(
+Ice::ObjectAdapterPtr adapter, LoggerFactory &factory)
+{
+Ice::CommunicatorPtr communicator = adapter->getCommunicator();
+
+try
+{
+ IceStorm::TopicManagerPrx topicManager =
+ IceStorm::TopicManagerPrx::checkedCast(communicator->propertyToProxy(
+ "TopicManager.Proxy"));
+
+ if (topicManager)
+ {
+ IceStorm::TopicPrx topic = topicManager->retrieve(
+ ServerConfigurationTopic);
+ IceConfiguratorPtr r = new IceConfigurator(factory);
+ Ice::ObjectPrx proxy = adapter->addWithUUID(r)->ice_oneway();
+ topic->subscribeAndGetPublisher(IceStorm::QoS(), proxy);
+ adapter->activate();
+ return r;
+ }
+}
+catch (std::exception const &e)
+{
+ std::clog << "Error registering with IceStorm: " << e.what() << '\n';
+}
+
+std::clog << "IceStorm not available. Cannot listen to config events.\n";
+return IceConfiguratorPtr();
+}
diff --git a/client/src/IceConfigurator.h b/client/src/IceConfigurator.h
new file mode 100644
index 0000000..9b584a0
--- /dev/null
+++ b/client/src/IceConfigurator.h
@@ -0,0 +1,45 @@
+/*
+ * Asterisk Scalable Communications Framework
+ *
+ * Copyright (C) 2010 -- Digium, Inc.
+ *
+ * All rights reserved.
+ */
+
+#pragma once
+
+#include "logger.h"
+
+namespace AsteriskSCF
+{
+namespace System
+{
+namespace Logging
+{
+
+/**
+ * Listens for configuration events from the server, and updates the
+ * Logger appropriately.
+ */
+class IceConfigurator : public ServerConfigurationListener
+{
+public:
+ IceConfigurator(LoggerFactory &factory) :
+ factory(factory)
+ {
+ }
+
+ void configured(Configuration const &logConfiguration, Ice::Current const &);
+ void configured(Configuration const &logConfiguration);
+private:
+ LoggerFactory &factory;
+};
+
+typedef IceUtil::Handle<IceConfigurator> IceConfiguratorPtr;
+
+IceConfiguratorPtr createIceConfigurator(Ice::ObjectAdapterPtr adapter,
+ LoggerFactory &factory);
+
+} // Logging
+} // System
+} // AsteriskSCF
diff --git a/client/src/Logger.cpp b/client/src/Logger.cpp
index a058d7a..bbe2d6a 100644
--- a/client/src/Logger.cpp
+++ b/client/src/Logger.cpp
@@ -52,15 +52,14 @@ void LogBuf::sendBuffer()
out.logs(name, logLevel, message);
}
-
Logger::Logger(std::string const &name, LogOut &out, Level logLevel) :
parent(0), name(name), out(out), logLevel(logLevel), inheritedLevel(false)
{
}
Logger::Logger(Logger const &parent, std::string const &name) :
- parent(&parent), name(name), out(parent.out), logLevel(Off),
- inheritedLevel(true)
+ parent(&parent), name(name), out(parent.out), logLevel(Off), inheritedLevel(
+ true)
{
// our name must begin w/ parent's name
assert(name.find(parent.name) == 0);
@@ -139,8 +138,20 @@ Logger &Logger::getChild(std::string const &childName)
if (child == 0)
{
std::string fullName = getName().empty() ? childName : getName() + "."
- + childName;
+ + childName;
child = new Logger(*this, fullName);
}
return *child;
}
+
+std::vector<Logger const *> Logger::getChildren() const
+{
+ std::vector<Logger const *> r;
+ for (std::map<std::string, Logger *>::const_iterator i = children.begin(); i
+ != children.end(); ++i)
+ {
+ r.push_back(i->second);
+ }
+ return r;
+}
+
diff --git a/client/src/LoggerFactory.cpp b/client/src/LoggerFactory.cpp
index eb7ad36..9865f3c 100644
--- a/client/src/LoggerFactory.cpp
+++ b/client/src/LoggerFactory.cpp
@@ -66,3 +66,23 @@ Logger &LoggerFactory::getLogger(std::string const &name)
return *logger;
}
+
+std::vector<std::string> LoggerFactory::getLoggerNames() const
+{
+ std::vector<std::string> r;
+ accumulateLoggerNames(root, r);
+ return r;
+}
+
+void LoggerFactory::accumulateLoggerNames(Logger const &logger, std::vector<
+ std::string> &out)
+{
+ out.push_back(logger.getName());
+ // recurse through the children
+ std::vector<Logger const *> const &children = logger.getChildren();
+ for (std::vector<Logger const *>::const_iterator i = children.begin(); i
+ != children.end(); ++i)
+ {
+ accumulateLoggerNames(**i, out);
+ }
+}
diff --git a/client/src/logger.h b/client/src/logger.h
index 1fdac36..f790e3e 100644
--- a/client/src/logger.h
+++ b/client/src/logger.h
@@ -168,6 +168,7 @@ public:
}
Logger &getChild(std::string const &childName);
+ std::vector<Logger const *> getChildren() const;
std::string const &getName() const
{
@@ -242,15 +243,24 @@ public:
*
* @param name Name of the Logger to be retrieved.
* @return Ref to the Logger.
+ * @thread-safe
*/
Logger &getLogger(std::string const &name);
+ /**
+ * Returns a vector of the names of all currently configured Logger's.
+ * @return Vector of Logger names.
+ */
+ std::vector<std::string> getLoggerNames() const;
+
private:
/**
* LogOut for new Logger's.
*/
LogOut &out;
Logger root;
+
+ static void accumulateLoggerNames(Logger const &logger, std::vector<std::string> &out);
};
std::auto_ptr<LogOut> buildOstreamLogger(std::ostream &out);
diff --git a/client/test/CMakeLists.txt b/client/test/CMakeLists.txt
index 4ea9102..b4c198b 100644
--- a/client/test/CMakeLists.txt
+++ b/client/test/CMakeLists.txt
@@ -14,6 +14,7 @@ include_directories(../../common)
hydra_component_add_file(logging-client-test Logger-test.cpp)
hydra_component_add_file(logging-client-test LoggerFactory-test.cpp)
hydra_component_add_file(logging-client-test LogBuf-test.cpp)
+hydra_component_add_file(logging-client-test IceConfigurator-test.cpp)
hydra_component_add_file(logging-client-test client-test.cpp)
hydra_component_add_boost_libraries(logging-client-test unit_test_framework)
diff --git a/client/test/IceConfigurator-test.cpp b/client/test/IceConfigurator-test.cpp
new file mode 100644
index 0000000..d612959
--- /dev/null
+++ b/client/test/IceConfigurator-test.cpp
@@ -0,0 +1,75 @@
+/*
+ * Asterisk Scalable Communications Framework
+ *
+ * Copyright (C) 2010 -- Digium, Inc.
+ *
+ * All rights reserved.
+ */
+
+
+#include <boost/test/unit_test.hpp>
+
+#include "ExpectedLogOut.h"
+#include "IceConfigurator.h"
+
+using namespace AsteriskSCF::System::Logging;
+
+namespace
+{
+void addConfig(Configuration &cfg, std::string const &name, Level logLevel)
+{
+ SourceConfiguration sourceConfig = {};
+ sourceConfig.name = name;
+ sourceConfig.logLevel = logLevel;
+
+ cfg.sourceSettings.push_back(sourceConfig);
+}
+}
+
+BOOST_AUTO_TEST_SUITE(IceConfiguratorTest)
+
+BOOST_AUTO_TEST_CASE(test_simple)
+{
+ ExpectedLogOut out("");
+ LoggerFactory factory(out);
+ IceConfigurator uut(factory);
+
+ Configuration cfg;
+ addConfig(cfg, "", Error);
+ addConfig(cfg, "AsteriskSCF", Info);
+ addConfig(cfg, "AsteriskSCF.Core", Debug);
+ addConfig(cfg, "AsteriskSCF.Media", Off);
+
+ uut.configured(cfg);
+
+ BOOST_CHECK_EQUAL(Error, factory.getLogger("").getEffectiveLevel());
+ BOOST_CHECK_EQUAL(Info, factory.getLogger("AsteriskSCF").getEffectiveLevel());
+ BOOST_CHECK_EQUAL(Debug, factory.getLogger("AsteriskSCF.Core").getEffectiveLevel());
+ BOOST_CHECK_EQUAL(Off, factory.getLogger("AsteriskSCF.Media").getEffectiveLevel());
+}
+
+
+BOOST_AUTO_TEST_CASE(test_reset)
+{
+ ExpectedLogOut out("");
+ LoggerFactory factory(out);
+ IceConfigurator uut(factory);
+
+ Configuration cfg;
+ addConfig(cfg, "", Error);
+ addConfig(cfg, "AsteriskSCF", Info);
+ addConfig(cfg, "AsteriskSCF.Core", Debug);
+ addConfig(cfg, "AsteriskSCF.Media", Off);
+ uut.configured(cfg);
+
+ cfg.sourceSettings.clear();
+ addConfig(cfg, "", Critical);
+ uut.configured(cfg);
+
+ BOOST_CHECK_EQUAL(Critical, factory.getLogger("").getEffectiveLevel());
+ BOOST_CHECK_EQUAL(Critical, factory.getLogger("AsteriskSCF").getEffectiveLevel());
+ BOOST_CHECK_EQUAL(Critical, factory.getLogger("AsteriskSCF.Core").getEffectiveLevel());
+ BOOST_CHECK_EQUAL(Critical, factory.getLogger("AsteriskSCF.Media").getEffectiveLevel());
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/ice/LoggerIf.ice b/ice/LoggerIf.ice
index 939adf1..2e38815 100644
--- a/ice/LoggerIf.ice
+++ b/ice/LoggerIf.ice
@@ -24,6 +24,10 @@ const string LoggingServerCategory = "LoggingServer";
* ServiceLocator.
*/
const string LoggingServerGuid = "LoggingServer";
+/**
+ * Topic name for configuration updates.
+ */
+const string ServerConfigurationTopic = "AsteriskSCF.System.Logging.config";
/**
* Warning levels, inspired by syslog.
@@ -96,17 +100,13 @@ interface LoggingServer
idempotent Configuration getConfiguration();
};
-/**
- * Topic name for configuration updates.
- */
-const string ServerConfigurationTopic = "AsteriskSCF.System.Logging.config";
/**
* Topic interface for notification of Configuration changes.
*/
interface ServerConfigurationListener
{
- void configured(LoggingServer *server, Configuration logConfiguration);
+ void configured(Configuration logConfiguration);
};
}; // Logging
diff --git a/server/config/logging-server.conf b/server/config/logging-server.conf
index faf6ba4..a601ad9 100644
--- a/server/config/logging-server.conf
+++ b/server/config/logging-server.conf
@@ -6,6 +6,9 @@ AsteriskSCF.LoggingService.Endpoints=default
# A proxy to the service locator management service
ServiceLocatorManagement.Proxy=LocatorServiceManagement:tcp -p 4422
+# A proxy to the IceStorm topic manager
+TopicManager.Proxy=HydraIceStorm/TopicManager:default -p 10000
+
# Log levels
AsteriskSCF.Logging.logger=Error
AsteriskSCF.Logging.logger.AsteriskSCF=Info
\ No newline at end of file
diff --git a/server/src/CMakeLists.txt b/server/src/CMakeLists.txt
index 3df642d..fb49ccb 100644
--- a/server/src/CMakeLists.txt
+++ b/server/src/CMakeLists.txt
@@ -16,6 +16,8 @@ hydra_component_add_slice(logging-service ServiceLocatorIf)
hydra_component_add_file(logging-service LoggingServer.cpp)
hydra_component_add_file(logging-service main.cpp)
+hydra_add_ice_libraries(IceStorm)
+
hydra_component_build_standalone(logging-service)
hydra_component_install(logging-service RUNTIME bin "Logging Service" System)
diff --git a/server/src/LoggingServer.cpp b/server/src/LoggingServer.cpp
index f8392c4..f3c72d1 100644
--- a/server/src/LoggingServer.cpp
+++ b/server/src/LoggingServer.cpp
@@ -69,9 +69,17 @@ Level LoggingServerI::getEffectiveLevel(std::string const &name) const
void LoggingServerI::setLevel(std::string const &name, Level level)
{
- // thread safety
- IceUtil::Mutex::Lock sourcesLock(sourcesMutex);
- sources[name].setLevel(level);
+ {
+ // thread safety. getConfiguration needs the lock, so we need to release
+ // it prior to that call.
+ IceUtil::Mutex::Lock sourcesLock(sourcesMutex);
+ sources[name].setLevel(level);
+ }
+
+ if (configurationListener)
+ {
+ configurationListener->configured(getConfiguration());
+ }
}
void LoggingServerI::logs(std::string const &name, Level level,
@@ -95,7 +103,8 @@ Configuration LoggingServerI::getConfiguration() const
for (Sources::const_reverse_iterator i = sources.rbegin(); i
!= sources.rend(); ++i)
{
- SourceConfiguration v = {};
+ SourceConfiguration v =
+ { };
v.name = i->first;
v.logLevel = i->second.getLevel();
r.sourceSettings.push_back(v);
@@ -149,8 +158,12 @@ bool LoggingServerI::isSubpathOf(std::string const &path,
// <prefix>.logger=level
// <prefix>.logger.<name>=level
-void LoggingServerI::configure(Ice::PropertiesPtr props)
+void LoggingServerI::configure(
+ ServerConfigurationListenerPrx configurationListener,
+ Ice::PropertiesPtr props)
{
+ this->configurationListener = configurationListener;
+
Ice::PropertyDict myProps = props->getPropertiesForPrefix(
LoggingPropertyPrefix);
diff --git a/server/src/LoggingServer.h b/server/src/LoggingServer.h
index c7427e9..1c2505f 100644
--- a/server/src/LoggingServer.h
+++ b/server/src/LoggingServer.h
@@ -67,7 +67,7 @@ public:
Level getEffectiveLevel(std::string const &name) const;
void setLevel(std::string const &name, Level level);
- void configure(Ice::PropertiesPtr props);
+ void configure(ServerConfigurationListenerPrx configurationListener, Ice::PropertiesPtr props);
static const std::string LoggingPropertyPrefix;
@@ -93,6 +93,8 @@ private:
IceUtil::Mutex sourcesMutex;
IceUtil::Mutex outputMutex;
Sources sources;
+
+ ServerConfigurationListenerPrx configurationListener;
};
} // Logging
diff --git a/server/src/main.cpp b/server/src/main.cpp
index 0b1f494..9abb626 100644
--- a/server/src/main.cpp
+++ b/server/src/main.cpp
@@ -8,6 +8,7 @@
#include <Ice/Properties.h>
#include <Ice/Service.h>
+#include <IceStorm/IceStorm.h>
#include "Core/Discovery/ServiceLocatorIf.h"
@@ -51,7 +52,8 @@ void LoggingServerDaemon::registerWithServiceLocator(
communicator()->stringToProxy(locatorManagementProxyString));
serviceManagement = management->addService(serverProxy,
LoggingServerGuid);
- ServiceLocatorParamsPtr params = new ServiceLocatorParams(LoggingServerCategory);
+ ServiceLocatorParamsPtr params = new ServiceLocatorParams(
+ LoggingServerCategory);
serviceManagement->addLocatorParams(params, "");
}
}
@@ -84,8 +86,54 @@ bool LoggingServerDaemon::start(int argc, char *argv[], int &status)
adapter = communicator()->createObjectAdapter(AdapterName);
+ ServerConfigurationListenerPrx configurationListener;
+
+ try
+ {
+ IceStorm::TopicManagerPrx topicManager =
+ IceStorm::TopicManagerPrx::checkedCast(
+ communicator()->propertyToProxy("TopicManager.Proxy"));
+
+ if (topicManager)
+ {
+ IceStorm::TopicPrx topic;
+ while (!topic)
+ {
+ try
+ {
+ topic = topicManager->retrieve(ServerConfigurationTopic);
+ }
+ catch (IceStorm::NoSuchTopic const &e)
+ {
+ try
+ {
+ topic = topicManager->create(ServerConfigurationTopic);
+ }
+ catch (IceStorm::TopicExists const &e)
+ {
+ // we had a race to create the object w/ someone else
+ // and lost
+ }
+ }
+ }
+ configurationListener = ServerConfigurationListenerPrx::uncheckedCast(
+ topic->getPublisher()->ice_oneway());
+ }
+ else
+ {
+ std::clog
+ << "IceStorm unavailable. Cannot send configuration updates.\n";
+ }
+ }
+ catch (std::exception const &e)
+ {
+ std::clog << "Failed to contact ServiceLocator: ";
+ std::clog << e.what() << '\n';
+ }
+
IceUtil::Handle<LoggingServerI> server = new LoggingServerI;
- server->configure(communicator()->getProperties());
+ server->configure(ServerConfigurationListenerPrx(),
+ communicator()->getProperties());
LoggingServerPrx serverProxy = LoggingServerPrx::uncheckedCast(
adapter->addWithUUID(server));
-----------------------------------------------------------------------
--
asterisk-scf/integration/logger.git
More information about the asterisk-scf-commits
mailing list