[asterisk-scf-commits] asterisk-scf/integration/log4scf.git branch "master" created.

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Tue Sep 21 10:42:40 CDT 2010


branch "master" has been created
        at  53d97ac8fa9b68aafeb73ca5dc8bbbd2bdeb5d74 (commit)

- Log -----------------------------------------------------------------
commit 53d97ac8fa9b68aafeb73ca5dc8bbbd2bdeb5d74
Author: David M. Lee <dlee at digium.com>
Date:   Tue Sep 21 10:40:23 2010 -0500

    Comments

diff --git a/client/src/logger.h b/client/src/logger.h
index 0df0750..b03dbb7 100644
--- a/client/src/logger.h
+++ b/client/src/logger.h
@@ -100,6 +100,9 @@ public:
       inheritedLevel = true;
    }
 
+   /**
+    * Returns the effective level of this Logger.
+    */
    Level getEffectiveLevel() const
    {
       if (inheritedLevel == true && parent != 0)

commit 7eeaa53a4b462d9089fe9767d552a7d46bb33136
Author: David M. Lee <dlee at digium.com>
Date:   Tue Sep 21 09:39:24 2010 -0500

    Removed getLevel() from Logger.  Could be confusing.

diff --git a/client/src/logger.h b/client/src/logger.h
index b54c4e5..0df0750 100644
--- a/client/src/logger.h
+++ b/client/src/logger.h
@@ -100,11 +100,6 @@ public:
       inheritedLevel = true;
    }
 
-   Level getLevel() const
-   {
-      return logLevel;
-   }
-
    Level getEffectiveLevel() const
    {
       if (inheritedLevel == true && parent != 0)
@@ -113,7 +108,7 @@ public:
       }
       else
       {
-         return getLevel();
+         return logLevel;
       }
    }
 

commit 36e5db995d663d9d6f68cedcf9cd8a6b17c5e628
Author: David M. Lee <dlee at digium.com>
Date:   Tue Sep 21 09:14:27 2010 -0500

    Added singleton for LoggerFactory.  Made Level/ostream stuff common for client and server.  Got rid of SourceNode on client.

diff --git a/client/src/CMakeLists.txt b/client/src/CMakeLists.txt
index fc5964a..18ee4f1 100644
--- a/client/src/CMakeLists.txt
+++ b/client/src/CMakeLists.txt
@@ -8,6 +8,8 @@
 
 hydra_component_init(logging-client CXX)
 
+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 IceLogger.cpp)
diff --git a/client/src/IceLogger.cpp b/client/src/IceLogger.cpp
index bcfceb4..a669ad7 100644
--- a/client/src/IceLogger.cpp
+++ b/client/src/IceLogger.cpp
@@ -33,7 +33,7 @@ private:
 
 }
 
-std::auto_ptr<LogOut> buildIceLogger(LoggingServerPrx const &server)
+std::auto_ptr<LogOut> AsteriskSCF::System::Logging::buildIceLogger(LoggingServerPrx const &server)
 {
    return std::auto_ptr<LogOut>(new IceLogger(server));
 }
diff --git a/client/src/LoggerFactory.cpp b/client/src/LoggerFactory.cpp
index 826d26b..5ea4689 100644
--- a/client/src/LoggerFactory.cpp
+++ b/client/src/LoggerFactory.cpp
@@ -21,19 +21,6 @@
 using namespace AsteriskSCF::System::Logging;
 using namespace boost::algorithm;
 
-SourceNode &SourceNode::getChild(std::string const &name)
-{
-   // ref to ptr allows us to update the map in-place
-   SourceNode *&child = children[name];
-   if (child == 0)
-   {
-      std::string childName = logger.getName().empty() ? name
-         : logger.getName() + "." + name;
-      child = new SourceNode(childName, logger);
-   }
-   return *child;
-}
-
 LoggerFactory::LoggerFactory(LogOut &out) :
    out(out), root("", out)
 {
@@ -44,11 +31,18 @@ Logger &LoggerFactory::getLogger(std::string const &source)
    std::vector<std::string> path;
    split(path, source, std::bind1st(std::equal_to<char>(), '.'));
 
-   SourceNode *node = &root;
+   Logger *logger = &root;
    for (std::vector<std::string>::iterator i = path.begin(); i != path.end(); ++i)
    {
-      node = &node->getChild(*i);
+      logger = &logger->getChild(*i);
    }
 
-   return node->getLogger();
+   return *logger;
+}
+
+LoggerFactory &AsteriskSCF::System::Logging::getLoggerFactory()
+{
+   static std::auto_ptr<LogOut> stdout = buildOstreamLogger(std::cout);
+   static LoggerFactory singleton(*stdout);
+   return singleton;
 }
diff --git a/client/src/logger.cpp b/client/src/logger.cpp
index 60fb66f..f84c992 100644
--- a/client/src/logger.cpp
+++ b/client/src/logger.cpp
@@ -59,3 +59,16 @@ void Logger::vlogf(Level level, char const *fmt, va_list ap) const
       }
    }
 }
+
+Logger &Logger::getChild(std::string const &childName)
+{
+   // ref to ptr allows us to update the map in-place
+   Logger *&child = children[childName];
+   if (child == 0)
+   {
+      std::string fullName = getName().empty() ? childName
+         : getName() + "." + childName;
+      child = new Logger(*this, fullName);
+   }
+   return *child;
+}
diff --git a/client/src/logger.h b/client/src/logger.h
index f648e40..b54c4e5 100644
--- a/client/src/logger.h
+++ b/client/src/logger.h
@@ -13,6 +13,7 @@
 #include <memory>
 
 #include "log4scf.h"
+#include "Level.h"
 
 namespace AsteriskSCF
 {
@@ -20,36 +21,6 @@ namespace System
 {
 namespace Logging
 {
-
-/**
- * Helper to readably output Level.
- */
-inline std::ostream &operator<<(std::ostream &o, Level level)
-{
-   switch (level)
-   {
-   case Debug:
-      return o << "Debug";
-   case Info:
-      return o << "Info";
-   case Notice:
-      return o << "Notice";
-   case Warning:
-      return o << "Warning";
-   case Error:
-      return o << "Error";
-   case Critical:
-      return o << "Critical";
-   case Alert:
-      return o << "Alert";
-   case Emergency:
-      return o << "Emergency";
-   case Off:
-      return o << "Off";
-   }
-   return o << "Unknown(" << level << ")";
-}
-
 /**
  * Interface abstracting how the logs actually get written.
  */
@@ -123,6 +94,12 @@ public:
       inheritedLevel = false;
    }
 
+   void unsetLevel()
+   {
+      logLevel = Off;
+      inheritedLevel = true;
+   }
+
    Level getLevel() const
    {
       return logLevel;
@@ -144,6 +121,7 @@ public:
    {
       return parent;
    }
+   Logger &getChild(std::string const &childName);
 
 private:
    // non-copyable
@@ -151,41 +129,14 @@ private:
    Logger const &operator=(Logger const &);
 
    Logger const *parent;
+   std::map<std::string, Logger *> children;
+
    const std::string name;
    LogOut &out;
    Level logLevel;
    bool inheritedLevel;
 };
 
-class SourceNode
-{
-public:
-   SourceNode(std::string const &name, LogOut &out) :
-      logger(name, out)
-   {
-   }
-
-   SourceNode(std::string const &name, Logger &parent) :
-      logger(parent, name)
-   {
-   }
-
-   Logger &getLogger()
-   {
-      return logger;
-   }
-   Logger const &getLogger() const
-   {
-      return logger;
-   }
-
-   SourceNode &getChild(std::string const &name);
-
-private:
-   Logger logger;
-   std::map<std::string, SourceNode *> children;
-};
-
 /**
  * Main entry point into the Logger system.
  */
@@ -198,12 +149,17 @@ public:
 
 private:
    LogOut &out;
-   SourceNode root;
+   Logger root;
 };
 
 std::auto_ptr<LogOut> buildIceLogger(LoggingServerPrx const &server);
 std::auto_ptr<LogOut> buildOstreamLogger(std::ostream &out);
 
+/**
+ * Returns the default configured LoggerFactory.
+ */
+LoggerFactory &getLoggerFactory();
+
 } // Logging
 } // System
 } // AsteriskSCF
