From 984d8d2ba9e5acd44031789c2fb7598fa274e84c Mon Sep 17 00:00:00 2001
From: Nicolas Werner <nicolas.werner@hotmail.de>
Date: Sun, 3 Apr 2022 03:39:43 +0200
Subject: [PATCH] Use spdlog for logging

---
 CMakeLists.txt                     |  9 +++++++--
 README.md                          |  1 +
 examples/CMakeLists.txt            | 10 ----------
 examples/meson.build               |  4 +---
 include/mtx/log.hpp                |  9 ++++-----
 include/mtxclient/crypto/utils.hpp |  3 ---
 lib/crypto/client.cpp              |  8 ++++----
 lib/crypto/utils.cpp               | 12 +-----------
 lib/http/client.cpp                |  4 ++--
 lib/log.cpp                        | 15 ++++++---------
 lib/structs/events/collections.cpp |  3 +--
 lib/structs/requests.cpp           |  2 +-
 lib/structs/responses/common.cpp   |  9 +++------
 lib/structs/responses/members.cpp  |  4 ++--
 meson.build                        |  4 +++-
 15 files changed, 36 insertions(+), 61 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 777575cab..83b896ee6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -33,7 +33,6 @@ option(USE_BUNDLED_COEURL "Use a bundled version of the Curl wrapper"
 	${HUNTER_ENABLED})
 option(USE_BUNDLED_LIBEVENT "Use the bundled version of spdlog." ${HUNTER_ENABLED})
 option(USE_BUNDLED_LIBCURL "Use the bundled version of spdlog." ${HUNTER_ENABLED})
-option(USE_BUNDLED_SPDLOG "Use the bundled version of spdlog." ${HUNTER_ENABLED})
 
 
 if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.12)
@@ -155,7 +154,13 @@ endif()
 if(USE_BUNDLED_SPDLOG)
 	hunter_add_package(spdlog)
 endif()
-find_package(spdlog 1.0.0 CONFIG REQUIRED)
+find_package(spdlog 1.0.0 CONFIG)
+set_package_properties(spdlog PROPERTIES
+    DESCRIPTION "Very fast, header only, C++ logging library"
+    URL "https://github.com/gabime/spdlog"
+    TYPE REQUIRED
+)
+target_link_libraries(matrix_client PUBLIC spdlog::spdlog)
 
 if(USE_BUNDLED_COEURL)
 	include(FetchContent)
diff --git a/README.md b/README.md
index a268c3e78..01cc381a0 100644
--- a/README.md
+++ b/README.md
@@ -16,6 +16,7 @@ Client API library for the Matrix protocol.
 - C++ 17 compiler
 - CMake 3.15 or greater (lower versions can work, but not all build system options may work.)
 - Google Test (for testing)
+- spdlog (for logging)
 
 If you are missing some or all of those above dependencies, you can add `-DHUNTER_ENABLED=ON` to the cmake configure command to use bundled dependencies. You can finetune them with the following variables. They default to ON, if Hunter is enabled and to OFF otherwise.
 
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 34edc0613..e6b779dd1 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -1,13 +1,3 @@
-if(USE_BUNDLED_SPDLOG)
-	hunter_add_package(spdlog)
-endif()
-find_package(spdlog 1.0.0 CONFIG)
-set_package_properties(spdlog PROPERTIES
-    DESCRIPTION "Very fast, header only, C++ logging library"
-    URL "https://github.com/gabime/spdlog"
-    TYPE REQUIRED
-)
-
 include_directories(../tests)
 
 add_executable(room_feed room_feed.cpp)
