diff --git a/CHANGELOG.md b/CHANGELOG.md
index 61d48aaebd50731104612da10f4c3d35864c9d5c..86853ffac98fbfbc5fa4c85696ccba2b8a8efdd6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
 
 ## [Unreleased]
 
+### Added
+
+- Added support for syslog logging.
+
 ### Fixed
 
 - Close logging down in destructor so linked device server can be restarted.
@@ -17,6 +21,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
 - Removed Clang path from build (CMake checks PATH)
 - Corrected static library build
 - Install now places header in include/hdb++/
+- Entire library now uses the global default logger from spdlog.
+
+#### Submodules
+
+- Updated spdlog submodule to release v1.4.3
 
 ## [0.9.1] - 2019-07-18
 
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0602e9b62a08f2c4cc10f82dbc4d76520437c5b9..e36b9adaa3f498ae6ec824fa2a319469242218ae 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -38,9 +38,9 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
 set(CMAKE_CXX_EXTENSIONS OFF)
 
 # Build options
-option(BUILD_UNIT_TESTS "Build unit tests" OFF)
-option(BUILD_BENCHMARK_TESTS "Build benchmarking tests (Forces RELEASE build)" OFF)
-option(ENABLE_CLANG "Enable clang code and layout analysis" OFF)
+option(BUILD_UNIT_TESTS "Build unit tests" ON)
+option(BUILD_BENCHMARK_TESTS "Build benchmarking tests (Forces RELEASE build)" ON)
+option(ENABLE_CLANG "Enable clang code and layout analysis" ON)
 
 if(BUILD_UNIT_TESTS)
     message(STATUS "Unit tests will be built")
@@ -137,7 +137,7 @@ add_subdirectory(src)
 add_library(libhdbpp_timescale_shared_library SHARED ${SRC_FILES})
 
 target_link_libraries(libhdbpp_timescale_shared_library 
-    PUBLIC ${TDB_FOUND_LIBRARIES} pqxx_static libhdbpp_headers spdlog Threads::Threads
+    PUBLIC ${TDB_FOUND_LIBRARIES} pqxx_static libhdbpp_headers spdlog::spdlog_header_only Threads::Threads
     PRIVATE TangoInterfaceLibrary)
 
 target_include_directories(libhdbpp_timescale_shared_library 
diff --git a/benchmark/QueryBuilderTests.cpp b/benchmark/QueryBuilderTests.cpp
index 1a02b5a7702d4d0206aec979ea60e77b9db98d2e..5da87889875fa1c9db4de13e2f0d41b2fbbb88be 100644
--- a/benchmark/QueryBuilderTests.cpp
+++ b/benchmark/QueryBuilderTests.cpp
@@ -26,8 +26,7 @@ void bmAllocateQueryBuilder(benchmark::State& state)
 {
     // Test - Testing the time it takes to allocate a QueryBuilder, mainly for future test
     // reference
-    hdbpp_internal::LogConfigurator::initLoggingMetrics(false, false);
-    hdbpp_internal::LogConfigurator::setLoggingLevel(spdlog::level::err);
+    hdbpp_internal::LogConfigurator::initLogging();
 
     for (auto _ : state)
         hdbpp_internal::pqxx_conn::QueryBuilder query_builder;
diff --git a/src/ColumnCache.hpp b/src/ColumnCache.hpp
index c451eb76bd0fc32c464af39c8ebe05fff0b90a0f..44674be924839302a1a1923a56367f4554a30480 100644
--- a/src/ColumnCache.hpp
+++ b/src/ColumnCache.hpp
@@ -80,9 +80,6 @@ namespace pqxx_conn
         // cache of values to a reference, the unordered map is not sorted
         // so we do not loose time on each insert having it resorted
         std::unordered_map<TRef, TValue> _values;
-
-        // logging subsystem
-        std::shared_ptr<spdlog::logger> _logger;
     };
 
     //=============================================================================
@@ -106,9 +103,7 @@ namespace pqxx_conn
         _fetch_all_query_name = _column_name + _table_name + _reference + "_all";
         _fetch_id_query_name = _column_name + _table_name + _reference + "_id";
 
-        _logger = spdlog::get(LibLoggerName);
-
-        _logger->trace("Cache created for table: {} using columns {}/{}", _table_name, _column_name, _reference);
+        spdlog::trace("Cache created for table: {} using columns {}/{}", _table_name, _column_name, _reference);
     }
 
     //=============================================================================
@@ -133,7 +128,7 @@ namespace pqxx_conn
                     tx.conn().prepare(_fetch_all_query_name,
                         QueryBuilder::fetchAllValuesQuery(_column_name, _table_name, _reference));
 
-                    _logger->trace("Created prepared statement for: {}", _fetch_all_query_name);
+                    spdlog::trace("Created prepared statement for: {}", _fetch_all_query_name);
                 }
 
                 auto result = tx.exec_prepared(_fetch_all_query_name);
@@ -143,7 +138,7 @@ namespace pqxx_conn
                 for (const auto &row : result)
                     _values.insert({row[1].template as<TRef>(), row[0].template as<TValue>()});
 
-                _logger->debug("Loaded: {} values into cache", _values.size());
+                spdlog::debug("Loaded: {} values into cache", _values.size());
             });
         }
         catch (const pqxx::pqxx_exception &ex)
@@ -151,9 +146,9 @@ namespace pqxx_conn
             string msg {"The database transaction failed. Unable to fetchAll for column: " + _column_name +
                 " in table: " + _table_name + ". Error: " + ex.base().what()};
 
-            _logger->error("Error: An unexpected error occurred when trying to run the database query");
-            _logger->error("Caught error: \"{}\"", ex.base().what());
-            _logger->error("Throwing storage error with message: \"{}\"", msg);
+            spdlog::error("Error: An unexpected error occurred when trying to run the database query");
+            spdlog::error("Caught error: \"{}\"", ex.base().what());
+            spdlog::error("Throwing storage error with message: \"{}\"", msg);
 
             Tango::Except::throw_exception("Storage Error", msg, LOCATION_INFO);
         }
@@ -189,7 +184,7 @@ namespace pqxx_conn
                         tx.conn().prepare(
                             _fetch_id_query_name, QueryBuilder::fetchValueQuery(_column_name, _table_name, _reference));
 
-                        _logger->trace("Created prepared statement for: {}", _fetch_id_query_name);
+                        spdlog::trace("Created prepared statement for: {}", _fetch_id_query_name);
                     }
 
                     auto result = tx.exec_prepared(_fetch_id_query_name, reference);
@@ -206,7 +201,7 @@ namespace pqxx_conn
                             auto value = result.at(0).at(0).template as<TValue>();
                             _values.insert({reference, value});
 
-                            _logger->debug("Cached value: \'{} \' with reference: \'{}\'", value, reference);
+                            spdlog::debug("Cached value: \'{} \' with reference: \'{}\'", value, reference);
                             return true;
                         }
                         else
@@ -224,9 +219,9 @@ namespace pqxx_conn
                 string msg {"The database transaction failed. Unable to query column: " + _column_name +
                     " in table: " + _table_name + ". Error: " + ex.base().what()};
 
