diff --git a/.devcontainer/README.md b/.devcontainer/README.md index 00eabf2f42..2844f58341 100644 --- a/.devcontainer/README.md +++ b/.devcontainer/README.md @@ -12,7 +12,7 @@ environment variables (for evaluation in `devcontainer.json`). * **abseil-cpp version:** This is the version of abseil-cpp that will be used to build protobuf, gRPC, - and opentelemetry-cpp (when WITH_ABSEIL is set). + and opentelemetry-cpp. * Docker ARG: `ABSEIL_CPP_VERSION` * Host Environment Variable: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bc8fde8bbc..61f7a97db5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,15 +30,6 @@ jobs: # sudo -E ./ci/setup_googletest.sh # sudo -E ./ci/install_abseil.sh # sudo -E ./ci/install_protobuf.sh -# - name: run otlp exporter tests -# env: -# CC: /usr/bin/gcc-10 -# CXX: /usr/bin/g++-10 -# WITH_ABSEIL: 'ON' -# CXX_STANDARD: '14' -# run: | -# sudo -E ./ci/setup_grpc.sh -m -p protobuf -p abseil-cpp -# ./ci/do_ci.sh cmake.exporter.otprotocol.test cmake_test: name: CMake test (prometheus, elasticsearch, zipkin) @@ -528,7 +519,6 @@ jobs: sudo -E ./ci/install_protobuf.sh - name: run otlp exporter tests env: - WITH_ABSEIL: 'ON' CXX_STANDARD: '14' run: | sudo -E ./ci/setup_grpc.sh -m -p protobuf -p abseil-cpp diff --git a/.github/workflows/clang-tidy.yaml b/.github/workflows/clang-tidy.yaml index b467c56d44..599d09bd44 100644 --- a/.github/workflows/clang-tidy.yaml +++ b/.github/workflows/clang-tidy.yaml @@ -78,4 +78,4 @@ jobs: COUNT=$(grep -c "warning:" clang-tidy.log) echo "clang-tidy reported ${COUNT} warning(s)" -# TODO: include WITH_OTLP_GRPC and WITH_ABSEIL flags. +# TODO: include WITH_OTLP_GRPC flags. diff --git a/CHANGELOG.md b/CHANGELOG.md index 62262afe08..2c5668f161 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,24 +15,134 @@ Increment the: ## [Unreleased] -* [BUILD] Fix misssing exported definition for OTLP file exporter and forceflush - [#3319](https://github.com/open-telemetry/opentelemetry-cpp/pull/3319) +* [API] Remove `WITH_ABSEIL` and `HAVE_ABSEIL` + [#3318](https://github.com/open-telemetry/opentelemetry-cpp/pull/3318) + +## [1.20 2025-04-01] + +* [BUILD] Update opentelemetry-proto version + [#3254](https://github.com/open-telemetry/opentelemetry-cpp/pull/3254) + +* [BUILD] Build break with CURL 7.29.0 + [#3255](https://github.com/open-telemetry/opentelemetry-cpp/pull/3255) + +* [SEMANTIC CONVENTIONS] Upgrade to semantic conventions 1.30.0 + [#3258](https://github.com/open-telemetry/opentelemetry-cpp/pull/3258) * [SDK] Add tracer scope configurator [#3137](https://github.com/open-telemetry/opentelemetry-cpp/pull/3137) +* [DOC] Add document and example for sharing gRPC Client + [#3260](https://github.com/open-telemetry/opentelemetry-cpp/pull/3260) + +* [SDK] Fix BatchLogRecordProcessor to instrument shutdown + [#3262](https://github.com/open-telemetry/opentelemetry-cpp/pull/3262) + * [SDK] Support OTEL_SDK_DISABLED environment variable [#3245](https://github.com/open-telemetry/opentelemetry-cpp/pull/3245) +* [CI] OTLP in Windows builds + [#3263](https://github.com/open-telemetry/opentelemetry-cpp/pull/3263) + +* [BUILD] Fixes compatibility of type_traits + [#3274](https://github.com/open-telemetry/opentelemetry-cpp/pull/3274) + +* [BUILD] Fix compilation with Regex being disabled + [#3276](https://github.com/open-telemetry/opentelemetry-cpp/pull/3276) + +* [EXPORTER] Support exporting event_name using OTLP Exporter + [#3277](https://github.com/open-telemetry/opentelemetry-cpp/pull/3277) + +* [CI] Add FOSSA scanning workflow + [#3279](https://github.com/open-telemetry/opentelemetry-cpp/pull/3279) + +* [BUILD] Adding typecast without whom c++latest build fails + [#3281](https://github.com/open-telemetry/opentelemetry-cpp/pull/3281) + +* [ADMIN] Add FOSSA badges + [#3280](https://github.com/open-telemetry/opentelemetry-cpp/pull/3280) + +* [BUILD] Fix compiling problems with abiv2 and MSVC + [#3284](https://github.com/open-telemetry/opentelemetry-cpp/pull/3284) + +* [BUILD] Enable old behavior of CMP0092 + [#3269](https://github.com/open-telemetry/opentelemetry-cpp/pull/3269) + * [SDK] Add meter scope configurator [#3268](https://github.com/open-telemetry/opentelemetry-cpp/pull/3268) * [DEVCONTAINER] Support customization and run as non-root user [#3270](https://github.com/open-telemetry/opentelemetry-cpp/pull/3270) +* [ETW] Add configuration to export 64-bit integer as timestamp + [#3286](https://github.com/open-telemetry/opentelemetry-cpp/pull/3286) + +* [API] Deprecate event logger + [#3285](https://github.com/open-telemetry/opentelemetry-cpp/pull/3285) + +* [BUILD] Add link directory to support curl 8.12 + [#3272](https://github.com/open-telemetry/opentelemetry-cpp/pull/3272) + +* [API] Change the param-pack unpacking order to start from left to right + [#3296](https://github.com/open-telemetry/opentelemetry-cpp/pull/3296) + +* [SDK] Implement spec: MetricFilter + [#3235](https://github.com/open-telemetry/opentelemetry-cpp/pull/3235) + +* [SEMANTIC CONVENTIONS] Upgrade semantic conventions to 1.31.0 + [#3297](https://github.com/open-telemetry/opentelemetry-cpp/pull/3297) + * [SDK] Add logger scope configurator [#3282](https://github.com/open-telemetry/opentelemetry-cpp/pull/3282) +* [EXAMPLE] fix buffer overrun in the gRPC sample project + [#3304](https://github.com/open-telemetry/opentelemetry-cpp/pull/3304) + +* [CI] Bump fossas/fossa-action from 1.5.0 to 1.6.0 + [#3305](https://github.com/open-telemetry/opentelemetry-cpp/pull/3305) + +* [TEST] fix segfault in singleton test with cmake on macos-latest + [#3316](https://github.com/open-telemetry/opentelemetry-cpp/pull/3316) + +* [TEST] fix test failure with elasticsearch exporter on cxx20 + [#3308](https://github.com/open-telemetry/opentelemetry-cpp/pull/3308) + +* [TEST] otlp grpc exporter retry test fix + [#3311](https://github.com/open-telemetry/opentelemetry-cpp/pull/3311) + +* [SDK] Use OPENTELEMETRY_EXPORT and static local variables + [#3314](https://github.com/open-telemetry/opentelemetry-cpp/pull/3314) + +* [BUILD] Fix elasticsearch exporter json compatibility + [#3313](https://github.com/open-telemetry/opentelemetry-cpp/pull/3313) + +* [BUILD] Fix missing exported definition for OTLP file exporter and forceflush + [#3319](https://github.com/open-telemetry/opentelemetry-cpp/pull/3319) + +* [BUILD] Remove gRPC header including in OtlpGrpcClientFactory + [#3321](https://github.com/open-telemetry/opentelemetry-cpp/pull/3321) + +* [ADMIN] Add Pranav Sharma in cpp-approvers + [#3323](https://github.com/open-telemetry/opentelemetry-cpp/pull/3323) + +* [DEVCONTAINER] fix grpc install + [#3325](https://github.com/open-telemetry/opentelemetry-cpp/pull/3325) + +* [ADMIN] Add dbarker to approvers + [#3331](https://github.com/open-telemetry/opentelemetry-cpp/pull/3331) + +* [CI] Upgrade CI to ubuntu 22.04 + [#3330](https://github.com/open-telemetry/opentelemetry-cpp/pull/3330) + +* [CI] Add ossf-scorecard scanning workflow + [#3332](https://github.com/open-telemetry/opentelemetry-cpp/pull/3332) + +* [CI] pin cmake in ci and devcontainer + [#3336](https://github.com/open-telemetry/opentelemetry-cpp/pull/3336) + +* [METRICS SDK] Fix hash collision in MetricAttributes + [#3322](https://github.com/open-telemetry/opentelemetry-cpp/pull/3322) + Important changes: * [SDK] Support OTEL_SDK_DISABLED environment variable @@ -52,9 +162,6 @@ Important changes: * All the example code has been updated to reflect the new usage. -* [SDK] Implement spec: MetricFilter - [#3235](https://github.com/open-telemetry/opentelemetry-cpp/pull/3235) - ## [1.19 2025-01-22] * [PROMETHEUS_EXPORTER] Fix default for emitting otel_scope attributes diff --git a/CMakeLists.txt b/CMakeLists.txt index dc0a3af9db..0bee414678 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -188,8 +188,6 @@ set(WITH_STL option(WITH_GSL "Whether to use Guidelines Support Library for C++ latest features" OFF) -option(WITH_ABSEIL "Whether to use Abseil for C++latest features" OFF) - set(OPENTELEMETRY_INSTALL_default ON) if(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) set(OPENTELEMETRY_INSTALL_default OFF) @@ -400,10 +398,8 @@ if(WITH_PROMETHEUS) endif() endif() -if(WITH_ABSEIL) - if(NOT TARGET absl::strings) - find_package(absl CONFIG REQUIRED) - endif() +if(WITH_OTLP_GRPC) + find_package(absl CONFIG REQUIRED) endif() if(WITH_OTLP_GRPC diff --git a/api/BUILD b/api/BUILD index dfc7d3c645..fb31393569 100644 --- a/api/BUILD +++ b/api/BUILD @@ -23,7 +23,7 @@ string_flag( cc_library( name = "api", hdrs = glob(["include/**/*.h"]), - defines = ["HAVE_ABSEIL"] + select({ + defines = select({ ":set_cxx_stdlib_none": [], ### automatic selection ":set_cxx_stdlib_best": ["OPENTELEMETRY_STL_VERSION=(__cplusplus/100)"], diff --git a/api/CMakeLists.txt b/api/CMakeLists.txt index 78b924681f..4d7e4542b0 100644 --- a/api/CMakeLists.txt +++ b/api/CMakeLists.txt @@ -35,21 +35,6 @@ if(WITH_NO_DEPRECATED_CODE) INTERFACE OPENTELEMETRY_NO_DEPRECATED_CODE) endif() -if(WITH_ABSEIL) - target_compile_definitions(opentelemetry_api INTERFACE HAVE_ABSEIL) - target_link_libraries( - opentelemetry_api INTERFACE absl::bad_variant_access absl::any absl::base - absl::bits absl::city) - list( - APPEND - TARGET_DEPS - "absl_bad_variant_access" - "absl_any" - "absl_base" - "absl_bits" - "absl_city") -endif() - if(WITH_STL STREQUAL "OFF") message(STATUS "Building WITH_STL=OFF") elseif(WITH_STL STREQUAL "CXX11") diff --git a/api/include/opentelemetry/nostd/variant.h b/api/include/opentelemetry/nostd/variant.h index b03a9b844b..4abac7766a 100644 --- a/api/include/opentelemetry/nostd/variant.h +++ b/api/include/opentelemetry/nostd/variant.h @@ -14,13 +14,12 @@ #if !defined(OPENTELEMETRY_HAVE_STD_VARIANT) -# ifndef HAVE_ABSEIL // We use a LOCAL snapshot of Abseil that is known to compile with Visual Studio 2015. // Header-only. Without compiling the actual Abseil binary. As Abseil moves on to new // toolchains, it may drop support for Visual Studio 2015 in future versions. -# if defined(__EXCEPTIONS) -# include +# if defined(__EXCEPTIONS) +# include OPENTELEMETRY_BEGIN_NAMESPACE namespace nostd { @@ -37,10 +36,9 @@ class bad_variant_access : public std::exception } } // namespace nostd OPENTELEMETRY_END_NAMESPACE -# define THROW_BAD_VARIANT_ACCESS opentelemetry::nostd::throw_bad_variant_access() -# else -# define THROW_BAD_VARIANT_ACCESS std::terminate() -# endif +# define THROW_BAD_VARIANT_ACCESS opentelemetry::nostd::throw_bad_variant_access() +# else +# define THROW_BAD_VARIANT_ACCESS std::terminate() # endif # ifdef _MSC_VER @@ -51,10 +49,7 @@ OPENTELEMETRY_END_NAMESPACE # pragma warning(disable : 4127) // conditional expression is constant # endif -# ifdef HAVE_ABSEIL -# include "absl/types/variant.h" -# else -# include "opentelemetry/nostd/internal/absl/base/options.h" +# include "opentelemetry/nostd/internal/absl/base/options.h" namespace absl { @@ -67,8 +62,7 @@ class variant; } // namespace OTABSL_OPTION_NAMESPACE_NAME } // namespace absl -# include "opentelemetry/nostd/internal/absl/types/variant.h" -# endif +# include "opentelemetry/nostd/internal/absl/types/variant.h" # ifdef _MSC_VER # pragma warning(pop) @@ -77,17 +71,6 @@ class variant; OPENTELEMETRY_BEGIN_NAMESPACE namespace nostd { -# ifdef HAVE_ABSEIL -using absl::bad_variant_access; -using absl::get; -using absl::get_if; -using absl::holds_alternative; -using absl::monostate; -using absl::variant; -using absl::variant_alternative_t; -using absl::variant_size; -using absl::visit; -# else using absl::OTABSL_OPTION_NAMESPACE_NAME::get; using absl::OTABSL_OPTION_NAMESPACE_NAME::get_if; using absl::OTABSL_OPTION_NAMESPACE_NAME::holds_alternative; @@ -96,7 +79,6 @@ using absl::OTABSL_OPTION_NAMESPACE_NAME::variant; using absl::OTABSL_OPTION_NAMESPACE_NAME::variant_alternative_t; using absl::OTABSL_OPTION_NAMESPACE_NAME::variant_size; using absl::OTABSL_OPTION_NAMESPACE_NAME::visit; -# endif } // namespace nostd OPENTELEMETRY_END_NAMESPACE diff --git a/api/include/opentelemetry/version.h b/api/include/opentelemetry/version.h index c69f6d4df9..03a2d83956 100644 --- a/api/include/opentelemetry/version.h +++ b/api/include/opentelemetry/version.h @@ -10,9 +10,9 @@ # define OPENTELEMETRY_ABI_VERSION_NO 1 #endif -#define OPENTELEMETRY_VERSION "1.19.0" +#define OPENTELEMETRY_VERSION "1.20.0" #define OPENTELEMETRY_VERSION_MAJOR 1 -#define OPENTELEMETRY_VERSION_MINOR 19 +#define OPENTELEMETRY_VERSION_MINOR 20 #define OPENTELEMETRY_VERSION_PATCH 0 #define OPENTELEMETRY_ABI_VERSION OPENTELEMETRY_STRINGIFY(OPENTELEMETRY_ABI_VERSION_NO) diff --git a/cmake/opentelemetry-cpp-config.cmake.in b/cmake/opentelemetry-cpp-config.cmake.in index 254bcc662b..db801b7499 100644 --- a/cmake/opentelemetry-cpp-config.cmake.in +++ b/cmake/opentelemetry-cpp-config.cmake.in @@ -1,17 +1,13 @@ # Copyright The OpenTelemetry Authors # SPDX-License-Identifier: Apache-2.0 +#[[ #.rst: # opentelemetry-cpp-config.cmake # -------- # # Find the native opentelemetry-cpp includes and library. # -# Result Variables -# ^^^^^^^^^^^^^^^^ -# -# This module defines the following variables: -# # :: # # OPENTELEMETRY_CPP_INCLUDE_DIRS - Include directories of opentelemetry-cpp. @@ -52,10 +48,9 @@ # opentelemetry-cpp::http_client_curl - Imported target of opentelemetry-cpp::http_client_curl # opentelemetry-cpp::opentracing_shim - Imported target of opentelemetry-cpp::opentracing_shim # - +]] # ============================================================================= -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 +# Copyright The OpenTelemetry Authors SPDX-License-Identifier: Apache-2.0 # ============================================================================= set(OPENTELEMETRY_ABI_VERSION_NO @@ -73,10 +68,6 @@ include(CMakeFindDependencyMacro) find_dependency(Threads) -if(@WITH_ABSEIL@) - find_dependency(absl) -endif() - if(@WITH_OTLP_GRPC@) find_dependency(gRPC) endif() @@ -93,7 +84,7 @@ if("@Protobuf_FOUND@" OR "@PROTOBUF_FOUND@") find_dependency(Protobuf) endif() -if (@WITH_HTTP_CLIENT_CURL@ AND NOT @BUILD_SHARED_LIBS@) +if(@WITH_HTTP_CLIENT_CURL@ AND NOT @BUILD_SHARED_LIBS@) if("@CURL_FOUND@") find_dependency(CURL) endif() @@ -103,7 +94,7 @@ if (@WITH_HTTP_CLIENT_CURL@ AND NOT @BUILD_SHARED_LIBS@) endif() endif() -if(@WITH_ABSEIL@ OR @WITH_OTLP_GRPC@) +if(@WITH_OTLP_GRPC@) find_package(absl CONFIG) elseif(@WITH_OTLP_HTTP@ OR @WITH_OTLP_FILE@) if("@Protobuf_VERSION@" VERSION_GREATER_EQUAL "3.22.0") diff --git a/cmake/opentelemetry-proto.cmake b/cmake/opentelemetry-proto.cmake index 06d6f76f69..d30e8d2293 100644 --- a/cmake/opentelemetry-proto.cmake +++ b/cmake/opentelemetry-proto.cmake @@ -286,11 +286,9 @@ add_custom_command( ${PROTOBUF_PROTOC_EXECUTABLE} ${PROTOBUF_COMMON_FLAGS} ${PROTOBUF_INCLUDE_FLAGS} ${COMMON_PROTO} ${RESOURCE_PROTO} ${TRACE_PROTO} ${LOGS_PROTO} ${METRICS_PROTO} ${TRACE_SERVICE_PROTO} ${LOGS_SERVICE_PROTO} - ${METRICS_SERVICE_PROTO} ${PROFILES_PROTO} - ${PROFILES_SERVICE_PROTO} + ${METRICS_SERVICE_PROTO} ${PROFILES_PROTO} ${PROFILES_SERVICE_PROTO} COMMENT "[Run]: ${PROTOBUF_RUN_PROTOC_COMMAND}" - DEPENDS ${PROTOBUF_PROTOC_EXECUTABLE} - ) + DEPENDS ${PROTOBUF_PROTOC_EXECUTABLE}) include_directories("${GENERATED_PROTOBUF_PATH}") @@ -343,7 +341,8 @@ if(WITH_OTLP_GRPC) set_target_version(opentelemetry_proto_grpc) # Disable include-what-you-use on generated code. - set_target_properties(opentelemetry_proto_grpc PROPERTIES CXX_INCLUDE_WHAT_YOU_USE "") + set_target_properties(opentelemetry_proto_grpc + PROPERTIES CXX_INCLUDE_WHAT_YOU_USE "") list(APPEND OPENTELEMETRY_PROTO_TARGETS opentelemetry_proto_grpc) target_link_libraries(opentelemetry_proto_grpc PUBLIC opentelemetry_proto) @@ -392,7 +391,6 @@ else() # cmake 3.8 or lower endif() if(WITH_OTLP_GRPC) - find_package(absl CONFIG) if(TARGET absl::synchronization) target_link_libraries(opentelemetry_proto_grpc PRIVATE absl::synchronization) diff --git a/cmake/patch-imported-config.cmake b/cmake/patch-imported-config.cmake index 25d6b2f78f..b49903eb29 100644 --- a/cmake/patch-imported-config.cmake +++ b/cmake/patch-imported-config.cmake @@ -29,7 +29,7 @@ if(TARGET CURL::libcurl endif() # abseil targets -if(WITH_ABSEIL OR WITH_OTLP_GRPC) +if(TARGET absl::bad_variant_access) project_build_tools_patch_default_imported_config( absl::bad_variant_access absl::raw_logging_internal diff --git a/docs/dependencies.md b/docs/dependencies.md index 6375ec79e2..8d19b6490b 100644 --- a/docs/dependencies.md +++ b/docs/dependencies.md @@ -34,9 +34,6 @@ Both these dependencies are listed here: .We don't use the std::span in this situation.Users can also define `OPENTELEMETRY_OPTION_USE_STD_SPAN=0` to indicate nostd:span will always not be a alias for std::span. - - Uses Abseil C++ Library for `absl::variant` as default `nostd::variant` if - `WITH_ABSEIL` cmake option (always enabled with bazel) - License: `Apache License 2.0` - [OTLP/HTTP+JSON](/exporters/otlp) exporter: diff --git a/docs/public/conf.py b/docs/public/conf.py index b1f3249d6b..ba81ac2f0b 100644 --- a/docs/public/conf.py +++ b/docs/public/conf.py @@ -24,7 +24,7 @@ author = 'OpenTelemetry authors' # The full version, including alpha/beta/rc tags -release = "1.19.0" +release = "1.20.0" # Run sphinx on subprojects and copy output # ----------------------------------------- diff --git a/examples/grpc/CMakeLists.txt b/examples/grpc/CMakeLists.txt index 015f4a2287..ea34e58364 100644 --- a/examples/grpc/CMakeLists.txt +++ b/examples/grpc/CMakeLists.txt @@ -42,7 +42,7 @@ else() target_link_libraries(example_grpc_proto PUBLIC gRPC::grpc++ ${Protobuf_LIBRARIES}) endif() -if(WITH_ABSEIL OR WITH_OTLP_GRPC) +if(WITH_OTLP_GRPC) target_link_libraries(example_grpc_proto PUBLIC absl::bad_variant_access) endif() diff --git a/exporters/otlp/CMakeLists.txt b/exporters/otlp/CMakeLists.txt index bccc15a8f8..126a62310c 100644 --- a/exporters/otlp/CMakeLists.txt +++ b/exporters/otlp/CMakeLists.txt @@ -41,7 +41,8 @@ if(WITH_OTLP_GRPC) PUBLIC opentelemetry_sdk opentelemetry_common opentelemetry_ext # gRPC::grpc++ must be linked before opentelemetry_proto_grpc. opentelemetry_proto_grpc - PRIVATE gRPC::grpc++) + PRIVATE gRPC::grpc++ absl::bad_variant_access absl::any absl::base + absl::bits absl::city) get_target_property(GRPC_INCLUDE_DIRECTORY gRPC::grpc++ INTERFACE_INCLUDE_DIRECTORIES) diff --git a/exporters/otlp/test/otlp_file_exporter_test.cc b/exporters/otlp/test/otlp_file_exporter_test.cc index ab67d1a478..d0c530f55a 100644 --- a/exporters/otlp/test/otlp_file_exporter_test.cc +++ b/exporters/otlp/test/otlp_file_exporter_test.cc @@ -108,9 +108,9 @@ class OtlpFileExporterTestPeer : public ::testing::Test std::string report_trace_id; #if OPENTELEMETRY_ABI_VERSION_NO >= 2 - auto tracer = provider->GetTracer("scope_name", "scope_version", "scope_url", - {{ "scope_key", - "scope_value" }}); + std::unordered_map scope_attributes; + scope_attributes["scope_key"] = common::AttributeValue("scope_value"); + auto tracer = provider->GetTracer("scope_name", "scope_version", "scope_url", scope_attributes); #else auto tracer = provider->GetTracer("scope_name", "scope_version", "scope_url"); #endif @@ -139,6 +139,12 @@ class OtlpFileExporterTestPeer : public ::testing::Test auto check_json_text = output.str(); if (!check_json_text.empty()) { + // If the exporting is splited to two standalone resource_span, just checking the first one. + std::string::size_type eol = check_json_text.find('\n'); + if (eol != std::string::npos) + { + check_json_text = check_json_text.substr(0, eol); + } auto check_json = nlohmann::json::parse(check_json_text, nullptr, false); if (!check_json.is_discarded()) { diff --git a/sdk/include/opentelemetry/sdk/common/attributemap_hash.h b/sdk/include/opentelemetry/sdk/common/attributemap_hash.h index 39df29b278..e56d6aaf75 100644 --- a/sdk/include/opentelemetry/sdk/common/attributemap_hash.h +++ b/sdk/include/opentelemetry/sdk/common/attributemap_hash.h @@ -10,10 +10,6 @@ #include #include -#include "opentelemetry/common/attribute_value.h" -#include "opentelemetry/common/key_value_iterable.h" -#include "opentelemetry/nostd/function_ref.h" -#include "opentelemetry/nostd/string_view.h" #include "opentelemetry/nostd/variant.h" #include "opentelemetry/sdk/common/attribute_utils.h" #include "opentelemetry/version.h" @@ -74,27 +70,6 @@ inline size_t GetHashForAttributeMap(const OrderedAttributeMap &attribute_map) return seed; } -// Calculate hash of keys and values of KeyValueIterable, filtered using callback. -inline size_t GetHashForAttributeMap( - const opentelemetry::common::KeyValueIterable &attributes, - nostd::function_ref is_key_present_callback) -{ - AttributeConverter converter; - size_t seed = 0UL; - attributes.ForEachKeyValue( - [&](nostd::string_view key, opentelemetry::common::AttributeValue value) noexcept { - if (!is_key_present_callback(key)) - { - return true; - } - GetHash(seed, key); - auto attr_val = nostd::visit(converter, value); - nostd::visit(GetHashForAttributeValueVisitor(seed), attr_val); - return true; - }); - return seed; -} - template inline size_t GetHash(T value) { diff --git a/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir_cell.h b/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir_cell.h index 03941870c0..cc315b7131 100644 --- a/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir_cell.h +++ b/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir_cell.h @@ -125,6 +125,7 @@ class ReservoirCell res.erase(it); } } + res.UpdateHash(); return res; } diff --git a/sdk/include/opentelemetry/sdk/metrics/instruments.h b/sdk/include/opentelemetry/sdk/metrics/instruments.h index 76ad07b2e3..6473a267f2 100644 --- a/sdk/include/opentelemetry/sdk/metrics/instruments.h +++ b/sdk/include/opentelemetry/sdk/metrics/instruments.h @@ -65,6 +65,7 @@ struct InstrumentDescriptor }; using MetricAttributes = opentelemetry::sdk::metrics::FilteredOrderedAttributeMap; +using MetricAttributesHash = opentelemetry::sdk::metrics::FilteredOrderedAttributeMapHash; using AggregationTemporalitySelector = std::function; /*class InstrumentSelector { diff --git a/sdk/include/opentelemetry/sdk/metrics/state/async_metric_storage.h b/sdk/include/opentelemetry/sdk/metrics/state/async_metric_storage.h index 14e9a3fbfa..93ffccc48c 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/async_metric_storage.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/async_metric_storage.h @@ -71,24 +71,22 @@ class AsyncMetricStorage : public MetricStorage, public AsyncWritableMetricStora auto aggr = DefaultAggregation::CreateAggregation(aggregation_type_, instrument_descriptor_); aggr->Aggregate(measurement.second); - auto hash = opentelemetry::sdk::common::GetHashForAttributeMap(measurement.first); - auto prev = cumulative_hash_map_->Get(hash); + auto prev = cumulative_hash_map_->Get(measurement.first); if (prev) { auto delta = prev->Diff(*aggr); // store received value in cumulative map, and the diff in delta map (to pass it to temporal // storage) - cumulative_hash_map_->Set(measurement.first, std::move(aggr), hash); - delta_hash_map_->Set(measurement.first, std::move(delta), hash); + cumulative_hash_map_->Set(measurement.first, std::move(aggr)); + delta_hash_map_->Set(measurement.first, std::move(delta)); } else { // store received value in cumulative and delta map. cumulative_hash_map_->Set( measurement.first, - DefaultAggregation::CloneAggregation(aggregation_type_, instrument_descriptor_, *aggr), - hash); - delta_hash_map_->Set(measurement.first, std::move(aggr), hash); + DefaultAggregation::CloneAggregation(aggregation_type_, instrument_descriptor_, *aggr)); + delta_hash_map_->Set(measurement.first, std::move(aggr)); } } } diff --git a/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h b/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h index ddf2a8b206..bcc7610aae 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h @@ -15,6 +15,7 @@ #include "opentelemetry/sdk/common/attribute_utils.h" #include "opentelemetry/sdk/common/attributemap_hash.h" #include "opentelemetry/sdk/metrics/aggregation/aggregation.h" +#include "opentelemetry/sdk/metrics/state/filtered_ordered_attribute_map.h" #include "opentelemetry/sdk/metrics/view/attributes_processor.h" #include "opentelemetry/version.h" @@ -29,9 +30,9 @@ using opentelemetry::sdk::common::OrderedAttributeMap; constexpr size_t kAggregationCardinalityLimit = 2000; const std::string kAttributesLimitOverflowKey = "otel.metrics.overflow"; const bool kAttributesLimitOverflowValue = true; -const size_t kOverflowAttributesHash = opentelemetry::sdk::common::GetHashForAttributeMap( - {{kAttributesLimitOverflowKey, - kAttributesLimitOverflowValue}}); // precalculated for optimization +const MetricAttributes kOverflowAttributes = { + {kAttributesLimitOverflowKey, + kAttributesLimitOverflowValue}}; // precalculated for optimization class AttributeHashGenerator { @@ -42,18 +43,19 @@ class AttributeHashGenerator } }; -class AttributesHashMap +template +class AttributesHashMapWithCustomHash { public: - AttributesHashMap(size_t attributes_limit = kAggregationCardinalityLimit) + AttributesHashMapWithCustomHash(size_t attributes_limit = kAggregationCardinalityLimit) : attributes_limit_(attributes_limit) {} - Aggregation *Get(size_t hash) const + Aggregation *Get(const MetricAttributes &attributes) const { - auto it = hash_map_.find(hash); + auto it = hash_map_.find(attributes); if (it != hash_map_.end()) { - return it->second.second.get(); + return it->second.get(); } return nullptr; } @@ -62,7 +64,10 @@ class AttributesHashMap * @return check if key is present in hash * */ - bool Has(size_t hash) const { return hash_map_.find(hash) != hash_map_.end(); } + bool Has(const MetricAttributes &attributes) const + { + return hash_map_.find(attributes) != hash_map_.end(); + } /** * @return the pointer to value for given key if present. @@ -71,13 +76,16 @@ class AttributesHashMap */ Aggregation *GetOrSetDefault(const opentelemetry::common::KeyValueIterable &attributes, const AttributesProcessor *attributes_processor, - std::function()> aggregation_callback, - size_t hash) + std::function()> aggregation_callback) { - auto it = hash_map_.find(hash); + // TODO: avoid constructing MetricAttributes from KeyValueIterable for + // hash_map_.find which is a heavy operation + MetricAttributes attr{attributes, attributes_processor}; + + auto it = hash_map_.find(attr); if (it != hash_map_.end()) { - return it->second.second.get(); + return it->second.get(); } if (IsOverflowAttributes()) @@ -85,19 +93,17 @@ class AttributesHashMap return GetOrSetOveflowAttributes(aggregation_callback); } - MetricAttributes attr{attributes, attributes_processor}; - - hash_map_[hash] = {attr, aggregation_callback()}; - return hash_map_[hash].second.get(); + auto result = hash_map_.emplace(std::move(attr), aggregation_callback()); + return result.first->second.get(); } - Aggregation *GetOrSetDefault(std::function()> aggregation_callback, - size_t hash) + Aggregation *GetOrSetDefault(const MetricAttributes &attributes, + std::function()> aggregation_callback) { - auto it = hash_map_.find(hash); + auto it = hash_map_.find(attributes); if (it != hash_map_.end()) { - return it->second.second.get(); + return it->second.get(); } if (IsOverflowAttributes()) @@ -105,19 +111,17 @@ class AttributesHashMap return GetOrSetOveflowAttributes(aggregation_callback); } - MetricAttributes attr{}; - hash_map_[hash] = {attr, aggregation_callback()}; - return hash_map_[hash].second.get(); + hash_map_[attributes] = aggregation_callback(); + return hash_map_[attributes].get(); } - Aggregation *GetOrSetDefault(const MetricAttributes &attributes, - std::function()> aggregation_callback, - size_t hash) + Aggregation *GetOrSetDefault(MetricAttributes &&attributes, + std::function()> aggregation_callback) { - auto it = hash_map_.find(hash); + auto it = hash_map_.find(attributes); if (it != hash_map_.end()) { - return it->second.second.get(); + return it->second.get(); } if (IsOverflowAttributes()) @@ -125,54 +129,50 @@ class AttributesHashMap return GetOrSetOveflowAttributes(aggregation_callback); } - MetricAttributes attr{attributes}; - - hash_map_[hash] = {attr, aggregation_callback()}; - return hash_map_[hash].second.get(); + auto result = hash_map_.emplace(std::move(attributes), aggregation_callback()); + return result.first->second.get(); } - /** * Set the value for given key, overwriting the value if already present */ void Set(const opentelemetry::common::KeyValueIterable &attributes, const AttributesProcessor *attributes_processor, - std::unique_ptr aggr, - size_t hash) + std::unique_ptr aggr) + { + Set(MetricAttributes{attributes, attributes_processor}, std::move(aggr)); + } + + void Set(const MetricAttributes &attributes, std::unique_ptr aggr) { - auto it = hash_map_.find(hash); + auto it = hash_map_.find(attributes); if (it != hash_map_.end()) { - it->second.second = std::move(aggr); + it->second = std::move(aggr); } else if (IsOverflowAttributes()) { - hash_map_[kOverflowAttributesHash] = { - MetricAttributes{{kAttributesLimitOverflowKey, kAttributesLimitOverflowValue}}, - std::move(aggr)}; + hash_map_[kOverflowAttributes] = std::move(aggr); } else { - MetricAttributes attr{attributes, attributes_processor}; - hash_map_[hash] = {attr, std::move(aggr)}; + hash_map_[attributes] = std::move(aggr); } } - void Set(const MetricAttributes &attributes, std::unique_ptr aggr, size_t hash) + void Set(MetricAttributes &&attributes, std::unique_ptr aggr) { - auto it = hash_map_.find(hash); + auto it = hash_map_.find(attributes); if (it != hash_map_.end()) { - it->second.second = std::move(aggr); + it->second = std::move(aggr); } else if (IsOverflowAttributes()) { - hash_map_[kOverflowAttributesHash] = { - MetricAttributes{{kAttributesLimitOverflowKey, kAttributesLimitOverflowValue}}, - std::move(aggr)}; + hash_map_[kOverflowAttributes] = std::move(aggr); } else { - hash_map_[hash] = {attributes, std::move(aggr)}; + hash_map_[std::move(attributes)] = std::move(aggr); } } @@ -184,7 +184,7 @@ class AttributesHashMap { for (auto &kv : hash_map_) { - if (!callback(kv.second.first, *(kv.second.second.get()))) + if (!callback(kv.first, *(kv.second.get()))) { return false; // callback is not prepared to consume data } @@ -197,8 +197,13 @@ class AttributesHashMap */ size_t Size() { return hash_map_.size(); } +#ifdef UNIT_TESTING + size_t BucketCount() { return hash_map_.bucket_count(); } + size_t BucketSize(size_t n) { return hash_map_.bucket_size(n); } +#endif + private: - std::unordered_map>> hash_map_; + std::unordered_map, CustomHash> hash_map_; size_t attributes_limit_; Aggregation *GetOrSetOveflowAttributes( @@ -210,19 +215,21 @@ class AttributesHashMap Aggregation *GetOrSetOveflowAttributes(std::unique_ptr agg) { - auto it = hash_map_.find(kOverflowAttributesHash); + auto it = hash_map_.find(kOverflowAttributes); if (it != hash_map_.end()) { - return it->second.second.get(); + return it->second.get(); } - MetricAttributes attr{{kAttributesLimitOverflowKey, kAttributesLimitOverflowValue}}; - hash_map_[kOverflowAttributesHash] = {attr, std::move(agg)}; - return hash_map_[kOverflowAttributesHash].second.get(); + auto result = hash_map_.emplace(kOverflowAttributes, std::move(agg)); + return result.first->second.get(); } bool IsOverflowAttributes() const { return (hash_map_.size() + 1 >= attributes_limit_); } }; + +using AttributesHashMap = AttributesHashMapWithCustomHash<>; + } // namespace metrics } // namespace sdk diff --git a/sdk/include/opentelemetry/sdk/metrics/state/filtered_ordered_attribute_map.h b/sdk/include/opentelemetry/sdk/metrics/state/filtered_ordered_attribute_map.h index 329e75bfa7..6a0562e0e9 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/filtered_ordered_attribute_map.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/filtered_ordered_attribute_map.h @@ -3,13 +3,21 @@ #pragma once +#include +#include +#include #include +#include +#include +#include #include - +#include #include "opentelemetry/common/attribute_value.h" #include "opentelemetry/common/key_value_iterable.h" #include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/nostd/variant.h" #include "opentelemetry/sdk/common/attribute_utils.h" +#include "opentelemetry/sdk/common/attributemap_hash.h" #include "opentelemetry/version.h" OPENTELEMETRY_BEGIN_NAMESPACE @@ -22,22 +30,65 @@ class AttributesProcessor; // IWYU pragma: keep class FilteredOrderedAttributeMap : public opentelemetry::sdk::common::OrderedAttributeMap { public: - FilteredOrderedAttributeMap() = default; + FilteredOrderedAttributeMap() : OrderedAttributeMap() { UpdateHash(); } + FilteredOrderedAttributeMap( std::initializer_list> attributes) : OrderedAttributeMap(attributes) - {} + { + UpdateHash(); + } + FilteredOrderedAttributeMap(const opentelemetry::common::KeyValueIterable &attributes) : FilteredOrderedAttributeMap(attributes, nullptr) - {} + { + // No need to update hash here as it is already updated in the constructor above + } + FilteredOrderedAttributeMap(const opentelemetry::common::KeyValueIterable &attributes, const opentelemetry::sdk::metrics::AttributesProcessor *processor); + FilteredOrderedAttributeMap( std::initializer_list> attributes, const opentelemetry::sdk::metrics::AttributesProcessor *processor); + + // + // Copy and move constructors, assignment operators + // + FilteredOrderedAttributeMap(const FilteredOrderedAttributeMap &other) = default; + FilteredOrderedAttributeMap(FilteredOrderedAttributeMap &&other) = default; + FilteredOrderedAttributeMap &operator=(const FilteredOrderedAttributeMap &other) = default; + FilteredOrderedAttributeMap &operator=(FilteredOrderedAttributeMap &&other) = default; + + // + // equality operator + // + bool operator==(const FilteredOrderedAttributeMap &other) const + { + return hash_ == other.hash_ && static_cast(*this) == + static_cast(other); + } + + size_t GetHash() const { return hash_; } + + void UpdateHash() { hash_ = GetHashForAttributeMap(*this); } + +private: + size_t hash_ = (std::numeric_limits::max)(); }; + +class FilteredOrderedAttributeMapHash +{ +public: + size_t operator()( + const opentelemetry::sdk::metrics::FilteredOrderedAttributeMap &attributes) const + { + return attributes.GetHash(); + } +}; + } // namespace metrics } // namespace sdk OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h b/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h index 6e5b799e3f..0c9dea9c90 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h @@ -95,9 +95,9 @@ class SyncMetricStorage : public MetricStorage, public SyncWritableMetricStorage exemplar_reservoir_->OfferMeasurement(value, {}, context, std::chrono::system_clock::now()); } #endif - static size_t hash = opentelemetry::sdk::common::GetHash(""); + static MetricAttributes attr = MetricAttributes{}; std::lock_guard guard(attribute_hashmap_lock_); - attributes_hashmap_->GetOrSetDefault(create_default_aggregation_, hash)->Aggregate(value); + attributes_hashmap_->GetOrSetDefault(attr, create_default_aggregation_)->Aggregate(value); } void RecordLong(int64_t value, @@ -116,21 +116,10 @@ class SyncMetricStorage : public MetricStorage, public SyncWritableMetricStorage std::chrono::system_clock::now()); } #endif - auto hash = opentelemetry::sdk::common::GetHashForAttributeMap( - attributes, [this](nostd::string_view key) { - if (attributes_processor_) - { - return attributes_processor_->isPresent(key); - } - else - { - return true; - } - }); std::lock_guard guard(attribute_hashmap_lock_); attributes_hashmap_ - ->GetOrSetDefault(attributes, attributes_processor_, create_default_aggregation_, hash) + ->GetOrSetDefault(attributes, attributes_processor_, create_default_aggregation_) ->Aggregate(value); } @@ -148,9 +137,9 @@ class SyncMetricStorage : public MetricStorage, public SyncWritableMetricStorage exemplar_reservoir_->OfferMeasurement(value, {}, context, std::chrono::system_clock::now()); } #endif - static size_t hash = opentelemetry::sdk::common::GetHash(""); + static MetricAttributes attr = MetricAttributes{}; std::lock_guard guard(attribute_hashmap_lock_); - attributes_hashmap_->GetOrSetDefault(create_default_aggregation_, hash)->Aggregate(value); + attributes_hashmap_->GetOrSetDefault(attr, create_default_aggregation_)->Aggregate(value); } void RecordDouble(double value, @@ -169,20 +158,9 @@ class SyncMetricStorage : public MetricStorage, public SyncWritableMetricStorage std::chrono::system_clock::now()); } #endif - auto hash = opentelemetry::sdk::common::GetHashForAttributeMap( - attributes, [this](nostd::string_view key) { - if (attributes_processor_) - { - return attributes_processor_->isPresent(key); - } - else - { - return true; - } - }); std::lock_guard guard(attribute_hashmap_lock_); attributes_hashmap_ - ->GetOrSetDefault(attributes, attributes_processor_, create_default_aggregation_, hash) + ->GetOrSetDefault(attributes, attributes_processor_, create_default_aggregation_) ->Aggregate(value); } diff --git a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h index 4e20e7d65f..7ab8cafb13 100644 --- a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h +++ b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h @@ -87,6 +87,8 @@ class FilteringAttributesProcessor : public AttributesProcessor } return true; }); + + result.UpdateHash(); return result; } diff --git a/sdk/include/opentelemetry/sdk/version/version.h b/sdk/include/opentelemetry/sdk/version/version.h index b462144e20..0adaf79676 100644 --- a/sdk/include/opentelemetry/sdk/version/version.h +++ b/sdk/include/opentelemetry/sdk/version/version.h @@ -3,7 +3,7 @@ #pragma once -#define OPENTELEMETRY_SDK_VERSION "1.19.0" +#define OPENTELEMETRY_SDK_VERSION "1.20.0" #include "opentelemetry/version.h" diff --git a/sdk/src/common/CMakeLists.txt b/sdk/src/common/CMakeLists.txt index 06b3c88c1e..db36266a4f 100644 --- a/sdk/src/common/CMakeLists.txt +++ b/sdk/src/common/CMakeLists.txt @@ -18,7 +18,7 @@ target_link_libraries( opentelemetry_common PUBLIC opentelemetry_api opentelemetry_sdk Threads::Threads) -if(WITH_ABSEIL OR WITH_OTLP_GRPC) +if(WITH_OTLP_GRPC) target_link_libraries(opentelemetry_common PUBLIC absl::strings) endif() diff --git a/sdk/src/common/base64.cc b/sdk/src/common/base64.cc index a78b88ad68..b6da954677 100644 --- a/sdk/src/common/base64.cc +++ b/sdk/src/common/base64.cc @@ -11,16 +11,11 @@ #include #include -#if defined(HAVE_ABSEIL) -# include "absl/strings/escaping.h" -#endif - OPENTELEMETRY_BEGIN_NAMESPACE namespace sdk { namespace common { -#if !defined(HAVE_ABSEIL) namespace { using Base64EscapeChars = const unsigned char[64]; @@ -145,11 +140,11 @@ static inline int Base64EscapeInternal(std::string &dest, int ret = Base64EscapeInternal(reinterpret_cast(&dest[0]), dest.size(), &olen, src, slen, base64_enc_map, padding_char); -# if defined(HAVE_GSL) +#if defined(HAVE_GSL) Expects(0 != ret || dest.size() == olen + 1); -# else +#else assert(0 != ret || dest.size() == olen + 1); -# endif +#endif // pop back last zero if (!dest.empty() && *dest.rbegin() == 0) { @@ -278,7 +273,6 @@ static int Base64UnescapeInternal(unsigned char *dst, } } // namespace -#endif // Base64Escape() // @@ -292,12 +286,8 @@ OPENTELEMETRY_EXPORT void Base64Escape(opentelemetry::nostd::string_view src, st return; } -#if defined(HAVE_ABSEIL) - absl::Base64Escape(absl::string_view{src.data(), src.size()}, dest); -#else Base64EscapeInternal(*dest, reinterpret_cast(src.data()), src.size(), kBase64EscapeCharsBasic, '='); -#endif } OPENTELEMETRY_EXPORT std::string Base64Escape(opentelemetry::nostd::string_view src) @@ -315,9 +305,6 @@ OPENTELEMETRY_EXPORT bool Base64Unescape(opentelemetry::nostd::string_view src, return false; } -#if defined(HAVE_ABSEIL) - return absl::Base64Unescape(absl::string_view{src.data(), src.size()}, dest); -#else if (src.empty()) { return true; @@ -337,7 +324,6 @@ OPENTELEMETRY_EXPORT bool Base64Unescape(opentelemetry::nostd::string_view src, reinterpret_cast(src.data()), src.size(), kBase64UnescapeCharsBasic, '='); return true; -#endif } } // namespace common diff --git a/sdk/src/metrics/state/filtered_ordered_attribute_map.cc b/sdk/src/metrics/state/filtered_ordered_attribute_map.cc index baed0fce9a..85f4bc9d6e 100644 --- a/sdk/src/metrics/state/filtered_ordered_attribute_map.cc +++ b/sdk/src/metrics/state/filtered_ordered_attribute_map.cc @@ -3,6 +3,7 @@ #include "opentelemetry/sdk/metrics/state/filtered_ordered_attribute_map.h" #include "opentelemetry/nostd/function_ref.h" +#include "opentelemetry/sdk/common/attribute_utils.h" #include "opentelemetry/sdk/metrics/view/attributes_processor.h" OPENTELEMETRY_BEGIN_NAMESPACE @@ -23,6 +24,8 @@ FilteredOrderedAttributeMap::FilteredOrderedAttributeMap( } return true; }); + + UpdateHash(); } FilteredOrderedAttributeMap::FilteredOrderedAttributeMap( @@ -38,6 +41,8 @@ FilteredOrderedAttributeMap::FilteredOrderedAttributeMap( SetAttribute(kv.first, kv.second); } } + + UpdateHash(); } } // namespace metrics } // namespace sdk diff --git a/sdk/src/metrics/state/observable_registry.cc b/sdk/src/metrics/state/observable_registry.cc index 8db11d4605..d8d6afb01b 100644 --- a/sdk/src/metrics/state/observable_registry.cc +++ b/sdk/src/metrics/state/observable_registry.cc @@ -3,10 +3,8 @@ #include #include -#include #include #include -#include #include #include @@ -14,7 +12,6 @@ #include "opentelemetry/metrics/async_instruments.h" #include "opentelemetry/metrics/observer_result.h" #include "opentelemetry/nostd/shared_ptr.h" -#include "opentelemetry/nostd/variant.h" #include "opentelemetry/sdk/common/global_log_handler.h" #include "opentelemetry/sdk/metrics/async_instruments.h" #include "opentelemetry/sdk/metrics/instruments.h" diff --git a/sdk/src/metrics/state/temporal_metric_storage.cc b/sdk/src/metrics/state/temporal_metric_storage.cc index 1302f9d642..d027c9883c 100644 --- a/sdk/src/metrics/state/temporal_metric_storage.cc +++ b/sdk/src/metrics/state/temporal_metric_storage.cc @@ -13,7 +13,6 @@ #include "opentelemetry/common/timestamp.h" #include "opentelemetry/nostd/function_ref.h" #include "opentelemetry/nostd/span.h" -#include "opentelemetry/sdk/common/attributemap_hash.h" #include "opentelemetry/sdk/metrics/aggregation/aggregation.h" #include "opentelemetry/sdk/metrics/aggregation/aggregation_config.h" #include "opentelemetry/sdk/metrics/aggregation/default_aggregation.h" @@ -104,19 +103,17 @@ bool TemporalMetricStorage::buildMetrics(CollectorHandle *collector, { agg_hashmap->GetAllEnteries( [&merged_metrics, this](const MetricAttributes &attributes, Aggregation &aggregation) { - auto hash = opentelemetry::sdk::common::GetHashForAttributeMap(attributes); - auto agg = merged_metrics->Get(hash); + auto agg = merged_metrics->Get(attributes); if (agg) { - merged_metrics->Set(attributes, agg->Merge(aggregation), hash); + merged_metrics->Set(attributes, agg->Merge(aggregation)); } else { merged_metrics->Set(attributes, DefaultAggregation::CreateAggregation( aggregation_type_, instrument_descriptor_, aggregation_config_) - ->Merge(aggregation), - hash); + ->Merge(aggregation)); } return true; }); @@ -139,17 +136,16 @@ bool TemporalMetricStorage::buildMetrics(CollectorHandle *collector, // merge current delta to previous cumulative last_aggr_hashmap->GetAllEnteries( [&merged_metrics, this](const MetricAttributes &attributes, Aggregation &aggregation) { - auto hash = opentelemetry::sdk::common::GetHashForAttributeMap(attributes); - auto agg = merged_metrics->Get(hash); + auto agg = merged_metrics->Get(attributes); if (agg) { - merged_metrics->Set(attributes, agg->Merge(aggregation), hash); + merged_metrics->Set(attributes, agg->Merge(aggregation)); } else { auto def_agg = DefaultAggregation::CreateAggregation( aggregation_type_, instrument_descriptor_, aggregation_config_); - merged_metrics->Set(attributes, def_agg->Merge(aggregation), hash); + merged_metrics->Set(attributes, def_agg->Merge(aggregation)); } return true; }); diff --git a/sdk/src/version/version.cc b/sdk/src/version/version.cc index edcaedb9aa..30ad55db61 100644 --- a/sdk/src/version/version.cc +++ b/sdk/src/version/version.cc @@ -12,13 +12,13 @@ namespace sdk namespace version { const int major_version = 1; -const int minor_version = 19; +const int minor_version = 20; const int patch_version = 0; const char *pre_release = "NONE"; const char *build_metadata = "NONE"; -const char *short_version = "1.19.0"; -const char *full_version = "1.18.0-NONE-NONE"; -const char *build_date = "Tue Jan 21 09:34:26 PM UTC 2025"; +const char *short_version = "1.20.0"; +const char *full_version = "1.20.0-NONE-NONE"; +const char *build_date = "Tue Apr 1 08:14:47 PM UTC 2025"; } // namespace version } // namespace sdk OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/test/metrics/BUILD b/sdk/test/metrics/BUILD index 929511a89b..519cb1fc1f 100644 --- a/sdk/test/metrics/BUILD +++ b/sdk/test/metrics/BUILD @@ -36,6 +36,9 @@ cc_test( cc_test( name = "all_tests", srcs = glob(["*_test.cc"]), + copts = [ + "-DUNIT_TESTING", + ], tags = [ "metrics", "test", diff --git a/sdk/test/metrics/CMakeLists.txt b/sdk/test/metrics/CMakeLists.txt index 4e09af4d2e..79b8c28a2f 100644 --- a/sdk/test/metrics/CMakeLists.txt +++ b/sdk/test/metrics/CMakeLists.txt @@ -38,6 +38,7 @@ foreach( target_link_libraries( ${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} metrics_common_test_utils opentelemetry_resources) + target_compile_definitions(${testname} PRIVATE UNIT_TESTING) gtest_add_tests( TARGET ${testname} TEST_PREFIX metrics. diff --git a/sdk/test/metrics/attributes_hashmap_benchmark.cc b/sdk/test/metrics/attributes_hashmap_benchmark.cc index 8c4bc69f9e..8225f8ba12 100644 --- a/sdk/test/metrics/attributes_hashmap_benchmark.cc +++ b/sdk/test/metrics/attributes_hashmap_benchmark.cc @@ -11,11 +11,9 @@ #include #include -#include "opentelemetry/sdk/common/attributemap_hash.h" #include "opentelemetry/sdk/metrics/aggregation/aggregation.h" #include "opentelemetry/sdk/metrics/aggregation/drop_aggregation.h" #include "opentelemetry/sdk/metrics/state/attributes_hashmap.h" -#include "opentelemetry/sdk/metrics/state/filtered_ordered_attribute_map.h" #include "opentelemetry/sdk/metrics/view/attributes_processor.h" using namespace opentelemetry::sdk::metrics; @@ -39,10 +37,9 @@ void BM_AttributseHashMap(benchmark::State &state) return std::unique_ptr(new DropAggregation); }; m.lock(); - auto hash = opentelemetry::sdk::common::GetHashForAttributeMap(attributes[i % 2]); - hash_map.GetOrSetDefault(attributes[i % 2], create_default_aggregation, hash) + hash_map.GetOrSetDefault(attributes[i % 2], create_default_aggregation) ->Aggregate(static_cast(1)); - benchmark::DoNotOptimize(hash_map.Has(hash)); + benchmark::DoNotOptimize(hash_map.Has(attributes[i % 2])); m.unlock(); }; while (state.KeepRunning()) diff --git a/sdk/test/metrics/attributes_hashmap_test.cc b/sdk/test/metrics/attributes_hashmap_test.cc index 153c6ada25..c51f4fe800 100644 --- a/sdk/test/metrics/attributes_hashmap_test.cc +++ b/sdk/test/metrics/attributes_hashmap_test.cc @@ -5,12 +5,10 @@ #include #include #include -#include #include #include #include -#include "opentelemetry/common/key_value_iterable_view.h" #include "opentelemetry/nostd/function_ref.h" #include "opentelemetry/nostd/string_view.h" #include "opentelemetry/sdk/common/attributemap_hash.h" @@ -28,34 +26,32 @@ TEST(AttributesHashMap, BasicTests) AttributesHashMap hash_map; EXPECT_EQ(hash_map.Size(), 0); MetricAttributes m1 = {{"k1", "v1"}}; - auto hash = opentelemetry::sdk::common::GetHashForAttributeMap(m1); - EXPECT_EQ(hash_map.Get(hash), nullptr); - EXPECT_EQ(hash_map.Has(hash), false); + EXPECT_EQ(hash_map.Get(m1), nullptr); + EXPECT_EQ(hash_map.Has(m1), false); // Set std::unique_ptr aggregation1( new DropAggregation()); // = std::unique_ptr(new DropAggregation); - hash_map.Set(m1, std::move(aggregation1), hash); - hash_map.Get(hash)->Aggregate(static_cast(1)); + hash_map.Set(m1, std::move(aggregation1)); + hash_map.Get(m1)->Aggregate(static_cast(1)); EXPECT_EQ(hash_map.Size(), 1); - EXPECT_EQ(hash_map.Has(hash), true); + EXPECT_EQ(hash_map.Has(m1), true); // Set same key again auto aggregation2 = std::unique_ptr(new DropAggregation()); - hash_map.Set(m1, std::move(aggregation2), hash); - hash_map.Get(hash)->Aggregate(static_cast(1)); + hash_map.Set(m1, std::move(aggregation2)); + hash_map.Get(m1)->Aggregate(static_cast(1)); EXPECT_EQ(hash_map.Size(), 1); - EXPECT_EQ(hash_map.Has(hash), true); + EXPECT_EQ(hash_map.Has(m1), true); // Set more enteria auto aggregation3 = std::unique_ptr(new DropAggregation()); MetricAttributes m3 = {{"k1", "v1"}, {"k2", "v2"}}; - auto hash3 = opentelemetry::sdk::common::GetHashForAttributeMap(m3); - hash_map.Set(m3, std::move(aggregation3), hash3); - EXPECT_EQ(hash_map.Has(hash), true); - EXPECT_EQ(hash_map.Has(hash3), true); - hash_map.Get(hash3)->Aggregate(static_cast(1)); + hash_map.Set(m3, std::move(aggregation3)); + EXPECT_EQ(hash_map.Has(m1), true); + EXPECT_EQ(hash_map.Has(m3), true); + hash_map.Get(m3)->Aggregate(static_cast(1)); EXPECT_EQ(hash_map.Size(), 2); // GetOrSetDefault @@ -64,15 +60,16 @@ TEST(AttributesHashMap, BasicTests) return std::unique_ptr(new DropAggregation); }; MetricAttributes m4 = {{"k1", "v1"}, {"k2", "v2"}, {"k3", "v3"}}; - auto hash4 = opentelemetry::sdk::common::GetHashForAttributeMap(m4); - hash_map.GetOrSetDefault(m4, create_default_aggregation, hash4) - ->Aggregate(static_cast(1)); + hash_map.GetOrSetDefault(m4, create_default_aggregation)->Aggregate(static_cast(1)); EXPECT_EQ(hash_map.Size(), 3); // Set attributes with different order - shouldn't create a new entry. MetricAttributes m5 = {{"k2", "v2"}, {"k1", "v1"}}; - auto hash5 = opentelemetry::sdk::common::GetHashForAttributeMap(m5); - EXPECT_EQ(hash_map.Has(hash5), true); + EXPECT_EQ(hash_map.Has(m5), true); + + // Set attributes with different order - shouldn't create a new entry. + MetricAttributes m6 = {{"k1", "v2"}, {"k2", "v1"}}; + EXPECT_EQ(hash_map.Has(m6), false); // GetAllEnteries size_t count = 0; @@ -84,49 +81,52 @@ TEST(AttributesHashMap, BasicTests) EXPECT_EQ(count, hash_map.Size()); } -std::string make_unique_string(const char *str) +class MetricAttributeMapHashForCollision { - return std::string(str); -} +public: + size_t operator()(const MetricAttributes & /*attributes*/) const { return 42; } +}; -TEST(AttributesHashMap, HashWithKeyValueIterable) +TEST(AttributesHashMap, CollisionTest) { - std::string key1 = make_unique_string("k1"); - std::string value1 = make_unique_string("v1"); - std::string key2 = make_unique_string("k2"); - std::string value2 = make_unique_string("v2"); - std::string key3 = make_unique_string("k3"); - std::string value3 = make_unique_string("v3"); - - // Create mock KeyValueIterable instances with the same content but different variables - std::map attributes1({{key1, value1}, {key2, value2}}); - std::map attributes2({{key1, value1}, {key2, value2}}); - std::map attributes3({{key1, value1}, {key2, value2}, {key3, value3}}); - - // Create a callback that filters "k3" key - auto is_key_filter_k3_callback = [](nostd::string_view key) { - if (key == "k3") + // The hash on MetricsAttributes will be ignored by MetricAttributeMapHashForCollision + MetricAttributes m1 = {{"k1", "v1"}}; + MetricAttributes m2 = {{"k2", "v2"}}; + MetricAttributes m3 = {{"k1", "v1"}, {"k2", "v2"}}; + MetricAttributes m4 = {}; + + AttributesHashMapWithCustomHash hash_map; + + hash_map.Set(m1, std::unique_ptr(new DropAggregation())); + hash_map.Set(m2, std::unique_ptr(new DropAggregation())); + hash_map.Set(m3, std::unique_ptr(new DropAggregation())); + hash_map.Set(m4, std::unique_ptr(new DropAggregation())); + + EXPECT_EQ(hash_map.Size(), 4); + EXPECT_EQ(hash_map.Has(m1), true); + EXPECT_EQ(hash_map.Has(m2), true); + EXPECT_EQ(hash_map.Has(m3), true); + EXPECT_EQ(hash_map.Has(m4), true); + + MetricAttributes m5 = {{"k2", "v1"}}; + EXPECT_EQ(hash_map.Has(m5), false); + + // + // Verify only one bucket used based on the custom hash + // + size_t total_active_buckets = 0; + size_t total_elements = 0; + for (size_t i = 0; i < hash_map.BucketCount(); i++) + { + size_t bucket_size = hash_map.BucketSize(i); + if (bucket_size > 0) { - return false; + total_active_buckets++; + total_elements += bucket_size; } - return true; - }; - // Calculate hash - size_t hash1 = opentelemetry::sdk::common::GetHashForAttributeMap( - opentelemetry::common::KeyValueIterableView>(attributes1), - is_key_filter_k3_callback); - size_t hash2 = opentelemetry::sdk::common::GetHashForAttributeMap( - opentelemetry::common::KeyValueIterableView>(attributes2), - is_key_filter_k3_callback); - - size_t hash3 = opentelemetry::sdk::common::GetHashForAttributeMap( - opentelemetry::common::KeyValueIterableView>(attributes3), - is_key_filter_k3_callback); - - // Expect the hashes to be the same because the content is the same - EXPECT_EQ(hash1, hash2); - // Expect the hashes to be the same because the content is the same - EXPECT_EQ(hash1, hash3); + } + EXPECT_EQ(total_active_buckets, 1); + EXPECT_EQ(total_elements, 4); } TEST(AttributesHashMap, HashConsistencyAcrossStringTypes) diff --git a/sdk/test/metrics/cardinality_limit_test.cc b/sdk/test/metrics/cardinality_limit_test.cc index c785eeb5d5..801096b269 100644 --- a/sdk/test/metrics/cardinality_limit_test.cc +++ b/sdk/test/metrics/cardinality_limit_test.cc @@ -19,7 +19,6 @@ #include "opentelemetry/nostd/function_ref.h" #include "opentelemetry/nostd/span.h" #include "opentelemetry/nostd/variant.h" -#include "opentelemetry/sdk/common/attributemap_hash.h" #include "opentelemetry/sdk/metrics/aggregation/aggregation.h" #include "opentelemetry/sdk/metrics/aggregation/sum_aggregation.h" #include "opentelemetry/sdk/metrics/data/metric_data.h" @@ -51,9 +50,7 @@ TEST(CardinalityLimit, AttributesHashMapBasicTests) for (auto i = 0; i < 10; i++) { FilteredOrderedAttributeMap attributes = {{"key", std::to_string(i)}}; - auto hash = opentelemetry::sdk::common::GetHashForAttributeMap(attributes); - static_cast( - hash_map.GetOrSetDefault(attributes, aggregation_callback, hash)) + static_cast(hash_map.GetOrSetDefault(attributes, aggregation_callback)) ->Aggregate(record_value); } EXPECT_EQ(hash_map.Size(), 10); @@ -62,9 +59,7 @@ TEST(CardinalityLimit, AttributesHashMapBasicTests) for (auto i = 10; i < 15; i++) { FilteredOrderedAttributeMap attributes = {{"key", std::to_string(i)}}; - auto hash = opentelemetry::sdk::common::GetHashForAttributeMap(attributes); - static_cast( - hash_map.GetOrSetDefault(attributes, aggregation_callback, hash)) + static_cast(hash_map.GetOrSetDefault(attributes, aggregation_callback)) ->Aggregate(record_value); } EXPECT_EQ(hash_map.Size(), 10); // only one more metric point should be added as overflow. @@ -73,17 +68,13 @@ TEST(CardinalityLimit, AttributesHashMapBasicTests) for (auto i = 0; i < 5; i++) { FilteredOrderedAttributeMap attributes = {{"key", std::to_string(i)}}; - auto hash = opentelemetry::sdk::common::GetHashForAttributeMap(attributes); - static_cast( - hash_map.GetOrSetDefault(attributes, aggregation_callback, hash)) + static_cast(hash_map.GetOrSetDefault(attributes, aggregation_callback)) ->Aggregate(record_value); } EXPECT_EQ(hash_map.Size(), 10); // no new metric point added // get the overflow metric point - auto agg1 = hash_map.GetOrSetDefault( - FilteredOrderedAttributeMap({{kAttributesLimitOverflowKey, kAttributesLimitOverflowValue}}), - aggregation_callback, kOverflowAttributesHash); + auto agg1 = hash_map.GetOrSetDefault(kOverflowAttributes, aggregation_callback); EXPECT_NE(agg1, nullptr); auto sum_agg1 = static_cast(agg1); EXPECT_EQ(nostd::get(nostd::get(sum_agg1->ToPoint()).value_), @@ -92,10 +83,7 @@ TEST(CardinalityLimit, AttributesHashMapBasicTests) for (auto i = 0; i < 9; i++) { FilteredOrderedAttributeMap attributes = {{"key", std::to_string(i)}}; - auto hash = opentelemetry::sdk::common::GetHashForAttributeMap(attributes); - auto agg2 = hash_map.GetOrSetDefault( - FilteredOrderedAttributeMap({{kAttributesLimitOverflowKey, kAttributesLimitOverflowValue}}), - aggregation_callback, hash); + auto agg2 = hash_map.GetOrSetDefault(attributes, aggregation_callback); EXPECT_NE(agg2, nullptr); auto sum_agg2 = static_cast(agg2); if (i < 5) diff --git a/sdk/test/metrics/observer_result_test.cc b/sdk/test/metrics/observer_result_test.cc index fc4835786c..b33141b4f7 100644 --- a/sdk/test/metrics/observer_result_test.cc +++ b/sdk/test/metrics/observer_result_test.cc @@ -6,10 +6,8 @@ #include #include #include -#include #include "opentelemetry/common/key_value_iterable_view.h" -#include "opentelemetry/nostd/variant.h" #include "opentelemetry/sdk/metrics/observer_result.h" #include "opentelemetry/sdk/metrics/view/attributes_processor.h" diff --git a/tools/ports/opentelemetry/portfile.cmake b/tools/ports/opentelemetry/portfile.cmake index 7c10e1a48f..23a8b87994 100644 --- a/tools/ports/opentelemetry/portfile.cmake +++ b/tools/ports/opentelemetry/portfile.cmake @@ -13,7 +13,6 @@ message("VCPKG_LIBRARY_LINKAGE = ${VCPKG_LIBRARY_LINKAGE}") vcpkg_check_features( OUT_FEATURE_OPTIONS FEATURE_OPTIONS stdlib WITH_STDLIB - abseil WITH_ABSEIL ) # TODO: if building dynamic, use portable ABI. if building static, use STDLIB