diff --git a/client/test/CMakeLists.txt b/client/test/CMakeLists.txt
index 5c6089d..b7d8bbf 100644
--- a/client/test/CMakeLists.txt
+++ b/client/test/CMakeLists.txt
@@ -8,7 +8,8 @@
 
 hydra_component_init(logging-client-test CXX)
 
-include_directories("../src")
+include_directories(../src)
+include_directories(../../common)
 
 hydra_component_add_file(logging-client-test Logger-test.cpp)
 hydra_component_add_file(logging-client-test LoggerFactory-test.cpp)
@@ -22,3 +23,11 @@ hydra_component_build_standalone(logging-client-test)
 target_link_libraries(logging-client-test logging-client)
 
 boost_add_test(logging-client-test)
+
+hydra_component_init(scf-log CXX)
+
+hydra_component_add_file(scf-log scf-log.cpp)
+hydra_component_add_slice(scf-log log4scf)
+
+hydra_component_build_standalone(scf-log)
+target_link_libraries(scf-log logging-client)
diff --git a/client/test/scf-log.cpp b/client/test/scf-log.cpp
new file mode 100644
index 0000000..058ea03
--- /dev/null
+++ b/client/test/scf-log.cpp
@@ -0,0 +1,45 @@
+/*
+ * Asterisk Scalable Communications Framework
+ *
+ * Copyright (C) 2010 -- Digium, Inc.
+ *
+ * All rights reserved.
+ */
+
+#include <Ice/Ice.h>
+
+#include "logger.h"
+
+using namespace AsteriskSCF::System::Logging;
+
+int main(int argc, char *argv[])
+{
+   int status = 0;
+   Ice::CommunicatorPtr ic;
+   try
+   {
+      ic = Ice::initialize(argc, argv);
+      Ice::ObjectPrx base = ic->stringToProxy("LoggingServer:default -p 10000");
+      LoggingServerPrx logger = LoggingServerPrx::checkedCast(base);
+      if (!logger)
+         throw "Invalid proxy";
+
+      std::auto_ptr<LogOut> logOut = buildIceLogger(logger);
+      LoggerFactory factory(*logOut);
+
+      factory.getLogger("AsteriskSCF.System.Logger").logs(Debug, "Hello, Asterisk-SCF");
+   }
+   catch (const Ice::Exception& ex)
+   {
+      std::cerr << ex << '\n';
+      status = 1;
+   }
+   catch (const char* msg)
+   {
+      std::cerr << msg << '\n';
+      status = 1;
+   }
+   if (ic)
+      ic->destroy();
+   return status;
+}
diff --git a/common/Level.h b/common/Level.h
new file mode 100644
index 0000000..855d95c
--- /dev/null
+++ b/common/Level.h
@@ -0,0 +1,53 @@
+/*
+ * Asterisk Scalable Communications Framework
+ *
+ * Copyright (C) 2010 -- Digium, Inc.
+ *
+ * All rights reserved.
+ */
+
+#pragma once
+
+#include <ostream>
+
+#include "log4scf.h"
+
+namespace AsteriskSCF
+{
+namespace System
+{
+namespace Logging
+{
+
+/**
+ * Helper to readably output Level.
+ */
+inline std::ostream &operator<<(std::ostream &o, Level level)
+{
+   switch (level)
+   {
+   case Debug:
+      return o << "Debug";
+   case Info:
+      return o << "Info";
+   case Notice:
+      return o << "Notice";
+   case Warning:
+      return o << "Warning";
+   case Error:
+      return o << "Error";
+   case Critical:
+      return o << "Critical";
+   case Alert:
+      return o << "Alert";
+   case Emergency:
+      return o << "Emergency";
+   case Off:
+      return o << "Off";
+   }
+   return o << "Unknown(" << level << ")";
+}
+
+} // Logging
+} // System
+} // AsteriskSCF
diff --git a/server/src/CMakeLists.txt b/server/src/CMakeLists.txt
index 1934045..2e6f0b4 100644
--- a/server/src/CMakeLists.txt
+++ b/server/src/CMakeLists.txt
@@ -8,6 +8,8 @@
 
 hydra_component_init(logging-service CXX)
 
+include_directories(../../common)
+
 hydra_component_add_slice(logging-service log4scf)
 
 hydra_component_add_file(logging-service LoggingServer.cpp)
diff --git a/server/src/LoggingServer.cpp b/server/src/LoggingServer.cpp
index 0b5116e..3f2813e 100644
--- a/server/src/LoggingServer.cpp
+++ b/server/src/LoggingServer.cpp
@@ -6,7 +6,10 @@
  * All rights reserved.
  */
 
+#include <iomanip>
+
 #include "LoggingServer.h"
+#include "Level.h"
 
 using namespace AsteriskSCF::System::Logging;
 
@@ -81,8 +84,8 @@ void LoggingServerI::logs(std::string const &source, Level level,
          lastDot = 0;
       }
       std::string lastSource = source.substr(lastDot + 1);
-      std::cout << getCurrentTime() << ' ' << level << ' ' << lastSource << ' '
-            << message << '\n';
+      std::cout << getCurrentTime() << ' ' << std::setw(9) << level << ' '
+            << std::setw(9) << lastSource << ' ' << message << '\n';
    }
 }
 
diff --git a/server/test/CMakeLists.txt b/server/test/CMakeLists.txt
index ae01df5..992ed7b 100644
--- a/server/test/CMakeLists.txt
+++ b/server/test/CMakeLists.txt
@@ -8,7 +8,8 @@
 
 hydra_component_init(logging-service-test CXX)
 
-include_directories("../src")
+include_directories(../src)
+include_directories(../../common)
 
 hydra_component_add_slice(logging-service-test log4scf)
 

commit 16d08d810c47caa7aca32903b38d4f3529c09b19
Author: David M. Lee <dlee at digium.com>
Date:   Mon Sep 20 20:56:15 2010 -0500

    Client reasonably complete.

diff --git a/client/src/CMakeLists.txt b/client/src/CMakeLists.txt
index 38beaf7..fc5964a 100644
--- a/client/src/CMakeLists.txt
+++ b/client/src/CMakeLists.txt
@@ -8,6 +8,12 @@
 
 hydra_component_init(logging-client CXX)
 