-                _logger->error("Error: An unexpected error occurred when trying to run the database query");
-                _logger->error("Caught error: \"{}\"", ex.base().what());
-                _logger->error("Throwing storage error with message: \"{}\"", msg);
+                spdlog::error("Error: An unexpected error occurred when trying to run the database query");
+                spdlog::error("Caught error: \"{}\"", ex.base().what());
+                spdlog::error("Throwing storage error with message: \"{}\"", msg);
 
                 Tango::Except::throw_exception("Storage Error", msg, LOCATION_INFO);
             }
@@ -248,7 +243,7 @@ namespace pqxx_conn
         {
             // this is pretty fatal, we can not store information if it does not exist
             string msg {"Unable to find a value in either the cache or database for reference: " + reference};
-            _logger->error("Error: {}", msg);
+            spdlog::error("Error: {}", msg);
             Tango::Except::throw_exception("Storage Error", msg, LOCATION_INFO);
         }
 
@@ -267,12 +262,12 @@ namespace pqxx_conn
         // the caller to deal with
         if (_values.find(reference) != _values.end())
         {
-            _logger->warn("Value already exists in cache, not caching. Value: {} with reference: {}", value, reference);
+            spdlog::warn("Value already exists in cache, not caching. Value: {} with reference: {}", value, reference);
             return;
         }
 
         _values.insert({reference, value});
-        _logger->debug("Cached new value: {} with reference: {} by request", value, reference);
+        spdlog::debug("Cached new value: {} with reference: {} by request", value, reference);
     }
 
     //=============================================================================
diff --git a/src/DbConnection.cpp b/src/DbConnection.cpp
index 00af4f9876e7270ee9cc3af79f46936678c9fc93..85e16048df8c92e446e2a8e762c6b888a072d2f6 100644
--- a/src/DbConnection.cpp
+++ b/src/DbConnection.cpp
@@ -33,13 +33,13 @@ namespace pqxx_conn
 {
     //=============================================================================
     //=============================================================================
-    DbConnection::DbConnection() { _logger = spdlog::get(LibLoggerName); }
+    DbConnection::DbConnection() {}
 
     //=============================================================================
     //=============================================================================
     void DbConnection::connect(const string &connect_string)
     {
-        _logger->info("Connecting to postgres database with string: \"{}\"", connect_string);
+        spdlog::info("Connecting to postgres database with string: \"{}\"", connect_string);
 
         // construct the database connection
         try
@@ -54,16 +54,16 @@ namespace pqxx_conn
 
             // mark the connected flag as true to cache this state
             _connected = true;
-            _logger->info("Connected to postgres successfully");
+            spdlog::info("Connected to postgres successfully");
         }
         catch (const pqxx::broken_connection &ex)
         {
             string msg {"Failed to connect to database. Exception: "};
             msg += ex.what();
 
-            _logger->error("Error: Connecting to postgres database with connect string: \"{}\"", connect_string);
-            _logger->error("Caught error: \"{}\"", ex.what());
-            _logger->error("Throwing connection error with message: \"{}\"", msg);
+            spdlog::error("Error: Connecting to postgres database with connect string: \"{}\"", connect_string);
+            spdlog::error("Caught error: \"{}\"", ex.what());
+            spdlog::error("Throwing connection error with message: \"{}\"", msg);
             Tango::Except::throw_exception("Connection Error", msg, LOCATION_INFO);
         }
 
@@ -96,7 +96,7 @@ namespace pqxx_conn
 
         // stop attempts to use the connection
         _connected = false;
-        _logger->debug("Disconnected from the postgres database");
+        spdlog::debug("Disconnected from the postgres database");
     }
 
     //=============================================================================
@@ -121,7 +121,7 @@ namespace pqxx_conn
         assert(_error_desc_id_cache != nullptr);
         assert(_event_id_cache != nullptr);
 
-        _logger->trace("Storing new attribute {} of type {}", full_attr_name, traits);
+        spdlog::trace("Storing new attribute {} of type {}", full_attr_name, traits);
 
         checkConnection(LOCATION_INFO);
 
@@ -132,9 +132,9 @@ namespace pqxx_conn
             string msg {
                 "This attribute [" + full_attr_name + "] already exists in the database. Unable to add it again."};
 
-            _logger->error("Error: The attribute already exists in the database and can not be added again");
-            _logger->error("Attribute details. Name: {} traits: {}", full_attr_name, traits);
-            _logger->error("Throwing consistency error with message: \"{}\"", msg);
+            spdlog::error("Error: The attribute already exists in the database and can not be added again");
+            spdlog::error("Attribute details. Name: {} traits: {}", full_attr_name, traits);
+            spdlog::error("Throwing consistency error with message: \"{}\"", msg);
             Tango::Except::throw_exception("Consistency Error", msg, LOCATION_INFO);
         }
 
@@ -147,7 +147,7 @@ namespace pqxx_conn
                 if (!tx.prepared(StoreAttribute).exists())
                 {
                     tx.conn().prepare(StoreAttribute, QueryBuilder::storeAttributeQuery());
-                    _logger->trace("Created prepared statement for: {}", StoreAttribute);
+                    spdlog::trace("Created prepared statement for: {}", StoreAttribute);
                 }
 
                 // execute the statement with the expectation that we get a row back
@@ -171,7 +171,7 @@ namespace pqxx_conn
                 return row.at(0).as<int>();
             });
 
-            _logger->debug("Stored new attribute {} of type {} with db id: {}", full_attr_name, traits, conf_id);
+            spdlog::debug("Stored new attribute {} of type {} with db id: {}", full_attr_name, traits, conf_id);
 
             // cache the new conf id for future use
             _conf_id_cache->cacheValue(conf_id, full_attr_name);
@@ -196,7 +196,7 @@ namespace pqxx_conn
         assert(_error_desc_id_cache != nullptr);
         assert(_event_id_cache != nullptr);
 
-        _logger->trace("Storing history event {} for attribute {}", event, full_attr_name);
+        spdlog::trace("Storing history event {} for attribute {}", event, full_attr_name);
 
         checkConnection(LOCATION_INFO);
         checkAttributeExists(full_attr_name, LOCATION_INFO);
@@ -210,10 +210,10 @@ namespace pqxx_conn
             string msg {
                 "The event [" + event + "] is missing in both the cache and database, this is an unrecoverable error."};
 
-            _logger->error(
+            spdlog::error(
                 "Event found missing, this occurred when storing event: {} for attribute: {}", event, full_attr_name);
 
-            _logger->error("Throwing consistency error with message: \"{}\"", msg);
+            spdlog::error("Throwing consistency error with message: \"{}\"", msg);
             Tango::Except::throw_exception("Consistency Error", msg, LOCATION_INFO);
         }
 
@@ -226,7 +226,7 @@ namespace pqxx_conn
                 if (!tx.prepared(StoreHistoryEvent).exists())
                 {
                     tx.conn().prepare(StoreHistoryEvent, QueryBuilder::storeHistoryEventQuery());
-                    _logger->trace("Created prepared statement for: {}", StoreHistoryEvent);
+                    spdlog::trace("Created prepared statement for: {}", StoreHistoryEvent);
                 }
 
                 // expect no result, this is an insert only query
