From 199d70751cd1e2b7fd66a5f1f044b62b982fc83b Mon Sep 17 00:00:00 2001
From: Peter M. Groen <peter.groen@priva.com>
Date: Thu, 21 Apr 2022 17:56:00 +0200
Subject: [PATCH] implement logging to mqttclient

---
 CMakeLists.txt              | 27 ++-------------------------
 examples/pub/CMakeLists.txt |  4 ++--
 examples/sub/CMakeLists.txt |  2 +-
 src/CMakeLists.txt          | 25 +++----------------------
 src/mqttclient.cpp          | 58 ++++++++++++++++++++++++++++++++--------------------------
 test/CMakeLists.txt         |  2 +-
 6 files changed, 41 insertions(+), 77 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 747cca2..6996aa8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,39 +1,16 @@
 cmake_minimum_required(VERSION 3.0)
 project(osdev_mqtt)
-# ==============================================================================
-# Check to see if we're a submodule or top-repo.
-if(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
-    message( STATUS "Looks like we're a single module" )
-    LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
-elseif(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../cmake)
-    message( STATUS "Looks like we're a submodule" )
-    LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../cmake)
-else()
-    message( FATAL_ERROR "No cmake directory found. Did you run the submodules script?" )
-endif()
-
-# ==============================================================================
-# Check to see if there is versioning information available
-if(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/versioning)
-    LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/versioning/cmake)
-elseif(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../versioning)
-    LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../versioning/cmake)
-else()
-    message( FATAL_ERROR "No ${CURRENT_SOURCE_DIR}/osdev_versioning directory found. Did you run the submodules script?" )
-endif()
+LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/submodules/cmake)
 
 # ==============================================================================
 # = Include build information
-include(osdevversion)
 include(projectheader)
-
 project_header(osdev_mqtt)
 
+add_subdirectory(submodules/logger)
 add_subdirectory(src)
 add_subdirectory(examples/pub)
 add_subdirectory(examples/sub)
 
 include(packaging)
 package_component()
-
-# add_subdirectory(test)
diff --git a/examples/pub/CMakeLists.txt b/examples/pub/CMakeLists.txt
index d26ac52..89130cc 100644
--- a/examples/pub/CMakeLists.txt
+++ b/examples/pub/CMakeLists.txt
@@ -1,5 +1,5 @@
 cmake_minimum_required(VERSION 3.0)
-LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../cmake)
+LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/submodules/cmake)
 
 include(projectheader)
 project_header(test_mqtt_pub)
@@ -27,7 +27,7 @@ target_link_libraries(
 set_target_properties( ${PROJECT_NAME} PROPERTIES
     RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
     LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib
-    ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/archive
+    ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib
 )
 
 include(installation)
diff --git a/examples/sub/CMakeLists.txt b/examples/sub/CMakeLists.txt
index 281089e..9b512b8 100644
--- a/examples/sub/CMakeLists.txt
+++ b/examples/sub/CMakeLists.txt
@@ -1,5 +1,5 @@
 cmake_minimum_required(VERSION 3.0)
-LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../cmake)
+LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/submodules/cmake)
 
 include(projectheader)
 project_header(test_mqtt_sub)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6820971..0876440 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,28 +1,7 @@
 cmake_minimum_required(VERSION 3.12)
-# ==============================================================================
-# Check to see if we're a submodule or top-repo.
-if(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../cmake)
-    message( STATUS "Looks like we're a single module" )
-    LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../cmake)
-elseif(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../cmake)
-    message( STATUS "Looks like we're a submodule" )
-    LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../cmake)
-else()
-    message( FATAL_ERROR "No cmake directory found. Did you run the submodules script?" )
-endif()
+LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/submodules/cmake)
 
-# ==============================================================================
-# Check to see if there is versioning information available
-if(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../versioning)
-    LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../versioning/cmake)
-elseif(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../versioning)
-    LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../versioning/cmake)
-else()
-    message( FATAL_ERROR "No ${CURRENT_SOURCE_DIR}/osdev_versioning directory found. Did you run the submodules script?" )
-endif()
-# ==============================================================================
 include(projectheader)
-
 project_header(mqtt-cpp)
 
 find_package( Boost REQUIRED COMPONENTS regex )