-add_library(logging-client Logger.cpp LoggerFactory.cpp OstreamLogger.cpp logger.h)
+hydra_component_add_file(logging-client Logger.cpp)
+hydra_component_add_file(logging-client LoggerFactory.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_slice(logging-client log4scf)
+
+hydra_component_build_library(logging-client)
diff --git a/client/src/IceLogger.cpp b/client/src/IceLogger.cpp
index 0bc028a..bcfceb4 100644
--- a/client/src/IceLogger.cpp
+++ b/client/src/IceLogger.cpp
@@ -19,7 +19,6 @@ public:
    IceLogger(LoggingServerPrx const &server) :
       server(server)
    {
-
    }
 
    void logs(std::string const &source, Level logLevel,
diff --git a/client/src/LoggerFactory.cpp b/client/src/LoggerFactory.cpp
index b479dd7..826d26b 100644
--- a/client/src/LoggerFactory.cpp
+++ b/client/src/LoggerFactory.cpp
@@ -21,13 +21,25 @@
 using namespace AsteriskSCF::System::Logging;
 using namespace boost::algorithm;
 
+SourceNode &SourceNode::getChild(std::string const &name)
+{
+   // ref to ptr allows us to update the map in-place
+   SourceNode *&child = children[name];
+   if (child == 0)
+   {
+      std::string childName = logger.getName().empty() ? name
+         : logger.getName() + "." + name;
+      child = new SourceNode(childName, logger);
+   }
+   return *child;
+}
+
 LoggerFactory::LoggerFactory(LogOut &out) :
-   out(out),
-   root("", out)
+   out(out), root("", out)
 {
 }
 
-Logger const &LoggerFactory::getLogger(std::string const &source)
+Logger &LoggerFactory::getLogger(std::string const &source)
 {
    std::vector<std::string> path;
    split(path, source, std::bind1st(std::equal_to<char>(), '.'));
diff --git a/client/src/OstreamLogger.cpp b/client/src/OstreamLogger.cpp
index 9f1aab4..7579645 100644
--- a/client/src/OstreamLogger.cpp
+++ b/client/src/OstreamLogger.cpp
@@ -34,7 +34,7 @@ private:
 
 }
 
-std::auto_ptr<LogOut> buildStdoutLogger(std::ostream &out)
+std::auto_ptr<LogOut> AsteriskSCF::System::Logging::buildOstreamLogger(std::ostream &out)
 {
    return std::auto_ptr<LogOut>(new OstreamLogger(out));
 }
diff --git a/client/src/logger.h b/client/src/logger.h
index a5d642b..f648e40 100644
--- a/client/src/logger.h
+++ b/client/src/logger.h
@@ -68,9 +68,18 @@ class Logger
 {
 public:
    Logger(std::string const &name, LogOut &out, Level logLevel = Debug) :
-      name(name), out(out), logLevel(logLevel)
+      parent(0), name(name), out(out), logLevel(logLevel),
+            inheritedLevel(false)
    {
    }
+
+   Logger(Logger const &parent, std::string const &name) :
+      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);
+   }
    virtual ~Logger();
 
    /**
@@ -81,7 +90,7 @@ public:
     */
    bool isEnabledFor(Level level) const
    {
-      return logLevel <= level;
+      return level >= getEffectiveLevel();
    }
 
    /**
@@ -108,10 +117,44 @@ public:
       return out;
    }
 
+   void setLevel(Level logLevel)
+   {
+      this->logLevel = logLevel;
+      inheritedLevel = false;
+   }
+
+   Level getLevel() const
+   {
+      return logLevel;
+   }
+
+   Level getEffectiveLevel() const
+   {
+      if (inheritedLevel == true && parent != 0)
+      {
+         return parent->getEffectiveLevel();
+      }
+      else
+      {
+         return getLevel();
+      }
+   }
+
+   Logger const *getParent() const
+   {
+      return parent;
+   }
+
 private:
+   // non-copyable
+   Logger(Logger const &);
+   Logger const &operator=(Logger const &);
+
+   Logger const *parent;
    const std::string name;
    LogOut &out;
    Level logLevel;
+   bool inheritedLevel;
 };
 
 class SourceNode
@@ -122,6 +165,11 @@ public:
    {
    }
 
+   SourceNode(std::string const &name, Logger &parent) :
+      logger(parent, name)
+   {
+   }
+
    Logger &getLogger()
    {
       return logger;
@@ -131,17 +179,7 @@ public:
       return logger;
    }
 
-   SourceNode &getChild(std::string const &name)
-   {
-      // ref to ptr allows us to update the map in-place
-      SourceNode *&child = children[name];
-      if (child == 0)
-      {
-         child = new SourceNode(logger.getName() + "." + name,
-                                logger.getOutput());
-      }
-      return *child;
-   }
+   SourceNode &getChild(std::string const &name);
 
 private:
    Logger logger;
@@ -156,7 +194,7 @@ class LoggerFactory
 public:
    LoggerFactory(LogOut &out);
 
-   Logger const &getLogger(std::string const &source);
+   Logger &getLogger(std::string const &source);
 
 private:
    LogOut &out;
diff --git a/client/test/CMakeLists.txt b/client/test/CMakeLists.txt
index 08f8d29..5c6089d 100644
--- a/client/test/CMakeLists.txt
+++ b/client/test/CMakeLists.txt
@@ -10,11 +10,15 @@ hydra_component_init(logging-client-test CXX)
 
 include_directories("../src")
 
-add_executable(logging-client-test Logger-test.cpp client-test.cpp)
+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 client-test.cpp)
 
-target_link_libraries(logging-client-test logging-client)
 hydra_component_add_boost_libraries(logging-client-test unit_test_framework)
 
 hydra_component_add_slice(logging-client-test log4scf)
 
+hydra_component_build_standalone(logging-client-test)
+target_link_libraries(logging-client-test logging-client)
+
 boost_add_test(logging-client-test)
diff --git a/client/test/LogStream-test.cpp b/client/test/LogStream-test.cpp
deleted file mode 100644
index a7c4c4e..0000000
--- a/client/test/LogStream-test.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Asterisk Scalable Communications Framework
- *
- * Copyright (C) 2010 -- Digium, Inc.
- *
- * All rights reserved.
- */
-
-#include <boost/test/unit_test.hpp>
-
-#include "logger.h"
-
-using namespace AsteriskSCF::System::Logging;
-
-BOOST_AUTO_TEST_SUITE( LogStreamTest )
-
-BOOST_AUTO_TEST_CASE( test_enabled )
-{
-   std::stringstream o;
-   LogStream uut(o, true);
-
-   uut << "Hello, log4scf\n";
-   BOOST_CHECK_EQUAL("Hello, log4scf\n", o.str());
-}
-
-BOOST_AUTO_TEST_CASE( test_disabled )
-{
-   std::stringstream o;
-   LogStream uut(o, false);
-
-   uut << "Hello, log4scf\n";
-   BOOST_CHECK_EQUAL("", o.str());
-}
-
-BOOST_AUTO_TEST_SUITE_END()
diff --git a/client/test/LoggerFactory-test.cpp b/client/test/LoggerFactory-test.cpp
index f6918eb..110d541 100644
--- a/client/test/LoggerFactory-test.cpp
+++ b/client/test/LoggerFactory-test.cpp
@@ -6,7 +6,6 @@
  * All rights reserved.
  */
 
-
 #include <boost/test/unit_test.hpp>
 
 #include "logger.h"
@@ -18,13 +17,45 @@ BOOST_AUTO_TEST_SUITE(LoggerFactoryTest)
 BOOST_AUTO_TEST_CASE(testGetDistinct)
 {
    std::stringstream tmp;
-   RefOstreamFactory streamFactory(tmp);
-   LoggerFactory uut(streamFactory);
+   std::auto_ptr<LogOut> logOut = buildOstreamLogger(tmp);
+   LoggerFactory uut(*logOut);
 
-   Logger asteriskScf = uut.getLogger("AsteriskSCF");
-   Logger core = uut.getLogger("AsteriskSCF.Core");
+   Logger const &asteriskScf = uut.getLogger("AsteriskSCF");
+   Logger const &core = uut.getLogger("AsteriskSCF.Core");
 
    BOOST_CHECK_NE(&core, &asteriskScf);
+   BOOST_CHECK_EQUAL(&asteriskScf, core.getParent());
+   BOOST_CHECK_EQUAL(&uut.getLogger(""), asteriskScf.getParent());
+}
+
+BOOST_AUTO_TEST_CASE(testInheritence_off)
+{
+   std::stringstream actual;
+   std::auto_ptr<LogOut> logOut = buildOstreamLogger(actual);
+   LoggerFactory uut(*logOut);
+
+   Logger &root = uut.getLogger("");
+   Logger &asteriskScf = uut.getLogger("AsteriskSCF");
+
+   root.setLevel(Off);
+
+   asteriskScf.logs(Debug, "Should not log");
+   BOOST_CHECK_EQUAL("", actual.str());
+}
+
+BOOST_AUTO_TEST_CASE(testInheritence_on)
+{
+   std::stringstream actual;
+   std::auto_ptr<LogOut> logOut = buildOstreamLogger(actual);
+   LoggerFactory uut(*logOut);
+
+   Logger &root = uut.getLogger("");
+   Logger &asteriskScf = uut.getLogger("AsteriskSCF");
+
+   root.setLevel(Debug);
+
+   asteriskScf.logs(Debug, "Should log");
+   BOOST_CHECK_EQUAL("AsteriskSCF:Debug:Should log\n", actual.str());
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/client/test/OstreamLoggerFactory-test.cpp b/client/test/OstreamLoggerFactory-test.cpp
deleted file mode 100644
index 41dd928..0000000
--- a/client/test/OstreamLoggerFactory-test.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Asterisk Scalable Communications Framework
- *
- * Copyright (C) 2010 -- Digium, Inc.
- *
- * All rights reserved.
- */
-
-#include <boost/test/unit_test.hpp>
-
-#include "logger.h"
-
-using namespace AsteriskSCF::System::Logging;
-
-BOOST_AUTO_TEST_SUITE( OstreamLoggerFactoryTest )
-
-BOOST_AUTO_TEST_SUITE_END()
diff --git a/client/test/log4scf-test.cpp b/client/test/log4scf-test.cpp
deleted file mode 100644
index 86439de..0000000
--- a/client/test/log4scf-test.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Asterisk Scalable Communications Framework
- *
- * Copyright (C) 2010 -- Digium, Inc.
- *
- * All rights reserved.
- */
-
-#define BOOST_TEST_MODULE log4scf
-#include <boost/test/included/unit_test.hpp>
diff --git a/server/src/CMakeLists.txt b/server/src/CMakeLists.txt
index 942b2bc..1934045 100644
--- a/server/src/CMakeLists.txt
+++ b/server/src/CMakeLists.txt
@@ -10,7 +10,8 @@ hydra_component_init(logging-service CXX)
 
 hydra_component_add_slice(logging-service log4scf)
 
-hydra_component_add_file(logging-service LoggingServer.cpp main.cpp)
+hydra_component_add_file(logging-service LoggingServer.cpp)
+hydra_component_add_file(logging-service main.cpp)
 
 hydra_component_build_standalone(logging-service)
 
diff --git a/server/src/LoggingServer.cpp b/server/src/LoggingServer.cpp
index 0948242..0b5116e 100644
--- a/server/src/LoggingServer.cpp
+++ b/server/src/LoggingServer.cpp
@@ -13,7 +13,6 @@ using namespace AsteriskSCF::System::Logging;
 namespace
 {
 
-
 /**
  * Current time, as formatted string.
  */

commit abc8bc8f712a7de6a71885dc79115b3c6a078e60
Author: David M. Lee <dlee at digium.com>
Date:   Mon Sep 20 16:14:13 2010 -0500

    Removed ostream method of logging.  Now can log level through to LogOut inteface.

diff --git a/client/src/CMakeLists.txt b/client/src/CMakeLists.txt
index 2f443c5..38beaf7 100644
--- a/client/src/CMakeLists.txt
+++ b/client/src/CMakeLists.txt
@@ -8,6 +8,6 @@
 
 hydra_component_init(logging-client CXX)
 
-add_library(logging-client Logger.cpp LoggerFactory.cpp logger.h)
+add_library(logging-client Logger.cpp LoggerFactory.cpp OstreamLogger.cpp logger.h)
 
 hydra_component_add_slice(logging-client log4scf)
diff --git a/client/src/IceLogger.cpp b/client/src/IceLogger.cpp
new file mode 100644
index 0000000..0bc028a
--- /dev/null
+++ b/client/src/IceLogger.cpp
@@ -0,0 +1,40 @@
+/*
+ * Asterisk Scalable Communications Framework
+ *
+ * Copyright (C) 2010 -- Digium, Inc.
+ *
+ * All rights reserved.
+ */
+
+#include "logger.h"
+
+using namespace AsteriskSCF::System::Logging;
+
+namespace
+{
+
+class IceLogger : public LogOut
+{
+public:
+   IceLogger(LoggingServerPrx const &server) :
+      server(server)
+   {
+
+   }
+
+   void logs(std::string const &source, Level logLevel,
+             std::string const &message)
+   {
+      server->logs(source, logLevel, message);
+   }
+
+private:
+   LoggingServerPrx server;
+};
+
+}
+
+std::auto_ptr<LogOut> buildIceLogger(LoggingServerPrx const &server)
+{
+   return std::auto_ptr<LogOut>(new IceLogger(server));
+}
diff --git a/client/src/LoggerFactory.cpp b/client/src/LoggerFactory.cpp
index 7b52f46..b479dd7 100644
--- a/client/src/LoggerFactory.cpp
+++ b/client/src/LoggerFactory.cpp
@@ -21,16 +21,10 @@
 using namespace AsteriskSCF::System::Logging;
 using namespace boost::algorithm;
 
-SourceNode::SourceNode() :
-   logger(std::cout, Debug)
+LoggerFactory::LoggerFactory(LogOut &out) :
+   out(out),
+   root("", out)
 {
-
-}
-
-LoggerFactory::LoggerFactory(OstreamFactory &ostreamFactory) :
-   ostreamFactory(ostreamFactory)
-{
-
 }
 
 Logger const &LoggerFactory::getLogger(std::string const &source)
diff --git a/client/src/OstreamLogger.cpp b/client/src/OstreamLogger.cpp
new file mode 100644
index 0000000..9f1aab4
--- /dev/null
+++ b/client/src/OstreamLogger.cpp
@@ -0,0 +1,40 @@
+/*
+ * Asterisk Scalable Communications Framework
+ *
+ * Copyright (C) 2010 -- Digium, Inc.
+ *
+ * All rights reserved.
+ */
+
+#include "logger.h"
+
+using namespace AsteriskSCF::System::Logging;
+
+namespace
+{
+
+class OstreamLogger : public LogOut
+{
+public:
+   OstreamLogger(std::ostream &out) :
+      out(out)
+   {
+
+   }
+
+   void logs(std::string const &source, Level logLevel,
+             std::string const &message)
+   {
+      out << source << ":" << logLevel << ":" << message << '\n';
+   }
+
+private:
+   std::ostream &out;
+};
+
+}
+
+std::auto_ptr<LogOut> buildStdoutLogger(std::ostream &out)
+{
+   return std::auto_ptr<LogOut>(new OstreamLogger(out));
+}
diff --git a/client/src/logger.cpp b/client/src/logger.cpp
index b4b72ff..60fb66f 100644
--- a/client/src/logger.cpp
+++ b/client/src/logger.cpp
@@ -13,6 +13,12 @@
 
 using namespace AsteriskSCF::System::Logging;
 
+LogOut::~LogOut()
+{
+   // no-op
+}
+
+
 Logger::~Logger()
 {
    // no-op
@@ -22,7 +28,7 @@ void Logger::logs(Level level, std::string const &message) const
 {
    if (isEnabledFor(level))
    {
-      out << message << std::endl;
+      out.logs(name, level, message);
    }
 }
 
@@ -42,7 +48,7 @@ void Logger::vlogf(Level level, char const *fmt, va_list ap) const
       vasprintf(&message, fmt, ap);
       if (message)
       {
-         out << message << std::endl;
+         out.logs(name, level, message);
          free(message);
       }
       else
diff --git a/client/src/logger.h b/client/src/logger.h
index 8882b5c..a5d642b 100644
--- a/client/src/logger.h
+++ b/client/src/logger.h
@@ -10,6 +10,7 @@
 
 #include <ostream>
 #include <cstdarg>
+#include <memory>
 
 #include "log4scf.h"
 
@@ -21,36 +22,43 @@ namespace Logging
 {
 
 /**
- * Class which mimics std::ostream, but can be disabled.  Used for logging.
+ * Helper to readably output Level.
  */
-class LogStream
+inline std::ostream &operator<<(std::ostream &o, Level level)
 {
-public:
-   LogStream(std::ostream &real, bool enabled) :
-      real(real), enabled(enabled)
+   switch (level)
    {
+   case Debug:
+      return o << "Debug";
+   case Info:
+      return o << "Info";
+   case Notice:
+      return o << "Notice";
+   case Warning:
+      return o << "Warning";
+   case Error:
+      return o << "Error";
+   case Critical:
+      return o << "Critical";
+   case Alert:
+      return o << "Alert";
+   case Emergency:
+      return o << "Emergency";
+   case Off:
+      return o << "Off";
    }
+   return o << "Unknown(" << level << ")";
+}
 
-   /**
-    * Streaming operator to mimic std::ostream.  Objects and manipulators
-    * are only written if enabled == true.
-    *
-    * @param v Object to write
-    * @return this, for chaining.
-    */
-   template<typename T>
-   LogStream const &operator<<(T const &v) const
-   {
-      if (enabled)
-      {
-         real << v;
-      }
-      return *this;
-   }
-
-private:
-   std::ostream &real;
-   bool enabled;
+/**
+ * Interface abstracting how the logs actually get written.
+ */
+class LogOut
+{
+public:
+   virtual ~LogOut();
+   virtual void logs(std::string const &source, Level logLevel,
+                     std::string const &message) = 0;
 };
 
 /**
@@ -59,8 +67,8 @@ private:
 class Logger
 {
 public:
-   Logger(std::ostream &out, Level logLevel) :
-      out(out), logLevel(logLevel)
+   Logger(std::string const &name, LogOut &out, Level logLevel = Debug) :
+      name(name), out(out), logLevel(logLevel)
    {
    }
    virtual ~Logger();
@@ -77,20 +85,6 @@ public:
    }
 
    /**
-    * Provides std::ostream-style logging.
-    * <code>
-    *   logger(level) << "Message to log: " << otherInfo << '\n';
-    * </code>
-    *
-    * @param level Level of this message
-    * @param A LogStream that will only log if isEnabledFor(level).
-    */
-   LogStream operator()(Level level) const
-   {
-      return LogStream(out, isEnabledFor(level));
-   }
-
-   /**
     * Log a single message.
     */
    void logs(Level level, std::string const &message) const;
@@ -105,15 +99,28 @@ public:
     */
    void vlogf(Level level, char const *fmt, va_list ap) const;
 
+   std::string const &getName() const
+   {
+      return name;
+   }
+   LogOut &getOutput() const
+   {
+      return out;
+   }
+
 private:
-   std::ostream &out;
+   const std::string name;
+   LogOut &out;
    Level logLevel;
 };
 
 class SourceNode
 {
 public:
-   SourceNode();
+   SourceNode(std::string const &name, LogOut &out) :
+      logger(name, out)
+   {
+   }
 
    Logger &getLogger()
    {
@@ -124,29 +131,21 @@ public:
       return logger;
    }
 
-   SourceNode &getChild(std::string const &name) { return children[name]; }
+   SourceNode &getChild(std::string const &name)
+   {
+      // ref to ptr allows us to update the map in-place
+      SourceNode *&child = children[name];
+      if (child == 0)
+      {
+         child = new SourceNode(logger.getName() + "." + name,
+                                logger.getOutput());
+      }
+      return *child;
+   }
 
 private:
    Logger logger;
-   std::map<std::string, SourceNode> children;
-};
-
-/**
- * Interface for creating ostreams for logging.
- */
-class OstreamFactory
-{
-public:
-   virtual std::ostream &operator()() const = 0;
-};
-
-class RefOstreamFactory : public OstreamFactory
-{
-public:
-   RefOstreamFactory(std::ostream &ref) : ref(ref) {}
-   virtual std::ostream &operator()() const { return ref; }
-private:
-   std::ostream &ref;
+   std::map<std::string, SourceNode *> children;
 };
 
 /**
@@ -155,14 +154,18 @@ private:
 class LoggerFactory
 {
 public:
-   LoggerFactory(OstreamFactory &ostreamFactory);
+   LoggerFactory(LogOut &out);
 
    Logger const &getLogger(std::string const &source);
+
 private:
-   OstreamFactory &ostreamFactory;
+   LogOut &out;
    SourceNode root;
 };
 
+std::auto_ptr<LogOut> buildIceLogger(LoggingServerPrx const &server);
+std::auto_ptr<LogOut> buildOstreamLogger(std::ostream &out);
+
 } // Logging
 } // System
 } // AsteriskSCF
diff --git a/client/test/CMakeLists.txt b/client/test/CMakeLists.txt
index 26217df..08f8d29 100644
--- a/client/test/CMakeLists.txt
+++ b/client/test/CMakeLists.txt
@@ -10,7 +10,7 @@ hydra_component_init(logging-client-test CXX)
 
 include_directories("../src")
 
-add_executable(logging-client-test LogStream-test.cpp Logger-test.cpp client-test.cpp)
+add_executable(logging-client-test Logger-test.cpp client-test.cpp)
 
 target_link_libraries(logging-client-test logging-client)
 hydra_component_add_boost_libraries(logging-client-test unit_test_framework)
diff --git a/client/test/Logger-test.cpp b/client/test/Logger-test.cpp
index 14ee1bf..2984862 100644
--- a/client/test/Logger-test.cpp
+++ b/client/test/Logger-test.cpp
@@ -6,84 +6,77 @@
  * All rights reserved.
  */
 
+#include <sstream>
+
 #include <boost/test/unit_test.hpp>
 
 #include "logger.h"
 
 using namespace AsteriskSCF::System::Logging;
 
-BOOST_AUTO_TEST_SUITE( LoggerTest )
-
-BOOST_AUTO_TEST_CASE( test_ostream )
+namespace
 {
-   std::stringstream out;
-   Logger uut(out, Debug);
-
-   uut(Critical) << "Critical message\n";
-   BOOST_CHECK_EQUAL("Critical message\n", out.str());
-}
-
-BOOST_AUTO_TEST_CASE( test_ostream_formatted )
+class ExpectedLogOut : public LogOut
 {
-   std::stringstream out;
-   Logger uut(out, Debug);
-
-   uut(Critical) << std::hex << 61453 << '\n';
-   BOOST_CHECK_EQUAL("f00d\n", out.str());
+public:
+   ExpectedLogOut(std::string const &expected) :
+      expected(expected)
+   {
+   }
+
+   void logs(std::string const &source, Level logLevel,
+             std::string const &message)
+   {
+      actual << source << ":" << logLevel << ":" << message << '\n';
+   }
+
+   void check()
+   {
+      BOOST_CHECK_EQUAL(expected, actual.str());
+   }
+
+private:
+   std::string expected;
+   std::stringstream actual;
+};
 }
 
+BOOST_AUTO_TEST_SUITE( LoggerTest )
+
 BOOST_AUTO_TEST_CASE( test_log )
 {
-   std::stringstream out;
-   Logger uut(out, Debug);
+   ExpectedLogOut out("src:Critical:Critical Message\n");
+   Logger uut("src", out, Debug);
 
-   uut.logs(Critical, "Critical message");
-   BOOST_CHECK_EQUAL("Critical message\n", out.str());
+   uut.logs(Critical, "Critical Message");
+   out.check();
 }
 
 BOOST_AUTO_TEST_CASE( test_logf )
 {
-   std::stringstream out;
-   Logger uut(out, Debug);
+   ExpectedLogOut out("src:Critical:Critical message f00d\n");
+   Logger uut("src", out, Debug);
 
    uut.logf(Critical, "Critical message %04x", 61453);
-   BOOST_CHECK_EQUAL("Critical message f00d\n", out.str());
+   out.check();
 }
 
 BOOST_AUTO_TEST_CASE( test_same_level )
 {
-   std::stringstream out;
-   Logger uut(out, Debug);
+   ExpectedLogOut out("src:Debug:debug\n");
+   Logger uut("src", out, Debug);
 
-   uut(Debug) << "debug\n";
-   BOOST_CHECK_EQUAL("debug\n", out.str());
-}
-
-BOOST_AUTO_TEST_CASE( test_stream_squelched )
-{
-   std::stringstream out;
-   Logger uut(out, Info);
-
-   uut(Debug) << "debug\n";
-   BOOST_CHECK_EQUAL("", out.str());
+   uut.logs(Debug, "debug");
+   out.check();
 }
 
 BOOST_AUTO_TEST_CASE( test_log_squelched )
 {
-   std::stringstream out;
-   Logger uut(out, Info);
+   ExpectedLogOut out("");
+   Logger uut("src", out, Info);
 
    uut.logs(Debug, "debug\n");
-   BOOST_CHECK_EQUAL("", out.str());
-}
-
-BOOST_AUTO_TEST_CASE( test_logf_squelched )
-{
-   std::stringstream out;
-   Logger uut(out, Info);
-
-   uut.logf(Debug, "debug\n");
-   BOOST_CHECK_EQUAL("", out.str());
+   out.check();
 }
 
 BOOST_AUTO_TEST_SUITE_END()
diff --git a/server/src/LoggingServer.cpp b/server/src/LoggingServer.cpp
index 2065d52..0948242 100644
--- a/server/src/LoggingServer.cpp
+++ b/server/src/LoggingServer.cpp
@@ -13,34 +13,6 @@ using namespace AsteriskSCF::System::Logging;
 namespace
 {
 
-/**
- * Helper to readably output Level.
- */
-std::ostream &operator<<(std::ostream &o, Level level)
-{
-   switch (level)
-   {
-   case Debug:
-      return o << "Debug";
-   case Info:
-      return o << "Info";
-   case Notice:
-      return o << "Notice";
-   case Warning:
-      return o << "Warning";
-   case Error:
-      return o << "Error";
-   case Critical:
-      return o << "Critical";
-   case Alert:
-      return o << "Alert";
-   case Emergency:
-      return o << "Emergency";
-   case Off:
-      return o << "Off";
-   }
-   return o << "Unknown(" << level << ")";
-}
 
 /**
  * Current time, as formatted string.

commit b4c1698972361746e82884025f5e5016cbe23ad5
Author: David M. Lee <dlee at digium.com>
Date:   Mon Sep 20 14:54:37 2010 -0500

    Committing prior to a change in direction.

diff --git a/client/src/CMakeLists.txt b/client/src/CMakeLists.txt
index cd8825c..2f443c5 100644
--- a/client/src/CMakeLists.txt
+++ b/client/src/CMakeLists.txt
@@ -8,6 +8,6 @@
 
 hydra_component_init(logging-client CXX)
 
-add_library(logging-client logger.cpp logger.h)
+add_library(logging-client Logger.cpp LoggerFactory.cpp logger.h)
 
 hydra_component_add_slice(logging-client log4scf)
diff --git a/client/src/LoggerFactory.cpp b/client/src/LoggerFactory.cpp
index 729c11f..7b52f46 100644
--- a/client/src/LoggerFactory.cpp
+++ b/client/src/LoggerFactory.cpp
@@ -6,22 +6,43 @@
  * All rights reserved.
  */
 
+#include <string>
+#include <map>
+#include <vector>
+#include <functional>
+#include <algorithm>
+
+#include <iostream>
+
+#include <boost/algorithm/string/split.hpp>
+
 #include "logger.h"
 
 using namespace AsteriskSCF::System::Logging;
+using namespace boost::algorithm;
+
+SourceNode::SourceNode() :
+   logger(std::cout, Debug)
+{
 
-namespace {
-   struct SourceNode {
-      SourceNode(Level level = off) : level(level) {}
-      std::map<std::string, SourceNode *> children;
-      Level level;
-      Source source;
-   };
 }
 
-static std::auto_ptr<LoggerFactory> LoggerFactory::singleton;
+LoggerFactory::LoggerFactory(OstreamFactory &ostreamFactory) :
+   ostreamFactory(ostreamFactory)
+{
+
+}
 
-~LoggerFactory::LoggerFactory() 
+Logger const &LoggerFactory::getLogger(std::string const &source)
 {
-   // no-op
+   std::vector<std::string> path;
+   split(path, source, std::bind1st(std::equal_to<char>(), '.'));
+
+   SourceNode *node = &root;
+   for (std::vector<std::string>::iterator i = path.begin(); i != path.end(); ++i)
+   {
+      node = &node->getChild(*i);
+   }
+
+   return node->getLogger();
 }
diff --git a/client/src/logger.cpp b/client/src/logger.cpp
index 1c59770..b4b72ff 100644
--- a/client/src/logger.cpp
+++ b/client/src/logger.cpp
@@ -18,7 +18,7 @@ Logger::~Logger()
    // no-op
 }
 
-void Logger::log(Level level, std::string const &message) const
+void Logger::logs(Level level, std::string const &message) const
 {
    if (isEnabledFor(level))
    {
diff --git a/client/src/logger.h b/client/src/logger.h
index 9a6eaa9..8882b5c 100644
--- a/client/src/logger.h
+++ b/client/src/logger.h
@@ -19,114 +19,149 @@ namespace System
 {
 namespace Logging
 {
+
+/**
+ * Class which mimics std::ostream, but can be disabled.  Used for logging.
+ */
+class LogStream
+{
+public:
+   LogStream(std::ostream &real, bool enabled) :
+      real(real), enabled(enabled)
+   {
+   }
+
    /**
-    * Class which mimics std::ostream, but can be disabled.  Used for logging.
+    * Streaming operator to mimic std::ostream.  Objects and manipulators
+    * are only written if enabled == true.
+    *
+    * @param v Object to write
+    * @return this, for chaining.
     */
-   class LogStream
+   template<typename T>
+   LogStream const &operator<<(T const &v) const
    {
-   public:
-      LogStream(std::ostream &real, bool enabled) : 
-         real(real), enabled(enabled) {}
-
-      /**
-       * Streaming operator to mimic std::ostream.  Objects and manipulators
-       * are only written if enabled == true.
-       *
-       * @param v Object to write
-       * @return this, for chaining.
-       */
-      template<typename T>
-      LogStream const &operator<<(T const &v) const
+      if (enabled)
       {
-         if (enabled) 
-         {
-            real << v;
-         }
-         return *this;
+         real << v;
       }
+      return *this;
+   }
 
-   private:
-      std::ostream &real;
-      bool enabled;
-   };
+private:
+   std::ostream &real;
+   bool enabled;
+};
+
+/**
+ * The Logger for a particular Source.
+ */
+class Logger
+{
+public:
+   Logger(std::ostream &out, Level logLevel) :
+      out(out), logLevel(logLevel)
+   {
+   }
+   virtual ~Logger();
 
    /**
-    * The Logger for a particular Source.
+    * If true, this Logger would log messages of the given Level.
+    *
+    * @param level Level to check.
+    * @return true if enabled for given level.
     */
-   class Logger
+   bool isEnabledFor(Level level) const
    {
-   public:
-      Logger(std::ostream &out, Level logLevel) : out(out), logLevel(logLevel) {}
-      virtual ~Logger();
-
-      /**
-       * If true, this Logger would log messages of the given Level.
-       *
-       * @param level Level to check.
-       * @return true if enabled for given level.
-       */
-      bool isEnabledFor(Level level) const { return logLevel <= level; }
-
-      /**
-       * Provides std::ostream-style logging.
-       * <code>
-       *   logger(level) << "Message to log: " << otherInfo << '\n';
-       * </code>
-       * 
-       * @param level Level of this message
-       * @param A LogStream that will only log if isEnabledFor(level).
-       */
-      LogStream operator()(Level level) const
-      {
-         return LogStream(out, isEnabledFor(level));
-      }
+      return logLevel <= level;
+   }
 
-      /**
-       * Log a single message.
-       */
-      void log(Level level, std::string const &message) const;
+   /**
+    * Provides std::ostream-style logging.
+    * <code>
+    *   logger(level) << "Message to log: " << otherInfo << '\n';
+    * </code>
+    *
+    * @param level Level of this message
+    * @param A LogStream that will only log if isEnabledFor(level).
+    */
+   LogStream operator()(Level level) const
+   {
+      return LogStream(out, isEnabledFor(level));
+   }
 
-      /**
-       * Log a single printf-formatted message.
-       */
-      void logf(Level level, char const *fmt, ...) const;
+   /**
+    * Log a single message.
+    */
+   void logs(Level level, std::string const &message) const;
 
-      /**
-       * Log a single vprintf-formatted message.
-       */
-      void vlogf(Level level, char const *fmt, va_list ap) const;
+   /**
+    * Log a single printf-formatted message.
+    */
+   void logf(Level level, char const *fmt, ...) const;
 
-   private:
-      std::ostream &out;
-      Level logLevel;
-   };
+   /**
+    * Log a single vprintf-formatted message.
+    */
+   void vlogf(Level level, char const *fmt, va_list ap) const;
+
+private:
+   std::ostream &out;
+   Level logLevel;
+};
+
+class SourceNode
+{
+public:
+   SourceNode();
 
-   class LoggerFactory
+   Logger &getLogger()
    {
-   public:
-      virtual ~LoggerFactory() throw();
+      return logger;
+   }
+   Logger const &getLogger() const
+   {
+      return logger;
+   }
 
-      static Logger const &getLogger(std::string const &source) throw()
-      {
-         return getInstance().getLoggerImpl(source);
-      }
-      static LoggerFactory &getInstance() throw()
-      {
-         return *singleton;
-      }
-      static void setInstance(std::auto_ptr<LoggerFactory> newFactory) throw()
-      {
-         singleton = newFactory;
-      }
+   SourceNode &getChild(std::string const &name) { return children[name]; }
 
-   protected:
-      virtual Logger const &getLoggerImpl(std::string const &source) const throw() = 0;
+private:
+   Logger logger;
+   std::map<std::string, SourceNode> children;
+};
 
-   private:
-      static std::auto_ptr<LoggerFactory> singleton;
-   };
+/**
+ * Interface for creating ostreams for logging.
+ */
+class OstreamFactory
+{
+public:
+   virtual std::ostream &operator()() const = 0;
+};
 
-   std::auto_ptr<LoggerFactory> buildOstreamLoggerFactory(std::ostream &out, Level defaultLevel = Debug);
+class RefOstreamFactory : public OstreamFactory
+{
+public:
+   RefOstreamFactory(std::ostream &ref) : ref(ref) {}
+   virtual std::ostream &operator()() const { return ref; }
+private:
+   std::ostream &ref;
+};
+
+/**
+ * Main entry point into the Logger system.
+ */
+class LoggerFactory
+{
+public:
+   LoggerFactory(OstreamFactory &ostreamFactory);
+
+   Logger const &getLogger(std::string const &source);
+private:
+   OstreamFactory &ostreamFactory;
+   SourceNode root;
+};
 
 } // Logging
 } // System
diff --git a/client/test/CMakeLists.txt b/client/test/CMakeLists.txt
index 31f6496..26217df 100644
--- a/client/test/CMakeLists.txt
+++ b/client/test/CMakeLists.txt
@@ -10,7 +10,7 @@ hydra_component_init(logging-client-test CXX)
 
 include_directories("../src")
 
-add_executable(logging-client-test LogStream-test.cpp Logger-test.cpp log4scf-test.cpp)
+add_executable(logging-client-test LogStream-test.cpp Logger-test.cpp client-test.cpp)
 
 target_link_libraries(logging-client-test logging-client)
 hydra_component_add_boost_libraries(logging-client-test unit_test_framework)
diff --git a/client/test/LogStream-test.cpp b/client/test/LogStream-test.cpp
index 2239074..a7c4c4e 100644
--- a/client/test/LogStream-test.cpp
+++ b/client/test/LogStream-test.cpp
@@ -12,7 +12,7 @@
 
 using namespace AsteriskSCF::System::Logging;
 
-//BOOST_AUTO_TEST_SUITE( LogStreamTest )
+BOOST_AUTO_TEST_SUITE( LogStreamTest )
 
 BOOST_AUTO_TEST_CASE( test_enabled )
 {
@@ -32,4 +32,4 @@ BOOST_AUTO_TEST_CASE( test_disabled )
    BOOST_CHECK_EQUAL("", o.str());
 }
 
-//BOOST_AUTO_TEST_SUITE_END()
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/client/test/Logger-test.cpp b/client/test/Logger-test.cpp
index 7bda0b1..14ee1bf 100644
--- a/client/test/Logger-test.cpp
+++ b/client/test/Logger-test.cpp
@@ -37,7 +37,7 @@ BOOST_AUTO_TEST_CASE( test_log )
    std::stringstream out;
    Logger uut(out, Debug);
 
-   uut.log(Critical, "Critical message");
+   uut.logs(Critical, "Critical message");
    BOOST_CHECK_EQUAL("Critical message\n", out.str());
 }
 
@@ -73,7 +73,7 @@ BOOST_AUTO_TEST_CASE( test_log_squelched )
    std::stringstream out;
    Logger uut(out, Info);
 
-   uut.log(Debug, "debug\n");
+   uut.logs(Debug, "debug\n");
    BOOST_CHECK_EQUAL("", out.str());
 }
 
diff --git a/client/test/LoggerFactory-test.cpp b/client/test/LoggerFactory-test.cpp
new file mode 100644
index 0000000..f6918eb
--- /dev/null
+++ b/client/test/LoggerFactory-test.cpp
@@ -0,0 +1,30 @@
+/*
+ * Asterisk Scalable Communications Framework
+ *
+ * Copyright (C) 2010 -- Digium, Inc.
+ *
+ * All rights reserved.
+ */
+
+
+#include <boost/test/unit_test.hpp>
+
+#include "logger.h"
+
+using namespace AsteriskSCF::System::Logging;
+
+BOOST_AUTO_TEST_SUITE(LoggerFactoryTest)
+
+BOOST_AUTO_TEST_CASE(testGetDistinct)
+{
+   std::stringstream tmp;
+   RefOstreamFactory streamFactory(tmp);
+   LoggerFactory uut(streamFactory);
+
+   Logger asteriskScf = uut.getLogger("AsteriskSCF");
+   Logger core = uut.getLogger("AsteriskSCF.Core");
+
+   BOOST_CHECK_NE(&core, &asteriskScf);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/client/test/client-test.cpp b/client/test/client-test.cpp
new file mode 100644
index 0000000..4558669
--- /dev/null
+++ b/client/test/client-test.cpp
@@ -0,0 +1,10 @@
+/*
+ * Asterisk Scalable Communications Framework
+ *
+ * Copyright (C) 2010 -- Digium, Inc.
+ *
+ * All rights reserved.
+ */
+
+#define BOOST_TEST_MODULE log4scf-client
+#include <boost/test/included/unit_test.hpp>
diff --git a/cmake b/cmake
index 3f25bd2..4f2c4db 160000
--- a/cmake
+++ b/cmake
@@ -1 +1 @@
-Subproject commit 3f25bd27601d0d4befc9a82cc9b1a5e71d58625b
+Subproject commit 4f2c4db13921b9af66b4b34a435c72c490d7aaaa
diff --git a/ice/log4scf.ice b/ice/log4scf.ice
index a071403..a504a87 100644
--- a/ice/log4scf.ice
+++ b/ice/log4scf.ice
@@ -27,29 +27,23 @@ module Logging
       Critical,
       Alert,
       Emergency,
-      Off,
-      Unset
+      Off
    };
 
    sequence<string> StringSeq;
 
    /**
-    * A Source identifies the source component of a log message.  It can
-    * be represented as a dot-notation from the source path.
-    * i.e. if the sourcePath is ["AsteriskSCF", "Core", "Routing"], then the
-    * dot-notation would be "AsteriskSCF.Core.Routing".
-    */
-   struct Source
-   {
-      StringSeq sourcePath;
-   };
-
-   /**
     * The configuration for a particular Source.
     */
    struct SourceConfiguration
    {
-      Source logSource;
+     /**
+      * A Source identifies the source component of a log message.  It can
+      * be represented as a dot-notation from the source path.
+      * i.e. if the sourcePath is ["AsteriskSCF", "Core", "Routing"], then the
+      * dot-notation would be "AsteriskSCF.Core.Routing".
+      */
+      string source;
       Level logLevel;
    };
    sequence<SourceConfiguration> SourceConfigurationSeq;
@@ -70,8 +64,9 @@ module Logging
       /**
        * Log a message from a given source, at a given level.  Note that
        * server configuration may filter this message at the destination.
+       * log may be a #define, hence the name logm.
        */
-      idempotent void log(Source logSource, Level logLevel, string message);
+      idempotent void logs(string source, Level logLevel, string message);
    };
 
    /**
diff --git a/log-client.rb b/log-client.rb
new file mode 100644
index 0000000..e652f3c
--- /dev/null
+++ b/log-client.rb
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+require 'log4scf.rb'
+
+status = 0
+ic = nil
+begin
+    ic = Ice::initialize(ARGV)
+    base = ic.stringToProxy("LoggingServer:tcp -h localhost ‑p 10000")
+    logger = AsteriskSCF::System::Logging::checkedCast(base)
+    if not logger
+        raise "Invalid proxy"
+    end
+
+    logger.log("component", -1, "Hello, log4scf")
+#rescue
+#    puts $!
+#    puts $!.backtrace.join("\n")
+#    status = 1
+end
+
+if ic
+    # Clean up
+    begin
+        ic.destroy()
+    rescue
+        puts $!
+        puts $!.backtrace.join("\n")
+        status = 1
+    end
+end
+
+exit(status)
diff --git a/log4scf.rb b/log4scf.rb
new file mode 100644
index 0000000..3770d8e
--- /dev/null
+++ b/log4scf.rb
@@ -0,0 +1,297 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2010 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+# Ice version 3.4.1
+
+# <auto-generated>
+#
+# Generated from file `log4scf.ice'
+#
+# Warning: do not edit this file.
+#
+# </auto-generated>
+
+require 'Ice'
+
+module AsteriskSCF
+
+    module System
+
+        module Logging
+
+            module V1
+
+                Version = "V1.0"
+
... 2105 lines suppressed ...


-- 
asterisk-scf/integration/log4scf.git



More information about the asterisk-scf-commits mailing list