[asterisk-scf-commits] asterisk-scf/integration/logger.git branch "logformat2" updated.

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Thu Sep 29 19:19:01 CDT 2011


branch "logformat2" has been updated
       via  127794c0c86b0e5e3b4d71de681c3053c64bb596 (commit)
       via  cda44d45498ee43e3404cb86e1a627b83918d5dc (commit)
       via  dc4bdbc50de42e3c810f6ea31aa6e6e14b7b56b7 (commit)
       via  19678a832f728be13b5230e56b5b5e7db6ddf5d4 (commit)
       via  2f13e1c4e013cc20d3672df8029502c6836613c1 (commit)
       via  8b3d9fc03b820e35cc859a05fbd246b930ce6237 (commit)
       via  cc3eee6c90fcb07de28d2e40d25d491f9371ec18 (commit)
       via  f09864c318aef8135d49204db7d268a0e56bef11 (commit)
       via  b7ef57dd33f9efa42dc85a5dddd51876c2f0f2ef (commit)
       via  a01a6b277c53958361ff9ec089d89bffcfaaeed0 (commit)
       via  1ca7bc4b970d94e072e5ffb0d2cf7fbf938292f0 (commit)
       via  5fc48c25d75b42b9cee68fae5969935434bdc16a (commit)
       via  1ac6860fe3206e37cca9adb4745999d874f18a73 (commit)
       via  43bb75fbdf04568405f509920a69f5799722b5f0 (commit)
      from  fb443735377d9e1488c469c09f98501008cddd78 (commit)

Summary of changes:
 client/config/logging-client.conf                  |    5 +-
 client/src/CMakeLists.txt                          |    2 +-
 client/src/IceLogger.cpp                           |   13 ++-
 client/src/LogFormatter.cpp                        |   99 +++++++++++++------
 client/src/Logger.cpp                              |   28 +++++-
 client/src/LoggerFactory.cpp                       |   40 --------
 include/AsteriskSCF/Logger/IceLogger.h             |    5 +-
 include/AsteriskSCF/Logger/Level.h                 |    6 +
 include/AsteriskSCF/Logger/LogFormatter.h          |   11 +--
 include/AsteriskSCF/Logger/LogOut.h                |    8 +-
 include/AsteriskSCF/logger.h                       |   14 ++-
 server/config/Logger.config                        |   62 ++++++++++++
 server/config/LoggerConfigurator.py                |  104 ++++++++++++++++++++
 server/config/logging-server.conf                  |   10 +--
 server/config/testloggingserver.conf               |   49 ++++------
 server/src/CMakeLists.txt                          |    3 +-
 server/src/ChainedLogOut.cpp                       |    2 +-
 server/src/Configuration.cpp                       |    8 +-
 server/src/FileChainedLogOut.cpp                   |   10 ++-
 server/src/main.cpp                                |   51 +++++++---
 server/test/ConfigurationTest.cpp                  |    2 -
 server/test/LoggingConfigurationHelper.cpp         |   48 +++++-----
 .../LoggingService/LoggingConfigurationIf.ice      |   13 ++-
 23 files changed, 402 insertions(+), 191 deletions(-)
 create mode 100644 server/config/Logger.config
 create mode 100644 server/config/LoggerConfigurator.py


- Log -----------------------------------------------------------------
commit 127794c0c86b0e5e3b4d71de681c3053c64bb596
Author: Ken Hunt <ken.hunt at digium.com>
Date:   Thu Sep 29 19:08:43 2011 -0500

    Incorporated review feedback.

diff --git a/client/src/LogFormatter.cpp b/client/src/LogFormatter.cpp
index f747772..e05e3d6 100644
--- a/client/src/LogFormatter.cpp
+++ b/client/src/LogFormatter.cpp
@@ -22,7 +22,7 @@
 using namespace AsteriskSCF::System::Logging;
 using namespace std;
 
-LogFormatter::LogFormatter(const std::string& fmtStr) :
+LogFormatter::LogFormatter(const string& fmtStr) :
     mFormat(fmtStr)
 {
 }
@@ -34,60 +34,60 @@ LogFormatter::~LogFormatter()
 /**
  * Builds a formatted string with some source code information in it.
  */
