[cpp-sp] branch main updated: Flesh out logging framework classes.

Scott Cantor cantor.2 at osu.edu
Mon Nov 25 14:24:47 UTC 2024


This is an automated email from the git hooks/post-receive script.

scantor pushed a commit to branch main
in repository cpp-sp.

View the commit online:
http://git.shibboleth.net/view/?p=cpp-sp.git;a=commit;h=b6cda251eccdf048fa31b0500c73eeca68330e82

The following commit(s) were added to refs/heads/main by this push:
     new b6cda251 Flesh out logging framework classes.
b6cda251 is described below

commit b6cda251eccdf048fa31b0500c73eeca68330e82
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Mon Nov 25 09:24:38 2024 -0500

    Flesh out logging framework classes.
---
 shibsp/AgentConfig.h                           | 21 ++----
 shibsp/Makefile.am                             |  4 ++
 shibsp/logging/Category.h                      | 45 +++++-------
 shibsp/logging/LoggingService.h                | 79 +++++++++++++++++++++
 shibsp/logging/Priority.h                      | 12 +++-
 shibsp/logging/impl/AbstractLoggingService.cpp | 96 ++++++++++++++++++++++++++
 shibsp/logging/impl/AbstractLoggingService.h   | 67 ++++++++++++++++++
 shibsp/logging/impl/Category.cpp               | 19 ++---
 shibsp/logging/impl/LoggingServiceSPI.h        | 71 +++++++++++++++++++
 shibsp/logging/impl/StringUtil.cpp             |  2 +-
 shibsp/logging/impl/StringUtil.h               |  2 +-
 shibsp/util/TemplateParameters.h               |  1 +
 12 files changed, 360 insertions(+), 59 deletions(-)

diff --git a/shibsp/AgentConfig.h b/shibsp/AgentConfig.h
index 3e64af5a..dbb3163c 100644
--- a/shibsp/AgentConfig.h
+++ b/shibsp/AgentConfig.h
@@ -21,28 +21,16 @@
 #ifndef __shibsp_agentconfig_h__
 #define __shibsp_agentconfig_h__
 
-#include <shibsp/base.h>
+#include <shibsp/util/PluginManager.h>
 
-#include <memory>
 #include <string>
