diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 01ea48fb86..30b3b3fbde 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,12 +28,8 @@ jobs: run: | ./ci/do_ci.sh cmake.test - # - # This build uses the latest libraries compatible - # with C++11 - # - cmake_gcc_maintainer_cpp11_async_test: - name: CMake gcc 12 (maintainer mode, C++11, async) + cmake_gcc_maintainer_sync_test: + name: CMake gcc 12 (maintainer mode, sync) runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -43,18 +39,17 @@ jobs: env: CC: /usr/bin/gcc-12 CXX: /usr/bin/g++-12 - GOOGLETEST_VERSION: 1.12.1 PROTOBUF_VERSION: 21.12 run: | sudo -E ./ci/setup_cmake.sh sudo -E ./ci/setup_ci_environment.sh sudo -E ./ci/install_protobuf.sh - - name: run cmake gcc (maintainer mode, C++11, async) + - name: run cmake gcc (maintainer mode, sync) env: CC: /usr/bin/gcc-12 CXX: /usr/bin/g++-12 run: | - ./ci/do_ci.sh cmake.maintainer.cpp11.async.test + ./ci/do_ci.sh cmake.maintainer.sync.test - name: generate test cert env: CFSSL_VERSION: 1.6.3 @@ -65,8 +60,8 @@ jobs: run: | (cd ./functional/otlp; ./run_test.sh) - cmake_gcc_maintainer_sync_test: - name: CMake gcc 12 (maintainer mode, sync) + cmake_gcc_maintainer_async_test: + name: CMake gcc 12 (maintainer mode, async) runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -81,12 +76,12 @@ jobs: sudo -E ./ci/setup_cmake.sh sudo -E ./ci/setup_ci_environment.sh sudo -E ./ci/install_protobuf.sh - - name: run cmake gcc (maintainer mode, sync) + - name: run cmake gcc (maintainer mode, async) env: CC: /usr/bin/gcc-12 CXX: /usr/bin/g++-12 run: | - ./ci/do_ci.sh cmake.maintainer.sync.test + ./ci/do_ci.sh cmake.maintainer.async.test - name: generate test cert env: CFSSL_VERSION: 1.6.3 @@ -97,8 +92,8 @@ jobs: run: | (cd ./functional/otlp; ./run_test.sh) - cmake_gcc_maintainer_async_test: - name: CMake gcc 12 (maintainer mode, async) + cmake_clang_maintainer_sync_test: + name: CMake clang 14 (maintainer mode, sync) runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -106,19 +101,19 @@ jobs: submodules: 'recursive' - name: setup env: - CC: /usr/bin/gcc-12 - CXX: /usr/bin/g++-12 + CC: /usr/bin/clang-14 + CXX: /usr/bin/clang++-14 PROTOBUF_VERSION: 21.12 run: | sudo -E ./ci/setup_cmake.sh sudo -E ./ci/setup_ci_environment.sh sudo -E ./ci/install_protobuf.sh - - name: run cmake gcc (maintainer mode, async) + - name: run cmake clang (maintainer mode, sync) env: - CC: /usr/bin/gcc-12 - CXX: /usr/bin/g++-12 + CC: /usr/bin/clang-14 + CXX: /usr/bin/clang++-14 run: | - ./ci/do_ci.sh cmake.maintainer.async.test + ./ci/do_ci.sh cmake.maintainer.sync.test - name: generate test cert env: CFSSL_VERSION: 1.6.3 @@ -129,8 +124,8 @@ jobs: run: | (cd ./functional/otlp; ./run_test.sh) - cmake_clang_maintainer_sync_test: - name: CMake clang 14 (maintainer mode, sync) + cmake_clang_maintainer_async_test: + name: CMake clang 14 (maintainer mode, async) runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -145,12 +140,12 @@ jobs: sudo -E ./ci/setup_cmake.sh sudo -E ./ci/setup_ci_environment.sh sudo -E ./ci/install_protobuf.sh - - name: run cmake clang (maintainer mode, sync) + - name: run cmake clang (maintainer mode, async) env: CC: /usr/bin/clang-14 CXX: /usr/bin/clang++-14 run: | - ./ci/do_ci.sh cmake.maintainer.sync.test + ./ci/do_ci.sh cmake.maintainer.async.test - name: generate test cert env: CFSSL_VERSION: 1.6.3 @@ -161,8 +156,8 @@ jobs: run: | (cd ./functional/otlp; ./run_test.sh) - cmake_clang_maintainer_async_test: - name: CMake clang 14 (maintainer mode, async) + cmake_clang_maintainer_abiv2_test: + name: CMake clang 14 (maintainer mode, abiv2) runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -177,12 +172,12 @@ jobs: sudo -E ./ci/setup_cmake.sh sudo -E ./ci/setup_ci_environment.sh sudo -E ./ci/install_protobuf.sh - - name: run cmake clang (maintainer mode, async) + - name: run cmake clang (maintainer mode, abiv2) env: CC: /usr/bin/clang-14 CXX: /usr/bin/clang++-14 run: | - ./ci/do_ci.sh cmake.maintainer.async.test + ./ci/do_ci.sh cmake.maintainer.abiv2.test - name: generate test cert env: CFSSL_VERSION: 1.6.3 @@ -258,64 +253,6 @@ jobs: - name: run cmake tests (enable opentracing-shim) run: ./ci/do_ci.sh cmake.opentracing_shim.test - cmake_gcc_48_test: - name: CMake gcc 4.8 (without otlp exporter) - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v4 - with: - submodules: 'recursive' - - name: Add Ubuntu Xenial package sources - run: | - sudo apt-add-repository 'deb http://archive.ubuntu.com/ubuntu/ xenial main' - sudo apt-add-repository 'deb http://archive.ubuntu.com/ubuntu/ xenial universe' - - name: setup - run: | - sudo ./ci/setup_ci_environment.sh - sudo ./ci/install_gcc48.sh - - name: setup cmake - env: - CC: /usr/bin/gcc-4.8 - CXX: /usr/bin/g++-4.8 - GOOGLETEST_VERSION: 1.10.0 - run: | - sudo -E ./ci/setup_cmake.sh - - name: run tests - env: - CC: /usr/bin/gcc-4.8 - CXX: /usr/bin/g++-4.8 - CXX_STANDARD: '11' - run: ./ci/do_ci.sh cmake.legacy.test - - cmake_gcc_48_otlp_exporter_test: - name: CMake gcc 4.8 (with otlp exporter) - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v4 - with: - submodules: 'recursive' - - name: Add Ubuntu Xenial package sources - run: | - sudo apt-add-repository 'deb http://archive.ubuntu.com/ubuntu/ xenial main' - sudo apt-add-repository 'deb http://archive.ubuntu.com/ubuntu/ xenial universe' - - name: setup - run: | - sudo ./ci/setup_ci_environment.sh - sudo ./ci/install_gcc48.sh - - name: setup cmake and grpc - env: - CC: /usr/bin/gcc-4.8 - CXX: /usr/bin/g++-4.8 - GOOGLETEST_VERSION: 1.10.0 - run: | - sudo -E ./ci/setup_cmake.sh - sudo -E ./ci/setup_grpc.sh -v 4.8 - - name: run tests - env: - CC: /usr/bin/gcc-4.8 - CXX: /usr/bin/g++-4.8 - run: ./ci/do_ci.sh cmake.legacy.exporter.otprotocol.test - cmake_test_cxx14_gcc: name: CMake C++14 test(GCC) runs-on: ubuntu-20.04 diff --git a/CHANGELOG.md b/CHANGELOG.md index c4a6566d96..62617156bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,9 +22,23 @@ Increment the: * [EXPORTER] Remove explicit timestamps from metric points exported by Prometheus [#2324](https://github.com/open-telemetry/opentelemetry-cpp/pull/2324) * [EXPORTER] Handle attribute key collisions caused by sanitation - [#2324](https://github.com/open-telemetry/opentelemetry-cpp/pull/2326) + [#2326](https://github.com/open-telemetry/opentelemetry-cpp/pull/2326) * [EXPORTER] Replace colons with underscores when converting to Prometheus label - [#2324](https://github.com/open-telemetry/opentelemetry-cpp/pull/2330) + [#2330](https://github.com/open-telemetry/opentelemetry-cpp/pull/2330) +* [API] Add InstrumentationScope attributes in MeterProvider::GetMeter() + [#2224](https://github.com/open-telemetry/opentelemetry-cpp/pull/2224) +* [REMOVAL] Drop C++11 support + [#2342](https://github.com/open-telemetry/opentelemetry-cpp/pull/2342) + +Important changes: + +* [API] Add InstrumentationScope attributes in MeterProvider::GetMeter() + [#2224](https://github.com/open-telemetry/opentelemetry-cpp/pull/2224) + * MeterProvider::GetMeter() now accepts InstrumentationScope attributes. + * Because this is an `ABI` breaking change, the fix is only available + with the `CMake` option `WITH_ABI_VERSION_2=ON`. + * When building with `CMake` option `WITH_ABI_VERSION_1=ON` (by default) + the `ABI` is unchanged, and the fix is not available. Breaking changes: @@ -49,6 +63,10 @@ Breaking changes: * Applications that set neither CMAKE_CXX_STANDARD nor -stdc++ options may need to provide a C++ standard in their makefiles. +* [REMOVAL] Drop C++11 support + [#2342](https://github.com/open-telemetry/opentelemetry-cpp/pull/2342) + * Building with C++11 is no longer supported. + ## [1.11.0] 2023-08-21 * [BUILD] Fix more cases for symbol name for 32-bit win32 DLL build diff --git a/DEPRECATED.md b/DEPRECATED.md index 05ba8e52d4..c9ad356696 100644 --- a/DEPRECATED.md +++ b/DEPRECATED.md @@ -30,66 +30,7 @@ N/A ## [Compilers] -### Drop C++11 support - -#### Announcement (C++11) - -* Date: 2022-12-01 -* Issue: [DEPRECATION] Drop C++11 support - [#1830](https://github.com/open-telemetry/opentelemetry-cpp/pull/1830) -* This announcement has been pinned, - visible in the issues pages since December 2022. - -#### Motivation (C++11) - -This repository, opentelemetry-cpp, supports a "bring your own dependency" model. - -In this model, -the build scripts can be configured to: - -* pick a given version for a third party library, -* build opentelemetry-cpp with the library given. - -The makefiles do not mandate to use a particular version, -hence the "bring your own" denomination. - -To have an up to date build, projects are encouraged to use up to date -versions of third party libraries, to benefit from bug fixes. - -Now, many libraries deliver new versions that require C++14, bug fixes -releases for C++11 are no longer available. - -In particular, the following components: - -* GRPC C++ -* abseil -* googletest - -now require C++14, per -[google support policies](https://github.com/google/oss-policies-info/blob/main/foundational-cxx-support-matrix.md) - -As a result, to stay up to date, opentelemetry-cpp needs to upgrade its -minimum build requirements to use C++14 instead of C++11. - -#### Scope (C++11) - -Continuous Integration (CI) builds will use C++14 instead of C++11. - -The CI build for gcc 4.8 is now deprecated, to be decommissioned when C++11 -support is dropped. - -#### Mitigation (C++11) - -Building the code with recent third party libraries will require C++14 -instead of C++11. - -#### Planned end of life (C++11) - -Support for C++11 in opentelemetry-cpp will end on September 2023. - -After this date, opentelemetry-cpp may still build properly in C++11 mode, -assuming a suitable, old, version for each dependency is used, -but the C++11 build will no longer be tested for each new release. +N/A ## [Third party dependencies] diff --git a/INSTALL.md b/INSTALL.md index 48d1ee8a45..68fefff1fe 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -16,7 +16,7 @@ You can link OpenTelemetry C++ SDK with libraries provided in - A supported platform (e.g. Windows, macOS or Linux). Refer to [Platforms Supported](./README.md#supported-development-platforms) for more information. -- A compatible C++ compiler supporting at least C++11. Major compilers are +- A compatible C++ compiler supporting at least C++14. Major compilers are supported. Refer to [Supported Compilers](./README.md#supported-c-versions) for more information. - [Git](https://git-scm.com/) for fetching opentelemetry-cpp source code from @@ -158,7 +158,7 @@ path. - A supported platform (e.g. Windows, macOS or Linux). Refer to [Platforms Supported](./README.md#supported-development-platforms) for more information. -- A compatible C++ compiler supporting at least C++11. Major compilers are +- A compatible C++ compiler supporting at least C++14. Major compilers are supported. Refer to [Supported Compilers](./README.md#supported-c-versions) for more information. - [Git](https://git-scm.com/) for fetching opentelemetry-cpp source code from diff --git a/README.md b/README.md index 37a02a84c2..d6a16f3de0 100644 --- a/README.md +++ b/README.md @@ -22,9 +22,8 @@ repo. Code shipped from this repository generally supports the following versions of C++ standards: -* ISO/IEC 14882:2011 (C++11, C++0x) -* ISO/IEC 14882:2014 (C++14, C++1y) -* ISO/IEC 14882:2017 (C++17, C++1z) +* ISO/IEC 14882:2014 (C++14) +* ISO/IEC 14882:2017 (C++17) * ISO/IEC 14882:2020 (C++20) Any exceptions to this are noted in the individual `README.md` files. @@ -39,19 +38,13 @@ of the current project. | Platform | Build type | |---------------------------------------------------------------------|---------------| -| ubuntu-22.04 (GCC - 10, 12) | CMake, Bazel | -| ubuntu-20.04 (GCC 4.8 with -std=c++11 flag) | CMake [1] | -| ubuntu-20.04 (GCC 9.4.0) | CMake, Bazel | -| ubuntu-20.04 (Default GCC Compiler - 9.4.0 with -std=c++20 flags) | CMake, Bazel | -| macOS 12.0 (Xcode 14.2) | Bazel | +| ubuntu-22.04 (GCC 10, GCC 12, Clang 14) | CMake, Bazel | +| ubuntu-20.04 (GCC 9.4.0 - default compiler) | CMake, Bazel | +| ubuntu-20.04 (GCC 9.4.0 with -std=c++14/17/20 flags) | CMake, Bazel | +| macOS 12.7 (Xcode 14.2) | Bazel | | Windows Server 2019 (Visual Studio Enterprise 2019) | CMake, Bazel | | Windows Server 2022 (Visual Studio Enterprise 2022) | CMake | -[1]: Bazel build is disabled for GCC 4.8, as gRPC library 1.38 and above - (required by OTLP exporter) don't build with this compiler. See gRPC [official - support](https://grpc.io/docs/#official-support) document. CMake build doesn't - build OTLP exporter with GCC 4.8. - In general, the code shipped from this repository should build on all platforms having C++ compiler with [supported C++ standards](#supported-c-versions). diff --git a/api/include/opentelemetry/metrics/meter_provider.h b/api/include/opentelemetry/metrics/meter_provider.h index e0b0285ef4..152e543d36 100644 --- a/api/include/opentelemetry/metrics/meter_provider.h +++ b/api/include/opentelemetry/metrics/meter_provider.h @@ -3,8 +3,11 @@ #pragma once +#include "opentelemetry/common/key_value_iterable.h" +#include "opentelemetry/common/key_value_iterable_view.h" #include "opentelemetry/nostd/shared_ptr.h" #include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/nostd/type_traits.h" #include "opentelemetry/version.h" OPENTELEMETRY_BEGIN_NAMESPACE @@ -20,19 +23,113 @@ class MeterProvider { public: virtual ~MeterProvider() = default; + +#if OPENTELEMETRY_ABI_VERSION_NO >= 2 + + /** + * Gets or creates a named Meter instance (ABI). + * + * @since ABI_VERSION 2 + * + * @param[in] name Meter instrumentation scope + * @param[in] version Instrumentation scope version + * @param[in] schema_url Instrumentation scope schema URL + * @param[in] attributes Instrumentation scope attributes (optional, may be nullptr) + */ + virtual nostd::shared_ptr GetMeter( + nostd::string_view name, + nostd::string_view version, + nostd::string_view schema_url, + const common::KeyValueIterable *attributes) noexcept = 0; + + /** + * Gets or creates a named Meter instance (API helper). + * + * @since ABI_VERSION 2 + * + * @param[in] name Meter instrumentation scope + * @param[in] version Instrumentation scope version, optional + * @param[in] schema_url Instrumentation scope schema URL, optional + */ + nostd::shared_ptr GetMeter(nostd::string_view name, + nostd::string_view version = "", + nostd::string_view schema_url = "") + { + return GetMeter(name, version, schema_url, nullptr); + } + + /** + * Gets or creates a named Meter instance (API helper). + * + * @since ABI_VERSION 2 + * + * @param[in] name Meter instrumentation scope + * @param[in] version Instrumentation scope version + * @param[in] schema_url Instrumentation scope schema URL + * @param[in] attributes Instrumentation scope attributes + */ + nostd::shared_ptr GetMeter( + nostd::string_view name, + nostd::string_view version, + nostd::string_view schema_url, + std::initializer_list> attributes) + { + /* Build a container from std::initializer_list. */ + nostd::span> attributes_span{ + attributes.begin(), attributes.end()}; + + /* Build a view on the container. */ + common::KeyValueIterableView< + nostd::span>> + iterable_attributes{attributes_span}; + + /* Add attributes using the view. */ + return GetMeter(name, version, schema_url, &iterable_attributes); + } + + /** + * Gets or creates a named Meter instance (API helper). + * + * @since ABI_VERSION 2 + * + * @param[in] name Meter instrumentation scope + * @param[in] version Instrumentation scope version + * @param[in] schema_url Instrumentation scope schema URL + * @param[in] attributes Instrumentation scope attributes container + */ + template ::value> * = nullptr> + nostd::shared_ptr GetMeter(nostd::string_view name, + nostd::string_view version, + nostd::string_view schema_url, + const T &attributes) + { + /* Build a view on the container. */ + common::KeyValueIterableView iterable_attributes(attributes); + + /* Add attributes using the view. */ + return GetMeter(name, version, schema_url, &iterable_attributes); + } + +#else /** - * Gets or creates a named Meter instance. + * Gets or creates a named Meter instance (ABI) * - * Optionally a version can be passed to create a named and versioned Meter - * instance. + * @since ABI_VERSION 1 + * + * @param[in] name Meter instrumentation scope + * @param[in] version Instrumentation scope version, optional + * @param[in] schema_url Instrumentation scope schema URL, optional */ - virtual nostd::shared_ptr GetMeter(nostd::string_view library_name, - nostd::string_view library_version = "", - nostd::string_view schema_url = "") noexcept = 0; + virtual nostd::shared_ptr GetMeter(nostd::string_view name, + nostd::string_view version = "", + nostd::string_view schema_url = "") noexcept = 0; +#endif + #ifdef ENABLE_REMOVE_METER_PREVIEW - virtual void RemoveMeter(nostd::string_view library_name, - nostd::string_view library_version = "", - nostd::string_view schema_url = "") noexcept = 0; + virtual void RemoveMeter(nostd::string_view name, + nostd::string_view version = "", + nostd::string_view schema_url = "") noexcept = 0; #endif }; } // namespace metrics diff --git a/api/include/opentelemetry/metrics/noop.h b/api/include/opentelemetry/metrics/noop.h index c5802f3dd3..edbbe2c100 100644 --- a/api/include/opentelemetry/metrics/noop.h +++ b/api/include/opentelemetry/metrics/noop.h @@ -196,12 +196,23 @@ class NoopMeterProvider final : public MeterProvider public: NoopMeterProvider() : meter_{nostd::shared_ptr(new NoopMeter)} {} - nostd::shared_ptr GetMeter(nostd::string_view /* library_name */, - nostd::string_view /* library_version */, +#if OPENTELEMETRY_ABI_VERSION_NO >= 2 + nostd::shared_ptr GetMeter( + nostd::string_view /* name */, + nostd::string_view /* version */, + nostd::string_view /* schema_url */, + const common::KeyValueIterable * /* attributes */) noexcept override + { + return meter_; + } +#else + nostd::shared_ptr GetMeter(nostd::string_view /* name */, + nostd::string_view /* version */, nostd::string_view /* schema_url */) noexcept override { return meter_; } +#endif #ifdef ENABLE_REMOVE_METER_PREVIEW void RemoveMeter(nostd::string_view /* name */, diff --git a/ci/do_ci.sh b/ci/do_ci.sh index 04063eb6ba..948a62b9dd 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -174,6 +174,31 @@ elif [[ "$1" == "cmake.maintainer.cpp11.async.test" ]]; then make -k -j $(nproc) make test exit 0 +elif [[ "$1" == "cmake.maintainer.abiv2.test" ]]; then + cd "${BUILD_DIR}" + rm -rf * + cmake ${CMAKE_OPTIONS[@]} \ + -DWITH_OTLP_HTTP=ON \ + -DWITH_OTLP_HTTP_SSL_PREVIEW=ON \ + -DWITH_OTLP_HTTP_SSL_TLS_PREVIEW=ON \ + -DWITH_REMOVE_METER_PREVIEW=ON \ + -DWITH_PROMETHEUS=ON \ + -DWITH_EXAMPLES=ON \ + -DWITH_EXAMPLES_HTTP=ON \ + -DWITH_ZIPKIN=ON \ + -DBUILD_W3CTRACECONTEXT_TEST=ON \ + -DWITH_ELASTICSEARCH=ON \ + -DWITH_METRICS_EXEMPLAR_PREVIEW=ON \ + -DWITH_ASYNC_EXPORT_PREVIEW=OFF \ + -DOTELCPP_MAINTAINER_MODE=ON \ + -DWITH_NO_DEPRECATED_CODE=ON \ + -DWITH_ABI_VERSION_1=OFF \ + -DWITH_ABI_VERSION_2=ON \ + ${IWYU} \ + "${SRC_DIR}" + eval "$MAKE_COMMAND" + make test + exit 0 elif [[ "$1" == "cmake.with_async_export.test" ]]; then cd "${BUILD_DIR}" rm -rf * diff --git a/docs/building-with-stdlib.md b/docs/building-with-stdlib.md index d9c73073da..22b8935595 100644 --- a/docs/building-with-stdlib.md +++ b/docs/building-with-stdlib.md @@ -19,7 +19,7 @@ API surface classes with [Abseil classes](https://abseil.io/) instead of * ABI stability: scenario where different modules are compiled with different compiler and incompatible standard library. -* backport of C++17 and above features to C++11 compiler. +* backport of C++17 and above features to C++14 compiler. The need for custom `nostd` classes is significantly diminished when the SDK is compiled with C++17 or above compiler. Only `std::span` needs to be backported. @@ -137,9 +137,9 @@ Visual Studio provides 1st class debug experience for the standard library. Supported build flavors: -* `nostd` - OpenTelemetry backport of classes for C++11. Not using standard lib. +* `nostd` - OpenTelemetry backport of classes for C++14. Not using standard lib. * `stdlib` - Standard Library. - Native experience with C++11/C++14/C++17/C++20/C++23 compiler. + Native experience with C++14/C++17/C++20/C++23 compiler. Depending on the stdlib level in effect, C++ features are used from the standard library, completed with `nostd` replacement implementations. diff --git a/docs/dependencies.md b/docs/dependencies.md index d0dc09c54f..2f2f2368f6 100644 --- a/docs/dependencies.md +++ b/docs/dependencies.md @@ -27,7 +27,7 @@ Both these dependencies are listed here: compiler if cmake option `WITH_STL` is enabled or macro `OPENTELEMETRY_STL_VERSION` is defined. License: `GNU General Public License` - - For C++11/14/17 compilers, fallback to gsl::span if [GSL C++ + - For C++14/17 compilers, fallback to gsl::span if [GSL C++ library](https://github.com/microsoft/GSL) is installed. License: `MIT License` - libc++ 14.0.0 do not support construct std::span from a range or container diff --git a/docs/google-test.md b/docs/google-test.md index dadf5b1577..7f767e54e7 100644 --- a/docs/google-test.md +++ b/docs/google-test.md @@ -93,7 +93,7 @@ this, Google Test also allows us to easily integrate code coverage tools such as ## Integration and Usage One of the base requirements to build and use Google Test from a source package -are to use either Bazel or CMake; the other is a C++11-standard-compliant +are to use either Bazel or CMake; the other is a C++14-standard-compliant compiler like GCC or Clang. ### Bazel diff --git a/docs/public/api/Overview.rst b/docs/public/api/Overview.rst index cdd160ce23..6b1e826d01 100644 --- a/docs/public/api/Overview.rst +++ b/docs/public/api/Overview.rst @@ -15,7 +15,7 @@ Library design -------------- The OpenTelemetry C++ API is provided as a header-only library and -supports all recent versions of the C++ standard, down to C++11. +supports all recent versions of the C++ standard, down to C++14. A single application might dynamically or statically link to different libraries that were compiled with different compilers, while several of diff --git a/sdk/include/opentelemetry/sdk/common/attribute_utils.h b/sdk/include/opentelemetry/sdk/common/attribute_utils.h index c8afd657e2..e21649b695 100644 --- a/sdk/include/opentelemetry/sdk/common/attribute_utils.h +++ b/sdk/include/opentelemetry/sdk/common/attribute_utils.h @@ -105,10 +105,10 @@ struct AttributeConverter class AttributeMap : public std::unordered_map { public: - // Contruct empty attribute map + // Construct empty attribute map AttributeMap() : std::unordered_map() {} - // Contruct attribute map and populate with attributes + // Construct attribute map and populate with attributes AttributeMap(const opentelemetry::common::KeyValueIterable &attributes) : AttributeMap() { attributes.ForEachKeyValue( @@ -118,6 +118,19 @@ class AttributeMap : public std::unordered_map }); } + // Construct attribute map and populate with optional attributes + AttributeMap(const opentelemetry::common::KeyValueIterable *attributes) : AttributeMap() + { + if (attributes != nullptr) + { + attributes->ForEachKeyValue( + [&](nostd::string_view key, opentelemetry::common::AttributeValue value) noexcept { + SetAttribute(key, value); + return true; + }); + } + } + // Construct map from initializer list by applying `SetAttribute` transform for every attribute AttributeMap( std::initializer_list> diff --git a/sdk/include/opentelemetry/sdk/metrics/meter_provider.h b/sdk/include/opentelemetry/sdk/metrics/meter_provider.h index c74c37f8a4..00f9a35ac2 100644 --- a/sdk/include/opentelemetry/sdk/metrics/meter_provider.h +++ b/sdk/include/opentelemetry/sdk/metrics/meter_provider.h @@ -48,10 +48,23 @@ class MeterProvider final : public opentelemetry::metrics::MeterProvider */ explicit MeterProvider(std::unique_ptr context) noexcept; + /* + Make sure GetMeter() helpers from the API are seen in overload resolution. + */ + using opentelemetry::metrics::MeterProvider::GetMeter; + +#if OPENTELEMETRY_ABI_VERSION_NO >= 2 + nostd::shared_ptr GetMeter( + nostd::string_view name, + nostd::string_view version, + nostd::string_view schema_url, + const opentelemetry::common::KeyValueIterable *attributes) noexcept override; +#else nostd::shared_ptr GetMeter( nostd::string_view name, nostd::string_view version = "", nostd::string_view schema_url = "") noexcept override; +#endif #ifdef ENABLE_REMOVE_METER_PREVIEW void RemoveMeter(nostd::string_view name, diff --git a/sdk/src/metrics/meter_provider.cc b/sdk/src/metrics/meter_provider.cc index 84ab58c4cf..23ddbc75cf 100644 --- a/sdk/src/metrics/meter_provider.cc +++ b/sdk/src/metrics/meter_provider.cc @@ -32,11 +32,23 @@ MeterProvider::MeterProvider(std::unique_ptr views, OTEL_INTERNAL_LOG_DEBUG("[MeterProvider] MeterProvider created."); } +#if OPENTELEMETRY_ABI_VERSION_NO >= 2 +nostd::shared_ptr MeterProvider::GetMeter( + nostd::string_view name, + nostd::string_view version, + nostd::string_view schema_url, + const opentelemetry::common::KeyValueIterable *attributes) noexcept +#else nostd::shared_ptr MeterProvider::GetMeter( nostd::string_view name, nostd::string_view version, nostd::string_view schema_url) noexcept +#endif { +#if OPENTELEMETRY_ABI_VERSION_NO < 2 + const opentelemetry::common::KeyValueIterable *attributes = nullptr; +#endif + if (name.data() == nullptr || name == "") { OTEL_INTERNAL_LOG_WARN("[MeterProvider::GetMeter] Library name is empty."); @@ -53,8 +65,12 @@ nostd::shared_ptr MeterProvider::GetMeter( return nostd::shared_ptr{meter}; } } - auto lib = instrumentationscope::InstrumentationScope::Create(name, version, schema_url); - auto meter = std::shared_ptr(new Meter(context_, std::move(lib))); + + instrumentationscope::InstrumentationScopeAttributes attrs_map(attributes); + auto scope = + instrumentationscope::InstrumentationScope::Create(name, version, schema_url, attrs_map); + + auto meter = std::shared_ptr(new Meter(context_, std::move(scope))); context_->AddMeter(meter); return nostd::shared_ptr{meter}; } diff --git a/sdk/test/metrics/meter_provider_sdk_test.cc b/sdk/test/metrics/meter_provider_sdk_test.cc index a1ca8de330..1844f113d2 100644 --- a/sdk/test/metrics/meter_provider_sdk_test.cc +++ b/sdk/test/metrics/meter_provider_sdk_test.cc @@ -59,6 +59,138 @@ TEST(MeterProvider, GetMeter) mp1.Shutdown(); } +#if OPENTELEMETRY_ABI_VERSION_NO >= 2 +TEST(MeterProvider, GetMeterAbiv2) +{ + MeterProvider mp; + + auto m1 = mp.GetMeter("name1", "version1", "url1"); + ASSERT_NE(nullptr, m1); + + auto m2 = mp.GetMeter("name2", "version2", "url2", nullptr); + ASSERT_NE(nullptr, m2); + + auto m3 = mp.GetMeter("name3", "version3", "url3", {{"accept_single_attr", true}}); + ASSERT_NE(nullptr, m3); + { + auto meter = static_cast(m3.get()); + auto scope = meter->GetInstrumentationScope(); + auto attrs = scope->GetAttributes(); + ASSERT_EQ(attrs.size(), 1); + auto attr = attrs.find("accept_single_attr"); + ASSERT_FALSE(attr == attrs.end()); + ASSERT_TRUE(opentelemetry::nostd::holds_alternative(attr->second)); + EXPECT_EQ(opentelemetry::nostd::get(attr->second), true); + } + + std::pair attr4 = { + "accept_single_attr", true}; + auto m4 = mp.GetMeter("name4", "version4", "url4", {attr4}); + ASSERT_NE(nullptr, m4); + { + auto meter = static_cast(m4.get()); + auto scope = meter->GetInstrumentationScope(); + auto attrs = scope->GetAttributes(); + ASSERT_EQ(attrs.size(), 1); + auto attr = attrs.find("accept_single_attr"); + ASSERT_FALSE(attr == attrs.end()); + ASSERT_TRUE(opentelemetry::nostd::holds_alternative(attr->second)); + EXPECT_EQ(opentelemetry::nostd::get(attr->second), true); + } + + auto m5 = mp.GetMeter("name5", "version5", "url5", {{"foo", "1"}, {"bar", "2"}}); + ASSERT_NE(nullptr, m5); + { + auto meter = static_cast(m5.get()); + auto scope = meter->GetInstrumentationScope(); + auto attrs = scope->GetAttributes(); + ASSERT_EQ(attrs.size(), 2); + auto attr = attrs.find("bar"); + ASSERT_FALSE(attr == attrs.end()); + ASSERT_TRUE(opentelemetry::nostd::holds_alternative(attr->second)); + EXPECT_EQ(opentelemetry::nostd::get(attr->second), "2"); + } + + std::initializer_list< + std::pair> + attrs6 = {{"foo", "1"}, {"bar", 42}}; + + auto m6 = mp.GetMeter("name6", "version6", "url6", attrs6); + ASSERT_NE(nullptr, m6); + { + auto meter = static_cast(m6.get()); + auto scope = meter->GetInstrumentationScope(); + auto attrs = scope->GetAttributes(); + ASSERT_EQ(attrs.size(), 2); + auto attr = attrs.find("bar"); + ASSERT_FALSE(attr == attrs.end()); + ASSERT_TRUE(opentelemetry::nostd::holds_alternative(attr->second)); + EXPECT_EQ(opentelemetry::nostd::get(attr->second), 42); + } + + typedef std::pair KV; + + std::initializer_list attrs7 = {{"foo", 3.14}, {"bar", "2"}}; + auto m7 = mp.GetMeter("name7", "version7", "url7", attrs7); + ASSERT_NE(nullptr, m7); + { + auto meter = static_cast(m7.get()); + auto scope = meter->GetInstrumentationScope(); + auto attrs = scope->GetAttributes(); + ASSERT_EQ(attrs.size(), 2); + auto attr = attrs.find("foo"); + ASSERT_FALSE(attr == attrs.end()); + ASSERT_TRUE(opentelemetry::nostd::holds_alternative(attr->second)); + EXPECT_EQ(opentelemetry::nostd::get(attr->second), 3.14); + } + + auto m8 = mp.GetMeter("name8", "version8", "url8", + {{"a", "string"}, + {"b", false}, + {"c", 314159}, + {"d", (unsigned int)314159}, + {"e", (int32_t)-20}, + {"f", (uint32_t)20}, + {"g", (int64_t)-20}, + {"h", (uint64_t)20}, + {"i", 3.1}, + {"j", "string"}}); + ASSERT_NE(nullptr, m8); + { + auto meter = static_cast(m8.get()); + auto scope = meter->GetInstrumentationScope(); + auto attrs = scope->GetAttributes(); + ASSERT_EQ(attrs.size(), 10); + auto attr = attrs.find("e"); + ASSERT_FALSE(attr == attrs.end()); + ASSERT_TRUE(opentelemetry::nostd::holds_alternative(attr->second)); + EXPECT_EQ(opentelemetry::nostd::get(attr->second), -20); + } + + std::map attr9{ + {"a", "string"}, {"b", false}, {"c", 314159}, {"d", (unsigned int)314159}, + {"e", (int32_t)-20}, {"f", (uint32_t)20}, {"g", (int64_t)-20}, {"h", (uint64_t)20}, + {"i", 3.1}, {"j", "string"}}; + + auto m9 = mp.GetMeter("name9", "version9", "url9", attr9); + ASSERT_NE(nullptr, m9); + { + auto meter = static_cast(m9.get()); + auto scope = meter->GetInstrumentationScope(); + auto attrs = scope->GetAttributes(); + ASSERT_EQ(attrs.size(), 10); + auto attr = attrs.find("h"); + ASSERT_FALSE(attr == attrs.end()); + ASSERT_TRUE(opentelemetry::nostd::holds_alternative(attr->second)); + EXPECT_EQ(opentelemetry::nostd::get(attr->second), 20); + } + + // cleanup properly without crash + mp.ForceFlush(); + mp.Shutdown(); +} +#endif /* OPENTELEMETRY_ABI_VERSION_NO >= 2 */ + #ifdef ENABLE_REMOVE_METER_PREVIEW TEST(MeterProvider, RemoveMeter) {