From efa496c4cdb8ea540d93ec5b4e95ca8a0f7baee1 Mon Sep 17 00:00:00 2001 From: owent Date: Tue, 24 Dec 2024 15:57:59 +0800 Subject: [PATCH 1/5] Try to fix lifetime of GlobalLogHandler --- .../sdk/common/global_log_handler.h | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/common/global_log_handler.h b/sdk/include/opentelemetry/sdk/common/global_log_handler.h index eadd408762..c33062756b 100644 --- a/sdk/include/opentelemetry/sdk/common/global_log_handler.h +++ b/sdk/include/opentelemetry/sdk/common/global_log_handler.h @@ -142,24 +142,23 @@ OPENTELEMETRY_END_NAMESPACE * To ensure that GlobalLogHandler is the first one to be initialized (and so last to be * destroyed), it is first used inside the constructors of TraceProvider, MeterProvider * and LoggerProvider for debug logging. */ -#define OTEL_INTERNAL_LOG_DISPATCH(level, message, attributes) \ - do \ - { \ - using opentelemetry::sdk::common::internal_log::GlobalLogHandler; \ - using opentelemetry::sdk::common::internal_log::LogHandler; \ - if (level > GlobalLogHandler::GetLogLevel()) \ - { \ - break; \ - } \ - const opentelemetry::nostd::shared_ptr &log_handler = \ - GlobalLogHandler::GetLogHandler(); \ - if (!log_handler) \ - { \ - break; \ - } \ - std::stringstream tmp_stream; \ - tmp_stream << message; \ - log_handler->Handle(level, __FILE__, __LINE__, tmp_stream.str().c_str(), attributes); \ +#define OTEL_INTERNAL_LOG_DISPATCH(level, message, attributes) \ + do \ + { \ + using opentelemetry::sdk::common::internal_log::GlobalLogHandler; \ + using opentelemetry::sdk::common::internal_log::LogHandler; \ + if (level > GlobalLogHandler::GetLogLevel()) \ + { \ + break; \ + } \ + opentelemetry::nostd::shared_ptr log_handler = GlobalLogHandler::GetLogHandler(); \ + if (!log_handler) \ + { \ + break; \ + } \ + std::stringstream tmp_stream; \ + tmp_stream << message; \ + log_handler->Handle(level, __FILE__, __LINE__, tmp_stream.str().c_str(), attributes); \ } while (false); #define OTEL_INTERNAL_LOG_GET_3RD_ARG(arg1, arg2, arg3, ...) arg3 From 1dba9526050dd0aee88b22561e36f084009df435 Mon Sep 17 00:00:00 2001 From: owent Date: Tue, 31 Dec 2024 20:03:13 +0800 Subject: [PATCH 2/5] Ignore global handle when singlethon is destroyed --- .../sdk/common/global_log_handler.h | 41 ++++++++++++++++--- sdk/src/common/global_log_handler.cc | 11 +++-- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/common/global_log_handler.h b/sdk/include/opentelemetry/sdk/common/global_log_handler.h index c33062756b..5ced1ad18e 100644 --- a/sdk/include/opentelemetry/sdk/common/global_log_handler.h +++ b/sdk/include/opentelemetry/sdk/common/global_log_handler.h @@ -93,15 +93,36 @@ class NoopLogHandler : public LogHandler */ class GlobalLogHandler { +private: + struct GlobalLogHandlerData + { + nostd::shared_ptr handler; + LogLevel log_level; + bool destroyed; + + ~GlobalLogHandlerData(); + + GlobalLogHandlerData(const GlobalLogHandlerData &) = delete; + GlobalLogHandlerData(GlobalLogHandlerData &&) = delete; + + GlobalLogHandlerData &operator=(const GlobalLogHandlerData &) = delete; + GlobalLogHandlerData &operator=(GlobalLogHandlerData &&) = delete; + }; + public: /** * Returns the singleton LogHandler. * * By default, a default LogHandler is returned. */ - static inline const nostd::shared_ptr &GetLogHandler() noexcept + static inline nostd::shared_ptr GetLogHandler() noexcept { - return GetHandlerAndLevel().first; + if OPENTELEMETRY_UNLIKELY_CONDITION (GetHandlerAndLevel().destroyed) + { + return nostd::shared_ptr(); + } + + return GetHandlerAndLevel().handler; } /** @@ -111,7 +132,12 @@ class GlobalLogHandler */ static inline void SetLogHandler(const nostd::shared_ptr &eh) noexcept { - GetHandlerAndLevel().first = eh; + if OPENTELEMETRY_UNLIKELY_CONDITION (GetHandlerAndLevel().destroyed) + { + return; + } + + GetHandlerAndLevel().handler = eh; } /** @@ -119,17 +145,20 @@ class GlobalLogHandler * * By default, a default log level is returned. */ - static inline LogLevel GetLogLevel() noexcept { return GetHandlerAndLevel().second; } + static inline LogLevel GetLogLevel() noexcept { return GetHandlerAndLevel().log_level; } /** * Changes the singleton Log level. * This should be called once at the start of application before creating any Provider * instance. */ - static inline void SetLogLevel(LogLevel level) noexcept { GetHandlerAndLevel().second = level; } + static inline void SetLogLevel(LogLevel level) noexcept + { + GetHandlerAndLevel().log_level = level; + } private: - static std::pair, LogLevel> &GetHandlerAndLevel() noexcept; + static GlobalLogHandlerData &GetHandlerAndLevel() noexcept; }; } // namespace internal_log diff --git a/sdk/src/common/global_log_handler.cc b/sdk/src/common/global_log_handler.cc index f60527eee8..741be179ae 100644 --- a/sdk/src/common/global_log_handler.cc +++ b/sdk/src/common/global_log_handler.cc @@ -57,10 +57,15 @@ void NoopLogHandler::Handle(LogLevel, const sdk::common::AttributeMap &) noexcept {} -std::pair, LogLevel> &GlobalLogHandler::GetHandlerAndLevel() noexcept +GlobalLogHandler::GlobalLogHandlerData::~GlobalLogHandlerData() { - static std::pair, LogLevel> handler_and_level{ - nostd::shared_ptr(new DefaultLogHandler), LogLevel::Warning}; + destroyed = true; +} + +GlobalLogHandler::GlobalLogHandlerData &GlobalLogHandler::GetHandlerAndLevel() noexcept +{ + static GlobalLogHandlerData handler_and_level{ + nostd::shared_ptr(new DefaultLogHandler), LogLevel::Warning, false}; return handler_and_level; } From 2bb008b1623c1000f5ecf107f2a5e30594122990 Mon Sep 17 00:00:00 2001 From: owent Date: Tue, 31 Dec 2024 20:17:11 +0800 Subject: [PATCH 3/5] Fix compiling --- .../opentelemetry/sdk/common/global_log_handler.h | 1 + sdk/src/common/global_log_handler.cc | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/common/global_log_handler.h b/sdk/include/opentelemetry/sdk/common/global_log_handler.h index 5ced1ad18e..55cc333d25 100644 --- a/sdk/include/opentelemetry/sdk/common/global_log_handler.h +++ b/sdk/include/opentelemetry/sdk/common/global_log_handler.h @@ -100,6 +100,7 @@ class GlobalLogHandler LogLevel log_level; bool destroyed; + GlobalLogHandlerData(); ~GlobalLogHandlerData(); GlobalLogHandlerData(const GlobalLogHandlerData &) = delete; diff --git a/sdk/src/common/global_log_handler.cc b/sdk/src/common/global_log_handler.cc index 741be179ae..c350667c62 100644 --- a/sdk/src/common/global_log_handler.cc +++ b/sdk/src/common/global_log_handler.cc @@ -57,6 +57,12 @@ void NoopLogHandler::Handle(LogLevel, const sdk::common::AttributeMap &) noexcept {} +GlobalLogHandler::GlobalLogHandlerData::GlobalLogHandlerData() + : handler(nostd::shared_ptr(new DefaultLogHandler)), + log_level(LogLevel::Warning), + destroyed(false) +{} + GlobalLogHandler::GlobalLogHandlerData::~GlobalLogHandlerData() { destroyed = true; @@ -64,8 +70,7 @@ GlobalLogHandler::GlobalLogHandlerData::~GlobalLogHandlerData() GlobalLogHandler::GlobalLogHandlerData &GlobalLogHandler::GetHandlerAndLevel() noexcept { - static GlobalLogHandlerData handler_and_level{ - nostd::shared_ptr(new DefaultLogHandler), LogLevel::Warning, false}; + static GlobalLogHandlerData handler_and_level; return handler_and_level; } From 5ac5e4fe1b4fdbf33701767117f56895ac4896eb Mon Sep 17 00:00:00 2001 From: owent Date: Wed, 15 Jan 2025 23:00:14 +0800 Subject: [PATCH 4/5] Use static variable to check if global log handle is destroyed. --- .../sdk/common/global_log_handler.h | 6 +- sdk/src/common/global_log_handler.cc | 20 +++- sdk/test/common/BUILD | 14 +++ sdk/test/common/CMakeLists.txt | 1 + ...obal_log_handle_singleton_lifetime_test.cc | 107 ++++++++++++++++++ 5 files changed, 141 insertions(+), 7 deletions(-) create mode 100644 sdk/test/common/global_log_handle_singleton_lifetime_test.cc diff --git a/sdk/include/opentelemetry/sdk/common/global_log_handler.h b/sdk/include/opentelemetry/sdk/common/global_log_handler.h index 55cc333d25..b2d72d4d5f 100644 --- a/sdk/include/opentelemetry/sdk/common/global_log_handler.h +++ b/sdk/include/opentelemetry/sdk/common/global_log_handler.h @@ -98,7 +98,6 @@ class GlobalLogHandler { nostd::shared_ptr handler; LogLevel log_level; - bool destroyed; GlobalLogHandlerData(); ~GlobalLogHandlerData(); @@ -118,7 +117,7 @@ class GlobalLogHandler */ static inline nostd::shared_ptr GetLogHandler() noexcept { - if OPENTELEMETRY_UNLIKELY_CONDITION (GetHandlerAndLevel().destroyed) + if OPENTELEMETRY_UNLIKELY_CONDITION (IsHandlerAndLevelDestroyed()) { return nostd::shared_ptr(); } @@ -133,7 +132,7 @@ class GlobalLogHandler */ static inline void SetLogHandler(const nostd::shared_ptr &eh) noexcept { - if OPENTELEMETRY_UNLIKELY_CONDITION (GetHandlerAndLevel().destroyed) + if OPENTELEMETRY_UNLIKELY_CONDITION (IsHandlerAndLevelDestroyed()) { return; } @@ -160,6 +159,7 @@ class GlobalLogHandler private: static GlobalLogHandlerData &GetHandlerAndLevel() noexcept; + static bool IsHandlerAndLevelDestroyed() noexcept; }; } // namespace internal_log diff --git a/sdk/src/common/global_log_handler.cc b/sdk/src/common/global_log_handler.cc index c350667c62..64b84fa90d 100644 --- a/sdk/src/common/global_log_handler.cc +++ b/sdk/src/common/global_log_handler.cc @@ -13,6 +13,15 @@ namespace common namespace internal_log { +namespace +{ +bool &InternalHandlerAndLevelDestroyedFlag() noexcept +{ + static bool destroyed = false; + return destroyed; +} +} // namespace + LogHandler::~LogHandler() {} void DefaultLogHandler::Handle(LogLevel level, @@ -58,14 +67,12 @@ void NoopLogHandler::Handle(LogLevel, {} GlobalLogHandler::GlobalLogHandlerData::GlobalLogHandlerData() - : handler(nostd::shared_ptr(new DefaultLogHandler)), - log_level(LogLevel::Warning), - destroyed(false) + : handler(nostd::shared_ptr(new DefaultLogHandler)), log_level(LogLevel::Warning) {} GlobalLogHandler::GlobalLogHandlerData::~GlobalLogHandlerData() { - destroyed = true; + InternalHandlerAndLevelDestroyedFlag() = true; } GlobalLogHandler::GlobalLogHandlerData &GlobalLogHandler::GetHandlerAndLevel() noexcept @@ -74,6 +81,11 @@ GlobalLogHandler::GlobalLogHandlerData &GlobalLogHandler::GetHandlerAndLevel() n return handler_and_level; } +bool GlobalLogHandler::IsHandlerAndLevelDestroyed() noexcept +{ + return InternalHandlerAndLevelDestroyedFlag(); +} + } // namespace internal_log } // namespace common } // namespace sdk diff --git a/sdk/test/common/BUILD b/sdk/test/common/BUILD index b08bcc0976..de4c02ec56 100644 --- a/sdk/test/common/BUILD +++ b/sdk/test/common/BUILD @@ -160,6 +160,20 @@ cc_test( ], ) +cc_test( + name = "global_log_handle_singleton_lifetime_test", + srcs = [ + "global_log_handle_singleton_lifetime_test.cc", + ], + tags = ["test"], + deps = [ + "//api", + "//sdk:headers", + "//sdk/src/common:global_log_handler", + "@com_google_googletest//:gtest_main", + ], +) + cc_test( name = "attributemap_hash_test", srcs = [ diff --git a/sdk/test/common/CMakeLists.txt b/sdk/test/common/CMakeLists.txt index 00ad67a5bf..fab78de90e 100644 --- a/sdk/test/common/CMakeLists.txt +++ b/sdk/test/common/CMakeLists.txt @@ -11,6 +11,7 @@ foreach( attribute_utils_test attributemap_hash_test global_log_handle_test + global_log_handle_singleton_lifetime_test env_var_test) add_executable(${testname} "${testname}.cc") diff --git a/sdk/test/common/global_log_handle_singleton_lifetime_test.cc b/sdk/test/common/global_log_handle_singleton_lifetime_test.cc new file mode 100644 index 0000000000..98db83713d --- /dev/null +++ b/sdk/test/common/global_log_handle_singleton_lifetime_test.cc @@ -0,0 +1,107 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include + +#include "opentelemetry/nostd/shared_ptr.h" +#include "opentelemetry/sdk/common/attribute_utils.h" +#include "opentelemetry/sdk/common/global_log_handler.h" + +class GlobalLogHandlerChecker +{ +public: + GlobalLogHandlerChecker() {} + ~GlobalLogHandlerChecker() + { + using opentelemetry::sdk::common::internal_log::GlobalLogHandler; + auto handle = GlobalLogHandler::GetLogHandler(); + if (handle && custom_handler_destroyed) + { + OTEL_INTERNAL_LOG_ERROR("GlobalLogHandler should be destroyed here"); + abort(); + } + std::cout << "GlobalLogHandlerChecker destroyed and check pass.\n"; + } + + void Print() { std::cout << "GlobalLogHandlerChecker constructed\n"; } + + GlobalLogHandlerChecker(const GlobalLogHandlerChecker &) = delete; + GlobalLogHandlerChecker(GlobalLogHandlerChecker &&) = delete; + GlobalLogHandlerChecker &operator=(const GlobalLogHandlerChecker &) = delete; + GlobalLogHandlerChecker &operator=(GlobalLogHandlerChecker &&) = delete; + + static bool custom_handler_destroyed; +}; +bool GlobalLogHandlerChecker::custom_handler_destroyed = false; + +namespace +{ +static GlobalLogHandlerChecker &ConstructChecker() +{ + static GlobalLogHandlerChecker checker; + return checker; +} +} // namespace + +class CustomLogHandler : public opentelemetry::sdk::common::internal_log::LogHandler +{ +public: + ~CustomLogHandler() + { + GlobalLogHandlerChecker::custom_handler_destroyed = true; + std::cout << "Custom Gobal Log Handle destroyed\n"; + } + + void Handle(opentelemetry::sdk::common::internal_log::LogLevel level, + const char *, + int, + const char *msg, + const opentelemetry::sdk::common::AttributeMap &) noexcept override + { + if (level == opentelemetry::sdk::common::internal_log::LogLevel::Debug) + { + std::cout << "Custom Gobal Log Handle[Debug]: " << msg << "\n"; + } + else if (level == opentelemetry::sdk::common::internal_log::LogLevel::Error) + { + std::cout << "Custom Gobal Log Handle[Error]: " << msg << "\n"; + } + else if (level == opentelemetry::sdk::common::internal_log::LogLevel::Info) + { + std::cout << "Custom Gobal Log Handle[Info]: " << msg << "\n"; + } + else if (level == opentelemetry::sdk::common::internal_log::LogLevel::Warning) + { + std::cout << "Custom Gobal Log Handle[Warning]: " << msg << "\n"; + } + ++count; + } + + size_t count = 0; +}; + +TEST(GlobalLogHandleSingletonTest, Lifetime) +{ + // Setup a new static variable which will be destroyed after the global handle + ConstructChecker().Print(); + + using opentelemetry::sdk::common::internal_log::GlobalLogHandler; + using opentelemetry::sdk::common::internal_log::LogHandler; + + auto custom_log_handler = opentelemetry::nostd::shared_ptr(new CustomLogHandler{}); + opentelemetry::sdk::common::internal_log::GlobalLogHandler::SetLogHandler(custom_log_handler); + auto before_count = static_cast(custom_log_handler.get())->count; + opentelemetry::sdk::common::AttributeMap attributes = { + {"url", "https://opentelemetry.io/"}, {"content-length", 0}, {"content-type", "text/html"}}; + OTEL_INTERNAL_LOG_ERROR("Error message"); + OTEL_INTERNAL_LOG_DEBUG("Debug message. Headers:", attributes); + EXPECT_EQ(before_count + 1, static_cast(custom_log_handler.get())->count); + + { + auto handle = GlobalLogHandler::GetLogHandler(); + EXPECT_TRUE(!!handle); + } +} From f7d1993f2b2daebce3cf933fd0fcb84bd7093479 Mon Sep 17 00:00:00 2001 From: owent Date: Wed, 15 Jan 2025 23:37:41 +0800 Subject: [PATCH 5/5] Remove `GlobalLogHandlerData` and move functions of `GlobalLogHandler` into .cc --- .../sdk/common/global_log_handler.h | 47 ++----------- sdk/src/common/global_log_handler.cc | 68 +++++++++++++++---- ...obal_log_handle_singleton_lifetime_test.cc | 2 +- 3 files changed, 60 insertions(+), 57 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/common/global_log_handler.h b/sdk/include/opentelemetry/sdk/common/global_log_handler.h index b2d72d4d5f..d11e1e0b7d 100644 --- a/sdk/include/opentelemetry/sdk/common/global_log_handler.h +++ b/sdk/include/opentelemetry/sdk/common/global_log_handler.h @@ -93,73 +93,34 @@ class NoopLogHandler : public LogHandler */ class GlobalLogHandler { -private: - struct GlobalLogHandlerData - { - nostd::shared_ptr handler; - LogLevel log_level; - - GlobalLogHandlerData(); - ~GlobalLogHandlerData(); - - GlobalLogHandlerData(const GlobalLogHandlerData &) = delete; - GlobalLogHandlerData(GlobalLogHandlerData &&) = delete; - - GlobalLogHandlerData &operator=(const GlobalLogHandlerData &) = delete; - GlobalLogHandlerData &operator=(GlobalLogHandlerData &&) = delete; - }; - public: /** * Returns the singleton LogHandler. * * By default, a default LogHandler is returned. */ - static inline nostd::shared_ptr GetLogHandler() noexcept - { - if OPENTELEMETRY_UNLIKELY_CONDITION (IsHandlerAndLevelDestroyed()) - { - return nostd::shared_ptr(); - } - - return GetHandlerAndLevel().handler; - } + static nostd::shared_ptr GetLogHandler() noexcept; /** * Changes the singleton LogHandler. * This should be called once at the start of application before creating any Provider * instance. */ - static inline void SetLogHandler(const nostd::shared_ptr &eh) noexcept - { - if OPENTELEMETRY_UNLIKELY_CONDITION (IsHandlerAndLevelDestroyed()) - { - return; - } - - GetHandlerAndLevel().handler = eh; - } + static void SetLogHandler(const nostd::shared_ptr &eh) noexcept; /** * Returns the singleton log level. * * By default, a default log level is returned. */ - static inline LogLevel GetLogLevel() noexcept { return GetHandlerAndLevel().log_level; } + static LogLevel GetLogLevel() noexcept; /** * Changes the singleton Log level. * This should be called once at the start of application before creating any Provider * instance. */ - static inline void SetLogLevel(LogLevel level) noexcept - { - GetHandlerAndLevel().log_level = level; - } - -private: - static GlobalLogHandlerData &GetHandlerAndLevel() noexcept; - static bool IsHandlerAndLevelDestroyed() noexcept; + static void SetLogLevel(LogLevel level) noexcept; }; } // namespace internal_log diff --git a/sdk/src/common/global_log_handler.cc b/sdk/src/common/global_log_handler.cc index 64b84fa90d..0883e5dfab 100644 --- a/sdk/src/common/global_log_handler.cc +++ b/sdk/src/common/global_log_handler.cc @@ -15,11 +15,34 @@ namespace internal_log namespace { -bool &InternalHandlerAndLevelDestroyedFlag() noexcept +struct GlobalLogHandlerData { - static bool destroyed = false; - return destroyed; + nostd::shared_ptr handler; + LogLevel log_level; + + GlobalLogHandlerData() + : handler(nostd::shared_ptr(new DefaultLogHandler)), log_level(LogLevel::Warning) + {} + ~GlobalLogHandlerData() { is_singleton_destroyed = true; } + + GlobalLogHandlerData(const GlobalLogHandlerData &) = delete; + GlobalLogHandlerData(GlobalLogHandlerData &&) = delete; + + GlobalLogHandlerData &operator=(const GlobalLogHandlerData &) = delete; + GlobalLogHandlerData &operator=(GlobalLogHandlerData &&) = delete; + + static GlobalLogHandlerData &Instance() noexcept; + static bool is_singleton_destroyed; +}; + +bool GlobalLogHandlerData::is_singleton_destroyed = false; + +GlobalLogHandlerData &GlobalLogHandlerData::Instance() noexcept +{ + static GlobalLogHandlerData instance; + return instance; } + } // namespace LogHandler::~LogHandler() {} @@ -66,24 +89,43 @@ void NoopLogHandler::Handle(LogLevel, const sdk::common::AttributeMap &) noexcept {} -GlobalLogHandler::GlobalLogHandlerData::GlobalLogHandlerData() - : handler(nostd::shared_ptr(new DefaultLogHandler)), log_level(LogLevel::Warning) -{} +nostd::shared_ptr GlobalLogHandler::GetLogHandler() noexcept +{ + if OPENTELEMETRY_UNLIKELY_CONDITION (GlobalLogHandlerData::is_singleton_destroyed) + { + return nostd::shared_ptr(); + } + + return GlobalLogHandlerData::Instance().handler; +} -GlobalLogHandler::GlobalLogHandlerData::~GlobalLogHandlerData() +void GlobalLogHandler::SetLogHandler(const nostd::shared_ptr &eh) noexcept { - InternalHandlerAndLevelDestroyedFlag() = true; + if OPENTELEMETRY_UNLIKELY_CONDITION (GlobalLogHandlerData::is_singleton_destroyed) + { + return; + } + + GlobalLogHandlerData::Instance().handler = eh; } -GlobalLogHandler::GlobalLogHandlerData &GlobalLogHandler::GetHandlerAndLevel() noexcept +LogLevel GlobalLogHandler::GetLogLevel() noexcept { - static GlobalLogHandlerData handler_and_level; - return handler_and_level; + if OPENTELEMETRY_UNLIKELY_CONDITION (GlobalLogHandlerData::is_singleton_destroyed) + { + return LogLevel::None; + } + + return GlobalLogHandlerData::Instance().log_level; } -bool GlobalLogHandler::IsHandlerAndLevelDestroyed() noexcept +void GlobalLogHandler::SetLogLevel(LogLevel level) noexcept { - return InternalHandlerAndLevelDestroyedFlag(); + if OPENTELEMETRY_UNLIKELY_CONDITION (GlobalLogHandlerData::is_singleton_destroyed) + { + return; + } + GlobalLogHandlerData::Instance().log_level = level; } } // namespace internal_log diff --git a/sdk/test/common/global_log_handle_singleton_lifetime_test.cc b/sdk/test/common/global_log_handle_singleton_lifetime_test.cc index 98db83713d..5b163dc6b9 100644 --- a/sdk/test/common/global_log_handle_singleton_lifetime_test.cc +++ b/sdk/test/common/global_log_handle_singleton_lifetime_test.cc @@ -49,7 +49,7 @@ static GlobalLogHandlerChecker &ConstructChecker() class CustomLogHandler : public opentelemetry::sdk::common::internal_log::LogHandler { public: - ~CustomLogHandler() + ~CustomLogHandler() override { GlobalLogHandlerChecker::custom_handler_destroyed = true; std::cout << "Custom Gobal Log Handle destroyed\n";