@@ -31,6 +10,7 @@ include(compiler)
 
 include_directories(
     ${CMAKE_SOURCE_DIR}/include
+    ${CMAKE_SOURCE_DIR}/submodules/logger/src
 )
 
 set(SRC_LIST
@@ -67,6 +47,7 @@ add_libraries(
         Boost::boost
         Boost::regex
         paho-mqtt3a
+        ${CMAKE_SOURCE_DIR}/build/lib/liblogger.a
 )
 
 include(installation)
diff --git a/src/mqttclient.cpp b/src/mqttclient.cpp
index ac7ea4f..5e2d1e6 100644
--- a/src/mqttclient.cpp
+++ b/src/mqttclient.cpp
@@ -21,6 +21,9 @@
  * ***************************************************************************/
 #include "mqttclient.h"
 
+// osdev::components::logger
+#include "log.h"
+ 
 // osdev::components::mqtt
 #include "clientpaho.h"
 #include "mqttutil.h"
@@ -32,8 +35,10 @@
 // std
 #include <numeric>
 #include <iostream>
+#include <string>
 
 using namespace osdev::components::mqtt;
+using namespace osdev::components::log;
 
 namespace {
 /**
@@ -63,6 +68,8 @@ MqttClient::MqttClient(const std::string& _clientId, const std::function<void(co
     , m_eventQueue(_clientId)
     , m_workerThread( std::thread( &MqttClient::eventHandler, this ) )
 {
+    Log::init( "mqtt-library" );
+    LogInfo( "MQTT Client started", "[MqttClient::MqttClient]");
 }
 
 MqttClient::~MqttClient()
@@ -73,16 +80,16 @@ MqttClient::~MqttClient()
         decltype(m_principalClient) principalClient{};
 
         OSDEV_COMPONENTS_LOCKGUARD(m_internalMutex);
-        // LogDebug( "MqttClient", std::string( m_clientId + " - cleanup principal client" ) );
+        LogDebug( "MqttClient", std::string( m_clientId + " - cleanup principal client" ) );
         m_principalClient.swap(principalClient);
     }
 
-    // LogDebug( "MqttClient", std::string( m_clientId + " - dtor stop queue" ) );
+    LogDebug( "MqttClient", std::string( m_clientId + " - dtor stop queue" ) );
     m_eventQueue.stop();
     if (m_workerThread.joinable()) {
         m_workerThread.join();
     }
-    // LogDebug( "MqttClient", std::string( m_clientId + " - dtor ready" ) );
+    LogDebug( "MqttClient", std::string( m_clientId + " - dtor ready" ) );
 }
 
 std::string MqttClient::clientId() const
@@ -133,7 +140,7 @@ void MqttClient::connect(const std::string& host, int port, const Credentials& c
 
 void MqttClient::connect(const std::string& _endpoint)
 {
-    // LogInfo( "MqttClient", std::string( m_clientId + " - Request connect" ) );
+    LogInfo( "MqttClient", std::string( m_clientId + " - Request connect" ) );
 
     OSDEV_COMPONENTS_LOCKGUARD(m_interfaceMutex);
     IMqttClientImpl* client(nullptr);
@@ -147,7 +154,7 @@ void MqttClient::connect(const std::string& _endpoint)
             }
             else
             {
-                // LogError( "MqttClient", std::string( m_clientId + " - Cannot connect to different endpoint. Disconnect first." ) );
+                LogError( "MqttClient", std::string( m_clientId + " - Cannot connect to different endpoint. Disconnect first." ) );
                 return;
             }
         }
@@ -167,7 +174,7 @@ void MqttClient::connect(const std::string& _endpoint)
 
 void MqttClient::disconnect()
 {
-    // LogInfo( "MqttClient", std::string( m_clientId + " - Request disconnect" ) );
+    LogInfo( "MqttClient", std::string( m_clientId + " - Request disconnect" ) );
     OSDEV_COMPONENTS_LOCKGUARD(m_interfaceMutex);
 
     decltype(m_additionalClients) additionalClients{};
@@ -176,6 +183,7 @@ void MqttClient::disconnect()
         OSDEV_COMPONENTS_LOCKGUARD(m_internalMutex);
         if (!m_principalClient || m_principalClient->connectionStatus() == ConnectionStatus::Disconnected || m_principalClient->connectionStatus() == ConnectionStatus::DisconnectInProgress)
         {
+            LogDebug( "MqttClient", std::string( m_clientId + " - Principal client not connected" ) );
             return;
         }
         m_additionalClients.swap( additionalClients );
@@ -188,8 +196,7 @@ void MqttClient::disconnect()
     }
 
 
-    // LogDebug( "MqttClient", std::string( m_clientId +  " - Unsubscribe and disconnect clients" ) );
-    // DebugLogToFIle ("MqttClient", "%1 - Unsubscribe and disconnect clients", m_clientId);
+    LogDebug( "MqttClient", std::string( m_clientId +  " - Unsubscribe and disconnect clients" ) );
     for ( auto& cl : clients )
     {
         cl->unsubscribeAll();
@@ -215,15 +222,15 @@ Token MqttClient::publish(const MqttMessage& message, int qos)
         {
             if( !m_principalClient )
             {
-                std::cout << "Principal client not initialized" << std::endl;
+                LogInfo( "[MqttClient::publish]", std::string( "Principal client not initialized") );
             }
 
             if( m_principalClient->connectionStatus() == ConnectionStatus::Disconnected )
             {
                 std::cout << "Unable to publish, not connected.." << std::endl;
             }
-            // ErrorLogToFIle ("MqttClient", "%1 - Unable to publish, not connected", m_clientId);
-            // Throw (MqttException, "Not connected");
+            LogError("MqttClient", std::string( m_clientId + " - Unable to publish, not connected" ) );
+
             return Token(m_clientId, -1);
         }
         client = m_principalClient.get();
@@ -233,7 +240,7 @@ Token MqttClient::publish(const MqttMessage& message, int qos)
 
 Token MqttClient::subscribe(const std::string& topic, int qos, const std::function<void(MqttMessage)>& cb)
 {
-    // DebugLogToFIle ("MqttClient", "%1 - Subscribe to topic %2 with qos %3", m_clientId, topic, qos);
+    LogDebug( "[MqttClient::subscribe]", std::string( m_clientId + " - Subscribe to topic " + topic ) );
     // OSDEV_COMPONENTS_LOCKGUARD(m_interfaceMutex);
     bool clientFound = false;
     IMqttClientImpl* client(nullptr);
@@ -241,7 +248,7 @@ Token MqttClient::subscribe(const std::string& topic, int qos, const std::functi
         // OSDEV_COMPONENTS_LOCKGUARD(m_internalMutex);
         if (!m_principalClient || m_principalClient->connectionStatus() == ConnectionStatus::Disconnected)
         {
-            // ErrorLogToFIle ("MqttClient", "%1 - Unable to subscribe, not connected", m_clientId);
+            LogError("MqttClient", std::string( m_clientId + " - Unable to subscribe, not connected" ) );
             // throw (?)(MqttException, "Not connected");
             return Token(m_clientId, -1);
         }
@@ -259,7 +266,7 @@ Token MqttClient::subscribe(const std::string& topic, int qos, const std::functi
             }
         }
         if (!clientFound) {
-            // DebugLogToFIle ("MqttClient", "%1 - Creating new ClientPaho instance for subscription on topic %2", m_clientId, topic);
+            LogDebug("[MqttClient::subscribe]", std::string( m_clientId + " - Creating new ClientPaho instance for subscription on topic " + topic ) );
             std::string derivedClientId(generateUniqueClientId(m_clientId, m_additionalClients.size() + 2)); // principal client is nr 1.
             m_additionalClients.emplace_back(std::make_unique<ClientPaho>(
                 m_endpoint,
@@ -277,13 +284,13 @@ Token MqttClient::subscribe(const std::string& topic, int qos, const std::functi
 
 std::set<Token> MqttClient::unsubscribe(const std::string& topic, int qos)
 {
-    // DebugLogToFIle ("MqttClient", "%1 - Unsubscribe from topic %2 with qos %3", m_clientId, topic, qos);
+    LogDebug("[MqttClient::unsubscribe]", std::string( m_clientId + " - Unsubscribe from topic " + topic ) );
     OSDEV_COMPONENTS_LOCKGUARD(m_interfaceMutex);
     std::vector<IMqttClientImpl*> clients{};
     {
         OSDEV_COMPONENTS_LOCKGUARD(m_internalMutex);
         if (!m_principalClient || m_principalClient->connectionStatus() == ConnectionStatus::Disconnected) {
-            // ErrorLogToFIle ("MqttClient", "%1 - Unable to unsubscribe, not connected", m_clientId);
+            LogError("[MqttClient::unsubscribe]", std::string( m_clientId + " - Unable to unsubscribe, not connected" ) );
             // Throw (MqttException, "Not connected");
             return std::set<Token>();
         }
@@ -366,9 +373,7 @@ std::string MqttClient::endpoint() const
 
 void MqttClient::connectionStatusChanged(const std::string& id, ConnectionStatus cs)
 {
-    (void)id;
-    (void)cs;
-    // DebugLogToFIle ("MqttClient", "%1 - connection status of wrapped client %2 changed to %3", m_clientId, id, cs);
+    LogDebug("[MqttClient::connectionStatusChanged]", std::string( m_clientId + " - connection status of wrapped client " + id + " changed to " + std::to_string( static_cast<int>(cs) ) ) );
     IMqttClientImpl* principalClient{ nullptr };
     std::vector<IMqttClientImpl*> clients{};
     std::vector<ConnectionStatus> connectionStates{};
@@ -399,7 +404,7 @@ void MqttClient::connectionStatusChanged(const std::string& id, ConnectionStatus
                 cl->resubscribe();
             }
             catch (const std::exception& e) {
-                // ErrorLogToFIle ("MqttClient", "%1 - resubscribe on wrapped client %2 in context of connection status change in wrapped client %3 failed : %4", m_clientId, cl->clientId(), id, e.what());
+                LogError("[MqttClient::connectionStatusChanged]", std::string( m_clientId + " - resubscribe on wrapped client " + cl->clientId() + " in context of connection status change in wrapped client : " + id + " => FAILED : " + e.what() ) );
             }
         }
         m_activeTokensCV.notify_all();
@@ -414,7 +419,7 @@ void MqttClient::connectionStatusChanged(const std::string& id, ConnectionStatus
             auto waitFor = std::chrono::milliseconds(1000);
             if (!waitForCompletionInternalClients(clients, waitFor, std::set<Token>{})) {
                 if (std::accumulate(clients.begin(), clients.end(), false, [](bool hasPending, IMqttClientImpl* client) { return hasPending || client->hasPendingSubscriptions(); })) {
-                    // WarnLogToFIle ("MqttClient", "%1 - subscriptions are not recovered within timeout.", m_clientId)
+                    LogWarning("[MqttClient::connectionStatusChanged]", std::string( m_clientId + " - subscriptions are not recovered within timeout." ) );
                 }
             }
             if (principalClient) {
@@ -422,7 +427,7 @@ void MqttClient::connectionStatusChanged(const std::string& id, ConnectionStatus
                     principalClient->publishPending();
                 }
                 catch (const std::exception& e) {
-                    // ErrorLogToFIle ("MqttClient", "%1 - publishPending on wrapped client %2 failed : %3", m_clientId, principalClient->clientId(), e.what());
+                    LogError( "[MqttClient::connectionStatusChanged]", std::string( m_clientId + " - publishPending on wrapped client " + principalClient->clientId() + " => FAILED " + e.what() ) );
                 }
             }
         }
@@ -441,7 +446,7 @@ void MqttClient::deliveryComplete(const std::string& _clientId, std::int32_t tok
         OSDEV_COMPONENTS_LOCKGUARD(m_internalMutex);
         if (!m_activeTokens.insert(t).second) {
             // This should not happen. This means that some callback on the wrapper never came.
-            // ErrorLogToFIle ("MqttClient", "%1 -deliveryComplete, token %1 is already active", m_clientId, t);
+            LogDebug("[MqttClient::deliveryComplete]", std::string( m_clientId + " - deliveryComplete, token is already active" ) );
         }
     }
     this->pushEvent([this, t]() {
@@ -538,8 +543,9 @@ void MqttClient::pushEvent(std::function<void()> ev)
 
 void MqttClient::eventHandler()
 {
-    // InfoLogToFIle ("MqttClient", "%1 - starting event handler", m_clientId);
-    for (;;) {
+    LogInfo("[MqttClient::eventHandler]", std::string( m_clientId + " - starting event handler." ) );
+    for (;;)
+    {
         std::vector<std::function<void()>> events;
         if (!m_eventQueue.pop(events))
         {
@@ -550,5 +556,5 @@ void MqttClient::eventHandler()
             ev();
         }
     }
-    // InfoLogToFIle ("MqttClient", "%1 - leaving event handler", m_clientId);
+    LogInfo("[MqttClient::eventHandler]", std::string( m_clientId + " - leaving event handler." ) );
 }
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 2c88488..ff85c98 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -27,7 +27,7 @@ target_link_libraries(
 set_target_properties( ${PROJECT_NAME} PROPERTIES
     RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
     LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib
-    ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/archive
+    ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib
 )
 
 include(installation)
--
libgit2 0.21.4