-#include <xmltooling/PluginManager.h>
-
-/**
- * @namespace shibsp
- * Shibboleth Service Provider Library
- */
+#include <boost/property_tree/ptree_fwd.hpp>
 
 namespace shibsp {
 
-    class SHIBSP_API AccessControl;
     class SHIBSP_API Agent;
     class SHIBSP_API Category;
-    class SHIBSP_API Handler;
-    class SHIBSP_API ListenerService;
     class SHIBSP_API LoggingService;
-    class SHIBSP_API RequestMapper;
-    class SHIBSP_API SessionCache;
-    class SHIBSP_API SessionInitiator;
 
 #if defined (_MSC_VER)
     #pragma warning( push )
@@ -86,6 +74,11 @@ namespace shibsp {
          */
         virtual void term();
 
+        /**
+         * Manages factories for LoggingService plugins.
+         */
+        PluginManager<LoggingService,std::string,const boost::property_tree::ptree&> LoggingServiceManager;
+
         /**
          * Returns the global Agent instance.
          * 
diff --git a/shibsp/Makefile.am b/shibsp/Makefile.am
index d244609c..370cd76c 100644
--- a/shibsp/Makefile.am
+++ b/shibsp/Makefile.am
@@ -50,6 +50,7 @@ handinclude_HEADERS = \
 
 loginclude_HEADERS = \
 	logging/Category.h \
+	logging/LoggingService.h \
 	logging/Priority.h
 
 reminclude_HEADERS = \
@@ -71,6 +72,8 @@ noinst_HEADERS = \
 	impl/StorageServiceSessionCache.h \
 	impl/XMLApplication.h \
 	impl/XMLServiceProvider.h \
+	logging/impl/AbstractLoggingService.h \
+	logging/impl/LoggingServiceSPI.h \
 	logging/impl/StringUtil.h \
 	remoting/impl/SocketListener.h
 
@@ -114,6 +117,7 @@ libshibsp_la_SOURCES = \
 	impl/XMLRequestMapper.cpp \
 	impl/XMLServiceProvider.cpp \
 	logging/impl/Category.cpp \
+	logging/impl/AbstractLoggingService.cpp \
 	logging/impl/Priority.cpp \
 	logging/impl/StringUtil.cpp \
 	remoting/impl/ddf.cpp \
diff --git a/shibsp/logging/Category.h b/shibsp/logging/Category.h
index e98718ec..14646244 100644
--- a/shibsp/logging/Category.h
+++ b/shibsp/logging/Category.h
@@ -12,38 +12,42 @@
  * limitations under the License.
  */
 
+/**
+ * @file shibsp/logging/Category.h
+ *
+ * Logging facade used to send messages to LoggingService.
+ */
+
 #ifndef __shibsp_logging_category_h__
 #define __shibsp_logging_category_h__
 
 #include <shibsp/logging/Priority.h>
 
-#include <map>
-#include <vector>
 #include <cstdarg>
-#include <stdexcept>
 
 namespace shibsp {
 
+    class SHIBSP_API LoggingServiceSPI;
+
     /**
-     * This is the central class in the logging API, but is not a fully caoable
-     * port of a hierarchical logging system that allows differentiation of logging
-     * levels by category. This is merely a porting convenience and to potentially
-     * allow for that in the future.
+     * This is the central class in the logging API, and provides a convenience method
+     * to obtain instances of the class via an installed LoggingService.
      */   
     class SHIBSP_API Category {
         MAKE_NONCOPYABLE(Category);
     public:
         /**
-         * Instantiate a Category with name <code>name</code>. This
-         * method does not set priority of the category which is by
-         * default <code>Priority::NOTSET</code>.
+         * Instantiate a Category with the designated name.
+         * 
+         * This is a convenience method to match the original logging API used
+         * across the code base.
          * 
-         * @param name The name of the category to retrieve.
+         * @param name name of the category to retrieve.
          */
         static Category& getInstance(const std::string& name);
             
         /**
-         * Destructor for Category.
+         * Destructor.
          */
         virtual ~Category();
         
@@ -53,17 +57,6 @@ namespace shibsp {
          * @returns The category name.
          */       
         virtual const std::string& getName() const;
-        
-        /**
-         * Set the priority of this Category.
-         * 
-         * @param priority The priority to set. Use Priority::NOTSET to let 
-         * the category use its parents priority as effective priority.
-         * 
-         * @exception std::invalid_argument if the caller tries to set
-         * Priority::NOTSET on the Root Category.
-         */
-        virtual void setPriority(Priority::Value priority);
 
         /**
          * Returns the assigned Priority, if any, for this Category.
@@ -235,13 +228,12 @@ namespace shibsp {
         /**
          * Constructor.
          * 
+         * @param spi implementation interface for logging service to handle output
          * @param name the fully qualified name of this Category
-         * @param parent the parent of this parent, or NULL for the root 
-         * Category
          * @param priority the priority for this Category. Defaults to
          * Priority::SHIB_NOTSET
          */
-        Category(const std::string& name, Priority::Value priority = Priority::SHIB_NOTSET);
+        Category(LoggingServiceSPI& spi, const std::string& name, Priority::Value priority = Priority::SHIB_NOTSET);
         
         /** 
          * Unconditionally log a message with the specified priority.
@@ -261,6 +253,7 @@ namespace shibsp {
         virtual void _logUnconditionally2(Priority::Value priority, const std::string& message) throw();
 
     private:
+        LoggingServiceSPI& m_spi;
         const std::string m_name;
         Priority::Value m_priority;
     };
diff --git a/shibsp/logging/LoggingService.h b/shibsp/logging/LoggingService.h
new file mode 100644
index 00000000..cecef4f0
--- /dev/null
+++ b/shibsp/logging/LoggingService.h
@@ -0,0 +1,79 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file shibsp/logging/LoggingService.h
+ *
+ * Logging service abstracting configuration and output of log messages.
+ */
+
+#ifndef __shibsp_logging_h__
+#define __shibsp_logging_h__
+
+#include <shibsp/logging/Category.h>
+
+namespace shibsp {
+
+     /**
+     * Interface to a logging service.
+     *
+     * Logging services expose a simple API to obtain Category instances to log
+     * messages. Applications interact with this service by obtaining Category objects
+     * and using them to log messages.
+     */
+    class SHIBSP_API LoggingService
+    {
+        MAKE_NONCOPYABLE(LoggingService);
+    protected:
+        LoggingService();
+    public:
+        virtual ~LoggingService();
+
+        /**
+         * Initializes the designated logging service.
+         */
+        virtual bool init()=0;
+
+        /**
+         * Terminates the designated logging service.
+         */
+        virtual bool term()=0;
+
+        /**
+         * Retrieves an instance of a logging Category of the specified name (empty is permitted).
+         * 
+         * The object may (but need not be) shared and is owned by the logging service. Its priority
+         * will be set based on the underlying configuration of this service and is immutable.
+         * 
+         * @param name category name
+         */
+        virtual Category& getCategory(const std::string& name)=0;
+    };
+
+    /**
+     * Registers LoggingService classes into the runtime.
+     */
+    void SHIBSP_API registerLoggingServices();
+
+    /** Logging to the console. */
+    #define CONSOLE_LOGGING_SERVICE     "console"
+
+    /** Logging to the syslog API. */
+    #define SYSLOG_LOGGING_SERVICE      "syslog"
+
+    /** Logging to the Windows Event Log. */
+    #define WINDOWS_LOGGING_SERVICE     "windows"
+};
+
+#endif /* __shibsp_logging_h__ */
diff --git a/shibsp/logging/Priority.h b/shibsp/logging/Priority.h
index 3a383845..8168ae46 100644
--- a/shibsp/logging/Priority.h
+++ b/shibsp/logging/Priority.h
@@ -12,13 +12,19 @@
  * limitations under the License.
  */
 
+/**
+ * @file shibsp/logging/Priority.h
+ *
+ * Constrained set of logging levels.
+ */
+
+
 #ifndef __shibsp_logging_priority_h__
 #define __shibsp_logging_priority_h__
 
 #include <shibsp/base.h>
 
 #include <string>
-#include <stdexcept>
 
 namespace shibsp {
 
@@ -31,14 +37,14 @@ namespace shibsp {
         /**
          * Predefined Levels of Priorities.
          */
-        enum {
+        enum PriorityLevel {
             SHIB_CRIT   = 0,
             SHIB_ERROR  = 100,
             SHIB_WARN   = 200,
             SHIB_INFO   = 300,
             SHIB_DEBUG  = 400,
             SHIB_NOTSET = 500
-        } PriorityLevel;
+        };
 
         /**
          * The type of Priority Values.
diff --git a/shibsp/logging/impl/AbstractLoggingService.cpp b/shibsp/logging/impl/AbstractLoggingService.cpp
new file mode 100644
index 00000000..c5371723
--- /dev/null
+++ b/shibsp/logging/impl/AbstractLoggingService.cpp
@@ -0,0 +1,96 @@
+/**
+ * Licensed to the University Corporation for Advanced Internet
+ * Development, Inc. (UCAID) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for
+ * additional information regarding copyright ownership.
+ *
+ * UCAID licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the
+ * License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the License.
+ */
+
+/**
+ * logging/impl/AbstractLoggingService.cpp
+ *
+ * Base class for logging service implementations.
+ */
+
+#include "internal.h"
+
+#include "AgentConfig.h"
+#include "logging/impl/AbstractLoggingService.h"
+
+using namespace shibsp;
+using namespace boost::property_tree;
+using namespace std;
+
+namespace shibsp {
+    class CategoryImpl : public virtual Category {
+    public:
+        CategoryImpl(LoggingServiceSPI& spi, const std::string& name, Priority::Value priority)
+            : Category(spi, name, priority) {
+        }
+    };
+
+    //extern LoggingService* SHIBSP_DLLLOCAL ConsoleLoggingServiceFactory(const ptree& pt, bool);
+#ifdef WIN32
+    extern LoggingService* SHIBSP_DLLLOCAL WindowsLoggingServiceFactory(const ptree& pt, bool);
+#else
+    //extern LoggingService* SHIBSP_DLLLOCAL SyslogLoggingServiceFactory(const ptree& pt, bool);
+#endif
+}
+
+void SHIBSP_API shibsp::registerLoggingServices()
+{
+    AgentConfig& conf=AgentConfig::getConfig();
+    //conf.LoggingServiceManager.registerFactory(CONSOLE_LOGGING_SERVICE, ConsoleLoggingServiceFactory);
+#ifdef WIN32
+    conf.LoggingServiceManager.registerFactory(WINDOWS_LOGGING_SERVICE, WindowsLoggingServiceFactory);
+#else
+    //conf.LoggingServiceManager.registerFactory(SYSLOG_LOGGING_SERVICE, SyslogLoggingServiceFactory);
+#endif
+}
+
+LoggingService::LoggingService() {}
+
+LoggingService::~LoggingService() {}
+
+LoggingServiceSPI::LoggingServiceSPI() {}
+
+LoggingServiceSPI::~LoggingServiceSPI() {}
+
+AbstractLoggingService::~AbstractLoggingService() {}
+
+AbstractLoggingService::AbstractLoggingService(const ptree& pt)
+{
+    // Processes property tree to create mappings from category name to logging level.
+    // If an invalid property token is seen, the default level is SHIB_INFO.
+}
+
+Category& AbstractLoggingService::getCategory(const std::string& name)
+{
+    lock_guard<mutex> locker(m_lock);
+
+    auto cat = m_categoryMap.find(name);
+    if (cat != end(m_categoryMap)) {
+        return *(cat->second);
+    }
+
+    // Whoever designed STL's map interface is some kind of sadistic psychppath.
+
+    auto iter = m_priorityMap.find(name);
+    Priority::PriorityLevel prio = iter != end(m_priorityMap) ? iter->second : m_defaultPriority;
+    
+    auto map_insert_result = m_categoryMap.insert({name, unique_ptr<Category>(new CategoryImpl(*this, name, prio))});
+    // The insert result is a pair<iterator,bool> and the map's value is a pair<key.value>, thus....
+    return *(map_insert_result.first->second.get());
+}
diff --git a/shibsp/logging/impl/AbstractLoggingService.h b/shibsp/logging/impl/AbstractLoggingService.h
new file mode 100644
index 00000000..60b30dad
--- /dev/null
+++ b/shibsp/logging/impl/AbstractLoggingService.h
@@ -0,0 +1,67 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * shibsp/logging/AbstractLoggingService.h
+ *
+ * Base class for LoggingService/SPI implementations.
+ */
+
+#ifndef __shibsp_abstractlogging_h__
+#define __shibsp_abstractlogging_h__
+
+#include "internal.h"
+#include "logging/impl/LoggingServiceSPI.h"
+
+#include <map>
+#include <memory>
+#include <string>
+#include <thread>
+#include <shibsp/logging/LoggingService.h>
+#include <shibsp/logging/Priority.h>
+
+#include <boost/property_tree/ptree_fwd.hpp>
+
+namespace shibsp {
+
+     /**
+     * Base class for logging services that handles category management.
+     */
+    class SHIBSP_API AbstractLoggingService : public virtual LoggingService, public virtual LoggingServiceSPI
+    {
+        MAKE_NONCOPYABLE(AbstractLoggingService);
+    protected:
+        AbstractLoggingService(const boost::property_tree::ptree& pt);
+    public:
+        virtual ~AbstractLoggingService();
+
+        Category& getCategory(const std::string& name);
+
+    private:
+        // Default logging level.
+        Priority::PriorityLevel m_defaultPriority;
+
+        // Result of parsing configuration.
+        std::map<std::string,Priority::PriorityLevel> m_priorityMap;
+
+        // Manages shared Category objects.
+        std::map<std::string,std::unique_ptr<Category>> m_categoryMap;
+
+        // Guards category map.
+        std::mutex m_lock;
+    };
+
+};
+
+#endif /* __shibsp_abstractlogging_h__ */
diff --git a/shibsp/logging/impl/Category.cpp b/shibsp/logging/impl/Category.cpp
index 09057205..17b43027 100644
--- a/shibsp/logging/impl/Category.cpp
+++ b/shibsp/logging/impl/Category.cpp
@@ -13,7 +13,8 @@
  */
 
 #include "logging/Category.h"
-#include "StringUtil.h"
+#include "logging/impl/LoggingServiceSPI.h"
+#include "logging/impl/StringUtil.h"
 
 using namespace shibsp;
 
@@ -21,7 +22,8 @@ Category& Category::getInstance(const std::string& name) {
     //return HierarchyMaintainer::getDefaultMaintainer().getInstance(name);
 }
 
-Category::Category(const std::string& name, Priority::Value priority) : m_name(name), m_priority(priority) {
+Category::Category(LoggingServiceSPI& spi, const std::string& name, Priority::Value priority)
+    : m_spi(spi), m_name(name), m_priority(priority) {
 }
 
 Category::~Category() {
@@ -35,23 +37,12 @@ Priority::Value Category::getPriority() const {
     return m_priority; 
 }
 
-void Category::setPriority(Priority::Value priority) {
-    if ((priority < Priority::SHIB_NOTSET)) {
-        m_priority = priority;
-    } else {
-        /* caller tried to set NOTSET priority to root Category. 
-            Bad caller!
-        */
-        throw std::invalid_argument("cannot set priority SHIB_NOTSET on Root Category");
-    }
-}
-
 void Category::_logUnconditionally(Priority::Value priority, const char* format, va_list arguments) throw() {
     _logUnconditionally2(priority, StringUtil::vform(format, arguments));
 }
 
 void Category::_logUnconditionally2(Priority::Value priority, const std::string& message) throw() {
-    // TODO: do the actual logging
+    m_spi.outputMessage(*this, message);
 }
 
 bool Category::isPriorityEnabled(Priority::Value priority) const {
diff --git a/shibsp/logging/impl/LoggingServiceSPI.h b/shibsp/logging/impl/LoggingServiceSPI.h
new file mode 100644
index 00000000..a4a87fd6
--- /dev/null
+++ b/shibsp/logging/impl/LoggingServiceSPI.h
@@ -0,0 +1,71 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * shibsp/logging/LoggingServiceSPI.h
+ *
+ * Logging service abstracting configuration and output of log messages.
+ */
+
+#ifndef __shibsp_loggingspi_h__
+#define __shibsp_loggingspi_h__
+
+#include <shibsp/logging/Category.h>
+
+namespace shibsp {
+
+     /**
+     * Interface to a logging service implementation.
+     *
+     * Logging service implementations expose a simple API to output log
+     * messages and are the "internal" portion of a LoggingService.
+     */
+    class SHIBSP_API LoggingServiceSPI
+    {
+        MAKE_NONCOPYABLE(LoggingServiceSPI);
+    protected:
+        LoggingServiceSPI();
+    public:
+        virtual ~LoggingServiceSPI();
+
+        /**
+         * Initializes the designated logging service.
+         */
+        virtual bool init()=0;
+
+        /**
+         * Terminates the designated logging service.
+         */
+        virtual bool term()=0;
+
+        /**
+         * Outputs a logging message in whatever manner is defined by the underlying implementation.
+         * 
+         * @param category logging category
+         * @param message logging message
+         */
+        virtual void outputMessage(Category& category, const std::string& message)=0;
+
+        /**
+         * Outputs a logging message in whatever manner is defined by the underlying implementation.
+         * 
+         * @param category logging category
+         * @param message logging message
+         */
+        virtual void outputMessage(Category& category, const char* message)=0;
+    };
+
+};
+
+#endif /* __shibsp_loggingspi_h__ */
diff --git a/shibsp/logging/impl/StringUtil.cpp b/shibsp/logging/impl/StringUtil.cpp
index a5f50bae..2c2b4f45 100644
--- a/shibsp/logging/impl/StringUtil.cpp
+++ b/shibsp/logging/impl/StringUtil.cpp
@@ -12,7 +12,7 @@
  * limitations under the License.
  */
 
-#include "StringUtil.h"
+#include "logging/impl/StringUtil.h"
 
 #include <cstdio>
 
diff --git a/shibsp/logging/impl/StringUtil.h b/shibsp/logging/impl/StringUtil.h
index f4b42a7a..3bf48ca6 100644
--- a/shibsp/logging/impl/StringUtil.h
+++ b/shibsp/logging/impl/StringUtil.h
@@ -15,7 +15,7 @@
 #ifndef __shibsp_logging_stringutil_h__
 #define __shibsp_logging_stringutil_h__
 
-#include <shibsp/base.h>
+#include "internal.h"
 
 #include <string>
 #include <vector>
diff --git a/shibsp/util/TemplateParameters.h b/shibsp/util/TemplateParameters.h
index dc7b12e3..a93aabe2 100644
--- a/shibsp/util/TemplateParameters.h
+++ b/shibsp/util/TemplateParameters.h
@@ -29,6 +29,7 @@
 
 #include <shibsp/base.h>
 
+#include <xmltooling/exceptions.h>
 #include <xmltooling/util/TemplateEngine.h>
 
 namespace shibsp {

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list