-std::string AsteriskSCF::System::Logging::sourceInfoStr(const std::string& fmt, unsigned int line,
+string AsteriskSCF::System::Logging::sourceInfoStr(const string& fmt, unsigned int line,
                                                         const char* fcn, const char* file)
 {
-    std::string s(fmt);
-    std::size_t pos;
+    string s(fmt);
+    size_t pos;
     bool found = true;
     
     while (found)
     {
         found = false;
-        if ((pos=s.find("$l",0))!=std::string::npos)
+        if ((pos=s.find("$l",0))!=string::npos)
         {
-            s.replace(pos,2,boost::lexical_cast<std::string>(line));
+            s.replace(pos,2,boost::lexical_cast<string>(line));
             found = true;
         }
-        if ((pos=s.find("$f",0))!=std::string::npos)
+        if ((pos=s.find("$f",0))!=string::npos)
         {
-            s.replace(pos,2,boost::lexical_cast<std::string>(fcn));
+            s.replace(pos,2,boost::lexical_cast<string>(fcn));
             found = true;
         }
-        if ((pos=s.find("$sp",0))!=std::string::npos)
+        if ((pos=s.find("$sp",0))!=string::npos)
         {
-            s.replace(pos,3,boost::lexical_cast<std::string>(file));
+            s.replace(pos,3,boost::lexical_cast<string>(file));
             found = true;
         }
-        if ((pos=s.find("$sf",0))!=std::string::npos)
+        if ((pos=s.find("$sf",0))!=string::npos)
         {
             boost::filesystem::path p(file);
-            s.replace(pos,3,boost::lexical_cast<std::string>(p.leaf()));
+            s.replace(pos,3,boost::lexical_cast<string>(p.leaf()));
             found = true;
         }
     }
     return s;
 }
 
-void LogFormatter::setFormat(const std::string& fmtStr)
+void LogFormatter::setFormat(const string& fmtStr)
 {
     boost::unique_lock<boost::shared_mutex> lock(mMutex);
     mFormat = fmtStr;
 }
 
-std::string LogFormatter::getFormat()
+string LogFormatter::getFormat()
 {
     boost::shared_lock<boost::shared_mutex> lock(mMutex);
 
     return mFormat;
 }
 
-std::string getFormattedTime(const boost::posix_time::ptime& t, const std::string& format)
+string getFormattedTime(const boost::posix_time::ptime& t, const string& format)
 {
     boost::posix_time::time_facet* outputFacet = new boost::posix_time::time_facet();
 
-    std::stringstream ss;
-    ss.imbue(std::locale(std::locale::classic(), outputFacet));
+    stringstream ss;
+    ss.imbue(locale(locale::classic(), outputFacet));
     outputFacet->format(format.c_str());
 
     ss << t;
@@ -95,9 +95,9 @@ std::string getFormattedTime(const boost::posix_time::ptime& t, const std::strin
     return ss.str();
 }
 
-std::string getFormattedTime(const  boost::posix_time::ptime& t)
+string getFormattedTime(const  boost::posix_time::ptime& t)
 {
-    std::stringstream ss;
+    stringstream ss;
 
     ss << t;
     return ss.str();
@@ -106,26 +106,26 @@ std::string getFormattedTime(const  boost::posix_time::ptime& t)
 /**
  * Formats a log string and returns it for output
  */
-std::string LogFormatter::formatMessage(const std::string& message, const std::string& name, Level level,
-        const std::string& hostName, Ice::Long pid, 
-        const std::string& componentCategory, const std::string& serviceId, const std::string& instanceId) const
+string LogFormatter::formatMessage(const string& message, const string& name, Level level,
+        const string& hostName, Ice::Long pid, 
+        const string& componentCategory, const string& serviceId, const string& instanceId) const
 {
-    std::string outStr;
-    std::size_t pos;
+    string outStr;
+    size_t pos;
     outStr = mFormat;
 
-    if ((pos=outStr.find("$t{",0)) != std::string::npos)
+    if ((pos=outStr.find("$t{",0)) != string::npos)
     {
         // Client timestamp (formatted). 
         try
         {
             boost::posix_time::ptime now(boost::posix_time::microsec_clock::universal_time());
 
-            std::size_t pos2 = outStr.find("}",pos+3);
-            if (pos2 != std::string::npos)
+            size_t pos2 = outStr.find("}",pos+3);
+            if (pos2 != string::npos)
             {
-                std::string userTimeFormat = outStr.substr(pos+3,pos2-3);
-                std::string nowStr = getFormattedTime(now, userTimeFormat);
+                string userTimeFormat = outStr.substr(pos+3,pos2-3);
+                string nowStr = getFormattedTime(now, userTimeFormat);
 
                 outStr.replace(pos,pos+pos2+1,nowStr);
             }
@@ -136,7 +136,7 @@ std::string LogFormatter::formatMessage(const std::string& message, const std::s
            // in the output and signal to someone that the format is wrong
         }
     }
-    else if ((pos=outStr.find("$t",0)) != std::string::npos)
+    else if ((pos=outStr.find("$t",0)) != string::npos)
     {
         // Client timestamp (default formatting)
         boost::posix_time::ptime now(boost::posix_time::microsec_clock::universal_time());
@@ -145,22 +145,22 @@ std::string LogFormatter::formatMessage(const std::string& message, const std::s
         outStr.replace(pos,2,nowString);
     }
 
-    if ((pos=outStr.find("$n",0)) != std::string::npos)
+    if ((pos=outStr.find("$n",0)) != string::npos)
     {
         // Logger name
         outStr.replace(pos,2,name);
     }
 
-    if ((pos=outStr.find("$l",0)) != std::string::npos)
+    if ((pos=outStr.find("$l",0)) != string::npos)
     {
         // Priority / level
-        std::stringstream s("");
+        stringstream s("");
 
         s << level;
         outStr.replace(pos,2,s.str());
     }
 
-    if ((pos=outStr.find("$h",0)) != std::string::npos)
+    if ((pos=outStr.find("$h",0)) != string::npos)
     {
         // Client host name
         if (hostName.size()==0)
@@ -170,28 +170,28 @@ std::string LogFormatter::formatMessage(const std::string& message, const std::s
         else outStr.replace(pos,2,hostName);
     }
 
-    if ((pos=outStr.find("$p",0)) != std::string::npos)
+    if ((pos=outStr.find("$p",0)) != string::npos)
     {
         // Process ID
-        outStr.replace(pos,2,boost::lexical_cast<std::string>(pid));
+        outStr.replace(pos,2,boost::lexical_cast<string>(pid));
     }
 
-    if ((pos=outStr.find("$C",0)) != std::string::npos)
+    if ((pos=outStr.find("$C",0)) != string::npos)
     {
         outStr.replace(pos, 2, componentCategory);
     }
 
-    if ((pos=outStr.find("$S",0)) != std::string::npos)
+    if ((pos=outStr.find("$S",0)) != string::npos)
     {
          outStr.replace(pos, 2, serviceId);
     }
 
-    if ((pos=outStr.find("$I",0)) != std::string::npos)
+    if ((pos=outStr.find("$I",0)) != string::npos)
     {
          outStr.replace(pos, 2, instanceId);
     }
 
-    if ((pos=outStr.find("$m",0)) != std::string::npos)
+    if ((pos=outStr.find("$m",0)) != string::npos)
     {
         // Check for message specifier last so we don't modify the message itself
         outStr.replace(pos,2,message);
diff --git a/client/src/LoggerFactory.cpp b/client/src/LoggerFactory.cpp
index 45e1fb7..04aa039 100644
--- a/client/src/LoggerFactory.cpp
+++ b/client/src/LoggerFactory.cpp
@@ -47,46 +47,6 @@ void initLoggerFactory()
 
 }
 
-
-/**
- * Builds a formatted string with some source code information in it.
- */
-std::string AsteriskSCF::System::Logging::sourceInfoStr(const std::string& fmt, unsigned int line,
-                                                        const char* fcn, const char* file)
-{
-    std::string s(fmt);
-    std::size_t pos;
-    bool found = true;
-    
-    while (found)
-    {
-        found = false;
-        if ((pos=s.find(SPECIFIER("l"),0))!=std::string::npos)
-        {
-            s.replace(pos,2,boost::lexical_cast<std::string>(line));
-            found = true;
-        }
-        if ((pos=s.find(SPECIFIER("f"),0))!=std::string::npos)
-        {
-            s.replace(pos,2,boost::lexical_cast<std::string>(fcn));
-            found = true;
-        }
-        if ((pos=s.find(SPECIFIER("sp"),0))!=std::string::npos)
-        {
-            s.replace(pos,3,boost::lexical_cast<std::string>(file));
-            found = true;
-        }
-        if ((pos=s.find(SPECIFIER("sf"),0))!=std::string::npos)
-        {
-            boost::filesystem::path p(file);
-            s.replace(pos,3,boost::lexical_cast<std::string>(p.leaf()));
-            found = true;
-        }
-    }
-    return s;
-}
-
-
 LoggerFactory& AsteriskSCF::System::Logging::getLoggerFactory()
 {
     boost::call_once(initLoggerFactory, oneFactory);

commit cda44d45498ee43e3404cb86e1a627b83918d5dc
Merge: dc4bdbc fb44373
Author: Ken Hunt <ken.hunt at digium.com>
Date:   Thu Sep 29 18:52:30 2011 -0500

    Merge branch 'logformat2' of git.asterisk.org:asterisk-scf/integration/logger into integbranch

diff --cc server/test/LoggingConfigurationHelper.cpp
index fa03dd7,65d47ad..858b140
--- a/server/test/LoggingConfigurationHelper.cpp
+++ b/server/test/LoggingConfigurationHelper.cpp
@@@ -214,4 -215,4 +214,3 @@@ AsteriskSCF::System::Logging::Level Log
      return v->mLevelItem->loggingLevel;
  }
  
--

commit dc4bdbc50de42e3c810f6ea31aa6e6e14b7b56b7
Author: Kevin P. Fleming <kpfleming at digium.com>
Date:   Fri Sep 23 16:17:37 2011 -0500

    Make yesterday's change to FileChainedLogout.cpp compile on Linux.

diff --git a/server/src/FileChainedLogOut.cpp b/server/src/FileChainedLogOut.cpp
index 3b56776..a8cb7ad 100644
--- a/server/src/FileChainedLogOut.cpp
+++ b/server/src/FileChainedLogOut.cpp
@@ -35,7 +35,7 @@ void FileChainedLogOut::myLogs(const std::string& name, Level logLevel,
     if (!mOut || !mOut.is_open())
     {
         // open the file
-        mOut.open(mLogFile);
+        mOut.open(mLogFile.c_str());
         if (mOut.fail())
         {
              std::cerr << "Logger error opening output file " << mLogFile << " due to: " << strerror(errno) << '\n';

commit 19678a832f728be13b5230e56b5b5e7db6ddf5d4
Author: Ken Hunt <ken.hunt at digium.com>
Date:   Thu Sep 22 15:20:50 2011 -0500

    Corrected log config file handling. Special handling for quoted config values required.

diff --git a/server/config/LoggerConfigurator.py b/server/config/LoggerConfigurator.py
index 26251cb..a9ac6f4 100644
--- a/server/config/LoggerConfigurator.py
+++ b/server/config/LoggerConfigurator.py
@@ -27,9 +27,9 @@ import AsteriskSCF.Configuration.LoggingService.V1
 class LoggingServiceSectionVisitors(Configurator.SectionVisitors):
 
     def getLevel(self, levelName):
-	levelName = levelName.strip()
-	if levelName == 'Trace':
-	    return AsteriskSCF.System.Logging.Level.Trace
+        levelName = levelName.strip()
+        if levelName == 'Trace':
+            return AsteriskSCF.System.Logging.Level.Trace
         elif levelName == 'Debug':
             return AsteriskSCF.System.Logging.Level.Debug
         elif levelName == 'Info':
@@ -53,41 +53,46 @@ class LoggingServiceSectionVisitors(Configurator.SectionVisitors):
 
     def visit_general(self, config, section):
         group = AsteriskSCF.Configuration.LoggingService.V1.LoggerGeneralGroup()
-	group.name = section
+        group.name = section
         group.configurationItems = { }
 
-        mapper = Configurator.OptionMapper()
-
-	try:
-	    levels = config.get(section, 'levels')
-	    levelsList = levels.split(';')
-	    levelItemCount = 0
-	    for levelSpec in levelsList:
+        try:
+            levels = config.get(section, 'levels')
+            levelsList = levels.split(';')
+            levelItemCount = 0
+            for levelSpec in levelsList:
                 levelParts = levelSpec.split(',')
-		logLevel = self.getLevel(levelParts[0])
-		loggerName = levelParts[1]
-#		print "logLevel = {0} and loggerName = {1}".format(logLevel, loggerName)
-		levelItem =  AsteriskSCF.Configuration.LoggingService.V1.LevelItem()
+                logLevel = self.getLevel(levelParts[0])
+                loggerName = levelParts[1]
+#               print "logLevel = {0} and loggerName = {1}".format(logLevel, loggerName)
+                levelItem =  AsteriskSCF.Configuration.LoggingService.V1.LevelItem()
 
                 levelItem.loggingLevel = logLevel
-		levelItem.loggerName = loggerName
-		group.configurationItems['loggingLevel' + `levelItemCount`] = levelItem
-		levelItemCount = levelItemCount + 1
-	except ConfigParser.NoOptionError:
-		pass
-
+                levelItem.loggerName = loggerName
+                group.configurationItems['loggingLevel' + `levelItemCount`] = levelItem
+                levelItemCount = levelItemCount + 1
+        except ConfigParser.NoOptionError:
+            pass
+
+        # Not using the mapper for filename because we want to strip the double quotes off the strings. 
+        # Filenames must be double-quoted in the config file to support spaces in filenames. 
         fileItem = AsteriskSCF.Configuration.LoggingService.V1.FileItem()
-	mapper.map('filename', fileItem, 'fileName', 'filename', config.get, None)
-
+        fileName = config.get(section, 'filename')
+        fileName = fileName.strip('\"')
+        fileName = fileName.strip()
+        fileItem.fileName = fileName
+        group.configurationItems['filename'] = fileItem
+
+        # Similarly to filenames, the format is double quoted in the config file 
+        # because format strings can have spaces. 
         formatItem = AsteriskSCF.Configuration.LoggingService.V1.FormatItem()
-	mapper.map('format', formatItem, 'formatSpec', 'format', config.get, None)
-
-        for option in config.options(section):
-            mapper.execute(group, section, option)
-
-        mapper.finish(group)
+        formatString = config.get(section, 'format')
+        formatString = formatString.strip('\"')
+        formatString = formatString.strip()
+        formatItem.formatSpec = formatString
+        group.configurationItems['format'] = formatItem
 
-	self.groups.append(group)
+        self.groups.append(group)
 
 # In order to do service locator based lookup we need to pass in a params object
 serviceLocatorParams = AsteriskSCF.Core.Discovery.V1.ServiceLocatorParams()
diff --git a/server/src/FileChainedLogOut.cpp b/server/src/FileChainedLogOut.cpp
index ad9abd9..3b56776 100644
--- a/server/src/FileChainedLogOut.cpp
+++ b/server/src/FileChainedLogOut.cpp
@@ -13,7 +13,9 @@
  * the GNU General Public License Version 2. See the LICENSE.txt file
  * at the top of the source tree.
  */
+#include <iostream>
 #include <fstream>
+#include <cerrno>
 #include <IceUtil/IceUtil.h>
 
 #include "FileChainedLogOut.h"
@@ -32,8 +34,12 @@ void FileChainedLogOut::myLogs(const std::string& name, Level logLevel,
     IceUtil::Mutex::Lock lock(mFileMutex);
     if (!mOut || !mOut.is_open())
     {
-        // reopen the file
-        mOut.open(mLogFile.c_str(), std::ios::out);
+        // open the file
+        mOut.open(mLogFile);
+        if (mOut.fail())
+        {
+             std::cerr << "Logger error opening output file " << mLogFile << " due to: " << strerror(errno) << '\n';
+        }
     }
 
     if (mOut && mOut.is_open())

commit 2f13e1c4e013cc20d3672df8029502c6836613c1
Author: Ken Hunt <ken.hunt at digium.com>
Date:   Thu Sep 22 12:59:08 2011 -0500

    Added configurator and sample config file for logger.

diff --git a/server/config/Logger.config b/server/config/Logger.config
new file mode 100644
index 0000000..251a82a
--- /dev/null
+++ b/server/config/Logger.config
@@ -0,0 +1,62 @@
+
+[general]
+
+# Logging level.
+# This is an array of level item values.
+# Each level item contains a logging level, and a logger name param.
+# A comma sepatates the params, and semi-colon each item.
+#
+# @param level The valid levels are (in increasing levels of verbosity):
+#   Emergency, Alert, Critical, Error, Warning, Notice, Info, Debug, Trace
+#
+# @param loggerName The logger names are defined by each component. If
+# the name is empty (i.e. ""), sets the default log level.
+#
+# Component logger names:
+#   "AsteriskSCF.BasicRoutingService"
+#   "AsteriskSCF.BasicRoutingServiceStateReplicator"
+#   "AsteriskSCF.BridgeService"
+#   "AsteriskSCF.BridgeReplicator"
+#   "AsteriskSCF.MediaOperationsCore"
+#   "AsteriskSCF.MediaOperationStateReplicator"
+#   "AsteriskSCF.MediaRTP"
+#   "AsteriskSCF.MediaFormatGeneric"
+#   "SipSessionGateway"
+#   "SipSessionGatewayReplicator"
+#   "AsteriskSCF.System.Discovery"
+#
+# In this example, the default logging level is set to Debug,
+# the RoutingService output level is decreased to Info.
+# Example:
+#   levels= Debug,"";Info,"AsteriskSCF.BasicRoutingService"
+#
+
+levels= Debug,""
+
+# Filename for logging output
+
+filename = "logout.txt"
+
+# The format string is composed of format parameters and other text, much like
+# the printf statement. Valid format parameters are:
+#
+# $m - the message to log. You always want this one in your format string.
+# $n - the name of the logger
+# $l - the level of the message being logged
+# $h - the client host name
+# $t - current time, can be further formatted with additional specifiers following the
+#      boost::posix_time::time_facet format, which is similar to the strftime() format.
+#      The additional specifiers should be in a set of curly braces,
+#      like: $t{%x %X} would format the time into a date/time string. If no additional
+#      format specifiers are given (ie, just $t), the system uses the default
+#      time format.
+# $p - current process id
+# $C - component category. This is part of the Service Locator params for the Component
+#      Service for the component performing the logging.
+# $S - service name. This is part of the Service Locator params for the Component
+#      Service for the component performing the logging.
+# $I - component instance id. This is part of the Service Locator params for the Component
+#      Service for the component performing the logging.
+
+format="$n($l): $m @ $t (from $I)"
+
diff --git a/server/config/LoggerConfigurator.py b/server/config/LoggerConfigurator.py
new file mode 100644
index 0000000..26251cb
--- /dev/null
+++ b/server/config/LoggerConfigurator.py
@@ -0,0 +1,99 @@
+#!/usr/bin/env python
+
+#
+# Asterisk SCF -- An open-source communications framework.
+#
+# Copyright (C) 2011, Digium, Inc.
+#
+# See http://www.asterisk.org for more information about
+# the Asterisk SCF project. Please do not directly contact
+# any of the maintainers of this project for assistance;
+# the project provides a web site, mailing lists and IRC
+# channels for your use.
+#
+# This program is free software, distributed under the terms of
+# the GNU General Public License Version 2. See the LICENSE.txt file
+# at the top of the source tree.
+#
+
+# Bring in the common configuration infrastructure
+import ConfigParser, Ice, Configurator, sys, os
+
+# Load our component specific configuration definitions
+Ice.loadSlice("-I\"" + os.environ["ASTSCF_HOME"] + "\" -I\"" + Ice.getSliceDir() + "\" --all LoggingConfigurationIf.ice")
+import AsteriskSCF.Configuration.LoggingService.V1
+
+# Add our own visitor implementations for the sections we support
+class LoggingServiceSectionVisitors(Configurator.SectionVisitors):
+
+    def getLevel(self, levelName):
+	levelName = levelName.strip()
+	if levelName == 'Trace':
+	    return AsteriskSCF.System.Logging.Level.Trace
+        elif levelName == 'Debug':
+            return AsteriskSCF.System.Logging.Level.Debug
+        elif levelName == 'Info':
+            return AsteriskSCF.System.Logging.Level.Info
+        elif levelName == 'Notice':
+            return AsteriskSCF.System.Logging.Level.Notice
+        elif levelName == 'Warning':
+            return AsteriskSCF.System.Logging.Level.Warning
+        elif levelName == 'Error':
+            return AsteriskSCF.System.Logging.Level.Error
+        elif levelName == 'Critical':
+            return AsteriskSCF.System.Logging.Level.Critical
+        elif levelName == 'Alert':
+            return AsteriskSCF.System.Logging.Level.Alert
+        elif levelName == 'Emergency':
+            return AsteriskSCF.System.Logging.Level.Emergency
+        elif levelName == 'Off':
+            return AsteriskSCF.System.Logging.Level.Off
+        print "Level identifier " + levelName + " is unknown. Defaulting to Debug"
+        return AsteriskSCF.System.Logging.Level.Debug
+
+    def visit_general(self, config, section):
+        group = AsteriskSCF.Configuration.LoggingService.V1.LoggerGeneralGroup()
+	group.name = section
+        group.configurationItems = { }
+
+        mapper = Configurator.OptionMapper()
+
+	try:
+	    levels = config.get(section, 'levels')
+	    levelsList = levels.split(';')
+	    levelItemCount = 0
+	    for levelSpec in levelsList:
+                levelParts = levelSpec.split(',')
+		logLevel = self.getLevel(levelParts[0])
+		loggerName = levelParts[1]
+#		print "logLevel = {0} and loggerName = {1}".format(logLevel, loggerName)
+		levelItem =  AsteriskSCF.Configuration.LoggingService.V1.LevelItem()
+
+                levelItem.loggingLevel = logLevel
+		levelItem.loggerName = loggerName
+		group.configurationItems['loggingLevel' + `levelItemCount`] = levelItem
+		levelItemCount = levelItemCount + 1
+	except ConfigParser.NoOptionError:
+		pass
+
+        fileItem = AsteriskSCF.Configuration.LoggingService.V1.FileItem()
+	mapper.map('filename', fileItem, 'fileName', 'filename', config.get, None)
+
+        formatItem = AsteriskSCF.Configuration.LoggingService.V1.FormatItem()
+	mapper.map('format', formatItem, 'formatSpec', 'format', config.get, None)
+
+        for option in config.options(section):
+            mapper.execute(group, section, option)
+
+        mapper.finish(group)
+
+	self.groups.append(group)
+
+# In order to do service locator based lookup we need to pass in a params object
+serviceLocatorParams = AsteriskSCF.Core.Discovery.V1.ServiceLocatorParams()
+serviceLocatorParams.category = AsteriskSCF.Configuration.LoggingService.V1.ConfigurationDiscoveryCategory
+serviceLocatorParams.service = 'default'
+
+# Make a configurator application and let it run
+app = Configurator.ConfiguratorApp('Logger.config', LoggingServiceSectionVisitors(), None, serviceLocatorParams)
+sys.exit(app.main(sys.argv))
diff --git a/server/src/Configuration.cpp b/server/src/Configuration.cpp
index aabf7a6..eb3ed8b 100644
--- a/server/src/Configuration.cpp
+++ b/server/src/Configuration.cpp
@@ -55,7 +55,6 @@ public:
     FormatItemI(const LoggingServerIPtr& server, const std::string& fmt)
         : mServer(server)
     {
-        printf("FormatItem constructor, this = %p\n",this);
         formatSpec = fmt;
         mServer->setFormat(fmt);
     }
@@ -74,7 +73,6 @@ public:
     LevelItemI(const LoggingServerIPtr& server, const std::string& name, const Level level)
         : mServer(server), mName(name)
     {
-        printf("LevelItem constructor, this = %p\n",this);
         mServer->setLevel(name, level);
     }
     ~LevelItemI()
@@ -292,9 +290,7 @@ void LoggerConfigurationService::setConfiguration(const ConfigurationGroupSeq& g
                 }
                 void visitFormatItem(const FormatItemPtr& formatItem)
                 {
-                    printf("Calling format constructor\n");
                     mPriv->mGeneralConfiguration->mFormat = new FormatItemI(mPriv->mServer, formatItem->formatSpec);
-                    printf("Back from calling format constructor\n");
                 }
                 void visitLevelItem(const LevelItemPtr &levelItem)
                 {
diff --git a/server/src/FileChainedLogOut.cpp b/server/src/FileChainedLogOut.cpp
index 5c26433..ad9abd9 100644
--- a/server/src/FileChainedLogOut.cpp
+++ b/server/src/FileChainedLogOut.cpp
@@ -13,7 +13,7 @@
  * the GNU General Public License Version 2. See the LICENSE.txt file
  * at the top of the source tree.
  */
-
+#include <fstream>
 #include <IceUtil/IceUtil.h>
 
 #include "FileChainedLogOut.h"
@@ -33,7 +33,7 @@ void FileChainedLogOut::myLogs(const std::string& name, Level logLevel,
     if (!mOut || !mOut.is_open())
     {
         // reopen the file
-        mOut.open(mLogFile.c_str());
+        mOut.open(mLogFile.c_str(), std::ios::out);
     }
 
     if (mOut && mOut.is_open())
diff --git a/server/src/main.cpp b/server/src/main.cpp
index 18bf604..e258ec5 100644
--- a/server/src/main.cpp
+++ b/server/src/main.cpp
@@ -44,22 +44,21 @@ protected:
 private:
     Ice::ObjectAdapterPtr mAdapter;
     ServiceManagementPrx mServiceManagement;
+    LoggingServerPrx mServerPrx;
+
     ServiceManagementPrx mConfigManagement;
     ConfigurationServicePtr mConfigurationService;
     ConfigurationServicePrx mConfigurationServicePrx;
     std::string mName;
 
-    void registerWithServiceLocator(const Ice::CommunicatorPtr& communicator,
-        const LoggingServerPrx& serverProxy);
+    void registerWithServiceLocator(const Ice::CommunicatorPtr& communicator);
     void setupDefaultProperties(const Ice::CommunicatorPtr& communicator);
     void setDefaultProperty(Ice::Properties& properties, const std::string& key,
         const std::string& defaultValue);
 };
 }
 
-void LoggingService::registerWithServiceLocator(
-    const Ice::CommunicatorPtr& communicator,
-        const LoggingServerPrx& serverProxy)
+void LoggingService::registerWithServiceLocator(const Ice::CommunicatorPtr& communicator)
 {
     try
     {
@@ -76,7 +75,8 @@ void LoggingService::registerWithServiceLocator(
                 ServiceLocatorManagementPrx::checkedCast(
                     communicator->stringToProxy(locatorManagementProxyString));
 
-            mServiceManagement = management->addService(serverProxy,
+            {
+            mServiceManagement = management->addService(mServerPrx,
                 mName + "." + LoggingServerGuid);
 
             ServiceLocatorParamsPtr params(new ServiceLocatorParams);
@@ -84,9 +84,11 @@ void LoggingService::registerWithServiceLocator(
             params->service = serviceName;
             params->id = mName;
             mServiceManagement->addLocatorParams(params, "");
+            }
 
             // Do the same for the configuration interface.
-            mConfigManagement = management->addService(serverProxy,
+            {
+            mConfigManagement = management->addService(mConfigurationServicePrx,
                 IceUtil::generateUUID());
 
             ServiceLocatorParamsPtr configParams(new ServiceLocatorParams);
@@ -94,6 +96,7 @@ void LoggingService::registerWithServiceLocator(
             configParams->service = serviceName;
             configParams->id = mName;
              mConfigManagement->addLocatorParams(configParams, "");
+            }
         }
         else
         {
@@ -187,7 +190,7 @@ void LoggingService::start(const std::string& name,
     server->configure(configurationListener,
         communicator->getProperties());
 
-    LoggingServerPrx serverProxy = LoggingServerPrx::uncheckedCast(
+    mServerPrx = LoggingServerPrx::uncheckedCast(
         mAdapter->addWithUUID(server));
 
     mConfigurationService = new LoggerConfigurationService(server);
@@ -196,8 +199,8 @@ void LoggingService::start(const std::string& name,
 
     mAdapter->activate();
 
-    std::cout << serverProxy->ice_toString() << '\n';
-    registerWithServiceLocator(communicator, serverProxy);
+    std::cout << mServerPrx->ice_toString() << '\n';
+    registerWithServiceLocator(communicator);
 }
 
 void LoggingService::stop()
diff --git a/slice/AsteriskSCF/Configuration/LoggingService/LoggingConfigurationIf.ice b/slice/AsteriskSCF/Configuration/LoggingService/LoggingConfigurationIf.ice
index 955c770..7034412 100644
--- a/slice/AsteriskSCF/Configuration/LoggingService/LoggingConfigurationIf.ice
+++ b/slice/AsteriskSCF/Configuration/LoggingService/LoggingConfigurationIf.ice
@@ -53,7 +53,7 @@ module V1
    /**
     * General Logger configuration group that contains general items related to the Logger component as a whole
     */
-   unsliceable class LoggerGeneralGroup extends LoggerConfigurationGroup
+   class LoggerGeneralGroup extends LoggerConfigurationGroup
    {
    };
 
@@ -63,19 +63,19 @@ module V1
    local class LoggerConfigurationItemVisitor extends AsteriskSCF::System::Configuration::V1::ConfigurationItemVisitor
    {
    };
-
+    
    /**
     * Generic Logger configuration item
     */
    ["visitor:LoggerConfigurationItemVisitor"] 
-   unsliceable class LoggerConfigurationItem extends AsteriskSCF::System::Configuration::V1::ConfigurationItem
+   class LoggerConfigurationItem extends AsteriskSCF::System::Configuration::V1::ConfigurationItem
    {
    };
 
    /**
     * ConfigurationItem that describes an output file to which logger output should be sent
     */
-   unsliceable class FileItem extends LoggerConfigurationItem
+   class FileItem extends LoggerConfigurationItem
    {
        /**
         * The name of the file to send output to
@@ -86,7 +86,7 @@ module V1
    /**
     * ConfigurationItem that describes the logger's output level.
     */
-   unsliceable class LevelItem extends LoggerConfigurationItem
+   class LevelItem extends LoggerConfigurationItem
    {
        /** 
         * Name of the logger to set the level for. 
@@ -104,7 +104,7 @@ module V1
    /**
     * ConfigurationItem that describes a format string the logger will use in preparing messages
     */
-   unsliceable class FormatItem extends LoggerConfigurationItem
+   class FormatItem extends LoggerConfigurationItem
    {
         /**
          * String describing the logger format. 

commit 8b3d9fc03b820e35cc859a05fbd246b930ce6237
Author: Ken Hunt <ken.hunt at digium.com>
Date:   Tue Sep 20 13:39:56 2011 -0500

    Added some cleanup so that logger clients don't leave user thinking the logging service is never found.
    Also registers the config interface to the service locator. (Testing of config always used hard-coded proxy before. Tests still need updating to use service locator.)

diff --git a/client/src/IceLogger.cpp b/client/src/IceLogger.cpp
index 0b2d50f..87d85ae 100644
--- a/client/src/IceLogger.cpp
+++ b/client/src/IceLogger.cpp
@@ -71,6 +71,15 @@ void IceLogger::logs(const std::string& name, Level logLevel,
         }
         std::clog << message << '\n';
     }
+    else
+    {
+        if (mHasPrintedNoServerNotice && !mHasPrintedServiceFoundNotice)
+        {
+            mHasPrintedServiceFoundNotice = true;
+            std::clog <<
+                "Logging server found. No longer logging to stderr.\n";
+        }
+    }
 }
 
 void IceLogger::setComponentInfo(const std::string& componentCategory, 
diff --git a/include/AsteriskSCF/Logger/IceLogger.h b/include/AsteriskSCF/Logger/IceLogger.h
index 8f3c012..dbac457 100644
--- a/include/AsteriskSCF/Logger/IceLogger.h
+++ b/include/AsteriskSCF/Logger/IceLogger.h
@@ -27,7 +27,7 @@ namespace Logging
 class IceLogger : public LogOut
 {
 public:
-    IceLogger() : mHasPrintedNoServerNotice(false) {}
+    IceLogger() : mHasPrintedNoServerNotice(false), mHasPrintedServiceFoundNotice(false) {}
 
     void logs(const std::string& name, Level logLevel,
         const std::string& message);
@@ -40,6 +40,7 @@ public:
 private:
     LoggingServerPrx mServer;
     bool mHasPrintedNoServerNotice;
+    bool mHasPrintedServiceFoundNotice;
     std::string mComponentCategory;
     std::string mComponentServiceName;
     std::string mComponentId;
diff --git a/server/src/main.cpp b/server/src/main.cpp
index 72edb51..18bf604 100644
--- a/server/src/main.cpp
+++ b/server/src/main.cpp
@@ -44,7 +44,9 @@ protected:
 private:
     Ice::ObjectAdapterPtr mAdapter;
     ServiceManagementPrx mServiceManagement;
+    ServiceManagementPrx mConfigManagement;
     ConfigurationServicePtr mConfigurationService;
+    ConfigurationServicePrx mConfigurationServicePrx;
     std::string mName;
 
     void registerWithServiceLocator(const Ice::CommunicatorPtr& communicator,
@@ -67,18 +69,31 @@ void LoggingService::registerWithServiceLocator(
                locatorServiceProxyStr);
         std::string serviceName = communicator->getProperties()->getPropertyWithDefault(
                "LoggerServer.ServiceName", "default");
+
         if (!locatorManagementProxyString.empty())
         {
             ServiceLocatorManagementPrx management =
                 ServiceLocatorManagementPrx::checkedCast(
                     communicator->stringToProxy(locatorManagementProxyString));
+
             mServiceManagement = management->addService(serverProxy,
-                LoggingServerGuid);
+                mName + "." + LoggingServerGuid);
 
             ServiceLocatorParamsPtr params(new ServiceLocatorParams);
             params->category = LoggingServerCategory;
             params->service = serviceName;
+            params->id = mName;
             mServiceManagement->addLocatorParams(params, "");
+
+            // Do the same for the configuration interface.
+            mConfigManagement = management->addService(serverProxy,
+                IceUtil::generateUUID());
+
+            ServiceLocatorParamsPtr configParams(new ServiceLocatorParams);
+            configParams->category = AsteriskSCF::Configuration::LoggingService::V1::ConfigurationDiscoveryCategory;
+            configParams->service = serviceName;
+            configParams->id = mName;
+             mConfigManagement->addLocatorParams(configParams, "");
         }
         else
         {
@@ -176,7 +191,8 @@ void LoggingService::start(const std::string& name,
         mAdapter->addWithUUID(server));
 
     mConfigurationService = new LoggerConfigurationService(server);
-    mAdapter->add(mConfigurationService, communicator->stringToIdentity(ConfigurationServiceId));
+    mConfigurationServicePrx = ConfigurationServicePrx::uncheckedCast(mAdapter->add(mConfigurationService, 
+                              communicator->stringToIdentity(ConfigurationServiceId)));
 
     mAdapter->activate();
 
diff --git a/slice/AsteriskSCF/Configuration/LoggingService/LoggingConfigurationIf.ice b/slice/AsteriskSCF/Configuration/LoggingService/LoggingConfigurationIf.ice
index 049a88e..955c770 100644
--- a/slice/AsteriskSCF/Configuration/LoggingService/LoggingConfigurationIf.ice
+++ b/slice/AsteriskSCF/Configuration/LoggingService/LoggingConfigurationIf.ice
@@ -32,6 +32,11 @@ module V1
 {
 
    /**
+    * Service locator category for finding the configuration service
+    */
+   const string ConfigurationDiscoveryCategory = "LoggingServiceConfiguration";
+
+   /**
     * Local visitor class for visiting Logger configuration groups
     */
    local class LoggerConfigurationGroupVisitor extends AsteriskSCF::System::Configuration::V1::ConfigurationGroupVisitor

commit cc3eee6c90fcb07de28d2e40d25d491f9371ec18
Author: Ken Hunt <ken.hunt at digium.com>
Date:   Tue Sep 20 12:04:16 2011 -0500

    Fix the ServiceAdapter name construction.

diff --git a/server/config/logging-server.conf b/server/config/logging-server.conf
index 988921a..51ccfda 100644
--- a/server/config/logging-server.conf
+++ b/server/config/logging-server.conf
@@ -7,7 +7,7 @@ IceBox.Service.Logger=logging-service:createLoggingService
 Logger.ServiceAdapter.Endpoints=tcp -p 4431
 
 # A proxy to the service locator management service
-LocatorServiceManagement.Proxy=LocatorServiceManagement:tcp -p 4422
+LocatorServiceManagement.Proxy=LocatorServiceManagement:tcp -p 4412
 
 # A proxy to the IceStorm topic manager
 TopicManager.Proxy=ServiceDiscoveryIceStorm/TopicManager:tcp -p 4421
diff --git a/server/config/testloggingserver.conf b/server/config/testloggingserver.conf
index 3edbbf4..29d0976 100644
--- a/server/config/testloggingserver.conf
+++ b/server/config/testloggingserver.conf
@@ -18,7 +18,7 @@ LocatorServiceManagement.Proxy=LocatorServiceManagement:tcp -p 4412
 LocatorService.Proxy=LocatorService:tcp -p 4411
 
 # Test endpoints for IceStorm
-TopicManager.Proxy=ServiceDiscoveryIceStorm/TopicManager:default -p 4421
+TopicManager.Proxy=ServiceDiscovery/TopicManager:default -p 4421
 
 #################################################
 # Properties for service locator
@@ -27,7 +27,6 @@ ServiceDiscovery.Management.ServiceAdapter.Endpoints=tcp -p 4412
 ServiceDiscovery.Locator.ServiceAdapter.Endpoints=tcp -p 4411
 ServiceDiscovery.IceStorm.InstanceName=ServiceDiscovery
 
-
 # This property defines the endpoints on which the IceStorm
 # TopicManager listens.
 #
diff --git a/server/src/main.cpp b/server/src/main.cpp
index 63ef85a..72edb51 100644
--- a/server/src/main.cpp
+++ b/server/src/main.cpp
@@ -96,7 +96,7 @@ void LoggingService::setupDefaultProperties(const Ice::CommunicatorPtr& communic
 {
     Ice::PropertiesPtr props = communicator->getProperties();
 
-    setDefaultProperty(*props, mName + "ServiceAdapter.Endpoints", "default");
+    setDefaultProperty(*props, mName + ".ServiceAdapter.Endpoints", "default");
 }
 
 void LoggingService::setDefaultProperty(Ice::Properties& props,

commit f09864c318aef8135d49204db7d268a0e56bef11
Author: Brent Eagles <beagles at digium.com>
Date:   Tue Sep 20 14:07:22 2011 -0230

    Fix a reference count bug in the logger client library that would cause the
    LogOut object to be destroyed once the IceLogger factory goes out of scope IF
    it were TopicManager.Proxy was NOT defined as the servant would not be added to
    the object adapter. The current fix is to add it to the adapter regardless. It
    will be cleaned up when the adapter is destroyed.
    
    Also added assignment operator (prob unnecessary, was written whilst tracking
    down the above issue), and moved the DLL export macro to the class
    declaration instead of the individual methods.
    
    Also added LogOut to the server project since it was missing linking with
    the destructor.

diff --git a/client/src/IceLogger.cpp b/client/src/IceLogger.cpp
index 070c1b2..0b2d50f 100644
--- a/client/src/IceLogger.cpp
+++ b/client/src/IceLogger.cpp
@@ -247,6 +247,7 @@ ConfiguredIceLoggerPtr AsteriskSCF::System::Logging::createIceLogger(
     }
 
     ConfiguredIceLoggerPtr logger = ConfiguredIceLogger::create(locator, serviceName);
+    Ice::ObjectPrx proxy = adapter->addWithUUID(logger);
 
     IceStorm::TopicManagerPrx topicManager =
         IceStorm::TopicManagerPrx::uncheckedCast(
@@ -256,11 +257,10 @@ ConfiguredIceLoggerPtr AsteriskSCF::System::Logging::createIceLogger(
     {
         try
         {
-            Ice::ObjectPrx proxy = adapter->addWithUUID(logger)->ice_oneway();
             IceStorm::TopicPrx topic = topicManager->retrieve(Discovery::TOPIC);
             if (topic)
             {
-                topic->subscribeAndGetPublisher(IceStorm::QoS(), proxy);
+                topic->subscribeAndGetPublisher(IceStorm::QoS(), proxy->ice_oneway());
             }
         }
         catch (const std::exception& e)
diff --git a/client/src/Logger.cpp b/client/src/Logger.cpp
index f06015a..7de61e3 100644
--- a/client/src/Logger.cpp
+++ b/client/src/Logger.cpp
@@ -55,6 +55,21 @@ LogBuf::~LogBuf()
     }
 }
 
+LogBuf& LogBuf::operator=(const LogBuf& rhs)
+{
+    if (this == &rhs)
+    {
+        return *this;
+    }
+    if (!mBuffer.str().empty())
+    {
+        sendBuffer();
+    }
+    mOut = rhs.mOut;
+    mName = rhs.mName;
+    mLogLevel = rhs.mLogLevel;
+    return *this;
+}
 
 int LogBuf::overflow(int c)
 {
@@ -73,7 +88,18 @@ void LogBuf::sendBuffer()
     // throws an exception, we still want to clear the buffer.
     const std::string& message = mBuffer.str();
     mBuffer.str("");
-    mOut.logs(mName,mLogLevel,message);
+    try
+    {
+        mOut.logs(mName,mLogLevel,message);
+    }
+    catch (...)
+    {
+        //
+        // Where sendBuffer is called from an destructor, we really don't want exceptions
+        // coming out of logs()
+        //
+        std::cerr << "An exception occurred when outputting log data" << std::endl;
+    }
 }
 
 
@@ -99,7 +125,7 @@ Logger::LoggerImpl::~LoggerImpl()
 
 CondStream Logger::LoggerImpl::operator()(Level level) const
 {
-    return CondStream(*mOut,mName,level,isEnabledFor(level));
+    return CondStream(*mOut, mName, level, isEnabledFor(level));
 }
 
 
diff --git a/include/AsteriskSCF/Logger/IceLogger.h b/include/AsteriskSCF/Logger/IceLogger.h
index 487b834..8f3c012 100644
--- a/include/AsteriskSCF/Logger/IceLogger.h
+++ b/include/AsteriskSCF/Logger/IceLogger.h
@@ -34,7 +34,7 @@ public:
     void setComponentInfo(const std::string& componentCategory, 
                           const std::string& serviceName,
                           const std::string& id);
-    const LoggingServerPrx& getServer() const { return mServer; }
+    const LoggingServerPrx getServer() const { return mServer; }
     void setServer(const LoggingServerPrx& server) { this->mServer = server; }
 
 private:
diff --git a/include/AsteriskSCF/Logger/LogOut.h b/include/AsteriskSCF/Logger/LogOut.h
index 78ee517..6523e53 100644
--- a/include/AsteriskSCF/Logger/LogOut.h
+++ b/include/AsteriskSCF/Logger/LogOut.h
@@ -32,13 +32,13 @@ namespace Logging
  *
  * NOTE: it is your responsibility to make sure your LogOut implementation is threadsafe
  */
-class LogOut
+class ASTSCF_DLL_EXPORT LogOut
 {
 public:
-    ASTSCF_DLL_EXPORT virtual ~LogOut();
-    ASTSCF_DLL_EXPORT virtual void logs(const std::string& name, Level logLevel,
+    virtual ~LogOut();
+    virtual void logs(const std::string& name, Level logLevel,
         const std::string& message) = 0;
-    ASTSCF_DLL_EXPORT virtual void setComponentInfo(
+    virtual void setComponentInfo(
         const std::string& componentCategory, 
         const std::string& serviceName,
         const std::string& id) = 0;
diff --git a/include/AsteriskSCF/logger.h b/include/AsteriskSCF/logger.h
index ad790fc..158cdd4 100644
--- a/include/AsteriskSCF/logger.h
+++ b/include/AsteriskSCF/logger.h
@@ -45,18 +45,24 @@ namespace Logging
  * or when destroyed.  The way temporary object lifecycles work in C++, this is
  * very convenient.
  */
-class LogBuf : public std::streambuf
+class ASTSCF_DLL_EXPORT LogBuf : public std::streambuf
 {
 public:
-    ASTSCF_DLL_EXPORT LogBuf(LogOut& out, const std::string& name, Level logLevel);
+    LogBuf(LogOut& out, const std::string& name, Level logLevel);
 
     /**
      * Copy ctor.
      * @param orig Original.
      */
-    ASTSCF_DLL_EXPORT LogBuf(const LogBuf& orig);
+    LogBuf(const LogBuf& orig);
 
-    ASTSCF_DLL_EXPORT ~LogBuf();
+    ~LogBuf();
+
+
+    /**
+     * Assignment probably never gets used, but just in case.
+     */
+    LogBuf& operator=(const LogBuf& orig);
 
 protected:
     int overflow(int c);
diff --git a/server/src/CMakeLists.txt b/server/src/CMakeLists.txt
index a532caa..cb4f86f 100644
--- a/server/src/CMakeLists.txt
+++ b/server/src/CMakeLists.txt
@@ -13,6 +13,7 @@ astscf_component_add_files(logging-service-lib OstreamChainedLogOut.h)
 astscf_component_add_files(logging-service-lib LoggingServer.h)
 astscf_component_add_files(logging-service-lib Configuration.h)
 astscf_component_add_files(logging-service-lib ../../client/src/LogFormatter.cpp)
+astscf_component_add_files(logging-service-lib ../../client/src/LogOut.cpp)
 astscf_component_add_slices(logging-service-lib PROJECT AsteriskSCF/Configuration/LoggingService/LoggingConfigurationIf.ice)
 astscf_component_add_boost_libraries(logging-service-lib core thread filesystem date_time system)
 astscf_component_add_ice_libraries(logging-service-lib IceStorm)

commit b7ef57dd33f9efa42dc85a5dddd51876c2f0f2ef
Author: Ken Hunt <ken.hunt at digium.com>
Date:   Mon Sep 19 14:58:32 2011 -0500

    Logger updates for configuration refactoring.

diff --git a/client/config/logging-client.conf b/client/config/logging-client.conf
index f940860..3488cdb 100644
--- a/client/config/logging-client.conf
+++ b/client/config/logging-client.conf
@@ -2,11 +2,8 @@
 
 AsteriskSCF.LoggingClient.Endpoints=default
 
-# Optionally directly specify LoggerServer proxy string
-#LoggerServer.Proxy=5BC84ACA-3F4C-4B78-BC75-5E6B1CC98680:tcp -h 10.24.21.100 -p 51030
-
 # Where to find the Service Locator.
 LocatorService.Proxy=LocatorService:tcp -p 4411
 
 # A proxy to the IceStorm topic manager
-TopicManager.Proxy=AsteriskSCFIceStorm/TopicManager:default -p 10000
+TopicManager.Proxy=ServiceDiscoveryIceStorm/TopicManager:default -p 4421
diff --git a/server/config/logging-server.conf b/server/config/logging-server.conf
index 4611cfb..988921a 100644
--- a/server/config/logging-server.conf
+++ b/server/config/logging-server.conf
@@ -4,15 +4,11 @@
 IceBox.InheritProperties=1
 IceBox.Service.Logger=logging-service:createLoggingService
 
-# Ice config
-AsteriskSCF.LoggingService.Endpoints=default
+Logger.ServiceAdapter.Endpoints=tcp -p 4431
 
 # A proxy to the service locator management service
 LocatorServiceManagement.Proxy=LocatorServiceManagement:tcp -p 4422
 
 # A proxy to the IceStorm topic manager
-TopicManager.Proxy=AsteriskSCFIceStorm/TopicManager:default -p 10000
+TopicManager.Proxy=ServiceDiscoveryIceStorm/TopicManager:tcp -p 4421
 
-# Log levels
-AsteriskSCF.Logging.logger=Error
-AsteriskSCF.Logging.logger.AsteriskSCF=Info
diff --git a/server/config/testloggingserver.conf b/server/config/testloggingserver.conf
index 537b754..3edbbf4 100644
--- a/server/config/testloggingserver.conf
+++ b/server/config/testloggingserver.conf
@@ -1,51 +1,41 @@
 IceBox.InheritProperties=1
 
 IceBox.Service.ServiceDiscovery=service_locator:create
-
 IceBox.Service.Logger=logging-service:createLoggingService
 IceBox.Service.LoggerTest=LoggingConfigurationTest:create
 
 IceBox.LoadOrder=ServiceDiscovery,Logger,LoggerTest
 
-AsteriskSCF.LoggingService.Endpoints=tcp -p 31337
+Logger.ServiceAdapter.Endpoints=tcp -p 31337
+
+#################################################
+# Properties for test component.
+LoggerTestAdapter.Endpoints=default
 LoggerConfiguration.Proxy=LoggerConfigurationService:tcp -p 31337
 
 # A proxy to the service locator management service
-LocatorServiceManagement.Proxy=LocatorServiceManagement:tcp -p 4422
-ServiceLocatorManagementAdapter.Endpoints=tcp -p 4422
-ServiceLocatorAdapter.Endpoints=tcp -p 4411
+LocatorServiceManagement.Proxy=LocatorServiceManagement:tcp -p 4412
 LocatorService.Proxy=LocatorService:tcp -p 4411
-ServiceLocatorLocalAdapter.Endpoints=tcp -p 4412
 
 # Test endpoints for IceStorm
-TopicManager.Proxy=AsteriskSCFIceStorm/TopicManager:default -p 10000
+TopicManager.Proxy=ServiceDiscoveryIceStorm/TopicManager:default -p 4421
+
+#################################################
+# Properties for service locator
+ServiceDiscovery.BackplaneAdapter.Endpoints=tcp -p 4410
+ServiceDiscovery.Management.ServiceAdapter.Endpoints=tcp -p 4412
+ServiceDiscovery.Locator.ServiceAdapter.Endpoints=tcp -p 4411
+ServiceDiscovery.IceStorm.InstanceName=ServiceDiscovery
+
 
-AsteriskSCFIceStorm.InstanceName=AsteriskSCFIceStorm
-#
 # This property defines the endpoints on which the IceStorm
 # TopicManager listens.
 #
-AsteriskSCFIceStorm.TopicManager.Endpoints=default -p 10000
-
-#
-# This property defines the endpoints on which the topic
-# publisher objects listen. If you want to federate
-# IceStorm instances this must run on a fixed port (or use
-# IceGrid).
-#
-AsteriskSCFIceStorm.Publish.Endpoints=tcp -p 10001:udp -p 10001
 
-#
-# TopicManager Tracing
-#
-# 0 = no tracing
-# 1 = trace topic creation, subscription, unsubscription
-# 2 = like 1, but with more detailed subscription information
-#
-AsteriskSCFIceStorm.Trace.TopicManager=2
-AsteriskSCFIceStorm.Transient=1
+ServiceDiscovery.IceStorm.TopicManager.Endpoints=default -p 4421
+ServiceDiscovery.IceStorm.Publish.Endpoints=tcp -p 4422:udp -p 4422
+ServiceDiscovery.IceStorm.Trace.TopicManager=2
+ServiceDiscovery.IceStorm.Transient=1
+ServiceDiscovery.IceStorm.Flush.Timeout=2000
 
-#
-AsteriskSCFIceStorm.Flush.Timeout=2000
 
-LoggerTestAdapter.Endpoints=default
diff --git a/server/src/main.cpp b/server/src/main.cpp
index 211b3d8..63ef85a 100644
--- a/server/src/main.cpp
+++ b/server/src/main.cpp
@@ -32,7 +32,6 @@ using namespace AsteriskSCF::System::Configuration::V1;
 
 namespace
 {
-const std::string AdapterName = "AsteriskSCF.LoggingService";
 const std::string ConfigurationServiceId = "LoggerConfigurationService";
 
 class LoggingService : public IceBox::Service
@@ -46,6 +45,7 @@ private:
     Ice::ObjectAdapterPtr mAdapter;
     ServiceManagementPrx mServiceManagement;
     ConfigurationServicePtr mConfigurationService;
+    std::string mName;
 
     void registerWithServiceLocator(const Ice::CommunicatorPtr& communicator,
         const LoggingServerPrx& serverProxy);
@@ -96,7 +96,7 @@ void LoggingService::setupDefaultProperties(const Ice::CommunicatorPtr& communic
 {
     Ice::PropertiesPtr props = communicator->getProperties();
 
-    setDefaultProperty(*props, AdapterName + ".Endpoints", "default");
+    setDefaultProperty(*props, mName + "ServiceAdapter.Endpoints", "default");
 }
 
 void LoggingService::setDefaultProperty(Ice::Properties& props,
@@ -108,13 +108,15 @@ void LoggingService::setDefaultProperty(Ice::Properties& props,
     }
 }
 
-void LoggingService::start(const std::string&,
+void LoggingService::start(const std::string& name,
     const Ice::CommunicatorPtr& communicator,
     const Ice::StringSeq&)
 {
+    mName = name;
+
     setupDefaultProperties(communicator);
 
-    mAdapter = communicator->createObjectAdapter(AdapterName);
+    mAdapter = communicator->createObjectAdapter(mName + ".ServiceAdapter");
 
     ServerConfigurationListenerPrx configurationListener;
 

commit a01a6b277c53958361ff9ec089d89bffcfaaeed0
Author: Brent Eagles <beagles at digium.com>
Date:   Fri Sep 16 13:29:10 2011 -0230

    Add filesystem library to logging server.

diff --git a/server/src/CMakeLists.txt b/server/src/CMakeLists.txt
index 622a1a8..a532caa 100644
--- a/server/src/CMakeLists.txt
+++ b/server/src/CMakeLists.txt
@@ -14,7 +14,7 @@ astscf_component_add_files(logging-service-lib LoggingServer.h)
 astscf_component_add_files(logging-service-lib Configuration.h)
 astscf_component_add_files(logging-service-lib ../../client/src/LogFormatter.cpp)
 astscf_component_add_slices(logging-service-lib PROJECT AsteriskSCF/Configuration/LoggingService/LoggingConfigurationIf.ice)
-astscf_component_add_boost_libraries(logging-service-lib core thread date_time system)
+astscf_component_add_boost_libraries(logging-service-lib core thread filesystem date_time system)
 astscf_component_add_ice_libraries(logging-service-lib IceStorm)
 astscf_component_add_slice_collection_libraries(logging-service-lib ASTSCF)
 astscf_component_build_library(logging-service-lib STATIC)

commit 1ca7bc4b970d94e072e5ffb0d2cf7fbf938292f0
Author: Brent Eagles <beagles at digium.com>
Date:   Fri Sep 16 12:57:34 2011 -0230

    Fix missing boost library for building on Windows.

diff --git a/client/src/CMakeLists.txt b/client/src/CMakeLists.txt
index 0b1db78..fe5faab 100644
--- a/client/src/CMakeLists.txt
+++ b/client/src/CMakeLists.txt
@@ -13,7 +13,7 @@ astscf_component_add_files(logging-client ../../include/AsteriskSCF/Logger/LogCo
 astscf_component_add_files(logging-client ../../include/AsteriskSCF/Logger/IceLogger.h)
 astscf_component_add_files(logging-client ../../include/AsteriskSCF/Logger/Level.h)
 astscf_component_add_files(logging-client ../../include/AsteriskSCF/Logger/LogFormatter.h)
-astscf_component_add_boost_libraries(logging-client thread date_time system)
+astscf_component_add_boost_libraries(logging-client thread date_time filesystem system)
 astscf_component_add_ice_libraries(logging-client IceStorm)
 astscf_component_add_slice_collection_libraries(logging-client ASTSCF)
 astscf_component_build_library(logging-client)

commit 5fc48c25d75b42b9cee68fae5969935434bdc16a
Author: Brent Eagles <beagles at digium.com>
Date:   Thu Sep 15 11:25:06 2011 -0230

    Add "Trace" logging level

diff --git a/include/AsteriskSCF/Logger/Level.h b/include/AsteriskSCF/Logger/Level.h
index 8c4353a..4f0cd99 100644
--- a/include/AsteriskSCF/Logger/Level.h
+++ b/include/AsteriskSCF/Logger/Level.h
@@ -25,6 +25,8 @@ inline std::ostream& operator<<(std::ostream& o, Level level)
 {
     switch (level)
     {
+    case Trace:
+        return o << "Trace";
     case Debug:
         return o << "Debug";
     case Info:
@@ -49,6 +51,10 @@ inline std::ostream& operator<<(std::ostream& o, Level level)
 
 inline Level parseString(const std::string& str)
 {
+    if (str == "Trace")
+    {
+        return Trace;
+    }
     if (str == "Debug")
     {
         return Debug;

commit 1ac6860fe3206e37cca9adb4745999d874f18a73
Author: Ken Hunt <ken.hunt at digium.com>
Date:   Mon Sep 12 17:06:06 2011 -0500

    Updates for compiler differences for the formmatted logging support.

diff --git a/server/src/ChainedLogOut.cpp b/server/src/ChainedLogOut.cpp
index 5870602..796be37 100644
--- a/server/src/ChainedLogOut.cpp
+++ b/server/src/ChainedLogOut.cpp
@@ -37,7 +37,7 @@ void ChainedLogOut::logs(const std::string& name, Level logLevel,
 }
 
 std::ostream& ChainedLogOut::logs(std::ostream& out, const std::string& name,
-    Level logLevel, const std::string& message)
+    Level, const std::string& message)
 {
     // date level name(1) message
     std::string::size_type nameStart = name.rfind('.');
diff --git a/server/src/Configuration.cpp b/server/src/Configuration.cpp
index 463b5dd..aabf7a6 100644
--- a/server/src/Configuration.cpp
+++ b/server/src/Configuration.cpp
@@ -375,9 +375,9 @@ void LoggerConfigurationService::removeConfigurationItems(const ConfigurationGro
                 {
                     if (mPriv->mGeneralConfiguration->mOutputFile && mPriv->mGeneralConfiguration->mOutputFile->fileName == fileItem->fileName)
                     {
-                        FileItemIPtr fileItem = mPriv->mGeneralConfiguration->mOutputFile;
+                        FileItemIPtr outputFile = mPriv->mGeneralConfiguration->mOutputFile;
                         mPriv->mGeneralConfiguration->mOutputFile = 0;
-                        mPriv->mServer->removeLogOut(fileItem->mOut);
+                        mPriv->mServer->removeLogOut(outputFile->mOut);
                     }
                 }
                 void visitFormatItem(const FormatItemPtr& formatItem)
diff --git a/server/test/ConfigurationTest.cpp b/server/test/ConfigurationTest.cpp
index 7f1b983..9b3d0eb 100644
--- a/server/test/ConfigurationTest.cpp
+++ b/server/test/ConfigurationTest.cpp
@@ -304,8 +304,6 @@ BOOST_AUTO_TEST_CASE(SetFormat)
     TestBed.confHelper->setFormat(std::string("$t{%Y%m%d %H:%M:%S}: $m: $n,$l"),serial++);
     //time_t Now = time(0);
     lg(Info) << "Informational message 3";
-    Ice::Long pid = (Ice::Long)boost::interprocess::detail::get_current_process_id();
-    // Set format to "logger_name : pid : msg_level : msg"
     TestBed.confHelper->setFormat(std::string("$l : $p : $n : $m"),serial++);
     std::string CurSourceInfo = SRCINFO(" (line=$l:function=$f:source=$sf)");
     lg(Debug) << "Debug message" << CurSourceInfo;
diff --git a/server/test/LoggingConfigurationHelper.cpp b/server/test/LoggingConfigurationHelper.cpp
index 65d47ad..fa03dd7 100644
--- a/server/test/LoggingConfigurationHelper.cpp
+++ b/server/test/LoggingConfigurationHelper.cpp
@@ -41,36 +41,35 @@ public:
      LevelItemPtr mLevelItem;
 
 private:
-    void visitLoggerGeneralGroup(const LoggerGeneralGroupPtr &group)
+    class ItemVisitor : public LoggerConfigurationItemVisitor
     {
-        class ItemVisitor : public LoggerConfigurationItemVisitor
+    public:
+        ItemVisitor() { }
+
+        FileItemPtr mFileItem;
+        FormatItemPtr mFormatItem;
+        LevelItemPtr mLevelItem;
+
+    private:
+        void visitFileItem(const FileItemPtr &fileItem)
         {
-        public:
-            ItemVisitor() { }
-
-            FileItemPtr mFileItem;
-            FormatItemPtr mFormatItem;
-            LevelItemPtr mLevelItem;
-
-        private:
-            void visitFileItem(const FileItemPtr &fileItem)
-            {
-                mFileItem = fileItem;
-            }
-
-            void visitFormatItem(const FormatItemPtr &formatItem)
-            {
-                mFormatItem = formatItem;
-            }
-
-            void visitLevelItem(const LevelItemPtr &levelItem)
-            {
-                mLevelItem = levelItem;
-            }
-        };
-        typedef IceUtil::Handle<ItemVisitor> ItemVisitorPtr;
-
-        ItemVisitorPtr generalVisitor = new ItemVisitor();
+            mFileItem = fileItem;
+        }
+
+        void visitFormatItem(const FormatItemPtr &formatItem)
+        {
+            mFormatItem = formatItem;
+        }
+
+        void visitLevelItem(const LevelItemPtr &levelItem)
+        {
+            mLevelItem = levelItem;
+        }
+    };
+
+    void visitLoggerGeneralGroup(const LoggerGeneralGroupPtr &group)
+    {
+        IceUtil::Handle<LogConfigVisitor::ItemVisitor> generalVisitor = new ItemVisitor();
 
         for (ConfigurationItemDict::const_iterator item = group->configurationItems.begin();
                 item != group->configurationItems.end();

commit 43bb75fbdf04568405f509920a69f5799722b5f0
Author: Ken Hunt <ken.hunt at digium.com>
Date:   Mon Sep 12 12:02:37 2011 -0500

     Logger formatting support.
      - Integrates the logger formatting support.
     - Updates the formatting to use boost for time and process id handling.
     - Updates the configurator to support setting format.
     - Updates the configurator to support setting the logging level.
     - Updates the tests.

diff --git a/client/src/CMakeLists.txt b/client/src/CMakeLists.txt
index 9cfff78..0b1db78 100644
--- a/client/src/CMakeLists.txt
+++ b/client/src/CMakeLists.txt
@@ -2,15 +2,18 @@ astscf_component_init(logging-client)
 astscf_component_add_files(logging-client Logger.cpp)
 astscf_component_add_files(logging-client LoggerFactory.cpp)
 astscf_component_add_files(logging-client LogOut.cpp)
+astscf_component_add_files(logging-client LogFormatter.cpp)
 astscf_component_add_files(logging-client IceConfigurator.cpp)
 astscf_component_add_files(logging-client IceLogger.cpp)
 astscf_component_add_files(logging-client OstreamLogger.cpp)
 astscf_component_add_files(logging-client IceConfigurator.h)
 astscf_component_add_files(logging-client ../../include/AsteriskSCF/logger.h)
 astscf_component_add_files(logging-client ../../include/AsteriskSCF/Logger/LogOut.h)
+astscf_component_add_files(logging-client ../../include/AsteriskSCF/Logger/LogConsts.h)
 astscf_component_add_files(logging-client ../../include/AsteriskSCF/Logger/IceLogger.h)
 astscf_component_add_files(logging-client ../../include/AsteriskSCF/Logger/Level.h)
-astscf_component_add_boost_libraries(logging-client thread date_time)
+astscf_component_add_files(logging-client ../../include/AsteriskSCF/Logger/LogFormatter.h)
+astscf_component_add_boost_libraries(logging-client thread date_time system)
 astscf_component_add_ice_libraries(logging-client IceStorm)
 astscf_component_add_slice_collection_libraries(logging-client ASTSCF)
 astscf_component_build_library(logging-client)
diff --git a/client/src/IceLogger.cpp b/client/src/IceLogger.cpp
index a72d48e..070c1b2 100644
--- a/client/src/IceLogger.cpp
+++ b/client/src/IceLogger.cpp
@@ -14,12 +14,16 @@
  * at the top of the source tree.
  */
 
+#include <boost/asio/ip/host_name.hpp>
+#include <boost/interprocess/detail/os_thread_functions.hpp>
+
 #include <IceStorm/IceStorm.h>
 
 #include <AsteriskSCF/Core/Discovery/ServiceLocatorIf.h>
 
 #include <AsteriskSCF/Logger/IceLogger.h>
 #include <AsteriskSCF/Logger/Level.h>
+#include <AsteriskSCF/Logger/LogConsts.h>
 
 using namespace AsteriskSCF::Core::Discovery::V1;
 using namespace AsteriskSCF::System::Logging;
@@ -30,9 +34,19 @@ void IceLogger::logs(const std::string& name, Level logLevel,
     bool logged = false;
     try
     {
+
+        std::string hostName = boost::asio::ip::host_name();
+
         if (mServer)
         {
-            mServer->logs(name, logLevel, message);
+            mServer->logs(name, 
+                          logLevel, 
+                          message, 
+                          hostName,
+                          (Ice::Long)boost::interprocess::detail::get_current_process_id(), 
+                          mComponentCategory,
+                          mComponentServiceName,
+                          mComponentId);
             logged = true;
         }
     }
@@ -55,10 +69,19 @@ void IceLogger::logs(const std::string& name, Level logLevel,
                 "!!! Unable to log to server.  Please check configuration and server status.\n"
                 "!!! Logging to stderr instead.\n";
         }
-        std::clog << name << ":" << logLevel << ":" << message << '\n';
+        std::clog << message << '\n';
     }
 }
 
+void IceLogger::setComponentInfo(const std::string& componentCategory, 
+                        const std::string& serviceName,
+                        const std::string& id)
+{
+    mComponentCategory = componentCategory;
+    mComponentServiceName = serviceName;
+    mComponentId = id;
+}
+
 IceUtil::Handle<ConfiguredIceLogger> ConfiguredIceLogger::create(
     const LoggingServerPrx& server)
 {
diff --git a/client/src/LogFormatter.cpp b/client/src/LogFormatter.cpp
new file mode 100644
index 0000000..f747772
--- /dev/null
+++ b/client/src/LogFormatter.cpp
@@ -0,0 +1,201 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/filesystem.hpp>
+
+#include <AsteriskSCF/logger.h>
+
+using namespace AsteriskSCF::System::Logging;
+using namespace std;
+
+LogFormatter::LogFormatter(const std::string& fmtStr) :
+    mFormat(fmtStr)
+{
+}
+
+LogFormatter::~LogFormatter()
+{
+}
+
+/**
+ * Builds a formatted string with some source code information in it.
+ */
+std::string AsteriskSCF::System::Logging::sourceInfoStr(const std::string& fmt, unsigned int line,
+                                                        const char* fcn, const char* file)
+{
+    std::string s(fmt);
+    std::size_t pos;
+    bool found = true;
+    
+    while (found)
+    {
+        found = false;
+        if ((pos=s.find("$l",0))!=std::string::npos)
+        {
+            s.replace(pos,2,boost::lexical_cast<std::string>(line));
+            found = true;
+        }
+        if ((pos=s.find("$f",0))!=std::string::npos)
+        {
+            s.replace(pos,2,boost::lexical_cast<std::string>(fcn));
+            found = true;
+        }
+        if ((pos=s.find("$sp",0))!=std::string::npos)
+        {
+            s.replace(pos,3,boost::lexical_cast<std::string>(file));
+            found = true;
+        }
+        if ((pos=s.find("$sf",0))!=std::string::npos)
+        {
+            boost::filesystem::path p(file);
+            s.replace(pos,3,boost::lexical_cast<std::string>(p.leaf()));
+            found = true;
+        }
+    }
+    return s;
+}
+
+void LogFormatter::setFormat(const std::string& fmtStr)
+{
+    boost::unique_lock<boost::shared_mutex> lock(mMutex);
+    mFormat = fmtStr;
+}
+
+std::string LogFormatter::getFormat()
+{
+    boost::shared_lock<boost::shared_mutex> lock(mMutex);
+
+    return mFormat;
+}
+
+std::string getFormattedTime(const boost::posix_time::ptime& t, const std::string& format)
+{
+    boost::posix_time::time_facet* outputFacet = new boost::posix_time::time_facet();
+
+    std::stringstream ss;
+    ss.imbue(std::locale(std::locale::classic(), outputFacet));
+    outputFacet->format(format.c_str());
+
+    ss << t;
+
+    return ss.str();
+}
+
+std::string getFormattedTime(const  boost::posix_time::ptime& t)
+{
+    std::stringstream ss;
+
+    ss << t;
+    return ss.str();
+}
+
+/**
+ * Formats a log string and returns it for output
+ */
+std::string LogFormatter::formatMessage(const std::string& message, const std::string& name, Level level,
+        const std::string& hostName, Ice::Long pid, 
+        const std::string& componentCategory, const std::string& serviceId, const std::string& instanceId) const
+{
+    std::string outStr;
+    std::size_t pos;
+    outStr = mFormat;
+
+    if ((pos=outStr.find("$t{",0)) != std::string::npos)
+    {
+        // Client timestamp (formatted). 
+        try
+        {
+            boost::posix_time::ptime now(boost::posix_time::microsec_clock::universal_time());
+
+            std::size_t pos2 = outStr.find("}",pos+3);
+            if (pos2 != std::string::npos)
+            {
+                std::string userTimeFormat = outStr.substr(pos+3,pos2-3);
+                std::string nowStr = getFormattedTime(now, userTimeFormat);
+
+                outStr.replace(pos,pos+pos2+1,nowStr);
+            }
+        }
+        catch (...)
+        {
+           // Don't do anything to outStr, so the timestamp format specifier will show up
+           // in the output and signal to someone that the format is wrong
+        }
+    }
+    else if ((pos=outStr.find("$t",0)) != std::string::npos)
+    {
+        // Client timestamp (default formatting)
+        boost::posix_time::ptime now(boost::posix_time::microsec_clock::universal_time());
+        string nowString = getFormattedTime(now);
+
+        outStr.replace(pos,2,nowString);
+    }
+
+    if ((pos=outStr.find("$n",0)) != std::string::npos)
+    {
+        // Logger name
+        outStr.replace(pos,2,name);
+    }
+
+    if ((pos=outStr.find("$l",0)) != std::string::npos)
+    {
+        // Priority / level
+        std::stringstream s("");
+
+        s << level;
+        outStr.replace(pos,2,s.str());
+    }
+
+    if ((pos=outStr.find("$h",0)) != std::string::npos)
+    {
+        // Client host name
+        if (hostName.size()==0)
+        {
+            outStr.replace(pos,2,"");
+        }
+        else outStr.replace(pos,2,hostName);
+    }
+
+    if ((pos=outStr.find("$p",0)) != std::string::npos)
+    {
+        // Process ID
+        outStr.replace(pos,2,boost::lexical_cast<std::string>(pid));
+    }
+
+    if ((pos=outStr.find("$C",0)) != std::string::npos)
+    {
+        outStr.replace(pos, 2, componentCategory);
+    }
+
+    if ((pos=outStr.find("$S",0)) != std::string::npos)
+    {
+         outStr.replace(pos, 2, serviceId);
+    }
+
+    if ((pos=outStr.find("$I",0)) != std::string::npos)
+    {
+         outStr.replace(pos, 2, instanceId);
+    }
+
+    if ((pos=outStr.find("$m",0)) != std::string::npos)
+    {
+        // Check for message specifier last so we don't modify the message itself
+        outStr.replace(pos,2,message);
+    }
+
+    return outStr;
+}
diff --git a/client/src/Logger.cpp b/client/src/Logger.cpp
index 99b651b..f06015a 100644
--- a/client/src/Logger.cpp
+++ b/client/src/Logger.cpp
@@ -16,29 +16,37 @@
 
 #include <cassert>
 #include <cstdio>
+#include <sstream>
+#include <iomanip>
+#include <cstdlib>
+#include <time.h>
+
+#include <boost/thread/thread.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
 
 #include <AsteriskSCF/logger.h>
 
 using namespace AsteriskSCF::System::Logging;
 
-const int MESSAGE_SIZE = 120;
 
-LogBuf::LogBuf(LogOut& out, const std::string& name, Level logLevel) :
-    mOut(out), nName(name), mLogLevel(logLevel)
+LogBuf::LogBuf(LogOut& out, const std::string& name, Level level) :
+    mOut(out), mName(name), mLogLevel(level)
 {
 }
 
+
 // NOTE: The copy constructor below intentionally calls the default constructor of its
 // std::streambuf base, rather than calling the copy constructor. The copy constructor
 // of std::streambuf is private (so it cannot be called), but more importantly, the
 // std::streambuf base object has no useful state that needs to be copied when a
 // LogBuf is copied.
 LogBuf::LogBuf(const LogBuf& orig) :
-    std::streambuf(), mOut(orig.mOut), nName(orig.nName), mLogLevel(orig.mLogLevel)
+    std::streambuf(), mOut(orig.mOut), mName(orig.mName), mLogLevel(orig.mLogLevel)
 {
     mBuffer.str(orig.mBuffer.str());
 }
 
+
 LogBuf::~LogBuf()
 {
     if (!mBuffer.str().empty())
@@ -47,6 +55,7 @@ LogBuf::~LogBuf()
     }
 }
 
+
 int LogBuf::overflow(int c)
 {
     if (c == '\n' || c == traits_type::eof())
@@ -57,24 +66,25 @@ int LogBuf::overflow(int c)
     return mBuffer.sputc((char) c);
 }
 
+
 void LogBuf::sendBuffer()
 {
-    // logic looks a bit backwards, but that's in case out.logs()
+    // logic looks a bit backwards, but that's in case mOut.logs()
     // throws an exception, we still want to clear the buffer.
     const std::string& message = mBuffer.str();
     mBuffer.str("");
-    // send
-    mOut.logs(nName, mLogLevel, message);
+    mOut.logs(mName,mLogLevel,message);
 }
 
+
 Logger::LoggerImpl::LoggerImpl(const std::string& name, LogOut& out, Level logLevel) :
     mParent(), mName(name), mOut(&out), mLogLevel(logLevel), mInheritedLevel(false)
 {
 }
 
+
 Logger::LoggerImpl::LoggerImpl(const boost::shared_ptr<LoggerImpl>& parent, const std::string& name) :
-    mParent(parent), mName(name), mOut(parent->mOut), mLogLevel(Off),
-    mInheritedLevel(true)
+    mParent(parent), mName(name), mOut(parent->mOut), mLogLevel(Off), mInheritedLevel(true)
 {
     // parent ptr must be non-null
     assert(parent != 0);
@@ -86,29 +96,33 @@ Logger::LoggerImpl::~LoggerImpl()
 {
 }
 
+
 CondStream Logger::LoggerImpl::operator()(Level level) const
 {
-    return CondStream(*mOut, mName, level, isEnabledFor(level));
+    return CondStream(*mOut,mName,level,isEnabledFor(level));
 }
 
+
 void Logger::LoggerImpl::logs(Level level, const std::string& message) const
 {
     if (isEnabledFor(level))
     {
-        mOut->logs(mName, level, message);
+        mOut->logs(mName,level,message);
     }
 }
 
+
 void Logger::LoggerImpl::vlogf(Level level, char const *fmt, va_list ap) const
 {
     if (isEnabledFor(level))
     {
         char message[MESSAGE_SIZE];
         vsnprintf(message, sizeof(message), fmt, ap);
-        mOut->logs(mName, level, message);
+        mOut->logs(mName,level,std::string(message));
     }
 }
 
+
 void Logger::LoggerImpl::setOutput(LogOut& out)
 {
     this->mOut = &out;
@@ -124,21 +138,23 @@ void Logger::LoggerImpl::setOutput(LogOut& out)
 
 void Logger::LoggerImpl::setLevel(Level logLevel)
 {
-    boost::unique_lock<boost::shared_mutex> lock(mLevelMutex);
+    boost::unique_lock<boost::shared_mutex> lock(mInheritedMutex);
     mLogLevel = logLevel;
     mInheritedLevel = false;
 }
 
+
 void Logger::LoggerImpl::unsetLevel()
 {
-    boost::unique_lock<boost::shared_mutex> lock(mLevelMutex);
+    boost::unique_lock<boost::shared_mutex> lock(mInheritedMutex);
     mInheritedLevel = true;
... 1883 lines suppressed ...


-- 
asterisk-scf/integration/logger.git



More information about the asterisk-scf-commits mailing list