@@ -234,7 +234,7 @@ namespace pqxx_conn
                 tx.commit();
             });
 
-            _logger->debug("Stored event {} and for attribute {}", event, full_attr_name);
+            spdlog::debug("Stored event {} and for attribute {}", event, full_attr_name);
         }
         catch (const pqxx::pqxx_exception &ex)
         {
@@ -274,9 +274,9 @@ namespace pqxx_conn
         assert(_error_desc_id_cache != nullptr);
         assert(_event_id_cache != nullptr);
 
-        _logger->trace("Storing parameter event for attribute {}", full_attr_name);
+        spdlog::trace("Storing parameter event for attribute {}", full_attr_name);
 
-        _logger->trace("Parmater event data: event_time {}, label {}, unit {}, standard_unit {}, display_unit {}, "
+        spdlog::trace("Parmater event data: event_time {}, label {}, unit {}, standard_unit {}, display_unit {}, "
                        "format {}, archive_rel_change {}, archive_abs_change {}, archive_period {}, description {}",
             event_time,
             label,
@@ -301,7 +301,7 @@ namespace pqxx_conn
                 if (!tx.prepared(StoreParameterEvent).exists())
                 {
                     tx.conn().prepare(StoreParameterEvent, QueryBuilder::storeParameterEventQuery());
-                    _logger->trace("Created prepared statement for: {}", StoreParameterEvent);
+                    spdlog::trace("Created prepared statement for: {}", StoreParameterEvent);
                 }
 
                 // no result expected
@@ -321,7 +321,7 @@ namespace pqxx_conn
                 tx.commit();
             });
 
-            _logger->debug("Stored parameter event and for attribute {}", full_attr_name);
+            spdlog::debug("Stored parameter event and for attribute {}", full_attr_name);
         }
         catch (const pqxx::pqxx_exception &ex)
         {
@@ -348,7 +348,7 @@ namespace pqxx_conn
         assert(_error_desc_id_cache != nullptr);
         assert(_event_id_cache != nullptr);
 
-        _logger->trace("Storing error message event for attribute {}. Quality: {}. Error message: \"{}\"",
+        spdlog::trace("Storing error message event for attribute {}. Quality: {}. Error message: \"{}\"",
             full_attr_name,
             quality,
             error_msg);
@@ -367,11 +367,11 @@ namespace pqxx_conn
             string msg {"The error message [" + error_msg +
                 "] is missing in both the cache and database, this is an unrecoverable error."};
 
-            _logger->error("Error message found missing, this occurred when storing msg: \"{}\" for attribute: {}",
+            spdlog::error("Error message found missing, this occurred when storing msg: \"{}\" for attribute: {}",
                 error_msg,
                 full_attr_name);
 
-            _logger->error("Throwing consistency error with message: \"{}\"", msg);
+            spdlog::error("Throwing consistency error with message: \"{}\"", msg);
             Tango::Except::throw_exception("Consistency Error", msg, LOCATION_INFO);
         }
 
@@ -385,7 +385,7 @@ namespace pqxx_conn
                 {
                     tx.conn().prepare(_query_builder.storeDataEventErrorName(traits),
                         _query_builder.storeDataEventErrorQuery(traits));
-                    _logger->trace(
+                    spdlog::trace(
                         "Created prepared statement for: {}", _query_builder.storeDataEventErrorName(traits));
                 }
 
@@ -421,7 +421,7 @@ namespace pqxx_conn
         checkConnection(LOCATION_INFO);
         checkAttributeExists(full_attr_name, LOCATION_INFO);
 
-        _logger->trace("Fetching last history event for attribute: {}", full_attr_name);
+        spdlog::trace("Fetching last history event for attribute: {}", full_attr_name);
 
         // the result
         string last_event;
@@ -471,11 +471,11 @@ namespace pqxx_conn
 
         if (_conf_id_cache->valueExists(full_attr_name))
         {
-            _logger->trace("Query attribute archived returns true for: {}", full_attr_name);
+            spdlog::trace("Query attribute archived returns true for: {}", full_attr_name);
             return true;
         }
 
-        _logger->trace("Query attribute archived returns false for: {}", full_attr_name);
+        spdlog::trace("Query attribute archived returns false for: {}", full_attr_name);
         return false;
     }
 
@@ -492,7 +492,7 @@ namespace pqxx_conn
         checkConnection(LOCATION_INFO);
         checkAttributeExists(full_attr_name, LOCATION_INFO);
 
-        _logger->trace("Fetching attribute traits for attribute: {}", full_attr_name);
+        spdlog::trace("Fetching attribute traits for attribute: {}", full_attr_name);
 
         AttributeTraits traits;
 
@@ -530,7 +530,7 @@ namespace pqxx_conn
     //=============================================================================
     void DbConnection::storeEvent(const std::string &full_attr_name, const std::string &event)
     {
-        _logger->debug("Event {} needs adding to the database, by request of attribute {}", event, full_attr_name);
+        spdlog::debug("Event {} needs adding to the database, by request of attribute {}", event, full_attr_name);
 
         try
         {
@@ -542,7 +542,7 @@ namespace pqxx_conn
                 if (!tx.prepared(StoreHistoryString).exists())
                 {
                     tx.conn().prepare(StoreHistoryString, QueryBuilder::storeHistoryStringQuery());
-                    _logger->trace("Created prepared statement for: {}", StoreHistoryString);
+                    spdlog::trace("Created prepared statement for: {}", StoreHistoryString);
                 }
 
                 auto row = tx.exec_prepared1(StoreHistoryString, event);
@@ -552,7 +552,7 @@ namespace pqxx_conn
                 return row.at(0).as<int>();
             });
 
-            _logger->debug(
+            spdlog::debug(
                 "Stored event {} for attribute {} and got database id for it: {}", event, full_attr_name, event_id);
 
             // cache the new event id for future use
@@ -571,7 +571,7 @@ namespace pqxx_conn
     //=============================================================================
     void DbConnection::storeErrorMsg(const std::string &full_attr_name, const std::string &error_msg)
     {
-        _logger->debug(
+        spdlog::debug(
             "Error message \"{}\" needs adding to the database, by request of attribute {}", error_msg, full_attr_name);
 
         try
@@ -583,7 +583,7 @@ namespace pqxx_conn
                 if (!tx.prepared(StoreErrorString).exists())
                 {
                     tx.conn().prepare(StoreErrorString, QueryBuilder::storeErrorQuery());
-                    _logger->trace("Created prepared statement for: {}", StoreErrorString);
+                    spdlog::trace("Created prepared statement for: {}", StoreErrorString);
                 }
 
                 // expect a single row returned
@@ -594,7 +594,7 @@ namespace pqxx_conn
                 return row.at(0).as<int>();
             });
 
-            _logger->debug("Stored error message \"{}\" for attribute {} and got database id for it: {}",
+            spdlog::debug("Stored error message \"{}\" for attribute {} and got database id for it: {}",
                 error_msg,
                 full_attr_name,
                 error_id);
@@ -622,9 +622,9 @@ namespace pqxx_conn
             string msg {"This attribute [" + full_attr_name +
                 "] does not exist in the database. Unable to work with this attribute until it is added."};
 
-            _logger->error("Error: The attribute does not exist in the database, add it first.");
-            _logger->error("Attribute details. Name: {}", full_attr_name);
-            _logger->error("Throwing consistency error with message: \"{}\"", msg);
+            spdlog::error("Error: The attribute does not exist in the database, add it first.");
+            spdlog::error("Attribute details. Name: {}", full_attr_name);
+            spdlog::error("Throwing consistency error with message: \"{}\"", msg);
             Tango::Except::throw_exception("Consistency Error", msg, location);
         }
     }
@@ -638,10 +638,10 @@ namespace pqxx_conn
             string msg {
                 "Connection to database is closed. Ensure it has been opened before trying to use the connection."};
 
-            _logger->error(
+            spdlog::error(
                 "Error: The DbConnection is showing a closed connection status, open it before using store functions");
 
-            _logger->error("Throwing connection error with message: \"{}\"", msg);
+            spdlog::error("Throwing connection error with message: \"{}\"", msg);
             Tango::Except::throw_exception("Connection Error", msg, location);
         }
     }
@@ -652,12 +652,11 @@ namespace pqxx_conn
         const string &msg, const string &what, const string &query, const std::string &location)
     {
         string full_msg {"The database transaction failed. " + msg};
-        _logger->error("Error: An unexpected error occurred when trying to run the database query");
-        _logger->error("Caught error at: {} Error: \"{}\"", location, what);
-        _logger->error("Error: Failed query: {}", query);
-        _logger->error("Throwing storage error with message: \"{}\"", full_msg);
+        spdlog::error("Error: An unexpected error occurred when trying to run the database query");
+        spdlog::error("Caught error at: {} Error: \"{}\"", location, what);
+        spdlog::error("Error: Failed query: {}", query);
+        spdlog::error("Throwing storage error with message: \"{}\"", full_msg);
         Tango::Except::throw_exception("Storage Error", full_msg, location);
     }
