From 87c085eae262fae04db8bf420e9df425ba3c956a Mon Sep 17 00:00:00 2001 From: owent Date: Sun, 12 Apr 2026 23:52:49 +0800 Subject: [PATCH 1/3] Implement non-utf8 string to bytes in OTLP exporters. https://github.com/open-telemetry/opentelemetry-specification/blame/v1.55.0/specification/common/attribute-type-mapping.md --- cmake/protobuf.cmake | 91 ++++++++++++++----- exporters/otlp/BUILD | 14 +++ exporters/otlp/CMakeLists.txt | 23 ++++- .../otlp/src/otlp_populate_attribute_utils.cc | 69 +++++++++++++- .../otlp/test/otlp_log_recordable_test.cc | 33 +++++++ 5 files changed, 200 insertions(+), 30 deletions(-) diff --git a/cmake/protobuf.cmake b/cmake/protobuf.cmake index 9bdcac91c0..325c5210d5 100644 --- a/cmake/protobuf.cmake +++ b/cmake/protobuf.cmake @@ -1,29 +1,37 @@ # Copyright The OpenTelemetry Authors # SPDX-License-Identifier: Apache-2.0 - -# Import Protobuf targets (protobuf::libprotobuf and protobuf::protoc) and set PROTOBUF_PROTOC_EXECUTABLE. -# 1. If gRPC was fetched from github then use the Protobuf submodule built with gRPC -# 2. Find an installed Protobuf package -# 3. Use FetchContent to fetch and build Protobuf from GitHub - -if(DEFINED gRPC_PROVIDER AND NOT gRPC_PROVIDER STREQUAL "find_package" AND TARGET libprotobuf) +# Import Protobuf targets (protobuf::libprotobuf and protobuf::protoc) and set +# PROTOBUF_PROTOC_EXECUTABLE. 1. If gRPC was fetched from github then use the +# Protobuf submodule built with gRPC 2. Find an installed Protobuf package 3. +# Use FetchContent to fetch and build Protobuf from GitHub + +if(DEFINED gRPC_PROVIDER + AND NOT gRPC_PROVIDER STREQUAL "find_package" + AND TARGET libprotobuf) # gRPC was fetched and built Protobuf as a submodule - set(_Protobuf_VERSION_REGEX "\"cpp\"[ \t]*:[ \t]*\"([0-9]+\\.[0-9]+(\\.[0-9]+)?)\"") - set(_Protobuf_VERSION_FILE "${grpc_SOURCE_DIR}/third_party/protobuf/version.json") + set(_Protobuf_VERSION_REGEX + "\"cpp\"[ \t]*:[ \t]*\"([0-9]+\\.[0-9]+(\\.[0-9]+)?)\"") + set(_Protobuf_VERSION_FILE + "${grpc_SOURCE_DIR}/third_party/protobuf/version.json") file(READ "${_Protobuf_VERSION_FILE}" _Protobuf_VERSION_FILE_CONTENTS) if(_Protobuf_VERSION_FILE_CONTENTS MATCHES ${_Protobuf_VERSION_REGEX}) set(Protobuf_VERSION "${CMAKE_MATCH_1}") else() - message(WARNING "Failed to parse Protobuf version from ${_Protobuf_VERSION_FILE} using regex ${_Protobuf_VERSION_REGEX}") + message( + WARNING + "Failed to parse Protobuf version from ${_Protobuf_VERSION_FILE} using regex ${_Protobuf_VERSION_REGEX}" + ) endif() set(Protobuf_PROVIDER "grpc_submodule") else() - # Search for an installed Protobuf package explicitly using the CONFIG search mode first followed by the MODULE search mode. - # Protobuf versions < 3.22.0 may be found using the module mode and some protobuf apt packages do not support the CONFIG search. + # Search for an installed Protobuf package explicitly using the CONFIG search + # mode first followed by the MODULE search mode. Protobuf versions < 3.22.0 + # may be found using the module mode and some protobuf apt packages do not + # support the CONFIG search. find_package(Protobuf CONFIG QUIET) set(Protobuf_PROVIDER "find_package") @@ -36,33 +44,48 @@ else() FetchContent_Declare( "protobuf" GIT_REPOSITORY "https://github.com/protocolbuffers/protobuf.git" - GIT_TAG "${protobuf_GIT_TAG}" - ) - - set(protobuf_INSTALL ${OPENTELEMETRY_INSTALL} CACHE BOOL "" FORCE) - set(protobuf_BUILD_TESTS OFF CACHE BOOL "" FORCE) - set(protobuf_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) + GIT_TAG "${protobuf_GIT_TAG}") + + set(protobuf_INSTALL + ${OPENTELEMETRY_INSTALL} + CACHE BOOL "" FORCE) + set(protobuf_BUILD_TESTS + OFF + CACHE BOOL "" FORCE) + set(protobuf_BUILD_EXAMPLES + OFF + CACHE BOOL "" FORCE) FetchContent_MakeAvailable(protobuf) set(Protobuf_PROVIDER "fetch_repository") # Set the Protobuf_VERSION variable from the git tag. - string(REGEX REPLACE "^v([0-9]+\\.[0-9]+\\.[0-9]+)$" "\\1" Protobuf_VERSION "${protobuf_GIT_TAG}") + string(REGEX REPLACE "^v([0-9]+\\.[0-9]+\\.[0-9]+)$" "\\1" Protobuf_VERSION + "${protobuf_GIT_TAG}") if(TARGET libprotobuf) - set_target_properties(libprotobuf PROPERTIES POSITION_INDEPENDENT_CODE ON CXX_CLANG_TIDY "" CXX_INCLUDE_WHAT_YOU_USE "") + set_target_properties( + libprotobuf + PROPERTIES POSITION_INDEPENDENT_CODE ON + CXX_CLANG_TIDY "" + CXX_INCLUDE_WHAT_YOU_USE "") endif() endif() endif() if(NOT TARGET protobuf::libprotobuf) - message(FATAL_ERROR "A required protobuf target (protobuf::libprotobuf) was not imported") + message( + FATAL_ERROR + "A required protobuf target (protobuf::libprotobuf) was not imported") endif() if(PROTOBUF_PROTOC_EXECUTABLE AND NOT Protobuf_PROTOC_EXECUTABLE) - message(WARNING "Use of PROTOBUF_PROTOC_EXECUTABLE is deprecated. Please use Protobuf_PROTOC_EXECUTABLE instead.") + message( + WARNING + "Use of PROTOBUF_PROTOC_EXECUTABLE is deprecated. Please use Protobuf_PROTOC_EXECUTABLE instead." + ) set(Protobuf_PROTOC_EXECUTABLE "${PROTOBUF_PROTOC_EXECUTABLE}") endif() @@ -70,7 +93,9 @@ if(CMAKE_CROSSCOMPILING) find_program(Protobuf_PROTOC_EXECUTABLE protoc) else() if(NOT TARGET protobuf::protoc) - message(FATAL_ERROR "A required protobuf target (protobuf::protoc) was not imported") + message( + FATAL_ERROR + "A required protobuf target (protobuf::protoc) was not imported") endif() set(Protobuf_PROTOC_EXECUTABLE "$") endif() @@ -78,3 +103,23 @@ endif() set(PROTOBUF_PROTOC_EXECUTABLE "${Protobuf_PROTOC_EXECUTABLE}") message(STATUS "PROTOBUF_PROTOC_EXECUTABLE=${PROTOBUF_PROTOC_EXECUTABLE}") + +# When protobuf is fetched or built as a gRPC submodule utf8_range is compiled +# but may need the alias target created +if(TARGET utf8_validity AND NOT TARGET utf8_range::utf8_validity) + add_library(utf8_range::utf8_validity ALIAS utf8_validity) +endif() + +# For the find_package(Protobuf) path, utf8_range can also be found +if(NOT TARGET utf8_range::utf8_validity) + find_package(utf8_range CONFIG QUIET) +endif() + +# The utf8_range target should now be available for use in otel-cpp +if(NOT TARGET utf8_range::utf8_validity) + message( + WARNING + "Target (utf8_range::utf8_validity) was not found. " + "We will not validate UTF-8 strings in the OTLP exporter." + "Which may lead to record drops when sending non UTF-8 data as string.") +endif() diff --git a/exporters/otlp/BUILD b/exporters/otlp/BUILD index cd505295dd..60311dc949 100644 --- a/exporters/otlp/BUILD +++ b/exporters/otlp/BUILD @@ -8,6 +8,19 @@ load("//bazel:otel_cc_benchmark.bzl", "otel_cc_benchmark") package(default_visibility = ["//visibility:public"]) +# utf8_range from protobuf source tree for UTF-8 validation in OTLP +# value conversion. This mirrors the CMake opentelemetry_otlp_utf8_validity +# target. +cc_library( + name = "otlp_utf8_validity", + defines = ["ENABLE_OTLP_UTF8_VALIDITY"], + tags = ["otlp"], + deps = [ + "@com_google_protobuf//third_party/utf8_range", + "@com_google_protobuf//third_party/utf8_range:utf8_validity", + ], +) + cc_library( name = "otlp_recordable", srcs = [ @@ -32,6 +45,7 @@ cc_library( strip_include_prefix = "include", tags = ["otlp"], deps = [ + ":otlp_utf8_validity", "//sdk/src/logs", "//sdk/src/resource", "//sdk/src/trace", diff --git a/exporters/otlp/CMakeLists.txt b/exporters/otlp/CMakeLists.txt index 1d460d6d4c..e3d1d64079 100644 --- a/exporters/otlp/CMakeLists.txt +++ b/exporters/otlp/CMakeLists.txt @@ -33,9 +33,16 @@ target_include_directories( set(OPENTELEMETRY_OTLP_TARGETS opentelemetry_otlp_recordable) -target_link_libraries(opentelemetry_otlp_recordable PUBLIC opentelemetry_logs) -target_link_libraries(opentelemetry_otlp_recordable - PUBLIC opentelemetry_metrics) +if(TARGET utf8_range::utf8_validity) + target_link_libraries( + opentelemetry_otlp_recordable + PUBLIC opentelemetry_logs opentelemetry_metrics utf8_range::utf8_validity) + target_compile_definitions(opentelemetry_otlp_recordable + PRIVATE ENABLE_OTLP_UTF8_VALIDITY) +else() + target_link_libraries(opentelemetry_otlp_recordable + PUBLIC opentelemetry_logs opentelemetry_metrics) +endif() # # opentelemetry_exporter_otlp_builder_utils @@ -57,6 +64,12 @@ target_link_libraries(opentelemetry_exporter_otlp_builder_utils PUBLIC opentelemetry_otlp_recordable) if(OPENTELEMETRY_INSTALL) + if(TARGET opentelemetry_otlp_utf8_validity) + opentelemetry_add_pkgconfig( + otlp_utf8_validity "OpenTelemetry OTLP - UTF-8 Validity" + "OTLP UTF-8 validity implementation for value conversion.") + endif() + opentelemetry_add_pkgconfig( otlp_recordable "OpenTelemetry OTLP - Recordable" @@ -875,6 +888,10 @@ if(BUILD_TESTING) add_executable(otlp_log_recordable_test test/otlp_log_recordable_test.cc) target_link_libraries(otlp_log_recordable_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_otlp_recordable) + if(TARGET utf8_range::utf8_validity) + target_compile_definitions(otlp_log_recordable_test + PRIVATE ENABLE_OTLP_UTF8_VALIDITY) + endif() gtest_add_tests( TARGET otlp_log_recordable_test TEST_PREFIX exporter.otlp. diff --git a/exporters/otlp/src/otlp_populate_attribute_utils.cc b/exporters/otlp/src/otlp_populate_attribute_utils.cc index bc9a7d618a..6307eda70a 100644 --- a/exporters/otlp/src/otlp_populate_attribute_utils.cc +++ b/exporters/otlp/src/otlp_populate_attribute_utils.cc @@ -1,6 +1,10 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#if defined(ENABLE_OTLP_UTF8_VALIDITY) +# include +#endif + #include #include #include @@ -81,12 +85,35 @@ void OtlpPopulateAttributeUtils::PopulateAnyValue( } else if (nostd::holds_alternative(value)) { - proto_value->set_string_value(nostd::get(value)); + const char *str_value = nostd::get(value); +#if defined(ENABLE_OTLP_UTF8_VALIDITY) + if (utf8_range::IsStructurallyValid(str_value)) + { + proto_value->set_string_value(str_value); + } + else + { + proto_value->set_bytes_value(str_value, strlen(str_value)); + } +#else + proto_value->set_string_value(str_value); +#endif } else if (nostd::holds_alternative(value)) { - proto_value->set_string_value(nostd::get(value).data(), - nostd::get(value).size()); + nostd::string_view str_value = nostd::get(value); +#if defined(ENABLE_OTLP_UTF8_VALIDITY) + if (utf8_range::IsStructurallyValid({str_value.data(), str_value.size()})) + { + proto_value->set_string_value(str_value.data(), str_value.size()); + } + else + { + proto_value->set_bytes_value(str_value.data(), str_value.size()); + } +#else + proto_value->set_string_value(str_value.data(), str_value.size()); +#endif } else if (nostd::holds_alternative>(value)) { @@ -159,7 +186,18 @@ void OtlpPopulateAttributeUtils::PopulateAnyValue( auto array_value = proto_value->mutable_array_value(); for (const auto &val : nostd::get>(value)) { +#if defined(ENABLE_OTLP_UTF8_VALIDITY) + if (utf8_range::IsStructurallyValid({val.data(), val.size()})) + { + array_value->add_values()->set_string_value(val.data(), val.size()); + } + else + { + array_value->add_values()->set_bytes_value(val.data(), val.size()); + } +#else array_value->add_values()->set_string_value(val.data(), val.size()); +#endif } } } @@ -224,7 +262,19 @@ void OtlpPopulateAttributeUtils::PopulateAnyValue( } else if (nostd::holds_alternative(value)) { - proto_value->set_string_value(nostd::get(value)); + const std::string &str_value = nostd::get(value); +#if defined(ENABLE_OTLP_UTF8_VALIDITY) + if (utf8_range::IsStructurallyValid(str_value)) + { + proto_value->set_string_value(str_value); + } + else + { + proto_value->set_bytes_value(str_value); + } +#else + proto_value->set_string_value(str_value); +#endif } else if (nostd::holds_alternative>(value)) { @@ -281,7 +331,18 @@ void OtlpPopulateAttributeUtils::PopulateAnyValue( auto array_value = proto_value->mutable_array_value(); for (const auto &val : nostd::get>(value)) { +#if defined(ENABLE_OTLP_UTF8_VALIDITY) + if (utf8_range::IsStructurallyValid(val)) + { + array_value->add_values()->set_string_value(val); + } + else + { + array_value->add_values()->set_bytes_value(val); + } +#else array_value->add_values()->set_string_value(val); +#endif } } } diff --git a/exporters/otlp/test/otlp_log_recordable_test.cc b/exporters/otlp/test/otlp_log_recordable_test.cc index 488d8f12dc..0c4000ac0f 100644 --- a/exporters/otlp/test/otlp_log_recordable_test.cc +++ b/exporters/otlp/test/otlp_log_recordable_test.cc @@ -84,6 +84,17 @@ TEST(OtlpLogRecordable, Basic) memcmp(reinterpret_cast(rec.log_record().body().bytes_value().data()), reinterpret_cast(byte_arr), 5)); EXPECT_EQ(rec.log_record().body().bytes_value().size(), 5); + +#if defined(ENABLE_OTLP_UTF8_VALIDITY) + // Test bytes body: non-UTF8 string_view is automatically converted to bytes_value + const char byte_body[] = {'\x80', '\x81', '\x82', '\x83', '\x84'}; + nostd::string_view byte_body_view(byte_body, 5); + rec.SetBody(byte_body_view); + EXPECT_TRUE(0 == + memcmp(reinterpret_cast(rec.log_record().body().bytes_value().data()), + reinterpret_cast(byte_body), 5)); + EXPECT_EQ(rec.log_record().body().bytes_value().size(), 5); +#endif } TEST(OtlpLogRecordable, GetResource) @@ -128,6 +139,14 @@ TEST(OtlpLogRecordable, SetSingleAttribute) nostd::span{reinterpret_cast(byte_arr), 4}); rec.SetAttribute(byte_key, byte_val); +#if defined(ENABLE_OTLP_UTF8_VALIDITY) + // Non-UTF8 string_view is automatically converted to bytes_value + nostd::string_view non_utf8_string_key = "non_utf8_string_attr"; + const char non_utf8_string_arr[] = {'\x80', '\x81', '\x82', '\x83'}; + common::AttributeValue non_utf8_string_val(nostd::string_view(non_utf8_string_arr, 4)); + rec.SetAttribute(non_utf8_string_key, non_utf8_string_val); +#endif + int checked_attributes = 0; for (auto &attribute : rec.log_record().attributes()) { @@ -154,8 +173,22 @@ TEST(OtlpLogRecordable, SetSingleAttribute) reinterpret_cast(byte_arr), 4)); EXPECT_EQ(attribute.value().bytes_value().size(), 4); } +#if defined(ENABLE_OTLP_UTF8_VALIDITY) + else if (attribute.key() == non_utf8_string_key) + { + ++checked_attributes; + EXPECT_TRUE(0 == + memcmp(reinterpret_cast(attribute.value().bytes_value().data()), + reinterpret_cast(non_utf8_string_arr), 4)); + EXPECT_EQ(attribute.value().bytes_value().size(), 4); + } +#endif } +#if defined(ENABLE_OTLP_UTF8_VALIDITY) + EXPECT_EQ(5, checked_attributes); +#else EXPECT_EQ(4, checked_attributes); +#endif } // Test non-int array types. Int array types are tested using templates (see IntAttributeTest) From 49895b199abf55bca85cc5ca8cf6c051501902f5 Mon Sep 17 00:00:00 2001 From: owent Date: Sat, 18 Apr 2026 22:18:38 +0800 Subject: [PATCH 2/3] Fixes include dir of utf8_validity when it's imported as a sub directory. --- cmake/protobuf.cmake | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cmake/protobuf.cmake b/cmake/protobuf.cmake index 325c5210d5..6d00c11fc0 100644 --- a/cmake/protobuf.cmake +++ b/cmake/protobuf.cmake @@ -108,6 +108,12 @@ message(STATUS "PROTOBUF_PROTOC_EXECUTABLE=${PROTOBUF_PROTOC_EXECUTABLE}") # but may need the alias target created if(TARGET utf8_validity AND NOT TARGET utf8_range::utf8_validity) add_library(utf8_range::utf8_validity ALIAS utf8_validity) + if(protobuf_SOURCE_DIR AND EXISTS + "${protobuf_SOURCE_DIR}/third_party/utf8_range") + target_include_directories( + utf8_validity + PUBLIC "$") + endif() endif() # For the find_package(Protobuf) path, utf8_range can also be found From 2999fdb576e562ae0ba77c6978455e5923e56ca0 Mon Sep 17 00:00:00 2001 From: owent Date: Sun, 26 Apr 2026 16:56:42 +0800 Subject: [PATCH 3/3] Fixes feedbacks --- CMakeLists.txt | 4 ++ cmake/protobuf.cmake | 112 ++++++++++++++-------------------- exporters/otlp/CMakeLists.txt | 13 ++-- 3 files changed, 53 insertions(+), 76 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 453c65bb6f..fa28c26e22 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -153,6 +153,10 @@ option( "Whether to include gzip compression for the OTLP http exporter in the SDK" OFF) +option( + WITH_OTLP_UTF8_VALIDITY + "Whether to enable UTF-8 validity checks for the OTLP exporter in the SDK" ON) + option(WITH_CURL_LOGGING "Whether to enable select CURL verbosity in OTel logs" OFF) diff --git a/cmake/protobuf.cmake b/cmake/protobuf.cmake index 6d00c11fc0..9375a5bbea 100644 --- a/cmake/protobuf.cmake +++ b/cmake/protobuf.cmake @@ -1,37 +1,29 @@ # Copyright The OpenTelemetry Authors # SPDX-License-Identifier: Apache-2.0 -# Import Protobuf targets (protobuf::libprotobuf and protobuf::protoc) and set -# PROTOBUF_PROTOC_EXECUTABLE. 1. If gRPC was fetched from github then use the -# Protobuf submodule built with gRPC 2. Find an installed Protobuf package 3. -# Use FetchContent to fetch and build Protobuf from GitHub - -if(DEFINED gRPC_PROVIDER - AND NOT gRPC_PROVIDER STREQUAL "find_package" - AND TARGET libprotobuf) + +# Import Protobuf targets (protobuf::libprotobuf and protobuf::protoc) and set PROTOBUF_PROTOC_EXECUTABLE. +# 1. If gRPC was fetched from github then use the Protobuf submodule built with gRPC +# 2. Find an installed Protobuf package +# 3. Use FetchContent to fetch and build Protobuf from GitHub + +if(DEFINED gRPC_PROVIDER AND NOT gRPC_PROVIDER STREQUAL "find_package" AND TARGET libprotobuf) # gRPC was fetched and built Protobuf as a submodule - set(_Protobuf_VERSION_REGEX - "\"cpp\"[ \t]*:[ \t]*\"([0-9]+\\.[0-9]+(\\.[0-9]+)?)\"") - set(_Protobuf_VERSION_FILE - "${grpc_SOURCE_DIR}/third_party/protobuf/version.json") + set(_Protobuf_VERSION_REGEX "\"cpp\"[ \t]*:[ \t]*\"([0-9]+\\.[0-9]+(\\.[0-9]+)?)\"") + set(_Protobuf_VERSION_FILE "${grpc_SOURCE_DIR}/third_party/protobuf/version.json") file(READ "${_Protobuf_VERSION_FILE}" _Protobuf_VERSION_FILE_CONTENTS) if(_Protobuf_VERSION_FILE_CONTENTS MATCHES ${_Protobuf_VERSION_REGEX}) set(Protobuf_VERSION "${CMAKE_MATCH_1}") else() - message( - WARNING - "Failed to parse Protobuf version from ${_Protobuf_VERSION_FILE} using regex ${_Protobuf_VERSION_REGEX}" - ) + message(WARNING "Failed to parse Protobuf version from ${_Protobuf_VERSION_FILE} using regex ${_Protobuf_VERSION_REGEX}") endif() set(Protobuf_PROVIDER "grpc_submodule") else() - # Search for an installed Protobuf package explicitly using the CONFIG search - # mode first followed by the MODULE search mode. Protobuf versions < 3.22.0 - # may be found using the module mode and some protobuf apt packages do not - # support the CONFIG search. + # Search for an installed Protobuf package explicitly using the CONFIG search mode first followed by the MODULE search mode. + # Protobuf versions < 3.22.0 may be found using the module mode and some protobuf apt packages do not support the CONFIG search. find_package(Protobuf CONFIG QUIET) set(Protobuf_PROVIDER "find_package") @@ -44,48 +36,33 @@ else() FetchContent_Declare( "protobuf" GIT_REPOSITORY "https://github.com/protocolbuffers/protobuf.git" - GIT_TAG "${protobuf_GIT_TAG}") - - set(protobuf_INSTALL - ${OPENTELEMETRY_INSTALL} - CACHE BOOL "" FORCE) - set(protobuf_BUILD_TESTS - OFF - CACHE BOOL "" FORCE) - set(protobuf_BUILD_EXAMPLES - OFF - CACHE BOOL "" FORCE) + GIT_TAG "${protobuf_GIT_TAG}" + ) + + set(protobuf_INSTALL ${OPENTELEMETRY_INSTALL} CACHE BOOL "" FORCE) + set(protobuf_BUILD_TESTS OFF CACHE BOOL "" FORCE) + set(protobuf_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) FetchContent_MakeAvailable(protobuf) set(Protobuf_PROVIDER "fetch_repository") # Set the Protobuf_VERSION variable from the git tag. - string(REGEX REPLACE "^v([0-9]+\\.[0-9]+\\.[0-9]+)$" "\\1" Protobuf_VERSION - "${protobuf_GIT_TAG}") + string(REGEX REPLACE "^v([0-9]+\\.[0-9]+\\.[0-9]+)$" "\\1" Protobuf_VERSION "${protobuf_GIT_TAG}") if(TARGET libprotobuf) - set_target_properties( - libprotobuf - PROPERTIES POSITION_INDEPENDENT_CODE ON - CXX_CLANG_TIDY "" - CXX_INCLUDE_WHAT_YOU_USE "") + set_target_properties(libprotobuf PROPERTIES POSITION_INDEPENDENT_CODE ON CXX_CLANG_TIDY "" CXX_INCLUDE_WHAT_YOU_USE "") endif() endif() endif() if(NOT TARGET protobuf::libprotobuf) - message( - FATAL_ERROR - "A required protobuf target (protobuf::libprotobuf) was not imported") + message(FATAL_ERROR "A required protobuf target (protobuf::libprotobuf) was not imported") endif() if(PROTOBUF_PROTOC_EXECUTABLE AND NOT Protobuf_PROTOC_EXECUTABLE) - message( - WARNING - "Use of PROTOBUF_PROTOC_EXECUTABLE is deprecated. Please use Protobuf_PROTOC_EXECUTABLE instead." - ) + message(WARNING "Use of PROTOBUF_PROTOC_EXECUTABLE is deprecated. Please use Protobuf_PROTOC_EXECUTABLE instead.") set(Protobuf_PROTOC_EXECUTABLE "${PROTOBUF_PROTOC_EXECUTABLE}") endif() @@ -93,9 +70,7 @@ if(CMAKE_CROSSCOMPILING) find_program(Protobuf_PROTOC_EXECUTABLE protoc) else() if(NOT TARGET protobuf::protoc) - message( - FATAL_ERROR - "A required protobuf target (protobuf::protoc) was not imported") + message(FATAL_ERROR "A required protobuf target (protobuf::protoc) was not imported") endif() set(Protobuf_PROTOC_EXECUTABLE "$") endif() @@ -106,26 +81,29 @@ message(STATUS "PROTOBUF_PROTOC_EXECUTABLE=${PROTOBUF_PROTOC_EXECUTABLE}") # When protobuf is fetched or built as a gRPC submodule utf8_range is compiled # but may need the alias target created -if(TARGET utf8_validity AND NOT TARGET utf8_range::utf8_validity) - add_library(utf8_range::utf8_validity ALIAS utf8_validity) - if(protobuf_SOURCE_DIR AND EXISTS - "${protobuf_SOURCE_DIR}/third_party/utf8_range") - target_include_directories( - utf8_validity - PUBLIC "$") +if(WITH_OTLP_UTF8_VALIDITY) + if(TARGET utf8_validity AND NOT TARGET utf8_range::utf8_validity) + add_library(utf8_range::utf8_validity ALIAS utf8_validity) + if(protobuf_SOURCE_DIR AND EXISTS + "${protobuf_SOURCE_DIR}/third_party/utf8_range") + target_include_directories( + utf8_validity + PUBLIC + "$") + endif() endif() -endif() -# For the find_package(Protobuf) path, utf8_range can also be found -if(NOT TARGET utf8_range::utf8_validity) - find_package(utf8_range CONFIG QUIET) -endif() + # For the find_package(Protobuf) path, utf8_range can also be found + if(NOT TARGET utf8_range::utf8_validity) + find_package(utf8_range CONFIG QUIET) + endif() -# The utf8_range target should now be available for use in otel-cpp -if(NOT TARGET utf8_range::utf8_validity) - message( - WARNING - "Target (utf8_range::utf8_validity) was not found. " - "We will not validate UTF-8 strings in the OTLP exporter." - "Which may lead to record drops when sending non UTF-8 data as string.") + # The utf8_range target should now be available for use in otel-cpp + if(NOT TARGET utf8_range::utf8_validity) + message( + WARNING + "Target (utf8_range::utf8_validity) was not found. " + "We will not validate UTF-8 strings in the OTLP exporter." + "Which may lead to record drops when sending non UTF-8 data as string.") + endif() endif() diff --git a/exporters/otlp/CMakeLists.txt b/exporters/otlp/CMakeLists.txt index e3d1d64079..2d53476be6 100644 --- a/exporters/otlp/CMakeLists.txt +++ b/exporters/otlp/CMakeLists.txt @@ -33,10 +33,11 @@ target_include_directories( set(OPENTELEMETRY_OTLP_TARGETS opentelemetry_otlp_recordable) -if(TARGET utf8_range::utf8_validity) +if(WITH_OTLP_UTF8_VALIDITY AND TARGET utf8_range::utf8_validity) target_link_libraries( opentelemetry_otlp_recordable - PUBLIC opentelemetry_logs opentelemetry_metrics utf8_range::utf8_validity) + PUBLIC opentelemetry_logs opentelemetry_metrics + PRIVATE utf8_range::utf8_validity) target_compile_definitions(opentelemetry_otlp_recordable PRIVATE ENABLE_OTLP_UTF8_VALIDITY) else() @@ -64,12 +65,6 @@ target_link_libraries(opentelemetry_exporter_otlp_builder_utils PUBLIC opentelemetry_otlp_recordable) if(OPENTELEMETRY_INSTALL) - if(TARGET opentelemetry_otlp_utf8_validity) - opentelemetry_add_pkgconfig( - otlp_utf8_validity "OpenTelemetry OTLP - UTF-8 Validity" - "OTLP UTF-8 validity implementation for value conversion.") - endif() - opentelemetry_add_pkgconfig( otlp_recordable "OpenTelemetry OTLP - Recordable" @@ -888,7 +883,7 @@ if(BUILD_TESTING) add_executable(otlp_log_recordable_test test/otlp_log_recordable_test.cc) target_link_libraries(otlp_log_recordable_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_otlp_recordable) - if(TARGET utf8_range::utf8_validity) + if(WITH_OTLP_UTF8_VALIDITY AND TARGET utf8_range::utf8_validity) target_compile_definitions(otlp_log_recordable_test PRIVATE ENABLE_OTLP_UTF8_VALIDITY) endif()