diff --git a/lib/api/LogManagerImpl.cpp b/lib/api/LogManagerImpl.cpp index 6a98e6406..7208ca650 100644 --- a/lib/api/LogManagerImpl.cpp +++ b/lib/api/LogManagerImpl.cpp @@ -642,7 +642,7 @@ namespace MAT_NS_BEGIN return m_logConfiguration; } - ILogger* LogManagerImpl::GetLogger(const std::string& tenantToken, const std::string& source, const std::string& scope) + ILogger* LogManagerImpl::GetLogger(const std::string& tenantToken, const std::string& source, const std::string& scope) { { LOCKGUARD(m_lock); diff --git a/lib/api/LogManagerProvider.cpp b/lib/api/LogManagerProvider.cpp index 9c6e2861d..2937c94c3 100644 --- a/lib/api/LogManagerProvider.cpp +++ b/lib/api/LogManagerProvider.cpp @@ -8,21 +8,21 @@ namespace MAT_NS_BEGIN { - ILogManager * LogManagerProvider::Get( + std::unique_ptr LogManagerProvider::Get( ILogConfiguration & config, - status_t &status + status_t &/*status*/ ) { - return LogManagerFactory::Get(config, status); + return std::unique_ptr(LogManagerFactory::Create(config)); } // TODO: consider utilizing a default reference - ILogManager* LogManagerProvider::Get( + std::unique_ptr LogManagerProvider::Get( const char * moduleName, status_t& status ) { - return LogManagerFactory::Get(moduleName, status); + return std::unique_ptr(LogManagerFactory::Get(moduleName, status)); } /// diff --git a/lib/api/capi.cpp b/lib/api/capi.cpp index 3e0d9bd53..e8a99ed5e 100644 --- a/lib/api/capi.cpp +++ b/lib/api/capi.cpp @@ -8,6 +8,7 @@ #if !defined (ANDROID) || defined(ENABLE_CAPI_HTTP_CLIENT) #include "http/HttpClient_CAPI.hpp" #endif +#include "LogManagerFactory.hpp" #include "LogManagerProvider.hpp" #include "mat.h" #include "pal/TaskDispatcher_CAPI.hpp" @@ -163,7 +164,7 @@ evt_status_t mat_open_core( } status_t status = static_cast(EFAULT); - clients[code].logmanager = LogManagerProvider::CreateLogManager(clients[code].config, status); + clients[code].logmanager = LogManagerFactory::Get(clients[code].config, status); // Verify that the instance pointer is valid if (clients[code].logmanager == nullptr) @@ -271,7 +272,7 @@ evt_status_t mat_log(evt_context_t *ctx) const auto & it = m.find(COMMONFIELDS_EVENT_SOURCE); std::string source = ((it != m.cend()) && (it->second.type == EventProperty::TYPE_STRING)) ? it->second.as_string : ""; - ILogger *logger = client->logmanager->GetLogger(token, source, scope); + ILogger* logger = client->logmanager->GetLogger(token, source, scope); if (logger == nullptr) { ctx->result = EFAULT; /* invalid address */ diff --git a/lib/include/public/LogManager.hpp b/lib/include/public/LogManager.hpp index 4833ac947..fbab0b960 100644 --- a/lib/include/public/LogManager.hpp +++ b/lib/include/public/LogManager.hpp @@ -12,7 +12,6 @@ namespace MAT_NS_BEGIN { class LogManager : public LogManagerBase {}; } MAT_NS_END +// Singleton LogManager Instance is deprecated. #define LOGMANAGER_INSTANCE namespace MAT_NS_BEGIN { DEFINE_LOGMANAGER(LogManager, ModuleLogConfiguration); } MAT_NS_END - #endif - diff --git a/lib/include/public/LogManagerBase.hpp b/lib/include/public/LogManagerBase.hpp index b1f1f9097..baf6f7d2e 100644 --- a/lib/include/public/LogManagerBase.hpp +++ b/lib/include/public/LogManagerBase.hpp @@ -170,7 +170,7 @@ namespace MAT_NS_BEGIN /// /// Concrete instance for servicing all singleton calls /// - static ILogManager* instance; + static std::unique_ptr instance; /// /// Debug event source associated with this singleton @@ -731,7 +731,7 @@ namespace MAT_NS_BEGIN static ILogManager* GetInstance() noexcept { LM_LOCKGUARD(stateLock()); - return instance; + return instance.get(); } }; @@ -743,16 +743,16 @@ namespace MAT_NS_BEGIN // https://developercommunity.visualstudio.com/content/problem/134886/initialization-of-template-static-variable-wrong.html // #define DEFINE_LOGMANAGER(LogManagerClass, LogConfigurationClass) \ - ILogManager* LogManagerClass::instance = nullptr; + std::unique_ptr LogManagerClass::instance = nullptr; #elif defined(__APPLE__) && defined(MAT_USE_WEAK_LOGMANAGER) #define DEFINE_LOGMANAGER(LogManagerClass, LogConfigurationClass) \ template <> \ - __attribute__((weak)) ILogManager* LogManagerBase::instance{}; + __attribute__((weak)) std::unique_ptr LogManagerBase::instance{}; #else // ISO C++ -compliant declaration #define DEFINE_LOGMANAGER(LogManagerClass, LogConfigurationClass) \ template <> \ - ILogManager* LogManagerBase::instance{}; + std::unique_ptr LogManagerBase::instance{}; #endif } diff --git a/lib/include/public/LogManagerProvider.hpp b/lib/include/public/LogManagerProvider.hpp index 26d76d29a..32624f425 100644 --- a/lib/include/public/LogManagerProvider.hpp +++ b/lib/include/public/LogManagerProvider.hpp @@ -39,7 +39,7 @@ namespace MAT_NS_BEGIN /// Status. /// WantController. /// - static ILogManager* MATSDK_SPEC CreateLogManager( + static std::unique_ptr MATSDK_SPEC CreateLogManager( char const* id, bool wantController, ILogConfiguration& cfg, @@ -93,7 +93,7 @@ namespace MAT_NS_BEGIN /// Instance Id. /// Status. /// - static ILogManager* MATSDK_SPEC CreateLogManager(char const* id, + static std::unique_ptr MATSDK_SPEC CreateLogManager(char const* id, status_t& status, uint64_t targetVersion = MAT::Version) { @@ -105,13 +105,19 @@ namespace MAT_NS_BEGIN ); } - static ILogManager* MATSDK_SPEC CreateLogManager( + static std::unique_ptr MATSDK_SPEC CreateLogManager( ILogConfiguration& cfg, status_t& status) { return Get(cfg, status); } + static std::unique_ptr MATSDK_SPEC CreateLogManager(ILogConfiguration& cfg) + { + status_t status; + return Get(cfg, status); + } + /// /// Releases a guest or host LogManager by its instance id. /// Instance Id. @@ -139,12 +145,12 @@ namespace MAT_NS_BEGIN // methods deprecated. // - static ILogManager * MATSDK_SPEC Get( + static std::unique_ptr MATSDK_SPEC Get( ILogConfiguration & cfg, status_t &status ); - static ILogManager* MATSDK_SPEC Get( + static std::unique_ptr MATSDK_SPEC Get( const char * id, status_t& status ); diff --git a/lib/include/public/NullObjects.hpp b/lib/include/public/NullObjects.hpp index fcc640c05..99908217c 100644 --- a/lib/include/public/NullObjects.hpp +++ b/lib/include/public/NullObjects.hpp @@ -305,7 +305,7 @@ namespace MAT_NS_BEGIN return STATUS_ENOSYS; } - virtual ILogger * GetLogger(std::string const & /*tenantToken*/, std::string const & /*source*/ = std::string(), std::string const & /*experimentationProject*/ = std::string()) override + virtual ILogger* GetLogger(std::string const & /*tenantToken*/, std::string const & /*source*/ = std::string(), std::string const & /*experimentationProject*/ = std::string()) override { static NullLogger nullLogger; return &nullLogger; diff --git a/lib/jni/LogManager_jni.cpp b/lib/jni/LogManager_jni.cpp index dfd2697e9..37b9400de 100644 --- a/lib/jni/LogManager_jni.cpp +++ b/lib/jni/LogManager_jni.cpp @@ -30,7 +30,7 @@ using namespace MAT; template <> -ILogManager* LogManagerBase::instance{}; +std::unique_ptr LogManagerBase::instance{}; extern "C" { @@ -857,7 +857,7 @@ Java_com_microsoft_applications_events_LogManagerProvider_nativeCreateLogManager status_t status = status_t::STATUS_SUCCESS; mcPointer->manager = MAT::LogManagerProvider::CreateLogManager( mcPointer->config, - status); + status).release(); if (status == status_t::STATUS_SUCCESS && !!mcPointer->manager) { std::lock_guard lock(jniManagersMutex); diff --git a/tests/functests/AISendTests.cpp b/tests/functests/AISendTests.cpp index 508718763..910aeb184 100644 --- a/tests/functests/AISendTests.cpp +++ b/tests/functests/AISendTests.cpp @@ -97,6 +97,8 @@ class AISendTests : public ::testing::Test, std::string serverAddress; HttpServer server; + ILogConfiguration configuration; + std::unique_ptr logManager; ILogger* logger; std::atomic isSetup; @@ -147,7 +149,8 @@ class AISendTests : public ::testing::Test, virtual void Initialize(DebugEventListener& debugListener, std::string const& path, bool compression) { receivedRequests.clear(); - auto configuration = LogManager::GetLogConfiguration(); + configuration = ILogConfiguration{}; + configuration[CFG_STR_PRIMARY_TOKEN] = std::string{TEST_TOKEN}; configuration[CFG_INT_SDK_MODE] = SdkModeTypes_AI; configuration[CFG_STR_COLLECTOR_URL] = (serverAddress + path).c_str(); configuration[CFG_MAP_HTTP][CFG_BOOL_HTTP_COMPRESSION] = compression; @@ -167,32 +170,31 @@ class AISendTests : public ::testing::Test, configuration["version"] = "1.0.0"; configuration["config"] = {{"host", __FILE__}}; // Host instance - LogManager::Initialize(TEST_TOKEN, configuration); - LogManager::SetLevelFilter(DIAG_LEVEL_DEFAULT, {DIAG_LEVEL_DEFAULT_MIN, DIAG_LEVEL_DEFAULT_MAX}); - LogManager::ResumeTransmission(); + logManager = LogManagerProvider::CreateLogManager(configuration); + logManager->SetLevelFilter(DIAG_LEVEL_DEFAULT, {DIAG_LEVEL_DEFAULT_MIN, DIAG_LEVEL_DEFAULT_MAX}); + logManager->ResumeTransmission(); - LogManager::AddEventListener(DebugEventType::EVT_HTTP_OK, debugListener); - LogManager::AddEventListener(DebugEventType::EVT_HTTP_ERROR, debugListener); - LogManager::AddEventListener(DebugEventType::EVT_HTTP_FAILURE, debugListener); - LogManager::AddEventListener(DebugEventType::EVT_HTTP_STATE, debugListener); - LogManager::AddEventListener(DebugEventType::EVT_ADDED, debugListener); + logManager->AddEventListener(DebugEventType::EVT_HTTP_OK, debugListener); + logManager->AddEventListener(DebugEventType::EVT_HTTP_ERROR, debugListener); + logManager->AddEventListener(DebugEventType::EVT_HTTP_FAILURE, debugListener); + logManager->AddEventListener(DebugEventType::EVT_HTTP_STATE, debugListener); + logManager->AddEventListener(DebugEventType::EVT_ADDED, debugListener); - logger = LogManager::GetLogger(TEST_TOKEN); + logger = logManager->GetLogger(TEST_TOKEN); } virtual void FlushAndTeardown(DebugEventListener& debugListener) { - LogManager::Flush(); + logManager->Flush(); - LogManager::RemoveEventListener(DebugEventType::EVT_HTTP_OK, debugListener); - LogManager::RemoveEventListener(DebugEventType::EVT_HTTP_ERROR, debugListener); - LogManager::RemoveEventListener(DebugEventType::EVT_HTTP_FAILURE, debugListener); - LogManager::RemoveEventListener(DebugEventType::EVT_HTTP_STATE, debugListener); - LogManager::RemoveEventListener(DebugEventType::EVT_ADDED, debugListener); + logManager->RemoveEventListener(DebugEventType::EVT_HTTP_OK, debugListener); + logManager->RemoveEventListener(DebugEventType::EVT_HTTP_ERROR, debugListener); + logManager->RemoveEventListener(DebugEventType::EVT_HTTP_FAILURE, debugListener); + logManager->RemoveEventListener(DebugEventType::EVT_HTTP_STATE, debugListener); + logManager->RemoveEventListener(DebugEventType::EVT_ADDED, debugListener); - LogManager::FlushAndTeardown(); + logManager->FlushAndTeardown(); - auto &configuration = LogManager::GetLogConfiguration(); configuration[CFG_INT_SDK_MODE] = SdkModeTypes_CS; } diff --git a/tests/functests/APITest.cpp b/tests/functests/APITest.cpp index 5c2dbb770..4e8b8e9ae 100644 --- a/tests/functests/APITest.cpp +++ b/tests/functests/APITest.cpp @@ -38,8 +38,6 @@ using namespace MAT; -LOGMANAGER_INSTANCE - // 1DSCppSdkTest sandbox key #define TEST_TOKEN "7c8b1796cbc44bd5a03803c01c2b9d61-b6e370dd-28d9-4a52-9556-762543cf7aa7-6991" @@ -218,44 +216,44 @@ class TestDebugEventListener : public DebugEventListener { /// Add all event listeners /// /// -void addAllListeners(DebugEventListener& listener) +void addAllListeners(ILogManager& logManager, DebugEventListener& listener) { - LogManager::AddEventListener(DebugEventType::EVT_LOG_EVENT, listener); - LogManager::AddEventListener(DebugEventType::EVT_LOG_SESSION, listener); - LogManager::AddEventListener(DebugEventType::EVT_REJECTED, listener); - LogManager::AddEventListener(DebugEventType::EVT_SEND_FAILED, listener); - LogManager::AddEventListener(DebugEventType::EVT_SENT, listener); - LogManager::AddEventListener(DebugEventType::EVT_DROPPED, listener); - LogManager::AddEventListener(DebugEventType::EVT_HTTP_OK, listener); - LogManager::AddEventListener(DebugEventType::EVT_HTTP_ERROR, listener); - LogManager::AddEventListener(DebugEventType::EVT_SEND_RETRY, listener); - LogManager::AddEventListener(DebugEventType::EVT_SEND_RETRY_DROPPED, listener); - LogManager::AddEventListener(DebugEventType::EVT_CACHED, listener); - LogManager::AddEventListener(DebugEventType::EVT_NET_CHANGED, listener); - LogManager::AddEventListener(DebugEventType::EVT_STORAGE_FULL, listener); - LogManager::AddEventListener(DebugEventType::EVT_FILTERED, listener); + logManager.AddEventListener(DebugEventType::EVT_LOG_EVENT, listener); + logManager.AddEventListener(DebugEventType::EVT_LOG_SESSION, listener); + logManager.AddEventListener(DebugEventType::EVT_REJECTED, listener); + logManager.AddEventListener(DebugEventType::EVT_SEND_FAILED, listener); + logManager.AddEventListener(DebugEventType::EVT_SENT, listener); + logManager.AddEventListener(DebugEventType::EVT_DROPPED, listener); + logManager.AddEventListener(DebugEventType::EVT_HTTP_OK, listener); + logManager.AddEventListener(DebugEventType::EVT_HTTP_ERROR, listener); + logManager.AddEventListener(DebugEventType::EVT_SEND_RETRY, listener); + logManager.AddEventListener(DebugEventType::EVT_SEND_RETRY_DROPPED, listener); + logManager.AddEventListener(DebugEventType::EVT_CACHED, listener); + logManager.AddEventListener(DebugEventType::EVT_NET_CHANGED, listener); + logManager.AddEventListener(DebugEventType::EVT_STORAGE_FULL, listener); + logManager.AddEventListener(DebugEventType::EVT_FILTERED, listener); } /// /// Remove all event listeners /// /// -void removeAllListeners(DebugEventListener& listener) +void removeAllListeners(ILogManager& logManager, DebugEventListener& listener) { - LogManager::RemoveEventListener(DebugEventType::EVT_LOG_EVENT, listener); - LogManager::RemoveEventListener(DebugEventType::EVT_LOG_SESSION, listener); - LogManager::RemoveEventListener(DebugEventType::EVT_REJECTED, listener); - LogManager::RemoveEventListener(DebugEventType::EVT_SEND_FAILED, listener); - LogManager::RemoveEventListener(DebugEventType::EVT_SENT, listener); - LogManager::RemoveEventListener(DebugEventType::EVT_DROPPED, listener); - LogManager::RemoveEventListener(DebugEventType::EVT_HTTP_OK, listener); - LogManager::RemoveEventListener(DebugEventType::EVT_HTTP_ERROR, listener); - LogManager::RemoveEventListener(DebugEventType::EVT_SEND_RETRY, listener); - LogManager::RemoveEventListener(DebugEventType::EVT_SEND_RETRY_DROPPED, listener); - LogManager::RemoveEventListener(DebugEventType::EVT_CACHED, listener); - LogManager::RemoveEventListener(DebugEventType::EVT_NET_CHANGED, listener); - LogManager::RemoveEventListener(DebugEventType::EVT_STORAGE_FULL, listener); - LogManager::RemoveEventListener(DebugEventType::EVT_FILTERED, listener); + logManager.RemoveEventListener(DebugEventType::EVT_LOG_EVENT, listener); + logManager.RemoveEventListener(DebugEventType::EVT_LOG_SESSION, listener); + logManager.RemoveEventListener(DebugEventType::EVT_REJECTED, listener); + logManager.RemoveEventListener(DebugEventType::EVT_SEND_FAILED, listener); + logManager.RemoveEventListener(DebugEventType::EVT_SENT, listener); + logManager.RemoveEventListener(DebugEventType::EVT_DROPPED, listener); + logManager.RemoveEventListener(DebugEventType::EVT_HTTP_OK, listener); + logManager.RemoveEventListener(DebugEventType::EVT_HTTP_ERROR, listener); + logManager.RemoveEventListener(DebugEventType::EVT_SEND_RETRY, listener); + logManager.RemoveEventListener(DebugEventType::EVT_SEND_RETRY_DROPPED, listener); + logManager.RemoveEventListener(DebugEventType::EVT_CACHED, listener); + logManager.RemoveEventListener(DebugEventType::EVT_NET_CHANGED, listener); + logManager.RemoveEventListener(DebugEventType::EVT_STORAGE_FULL, listener); + logManager.RemoveEventListener(DebugEventType::EVT_FILTERED, listener); } #ifdef HAVE_MAT_DEFAULT_HTTP_CLIENT @@ -268,9 +266,10 @@ void removeAllListeners(DebugEventListener& listener) /// TEST(APITest, LogManager_Initialize_Default_Test) { - ILogger *result = LogManager::Initialize(TEST_TOKEN); - EXPECT_EQ(true, (result != NULL)); - LogManager::FlushAndTeardown(); + ILogConfiguration config; + auto logManager = LogManagerProvider::CreateLogManager(config); + auto logger = logManager->GetLogger(TEST_TOKEN); + EXPECT_NE(logger, nullptr); } /// @@ -281,13 +280,13 @@ TEST(APITest, LogManager_Initialize_Default_Test) /// TEST(APITest, LogManager_Initialize_Custom) { - auto& configuration = LogManager::GetLogConfiguration(); + ILogConfiguration configuration; configuration[CFG_INT_TRACE_LEVEL_MASK] = 0xFFFFFFFF ^ 128; // API calls + Global mask for general messages - less SQL configuration[CFG_INT_TRACE_LEVEL_MIN] = ACTTraceLevel_Trace; configuration[CFG_STR_COLLECTOR_URL] = "https://127.0.0.1/"; - ILogger *result = LogManager::Initialize(TEST_TOKEN, configuration); - EXPECT_EQ(true, (result != NULL)); - LogManager::FlushAndTeardown(); + auto logManager = LogManagerProvider::CreateLogManager(configuration); + auto logger =logManager->GetLogger(TEST_TOKEN); + EXPECT_NE(logger, nullptr); } #define TEST_STORAGE_FILENAME "offlinestorage.db" @@ -369,7 +368,7 @@ TEST(APITest, LogManager_Initialize_DebugEventListener) TestDebugEventListener debugListener; - auto& configuration = LogManager::GetLogConfiguration(); + auto configuration = ILogConfiguration{}; configuration[CFG_INT_TRACE_LEVEL_MASK] = 0xFFFFFFFF ^ 128; // API calls + Global mask for general messages - less SQL configuration[CFG_INT_TRACE_LEVEL_MIN] = ACTTraceLevel_Warn; // Don't log too much on a slow machine configuration[CFG_STR_COLLECTOR_URL] = COLLECTOR_URL_PROD; @@ -385,22 +384,25 @@ TEST(APITest, LogManager_Initialize_DebugEventListener) eventToLog.SetLevel(DIAG_LEVEL_REQUIRED); CleanStorage(); - addAllListeners(debugListener); + auto logManager = LogManagerProvider::CreateLogManager(configuration); + addAllListeners(*logManager, debugListener); { - LogManager::Initialize(TEST_TOKEN, configuration); - LogManager::PauseTransmission(); + logManager->PauseTransmission(); size_t numIterations = MAX_ITERATIONS * 1000; // 100K events while (numIterations--) { - LogManager::GetLogger()->LogEvent(eventToLog); + logManager->GetLogger(TEST_TOKEN)->LogEvent(eventToLog); } - LogManager::Flush(); + logManager->Flush(); EXPECT_GE(debugListener.storageFullPct.load(), (unsigned)100); - LogManager::FlushAndTeardown(); + logManager = nullptr; debugListener.storageFullPct = 0; - LogManager::Initialize(TEST_TOKEN, configuration); - LogManager::FlushAndTeardown(); + + logManager = LogManagerProvider::CreateLogManager(configuration); + addAllListeners(*logManager, debugListener); + logManager->GetLogger(TEST_TOKEN); + logManager = nullptr; EXPECT_EQ(debugListener.storageFullPct.load(), 0u); } @@ -409,7 +411,9 @@ TEST(APITest, LogManager_Initialize_DebugEventListener) debugListener.numLogged = 0; CleanStorage(); - ILogger *result = LogManager::Initialize(TEST_TOKEN, configuration); + logManager = LogManagerProvider::CreateLogManager(configuration); + addAllListeners(*logManager, debugListener); + auto result = logManager->GetLogger(TEST_TOKEN); // Log some foo size_t numIterations = MAX_ITERATIONS; @@ -420,11 +424,11 @@ TEST(APITest, LogManager_Initialize_DebugEventListener) EXPECT_EQ(0u, debugListener.numDropped); EXPECT_EQ(0u, debugListener.numReject); - LogManager::UploadNow(); // Try to upload whatever we got + logManager->UploadNow(); // Try to upload whatever we got PAL::sleep(1000); // Give enough time to upload at least one event EXPECT_NE(0u, debugListener.numSent); // Some posts must succeed within 500ms - LogManager::PauseTransmission(); // There could still be some pending at this point - LogManager::Flush(); // Save all pending to disk + logManager->PauseTransmission(); // There could still be some pending at this point + logManager->Flush(); // Save all pending to disk numIterations = MAX_ITERATIONS; debugListener.numLogged = 0; // Reset the logged counter @@ -435,23 +439,22 @@ TEST(APITest, LogManager_Initialize_DebugEventListener) result->LogEvent(eventToStore); // New events go straight to offline storage EXPECT_EQ(MAX_ITERATIONS, debugListener.numLogged); - LogManager::Flush(); + logManager->Flush(); EXPECT_EQ(MAX_ITERATIONS, debugListener.numCached); - LogManager::SetTransmitProfile(TransmitProfile_RealTime); - LogManager::ResumeTransmission(); - LogManager::FlushAndTeardown(); + logManager->SetTransmitProfile(TransmitProfile_RealTime); + logManager->ResumeTransmission(); + logManager->FlushAndTeardown(); // Check that we sent all of logged + whatever left overs // prior to PauseTransmission EXPECT_GE(debugListener.numSent, debugListener.numLogged); debugListener.printStats(); - removeAllListeners(debugListener); } #ifdef _WIN32 TEST(APITest, LogManager_UTCSingleEventSent) { - auto& configuration = LogManager::GetLogConfiguration(); + ILogConfiguration configuration; configuration[CFG_INT_TRACE_LEVEL_MASK] = 0xFFFFFFFF ^ 128; // API calls + Global mask for general messages - less SQL configuration[CFG_INT_TRACE_LEVEL_MIN] = ACTTraceLevel_Info; configuration[CFG_INT_SDK_MODE] = SdkModeTypes::SdkModeTypes_UTCCommonSchema; @@ -471,9 +474,10 @@ TEST(APITest, LogManager_UTCSingleEventSent) { event.SetLatency(EventLatency_Normal); event.SetLevel(DIAG_LEVEL_REQUIRED); - ILogger *logger = LogManager::Initialize(TEST_TOKEN, configuration); + auto logManager = LogManagerProvider::CreateLogManager(configuration); + auto logger = logManager->GetLogger(TEST_TOKEN); logger->LogEvent(event); - LogManager::FlushAndTeardown(); + logManager->FlushAndTeardown(); } #endif @@ -482,7 +486,9 @@ TEST(APITest, LogManager_SemanticAPI) bool failed = false; try { - ILogger *result = LogManager::Initialize(TEST_TOKEN); + ILogConfiguration config; + auto logManager = LogManagerProvider::CreateLogManager(config); + auto result = logManager->GetLogger(TEST_TOKEN); // ISemanticContext *context = result->GetSemanticContext(); { @@ -509,8 +515,6 @@ TEST(APITest, LogManager_SemanticAPI) PageActionData data("page_action", ActionType_Unknown); result->LogPageAction(data, props); } - - LogManager::FlushAndTeardown(); } catch (...) { @@ -527,25 +531,22 @@ unsigned StressSingleThreaded(ILogConfiguration& config) { TestDebugEventListener debugListener; - addAllListeners(debugListener); - ILogger *result = LogManager::Initialize(TEST_TOKEN, config); + auto logManager = LogManagerProvider::CreateLogManager(config); + addAllListeners(*logManager, debugListener); + auto result = logManager->GetLogger(TEST_TOKEN); size_t numIterations = MAX_ITERATIONS; while (numIterations--) { EventProperties props = testing::CreateSampleEvent("event_name", EventPriority_Normal); result->LogEvent(props); } - LogManager::FlushAndTeardown(); - unsigned retVal = debugListener.numLogged; - removeAllListeners(debugListener); - return retVal; } TEST(APITest, LogManager_Stress_SingleThreaded) { - auto& config = LogManager::GetLogConfiguration(); + ILogConfiguration config; EXPECT_GE(StressSingleThreaded(config), MAX_ITERATIONS); } @@ -560,7 +561,8 @@ void StressUploadLockMultiThreaded(ILogConfiguration& config) std::srand(static_cast(std::time(nullptr))); TestDebugEventListener debugListener; - addAllListeners(debugListener); + auto logManager = LogManagerProvider::CreateLogManager(config); + addAllListeners(*logManager, debugListener); size_t numIterations = MAX_ITERATIONS_MT; std::mutex m_threads_mtx; @@ -568,7 +570,7 @@ void StressUploadLockMultiThreaded(ILogConfiguration& config) while (numIterations--) { - ILogger *result = LogManager::Initialize(TEST_TOKEN, config); + auto result = logManager->GetLogger(TEST_TOKEN); // Keep spawning UploadNow threads while the main thread is trying to perform // Initialize and Teardown, but no more than MAX_THREADS at a time. for (size_t i = 0; i < MAX_THREADS; i++) @@ -578,7 +580,7 @@ void StressUploadLockMultiThreaded(ILogConfiguration& config) auto t = std::thread([&]() { std::this_thread::yield(); - LogManager::UploadNow(); + logManager->UploadNow(); const auto randTimeSub2ms = std::rand() % 2; PAL::sleep(randTimeSub2ms); threadCount--; @@ -588,29 +590,27 @@ void StressUploadLockMultiThreaded(ILogConfiguration& config) }; EventProperties props = testing::CreateSampleEvent("event_name", EventPriority_Normal); result->LogEvent(props); - LogManager::FlushAndTeardown(); } - removeAllListeners(debugListener); } TEST(APITest, LogManager_StressUploadLock_MultiThreaded) { - auto& config = LogManager::GetLogConfiguration(); + ILogConfiguration config; config[CFG_INT_MAX_TEARDOWN_TIME] = 0; StressUploadLockMultiThreaded(config); // Basic expectation here is just that we do not crash.. // We can add memory utilization metric in here as well. } - TEST(APITest, LogManager_Reinitialize_Test) { - size_t numIterations = 5; + ILogConfiguration config; + size_t numIterations = 1; while (numIterations--) { - ILogger *result = LogManager::Initialize(TEST_TOKEN); + auto logManager = LogManagerProvider::CreateLogManager(config); + auto result = logManager->GetLogger(TEST_TOKEN); EXPECT_EQ(true, (result != NULL)); - LogManager::FlushAndTeardown(); } } @@ -746,14 +746,15 @@ TEST(APITest, UTC_Callback_Test) { TestDebugEventListener debugListener; - auto& configuration = LogManager::GetLogConfiguration(); + ILogConfiguration configuration; configuration[CFG_INT_SDK_MODE] = SdkModeTypes::SdkModeTypes_UTCCommonSchema; std::time_t now = time(0); MAT::time_ticks_t ticks(&now); - LogManager::AddEventListener(EVT_LOG_EVENT, debugListener); - auto logger = LogManager::Initialize(TEST_TOKEN); + auto logManager = LogManagerProvider::CreateLogManager(configuration); + logManager->AddEventListener(EVT_LOG_EVENT, debugListener); + auto logger = logManager->GetLogger(TEST_TOKEN); unsigned totalEvents = 0; debugListener.OnLogX = [&](::CsProtocol::Record& record) { @@ -809,8 +810,6 @@ TEST(APITest, UTC_Callback_Test) event.SetTimestamp((int64_t)(now * 1000L)); logger->LogEvent(event); } - LogManager::FlushAndTeardown(); - LogManager::RemoveEventListener(EVT_LOG_EVENT, debugListener); } #endif @@ -818,14 +817,15 @@ TEST(APITest, Pii_DROP_Test) { TestDebugEventListener debugListener; - auto& config = LogManager::GetLogConfiguration(); + ILogConfiguration config; config[CFG_INT_SDK_MODE] = SdkModeTypes::SdkModeTypes_CS; config[CFG_MAP_METASTATS_CONFIG][CFG_INT_METASTATS_INTERVAL] = 0; // avoid sending stats for this test config[CFG_INT_MAX_TEARDOWN_TIME] = 1; // give enough time to upload // register a listener - LogManager::AddEventListener(EVT_LOG_EVENT, debugListener); - auto logger = LogManager::Initialize(TEST_TOKEN); + auto logManager = LogManagerProvider::CreateLogManager(config); + logManager->AddEventListener(EVT_LOG_EVENT, debugListener); + auto logger = logManager->GetLogger(TEST_TOKEN); unsigned totalEvents = 0; std::string realDeviceId; @@ -885,10 +885,8 @@ TEST(APITest, Pii_DROP_Test) logger->LogEvent(event); } - LogManager::FlushAndTeardown(); + logManager->FlushAndTeardown(); ASSERT_EQ(totalEvents, 4u); - LogManager::RemoveEventListener(EVT_LOG_EVENT, debugListener); - } #endif @@ -897,16 +895,17 @@ TEST(APITest, SemanticContext_Test) { TestDebugEventListener debugListener; - auto& config = LogManager::GetLogConfiguration(); + ILogConfiguration config; config[CFG_INT_SDK_MODE] = SdkModeTypes::SdkModeTypes_CS; config[CFG_MAP_METASTATS_CONFIG][CFG_INT_METASTATS_INTERVAL] = 0; // avoid sending stats for this test config[CFG_INT_MAX_TEARDOWN_TIME] = 1; // give enough time to upload // register a listener - LogManager::AddEventListener(EVT_LOG_EVENT, debugListener); + auto logManager = LogManagerProvider::CreateLogManager(config); + logManager->AddEventListener(EVT_LOG_EVENT, debugListener); CleanStorage(); - auto logger = LogManager::Initialize(TEST_TOKEN); + auto logger = logManager->GetLogger(TEST_TOKEN); unsigned totalEvents = 0; // Verify that semantic context fields have been set on record @@ -971,10 +970,9 @@ TEST(APITest, SemanticContext_Test) logger->LogEvent("LoggerContext.Event"); - LogManager::FlushAndTeardown(); + logManager->FlushAndTeardown(); ASSERT_EQ(totalEvents, 1u); - LogManager::RemoveEventListener(EVT_LOG_EVENT, debugListener); } TEST(APITest, SetType_Test) @@ -982,20 +980,21 @@ TEST(APITest, SetType_Test) TestDebugEventListener debugListener; for (auto customPrefix : {EVENTRECORD_TYPE_CUSTOM_EVENT, ""}) { - auto& config = LogManager::GetLogConfiguration(); + ILogConfiguration config; config[CFG_INT_SDK_MODE] = SdkModeTypes::SdkModeTypes_CS; config[CFG_MAP_METASTATS_CONFIG][CFG_INT_METASTATS_INTERVAL] = 0; // avoid sending stats for this test config[CFG_INT_MAX_TEARDOWN_TIME] = 0; // Iterate over default ("custom") and empty prefix. config[CFG_MAP_COMPAT][CFG_STR_COMPAT_PREFIX] = customPrefix; // Register a listener. - LogManager::AddEventListener(EVT_LOG_EVENT, debugListener); + auto logManager = LogManagerProvider::CreateLogManager(config); + logManager->AddEventListener(EVT_LOG_EVENT, debugListener); // Clean storage to avoid polluting our test callback by unwanted events. CleanStorage(); - auto logger = LogManager::Initialize(TEST_TOKEN); + auto logger = logManager->GetLogger(TEST_TOKEN); unsigned totalEvents = 0; // We don't need to upload for this test. - LogManager::PauseTransmission(); + logManager->PauseTransmission(); // Verify that record.baseType have been properly decorated. debugListener.OnLogX = [&](::CsProtocol::Record& record) { totalEvents++; @@ -1014,14 +1013,9 @@ TEST(APITest, SetType_Test) // Specify totally custom base type for export to other pipelines. myEvent.SetType("MyEventType"); logger->LogEvent(myEvent); - LogManager::FlushAndTeardown(); - LogManager::RemoveEventListener(EVT_LOG_EVENT, debugListener); + logManager->FlushAndTeardown(); + logManager->RemoveEventListener(EVT_LOG_EVENT, debugListener); } - // When we are done, the configuration static object is never gone. - // We restore the compat prefix to defaults, that is to avoid - // breaking some other subsequent test expectations. - auto& config = LogManager::GetLogConfiguration(); - config[CFG_MAP_COMPAT][CFG_STR_COMPAT_PREFIX] = EVENTRECORD_TYPE_CUSTOM_EVENT; } static void logBenchMark(const char * label) @@ -1051,7 +1045,7 @@ TEST(APITest, LogManager_Reinitialize_UploadNow) while (numIterations--) { logBenchMark("started"); - auto& config = LogManager::GetLogConfiguration(); + ILogConfiguration config; logBenchMark("created"); config[CFG_INT_TRACE_LEVEL_MASK] = 0xFFFFFFFF; @@ -1061,31 +1055,32 @@ TEST(APITest, LogManager_Reinitialize_UploadNow) config[CFG_INT_MAX_TEARDOWN_TIME] = 1; logBenchMark("config "); - ILogger *logger = LogManager::Initialize(TEST_TOKEN, config); + auto logManager = LogManagerProvider::CreateLogManager(config); + ILogger *logger = logManager->GetLogger(TEST_TOKEN); logBenchMark("inited "); logger->LogEvent("test"); logBenchMark("logged "); // Try to switch transmit profile - LogManager::SetTransmitProfile(TRANSMITPROFILE_REALTIME); + logManager->SetTransmitProfile(TRANSMITPROFILE_REALTIME); logBenchMark("profile"); if (flipFlop) { - LogManager::PauseTransmission(); + logManager->PauseTransmission(); } else { - LogManager::ResumeTransmission(); + logManager->ResumeTransmission(); } logBenchMark("flipflp"); logBenchMark("upload "); - LogManager::UploadNow(); + logManager->UploadNow(); logBenchMark("flush "); - LogManager::FlushAndTeardown(); + logManager->FlushAndTeardown(); logBenchMark("done "); flipFlop = !flipFlop; @@ -1101,7 +1096,7 @@ TEST(APITest, LogManager_Reinitialize_UploadNow) TEST(APITest, LogManager_BadStoragePath_Test) { TestDebugEventListener debugListener; - auto& config = LogManager::GetLogConfiguration(); + ILogConfiguration config; config[CFG_INT_TRACE_LEVEL_MASK] = 0xFFFFFFFF; // API calls + Global mask for general messages - less SQL config[CFG_INT_TRACE_LEVEL_MIN] = ACTTraceLevel_Trace; config[CFG_INT_MAX_TEARDOWN_TIME] = 16; @@ -1123,13 +1118,14 @@ TEST(APITest, LogManager_BadStoragePath_Test) { debugListener.storageFailed = false; config[CFG_STR_CACHE_FILE_PATH] = path.c_str(); - ILogger *result = LogManager::Initialize(TEST_TOKEN, config); - LogManager::AddEventListener(DebugEventType::EVT_STORAGE_FAILED, debugListener); + auto logManager = LogManagerProvider::CreateLogManager(config); + auto result = logManager->GetLogger(TEST_TOKEN); + logManager->AddEventListener(DebugEventType::EVT_STORAGE_FAILED, debugListener); EXPECT_EQ(true, (result != NULL)); result->LogEvent("test"); - LogManager::Flush(); - LogManager::FlushAndTeardown(); - LogManager::RemoveEventListener(DebugEventType::EVT_STORAGE_FAILED, debugListener); + logManager->Flush(); + logManager->FlushAndTeardown(); + logManager->RemoveEventListener(DebugEventType::EVT_STORAGE_FAILED, debugListener); EXPECT_EQ(true, debugListener.storageFailed); } @@ -1153,7 +1149,7 @@ TEST(APITest, LogConfiguration_MsRoot_Check) { CleanStorage(); - auto& config = LogManager::GetLogConfiguration(); + ILogConfiguration config; config[CFG_MAP_METASTATS_CONFIG][CFG_INT_METASTATS_INTERVAL] = 0; // avoid sending stats for this test, just customer events config[CFG_STR_COLLECTOR_URL] = std::get<0>(params); config[CFG_MAP_HTTP][CFG_BOOL_HTTP_MS_ROOT_CHECK] = std::get<1>(params); // MS root check depends on what URL we are sending to @@ -1161,13 +1157,12 @@ TEST(APITest, LogConfiguration_MsRoot_Check) config[CFG_STR_CACHE_FILE_PATH] = GetStoragePath(); auto expectedHttpCount = std::get<2>(params); - auto logger = LogManager::Initialize(TEST_TOKEN, config); + auto logManager = LogManagerProvider::CreateLogManager(config); + auto logger = logManager->GetLogger(TEST_TOKEN); debugListener.reset(); - addAllListeners(debugListener); + addAllListeners(*logManager, debugListener); logger->LogEvent("fooBar"); - LogManager::FlushAndTeardown(); - removeAllListeners(debugListener); // Connection is a best-effort, occasionally we can't connect, // but we MUST NOT connect to end-point that doesn't have the @@ -1178,7 +1173,7 @@ TEST(APITest, LogConfiguration_MsRoot_Check) #endif TEST(APITest, LogManager_BadNetwork_Test) { - auto& config = LogManager::GetLogConfiguration(); + ILogConfiguration config; // Clean temp file first const char *cacheFilePath = "bad-network.db"; @@ -1216,12 +1211,13 @@ TEST(APITest, LogManager_BadNetwork_Test) TEST(APITest, LogManager_GetLoggerSameLoggerMultithreaded) { - auto& config = LogManager::GetLogConfiguration(); + ILogConfiguration config; + auto logManager = LogManagerProvider::CreateLogManager(config); - auto logger0 = LogManager::Initialize(TEST_TOKEN, config); - auto logger1 = LogManager::GetLogger(); - auto logger2 = LogManager::GetLogger("my_source"); - auto logger3 = LogManager::GetLogger(TEST_TOKEN, "my_source"); + auto logger0 = logManager->GetLogger(TEST_TOKEN); + auto logger1 = logManager->GetLogger(TEST_TOKEN); + auto logger2 = logManager->GetLogger(TEST_TOKEN, "my_source"); + auto logger3 = logManager->GetLogger(TEST_TOKEN, "my_source"); EXPECT_EQ(logger0, logger1); EXPECT_EQ(logger2, logger3); @@ -1238,13 +1234,13 @@ TEST(APITest, LogManager_GetLoggerSameLoggerMultithreaded) std::vector threads; for (size_t i = 0; i < numThreads; i++) { - threads.push_back(std::thread([logger1, logger2, logger3]() { + threads.push_back(std::thread([&logManager, logger1, logger2, logger3]() { size_t count = 1000; while (count--) { - auto myLogger1 = LogManager::GetLogger(); - auto myLogger2 = LogManager::GetLogger("my_source"); - auto myLogger3 = LogManager::GetLogger(TEST_TOKEN, "my_source"); + auto myLogger1 = logManager->GetLogger(TEST_TOKEN); + auto myLogger2 = logManager->GetLogger(TEST_TOKEN,"my_source"); + auto myLogger3 = logManager->GetLogger(TEST_TOKEN, "my_source"); EXPECT_EQ(myLogger1, logger1); EXPECT_EQ(myLogger2, logger2); EXPECT_EQ(myLogger3, logger3); @@ -1255,30 +1251,28 @@ TEST(APITest, LogManager_GetLoggerSameLoggerMultithreaded) for (auto& thread : threads) thread.join(); logBenchMark("destroyed"); - LogManager::FlushAndTeardown(); - - LogManager::GetLogger(); } TEST(APITest, LogManager_DiagLevels) { TestDebugEventListener eventListener; - auto& config = LogManager::GetLogConfiguration(); + ILogConfiguration config; + auto logManager = LogManagerProvider::CreateLogManager(config); // default - auto logger0 = LogManager::Initialize(TEST_TOKEN, config); - LogManager::GetEventFilters().UnregisterAllFilters(); + auto logger0 = logManager->GetLogger(TEST_TOKEN); + logManager->GetEventFilters().UnregisterAllFilters(); // inherit diagnostic level from parent (basic) - auto logger1 = LogManager::GetLogger(); + auto logger1 = logManager->GetLogger(TEST_TOKEN); // set diagnostic level to optional - auto logger2 = LogManager::GetLogger(TEST_TOKEN, "my_optional_source"); + auto logger2 = logManager->GetLogger(TEST_TOKEN, "my_optional_source"); logger2->SetLevel(DIAG_LEVEL_OPTIONAL); // set diagnostic level to a custom value - auto logger3 = LogManager::GetLogger("my_custom_source"); + auto logger3 = logManager->GetLogger("my_custom_source"); logger3->SetLevel(5); std::set logNone = { DIAG_LEVEL_NONE }; @@ -1289,14 +1283,14 @@ TEST(APITest, LogManager_DiagLevels) size_t expectedCounts[] = { 12, 0, 8 }; - addAllListeners(eventListener); + addAllListeners(*logManager, eventListener); // Filter test size_t i = 0; for (auto filter : filters) { // Specify diagnostic level filter - LogManager::SetLevelFilter(DIAG_LEVEL_DEFAULT, filter); + logManager->SetLevelFilter(DIAG_LEVEL_DEFAULT, filter); for (auto logger : { logger0, logger1, logger2, logger3 }) { EventProperties defLevelEvent("My.DefaultLevelEvent"); @@ -1314,14 +1308,12 @@ TEST(APITest, LogManager_DiagLevels) eventListener.numFiltered = 0; i++; } - removeAllListeners(eventListener); - LogManager::FlushAndTeardown(); } TEST(APITest, Pii_Kind_E2E_Test) { - auto& config = LogManager::GetLogConfiguration(); - LogManager::Initialize(TEST_TOKEN, config); + ILogConfiguration config; + auto logManager = LogManagerProvider::CreateLogManager(config); // Log detailed event with various properties EventProperties detailed_event("MyApp.DetailedEvent.Pii", { @@ -1354,10 +1346,10 @@ TEST(APITest, Pii_Kind_E2E_Test) { "guidKey2", GUID_t("00010203-0405-0607-0809-0A0B0C0D0E0F") }, { "timeKey1", time_ticks_t((uint64_t)0) }, // time in .NET ticks }); - auto logger = LogManager::GetLogger(); + auto logger = logManager->GetLogger(TEST_TOKEN); EXPECT_NE(logger, nullptr); logger->LogEvent(detailed_event); - LogManager::FlushAndTeardown(); + // Verify that contents get hashed by server } @@ -1438,17 +1430,18 @@ CustomDecorator myDecorator; TEST(APITest, Custom_Decorator) { - auto& config = LogManager::GetLogConfiguration(); + ILogConfiguration config; config.AddModule(CFG_MODULE_DECORATOR, std::make_shared(myDecorator) ); - LogManager::Initialize(TEST_TOKEN, config); - LogManager::GetLogger()->LogEvent("foobar"); + auto logManager = LogManagerProvider::CreateLogManager(config); + auto logger = logManager->GetLogger(TEST_TOKEN); + logger->LogEvent("foobar"); EventProperties myEvent2("MyEvent.With.Props", { {"keyString", "Hello World!"}, {"keyGuid", GUID_t("{76ce7649-3a58-4861-8202-7d7fdfaed483}")} }); - LogManager::GetLogger()->LogEvent(myEvent2); - LogManager::FlushAndTeardown(); + logger->LogEvent(myEvent2); + logManager->FlushAndTeardown(); // In-lieu of RemoveModule(...) the current solution is to set the module to nullptr. // This is functionally nearly equivalent to unsetting it since GetModule(CFG_MODULE_DECORATOR) // for non-existing module also returns nullptr. diff --git a/tests/functests/BasicFuncTests.cpp b/tests/functests/BasicFuncTests.cpp index 8225edd61..4f5753b40 100644 --- a/tests/functests/BasicFuncTests.cpp +++ b/tests/functests/BasicFuncTests.cpp @@ -70,26 +70,6 @@ namespace PAL_NS_BEGIN } PAL_NS_END; -namespace MAT_NS_BEGIN -{ - class ModuleA : public ILogConfiguration - { - }; - class LogManagerA : public LogManagerBase - { - }; - class ModuleB : public ILogConfiguration - { - }; - class LogManagerB : public LogManagerBase - { - }; - // Two distinct LogManagerX 'singelton' instances - DEFINE_LOGMANAGER(LogManagerB, ModuleB); - DEFINE_LOGMANAGER(LogManagerA, ModuleA); -} -MAT_NS_END - char const* const TEST_STORAGE_FILENAME = "BasicFuncTests.db"; // 1DSCppSdktest sandbox key @@ -131,6 +111,9 @@ class BasicFuncTests : public ::testing::Test, std::string serverAddress; HttpServer server; + ILogConfiguration configuration; + std::unique_ptr logManager; + ILogger* logger; ILogger* logger2; @@ -184,7 +167,7 @@ class BasicFuncTests : public ::testing::Test, virtual void Initialize() { receivedRequests.clear(); - auto configuration = LogManager::GetLogConfiguration(); + configuration = ILogConfiguration{}; configuration[CFG_INT_TRACE_LEVEL_MASK] = 0xFFFFFFFF; #ifdef NDEBUG @@ -205,18 +188,16 @@ class BasicFuncTests : public ::testing::Test, configuration["version"] = "1.0.0"; configuration["config"] = { { "host", __FILE__ } }; // Host instance - LogManager::Initialize(TEST_TOKEN, configuration); - LogManager::SetLevelFilter(DIAG_LEVEL_DEFAULT, { DIAG_LEVEL_DEFAULT_MIN, DIAG_LEVEL_DEFAULT_MAX }); - LogManager::ResumeTransmission(); + logManager = LogManagerProvider::CreateLogManager(configuration); + logManager->SetLevelFilter(DIAG_LEVEL_DEFAULT, { DIAG_LEVEL_DEFAULT_MIN, DIAG_LEVEL_DEFAULT_MAX }); - logger = LogManager::GetLogger(TEST_TOKEN, "source1"); - logger2 = LogManager::GetLogger(TEST_TOKEN, "source2"); + logger = logManager->GetLogger(TEST_TOKEN, "source1"); + logger2 = logManager->GetLogger(TEST_TOKEN, "source2"); } virtual void FlushAndTeardown() { - LogManager::Flush(); - LogManager::FlushAndTeardown(); + logManager->FlushAndTeardown(); } virtual int onHttpRequest(HttpServer::Request const& request, HttpServer::Response& response) override @@ -547,7 +528,7 @@ TEST_F(BasicFuncTests, sendOneEvent_immediatelyStop) EventProperties event("first_event"); event.SetProperty("property", "value"); logger->LogEvent(event); - LogManager::UploadNow(); + logManager->UploadNow(); PAL::sleep(500); // for a certain value of immediately FlushAndTeardown(); EXPECT_GE(receivedRequests.size(), (size_t)1); // at least 1 HTTP request with customer payload and stats @@ -562,7 +543,7 @@ TEST_F(BasicFuncTests, sendNoPriorityEvents) - public MAT::exporters::DecodeRequest(...) via debug callback */ HttpPostListener listener; - LogManager::AddEventListener(EVT_HTTP_OK, listener); + logManager->AddEventListener(EVT_HTTP_OK, listener); EventProperties event("first_event"); event.SetProperty("property", "value"); @@ -573,10 +554,10 @@ TEST_F(BasicFuncTests, sendNoPriorityEvents) event2.SetProperty("property2", "another value"); logger->LogEvent(event2); - LogManager::UploadNow(); + logManager->UploadNow(); waitForEvents(1, 3); EXPECT_GE(receivedRequests.size(), (size_t)1); - LogManager::RemoveEventListener(EVT_HTTP_OK, listener); + logManager->RemoveEventListener(EVT_HTTP_OK, listener); FlushAndTeardown(); if (receivedRequests.size() >= 1) @@ -671,7 +652,7 @@ TEST_F(BasicFuncTests, sendDifferentPriorityEvents) logger->LogEvent(event2); - LogManager::UploadNow(); + logManager->UploadNow(); // 2 x customer events + 1 x evt_stats on start waitForEvents(1, 3); @@ -718,7 +699,7 @@ TEST_F(BasicFuncTests, sendMultipleTenantsTogether) logger2->LogEvent(event2); - LogManager::UploadNow(); + logManager->UploadNow(); // 2 x customer events + 1 x evt_stats on start waitForEvents(1, 3); @@ -748,7 +729,7 @@ TEST_F(BasicFuncTests, configDecorations) EventProperties event4("4th_event"); logger->LogEvent(event4); - LogManager::UploadNow(); + logManager->UploadNow(); waitForEvents(2, 5); for (const auto &evt : { event1, event2, event3, event4 }) @@ -765,7 +746,7 @@ TEST_F(BasicFuncTests, restartRecoversEventsFromStorage) CleanStorage(); Initialize(); // This code is a bit racy because ResumeTransmission is done in Initialize - LogManager::PauseTransmission(); + // logManager->PauseTransmission(); EventProperties event1("first_event"); EventProperties event2("second_event"); event1.SetProperty("property1", "value1"); @@ -776,6 +757,7 @@ TEST_F(BasicFuncTests, restartRecoversEventsFromStorage) event2.SetPersistence(MAT::EventPersistence::EventPersistence_Critical); logger->LogEvent(event1); logger->LogEvent(event2); + logManager->Flush(); FlushAndTeardown(); } @@ -784,8 +766,10 @@ TEST_F(BasicFuncTests, restartRecoversEventsFromStorage) EventProperties fooEvent("fooEvent"); fooEvent.SetLatency(EventLatency_RealTime); fooEvent.SetPersistence(EventPersistence_Critical); - LogManager::GetLogger()->LogEvent(fooEvent); - LogManager::UploadNow(); + + logger->LogEvent(fooEvent); + + logManager->UploadNow(); // 1st request for realtime event waitForEvents(3, 5); // start, first_event, second_event, ongoing, stop, start, fooEvent @@ -879,7 +863,7 @@ TEST_F(BasicFuncTests, sendMetaStatsOnStart) CleanStorage(); // Run offline Initialize(); - LogManager::PauseTransmission(); + logManager->PauseTransmission(); EventProperties event1("first_event"); event1.SetPriority(EventPriority_High); @@ -889,6 +873,7 @@ TEST_F(BasicFuncTests, sendMetaStatsOnStart) EventProperties event2("second_event"); event2.SetProperty("property2", "value2"); logger->LogEvent(event2); + logManager->Flush(); FlushAndTeardown(); auto r1 = records(); @@ -896,8 +881,8 @@ TEST_F(BasicFuncTests, sendMetaStatsOnStart) // Check Initialize(); - LogManager::ResumeTransmission(); // ? - LogManager::UploadNow(); + logManager->ResumeTransmission(); // ? + logManager->UploadNow(); PAL::sleep(2000); auto r2 = records(); @@ -915,7 +900,7 @@ TEST_F(BasicFuncTests, DiagLevelRequiredOnly_OneEventWithoutLevelOneWithButNotAl { CleanStorage(); Initialize(); - LogManager::SetLevelFilter(DIAG_LEVEL_OPTIONAL, { DIAG_LEVEL_REQUIRED }); + logManager->SetLevelFilter(DIAG_LEVEL_OPTIONAL, { DIAG_LEVEL_REQUIRED }); EventProperties eventWithoutLevel("EventWithoutLevel"); logger->LogEvent(eventWithoutLevel); @@ -927,7 +912,7 @@ TEST_F(BasicFuncTests, DiagLevelRequiredOnly_OneEventWithoutLevelOneWithButNotAl eventWithAllowedLevel.SetLevel(DIAG_LEVEL_REQUIRED); logger->LogEvent(eventWithAllowedLevel); - LogManager::UploadNow(); + logManager->UploadNow(); waitForEvents(1 /*timeout*/, 2 /*expected count*/); // Start and EventWithAllowedLevel ASSERT_EQ(records().size(), static_cast(2)); // Start and EventWithAllowedLevel @@ -964,13 +949,13 @@ TEST_F(BasicFuncTests, DiagLevelRequiredOnly_SendTwoEventsUpdateAllowedLevelsSen CleanStorage(); Initialize(); - LogManager::SetLevelFilter(DIAG_LEVEL_OPTIONAL, { DIAG_LEVEL_REQUIRED }); + logManager->SetLevelFilter(DIAG_LEVEL_OPTIONAL, { DIAG_LEVEL_REQUIRED }); SendEventWithOptionalThenRequired(logger); - LogManager::SetLevelFilter(DIAG_LEVEL_OPTIONAL, { DIAG_LEVEL_OPTIONAL, DIAG_LEVEL_REQUIRED }); + logManager->SetLevelFilter(DIAG_LEVEL_OPTIONAL, { DIAG_LEVEL_OPTIONAL, DIAG_LEVEL_REQUIRED }); SendEventWithOptionalThenRequired(logger); - LogManager::UploadNow(); + logManager->UploadNow(); waitForEvents(2 /*timeout*/, 4 /*expected count*/); // Start and EventWithAllowedLevel auto sentRecords = records(); @@ -1102,60 +1087,60 @@ public : } }; -void addListeners(DebugEventListener &listener) { - LogManager::AddEventListener(DebugEventType::EVT_LOG_SESSION, listener); - LogManager::AddEventListener(DebugEventType::EVT_REJECTED, listener); - LogManager::AddEventListener(DebugEventType::EVT_SENT, listener); - LogManager::AddEventListener(DebugEventType::EVT_DROPPED, listener); - LogManager::AddEventListener(DebugEventType::EVT_HTTP_OK, listener); - LogManager::AddEventListener(DebugEventType::EVT_HTTP_ERROR, listener); - LogManager::AddEventListener(DebugEventType::EVT_HTTP_FAILURE, listener); - LogManager::AddEventListener(DebugEventType::EVT_CACHED, listener); +void addListeners(ILogManager& logManager, DebugEventListener &listener) { + logManager.AddEventListener(DebugEventType::EVT_LOG_SESSION, listener); + logManager.AddEventListener(DebugEventType::EVT_REJECTED, listener); + logManager.AddEventListener(DebugEventType::EVT_SENT, listener); + logManager.AddEventListener(DebugEventType::EVT_DROPPED, listener); + logManager.AddEventListener(DebugEventType::EVT_HTTP_OK, listener); + logManager.AddEventListener(DebugEventType::EVT_HTTP_ERROR, listener); + logManager.AddEventListener(DebugEventType::EVT_HTTP_FAILURE, listener); + logManager.AddEventListener(DebugEventType::EVT_CACHED, listener); } -void removeListeners(DebugEventListener &listener) { - LogManager::RemoveEventListener(DebugEventType::EVT_LOG_SESSION, listener); - LogManager::RemoveEventListener(DebugEventType::EVT_REJECTED, listener); - LogManager::RemoveEventListener(DebugEventType::EVT_SENT, listener); - LogManager::RemoveEventListener(DebugEventType::EVT_DROPPED, listener); - LogManager::RemoveEventListener(DebugEventType::EVT_HTTP_OK, listener); - LogManager::RemoveEventListener(DebugEventType::EVT_HTTP_ERROR, listener); - LogManager::RemoveEventListener(DebugEventType::EVT_HTTP_FAILURE, listener); - LogManager::RemoveEventListener(DebugEventType::EVT_CACHED, listener); +void removeListeners(ILogManager& logManager, DebugEventListener &listener) { + logManager.RemoveEventListener(DebugEventType::EVT_LOG_SESSION, listener); + logManager.RemoveEventListener(DebugEventType::EVT_REJECTED, listener); + logManager.RemoveEventListener(DebugEventType::EVT_SENT, listener); + logManager.RemoveEventListener(DebugEventType::EVT_DROPPED, listener); + logManager.RemoveEventListener(DebugEventType::EVT_HTTP_OK, listener); + logManager.RemoveEventListener(DebugEventType::EVT_HTTP_ERROR, listener); + logManager.RemoveEventListener(DebugEventType::EVT_HTTP_FAILURE, listener); + logManager.RemoveEventListener(DebugEventType::EVT_CACHED, listener); } TEST_F(BasicFuncTests, killSwitchWorks) { CleanStorage(); // Create the configuration to send to fake server - auto configuration = LogManager::GetLogConfiguration(); + ILogConfiguration myConfiguration; - configuration[CFG_INT_TRACE_LEVEL_MASK] = 0xFFFFFFFF; - configuration[CFG_INT_TRACE_LEVEL_MIN] = ACTTraceLevel_Warn; - configuration[CFG_INT_SDK_MODE] = SdkModeTypes::SdkModeTypes_CS; + myConfiguration[CFG_INT_TRACE_LEVEL_MASK] = 0xFFFFFFFF; + myConfiguration[CFG_INT_TRACE_LEVEL_MIN] = ACTTraceLevel_Warn; + myConfiguration[CFG_INT_SDK_MODE] = SdkModeTypes::SdkModeTypes_CS; - configuration[CFG_INT_RAM_QUEUE_SIZE] = 4096 * 20; - configuration[CFG_STR_CACHE_FILE_PATH] = TEST_STORAGE_FILENAME; - configuration[CFG_INT_MAX_TEARDOWN_TIME] = 2; // 2 seconds wait on shutdown - configuration[CFG_STR_COLLECTOR_URL] = serverAddress.c_str(); - configuration[CFG_MAP_HTTP][CFG_BOOL_HTTP_COMPRESSION] = false; // disable compression for now - configuration[CFG_MAP_METASTATS_CONFIG]["interval"] = 30 * 60; // 30 mins + myConfiguration[CFG_INT_RAM_QUEUE_SIZE] = 4096 * 20; + myConfiguration[CFG_STR_CACHE_FILE_PATH] = TEST_STORAGE_FILENAME; + myConfiguration[CFG_INT_MAX_TEARDOWN_TIME] = 2; // 2 seconds wait on shutdown + myConfiguration[CFG_STR_COLLECTOR_URL] = serverAddress.c_str(); + myConfiguration[CFG_MAP_HTTP][CFG_BOOL_HTTP_COMPRESSION] = false; // disable compression for now + myConfiguration[CFG_MAP_METASTATS_CONFIG]["interval"] = 30 * 60; // 30 mins - configuration["name"] = __FILE__; - configuration["version"] = "1.0.0"; - configuration["config"] = { { "host", __FILE__ } }; // Host instance + myConfiguration["name"] = __FILE__; + myConfiguration["version"] = "1.0.0"; + myConfiguration["config"] = { { "host", __FILE__ } }; // Host instance // set the killed token on the server server.setKilledToken(KILLED_TOKEN, 6384); KillSwitchListener listener; - addListeners(listener); + + auto myLogManager = LogManagerProvider::CreateLogManager(myConfiguration); + addListeners(*myLogManager, listener); // Log 100 events from valid and invalid 4 times int repetitions = 4; for (int i = 0; i < repetitions; i++) { // Initialize the logger for the valid token and log 100 events - LogManager::Initialize(TEST_TOKEN, configuration); - LogManager::ResumeTransmission(); - auto myLogger = LogManager::GetLogger(TEST_TOKEN, "killed"); + auto myLogger = myLogManager->GetLogger(TEST_TOKEN, "killed"); int numIterations = 100; while (numIterations--) { EventProperties event1("fooEvent"); @@ -1163,9 +1148,8 @@ TEST_F(BasicFuncTests, killSwitchWorks) myLogger->LogEvent(event1); } // Initialize the logger for the killed token and log 100 events - LogManager::Initialize(KILLED_TOKEN, configuration); - LogManager::ResumeTransmission(); - myLogger = LogManager::GetLogger(KILLED_TOKEN, "killed"); + myLogManager->ResumeTransmission(); + myLogger = myLogManager->GetLogger(KILLED_TOKEN, "killed"); numIterations = 100; while (numIterations--) { EventProperties event2("failEvent"); @@ -1174,13 +1158,12 @@ TEST_F(BasicFuncTests, killSwitchWorks) } } // Try to upload and wait for 2 seconds to complete - LogManager::UploadNow(); + myLogManager->UploadNow(); PAL::sleep(2000); // Log 100 events with valid logger - LogManager::Initialize(TEST_TOKEN, configuration); - LogManager::ResumeTransmission(); - auto myLogger = LogManager::GetLogger(TEST_TOKEN, "killed"); + myLogManager->ResumeTransmission(); + auto myLogger = myLogManager->GetLogger(TEST_TOKEN, "killed"); int numIterations = 100; while (numIterations--) { EventProperties event1("fooEvent"); @@ -1188,9 +1171,8 @@ TEST_F(BasicFuncTests, killSwitchWorks) myLogger->LogEvent(event1); } - LogManager::Initialize(KILLED_TOKEN, configuration); - LogManager::ResumeTransmission(); - myLogger = LogManager::GetLogger(KILLED_TOKEN, "killed"); + myLogManager->ResumeTransmission(); + myLogger = myLogManager->GetLogger(KILLED_TOKEN, "killed"); numIterations = 100; while (numIterations--) { EventProperties event2("failEvent"); @@ -1199,10 +1181,9 @@ TEST_F(BasicFuncTests, killSwitchWorks) } // Expect all events to be dropped EXPECT_EQ(uint32_t { 100 }, listener.numDropped); - LogManager::FlushAndTeardown(); - + myLogManager->FlushAndTeardown(); listener.printStats(); - removeListeners(listener); + removeListeners(*myLogManager, listener); server.clearKilledTokens(); } @@ -1210,34 +1191,34 @@ TEST_F(BasicFuncTests, killIsTemporary) { CleanStorage(); // Create the configuration to send to fake server - auto configuration = LogManager::GetLogConfiguration(); + ILogConfiguration myConfiguration; - configuration[CFG_INT_TRACE_LEVEL_MASK] = 0xFFFFFFFF; - configuration[CFG_INT_TRACE_LEVEL_MIN] = ACTTraceLevel_Warn; - configuration[CFG_INT_SDK_MODE] = SdkModeTypes::SdkModeTypes_CS; + myConfiguration[CFG_INT_TRACE_LEVEL_MASK] = 0xFFFFFFFF; + myConfiguration[CFG_INT_TRACE_LEVEL_MIN] = ACTTraceLevel_Warn; + myConfiguration[CFG_INT_SDK_MODE] = SdkModeTypes::SdkModeTypes_CS; - configuration[CFG_INT_RAM_QUEUE_SIZE] = 4096 * 20; - configuration[CFG_STR_CACHE_FILE_PATH] = TEST_STORAGE_FILENAME; - configuration[CFG_INT_MAX_TEARDOWN_TIME] = 2; // 2 seconds wait on shutdown - configuration[CFG_STR_COLLECTOR_URL] = serverAddress.c_str(); - configuration[CFG_MAP_HTTP][CFG_BOOL_HTTP_COMPRESSION] = false; // disable compression for now - configuration[CFG_MAP_METASTATS_CONFIG]["interval"] = 30 * 60; // 30 mins + myConfiguration[CFG_INT_RAM_QUEUE_SIZE] = 4096 * 20; + myConfiguration[CFG_STR_CACHE_FILE_PATH] = TEST_STORAGE_FILENAME; + myConfiguration[CFG_INT_MAX_TEARDOWN_TIME] = 2; // 2 seconds wait on shutdown + myConfiguration[CFG_STR_COLLECTOR_URL] = serverAddress.c_str(); + myConfiguration[CFG_MAP_HTTP][CFG_BOOL_HTTP_COMPRESSION] = false; // disable compression for now + myConfiguration[CFG_MAP_METASTATS_CONFIG]["interval"] = 30 * 60; // 30 mins - configuration["name"] = __FILE__; - configuration["version"] = "1.0.0"; - configuration["config"] = { { "host", __FILE__ } }; // Host instance + myConfiguration["name"] = __FILE__; + myConfiguration["version"] = "1.0.0"; + myConfiguration["config"] = { { "host", __FILE__ } }; // Host instance // set the killed token on the server server.setKilledToken(KILLED_TOKEN, 10); KillSwitchListener listener; - addListeners(listener); + auto myLogManager = LogManagerProvider::CreateLogManager(myConfiguration); + addListeners(*myLogManager, listener); // Log 100 events from valid and invalid 4 times int repetitions = 4; for (int i = 0; i < repetitions; i++) { // Initialize the logger for the valid token and log 100 events - LogManager::Initialize(TEST_TOKEN, configuration); - LogManager::ResumeTransmission(); - auto myLogger = LogManager::GetLogger(TEST_TOKEN, "killed"); + myLogManager->ResumeTransmission(); + auto myLogger = myLogManager->GetLogger(TEST_TOKEN, "killed"); int numIterations = 100; while (numIterations--) { EventProperties event1("fooEvent"); @@ -1245,9 +1226,8 @@ TEST_F(BasicFuncTests, killIsTemporary) myLogger->LogEvent(event1); } // Initialize the logger for the killed token and log 100 events - LogManager::Initialize(KILLED_TOKEN, configuration); - LogManager::ResumeTransmission(); - myLogger = LogManager::GetLogger(KILLED_TOKEN, "killed"); + myLogManager->ResumeTransmission(); + myLogger = myLogManager->GetLogger(KILLED_TOKEN, "killed"); numIterations = 100; while (numIterations--) { EventProperties event2("failEvent"); @@ -1256,15 +1236,15 @@ TEST_F(BasicFuncTests, killIsTemporary) } } // Try and wait to upload - LogManager::UploadNow(); + myLogManager->UploadNow(); PAL::sleep(2000); // Sleep for 11 seconds so the killed time has expired, clear the killed tokens on server PAL::sleep(11000); server.clearKilledTokens(); // Log 100 events with valid logger - LogManager::Initialize(TEST_TOKEN, configuration); - LogManager::ResumeTransmission(); - auto myLogger = LogManager::GetLogger(TEST_TOKEN, "killed"); + myLogManager->ResumeTransmission(); + auto myLogger = myLogManager->GetLogger(TEST_TOKEN, "killed"); + int numIterations = 100; while (numIterations--) { EventProperties event1("fooEvent"); @@ -1272,9 +1252,9 @@ TEST_F(BasicFuncTests, killIsTemporary) myLogger->LogEvent(event1); } - LogManager::Initialize(KILLED_TOKEN, configuration); - LogManager::ResumeTransmission(); - myLogger = LogManager::GetLogger(KILLED_TOKEN, "killed"); + myLogManager->ResumeTransmission(); + myLogger = myLogManager->GetLogger(KILLED_TOKEN, "killed"); + numIterations = 100; while (numIterations--) { EventProperties event2("failEvent"); @@ -1283,10 +1263,10 @@ TEST_F(BasicFuncTests, killIsTemporary) } // Expect to 0 events to be dropped EXPECT_EQ(uint32_t { 0 }, listener.numDropped); - LogManager::FlushAndTeardown(); + myLogManager->FlushAndTeardown(); listener.printStats(); - removeListeners(listener); + removeListeners(*myLogManager, listener); server.clearKilledTokens(); } @@ -1297,29 +1277,30 @@ TEST_F(BasicFuncTests, sendManyRequestsAndCancel) CleanStorage(); RequestMonitor listener; - auto eventsList = { - DebugEventType::EVT_HTTP_OK, - DebugEventType::EVT_HTTP_ERROR, - DebugEventType::EVT_HTTP_FAILURE - }; - // Add event listeners - for (auto evt : eventsList) - { - LogManager::AddEventListener(evt, listener); - } - for (size_t i = 0; i < 20; i++) { - auto &configuration = LogManager::GetLogConfiguration(); - configuration[CFG_INT_RAM_QUEUE_SIZE] = 4096 * 20; - configuration[CFG_STR_CACHE_FILE_PATH] = TEST_STORAGE_FILENAME; - configuration[CFG_MAP_HTTP][CFG_BOOL_HTTP_COMPRESSION] = true; - configuration[CFG_STR_COLLECTOR_URL] = COLLECTOR_URL_PROD; - configuration[CFG_INT_MAX_TEARDOWN_TIME] = (int64_t)(i % 2); - configuration[CFG_INT_TRACE_LEVEL_MASK] = 0; - configuration[CFG_INT_TRACE_LEVEL_MIN] = ACTTraceLevel_Warn; - LogManager::Initialize(TEST_TOKEN); - auto myLogger = LogManager::GetLogger(); + ILogConfiguration myConfiguration; + myConfiguration[CFG_INT_RAM_QUEUE_SIZE] = 4096 * 20; + myConfiguration[CFG_STR_CACHE_FILE_PATH] = TEST_STORAGE_FILENAME; + myConfiguration[CFG_MAP_HTTP][CFG_BOOL_HTTP_COMPRESSION] = true; + myConfiguration[CFG_STR_COLLECTOR_URL] = COLLECTOR_URL_PROD; + myConfiguration[CFG_INT_MAX_TEARDOWN_TIME] = (int64_t)(i % 2); + myConfiguration[CFG_INT_TRACE_LEVEL_MASK] = 0; + myConfiguration[CFG_INT_TRACE_LEVEL_MIN] = ACTTraceLevel_Warn; + auto myLogManager = LogManagerProvider::CreateLogManager(myConfiguration); + + auto eventsList = { + DebugEventType::EVT_HTTP_OK, + DebugEventType::EVT_HTTP_ERROR, + DebugEventType::EVT_HTTP_FAILURE + }; + // Add event listeners + for (auto evt : eventsList) + { + myLogManager->AddEventListener(evt, listener); + } + + auto myLogger = myLogManager->GetLogger(TEST_TOKEN); for (size_t j = 0; j < 200; j++) { EventProperties myEvent1("sample_realtime"); @@ -1330,7 +1311,7 @@ TEST_F(BasicFuncTests, sendManyRequestsAndCancel) myLogger->LogEvent(myEvent2); } // force upload - LogManager::UploadNow(); + myLogManager->UploadNow(); if ((i % 3) == 0) { PAL::sleep(100); @@ -1343,15 +1324,9 @@ TEST_F(BasicFuncTests, sendManyRequestsAndCancel) std::this_thread::yield(); } } - LogManager::FlushAndTeardown(); } listener.dump(); - // Remove event listeners - for (auto evt : eventsList) - { - LogManager::RemoveEventListener(evt, listener); - } } #define MAX_TEST_RETRIES 10 @@ -1360,6 +1335,37 @@ TEST_F(BasicFuncTests, raceBetweenUploadAndShutdownMultipleLogManagers) { CleanStorage(); + std::unique_ptr logManagerA, logManagerB; + + // string values in ILogConfiguration must stay immutable for the duration of the run + ILogConfiguration aConfiguration, bConfiguration; + { // LogManager A + aConfiguration[CFG_INT_RAM_QUEUE_SIZE] = 4096 * 20; + aConfiguration[CFG_STR_CACHE_FILE_PATH] = TEST_STORAGE_FILENAME; + aConfiguration[CFG_MAP_HTTP][CFG_BOOL_HTTP_COMPRESSION] = true; + aConfiguration[CFG_STR_COLLECTOR_URL] = COLLECTOR_URL_PROD; + aConfiguration[CFG_INT_MAX_TEARDOWN_TIME] = 1; + aConfiguration[CFG_INT_TRACE_LEVEL_MASK] = 0; + aConfiguration["name"] = "LogManagerA"; + aConfiguration["version"] = "1.0.0"; + aConfiguration["config"]["host"] = "LogManagerA"; + logManagerA = LogManagerProvider::CreateLogManager(aConfiguration); + EXPECT_EQ(PAL::PALTest::GetPalRefCount(), 1); + } + { // LogManager B + bConfiguration[CFG_INT_RAM_QUEUE_SIZE] = 4096 * 20; + bConfiguration[CFG_STR_CACHE_FILE_PATH] = TEST_STORAGE_FILENAME; + bConfiguration[CFG_MAP_HTTP][CFG_BOOL_HTTP_COMPRESSION] = true; + bConfiguration[CFG_STR_COLLECTOR_URL] = COLLECTOR_URL_PROD; + bConfiguration[CFG_INT_MAX_TEARDOWN_TIME] = 1; + bConfiguration[CFG_INT_TRACE_LEVEL_MASK] = 0; + bConfiguration["name"] = "LogManagerB"; + bConfiguration["version"] = "1.0.0"; + bConfiguration["config"]["host"] = "LogManagerB"; + logManagerB = LogManagerProvider::CreateLogManager(bConfiguration); + EXPECT_EQ(PAL::PALTest::GetPalRefCount(), 2); + } + RequestMonitor listener; auto eventsList = { DebugEventType::EVT_HTTP_OK, @@ -1368,36 +1374,10 @@ TEST_F(BasicFuncTests, raceBetweenUploadAndShutdownMultipleLogManagers) // Add event listeners for (auto evt : eventsList) { - LogManagerA::AddEventListener(evt, listener); - LogManagerB::AddEventListener(evt, listener); + logManagerA->AddEventListener(evt, listener); + logManagerB->AddEventListener(evt, listener); }; - // string values in ILogConfiguration must stay immutable for the duration of the run - { // LogManager A - auto& configuration = LogManagerA::GetLogConfiguration(); - configuration[CFG_INT_RAM_QUEUE_SIZE] = 4096 * 20; - configuration[CFG_STR_CACHE_FILE_PATH] = TEST_STORAGE_FILENAME; - configuration[CFG_MAP_HTTP][CFG_BOOL_HTTP_COMPRESSION] = true; - configuration[CFG_STR_COLLECTOR_URL] = COLLECTOR_URL_PROD; - configuration[CFG_INT_MAX_TEARDOWN_TIME] = 1; - configuration[CFG_INT_TRACE_LEVEL_MASK] = 0; - configuration["name"] = "LogManagerA"; - configuration["version"] = "1.0.0"; - configuration["config"]["host"] = "LogManagerA"; - } - { // LogManager B - auto& configuration = LogManagerB::GetLogConfiguration(); - configuration[CFG_INT_RAM_QUEUE_SIZE] = 4096 * 20; - configuration[CFG_STR_CACHE_FILE_PATH] = TEST_STORAGE_FILENAME; - configuration[CFG_MAP_HTTP][CFG_BOOL_HTTP_COMPRESSION] = true; - configuration[CFG_STR_COLLECTOR_URL] = COLLECTOR_URL_PROD; - configuration[CFG_INT_MAX_TEARDOWN_TIME] = 1; - configuration[CFG_INT_TRACE_LEVEL_MASK] = 0; - configuration["name"] = "LogManagerB"; - configuration["version"] = "1.0.0"; - configuration["config"]["host"] = "LogManagerB"; - } - std::atomic testRunning(true); auto t = std::thread([&]() { while (testRunning) @@ -1405,32 +1385,31 @@ TEST_F(BasicFuncTests, raceBetweenUploadAndShutdownMultipleLogManagers) // Abuse LogManagerA and LogManagerB badly. // Both may or may not have a valid implementation instance. // PAL could be dead while this abuse is happening. - LogManagerA::UploadNow(); - LogManagerB::UploadNow(); + logManagerA->UploadNow(); + logManagerB->UploadNow(); } }); for (size_t i = 0; i < MAX_TEST_RETRIES; i++) { - auto loggerA = LogManagerA::Initialize(TEST_TOKEN); - EXPECT_EQ(PAL::PALTest::GetPalRefCount(), 1); - - auto loggerB = LogManagerB::Initialize(TEST_TOKEN); - EXPECT_EQ(PAL::PALTest::GetPalRefCount(), 2); + logManagerA = LogManagerProvider::CreateLogManager(aConfiguration); + logManagerB = LogManagerProvider::CreateLogManager(bConfiguration); + auto loggerA = logManagerA->GetLogger(TEST_TOKEN); + auto loggerB = logManagerB->GetLogger(TEST_TOKEN); EventProperties evtCritical("BasicFuncTests.stress_test_critical_A"); evtCritical.SetPriority(EventPriority_Immediate); evtCritical.SetPolicyBitFlags(MICROSOFT_EVENTTAG_CORE_DATA | MICROSOFT_EVENTTAG_REALTIME_LATENCY | MICROSOFT_KEYWORD_CRITICAL_DATA); loggerA->LogEvent("BasicFuncTests.stress_test_A"); - LogManagerA::UploadNow(); + logManagerA->UploadNow(); loggerB->LogEvent("BasicFuncTests.stress_test_B"); - LogManagerB::UploadNow(); + logManagerB->UploadNow(); - EXPECT_EQ(LogManagerB::FlushAndTeardown(), STATUS_SUCCESS); + EXPECT_NO_THROW(logManagerB->FlushAndTeardown()); EXPECT_EQ(PAL::PALTest::GetPalRefCount(), 1); - EXPECT_EQ(LogManagerA::FlushAndTeardown(), STATUS_SUCCESS); + EXPECT_NO_THROW(logManagerA->FlushAndTeardown()); EXPECT_EQ(PAL::PALTest::GetPalRefCount(), 0); } @@ -1439,7 +1418,7 @@ TEST_F(BasicFuncTests, raceBetweenUploadAndShutdownMultipleLogManagers) { t.join(); } - catch (std::exception) + catch (const std::exception&) { // catch exception if can't join because the thread is already gone }; @@ -1447,26 +1426,26 @@ TEST_F(BasicFuncTests, raceBetweenUploadAndShutdownMultipleLogManagers) // Remove event listeners for (auto evt : eventsList) { - LogManagerB::RemoveEventListener(evt, listener); - LogManagerA::RemoveEventListener(evt, listener); + logManagerB->RemoveEventListener(evt, listener); + logManagerA->RemoveEventListener(evt, listener); } CleanStorage(); } #endif -TEST_F(BasicFuncTests, logManager_getLogManagerInstance_uninitializedReturnsNull) -{ - auto lm = LogManager::GetInstance(); - EXPECT_EQ(lm,nullptr); -} +//TEST_F(BasicFuncTests, logManager_getLogManagerInstance_uninitializedReturnsNull) +//{ +// auto lm = LogManager::GetInstance(); +// EXPECT_EQ(lm,nullptr); +//} -TEST_F(BasicFuncTests, logManager_getLogManagerInstance_initializedReturnsNonnull) -{ - LogManager::Initialize(); - auto lm = LogManager::GetInstance(); - EXPECT_NE(lm,nullptr); - LogManager::FlushAndTeardown(); -} +//TEST_F(BasicFuncTests, logManager_getLogManagerInstance_initializedReturnsNonnull) +//{ +// LogManager::Initialize(); +// auto lm = LogManager::GetInstance(); +// EXPECT_NE(lm,nullptr); +// LogManager::FlushAndTeardown(); +//} #ifndef ANDROID TEST_F(BasicFuncTests, deleteEvents) @@ -1478,7 +1457,7 @@ TEST_F(BasicFuncTests, deleteEvents) size_t iteration = 0; // pause the transmission so events get collected in storage - LogManager::PauseTransmission(); + logManager->PauseTransmission(); std::string eventset1 = "EventSet1_"; std::vector events1; while ( iteration++ < max_events ) @@ -1490,9 +1469,9 @@ TEST_F(BasicFuncTests, deleteEvents) events1.push_back(event); logger->LogEvent(event); } - LogManager::DeleteData(); - LogManager::ResumeTransmission(); - LogManager::UploadNow(); //forc upload if something is there in local storage + logManager->DeleteData(); + logManager->ResumeTransmission(); + logManager->UploadNow(); //force upload if something is there in local storage PAL::sleep(2000) ; //wait for some time. for (auto &e: events1) { ASSERT_EQ(find(e.GetName()).name, ""); @@ -1511,7 +1490,7 @@ TEST_F(BasicFuncTests, deleteEvents) events2.push_back(event); logger->LogEvent(event); } - LogManager::UploadNow(); //forc upload if something is there in local storage + logManager->UploadNow(); //forc upload if something is there in local storage waitForEvents(3 /*timeout*/, max_events /*expected count*/); for (auto &e: events2) { verifyEvent(e, find(e.GetName())); diff --git a/tests/functests/BondDecoderTests.cpp b/tests/functests/BondDecoderTests.cpp index e60f10092..6da29c744 100644 --- a/tests/functests/BondDecoderTests.cpp +++ b/tests/functests/BondDecoderTests.cpp @@ -78,30 +78,35 @@ void SendEvents(ILogger* pLogger, uint8_t eventCount, std::chrono::milliseconds TEST(BondDecoderTests, BasicTest) { - EventDecoderListener eventDecoderListener; + // Set config settings + ILogConfiguration config; + Configure(config); + auto logManager = LogManagerProvider::CreateLogManager(config); + EventDecoderListener eventDecoderListener { *logManager }; + // Register listeners for HTTP OK and ERROR const auto dbgEvents = { EVT_HTTP_OK, EVT_HTTP_ERROR }; for (const auto& dbgEvt : dbgEvents) { - LogManager::AddEventListener(dbgEvt, eventDecoderListener); + logManager->AddEventListener(dbgEvt, eventDecoderListener); } // Set config settings Configure(LogManager::GetLogConfiguration()); // Obtains default primary logger - auto pLogger = LogManager::Initialize(TOKEN); + auto pLogger = logManager->GetLogger(TOKEN); // Send 10 events with 50ms delay SendEvents(pLogger, 10, std::chrono::milliseconds(50)); // Trigger upload on shutdown - LogManager::FlushAndTeardown(); + logManager->FlushAndTeardown(); // Unregister listeners for (const auto& dbgEvt : dbgEvents) { - LogManager::RemoveEventListener(dbgEvt, eventDecoderListener); + logManager->RemoveEventListener(dbgEvt, eventDecoderListener); } } diff --git a/tests/functests/EventDecoderListener.cpp b/tests/functests/EventDecoderListener.cpp index ab1e6ee23..296fbf2ed 100644 --- a/tests/functests/EventDecoderListener.cpp +++ b/tests/functests/EventDecoderListener.cpp @@ -129,7 +129,7 @@ void EventDecoderListener::OnDebugEvent(DebugEvent &evt) if (evt.param1 >= 75) { // UploadNow must NEVER EVER be called from Aria callback thread, so either use this structure below // or notify the main app that it has to do the profile timers housekeeping / force the upload... - std::thread([]() { LogManager::UploadNow(); }).detach(); + std::thread([&]() { parent.UploadNow(); }).detach(); } break; diff --git a/tests/functests/EventDecoderListener.hpp b/tests/functests/EventDecoderListener.hpp index 0f7c66d4e..90fd462d8 100644 --- a/tests/functests/EventDecoderListener.hpp +++ b/tests/functests/EventDecoderListener.hpp @@ -9,23 +9,29 @@ #include #include #include +#include +#include #include using namespace MAT; static const constexpr size_t MAX_LATENCY_SAMPLES = 10; -class EventDecoderListener : public DebugEventListener { +class EventDecoderListener : public DebugEventListener +{ std::mutex dbg_callback_mtx; + ILogManager& parent; -public: - EventDecoderListener() : DebugEventListener() + public: + EventDecoderListener(ILogManager& parent) : + DebugEventListener(), + parent(parent) { reset(); } - virtual void DecodeBuffer(void *data, size_t size); - virtual void OnDebugEvent(DebugEvent &evt); + virtual void DecodeBuffer(void* data, size_t size); + virtual void OnDebugEvent(DebugEvent& evt); virtual void reset(); }; diff --git a/tests/functests/MultipleLogManagersTests.cpp b/tests/functests/MultipleLogManagersTests.cpp index b6f2878e7..5e9715df8 100644 --- a/tests/functests/MultipleLogManagersTests.cpp +++ b/tests/functests/MultipleLogManagersTests.cpp @@ -176,9 +176,9 @@ TEST_F(MultipleLogManagersTests, ThreeInstancesCoexist) lm1->SetContext("test1", "abc"); lm2->GetSemanticContext().SetAppId("123"); - ILogger* l1 = lm1->GetLogger("lm1_token1", "aaa-source"); - ILogger* l2 = lm2->GetLogger("lm2_token1", "bbb-source"); - ILogger* l3 = lm3->GetLogger("lm3_token1", "ccc-source"); + auto l1 = lm1->GetLogger("lm1_token1", "aaa-source"); + auto l2 = lm2->GetLogger("lm2_token1", "bbb-source"); + auto l3 = lm3->GetLogger("lm3_token1", "ccc-source"); EventProperties l1_prop("l1a1"); l1_prop.SetProperty("X", "Y"); @@ -213,7 +213,7 @@ TEST_F(MultipleLogManagersTests, MultiProcessesLogManager) config1[CFG_STR_CACHE_FILE_PATH] = testing::GetUniqueDBFileName(); std::unique_ptr lm(LogManagerFactory::Create(config1)); CAPTURE_PERF_STATS("LogManager created"); - ILogger* logger = lm->GetLogger("aaa"); + auto logger = lm->GetLogger("aaa"); CAPTURE_PERF_STATS("Logger created"); size_t numIterations = max_iterations; while (numIterations--) @@ -262,7 +262,7 @@ TEST_F(MultipleLogManagersTests, PrivacyGuardSharedWithTwoInstancesCoexist) lm1->SetDataInspector(privacyGuard); lm2->SetDataInspector(privacyGuard); - ILogger* l2a = lm2->GetLogger("aaa", "aaa-source"); + auto l2a = lm2->GetLogger("aaa", "aaa-source"); EventProperties l2a1p("l2a1"); l2a1p.SetProperty("Field1", "http://www.microsoft.com"); //DataConcernType::Url l2a1p.SetProperty("Field2", "HTTPS://www.microsoft.com"); //DataConcernType::Url @@ -273,7 +273,7 @@ TEST_F(MultipleLogManagersTests, PrivacyGuardSharedWithTwoInstancesCoexist) privacyConcernLogCount = 0; - ILogger* l1a = lm1->GetLogger("aaa"); + auto l1a = lm1->GetLogger("aaa"); EventProperties l1a1p("l1a1"); l1a1p.SetProperty("Field1", "Some%2eone%40Microsoft%2ecom"); //ConcernType::InternalEmailAddress //As happens in escaped URLs l1a1p.SetProperty("Field2", "Someone@Microsoft.com"); //ConcernType::InternalEmailAddress diff --git a/wrappers/obj-c/ODWLogManager.mm b/wrappers/obj-c/ODWLogManager.mm index 127de8dc3..1a444e398 100644 --- a/wrappers/obj-c/ODWLogManager.mm +++ b/wrappers/obj-c/ODWLogManager.mm @@ -73,9 +73,9 @@ +(nullable ODWLogger *)loggerWithTenant:(nonnull NSString *)tenantToken return nil; } - ILogManager* manager = LogManagerProvider::CreateLogManager( + auto manager = LogManagerProvider::CreateLogManager( *wrappedConfig, - status); + status).release(); if (status == status_t::STATUS_SUCCESS && manager != nil) {