-
 } // namespace pqxx_conn
 } // namespace hdbpp_internal
diff --git a/src/DbConnection.hpp b/src/DbConnection.hpp
index c1bfc0d88707b94c42b9da875478c606246ece7f..8082c821df46d7d79173470e17a8012ed8fca48f 100644
--- a/src/DbConnection.hpp
+++ b/src/DbConnection.hpp
@@ -144,9 +144,6 @@ namespace pqxx_conn
         std::unique_ptr<ColumnCache<int, std::string>> _error_desc_id_cache;
         std::unique_ptr<ColumnCache<int, std::string>> _event_id_cache;
         std::unique_ptr<ColumnCache<int, int>> _type_id_cache;
-
-        // logging subsystem
-        std::shared_ptr<spdlog::logger> _logger;
     };
 } // namespace pqxx_conn
 } // namespace hdbpp_internal
diff --git a/src/DbConnection.tpp b/src/DbConnection.tpp
index 6c4e14b618621bcdda25e1bf8e15d83cb814168b..8c71da326167988670f43790152e7ab01f59b7bc 100644
--- a/src/DbConnection.tpp
+++ b/src/DbConnection.tpp
@@ -30,26 +30,6 @@ namespace pqxx_conn
     // specialisations can not be handled by the main function, so we break them out here.
     namespace store_data_utils
     {
-        //=============================================================================
-        //=============================================================================
-        template<typename T>
-        struct Preprocess
-        {
-            static void run(std::unique_ptr<std::vector<T>> &, pqxx::work &) {}
-        };
-
-        //=============================================================================
-        //=============================================================================
-        template<>
-        struct Preprocess<std::string>
-        {
-            static void run(std::unique_ptr<std::vector<std::string>> &value, pqxx::work &tx)
-            {
-                for (auto &str : *value)
-                    str = tx.quote(str);
-            }
-        };
-
         //=============================================================================
         //=============================================================================
         template<typename T>
@@ -105,7 +85,7 @@ namespace pqxx_conn
         assert(!full_attr_name.empty());
         assert(traits.isValid());
 
-        _logger->trace("Storing data event for attribute {} with traits {}, value_r valid: {}, value_w valid: {}",
+        spdlog::trace("Storing data event for attribute {} with traits {}, value_r valid: {}, value_w valid: {}",
             full_attr_name,
             traits,
             value_r->size() > 0,
@@ -119,53 +99,98 @@ namespace pqxx_conn
             return pqxx::perform([&, this]() {
                 pqxx::work tx {(*_conn), StoreDataEvent};
 
-                // prepare as a prepared statement, we are going to use these
-                // queries often
-                if (!tx.prepared(_query_builder.storeDataEventName(traits)).exists())
+                // there is a single special case here, arrays of strings need a different syntax to store, 
+                // to avoid the quoting. Its likely we will need more for DevEncoded and DevEnum
+                if (traits.isArray() && traits.type() == Tango::DEV_STRING)
                 {
-                    tx.conn().prepare(
-                        _query_builder.storeDataEventName(traits), _query_builder.storeDataEventQuery<T>(traits));
-                }
+                    auto prepare_array = [](auto &value) {
+                        auto iter = value->begin();
+                        std::string result = "ARRAY[";
 
-                // get the pqxx prepared statement invocation object to allow us to
-                // bind each parameter in turn, this gives us the flexibility to bind
-                // conditional parameters (as long as the query string matches)
-                auto inv = tx.prepared(_query_builder.storeDataEventName(traits));
-
-                // this lambda stores the data value correctly into the invocation,
-                // we must treat scalar/spectrum in different ways, one is a single
-                // element and the other an array. Further, the unique_ptr may be
-                // empty and signify a null should be stored in the column instead
-                auto store_value = [&tx, &inv, &traits](auto &value) {
-                    if (value && value->size() > 0)
-                    {
-                        // this ensures strings are quoted and escaped, other types are ignored
-                        store_data_utils::Preprocess<T>::run(value, tx);
-                        store_data_utils::Store<T>::run(value, inv, traits);
-                    }
-                    else
-                    {
-                        // no value was given for this field, simply add a null
-                        // instead, this allows invalid quality attributes to be saved
-                        // with no data
-                        inv();
-                    }
-                };
+                        result = "$$" + pqxx::to_string((*iter)) + "$$";
+
+                        for (++iter; iter != value->end(); ++iter)
+                        {
+                            result += ",";
+                            result += "$$" + pqxx::to_string((*iter)) + "$$";
+                        }
+
+                        result += "]";
+                        return result;
+                    };
+
+                    auto query = "INSERT INTO " + QueryBuilder::tableName(traits) + " (" + DAT_COL_ID + "," + DAT_COL_DATA_TIME;
+
+                    if (traits.hasReadData())
+                        query = query + "," + DAT_COL_VALUE_R;
+
+                    if (traits.hasWriteData())
+                        query = query + "," + DAT_COL_VALUE_W;
 
-                // bind all the parameters
-                inv(_conf_id_cache->value(full_attr_name));
-                inv(event_time);
+                    // split to ensure increments are in the correct order
+                    query = query + "," + DAT_COL_QUALITY + ") VALUES (" + pqxx::to_string(full_attr_name);
+                    query = query + ",TO_TIMESTAMP(" + pqxx::to_string(event_time) + ")";
 
-                if (traits.hasReadData())
-                    store_value(value_r);
+                    // add the read parameter with cast
+                    if (traits.hasReadData())
+                        query = query + "," + prepare_array(value_r);
 
-                if (traits.hasWriteData())
-                    store_value(value_w);
+                    // add the write parameter with cast
+                    if (traits.hasWriteData())
+                        query = query + "," + prepare_array(value_w);
 
-                inv(quality);
+                    query = query + "," + pqxx::to_string(quality) + ")";
 
-                // execute
-                inv.exec();
+                    tx.exec0(query);
+                }
+                else
+                {
+                    // prepare as a prepared statement, we are going to use these
+                    // queries often
+                    if (!tx.prepared(_query_builder.storeDataEventName(traits)).exists())
+                    {
+                        tx.conn().prepare(
+                            _query_builder.storeDataEventName(traits), _query_builder.storeDataEventQuery<T>(traits));
+                    }
+
+                    // get the pqxx prepared statement invocation object to allow us to
+                    // bind each parameter in turn, this gives us the flexibility to bind
+                    // conditional parameters (as long as the query string matches)
+                    auto inv = tx.prepared(_query_builder.storeDataEventName(traits));
+
+                    // this lambda stores the data value correctly into the invocation,
+                    // we must treat scalar/spectrum in different ways, one is a single
+                    // element and the other an array. Further, the unique_ptr may be
+                    // empty and signify a null should be stored in the column instead
+                    auto store_value = [&tx, &inv, &traits](auto &value) {
+                        if (value && value->size() > 0)
+                        {
+                            store_data_utils::Store<T>::run(value, inv, traits);
+                        }
+                        else
+                        {
+                            // no value was given for this field, simply add a null
+                            // instead, this allows invalid quality attributes to be saved
+                            // with no data
+                            inv();
+                        }
+                    };
+
+                    // bind all the parameters
+                    inv(_conf_id_cache->value(full_attr_name));
+                    inv(event_time);
+
+                    if (traits.hasReadData())
+                        store_value(value_r);
+
+                    if (traits.hasWriteData())
+                        store_value(value_w);
+
+                    inv(quality);
+
+                    // execute
+                    inv.exec();
+                }
 
                 // commit the result
                 tx.commit();
@@ -179,7 +204,6 @@ namespace pqxx_conn
                 LOCATION_INFO);
         }
     }
-
 } // namespace pqxx_conn
 } // namespace hdbpp_internal
 #endif // _PSQL_CONNECTION_TPP
