diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3a1c419334..3fd4be9c11 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,6 +23,52 @@ jobs: sudo ./ci/setup_thrift.sh ./ci/do_ci.sh cmake.test + cmake_gcc_maintainer_test: + name: CMake gcc (maintainer mode) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + submodules: 'recursive' + - name: setup + run: | + sudo CC=/usr/bin/gcc-10 CXX=/usr/bin/g++-10 ./ci/setup_cmake.sh + sudo CC=/usr/bin/gcc-10 CXX=/usr/bin/g++-10 ./ci/setup_ci_environment.sh + - name: run cmake gcc (maintainer mode) + run: | + sudo CC=/usr/bin/gcc-10 CXX=/usr/bin/g++-10 ./ci/setup_thrift.sh + CC=/usr/bin/gcc-10 CXX=/usr/bin/g++-10 ./ci/do_ci.sh cmake.maintainer.test + + cmake_clang_maintainer_test: + name: CMake clang (maintainer mode) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + submodules: 'recursive' + - name: setup + run: | + sudo CC=/usr/bin/clang-12 CXX=/usr/bin/clang++-12 ./ci/setup_cmake.sh + sudo CC=/usr/bin/clang-12 CXX=/usr/bin/clang++-12 ./ci/setup_ci_environment.sh + - name: run cmake clang (maintainer mode) + run: | + sudo CC=/usr/bin/clang-12 CXX=/usr/bin/clang++-12 ./ci/setup_thrift.sh + CC=/usr/bin/clang-12 CXX=/usr/bin/clang++-12 ./ci/do_ci.sh cmake.maintainer.test + + cmake_msvc_maintainer_test: + name: CMake msvc (maintainer mode) + runs-on: windows-latest + steps: + - uses: actions/checkout@v3 + with: + submodules: 'recursive' + - name: setup + run: | + ./ci/setup_windows_cmake.ps1 + ./ci/setup_windows_ci_environment.ps1 + - name: run tests + run: ./ci/do_ci.ps1 cmake.maintainer.test + cmake_deprecated_metrics_test: name: CMake test (without otlp-exporter and with deprecated metrics) runs-on: ubuntu-latest diff --git a/CHANGELOG.md b/CHANGELOG.md index 1155625e50..4368f441dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,57 @@ Increment the: ## [Unreleased] +## [1.7.0] 2022-10-28 + +* [METRICS SDK] Validate Instrument meta data (name, unit, description) [#1713](https://github.com/open-telemetry/opentelemetry-cpp/pull/1713) +* [DOCS] Document libthrift 0.12.0 doesn't work with Jaeger exporter [#1714](https://github.com/open-telemetry/opentelemetry-cpp/pull/1714) +* [Metrics SDK] Add Monotonic Property to Sum Aggregation, and +unit tests for Up Down Counter [#1675](https://github.com/open-telemetry/opentelemetry-cpp/pull/1675) +* [Metrics SDK] Move Metrics Exemplar processing behind feature flag [#1710](https://github.com/open-telemetry/opentelemetry-cpp/pull/1710) +* [Metrics API/SDK] Change Meter API/SDK to return nostd::unique_ptr + for Sync Instruments [#1707](https://github.com/open-telemetry/opentelemetry-cpp/pull/1707) +which includes breaking change in the Metrics api and sdk. +* [BUILD] Add e2e test to asan & tsan CI [#1670](https://github.com/open-telemetry/opentelemetry-cpp/pull/1670) +* [BUILD] Add otlp-grpc example bazel [#1708](https://github.com/open-telemetry/opentelemetry-cpp/pull/1708) +* [TRACE SDK] Fix debug log of OTLP HTTP exporter and ES log exporter [#1703](https://github.com/open-telemetry/opentelemetry-cpp/pull/1703) +* [METRICS SDK] Fix a potential precision loss on integer in +ReservoirCellIndexFor [#1696](https://github.com/open-telemetry/opentelemetry-cpp/pull/1696) +* [METRICS SDK] Fix Histogram crash [#1685](https://github.com/open-telemetry/opentelemetry-cpp/pull/1685) +* [METRICS SDK] Fix:1676 Segfault when short export period is used for metrics [#1682](https://github.com/open-telemetry/opentelemetry-cpp/pull/1682) +* [METRICS SDK] Add timeout support to MeterContext::ForceFlush [#1673](https://github.com/open-telemetry/opentelemetry-cpp/pull/1673) +* [DOCS] - Minor updates to OStream Metrics exporter documentation [#1679](https://github.com/open-telemetry/opentelemetry-cpp/pull/1679) +* [DOCS] Fix:#1575 API Documentation for Metrics SDK and API [#1678](https://github.com/open-telemetry/opentelemetry-cpp/pull/1678) +* [BUILD] Fixed compiler warnings [#1677](https://github.com/open-telemetry/opentelemetry-cpp/pull/1677) +* [METRICS SDK] Fix threading issue between Meter::RegisterSyncMetricStorage + and Meter::Collect [#1666](https://github.com/open-telemetry/opentelemetry-cpp/pull/1666) +* [METRICS SDK] Fix data race on MeterContext::meters_ [#1668](https://github.com/open-telemetry/opentelemetry-cpp/pull/1668) +* [METRICS SDK] Fix observable Gauge metrics generation [#1651](https://github.com/open-telemetry/opentelemetry-cpp/pull/1651) +* [BUILD] Detect ARCH=sparc in CMake [#1660](https://github.com/open-telemetry/opentelemetry-cpp/pull/1660) +* [SDK] Add user agent for OTLP http/grpc client [#1657](https://github.com/open-telemetry/opentelemetry-cpp/pull/1657) +* [BUILD] Fix clang and gcc warnings [#1658](https://github.com/open-telemetry/opentelemetry-cpp/pull/1658) +* [Metrics SDK] Add Metrics ExemplarFilter and ExemplarReservoir [#1584](https://github.com/open-telemetry/opentelemetry-cpp/pull/1584) +* [LOGS SDK] Rename OnReceive to OnEmit [#1652](https://github.com/open-telemetry/opentelemetry-cpp/pull/1652) +* [METRICS SDK] Fix Observable Gauge does not reflect updated values, +and send the old value always [#1641](https://github.com/open-telemetry/opentelemetry-cpp/pull/1641) +* [Metrics SDK] Change boundary type to double for Explicit Bucket Histogram Aggregation, +and change default bucket range [#1626](https://github.com/open-telemetry/opentelemetry-cpp/pull/1626) +* [METRICS SDK] Fix occasional Segfault with LongCounter instrument [#1638](https://github.com/open-telemetry/opentelemetry-cpp/pull/1638) +* [BUILD] Bump vcpk to 2022.08.15 [#1633](https://github.com/open-telemetry/opentelemetry-cpp/pull/1633) +* [BUILD] Bump gRPC to v1.48.1 for CMake Linux CI [#1608](https://github.com/open-telemetry/opentelemetry-cpp/pull/1608) +* [Metrics] Switch to explicit 64 bit integers [#1686](https://github.com/open-telemetry/opentelemetry-cpp/pull/1686) + which includes breaking change in the Metrics api and sdk. +* [Metrics SDK] Add support for Pull Metric Exporter [#1701](https://github.com/open-telemetry/opentelemetry-cpp/pull/1701) + which includes breaking change in the Metrics api. +* [BUILD] Add CMake OTELCPP_MAINTAINER_MODE [#1650](https://github.com/open-telemetry/opentelemetry-cpp/pull/1650) +* [SEMANTIC CONVENTIONS] Upgrade to version 1.14.0 [#1697](https://github.com/open-telemetry/opentelemetry-cpp/pull/1697) + +Notes: + +Metrics API/SDK GA release includes PRs [#1686](https://github.com/open-telemetry/opentelemetry-cpp/pull/1686), +[#1701](https://github.com/open-telemetry/opentelemetry-cpp/pull/1701), and +[#1707](https://github.com/open-telemetry/opentelemetry-cpp/pull/1707) +with breaking changes in the Metrics API and SDK. + ## [1.6.1] 2022-09-22 * [BUILD] Upgrade opentelemetry-proto to v0.19.0 [#1579](https://github.com/open-telemetry/opentelemetry-cpp/pull/1579) @@ -45,12 +96,12 @@ Increment the: Notes: -While [OpenTelemetry sememantic +While [OpenTelemetry semantic convention](https://github.com/open-telemetry/opentelemetry-specification/tree/main/semantic_conventions) is still in experimental state, PR [#1624](https://github.com/open-telemetry/opentelemetry-cpp/pull/1624) upgraded it from 1.12.0 to 1.13.0 which **MAY** break the instrumentation library. Please -update the sementic convention in instruementation library is needed. +update the semantic convention in instrumentation library is needed. ## [1.6.0] 2022-08-15 diff --git a/CMakeLists.txt b/CMakeLists.txt index a1b6934003..e7597fc87a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,10 +64,13 @@ else() set(ARCH riscv) elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(s390x.*|S390X.*)") set(ARCH s390x) + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(sparc.*|SPARC.*)") + set(ARCH sparc) else() message( FATAL_ERROR - "opentelemetry-cpp: unrecognized target processor configuration!") + "opentelemetry-cpp: unrecognized target processor ${CMAKE_SYSTEM_PROCESSOR} configuration!" + ) endif() endif() message(STATUS "Building for architecture ARCH=${ARCH}") @@ -163,6 +166,8 @@ option(BUILD_TESTING "Whether to enable tests" ON) option(BUILD_W3CTRACECONTEXT_TEST "Whether to build w3c trace context" OFF) +option(OTELCPP_MAINTAINER_MODE "Build in maintainer mode (-Wall -Werror)" OFF) + if(WIN32) if(BUILD_TESTING) if(MSVC) @@ -187,6 +192,9 @@ option(WITH_EXAMPLES "Whether to build examples" ON) option(WITH_METRICS_PREVIEW "Whether to build metrics preview" OFF) option(WITH_LOGS_PREVIEW "Whether to build logs preview" OFF) option(WITH_ASYNC_EXPORT_PREVIEW "Whether enable async export" OFF) +# Exemplar specs status is experimental, so behind feature flag by default +option(WITH_METRICS_EXEMPLAR_PREVIEW + "Whethere to enable exemplar within metrics" OFF) find_package(Threads) @@ -355,6 +363,88 @@ if((NOT WITH_API_ONLY) AND USE_NLOHMANN_JSON) endif() endif() +if(OTELCPP_MAINTAINER_MODE) + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + message("Building with gcc in maintainer mode.") + + add_compile_options(-Wall) + add_compile_options(-Werror) + add_compile_options(-Wextra) + + # Tested with GCC 9.4 on github. + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 9.4) + message("Building with additional warnings for gcc.") + + # Relaxed warnings + + # Enforced warnings + + # C++ options only + add_compile_options($<$,CXX>:-Wextra-semi>) + add_compile_options( + $<$,CXX>:-Woverloaded-virtual>) + add_compile_options( + $<$,CXX>:-Wsuggest-override>) + + # C and C++ + add_compile_options(-Wcast-qual) + add_compile_options(-Wformat-security) + add_compile_options(-Wlogical-op) + add_compile_options(-Wmissing-include-dirs) + add_compile_options(-Wstringop-truncation) + add_compile_options(-Wundef) + add_compile_options(-Wvla) + endif() + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + message("Building with clang in maintainer mode.") + + add_compile_options(-Wall) + add_compile_options(-Werror) + add_compile_options(-Wextra) + + # Tested with Clang 11.0 on github. + if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 11.0) + message("Building with additional warnings for clang.") + + # Relaxed warnings + add_compile_options(-Wno-error=unused-private-field) + + # Enforced warnings + add_compile_options(-Wcast-qual) + add_compile_options(-Wconditional-uninitialized) + add_compile_options(-Wextra-semi) + add_compile_options(-Wformat-security) + add_compile_options(-Wheader-hygiene) + add_compile_options(-Winconsistent-missing-destructor-override) + add_compile_options(-Winconsistent-missing-override) + add_compile_options(-Wnewline-eof) + add_compile_options(-Wnon-virtual-dtor) + add_compile_options(-Woverloaded-virtual) + add_compile_options(-Wrange-loop-analysis) + add_compile_options(-Wundef) + add_compile_options(-Wundefined-reinterpret-cast) + add_compile_options(-Wvla) + endif() + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + message("Building with msvc in maintainer mode.") + + add_compile_options(/WX) + add_compile_options(/W4) + + # Relaxed warnings + add_compile_options(/wd4100) + add_compile_options(/wd4125) + add_compile_options(/wd4566) + add_compile_options(/wd4127) + add_compile_options(/wd4512) + add_compile_options(/wd4267) + + # Enforced warnings + elseif() + message(FATAL_ERROR "Building with unknown compiler in maintainer mode.") + endif() +endif(OTELCPP_MAINTAINER_MODE) + list(APPEND CMAKE_PREFIX_PATH "${CMAKE_BINARY_DIR}") include(CTest) diff --git a/README.md b/README.md index 72f0f691a4..3cf157687d 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,7 @@ For edit access, get in touch on ([@open-telemetry/cpp-approvers](https://github.com/orgs/open-telemetry/teams/cpp-approvers)): * [Josh Suereth](https://github.com/jsuereth), Google +* [Marc Alff](https://github.com/marcalff), Oracle * [Reiley Yang](https://github.com/reyang), Microsoft * [WenTao Ou](https://github.com/owent), Tencent diff --git a/api/CMakeLists.txt b/api/CMakeLists.txt index 21aae1792c..5ea07841d4 100644 --- a/api/CMakeLists.txt +++ b/api/CMakeLists.txt @@ -101,3 +101,8 @@ endif() if(WITH_ASYNC_EXPORT_PREVIEW) target_compile_definitions(opentelemetry_api INTERFACE ENABLE_ASYNC_EXPORT) endif() + +if(WITH_METRICS_EXEMPLAR_PREVIEW) + target_compile_definitions(opentelemetry_api + INTERFACE ENABLE_METRICS_EXEMPLAR_PREVIEW) +endif() diff --git a/api/include/opentelemetry/common/kv_properties.h b/api/include/opentelemetry/common/kv_properties.h index 7ac747a733..96442021b5 100644 --- a/api/include/opentelemetry/common/kv_properties.h +++ b/api/include/opentelemetry/common/kv_properties.h @@ -270,4 +270,4 @@ class KeyValueProperties size_t Size() const noexcept { return num_entries_; } }; } // namespace common -OPENTELEMETRY_END_NAMESPACE \ No newline at end of file +OPENTELEMETRY_END_NAMESPACE diff --git a/api/include/opentelemetry/common/macros.h b/api/include/opentelemetry/common/macros.h index 8f88fc8f85..4741677a74 100644 --- a/api/include/opentelemetry/common/macros.h +++ b/api/include/opentelemetry/common/macros.h @@ -90,6 +90,14 @@ # define OPENTELEMETRY_DEPRECATED_MESSAGE(msg) #endif +// Regex support +#if (__GNUC__ == 4 && (__GNUC_MINOR__ == 8 || __GNUC_MINOR__ == 9)) +# define HAVE_WORKING_REGEX 0 +#else +# include +# define HAVE_WORKING_REGEX 1 +#endif + /* clang-format off */ /** diff --git a/api/include/opentelemetry/context/propagation/composite_propagator.h b/api/include/opentelemetry/context/propagation/composite_propagator.h index d7a6cbda17..dedcac85ca 100644 --- a/api/include/opentelemetry/context/propagation/composite_propagator.h +++ b/api/include/opentelemetry/context/propagation/composite_propagator.h @@ -89,4 +89,4 @@ class CompositePropagator : public TextMapPropagator }; } // namespace propagation } // namespace context -OPENTELEMETRY_END_NAMESPACE; +OPENTELEMETRY_END_NAMESPACE diff --git a/api/include/opentelemetry/metrics/meter.h b/api/include/opentelemetry/metrics/meter.h index 0bc9b7116c..96fcb4724b 100644 --- a/api/include/opentelemetry/metrics/meter.h +++ b/api/include/opentelemetry/metrics/meter.h @@ -9,6 +9,7 @@ # include "opentelemetry/nostd/shared_ptr.h" # include "opentelemetry/nostd/span.h" # include "opentelemetry/nostd/string_view.h" +# include "opentelemetry/nostd/unique_ptr.h" # include "opentelemetry/version.h" OPENTELEMETRY_BEGIN_NAMESPACE @@ -28,7 +29,7 @@ class Meter virtual ~Meter() = default; /** - * Creates a Counter with the passed characteristics and returns a shared_ptr to that Counter. + * Creates a Counter with the passed characteristics and returns a unique_ptr to that Counter. * * @param name the name of the new Counter. * @param description a brief description of what the Counter is used for. @@ -36,12 +37,12 @@ class Meter * @return a shared pointer to the created Counter. */ - virtual nostd::shared_ptr> CreateLongCounter( + virtual nostd::unique_ptr> CreateUInt64Counter( nostd::string_view name, nostd::string_view description = "", nostd::string_view unit = "") noexcept = 0; - virtual nostd::shared_ptr> CreateDoubleCounter( + virtual nostd::unique_ptr> CreateDoubleCounter( nostd::string_view name, nostd::string_view description = "", nostd::string_view unit = "") noexcept = 0; @@ -54,7 +55,7 @@ class Meter * @param description a brief description of what the Observable Counter is used for. * @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html. */ - virtual nostd::shared_ptr CreateLongObservableCounter( + virtual nostd::shared_ptr CreateInt64ObservableCounter( nostd::string_view name, nostd::string_view description = "", nostd::string_view unit = "") noexcept = 0; @@ -65,19 +66,19 @@ class Meter nostd::string_view unit = "") noexcept = 0; /** - * Creates a Histogram with the passed characteristics and returns a shared_ptr to that Histogram. + * Creates a Histogram with the passed characteristics and returns a unique_ptr to that Histogram. * * @param name the name of the new Histogram. * @param description a brief description of what the Histogram is used for. * @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html. * @return a shared pointer to the created Histogram. */ - virtual nostd::shared_ptr> CreateLongHistogram( + virtual nostd::unique_ptr> CreateUInt64Histogram( nostd::string_view name, nostd::string_view description = "", nostd::string_view unit = "") noexcept = 0; - virtual nostd::shared_ptr> CreateDoubleHistogram( + virtual nostd::unique_ptr> CreateDoubleHistogram( nostd::string_view name, nostd::string_view description = "", nostd::string_view unit = "") noexcept = 0; @@ -90,7 +91,7 @@ class Meter * @param description a brief description of what the Observable Gauge is used for. * @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html. */ - virtual nostd::shared_ptr CreateLongObservableGauge( + virtual nostd::shared_ptr CreateInt64ObservableGauge( nostd::string_view name, nostd::string_view description = "", nostd::string_view unit = "") noexcept = 0; @@ -101,7 +102,7 @@ class Meter nostd::string_view unit = "") noexcept = 0; /** - * Creates an UpDownCounter with the passed characteristics and returns a shared_ptr to that + * Creates an UpDownCounter with the passed characteristics and returns a unique_ptr to that * UpDownCounter. * * @param name the name of the new UpDownCounter. @@ -109,12 +110,12 @@ class Meter * @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html. * @return a shared pointer to the created UpDownCounter. */ - virtual nostd::shared_ptr> CreateLongUpDownCounter( + virtual nostd::unique_ptr> CreateInt64UpDownCounter( nostd::string_view name, nostd::string_view description = "", nostd::string_view unit = "") noexcept = 0; - virtual nostd::shared_ptr> CreateDoubleUpDownCounter( + virtual nostd::unique_ptr> CreateDoubleUpDownCounter( nostd::string_view name, nostd::string_view description = "", nostd::string_view unit = "") noexcept = 0; @@ -127,7 +128,7 @@ class Meter * @param description a brief description of what the Observable UpDownCounter is used for. * @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html. */ - virtual nostd::shared_ptr CreateLongObservableUpDownCounter( + virtual nostd::shared_ptr CreateInt64ObservableUpDownCounter( nostd::string_view name, nostd::string_view description = "", nostd::string_view unit = "") noexcept = 0; diff --git a/api/include/opentelemetry/metrics/noop.h b/api/include/opentelemetry/metrics/noop.h index 289c2750ad..1200c5c6f1 100644 --- a/api/include/opentelemetry/metrics/noop.h +++ b/api/include/opentelemetry/metrics/noop.h @@ -58,7 +58,7 @@ class NoopUpDownCounter : public UpDownCounter nostd::string_view /* description */, nostd::string_view /* unit */) noexcept {} - ~NoopUpDownCounter() = default; + ~NoopUpDownCounter() override = default; void Add(T /* value */) noexcept override {} void Add(T /* value */, const opentelemetry::context::Context & /* context */) noexcept override {} @@ -87,22 +87,23 @@ class NoopObservableInstrument : public ObservableInstrument class NoopMeter final : public Meter { public: - nostd::shared_ptr> CreateLongCounter(nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept override + nostd::unique_ptr> CreateUInt64Counter( + nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept override { - return nostd::shared_ptr>{new NoopCounter(name, description, unit)}; + return nostd::unique_ptr>{new NoopCounter(name, description, unit)}; } - nostd::shared_ptr> CreateDoubleCounter( + nostd::unique_ptr> CreateDoubleCounter( nostd::string_view name, nostd::string_view description = "", nostd::string_view unit = "") noexcept override { - return nostd::shared_ptr>{new NoopCounter(name, description, unit)}; + return nostd::unique_ptr>{new NoopCounter(name, description, unit)}; } - nostd::shared_ptr CreateLongObservableCounter( + nostd::shared_ptr CreateInt64ObservableCounter( nostd::string_view name, nostd::string_view description = "", nostd::string_view unit = "") noexcept override @@ -120,23 +121,24 @@ class NoopMeter final : public Meter new NoopObservableInstrument(name, description, unit)); } - nostd::shared_ptr> CreateLongHistogram( + nostd::unique_ptr> CreateUInt64Histogram( nostd::string_view name, nostd::string_view description = "", nostd::string_view unit = "") noexcept override { - return nostd::shared_ptr>{new NoopHistogram(name, description, unit)}; + return nostd::unique_ptr>{ + new NoopHistogram(name, description, unit)}; } - nostd::shared_ptr> CreateDoubleHistogram( + nostd::unique_ptr> CreateDoubleHistogram( nostd::string_view name, nostd::string_view description = "", nostd::string_view unit = "") noexcept override { - return nostd::shared_ptr>{new NoopHistogram(name, description, unit)}; + return nostd::unique_ptr>{new NoopHistogram(name, description, unit)}; } - nostd::shared_ptr CreateLongObservableGauge( + nostd::shared_ptr CreateInt64ObservableGauge( nostd::string_view name, nostd::string_view description = "", nostd::string_view unit = "") noexcept override @@ -154,25 +156,25 @@ class NoopMeter final : public Meter new NoopObservableInstrument(name, description, unit)); } - nostd::shared_ptr> CreateLongUpDownCounter( + nostd::unique_ptr> CreateInt64UpDownCounter( nostd::string_view name, nostd::string_view description = "", nostd::string_view unit = "") noexcept override { - return nostd::shared_ptr>{ - new NoopUpDownCounter(name, description, unit)}; + return nostd::unique_ptr>{ + new NoopUpDownCounter(name, description, unit)}; } - nostd::shared_ptr> CreateDoubleUpDownCounter( + nostd::unique_ptr> CreateDoubleUpDownCounter( nostd::string_view name, nostd::string_view description = "", nostd::string_view unit = "") noexcept override { - return nostd::shared_ptr>{ + return nostd::unique_ptr>{ new NoopUpDownCounter(name, description, unit)}; } - nostd::shared_ptr CreateLongObservableUpDownCounter( + nostd::shared_ptr CreateInt64ObservableUpDownCounter( nostd::string_view name, nostd::string_view description = "", nostd::string_view unit = "") noexcept override diff --git a/api/include/opentelemetry/metrics/observer_result.h b/api/include/opentelemetry/metrics/observer_result.h index 39cf3baf7e..ab41bbf025 100644 --- a/api/include/opentelemetry/metrics/observer_result.h +++ b/api/include/opentelemetry/metrics/observer_result.h @@ -46,7 +46,7 @@ class ObserverResultT } }; -using ObserverResult = nostd::variant>, +using ObserverResult = nostd::variant>, nostd::shared_ptr>>; } // namespace metrics diff --git a/api/include/opentelemetry/nostd/internal/absl/types/bad_variant_access.h b/api/include/opentelemetry/nostd/internal/absl/types/bad_variant_access.h index 9783504d2d..81caa0d75c 100644 --- a/api/include/opentelemetry/nostd/internal/absl/types/bad_variant_access.h +++ b/api/include/opentelemetry/nostd/internal/absl/types/bad_variant_access.h @@ -75,7 +75,7 @@ namespace variant_internal { [[noreturn]] static inline void ThrowBadVariantAccess() { THROW_BAD_VARIANT_ACCESS; -}; +} //[[noreturn]] static inline void Rethrow() //{ // THROW_BAD_VARIANT_ACCESS; // Unused! diff --git a/api/include/opentelemetry/std/utility.h b/api/include/opentelemetry/std/utility.h index 7a8233f67d..01cdc18331 100644 --- a/api/include/opentelemetry/std/utility.h +++ b/api/include/opentelemetry/std/utility.h @@ -54,7 +54,7 @@ auto size(const C &c) noexcept(noexcept(c.size())) -> decltype(c.size()) } template -std::size_t size(T (&array)[N]) noexcept +std::size_t size(T (&/* array */)[N]) noexcept { return N; } diff --git a/api/include/opentelemetry/std/variant.h b/api/include/opentelemetry/std/variant.h index cb696ab397..30d38d9c63 100644 --- a/api/include/opentelemetry/std/variant.h +++ b/api/include/opentelemetry/std/variant.h @@ -146,58 +146,58 @@ template constexpr std::variant_alternative_t> &get(std::variant &v) { return std::get(v); -}; +} template constexpr std::variant_alternative_t> &&get(std::variant &&v) { return std::get(std::forward(v)); -}; +} template constexpr const std::variant_alternative_t> &get( const std::variant &v) { return std::get(v); -}; +} template constexpr const std::variant_alternative_t> &&get( const std::variant &&v) { return std::get(std::forward(v)); -}; +} template constexpr T &get(std::variant &v) { return std::get(v); -}; +} template constexpr T &&get(std::variant &&v) { return std::get(std::forward(v)); -}; +} template constexpr const T &get(const std::variant &v) { return std::get(v); -}; +} template constexpr const T &&get(const std::variant &&v) { return std::get(std::forward(v)); -}; +} template constexpr auto visit(_Callable &&_Obj, _Variants &&... _Args) { return std::visit<_Callable, _Variants...>(static_cast<_Callable &&>(_Obj), static_cast<_Variants &&>(_Args)...); -}; +} #endif diff --git a/api/include/opentelemetry/trace/context.h b/api/include/opentelemetry/trace/context.h index 963c187177..0a57e725c1 100644 --- a/api/include/opentelemetry/trace/context.h +++ b/api/include/opentelemetry/trace/context.h @@ -30,4 +30,4 @@ inline context::Context SetSpan(opentelemetry::context::Context &context, } } // namespace trace -OPENTELEMETRY_END_NAMESPACE \ No newline at end of file +OPENTELEMETRY_END_NAMESPACE diff --git a/api/include/opentelemetry/trace/semantic_conventions.h b/api/include/opentelemetry/trace/semantic_conventions.h index 93bb86d789..063b49cf97 100644 --- a/api/include/opentelemetry/trace/semantic_conventions.h +++ b/api/include/opentelemetry/trace/semantic_conventions.h @@ -33,7 +33,40 @@ namespace SemanticConventions /** * The URL of the OpenTelemetry schema for these keys and values. */ -static constexpr const char *SCHEMA_URL = "https://opentelemetry.io/schemas/1.13.0"; +static constexpr const char *SCHEMA_URL = "https://opentelemetry.io/schemas/1.14.0"; + +/** + * The type of the exception (its fully-qualified class name, if applicable). The dynamic type of + * the exception should be preferred over the static type in languages that support it. + */ +static constexpr const char *EXCEPTION_TYPE = "exception.type"; + +/** + * The exception message. + */ +static constexpr const char *EXCEPTION_MESSAGE = "exception.message"; + +/** + * A stacktrace as a string in the natural representation for the language runtime. The + * representation is to be determined and documented by each language SIG. + */ +static constexpr const char *EXCEPTION_STACKTRACE = "exception.stacktrace"; + +/** + * The name identifies the event. + */ +static constexpr const char *EVENT_NAME = "event.name"; + +/** + * The domain identifies the context in which an event happened. An event name is unique only within +a domain. + * + *

Notes: +

  • An {@code event.name} is supposed to be unique only in the context of an +{@code event.domain}, so this allows for two events in different domains to +have same {@code event.name}, yet be unrelated events.
+ */ +static constexpr const char *EVENT_DOMAIN = "event.domain"; /** * The full invoked ARN as provided on the {@code Context} passed to the function ({@code @@ -224,42 +257,6 @@ static constexpr const char *DB_MONGODB_COLLECTION = "db.mongodb.collection"; */ static constexpr const char *DB_SQL_TABLE = "db.sql.table"; -/** - * The type of the exception (its fully-qualified class name, if applicable). The dynamic type of - * the exception should be preferred over the static type in languages that support it. - */ -static constexpr const char *EXCEPTION_TYPE = "exception.type"; - -/** - * The exception message. - */ -static constexpr const char *EXCEPTION_MESSAGE = "exception.message"; - -/** - * A stacktrace as a string in the natural representation for the language runtime. The - * representation is to be determined and documented by each language SIG. - */ -static constexpr const char *EXCEPTION_STACKTRACE = "exception.stacktrace"; - -/** - * SHOULD be set to true if the exception event is recorded at a point where it is known that the -exception is escaping the scope of the span. - * - *

Notes: -

  • An exception is considered to have escaped (or left) the scope of a span, -if that span is ended while the exception is still logically "in flight". -This may be actually "in flight" in some languages (e.g. if the exception -is passed to a Context manager's {@code __exit__} method in Python) but will -usually be caught at the point of recording the exception in most languages.
  • It is usually -not possible to determine at the point where an exception is thrown whether it will escape the scope -of a span. However, it is trivial to know that an exception will escape, if one checks for an active -exception just before ending the span, as done in the example -above.
  • It follows that an exception may still escape the scope of the span even if the -{@code exception.escaped} attribute was not set or set to false, since the event might have been -recorded at a time where it was not clear whether the exception will escape.
- */ -static constexpr const char *EXCEPTION_ESCAPED = "exception.escaped"; - /** * Type of the trigger which caused this function execution. * @@ -961,32 +958,17 @@ static constexpr const char *RPC_JSONRPC_ERROR_CODE = "rpc.jsonrpc.error_code"; */ static constexpr const char *RPC_JSONRPC_ERROR_MESSAGE = "rpc.jsonrpc.error_message"; -/** - * Whether this is a received or sent message. - */ -static constexpr const char *MESSAGE_TYPE = "message.type"; - -/** - * MUST be calculated as two different counters starting from {@code 1} one for sent messages and - one for received message. - * - *

Notes: -

  • This way we guarantee that the values will be consistent between different - implementations.
- */ -static constexpr const char *MESSAGE_ID = "message.id"; - -/** - * Compressed size of the message in bytes. - */ -static constexpr const char *MESSAGE_COMPRESSED_SIZE = "message.compressed_size"; - -/** - * Uncompressed size of the message in bytes. - */ -static constexpr const char *MESSAGE_UNCOMPRESSED_SIZE = "message.uncompressed_size"; - // Enum definitions +namespace EventDomainValues +{ +/** Events from browser apps. */ +static constexpr const char *BROWSER = "browser"; +/** Events from mobile apps. */ +static constexpr const char *DEVICE = "device"; +/** Events from Kubernetes. */ +static constexpr const char *K8S = "k8s"; +} // namespace EventDomainValues + namespace OpentracingRefTypeValues { /** The parent Span depends on the child Span in some capacity. */ @@ -1355,14 +1337,6 @@ static constexpr const int DATA_LOSS = 15; static constexpr const int UNAUTHENTICATED = 16; } // namespace RpcGrpcStatusCodeValues -namespace MessageTypeValues -{ -/** sent. */ -static constexpr const char *SENT = "SENT"; -/** received. */ -static constexpr const char *RECEIVED = "RECEIVED"; -} // namespace MessageTypeValues - } // namespace SemanticConventions } // namespace trace OPENTELEMETRY_END_NAMESPACE diff --git a/api/include/opentelemetry/trace/span_metadata.h b/api/include/opentelemetry/trace/span_metadata.h index 977329a151..f27239c739 100644 --- a/api/include/opentelemetry/trace/span_metadata.h +++ b/api/include/opentelemetry/trace/span_metadata.h @@ -40,4 +40,4 @@ struct EndSpanOptions }; } // namespace trace -OPENTELEMETRY_END_NAMESPACE \ No newline at end of file +OPENTELEMETRY_END_NAMESPACE diff --git a/api/include/opentelemetry/trace/span_startoptions.h b/api/include/opentelemetry/trace/span_startoptions.h index 688b768bd0..9265574a57 100644 --- a/api/include/opentelemetry/trace/span_startoptions.h +++ b/api/include/opentelemetry/trace/span_startoptions.h @@ -42,4 +42,4 @@ struct StartSpanOptions }; } // namespace trace -OPENTELEMETRY_END_NAMESPACE \ No newline at end of file +OPENTELEMETRY_END_NAMESPACE diff --git a/api/include/opentelemetry/version.h b/api/include/opentelemetry/version.h index 85357309bf..06b7136703 100644 --- a/api/include/opentelemetry/version.h +++ b/api/include/opentelemetry/version.h @@ -6,7 +6,7 @@ #include "opentelemetry/detail/preprocessor.h" #define OPENTELEMETRY_ABI_VERSION_NO 1 -#define OPENTELEMETRY_VERSION "1.6.1" +#define OPENTELEMETRY_VERSION "1.7.0" #define OPENTELEMETRY_ABI_VERSION OPENTELEMETRY_STRINGIFY(OPENTELEMETRY_ABI_VERSION_NO) // clang-format off diff --git a/api/test/metrics/noop_sync_instrument_test.cc b/api/test/metrics/noop_sync_instrument_test.cc index 9d7c1f2fe6..3cd5d408e6 100644 --- a/api/test/metrics/noop_sync_instrument_test.cc +++ b/api/test/metrics/noop_sync_instrument_test.cc @@ -9,42 +9,42 @@ TEST(Counter, Add) { - std::shared_ptr> counter{ - new opentelemetry::metrics::NoopCounter("test", "none", "unitless")}; + std::shared_ptr> counter{ + new opentelemetry::metrics::NoopCounter("test", "none", "unitless")}; std::map labels = {{"k1", "v1"}}; - counter->Add(10l, labels); - counter->Add(10l, labels, opentelemetry::context::Context{}); - counter->Add(2l); - counter->Add(2l, opentelemetry::context::Context{}); - counter->Add(10l, {{"k1", "1"}, {"k2", 2}}); - counter->Add(10l, {{"k1", "1"}, {"k2", 2}}, opentelemetry::context::Context{}); + counter->Add(10, labels); + counter->Add(10, labels, opentelemetry::context::Context{}); + counter->Add(2); + counter->Add(2, opentelemetry::context::Context{}); + counter->Add(10, {{"k1", "1"}, {"k2", 2}}); + counter->Add(10, {{"k1", "1"}, {"k2", 2}}, opentelemetry::context::Context{}); } TEST(histogram, Record) { - std::shared_ptr> counter{ - new opentelemetry::metrics::NoopHistogram("test", "none", "unitless")}; + std::shared_ptr> histogram{ + new opentelemetry::metrics::NoopHistogram("test", "none", "unitless")}; std::map labels = {{"k1", "v1"}}; - counter->Record(10l, labels, opentelemetry::context::Context{}); - counter->Record(2l, opentelemetry::context::Context{}); + histogram->Record(10, labels, opentelemetry::context::Context{}); + histogram->Record(2, opentelemetry::context::Context{}); - counter->Record(10l, {{"k1", "1"}, {"k2", 2}}, opentelemetry::context::Context{}); + histogram->Record(10, {{"k1", "1"}, {"k2", 2}}, opentelemetry::context::Context{}); } TEST(UpDownCountr, Record) { - std::shared_ptr> counter{ - new opentelemetry::metrics::NoopUpDownCounter("test", "none", "unitless")}; + std::shared_ptr> counter{ + new opentelemetry::metrics::NoopUpDownCounter("test", "none", "unitless")}; std::map labels = {{"k1", "v1"}}; - counter->Add(10l, labels); - counter->Add(10l, labels, opentelemetry::context::Context{}); - counter->Add(2l); - counter->Add(2l, opentelemetry::context::Context{}); - counter->Add(10l, {{"k1", "1"}, {"k2", 2}}); - counter->Add(10l, {{"k1", "1"}, {"k2", 2}}, opentelemetry::context::Context{}); + counter->Add(10, labels); + counter->Add(10, labels, opentelemetry::context::Context{}); + counter->Add(2); + counter->Add(2, opentelemetry::context::Context{}); + counter->Add(10, {{"k1", "1"}, {"k2", 2}}); + counter->Add(10, {{"k1", "1"}, {"k2", 2}}, opentelemetry::context::Context{}); } -#endif \ No newline at end of file +#endif diff --git a/api/test/nostd/unique_ptr_test.cc b/api/test/nostd/unique_ptr_test.cc index 1d2e6c062f..aa49d387b7 100644 --- a/api/test/nostd/unique_ptr_test.cc +++ b/api/test/nostd/unique_ptr_test.cc @@ -122,7 +122,7 @@ TEST(UniquePtrTest, Reset) { bool was_destructed1; unique_ptr ptr{new A{was_destructed1}}; - bool was_destructed2; + bool was_destructed2 = true; ptr.reset(new A{was_destructed2}); EXPECT_TRUE(was_destructed1); EXPECT_FALSE(was_destructed2); diff --git a/api/test/trace/span_benchmark.cc b/api/test/trace/span_benchmark.cc index ef14cd4ca3..3120eb0e5a 100644 --- a/api/test/trace/span_benchmark.cc +++ b/api/test/trace/span_benchmark.cc @@ -55,19 +55,19 @@ void BM_NestedSpanCreationWithScope(benchmark::State &state) auto tracer = initTracer(); while (state.KeepRunning()) { - auto span = tracer->StartSpan("outer"); - auto scope = tracer->WithActiveSpan(span); + auto o_span = tracer->StartSpan("outer"); + auto o_scope = tracer->WithActiveSpan(o_span); { - auto span = tracer->StartSpan("inner"); - auto scope = tracer->WithActiveSpan(span); + auto i_span = tracer->StartSpan("inner"); + auto i_scope = tracer->WithActiveSpan(i_span); { - auto span = tracer->StartSpan("innermost"); - auto scope = tracer->WithActiveSpan(span); - span->End(); + auto im_span = tracer->StartSpan("innermost"); + auto im_scope = tracer->WithActiveSpan(im_span); + im_span->End(); } - span->End(); + i_span->End(); } - span->End(); + o_span->End(); } } @@ -115,10 +115,10 @@ void BM_SpanCreationWitContextPropagation(benchmark::State &state) nostd::shared_ptr(new trace_api::DefaultSpan(outer_span_context)); trace_api::SetSpan(current_ctx, outer_span); auto inner_child = tracer->StartSpan("inner"); - auto scope = tracer->WithActiveSpan(inner_child); + auto inner_scope = tracer->WithActiveSpan(inner_child); { auto innermost_child = tracer->StartSpan("innermost"); - auto scope = tracer->WithActiveSpan(innermost_child); + auto innermost_scope = tracer->WithActiveSpan(innermost_child); innermost_child->End(); } inner_child->End(); diff --git a/buildscripts/semantic-convention/generate.sh b/buildscripts/semantic-convention/generate.sh index 5cf63ce5c2..ba8470e36d 100755 --- a/buildscripts/semantic-convention/generate.sh +++ b/buildscripts/semantic-convention/generate.sh @@ -10,7 +10,7 @@ SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" ROOT_DIR="${SCRIPT_DIR}/../../" # freeze the spec & generator tools versions to make SemanticAttributes generation reproducible -SEMCONV_VERSION=1.13.0 +SEMCONV_VERSION=1.14.0 SPEC_VERSION=v$SEMCONV_VERSION SCHEMA_URL=https://opentelemetry.io/schemas/$SEMCONV_VERSION GENERATOR_VERSION=0.14.0 @@ -28,10 +28,11 @@ git reset --hard FETCH_HEAD cd ${SCRIPT_DIR} docker run --rm \ - -v ${SCRIPT_DIR}/opentelemetry-specification/semantic_conventions/trace:/source \ + -v ${SCRIPT_DIR}/opentelemetry-specification/semantic_conventions:/source \ -v ${SCRIPT_DIR}/templates:/templates \ -v ${ROOT_DIR}/api/include/opentelemetry/trace/:/output \ otel/semconvgen:$GENERATOR_VERSION \ + --only span \ -f /source code \ --template /templates/SemanticAttributes.h.j2 \ --output /output/semantic_conventions.h \ @@ -42,10 +43,11 @@ docker run --rm \ -Dnamespace_close="}" docker run --rm \ - -v ${SCRIPT_DIR}/opentelemetry-specification/semantic_conventions/resource:/source \ + -v ${SCRIPT_DIR}/opentelemetry-specification/semantic_conventions:/source \ -v ${SCRIPT_DIR}/templates:/templates \ -v ${ROOT_DIR}/sdk/include/opentelemetry/sdk/resource/:/output \ otel/semconvgen:$GENERATOR_VERSION \ + --only resource \ -f /source code \ --template /templates/SemanticAttributes.h.j2 \ --output /output/semantic_conventions.h \ diff --git a/ci/README.md b/ci/README.md index 14a6107eb8..65bea032d7 100644 --- a/ci/README.md +++ b/ci/README.md @@ -4,6 +4,7 @@ CI tests can be run on docker by invoking the script `./ci/run_docker.sh ./ci/do_ci.sh {TARGET}` where the targets are: * `cmake.test`: build cmake targets and run tests. +* `cmake.maintainer.test`: build with cmake and test, in maintainer mode. * `cmake.legacy.test`: build cmake targets with gcc 4.8 and run tests. * `cmake.c++20.test`: build cmake targets with the C++20 standard and run tests. * `cmake.test_example_plugin`: build and test an example OpenTelemetry plugin. diff --git a/ci/do_ci.ps1 b/ci/do_ci.ps1 index 88e7becf90..f0d08a6d4d 100644 --- a/ci/do_ci.ps1 +++ b/ci/do_ci.ps1 @@ -48,6 +48,27 @@ switch ($action) { exit $exit } } + "cmake.maintainer.test" { + cd "$BUILD_DIR" + cmake $SRC_DIR ` + -DOTELCPP_MAINTAINER_MODE=ON ` + -DVCPKG_TARGET_TRIPLET=x64-windows ` + "-DCMAKE_TOOLCHAIN_FILE=$VCPKG_DIR/scripts/buildsystems/vcpkg.cmake" + $exit = $LASTEXITCODE + if ($exit -ne 0) { + exit $exit + } + cmake --build . + $exit = $LASTEXITCODE + if ($exit -ne 0) { + exit $exit + } + ctest -C Debug + $exit = $LASTEXITCODE + if ($exit -ne 0) { + exit $exit + } + } "cmake.with_async_export.test" { cd "$BUILD_DIR" cmake $SRC_DIR ` diff --git a/ci/do_ci.sh b/ci/do_ci.sh index bf775fa564..be583d75e1 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -59,7 +59,7 @@ mkdir -p "${BUILD_DIR}" [ -z "${PLUGIN_DIR}" ] && export PLUGIN_DIR=$HOME/plugin mkdir -p "${PLUGIN_DIR}" -BAZEL_OPTIONS="--copt=-DENABLE_LOGS_PREVIEW --copt=-DENABLE_TEST" +BAZEL_OPTIONS="--copt=-DENABLE_LOGS_PREVIEW --copt=-DENABLE_TEST --copt=-DENABLE_METRICS_EXEMPLAR_PREVIEW" BAZEL_TEST_OPTIONS="$BAZEL_OPTIONS --test_output=errors" @@ -82,13 +82,31 @@ if [[ "$1" == "cmake.test" ]]; then -DWITH_ZIPKIN=ON \ -DWITH_JAEGER=ON \ -DWITH_ELASTICSEARCH=ON \ - -DWITH_METRICS_PREVIEW=ON \ + -DWITH_METRICS_PREVIEW=OFF \ + -DWITH_METRICS_EXEMPLAR_PREVIEW=ON \ -DWITH_LOGS_PREVIEW=ON \ -DCMAKE_CXX_FLAGS="-Werror" \ "${SRC_DIR}" make make test exit 0 +elif [[ "$1" == "cmake.maintainer.test" ]]; then + cd "${BUILD_DIR}" + rm -rf * + cmake -DCMAKE_BUILD_TYPE=Debug \ + -DWITH_PROMETHEUS=ON \ + -DWITH_ZIPKIN=ON \ + -DWITH_JAEGER=ON \ + -DWITH_ELASTICSEARCH=ON \ + -DWITH_LOGS_PREVIEW=ON \ + -DWITH_METRICS_PREVIEW=OFF \ + -DWITH_METRICS_EXEMPLAR_PREVIEW=ON \ + -DWITH_ASYNC_EXPORT_PREVIEW=ON \ + -DOTELCPP_MAINTAINER_MODE=ON \ + "${SRC_DIR}" + make -k + make test + exit 0 elif [[ "$1" == "cmake.with_async_export.test" ]]; then cd "${BUILD_DIR}" rm -rf * @@ -98,6 +116,7 @@ elif [[ "$1" == "cmake.with_async_export.test" ]]; then -DWITH_JAEGER=ON \ -DWITH_ELASTICSEARCH=ON \ -DWITH_METRICS_PREVIEW=OFF \ + -DWITH_METRICS_EXEMPLAR_PREVIEW=ON \ -DWITH_LOGS_PREVIEW=ON \ -DCMAKE_CXX_FLAGS="-Werror" \ -DWITH_ASYNC_EXPORT_PREVIEW=ON \ @@ -126,6 +145,7 @@ elif [[ "$1" == "cmake.abseil.test" ]]; then rm -rf * cmake -DCMAKE_BUILD_TYPE=Debug \ -DWITH_METRICS_PREVIEW=OFF \ + -DWITH_METRICS_EXEMPLAR_PREVIEW=ON \ -DWITH_LOGS_PREVIEW=ON \ -DCMAKE_CXX_FLAGS="-Werror" \ -DWITH_ASYNC_EXPORT_PREVIEW=ON \ @@ -150,6 +170,7 @@ elif [[ "$1" == "cmake.c++20.stl.test" ]]; then rm -rf * cmake -DCMAKE_BUILD_TYPE=Debug \ -DWITH_METRICS_PREVIEW=OFF \ + -DWITH_METRICS_EXEMPLAR_PREVIEW=ON \ -DWITH_LOGS_PREVIEW=ON \ -DCMAKE_CXX_FLAGS="-Werror" \ -DWITH_ASYNC_EXPORT_PREVIEW=ON \ @@ -290,9 +311,13 @@ elif [[ "$1" == "bazel.nortti" ]]; then exit 0 elif [[ "$1" == "bazel.asan" ]]; then bazel $BAZEL_STARTUP_OPTIONS test --config=asan $BAZEL_TEST_OPTIONS_ASYNC //... + bazel $BAZEL_STARTUP_OPTIONS run --config=asan $BAZEL_TEST_OPTIONS_ASYNC \ + //examples/metrics_simple:metrics_ostream_example > /dev/null exit 0 elif [[ "$1" == "bazel.tsan" ]]; then bazel $BAZEL_STARTUP_OPTIONS test --config=tsan $BAZEL_TEST_OPTIONS_ASYNC //... + bazel $BAZEL_STARTUP_OPTIONS run --config=tsan $BAZEL_TEST_OPTIONS_ASYNC \ + //examples/metrics_simple:metrics_ostream_example > /dev/null exit 0 elif [[ "$1" == "bazel.valgrind" ]]; then bazel $BAZEL_STARTUP_OPTIONS build $BAZEL_OPTIONS_ASYNC //... diff --git a/ci/setup_grpc.sh b/ci/setup_grpc.sh index d42fbb7d2e..6e86f20cb9 100755 --- a/ci/setup_grpc.sh +++ b/ci/setup_grpc.sh @@ -6,14 +6,15 @@ set -e export DEBIAN_FRONTEND=noninteractive old_grpc_version='v1.33.2' -new_grpc_version='v1.43.2' +new_grpc_version='v1.48.1' gcc_version_for_new_grpc='5.1' +std_version='14' install_grpc_version=${new_grpc_version} grpc_version='v1.39.0' install_dir='/usr/local/' usage() { echo "Usage: $0 [-v ] [-i "] 1>&2; exit 1;} -while getopts ":v:i:" o; do +while getopts ":v:i:r:s:" o; do case "${o}" in v) gcc_version=${OPTARG} @@ -21,6 +22,12 @@ while getopts ":v:i:" o; do i) install_dir=${OPTARG} ;; + r) + install_grpc_version=${OPTARG} + ;; + s) + std_version=${OPTARG} + ;; *) usage ;; @@ -31,6 +38,7 @@ if [ -z "${gcc_version}" ]; then fi if [[ "${gcc_version}" < "${gcc_version_for_new_grpc}" ]]; then echo "less" + std_version='11' install_grpc_version=${old_grpc_version} fi if ! type cmake > /dev/null; then @@ -52,7 +60,7 @@ cmake -DCMAKE_BUILD_TYPE=Release \ make -j${nproc} install && popd mkdir -p build && pushd build cmake -DgRPC_INSTALL=ON \ - -DCMAKE_CXX_STANDARD=11 \ + -DCMAKE_CXX_STANDARD=${std_version} \ -DgRPC_BUILD_TESTS=OFF \ -DCMAKE_INSTALL_PREFIX=$INSTALL_DIR \ -DCMAKE_PREFIX_PATH=$INSTALL_DIR \ diff --git a/docs/dependencies.md b/docs/dependencies.md index 4cd4d39a5f..4cb082186d 100644 --- a/docs/dependencies.md +++ b/docs/dependencies.md @@ -31,7 +31,7 @@ Both these dependencies are listed here: License` - Uses Abseil C++ Library for `absl::variant` as default `nostd::variant` if `WITH_ABSEIL` cmake option or - `--@io_opentelemetry_cpp/api:with_abseil=true` (aka + `--@io_opentelemetry_cpp//api:with_abseil=true` (aka `--//api:with_abseil=true`) bazel option is enabled. License: `Apache License 2.0` @@ -77,7 +77,9 @@ Both these dependencies are listed here: framework. - `thrift` compiler to generate C++ stubs for IDL data model for Jaeger. - `libthrift` library to generate serialised trace/metrics/log data to be - sent to remote Jaeger service. + sent to remote Jaeger service. Note: libthrift **0.12.0** doesn't work + with this Jaeger exporter. See + [#1680](https://github.com/open-telemetry/opentelemetry-cpp/issues/1680). - License: `Apache License 2.0` - [ETW](/exporters/etw) diff --git a/docs/public/Doxyfile b/docs/public/Doxyfile index b605e1e712..263cf57922 100644 --- a/docs/public/Doxyfile +++ b/docs/public/Doxyfile @@ -799,11 +799,13 @@ INPUT = \ ../../api//include/opentelemetry/nostd/string_view.h \ ../../api/include/opentelemetry/nostd/unique_ptr.h \ ../../api/include/opentelemetry/nostd/variant.h \ + ../../api/include/opentelemetry/metrics \ ../../api/include/opentelemetry/trace \ ../../sdk/include/opentelemetry/sdk/instrumentationscope \ ../../sdk/include/opentelemetry/sdk/instrumentationlibrary \ ../../sdk/include/opentelemetry/sdk/resource \ - ../../sdk/include/opentelemetry/sdk/trace + ../../sdk/include/opentelemetry/sdk/metrics \ + ../../sdk/include/opentelemetry/sdk/trace \ # This tag can be used to specify the character encoding of the source files diff --git a/docs/public/conf.py b/docs/public/conf.py index eb79a39815..22e8709c6f 100644 --- a/docs/public/conf.py +++ b/docs/public/conf.py @@ -21,7 +21,7 @@ author = 'OpenTelemetry authors' # The full version, including alpha/beta/rc tags -release = "1.6.1" +release = "1.7.0" # Run sphinx on subprojects and copy output # ----------------------------------------- diff --git a/docs/public/index.rst b/docs/public/index.rst index 3103b8ca94..6eee939cfd 100644 --- a/docs/public/index.rst +++ b/docs/public/index.rst @@ -27,6 +27,7 @@ OpenTelemetry C++ otel_docs/namespace_opentelemetry__baggage otel_docs/namespace_opentelemetry__common otel_docs/namespace_opentelemetry__context + otel_docs/namespace_opentelemetry__metrics .. toctree:: :maxdepth: 1 @@ -35,6 +36,8 @@ OpenTelemetry C++ otel_docs/namespace_opentelemetry__sdk__trace otel_docs/namespace_opentelemetry__sdk__instrumentationlibrary otel_docs/namespace_opentelemetry__sdk__resource + otel_docs/namespace_opentelemetry__sdk__metrics + .. toctree:: :maxdepth: 1 diff --git a/examples/common/metrics_foo_library/foo_library.cc b/examples/common/metrics_foo_library/foo_library.cc index ec4fec736d..4b4ea98fd2 100644 --- a/examples/common/metrics_foo_library/foo_library.cc +++ b/examples/common/metrics_foo_library/foo_library.cc @@ -18,13 +18,15 @@ namespace metrics_api = opentelemetry::metrics; namespace { +static nostd::shared_ptr double_observable_counter; + std::map get_random_attr() { - static const std::vector> labels = {{"key1", "value1"}, - {"key2", "value2"}, - {"key3", "value3"}, - {"key4", "value4"}, - {"key5", "value5"}}; + const std::vector> labels = {{"key1", "value1"}, + {"key2", "value2"}, + {"key3", "value3"}, + {"key4", "value4"}, + {"key5", "value5"}}; return std::map{labels[rand() % (labels.size() - 1)], labels[rand() % (labels.size() - 1)]}; } @@ -32,20 +34,21 @@ std::map get_random_attr() class MeasurementFetcher { public: - static void Fetcher(opentelemetry::metrics::ObserverResult observer_result, void *state) + static void Fetcher(opentelemetry::metrics::ObserverResult observer_result, void * /* state */) { - std::map labels = get_random_attr(); - auto labelkv = opentelemetry::common::KeyValueIterableView{labels}; if (nostd::holds_alternative< nostd::shared_ptr>>(observer_result)) { - double val = (rand() % 700) + 1.1; + double random_incr = (rand() % 5) + 1.1; + value_ += random_incr; nostd::get>>( observer_result) - ->Observe(val /*, labelkv */); + ->Observe(value_ /*, labelkv */); } } + static double value_; }; +double MeasurementFetcher::value_ = 0.0; } // namespace void foo_library::counter_example(const std::string &name) @@ -55,7 +58,7 @@ void foo_library::counter_example(const std::string &name) nostd::shared_ptr meter = provider->GetMeter(name, "1.2.0"); auto double_counter = meter->CreateDoubleCounter(counter_name); - while (true) + for (uint32_t i = 0; i < 20; ++i) { double val = (rand() % 700) + 1.1; double_counter->Add(val); @@ -68,9 +71,9 @@ void foo_library::observable_counter_example(const std::string &name) std::string counter_name = name + "_observable_counter"; auto provider = metrics_api::Provider::GetMeterProvider(); nostd::shared_ptr meter = provider->GetMeter(name, "1.2.0"); - auto counter = meter->CreateDoubleObservableCounter(counter_name); - counter->AddCallback(MeasurementFetcher::Fetcher, nullptr); - while (true) + double_observable_counter = meter->CreateDoubleObservableCounter(counter_name); + double_observable_counter->AddCallback(MeasurementFetcher::Fetcher, nullptr); + for (uint32_t i = 0; i < 20; ++i) { std::this_thread::sleep_for(std::chrono::milliseconds(500)); } @@ -83,7 +86,7 @@ void foo_library::histogram_example(const std::string &name) nostd::shared_ptr meter = provider->GetMeter(name, "1.2.0"); auto histogram_counter = meter->CreateDoubleHistogram(histogram_name, "des", "unit"); auto context = opentelemetry::context::Context{}; - while (true) + for (uint32_t i = 0; i < 20; ++i) { double val = (rand() % 700) + 1.1; std::map labels = get_random_attr(); diff --git a/examples/grpc/tracer_common.h b/examples/grpc/tracer_common.h index 51ffeb101f..71f0afeaa7 100644 --- a/examples/grpc/tracer_common.h +++ b/examples/grpc/tracer_common.h @@ -29,7 +29,7 @@ class GrpcClientCarrier : public opentelemetry::context::propagation::TextMapCar GrpcClientCarrier(ClientContext *context) : context_(context) {} GrpcClientCarrier() = default; virtual opentelemetry::nostd::string_view Get( - opentelemetry::nostd::string_view key) const noexcept override + opentelemetry::nostd::string_view /* key */) const noexcept override { return ""; } @@ -60,8 +60,8 @@ class GrpcServerCarrier : public opentelemetry::context::propagation::TextMapCar return ""; } - virtual void Set(opentelemetry::nostd::string_view key, - opentelemetry::nostd::string_view value) noexcept override + virtual void Set(opentelemetry::nostd::string_view /* key */, + opentelemetry::nostd::string_view /* value */) noexcept override { // Not required for server } diff --git a/examples/http/server.cc b/examples/http/server.cc index b451499d58..12309cdb26 100644 --- a/examples/http/server.cc +++ b/examples/http/server.cc @@ -29,8 +29,9 @@ class RequestHandler : public HTTP_SERVER_NS::HttpRequestCallback std::string span_name = request.uri; // extract context from http header - const HttpTextMapCarrier> carrier( - (std::map &)request.headers); + std::map &request_headers = + const_cast &>(request.headers); + const HttpTextMapCarrier> carrier(request_headers); auto prop = context::propagation::GlobalTextMapPropagator::GetGlobalPropagator(); auto current_ctx = context::RuntimeContext::GetCurrent(); auto new_context = prop->Extract(carrier, current_ctx); diff --git a/examples/http/server.h b/examples/http/server.h index 2b94bf3a68..1f73744d65 100644 --- a/examples/http/server.h +++ b/examples/http/server.h @@ -50,4 +50,4 @@ class HttpServer : public HTTP_SERVER_NS::HttpRequestCallback ~HttpServer() { Stop(); } }; -} // namespace \ No newline at end of file +} // namespace diff --git a/examples/metrics_simple/README.md b/examples/metrics_simple/README.md index b2c5dc0a74..7e4f832160 100644 --- a/examples/metrics_simple/README.md +++ b/examples/metrics_simple/README.md @@ -1,86 +1,116 @@ # Simple Metrics Example -This example initializes the metrics pipeline with 2 different instrument types. -Here are more detailed explanations of each part. +This example initializes the metrics pipeline with 3 different instrument types: -1: Initialize an exporter and a reader. In this case, we initialize an OStream -Exporter which will print to stdout by default. -The reader periodically collects metrics from the collector and exports them. +- [Counter](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#counter) +- [Histogram](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#histogram) +- [Asynchronous/Observable Counter](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#asynchronous-counter) -```cpp -std::unique_ptr exporter{new exportermetrics::OStreamMetricExporter}; -std::unique_ptr reader{ - new metric_sdk::PeriodicExportingMetricReader(std::move(exporter), options)}; -``` + Here are more detailed steps with explanation. Note that the steps 4, 6, and 8 + are done in Instrumentation library for creating and recording Instruments, + and rest of the steps are done in application to configure SDK. -2: Initialize a MeterProvider and add the reader. -We will use this to obtain Meter objects in the future. + Namespace alias used in below steps -```cpp -auto provider = std::shared_ptr(new opentelemetry::metrics::MeterProvider()); -auto p = std::static_pointer_cast(provider); -p->AddMetricReader(std::move(reader)); -``` - -3: Create and add a view to the provider. - -```cpp -std::unique_ptr instrument_selector{ - new metric_sdk::InstrumentSelector(metric_sdk::InstrumentType::kCounter, "name_counter")}; -std::unique_ptr meter_selector{ - new metric_sdk::MeterSelector(name, version, schema)}; -std::unique_ptr sum_view{ - new metric_sdk::View{name, "description", metric_sdk::AggregationType::kSum}}; -p->AddView(std::move(instrument_selector), std::move(meter_selector), std::move(sum_view)); -``` - -4: Then create a -[Counter](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#counter) -instrument from it. Every Meter pointer returned by the -MeterProvider points to the same Meter. This means that the Meter will be able -to combine metrics captured from different functions without having to -constantly pass the Meter around the library. - -```cpp -nostd::shared_ptr meter = provider->GetMeter(name, "1.2.0"); -auto double_counter = meter->CreateDoubleCounter(counter_name); -// Create a label set which annotates metric values -std::map labels = {{"key", "value"}}; -auto labelkv = common::KeyValueIterableView{labels}; -double_counter->Add(val, labelkv); -``` - -5: To use histogram instrument, a view with proper `InstrumentType` and `AggregationType` -has to be added to the provider. - -```cpp -std::unique_ptr histogram_instrument_selector{ - new metric_sdk::InstrumentSelector(metric_sdk::InstrumentType::kHistogram, "histogram_name")}; -std::unique_ptr histogram_meter_selector{ - new metric_sdk::MeterSelector(name, version, schema)}; -std::unique_ptr histogram_view{ - new metric_sdk::View{name, "description", metric_sdk::AggregationType::kHistogram}}; -p->AddView(std::move(histogram_instrument_selector), std::move(histogram_meter_selector), - std::move(histogram_view)); - -auto histogram_counter = meter->CreateDoubleHistogram("histogram_name"); -auto context = opentelemetry::context::Context{}; -histogram_counter->Record(val, labelkv, context); -``` - -See [CONTRIBUTING.md](../../CONTRIBUTING.md) for instructions on building and -running the example. + ```cpp +using namespace metrics_api = opentelemetry::metrics; +using namespace metric_sdk = opentelemetry::sdk::metrics; +using namespace exportermetrics = opentelemetry::exporters; -## Additional Documentation + ``` -[API -Design](https://github.com/open-o11y/docs/blob/master/cpp-metrics/api-design.md) +1. Initialize an exporter and a reader. In this case, we initialize an OStream +Exporter which will print to stdout by default. +The reader periodically collects metrics from the Aggregation Store and exports them. -[SDK -Design](https://github.com/open-o11y/docs/blob/master/cpp-metrics/sdk-design.md) + ```cpp + std::unique_ptr exporter{new exportermetrics::OStreamMetricExporter}; + std::unique_ptr reader{ + new metric_sdk::PeriodicExportingMetricReader(std::move(exporter), options)}; + ``` -[OStreamExporters -Design](https://github.com/open-o11y/docs/blob/master/cpp-ostream/ostream-exporter-design.md) +2. Initialize a MeterProvider and add the reader. +We will use this to obtain Meter objects in the future. -[OpenTelemetry C++ Metrics -Overview](https://github.com/open-o11y/docs/blob/master/cpp-metrics/README.md) + ```cpp + auto provider = std::shared_ptr(new metric_sdk::MeterProvider()); + auto p = std::static_pointer_cast(provider); + p->AddMetricReader(std::move(reader)); + ``` + +3. Optional: Create a view to map the Counter Instrument to Sum Aggregation. +Add this view to provider. View creation is optional unless we want to add +custom aggregation config, and attribute processor. Metrics SDK will implicitly +create a missing view with default mapping between Instrument and Aggregation. + + ```cpp + std::unique_ptr instrument_selector{ + new metric_sdk::InstrumentSelector(metric_sdk::InstrumentType::kCounter, "counter_name")}; + std::unique_ptr meter_selector{ + new metric_sdk::MeterSelector(name, version, schema)}; + std::unique_ptr sum_view{ + new metric_sdk::View{name, "description", metric_sdk::AggregationType::kSum}}; + p->AddView(std::move(instrument_selector), std::move(meter_selector), std::move(sum_view)); + ``` + +4. Create a Counter instrument from the Meter, and record the measurement. +Every Meter pointer returned by the MeterProvider points to the same Meter. +This means that the Meter will be able to combine metrics captured from +different functions without having to constantly pass the Meter around the library. + + ```cpp + auto meter = provider->GetMeter(name, "1.2.0"); + auto double_counter = meter->CreateDoubleCounter(counter_name); + // Create a label set which annotates metric values + std::map labels = {{"key", "value"}}; + auto labelkv = common::KeyValueIterableView{labels}; + double_counter->Add(val, labelkv); + ``` + +5. Optional: Create a view to map the Histogram Instrument to Histogram Aggregation. + + ```cpp + std::unique_ptr histogram_instrument_selector{ + new metric_sdk::InstrumentSelector(metric_sdk::InstrumentType::kHistogram, "histogram_name")}; + std::unique_ptr histogram_meter_selector{ + new metric_sdk::MeterSelector(name, version, schema)}; + std::unique_ptr histogram_view{ + new metric_sdk::View{name, "description", metric_sdk::AggregationType::kHistogram}}; + p->AddView(std::move(histogram_instrument_selector), std::move(histogram_meter_selector), + std::move(histogram_view)); + ``` + +6. Create a Histogram instrument from the Meter, and record the measurement. + + ```cpp + auto meter = provider->GetMeter(name, "1.2.0"); + auto histogram_counter = meter->CreateDoubleHistogram("histogram_name"); + histogram_counter->Record(val, labelkv); + ``` + +7. Optional: Create a view to map the Observable Counter Instrument to Sum Aggregation + + ```cpp + std::unique_ptr observable_instrument_selector{ + new metric_sdk::InstrumentSelector(metric_sdk::InstrumentType::kObservableCounter, + "observable_counter_name")}; + std::unique_ptr observable_meter_selector{ + new metric_sdk::MeterSelector(name, version, schema)}; + std::unique_ptr observable_sum_view{ + new metric_sdk::View{name, "description", metric_sdk::AggregationType::kSum}}; + p->AddView(std::move(observable_instrument_selector), std::move(observable_meter_selector), + std::move(observable_sum_view)); + ``` + +8. Create a Observable Counter Instrument from the Meter, and add a callback. +The callbackwould be used to record the measurement during metrics collection. +Ensure to keep the Instrument object active for the lifetime of collection. + + ```cpp + auto meter = provider->GetMeter(name, "1.2.0"); + auto counter = meter->CreateDoubleObservableCounter(counter_name); + counter->AddCallback(MeasurementFetcher::Fetcher, nullptr); + ``` + +See [INSTALL.md](../../INSTALL.md) for instructions on building and +running the example. diff --git a/examples/metrics_simple/metrics_ostream.cc b/examples/metrics_simple/metrics_ostream.cc index 669362830b..627e06856e 100644 --- a/examples/metrics_simple/metrics_ostream.cc +++ b/examples/metrics_simple/metrics_ostream.cc @@ -29,7 +29,8 @@ namespace void initMetrics(const std::string &name) { - std::unique_ptr exporter{new exportermetrics::OStreamMetricExporter}; + std::unique_ptr exporter{ + new exportermetrics::OStreamMetricExporter}; std::string version{"1.2.0"}; std::string schema{"https://opentelemetry.io/schemas/1.2.0"}; @@ -62,7 +63,7 @@ void initMetrics(const std::string &name) std::unique_ptr observable_meter_selector{ new metric_sdk::MeterSelector(name, version, schema)}; std::unique_ptr observable_sum_view{ - new metric_sdk::View{name, "description", metric_sdk::AggregationType::kSum}}; + new metric_sdk::View{name, "test_description", metric_sdk::AggregationType::kSum}}; p->AddView(std::move(observable_instrument_selector), std::move(observable_meter_selector), std::move(observable_sum_view)); @@ -73,11 +74,10 @@ void initMetrics(const std::string &name) std::unique_ptr histogram_meter_selector{ new metric_sdk::MeterSelector(name, version, schema)}; std::shared_ptr aggregation_config{ - new opentelemetry::sdk::metrics::HistogramAggregationConfig}; - static_cast *>( - aggregation_config.get()) - ->boundaries_ = - std::list{0.0, 50.0, 100.0, 250.0, 500.0, 750.0, 1000.0, 2500.0, 5000.0, 10000.0}; + new opentelemetry::sdk::metrics::HistogramAggregationConfig}; + static_cast(aggregation_config.get()) + ->boundaries_ = std::list{0.0, 50.0, 100.0, 250.0, 500.0, 750.0, + 1000.0, 2500.0, 5000.0, 10000.0, 20000.0}; std::unique_ptr histogram_view{new metric_sdk::View{ name, "description", metric_sdk::AggregationType::kHistogram, aggregation_config}}; p->AddView(std::move(histogram_instrument_selector), std::move(histogram_meter_selector), diff --git a/examples/multithreaded/main.cc b/examples/multithreaded/main.cc index bb6020bf58..33679f8309 100644 --- a/examples/multithreaded/main.cc +++ b/examples/multithreaded/main.cc @@ -46,7 +46,7 @@ void run_threads() // parent spans across threads. threads.push_back(std::thread([=] { trace_api::Scope scope(thread_span); - auto thread_span = + auto thread_span_2 = get_tracer()->StartSpan(std::string("thread ") + std::to_string(thread_num)); })); } diff --git a/examples/otlp/BUILD b/examples/otlp/BUILD index 795493faa2..26dc26d7c9 100644 --- a/examples/otlp/BUILD +++ b/examples/otlp/BUILD @@ -71,3 +71,22 @@ cc_binary( "//sdk/src/trace", ], ) + +cc_binary( + name = "example_otlp_grpc_metrics", + srcs = [ + "grpc_metric_main.cc", + ], + tags = [ + "examples", + "metrics", + "otlp", + ], + deps = [ + "//api", + "//examples/common/metrics_foo_library:common_metrics_foo_library", + "//exporters/otlp:otlp_grpc_exporter", + "//exporters/otlp:otlp_grpc_metric_exporter", + "//sdk/src/metrics", + ], +) diff --git a/examples/otlp/grpc_metric_main.cc b/examples/otlp/grpc_metric_main.cc index c316ed4d1b..6f2d143c70 100644 --- a/examples/otlp/grpc_metric_main.cc +++ b/examples/otlp/grpc_metric_main.cc @@ -94,4 +94,6 @@ int main(int argc, char *argv[]) histogram_example.join(); } } +#else +int main() {} #endif diff --git a/examples/plugin/plugin/factory_impl.cc b/examples/plugin/plugin/factory_impl.cc index b3bafe7053..b262facfb8 100644 --- a/examples/plugin/plugin/factory_impl.cc +++ b/examples/plugin/plugin/factory_impl.cc @@ -25,8 +25,8 @@ class FactoryImpl final : public plugin::Factory::FactoryImpl public: // opentelemetry::plugin::Factory::FactoryImpl nostd::unique_ptr MakeTracerHandle( - nostd::string_view tracer_config, - nostd::unique_ptr &error_message) const noexcept override + nostd::string_view /* tracer_config */, + nostd::unique_ptr & /* error_message */) const noexcept override { std::shared_ptr tracer{new (std::nothrow) Tracer{""}}; if (tracer == nullptr) @@ -46,4 +46,4 @@ static nostd::unique_ptr MakeFactoryImpl( return nostd::unique_ptr{new (std::nothrow) FactoryImpl{}}; } -OPENTELEMETRY_DEFINE_PLUGIN_HOOK(MakeFactoryImpl); +OPENTELEMETRY_DEFINE_PLUGIN_HOOK(MakeFactoryImpl) diff --git a/examples/plugin/plugin/tracer.cc b/examples/plugin/plugin/tracer.cc index 517575c947..55de64438d 100644 --- a/examples/plugin/plugin/tracer.cc +++ b/examples/plugin/plugin/tracer.cc @@ -27,7 +27,7 @@ class Span final : public trace::Span std::cout << "StartSpan: " << name << "\n"; } - ~Span() { std::cout << "~Span\n"; } + ~Span() override { std::cout << "~Span\n"; } // opentelemetry::trace::Span void SetAttribute(nostd::string_view /*name*/, @@ -45,6 +45,10 @@ class Span final : public trace::Span const common::KeyValueIterable & /*attributes*/) noexcept override {} + void AddEvent(nostd::string_view /*name*/, + const common::KeyValueIterable & /*attributes*/) noexcept override + {} + void SetStatus(trace::StatusCode /*code*/, nostd::string_view /*description*/) noexcept override {} diff --git a/examples/prometheus/README.md b/examples/prometheus/README.md index d7e284a0ec..782e874644 100644 --- a/examples/prometheus/README.md +++ b/examples/prometheus/README.md @@ -24,7 +24,7 @@ The main difference between the [ostream-metrics](../metrics_simple/README.md) example with this one is that the line below is replaced: ```cpp -std::unique_ptr exporter{ +std::unique_ptr exporter{ new exportermetrics::OStreamMetricExporter}; ``` @@ -32,7 +32,7 @@ std::unique_ptr exporter{ with ```cpp -std::unique_ptr exporter{ +std::unique_ptr exporter{ new metrics_exporter::PrometheusExporter(opts)}; ``` diff --git a/examples/prometheus/main.cc b/examples/prometheus/main.cc index 77a648f55d..0bf0fb5427 100644 --- a/examples/prometheus/main.cc +++ b/examples/prometheus/main.cc @@ -36,7 +36,7 @@ void initMetrics(const std::string &name, const std::string &addr) } std::puts("PrometheusExporter example program running ..."); - std::unique_ptr exporter{ + std::unique_ptr exporter{ new metrics_exporter::PrometheusExporter(opts)}; std::string version{"1.2.0"}; diff --git a/exporters/elasticsearch/src/es_log_exporter.cc b/exporters/elasticsearch/src/es_log_exporter.cc index 618f6d6b30..13798ae300 100644 --- a/exporters/elasticsearch/src/es_log_exporter.cc +++ b/exporters/elasticsearch/src/es_log_exporter.cc @@ -35,10 +35,10 @@ class ResponseHandler : public http_client::EventHandler const std::string &body) noexcept { std::stringstream ss; - ss << "Status:" << response.GetStatusCode() << "Header:"; + ss << "Status:" << response.GetStatusCode() << ", Header:"; response.ForEachHeader([&ss](opentelemetry::nostd::string_view header_name, opentelemetry::nostd::string_view header_value) { - ss << "\t" << header_name.data() << " : " << header_value.data() << ","; + ss << "\t" << header_name.data() << ": " << header_value.data() << ","; return true; }); ss << "Body:" << body; @@ -107,25 +107,61 @@ class ResponseHandler : public http_client::EventHandler } // Callback method when an http event occurs - void OnEvent(http_client::SessionState state, nostd::string_view reason) noexcept override + void OnEvent(http_client::SessionState state, nostd::string_view /* reason */) noexcept override { // If any failure event occurs, release the condition variable to unblock main thread switch (state) { + case http_client::SessionState::CreateFailed: + OTEL_INTERNAL_LOG_ERROR("[ES Log Exporter] Failed to create session"); + cv_.notify_all(); + break; + case http_client::SessionState::Created: + OTEL_INTERNAL_LOG_DEBUG("[ES Log Exporter] Session created"); + break; + case http_client::SessionState::Destroyed: + OTEL_INTERNAL_LOG_DEBUG("[ES Log Exporter] Session destroyed"); + break; + case http_client::SessionState::Connecting: + OTEL_INTERNAL_LOG_DEBUG("[ES Log Exporter] Connecting to peer"); + break; case http_client::SessionState::ConnectFailed: - OTEL_INTERNAL_LOG_ERROR("[ES Log Exporter] Connection to elasticsearch failed"); + OTEL_INTERNAL_LOG_ERROR("[ES Log Exporter] Failed to connect to peer"); cv_.notify_all(); break; + case http_client::SessionState::Connected: + OTEL_INTERNAL_LOG_DEBUG("[ES Log Exporter] Connected to peer"); + break; + case http_client::SessionState::Sending: + OTEL_INTERNAL_LOG_DEBUG("[ES Log Exporter] Sending request"); + break; case http_client::SessionState::SendFailed: - OTEL_INTERNAL_LOG_ERROR("[ES Log Exporter] Request failed to be sent to elasticsearch"); + OTEL_INTERNAL_LOG_ERROR("[ES Log Exporter] Failed to send request"); + cv_.notify_all(); + break; + case http_client::SessionState::Response: + OTEL_INTERNAL_LOG_DEBUG("[ES Log Exporter] Received response"); + break; + case http_client::SessionState::SSLHandshakeFailed: + OTEL_INTERNAL_LOG_ERROR("[ES Log Exporter] Failed SSL Handshake"); cv_.notify_all(); break; case http_client::SessionState::TimedOut: - OTEL_INTERNAL_LOG_ERROR("[ES Log Exporter] Request to elasticsearch timed out"); + OTEL_INTERNAL_LOG_ERROR("[ES Log Exporter] Request timed out"); cv_.notify_all(); break; case http_client::SessionState::NetworkError: - OTEL_INTERNAL_LOG_ERROR("[ES Log Exporter] Network error to elasticsearch"); + OTEL_INTERNAL_LOG_ERROR("[ES Log Exporter] Network error"); + cv_.notify_all(); + break; + case http_client::SessionState::ReadError: + OTEL_INTERNAL_LOG_DEBUG("[ES Log Exporter] Read error"); + break; + case http_client::SessionState::WriteError: + OTEL_INTERNAL_LOG_DEBUG("[ES Log Exporter] Write error"); + break; + case http_client::SessionState::Cancelled: + OTEL_INTERNAL_LOG_ERROR("[ES Log Exporter] (manually) cancelled"); cv_.notify_all(); break; } @@ -160,15 +196,15 @@ class AsyncResponseHandler : public http_client::EventHandler std::shared_ptr session, std::function &&result_callback, bool console_debug = false) - : console_debug_{console_debug}, - session_{std::move(session)}, - result_callback_{std::move(result_callback)} + : session_{std::move(session)}, + result_callback_{std::move(result_callback)}, + console_debug_{console_debug} {} /** * Cleans up the session in the destructor. */ - ~AsyncResponseHandler() { session_->FinishSession(); } + ~AsyncResponseHandler() override { session_->FinishSession(); } /** * Automatically called when the response is received @@ -197,7 +233,7 @@ class AsyncResponseHandler : public http_client::EventHandler } // Callback method when an http event occurs - void OnEvent(http_client::SessionState state, nostd::string_view reason) noexcept override + void OnEvent(http_client::SessionState state, nostd::string_view /* reason */) noexcept override { bool need_stop = false; switch (state) @@ -364,7 +400,7 @@ sdk::common::ExportResult ElasticsearchLogExporter::Export( # endif } -bool ElasticsearchLogExporter::Shutdown(std::chrono::microseconds timeout) noexcept +bool ElasticsearchLogExporter::Shutdown(std::chrono::microseconds /* timeout */) noexcept { const std::lock_guard locked(lock_); is_shutdown_ = true; diff --git a/exporters/elasticsearch/test/es_log_exporter_test.cc b/exporters/elasticsearch/test/es_log_exporter_test.cc index 943f9fa7ba..e256c969e7 100644 --- a/exporters/elasticsearch/test/es_log_exporter_test.cc +++ b/exporters/elasticsearch/test/es_log_exporter_test.cc @@ -83,4 +83,4 @@ TEST(ElasticsearchLogsExporterTests, RecordableCreation) exporter->Export(nostd::span>(&record, 1)); } # endif -#endif \ No newline at end of file +#endif diff --git a/exporters/jaeger/BUILD b/exporters/jaeger/BUILD index 156d7cde62..1937d4457e 100644 --- a/exporters/jaeger/BUILD +++ b/exporters/jaeger/BUILD @@ -177,6 +177,8 @@ cc_library( "include/opentelemetry/exporters/jaeger/jaeger_exporter_factory.h", "include/opentelemetry/exporters/jaeger/jaeger_exporter_options.h", "include/opentelemetry/exporters/jaeger/recordable.h", + "include/opentelemetry/exporters/jaeger/thrift_include_prefix.h", + "include/opentelemetry/exporters/jaeger/thrift_include_suffix.h", ], copts = ["-fexceptions"], strip_include_prefix = "include", diff --git a/exporters/jaeger/CMakeLists.txt b/exporters/jaeger/CMakeLists.txt index 017b43d494..9641300124 100644 --- a/exporters/jaeger/CMakeLists.txt +++ b/exporters/jaeger/CMakeLists.txt @@ -9,6 +9,14 @@ set(JAEGER_THRIFT_GENCPP_SOURCES thrift-gen/Agent.cpp thrift-gen/jaeger_types.cpp thrift-gen/Collector.cpp thrift-gen/zipkincore_types.cpp) +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + message("Relaxing GCC warnings on thrift-gen") + # THRIFT generated code is not warning clean for gcc. + set_source_files_properties( + ${JAEGER_THRIFT_GENCPP_SOURCES} PROPERTIES COMPILE_OPTIONS + "-Wno-suggest-override") +endif() + set(JAEGER_EXPORTER_SOURCES src/jaeger_exporter.cc src/jaeger_exporter_factory.cc diff --git a/exporters/jaeger/include/opentelemetry/exporters/jaeger/recordable.h b/exporters/jaeger/include/opentelemetry/exporters/jaeger/recordable.h index e604d56d79..b1b944fd07 100644 --- a/exporters/jaeger/include/opentelemetry/exporters/jaeger/recordable.h +++ b/exporters/jaeger/include/opentelemetry/exporters/jaeger/recordable.h @@ -3,7 +3,12 @@ #pragma once +#include + #include + +#include + #include #include diff --git a/exporters/jaeger/include/opentelemetry/exporters/jaeger/thrift_include_prefix.h b/exporters/jaeger/include/opentelemetry/exporters/jaeger/thrift_include_prefix.h new file mode 100644 index 0000000000..92754d4800 --- /dev/null +++ b/exporters/jaeger/include/opentelemetry/exporters/jaeger/thrift_include_prefix.h @@ -0,0 +1,11 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file may be include multiple times, do not add #pragma once here + +#if defined(__GNUC__) && !defined(__clang__) && !defined(__apple_build_version__) +# if (__GNUC__ * 100 + __GNUC_MINOR__ * 10) >= 460 +# pragma GCC diagnostic push +# endif +# pragma GCC diagnostic ignored "-Wsuggest-override" +#endif diff --git a/exporters/jaeger/include/opentelemetry/exporters/jaeger/thrift_include_suffix.h b/exporters/jaeger/include/opentelemetry/exporters/jaeger/thrift_include_suffix.h new file mode 100644 index 0000000000..fc276705c3 --- /dev/null +++ b/exporters/jaeger/include/opentelemetry/exporters/jaeger/thrift_include_suffix.h @@ -0,0 +1,10 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// This file may be include multiple times, do not add #pragma once here + +#if defined(__GNUC__) && !defined(__clang__) && !defined(__apple_build_version__) +# if (__GNUC__ * 100 + __GNUC_MINOR__ * 10) >= 460 +# pragma GCC diagnostic pop +# endif +#endif diff --git a/exporters/jaeger/src/jaeger_exporter.cc b/exporters/jaeger/src/jaeger_exporter.cc index c07f2f0100..8e9e75bd73 100644 --- a/exporters/jaeger/src/jaeger_exporter.cc +++ b/exporters/jaeger/src/jaeger_exporter.cc @@ -1,7 +1,12 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#include + #include + +#include + #include #include #include "opentelemetry/sdk_config.h" @@ -93,7 +98,7 @@ void JaegerExporter::InitializeEndpoint() assert(false); } -bool JaegerExporter::Shutdown(std::chrono::microseconds timeout) noexcept +bool JaegerExporter::Shutdown(std::chrono::microseconds /* timeout */) noexcept { const std::lock_guard locked(lock_); is_shutdown_ = true; diff --git a/exporters/jaeger/src/recordable.cc b/exporters/jaeger/src/recordable.cc index b5f88780b8..d147d96553 100644 --- a/exporters/jaeger/src/recordable.cc +++ b/exporters/jaeger/src/recordable.cc @@ -191,7 +191,7 @@ void JaegerRecordable::SetInstrumentationScope( } void JaegerRecordable::AddLink(const trace::SpanContext &span_context, - const common::KeyValueIterable &attributes) noexcept + const common::KeyValueIterable & /* attributes */) noexcept { // Note: "The Link’s attributes cannot be represented in Jaeger explicitly." // -- https://opentelemetry.io/docs/reference/specification/trace/sdk_exporters/jaeger/#links diff --git a/exporters/jaeger/src/thrift_sender.h b/exporters/jaeger/src/thrift_sender.h index 0ec8d47f11..687f6fac45 100644 --- a/exporters/jaeger/src/thrift_sender.h +++ b/exporters/jaeger/src/thrift_sender.h @@ -3,7 +3,12 @@ #pragma once +#include + #include + +#include + #include #include #include diff --git a/exporters/jaeger/src/transport.h b/exporters/jaeger/src/transport.h index 8121e30076..d7ba8fa604 100644 --- a/exporters/jaeger/src/transport.h +++ b/exporters/jaeger/src/transport.h @@ -5,8 +5,12 @@ #include +#include + #include +#include + OPENTELEMETRY_BEGIN_NAMESPACE namespace exporter { diff --git a/exporters/jaeger/src/udp_transport.h b/exporters/jaeger/src/udp_transport.h index 0997a27c63..ce1f51e647 100644 --- a/exporters/jaeger/src/udp_transport.h +++ b/exporters/jaeger/src/udp_transport.h @@ -6,7 +6,12 @@ #include "TUDPTransport.h" #include "transport.h" +#include + #include + +#include + #include #include #include @@ -35,7 +40,7 @@ class UDPTransport : public Transport static constexpr auto kUDPPacketMaxLength = 65000; UDPTransport(const std::string &addr, uint16_t port); - virtual ~UDPTransport(); + ~UDPTransport() override; int EmitBatch(const thrift::Batch &batch) override; diff --git a/exporters/memory/src/in_memory_span_exporter_factory.cc b/exporters/memory/src/in_memory_span_exporter_factory.cc index 1b858fd9c7..ff5bab9253 100644 --- a/exporters/memory/src/in_memory_span_exporter_factory.cc +++ b/exporters/memory/src/in_memory_span_exporter_factory.cc @@ -16,7 +16,7 @@ std::unique_ptr InMemorySpanExporterFac std::shared_ptr &data) { return Create(data, MAX_BUFFER_SIZE); -}; +} std::unique_ptr InMemorySpanExporterFactory::Create( std::shared_ptr &data, diff --git a/exporters/ostream/include/opentelemetry/exporters/ostream/common_utils.h b/exporters/ostream/include/opentelemetry/exporters/ostream/common_utils.h index 6712e6a9da..1e51815b23 100644 --- a/exporters/ostream/include/opentelemetry/exporters/ostream/common_utils.h +++ b/exporters/ostream/include/opentelemetry/exporters/ostream/common_utils.h @@ -78,4 +78,4 @@ inline void print_value(const opentelemetry::sdk::common::OwnedAttributeValue &v } // namespace ostream_common } // namespace exporter -OPENTELEMETRY_END_NAMESPACE \ No newline at end of file +OPENTELEMETRY_END_NAMESPACE diff --git a/exporters/ostream/include/opentelemetry/exporters/ostream/metric_exporter.h b/exporters/ostream/include/opentelemetry/exporters/ostream/metric_exporter.h index 2a9e9751ea..9c45d011cf 100644 --- a/exporters/ostream/include/opentelemetry/exporters/ostream/metric_exporter.h +++ b/exporters/ostream/include/opentelemetry/exporters/ostream/metric_exporter.h @@ -9,7 +9,7 @@ # include "opentelemetry/common/spin_lock_mutex.h" # include "opentelemetry/sdk/metrics/data/metric_data.h" # include "opentelemetry/sdk/metrics/instruments.h" -# include "opentelemetry/sdk/metrics/metric_exporter.h" +# include "opentelemetry/sdk/metrics/push_metric_exporter.h" # include "opentelemetry/version.h" OPENTELEMETRY_BEGIN_NAMESPACE @@ -21,7 +21,7 @@ namespace metrics /** * The OStreamMetricExporter exports record data through an ostream */ -class OStreamMetricExporter final : public opentelemetry::sdk::metrics::MetricExporter +class OStreamMetricExporter final : public opentelemetry::sdk::metrics::PushMetricExporter { public: /** diff --git a/exporters/ostream/src/metric_exporter.cc b/exporters/ostream/src/metric_exporter.cc index 8491929533..c75a177036 100644 --- a/exporters/ostream/src/metric_exporter.cc +++ b/exporters/ostream/src/metric_exporter.cc @@ -164,9 +164,9 @@ void OStreamMetricExporter::printPointData(const opentelemetry::sdk::metrics::Po { sout_ << nostd::get(sum_point_data.value_); } - else if (nostd::holds_alternative(sum_point_data.value_)) + else if (nostd::holds_alternative(sum_point_data.value_)) { - sout_ << nostd::get(sum_point_data.value_); + sout_ << nostd::get(sum_point_data.value_); } } else if (nostd::holds_alternative(point_data)) @@ -179,24 +179,24 @@ void OStreamMetricExporter::printPointData(const opentelemetry::sdk::metrics::Po { sout_ << nostd::get(histogram_point_data.sum_); } - else if (nostd::holds_alternative(histogram_point_data.sum_)) + else if (nostd::holds_alternative(histogram_point_data.sum_)) { - sout_ << nostd::get(histogram_point_data.sum_); + sout_ << nostd::get(histogram_point_data.sum_); } if (histogram_point_data.record_min_max_) { - if (nostd::holds_alternative(histogram_point_data.min_)) + if (nostd::holds_alternative(histogram_point_data.min_)) { - sout_ << "\n min : " << nostd::get(histogram_point_data.min_); + sout_ << "\n min : " << nostd::get(histogram_point_data.min_); } else if (nostd::holds_alternative(histogram_point_data.min_)) { sout_ << "\n min : " << nostd::get(histogram_point_data.min_); } - if (nostd::holds_alternative(histogram_point_data.max_)) + if (nostd::holds_alternative(histogram_point_data.max_)) { - sout_ << "\n max : " << nostd::get(histogram_point_data.max_); + sout_ << "\n max : " << nostd::get(histogram_point_data.max_); } if (nostd::holds_alternative(histogram_point_data.max_)) { @@ -205,16 +205,7 @@ void OStreamMetricExporter::printPointData(const opentelemetry::sdk::metrics::Po } sout_ << "\n buckets : "; - if (nostd::holds_alternative>(histogram_point_data.boundaries_)) - { - auto &double_boundaries = nostd::get>(histogram_point_data.boundaries_); - printVec(sout_, double_boundaries); - } - else if (nostd::holds_alternative>(histogram_point_data.boundaries_)) - { - auto &long_boundaries = nostd::get>(histogram_point_data.boundaries_); - printVec(sout_, long_boundaries); - } + printVec(sout_, histogram_point_data.boundaries_); sout_ << "\n counts : "; printVec(sout_, histogram_point_data.counts_); @@ -231,9 +222,9 @@ void OStreamMetricExporter::printPointData(const opentelemetry::sdk::metrics::Po { sout_ << nostd::get(last_point_data.value_); } - else if (nostd::holds_alternative(last_point_data.value_)) + else if (nostd::holds_alternative(last_point_data.value_)) { - sout_ << nostd::get(last_point_data.value_); + sout_ << nostd::get(last_point_data.value_); } } } diff --git a/exporters/ostream/src/span_exporter_factory.cc b/exporters/ostream/src/span_exporter_factory.cc index f21a5271e3..5b3061ac3c 100644 --- a/exporters/ostream/src/span_exporter_factory.cc +++ b/exporters/ostream/src/span_exporter_factory.cc @@ -15,7 +15,7 @@ namespace trace std::unique_ptr OStreamSpanExporterFactory::Create() { return Create(std::cout); -}; +} std::unique_ptr OStreamSpanExporterFactory::Create(std::ostream &sout) { diff --git a/exporters/ostream/test/ostream_metric_test.cc b/exporters/ostream/test/ostream_metric_test.cc index ea46c09bbe..c7ecba6659 100644 --- a/exporters/ostream/test/ostream_metric_test.cc +++ b/exporters/ostream/test/ostream_metric_test.cc @@ -23,7 +23,7 @@ namespace exportermetrics = opentelemetry::exporter::metrics; TEST(OStreamMetricsExporter, Shutdown) { auto exporter = - std::unique_ptr(new exportermetrics::OStreamMetricExporter); + std::unique_ptr(new exportermetrics::OStreamMetricExporter); ASSERT_TRUE(exporter->Shutdown()); auto result = exporter->Export(metric_sdk::ResourceMetrics{}); EXPECT_EQ(result, opentelemetry::sdk::common::ExportResult::kFailure); @@ -32,7 +32,7 @@ TEST(OStreamMetricsExporter, Shutdown) TEST(OStreamMetricsExporter, ExportSumPointData) { auto exporter = - std::unique_ptr(new exportermetrics::OStreamMetricExporter); + std::unique_ptr(new exportermetrics::OStreamMetricExporter); metric_sdk::SumPointData sum_point_data{}; sum_point_data.value_ = 10.0; @@ -95,7 +95,7 @@ TEST(OStreamMetricsExporter, ExportSumPointData) TEST(OStreamMetricsExporter, ExportHistogramPointData) { auto exporter = - std::unique_ptr(new exportermetrics::OStreamMetricExporter); + std::unique_ptr(new exportermetrics::OStreamMetricExporter); metric_sdk::HistogramPointData histogram_point_data{}; histogram_point_data.boundaries_ = std::list{10.1, 20.2, 30.2}; @@ -105,10 +105,10 @@ TEST(OStreamMetricsExporter, ExportHistogramPointData) histogram_point_data.min_ = 1.8; histogram_point_data.max_ = 12.0; metric_sdk::HistogramPointData histogram_point_data2{}; - histogram_point_data2.boundaries_ = std::list{10, 20, 30}; + histogram_point_data2.boundaries_ = std::list{10.0, 20.0, 30.0}; histogram_point_data2.count_ = 3; histogram_point_data2.counts_ = {200, 300, 400, 500}; - histogram_point_data2.sum_ = 900l; + histogram_point_data2.sum_ = (int64_t)900; metric_sdk::ResourceMetrics data; auto resource = opentelemetry::sdk::resource::Resource::Create( opentelemetry::sdk::resource::ResourceAttributes{}); @@ -177,7 +177,7 @@ TEST(OStreamMetricsExporter, ExportHistogramPointData) TEST(OStreamMetricsExporter, ExportLastValuePointData) { auto exporter = - std::unique_ptr(new exportermetrics::OStreamMetricExporter); + std::unique_ptr(new exportermetrics::OStreamMetricExporter); metric_sdk::ResourceMetrics data; auto resource = opentelemetry::sdk::resource::Resource::Create( @@ -190,7 +190,7 @@ TEST(OStreamMetricsExporter, ExportLastValuePointData) last_value_point_data.is_lastvalue_valid_ = true; last_value_point_data.sample_ts_ = opentelemetry::common::SystemTimestamp{}; metric_sdk::LastValuePointData last_value_point_data2{}; - last_value_point_data2.value_ = 20l; + last_value_point_data2.value_ = (int64_t)20; last_value_point_data2.is_lastvalue_valid_ = true; last_value_point_data2.sample_ts_ = opentelemetry::common::SystemTimestamp{}; metric_sdk::MetricData metric_data{ @@ -246,7 +246,7 @@ TEST(OStreamMetricsExporter, ExportLastValuePointData) TEST(OStreamMetricsExporter, ExportDropPointData) { auto exporter = - std::unique_ptr(new exportermetrics::OStreamMetricExporter); + std::unique_ptr(new exportermetrics::OStreamMetricExporter); metric_sdk::ResourceMetrics data; auto resource = opentelemetry::sdk::resource::Resource::Create( diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_environment.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_environment.h index 787f852442..27bd378b7c 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_environment.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_environment.h @@ -8,6 +8,7 @@ #include "opentelemetry/sdk/common/attribute_utils.h" #include "opentelemetry/sdk/common/env_variables.h" +#include "opentelemetry/sdk/version/version.h" #include #include @@ -21,6 +22,11 @@ namespace exporter namespace otlp { +inline const std::string GetOtlpDefaultUserAgent() +{ + return "OTel-OTLP-Exporter-Cpp/" OPENTELEMETRY_SDK_VERSION; +} + inline const std::string GetOtlpDefaultGrpcEndpoint() { constexpr char kOtlpTracesEndpointEnv[] = "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT"; diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter_options.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter_options.h index c62a0f0af9..664ee2934b 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter_options.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter_options.h @@ -32,6 +32,8 @@ struct OtlpGrpcExporterOptions std::chrono::system_clock::duration timeout = GetOtlpDefaultTimeout(); // Additional HTTP headers OtlpHeaders metadata = GetOtlpDefaultHeaders(); + // User agent + std::string user_agent = GetOtlpDefaultUserAgent(); }; } // namespace otlp diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_metric_exporter.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_metric_exporter.h index 643a0cd3d5..ef6477d67f 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_metric_exporter.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_metric_exporter.h @@ -15,7 +15,7 @@ # include "opentelemetry/exporters/otlp/otlp_environment.h" # include "opentelemetry/exporters/otlp/otlp_grpc_metric_exporter_options.h" -# include "opentelemetry/sdk/metrics/metric_exporter.h" +# include "opentelemetry/sdk/metrics/push_metric_exporter.h" OPENTELEMETRY_BEGIN_NAMESPACE namespace exporter @@ -26,7 +26,7 @@ namespace otlp /** * The OTLP exporter exports metrics data in OpenTelemetry Protocol (OTLP) format in gRPC. */ -class OtlpGrpcMetricExporter : public opentelemetry::sdk::metrics::MetricExporter +class OtlpGrpcMetricExporter : public opentelemetry::sdk::metrics::PushMetricExporter { public: /** @@ -84,4 +84,4 @@ class OtlpGrpcMetricExporter : public opentelemetry::sdk::metrics::MetricExporte } // namespace otlp } // namespace exporter OPENTELEMETRY_END_NAMESPACE -#endif \ No newline at end of file +#endif diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_metric_exporter_factory.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_metric_exporter_factory.h index 5a105ba4c0..0fb4f46077 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_metric_exporter_factory.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_metric_exporter_factory.h @@ -6,7 +6,7 @@ #ifndef ENABLE_METRICS_PREVIEW # include "opentelemetry/exporters/otlp/otlp_grpc_metric_exporter_options.h" -# include "opentelemetry/sdk/metrics/metric_exporter.h" +# include "opentelemetry/sdk/metrics/push_metric_exporter.h" OPENTELEMETRY_BEGIN_NAMESPACE namespace exporter @@ -23,12 +23,12 @@ class OtlpGrpcMetricExporterFactory /** * Create a OtlpGrpcMetricExporter. */ - static std::unique_ptr Create(); + static std::unique_ptr Create(); /** * Create a OtlpGrpcMetricExporter. */ - static std::unique_ptr Create( + static std::unique_ptr Create( const OtlpGrpcMetricExporterOptions &options); }; diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_metric_exporter_options.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_metric_exporter_options.h index 1459fe8596..3d677c1a08 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_metric_exporter_options.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_metric_exporter_options.h @@ -27,4 +27,4 @@ struct OtlpGrpcMetricExporterOptions : public OtlpGrpcExporterOptions } // namespace otlp } // namespace exporter -OPENTELEMETRY_END_NAMESPACE \ No newline at end of file +OPENTELEMETRY_END_NAMESPACE diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_client.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_client.h index e5102c6ca0..bf154b23a0 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_client.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_client.h @@ -72,6 +72,9 @@ struct OtlpHttpClientOptions // Requests per connections std::size_t max_requests_per_connection = 8; + // User agent + std::string user_agent = GetOtlpDefaultUserAgent(); + inline OtlpHttpClientOptions(nostd::string_view input_url, HttpRequestContentType input_content_type, JsonBytesMappingKind input_json_bytes_mapping, @@ -80,7 +83,8 @@ struct OtlpHttpClientOptions std::chrono::system_clock::duration input_timeout, const OtlpHeaders &input_http_headers, std::size_t input_concurrent_sessions = 64, - std::size_t input_max_requests_per_connection = 8) + std::size_t input_max_requests_per_connection = 8, + nostd::string_view input_user_agent = GetOtlpDefaultUserAgent()) : url(input_url), content_type(input_content_type), json_bytes_mapping(input_json_bytes_mapping), @@ -89,7 +93,8 @@ struct OtlpHttpClientOptions timeout(input_timeout), http_headers(input_http_headers), max_concurrent_requests(input_concurrent_sessions), - max_requests_per_connection(input_max_requests_per_connection) + max_requests_per_connection(input_max_requests_per_connection), + user_agent(input_user_agent) {} }; diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_metric_exporter.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_metric_exporter.h index c037f58168..ff47452a07 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_metric_exporter.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_metric_exporter.h @@ -4,7 +4,7 @@ #pragma once #ifndef ENABLE_METRICS_PREVIEW -# include "opentelemetry/sdk/metrics/metric_exporter.h" +# include "opentelemetry/sdk/metrics/push_metric_exporter.h" # include "opentelemetry/exporters/otlp/otlp_environment.h" # include "opentelemetry/exporters/otlp/otlp_http_client.h" @@ -24,7 +24,7 @@ namespace otlp /** * The OTLP exporter exports metrics data in OpenTelemetry Protocol (OTLP) format in HTTP. */ -class OtlpHttpMetricExporter final : public opentelemetry::sdk::metrics::MetricExporter +class OtlpHttpMetricExporter final : public opentelemetry::sdk::metrics::PushMetricExporter { public: /** diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_metric_exporter_factory.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_metric_exporter_factory.h index 913e5097dc..b0e6fa1678 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_metric_exporter_factory.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_metric_exporter_factory.h @@ -5,7 +5,7 @@ #ifndef ENABLE_METRICS_PREVIEW # include "opentelemetry/exporters/otlp/otlp_http_metric_exporter_options.h" -# include "opentelemetry/sdk/metrics/metric_exporter.h" +# include "opentelemetry/sdk/metrics/push_metric_exporter.h" # include @@ -24,12 +24,12 @@ class OtlpHttpMetricExporterFactory /** * Create a OtlpHttpMetricExporter. */ - static std::unique_ptr Create(); + static std::unique_ptr Create(); /** * Create a OtlpHttpMetricExporter. */ - static std::unique_ptr Create( + static std::unique_ptr Create( const OtlpHttpMetricExporterOptions &options); }; diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_log_recordable.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_log_recordable.h index f8f0cabfdd..b10898ac3c 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_log_recordable.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_log_recordable.h @@ -30,7 +30,7 @@ namespace otlp class OtlpLogRecordable final : public opentelemetry::sdk::logs::Recordable { public: - virtual ~OtlpLogRecordable() = default; + ~OtlpLogRecordable() override = default; proto::logs::v1::LogRecord &log_record() noexcept { return log_record_; } const proto::logs::v1::LogRecord &log_record() const noexcept { return log_record_; } diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/protobuf_include_prefix.h b/exporters/otlp/include/opentelemetry/exporters/otlp/protobuf_include_prefix.h index ae103b0173..036cb0ae7f 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/protobuf_include_prefix.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/protobuf_include_prefix.h @@ -34,4 +34,5 @@ # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wunused-parameter" # pragma clang diagnostic ignored "-Wtype-limits" -#endif \ No newline at end of file +# pragma clang diagnostic ignored "-Wshadow-field" +#endif diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/protobuf_include_suffix.h b/exporters/otlp/include/opentelemetry/exporters/otlp/protobuf_include_suffix.h index 26e7a2913e..547eb3f335 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/protobuf_include_suffix.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/protobuf_include_suffix.h @@ -13,4 +13,4 @@ #if defined(_MSC_VER) # pragma warning(pop) -#endif \ No newline at end of file +#endif diff --git a/exporters/otlp/src/otlp_grpc_client.cc b/exporters/otlp/src/otlp_grpc_client.cc index ede5ca892d..158f276000 100644 --- a/exporters/otlp/src/otlp_grpc_client.cc +++ b/exporters/otlp/src/otlp_grpc_client.cc @@ -55,6 +55,8 @@ std::shared_ptr OtlpGrpcClient::MakeChannel(const OtlpGrpcExporte } std::string grpc_target = url.host_ + ":" + std::to_string(static_cast(url.port_)); + grpc::ChannelArguments grpc_arguments; + grpc_arguments.SetUserAgentPrefix(options.user_agent); if (options.use_ssl_credentials) { @@ -67,11 +69,13 @@ std::shared_ptr OtlpGrpcClient::MakeChannel(const OtlpGrpcExporte { ssl_opts.pem_root_certs = GetFileContents((options.ssl_credentials_cacert_path).c_str()); } - channel = grpc::CreateChannel(grpc_target, grpc::SslCredentials(ssl_opts)); + channel = + grpc::CreateCustomChannel(grpc_target, grpc::SslCredentials(ssl_opts), grpc_arguments); } else { - channel = grpc::CreateChannel(grpc_target, grpc::InsecureChannelCredentials()); + channel = + grpc::CreateCustomChannel(grpc_target, grpc::InsecureChannelCredentials(), grpc_arguments); } return channel; diff --git a/exporters/otlp/src/otlp_grpc_metric_exporter_factory.cc b/exporters/otlp/src/otlp_grpc_metric_exporter_factory.cc index 9060d705b9..fc7952474e 100644 --- a/exporters/otlp/src/otlp_grpc_metric_exporter_factory.cc +++ b/exporters/otlp/src/otlp_grpc_metric_exporter_factory.cc @@ -15,16 +15,17 @@ namespace exporter namespace otlp { -std::unique_ptr OtlpGrpcMetricExporterFactory::Create() +std::unique_ptr +OtlpGrpcMetricExporterFactory::Create() { OtlpGrpcMetricExporterOptions options; return Create(options); } -std::unique_ptr OtlpGrpcMetricExporterFactory::Create( - const OtlpGrpcMetricExporterOptions &options) +std::unique_ptr +OtlpGrpcMetricExporterFactory::Create(const OtlpGrpcMetricExporterOptions &options) { - std::unique_ptr exporter( + std::unique_ptr exporter( new OtlpGrpcMetricExporter(options)); return exporter; } diff --git a/exporters/otlp/src/otlp_http_client.cc b/exporters/otlp/src/otlp_http_client.cc index 9833d70d0a..8ea20919df 100644 --- a/exporters/otlp/src/otlp_http_client.cc +++ b/exporters/otlp/src/otlp_http_client.cc @@ -83,10 +83,10 @@ class ResponseHandler : public http_client::EventHandler const std::string &body) noexcept { std::stringstream ss; - ss << "Status:" << response.GetStatusCode() << "Header:"; + ss << "Status:" << response.GetStatusCode() << ", Header:"; response.ForEachHeader([&ss](opentelemetry::nostd::string_view header_name, opentelemetry::nostd::string_view header_value) { - ss << "\t" << header_name.data() << " : " << header_value.data() << ","; + ss << "\t" << header_name.data() << ": " << header_value.data() << ","; return true; }); ss << "Body:" << body; @@ -116,8 +116,7 @@ class ResponseHandler : public http_client::EventHandler OTEL_INTERNAL_LOG_ERROR("OTLP HTTP Client] Export failed, " << log_message); result = sdk::common::ExportResult::kFailure; } - - if (console_debug_) + else if (console_debug_) { if (log_message.empty()) { @@ -966,6 +965,7 @@ OtlpHttpClient::createSession( request->SetMethod(http_client::Method::Post); request->SetBody(body_vec); request->ReplaceHeader("Content-Type", content_type); + request->ReplaceHeader("User-Agent", options_.user_agent); // Returns the created session data return HttpSessionData{ diff --git a/exporters/otlp/src/otlp_http_metric_exporter_factory.cc b/exporters/otlp/src/otlp_http_metric_exporter_factory.cc index e5c194777f..9abc30d25c 100644 --- a/exporters/otlp/src/otlp_http_metric_exporter_factory.cc +++ b/exporters/otlp/src/otlp_http_metric_exporter_factory.cc @@ -13,16 +13,17 @@ namespace exporter namespace otlp { -std::unique_ptr OtlpHttpMetricExporterFactory::Create() +std::unique_ptr +OtlpHttpMetricExporterFactory::Create() { OtlpHttpMetricExporterOptions options; return Create(options); } -std::unique_ptr OtlpHttpMetricExporterFactory::Create( - const OtlpHttpMetricExporterOptions &options) +std::unique_ptr +OtlpHttpMetricExporterFactory::Create(const OtlpHttpMetricExporterOptions &options) { - std::unique_ptr exporter( + std::unique_ptr exporter( new OtlpHttpMetricExporter(options)); return exporter; } diff --git a/exporters/otlp/src/otlp_metric_utils.cc b/exporters/otlp/src/otlp_metric_utils.cc index 82c99684ef..39d133f4cf 100644 --- a/exporters/otlp/src/otlp_metric_utils.cc +++ b/exporters/otlp/src/otlp_metric_utils.cc @@ -62,9 +62,9 @@ void OtlpMetricUtils::ConvertSumMetric(const metric_sdk::MetricData &metric_data proto_sum_point_data->set_time_unix_nano(ts); auto sum_data = nostd::get(point_data_with_attributes.point_data); - if ((nostd::holds_alternative(sum_data.value_))) + if ((nostd::holds_alternative(sum_data.value_))) { - proto_sum_point_data->set_as_int(nostd::get(sum_data.value_)); + proto_sum_point_data->set_as_int(nostd::get(sum_data.value_)); } else { @@ -96,9 +96,9 @@ void OtlpMetricUtils::ConvertHistogramMetric( auto histogram_data = nostd::get(point_data_with_attributes.point_data); // sum - if ((nostd::holds_alternative(histogram_data.sum_))) + if ((nostd::holds_alternative(histogram_data.sum_))) { - proto_histogram_point_data->set_sum(nostd::get(histogram_data.sum_)); + proto_histogram_point_data->set_sum(nostd::get(histogram_data.sum_)); } else { @@ -108,17 +108,17 @@ void OtlpMetricUtils::ConvertHistogramMetric( proto_histogram_point_data->set_count(histogram_data.count_); if (histogram_data.record_min_max_) { - if (nostd::holds_alternative(histogram_data.min_)) + if (nostd::holds_alternative(histogram_data.min_)) { - proto_histogram_point_data->set_min(nostd::get(histogram_data.min_)); + proto_histogram_point_data->set_min(nostd::get(histogram_data.min_)); } else { proto_histogram_point_data->set_min(nostd::get(histogram_data.min_)); } - if (nostd::holds_alternative(histogram_data.max_)) + if (nostd::holds_alternative(histogram_data.max_)) { - proto_histogram_point_data->set_min(nostd::get(histogram_data.max_)); + proto_histogram_point_data->set_min(nostd::get(histogram_data.max_)); } else { @@ -126,21 +126,10 @@ void OtlpMetricUtils::ConvertHistogramMetric( } } // buckets - if ((nostd::holds_alternative>(histogram_data.boundaries_))) - { - auto boundaries = nostd::get>(histogram_data.boundaries_); - for (auto bound : boundaries) - { - proto_histogram_point_data->add_explicit_bounds(bound); - } - } - else + + for (auto bound : histogram_data.boundaries_) { - auto boundaries = nostd::get>(histogram_data.boundaries_); - for (auto bound : boundaries) - { - proto_histogram_point_data->add_explicit_bounds(bound); - } + proto_histogram_point_data->add_explicit_bounds(bound); } // bucket counts for (auto bucket_value : histogram_data.counts_) @@ -169,9 +158,9 @@ void OtlpMetricUtils::ConvertGaugeMetric(const opentelemetry::sdk::metrics::Metr auto gauge_data = nostd::get(point_data_with_attributes.point_data); - if ((nostd::holds_alternative(gauge_data.value_))) + if ((nostd::holds_alternative(gauge_data.value_))) { - proto_gauge_point_data->set_as_int(nostd::get(gauge_data.value_)); + proto_gauge_point_data->set_as_int(nostd::get(gauge_data.value_)); } else { diff --git a/exporters/otlp/src/otlp_populate_attribute_utils.cc b/exporters/otlp/src/otlp_populate_attribute_utils.cc index e19b6210b4..6dff7c4d01 100644 --- a/exporters/otlp/src/otlp_populate_attribute_utils.cc +++ b/exporters/otlp/src/otlp_populate_attribute_utils.cc @@ -176,7 +176,7 @@ void OtlpPopulateAttributeUtils::PopulateAttribute( } else if (nostd::holds_alternative>(value)) { - for (const auto &val : nostd::get>(value)) + for (const auto val : nostd::get>(value)) { attribute->mutable_value()->mutable_array_value()->add_values()->set_bool_value(val); } @@ -242,4 +242,4 @@ void OtlpPopulateAttributeUtils::PopulateAttribute( } // namespace otlp } // namespace exporter -OPENTELEMETRY_END_NAMESPACE \ No newline at end of file +OPENTELEMETRY_END_NAMESPACE diff --git a/exporters/otlp/src/otlp_recordable.cc b/exporters/otlp/src/otlp_recordable.cc index 78ca7c99ce..e0b181a452 100644 --- a/exporters/otlp/src/otlp_recordable.cc +++ b/exporters/otlp/src/otlp_recordable.cc @@ -77,7 +77,7 @@ proto::common::v1::InstrumentationScope OtlpRecordable::GetProtoInstrumentationS void OtlpRecordable::SetResource(const sdk::resource::Resource &resource) noexcept { resource_ = &resource; -}; +} void OtlpRecordable::SetAttribute(nostd::string_view key, const common::AttributeValue &value) noexcept diff --git a/exporters/otlp/test/otlp_grpc_metric_exporter_factory_test.cc b/exporters/otlp/test/otlp_grpc_metric_exporter_factory_test.cc index 8073b6658d..41bdf2dac2 100644 --- a/exporters/otlp/test/otlp_grpc_metric_exporter_factory_test.cc +++ b/exporters/otlp/test/otlp_grpc_metric_exporter_factory_test.cc @@ -27,7 +27,7 @@ TEST(OtlpGrpcMetricExporterFactory, BuildTest) OtlpGrpcMetricExporterOptions opts; opts.endpoint = "localhost:45454"; - std::unique_ptr exporter = + std::unique_ptr exporter = OtlpGrpcMetricExporterFactory::Create(opts); EXPECT_TRUE(exporter != nullptr); diff --git a/exporters/otlp/test/otlp_http_exporter_test.cc b/exporters/otlp/test/otlp_http_exporter_test.cc index e3152ff3ab..35ae5f50d7 100644 --- a/exporters/otlp/test/otlp_http_exporter_test.cc +++ b/exporters/otlp/test/otlp_http_exporter_test.cc @@ -163,6 +163,13 @@ class OtlpHttpExporterTestPeer : public ::testing::Test EXPECT_EQ("Custom-Header-Value", custom_header->second); } + auto user_agent_header = mock_session->GetRequest()->headers_.find("User-Agent"); + ASSERT_TRUE(user_agent_header != mock_session->GetRequest()->headers_.end()); + if (user_agent_header != mock_session->GetRequest()->headers_.end()) + { + EXPECT_EQ(GetOtlpDefaultUserAgent(), user_agent_header->second); + } + // let the otlp_http_client to continue http_client::nosend::Response response; response.Finish(*callback.get()); @@ -247,6 +254,13 @@ class OtlpHttpExporterTestPeer : public ::testing::Test EXPECT_EQ("Custom-Header-Value", custom_header->second); } + auto user_agent_header = mock_session->GetRequest()->headers_.find("User-Agent"); + ASSERT_TRUE(user_agent_header != mock_session->GetRequest()->headers_.end()); + if (user_agent_header != mock_session->GetRequest()->headers_.end()) + { + EXPECT_EQ(GetOtlpDefaultUserAgent(), user_agent_header->second); + } + // let the otlp_http_client to continue std::thread async_finish{[callback]() { std::this_thread::sleep_for(std::chrono::milliseconds(100)); diff --git a/exporters/otlp/test/otlp_http_metric_exporter_factory_test.cc b/exporters/otlp/test/otlp_http_metric_exporter_factory_test.cc index 949aa778e5..3cc77394ae 100644 --- a/exporters/otlp/test/otlp_http_metric_exporter_factory_test.cc +++ b/exporters/otlp/test/otlp_http_metric_exporter_factory_test.cc @@ -35,7 +35,7 @@ TEST(OtlpHttpMetricExporterFactory, BuildTest) OtlpHttpMetricExporterOptions opts; opts.url = "localhost:45454"; - std::unique_ptr exporter = + std::unique_ptr exporter = OtlpHttpMetricExporterFactory::Create(opts); EXPECT_TRUE(exporter != nullptr); diff --git a/exporters/otlp/test/otlp_http_metric_exporter_test.cc b/exporters/otlp/test/otlp_http_metric_exporter_test.cc index 295e18cb1b..1029df6145 100644 --- a/exporters/otlp/test/otlp_http_metric_exporter_test.cc +++ b/exporters/otlp/test/otlp_http_metric_exporter_test.cc @@ -78,10 +78,10 @@ namespace http_client = opentelemetry::ext::http::client; class OtlpHttpMetricExporterTestPeer : public ::testing::Test { public: - std::unique_ptr GetExporter( + std::unique_ptr GetExporter( std::unique_ptr http_client) { - return std::unique_ptr( + return std::unique_ptr( new OtlpHttpMetricExporter(std::move(http_client))); } @@ -296,7 +296,7 @@ class OtlpHttpMetricExporterTestPeer : public ::testing::Test last_value_point_data.is_lastvalue_valid_ = true; last_value_point_data.sample_ts_ = opentelemetry::common::SystemTimestamp{}; opentelemetry::sdk::metrics::LastValuePointData last_value_point_data2{}; - last_value_point_data2.value_ = 20l; + last_value_point_data2.value_ = (int64_t)20; last_value_point_data2.is_lastvalue_valid_ = true; last_value_point_data2.sample_ts_ = opentelemetry::common::SystemTimestamp{}; opentelemetry::sdk::metrics::MetricData metric_data{ @@ -392,7 +392,7 @@ class OtlpHttpMetricExporterTestPeer : public ::testing::Test last_value_point_data.is_lastvalue_valid_ = true; last_value_point_data.sample_ts_ = opentelemetry::common::SystemTimestamp{}; opentelemetry::sdk::metrics::LastValuePointData last_value_point_data2{}; - last_value_point_data2.value_ = 20l; + last_value_point_data2.value_ = (int64_t)20; last_value_point_data2.is_lastvalue_valid_ = true; last_value_point_data2.sample_ts_ = opentelemetry::common::SystemTimestamp{}; opentelemetry::sdk::metrics::MetricData metric_data{ @@ -482,17 +482,17 @@ class OtlpHttpMetricExporterTestPeer : public ::testing::Test auto exporter = GetExporter(std::unique_ptr{mock_otlp_http_client}); opentelemetry::sdk::metrics::HistogramPointData histogram_point_data{}; - histogram_point_data.boundaries_ = std::list{10.1, 20.2, 30.2}; + histogram_point_data.boundaries_ = {10.1, 20.2, 30.2}; histogram_point_data.count_ = 3; histogram_point_data.counts_ = {200, 300, 400, 500}; histogram_point_data.sum_ = 900.5; histogram_point_data.min_ = 1.8; histogram_point_data.max_ = 19.0; opentelemetry::sdk::metrics::HistogramPointData histogram_point_data2{}; - histogram_point_data2.boundaries_ = std::list{10, 20, 30}; + histogram_point_data2.boundaries_ = {10.0, 20.0, 30.0}; histogram_point_data2.count_ = 3; histogram_point_data2.counts_ = {200, 300, 400, 500}; - histogram_point_data2.sum_ = 900l; + histogram_point_data2.sum_ = (int64_t)900; opentelemetry::sdk::metrics::MetricData metric_data{ opentelemetry::sdk::metrics::InstrumentDescriptor{ @@ -619,15 +619,15 @@ class OtlpHttpMetricExporterTestPeer : public ::testing::Test "library_name", "1.5.0"); opentelemetry::sdk::metrics::HistogramPointData histogram_point_data{}; - histogram_point_data.boundaries_ = std::list{10.1, 20.2, 30.2}; + histogram_point_data.boundaries_ = {10.1, 20.2, 30.2}; histogram_point_data.count_ = 3; histogram_point_data.counts_ = {200, 300, 400, 500}; histogram_point_data.sum_ = 900.5; opentelemetry::sdk::metrics::HistogramPointData histogram_point_data2{}; - histogram_point_data2.boundaries_ = std::list{10, 20, 30}; + histogram_point_data2.boundaries_ = {10.0, 20.0, 30.0}; histogram_point_data2.count_ = 3; histogram_point_data2.counts_ = {200, 300, 400, 500}; - histogram_point_data2.sum_ = 900l; + histogram_point_data2.sum_ = (int64_t)900; opentelemetry::sdk::metrics::MetricData metric_data{ opentelemetry::sdk::metrics::InstrumentDescriptor{ @@ -734,8 +734,8 @@ class OtlpHttpMetricExporterTestPeer : public ::testing::Test TEST(OtlpHttpMetricExporterTest, Shutdown) { - auto exporter = - std::unique_ptr(new OtlpHttpMetricExporter()); + auto exporter = std::unique_ptr( + new OtlpHttpMetricExporter()); ASSERT_TRUE(exporter->Shutdown()); auto result = exporter->Export(opentelemetry::sdk::metrics::ResourceMetrics{}); EXPECT_EQ(result, opentelemetry::sdk::common::ExportResult::kFailure); diff --git a/exporters/otlp/test/otlp_recordable_test.cc b/exporters/otlp/test/otlp_recordable_test.cc index 03e6a37b99..abad2991b7 100644 --- a/exporters/otlp/test/otlp_recordable_test.cc +++ b/exporters/otlp/test/otlp_recordable_test.cc @@ -2,6 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 #include "opentelemetry/exporters/otlp/otlp_recordable.h" + +#if defined(__GNUC__) +// GCC raises -Wsuggest-override warnings on GTest, +// in code related to TYPED_TEST() . +# pragma GCC diagnostic ignored "-Wsuggest-override" +#endif + #include OPENTELEMETRY_BEGIN_NAMESPACE diff --git a/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter.h b/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter.h index cbb34c7392..2553d2fa42 100644 --- a/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter.h +++ b/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter.h @@ -12,7 +12,7 @@ # include "opentelemetry/exporters/prometheus/collector.h" # include "opentelemetry/nostd/span.h" # include "opentelemetry/sdk/common/env_variables.h" -# include "opentelemetry/sdk/metrics/metric_exporter.h" +# include "opentelemetry/sdk/metrics/push_metric_exporter.h" # include "opentelemetry/version.h" /** @@ -46,7 +46,7 @@ struct PrometheusExporterOptions std::string url = GetPrometheusDefaultHttpEndpoint(); }; -class PrometheusExporter : public sdk::metrics::MetricExporter +class PrometheusExporter : public sdk::metrics::PushMetricExporter { public: /** diff --git a/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter_utils.h b/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter_utils.h index c8df4f6cfd..9400cff40f 100644 --- a/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter_utils.h +++ b/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter_utils.h @@ -49,7 +49,8 @@ class PrometheusExporterUtils /** * Translate the OTel metric type to Prometheus metric type */ - static ::prometheus::MetricType TranslateType(opentelemetry::sdk::metrics::AggregationType kind); + static ::prometheus::MetricType TranslateType(opentelemetry::sdk::metrics::AggregationType kind, + bool is_monotonic = true); /** * Set metric data for: @@ -68,7 +69,7 @@ class PrometheusExporterUtils */ template static void SetData(std::vector values, - const opentelemetry::sdk::metrics::ListType &boundaries, + const std::list &boundaries, const std::vector &counts, const opentelemetry::sdk::metrics::PointAttributes &labels, std::chrono::nanoseconds time, @@ -103,9 +104,9 @@ class PrometheusExporterUtils /** * Handle Histogram */ - template + template static void SetValue(std::vector values, - const std::list &boundaries, + const std::list &boundaries, const std::vector &counts, ::prometheus::ClientMetric *metric); }; diff --git a/exporters/prometheus/src/exporter.cc b/exporters/prometheus/src/exporter.cc index 9d36cf00c9..f66dcb7d4f 100644 --- a/exporters/prometheus/src/exporter.cc +++ b/exporters/prometheus/src/exporter.cc @@ -34,7 +34,7 @@ PrometheusExporter::PrometheusExporter() : is_shutdown_(false) } sdk::metrics::AggregationTemporality PrometheusExporter::GetAggregationTemporality( - sdk::metrics::InstrumentType instrument_type) const noexcept + sdk::metrics::InstrumentType /* instrument_type */) const noexcept { // Prometheus exporter only support Cumulative return sdk::metrics::AggregationTemporality::kCumulative; @@ -69,7 +69,7 @@ sdk::common::ExportResult PrometheusExporter::Export( return sdk::common::ExportResult::kSuccess; } -bool PrometheusExporter::ForceFlush(std::chrono::microseconds timeout) noexcept +bool PrometheusExporter::ForceFlush(std::chrono::microseconds /* timeout */) noexcept { return true; } @@ -81,7 +81,7 @@ bool PrometheusExporter::ForceFlush(std::chrono::microseconds timeout) noexcept * collection to to client an HTTP request being sent, * so we flush the data. */ -bool PrometheusExporter::Shutdown(std::chrono::microseconds timeout) noexcept +bool PrometheusExporter::Shutdown(std::chrono::microseconds /* timeout */) noexcept { is_shutdown_ = true; return true; diff --git a/exporters/prometheus/src/exporter_utils.cc b/exporters/prometheus/src/exporter_utils.cc index 44f4395ece..fc2b102f24 100644 --- a/exporters/prometheus/src/exporter_utils.cc +++ b/exporters/prometheus/src/exporter_utils.cc @@ -54,8 +54,14 @@ std::vector PrometheusExporterUtils::TranslateT auto time = metric_data.start_ts.time_since_epoch(); for (const auto &point_data_attr : metric_data.point_data_attr_) { - auto kind = getAggregationType(point_data_attr.point_data); - const prometheus_client::MetricType type = TranslateType(kind); + auto kind = getAggregationType(point_data_attr.point_data); + bool is_monotonic = true; + if (kind == sdk::metrics::AggregationType::kSum) + { + is_monotonic = + nostd::get(point_data_attr.point_data).is_monotonic_; + } + const prometheus_client::MetricType type = TranslateType(kind, is_monotonic); metric_family.type = type; if (type == prometheus_client::MetricType::Histogram) // Histogram { @@ -70,7 +76,7 @@ std::vector PrometheusExporterUtils::TranslateT } else { - sum = nostd::get(histogram_point_data.sum_); + sum = nostd::get(histogram_point_data.sum_); } SetData(std::vector{sum, (double)histogram_point_data.count_}, boundaries, counts, point_data_attr.attributes, time, &metric_family); @@ -85,6 +91,14 @@ std::vector PrometheusExporterUtils::TranslateT std::vector values{last_value_point_data.value_}; SetData(values, point_data_attr.attributes, type, time, &metric_family); } + else if (nostd::holds_alternative( + point_data_attr.point_data)) + { + auto sum_point_data = + nostd::get(point_data_attr.point_data); + std::vector values{sum_point_data.value_}; + SetData(values, point_data_attr.attributes, type, time, &metric_family); + } else { OTEL_INTERNAL_LOG_WARN( @@ -159,16 +173,27 @@ metric_sdk::AggregationType PrometheusExporterUtils::getAggregationType( * Translate the OTel metric type to Prometheus metric type */ prometheus_client::MetricType PrometheusExporterUtils::TranslateType( - metric_sdk::AggregationType kind) + metric_sdk::AggregationType kind, + bool is_monotonic) { switch (kind) { case metric_sdk::AggregationType::kSum: - return prometheus_client::MetricType::Counter; + if (!is_monotonic) + { + return prometheus_client::MetricType::Gauge; + } + else + { + return prometheus_client::MetricType::Counter; + } + break; case metric_sdk::AggregationType::kHistogram: return prometheus_client::MetricType::Histogram; + break; case metric_sdk::AggregationType::kLastValue: return prometheus_client::MetricType::Gauge; + break; default: return prometheus_client::MetricType::Untyped; } @@ -197,7 +222,7 @@ void PrometheusExporterUtils::SetData(std::vector values, */ template void PrometheusExporterUtils::SetData(std::vector values, - const opentelemetry::sdk::metrics::ListType &boundaries, + const std::list &boundaries, const std::vector &counts, const metric_sdk::PointAttributes &labels, std::chrono::nanoseconds time, @@ -206,14 +231,7 @@ void PrometheusExporterUtils::SetData(std::vector values, metric_family->metric.emplace_back(); prometheus_client::ClientMetric &metric = metric_family->metric.back(); SetMetricBasic(metric, time, labels); - if (nostd::holds_alternative>(boundaries)) - { - SetValue(values, nostd::get>(boundaries), counts, &metric); - } - else - { - SetValue(values, nostd::get>(boundaries), counts, &metric); - } + SetValue(values, boundaries, counts, &metric); } /** @@ -237,7 +255,7 @@ void PrometheusExporterUtils::SetMetricBasic(prometheus_client::ClientMetric &me metric.label[i++].value = AttributeValueToString(label.second); } } -}; +} std::string PrometheusExporterUtils::AttributeValueToString( const opentelemetry::sdk::common::OwnedAttributeValue &value) @@ -290,9 +308,9 @@ void PrometheusExporterUtils::SetValue(std::vector values, { double value = 0.0; const auto &value_var = values[0]; - if (nostd::holds_alternative(value_var)) + if (nostd::holds_alternative(value_var)) { - value = nostd::get(value_var); + value = nostd::get(value_var); } else { @@ -321,9 +339,9 @@ void PrometheusExporterUtils::SetValue(std::vector values, /** * Handle Histogram */ -template +template void PrometheusExporterUtils::SetValue(std::vector values, - const std::list &boundaries, + const std::list &boundaries, const std::vector &counts, prometheus_client::ClientMetric *metric) { diff --git a/exporters/prometheus/test/prometheus_test_helper.h b/exporters/prometheus/test/prometheus_test_helper.h index 6f9bc73a49..1042804d00 100644 --- a/exporters/prometheus/test/prometheus_test_helper.h +++ b/exporters/prometheus/test/prometheus_test_helper.h @@ -46,15 +46,15 @@ inline metric_sdk::ResourceMetrics CreateSumPointData() inline metric_sdk::ResourceMetrics CreateHistogramPointData() { metric_sdk::HistogramPointData histogram_point_data{}; - histogram_point_data.boundaries_ = std::list{10.1, 20.2, 30.2}; + histogram_point_data.boundaries_ = {10.1, 20.2, 30.2}; histogram_point_data.count_ = 3; histogram_point_data.counts_ = {200, 300, 400, 500}; histogram_point_data.sum_ = 900.5; metric_sdk::HistogramPointData histogram_point_data2{}; - histogram_point_data2.boundaries_ = std::list{10, 20, 30}; + histogram_point_data2.boundaries_ = {10.0, 20.0, 30.0}; histogram_point_data2.count_ = 3; histogram_point_data2.counts_ = {200, 300, 400, 500}; - histogram_point_data2.sum_ = 900l; + histogram_point_data2.sum_ = (int64_t)900; metric_sdk::ResourceMetrics data; auto resource = opentelemetry::sdk::resource::Resource::Create( opentelemetry::sdk::resource::ResourceAttributes{}); @@ -90,7 +90,7 @@ inline metric_sdk::ResourceMetrics CreateLastValuePointData() last_value_point_data.is_lastvalue_valid_ = true; last_value_point_data.sample_ts_ = opentelemetry::common::SystemTimestamp{}; metric_sdk::LastValuePointData last_value_point_data2{}; - last_value_point_data2.value_ = 20l; + last_value_point_data2.value_ = (int64_t)20; last_value_point_data2.is_lastvalue_valid_ = true; last_value_point_data2.sample_ts_ = opentelemetry::common::SystemTimestamp{}; metric_sdk::MetricData metric_data{ diff --git a/exporters/zipkin/src/recordable.cc b/exporters/zipkin/src/recordable.cc index 1065c01619..6985fcb1ba 100644 --- a/exporters/zipkin/src/recordable.cc +++ b/exporters/zipkin/src/recordable.cc @@ -188,8 +188,8 @@ void Recordable::AddEvent(nostd::string_view name, span_["annotations"].push_back(annotation); } -void Recordable::AddLink(const trace_api::SpanContext &span_context, - const common::KeyValueIterable &attributes) noexcept +void Recordable::AddLink(const trace_api::SpanContext & /* span_context */, + const common::KeyValueIterable & /* attributes */) noexcept { // TODO: Currently not supported by specs: // https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/sdk_exporters/zipkin.md diff --git a/exporters/zipkin/src/zipkin_exporter.cc b/exporters/zipkin/src/zipkin_exporter.cc index 240144599f..802ecccffc 100644 --- a/exporters/zipkin/src/zipkin_exporter.cc +++ b/exporters/zipkin/src/zipkin_exporter.cc @@ -110,7 +110,7 @@ void ZipkinExporter::InitializeLocalEndpoint() local_end_point_["port"] = url_parser_.port_; } -bool ZipkinExporter::Shutdown(std::chrono::microseconds timeout) noexcept +bool ZipkinExporter::Shutdown(std::chrono::microseconds /* timeout */) noexcept { const std::lock_guard locked(lock_); is_shutdown_ = true; diff --git a/exporters/zipkin/test/zipkin_exporter_test.cc b/exporters/zipkin/test/zipkin_exporter_test.cc index eec71f43d6..af518d1655 100644 --- a/exporters/zipkin/test/zipkin_exporter_test.cc +++ b/exporters/zipkin/test/zipkin_exporter_test.cc @@ -148,9 +148,9 @@ TEST_F(ZipkinExporterTestPeer, ExportJsonIntegrationTest) auto expected_url = nostd::string_view{"http://localhost:9411/api/v2/spans"}; EXPECT_CALL(*mock_http_client, Post(expected_url, IsValidMessage(report_trace_id), _)) .Times(Exactly(1)) - .WillOnce(Return(ByMove(std::move(ext::http::client::Result{ + .WillOnce(Return(ByMove(ext::http::client::Result{ std::unique_ptr{new ext::http::client::curl::Response()}, - ext::http::client::SessionState::Response})))); + ext::http::client::SessionState::Response}))); child_span->End(); parent_span->End(); @@ -172,9 +172,9 @@ TEST_F(ZipkinExporterTestPeer, ShutdownTest) nostd::span> batch_1(&recordable_1, 1); EXPECT_CALL(*mock_http_client, Post(_, _, _)) .Times(Exactly(1)) - .WillOnce(Return(ByMove(std::move(ext::http::client::Result{ + .WillOnce(Return(ByMove(ext::http::client::Result{ std::unique_ptr{new ext::http::client::curl::Response()}, - ext::http::client::SessionState::Response})))); + ext::http::client::SessionState::Response}))); auto result = exporter->Export(batch_1); EXPECT_EQ(sdk_common::ExportResult::kSuccess, result); diff --git a/exporters/zipkin/test/zipkin_recordable_test.cc b/exporters/zipkin/test/zipkin_recordable_test.cc index 5da618d5b2..630ca332f0 100644 --- a/exporters/zipkin/test/zipkin_recordable_test.cc +++ b/exporters/zipkin/test/zipkin_recordable_test.cc @@ -12,6 +12,12 @@ #include "opentelemetry/common/timestamp.h" #include "opentelemetry/exporters/zipkin/recordable.h" +#if defined(__GNUC__) +// GCC raises -Wsuggest-override warnings on GTest, +// in code related to TYPED_TEST() . +# pragma GCC diagnostic ignored "-Wsuggest-override" +#endif + #include namespace trace = opentelemetry::trace; diff --git a/ext/include/opentelemetry/ext/http/client/curl/http_client_curl.h b/ext/include/opentelemetry/ext/http/client/curl/http_client_curl.h index 888b7e676f..43992bbdf5 100644 --- a/ext/include/opentelemetry/ext/http/client/curl/http_client_curl.h +++ b/ext/include/opentelemetry/ext/http/client/curl/http_client_curl.h @@ -263,7 +263,7 @@ class HttpClientSync : public opentelemetry::ext::http::client::HttpClientSync return opentelemetry::ext::http::client::Result(std::move(response), session_state); } - ~HttpClientSync() {} + ~HttpClientSync() override {} private: nostd::shared_ptr curl_global_initializer_; @@ -274,7 +274,7 @@ class HttpClient : public opentelemetry::ext::http::client::HttpClient public: // The call (curl_global_init) is not thread safe. Ensure this is called only once. HttpClient(); - ~HttpClient(); + ~HttpClient() override; std::shared_ptr CreateSession( nostd::string_view url) noexcept override; diff --git a/ext/include/opentelemetry/ext/http/client/nosend/http_client_nosend.h b/ext/include/opentelemetry/ext/http/client/nosend/http_client_nosend.h index f32a075879..4325885a96 100644 --- a/ext/include/opentelemetry/ext/http/client/nosend/http_client_nosend.h +++ b/ext/include/opentelemetry/ext/http/client/nosend/http_client_nosend.h @@ -15,7 +15,6 @@ # include # include "gmock/gmock.h" -using namespace testing; OPENTELEMETRY_BEGIN_NAMESPACE namespace ext { diff --git a/ext/include/opentelemetry/ext/http/server/http_server.h b/ext/include/opentelemetry/ext/http/server/http_server.h index 3cbb057ab4..5ea7debc43 100644 --- a/ext/include/opentelemetry/ext/http/server/http_server.h +++ b/ext/include/opentelemetry/ext/http/server/http_server.h @@ -54,6 +54,7 @@ class HttpRequestCallback public: HttpRequestCallback() {} + virtual ~HttpRequestCallback() = default; HttpRequestCallback &operator=(HttpRequestCallback other) { @@ -175,7 +176,7 @@ class HttpServer : private SocketTools::Reactor::SocketCallback addListeningPort(port); } - ~HttpServer() + ~HttpServer() override { for (auto &sock : m_listeningSockets) { diff --git a/ext/include/opentelemetry/ext/http/server/socket_tools.h b/ext/include/opentelemetry/ext/http/server/socket_tools.h index 7b234342fd..bb6302bac8 100644 --- a/ext/include/opentelemetry/ext/http/server/socket_tools.h +++ b/ext/include/opentelemetry/ext/http/server/socket_tools.h @@ -133,7 +133,7 @@ struct Thread virtual ~Thread() noexcept {} }; -}; // namespace common +} // namespace common namespace SocketTools { @@ -447,6 +447,8 @@ struct Reactor : protected common::Thread class SocketCallback { public: + SocketCallback() = default; + virtual ~SocketCallback() = default; virtual void onSocketReadable(Socket sock) = 0; virtual void onSocketWritable(Socket sock) = 0; virtual void onSocketAcceptable(Socket sock) = 0; @@ -502,7 +504,7 @@ struct Reactor : protected common::Thread #endif } - ~Reactor() + ~Reactor() override { #ifdef __linux__ ::close(m_epollFd); diff --git a/ext/include/opentelemetry/ext/zpages/tracez_processor.h b/ext/include/opentelemetry/ext/zpages/tracez_processor.h index 5e032c4568..081dd41117 100644 --- a/ext/include/opentelemetry/ext/zpages/tracez_processor.h +++ b/ext/include/opentelemetry/ext/zpages/tracez_processor.h @@ -64,8 +64,8 @@ class TracezSpanProcessor : public opentelemetry::sdk::trace::SpanProcessor * @param timeout an optional timeout. Currently, timeout does nothing. * @return return the status of the operation. */ - bool ForceFlush( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override + bool ForceFlush(std::chrono::microseconds timeout OPENTELEMETRY_MAYBE_UNUSED = + std::chrono::microseconds::max()) noexcept override { return true; } @@ -78,8 +78,8 @@ class TracezSpanProcessor : public opentelemetry::sdk::trace::SpanProcessor * timeout is applied. Currently, timeout does nothing. * @return return the status of the operation. */ - bool Shutdown( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override + bool Shutdown(std::chrono::microseconds timeout OPENTELEMETRY_MAYBE_UNUSED = + std::chrono::microseconds::max()) noexcept override { return true; } diff --git a/ext/src/zpages/tracez_processor.cc b/ext/src/zpages/tracez_processor.cc index 1e9115eb98..e7d68350d7 100644 --- a/ext/src/zpages/tracez_processor.cc +++ b/ext/src/zpages/tracez_processor.cc @@ -11,7 +11,8 @@ namespace zpages namespace trace_sdk = opentelemetry::sdk::trace; void TracezSpanProcessor::OnStart(trace_sdk::Recordable &span, - const opentelemetry::trace::SpanContext &parent_context) noexcept + const opentelemetry::trace::SpanContext & + /* parent_context */) noexcept { shared_data_->OnStart(static_cast(&span)); } diff --git a/ext/test/http/curl_http_test.cc b/ext/test/http/curl_http_test.cc index 5349cc0cb9..c0ee32d713 100644 --- a/ext/test/http/curl_http_test.cc +++ b/ext/test/http/curl_http_test.cc @@ -44,9 +44,9 @@ class CustomEventHandler : public http_client::EventHandler } } virtual void OnConnecting(const http_client::SSLCertificate &) noexcept override {} - virtual ~CustomEventHandler() = default; - bool is_called_ = false; - bool got_response_ = false; + ~CustomEventHandler() override = default; + bool is_called_ = false; + bool got_response_ = false; }; class GetEventHandler : public CustomEventHandler diff --git a/ext/test/zpages/tracez_processor_test.cc b/ext/test/zpages/tracez_processor_test.cc index f96385acda..6cc3640651 100644 --- a/ext/test/zpages/tracez_processor_test.cc +++ b/ext/test/zpages/tracez_processor_test.cc @@ -14,6 +14,7 @@ using namespace opentelemetry::sdk::trace; using namespace opentelemetry::ext::zpages; +using namespace testing; //////////////////////////////////// TEST HELPER FUNCTIONS ////////////////////////////// diff --git a/sdk/include/opentelemetry/sdk/common/attributemap_hash.h b/sdk/include/opentelemetry/sdk/common/attributemap_hash.h index 573f57eb1b..c6f2c93ccc 100644 --- a/sdk/include/opentelemetry/sdk/common/attributemap_hash.h +++ b/sdk/include/opentelemetry/sdk/common/attributemap_hash.h @@ -59,4 +59,4 @@ inline size_t GetHashForAttributeMap(const OrderedAttributeMap &attribute_map) } // namespace common } // namespace sdk -OPENTELEMETRY_END_NAMESPACE \ No newline at end of file +OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/include/opentelemetry/sdk/logs/batch_log_processor.h b/sdk/include/opentelemetry/sdk/logs/batch_log_processor.h index e70b511a10..efeb6dc675 100644 --- a/sdk/include/opentelemetry/sdk/logs/batch_log_processor.h +++ b/sdk/include/opentelemetry/sdk/logs/batch_log_processor.h @@ -64,7 +64,7 @@ class BatchLogProcessor : public LogProcessor * @param record the log record */ - void OnReceive(std::unique_ptr &&record) noexcept override; + void OnEmit(std::unique_ptr &&record) noexcept override; /** * Export all log records that have not been exported yet. @@ -87,7 +87,7 @@ class BatchLogProcessor : public LogProcessor /** * Class destructor which invokes the Shutdown() method. */ - virtual ~BatchLogProcessor(); + ~BatchLogProcessor() override; protected: /** diff --git a/sdk/include/opentelemetry/sdk/logs/logger_provider.h b/sdk/include/opentelemetry/sdk/logs/logger_provider.h index 9afb67ba0c..e91c69040e 100644 --- a/sdk/include/opentelemetry/sdk/logs/logger_provider.h +++ b/sdk/include/opentelemetry/sdk/logs/logger_provider.h @@ -61,7 +61,7 @@ class LoggerProvider final : public opentelemetry::logs::LoggerProvider */ explicit LoggerProvider(std::shared_ptr context) noexcept; - ~LoggerProvider(); + ~LoggerProvider() override; /** * Creates a logger with the given name, and returns a shared pointer to it. diff --git a/sdk/include/opentelemetry/sdk/logs/multi_log_processor.h b/sdk/include/opentelemetry/sdk/logs/multi_log_processor.h index c1bda24a0b..6b23a2652f 100644 --- a/sdk/include/opentelemetry/sdk/logs/multi_log_processor.h +++ b/sdk/include/opentelemetry/sdk/logs/multi_log_processor.h @@ -29,17 +29,17 @@ class MultiLogProcessor : public LogProcessor { public: MultiLogProcessor(std::vector> &&processors); - ~MultiLogProcessor(); + ~MultiLogProcessor() override; void AddProcessor(std::unique_ptr &&processor); std::unique_ptr MakeRecordable() noexcept override; /** - * OnReceive is called by the SDK once a log record has been successfully created. + * OnEmit is called by the SDK once a log record has been successfully created. * @param record the log record */ - void OnReceive(std::unique_ptr &&record) noexcept override; + void OnEmit(std::unique_ptr &&record) noexcept override; /** * Exports all log records that have not yet been exported to the configured Exporter. diff --git a/sdk/include/opentelemetry/sdk/logs/processor.h b/sdk/include/opentelemetry/sdk/logs/processor.h index 36da036f31..0fdc8a422f 100644 --- a/sdk/include/opentelemetry/sdk/logs/processor.h +++ b/sdk/include/opentelemetry/sdk/logs/processor.h @@ -32,10 +32,10 @@ class LogProcessor virtual std::unique_ptr MakeRecordable() noexcept = 0; /** - * OnReceive is called by the SDK once a log record has been successfully created. + * OnEmit is called by the SDK once a log record has been successfully created. * @param record the log record */ - virtual void OnReceive(std::unique_ptr &&record) noexcept = 0; + virtual void OnEmit(std::unique_ptr &&record) noexcept = 0; /** * Exports all log records that have not yet been exported to the configured Exporter. diff --git a/sdk/include/opentelemetry/sdk/logs/simple_log_processor.h b/sdk/include/opentelemetry/sdk/logs/simple_log_processor.h index 45f4683973..f8f29542a5 100644 --- a/sdk/include/opentelemetry/sdk/logs/simple_log_processor.h +++ b/sdk/include/opentelemetry/sdk/logs/simple_log_processor.h @@ -29,11 +29,11 @@ class SimpleLogProcessor : public LogProcessor public: explicit SimpleLogProcessor(std::unique_ptr &&exporter); - virtual ~SimpleLogProcessor() = default; + ~SimpleLogProcessor() override = default; std::unique_ptr MakeRecordable() noexcept override; - void OnReceive(std::unique_ptr &&record) noexcept override; + void OnEmit(std::unique_ptr &&record) noexcept override; bool ForceFlush( std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override; diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregation/aggregation.h b/sdk/include/opentelemetry/sdk/metrics/aggregation/aggregation.h index 7ec9a6ea2b..786466fd12 100644 --- a/sdk/include/opentelemetry/sdk/metrics/aggregation/aggregation.h +++ b/sdk/include/opentelemetry/sdk/metrics/aggregation/aggregation.h @@ -14,7 +14,7 @@ namespace metrics class Aggregation { public: - virtual void Aggregate(long value, const PointAttributes &attributes = {}) noexcept = 0; + virtual void Aggregate(int64_t value, const PointAttributes &attributes = {}) noexcept = 0; virtual void Aggregate(double value, const PointAttributes &attributes = {}) noexcept = 0; diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregation/aggregation_config.h b/sdk/include/opentelemetry/sdk/metrics/aggregation/aggregation_config.h index 67a092ff9c..61bf2716a7 100644 --- a/sdk/include/opentelemetry/sdk/metrics/aggregation/aggregation_config.h +++ b/sdk/include/opentelemetry/sdk/metrics/aggregation/aggregation_config.h @@ -16,15 +16,14 @@ class AggregationConfig virtual ~AggregationConfig() = default; }; -template class HistogramAggregationConfig : public AggregationConfig { public: - std::list boundaries_; + std::list boundaries_; bool record_min_max_ = true; }; } // namespace metrics } // namespace sdk OPENTELEMETRY_END_NAMESPACE -#endif // ENABLE_METRICS_PREVIEW \ No newline at end of file +#endif // ENABLE_METRICS_PREVIEW diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregation/default_aggregation.h b/sdk/include/opentelemetry/sdk/metrics/aggregation/default_aggregation.h index eb74b2d8dc..001e54a2af 100644 --- a/sdk/include/opentelemetry/sdk/metrics/aggregation/default_aggregation.h +++ b/sdk/include/opentelemetry/sdk/metrics/aggregation/default_aggregation.h @@ -27,27 +27,31 @@ class DefaultAggregation public: static std::unique_ptr CreateAggregation( const opentelemetry::sdk::metrics::InstrumentDescriptor &instrument_descriptor, - const opentelemetry::sdk::metrics::AggregationConfig *aggregation_config) + const AggregationConfig *aggregation_config) { switch (instrument_descriptor.type_) { case InstrumentType::kCounter: - case InstrumentType::kUpDownCounter: case InstrumentType::kObservableCounter: + return (instrument_descriptor.value_type_ == InstrumentValueType::kLong) + ? std::move(std::unique_ptr(new LongSumAggregation(true))) + : std::move(std::unique_ptr(new DoubleSumAggregation(true))); + case InstrumentType::kUpDownCounter: case InstrumentType::kObservableUpDownCounter: return (instrument_descriptor.value_type_ == InstrumentValueType::kLong) - ? std::move(std::unique_ptr(new LongSumAggregation())) - : std::move(std::unique_ptr(new DoubleSumAggregation())); + ? std::move(std::unique_ptr(new LongSumAggregation(false))) + : std::move(std::unique_ptr(new DoubleSumAggregation(false))); break; case InstrumentType::kHistogram: { - return (instrument_descriptor.value_type_ == InstrumentValueType::kLong) - ? std::move(std::unique_ptr(new LongHistogramAggregation( - static_cast< - const opentelemetry::sdk::metrics::HistogramAggregationConfig *>( - aggregation_config)))) - : std::move(std::unique_ptr(new DoubleHistogramAggregation( - static_cast *>(aggregation_config)))); + if (instrument_descriptor.value_type_ == InstrumentValueType::kLong) + { + return (std::unique_ptr(new LongHistogramAggregation(aggregation_config))); + } + else + { + return (std::unique_ptr(new DoubleHistogramAggregation(aggregation_config))); + } + break; } case InstrumentType::kObservableGauge: @@ -60,8 +64,10 @@ class DefaultAggregation }; } - static std::unique_ptr CreateAggregation(AggregationType aggregation_type, - InstrumentDescriptor instrument_descriptor) + static std::unique_ptr CreateAggregation( + AggregationType aggregation_type, + InstrumentDescriptor instrument_descriptor, + const AggregationConfig *aggregation_config = nullptr) { switch (aggregation_type) { @@ -71,11 +77,11 @@ class DefaultAggregation case AggregationType::kHistogram: if (instrument_descriptor.value_type_ == InstrumentValueType::kLong) { - return std::unique_ptr(new LongHistogramAggregation()); + return std::unique_ptr(new LongHistogramAggregation(aggregation_config)); } else { - return std::unique_ptr(new DoubleHistogramAggregation()); + return std::unique_ptr(new DoubleHistogramAggregation(aggregation_config)); } break; case AggregationType::kLastValue: @@ -88,18 +94,25 @@ class DefaultAggregation return std::unique_ptr(new DoubleLastValueAggregation()); } break; - case AggregationType::kSum: + case AggregationType::kSum: { + bool is_monotonic = true; + if (instrument_descriptor.type_ == InstrumentType::kUpDownCounter || + instrument_descriptor.type_ == InstrumentType::kObservableUpDownCounter) + { + is_monotonic = false; + } if (instrument_descriptor.value_type_ == InstrumentValueType::kLong) { - return std::unique_ptr(new LongSumAggregation()); + return std::unique_ptr(new LongSumAggregation(is_monotonic)); } else { - return std::unique_ptr(new DoubleSumAggregation()); + return std::unique_ptr(new DoubleSumAggregation(is_monotonic)); } break; + } default: - return DefaultAggregation::CreateAggregation(instrument_descriptor, nullptr); + return DefaultAggregation::CreateAggregation(instrument_descriptor, aggregation_config); } } diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregation/drop_aggregation.h b/sdk/include/opentelemetry/sdk/metrics/aggregation/drop_aggregation.h index c919c3a8e1..f32ffcd1d3 100644 --- a/sdk/include/opentelemetry/sdk/metrics/aggregation/drop_aggregation.h +++ b/sdk/include/opentelemetry/sdk/metrics/aggregation/drop_aggregation.h @@ -25,7 +25,7 @@ class DropAggregation : public Aggregation DropAggregation(const DropPointData &) {} - void Aggregate(long /* value */, const PointAttributes & /* attributes */) noexcept override {} + void Aggregate(int64_t /* value */, const PointAttributes & /* attributes */) noexcept override {} void Aggregate(double /* value */, const PointAttributes & /* attributes */) noexcept override {} diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h b/sdk/include/opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h index c78d02742e..0efe0c9a5b 100644 --- a/sdk/include/opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h +++ b/sdk/include/opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 #pragma once +#include #ifndef ENABLE_METRICS_PREVIEW # include "opentelemetry/common/spin_lock_mutex.h" # include "opentelemetry/sdk/metrics/aggregation/aggregation.h" @@ -18,11 +19,11 @@ namespace metrics class LongHistogramAggregation : public Aggregation { public: - LongHistogramAggregation(const HistogramAggregationConfig *aggregation_config = nullptr); + LongHistogramAggregation(const AggregationConfig *aggregation_config = nullptr); LongHistogramAggregation(HistogramPointData &&); LongHistogramAggregation(const HistogramPointData &); - void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override; + void Aggregate(int64_t value, const PointAttributes &attributes = {}) noexcept override; void Aggregate(double /* value */, const PointAttributes & /* attributes */) noexcept override {} @@ -48,12 +49,11 @@ class LongHistogramAggregation : public Aggregation class DoubleHistogramAggregation : public Aggregation { public: - DoubleHistogramAggregation( - const HistogramAggregationConfig *aggregation_config = nullptr); + DoubleHistogramAggregation(const AggregationConfig *aggregation_config = nullptr); DoubleHistogramAggregation(HistogramPointData &&); DoubleHistogramAggregation(const HistogramPointData &); - void Aggregate(long /* value */, const PointAttributes & /* attributes */) noexcept override {} + void Aggregate(int64_t /* value */, const PointAttributes & /* attributes */) noexcept override {} void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override; diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregation/lastvalue_aggregation.h b/sdk/include/opentelemetry/sdk/metrics/aggregation/lastvalue_aggregation.h index 47eabdf2f8..e4580e5e3a 100644 --- a/sdk/include/opentelemetry/sdk/metrics/aggregation/lastvalue_aggregation.h +++ b/sdk/include/opentelemetry/sdk/metrics/aggregation/lastvalue_aggregation.h @@ -20,7 +20,7 @@ class LongLastValueAggregation : public Aggregation LongLastValueAggregation(LastValuePointData &&); LongLastValueAggregation(const LastValuePointData &); - void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override; + void Aggregate(int64_t value, const PointAttributes &attributes = {}) noexcept override; void Aggregate(double /* value */, const PointAttributes & /* attributes */) noexcept override {} @@ -42,7 +42,7 @@ class DoubleLastValueAggregation : public Aggregation DoubleLastValueAggregation(LastValuePointData &&); DoubleLastValueAggregation(const LastValuePointData &); - void Aggregate(long /* value */, const PointAttributes & /* attributes */) noexcept override {} + void Aggregate(int64_t /* value */, const PointAttributes & /* attributes */) noexcept override {} void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override; diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregation/sum_aggregation.h b/sdk/include/opentelemetry/sdk/metrics/aggregation/sum_aggregation.h index 414f0e1c28..bb0d637b60 100644 --- a/sdk/include/opentelemetry/sdk/metrics/aggregation/sum_aggregation.h +++ b/sdk/include/opentelemetry/sdk/metrics/aggregation/sum_aggregation.h @@ -17,11 +17,11 @@ namespace metrics class LongSumAggregation : public Aggregation { public: - LongSumAggregation(); + LongSumAggregation(bool is_monotonic); LongSumAggregation(SumPointData &&); LongSumAggregation(const SumPointData &); - void Aggregate(long value, const PointAttributes &attributes = {}) noexcept override; + void Aggregate(int64_t value, const PointAttributes &attributes = {}) noexcept override; void Aggregate(double /* value */, const PointAttributes & /* attributes */) noexcept override {} @@ -39,11 +39,11 @@ class LongSumAggregation : public Aggregation class DoubleSumAggregation : public Aggregation { public: - DoubleSumAggregation(); + DoubleSumAggregation(bool is_monotonic); DoubleSumAggregation(SumPointData &&); DoubleSumAggregation(const SumPointData &); - void Aggregate(long /* value */, const PointAttributes & /* attributes */) noexcept override {} + void Aggregate(int64_t /* value */, const PointAttributes & /* attributes */) noexcept override {} void Aggregate(double value, const PointAttributes &attributes = {}) noexcept override; diff --git a/sdk/include/opentelemetry/sdk/metrics/async_instruments.h b/sdk/include/opentelemetry/sdk/metrics/async_instruments.h index b32f68fa1f..13a059962c 100644 --- a/sdk/include/opentelemetry/sdk/metrics/async_instruments.h +++ b/sdk/include/opentelemetry/sdk/metrics/async_instruments.h @@ -42,4 +42,4 @@ class ObservableInstrument : public opentelemetry::metrics::ObservableInstrument } // namespace metrics } // namespace sdk OPENTELEMETRY_END_NAMESPACE -#endif \ No newline at end of file +#endif diff --git a/sdk/include/opentelemetry/sdk/metrics/data/exemplar_data.h b/sdk/include/opentelemetry/sdk/metrics/data/exemplar_data.h new file mode 100644 index 0000000000..49ae1ed56c --- /dev/null +++ b/sdk/include/opentelemetry/sdk/metrics/data/exemplar_data.h @@ -0,0 +1,84 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once +#ifndef ENABLE_METRICS_PREVIEW +# include +# include "opentelemetry/common/timestamp.h" +# include "opentelemetry/context/context.h" +# include "opentelemetry/sdk/common/attribute_utils.h" +# include "opentelemetry/sdk/metrics/data/metric_data.h" +# include "opentelemetry/sdk/metrics/export/metric_producer.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ +using MetricAttributes = opentelemetry::sdk::common::OrderedAttributeMap; +/** + * A sample input measurement. + * + * Exemplars also hold information about the environment when the measurement was recorded, for + * example the span and trace ID of the active span when the exemplar was recorded. + */ +class ExemplarData +{ +public: + static ExemplarData Create(std::shared_ptr context, + const opentelemetry::common::SystemTimestamp ×tamp, + const PointDataAttributes &point_data_attr) + { + return ExemplarData(context, timestamp, point_data_attr); + } + + /** + * The set of key/value pairs that were filtered out by the aggregator, but recorded alongside + * the original measurement. Only key/value pairs that were filtered out by the aggregator + * should be included + */ + MetricAttributes GetFilteredAttributes() { return MetricAttributes{}; } + + /** Returns the timestamp in nanos when measurement was collected. */ + opentelemetry::common::SystemTimestamp GetEpochNanos() { return timestamp_; } + + /** + * Returns the SpanContext associated with this exemplar. If the exemplar was not recorded + * inside a sampled trace, the Context will be invalid. + */ + const trace::SpanContext &GetSpanContext() const noexcept { return context_; } + + static PointType CreateSumPointData(ValueType value) + { + SumPointData sum_point_data{}; + sum_point_data.value_ = value; + return sum_point_data; + } + + static PointType CreateLastValuePointData(ValueType value) + { + LastValuePointData last_value_point_data{}; + last_value_point_data.value_ = value; + last_value_point_data.is_lastvalue_valid_ = true; + last_value_point_data.sample_ts_ = opentelemetry::common::SystemTimestamp{}; + return last_value_point_data; + } + + static PointType CreateDropPointData() { return DropPointData{}; } + +private: + ExemplarData(std::shared_ptr context, + opentelemetry::common::SystemTimestamp timestamp, + const PointDataAttributes &point_data_attr) + : context_(*context.get()), timestamp_(timestamp), point_data_attr_(point_data_attr) + {} + + trace::SpanContext context_; + opentelemetry::common::SystemTimestamp timestamp_; + PointDataAttributes point_data_attr_; +}; + +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/sdk/include/opentelemetry/sdk/metrics/data/metric_data.h b/sdk/include/opentelemetry/sdk/metrics/data/metric_data.h index 3383f8d618..6b209f16d3 100644 --- a/sdk/include/opentelemetry/sdk/metrics/data/metric_data.h +++ b/sdk/include/opentelemetry/sdk/metrics/data/metric_data.h @@ -40,4 +40,4 @@ class MetricData } // namespace metrics } // namespace sdk OPENTELEMETRY_END_NAMESPACE -#endif \ No newline at end of file +#endif diff --git a/sdk/include/opentelemetry/sdk/metrics/data/point_data.h b/sdk/include/opentelemetry/sdk/metrics/data/point_data.h index ebc4bb98f2..81878ff757 100644 --- a/sdk/include/opentelemetry/sdk/metrics/data/point_data.h +++ b/sdk/include/opentelemetry/sdk/metrics/data/point_data.h @@ -16,8 +16,7 @@ namespace sdk namespace metrics { -using ValueType = nostd::variant; -using ListType = nostd::variant, std::list>; +using ValueType = nostd::variant; // TODO: remove ctors and initializers from below classes when GCC<5 stops shipping on Ubuntu @@ -30,7 +29,8 @@ class SumPointData SumPointData &operator=(SumPointData &&) = default; SumPointData() = default; - ValueType value_ = {}; + ValueType value_ = {}; + bool is_monotonic_ = true; }; class LastValuePointData @@ -55,8 +55,8 @@ class HistogramPointData HistogramPointData &operator=(HistogramPointData &&) = default; HistogramPointData(const HistogramPointData &) = default; HistogramPointData() = default; - - ListType boundaries_ = {}; + HistogramPointData(std::list &boundaries) : boundaries_(boundaries) {} + std::list boundaries_ = {}; ValueType sum_ = {}; ValueType min_ = {}; ValueType max_ = {}; diff --git a/sdk/include/opentelemetry/sdk/metrics/exemplar/always_sample_filter.h b/sdk/include/opentelemetry/sdk/metrics/exemplar/always_sample_filter.h index c21b4cc84a..8bcb974993 100644 --- a/sdk/include/opentelemetry/sdk/metrics/exemplar/always_sample_filter.h +++ b/sdk/include/opentelemetry/sdk/metrics/exemplar/always_sample_filter.h @@ -14,14 +14,8 @@ namespace metrics class AlwaysSampleFilter final : public ExemplarFilter { public: - static nostd::shared_ptr GetAlwaysSampleFilter() - { - static nostd::shared_ptr alwaysSampleFilter{new AlwaysSampleFilter{}}; - return alwaysSampleFilter; - } - bool ShouldSampleMeasurement( - long /* value */, + int64_t /* value */, const MetricAttributes & /* attributes */, const opentelemetry::context::Context & /* context */) noexcept override { @@ -36,7 +30,6 @@ class AlwaysSampleFilter final : public ExemplarFilter return true; } -private: explicit AlwaysSampleFilter() = default; }; } // namespace metrics diff --git a/sdk/include/opentelemetry/sdk/metrics/exemplar/data.h b/sdk/include/opentelemetry/sdk/metrics/exemplar/data.h deleted file mode 100644 index 14eac62499..0000000000 --- a/sdk/include/opentelemetry/sdk/metrics/exemplar/data.h +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once -#ifndef ENABLE_METRICS_PREVIEW -# include "opentelemetry/common/timestamp.h" -# include "opentelemetry/context/context.h" -# include "opentelemetry/sdk/common/attribute_utils.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace sdk -{ -namespace metrics -{ -using MetricAttributes = opentelemetry::sdk::common::OrderedAttributeMap; -/** - * A sample input measurement. - * - * Exemplars also hold information about the environment when the measurement was recorded, for - * example the span and trace ID of the active span when the exemplar was recorded. - */ -class ExemplarData -{ -public: - /** - * The set of key/value pairs that were filtered out by the aggregator, but recorded alongside the - * original measurement. Only key/value pairs that were filtered out by the aggregator should be - * included - */ - MetricAttributes GetFilteredAttributes(); - - /** Returns the timestamp in nanos when measurement was collected. */ - opentelemetry::common::SystemTimestamp GetEpochNanos(); - - /** - * Returns the SpanContext associated with this exemplar. If the exemplar was not recorded - * inside a sampled trace, the Context will be invalid. - */ - opentelemetry::context::Context GetSpanContext(); -}; - -} // namespace metrics -} // namespace sdk -OPENTELEMETRY_END_NAMESPACE -#endif diff --git a/sdk/include/opentelemetry/sdk/metrics/exemplar/filter.h b/sdk/include/opentelemetry/sdk/metrics/exemplar/filter.h index 4b512e1317..3c8c43fb58 100644 --- a/sdk/include/opentelemetry/sdk/metrics/exemplar/filter.h +++ b/sdk/include/opentelemetry/sdk/metrics/exemplar/filter.h @@ -21,7 +21,7 @@ class ExemplarFilter { public: // Returns whether or not a reservoir should attempt to filter a measurement. - virtual bool ShouldSampleMeasurement(long value, + virtual bool ShouldSampleMeasurement(int64_t value, const MetricAttributes &attributes, const opentelemetry::context::Context &context) noexcept = 0; @@ -31,6 +31,10 @@ class ExemplarFilter const opentelemetry::context::Context &context) noexcept = 0; virtual ~ExemplarFilter() = default; + + static std::shared_ptr GetNeverSampleFilter() noexcept; + static std::shared_ptr GetAlwaysSampleFilter() noexcept; + static std::shared_ptr GetWithTraceSampleFilter() noexcept; }; } // namespace metrics diff --git a/sdk/include/opentelemetry/sdk/metrics/exemplar/filtered_exemplar_reservoir.h b/sdk/include/opentelemetry/sdk/metrics/exemplar/filtered_exemplar_reservoir.h new file mode 100644 index 0000000000..f410bef6d0 --- /dev/null +++ b/sdk/include/opentelemetry/sdk/metrics/exemplar/filtered_exemplar_reservoir.h @@ -0,0 +1,65 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once +#ifndef ENABLE_METRICS_PREVIEW +# include +# include +# include "opentelemetry/context/context.h" +# include "opentelemetry/nostd/shared_ptr.h" +# include "opentelemetry/sdk/common/attribute_utils.h" +# include "opentelemetry/sdk/metrics/exemplar/filter.h" +# include "opentelemetry/sdk/metrics/exemplar/reservoir.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ +class FilteredExemplarReservoir final : public ExemplarReservoir +{ + +public: + FilteredExemplarReservoir(std::shared_ptr filter, + std::shared_ptr reservoir) + : filter_(filter), reservoir_(reservoir) + {} + + void OfferMeasurement(int64_t value, + const MetricAttributes &attributes, + const opentelemetry::context::Context &context, + const opentelemetry::common::SystemTimestamp ×tamp) noexcept override + { + if (filter_->ShouldSampleMeasurement(value, attributes, context)) + { + reservoir_->OfferMeasurement(value, attributes, context, timestamp); + } + } + + void OfferMeasurement(double value, + const MetricAttributes &attributes, + const opentelemetry::context::Context &context, + const opentelemetry::common::SystemTimestamp ×tamp) noexcept override + { + if (filter_->ShouldSampleMeasurement(value, attributes, context)) + { + reservoir_->OfferMeasurement(value, attributes, context, timestamp); + } + } + + std::vector> CollectAndReset( + const MetricAttributes &pointAttributes) noexcept override + { + return reservoir_->CollectAndReset(pointAttributes); + } + +private: + explicit FilteredExemplarReservoir() = default; + std::shared_ptr filter_; + std::shared_ptr reservoir_; +}; + +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/sdk/include/opentelemetry/sdk/metrics/exemplar/fixed_size_exemplar_reservoir.h b/sdk/include/opentelemetry/sdk/metrics/exemplar/fixed_size_exemplar_reservoir.h new file mode 100644 index 0000000000..e8564f4285 --- /dev/null +++ b/sdk/include/opentelemetry/sdk/metrics/exemplar/fixed_size_exemplar_reservoir.h @@ -0,0 +1,104 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once +#ifndef ENABLE_METRICS_PREVIEW +# include +# include +# include "opentelemetry/context/context.h" +# include "opentelemetry/nostd/function_ref.h" +# include "opentelemetry/nostd/shared_ptr.h" +# include "opentelemetry/sdk/common/attribute_utils.h" +# include "opentelemetry/sdk/metrics/exemplar/reservoir.h" +# include "opentelemetry/sdk/metrics/exemplar/reservoir_cell.h" +# include "opentelemetry/sdk/metrics/exemplar/reservoir_cell_selector.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ + +class FixedSizeExemplarReservoir : public ExemplarReservoir +{ + +public: + FixedSizeExemplarReservoir(size_t size, + std::shared_ptr reservoir_cell_selector, + std::shared_ptr (ReservoirCell::*map_and_reset_cell)( + const common::OrderedAttributeMap &attributes)) + : storage_(size), + reservoir_cell_selector_(reservoir_cell_selector), + map_and_reset_cell_(map_and_reset_cell) + {} + + void OfferMeasurement( + int64_t value, + const MetricAttributes &attributes, + const opentelemetry::context::Context &context, + const opentelemetry::common::SystemTimestamp & /* timestamp */) noexcept override + { + if (!reservoir_cell_selector_) + { + return; + } + auto idx = + reservoir_cell_selector_->ReservoirCellIndexFor(storage_, value, attributes, context); + if (idx != -1) + { + storage_[idx].RecordLongMeasurement(value, attributes, context); + } + } + + void OfferMeasurement( + double value, + const MetricAttributes &attributes, + const opentelemetry::context::Context &context, + const opentelemetry::common::SystemTimestamp & /* timestamp */) noexcept override + { + if (!reservoir_cell_selector_) + { + return; + } + auto idx = + reservoir_cell_selector_->ReservoirCellIndexFor(storage_, value, attributes, context); + if (idx != -1) + { + storage_[idx].RecordDoubleMeasurement(value, attributes, context); + } + } + + std::vector> CollectAndReset( + const MetricAttributes &pointAttributes) noexcept override + { + std::vector> results; + if (!reservoir_cell_selector_) + { + return results; + } + if (!map_and_reset_cell_) + { + reservoir_cell_selector_.reset(); + return results; + } + for (auto reservoirCell : storage_) + { + auto result = (reservoirCell.*(map_and_reset_cell_))(pointAttributes); + results.push_back(result); + } + reservoir_cell_selector_.reset(); + return results; + } + +private: + explicit FixedSizeExemplarReservoir() = default; + std::vector storage_; + std::shared_ptr reservoir_cell_selector_; + std::shared_ptr (ReservoirCell::*map_and_reset_cell_)( + const common::OrderedAttributeMap &attributes); +}; + +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/sdk/include/opentelemetry/sdk/metrics/exemplar/histogram_exemplar_reservoir.h b/sdk/include/opentelemetry/sdk/metrics/exemplar/histogram_exemplar_reservoir.h new file mode 100644 index 0000000000..ad7f163860 --- /dev/null +++ b/sdk/include/opentelemetry/sdk/metrics/exemplar/histogram_exemplar_reservoir.h @@ -0,0 +1,81 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once +#ifndef ENABLE_METRICS_PREVIEW +# include +# include +# include "opentelemetry/context/context.h" +# include "opentelemetry/nostd/shared_ptr.h" +# include "opentelemetry/sdk/common/attribute_utils.h" +# include "opentelemetry/sdk/metrics/data/exemplar_data.h" +# include "opentelemetry/sdk/metrics/exemplar/filter.h" +# include "opentelemetry/sdk/metrics/exemplar/fixed_size_exemplar_reservoir.h" +# include "opentelemetry/sdk/metrics/exemplar/reservoir.h" +# include "opentelemetry/sdk/metrics/exemplar/reservoir_cell_selector.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ + +class HistogramExemplarReservoir : public FixedSizeExemplarReservoir +{ + +public: + static std::shared_ptr GetHistogramCellSelector( + const std::vector &boundaries = std::vector{1.0, 2.0, 3.0, 4.0, 5.0}) + { + return std::shared_ptr{new HistogramCellSelector(boundaries)}; + } + + HistogramExemplarReservoir(size_t size, + std::shared_ptr reservoir_cell_selector, + std::shared_ptr (ReservoirCell::*map_and_reset_cell)( + const common::OrderedAttributeMap &attributes)) + : FixedSizeExemplarReservoir(size, reservoir_cell_selector, map_and_reset_cell) + {} + + class HistogramCellSelector : public ReservoirCellSelector + { + public: + HistogramCellSelector(const std::vector &boundaries) : boundaries_(boundaries) {} + + int ReservoirCellIndexFor(const std::vector &cells, + int64_t value, + const MetricAttributes &attributes, + const opentelemetry::context::Context &context) override + { + return ReservoirCellIndexFor(cells, (double)value, attributes, context); + } + + int ReservoirCellIndexFor(const std::vector & /* cells */, + double value, + const MetricAttributes & /* attributes */, + const opentelemetry::context::Context & /* context */) override + { + size_t max_size = boundaries_.size(); + for (size_t i = 0; i < max_size; ++i) + { + if (value <= boundaries_[i]) + { + return static_cast(i); + } + } + return -1; + } + + private: + void reset() override + { + // Do nothing + } + std::vector boundaries_; + }; +}; + +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/sdk/include/opentelemetry/sdk/metrics/exemplar/never_sample_filter.h b/sdk/include/opentelemetry/sdk/metrics/exemplar/never_sample_filter.h index 53d38142c1..e5015c9b9f 100644 --- a/sdk/include/opentelemetry/sdk/metrics/exemplar/never_sample_filter.h +++ b/sdk/include/opentelemetry/sdk/metrics/exemplar/never_sample_filter.h @@ -14,14 +14,8 @@ namespace metrics class NeverSampleFilter final : public ExemplarFilter { public: - static nostd::shared_ptr GetNeverSampleFilter() - { - nostd::shared_ptr neverSampleFilter{new NeverSampleFilter{}}; - return neverSampleFilter; - } - bool ShouldSampleMeasurement( - long /* value */, + int64_t /* value */, const MetricAttributes & /* attributes */, const opentelemetry::context::Context & /* context */) noexcept override { @@ -36,7 +30,6 @@ class NeverSampleFilter final : public ExemplarFilter return false; } -private: explicit NeverSampleFilter() = default; }; } // namespace metrics diff --git a/sdk/include/opentelemetry/sdk/metrics/exemplar/no_exemplar_reservoir.h b/sdk/include/opentelemetry/sdk/metrics/exemplar/no_exemplar_reservoir.h index 5ea1233c10..481690a0c3 100644 --- a/sdk/include/opentelemetry/sdk/metrics/exemplar/no_exemplar_reservoir.h +++ b/sdk/include/opentelemetry/sdk/metrics/exemplar/no_exemplar_reservoir.h @@ -18,13 +18,8 @@ class NoExemplarReservoir final : public ExemplarReservoir { public: - static nostd::shared_ptr GetNoExemplarReservoir() - { - return nostd::shared_ptr{new NoExemplarReservoir{}}; - } - void OfferMeasurement( - long /* value */, + int64_t /* value */, const MetricAttributes & /* attributes */, const opentelemetry::context::Context & /* context */, const opentelemetry::common::SystemTimestamp & /* timestamp */) noexcept override @@ -41,13 +36,12 @@ class NoExemplarReservoir final : public ExemplarReservoir // Stores nothing. } - std::vector CollectAndReset( + std::vector> CollectAndReset( const MetricAttributes & /* pointAttributes */) noexcept override { - return std::vector{}; + return std::vector>{}; } -private: explicit NoExemplarReservoir() = default; }; diff --git a/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir.h b/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir.h index 25e8421d6b..5fcb90d6b4 100644 --- a/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir.h +++ b/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir.h @@ -4,7 +4,9 @@ #pragma once #ifndef ENABLE_METRICS_PREVIEW # include -# include "opentelemetry/sdk/metrics/exemplar/data.h" +# include "opentelemetry/sdk/metrics/data/exemplar_data.h" +# include "opentelemetry/sdk/metrics/exemplar/filter.h" +# include "opentelemetry/sdk/metrics/exemplar/reservoir_cell_selector.h" OPENTELEMETRY_BEGIN_NAMESPACE namespace sdk @@ -23,7 +25,7 @@ class ExemplarReservoir /** Offers a long measurement to be sampled. */ virtual void OfferMeasurement( - long value, + int64_t value, const MetricAttributes &attributes, const opentelemetry::context::Context &context, const opentelemetry::common::SystemTimestamp ×tamp) noexcept = 0; @@ -45,8 +47,20 @@ class ExemplarReservoir * @return A vector of sampled exemplars for this point. Implementers are expected to * filter out pointAttributes from the original recorded attributes. */ - virtual std::vector CollectAndReset( + virtual std::vector> CollectAndReset( const MetricAttributes &pointAttributes) noexcept = 0; + + static nostd::shared_ptr GetFilteredExemplarReservoir( + std::shared_ptr filter, + std::shared_ptr reservoir); + + static nostd::shared_ptr GetHistogramExemplarReservoir( + size_t size, + std::shared_ptr reservoir_cell_selector, + std::shared_ptr (ReservoirCell::*map_and_reset_cell)( + const common::OrderedAttributeMap &attributes)); + + static nostd::shared_ptr GetNoExemplarReservoir(); }; } // namespace metrics diff --git a/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir_cell.h b/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir_cell.h new file mode 100644 index 0000000000..324fbe1993 --- /dev/null +++ b/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir_cell.h @@ -0,0 +1,153 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once +#ifndef ENABLE_METRICS_PREVIEW +# include +# include +# include +# include "opentelemetry/common/timestamp.h" +# include "opentelemetry/context/context.h" +# include "opentelemetry/nostd/shared_ptr.h" +# include "opentelemetry/sdk/common/attribute_utils.h" +# include "opentelemetry/sdk/metrics/data/exemplar_data.h" +# include "opentelemetry/sdk/metrics/exemplar/filter.h" +# include "opentelemetry/trace/context.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ +/** + * A Reservoir cell pre-allocated memories for Exemplar data. + */ +class ReservoirCell +{ +public: + ReservoirCell() = default; + + /** + * Record the long measurement to the cell. + */ + void RecordLongMeasurement(int64_t value, + const MetricAttributes &attributes, + const opentelemetry::context::Context &context) + { + value_ = value; + offerMeasurement(attributes, context); + } + + /** + * Record the long measurement to the cell. + */ + void RecordDoubleMeasurement(double value, + const MetricAttributes &attributes, + const opentelemetry::context::Context &context) + { + value_ = value; + offerMeasurement(attributes, context); + } + + /** + * Retrieve the cell's {@link ExemplarData}. + * + *

Must be used in tandem with {@link #recordLongMeasurement(int64_t, Attributes, Context)}. + */ + std::shared_ptr GetAndResetLong(const MetricAttributes &point_attributes) + { + if (!context_) + { + return nullptr; + } + auto attributes = attributes_; + PointDataAttributes point_data_attributes; + point_data_attributes.attributes = filtered(attributes, point_attributes); + if (nostd::holds_alternative(value_)) + { + point_data_attributes.point_data = + ExemplarData::CreateSumPointData(nostd::get(value_)); + } + std::shared_ptr result{ + new ExemplarData{ExemplarData::Create(context_, record_time_, point_data_attributes)}}; + reset(); + return result; + } + + /** + * Retrieve the cell's {@link ExemplarData}. + * + *

Must be used in tandem with {@link #recordDoubleMeasurement(double, Attributes, Context)}. + */ + std::shared_ptr GetAndResetDouble(const MetricAttributes &point_attributes) + { + if (!context_) + { + return nullptr; + } + auto attributes = attributes_; + PointDataAttributes point_data_attributes; + point_data_attributes.attributes = filtered(attributes, point_attributes); + if (nostd::holds_alternative(value_)) + { + point_data_attributes.point_data = + ExemplarData::CreateSumPointData(nostd::get(value_)); + } + std::shared_ptr result{ + new ExemplarData{ExemplarData::Create(context_, record_time_, point_data_attributes)}}; + reset(); + return result; + } + + void reset() + { + value_ = 0.0; + record_time_ = opentelemetry::common::SystemTimestamp{}; + } + +private: + /** Returns filtered attributes for exemplars. */ + static MetricAttributes filtered(const MetricAttributes &original, + const MetricAttributes &metric_point) + { + auto res = original; + for (const auto &kv : metric_point) + { + auto it = res.find(kv.first); + if (it != res.end()) + { + res.erase(it); + } + } + return res; + } + + void offerMeasurement(const MetricAttributes &attributes, + const opentelemetry::context::Context &context) + { + attributes_ = attributes; + record_time_ = opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now()); + auto span = opentelemetry::trace::GetSpan(context); + if (span) + { + auto current_ctx = span->GetContext(); + if (current_ctx.IsValid()) + { + context_.reset(new trace::SpanContext{current_ctx}); + } + } + } + + // Cell stores either long or double values, but must not store both + std::shared_ptr context_; + nostd::variant value_; + opentelemetry::common::SystemTimestamp record_time_; + MetricAttributes attributes_; + // For testing + friend class ReservoirCellTestPeer; +}; + +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir_cell_selector.h b/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir_cell_selector.h new file mode 100644 index 0000000000..6972bf429b --- /dev/null +++ b/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir_cell_selector.h @@ -0,0 +1,44 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once +#include +#ifndef ENABLE_METRICS_PREVIEW +# include +# include +# include "opentelemetry/context/context.h" +# include "opentelemetry/nostd/shared_ptr.h" +# include "opentelemetry/sdk/common/attribute_utils.h" +# include "opentelemetry/sdk/metrics/exemplar/reservoir_cell.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ +class ReservoirCellSelector +{ + +public: + virtual ~ReservoirCellSelector() = default; + + /** Determine the index of the {@code cells} to record the measurement to. */ + virtual int ReservoirCellIndexFor(const std::vector &cells, + int64_t value, + const MetricAttributes &attributes, + const opentelemetry::context::Context &context) = 0; + + /** Determine the index of the {@code cells} to record the measurement to. */ + virtual int ReservoirCellIndexFor(const std::vector &cells, + double value, + const MetricAttributes &attributes, + const opentelemetry::context::Context &context) = 0; + + /** Called when {@link FixedSizeExemplarReservoir#CollectAndReset(Attributes)}. */ + virtual void reset() = 0; +}; + +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/sdk/include/opentelemetry/sdk/metrics/exemplar/with_trace_sample_filter.h b/sdk/include/opentelemetry/sdk/metrics/exemplar/with_trace_sample_filter.h new file mode 100644 index 0000000000..afeb179866 --- /dev/null +++ b/sdk/include/opentelemetry/sdk/metrics/exemplar/with_trace_sample_filter.h @@ -0,0 +1,44 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/metrics/exemplar/filter.h" +# include "opentelemetry/trace/context.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ + +class WithTraceSampleFilter final : public ExemplarFilter +{ +public: + bool ShouldSampleMeasurement(int64_t /* value */, + const MetricAttributes & /* attributes */, + const opentelemetry::context::Context &context) noexcept override + { + return hasSampledTrace(context); + } + + bool ShouldSampleMeasurement(double /* value */, + const MetricAttributes & /* attributes */, + const opentelemetry::context::Context &context) noexcept override + { + return hasSampledTrace(context); + } + + explicit WithTraceSampleFilter() = default; + +private: + static bool hasSampledTrace(const opentelemetry::context::Context &context) + { + return opentelemetry::trace::GetSpan(context)->GetContext().IsValid() && + opentelemetry::trace::GetSpan(context)->GetContext().IsSampled(); + } +}; +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/sdk/include/opentelemetry/sdk/metrics/export/metric_producer.h b/sdk/include/opentelemetry/sdk/metrics/export/metric_producer.h index 7b4cf4d47f..07f4cadbd1 100644 --- a/sdk/include/opentelemetry/sdk/metrics/export/metric_producer.h +++ b/sdk/include/opentelemetry/sdk/metrics/export/metric_producer.h @@ -40,6 +40,9 @@ struct ResourceMetrics class MetricProducer { public: + MetricProducer() = default; + virtual ~MetricProducer() = default; + /** * The callback to be called for each metric exporter. This will only be those * metrics that have been produced since the last time this method was called. diff --git a/sdk/include/opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader.h b/sdk/include/opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader.h index 54c7c0536a..0e9f56722f 100644 --- a/sdk/include/opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader.h +++ b/sdk/include/opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader.h @@ -18,7 +18,7 @@ namespace sdk namespace metrics { -class MetricExporter; +class PushMetricExporter; /** * Struct to hold PeriodicExortingMetricReader options. */ @@ -40,7 +40,7 @@ class PeriodicExportingMetricReader : public MetricReader { public: - PeriodicExportingMetricReader(std::unique_ptr exporter, + PeriodicExportingMetricReader(std::unique_ptr exporter, const PeriodicExportingMetricReaderOptions &option); AggregationTemporality GetAggregationTemporality( @@ -53,7 +53,7 @@ class PeriodicExportingMetricReader : public MetricReader void OnInitialized() noexcept override; - std::unique_ptr exporter_; + std::unique_ptr exporter_; std::chrono::milliseconds export_interval_millis_; std::chrono::milliseconds export_timeout_millis_; diff --git a/sdk/include/opentelemetry/sdk/metrics/instrument_metadata_validator.h b/sdk/include/opentelemetry/sdk/metrics/instrument_metadata_validator.h new file mode 100644 index 0000000000..97e7550cde --- /dev/null +++ b/sdk/include/opentelemetry/sdk/metrics/instrument_metadata_validator.h @@ -0,0 +1,38 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#pragma once +#ifndef ENABLE_METRICS_PREVIEW +# include +# include "opentelemetry/common/macros.h" +# include "opentelemetry/nostd/string_view.h" +# include "opentelemetry/version.h" + +# if HAVE_WORKING_REGEX +# include +# endif + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ +class InstrumentMetaDataValidator +{ +public: + InstrumentMetaDataValidator(); + bool ValidateName(nostd::string_view name) const; + bool ValidateUnit(nostd::string_view unit) const; + bool ValidateDescription(nostd::string_view description) const; + +private: +# if HAVE_WORKING_REGEX + const std::regex name_reg_key_; + const std::regex unit_reg_key_; +# endif +}; + +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/sdk/include/opentelemetry/sdk/metrics/instruments.h b/sdk/include/opentelemetry/sdk/metrics/instruments.h index a529095600..b176eabe5e 100644 --- a/sdk/include/opentelemetry/sdk/metrics/instruments.h +++ b/sdk/include/opentelemetry/sdk/metrics/instruments.h @@ -62,18 +62,6 @@ struct InstrumentDescriptor using MetricAttributes = opentelemetry::sdk::common::OrderedAttributeMap; using AggregationTemporalitySelector = std::function; -OPENTELEMETRY_MAYBE_UNUSED static InstrumentClass GetInstrumentClass(InstrumentType type) -{ - if (type == InstrumentType::kCounter || type == InstrumentType::kHistogram || - type == InstrumentType::kUpDownCounter) - { - return InstrumentClass::kSync; - } - else - { - return InstrumentClass::kAsync; - } -} /*class InstrumentSelector { public: diff --git a/sdk/include/opentelemetry/sdk/metrics/meter.h b/sdk/include/opentelemetry/sdk/metrics/meter.h index ef0d5ffb4e..80f9d5bc67 100644 --- a/sdk/include/opentelemetry/sdk/metrics/meter.h +++ b/sdk/include/opentelemetry/sdk/metrics/meter.h @@ -5,7 +5,9 @@ #ifndef ENABLE_METRICS_PREVIEW # include # include "opentelemetry/metrics/meter.h" +# include "opentelemetry/metrics/noop.h" # include "opentelemetry/sdk/instrumentationscope/instrumentation_scope.h" +# include "opentelemetry/sdk/metrics/instrument_metadata_validator.h" # include "opentelemetry/sdk/metrics/instruments.h" # include "opentelemetry/sdk/metrics/meter_context.h" # include "opentelemetry/sdk/metrics/state/async_metric_storage.h" @@ -35,17 +37,17 @@ class Meter final : public opentelemetry::metrics::Meter std::unique_ptr scope = opentelemetry::sdk::instrumentationscope::InstrumentationScope::Create("")) noexcept; - nostd::shared_ptr> CreateLongCounter( + nostd::unique_ptr> CreateUInt64Counter( nostd::string_view name, nostd::string_view description = "", nostd::string_view unit = "") noexcept override; - nostd::shared_ptr> CreateDoubleCounter( + nostd::unique_ptr> CreateDoubleCounter( nostd::string_view name, nostd::string_view description = "", nostd::string_view unit = "") noexcept override; - nostd::shared_ptr CreateLongObservableCounter( + nostd::shared_ptr CreateInt64ObservableCounter( nostd::string_view name, nostd::string_view description = "", nostd::string_view unit = "") noexcept override; @@ -55,17 +57,17 @@ class Meter final : public opentelemetry::metrics::Meter nostd::string_view description = "", nostd::string_view unit = "") noexcept override; - nostd::shared_ptr> CreateLongHistogram( + nostd::unique_ptr> CreateUInt64Histogram( nostd::string_view name, nostd::string_view description = "", nostd::string_view unit = "") noexcept override; - nostd::shared_ptr> CreateDoubleHistogram( + nostd::unique_ptr> CreateDoubleHistogram( nostd::string_view name, nostd::string_view description = "", nostd::string_view unit = "") noexcept override; - nostd::shared_ptr CreateLongObservableGauge( + nostd::shared_ptr CreateInt64ObservableGauge( nostd::string_view name, nostd::string_view description = "", nostd::string_view unit = "") noexcept override; @@ -75,20 +77,20 @@ class Meter final : public opentelemetry::metrics::Meter nostd::string_view description = "", nostd::string_view unit = "") noexcept override; - nostd::shared_ptr> CreateLongUpDownCounter( + nostd::unique_ptr> CreateInt64UpDownCounter( nostd::string_view name, nostd::string_view description = "", nostd::string_view unit = "") noexcept override; - nostd::shared_ptr> CreateDoubleUpDownCounter( + nostd::unique_ptr> CreateDoubleUpDownCounter( nostd::string_view name, nostd::string_view description = "", nostd::string_view unit = "") noexcept override; - nostd::shared_ptr CreateLongObservableUpDownCounter( - nostd::string_view name, - nostd::string_view description = "", - nostd::string_view unit = "") noexcept override; + nostd::shared_ptr + CreateInt64ObservableUpDownCounter(nostd::string_view name, + nostd::string_view description = "", + nostd::string_view unit = "") noexcept override; nostd::shared_ptr CreateDoubleObservableUpDownCounter(nostd::string_view name, @@ -120,6 +122,24 @@ class Meter final : public opentelemetry::metrics::Meter InstrumentDescriptor &instrument_descriptor); std::unique_ptr RegisterAsyncMetricStorage( InstrumentDescriptor &instrument_descriptor); + opentelemetry::common::SpinLockMutex storage_lock_; + const InstrumentMetaDataValidator instrument_metadata_validator; + + static nostd::shared_ptr + GetNoopObservableInsrument() + { + static nostd::shared_ptr noop_instrument( + new opentelemetry::metrics::NoopObservableInstrument("", "", "")); + return noop_instrument; + } + static bool ValidateInstrument(nostd::string_view name, + nostd::string_view description, + nostd::string_view unit) + { + const static InstrumentMetaDataValidator instrument_validator; + return instrument_validator.ValidateName(name) && instrument_validator.ValidateUnit(unit) && + instrument_validator.ValidateDescription(description); + } }; } // namespace metrics } // namespace sdk diff --git a/sdk/include/opentelemetry/sdk/metrics/meter_context.h b/sdk/include/opentelemetry/sdk/metrics/meter_context.h index e35700175d..8af3c22eea 100644 --- a/sdk/include/opentelemetry/sdk/metrics/meter_context.h +++ b/sdk/include/opentelemetry/sdk/metrics/meter_context.h @@ -82,7 +82,7 @@ class MeterContext : public std::enable_shared_from_this * Note: This reader may not receive any in-flight meter data, but will get newly created meter * data. Note: This method is not thread safe, and should ideally be called from main thread. */ - void AddMetricReader(std::unique_ptr reader) noexcept; + void AddMetricReader(std::shared_ptr reader) noexcept; /** * Attaches a View to list of configured Views for this Meter context. @@ -125,6 +125,7 @@ class MeterContext : public std::enable_shared_from_this std::atomic_flag shutdown_latch_ = ATOMIC_FLAG_INIT; opentelemetry::common::SpinLockMutex forceflush_lock_; + opentelemetry::common::SpinLockMutex storage_lock_; }; } // namespace metrics diff --git a/sdk/include/opentelemetry/sdk/metrics/meter_provider.h b/sdk/include/opentelemetry/sdk/metrics/meter_provider.h index 685f43e747..8b41106bec 100644 --- a/sdk/include/opentelemetry/sdk/metrics/meter_provider.h +++ b/sdk/include/opentelemetry/sdk/metrics/meter_provider.h @@ -61,7 +61,7 @@ class MeterProvider final : public opentelemetry::metrics::MeterProvider * Note: This reader may not receive any in-flight meter data, but will get newly created meter * data. Note: This method is not thread safe, and should ideally be called from main thread. */ - void AddMetricReader(std::unique_ptr reader) noexcept; + void AddMetricReader(std::shared_ptr reader) noexcept; /** * Attaches a View to list of configured Views for this Meter provider. @@ -85,6 +85,8 @@ class MeterProvider final : public opentelemetry::metrics::MeterProvider */ bool ForceFlush(std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept; + ~MeterProvider() override; + private: std::shared_ptr context_; std::mutex lock_; diff --git a/sdk/include/opentelemetry/sdk/metrics/observer_result.h b/sdk/include/opentelemetry/sdk/metrics/observer_result.h index a8d3561f2e..e4f2a4887e 100644 --- a/sdk/include/opentelemetry/sdk/metrics/observer_result.h +++ b/sdk/include/opentelemetry/sdk/metrics/observer_result.h @@ -23,7 +23,7 @@ class ObserverResultT final : public opentelemetry::metrics::ObserverResultT : attributes_processor_(attributes_processor) {} - virtual ~ObserverResultT() = default; + ~ObserverResultT() override = default; void Observe(T value) noexcept override { data_.insert({{}, value}); } diff --git a/sdk/include/opentelemetry/sdk/metrics/metric_exporter.h b/sdk/include/opentelemetry/sdk/metrics/push_metric_exporter.h similarity index 91% rename from sdk/include/opentelemetry/sdk/metrics/metric_exporter.h rename to sdk/include/opentelemetry/sdk/metrics/push_metric_exporter.h index ec7831a32a..5c5b85931f 100644 --- a/sdk/include/opentelemetry/sdk/metrics/metric_exporter.h +++ b/sdk/include/opentelemetry/sdk/metrics/push_metric_exporter.h @@ -20,13 +20,13 @@ namespace metrics class MetricData; /** - * MetricExporter defines the interface to be used by metrics libraries to + * PushMetricExporter defines the interface to be used by metrics libraries to * push metrics data to the OpenTelemetry exporters. */ -class MetricExporter +class PushMetricExporter { public: - virtual ~MetricExporter() = default; + virtual ~PushMetricExporter() = default; /** * Exports a batch of metrics data. This method must not be called 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 b23443595b..82b5d385db 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/async_metric_storage.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/async_metric_storage.h @@ -28,7 +28,7 @@ class AsyncMetricStorage : public MetricStorage, public AsyncWritableMetricStora AsyncMetricStorage(InstrumentDescriptor instrument_descriptor, const AggregationType aggregation_type, const AttributesProcessor *attributes_processor, - nostd::shared_ptr aggregation_config, + const AggregationConfig *aggregation_config, void *state = nullptr) : instrument_descriptor_(instrument_descriptor), aggregation_type_{aggregation_type}, @@ -43,7 +43,10 @@ class AsyncMetricStorage : public MetricStorage, public AsyncWritableMetricStora void Record(const std::unordered_map &measurements, opentelemetry::common::SystemTimestamp /* observation_time */) noexcept { - // process the read measurements - aggregate and store in hashmap + // Async counter always record monotonically increasing values, and the + // exporter/reader can request either for delta or cumulative value. + // So we convert the async counter value to delta before passing it to temporal storage. + std::lock_guard guard(hashmap_lock_); for (auto &measurement : measurements) { auto aggr = DefaultAggregation::CreateAggregation(aggregation_type_, instrument_descriptor_); @@ -52,13 +55,14 @@ class AsyncMetricStorage : public MetricStorage, public AsyncWritableMetricStora if (prev) { auto delta = prev->Diff(*aggr); - cumulative_hash_map_->Set(measurement.first, - DefaultAggregation::CloneAggregation( - aggregation_type_, instrument_descriptor_, *delta)); + // 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)); 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)); @@ -68,14 +72,14 @@ class AsyncMetricStorage : public MetricStorage, public AsyncWritableMetricStora } void RecordLong( - const std::unordered_map &measurements, + const std::unordered_map &measurements, opentelemetry::common::SystemTimestamp observation_time) noexcept override { if (instrument_descriptor_.value_type_ != InstrumentValueType::kLong) { return; } - Record(measurements, observation_time); + Record(measurements, observation_time); } void RecordDouble( @@ -96,10 +100,16 @@ class AsyncMetricStorage : public MetricStorage, public AsyncWritableMetricStora nostd::function_ref metric_collection_callback) noexcept override { - auto status = temporal_metric_storage_.buildMetrics(collector, collectors, sdk_start_ts, - collection_ts, std::move(delta_hash_map_), - metric_collection_callback); - delta_hash_map_.reset(new AttributesHashMap()); + std::shared_ptr delta_metrics = nullptr; + { + std::lock_guard guard(hashmap_lock_); + delta_metrics = std::move(delta_hash_map_); + delta_hash_map_.reset(new AttributesHashMap); + } + + auto status = + temporal_metric_storage_.buildMetrics(collector, collectors, sdk_start_ts, collection_ts, + delta_metrics, metric_collection_callback); return status; } @@ -110,6 +120,7 @@ class AsyncMetricStorage : public MetricStorage, public AsyncWritableMetricStora void *state_; std::unique_ptr cumulative_hash_map_; std::unique_ptr delta_hash_map_; + opentelemetry::common::SpinLockMutex hashmap_lock_; TemporalMetricStorage temporal_metric_storage_; }; diff --git a/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h b/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h index be86c96826..2f93b32f66 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h @@ -3,7 +3,6 @@ #pragma once #ifndef ENABLE_METRICS_PREVIEW -# include "opentelemetry/common/spin_lock_mutex.h" # include "opentelemetry/nostd/function_ref.h" # include "opentelemetry/sdk/common/attribute_utils.h" # include "opentelemetry/sdk/common/attributemap_hash.h" @@ -13,7 +12,6 @@ # include # include -# include # include OPENTELEMETRY_BEGIN_NAMESPACE @@ -37,7 +35,6 @@ class AttributesHashMap public: Aggregation *Get(const MetricAttributes &attributes) const { - std::lock_guard guard(lock_); auto it = hash_map_.find(attributes); if (it != hash_map_.end()) { @@ -52,7 +49,6 @@ class AttributesHashMap */ bool Has(const MetricAttributes &attributes) const { - std::lock_guard guard(lock_); return (hash_map_.find(attributes) == hash_map_.end()) ? false : true; } @@ -64,8 +60,6 @@ class AttributesHashMap Aggregation *GetOrSetDefault(const MetricAttributes &attributes, std::function()> aggregation_callback) { - std::lock_guard guard(lock_); - auto it = hash_map_.find(attributes); if (it != hash_map_.end()) { @@ -81,7 +75,6 @@ class AttributesHashMap */ void Set(const MetricAttributes &attributes, std::unique_ptr value) { - std::lock_guard guard(lock_); hash_map_[attributes] = std::move(value); } @@ -91,7 +84,6 @@ class AttributesHashMap bool GetAllEnteries( nostd::function_ref callback) const { - std::lock_guard guard(lock_); for (auto &kv : hash_map_) { if (!callback(kv.first, *(kv.second.get()))) @@ -105,17 +97,11 @@ class AttributesHashMap /** * Return the size of hash. */ - size_t Size() - { - std::lock_guard guard(lock_); - return hash_map_.size(); - } + size_t Size() { return hash_map_.size(); } private: std::unordered_map, AttributeHashGenerator> hash_map_; - - mutable opentelemetry::common::SpinLockMutex lock_; }; } // namespace metrics diff --git a/sdk/include/opentelemetry/sdk/metrics/state/metric_collector.h b/sdk/include/opentelemetry/sdk/metrics/state/metric_collector.h index e466fa6a4f..5164aafe59 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/metric_collector.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/metric_collector.h @@ -18,6 +18,9 @@ class MeterContext; class CollectorHandle { public: + CollectorHandle() = default; + virtual ~CollectorHandle() = default; + virtual AggregationTemporality GetAggregationTemporality( InstrumentType instrument_type) noexcept = 0; }; @@ -31,9 +34,9 @@ class CollectorHandle class MetricCollector : public MetricProducer, public CollectorHandle { public: - MetricCollector(MeterContext *context, std::unique_ptr metric_reader); + MetricCollector(MeterContext *context, std::shared_ptr metric_reader); - virtual ~MetricCollector() = default; + ~MetricCollector() override = default; AggregationTemporality GetAggregationTemporality( InstrumentType instrument_type) noexcept override; diff --git a/sdk/include/opentelemetry/sdk/metrics/state/metric_storage.h b/sdk/include/opentelemetry/sdk/metrics/state/metric_storage.h index 7e57b43ac8..b85854358e 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/metric_storage.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/metric_storage.h @@ -22,6 +22,9 @@ class CollectorHandle; class MetricStorage { public: + MetricStorage() = default; + virtual ~MetricStorage() = default; + /* collect the metrics from this storage */ virtual bool Collect(CollectorHandle *collector, nostd::span> collectors, @@ -34,9 +37,10 @@ class MetricStorage class SyncWritableMetricStorage { public: - virtual void RecordLong(long value, const opentelemetry::context::Context &context) noexcept = 0; + virtual void RecordLong(int64_t value, + const opentelemetry::context::Context &context) noexcept = 0; - virtual void RecordLong(long value, + virtual void RecordLong(int64_t value, const opentelemetry::common::KeyValueIterable &attributes, const opentelemetry::context::Context &context) noexcept = 0; @@ -59,7 +63,7 @@ class AsyncWritableMetricStorage /* Records a batch of measurements */ virtual void RecordLong( - const std::unordered_map &measurements, + const std::unordered_map &measurements, opentelemetry::common::SystemTimestamp observation_time) noexcept = 0; virtual void RecordDouble( @@ -84,9 +88,10 @@ class NoopMetricStorage : public MetricStorage class NoopWritableMetricStorage : public SyncWritableMetricStorage { public: - void RecordLong(long value, const opentelemetry::context::Context &context) noexcept override = 0; + void RecordLong(int64_t value, + const opentelemetry::context::Context &context) noexcept override = 0; - void RecordLong(long /* value */, + void RecordLong(int64_t /* value */, const opentelemetry::common::KeyValueIterable & /* attributes */, const opentelemetry::context::Context & /* context */) noexcept override {} @@ -104,9 +109,9 @@ class NoopWritableMetricStorage : public SyncWritableMetricStorage class NoopAsyncWritableMetricStorage : public AsyncWritableMetricStorage { public: - void RecordLong( - const std::unordered_map & /* measurements */, - opentelemetry::common::SystemTimestamp /* observation_time */) noexcept override + void RecordLong(const std::unordered_map + & /* measurements */, + opentelemetry::common::SystemTimestamp /* observation_time */) noexcept override {} void RecordDouble(const std::unordered_map diff --git a/sdk/include/opentelemetry/sdk/metrics/state/multi_metric_storage.h b/sdk/include/opentelemetry/sdk/metrics/state/multi_metric_storage.h index b3cae8694c..740261a0c2 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/multi_metric_storage.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/multi_metric_storage.h @@ -23,7 +23,7 @@ class SyncMultiMetricStorage : public SyncWritableMetricStorage storages_.push_back(storage); } - virtual void RecordLong(long value, + virtual void RecordLong(int64_t value, const opentelemetry::context::Context &context) noexcept override { for (auto &s : storages_) @@ -32,7 +32,7 @@ class SyncMultiMetricStorage : public SyncWritableMetricStorage } } - virtual void RecordLong(long value, + virtual void RecordLong(int64_t value, const opentelemetry::common::KeyValueIterable &attributes, const opentelemetry::context::Context &context) noexcept override { @@ -74,7 +74,7 @@ class AsyncMultiMetricStorage : public AsyncWritableMetricStorage } void RecordLong( - const std::unordered_map &measurements, + const std::unordered_map &measurements, opentelemetry::common::SystemTimestamp observation_time) noexcept override { for (auto &s : storages_) diff --git a/sdk/include/opentelemetry/sdk/metrics/state/observable_registry.h b/sdk/include/opentelemetry/sdk/metrics/state/observable_registry.h index 045b83c27b..bf76145f03 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/observable_registry.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/observable_registry.h @@ -45,4 +45,4 @@ class ObservableRegistry } // namespace metrics } // namespace sdk OPENTELEMETRY_END_NAMESPACE -#endif \ No newline at end of file +#endif 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 a9b0604f05..f6af1f036f 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/sync_metric_storage.h @@ -31,31 +31,37 @@ class SyncMetricStorage : public MetricStorage, public SyncWritableMetricStorage const AggregationType aggregation_type, const AttributesProcessor *attributes_processor, nostd::shared_ptr &&exemplar_reservoir, - nostd::shared_ptr aggregation_config) + const AggregationConfig *aggregation_config) : instrument_descriptor_(instrument_descriptor), aggregation_type_{aggregation_type}, attributes_hashmap_(new AttributesHashMap()), attributes_processor_{attributes_processor}, +# ifdef ENABLE_METRICS_EXEMPLAR_PREVIEW exemplar_reservoir_(exemplar_reservoir), +# endif temporal_metric_storage_(instrument_descriptor, aggregation_config) { - create_default_aggregation_ = [&]() -> std::unique_ptr { - return DefaultAggregation::CreateAggregation(aggregation_type_, instrument_descriptor_); + create_default_aggregation_ = [&, aggregation_config]() -> std::unique_ptr { + return DefaultAggregation::CreateAggregation(aggregation_type_, instrument_descriptor_, + aggregation_config); }; } - void RecordLong(long value, const opentelemetry::context::Context &context) noexcept override + void RecordLong(int64_t value, const opentelemetry::context::Context &context) noexcept override { if (instrument_descriptor_.value_type_ != InstrumentValueType::kLong) { return; } +# ifdef ENABLE_METRICS_EXEMPLAR_PREVIEW exemplar_reservoir_->OfferMeasurement(value, {}, context, std::chrono::system_clock::now()); +# endif + std::lock_guard guard(attribute_hashmap_lock_); attributes_hashmap_->GetOrSetDefault({}, create_default_aggregation_)->Aggregate(value); } - void RecordLong(long value, + void RecordLong(int64_t value, const opentelemetry::common::KeyValueIterable &attributes, const opentelemetry::context::Context &context) noexcept override { @@ -63,10 +69,12 @@ class SyncMetricStorage : public MetricStorage, public SyncWritableMetricStorage { return; } - +# ifdef ENABLE_METRICS_EXEMPLAR_PREVIEW exemplar_reservoir_->OfferMeasurement(value, attributes, context, std::chrono::system_clock::now()); +# endif auto attr = attributes_processor_->process(attributes); + std::lock_guard guard(attribute_hashmap_lock_); attributes_hashmap_->GetOrSetDefault(attr, create_default_aggregation_)->Aggregate(value); } @@ -76,7 +84,10 @@ class SyncMetricStorage : public MetricStorage, public SyncWritableMetricStorage { return; } +# ifdef ENABLE_METRICS_EXEMPLAR_PREVIEW exemplar_reservoir_->OfferMeasurement(value, {}, context, std::chrono::system_clock::now()); +# endif + std::lock_guard guard(attribute_hashmap_lock_); attributes_hashmap_->GetOrSetDefault({}, create_default_aggregation_)->Aggregate(value); } @@ -84,15 +95,20 @@ class SyncMetricStorage : public MetricStorage, public SyncWritableMetricStorage const opentelemetry::common::KeyValueIterable &attributes, const opentelemetry::context::Context &context) noexcept override { +# ifdef ENABLE_METRICS_EXEMPLAR_PREVIEW exemplar_reservoir_->OfferMeasurement(value, attributes, context, std::chrono::system_clock::now()); +# endif if (instrument_descriptor_.value_type_ != InstrumentValueType::kDouble) { return; } +# ifdef ENABLE_METRICS_EXEMPLAR_PREVIEW exemplar_reservoir_->OfferMeasurement(value, attributes, context, std::chrono::system_clock::now()); +# endif auto attr = attributes_processor_->process(attributes); + std::lock_guard guard(attribute_hashmap_lock_); attributes_hashmap_->GetOrSetDefault(attr, create_default_aggregation_)->Aggregate(value); } @@ -115,8 +131,11 @@ class SyncMetricStorage : public MetricStorage, public SyncWritableMetricStorage std::unordered_map last_reported_metrics_; const AttributesProcessor *attributes_processor_; std::function()> create_default_aggregation_; +# ifdef ENABLE_METRICS_EXEMPLAR_PREVIEW nostd::shared_ptr exemplar_reservoir_; +# endif TemporalMetricStorage temporal_metric_storage_; + opentelemetry::common::SpinLockMutex attribute_hashmap_lock_; }; } // namespace metrics diff --git a/sdk/include/opentelemetry/sdk/metrics/state/temporal_metric_storage.h b/sdk/include/opentelemetry/sdk/metrics/state/temporal_metric_storage.h index f8a0c36b0f..5cb556ae20 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/temporal_metric_storage.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/temporal_metric_storage.h @@ -26,7 +26,7 @@ class TemporalMetricStorage { public: TemporalMetricStorage(InstrumentDescriptor instrument_descriptor, - nostd::shared_ptr aggregation_config); + const AggregationConfig *aggregation_config); bool buildMetrics(CollectorHandle *collector, nostd::span> collectors, @@ -46,7 +46,7 @@ class TemporalMetricStorage // Lock while building metrics mutable opentelemetry::common::SpinLockMutex lock_; - const nostd::shared_ptr aggregation_config_; + const AggregationConfig *aggregation_config_; }; } // namespace metrics } // namespace sdk diff --git a/sdk/include/opentelemetry/sdk/metrics/sync_instruments.h b/sdk/include/opentelemetry/sdk/metrics/sync_instruments.h index 05dae8558f..8e2f420598 100644 --- a/sdk/include/opentelemetry/sdk/metrics/sync_instruments.h +++ b/sdk/include/opentelemetry/sdk/metrics/sync_instruments.h @@ -7,6 +7,8 @@ # include "opentelemetry/metrics/sync_instruments.h" # include "opentelemetry/nostd/string_view.h" # include "opentelemetry/sdk/metrics/instruments.h" +# include "opentelemetry/sdk/metrics/state/metric_storage.h" +# include "opentelemetry/sdk_config.h" # include "opentelemetry/sdk/instrumentationscope/instrumentation_scope.h" @@ -32,19 +34,61 @@ class Synchronous std::unique_ptr storage_; }; -class LongCounter : public Synchronous, public opentelemetry::metrics::Counter +template +class LongCounter : public Synchronous, public opentelemetry::metrics::Counter { public: LongCounter(InstrumentDescriptor instrument_descriptor, - std::unique_ptr storage); - - void Add(long value, const opentelemetry::common::KeyValueIterable &attributes) noexcept override; - void Add(long value, + std::unique_ptr storage) + : Synchronous(instrument_descriptor, std::move(storage)) + { + if (!storage_) + { + OTEL_INTERNAL_LOG_ERROR("[LongCounter::LongCounter] - Error during constructing LongCounter." + << "The metric storage is invalid" + << "No value will be added"); + } + } + + void Add(T value, const opentelemetry::common::KeyValueIterable &attributes) noexcept override + { + if (!storage_) + { + return; + } + auto context = opentelemetry::context::Context{}; + return storage_->RecordLong(value, attributes, context); + } + + void Add(T value, const opentelemetry::common::KeyValueIterable &attributes, - const opentelemetry::context::Context &context) noexcept override; - - void Add(long value) noexcept override; - void Add(long value, const opentelemetry::context::Context &context) noexcept override; + const opentelemetry::context::Context &context) noexcept override + { + if (!storage_) + { + return; + } + return storage_->RecordLong(value, attributes, context); + } + + void Add(T value) noexcept override + { + auto context = opentelemetry::context::Context{}; + if (!storage_) + { + return; + } + return storage_->RecordLong(value, context); + } + + void Add(T value, const opentelemetry::context::Context &context) noexcept override + { + if (!storage_) + { + return; + } + return storage_->RecordLong(value, context); + } }; class DoubleCounter : public Synchronous, public opentelemetry::metrics::Counter @@ -64,19 +108,20 @@ class DoubleCounter : public Synchronous, public opentelemetry::metrics::Counter void Add(double value, const opentelemetry::context::Context &context) noexcept override; }; -class LongUpDownCounter : public Synchronous, public opentelemetry::metrics::UpDownCounter +class LongUpDownCounter : public Synchronous, public opentelemetry::metrics::UpDownCounter { public: LongUpDownCounter(InstrumentDescriptor instrument_descriptor, std::unique_ptr storage); - void Add(long value, const opentelemetry::common::KeyValueIterable &attributes) noexcept override; - void Add(long value, + void Add(int64_t value, + const opentelemetry::common::KeyValueIterable &attributes) noexcept override; + void Add(int64_t value, const opentelemetry::common::KeyValueIterable &attributes, const opentelemetry::context::Context &context) noexcept override; - void Add(long value) noexcept override; - void Add(long value, const opentelemetry::context::Context &context) noexcept override; + void Add(int64_t value) noexcept override; + void Add(int64_t value, const opentelemetry::context::Context &context) noexcept override; }; class DoubleUpDownCounter : public Synchronous, public opentelemetry::metrics::UpDownCounter @@ -95,17 +140,48 @@ class DoubleUpDownCounter : public Synchronous, public opentelemetry::metrics::U void Add(double value, const opentelemetry::context::Context &context) noexcept override; }; -class LongHistogram : public Synchronous, public opentelemetry::metrics::Histogram +template +class LongHistogram : public Synchronous, public opentelemetry::metrics::Histogram { public: LongHistogram(InstrumentDescriptor instrument_descriptor, - std::unique_ptr storage); - - void Record(long value, + std::unique_ptr storage) + : Synchronous(instrument_descriptor, std::move(storage)) + { + if (!storage_) + { + OTEL_INTERNAL_LOG_ERROR( + "[LongHistogram::LongHistogram] - Error during constructing LongHistogram." + << "The metric storage is invalid" + << "No value will be added"); + } + } + + void Record(T value, const opentelemetry::common::KeyValueIterable &attributes, - const opentelemetry::context::Context &context) noexcept override; - - void Record(long value, const opentelemetry::context::Context &context) noexcept override; + const opentelemetry::context::Context &context) noexcept override + { + if (value < 0) + { + OTEL_INTERNAL_LOG_WARN( + "[LongHistogram::Record(value, attributes)] negative value provided to histogram Name:" + << instrument_descriptor_.name_ << " Value:" << value); + return; + } + return storage_->RecordLong(value, attributes, context); + } + + void Record(T value, const opentelemetry::context::Context &context) noexcept override + { + if (value < 0) + { + OTEL_INTERNAL_LOG_WARN( + "[LongHistogram::Record(value)] negative value provided to histogram Name:" + << instrument_descriptor_.name_ << " Value:" << value); + return; + } + return storage_->RecordLong(value, context); + } }; class DoubleHistogram : public Synchronous, public opentelemetry::metrics::Histogram @@ -124,4 +200,4 @@ class DoubleHistogram : public Synchronous, public opentelemetry::metrics::Histo } // namespace metrics } // namespace sdk OPENTELEMETRY_END_NAMESPACE -#endif \ No newline at end of file +#endif diff --git a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h index ebd22b79b4..d6d536454c 100644 --- a/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h +++ b/sdk/include/opentelemetry/sdk/metrics/view/attributes_processor.h @@ -77,4 +77,4 @@ class FilteringAttributesProcessor : public AttributesProcessor } // namespace metrics } // namespace sdk OPENTELEMETRY_END_NAMESPACE -#endif \ No newline at end of file +#endif diff --git a/sdk/include/opentelemetry/sdk/metrics/view/predicate.h b/sdk/include/opentelemetry/sdk/metrics/view/predicate.h index 2fe5fbf155..b60a338b7f 100644 --- a/sdk/include/opentelemetry/sdk/metrics/view/predicate.h +++ b/sdk/include/opentelemetry/sdk/metrics/view/predicate.h @@ -4,15 +4,9 @@ #pragma once #ifndef ENABLE_METRICS_PREVIEW # include -# if (__GNUC__ == 4 && (__GNUC_MINOR__ == 8 || __GNUC_MINOR__ == 9)) -# define HAVE_WORKING_REGEX 0 -# include "opentelemetry/sdk/common/global_log_handler.h" -# else -# include -# define HAVE_WORKING_REGEX 1 -# endif - +# include "opentelemetry/common/macros.h" # include "opentelemetry/nostd/string_view.h" +# include "opentelemetry/sdk/common/global_log_handler.h" OPENTELEMETRY_BEGIN_NAMESPACE namespace sdk diff --git a/sdk/include/opentelemetry/sdk/metrics/view/view.h b/sdk/include/opentelemetry/sdk/metrics/view/view.h index 733e309bb7..7f2ca0e2b2 100644 --- a/sdk/include/opentelemetry/sdk/metrics/view/view.h +++ b/sdk/include/opentelemetry/sdk/metrics/view/view.h @@ -26,7 +26,7 @@ class View View(const std::string &name, const std::string &description = "", AggregationType aggregation_type = AggregationType::kDefault, - std::shared_ptr aggregation_config = std::shared_ptr{}, + std::shared_ptr aggregation_config = nullptr, std::unique_ptr attributes_processor = std::unique_ptr( new opentelemetry::sdk::metrics::DefaultAttributesProcessor())) @@ -45,9 +45,9 @@ class View virtual AggregationType GetAggregationType() const noexcept { return aggregation_type_; } - virtual nostd::shared_ptr GetAggregationConfig() const noexcept + virtual AggregationConfig *GetAggregationConfig() const noexcept { - return aggregation_config_; + return aggregation_config_.get(); } virtual const opentelemetry::sdk::metrics::AttributesProcessor &GetAttributesProcessor() @@ -60,7 +60,7 @@ class View std::string name_; std::string description_; AggregationType aggregation_type_; - nostd::shared_ptr aggregation_config_; + std::shared_ptr aggregation_config_; std::unique_ptr attributes_processor_; }; } // namespace metrics diff --git a/sdk/include/opentelemetry/sdk/metrics/view/view_registry.h b/sdk/include/opentelemetry/sdk/metrics/view/view_registry.h index 41755d23bf..dedd154b1c 100644 --- a/sdk/include/opentelemetry/sdk/metrics/view/view_registry.h +++ b/sdk/include/opentelemetry/sdk/metrics/view/view_registry.h @@ -96,7 +96,7 @@ class ViewRegistry (selector->GetInstrumentType() == instrument_descriptor.type_); } }; -}; // namespace metrics +} // namespace metrics } // namespace sdk OPENTELEMETRY_END_NAMESPACE #endif diff --git a/sdk/include/opentelemetry/sdk/resource/resource_detector.h b/sdk/include/opentelemetry/sdk/resource/resource_detector.h index 5f9d904aff..6447a2660d 100644 --- a/sdk/include/opentelemetry/sdk/resource/resource_detector.h +++ b/sdk/include/opentelemetry/sdk/resource/resource_detector.h @@ -20,7 +20,9 @@ class Resource; class ResourceDetector { public: - virtual Resource Detect() = 0; + ResourceDetector() = default; + virtual ~ResourceDetector() = default; + virtual Resource Detect() = 0; }; /** @@ -35,4 +37,4 @@ class OTELResourceDetector : public ResourceDetector } // namespace resource } // namespace sdk -OPENTELEMETRY_END_NAMESPACE \ No newline at end of file +OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/include/opentelemetry/sdk/resource/semantic_conventions.h b/sdk/include/opentelemetry/sdk/resource/semantic_conventions.h index 48f51b00b2..a018e28422 100644 --- a/sdk/include/opentelemetry/sdk/resource/semantic_conventions.h +++ b/sdk/include/opentelemetry/sdk/resource/semantic_conventions.h @@ -23,15 +23,15 @@ namespace SemanticConventions /** * The URL of the OpenTelemetry schema for these keys and values. */ -static constexpr const char *SCHEMA_URL = "https://opentelemetry.io/schemas/1.13.0"; +static constexpr const char *SCHEMA_URL = "https://opentelemetry.io/schemas/1.14.0"; /** * Array of brand name and version separated by a space * *

Notes:

+ href="https://wicg.github.io/ua-client-hints/#interface">UA client hints API ({@code + navigator.userAgentData.brands}). */ static constexpr const char *BROWSER_BRANDS = "browser.brands"; @@ -40,18 +40,28 @@ static constexpr const char *BROWSER_BRANDS = "browser.brands"; * *

Notes:

  • This value is intended to be taken from the UA client hints API -(navigator.userAgentData.platform). If unavailable, the legacy {@code navigator.platform} API SHOULD +href="https://wicg.github.io/ua-client-hints/#interface">UA client hints API ({@code +navigator.userAgentData.platform}). If unavailable, the legacy {@code navigator.platform} API SHOULD NOT be used instead and this attribute SHOULD be left unset in order for the values to be consistent. The list of possible values is defined in the W3C User-Agent Client Hints specification. Note that some (but not all) of these values can overlap with values in the os.type and os.name attributes. However, for consistency, the values in the -{@code browser.platform} attribute should capture the exact value that the user agent provides.
  • -
+href="./os.md">{@code os.type} and {@code os.name} attributes. However, for consistency, the +values in the {@code browser.platform} attribute should capture the exact value that the user agent +provides. */ static constexpr const char *BROWSER_PLATFORM = "browser.platform"; +/** + * A boolean that is true if the browser is running on a mobile device + * + *

Notes: +

  • This value is intended to be taken from the UA client hints API ({@code + navigator.userAgentData.mobile}). If unavailable, this attribute SHOULD be left unset.
+ */ +static constexpr const char *BROWSER_MOBILE = "browser.mobile"; + /** * Full user-agent string provided by the browser * @@ -62,6 +72,15 @@ static constexpr const char *BROWSER_PLATFORM = "browser.platform"; */ static constexpr const char *BROWSER_USER_AGENT = "browser.user_agent"; +/** + * Preferred language of the user using the browser + * + *

Notes: +

  • This value is intended to be taken from the Navigator API {@code + navigator.language}.
+ */ +static constexpr const char *BROWSER_LANGUAGE = "browser.language"; + /** * Name of the cloud provider. */ diff --git a/sdk/include/opentelemetry/sdk/trace/batch_span_processor.h b/sdk/include/opentelemetry/sdk/trace/batch_span_processor.h index f3f26c984f..309d849bc7 100644 --- a/sdk/include/opentelemetry/sdk/trace/batch_span_processor.h +++ b/sdk/include/opentelemetry/sdk/trace/batch_span_processor.h @@ -85,7 +85,7 @@ class BatchSpanProcessor : public SpanProcessor * shared ownership of the processor, and thus doesn't call Shutdown (as the processor might be * shared with other Tracers). */ - virtual ~BatchSpanProcessor(); + ~BatchSpanProcessor() override; protected: /** diff --git a/sdk/include/opentelemetry/sdk/trace/id_generator.h b/sdk/include/opentelemetry/sdk/trace/id_generator.h index da17effaeb..559870d961 100644 --- a/sdk/include/opentelemetry/sdk/trace/id_generator.h +++ b/sdk/include/opentelemetry/sdk/trace/id_generator.h @@ -28,4 +28,4 @@ class IdGenerator } // namespace trace } // namespace sdk -OPENTELEMETRY_END_NAMESPACE \ No newline at end of file +OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/include/opentelemetry/sdk/trace/multi_recordable.h b/sdk/include/opentelemetry/sdk/trace/multi_recordable.h index 3c485d8a3d..6abd39f90b 100644 --- a/sdk/include/opentelemetry/sdk/trace/multi_recordable.h +++ b/sdk/include/opentelemetry/sdk/trace/multi_recordable.h @@ -157,4 +157,4 @@ class MultiRecordable : public Recordable }; } // namespace trace } // namespace sdk -OPENTELEMETRY_END_NAMESPACE \ No newline at end of file +OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h b/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h index 8463ad5209..e3b4a2031e 100644 --- a/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h +++ b/sdk/include/opentelemetry/sdk/trace/multi_span_processor.h @@ -134,7 +134,7 @@ class MultiSpanProcessor : public SpanProcessor return result; } - ~MultiSpanProcessor() + ~MultiSpanProcessor() override { Shutdown(); Cleanup(); @@ -184,4 +184,4 @@ class MultiSpanProcessor : public SpanProcessor }; } // namespace trace } // namespace sdk -OPENTELEMETRY_END_NAMESPACE \ No newline at end of file +OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/include/opentelemetry/sdk/trace/random_id_generator.h b/sdk/include/opentelemetry/sdk/trace/random_id_generator.h index 908f1b8506..59df91651f 100644 --- a/sdk/include/opentelemetry/sdk/trace/random_id_generator.h +++ b/sdk/include/opentelemetry/sdk/trace/random_id_generator.h @@ -19,6 +19,5 @@ class RandomIdGenerator : public IdGenerator }; } // namespace trace - } // namespace sdk -OPENTELEMETRY_END_NAMESPACE \ No newline at end of file +OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/include/opentelemetry/sdk/trace/simple_processor.h b/sdk/include/opentelemetry/sdk/trace/simple_processor.h index bdb03868ac..09ab7b5c82 100644 --- a/sdk/include/opentelemetry/sdk/trace/simple_processor.h +++ b/sdk/include/opentelemetry/sdk/trace/simple_processor.h @@ -68,7 +68,7 @@ class SimpleSpanProcessor : public SpanProcessor return true; } - ~SimpleSpanProcessor() { Shutdown(); } + ~SimpleSpanProcessor() override { Shutdown(); } private: std::unique_ptr exporter_; diff --git a/sdk/include/opentelemetry/sdk/trace/tracer_provider.h b/sdk/include/opentelemetry/sdk/trace/tracer_provider.h index aa0f69a2ba..06088738c2 100644 --- a/sdk/include/opentelemetry/sdk/trace/tracer_provider.h +++ b/sdk/include/opentelemetry/sdk/trace/tracer_provider.h @@ -59,7 +59,7 @@ class TracerProvider final : public opentelemetry::trace::TracerProvider */ explicit TracerProvider(std::shared_ptr context) noexcept; - ~TracerProvider(); + ~TracerProvider() override; opentelemetry::nostd::shared_ptr GetTracer( nostd::string_view library_name, diff --git a/sdk/include/opentelemetry/sdk/version/version.h b/sdk/include/opentelemetry/sdk/version/version.h index 86176ba71f..bf89643dbf 100644 --- a/sdk/include/opentelemetry/sdk/version/version.h +++ b/sdk/include/opentelemetry/sdk/version/version.h @@ -5,7 +5,7 @@ #include "opentelemetry/detail/preprocessor.h" -#define OPENTELEMETRY_SDK_VERSION "1.6.1" +#define OPENTELEMETRY_SDK_VERSION "1.7.0" #include "opentelemetry/version.h" diff --git a/sdk/include/opentelemetry/sdk_config.h b/sdk/include/opentelemetry/sdk_config.h index 8ac72a10d5..280ccaa993 100644 --- a/sdk/include/opentelemetry/sdk_config.h +++ b/sdk/include/opentelemetry/sdk_config.h @@ -4,4 +4,4 @@ #pragma once #include "opentelemetry/config.h" -#include "opentelemetry/sdk/common/global_log_handler.h" \ No newline at end of file +#include "opentelemetry/sdk/common/global_log_handler.h" diff --git a/sdk/src/logs/batch_log_processor.cc b/sdk/src/logs/batch_log_processor.cc index ecba6d75bd..35092652cb 100644 --- a/sdk/src/logs/batch_log_processor.cc +++ b/sdk/src/logs/batch_log_processor.cc @@ -53,7 +53,7 @@ std::unique_ptr BatchLogProcessor::MakeRecordable() noexcept return exporter_->MakeRecordable(); } -void BatchLogProcessor::OnReceive(std::unique_ptr &&record) noexcept +void BatchLogProcessor::OnEmit(std::unique_ptr &&record) noexcept { if (synchronization_data_->is_shutdown.load() == true) { diff --git a/sdk/src/logs/logger.cc b/sdk/src/logs/logger.cc index f934107fae..d7ab485dff 100644 --- a/sdk/src/logs/logger.cc +++ b/sdk/src/logs/logger.cc @@ -111,7 +111,7 @@ void Logger::Log(opentelemetry::logs::Severity severity, } // Send the log record to the processor - processor.OnReceive(std::move(recordable)); + processor.OnEmit(std::move(recordable)); } const opentelemetry::sdk::instrumentationscope::InstrumentationScope & diff --git a/sdk/src/logs/multi_log_processor.cc b/sdk/src/logs/multi_log_processor.cc index 5c7fe400f9..f8de227806 100644 --- a/sdk/src/logs/multi_log_processor.cc +++ b/sdk/src/logs/multi_log_processor.cc @@ -48,7 +48,7 @@ std::unique_ptr MultiLogProcessor::MakeRecordable() noexcept return recordable; } -void MultiLogProcessor::OnReceive(std::unique_ptr &&record) noexcept +void MultiLogProcessor::OnEmit(std::unique_ptr &&record) noexcept { if (!record) { @@ -61,14 +61,14 @@ void MultiLogProcessor::OnReceive(std::unique_ptr &&record) noexcept auto recordable = multi_recordable->ReleaseRecordable(*processor); if (recordable) { - processor->OnReceive(std::move(recordable)); + processor->OnEmit(std::move(recordable)); } } } bool MultiLogProcessor::ForceFlush(std::chrono::microseconds timeout) noexcept { - // Converto nanos to prevent overflow + // Convert to nanos to prevent overflow std::chrono::nanoseconds timeout_ns = std::chrono::nanoseconds::max(); if (std::chrono::duration_cast(timeout_ns) > timeout) { diff --git a/sdk/src/logs/simple_log_processor.cc b/sdk/src/logs/simple_log_processor.cc index f5b82c0bbc..3d5d798c0a 100644 --- a/sdk/src/logs/simple_log_processor.cc +++ b/sdk/src/logs/simple_log_processor.cc @@ -29,7 +29,7 @@ std::unique_ptr SimpleLogProcessor::MakeRecordable() noexcept * Batches the log record it receives in a batch of 1 and immediately sends it * to the configured exporter */ -void SimpleLogProcessor::OnReceive(std::unique_ptr &&record) noexcept +void SimpleLogProcessor::OnEmit(std::unique_ptr &&record) noexcept { nostd::span> batch(&record, 1); // Get lock to ensure Export() is never called concurrently diff --git a/sdk/src/metrics/CMakeLists.txt b/sdk/src/metrics/CMakeLists.txt index dbbb465183..7f9214e324 100644 --- a/sdk/src/metrics/CMakeLists.txt +++ b/sdk/src/metrics/CMakeLists.txt @@ -5,6 +5,7 @@ add_library( meter.cc meter_context.cc metric_reader.cc + instrument_metadata_validator.cc export/periodic_exporting_metric_reader.cc state/metric_collector.cc state/observable_registry.cc @@ -13,6 +14,8 @@ add_library( aggregation/histogram_aggregation.cc aggregation/lastvalue_aggregation.cc aggregation/sum_aggregation.cc + exemplar/filter.cc + exemplar/reservoir.cc sync_instruments.cc) set_target_properties(opentelemetry_metrics PROPERTIES EXPORT_NAME metrics) diff --git a/sdk/src/metrics/aggregation/histogram_aggregation.cc b/sdk/src/metrics/aggregation/histogram_aggregation.cc index 5dcb277d6a..b8bbb190d3 100644 --- a/sdk/src/metrics/aggregation/histogram_aggregation.cc +++ b/sdk/src/metrics/aggregation/histogram_aggregation.cc @@ -6,6 +6,7 @@ # include # include # include +# include # include "opentelemetry/version.h" # include @@ -15,28 +16,29 @@ namespace sdk namespace metrics { -LongHistogramAggregation::LongHistogramAggregation( - const HistogramAggregationConfig *aggregation_config) +LongHistogramAggregation::LongHistogramAggregation(const AggregationConfig *aggregation_config) { - if (aggregation_config && aggregation_config->boundaries_.size()) + auto ac = static_cast(aggregation_config); + if (ac && ac->boundaries_.size()) { - point_data_.boundaries_ = aggregation_config->boundaries_; + point_data_.boundaries_ = ac->boundaries_; } else { - point_data_.boundaries_ = std::list{0l, 5l, 10l, 25l, 50l, 75l, 100l, 250l, 500l, 1000l}; + point_data_.boundaries_ = {0.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 250.0, + 500.0, 750.0, 1000.0, 2500.0, 5000.0, 7500.0, 10000.0}; } - if (aggregation_config) + + if (ac) { - record_min_max_ = aggregation_config->record_min_max_; + record_min_max_ = ac->record_min_max_; } - point_data_.counts_ = - std::vector(nostd::get>(point_data_.boundaries_).size() + 1, 0); - point_data_.sum_ = 0l; + point_data_.counts_ = std::vector(point_data_.boundaries_.size() + 1, 0); + point_data_.sum_ = (int64_t)0; point_data_.count_ = 0; point_data_.record_min_max_ = record_min_max_; - point_data_.min_ = std::numeric_limits::max(); - point_data_.max_ = std::numeric_limits::min(); + point_data_.min_ = std::numeric_limits::max(); + point_data_.max_ = std::numeric_limits::min(); } LongHistogramAggregation::LongHistogramAggregation(HistogramPointData &&data) @@ -47,20 +49,19 @@ LongHistogramAggregation::LongHistogramAggregation(const HistogramPointData &dat : point_data_{data}, record_min_max_{point_data_.record_min_max_} {} -void LongHistogramAggregation::Aggregate(long value, +void LongHistogramAggregation::Aggregate(int64_t value, const PointAttributes & /* attributes */) noexcept { const std::lock_guard locked(lock_); point_data_.count_ += 1; - point_data_.sum_ = nostd::get(point_data_.sum_) + value; + point_data_.sum_ = nostd::get(point_data_.sum_) + value; if (record_min_max_) { - point_data_.min_ = std::min(nostd::get(point_data_.min_), value); - point_data_.max_ = std::max(nostd::get(point_data_.max_), value); + point_data_.min_ = std::min(nostd::get(point_data_.min_), value); + point_data_.max_ = std::max(nostd::get(point_data_.max_), value); } size_t index = 0; - for (auto it = nostd::get>(point_data_.boundaries_).begin(); - it != nostd::get>(point_data_.boundaries_).end(); ++it) + for (auto it = point_data_.boundaries_.begin(); it != point_data_.boundaries_.end(); ++it) { if (value < *it) { @@ -78,7 +79,7 @@ std::unique_ptr LongHistogramAggregation::Merge( auto delta_value = nostd::get( (static_cast(delta).ToPoint())); LongHistogramAggregation *aggr = new LongHistogramAggregation(); - HistogramMerge(curr_value, delta_value, aggr->point_data_); + HistogramMerge(curr_value, delta_value, aggr->point_data_); return std::unique_ptr(aggr); } @@ -88,7 +89,7 @@ std::unique_ptr LongHistogramAggregation::Diff(const Aggregation &n auto next_value = nostd::get( (static_cast(next).ToPoint())); LongHistogramAggregation *aggr = new LongHistogramAggregation(); - HistogramDiff(curr_value, next_value, aggr->point_data_); + HistogramDiff(curr_value, next_value, aggr->point_data_); return std::unique_ptr(aggr); } @@ -98,24 +99,23 @@ PointType LongHistogramAggregation::ToPoint() const noexcept return point_data_; } -DoubleHistogramAggregation::DoubleHistogramAggregation( - const HistogramAggregationConfig *aggregation_config) +DoubleHistogramAggregation::DoubleHistogramAggregation(const AggregationConfig *aggregation_config) { - if (aggregation_config && aggregation_config->boundaries_.size()) + auto ac = static_cast(aggregation_config); + if (ac && ac->boundaries_.size()) { - point_data_.boundaries_ = aggregation_config->boundaries_; + point_data_.boundaries_ = ac->boundaries_; } else { point_data_.boundaries_ = std::list{0.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 250.0, 500.0, 1000.0}; } - if (aggregation_config) + if (ac) { - record_min_max_ = aggregation_config->record_min_max_; + record_min_max_ = ac->record_min_max_; } - point_data_.counts_ = - std::vector(nostd::get>(point_data_.boundaries_).size() + 1, 0); + point_data_.counts_ = std::vector(point_data_.boundaries_.size() + 1, 0); point_data_.sum_ = 0.0; point_data_.count_ = 0; point_data_.record_min_max_ = record_min_max_; @@ -143,8 +143,7 @@ void DoubleHistogramAggregation::Aggregate(double value, point_data_.max_ = std::max(nostd::get(point_data_.max_), value); } size_t index = 0; - for (auto it = nostd::get>(point_data_.boundaries_).begin(); - it != nostd::get>(point_data_.boundaries_).end(); ++it) + for (auto it = point_data_.boundaries_.begin(); it != point_data_.boundaries_.end(); ++it) { if (value < *it) { @@ -161,7 +160,12 @@ std::unique_ptr DoubleHistogramAggregation::Merge( auto curr_value = nostd::get(ToPoint()); auto delta_value = nostd::get( (static_cast(delta).ToPoint())); - DoubleHistogramAggregation *aggr = new DoubleHistogramAggregation(); + std::shared_ptr aggregation_config(new HistogramAggregationConfig); + static_cast(aggregation_config.get()) + ->boundaries_ = curr_value.boundaries_; + static_cast(aggregation_config.get()) + ->record_min_max_ = record_min_max_; + DoubleHistogramAggregation *aggr = new DoubleHistogramAggregation(aggregation_config.get()); HistogramMerge(curr_value, delta_value, aggr->point_data_); return std::unique_ptr(aggr); } diff --git a/sdk/src/metrics/aggregation/lastvalue_aggregation.cc b/sdk/src/metrics/aggregation/lastvalue_aggregation.cc index cbcce248a2..17ccbbd726 100644 --- a/sdk/src/metrics/aggregation/lastvalue_aggregation.cc +++ b/sdk/src/metrics/aggregation/lastvalue_aggregation.cc @@ -17,7 +17,7 @@ namespace metrics LongLastValueAggregation::LongLastValueAggregation() { point_data_.is_lastvalue_valid_ = false; - point_data_.value_ = 0l; + point_data_.value_ = (int64_t)0; } LongLastValueAggregation::LongLastValueAggregation(LastValuePointData &&data) @@ -28,12 +28,13 @@ LongLastValueAggregation::LongLastValueAggregation(const LastValuePointData &dat : point_data_{data} {} -void LongLastValueAggregation::Aggregate(long value, +void LongLastValueAggregation::Aggregate(int64_t value, const PointAttributes & /* attributes */) noexcept { const std::lock_guard locked(lock_); point_data_.is_lastvalue_valid_ = true; point_data_.value_ = value; + point_data_.sample_ts_ = std::chrono::system_clock::now(); } std::unique_ptr LongLastValueAggregation::Merge( @@ -93,6 +94,7 @@ void DoubleLastValueAggregation::Aggregate(double value, const std::lock_guard locked(lock_); point_data_.is_lastvalue_valid_ = true; point_data_.value_ = value; + point_data_.sample_ts_ = std::chrono::system_clock::now(); } std::unique_ptr DoubleLastValueAggregation::Merge( @@ -102,12 +104,12 @@ std::unique_ptr DoubleLastValueAggregation::Merge( nostd::get(delta.ToPoint()).sample_ts_.time_since_epoch()) { LastValuePointData merge_data = std::move(nostd::get(ToPoint())); - return std::unique_ptr(new LongLastValueAggregation(std::move(merge_data))); + return std::unique_ptr(new DoubleLastValueAggregation(std::move(merge_data))); } else { LastValuePointData merge_data = std::move(nostd::get(delta.ToPoint())); - return std::unique_ptr(new LongLastValueAggregation(std::move(merge_data))); + return std::unique_ptr(new DoubleLastValueAggregation(std::move(merge_data))); } } @@ -118,12 +120,12 @@ std::unique_ptr DoubleLastValueAggregation::Diff( nostd::get(next.ToPoint()).sample_ts_.time_since_epoch()) { LastValuePointData diff_data = std::move(nostd::get(ToPoint())); - return std::unique_ptr(new LongLastValueAggregation(std::move(diff_data))); + return std::unique_ptr(new DoubleLastValueAggregation(std::move(diff_data))); } else { LastValuePointData diff_data = std::move(nostd::get(next.ToPoint())); - return std::unique_ptr(new LongLastValueAggregation(std::move(diff_data))); + return std::unique_ptr(new DoubleLastValueAggregation(std::move(diff_data))); } } diff --git a/sdk/src/metrics/aggregation/sum_aggregation.cc b/sdk/src/metrics/aggregation/sum_aggregation.cc index 9a5b833eb2..eab53a49c2 100644 --- a/sdk/src/metrics/aggregation/sum_aggregation.cc +++ b/sdk/src/metrics/aggregation/sum_aggregation.cc @@ -3,6 +3,7 @@ #ifndef ENABLE_METRICS_PREVIEW # include "opentelemetry/sdk/metrics/aggregation/sum_aggregation.h" +# include "opentelemetry/sdk/common/global_log_handler.h" # include "opentelemetry/sdk/metrics/data/point_data.h" # include "opentelemetry/version.h" @@ -15,41 +16,50 @@ namespace sdk namespace metrics { -LongSumAggregation::LongSumAggregation() +LongSumAggregation::LongSumAggregation(bool is_monotonic) { - point_data_.value_ = 0l; + point_data_.value_ = (int64_t)0; + point_data_.is_monotonic_ = is_monotonic; } LongSumAggregation::LongSumAggregation(SumPointData &&data) : point_data_{std::move(data)} {} LongSumAggregation::LongSumAggregation(const SumPointData &data) : point_data_{data} {} -void LongSumAggregation::Aggregate(long value, const PointAttributes & /* attributes */) noexcept +void LongSumAggregation::Aggregate(int64_t value, const PointAttributes & /* attributes */) noexcept { + if (point_data_.is_monotonic_ && value < 0) + { + OTEL_INTERNAL_LOG_WARN( + " LongSumAggregation::Aggregate Negative value ignored for Monotonic increasing " + "measurement. Value" + << value); + return; + } const std::lock_guard locked(lock_); - point_data_.value_ = nostd::get(point_data_.value_) + value; + point_data_.value_ = nostd::get(point_data_.value_) + value; } std::unique_ptr LongSumAggregation::Merge(const Aggregation &delta) const noexcept { - long merge_value = - nostd::get( + int64_t merge_value = + nostd::get( nostd::get((static_cast(delta).ToPoint())) .value_) + - nostd::get(nostd::get(ToPoint()).value_); - std::unique_ptr aggr(new LongSumAggregation()); + nostd::get(nostd::get(ToPoint()).value_); + std::unique_ptr aggr(new LongSumAggregation(point_data_.is_monotonic_)); static_cast(aggr.get())->point_data_.value_ = merge_value; return aggr; } std::unique_ptr LongSumAggregation::Diff(const Aggregation &next) const noexcept { - - long diff_value = nostd::get(nostd::get( - (static_cast(next).ToPoint())) - .value_) - - nostd::get(nostd::get(ToPoint()).value_); - std::unique_ptr aggr(new LongSumAggregation()); + int64_t diff_value = + nostd::get( + nostd::get((static_cast(next).ToPoint())) + .value_) - + nostd::get(nostd::get(ToPoint()).value_); + std::unique_ptr aggr(new LongSumAggregation(point_data_.is_monotonic_)); static_cast(aggr.get())->point_data_.value_ = diff_value; return aggr; } @@ -60,9 +70,10 @@ PointType LongSumAggregation::ToPoint() const noexcept return point_data_; } -DoubleSumAggregation::DoubleSumAggregation() +DoubleSumAggregation::DoubleSumAggregation(bool is_monotonic) { - point_data_.value_ = 0.0; + point_data_.value_ = 0.0; + point_data_.is_monotonic_ = is_monotonic; } DoubleSumAggregation::DoubleSumAggregation(SumPointData &&data) : point_data_(std::move(data)) {} @@ -72,6 +83,14 @@ DoubleSumAggregation::DoubleSumAggregation(const SumPointData &data) : point_dat void DoubleSumAggregation::Aggregate(double value, const PointAttributes & /* attributes */) noexcept { + if (point_data_.is_monotonic_ && value < 0) + { + OTEL_INTERNAL_LOG_WARN( + " DoubleSumAggregation::Aggregate Negative value ignored for Monotonic increasing " + "measurement. Value" + << value); + return; + } const std::lock_guard locked(lock_); point_data_.value_ = nostd::get(point_data_.value_) + value; } @@ -83,20 +102,19 @@ std::unique_ptr DoubleSumAggregation::Merge(const Aggregation &delt nostd::get((static_cast(delta).ToPoint())) .value_) + nostd::get(nostd::get(ToPoint()).value_); - std::unique_ptr aggr(new DoubleSumAggregation()); + std::unique_ptr aggr(new DoubleSumAggregation(point_data_.is_monotonic_)); static_cast(aggr.get())->point_data_.value_ = merge_value; return aggr; } std::unique_ptr DoubleSumAggregation::Diff(const Aggregation &next) const noexcept { - double diff_value = nostd::get( nostd::get((static_cast(next).ToPoint())) .value_) - nostd::get(nostd::get(ToPoint()).value_); - std::unique_ptr aggr(new DoubleSumAggregation()); + std::unique_ptr aggr(new DoubleSumAggregation(point_data_.is_monotonic_)); static_cast(aggr.get())->point_data_.value_ = diff_value; return aggr; } diff --git a/sdk/src/metrics/exemplar/filter.cc b/sdk/src/metrics/exemplar/filter.cc new file mode 100644 index 0000000000..89d89b37a3 --- /dev/null +++ b/sdk/src/metrics/exemplar/filter.cc @@ -0,0 +1,37 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/metrics/exemplar/filter.h" +# include "opentelemetry/sdk/metrics/exemplar/always_sample_filter.h" +# include "opentelemetry/sdk/metrics/exemplar/never_sample_filter.h" +# include "opentelemetry/sdk/metrics/exemplar/with_trace_sample_filter.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ + +std::shared_ptr ExemplarFilter::GetNeverSampleFilter() noexcept +{ + static std::shared_ptr neverSampleFilter{new NeverSampleFilter{}}; + return neverSampleFilter; +} + +std::shared_ptr ExemplarFilter::GetAlwaysSampleFilter() noexcept +{ + static std::shared_ptr alwaysSampleFilter{new AlwaysSampleFilter{}}; + return alwaysSampleFilter; +} + +std::shared_ptr ExemplarFilter::GetWithTraceSampleFilter() noexcept +{ + std::shared_ptr withTraceSampleFilter{new WithTraceSampleFilter{}}; + return withTraceSampleFilter; +} + +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/sdk/src/metrics/exemplar/reservoir.cc b/sdk/src/metrics/exemplar/reservoir.cc new file mode 100644 index 0000000000..6209d91e80 --- /dev/null +++ b/sdk/src/metrics/exemplar/reservoir.cc @@ -0,0 +1,44 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/metrics/exemplar/reservoir.h" +# include +# include "opentelemetry/sdk/metrics/exemplar/filtered_exemplar_reservoir.h" +# include "opentelemetry/sdk/metrics/exemplar/fixed_size_exemplar_reservoir.h" +# include "opentelemetry/sdk/metrics/exemplar/histogram_exemplar_reservoir.h" +# include "opentelemetry/sdk/metrics/exemplar/no_exemplar_reservoir.h" +# include "opentelemetry/sdk/metrics/exemplar/reservoir_cell.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ + +nostd::shared_ptr ExemplarReservoir::GetFilteredExemplarReservoir( + std::shared_ptr filter, + std::shared_ptr reservoir) +{ + return nostd::shared_ptr{new FilteredExemplarReservoir{filter, reservoir}}; +} + +nostd::shared_ptr ExemplarReservoir::GetHistogramExemplarReservoir( + size_t size, + std::shared_ptr reservoir_cell_selector, + std::shared_ptr (ReservoirCell::*map_and_reset_cell)( + const common::OrderedAttributeMap &attributes)) +{ + return nostd::shared_ptr{ + new HistogramExemplarReservoir{size, reservoir_cell_selector, map_and_reset_cell}}; +} + +nostd::shared_ptr ExemplarReservoir::GetNoExemplarReservoir() +{ + return nostd::shared_ptr{new NoExemplarReservoir{}}; +} + +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/sdk/src/metrics/export/periodic_exporting_metric_reader.cc b/sdk/src/metrics/export/periodic_exporting_metric_reader.cc index 0174be87ec..eab145ecae 100644 --- a/sdk/src/metrics/export/periodic_exporting_metric_reader.cc +++ b/sdk/src/metrics/export/periodic_exporting_metric_reader.cc @@ -4,7 +4,7 @@ #ifndef ENABLE_METRICS_PREVIEW # include "opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader.h" # include "opentelemetry/sdk/common/global_log_handler.h" -# include "opentelemetry/sdk/metrics/metric_exporter.h" +# include "opentelemetry/sdk/metrics/push_metric_exporter.h" # include # include @@ -16,7 +16,7 @@ namespace metrics { PeriodicExportingMetricReader::PeriodicExportingMetricReader( - std::unique_ptr exporter, + std::unique_ptr exporter, const PeriodicExportingMetricReaderOptions &option) : exporter_{std::move(exporter)}, export_interval_millis_{option.export_interval_millis}, @@ -101,4 +101,4 @@ bool PeriodicExportingMetricReader::OnShutDown(std::chrono::microseconds timeout } // namespace metrics } // namespace sdk OPENTELEMETRY_END_NAMESPACE -#endif \ No newline at end of file +#endif diff --git a/sdk/src/metrics/instrument_metadata_validator.cc b/sdk/src/metrics/instrument_metadata_validator.cc new file mode 100644 index 0000000000..8dd0930e77 --- /dev/null +++ b/sdk/src/metrics/instrument_metadata_validator.cc @@ -0,0 +1,80 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/metrics/instrument_metadata_validator.h" +# include "opentelemetry/common/macros.h" +# include "opentelemetry/nostd/string_view.h" + +# include +# include + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ +// instrument-name = ALPHA 0*62 ("_" / "." / "-" / ALPHA / DIGIT) +const std::string kInstrumentNamePattern = "[a-zA-Z][-_.a-zA-Z0-9]{0,62}"; +// +const std::string kInstrumentUnitPattern = "[\x01-\x7F]{0,63}"; +// instrument-unit = It can have a maximum length of 63 ASCII chars + +InstrumentMetaDataValidator::InstrumentMetaDataValidator() +# if HAVE_WORKING_REGEX + // clang-format off + : name_reg_key_{kInstrumentNamePattern}, + unit_reg_key_{kInstrumentUnitPattern} +// clang-format on +# endif +{} + +bool InstrumentMetaDataValidator::ValidateName(nostd::string_view name) const +{ + +# if HAVE_WORKING_REGEX + return std::regex_match(name.data(), name_reg_key_); +# else + const size_t kMaxSize = 63; + // size atmost 63 chars + if (name.size() > kMaxSize) + { + return false; + } + // first char should be alpha + if (!isalpha(name[0])) + { + return false; + } + // subsequent chars should be either of alphabets, digits, underscore, minus, dot + return !std::any_of(std::next(name.begin()), name.end(), + [](char c) { return !isalnum(c) && c != '-' && c != '_' && c != '.'; }); +# endif +} + +bool InstrumentMetaDataValidator::ValidateUnit(nostd::string_view unit) const +{ +# if HAVE_WORKING_REGEX + return std::regex_match(unit.data(), unit_reg_key_); +# else + const size_t kMaxSize = 63; + // length atmost 63 chars + if (unit.size() > kMaxSize) + { + return false; + } + // all should be ascii chars. + return !std::any_of(unit.begin(), unit.end(), + [](char c) { return static_cast(c) > 127; }); +# endif +} + +bool InstrumentMetaDataValidator::ValidateDescription(nostd::string_view /*description*/) const +{ + return true; +} + +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/sdk/src/metrics/meter.cc b/sdk/src/metrics/meter.cc index 62f6eaf313..e5848e8619 100644 --- a/sdk/src/metrics/meter.cc +++ b/sdk/src/metrics/meter.cc @@ -3,14 +3,16 @@ #ifndef ENABLE_METRICS_PREVIEW # include "opentelemetry/sdk/metrics/meter.h" +# include # include "opentelemetry/metrics/noop.h" # include "opentelemetry/nostd/shared_ptr.h" # include "opentelemetry/sdk/metrics/async_instruments.h" -# include "opentelemetry/sdk/metrics/exemplar/no_exemplar_reservoir.h" +# include "opentelemetry/sdk/metrics/exemplar/histogram_exemplar_reservoir.h" # include "opentelemetry/sdk/metrics/state/multi_metric_storage.h" # include "opentelemetry/sdk/metrics/state/observable_registry.h" # include "opentelemetry/sdk/metrics/state/sync_metric_storage.h" +# include "opentelemetry/sdk/common/global_log_handler.h" # include "opentelemetry/sdk/metrics/sync_instruments.h" # include "opentelemetry/sdk_config.h" @@ -33,37 +35,61 @@ Meter::Meter( observable_registry_(new ObservableRegistry()) {} -nostd::shared_ptr> Meter::CreateLongCounter(nostd::string_view name, - nostd::string_view description, - nostd::string_view unit) noexcept +nostd::unique_ptr> Meter::CreateUInt64Counter( + nostd::string_view name, + nostd::string_view description, + nostd::string_view unit) noexcept { + if (!ValidateInstrument(name, description, unit)) + { + OTEL_INTERNAL_LOG_ERROR("Meter::CreateUInt64Counter - failed. Invalid parameters." + << name << " " << description << " " << unit + << ". Measurements won't be recorded."); + return nostd::unique_ptr>( + new metrics::NoopCounter(name, description, unit)); + } InstrumentDescriptor instrument_descriptor = { std::string{name.data(), name.size()}, std::string{description.data(), description.size()}, std::string{unit.data(), unit.size()}, InstrumentType::kCounter, InstrumentValueType::kLong}; auto storage = RegisterSyncMetricStorage(instrument_descriptor); - return nostd::shared_ptr>( - new LongCounter(instrument_descriptor, std::move(storage))); + return nostd::unique_ptr>( + new LongCounter(instrument_descriptor, std::move(storage))); } -nostd::shared_ptr> Meter::CreateDoubleCounter( +nostd::unique_ptr> Meter::CreateDoubleCounter( nostd::string_view name, nostd::string_view description, nostd::string_view unit) noexcept { + if (!ValidateInstrument(name, description, unit)) + { + OTEL_INTERNAL_LOG_ERROR("Meter::CreateDoubleCounter - failed. Invalid parameters." + << name << " " << description << " " << unit + << ". Measurements won't be recorded."); + return nostd::unique_ptr>( + new metrics::NoopCounter(name, description, unit)); + } InstrumentDescriptor instrument_descriptor = { std::string{name.data(), name.size()}, std::string{description.data(), description.size()}, std::string{unit.data(), unit.size()}, InstrumentType::kCounter, InstrumentValueType::kDouble}; auto storage = RegisterSyncMetricStorage(instrument_descriptor); - return nostd::shared_ptr>{ + return nostd::unique_ptr>{ new DoubleCounter(instrument_descriptor, std::move(storage))}; } -nostd::shared_ptr Meter::CreateLongObservableCounter( +nostd::shared_ptr Meter::CreateInt64ObservableCounter( nostd::string_view name, nostd::string_view description, nostd::string_view unit) noexcept { + if (!ValidateInstrument(name, description, unit)) + { + OTEL_INTERNAL_LOG_ERROR("Meter::CreateInt64ObservableCounter - failed. Invalid parameters." + << name << " " << description << " " << unit + << ". Measurements won't be recorded."); + return GetNoopObservableInsrument(); + } InstrumentDescriptor instrument_descriptor = { std::string{name.data(), name.size()}, std::string{description.data(), description.size()}, std::string{unit.data(), unit.size()}, InstrumentType::kObservableCounter, @@ -78,6 +104,13 @@ Meter::CreateDoubleObservableCounter(nostd::string_view name, nostd::string_view description, nostd::string_view unit) noexcept { + if (!ValidateInstrument(name, description, unit)) + { + OTEL_INTERNAL_LOG_ERROR("Meter::CreateDoubleObservableCounter - failed. Invalid parameters." + << name << " " << description << " " << unit + << ". Measurements won't be recorded."); + return GetNoopObservableInsrument(); + } InstrumentDescriptor instrument_descriptor = { std::string{name.data(), name.size()}, std::string{description.data(), description.size()}, std::string{unit.data(), unit.size()}, InstrumentType::kObservableCounter, @@ -87,39 +120,62 @@ Meter::CreateDoubleObservableCounter(nostd::string_view name, new ObservableInstrument(instrument_descriptor, std::move(storage), observable_registry_)}; } -nostd::shared_ptr> Meter::CreateLongHistogram( +nostd::unique_ptr> Meter::CreateUInt64Histogram( nostd::string_view name, nostd::string_view description, nostd::string_view unit) noexcept { + if (!ValidateInstrument(name, description, unit)) + { + OTEL_INTERNAL_LOG_ERROR("Meter::CreateUInt64Histogram - failed. Invalid parameters." + << name << " " << description << " " << unit + << ". Measurements won't be recorded."); + return nostd::unique_ptr>( + new metrics::NoopHistogram(name, description, unit)); + } InstrumentDescriptor instrument_descriptor = { std::string{name.data(), name.size()}, std::string{description.data(), description.size()}, std::string{unit.data(), unit.size()}, InstrumentType::kHistogram, InstrumentValueType::kLong}; auto storage = RegisterSyncMetricStorage(instrument_descriptor); - return nostd::shared_ptr>{ - new LongHistogram(instrument_descriptor, std::move(storage))}; + return nostd::unique_ptr>{ + new LongHistogram(instrument_descriptor, std::move(storage))}; } -nostd::shared_ptr> Meter::CreateDoubleHistogram( +nostd::unique_ptr> Meter::CreateDoubleHistogram( nostd::string_view name, nostd::string_view description, nostd::string_view unit) noexcept { + if (!ValidateInstrument(name, description, unit)) + { + OTEL_INTERNAL_LOG_ERROR("Meter::CreateDoubleHistogram - failed. Invalid parameters." + << name << " " << description << " " << unit + << ". Measurements won't be recorded."); + return nostd::unique_ptr>( + new metrics::NoopHistogram(name, description, unit)); + } InstrumentDescriptor instrument_descriptor = { std::string{name.data(), name.size()}, std::string{description.data(), description.size()}, std::string{unit.data(), unit.size()}, InstrumentType::kHistogram, InstrumentValueType::kDouble}; auto storage = RegisterSyncMetricStorage(instrument_descriptor); - return nostd::shared_ptr>{ + return nostd::unique_ptr>{ new DoubleHistogram(instrument_descriptor, std::move(storage))}; } -nostd::shared_ptr Meter::CreateLongObservableGauge( +nostd::shared_ptr Meter::CreateInt64ObservableGauge( nostd::string_view name, nostd::string_view description, nostd::string_view unit) noexcept { + if (!ValidateInstrument(name, description, unit)) + { + OTEL_INTERNAL_LOG_ERROR("Meter::CreateInt64ObservableGauge - failed. Invalid parameters." + << name << " " << description << " " << unit + << ". Measurements won't be recorded."); + return GetNoopObservableInsrument(); + } InstrumentDescriptor instrument_descriptor = { std::string{name.data(), name.size()}, std::string{description.data(), description.size()}, std::string{unit.data(), unit.size()}, InstrumentType::kObservableGauge, @@ -134,6 +190,13 @@ nostd::shared_ptr Meter::CreateDou nostd::string_view description, nostd::string_view unit) noexcept { + if (!ValidateInstrument(name, description, unit)) + { + OTEL_INTERNAL_LOG_ERROR("Meter::CreateDoubleObservableGauge - failed. Invalid parameters." + << name << " " << description << " " << unit + << ". Measurements won't be recorded."); + return GetNoopObservableInsrument(); + } InstrumentDescriptor instrument_descriptor = { std::string{name.data(), name.size()}, std::string{description.data(), description.size()}, std::string{unit.data(), unit.size()}, InstrumentType::kObservableGauge, @@ -143,39 +206,62 @@ nostd::shared_ptr Meter::CreateDou new ObservableInstrument(instrument_descriptor, std::move(storage), observable_registry_)}; } -nostd::shared_ptr> Meter::CreateLongUpDownCounter( +nostd::unique_ptr> Meter::CreateInt64UpDownCounter( nostd::string_view name, nostd::string_view description, nostd::string_view unit) noexcept { + if (!ValidateInstrument(name, description, unit)) + { + OTEL_INTERNAL_LOG_ERROR("Meter::CreateInt64UpDownCounter - failed. Invalid parameters." + << name << " " << description << " " << unit + << ". Measurements won't be recorded."); + return nostd::unique_ptr>( + new metrics::NoopUpDownCounter(name, description, unit)); + } InstrumentDescriptor instrument_descriptor = { std::string{name.data(), name.size()}, std::string{description.data(), description.size()}, std::string{unit.data(), unit.size()}, InstrumentType::kUpDownCounter, InstrumentValueType::kLong}; auto storage = RegisterSyncMetricStorage(instrument_descriptor); - return nostd::shared_ptr>{ + return nostd::unique_ptr>{ new LongUpDownCounter(instrument_descriptor, std::move(storage))}; } -nostd::shared_ptr> Meter::CreateDoubleUpDownCounter( +nostd::unique_ptr> Meter::CreateDoubleUpDownCounter( nostd::string_view name, nostd::string_view description, nostd::string_view unit) noexcept { + if (!ValidateInstrument(name, description, unit)) + { + OTEL_INTERNAL_LOG_ERROR("Meter::CreateDoubleUpDownCounter - failed. Invalid parameters." + << name << " " << description << " " << unit + << ". Measurements won't be recorded."); + return nostd::unique_ptr>( + new metrics::NoopUpDownCounter(name, description, unit)); + } InstrumentDescriptor instrument_descriptor = { std::string{name.data(), name.size()}, std::string{description.data(), description.size()}, std::string{unit.data(), unit.size()}, InstrumentType::kUpDownCounter, InstrumentValueType::kDouble}; auto storage = RegisterSyncMetricStorage(instrument_descriptor); - return nostd::shared_ptr>{ + return nostd::unique_ptr>{ new DoubleUpDownCounter(instrument_descriptor, std::move(storage))}; } nostd::shared_ptr -Meter::CreateLongObservableUpDownCounter(nostd::string_view name, - nostd::string_view description, - nostd::string_view unit) noexcept +Meter::CreateInt64ObservableUpDownCounter(nostd::string_view name, + nostd::string_view description, + nostd::string_view unit) noexcept { + if (!ValidateInstrument(name, description, unit)) + { + OTEL_INTERNAL_LOG_ERROR( + "Meter::CreateInt64ObservableUpDownCounter - failed. Invalid parameters -" + << name << " " << description << " " << unit << ". Measurements won't be recorded."); + return GetNoopObservableInsrument(); + } InstrumentDescriptor instrument_descriptor = { std::string{name.data(), name.size()}, std::string{description.data(), description.size()}, std::string{unit.data(), unit.size()}, InstrumentType::kObservableUpDownCounter, @@ -190,6 +276,13 @@ Meter::CreateDoubleObservableUpDownCounter(nostd::string_view name, nostd::string_view description, nostd::string_view unit) noexcept { + if (!ValidateInstrument(name, description, unit)) + { + OTEL_INTERNAL_LOG_ERROR( + "Meter::CreateDoubleObservableUpDownCounter - failed. Invalid parameters." + << name << " " << description << " " << unit << ". Measurements won't be recorded."); + return GetNoopObservableInsrument(); + } InstrumentDescriptor instrument_descriptor = { std::string{name.data(), name.size()}, std::string{description.data(), description.size()}, std::string{unit.data(), unit.size()}, InstrumentType::kObservableUpDownCounter, @@ -208,6 +301,7 @@ const sdk::instrumentationscope::InstrumentationScope *Meter::GetInstrumentation std::unique_ptr Meter::RegisterSyncMetricStorage( InstrumentDescriptor &instrument_descriptor) { + std::lock_guard guard(storage_lock_); auto ctx = meter_context_.lock(); if (!ctx) { @@ -233,7 +327,7 @@ std::unique_ptr Meter::RegisterSyncMetricStorage( auto storage = std::shared_ptr(new SyncMetricStorage( view_instr_desc, view.GetAggregationType(), &view.GetAttributesProcessor(), - NoExemplarReservoir::GetNoExemplarReservoir(), view.GetAggregationConfig())); + ExemplarReservoir::GetNoExemplarReservoir(), view.GetAggregationConfig())); storage_registry_[instrument_descriptor.name_] = storage; multi_storage->AddStorage(storage); return true; @@ -251,6 +345,7 @@ std::unique_ptr Meter::RegisterSyncMetricStorage( std::unique_ptr Meter::RegisterAsyncMetricStorage( InstrumentDescriptor &instrument_descriptor) { + std::lock_guard guard(storage_lock_); auto ctx = meter_context_.lock(); if (!ctx) { @@ -293,7 +388,6 @@ std::unique_ptr Meter::RegisterAsyncMetricStorage( std::vector Meter::Collect(CollectorHandle *collector, opentelemetry::common::SystemTimestamp collect_ts) noexcept { - observable_registry_->Observe(collect_ts); std::vector metric_data_list; auto ctx = meter_context_.lock(); @@ -303,6 +397,7 @@ std::vector Meter::Collect(CollectorHandle *collector, << "The metric context is invalid"); return std::vector{}; } + std::lock_guard guard(storage_lock_); for (auto &metric_storage : storage_registry_) { metric_storage.second->Collect(collector, ctx->GetCollectors(), ctx->GetSDKStartTime(), diff --git a/sdk/src/metrics/meter_context.cc b/sdk/src/metrics/meter_context.cc index 346b1dce29..581a6b1b93 100644 --- a/sdk/src/metrics/meter_context.cc +++ b/sdk/src/metrics/meter_context.cc @@ -31,6 +31,7 @@ ViewRegistry *MeterContext::GetViewRegistry() const noexcept nostd::span> MeterContext::GetMeters() noexcept { + std::lock_guard guard(storage_lock_); return nostd::span>{meters_}; } @@ -44,9 +45,9 @@ opentelemetry::common::SystemTimestamp MeterContext::GetSDKStartTime() noexcept return sdk_start_ts_; } -void MeterContext::AddMetricReader(std::unique_ptr reader) noexcept +void MeterContext::AddMetricReader(std::shared_ptr reader) noexcept { - auto collector = std::shared_ptr{new MetricCollector(this, std::move(reader))}; + auto collector = std::shared_ptr{new MetricCollector(this, reader)}; collectors_.push_back(collector); } @@ -59,12 +60,14 @@ void MeterContext::AddView(std::unique_ptr instrument_select void MeterContext::AddMeter(std::shared_ptr meter) { + std::lock_guard guard(storage_lock_); meters_.push_back(meter); } bool MeterContext::Shutdown() noexcept { bool result = true; + // Shutdown only once. if (!shutdown_latch_.test_and_set(std::memory_order_acquire)) { @@ -78,26 +81,64 @@ bool MeterContext::Shutdown() noexcept OTEL_INTERNAL_LOG_WARN("[MeterContext::Shutdown] Unable to shutdown all metric readers"); } } + else + { + OTEL_INTERNAL_LOG_WARN("[MeterContext::Shutdown] Shutdown can be invoked only once."); + } return result; } bool MeterContext::ForceFlush(std::chrono::microseconds timeout) noexcept { - // TODO - Implement timeout logic. bool result = true; - if (!shutdown_latch_.test_and_set(std::memory_order_acquire)) + // Simultaneous flush not allowed. + const std::lock_guard locked(forceflush_lock_); + // Convert to nanos to prevent overflow + auto timeout_ns = std::chrono::nanoseconds::max(); + if (std::chrono::duration_cast(timeout_ns) > timeout) { + timeout_ns = std::chrono::duration_cast(timeout); + } - for (auto &collector : collectors_) + auto current_time = std::chrono::system_clock::now(); + std::chrono::system_clock::time_point expire_time; + auto overflow_checker = std::chrono::system_clock::time_point::max(); + + // check if the expected expire time doesn't overflow. + if (overflow_checker - current_time > timeout_ns) + { + expire_time = + current_time + std::chrono::duration_cast(timeout_ns); + } + else + { + // overflow happens, reset expire time to max. + expire_time = overflow_checker; + } + + for (auto &collector : collectors_) + { + if (!std::static_pointer_cast(collector)->ForceFlush( + std::chrono::duration_cast(timeout_ns))) { - bool status = std::static_pointer_cast(collector)->ForceFlush(timeout); - result = result && status; + result = false; } - if (!result) + + current_time = std::chrono::system_clock::now(); + + if (expire_time >= current_time) + { + timeout_ns = std::chrono::duration_cast(expire_time - current_time); + } + else { - OTEL_INTERNAL_LOG_WARN("[MeterContext::ForceFlush] Unable to ForceFlush all metric readers"); + timeout_ns = std::chrono::nanoseconds::zero(); } } + if (!result) + { + OTEL_INTERNAL_LOG_WARN("[MeterContext::ForceFlush] Unable to ForceFlush all metric readers"); + } return result; } diff --git a/sdk/src/metrics/meter_provider.cc b/sdk/src/metrics/meter_provider.cc index 3a221b5db0..1114f73537 100644 --- a/sdk/src/metrics/meter_provider.cc +++ b/sdk/src/metrics/meter_provider.cc @@ -59,9 +59,9 @@ const resource::Resource &MeterProvider::GetResource() const noexcept return context_->GetResource(); } -void MeterProvider::AddMetricReader(std::unique_ptr reader) noexcept +void MeterProvider::AddMetricReader(std::shared_ptr reader) noexcept { - return context_->AddMetricReader(std::move(reader)); + return context_->AddMetricReader(reader); } void MeterProvider::AddView(std::unique_ptr instrument_selector, @@ -88,6 +88,18 @@ bool MeterProvider::ForceFlush(std::chrono::microseconds timeout) noexcept return context_->ForceFlush(timeout); } +/** + * Shutdown MeterContext when MeterProvider is destroyed. + * + */ +MeterProvider::~MeterProvider() +{ + if (context_) + { + context_->Shutdown(); + } +} + } // namespace metrics } // namespace sdk OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/src/metrics/state/metric_collector.cc b/sdk/src/metrics/state/metric_collector.cc index 97f29a8fbe..fd61b4f782 100644 --- a/sdk/src/metrics/state/metric_collector.cc +++ b/sdk/src/metrics/state/metric_collector.cc @@ -17,8 +17,8 @@ namespace metrics { MetricCollector::MetricCollector(opentelemetry::sdk::metrics::MeterContext *context, - std::unique_ptr metric_reader) - : meter_context_{context}, metric_reader_{std::move(metric_reader)} + std::shared_ptr metric_reader) + : meter_context_{context}, metric_reader_{metric_reader} { metric_reader_->SetMetricProducer(this); } diff --git a/sdk/src/metrics/state/observable_registry.cc b/sdk/src/metrics/state/observable_registry.cc index 0d6d770f87..215f202916 100644 --- a/sdk/src/metrics/state/observable_registry.cc +++ b/sdk/src/metrics/state/observable_registry.cc @@ -70,11 +70,11 @@ void ObservableRegistry::Observe(opentelemetry::common::SystemTimestamp collecti } else { - nostd::shared_ptr> ob_res( - new opentelemetry::sdk::metrics::ObserverResultT()); + nostd::shared_ptr> ob_res( + new opentelemetry::sdk::metrics::ObserverResultT()); callback_wrap->callback(ob_res, callback_wrap->state); storage->RecordLong( - static_cast *>(ob_res.get()) + static_cast *>(ob_res.get()) ->GetMeasurements(), collection_ts); } diff --git a/sdk/src/metrics/state/sync_metric_storage.cc b/sdk/src/metrics/state/sync_metric_storage.cc index eec68ed6d7..be753ca98f 100644 --- a/sdk/src/metrics/state/sync_metric_storage.cc +++ b/sdk/src/metrics/state/sync_metric_storage.cc @@ -20,8 +20,12 @@ bool SyncMetricStorage::Collect(CollectorHandle *collector, // Add the current delta metrics to `unreported metrics stash` for all the collectors, // this will also empty the delta metrics hashmap, and make it available for // recordings - std::shared_ptr delta_metrics = std::move(attributes_hashmap_); - attributes_hashmap_.reset(new AttributesHashMap); + std::shared_ptr delta_metrics = nullptr; + { + std::lock_guard guard(attribute_hashmap_lock_); + delta_metrics = std::move(attributes_hashmap_); + attributes_hashmap_.reset(new AttributesHashMap); + } return temporal_metric_storage_.buildMetrics(collector, collectors, sdk_start_ts, collection_ts, std::move(delta_metrics), callback); diff --git a/sdk/src/metrics/state/temporal_metric_storage.cc b/sdk/src/metrics/state/temporal_metric_storage.cc index 3c8f80695e..0cb84aa39b 100644 --- a/sdk/src/metrics/state/temporal_metric_storage.cc +++ b/sdk/src/metrics/state/temporal_metric_storage.cc @@ -17,9 +17,8 @@ namespace sdk namespace metrics { -TemporalMetricStorage::TemporalMetricStorage( - InstrumentDescriptor instrument_descriptor, - nostd::shared_ptr aggregation_config) +TemporalMetricStorage::TemporalMetricStorage(InstrumentDescriptor instrument_descriptor, + const AggregationConfig *aggregation_config) : instrument_descriptor_(instrument_descriptor), aggregation_config_(aggregation_config) {} @@ -34,6 +33,7 @@ bool TemporalMetricStorage::buildMetrics(CollectorHandle *collector, opentelemetry::common::SystemTimestamp last_collection_ts = sdk_start_ts; AggregationTemporality aggregation_temporarily = collector->GetAggregationTemporality(instrument_descriptor_.type_); + if (delta_metrics->Size()) { for (auto &col : collectors) @@ -66,7 +66,7 @@ bool TemporalMetricStorage::buildMetrics(CollectorHandle *collector, else { merged_metrics->Set(attributes, DefaultAggregation::CreateAggregation( - instrument_descriptor_, aggregation_config_.get()) + instrument_descriptor_, aggregation_config_) ->Merge(aggregation)); } return true; @@ -89,20 +89,21 @@ bool TemporalMetricStorage::buildMetrics(CollectorHandle *collector, if (aggregation_temporarily == AggregationTemporality::kCumulative) { // merge current delta to previous cumulative - last_aggr_hashmap->GetAllEnteries( - [&merged_metrics, this](const MetricAttributes &attributes, Aggregation &aggregation) { - auto agg = merged_metrics->Get(attributes); - if (agg) - { - merged_metrics->Set(attributes, agg->Merge(aggregation)); - } - else - { - auto def_agg = DefaultAggregation::CreateAggregation(instrument_descriptor_, nullptr); - merged_metrics->Set(attributes, def_agg->Merge(aggregation)); - } - return true; - }); + last_aggr_hashmap->GetAllEnteries([&merged_metrics, this](const MetricAttributes &attributes, + Aggregation &aggregation) { + auto agg = merged_metrics->Get(attributes); + if (agg) + { + merged_metrics->Set(attributes, agg->Merge(aggregation)); + } + else + { + auto def_agg = + DefaultAggregation::CreateAggregation(instrument_descriptor_, aggregation_config_); + merged_metrics->Set(attributes, def_agg->Merge(aggregation)); + } + return true; + }); } last_reported_metrics_[collector] = LastReportedMetrics{std::move(merged_metrics), collection_ts}; diff --git a/sdk/src/metrics/sync_instruments.cc b/sdk/src/metrics/sync_instruments.cc index 5db5d02251..a39e622d78 100644 --- a/sdk/src/metrics/sync_instruments.cc +++ b/sdk/src/metrics/sync_instruments.cc @@ -3,8 +3,6 @@ #ifndef ENABLE_METRICS_PREVIEW # include "opentelemetry/sdk/metrics/sync_instruments.h" -# include "opentelemetry/sdk/metrics/state/metric_storage.h" -# include "opentelemetry/sdk_config.h" # include @@ -13,59 +11,6 @@ namespace sdk { namespace metrics { -LongCounter::LongCounter(InstrumentDescriptor instrument_descriptor, - std::unique_ptr storage) - : Synchronous(instrument_descriptor, std::move(storage)) -{ - if (!storage_) - { - OTEL_INTERNAL_LOG_ERROR("[LongCounter::LongCounter] - Error during constructing LongCounter." - << "The metric storage is invalid" - << "No value will be added"); - } -} - -void LongCounter::Add(long value, - const opentelemetry::common::KeyValueIterable &attributes) noexcept -{ - if (!storage_) - { - return; - } - auto context = opentelemetry::context::Context{}; - return storage_->RecordLong(value, attributes, context); -} - -void LongCounter::Add(long value, - const opentelemetry::common::KeyValueIterable &attributes, - const opentelemetry::context::Context &context) noexcept -{ - if (!storage_) - { - return; - } - return storage_->RecordLong(value, attributes, context); -} - -void LongCounter::Add(long value) noexcept -{ - auto context = opentelemetry::context::Context{}; - if (!storage_) - { - return; - } - return storage_->RecordLong(value, context); -} - -void LongCounter::Add(long value, const opentelemetry::context::Context &context) noexcept -{ - if (!storage_) - { - return; - } - return storage_->RecordLong(value, context); -} - DoubleCounter::DoubleCounter(InstrumentDescriptor instrument_descriptor, std::unique_ptr storage) : Synchronous(instrument_descriptor, std::move(storage)) @@ -133,7 +78,7 @@ LongUpDownCounter::LongUpDownCounter(InstrumentDescriptor instrument_descriptor, } } -void LongUpDownCounter::Add(long value, +void LongUpDownCounter::Add(int64_t value, const opentelemetry::common::KeyValueIterable &attributes) noexcept { auto context = opentelemetry::context::Context{}; @@ -144,7 +89,7 @@ void LongUpDownCounter::Add(long value, return storage_->RecordLong(value, attributes, context); } -void LongUpDownCounter::Add(long value, +void LongUpDownCounter::Add(int64_t value, const opentelemetry::common::KeyValueIterable &attributes, const opentelemetry::context::Context &context) noexcept { @@ -155,7 +100,7 @@ void LongUpDownCounter::Add(long value, return storage_->RecordLong(value, attributes, context); } -void LongUpDownCounter::Add(long value) noexcept +void LongUpDownCounter::Add(int64_t value) noexcept { auto context = opentelemetry::context::Context{}; if (!storage_) @@ -165,7 +110,7 @@ void LongUpDownCounter::Add(long value) noexcept return storage_->RecordLong(value, context); } -void LongUpDownCounter::Add(long value, const opentelemetry::context::Context &context) noexcept +void LongUpDownCounter::Add(int64_t value, const opentelemetry::context::Context &context) noexcept { if (!storage_) { @@ -225,45 +170,6 @@ void DoubleUpDownCounter::Add(double value, const opentelemetry::context::Contex return storage_->RecordDouble(value, context); } -LongHistogram::LongHistogram(InstrumentDescriptor instrument_descriptor, - std::unique_ptr storage) - : Synchronous(instrument_descriptor, std::move(storage)) -{ - if (!storage_) - { - OTEL_INTERNAL_LOG_ERROR( - "[LongHistogram::LongHistogram] - Error during constructing LongHistogram." - << "The metric storage is invalid" - << "No value will be added"); - } -} - -void LongHistogram::Record(long value, - const opentelemetry::common::KeyValueIterable &attributes, - const opentelemetry::context::Context &context) noexcept -{ - if (value < 0) - { - OTEL_INTERNAL_LOG_WARN( - "[LongHistogram::Record(value, attributes)] negative value provided to histogram Name:" - << instrument_descriptor_.name_ << " Value:" << value); - return; - } - return storage_->RecordLong(value, attributes, context); -} - -void LongHistogram::Record(long value, const opentelemetry::context::Context &context) noexcept -{ - if (value < 0) - { - OTEL_INTERNAL_LOG_WARN( - "[LongHistogram::Record(value)] negative value provided to histogram Name:" - << instrument_descriptor_.name_ << " Value:" << value); - return; - } - return storage_->RecordLong(value, context); -} - DoubleHistogram::DoubleHistogram(InstrumentDescriptor instrument_descriptor, std::unique_ptr storage) : Synchronous(instrument_descriptor, std::move(storage)) diff --git a/sdk/src/trace/batch_span_processor_factory.cc b/sdk/src/trace/batch_span_processor_factory.cc index 18c3f955f5..b2b23857a1 100644 --- a/sdk/src/trace/batch_span_processor_factory.cc +++ b/sdk/src/trace/batch_span_processor_factory.cc @@ -16,7 +16,7 @@ std::unique_ptr BatchSpanProcessorFactory::Create( { std::unique_ptr processor(new BatchSpanProcessor(std::move(exporter), options)); return processor; -}; +} } // namespace trace } // namespace sdk diff --git a/sdk/src/trace/simple_processor_factory.cc b/sdk/src/trace/simple_processor_factory.cc index 92e7b4dbee..59e3ea92f1 100644 --- a/sdk/src/trace/simple_processor_factory.cc +++ b/sdk/src/trace/simple_processor_factory.cc @@ -14,7 +14,7 @@ std::unique_ptr SimpleSpanProcessorFactory::Create( { std::unique_ptr processor(new SimpleSpanProcessor(std::move(exporter))); return processor; -}; +} } // namespace trace } // namespace sdk diff --git a/sdk/src/version/version.cc b/sdk/src/version/version.cc index c4dff0cb56..b0c6531c8e 100644 --- a/sdk/src/version/version.cc +++ b/sdk/src/version/version.cc @@ -9,17 +9,17 @@ namespace sdk namespace version { const int MAJOR_VERSION = 1; -const int MINOR_VERSION = 6; -const int PATCH_VERSION = 1; +const int MINOR_VERSION = 7; +const int PATCH_VERSION = 0; const char *PRE_RELEASE = "NONE"; const char *BUILD_METADATA = "NONE"; -const int COUNT_NEW_COMMITS = 27; -const char *BRANCH = "pre_release_1.6.1"; -const char *COMMIT_HASH = "38012fab34faa50d5020959b68eba77ac485b508"; -const char *SHORT_VERSION = "1.6.1"; +const int COUNT_NEW_COMMITS = 35; +const char *BRANCH = "pre_release_1.7.0"; +const char *COMMIT_HASH = "dd7e257b6de71eeaf9e3149530962301705b9a0d"; +const char *SHORT_VERSION = "1.7.0"; const char *FULL_VERSION = - "1.6.0-NONE-NONE-27-pre_release_1.6.1-38012fab34faa50d5020959b68eba77ac485b508"; -const char *BUILD_DATE = "Thu Sep 22 18:05:21 UTC 2022"; + "1.7.0-NONE-NONE-35-pre_release_1.7.0-dd7e257b6de71eeaf9e3149530962301705b9a0d"; +const char *BUILD_DATE = "Fri 28 Oct 2022 06:22:43 PM UTC"; } // namespace version } // namespace sdk OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/test/common/attributemap_hash_test.cc b/sdk/test/common/attributemap_hash_test.cc index 7d2748670d..49e53361ba 100644 --- a/sdk/test/common/attributemap_hash_test.cc +++ b/sdk/test/common/attributemap_hash_test.cc @@ -29,4 +29,4 @@ TEST(AttributeMapHashTest, BasicTests) OrderedAttributeMap map1 = {}; EXPECT_TRUE(GetHashForAttributeMap(map1) == 0); } -} \ No newline at end of file +} diff --git a/sdk/test/common/random_test.cc b/sdk/test/common/random_test.cc index 35cfd4a1ee..8132b2d5a4 100644 --- a/sdk/test/common/random_test.cc +++ b/sdk/test/common/random_test.cc @@ -16,20 +16,21 @@ TEST(RandomTest, GenerateRandom64) TEST(RandomTest, GenerateRandomBuffer) { - uint8_t buf1[8] = {0}; - uint8_t buf2[8] = {0}; - Random::GenerateRandomBuffer(buf1); - Random::GenerateRandomBuffer(buf2); - EXPECT_FALSE(std::equal(std::begin(buf1), std::end(buf1), std::begin(buf2))); + uint8_t buf1_array[8] = {0}; + uint8_t buf2_array[8] = {0}; + Random::GenerateRandomBuffer(buf1_array); + Random::GenerateRandomBuffer(buf2_array); + EXPECT_FALSE(std::equal(std::begin(buf1_array), std::end(buf1_array), std::begin(buf2_array))); // Edge cases. for (auto size : {7, 8, 9, 16, 17}) { - std::vector buf1(size); - std::vector buf2(size); + std::vector buf1_vector(size); + std::vector buf2_vector(size); - Random::GenerateRandomBuffer(buf1); - Random::GenerateRandomBuffer(buf2); - EXPECT_FALSE(std::equal(std::begin(buf1), std::end(buf1), std::begin(buf2))); + Random::GenerateRandomBuffer(buf1_vector); + Random::GenerateRandomBuffer(buf2_vector); + EXPECT_FALSE( + std::equal(std::begin(buf1_vector), std::end(buf1_vector), std::begin(buf2_vector))); } } diff --git a/sdk/test/logs/batch_log_processor_test.cc b/sdk/test/logs/batch_log_processor_test.cc index 18e3ee531d..b6fb240ee5 100644 --- a/sdk/test/logs/batch_log_processor_test.cc +++ b/sdk/test/logs/batch_log_processor_test.cc @@ -111,7 +111,7 @@ TEST_F(BatchLogProcessorTest, TestShutdown) { auto log = batch_processor->MakeRecordable(); log->SetBody("Log" + std::to_string(i)); - batch_processor->OnReceive(std::move(log)); + batch_processor->OnEmit(std::move(log)); } // Test that shutting down the processor will first wait for the @@ -146,7 +146,7 @@ TEST_F(BatchLogProcessorTest, TestForceFlush) { auto log = batch_processor->MakeRecordable(); log->SetBody("Log" + std::to_string(i)); - batch_processor->OnReceive(std::move(log)); + batch_processor->OnEmit(std::move(log)); } EXPECT_TRUE(batch_processor->ForceFlush()); @@ -162,7 +162,7 @@ TEST_F(BatchLogProcessorTest, TestForceFlush) { auto log = batch_processor->MakeRecordable(); log->SetBody("Log" + std::to_string(i)); - batch_processor->OnReceive(std::move(log)); + batch_processor->OnEmit(std::move(log)); } EXPECT_TRUE(batch_processor->ForceFlush()); @@ -191,7 +191,7 @@ TEST_F(BatchLogProcessorTest, TestManyLogsLoss) { auto log = batch_processor->MakeRecordable(); log->SetBody("Log" + std::to_string(i)); - batch_processor->OnReceive(std::move(log)); + batch_processor->OnEmit(std::move(log)); } EXPECT_TRUE(batch_processor->ForceFlush()); @@ -215,7 +215,7 @@ TEST_F(BatchLogProcessorTest, TestManyLogsLossLess) { auto log = batch_processor->MakeRecordable(); log->SetBody("Log" + std::to_string(i)); - batch_processor->OnReceive(std::move(log)); + batch_processor->OnEmit(std::move(log)); } EXPECT_TRUE(batch_processor->ForceFlush()); @@ -248,7 +248,7 @@ TEST_F(BatchLogProcessorTest, TestScheduledDelayMillis) { auto log = batch_processor->MakeRecordable(); log->SetBody("Log" + std::to_string(i)); - batch_processor->OnReceive(std::move(log)); + batch_processor->OnEmit(std::move(log)); } // Sleep for scheduled_delay_millis milliseconds std::this_thread::sleep_for(scheduled_delay_millis); diff --git a/sdk/test/logs/logger_provider_sdk_test.cc b/sdk/test/logs/logger_provider_sdk_test.cc index 1488798f07..6bf738e812 100644 --- a/sdk/test/logs/logger_provider_sdk_test.cc +++ b/sdk/test/logs/logger_provider_sdk_test.cc @@ -86,7 +86,7 @@ class DummyProcessor : public LogProcessor return std::unique_ptr(new LogRecord); } - void OnReceive(std::unique_ptr && /* record */) noexcept override {} + void OnEmit(std::unique_ptr && /* record */) noexcept override {} bool ForceFlush(std::chrono::microseconds /* timeout */) noexcept override { return true; } bool Shutdown(std::chrono::microseconds /* timeout */) noexcept override { return true; } }; diff --git a/sdk/test/logs/logger_sdk_test.cc b/sdk/test/logs/logger_sdk_test.cc index 36278349ba..91279341c6 100644 --- a/sdk/test/logs/logger_sdk_test.cc +++ b/sdk/test/logs/logger_sdk_test.cc @@ -15,7 +15,7 @@ TEST(LoggerSDK, LogToNullProcessor) { // Confirm Logger::Log() does not have undefined behavior // even when there is no processor set - // since it calls Processor::OnReceive() + // since it calls Processor::OnEmit() auto lp = std::shared_ptr(new LoggerProvider()); const std::string schema_url{"https://opentelemetry.io/schemas/1.11.0"}; @@ -44,9 +44,10 @@ class MockProcessor final : public LogProcessor { return std::unique_ptr(new LogRecord); } - // OnReceive stores the record it receives into the shared_ptr recordable passed into its + + // OnEmit stores the record it receives into the shared_ptr recordable passed into its // constructor - void OnReceive(std::unique_ptr &&record) noexcept override + void OnEmit(std::unique_ptr &&record) noexcept override { // Cast the recordable received into a concrete LogRecord type auto copy = std::shared_ptr(static_cast(record.release())); diff --git a/sdk/test/logs/simple_log_processor_test.cc b/sdk/test/logs/simple_log_processor_test.cc index 1e77b2a858..008ca7c522 100644 --- a/sdk/test/logs/simple_log_processor_test.cc +++ b/sdk/test/logs/simple_log_processor_test.cc @@ -86,7 +86,7 @@ TEST(SimpleLogProcessorTest, SendReceivedLogsToExporter) { auto recordable = processor.MakeRecordable(); recordable->SetBody("Log Body"); - processor.OnReceive(std::move(recordable)); + processor.OnEmit(std::move(recordable)); // Verify that the batch of 1 log record sent by processor matches what exporter received EXPECT_EQ(1, batch_size_received); diff --git a/sdk/test/metrics/BUILD b/sdk/test/metrics/BUILD index 336fbc8b03..333670dc6f 100644 --- a/sdk/test/metrics/BUILD +++ b/sdk/test/metrics/BUILD @@ -1,5 +1,20 @@ load("//bazel:otel_cc_benchmark.bzl", "otel_cc_benchmark") +cc_test( + name = "meter_test", + srcs = [ + "meter_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//sdk/src/metrics", + "@com_google_googletest//:gtest_main", + ], +) + cc_test( name = "meter_provider_sdk_test", srcs = [ @@ -80,6 +95,22 @@ cc_test( ], ) +cc_test( + name = "sync_metric_storage_up_down_counter_test", + srcs = [ + "sync_metric_storage_up_down_counter_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//sdk/src/metrics", + "//sdk/src/resource", + "@com_google_googletest//:gtest_main", + ], +) + cc_test( name = "sync_metric_storage_histogram_test", srcs = [ @@ -112,6 +143,21 @@ cc_test( ], ) +cc_test( + name = "async_instruments_test", + srcs = [ + "async_instruments_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//sdk/src/metrics", + "@com_google_googletest//:gtest_main", + ], +) + cc_test( name = "async_metric_storage_test", srcs = [ diff --git a/sdk/test/metrics/CMakeLists.txt b/sdk/test/metrics/CMakeLists.txt index 75a3a0e559..3e5e8f488a 100644 --- a/sdk/test/metrics/CMakeLists.txt +++ b/sdk/test/metrics/CMakeLists.txt @@ -8,6 +8,7 @@ foreach( attributes_hashmap_test sync_metric_storage_counter_test sync_metric_storage_histogram_test + sync_metric_storage_up_down_counter_test async_metric_storage_test multi_metric_storage_test observer_result_test @@ -15,7 +16,8 @@ foreach( async_instruments_test metric_reader_test observable_registry_test - periodic_exporting_metric_reader_test) + periodic_exporting_metric_reader_test + instrument_metadata_validator_test) add_executable(${testname} "${testname}.cc") target_link_libraries( ${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} diff --git a/sdk/test/metrics/aggregation_test.cc b/sdk/test/metrics/aggregation_test.cc index c10ccae366..6e4121931c 100644 --- a/sdk/test/metrics/aggregation_test.cc +++ b/sdk/test/metrics/aggregation_test.cc @@ -14,21 +14,21 @@ using namespace opentelemetry::sdk::metrics; namespace nostd = opentelemetry::nostd; TEST(Aggregation, LongSumAggregation) { - LongSumAggregation aggr; + LongSumAggregation aggr(true); auto data = aggr.ToPoint(); ASSERT_TRUE(nostd::holds_alternative(data)); auto sum_data = nostd::get(data); - ASSERT_TRUE(nostd::holds_alternative(sum_data.value_)); - EXPECT_EQ(nostd::get(sum_data.value_), 0l); - aggr.Aggregate(12l, {}); - aggr.Aggregate(0l, {}); + ASSERT_TRUE(nostd::holds_alternative(sum_data.value_)); + EXPECT_EQ(nostd::get(sum_data.value_), 0); + aggr.Aggregate((int64_t)12, {}); + aggr.Aggregate((int64_t)0, {}); sum_data = nostd::get(aggr.ToPoint()); - EXPECT_EQ(nostd::get(sum_data.value_), 12l); + EXPECT_EQ(nostd::get(sum_data.value_), 12); } TEST(Aggregation, DoubleSumAggregation) { - DoubleSumAggregation aggr; + DoubleSumAggregation aggr(true); auto data = aggr.ToPoint(); ASSERT_TRUE(nostd::holds_alternative(data)); auto sum_data = nostd::get(data); @@ -46,12 +46,12 @@ TEST(Aggregation, LongLastValueAggregation) auto data = aggr.ToPoint(); ASSERT_TRUE(nostd::holds_alternative(data)); auto lastvalue_data = nostd::get(data); - ASSERT_TRUE(nostd::holds_alternative(lastvalue_data.value_)); + ASSERT_TRUE(nostd::holds_alternative(lastvalue_data.value_)); EXPECT_EQ(lastvalue_data.is_lastvalue_valid_, false); - aggr.Aggregate(12l, {}); - aggr.Aggregate(1l, {}); + aggr.Aggregate((int64_t)12, {}); + aggr.Aggregate((int64_t)1, {}); lastvalue_data = nostd::get(aggr.ToPoint()); - EXPECT_EQ(nostd::get(lastvalue_data.value_), 1.0); + EXPECT_EQ(nostd::get(lastvalue_data.value_), 1.0); } TEST(Aggregation, DoubleLastValueAggregation) @@ -74,40 +74,39 @@ TEST(Aggregation, LongHistogramAggregation) auto data = aggr.ToPoint(); ASSERT_TRUE(nostd::holds_alternative(data)); auto histogram_data = nostd::get(data); - ASSERT_TRUE(nostd::holds_alternative(histogram_data.sum_)); - ASSERT_TRUE(nostd::holds_alternative>(histogram_data.boundaries_)); - EXPECT_EQ(nostd::get(histogram_data.sum_), 0); + ASSERT_TRUE(nostd::holds_alternative(histogram_data.sum_)); + EXPECT_EQ(nostd::get(histogram_data.sum_), 0); EXPECT_EQ(histogram_data.count_, 0); - aggr.Aggregate(12l, {}); // lies in fourth bucket - aggr.Aggregate(100l, {}); // lies in eight bucket + aggr.Aggregate((int64_t)12, {}); // lies in fourth bucket + aggr.Aggregate((int64_t)100, {}); // lies in eight bucket histogram_data = nostd::get(aggr.ToPoint()); - EXPECT_EQ(nostd::get(histogram_data.min_), 12); - EXPECT_EQ(nostd::get(histogram_data.max_), 100); - EXPECT_EQ(nostd::get(histogram_data.sum_), 112); + EXPECT_EQ(nostd::get(histogram_data.min_), 12); + EXPECT_EQ(nostd::get(histogram_data.max_), 100); + EXPECT_EQ(nostd::get(histogram_data.sum_), 112); EXPECT_EQ(histogram_data.count_, 2); EXPECT_EQ(histogram_data.counts_[3], 1); EXPECT_EQ(histogram_data.counts_[7], 1); - aggr.Aggregate(13l, {}); // lies in fourth bucket - aggr.Aggregate(252l, {}); // lies in ninth bucket + aggr.Aggregate((int64_t)13, {}); // lies in fourth bucket + aggr.Aggregate((int64_t)252, {}); // lies in ninth bucket histogram_data = nostd::get(aggr.ToPoint()); EXPECT_EQ(histogram_data.count_, 4); EXPECT_EQ(histogram_data.counts_[3], 2); EXPECT_EQ(histogram_data.counts_[8], 1); - EXPECT_EQ(nostd::get(histogram_data.min_), 12); - EXPECT_EQ(nostd::get(histogram_data.max_), 252); + EXPECT_EQ(nostd::get(histogram_data.min_), 12); + EXPECT_EQ(nostd::get(histogram_data.max_), 252); // Merge LongHistogramAggregation aggr1; - aggr1.Aggregate(1l, {}); - aggr1.Aggregate(11l, {}); - aggr1.Aggregate(26l, {}); + aggr1.Aggregate((int64_t)1, {}); + aggr1.Aggregate((int64_t)11, {}); + aggr1.Aggregate((int64_t)26, {}); LongHistogramAggregation aggr2; - aggr2.Aggregate(2l, {}); - aggr2.Aggregate(3l, {}); - aggr2.Aggregate(13l, {}); - aggr2.Aggregate(28l, {}); - aggr2.Aggregate(105l, {}); + aggr2.Aggregate((int64_t)2, {}); + aggr2.Aggregate((int64_t)3, {}); + aggr2.Aggregate((int64_t)13, {}); + aggr2.Aggregate((int64_t)28, {}); + aggr2.Aggregate((int64_t)105, {}); auto aggr3 = aggr1.Merge(aggr2); histogram_data = nostd::get(aggr3->ToPoint()); @@ -117,8 +116,8 @@ TEST(Aggregation, LongHistogramAggregation) EXPECT_EQ(histogram_data.counts_[3], 2); // 11, 13 EXPECT_EQ(histogram_data.counts_[4], 2); // 25, 28 EXPECT_EQ(histogram_data.counts_[7], 1); // 105 - EXPECT_EQ(nostd::get(histogram_data.min_), 1); - EXPECT_EQ(nostd::get(histogram_data.max_), 105); + EXPECT_EQ(nostd::get(histogram_data.min_), 1); + EXPECT_EQ(nostd::get(histogram_data.max_), 105); // Diff auto aggr4 = aggr1.Diff(aggr2); @@ -132,22 +131,22 @@ TEST(Aggregation, LongHistogramAggregation) TEST(Aggregation, LongHistogramAggregationBoundaries) { - nostd::shared_ptr> - aggregation_config{new opentelemetry::sdk::metrics::HistogramAggregationConfig}; - std::list user_boundaries = {0, 50, 100, 250, 500, 750, 1000, 2500, 5000, 10000}; - aggregation_config->boundaries_ = user_boundaries; + std::shared_ptr aggregation_config{ + new opentelemetry::sdk::metrics::HistogramAggregationConfig}; + std::list user_boundaries = {0.0, 50.0, 100.0, 250.0, 500.0, + 750.0, 1000.0, 2500.0, 5000.0, 10000.0}; + aggregation_config->boundaries_ = user_boundaries; LongHistogramAggregation aggr{aggregation_config.get()}; auto data = aggr.ToPoint(); ASSERT_TRUE(nostd::holds_alternative(data)); auto histogram_data = nostd::get(data); - ASSERT_TRUE(nostd::holds_alternative>(histogram_data.boundaries_)); - EXPECT_EQ(nostd::get>(histogram_data.boundaries_), user_boundaries); + EXPECT_EQ(histogram_data.boundaries_, user_boundaries); } TEST(Aggregation, DoubleHistogramAggregationBoundaries) { - nostd::shared_ptr> - aggregation_config{new opentelemetry::sdk::metrics::HistogramAggregationConfig}; + std::shared_ptr aggregation_config{ + new opentelemetry::sdk::metrics::HistogramAggregationConfig}; std::list user_boundaries = {0.0, 50.0, 100.0, 250.0, 500.0, 750.0, 1000.0, 2500.0, 5000.0, 10000.0}; aggregation_config->boundaries_ = user_boundaries; @@ -155,8 +154,7 @@ TEST(Aggregation, DoubleHistogramAggregationBoundaries) auto data = aggr.ToPoint(); ASSERT_TRUE(nostd::holds_alternative(data)); auto histogram_data = nostd::get(data); - ASSERT_TRUE(nostd::holds_alternative>(histogram_data.boundaries_)); - EXPECT_EQ(nostd::get>(histogram_data.boundaries_), user_boundaries); + EXPECT_EQ(histogram_data.boundaries_, user_boundaries); } TEST(Aggregation, DoubleHistogramAggregation) @@ -166,7 +164,6 @@ TEST(Aggregation, DoubleHistogramAggregation) ASSERT_TRUE(nostd::holds_alternative(data)); auto histogram_data = nostd::get(data); ASSERT_TRUE(nostd::holds_alternative(histogram_data.sum_)); - ASSERT_TRUE(nostd::holds_alternative>(histogram_data.boundaries_)); EXPECT_EQ(nostd::get(histogram_data.sum_), 0); EXPECT_EQ(histogram_data.count_, 0); aggr.Aggregate(12.0, {}); // lies in fourth bucket diff --git a/sdk/test/metrics/async_metric_storage_test.cc b/sdk/test/metrics/async_metric_storage_test.cc index 02d2734ecf..fd4df4d7f8 100644 --- a/sdk/test/metrics/async_metric_storage_test.cc +++ b/sdk/test/metrics/async_metric_storage_test.cc @@ -1,15 +1,16 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#include #ifndef ENABLE_METRICS_PREVIEW -# include "opentelemetry/sdk/metrics/state/async_metric_storage.h" # include "opentelemetry/common/key_value_iterable_view.h" # include "opentelemetry/sdk/metrics/async_instruments.h" # include "opentelemetry/sdk/metrics/instruments.h" # include "opentelemetry/sdk/metrics/meter_context.h" -# include "opentelemetry/sdk/metrics/metric_exporter.h" # include "opentelemetry/sdk/metrics/metric_reader.h" # include "opentelemetry/sdk/metrics/observer_result.h" +# include "opentelemetry/sdk/metrics/push_metric_exporter.h" +# include "opentelemetry/sdk/metrics/state/async_metric_storage.h" # include "opentelemetry/sdk/metrics/state/metric_collector.h" # include "opentelemetry/sdk/metrics/state/observable_registry.h" @@ -31,7 +32,7 @@ class MockCollectorHandle : public CollectorHandle public: MockCollectorHandle(AggregationTemporality temp) : temporality(temp) {} - virtual ~MockCollectorHandle() = default; + ~MockCollectorHandle() override = default; AggregationTemporality GetAggregationTemporality( InstrumentType /* instrument_type */) noexcept override @@ -46,49 +47,12 @@ class MockCollectorHandle : public CollectorHandle class WritableMetricStorageTestFixture : public ::testing::TestWithParam {}; -class MeasurementFetcher -{ -public: - static void Fetcher(opentelemetry::metrics::ObserverResult observer_result, void * /*state*/) - { - fetch_count++; - if (fetch_count == 1) - { - opentelemetry::nostd::get<0>(observer_result)->Observe(20l, {{"RequestType", "GET"}}); - opentelemetry::nostd::get<0>(observer_result)->Observe(10l, {{"RequestType", "PUT"}}); - number_of_get += 20l; - number_of_put += 10l; - } - else if (fetch_count == 2) - { - opentelemetry::nostd::get<0>(observer_result)->Observe(40l, {{"RequestType", "GET"}}); - opentelemetry::nostd::get<0>(observer_result)->Observe(20l, {{"RequestType", "PUT"}}); - number_of_get += 40l; - number_of_put += 20l; - } - } - - static void init_values() - { - fetch_count = 0; - number_of_get = 0; - number_of_put = 0; - } - - static size_t fetch_count; - static long number_of_get; - static long number_of_put; - static const size_t number_of_attributes = 2; -}; - -size_t MeasurementFetcher::fetch_count; -long MeasurementFetcher::number_of_get; -long MeasurementFetcher::number_of_put; -const size_t MeasurementFetcher::number_of_attributes; +class WritableMetricStorageTestObservableGaugeFixture + : public ::testing::TestWithParam +{}; TEST_P(WritableMetricStorageTestFixture, TestAggregation) { - MeasurementFetcher::init_values(); AggregationTemporality temporality = GetParam(); InstrumentDescriptor instr_desc = {"name", "desc", "1unit", InstrumentType::kObservableCounter, @@ -105,38 +69,73 @@ TEST_P(WritableMetricStorageTestFixture, TestAggregation) std::unique_ptr default_attributes_processor{ new DefaultAttributesProcessor{}}; opentelemetry::sdk::metrics::AsyncMetricStorage storage( - instr_desc, AggregationType::kSum, default_attributes_processor.get(), - std::shared_ptr{}); - long get_count = 20l; - long put_count = 10l; - size_t attribute_count = 2; - std::unordered_map measurements = { - {{{"RequestType", "GET"}}, get_count}, {{{"RequestType", "PUT"}}, put_count}}; - storage.RecordLong(measurements, + instr_desc, AggregationType::kSum, default_attributes_processor.get(), nullptr); + int64_t get_count1 = 20; + int64_t put_count1 = 10; + std::unordered_map measurements1 = { + {{{"RequestType", "GET"}}, get_count1}, {{{"RequestType", "PUT"}}, put_count1}}; + storage.RecordLong(measurements1, opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now())); - storage.Collect(collector.get(), collectors, sdk_start_ts, collection_ts, - [&](const MetricData data) { - for (auto data_attr : data.point_data_attr_) - { - auto data = opentelemetry::nostd::get(data_attr.point_data); - if (opentelemetry::nostd::get( - data_attr.attributes.find("RequestType")->second) == "GET") - { - EXPECT_EQ(opentelemetry::nostd::get(data.value_), get_count); - } - else if (opentelemetry::nostd::get( - data_attr.attributes.find("RequestType")->second) == "PUT") - { - EXPECT_EQ(opentelemetry::nostd::get(data.value_), put_count); - } - } - return true; - }); + storage.Collect( + collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData &metric_data) { + for (const auto &data_attr : metric_data.point_data_attr_) + { + const auto &data = opentelemetry::nostd::get(data_attr.point_data); + if (opentelemetry::nostd::get( + data_attr.attributes.find("RequestType")->second) == "GET") + { + EXPECT_EQ(opentelemetry::nostd::get(data.value_), get_count1); + } + else if (opentelemetry::nostd::get( + data_attr.attributes.find("RequestType")->second) == "PUT") + { + EXPECT_EQ(opentelemetry::nostd::get(data.value_), put_count1); + } + } + return true; + }); // subsequent recording after collection shouldn't fail - storage.RecordLong(measurements, + // monotonic increasing values; + int64_t get_count2 = 50; + int64_t put_count2 = 70; + + std::unordered_map measurements2 = { + {{{"RequestType", "GET"}}, get_count2}, {{{"RequestType", "PUT"}}, put_count2}}; + storage.RecordLong(measurements2, opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now())); - EXPECT_EQ(MeasurementFetcher::number_of_attributes, attribute_count); + storage.Collect( + collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData &metric_data) { + for (const auto &data_attr : metric_data.point_data_attr_) + { + const auto &data = opentelemetry::nostd::get(data_attr.point_data); + if (opentelemetry::nostd::get( + data_attr.attributes.find("RequestType")->second) == "GET") + { + if (temporality == AggregationTemporality::kCumulative) + { + EXPECT_EQ(opentelemetry::nostd::get(data.value_), get_count2); + } + else + { + EXPECT_EQ(opentelemetry::nostd::get(data.value_), get_count2 - get_count1); + } + } + else if (opentelemetry::nostd::get( + data_attr.attributes.find("RequestType")->second) == "PUT") + { + if (temporality == AggregationTemporality::kCumulative) + { + EXPECT_EQ(opentelemetry::nostd::get(data.value_), put_count2); + } + else + { + EXPECT_EQ(opentelemetry::nostd::get(data.value_), put_count2 - put_count1); + } + } + } + return true; + }); } INSTANTIATE_TEST_SUITE_P(WritableMetricStorageTestLong, @@ -144,4 +143,81 @@ INSTANTIATE_TEST_SUITE_P(WritableMetricStorageTestLong, ::testing::Values(AggregationTemporality::kCumulative, AggregationTemporality::kDelta)); +TEST_P(WritableMetricStorageTestObservableGaugeFixture, TestAggregation) +{ + AggregationTemporality temporality = GetParam(); + + InstrumentDescriptor instr_desc = {"name", "desc", "1unit", InstrumentType::kObservableGauge, + InstrumentValueType::kLong}; + + auto sdk_start_ts = std::chrono::system_clock::now(); + // Some computation here + auto collection_ts = std::chrono::system_clock::now() + std::chrono::seconds(5); + + std::shared_ptr collector(new MockCollectorHandle(temporality)); + std::vector> collectors; + collectors.push_back(collector); + + std::unique_ptr default_attributes_processor{ + new DefaultAttributesProcessor{}}; + opentelemetry::sdk::metrics::AsyncMetricStorage storage( + instr_desc, AggregationType::kLastValue, default_attributes_processor.get(), nullptr); + int64_t freq_cpu0 = 3; + int64_t freq_cpu1 = 5; + std::unordered_map measurements1 = { + {{{"CPU", "0"}}, freq_cpu0}, {{{"CPU", "1"}}, freq_cpu1}}; + storage.RecordLong(measurements1, + opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now())); + + storage.Collect( + collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData metric_data) { + for (auto data_attr : metric_data.point_data_attr_) + { + auto data = opentelemetry::nostd::get(data_attr.point_data); + if (opentelemetry::nostd::get(data_attr.attributes.find("CPU")->second) == + "0") + { + EXPECT_EQ(opentelemetry::nostd::get(data.value_), freq_cpu0); + } + else if (opentelemetry::nostd::get( + data_attr.attributes.find("CPU")->second) == "1") + { + EXPECT_EQ(opentelemetry::nostd::get(data.value_), freq_cpu1); + } + } + return true; + }); + + freq_cpu0 = 6; + freq_cpu1 = 8; + + std::unordered_map measurements2 = { + {{{"CPU", "0"}}, freq_cpu0}, {{{"CPU", "1"}}, freq_cpu1}}; + storage.RecordLong(measurements2, + opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now())); + storage.Collect( + collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData metric_data) { + for (auto data_attr : metric_data.point_data_attr_) + { + auto data = opentelemetry::nostd::get(data_attr.point_data); + if (opentelemetry::nostd::get(data_attr.attributes.find("CPU")->second) == + "0") + { + EXPECT_EQ(opentelemetry::nostd::get(data.value_), freq_cpu0); + } + else if (opentelemetry::nostd::get( + data_attr.attributes.find("CPU")->second) == "1") + { + EXPECT_EQ(opentelemetry::nostd::get(data.value_), freq_cpu1); + } + } + return true; + }); +} + +INSTANTIATE_TEST_SUITE_P(WritableMetricStorageTestObservableGaugeFixtureLong, + WritableMetricStorageTestObservableGaugeFixture, + ::testing::Values(AggregationTemporality::kCumulative, + AggregationTemporality::kDelta)); + #endif diff --git a/sdk/test/metrics/attributes_hashmap_benchmark.cc b/sdk/test/metrics/attributes_hashmap_benchmark.cc index 2ebf03175a..2e90291e7c 100644 --- a/sdk/test/metrics/attributes_hashmap_benchmark.cc +++ b/sdk/test/metrics/attributes_hashmap_benchmark.cc @@ -25,14 +25,17 @@ void BM_AttributseHashMap(benchmark::State &state) std::vector attributes = {{{"k1", "v1"}, {"k2", "v2"}}, {{"k1", "v1"}, {"k2", "v2"}, {"k3", "v3"}}}; - auto work = [&attributes, &hash_map](const size_t i) { + std::mutex m; + + auto work = [&attributes, &hash_map, &m](const size_t i) { std::function()> create_default_aggregation = []() -> std::unique_ptr { return std::unique_ptr(new DropAggregation); }; - - hash_map.GetOrSetDefault(attributes[i % 2], create_default_aggregation)->Aggregate(1l); + m.lock(); + hash_map.GetOrSetDefault(attributes[i % 2], create_default_aggregation)->Aggregate((int64_t)1); benchmark::DoNotOptimize(hash_map.Has(attributes[i % 2])); + m.unlock(); }; while (state.KeepRunning()) { @@ -51,4 +54,4 @@ void BM_AttributseHashMap(benchmark::State &state) BENCHMARK(BM_AttributseHashMap); } // namespace #endif -BENCHMARK_MAIN(); \ No newline at end of file +BENCHMARK_MAIN(); diff --git a/sdk/test/metrics/attributes_hashmap_test.cc b/sdk/test/metrics/attributes_hashmap_test.cc index 0d95fbad61..c4a58b4813 100644 --- a/sdk/test/metrics/attributes_hashmap_test.cc +++ b/sdk/test/metrics/attributes_hashmap_test.cc @@ -26,14 +26,14 @@ TEST(AttributesHashMap, BasicTests) std::unique_ptr aggregation1( new DropAggregation()); // = std::unique_ptr(new DropAggregation); hash_map.Set(m1, std::move(aggregation1)); - EXPECT_NO_THROW(hash_map.Get(m1)->Aggregate(1l)); + EXPECT_NO_THROW(hash_map.Get(m1)->Aggregate((int64_t)1)); EXPECT_EQ(hash_map.Size(), 1); 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)); - EXPECT_NO_THROW(hash_map.Get(m1)->Aggregate(1l)); + EXPECT_NO_THROW(hash_map.Get(m1)->Aggregate((int64_t)1)); EXPECT_EQ(hash_map.Size(), 1); EXPECT_EQ(hash_map.Has(m1), true); @@ -43,7 +43,7 @@ TEST(AttributesHashMap, BasicTests) hash_map.Set(m3, std::move(aggregation3)); EXPECT_EQ(hash_map.Has(m1), true); EXPECT_EQ(hash_map.Has(m3), true); - EXPECT_NO_THROW(hash_map.Get(m3)->Aggregate(1l)); + EXPECT_NO_THROW(hash_map.Get(m3)->Aggregate((int64_t)1)); EXPECT_EQ(hash_map.Size(), 2); // GetOrSetDefault @@ -52,7 +52,7 @@ TEST(AttributesHashMap, BasicTests) return std::unique_ptr(new DropAggregation); }; MetricAttributes m4 = {{"k1", "v1"}, {"k2", "v2"}, {"k3", "v3"}}; - EXPECT_NO_THROW(hash_map.GetOrSetDefault(m4, create_default_aggregation)->Aggregate(1l)); + EXPECT_NO_THROW(hash_map.GetOrSetDefault(m4, create_default_aggregation)->Aggregate((int64_t)1)); EXPECT_EQ(hash_map.Size(), 3); // Set attributes with different order - shouldn't create a new entry. diff --git a/sdk/test/metrics/exemplar/BUILD b/sdk/test/metrics/exemplar/BUILD index 6481f679d2..1009999d02 100644 --- a/sdk/test/metrics/exemplar/BUILD +++ b/sdk/test/metrics/exemplar/BUILD @@ -10,6 +10,24 @@ cc_test( deps = [ "//api", "//sdk:headers", + "//sdk/src/metrics", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "with_trace_sample_filter_test", + srcs = [ + "with_trace_sample_filter_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//api", + "//sdk:headers", + "//sdk/src/metrics", "@com_google_googletest//:gtest_main", ], ) @@ -26,6 +44,7 @@ cc_test( deps = [ "//api", "//sdk:headers", + "//sdk/src/metrics", "@com_google_googletest//:gtest_main", ], ) @@ -42,6 +61,41 @@ cc_test( deps = [ "//api", "//sdk:headers", + "//sdk/src/metrics", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "reservoir_cell_test", + srcs = [ + "reservoir_cell_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//api", + "//sdk:headers", + "//sdk/src/metrics", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "histogram_exemplar_reservoir_test", + srcs = [ + "histogram_exemplar_reservoir_test.cc", + ], + tags = [ + "metrics", + "test", + ], + deps = [ + "//api", + "//sdk:headers", + "//sdk/src/metrics", "@com_google_googletest//:gtest_main", ], ) diff --git a/sdk/test/metrics/exemplar/CMakeLists.txt b/sdk/test/metrics/exemplar/CMakeLists.txt index 303294761a..33d04e913c 100644 --- a/sdk/test/metrics/exemplar/CMakeLists.txt +++ b/sdk/test/metrics/exemplar/CMakeLists.txt @@ -1,8 +1,12 @@ -foreach(testname no_exemplar_reservoir_test never_sample_filter_test - always_sample_filter_test) +foreach( + testname + no_exemplar_reservoir_test never_sample_filter_test always_sample_filter_test + histogram_exemplar_reservoir_test reservoir_cell_test + with_trace_sample_filter_test) add_executable(${testname} "${testname}.cc") - target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT} opentelemetry_metrics) + target_link_libraries( + ${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} + opentelemetry_metrics opentelemetry_metrics) gtest_add_tests( TARGET ${testname} TEST_PREFIX metrics. diff --git a/sdk/test/metrics/exemplar/always_sample_filter_test.cc b/sdk/test/metrics/exemplar/always_sample_filter_test.cc index cf4e449957..a2f70c1585 100644 --- a/sdk/test/metrics/exemplar/always_sample_filter_test.cc +++ b/sdk/test/metrics/exemplar/always_sample_filter_test.cc @@ -2,18 +2,18 @@ // SPDX-License-Identifier: Apache-2.0 #ifndef ENABLE_METRICS_PREVIEW -# include "opentelemetry/sdk/metrics/exemplar/always_sample_filter.h" # include +# include "opentelemetry/sdk/metrics/exemplar/filter.h" using namespace opentelemetry::sdk::metrics; TEST(AlwaysSampleFilter, SampleMeasurement) { - auto filter = opentelemetry::sdk::metrics::AlwaysSampleFilter::GetAlwaysSampleFilter(); + auto filter = opentelemetry::sdk::metrics::ExemplarFilter::GetAlwaysSampleFilter(); ASSERT_TRUE( filter->ShouldSampleMeasurement(1.0, MetricAttributes{}, opentelemetry::context::Context{})); - ASSERT_TRUE( - filter->ShouldSampleMeasurement(1l, MetricAttributes{}, opentelemetry::context::Context{})); + ASSERT_TRUE(filter->ShouldSampleMeasurement((int64_t)1, MetricAttributes{}, + opentelemetry::context::Context{})); } #endif diff --git a/sdk/test/metrics/exemplar/histogram_exemplar_reservoir_test.cc b/sdk/test/metrics/exemplar/histogram_exemplar_reservoir_test.cc new file mode 100644 index 0000000000..0d180b3836 --- /dev/null +++ b/sdk/test/metrics/exemplar/histogram_exemplar_reservoir_test.cc @@ -0,0 +1,36 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#include +#ifndef ENABLE_METRICS_PREVIEW +# include +# include "opentelemetry/sdk/metrics/exemplar/histogram_exemplar_reservoir.h" + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ +class HistogramExemplarReservoirTestPeer : public ::testing::Test +{ +public: +}; + +TEST_F(HistogramExemplarReservoirTestPeer, OfferMeasurement) +{ + std::vector boundaries{1, 5.0, 10, 15, 20}; + auto histogram_exemplar_reservoir = ExemplarReservoir::GetHistogramExemplarReservoir( + boundaries.size(), HistogramExemplarReservoir::GetHistogramCellSelector(boundaries), nullptr); + histogram_exemplar_reservoir->OfferMeasurement( + 1.0, MetricAttributes{}, opentelemetry::context::Context{}, std::chrono::system_clock::now()); + histogram_exemplar_reservoir->OfferMeasurement((int64_t)1, MetricAttributes{}, + opentelemetry::context::Context{}, + std::chrono::system_clock::now()); + auto exemplar_data = histogram_exemplar_reservoir->CollectAndReset(MetricAttributes{}); + ASSERT_TRUE(exemplar_data.empty()); +} + +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/sdk/test/metrics/exemplar/never_sample_filter_test.cc b/sdk/test/metrics/exemplar/never_sample_filter_test.cc index 930c572205..61d991e41e 100644 --- a/sdk/test/metrics/exemplar/never_sample_filter_test.cc +++ b/sdk/test/metrics/exemplar/never_sample_filter_test.cc @@ -4,17 +4,17 @@ #include "opentelemetry/context/context.h" #ifndef ENABLE_METRICS_PREVIEW # include -# include "opentelemetry/sdk/metrics/exemplar/never_sample_filter.h" +# include "opentelemetry/sdk/metrics/exemplar/filter.h" using namespace opentelemetry::sdk::metrics; TEST(NeverSampleFilter, SampleMeasurement) { - auto filter = opentelemetry::sdk::metrics::NeverSampleFilter::GetNeverSampleFilter(); + auto filter = opentelemetry::sdk::metrics::ExemplarFilter::GetNeverSampleFilter(); ASSERT_FALSE( filter->ShouldSampleMeasurement(1.0, MetricAttributes{}, opentelemetry::context::Context{})); - ASSERT_FALSE( - filter->ShouldSampleMeasurement(1l, MetricAttributes{}, opentelemetry::context::Context{})); + ASSERT_FALSE(filter->ShouldSampleMeasurement((int64_t)1, MetricAttributes{}, + opentelemetry::context::Context{})); } #endif diff --git a/sdk/test/metrics/exemplar/no_exemplar_reservoir_test.cc b/sdk/test/metrics/exemplar/no_exemplar_reservoir_test.cc index 72341de9de..d93ac0a018 100644 --- a/sdk/test/metrics/exemplar/no_exemplar_reservoir_test.cc +++ b/sdk/test/metrics/exemplar/no_exemplar_reservoir_test.cc @@ -9,10 +9,10 @@ using namespace opentelemetry::sdk::metrics; TEST(NoExemplarReservoir, OfferMeasurement) { - auto reservoir = opentelemetry::sdk::metrics::NoExemplarReservoir::GetNoExemplarReservoir(); + auto reservoir = opentelemetry::sdk::metrics::ExemplarReservoir::GetNoExemplarReservoir(); reservoir->OfferMeasurement(1.0, MetricAttributes{}, opentelemetry::context::Context{}, std::chrono::system_clock::now()); - reservoir->OfferMeasurement(1l, MetricAttributes{}, opentelemetry::context::Context{}, + reservoir->OfferMeasurement((int64_t)1, MetricAttributes{}, opentelemetry::context::Context{}, std::chrono::system_clock::now()); auto exemplar_data = reservoir->CollectAndReset(MetricAttributes{}); ASSERT_TRUE(exemplar_data.empty()); diff --git a/sdk/test/metrics/exemplar/reservoir_cell_test.cc b/sdk/test/metrics/exemplar/reservoir_cell_test.cc new file mode 100644 index 0000000000..c73701b9af --- /dev/null +++ b/sdk/test/metrics/exemplar/reservoir_cell_test.cc @@ -0,0 +1,74 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/metrics/exemplar/reservoir_cell.h" +# include + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace metrics +{ +class ReservoirCellTestPeer : public ::testing::Test +{ +public: + int64_t GetLongVal(const opentelemetry::sdk::metrics::ReservoirCell &reservoir_cell) + { + return nostd::get(reservoir_cell.value_); + } + + double GetDoubleVal(const opentelemetry::sdk::metrics::ReservoirCell &reservoir_cell) + { + return nostd::get(reservoir_cell.value_); + } + + opentelemetry::common::SystemTimestamp GetRecordTime( + const opentelemetry::sdk::metrics::ReservoirCell &reservoir_cell) + { + return reservoir_cell.record_time_; + } + + void FilteredTest() + { + MetricAttributes original{{"k1", "v1"}, {"k2", "v2"}, {"k3", "v3"}}; + MetricAttributes metric_point{{"k2", "v2"}, {"k4", "v4"}}; + MetricAttributes expected_result{{"k1", "v1"}, {"k3", "v3"}}; + auto result = opentelemetry::sdk::metrics::ReservoirCell::filtered(original, metric_point); + ASSERT_TRUE(result == expected_result); + } +}; + +TEST_F(ReservoirCellTestPeer, recordMeasurement) +{ + opentelemetry::sdk::metrics::ReservoirCell reservoir_cell; + reservoir_cell.RecordLongMeasurement((int64_t)1, MetricAttributes{}, + opentelemetry::context::Context{}); + ASSERT_TRUE(GetLongVal(reservoir_cell) == 1); + + reservoir_cell.RecordDoubleMeasurement(1.5, MetricAttributes{}, + opentelemetry::context::Context{}); + ASSERT_TRUE(GetDoubleVal(reservoir_cell) == 1.5); +} + +TEST_F(ReservoirCellTestPeer, GetAndReset) +{ + opentelemetry::sdk::metrics::ReservoirCell reservoir_cell; + auto double_data = reservoir_cell.GetAndResetDouble(MetricAttributes{}); + ASSERT_TRUE(GetRecordTime(reservoir_cell) == opentelemetry::common::SystemTimestamp{}); + ASSERT_TRUE(double_data == nullptr); + + auto long_data = reservoir_cell.GetAndResetLong(MetricAttributes{}); + ASSERT_TRUE(GetRecordTime(reservoir_cell) == opentelemetry::common::SystemTimestamp{}); + ASSERT_TRUE(long_data == nullptr); +} + +TEST_F(ReservoirCellTestPeer, Filtered) +{ + FilteredTest(); +} + +} // namespace metrics +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE +#endif diff --git a/sdk/test/metrics/exemplar/with_trace_sample_filter_test.cc b/sdk/test/metrics/exemplar/with_trace_sample_filter_test.cc new file mode 100644 index 0000000000..77bc534f46 --- /dev/null +++ b/sdk/test/metrics/exemplar/with_trace_sample_filter_test.cc @@ -0,0 +1,20 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#include "opentelemetry/context/context.h" +#ifndef ENABLE_METRICS_PREVIEW +# include +# include "opentelemetry/sdk/metrics/exemplar/filter.h" + +using namespace opentelemetry::sdk::metrics; + +TEST(WithTraceSampleFilter, SampleMeasurement) +{ + auto filter = opentelemetry::sdk::metrics::ExemplarFilter::GetWithTraceSampleFilter(); + ASSERT_FALSE( + filter->ShouldSampleMeasurement(1.0, MetricAttributes{}, opentelemetry::context::Context{})); + ASSERT_FALSE(filter->ShouldSampleMeasurement((int64_t)1, MetricAttributes{}, + opentelemetry::context::Context{})); +} + +#endif diff --git a/sdk/test/metrics/instrument_metadata_validator_test.cc b/sdk/test/metrics/instrument_metadata_validator_test.cc new file mode 100644 index 0000000000..df7e7be594 --- /dev/null +++ b/sdk/test/metrics/instrument_metadata_validator_test.cc @@ -0,0 +1,75 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/sdk/metrics/instrument_metadata_validator.h" +# include + +static std::string CreateVeryLargeString(size_t multiple) +{ + std::string result = "START"; + std::string repeater = "0123456789"; + for (size_t i = 0; i < multiple; i++) + { + result += repeater; + } + return result; +} + +TEST(InstrumentMetadataValidator, TestName) +{ + opentelemetry::sdk::metrics::InstrumentMetaDataValidator validator; + std::vector invalid_names = { + "", // empty string + "1sdf", // string starting with number + "123€AAA€BBB", // unicode characters + "/\\sdsd", // string starting with special character + "***sSSs", // string starting with special character + CreateVeryLargeString(5) + "ABCERTYGJ", // total 64 charactes + CreateVeryLargeString(7), // string much bigger than 63 chars + }; + for (auto const &str : invalid_names) + { + EXPECT_FALSE(validator.ValidateName(str)); + } + + std::vector valid_names = { + "T", // single char string + "s123", // starting with char, followed by numbers + "dsdsdsd_-.", // string , and valid nonalphanumeric + "d1234_-sDSDs.sdsd344", // combination of all valid characters + CreateVeryLargeString(5) + "ABCERTYG", // total 63 charactes + }; + for (auto const &str : valid_names) + { + EXPECT_TRUE(validator.ValidateName(str)); + } +} + +TEST(InstrumentMetadataValidator, TestUnit) +{ + opentelemetry::sdk::metrics::InstrumentMetaDataValidator validator; + std::vector invalid_units = { + CreateVeryLargeString(5) + "ABCERTYGJ", // total 64 charactes + CreateVeryLargeString(7), // string bigger than 63 chars + "123€AAA€BBB", // unicode string + }; + for (auto const &str : invalid_units) + { + EXPECT_FALSE(validator.ValidateUnit(str)); + } + + std::vector valid_units = { + "T", // single char + "s123", // starting with char, followed by numbers + "dsdsdsd_-.", // string , and valid nonalphanumeric + "d1234_-sdsds.sdsd344", // combination of all valid characters + CreateVeryLargeString(5) + "ABCERTYG", // total 63 charactes + "ASDDSDF", // uppercase + }; + for (auto const &str : valid_units) + { + EXPECT_TRUE(validator.ValidateName(str)); + } +} +#endif diff --git a/sdk/test/metrics/meter_provider_sdk_test.cc b/sdk/test/metrics/meter_provider_sdk_test.cc index d21e45f603..ee75ed54ac 100644 --- a/sdk/test/metrics/meter_provider_sdk_test.cc +++ b/sdk/test/metrics/meter_provider_sdk_test.cc @@ -6,14 +6,14 @@ # include "opentelemetry/sdk/metrics/export/metric_producer.h" # include "opentelemetry/sdk/metrics/meter.h" # include "opentelemetry/sdk/metrics/meter_provider.h" -# include "opentelemetry/sdk/metrics/metric_exporter.h" # include "opentelemetry/sdk/metrics/metric_reader.h" +# include "opentelemetry/sdk/metrics/push_metric_exporter.h" # include "opentelemetry/sdk/metrics/view/instrument_selector.h" # include "opentelemetry/sdk/metrics/view/meter_selector.h" using namespace opentelemetry::sdk::metrics; -class MockMetricExporter : public MetricExporter +class MockMetricExporter : public PushMetricExporter { public: @@ -38,7 +38,7 @@ class MockMetricExporter : public MetricExporter class MockMetricReader : public MetricReader { public: - MockMetricReader(std::unique_ptr exporter) : exporter_(std::move(exporter)) {} + MockMetricReader(std::unique_ptr exporter) : exporter_(std::move(exporter)) {} AggregationTemporality GetAggregationTemporality( InstrumentType instrument_type) const noexcept override { @@ -55,7 +55,7 @@ class MockMetricReader : public MetricReader virtual void OnInitialized() noexcept override {} private: - std::unique_ptr exporter_; + std::unique_ptr exporter_; }; TEST(MeterProvider, GetMeter) @@ -81,7 +81,7 @@ TEST(MeterProvider, GetMeter) ASSERT_EQ(m4, m5); ASSERT_NE(m3, m6); - // Should be an sdk::trace::Tracer with the processor attached. + // Should be an sdk::metrics::Meter # ifdef OPENTELEMETRY_RTTI_ENABLED auto sdkMeter1 = dynamic_cast(m1.get()); # else @@ -98,5 +98,9 @@ TEST(MeterProvider, GetMeter) std::unique_ptr meter_selector{new MeterSelector("name1", "version1", "schema1")}; mp1.AddView(std::move(instrument_selector), std::move(meter_selector), std::move(view)); + + // cleanup properly without crash + mp1.ForceFlush(); + mp1.Shutdown(); } #endif diff --git a/sdk/test/metrics/meter_test.cc b/sdk/test/metrics/meter_test.cc index 9108297624..521c1d0c1c 100644 --- a/sdk/test/metrics/meter_test.cc +++ b/sdk/test/metrics/meter_test.cc @@ -30,14 +30,15 @@ class MockMetricReader : public MetricReader namespace { -nostd::shared_ptr InitMeter(MetricReader **metricReaderPtr) +nostd::shared_ptr InitMeter(MetricReader **metricReaderPtr, + std::string meter_name = "meter_name") { static std::shared_ptr provider(new MeterProvider()); std::unique_ptr metric_reader(new MockMetricReader()); *metricReaderPtr = metric_reader.get(); auto p = std::static_pointer_cast(provider); p->AddMetricReader(std::move(metric_reader)); - auto meter = provider->GetMeter("meter_name"); + auto meter = provider->GetMeter(meter_name); return meter; } } // namespace @@ -45,15 +46,15 @@ nostd::shared_ptr InitMeter(MetricReader **metricReaderPtr) void asyc_generate_measurements(opentelemetry::metrics::ObserverResult observer, void * /* state */) { auto observer_long = - nostd::get>>(observer); - observer_long->Observe(10l); + nostd::get>>(observer); + observer_long->Observe(10); } TEST(MeterTest, BasicAsyncTests) { MetricReader *metric_reader_ptr = nullptr; auto meter = InitMeter(&metric_reader_ptr); - auto observable_counter = meter->CreateLongObservableCounter("observable_counter"); + auto observable_counter = meter->CreateInt64ObservableCounter("observable_counter"); observable_counter->AddCallback(asyc_generate_measurements, nullptr); size_t count = 0; @@ -70,6 +71,65 @@ TEST(MeterTest, BasicAsyncTests) } return true; }); + observable_counter->RemoveCallback(asyc_generate_measurements, nullptr); +} + +constexpr static unsigned MAX_THREADS = 25; +constexpr static unsigned MAX_ITERATIONS_MT = 1000; + +TEST(MeterTest, StressMultiThread) +{ + MetricReader *metric_reader_ptr = nullptr; + auto meter = InitMeter(&metric_reader_ptr, "stress_test_meter"); + std::atomic threadCount(0); + std::atomic numIterations(MAX_ITERATIONS_MT); + std::atomic do_collect{false}, do_sync_create{true}, do_async_create{false}; + std::vector> + observable_instruments; + std::vector meter_operation_threads; + std::atomic instrument_id(0); + while (numIterations--) + { + for (size_t i = 0; i < MAX_THREADS; i++) + { + if (threadCount++ < MAX_THREADS) + { + auto t = std::thread([&]() { + std::this_thread::yield(); + if (do_sync_create.exchange(false)) + { + std::string instrument_name = "test_couter_" + std::to_string(instrument_id); + meter->CreateUInt64Counter(instrument_name, "", ""); + do_async_create.store(true); + instrument_id++; + } + if (do_async_create.exchange(false)) + { + std::cout << "\n creating async thread " << std::to_string(numIterations); + auto observable_instrument = meter->CreateInt64ObservableUpDownCounter( + "test_gauge_" + std::to_string(instrument_id)); + observable_instrument->AddCallback(asyc_generate_measurements, nullptr); + observable_instruments.push_back(std::move(observable_instrument)); + do_collect.store(true); + instrument_id++; + } + if (do_collect.exchange(false)) + { + metric_reader_ptr->Collect([](ResourceMetrics & /* metric_data */) { return true; }); + do_sync_create.store(true); + } + }); + meter_operation_threads.push_back(std::move(t)); + } + } + } + for (auto &t : meter_operation_threads) + { + if (t.joinable()) + { + t.join(); + } + } } #endif diff --git a/sdk/test/metrics/metric_reader_test.cc b/sdk/test/metrics/metric_reader_test.cc index 44c30941f3..31987c6ada 100644 --- a/sdk/test/metrics/metric_reader_test.cc +++ b/sdk/test/metrics/metric_reader_test.cc @@ -5,7 +5,7 @@ # include "opentelemetry/sdk/metrics/metric_reader.h" # include # include "opentelemetry/sdk/metrics/meter_context.h" -# include "opentelemetry/sdk/metrics/metric_exporter.h" +# include "opentelemetry/sdk/metrics/push_metric_exporter.h" using namespace opentelemetry; using namespace opentelemetry::sdk::instrumentationscope; diff --git a/sdk/test/metrics/multi_metric_storage_test.cc b/sdk/test/metrics/multi_metric_storage_test.cc index 66e336192d..30d2e4ccb9 100644 --- a/sdk/test/metrics/multi_metric_storage_test.cc +++ b/sdk/test/metrics/multi_metric_storage_test.cc @@ -16,13 +16,13 @@ using namespace opentelemetry::sdk::metrics; class TestMetricStorage : public SyncWritableMetricStorage { public: - void RecordLong(long /* value */, + void RecordLong(int64_t /* value */, const opentelemetry::context::Context & /* context */) noexcept override { num_calls_long++; } - void RecordLong(long /* value */, + void RecordLong(int64_t /* value */, const opentelemetry::common::KeyValueIterable & /* attributes */, const opentelemetry::context::Context & /* context */) noexcept override { @@ -52,11 +52,11 @@ TEST(MultiMetricStorageTest, BasicTests) new TestMetricStorage()); SyncMultiMetricStorage storages{}; storages.AddStorage(storage); - storages.RecordLong(10l, opentelemetry::context::Context{}); - storages.RecordLong(20l, opentelemetry::context::Context{}); + storages.RecordLong(10, opentelemetry::context::Context{}); + storages.RecordLong(20, opentelemetry::context::Context{}); storages.RecordDouble(10.0, opentelemetry::context::Context{}); - storages.RecordLong(30l, opentelemetry::context::Context{}); + storages.RecordLong(30, opentelemetry::context::Context{}); EXPECT_EQ(static_cast(storage.get())->num_calls_long, 3); EXPECT_EQ(static_cast(storage.get())->num_calls_double, 1); diff --git a/sdk/test/metrics/observable_registry_test.cc b/sdk/test/metrics/observable_registry_test.cc index 77b5fc13fa..a0ee283ef7 100644 --- a/sdk/test/metrics/observable_registry_test.cc +++ b/sdk/test/metrics/observable_registry_test.cc @@ -19,17 +19,17 @@ class MeasurementFetcher fetch_count1++; if (fetch_count1 == 1) { - std::get observer_result(attributes_processor); + ObserverResultT observer_result(attributes_processor); - observer_result.Observe(10l); - observer_result.Observe(20l); + observer_result.Observe(10); + observer_result.Observe(20); EXPECT_EQ(observer_result.GetMeasurements().size(), 1); std::map m1 = {{"k2", 12}}; observer_result.Observe( - 30l, opentelemetry::common::KeyValueIterableView>(m1)); + 30, opentelemetry::common::KeyValueIterableView>(m1)); EXPECT_EQ(observer_result.GetMeasurements().size(), 2); observer_result.Observe( - 40l, opentelemetry::common::KeyValueIterableView>(m1)); + 40, opentelemetry::common::KeyValueIterableView>(m1)); EXPECT_EQ(observer_result.GetMeasurements().size(), 2); std::map m2 = {{"k2", 12}, {"k4", 12}}; observer_result.Observe( - 40l, opentelemetry::common::KeyValueIterableView>(m2)); + 40, opentelemetry::common::KeyValueIterableView>(m2)); EXPECT_EQ(observer_result.GetMeasurements().size(), 3); delete attributes_processor; } -#endif \ No newline at end of file +#endif diff --git a/sdk/test/metrics/periodic_exporting_metric_reader_test.cc b/sdk/test/metrics/periodic_exporting_metric_reader_test.cc index 4c7fd4aa4d..59ae25118b 100644 --- a/sdk/test/metrics/periodic_exporting_metric_reader_test.cc +++ b/sdk/test/metrics/periodic_exporting_metric_reader_test.cc @@ -5,7 +5,7 @@ # include "opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader.h" # include "opentelemetry/sdk/metrics/export/metric_producer.h" -# include "opentelemetry/sdk/metrics/metric_exporter.h" +# include "opentelemetry/sdk/metrics/push_metric_exporter.h" # include @@ -13,7 +13,7 @@ using namespace opentelemetry; using namespace opentelemetry::sdk::instrumentationscope; using namespace opentelemetry::sdk::metrics; -class MockPushMetricExporter : public MetricExporter +class MockPushMetricExporter : public PushMetricExporter { public: opentelemetry::sdk::common::ExportResult Export(const ResourceMetrics &record) noexcept override @@ -63,7 +63,7 @@ class MockMetricProducer : public MetricProducer TEST(PeriodicExporingMetricReader, BasicTests) { - std::unique_ptr exporter(new MockPushMetricExporter()); + std::unique_ptr exporter(new MockPushMetricExporter()); PeriodicExportingMetricReaderOptions options; options.export_timeout_millis = std::chrono::milliseconds(200); options.export_interval_millis = std::chrono::milliseconds(500); diff --git a/sdk/test/metrics/sync_instruments_test.cc b/sdk/test/metrics/sync_instruments_test.cc index 1c276c046f..fd9240518a 100644 --- a/sdk/test/metrics/sync_instruments_test.cc +++ b/sdk/test/metrics/sync_instruments_test.cc @@ -25,16 +25,15 @@ TEST(SyncInstruments, LongCounter) InstrumentDescriptor instrument_descriptor = { "long_counter", "description", "1", InstrumentType::kCounter, InstrumentValueType::kLong}; std::unique_ptr metric_storage(new SyncMultiMetricStorage()); - LongCounter counter(instrument_descriptor, std::move(metric_storage)); - counter.Add(10l); - counter.Add(10l, opentelemetry::context::Context{}); + LongCounter counter(instrument_descriptor, std::move(metric_storage)); + counter.Add(10); + counter.Add(10, opentelemetry::context::Context{}); - counter.Add(10l, - opentelemetry::common::KeyValueIterableView({{"abc", "123"}, {"xyz", "456"}})); - counter.Add(10l, opentelemetry::common::KeyValueIterableView({{"abc", "123"}, {"xyz", "456"}}), + counter.Add(10, opentelemetry::common::KeyValueIterableView({{"abc", "123"}, {"xyz", "456"}})); + counter.Add(10, opentelemetry::common::KeyValueIterableView({{"abc", "123"}, {"xyz", "456"}}), opentelemetry::context::Context{}); - counter.Add(10l, opentelemetry::common::KeyValueIterableView({})); - counter.Add(10l, opentelemetry::common::KeyValueIterableView({}), + counter.Add(10, opentelemetry::common::KeyValueIterableView({})); + counter.Add(10, opentelemetry::common::KeyValueIterableView({}), opentelemetry::context::Context{}); } @@ -64,15 +63,14 @@ TEST(SyncInstruments, LongUpDownCounter) InstrumentValueType::kLong}; std::unique_ptr metric_storage(new SyncMultiMetricStorage()); LongUpDownCounter counter(instrument_descriptor, std::move(metric_storage)); - counter.Add(10l); - counter.Add(10l, opentelemetry::context::Context{}); + counter.Add(10); + counter.Add(10, opentelemetry::context::Context{}); - counter.Add(10l, - opentelemetry::common::KeyValueIterableView({{"abc", "123"}, {"xyz", "456"}})); - counter.Add(10l, opentelemetry::common::KeyValueIterableView({{"abc", "123"}, {"xyz", "456"}}), + counter.Add(10, opentelemetry::common::KeyValueIterableView({{"abc", "123"}, {"xyz", "456"}})); + counter.Add(10, opentelemetry::common::KeyValueIterableView({{"abc", "123"}, {"xyz", "456"}}), opentelemetry::context::Context{}); - counter.Add(10l, opentelemetry::common::KeyValueIterableView({})); - counter.Add(10l, opentelemetry::common::KeyValueIterableView({}), + counter.Add(10, opentelemetry::common::KeyValueIterableView({})); + counter.Add(10, opentelemetry::common::KeyValueIterableView({}), opentelemetry::context::Context{}); } @@ -101,14 +99,14 @@ TEST(SyncInstruments, LongHistogram) InstrumentDescriptor instrument_descriptor = { "long_histogram", "description", "1", InstrumentType::kHistogram, InstrumentValueType::kLong}; std::unique_ptr metric_storage(new SyncMultiMetricStorage()); - LongHistogram counter(instrument_descriptor, std::move(metric_storage)); - counter.Record(10l, opentelemetry::context::Context{}); - counter.Record(-10l, opentelemetry::context::Context{}); // This is ignored + LongHistogram counter(instrument_descriptor, std::move(metric_storage)); + counter.Record(10, opentelemetry::context::Context{}); + counter.Record(-10, opentelemetry::context::Context{}); // This is ignored - counter.Record(10l, + counter.Record(10, opentelemetry::common::KeyValueIterableView({{"abc", "123"}, {"xyz", "456"}}), opentelemetry::context::Context{}); - counter.Record(10l, opentelemetry::common::KeyValueIterableView({}), + counter.Record(10, opentelemetry::common::KeyValueIterableView({}), opentelemetry::context::Context{}); } @@ -133,4 +131,4 @@ TEST(SyncInstruments, DoubleHistogram) opentelemetry::context::Context{}); } -#endif \ No newline at end of file +#endif diff --git a/sdk/test/metrics/sync_metric_storage_counter_test.cc b/sdk/test/metrics/sync_metric_storage_counter_test.cc index a2853f5181..7118e66529 100644 --- a/sdk/test/metrics/sync_metric_storage_counter_test.cc +++ b/sdk/test/metrics/sync_metric_storage_counter_test.cc @@ -5,7 +5,7 @@ #ifndef ENABLE_METRICS_PREVIEW # include "opentelemetry/common/key_value_iterable_view.h" # include "opentelemetry/nostd/shared_ptr.h" -# include "opentelemetry/sdk/metrics/exemplar/no_exemplar_reservoir.h" +# include "opentelemetry/sdk/metrics/exemplar/histogram_exemplar_reservoir.h" # include "opentelemetry/sdk/metrics/instruments.h" # include "opentelemetry/sdk/metrics/state/sync_metric_storage.h" # include "opentelemetry/sdk/metrics/view/attributes_processor.h" @@ -23,7 +23,7 @@ class MockCollectorHandle : public CollectorHandle public: MockCollectorHandle(AggregationTemporality temp) : temporality(temp) {} - virtual ~MockCollectorHandle() = default; + ~MockCollectorHandle() override = default; AggregationTemporality GetAggregationTemporality( InstrumentType /* instrument_type */) noexcept override @@ -38,13 +38,13 @@ class MockCollectorHandle : public CollectorHandle class WritableMetricStorageTestFixture : public ::testing::TestWithParam {}; -TEST_P(WritableMetricStorageTestFixture, LongSumAggregation) +TEST_P(WritableMetricStorageTestFixture, LongCounterSumAggregation) { - AggregationTemporality temporality = GetParam(); - auto sdk_start_ts = std::chrono::system_clock::now(); - long expected_total_get_requests = 0; - long expected_total_put_requests = 0; - InstrumentDescriptor instr_desc = {"name", "desc", "1unit", InstrumentType::kCounter, + AggregationTemporality temporality = GetParam(); + auto sdk_start_ts = std::chrono::system_clock::now(); + int64_t expected_total_get_requests = 0; + int64_t expected_total_put_requests = 0; + InstrumentDescriptor instr_desc = {"name", "desc", "1unit", InstrumentType::kCounter, InstrumentValueType::kLong}; std::map attributes_get = {{"RequestType", "GET"}}; std::map attributes_put = {{"RequestType", "PUT"}}; @@ -53,22 +53,21 @@ TEST_P(WritableMetricStorageTestFixture, LongSumAggregation) new DefaultAttributesProcessor{}}; opentelemetry::sdk::metrics::SyncMetricStorage storage( instr_desc, AggregationType::kSum, default_attributes_processor.get(), - NoExemplarReservoir::GetNoExemplarReservoir(), - std::shared_ptr{}); + ExemplarReservoir::GetNoExemplarReservoir(), nullptr); - storage.RecordLong(10l, KeyValueIterableView>(attributes_get), + storage.RecordLong(10, KeyValueIterableView>(attributes_get), opentelemetry::context::Context{}); expected_total_get_requests += 10; - storage.RecordLong(30l, KeyValueIterableView>(attributes_put), + storage.RecordLong(30, KeyValueIterableView>(attributes_put), opentelemetry::context::Context{}); expected_total_put_requests += 30; - storage.RecordLong(20l, KeyValueIterableView>(attributes_get), + storage.RecordLong(20, KeyValueIterableView>(attributes_get), opentelemetry::context::Context{}); expected_total_get_requests += 20; - storage.RecordLong(40l, KeyValueIterableView>(attributes_put), + storage.RecordLong(40, KeyValueIterableView>(attributes_put), opentelemetry::context::Context{}); expected_total_put_requests += 40; @@ -80,20 +79,20 @@ TEST_P(WritableMetricStorageTestFixture, LongSumAggregation) auto collection_ts = std::chrono::system_clock::now(); size_t count_attributes = 0; storage.Collect( - collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData data) { - for (auto data_attr : data.point_data_attr_) + collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData &metric_data) { + for (const auto &data_attr : metric_data.point_data_attr_) { - auto data = opentelemetry::nostd::get(data_attr.point_data); + const auto &data = opentelemetry::nostd::get(data_attr.point_data); if (opentelemetry::nostd::get( data_attr.attributes.find("RequestType")->second) == "GET") { - EXPECT_EQ(opentelemetry::nostd::get(data.value_), expected_total_get_requests); + EXPECT_EQ(opentelemetry::nostd::get(data.value_), expected_total_get_requests); count_attributes++; } else if (opentelemetry::nostd::get( data_attr.attributes.find("RequestType")->second) == "PUT") { - EXPECT_EQ(opentelemetry::nostd::get(data.value_), expected_total_put_requests); + EXPECT_EQ(opentelemetry::nostd::get(data.value_), expected_total_put_requests); count_attributes++; } } @@ -107,26 +106,25 @@ TEST_P(WritableMetricStorageTestFixture, LongSumAggregation) expected_total_get_requests = 0; expected_total_put_requests = 0; } - // collect one more time. collection_ts = std::chrono::system_clock::now(); count_attributes = 0; storage.Collect( - collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData data) { - for (auto data_attr : data.point_data_attr_) + collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData &metric_data) { + for (const auto &data_attr : metric_data.point_data_attr_) { - auto data = opentelemetry::nostd::get(data_attr.point_data); + const auto &data = opentelemetry::nostd::get(data_attr.point_data); if (opentelemetry::nostd::get( data_attr.attributes.find("RequestType")->second) == "GET") { count_attributes++; - EXPECT_EQ(opentelemetry::nostd::get(data.value_), expected_total_get_requests); + EXPECT_EQ(opentelemetry::nostd::get(data.value_), expected_total_get_requests); } else if (opentelemetry::nostd::get( data_attr.attributes.find("RequestType")->second) == "PUT") { count_attributes++; - EXPECT_EQ(opentelemetry::nostd::get(data.value_), expected_total_put_requests); + EXPECT_EQ(opentelemetry::nostd::get(data.value_), expected_total_put_requests); } } return true; @@ -136,30 +134,30 @@ TEST_P(WritableMetricStorageTestFixture, LongSumAggregation) EXPECT_EQ(count_attributes, 2); // GET AND PUT } - storage.RecordLong(50l, KeyValueIterableView>(attributes_get), + storage.RecordLong(50, KeyValueIterableView>(attributes_get), opentelemetry::context::Context{}); expected_total_get_requests += 50; - storage.RecordLong(40l, KeyValueIterableView>(attributes_put), + storage.RecordLong(40, KeyValueIterableView>(attributes_put), opentelemetry::context::Context{}); expected_total_put_requests += 40; collection_ts = std::chrono::system_clock::now(); count_attributes = 0; storage.Collect( - collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData data) { - for (auto data_attr : data.point_data_attr_) + collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData &metric_data) { + for (const auto &data_attr : metric_data.point_data_attr_) { - auto data = opentelemetry::nostd::get(data_attr.point_data); + const auto &data = opentelemetry::nostd::get(data_attr.point_data); if (opentelemetry::nostd::get( data_attr.attributes.find("RequestType")->second) == "GET") { - EXPECT_EQ(opentelemetry::nostd::get(data.value_), expected_total_get_requests); + EXPECT_EQ(opentelemetry::nostd::get(data.value_), expected_total_get_requests); count_attributes++; } else if (opentelemetry::nostd::get( data_attr.attributes.find("RequestType")->second) == "PUT") { - EXPECT_EQ(opentelemetry::nostd::get(data.value_), expected_total_put_requests); + EXPECT_EQ(opentelemetry::nostd::get(data.value_), expected_total_put_requests); count_attributes++; } } @@ -173,7 +171,7 @@ INSTANTIATE_TEST_SUITE_P(WritableMetricStorageTestLong, ::testing::Values(AggregationTemporality::kCumulative, AggregationTemporality::kDelta)); -TEST_P(WritableMetricStorageTestFixture, DoubleSumAggregation) +TEST_P(WritableMetricStorageTestFixture, DoubleCounterSumAggregation) { AggregationTemporality temporality = GetParam(); auto sdk_start_ts = std::chrono::system_clock::now(); @@ -188,8 +186,7 @@ TEST_P(WritableMetricStorageTestFixture, DoubleSumAggregation) new DefaultAttributesProcessor{}}; opentelemetry::sdk::metrics::SyncMetricStorage storage( instr_desc, AggregationType::kSum, default_attributes_processor.get(), - NoExemplarReservoir::GetNoExemplarReservoir(), - std::shared_ptr{}); + ExemplarReservoir::GetNoExemplarReservoir(), nullptr); storage.RecordDouble(10.0, KeyValueIterableView>(attributes_get), @@ -219,10 +216,10 @@ TEST_P(WritableMetricStorageTestFixture, DoubleSumAggregation) auto collection_ts = std::chrono::system_clock::now(); size_t count_attributes = 0; storage.Collect( - collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData data) { - for (auto data_attr : data.point_data_attr_) + collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData &metric_data) { + for (const auto &data_attr : metric_data.point_data_attr_) { - auto data = opentelemetry::nostd::get(data_attr.point_data); + const auto &data = opentelemetry::nostd::get(data_attr.point_data); if (opentelemetry::nostd::get( data_attr.attributes.find("RequestType")->second) == "GET") { @@ -252,10 +249,10 @@ TEST_P(WritableMetricStorageTestFixture, DoubleSumAggregation) collection_ts = std::chrono::system_clock::now(); count_attributes = 0; storage.Collect( - collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData data) { - for (auto data_attr : data.point_data_attr_) + collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData &metric_data) { + for (const auto &data_attr : metric_data.point_data_attr_) { - auto data = opentelemetry::nostd::get(data_attr.point_data); + const auto &data = opentelemetry::nostd::get(data_attr.point_data); if (opentelemetry::nostd::get( data_attr.attributes.find("RequestType")->second) == "GET") { @@ -288,10 +285,10 @@ TEST_P(WritableMetricStorageTestFixture, DoubleSumAggregation) collection_ts = std::chrono::system_clock::now(); count_attributes = 0; storage.Collect( - collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData data) { - for (auto data_attr : data.point_data_attr_) + collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData &metric_data) { + for (const auto &data_attr : metric_data.point_data_attr_) { - auto data = opentelemetry::nostd::get(data_attr.point_data); + const auto &data = opentelemetry::nostd::get(data_attr.point_data); if (opentelemetry::nostd::get( data_attr.attributes.find("RequestType")->second) == "GET") { diff --git a/sdk/test/metrics/sync_metric_storage_histogram_test.cc b/sdk/test/metrics/sync_metric_storage_histogram_test.cc index 0e0713d60a..a50848ad3d 100644 --- a/sdk/test/metrics/sync_metric_storage_histogram_test.cc +++ b/sdk/test/metrics/sync_metric_storage_histogram_test.cc @@ -23,7 +23,7 @@ class MockCollectorHandle : public CollectorHandle public: MockCollectorHandle(AggregationTemporality temp) : temporality(temp) {} - virtual ~MockCollectorHandle() = default; + ~MockCollectorHandle() override = default; AggregationTemporality GetAggregationTemporality( InstrumentType /* instrument_type */) noexcept override @@ -41,11 +41,11 @@ class WritableMetricStorageHistogramTestFixture TEST_P(WritableMetricStorageHistogramTestFixture, LongHistogram) { - AggregationTemporality temporality = GetParam(); - auto sdk_start_ts = std::chrono::system_clock::now(); - long expected_total_get_requests = 0; - long expected_total_put_requests = 0; - InstrumentDescriptor instr_desc = {"name", "desc", "1unit", InstrumentType::kHistogram, + AggregationTemporality temporality = GetParam(); + auto sdk_start_ts = std::chrono::system_clock::now(); + int64_t expected_total_get_requests = 0; + int64_t expected_total_put_requests = 0; + InstrumentDescriptor instr_desc = {"name", "desc", "1unit", InstrumentType::kHistogram, InstrumentValueType::kLong}; std::map attributes_get = {{"RequestType", "GET"}}; std::map attributes_put = {{"RequestType", "PUT"}}; @@ -54,22 +54,21 @@ TEST_P(WritableMetricStorageHistogramTestFixture, LongHistogram) new DefaultAttributesProcessor{}}; opentelemetry::sdk::metrics::SyncMetricStorage storage( instr_desc, AggregationType::kHistogram, default_attributes_processor.get(), - NoExemplarReservoir::GetNoExemplarReservoir(), - std::shared_ptr{}); + NoExemplarReservoir::GetNoExemplarReservoir(), nullptr); - storage.RecordLong(10l, KeyValueIterableView>(attributes_get), + storage.RecordLong(10, KeyValueIterableView>(attributes_get), opentelemetry::context::Context{}); expected_total_get_requests += 10; - storage.RecordLong(30l, KeyValueIterableView>(attributes_put), + storage.RecordLong(30, KeyValueIterableView>(attributes_put), opentelemetry::context::Context{}); expected_total_put_requests += 30; - storage.RecordLong(20l, KeyValueIterableView>(attributes_get), + storage.RecordLong(20, KeyValueIterableView>(attributes_get), opentelemetry::context::Context{}); expected_total_get_requests += 20; - storage.RecordLong(40l, KeyValueIterableView>(attributes_put), + storage.RecordLong(40, KeyValueIterableView>(attributes_put), opentelemetry::context::Context{}); expected_total_put_requests += 40; @@ -81,20 +80,20 @@ TEST_P(WritableMetricStorageHistogramTestFixture, LongHistogram) auto collection_ts = std::chrono::system_clock::now(); size_t count_attributes = 0; storage.Collect( - collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData data) { - for (auto data_attr : data.point_data_attr_) + collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData &metric_data) { + for (const auto &data_attr : metric_data.point_data_attr_) { - auto data = opentelemetry::nostd::get(data_attr.point_data); + const auto &data = opentelemetry::nostd::get(data_attr.point_data); if (opentelemetry::nostd::get( data_attr.attributes.find("RequestType")->second) == "GET") { - EXPECT_EQ(opentelemetry::nostd::get(data.sum_), expected_total_get_requests); + EXPECT_EQ(opentelemetry::nostd::get(data.sum_), expected_total_get_requests); count_attributes++; } else if (opentelemetry::nostd::get( data_attr.attributes.find("RequestType")->second) == "PUT") { - EXPECT_EQ(opentelemetry::nostd::get(data.sum_), expected_total_put_requests); + EXPECT_EQ(opentelemetry::nostd::get(data.sum_), expected_total_put_requests); count_attributes++; } } @@ -113,21 +112,21 @@ TEST_P(WritableMetricStorageHistogramTestFixture, LongHistogram) collection_ts = std::chrono::system_clock::now(); count_attributes = 0; storage.Collect( - collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData data) { - for (auto data_attr : data.point_data_attr_) + collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData &metric_data) { + for (const auto &data_attr : metric_data.point_data_attr_) { - auto data = opentelemetry::nostd::get(data_attr.point_data); + const auto &data = opentelemetry::nostd::get(data_attr.point_data); if (opentelemetry::nostd::get( data_attr.attributes.find("RequestType")->second) == "GET") { count_attributes++; - EXPECT_EQ(opentelemetry::nostd::get(data.sum_), expected_total_get_requests); + EXPECT_EQ(opentelemetry::nostd::get(data.sum_), expected_total_get_requests); } else if (opentelemetry::nostd::get( data_attr.attributes.find("RequestType")->second) == "PUT") { count_attributes++; - EXPECT_EQ(opentelemetry::nostd::get(data.sum_), expected_total_put_requests); + EXPECT_EQ(opentelemetry::nostd::get(data.sum_), expected_total_put_requests); } } return true; @@ -137,30 +136,30 @@ TEST_P(WritableMetricStorageHistogramTestFixture, LongHistogram) EXPECT_EQ(count_attributes, 2); // GET AND PUT } - storage.RecordLong(50l, KeyValueIterableView>(attributes_get), + storage.RecordLong(50, KeyValueIterableView>(attributes_get), opentelemetry::context::Context{}); expected_total_get_requests += 50; - storage.RecordLong(40l, KeyValueIterableView>(attributes_put), + storage.RecordLong(40, KeyValueIterableView>(attributes_put), opentelemetry::context::Context{}); expected_total_put_requests += 40; collection_ts = std::chrono::system_clock::now(); count_attributes = 0; storage.Collect( - collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData data) { - for (auto data_attr : data.point_data_attr_) + collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData &metric_data) { + for (const auto &data_attr : metric_data.point_data_attr_) { - auto data = opentelemetry::nostd::get(data_attr.point_data); + const auto &data = opentelemetry::nostd::get(data_attr.point_data); if (opentelemetry::nostd::get( data_attr.attributes.find("RequestType")->second) == "GET") { - EXPECT_EQ(opentelemetry::nostd::get(data.sum_), expected_total_get_requests); + EXPECT_EQ(opentelemetry::nostd::get(data.sum_), expected_total_get_requests); count_attributes++; } else if (opentelemetry::nostd::get( data_attr.attributes.find("RequestType")->second) == "PUT") { - EXPECT_EQ(opentelemetry::nostd::get(data.sum_), expected_total_put_requests); + EXPECT_EQ(opentelemetry::nostd::get(data.sum_), expected_total_put_requests); count_attributes++; } } @@ -189,8 +188,7 @@ TEST_P(WritableMetricStorageHistogramTestFixture, DoubleHistogram) new DefaultAttributesProcessor{}}; opentelemetry::sdk::metrics::SyncMetricStorage storage( instr_desc, AggregationType::kHistogram, default_attributes_processor.get(), - NoExemplarReservoir::GetNoExemplarReservoir(), - std::shared_ptr{}); + NoExemplarReservoir::GetNoExemplarReservoir(), nullptr); storage.RecordDouble(10.0, KeyValueIterableView>(attributes_get), @@ -220,10 +218,10 @@ TEST_P(WritableMetricStorageHistogramTestFixture, DoubleHistogram) auto collection_ts = std::chrono::system_clock::now(); size_t count_attributes = 0; storage.Collect( - collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData data) { - for (auto data_attr : data.point_data_attr_) + collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData &metric_data) { + for (const auto &data_attr : metric_data.point_data_attr_) { - auto data = opentelemetry::nostd::get(data_attr.point_data); + const auto &data = opentelemetry::nostd::get(data_attr.point_data); if (opentelemetry::nostd::get( data_attr.attributes.find("RequestType")->second) == "GET") { @@ -253,10 +251,10 @@ TEST_P(WritableMetricStorageHistogramTestFixture, DoubleHistogram) collection_ts = std::chrono::system_clock::now(); count_attributes = 0; storage.Collect( - collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData data) { - for (auto data_attr : data.point_data_attr_) + collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData &metric_data) { + for (const auto &data_attr : metric_data.point_data_attr_) { - auto data = opentelemetry::nostd::get(data_attr.point_data); + const auto &data = opentelemetry::nostd::get(data_attr.point_data); if (opentelemetry::nostd::get( data_attr.attributes.find("RequestType")->second) == "GET") { @@ -289,10 +287,10 @@ TEST_P(WritableMetricStorageHistogramTestFixture, DoubleHistogram) collection_ts = std::chrono::system_clock::now(); count_attributes = 0; storage.Collect( - collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData data) { - for (auto data_attr : data.point_data_attr_) + collector.get(), collectors, sdk_start_ts, collection_ts, [&](const MetricData &metric_data) { + for (const auto &data_attr : metric_data.point_data_attr_) { - auto data = opentelemetry::nostd::get(data_attr.point_data); + const auto &data = opentelemetry::nostd::get(data_attr.point_data); if (opentelemetry::nostd::get( data_attr.attributes.find("RequestType")->second) == "GET") { diff --git a/sdk/test/metrics/sync_metric_storage_up_down_counter_test.cc b/sdk/test/metrics/sync_metric_storage_up_down_counter_test.cc new file mode 100644 index 0000000000..77841d7330 --- /dev/null +++ b/sdk/test/metrics/sync_metric_storage_up_down_counter_test.cc @@ -0,0 +1,330 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include "opentelemetry/common/key_value_iterable_view.h" +# include "opentelemetry/nostd/shared_ptr.h" +# include "opentelemetry/sdk/metrics/exemplar/histogram_exemplar_reservoir.h" +# include "opentelemetry/sdk/metrics/instruments.h" +# include "opentelemetry/sdk/metrics/state/sync_metric_storage.h" +# include "opentelemetry/sdk/metrics/view/attributes_processor.h" + +# include +# include +# include + +using namespace opentelemetry::sdk::metrics; +using namespace opentelemetry::common; +using M = std::map; +namespace nostd = opentelemetry::nostd; + +class MockCollectorHandle : public CollectorHandle +{ +public: + MockCollectorHandle(AggregationTemporality temp) : temporality(temp) {} + + ~MockCollectorHandle() override = default; + + AggregationTemporality GetAggregationTemporality( + InstrumentType /* instrument_type */) noexcept override + { + return temporality; + } + +private: + AggregationTemporality temporality; +}; + +class WritableMetricStorageTestFixture : public ::testing::TestWithParam +{}; + +TEST_P(WritableMetricStorageTestFixture, LongUpDownCounterSumAggregation) +{ + AggregationTemporality temporality = GetParam(); + auto sdk_start_ts = std::chrono::system_clock::now(); + int64_t expected_total_active_get_requests = 0; + int64_t expected_total_active_put_requests = 0; + InstrumentDescriptor instr_desc = {"name", "desc", "1unit", InstrumentType::kUpDownCounter, + InstrumentValueType::kLong}; + std::map attributes_get = {{"RequestType", "GET"}}; + std::map attributes_put = {{"RequestType", "PUT"}}; + + std::unique_ptr default_attributes_processor{ + new DefaultAttributesProcessor{}}; + opentelemetry::sdk::metrics::SyncMetricStorage storage( + instr_desc, AggregationType::kSum, default_attributes_processor.get(), + ExemplarReservoir::GetNoExemplarReservoir(), nullptr); + + int64_t val1 = 10, val2 = 30, val3 = -5, val4 = -10; + storage.RecordLong(val1, KeyValueIterableView>(attributes_get), + opentelemetry::context::Context{}); + expected_total_active_get_requests += val1; + + storage.RecordLong(val2, KeyValueIterableView>(attributes_put), + opentelemetry::context::Context{}); + expected_total_active_put_requests += val2; + + storage.RecordLong(val3, KeyValueIterableView>(attributes_get), + opentelemetry::context::Context{}); + expected_total_active_get_requests += val3; + + storage.RecordLong(val4, KeyValueIterableView>(attributes_put), + opentelemetry::context::Context{}); + expected_total_active_put_requests += val4; + + std::shared_ptr collector(new MockCollectorHandle(temporality)); + std::vector> collectors; + collectors.push_back(collector); + + // Some computation here + auto collection_ts = std::chrono::system_clock::now(); + size_t count_attributes = 0; + storage.Collect(collector.get(), collectors, sdk_start_ts, collection_ts, + [&](const MetricData data) { + for (auto data_attr : data.point_data_attr_) + { + auto sum_data = opentelemetry::nostd::get(data_attr.point_data); + if (opentelemetry::nostd::get( + data_attr.attributes.find("RequestType")->second) == "GET") + { + EXPECT_EQ(opentelemetry::nostd::get(sum_data.value_), + expected_total_active_get_requests); + count_attributes++; + } + else if (opentelemetry::nostd::get( + data_attr.attributes.find("RequestType")->second) == "PUT") + { + EXPECT_EQ(opentelemetry::nostd::get(sum_data.value_), + expected_total_active_put_requests); + count_attributes++; + } + } + return true; + }); + EXPECT_EQ(count_attributes, 2); // GET and PUT + // In case of delta temporarily, subsequent collection would contain new data points, so resetting + // the counts + if (temporality == AggregationTemporality::kDelta) + { + expected_total_active_get_requests = 0; + expected_total_active_put_requests = 0; + } + + // collect one more time. + collection_ts = std::chrono::system_clock::now(); + count_attributes = 0; + storage.Collect(collector.get(), collectors, sdk_start_ts, collection_ts, + [&](const MetricData data) { + for (auto data_attr : data.point_data_attr_) + { + auto sum_data = opentelemetry::nostd::get(data_attr.point_data); + if (opentelemetry::nostd::get( + data_attr.attributes.find("RequestType")->second) == "GET") + { + count_attributes++; + EXPECT_EQ(opentelemetry::nostd::get(sum_data.value_), + expected_total_active_get_requests); + } + else if (opentelemetry::nostd::get( + data_attr.attributes.find("RequestType")->second) == "PUT") + { + count_attributes++; + EXPECT_EQ(opentelemetry::nostd::get(sum_data.value_), + expected_total_active_put_requests); + } + } + return true; + }); + if (temporality == AggregationTemporality::kCumulative) + { + EXPECT_EQ(count_attributes, 2); // GET AND PUT + } + + val1 = 50; + val2 = 40; + storage.RecordLong(val1, KeyValueIterableView>(attributes_get), + opentelemetry::context::Context{}); + expected_total_active_get_requests += val1; + storage.RecordLong(val2, KeyValueIterableView>(attributes_put), + opentelemetry::context::Context{}); + expected_total_active_put_requests += val2; + + collection_ts = std::chrono::system_clock::now(); + count_attributes = 0; + storage.Collect(collector.get(), collectors, sdk_start_ts, collection_ts, + [&](const MetricData data) { + for (auto data_attr : data.point_data_attr_) + { + auto sum_data = opentelemetry::nostd::get(data_attr.point_data); + if (opentelemetry::nostd::get( + data_attr.attributes.find("RequestType")->second) == "GET") + { + EXPECT_EQ(opentelemetry::nostd::get(sum_data.value_), + expected_total_active_get_requests); + count_attributes++; + } + else if (opentelemetry::nostd::get( + data_attr.attributes.find("RequestType")->second) == "PUT") + { + EXPECT_EQ(opentelemetry::nostd::get(sum_data.value_), + expected_total_active_put_requests); + count_attributes++; + } + } + return true; + }); + EXPECT_EQ(count_attributes, 2); // GET and PUT +} + +INSTANTIATE_TEST_SUITE_P(WritableMetricStorageTestLong, + WritableMetricStorageTestFixture, + ::testing::Values(AggregationTemporality::kCumulative, + AggregationTemporality::kDelta)); + +TEST_P(WritableMetricStorageTestFixture, DoubleUpDownCounterSumAggregation) +{ + AggregationTemporality temporality = GetParam(); + auto sdk_start_ts = std::chrono::system_clock::now(); + double expected_total_active_get_requests = 0; + double expected_total_active_put_requests = 0; + InstrumentDescriptor instr_desc = {"name", "desc", "1unit", InstrumentType::kUpDownCounter, + InstrumentValueType::kDouble}; + std::map attributes_get = {{"RequestType", "GET"}}; + std::map attributes_put = {{"RequestType", "PUT"}}; + + std::unique_ptr default_attributes_processor{ + new DefaultAttributesProcessor{}}; + opentelemetry::sdk::metrics::SyncMetricStorage storage( + instr_desc, AggregationType::kSum, default_attributes_processor.get(), + ExemplarReservoir::GetNoExemplarReservoir(), nullptr); + + storage.RecordDouble(10.0, + KeyValueIterableView>(attributes_get), + opentelemetry::context::Context{}); + expected_total_active_get_requests += 10; + + storage.RecordDouble(30.0, + KeyValueIterableView>(attributes_put), + opentelemetry::context::Context{}); + expected_total_active_put_requests += 30; + + storage.RecordDouble(-5.0, + KeyValueIterableView>(attributes_get), + opentelemetry::context::Context{}); + expected_total_active_get_requests -= 5; + + storage.RecordDouble(-10.0, + KeyValueIterableView>(attributes_put), + opentelemetry::context::Context{}); + expected_total_active_put_requests -= 10; + + std::shared_ptr collector(new MockCollectorHandle(temporality)); + std::vector> collectors; + collectors.push_back(collector); + + // Some computation here + auto collection_ts = std::chrono::system_clock::now(); + size_t count_attributes = 0; + storage.Collect(collector.get(), collectors, sdk_start_ts, collection_ts, + [&](const MetricData data) { + for (auto data_attr : data.point_data_attr_) + { + auto sum_data = opentelemetry::nostd::get(data_attr.point_data); + if (opentelemetry::nostd::get( + data_attr.attributes.find("RequestType")->second) == "GET") + { + EXPECT_EQ(opentelemetry::nostd::get(sum_data.value_), + expected_total_active_get_requests); + count_attributes++; + } + else if (opentelemetry::nostd::get( + data_attr.attributes.find("RequestType")->second) == "PUT") + { + EXPECT_EQ(opentelemetry::nostd::get(sum_data.value_), + expected_total_active_put_requests); + count_attributes++; + } + } + return true; + }); + EXPECT_EQ(count_attributes, 2); // GET and PUT + + // In case of delta temporarily, subsequent collection would contain new data points, so resetting + // the counts + if (temporality == AggregationTemporality::kDelta) + { + expected_total_active_get_requests = 0; + expected_total_active_put_requests = 0; + } + + // collect one more time. + collection_ts = std::chrono::system_clock::now(); + count_attributes = 0; + storage.Collect(collector.get(), collectors, sdk_start_ts, collection_ts, + [&](const MetricData data) { + for (auto data_attr : data.point_data_attr_) + { + auto sum_data = opentelemetry::nostd::get(data_attr.point_data); + if (opentelemetry::nostd::get( + data_attr.attributes.find("RequestType")->second) == "GET") + { + count_attributes++; + EXPECT_EQ(opentelemetry::nostd::get(sum_data.value_), + expected_total_active_get_requests); + } + else if (opentelemetry::nostd::get( + data_attr.attributes.find("RequestType")->second) == "PUT") + { + count_attributes++; + EXPECT_EQ(opentelemetry::nostd::get(sum_data.value_), + expected_total_active_put_requests); + } + } + return true; + }); + if (temporality == AggregationTemporality::kCumulative) + { + EXPECT_EQ(count_attributes, 2); // GET AND PUT + } + + storage.RecordDouble(50.0, + KeyValueIterableView>(attributes_get), + opentelemetry::context::Context{}); + expected_total_active_get_requests += 50; + storage.RecordDouble(40.0, + KeyValueIterableView>(attributes_put), + opentelemetry::context::Context{}); + expected_total_active_put_requests += 40; + + collection_ts = std::chrono::system_clock::now(); + count_attributes = 0; + storage.Collect(collector.get(), collectors, sdk_start_ts, collection_ts, + [&](const MetricData data) { + for (auto data_attr : data.point_data_attr_) + { + auto sum_data = opentelemetry::nostd::get(data_attr.point_data); + if (opentelemetry::nostd::get( + data_attr.attributes.find("RequestType")->second) == "GET") + { + EXPECT_EQ(opentelemetry::nostd::get(sum_data.value_), + expected_total_active_get_requests); + count_attributes++; + } + else if (opentelemetry::nostd::get( + data_attr.attributes.find("RequestType")->second) == "PUT") + { + EXPECT_EQ(opentelemetry::nostd::get(sum_data.value_), + expected_total_active_put_requests); + count_attributes++; + } + } + return true; + }); + EXPECT_EQ(count_attributes, 2); // GET and PUT +} +INSTANTIATE_TEST_SUITE_P(WritableMetricStorageTestDouble, + WritableMetricStorageTestFixture, + ::testing::Values(AggregationTemporality::kCumulative, + AggregationTemporality::kDelta)); + +#endif diff --git a/sdk/test/trace/tracer_test.cc b/sdk/test/trace/tracer_test.cc index 15a7566b9b..3287b39e5d 100644 --- a/sdk/test/trace/tracer_test.cc +++ b/sdk/test/trace/tracer_test.cc @@ -48,13 +48,17 @@ class MockSampler final : public Sampler return {Decision::RECORD_AND_SAMPLE, nostd::unique_ptr>( new const std::map( - {{"sampling_attr1", 123}, {"sampling_attr2", "string"}}))}; + {{"sampling_attr1", 123}, {"sampling_attr2", "string"}})), + nostd::shared_ptr(nullptr)}; } else { // we should never reach here assert(false); - return {Decision::DROP}; + return {Decision::DROP, + nostd::unique_ptr>( + nullptr), + nostd::shared_ptr(nullptr)}; } } @@ -719,10 +723,10 @@ TEST(Tracer, SpanCleanupWithScope) auto span0 = tracer->StartSpan("Span0"); auto span1 = tracer->StartSpan("span1"); { - trace_api::Scope scope(span1); + trace_api::Scope scope1(span1); auto span2 = tracer->StartSpan("span2"); { - trace_api::Scope scope(span2); + trace_api::Scope scope2(span2); auto span3 = tracer->StartSpan("span3"); } } diff --git a/third_party_release b/third_party_release index 2ae3f75bab..c1801018b4 100644 --- a/third_party_release +++ b/third_party_release @@ -20,4 +20,4 @@ ms-gsl=v3.1.0-67-g6f45293 nlohmann-json=v3.10.5 opentelemetry-proto=v0.19.0 prometheus-cpp=v1.0.0 -vcpkg=2022.04.12 +vcpkg=2022.08.15 diff --git a/tools/vcpkg b/tools/vcpkg index 5568f110b5..acc3bcf76b 160000 --- a/tools/vcpkg +++ b/tools/vcpkg @@ -1 +1 @@ -Subproject commit 5568f110b509a9fd90711978a7cb76bae75bb092 +Subproject commit acc3bcf76b84ae5041c86ab55fe138ae7b8255c7