diff --git a/CHANGELOG.md b/CHANGELOG.md index ab7a771cc4..85acb14840 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,8 @@ Increment the: [#2627](https://github.com/open-telemetry/opentelemetry-cpp/pull/2627) * [PROTO] Upgrade to opentelemetry-proto v1.2.0 [#2631](https://github.com/open-telemetry/opentelemetry-cpp/pull/2631) +* [SDK] DefaultLogHandler to print errors to std::cerr, add LogLevel::None + [#2622](https://github.com/open-telemetry/opentelemetry-cpp/pull/2622) Important changes: @@ -45,6 +47,23 @@ Important changes: * As part of this change, the script `ci/setup_cmake.sh` was renamed to `ci/setup_googletest.sh`, for clarity, now that this script only installs googletest. +* [SDK] DefaultLogHandler to print to std::cerr, add LogLevel::None + [#2622](https://github.com/open-telemetry/opentelemetry-cpp/pull/2622) + * Change DefaultLogHandler output + * Before, the default internal logger, DefaultLogHandler, + used to print to std::cout. + * Now, DefaultLogHandler prints errors and warnings to std::cerr, + as expected, while printing info and debug messages to std::cout. + * Applications that expected to find the opentelemetry-cpp internal + error log in std::cout may need adjustments, either by looking + at std::cerr instead, or by using a custom log handler. + * Additional LogLevel::None + * LogLevel::None is a new supported log level, which does not print + any message. + * Custom log handlers may need to implement a new case, to avoid + compiler warnings. + * Numbering of log levels like OTEL_INTERNAL_LOG_LEVEL_ERROR + has changed, which requires to rebuild, as the SDK ABI differs. ## [1.14.2] 2024-02-27 diff --git a/exporters/ostream/test/ostream_log_test.cc b/exporters/ostream/test/ostream_log_test.cc index 887495f892..7b22d9b3fd 100644 --- a/exporters/ostream/test/ostream_log_test.cc +++ b/exporters/ostream/test/ostream_log_test.cc @@ -49,12 +49,12 @@ TEST(OStreamLogRecordExporter, Shutdown) auto exporter = std::unique_ptr(new exporterlogs::OStreamLogRecordExporter); - // Save cout's original buffer here - std::streambuf *original = std::cout.rdbuf(); + // Save cerr original buffer here + std::streambuf *original = std::cerr.rdbuf(); - // Redirect cout to our stringstream buffer + // Redirect cerr to our stringstream buffer std::stringstream output; - std::cout.rdbuf(output.rdbuf()); + std::cerr.rdbuf(output.rdbuf()); EXPECT_TRUE(exporter->Shutdown()); @@ -64,7 +64,7 @@ TEST(OStreamLogRecordExporter, Shutdown) exporter->Export(nostd::span>(&record, 1)); // Restore original stringstream buffer - std::cout.rdbuf(original); + std::cerr.rdbuf(original); std::string err_message = "[Ostream Log Exporter] Exporting 1 log(s) failed, exporter is shutdown"; EXPECT_TRUE(output.str().find(err_message) != std::string::npos); diff --git a/exporters/ostream/test/ostream_span_test.cc b/exporters/ostream/test/ostream_span_test.cc index edfd66505e..f92f1bbffd 100644 --- a/exporters/ostream/test/ostream_span_test.cc +++ b/exporters/ostream/test/ostream_span_test.cc @@ -46,8 +46,8 @@ TEST(OStreamSpanExporter, Shutdown) auto recordable = processor->MakeRecordable(); recordable->SetName("Test Span"); - // Capture the output of cout - const auto captured = WithOStreamCapture(std::cout, [&]() { + // Capture the output of cerr + const auto captured = WithOStreamCapture(std::cerr, [&]() { EXPECT_TRUE(processor->Shutdown()); processor->OnEnd(std::move(recordable)); }); diff --git a/functional/otlp/func_http_main.cc b/functional/otlp/func_http_main.cc index 68638c97a9..d584a85687 100644 --- a/functional/otlp/func_http_main.cc +++ b/functional/otlp/func_http_main.cc @@ -128,6 +128,8 @@ class TestLogHandler : public opentelemetry::sdk::common::internal_log::LogHandl switch (level) { + case opentelemetry::sdk::common::internal_log::LogLevel::None: + break; case opentelemetry::sdk::common::internal_log::LogLevel::Error: std::cout << " - [E] " << msg << std::endl; parse_error_msg(&g_test_result, msg); diff --git a/sdk/include/opentelemetry/sdk/common/global_log_handler.h b/sdk/include/opentelemetry/sdk/common/global_log_handler.h index 14c956b96e..10bf42a145 100644 --- a/sdk/include/opentelemetry/sdk/common/global_log_handler.h +++ b/sdk/include/opentelemetry/sdk/common/global_log_handler.h @@ -10,10 +10,11 @@ #include "opentelemetry/sdk/common/attribute_utils.h" #include "opentelemetry/version.h" -#define OTEL_INTERNAL_LOG_LEVEL_ERROR 0 -#define OTEL_INTERNAL_LOG_LEVEL_WARN 1 -#define OTEL_INTERNAL_LOG_LEVEL_INFO 2 -#define OTEL_INTERNAL_LOG_LEVEL_DEBUG 3 +#define OTEL_INTERNAL_LOG_LEVEL_NONE 0 +#define OTEL_INTERNAL_LOG_LEVEL_ERROR 1 +#define OTEL_INTERNAL_LOG_LEVEL_WARN 2 +#define OTEL_INTERNAL_LOG_LEVEL_INFO 3 +#define OTEL_INTERNAL_LOG_LEVEL_DEBUG 4 #ifndef OTEL_INTERNAL_LOG_LEVEL // DEBUG by default, we can change log level on runtime # define OTEL_INTERNAL_LOG_LEVEL OTEL_INTERNAL_LOG_LEVEL_DEBUG @@ -29,16 +30,19 @@ namespace internal_log enum class LogLevel { - Error = 0, - Warning, - Info, - Debug + None = OTEL_INTERNAL_LOG_LEVEL_NONE, + Error = OTEL_INTERNAL_LOG_LEVEL_ERROR, + Warning = OTEL_INTERNAL_LOG_LEVEL_WARN, + Info = OTEL_INTERNAL_LOG_LEVEL_INFO, + Debug = OTEL_INTERNAL_LOG_LEVEL_DEBUG }; inline std::string LevelToString(LogLevel level) { switch (level) { + case LogLevel::None: + return "None"; case LogLevel::Error: return "Error"; case LogLevel::Warning: diff --git a/sdk/src/common/global_log_handler.cc b/sdk/src/common/global_log_handler.cc index bd1b56a9cd..40968f2b7e 100644 --- a/sdk/src/common/global_log_handler.cc +++ b/sdk/src/common/global_log_handler.cc @@ -33,7 +33,21 @@ void DefaultLogHandler::Handle(LogLevel level, } output_s << std::endl; // TBD - print attributes - std::cout << output_s.str(); // thread safe. + + switch (level) + { + case LogLevel::Error: + case LogLevel::Warning: + std::cerr << output_s.str(); // thread safe. + break; + case LogLevel::Info: + case LogLevel::Debug: + std::cout << output_s.str(); // thread safe. + break; + case LogLevel::None: + default: + break; + } } void NoopLogHandler::Handle(LogLevel, diff --git a/sdk/test/common/global_log_handle_test.cc b/sdk/test/common/global_log_handle_test.cc index a38bdc8728..28b111cc71 100644 --- a/sdk/test/common/global_log_handle_test.cc +++ b/sdk/test/common/global_log_handle_test.cc @@ -62,6 +62,14 @@ TEST(GlobalLogHandleTest, CustomLogHandler) OTEL_INTERNAL_LOG_WARN("Warning message"); EXPECT_EQ(before_count + 5, static_cast(custom_log_handler.get())->count); + opentelemetry::sdk::common::internal_log::GlobalLogHandler::SetLogLevel( + opentelemetry::sdk::common::internal_log::LogLevel::None); + OTEL_INTERNAL_LOG_ERROR("Error message"); + OTEL_INTERNAL_LOG_DEBUG("Debug message. Headers:", attributes); + OTEL_INTERNAL_LOG_INFO("Info message"); + OTEL_INTERNAL_LOG_WARN("Warning message"); + EXPECT_EQ(before_count + 5, static_cast(custom_log_handler.get())->count); + opentelemetry::sdk::common::internal_log::GlobalLogHandler::SetLogHandler(backup_log_handle); opentelemetry::sdk::common::internal_log::GlobalLogHandler::SetLogLevel(backup_log_level); }