diff --git a/src/HdbppTimescaleDb.cpp b/src/HdbppTimescaleDb.cpp
index 164a99b041eecc698fd7b77204ff04dded38e277..07e1e419aa5274430798f3d43813a36c7dbf6ee0 100644
--- a/src/HdbppTimescaleDb.cpp
+++ b/src/HdbppTimescaleDb.cpp
@@ -104,10 +104,20 @@ HdbppTimescaleDb::HdbppTimescaleDb(const vector<string> &configuration)
     auto level = param_to_lower(HdbppTimescaleDbUtils::getConfigParam(libhdb_conf, "logging_level", false));
     auto log_file = HdbppTimescaleDbUtils::getConfigParam(libhdb_conf, "log_file", false);
     auto log_console = HdbppTimescaleDbUtils::getConfigParam(libhdb_conf, "log_console", false);
+    auto log_syslog = HdbppTimescaleDbUtils::getConfigParam(libhdb_conf, "log_syslog", false);
     auto log_file_name = HdbppTimescaleDbUtils::getConfigParam(libhdb_conf, "log_file_name", false);
 
-    LogConfigurator::initLogging(
-        param_to_lower(log_file) == "true", param_to_lower(log_console) == "true", log_file_name);
+    // init the base logging system
+    LogConfigurator::initLogging();
+
+    if (param_to_lower(log_file) == "true")
+        LogConfigurator::initFileLogging(log_file_name);
+
+    if (param_to_lower(log_console) == "true")
+        LogConfigurator::initConsoleLogging();
+
+    if (param_to_lower(log_syslog) == "true")
+        LogConfigurator::initSyslogLogging();
 
     if (level == "error" || level.empty())
         LogConfigurator::setLoggingLevel(spdlog::level::level_enum::err);
@@ -125,7 +135,9 @@ HdbppTimescaleDb::HdbppTimescaleDb(const vector<string> &configuration)
         LogConfigurator::setLoggingLevel(spdlog::level::level_enum::err);
 
     spdlog::info("Logging level: {}", level);
-    spdlog::info("Logging to file: {}, logging to console: {}", log_file, log_console);
+    spdlog::info("Logging to console: {}", log_console);
+    spdlog::info("Logging to syslog: {}", log_syslog);
+    spdlog::info("Logging to file: {}", log_file);
     spdlog::info("Logfile (if any): {}", log_file_name);
 
     spdlog::info("Starting libhdbpp-timescale shared library...");