diff --git a/examples/meson.build b/examples/meson.build
index 845142e42..5f456ab4e 100644
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -1,5 +1,3 @@
-spdlog_dep = dependency('spdlog', fallback: ['spdlog', 'spdlog_dep'])
-
 room_feed = executable('room_feed',
     'room_feed.cpp',
     dependencies: [matrix_client_dep],
@@ -26,7 +24,7 @@ simple_bot = executable('simple_bot',
     )
 crypto_bot = executable('crypto_bot',
     'crypto_bot.cpp',
-    dependencies: [matrix_client_dep, spdlog_dep],
+    dependencies: [matrix_client_dep],
     include_directories : '../tests'
     )
 online_backup_exporter = executable('online_backup_exporter',
diff --git a/include/mtx/log.hpp b/include/mtx/log.hpp
index 9877c6318..97ea42766 100644
--- a/include/mtx/log.hpp
+++ b/include/mtx/log.hpp
@@ -1,14 +1,13 @@
 #pragma once
 
-#include <string_view>
+#include <memory>
+#include <spdlog/spdlog.h>
 
 namespace mtx {
 namespace utils {
 namespace log {
-void
-log_warning(const std::string_view &msg);
-void
-log_error(const std::string_view &msg);
+std::shared_ptr<spdlog::logger>
+log();
 }
 }
 }
diff --git a/include/mtxclient/crypto/utils.hpp b/include/mtxclient/crypto/utils.hpp
index 395b278a0..6a2e95b8b 100644
--- a/include/mtxclient/crypto/utils.hpp
+++ b/include/mtxclient/crypto/utils.hpp
@@ -165,9 +165,6 @@ uint8_to_uint32(uint8_t b[4], uint32_t &u32);
 void
 uint32_to_uint8(uint8_t b[4], uint32_t u32);
 
-void
-print_binary_buf(const BinaryBuf &buf);
-
 //! Convert base64 to binary
 std::string
 base642bin(const std::string &b64);
diff --git a/lib/crypto/client.cpp b/lib/crypto/client.cpp
index aaf29aa9a..5bf077ddc 100644
--- a/lib/crypto/client.cpp
+++ b/lib/crypto/client.cpp
@@ -1,5 +1,3 @@
-#include <iostream>
-
 #include <nlohmann/json.hpp>
 #include <utility>
 
@@ -10,6 +8,8 @@
 #include "mtxclient/crypto/types.hpp"
 #include "mtxclient/crypto/utils.hpp"
 
+#include "mtx/log.hpp"
+
 using json = nlohmann::json;
 using namespace mtx::crypto;
 
@@ -840,7 +840,7 @@ mtx::crypto::verify_identity_signature(const DeviceKeys &device_keys,
         return ed25519_verify_signature(signing_key, nlohmann::json(device_keys), signature);
 
     } catch (const nlohmann::json::exception &e) {
-        std::cerr << "verify_identity_signature: " << e.what();
+        mtx::utils::log::log()->error("verify_identity_signature: {}", e.what());
     }
 
     return false;
@@ -876,7 +876,7 @@ mtx::crypto::ed25519_verify_signature(std::string signing_key,
 
         return true;
     } catch (const nlohmann::json::exception &e) {
-        std::cerr << "verify_signature: " << e.what();
+        mtx::utils::log::log()->error("verify_signature: {}", e.what());
     }
 
     return false;
diff --git a/lib/crypto/utils.cpp b/lib/crypto/utils.cpp
index 48b2f8501..521e8f10f 100644
--- a/lib/crypto/utils.cpp
+++ b/lib/crypto/utils.cpp
@@ -12,9 +12,8 @@
 #include <olm/pk.h>
 
 #include <algorithm>
-#include <iomanip>
-#include <iostream>
 
+#include "mtx/log.hpp"
 #include "mtxclient/crypto/client.hpp"
 
 namespace mtx {
@@ -545,15 +544,6 @@ HMAC_SHA256(const BinaryBuf &hmacKey, const BinaryBuf &data)
     return output;
 }
 
-void
-print_binary_buf(const BinaryBuf &buf)
-{
-    for (uint8_t val : buf) {
-        std::cout << std::to_string(val) << ",";
-    }
-    std::cout << std::endl;
-}
-
 void
 uint8_to_uint32(uint8_t b[4], uint32_t &u32)
 {
diff --git a/lib/http/client.cpp b/lib/http/client.cpp
index 18af2e57e..293ff8000 100644
--- a/lib/http/client.cpp
+++ b/lib/http/client.cpp
@@ -2,7 +2,6 @@
 #include "mtx/log.hpp"
 #include "mtxclient/http/client_impl.hpp"
 
-#include <iostream>
 #include <mutex>
 #include <thread>
 
@@ -14,6 +13,7 @@
 
 #include "mtxclient/utils.hpp"
 
+#include "mtx/log.hpp"
 #include "mtx/requests.hpp"
 #include "mtx/responses.hpp"
 
@@ -981,7 +981,7 @@ Client::registration(const std::string &user,
           request,
           [this, cb, h](auto &r, RequestErr e) {
               if (e && e->status_code == 401) {
-                  std::cout << e->matrix_error.error << "\n";
+                  mtx::utils::log::log()->debug("{}", e->matrix_error.error);
                   h.prompt(h, e->matrix_error.unauthorized);
               } else {
                   if (!e && !r.access_token.empty()) {
diff --git a/lib/log.cpp b/lib/log.cpp
index 44e5164e6..9b8edd3df 100644
--- a/lib/log.cpp
+++ b/lib/log.cpp
@@ -1,17 +1,14 @@
 #include <mtx/log.hpp>
 
-#include <iostream>
+#include "spdlog/sinks/stdout_color_sinks.h"
 
 namespace mtx::utils::log {
-void
-log_warning(const std::string_view &msg)
+std::shared_ptr<spdlog::logger>
+log()
 {
-    std::cerr << "warning:" << msg << "\n";
-}
+    static auto mtx_logger = std::make_shared<spdlog::logger>(
+      "mtx", std::make_shared<spdlog::sinks::stderr_color_sink_mt>());
 
-void
-log_error(const std::string_view &msg)
-{
-    std::cerr << "error:" << msg << "\n";
+    return mtx_logger;
 }
 }
diff --git a/lib/structs/events/collections.cpp b/lib/structs/events/collections.cpp
index cb369e126..70d860f34 100644
--- a/lib/structs/events/collections.cpp
+++ b/lib/structs/events/collections.cpp
@@ -263,8 +263,7 @@ from_json(const json &obj, TimelineEvent &e)
                 e.data = events::RoomEvent<events::msg::Redacted>(obj);
                 return;
             } catch (json::exception &err) {
-                mtx::utils::log::log_error(std::string("Invalid event type: ") + err.what() + " " +
-                                           obj.dump(2));
+                mtx::utils::log::log()->error("Invalid event type: {} {}", err.what(), obj.dump(2));
                 return;
             }
         }
diff --git a/lib/structs/requests.cpp b/lib/structs/requests.cpp
index c907c2733..8ee88da25 100644
--- a/lib/structs/requests.cpp
+++ b/lib/structs/requests.cpp
@@ -1,7 +1,7 @@
 #include "mtx/requests.hpp"
 #include "mtx/events/collections.hpp"
 #include "mtx/events/encrypted.hpp"
-#include <iostream>
+
 #include <nlohmann/json.hpp>
 
 using json = nlohmann::json;
diff --git a/lib/structs/responses/common.cpp b/lib/structs/responses/common.cpp
index d714e4d37..4fbb2ee04 100644
--- a/lib/structs/responses/common.cpp
+++ b/lib/structs/responses/common.cpp
@@ -19,8 +19,7 @@
 #include "mtx/events/tag.hpp"
 #include "mtx/events/topic.hpp"
 #include "mtx/events/voip.hpp"
-
-#include <iostream>
+#include "mtx/log.hpp"
 
 using json = nlohmann::json;
 using namespace mtx::events::account_data;
@@ -85,15 +84,13 @@ namespace utils {
 void
 log_error(std::exception &err, const json &event)
 {
-    std::cout << err.what() << std::endl;
-    std::cout << event.dump(2) << std::endl;
+    mtx::utils::log::log()->error("Error parsing events: {}, {}", err.what(), event.dump(2));
 }
 
 void
 log_error(const std::string &err, const json &event)
 {
-    std::cout << err << std::endl;
-    std::cout << event.dump(2) << std::endl;
+    mtx::utils::log::log()->error("Error parsing events: {}, {}", err, event.dump(2));
 }
 
 void
diff --git a/lib/structs/responses/members.cpp b/lib/structs/responses/members.cpp
index 287a6b288..21e15c671 100644
--- a/lib/structs/responses/members.cpp
+++ b/lib/structs/responses/members.cpp
@@ -16,8 +16,8 @@ from_json(const nlohmann::json &obj, Members &res)
                 mtx::events::StateEvent<mtx::events::state::Member> member = e;
                 res.chunk.push_back(member);
             } catch (const std::exception &e) {
-                utils::log::log_warning(
-                  std::string("Failed to parse member event in members chunk: ") + e.what());
+                utils::log::log()->warn("Failed to parse member event in members chunk: {}",
+                                        e.what());
             }
         }
     }
diff --git a/meson.build b/meson.build
index fdb8aa53f..579b9658b 100644
--- a/meson.build
+++ b/meson.build
@@ -17,6 +17,7 @@ endif
 coeurl_dep = dependency('coeurl', version: '>=0.1.1', required: true)
 thread_dep = dependency('threads', required: true)
 openssl_dep = dependency('openssl', version: '>=1.1', required: true)
+spdlog_dep = dependency('spdlog', fallback: ['spdlog', 'spdlog_dep'])
 
 json_dep = dependency('nlohmann_json', version: '>=3.2.0', required: true)
 
@@ -46,7 +47,8 @@ deps = [
   thread_dep,
   olm_dep,
   openssl_dep,
-  json_dep
+  json_dep,
+  spdlog_dep
 ]
 
 inc = include_directories('include')
-- 
GitLab