diff --git a/src/HdbppTxNewAttribute.hpp b/src/HdbppTxNewAttribute.hpp
index 063bf643ea99fe11d27d7cf494ecc19063d70790..060446b47e64702a9c8d6f44df9f20fc3c0781f9 100644
--- a/src/HdbppTxNewAttribute.hpp
+++ b/src/HdbppTxNewAttribute.hpp
@@ -75,7 +75,7 @@ HdbppTxNewAttribute<Conn> &HdbppTxNewAttribute<Conn>::store()
     }
     else if (_traits.isInvalid())
     {
-        std::string msg {"AttributeTraits are invalid. Unable to complete the transaction. For attribute" +
+        std::string msg {"AttributeTraits are invalid. Unable to complete the transaction. For attribute: " +
             _attr_name.fqdnAttributeName()};
 
         spdlog::error("Error: {}", msg);
@@ -83,7 +83,7 @@ HdbppTxNewAttribute<Conn> &HdbppTxNewAttribute<Conn>::store()
     }
     else if (HdbppTxBase<Conn>::connection().isClosed())
     {
-        std::string msg {"The connection is reporting it is closed. Unable to store new attribute. For attribute" +
+        std::string msg {"The connection is reporting it is closed. Unable to store new attribute. For attribute: " +
             _attr_name.fqdnAttributeName()};
 
         spdlog::error("Error: {}", msg);
@@ -94,7 +94,7 @@ HdbppTxNewAttribute<Conn> &HdbppTxNewAttribute<Conn>::store()
     if (_traits.isImage())
     {
         std::string msg {
-            "Image type attributes are currently not supported. For attribute" + _attr_name.fqdnAttributeName()};
+            "Image type attributes are currently not supported. For attribute: " + _attr_name.fqdnAttributeName()};
 
         spdlog::error("Error: {}", msg);
         Tango::Except::throw_exception("Invalid Argument", msg, LOCATION_INFO);
@@ -103,7 +103,7 @@ HdbppTxNewAttribute<Conn> &HdbppTxNewAttribute<Conn>::store()
     // unsupported types
     if (_traits.type() == Tango::DEV_ENUM || _traits.type() == Tango::DEV_ENCODED)
     {
-        std::string msg {"Unsupported attribute type: " + tangoEnumToString(_traits.type()) + ". For attribute" +
+        std::string msg {"Unsupported attribute type: " + tangoEnumToString(_traits.type()) + ". For attribute: " +
             _attr_name.fqdnAttributeName()};
 
         spdlog::error("Error: {}", msg);
@@ -123,7 +123,7 @@ HdbppTxNewAttribute<Conn> &HdbppTxNewAttribute<Conn>::store()
         {
             // oops, someone is trying to change types, this is not supported yet, throw an exception
             std::string msg {
-                "Attempt to add an attribute which is already stored with different type information. For attribute" +
+                "Attempt to add an attribute which is already stored with different type information. For attribute: " +
                 _attr_name.fqdnAttributeName()};
 
             spdlog::error("Error: {}", msg);
@@ -151,7 +151,7 @@ HdbppTxNewAttribute<Conn> &HdbppTxNewAttribute<Conn>::store()
         {
             // someone is trying to add the same attribute over and over?
             std::string msg {"The attribute already exists in the database. Can not add again. "};
-            spdlog::warn("Warning: {} For attribute {}", msg, _attr_name.fqdnAttributeName());
+            spdlog::warn("Warning: {} For attribute: {}", msg, _attr_name.fqdnAttributeName());
 
             // bad black box behaviour, this is not an error, in fact, the system
             // built top assume this undocumented behaviour!!
@@ -159,7 +159,7 @@ HdbppTxNewAttribute<Conn> &HdbppTxNewAttribute<Conn>::store()
     }
     else
     {
-        spdlog::info("Adding a new attribute to the system: {}", _attr_name.fqdnAttributeName());
+        spdlog::debug("Adding a new attribute to the system: {}", _attr_name.fqdnAttributeName());
 
         // attempt to store the new attribute into the database for the first time
         HdbppTxBase<Conn>::connection().storeAttribute(prepared_attr_name,
diff --git a/src/LibUtils.cpp b/src/LibUtils.cpp
index 9be85ba0a6d3dcbb4acaf45d74f45c1357844226..5f14b3ba3ff3f759148a2c08abd54f5017fe7df8 100644
--- a/src/LibUtils.cpp
+++ b/src/LibUtils.cpp
@@ -23,6 +23,7 @@
 #include "spdlog/sinks/null_sink.h"
 #include "spdlog/sinks/rotating_file_sink.h"
 #include "spdlog/sinks/stdout_color_sinks.h"
+#include "spdlog/sinks/dist_sink.h"
 #include "spdlog/sinks/syslog_sink.h"
 
 namespace hdbpp_internal
@@ -134,47 +135,69 @@ ostream &operator<<(ostream &os, Tango::AttrQuality quality)
 
 //=============================================================================
 //=============================================================================
-void LogConfigurator::initLogging(bool enable_file, bool enable_console, const string &log_file_name)
+void LogConfigurator::initLogging()
 {
-    try
-    {
-        spdlog::init_thread_pool(8192, 1);
-
-        vector<spdlog::sink_ptr> sinks;
-
-        // attempt to create a rotating log files of size 10MB and 3 rotations
-        if (enable_file && !log_file_name.empty())
-            sinks.push_back(make_shared<spdlog::sinks::rotating_file_sink_mt>(log_file_name, 1024 * 1024 * 10, 3));
-
-        if (enable_console)
-            sinks.push_back(make_shared<spdlog::sinks::stdout_color_sink_mt>());
+    auto logger = spdlog::get(logging_utils::LibLoggerName);
 
-        if (sinks.empty())
-            sinks.push_back(make_shared<spdlog::sinks::null_sink_mt>());
-
-        auto logger = make_shared<spdlog::async_logger>(LibLoggerName,
-            sinks.begin(),
-            sinks.end(),
-            spdlog::thread_pool(),
-            spdlog::async_overflow_policy::overrun_oldest);
-
-        // set the logger as the default so it can be accessed all over the library
-        spdlog::register_logger(logger);
-        spdlog::flush_every(std::chrono::seconds(1));
-        spdlog::flush_on(spdlog::level::warn);
-        spdlog::set_default_logger(logger);
-
-        spdlog::debug("Initialised the logging system...");
+    if (!logger)
+    {
+        try
+        {
+            spdlog::init_thread_pool(8192, 1);
+
+            auto dist_sink = make_shared<spdlog::sinks::dist_sink_mt>();
+            
+            auto logger = make_shared<spdlog::async_logger>(logging_utils::LibLoggerName,
+                dist_sink,
+                spdlog::thread_pool(),
+                spdlog::async_overflow_policy::overrun_oldest);
+
+            // set the logger as the default so it can be accessed all over the library
+            spdlog::register_logger(logger);
+            spdlog::flush_every(std::chrono::seconds(1));
+            spdlog::flush_on(spdlog::level::warn);
+            spdlog::set_default_logger(logger);
+        }
+        catch (const spdlog::spdlog_ex &ex)
+        {
+            string msg {"Failed to initialise the logging system, caught error: " + string(ex.what())};
+            cout << msg << endl;
+            Tango::Except::throw_exception("Runtime Error", msg, LOCATION_INFO);
+        }
+    }
+}
 
-        if (enable_file && !log_file_name.empty())
-            spdlog::debug("File logging enabled. Log file at: {}", log_file_name);
+//=============================================================================
+//=============================================================================
+void LogConfigurator::initSyslogLogging()
+{
+    try
+    {
+        auto logger = spdlog::get(logging_utils::LibLoggerName);
+        auto &sinks_tmp = dynamic_pointer_cast<spdlog::sinks::dist_sink_mt>(*(logger->sinks().begin()))->sinks();
+        sinks_tmp.push_back(make_shared<spdlog::sinks::syslog_sink_mt>(logging_utils::SyslogIdent, 0, LOG_USER, false));
+    }
+    catch (const spdlog::spdlog_ex &ex)
+    {
+        string msg {"Failed to initialise the syslog logging system, caught error: " + string(ex.what())};
+        cout << msg << endl;
+        Tango::Except::throw_exception("Runtime Error", msg, LOCATION_INFO);
+    }
+}
 
-        if (enable_console)
-            spdlog::debug("Console logging enabled.");
+//=============================================================================
+//=============================================================================
+void LogConfigurator::initConsoleLogging()
+{
+    try
+    {
+        auto logger = spdlog::get(logging_utils::LibLoggerName);
+        auto &sinks_tmp = dynamic_pointer_cast<spdlog::sinks::dist_sink_mt>(*(logger->sinks().begin()))->sinks();
+        sinks_tmp.push_back(make_shared<spdlog::sinks::stdout_color_sink_mt>());
     }
     catch (const spdlog::spdlog_ex &ex)
     {
-        string msg {"Failed to initialise the logging system, caught error: " + string(ex.what())};
+        string msg {"Failed to initialise the console logging system, caught error: " + string(ex.what())};
         cout << msg << endl;
         Tango::Except::throw_exception("Runtime Error", msg, LOCATION_INFO);
     }
@@ -182,17 +205,27 @@ void LogConfigurator::initLogging(bool enable_file, bool enable_console, const s
 
 //=============================================================================
 //=============================================================================
-void LogConfigurator::initLoggingMetrics(bool enable_file, bool enable_console, const string &log_file_name)
+void LogConfigurator::initFileLogging(const std::string &log_file_name)
 {
-    auto logger = spdlog::get(LibLoggerName);
-    if (!logger) initLogging(enable_file, enable_console, log_file_name);
+    try
+    {
+        auto logger = spdlog::get(logging_utils::LibLoggerName);
+        auto &sinks_tmp = dynamic_pointer_cast<spdlog::sinks::dist_sink_mt>(*(logger->sinks().begin()))->sinks();
+        sinks_tmp.push_back(make_shared<spdlog::sinks::rotating_file_sink_mt>(log_file_name, 1024 * 1024 * 10, 3));
+    }
+    catch (const spdlog::spdlog_ex &ex)
+    {
+        string msg {"Failed to initialise the file logging system, caught error: " + string(ex.what())};
+        cout << msg << endl;
+        Tango::Except::throw_exception("Runtime Error", msg, LOCATION_INFO);
+    }
 }
 
 //=============================================================================
 //=============================================================================
 void LogConfigurator::shutdownLogging()
 {
-    auto logger = spdlog::get(LibLoggerName);
+    auto logger = spdlog::get(logging_utils::LibLoggerName);
 
     if (!logger)
     {
diff --git a/src/LibUtils.hpp b/src/LibUtils.hpp
index 266c7e0c7e11d1ad5248f04a526ddd59ad9cffc1..49dd0727fd7d1817710fba8682990876706c40cf 100644
--- a/src/LibUtils.hpp
+++ b/src/LibUtils.hpp
@@ -58,40 +58,44 @@ std::ostream &operator<<(std::ostream &os, Tango::AttrDataFormat format);
 std::ostream &operator<<(std::ostream &os, Tango::CmdArgType type);
 std::ostream &operator<<(std::ostream &os, Tango::AttrQuality quality);
 
-// SPDLOG config and setup
-const std::string LibLoggerName = "hdbpp";
-
 struct LogConfigurator
 {
-    static void initLogging(bool enable_file, bool enable_console, const std::string &log_file_name = "");
-
-    // this version is used for metrics testing, and ignores the call if the
-    // logger already exists
-    static void initLoggingMetrics(bool enable_file, bool enable_console, const std::string &log_file_name = "");
+    static void initLogging();
+    static void initSyslogLogging();
+    static void initConsoleLogging();
+    static void initFileLogging(const std::string &log_file_name);
 
     static void shutdownLogging();
     static void setLoggingLevel(spdlog::level::level_enum level);
 };
 
-// get the file name from the __FILE__ variable for error messages
-constexpr auto* getFileName(const char* const path)
+namespace logging_utils
 {
-    const auto* start_position = path;
+    // SPDLOG config and setup
+    const std::string LibLoggerName = "hdbpp";
+    const std::string SyslogIdent = "hdbpp-timescale";
 
-    for (const auto* current_character = path; *current_character != '\0'; ++current_character)
-        if (*current_character == '\\' || *current_character == '/')
-            start_position = current_character;
+    // get the file name from the __FILE__ variable for error messages
+    constexpr auto* getFileName(const char* const path)
+    {
+        const auto* start_position = path;
 
-    if (start_position != path)
-        ++start_position;
+        for (const auto* current_character = path; *current_character != '\0'; ++current_character)
+            if (*current_character == '\\' || *current_character == '/')
+                start_position = current_character;
 
-    return start_position;
-}
+        if (start_position != path)
+            ++start_position;
+
+        return start_position;
+    }
+} // namespace logging_utils
 
 // Macros to get the location for reporting errors
 #define S1(x) #x
 #define S2(x) S1(x)
-#define LOCATION_INFO string(getFileName(__FILE__)) + ":" + string(__func__) + ":" S2(__LINE__)
+
+#define LOCATION_INFO std::string(logging_utils::getFileName(__FILE__)) + ":" + std::string(__func__) + ":" S2(__LINE__)
 
 }; // namespace hdbpp_internal
 #endif // _LIBUTILS_H
diff --git a/src/PqxxExtension.hpp b/src/PqxxExtension.hpp
index c64de39d04af85a21eb6ce8ad6345fed98c48a48..4f814ab726fd22e60c99b58ccfca717e02045e7e 100644
--- a/src/PqxxExtension.hpp
+++ b/src/PqxxExtension.hpp
@@ -176,9 +176,10 @@ public:
     }
 };
 
-// This specialisation is for string types to ensure the string is quoted
-// for storage
-template<>
+// This specialisation is for string types. Unlike other types the string type requires
+// the use of the ARRAY notation and dollar quoting to ensure the strings are stored
+// without escape characters. 
+/*template<>
 struct string_traits<std::vector<std::string>>
 {
 public:
@@ -217,12 +218,27 @@ public:
         }
     }
 
+    // unlike other types, when encoed to a string th
     static std::string to_string(const std::vector<std::string> &value)
     {
-        // simply use the pqxx utilities for this, rather than reinvent the wheel
-        return "{" + separated_list(",", value.begin(), value.end()) + "}";
+        if (value.empty())
+            return {};
+
+        auto iter = value.begin()l
+        auto result = "ARRAY["
+
+        result = "$$" + to_string((*iter)) + "$$";
+
+        for (++iter; iter != value.end(); ++iter)
+        {
+            result += ",";
+            result += "$$" + to_string((*iter)) + "$$";
+        }
+
+        result += "]"
+        return result;
     }
-};
+};*/
 
 // This specialisation is for bool, since it is not a normal container class, but
 // rather some kind of alien bitfield. We have to adjust the from_string to take into
diff --git a/src/QueryBuilder.cpp b/src/QueryBuilder.cpp
index eac7987d3527fa511ee17bfffe7e4019aa6e6b4a..32208b8e2973ddadb8f11823a69b439450e87f72 100644
--- a/src/QueryBuilder.cpp
+++ b/src/QueryBuilder.cpp
@@ -247,8 +247,8 @@ namespace pqxx_conn
             // cache the query string against the traits
             _data_event_error_queries.emplace(traits, query);
 
-            _logger->debug("Built new data event error query and cached it against traits: {}", traits);
-            _logger->debug("New data event error query is: {}", query);
+            spdlog::debug("Built new data event error query and cached it against traits: {}", traits);
+            spdlog::debug("New data event error query is: {}", query);
 
             // now return it (must dereference the map again to get the static version)
             return _data_event_error_queries[traits];
@@ -392,7 +392,7 @@ namespace pqxx_conn
             // add to the cache for future hits
             cache.emplace(traits, new_name);
 
-            _logger->debug("New query name: {} cached against traits:", new_name, traits);
+            spdlog::debug("New query name: {} cached against traits:", new_name, traits);
             return cache[traits];
         }
 
diff --git a/src/QueryBuilder.hpp b/src/QueryBuilder.hpp
index 79cb042d34af857a38124de69cac861db0d85e1d..82bc533694190a73327d71138a7f6df59187cc4f 100644
--- a/src/QueryBuilder.hpp
+++ b/src/QueryBuilder.hpp
@@ -81,7 +81,6 @@ namespace pqxx_conn
     class QueryBuilder
     {
     public:
-        QueryBuilder() { _logger = spdlog::get(LibLoggerName); }
 
         // Non-static methods
 
@@ -96,12 +95,12 @@ namespace pqxx_conn
         const std::string &storeDataEventQuery(const AttributeTraits &traits);
 
         const std::string &storeDataEventErrorQuery(const AttributeTraits &traits);
-        std::string tableName(const AttributeTraits &traits);
 
         void print(std::ostream &os) const noexcept;
 
         // Static methods
 
+        static std::string tableName(const AttributeTraits &traits);
         static const std::string &storeAttributeQuery();
         static const std::string &storeHistoryEventQuery();
         static const std::string &storeHistoryStringQuery();
@@ -128,11 +127,8 @@ namespace pqxx_conn
         std::map<AttributeTraits, std::string> _data_event_error_query_names;
 
         // cached insert query strings built from the traits object
-        map<AttributeTraits, std::string> _data_event_queries;
-        map<AttributeTraits, std::string> _data_event_error_queries;
-
-        // logging subsystem
-        std::shared_ptr<spdlog::logger> _logger;
+        std::map<AttributeTraits, std::string> _data_event_queries;
+        std::map<AttributeTraits, std::string> _data_event_error_queries;
     };
 
     //=============================================================================
@@ -176,8 +172,8 @@ namespace pqxx_conn
             // cache the query string against the traits
             _data_event_queries.emplace(traits, query);
 
-            _logger->debug("Built new data event query and cached it against traits: {}", traits);
-            _logger->debug("New data event query is: {}", query);
+            spdlog::debug("Built new data event query and cached it against traits: {}", traits);
+            spdlog::debug("New data event query is: {}", query);
 
             // now return it (must dereference the map again to get the static version)
             return _data_event_queries[traits];
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 353a4276193140c384f27b8b4fea3a2d87a45d48..34869d53c93416e58e46bc6fccf9aac7342672be 100755
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -37,4 +37,18 @@ if(DO_CLANG_TIDY)
     set_target_properties(unit-tests  
         PROPERTIES 
             CXX_CLANG_TIDY ${DO_CLANG_TIDY})
-endif(DO_CLANG_TIDY)
\ No newline at end of file
+endif(DO_CLANG_TIDY)
+
+add_executable(tester test.cpp)
+target_compile_options(tester PRIVATE -Wall -Wextra -g)
+
+target_link_libraries(tester 
+    PRIVATE libhdbpp_headers libhdbpp_timescale_shared_library Catch2 TangoInterfaceLibrary)
+
+target_include_directories(tester 
+    PRIVATE ${CMAKE_SOURCE_DIR}/src ${PROJECT_SOURCE_DIR})
+
+set_target_properties(tester
+    PROPERTIES 
+        LINK_FLAGS "-Wl,--no-undefined"
+        CXX_STANDARD 14)
diff --git a/test/HdbppTxDataEventTests.cpp b/test/HdbppTxDataEventTests.cpp
index 8861eab72ed71e67a8d91444cf8ddc332b119607..5d1358f65f992abcd38e0da8bfbec10f456e1555 100644
--- a/test/HdbppTxDataEventTests.cpp
+++ b/test/HdbppTxDataEventTests.cpp
@@ -173,8 +173,10 @@ SCENARIO("Construct a valid HdbppTxDataEvent data event for storage", "[hdbpp-tx
     // ugly, how is this dealt with in Tango!?!
     struct timeval tv
     {};
+    
     struct Tango::TimeVal tango_tv
     {};
+
     gettimeofday(&tv, nullptr);
     tango_tv.tv_sec = tv.tv_sec;
     tango_tv.tv_usec = tv.tv_usec;
@@ -240,8 +242,10 @@ SCENARIO("An invalid quality results in an HdbppTxDataEvent event with no data",
     // ugly, how is this dealt with in Tango!?!
     struct timeval tv
     {};
+
     struct Tango::TimeVal tango_tv
     {};
+
     gettimeofday(&tv, nullptr);
     tango_tv.tv_sec = tv.tv_sec;
     tango_tv.tv_usec = tv.tv_usec;
@@ -284,8 +288,10 @@ SCENARIO("A DeviceAttribute with no data results in an HdbppTxDataEvent event wi
     // ugly, how is this dealt with in Tango!?!
     struct timeval tv
     {};
+
     struct Tango::TimeVal tango_tv
     {};
+
     gettimeofday(&tv, nullptr);
     tango_tv.tv_sec = tv.tv_sec;
     tango_tv.tv_usec = tv.tv_usec;
@@ -328,8 +334,10 @@ SCENARIO(
     // ugly, how is this dealt with in Tango!?!
     struct timeval tv
     {};
+
     struct Tango::TimeVal tango_tv
     {};
+
     gettimeofday(&tv, nullptr);
     tango_tv.tv_sec = tv.tv_sec;
     tango_tv.tv_usec = tv.tv_usec;
@@ -409,8 +417,10 @@ TEST_CASE("Creating HdbppTxDataEvents for each tango type and storing them", "[d
     // ugly, how is this dealt with in Tango!?!
     struct timeval tv
     {};
+
     struct Tango::TimeVal tango_tv
     {};
+
     gettimeofday(&tv, nullptr);
     tango_tv.tv_sec = tv.tv_sec;
     tango_tv.tv_usec = tv.tv_usec;
diff --git a/test/main.cpp b/test/main.cpp
index 2be52fded2c5230c8a1c9ad15202fc2fd2689e6a..74ae4d91c7923d829e6af91490497b4f8d9f0301 100644
--- a/test/main.cpp
+++ b/test/main.cpp
@@ -24,7 +24,7 @@
 
 int main(int argc, char *argv[])
 {
-    hdbpp_internal::LogConfigurator::initLogging(false, true, "/tmp/hdb/test.log");
+    hdbpp_internal::LogConfigurator::initLogging();
     hdbpp_internal::LogConfigurator::setLoggingLevel(spdlog::level::err);
 
     int result = Catch::Session().run(argc, argv);
diff --git a/thirdparty/spdlog b/thirdparty/spdlog
index a7148b718ea2fabb8387cb90aee9bf448da63e65..1549ff12f1aa61ffc4d9a8727c519034724392a0 160000
--- a/thirdparty/spdlog
+++ b/thirdparty/spdlog
@@ -1 +1 @@
-Subproject commit a7148b718ea2fabb8387cb90aee9bf448da63e65
+Subproject commit 1549ff12f1aa61ffc4d9a8727c519034724392a0