diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index 92981bc8d1..fbc746574a 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -35,7 +35,7 @@ jobs: mv api-benchmark_result.json benchmarks mv sdk-benchmark_result.json benchmarks mv exporters-benchmark_result.json benchmarks - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: benchmark_results path: benchmarks diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3f516dc385..04568539e3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -202,6 +202,22 @@ jobs: - name: run tests run: ./ci/do_ci.ps1 cmake.maintainer.test + cmake_msvc_maintainer_test_stl_cxx20: + name: CMake msvc (maintainer mode) with C++20 + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: 'recursive' + - name: setup + run: | + ./ci/setup_windows_cmake.ps1 + ./ci/setup_windows_ci_environment.ps1 + - name: run tests + env: + CXX_STANDARD: '20' + run: ./ci/do_ci.ps1 cmake.maintainer.cxx20.stl.test + cmake_with_async_export_test: name: CMake test (without otlp-exporter and with async export) runs-on: ubuntu-latest @@ -683,7 +699,7 @@ jobs: env BENCHMARK_DIR=/benchmark ./ci/do_ci.sh benchmark - name: Upload benchmark results - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: benchmark_reports path: /home/runner/benchmark diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 2d84fcff1c..7d6f5d2747 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -27,10 +27,10 @@ jobs: sudo -E ./ci/setup_cmake.sh sudo -E ./ci/setup_ci_environment.sh - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: cpp - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@v3 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/dependencies_image.yml b/.github/workflows/dependencies_image.yml index 2273dc66bb..723fd1256b 100644 --- a/.github/workflows/dependencies_image.yml +++ b/.github/workflows/dependencies_image.yml @@ -39,7 +39,7 @@ jobs: docker save -o /opt/otel-cpp-deps-debian.tar otel-cpp-deps - name: Upload Image - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: otel-cpp-deps path: /opt/otel-cpp-deps-debian.tar diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 65c084eb93..8949173a42 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -7,7 +7,7 @@ jobs: stale: runs-on: ubuntu-latest steps: - - uses: actions/stale@v8 + - uses: actions/stale@v9 with: stale-issue-message: "This issue was marked as stale due to lack of activity." days-before-issue-stale: 60 diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f89ef1505..e8379620fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,20 +15,88 @@ Increment the: ## [Unreleased] +* [REMOVAL] Remove option WITH_OTLP_HTTP_SSL_PREVIEW + [#2435](https://github.com/open-telemetry/opentelemetry-cpp/pull/2435) +* [BUILD] Fix removing of NOMINMAX on Windows + [#2449](https://github.com/open-telemetry/opentelemetry-cpp/pull/2449) +* [BUILD] Introduce CXX 20 CI pipeline for MSVC/Windows + [#2450](https://github.com/open-telemetry/opentelemetry-cpp/pull/2450) +* [EXPORTER] Set `is_monotonic` flag for Observable Counters + [#2478](https://github.com/open-telemetry/opentelemetry-cpp/pull/2478) + +Important changes: + +Breaking changes: + +* [REMOVAL] Remove option WITH_OTLP_HTTP_SSL_PREVIEW + [#2435](https://github.com/open-telemetry/opentelemetry-cpp/pull/2435) + * CMake options `WITH_OTLP_HTTP_SSL_PREVIEW` + and `WITH_OTLP_HTTP_SSL_TLS_PREVIEW` are removed. + Building opentelemetry-cpp without SSL support is no longer possible. + +## [1.13.0] 2023-12-06 + * [BUILD] Remove WITH_REMOVE_METER_PREVIEW, use WITH_ABI_VERSION_2 instead [#2370](https://github.com/open-telemetry/opentelemetry-cpp/pull/2370) +* [SDK] Metrics ObservableRegistry Cleanup + [#2376](https://github.com/open-telemetry/opentelemetry-cpp/pull/2376) * [BUILD] Make WITH_OTLP_HTTP_SSL_PREVIEW mainstream [#2378](https://github.com/open-telemetry/opentelemetry-cpp/pull/2378) +* [SDK] Creating DoubleUpDownCounter with no matching view + [#2379](https://github.com/open-telemetry/opentelemetry-cpp/pull/2379) * [API] Add InstrumentationScope attributes in TracerProvider::GetTracer() [#2371](https://github.com/open-telemetry/opentelemetry-cpp/pull/2371) +* [BUILD] DLL export interface for Metrics + [#2344](https://github.com/open-telemetry/opentelemetry-cpp/pull/2344) * [BUILD] enum CanonicalCode names too generic... conflict with old C defines [#2385](https://github.com/open-telemetry/opentelemetry-cpp/pull/2385) +* [BUILD] Fix cpack broken package version + [#2386](https://github.com/open-telemetry/opentelemetry-cpp/pull/2386) * [API] Add a new AddLink() operation to Span [#2380](https://github.com/open-telemetry/opentelemetry-cpp/pull/2380) +* [opentracing-shim] Add check for sampled context + [#2390](https://github.com/open-telemetry/opentelemetry-cpp/pull/2390) +* [BUILD] Fix exported definitions when building DLL with STL + [#2387](https://github.com/open-telemetry/opentelemetry-cpp/pull/2387) +* [BUILD] Add missing includes to runtime_context_test + [#2395](https://github.com/open-telemetry/opentelemetry-cpp/pull/2395) +* [ADMIN] Add file .github/repository-settings.md + [#2392](https://github.com/open-telemetry/opentelemetry-cpp/pull/2392) * [SDK] Fix GetLogger with empty library name [#2398](https://github.com/open-telemetry/opentelemetry-cpp/pull/2398) +* [TEST] Fix compiling problem and removed -DENABLE_TEST + [#2401](https://github.com/open-telemetry/opentelemetry-cpp/pull/2401) +* [BUILD] Check windows options are not passed to non-Windows build + [#2399](https://github.com/open-telemetry/opentelemetry-cpp/pull/2399) * [EXPORTER] Rework OTLP/HTTP and OTLP/GRPC exporter options [#2388](https://github.com/open-telemetry/opentelemetry-cpp/pull/2388) +* [Build] Update vcpkg to latest release + [#2412](https://github.com/open-telemetry/opentelemetry-cpp/pull/2412) +* [SDK] Cardinality limits for metrics streams + (Sync Instruments + Delta Temporality) + [#2255](https://github.com/open-telemetry/opentelemetry-cpp/pull/2255) +* [EXPORTER] Prometheus: Add unit to names, convert to word + [#2213](https://github.com/open-telemetry/opentelemetry-cpp/pull/2213) +* [Metrics] Make context optional for histogram instruments in Metrics SDK + [#2416](https://github.com/open-telemetry/opentelemetry-cpp/pull/2416) +* [BUILD] Fix references to trace namespace to be fully qualified + [#2422](https://github.com/open-telemetry/opentelemetry-cpp/pull/2422) +* [BUILD] Bump third_party/googletest to same version as bazel + [#2421](https://github.com/open-telemetry/opentelemetry-cpp/pull/2421) +* [BUILD] Remove defining NOMINMAX from api + [#2420](https://github.com/open-telemetry/opentelemetry-cpp/pull/2420) +* [BUILD] 'uint8_t' not declared in this scope with gcc 13.2.1 + [#2423](https://github.com/open-telemetry/opentelemetry-cpp/pull/2423) +* [BUILD] Improve the handling of OPENTELEMETRY_HAVE_WORKING_REGEX + [#2430](https://github.com/open-telemetry/opentelemetry-cpp/pull/2430) +* [SEMANTIC CONVENTION] Upgrade to semconv 1.23.1 + [#2428](https://github.com/open-telemetry/opentelemetry-cpp/pull/2428) +* [BUILD] Use fully qualified references to trace/common namespace + [#2424](https://github.com/open-telemetry/opentelemetry-cpp/pull/2424) +* [API] Create root span with active span + [#2427](https://github.com/open-telemetry/opentelemetry-cpp/pull/2427) +* [REMOVAL] Remove ZPAGES + [#2433](https://github.com/open-telemetry/opentelemetry-cpp/pull/2433) Important changes: @@ -101,6 +169,11 @@ Breaking changes: * Please check configuration variables, to make sure `_LOGS_` variables are set as expected. +* [REMOVAL] Remove ZPAGES + [#2433](https://github.com/open-telemetry/opentelemetry-cpp/pull/2433) + * As announced in release 1.12.0, + the deprecated ZPAGES exporter is now removed. + ## [1.12.0] 2023-10-16 * [BUILD] Support `pkg-config` diff --git a/CMakeLists.txt b/CMakeLists.txt index a5417de7fc..b412b91672 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -212,9 +212,6 @@ option(WITH_PROMETHEUS "Whether to include the Prometheus Client in the SDK" option(WITH_ELASTICSEARCH "Whether to include the Elasticsearch Client in the SDK" OFF) -option(WITH_ZPAGES - "DEPRECATED - Whether to include the Zpages Server in the SDK" OFF) - option(WITH_NO_GETENV "Whether the platform supports environment variables" OFF) option(BUILD_TESTING "Whether to enable tests" ON) @@ -281,25 +278,10 @@ endif() option(WITH_ASYNC_EXPORT_PREVIEW "Whether to enable async export" OFF) -# STABLE -option(WITH_OTLP_HTTP_SSL_PREVIEW "Whether to enable otlp http ssl export" ON) - -# STABLE -option(WITH_OTLP_HTTP_SSL_TLS_PREVIEW - "Whether to enable otlp http ssl tls min/max/cipher options" ON) - # Exemplar specs status is experimental, so behind feature flag by default option(WITH_METRICS_EXEMPLAR_PREVIEW "Whether to enable exemplar within metrics" OFF) -if(WITH_ZPAGES) - if(WITH_NO_DEPRECATED_CODE) - message(FATAL_ERROR "WITH_ZPAGES is DEPRECATED.") - else() - message(WARNING "WITH_ZPAGES is DEPRECATED.") - endif() -endif() - # # Verify options dependencies # @@ -308,13 +290,6 @@ if(WITH_EXAMPLES_HTTP AND NOT WITH_EXAMPLES) message(FATAL_ERROR "WITH_EXAMPLES_HTTP=ON requires WITH_EXAMPLES=ON") endif() -if(WITH_OTLP_HTTP_SSL_TLS_PREVIEW AND NOT WITH_OTLP_HTTP_SSL_PREVIEW) - message( - FATAL_ERROR - "WITH_OTLP_HTTP_SSL_TLS_PREVIEW=ON requires WITH_OTLP_HTTP_SSL_PREVIEW=ON" - ) -endif() - find_package(Threads) function(install_windows_deps) @@ -482,7 +457,6 @@ endif() if(WITH_ELASTICSEARCH OR WITH_ZIPKIN OR WITH_OTLP_HTTP - OR WITH_ZPAGES OR BUILD_W3CTRACECONTEXT_TEST OR WITH_ETW) set(USE_NLOHMANN_JSON ON) @@ -592,12 +566,10 @@ if(BUILD_TESTING) ${CMAKE_CURRENT_SOURCE_DIR}/third_party/googletest/googletest/include ${CMAKE_CURRENT_SOURCE_DIR}/third_party/googletest/googlemock/include) if(TARGET gtest) - set(GTEST_BOTH_LIBRARIES gtest gtest_main gmock) + set(GTEST_BOTH_LIBRARIES gtest gtest_main) else() - set(GTEST_BOTH_LIBRARIES - ${CMAKE_BINARY_DIR}/lib/libgtest.a - ${CMAKE_BINARY_DIR}/lib/libgtest_main.a - ${CMAKE_BINARY_DIR}/lib/libgmock.a) + set(GTEST_BOTH_LIBRARIES ${CMAKE_BINARY_DIR}/lib/libgtest.a + ${CMAKE_BINARY_DIR}/lib/libgtest_main.a) endif() elseif(WIN32) # Make sure we are always bootsrapped with vcpkg on Windows @@ -614,7 +586,7 @@ if(BUILD_TESTING) if(NOT GTEST_BOTH_LIBRARIES) # New GTest package names if(TARGET GTest::gtest) - set(GTEST_BOTH_LIBRARIES GTest::gtest GTest::gtest_main GTest::gmock) + set(GTEST_BOTH_LIBRARIES GTest::gtest GTest::gtest_main) elseif(TARGET GTest::GTest) set(GTEST_BOTH_LIBRARIES GTest::GTest GTest::Main) endif() diff --git a/DEPRECATED.md b/DEPRECATED.md index c9ad356696..0632f50503 100644 --- a/DEPRECATED.md +++ b/DEPRECATED.md @@ -92,89 +92,7 @@ N/A ## [opentelemetry-cpp Exporter] -### ZPages exporter - -#### Announcement (ZPages) - -* Version: 1.11.0 -* Date: 2023-09-01 -* PR: [DEPRECATION] Deprecate ZPAGES - [#2291](https://github.com/open-telemetry/opentelemetry-cpp/pull/2291) - -#### Motivation (ZPages) - -The ZPages specification itself was introduced in 2020, -and has been experimental ever since, -not getting a lot of attention, and never reaching a stable status. - -Several other opentelemetry projects have implemented support for zpages, -only to later deprecate and then remove the zpages implementation (Java, -C#), abandoning the zpages feature. - -In this context, it does not make sense to continue to maintain the zpages -code in opentelemetry-cpp. - -#### Scope (ZPages) - -The following are deprecated and planned for removal: - -* all the API headers located under - `ext/include/opentelemetry/ext/zpages/`, including: - * the C++ class `ThreadsafeSpanData` - * the C++ class `TracezDataAggregator` - * the C++ class `TracezHttpServer` - * the C++ class `TracezSpanProcessor` - * the C++ class `TracezSharedData` - * the C++ class `ZPages` - * the C++ class `zPagesHttpServer` -* all the code and doc located under `ext/src/zpages/` -* all the tests located under `ext/test/zpages/` -* the zpages exporter library(`opentelemetry_zpages`) -* the zpages build options in CMake (`WITH_ZPAGES`) - -The following code is no longer considered public, will no longer be -installed, and will no longer be useable outside of -the opentelemetry-cpp implementation: - -* all the API headers located under - `ext/include/opentelemetry/ext/http/server`, including: - * the C++ class `FileHttpServer` - * the C++ class `HttpRequestCallback` - * the C++ class `HttpServer` - * the C++ class `HttpRequestHandler` - * the C++ class `SocketCallback` - -This implementation of an HTTP server is meant to be used for testing only, -it is not production ready. - -#### Mitigation (ZPages) - -Consider using a different exporter, -for example the OTLP exporter (both OTLP HTTP and OTLP GRPC are supported), -to expose trace data to a separate trace backend. - -Note that this changes the access pattern: - -* with zpages, data is only available locally (in process) -* with other exporters, data is available externally (not in process) - -Our assessment is that the zpages implementation is no longer in use, -and can be removed. - -If that assessment is incorrect (i.e., if you own a project that depends -on the zpage exporter from opentelemetry-cpp), please comment on the -removal issue -[#2292](https://github.com/open-telemetry/opentelemetry-cpp/issues/2292). - -An alternative to zpage removal is to move the code to the -opentelemetry-cpp-contrib github -[repository](https://github.com/open-telemetry/opentelemetry-cpp-contrib). - -Contributions to migrate the code, and maintain zpages, are welcome. - -#### Planned removal (ZPages) - -* Date: December, 2023 +N/A ## [Documentation] diff --git a/INSTALL.md b/INSTALL.md index 68fefff1fe..9cd9cef6e2 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -124,10 +124,6 @@ You can link OpenTelemetry C++ SDK with libraries provided in -- Installing: //lib/cmake/opentelemetry-cpp/opentelemetry-cpp-config.cmake -- Installing: //lib/cmake/opentelemetry-cpp/opentelemetry-cpp-config-version.cmake ... - -- Installing: //include/opentelemetry//ext/zpages/static/tracez_index.h - -- Installing: //include/opentelemetry//ext/zpages/static/tracez_style.h - -- Installing: //include/opentelemetry//ext/zpages/threadsafe_span_data.h - -- Installing: //lib/libopentelemetry_zpages.a $ ``` diff --git a/api/CMakeLists.txt b/api/CMakeLists.txt index ecbb377725..14332e295b 100644 --- a/api/CMakeLists.txt +++ b/api/CMakeLists.txt @@ -17,13 +17,6 @@ if(OPENTELEMETRY_INSTALL) LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) - install( - DIRECTORY include/opentelemetry - DESTINATION include - FILES_MATCHING - PATTERN "*.h" - PATTERN "metrics" EXCLUDE) - install( DIRECTORY include/opentelemetry DESTINATION include @@ -104,7 +97,6 @@ if(WITH_NO_GETENV) endif() if(WIN32) - target_compile_definitions(opentelemetry_api INTERFACE NOMINMAX) if(WITH_ETW) target_compile_definitions(opentelemetry_api INTERFACE HAVE_MSGPACK) endif() @@ -118,21 +110,6 @@ target_compile_definitions( opentelemetry_api INTERFACE OPENTELEMETRY_ABI_VERSION_NO=${OPENTELEMETRY_ABI_VERSION_NO}) -# A better place should be in sdk, not api -if(WITH_OTLP_HTTP_SSL_PREVIEW) - target_compile_definitions(opentelemetry_api - INTERFACE ENABLE_OTLP_HTTP_SSL_PREVIEW) - target_compile_definitions(opentelemetry_api - INTERFACE ENABLE_HTTP_SSL_PREVIEW) - - if(WITH_OTLP_HTTP_SSL_TLS_PREVIEW) - target_compile_definitions(opentelemetry_api - INTERFACE ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW) - target_compile_definitions(opentelemetry_api - INTERFACE ENABLE_HTTP_SSL_TLS_PREVIEW) - endif() -endif() - if(WITH_OTLP_GRPC_SSL_MTLS_PREVIEW) target_compile_definitions(opentelemetry_api INTERFACE ENABLE_OTLP_GRPC_SSL_MTLS_PREVIEW) diff --git a/api/include/opentelemetry/common/spin_lock_mutex.h b/api/include/opentelemetry/common/spin_lock_mutex.h index 1877c8eb40..ac52f700bc 100644 --- a/api/include/opentelemetry/common/spin_lock_mutex.h +++ b/api/include/opentelemetry/common/spin_lock_mutex.h @@ -10,9 +10,6 @@ #include "opentelemetry/version.h" #if defined(_MSC_VER) -# ifndef NOMINMAX -# define NOMINMAX -# endif # define _WINSOCKAPI_ // stops including winsock.h # include #elif defined(__i386__) || defined(__x86_64__) diff --git a/api/include/opentelemetry/common/timestamp.h b/api/include/opentelemetry/common/timestamp.h index 14aa457b5b..f7c79b8b57 100644 --- a/api/include/opentelemetry/common/timestamp.h +++ b/api/include/opentelemetry/common/timestamp.h @@ -178,7 +178,7 @@ class DurationUtil std::chrono::duration indefinite_value) noexcept { // Do not call now() when this duration is max value, now() may have a expensive cost. - if (timeout == std::chrono::duration::max()) + if (timeout == (std::chrono::duration::max)()) { return indefinite_value; } @@ -186,13 +186,13 @@ class DurationUtil // std::future::wait_for, std::this_thread::sleep_for, and std::condition_variable::wait_for // may use steady_clock or system_clock.We need make sure now() + timeout do not overflow. auto max_timeout = std::chrono::duration_cast>( - std::chrono::steady_clock::time_point::max() - std::chrono::steady_clock::now()); + (std::chrono::steady_clock::time_point::max)() - std::chrono::steady_clock::now()); if (timeout >= max_timeout) { return indefinite_value; } max_timeout = std::chrono::duration_cast>( - std::chrono::system_clock::time_point::max() - std::chrono::system_clock::now()); + (std::chrono::system_clock::time_point::max)() - std::chrono::system_clock::now()); if (timeout >= max_timeout) { return indefinite_value; diff --git a/api/include/opentelemetry/metrics/noop.h b/api/include/opentelemetry/metrics/noop.h index f20e855cb7..d34a0e681b 100644 --- a/api/include/opentelemetry/metrics/noop.h +++ b/api/include/opentelemetry/metrics/noop.h @@ -44,6 +44,13 @@ class NoopHistogram : public Histogram const common::KeyValueIterable & /* attributes */, const context::Context & /* context */) noexcept override {} +#if OPENTELEMETRY_ABI_VERSION_NO >= 2 + void Record(T /*value*/, + const opentelemetry::common::KeyValueIterable & /*attributes*/) noexcept override + {} + + void Record(T /*value*/) noexcept override {} +#endif }; template diff --git a/api/include/opentelemetry/metrics/sync_instruments.h b/api/include/opentelemetry/metrics/sync_instruments.h index b26e527c2c..4471677433 100644 --- a/api/include/opentelemetry/metrics/sync_instruments.h +++ b/api/include/opentelemetry/metrics/sync_instruments.h @@ -22,31 +22,43 @@ class SynchronousInstrument virtual ~SynchronousInstrument() = default; }; +/* A Counter instrument that adds values. */ template class Counter : public SynchronousInstrument { public: /** - * Add adds the value to the counter's sum + * Record a value * * @param value The increment amount. MUST be non-negative. */ virtual void Add(T value) noexcept = 0; + /** + * Record a value + * + * @param value The increment amount. MUST be non-negative. + * @param context The explicit context to associate with this measurement. + */ virtual void Add(T value, const context::Context &context) noexcept = 0; /** - * Add adds the value to the counter's sum. The attributes should contain - * the keys and values to be associated with this value. Counters only - * accept positive valued updates. + * Record a value with a set of attributes. * * @param value The increment amount. MUST be non-negative. - * @param attributes the set of attributes, as key-value pairs + * @param attributes A set of attributes to associate with the value. */ virtual void Add(T value, const common::KeyValueIterable &attributes) noexcept = 0; + /** + * Record a value with a set of attributes. + * + * @param value The increment amount. MUST be non-negative. + * @param attributes A set of attributes to associate with the value. + * @param context The explicit context to associate with this measurement. + */ virtual void Add(T value, const common::KeyValueIterable &attributes, const context::Context &context) noexcept = 0; @@ -55,8 +67,7 @@ class Counter : public SynchronousInstrument nostd::enable_if_t::value> * = nullptr> void Add(T value, const U &attributes) noexcept { - auto context = context::Context{}; - this->Add(value, common::KeyValueIterableView{attributes}, context); + this->Add(value, common::KeyValueIterableView{attributes}); } template > attributes) noexcept { - auto context = context::Context{}; - this->Add(value, - nostd::span>{ - attributes.begin(), attributes.end()}, - context); + this->Add(value, nostd::span>{ + attributes.begin(), attributes.end()}); } void Add(T value, @@ -94,18 +102,54 @@ template class Histogram : public SynchronousInstrument { public: +#if OPENTELEMETRY_ABI_VERSION_NO >= 2 /** + * @since ABI_VERSION 2 * Records a value. * * @param value The measurement value. MUST be non-negative. */ + virtual void Record(T value) noexcept = 0; + + /** + * @since ABI_VERSION 2 + * Records a value with a set of attributes. + * + * @param value The measurement value. MUST be non-negative. + * @param attribute A set of attributes to associate with the value. + */ + virtual void Record(T value, const common::KeyValueIterable &attribute) noexcept = 0; + + template ::value> * = nullptr> + void Record(T value, const U &attributes) noexcept + { + this->Record(value, common::KeyValueIterableView{attributes}); + } + + void Record(T value, + std::initializer_list> + attributes) noexcept + { + this->Record(value, nostd::span>{ + attributes.begin(), attributes.end()}); + } +#endif + + /** + * Records a value. + * + * @param value The measurement value. MUST be non-negative. + * @param context The explicit context to associate with this measurement. + */ virtual void Record(T value, const context::Context &context) noexcept = 0; /** * Records a value with a set of attributes. * * @param value The measurement value. MUST be non-negative. - * @param attributes A set of attributes to associate with the count. + * @param attributes A set of attributes to associate with the value.. + * @param context The explicit context to associate with this measurement. */ virtual void Record(T value, const common::KeyValueIterable &attributes, @@ -137,22 +181,35 @@ class UpDownCounter : public SynchronousInstrument { public: /** - * Adds a value. + * Record a value. * - * @param value The amount of the measurement. + * @param value The increment amount. May be positive, negative or zero. */ virtual void Add(T value) noexcept = 0; + /** + * Record a value. + * + * @param value The increment amount. May be positive, negative or zero. + * @param context The explicit context to associate with this measurement. + */ virtual void Add(T value, const context::Context &context) noexcept = 0; /** - * Add a value with a set of attributes. + * Record a value with a set of attributes. * * @param value The increment amount. May be positive, negative or zero. * @param attributes A set of attributes to associate with the count. */ virtual void Add(T value, const common::KeyValueIterable &attributes) noexcept = 0; + /** + * Record a value with a set of attributes. + * + * @param value The increment amount. May be positive, negative or zero. + * @param attributes A set of attributes to associate with the count. + * @param context The explicit context to associate with this measurement. + */ virtual void Add(T value, const common::KeyValueIterable &attributes, const context::Context &context) noexcept = 0; @@ -161,8 +218,7 @@ class UpDownCounter : public SynchronousInstrument nostd::enable_if_t::value> * = nullptr> void Add(T value, const U &attributes) noexcept { - auto context = context::Context{}; - this->Add(value, common::KeyValueIterableView{attributes}, context); + this->Add(value, common::KeyValueIterableView{attributes}); } template > attributes) noexcept { - auto context = context::Context{}; - this->Add(value, - nostd::span>{ - attributes.begin(), attributes.end()}, - context); + this->Add(value, nostd::span>{ + attributes.begin(), attributes.end()}); } void Add(T value, diff --git a/api/include/opentelemetry/plugin/detail/dynamic_load_windows.h b/api/include/opentelemetry/plugin/detail/dynamic_load_windows.h index 3f5e05f198..5ed2833756 100644 --- a/api/include/opentelemetry/plugin/detail/dynamic_load_windows.h +++ b/api/include/opentelemetry/plugin/detail/dynamic_load_windows.h @@ -12,9 +12,6 @@ #include "opentelemetry/plugin/hook.h" #include "opentelemetry/version.h" -#ifndef NOMINMAX -# define NOMINMAX -#endif #include #include diff --git a/api/include/opentelemetry/std/span.h b/api/include/opentelemetry/std/span.h index 2a3dc12a84..1160d54fbe 100644 --- a/api/include/opentelemetry/std/span.h +++ b/api/include/opentelemetry/std/span.h @@ -60,7 +60,7 @@ OPENTELEMETRY_END_NAMESPACE OPENTELEMETRY_BEGIN_NAMESPACE namespace nostd { -constexpr std::size_t dynamic_extent = (std::numeric_limits::max()); +constexpr std::size_t dynamic_extent = (std::numeric_limits::max)(); template using span = std::span; diff --git a/api/include/opentelemetry/trace/context.h b/api/include/opentelemetry/trace/context.h index b68fe9e95a..cd8395d768 100644 --- a/api/include/opentelemetry/trace/context.h +++ b/api/include/opentelemetry/trace/context.h @@ -23,6 +23,16 @@ inline nostd::shared_ptr GetSpan(const context::Context &context) noexcept return nostd::shared_ptr(new DefaultSpan(SpanContext::GetInvalid())); } +inline bool IsRootSpan(const context::Context &context) noexcept +{ + context::ContextValue is_root_span = context.GetValue(kIsRootSpanKey); + if (nostd::holds_alternative(is_root_span)) + { + return nostd::get(is_root_span); + } + return false; +} + // Set Span into explicit context inline context::Context SetSpan(context::Context &context, nostd::shared_ptr span) noexcept { diff --git a/api/include/opentelemetry/trace/propagation/detail/hex.h b/api/include/opentelemetry/trace/propagation/detail/hex.h index c8bd58f8b8..157f5ec42a 100644 --- a/api/include/opentelemetry/trace/propagation/detail/hex.h +++ b/api/include/opentelemetry/trace/propagation/detail/hex.h @@ -4,6 +4,7 @@ #pragma once #include +#include #include #include "opentelemetry/nostd/string_view.h" diff --git a/api/include/opentelemetry/trace/semantic_conventions.h b/api/include/opentelemetry/trace/semantic_conventions.h index 16d6562ee9..49f507c90b 100644 --- a/api/include/opentelemetry/trace/semantic_conventions.h +++ b/api/include/opentelemetry/trace/semantic_conventions.h @@ -22,16 +22,16 @@ namespace SemanticConventions /** * The URL of the OpenTelemetry schema for these keys and values. */ -static constexpr const char *kSchemaUrl = "https://opentelemetry.io/schemas/1.22.0"; +static constexpr const char *kSchemaUrl = "https://opentelemetry.io/schemas/1.23.1"; /** - * Client address - domain name if available without reverse DNS lookup, otherwise IP address or + * Client address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. * *

Notes:

  • When observed from the server side, and when communicating through an intermediary, - {@code client.address} SHOULD represent the client address behind any intermediaries (e.g. proxies) - if it's available.
+ {@code client.address} SHOULD represent the client address behind any intermediaries, for example + proxies, if it's available. */ static constexpr const char *kClientAddress = "client.address"; @@ -40,125 +40,19 @@ static constexpr const char *kClientAddress = "client.address"; * *

Notes:

  • When observed from the server side, and when communicating through an intermediary, - {@code client.port} SHOULD represent the client port behind any intermediaries (e.g. proxies) if - it's available.
+ {@code client.port} SHOULD represent the client port behind any intermediaries, for example + proxies, if it's available. */ static constexpr const char *kClientPort = "client.port"; /** - * Deprecated, use {@code server.address}. - * - * @deprecated Deprecated, use `server.address`. - */ -OPENTELEMETRY_DEPRECATED -static constexpr const char *kNetHostName = "net.host.name"; - -/** - * Deprecated, use {@code server.port}. - * - * @deprecated Deprecated, use `server.port`. - */ -OPENTELEMETRY_DEPRECATED -static constexpr const char *kNetHostPort = "net.host.port"; - -/** - * Deprecated, use {@code server.address} on client spans and {@code client.address} on server - * spans. - * - * @deprecated Deprecated, use `server.address` on client spans and `client.address` on server - * spans. - */ -OPENTELEMETRY_DEPRECATED -static constexpr const char *kNetPeerName = "net.peer.name"; - -/** - * Deprecated, use {@code server.port} on client spans and {@code client.port} on server spans. - * - * @deprecated Deprecated, use `server.port` on client spans and `client.port` on server spans. - */ -OPENTELEMETRY_DEPRECATED -static constexpr const char *kNetPeerPort = "net.peer.port"; - -/** - * Deprecated, use {@code network.protocol.name}. - * - * @deprecated Deprecated, use `network.protocol.name`. - */ -OPENTELEMETRY_DEPRECATED -static constexpr const char *kNetProtocolName = "net.protocol.name"; - -/** - * Deprecated, use {@code network.protocol.version}. - * - * @deprecated Deprecated, use `network.protocol.version`. - */ -OPENTELEMETRY_DEPRECATED -static constexpr const char *kNetProtocolVersion = "net.protocol.version"; - -/** - * Deprecated, use {@code network.transport} and {@code network.type}. - * - * @deprecated Deprecated, use `network.transport` and `network.type`. - */ -OPENTELEMETRY_DEPRECATED -static constexpr const char *kNetSockFamily = "net.sock.family"; - -/** - * Deprecated, use {@code network.local.address}. - * - * @deprecated Deprecated, use `network.local.address`. - */ -OPENTELEMETRY_DEPRECATED -static constexpr const char *kNetSockHostAddr = "net.sock.host.addr"; - -/** - * Deprecated, use {@code network.local.port}. - * - * @deprecated Deprecated, use `network.local.port`. - */ -OPENTELEMETRY_DEPRECATED -static constexpr const char *kNetSockHostPort = "net.sock.host.port"; - -/** - * Deprecated, use {@code network.peer.address}. - * - * @deprecated Deprecated, use `network.peer.address`. - */ -OPENTELEMETRY_DEPRECATED -static constexpr const char *kNetSockPeerAddr = "net.sock.peer.addr"; - -/** - * Deprecated, no replacement at this time. - * - * @deprecated Deprecated, no replacement at this time. - */ -OPENTELEMETRY_DEPRECATED -static constexpr const char *kNetSockPeerName = "net.sock.peer.name"; - -/** - * Deprecated, use {@code network.peer.port}. - * - * @deprecated Deprecated, use `network.peer.port`. - */ -OPENTELEMETRY_DEPRECATED -static constexpr const char *kNetSockPeerPort = "net.sock.peer.port"; - -/** - * Deprecated, use {@code network.transport}. - * - * @deprecated Deprecated, use `network.transport`. - */ -OPENTELEMETRY_DEPRECATED -static constexpr const char *kNetTransport = "net.transport"; - -/** - * Destination address - domain name if available without reverse DNS lookup, otherwise IP address + * Destination address - domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain socket name. * *

Notes:

  • When observed from the source side, and when communicating through an intermediary, - {@code destination.address} SHOULD represent the destination address behind any intermediaries - (e.g. proxies) if it's available.
+ {@code destination.address} SHOULD represent the destination address behind any intermediaries, for + example proxies, if it's available. */ static constexpr const char *kDestinationAddress = "destination.address"; @@ -173,14 +67,15 @@ static constexpr const char *kDestinationPort = "destination.port"; *

Notes:

  • The {@code error.type} SHOULD be predictable and SHOULD have low cardinality. Instrumentations SHOULD document the list of errors they report.
  • The cardinality of {@code -error.type} within one instrumentation library SHOULD be low, but telemetry consumers that aggregate +error.type} within one instrumentation library SHOULD be low. Telemetry consumers that aggregate data from multiple instrumentation libraries and applications should be prepared for {@code -error.type} to have high cardinality at query time, when no additional filters are +error.type} to have high cardinality at query time when no additional filters are applied.
  • If the operation has completed successfully, instrumentations SHOULD NOT set {@code -error.type}.
  • If a specific domain defines its own set of error codes (such as HTTP or gRPC -status codes), it's RECOMMENDED to use a domain-specific attribute and also set {@code error.type} -to capture all errors, regardless of whether they are defined within the domain-specific set or -not.
+error.type}.
  • If a specific domain defines its own set of error identifiers (such as HTTP or +gRPC status codes), it's RECOMMENDED to:
  • Use a domain-specific attribute
  • Set {@code +error.type} to capture all errors, regardless of whether they are defined within the domain-specific +set or not.
  • + */ static constexpr const char *kErrorType = "error.type"; @@ -263,57 +158,12 @@ static constexpr const char *kEnduserRole = "enduser.role"; */ static constexpr const char *kEnduserScope = "enduser.scope"; -/** - * Whether the thread is daemon or not. - */ -static constexpr const char *kThreadDaemon = "thread.daemon"; - -/** - * Current "managed" thread ID (as opposed to OS thread ID). - */ -static constexpr const char *kThreadId = "thread.id"; - -/** - * Current thread name. - */ -static constexpr const char *kThreadName = "thread.name"; - -/** - * The column number in {@code code.filepath} best representing the operation. It SHOULD point - * within the code unit named in {@code code.function}. - */ -static constexpr const char *kCodeColumn = "code.column"; - -/** - * The source code file name that identifies the code unit as uniquely as possible (preferably an - * absolute file path). - */ -static constexpr const char *kCodeFilepath = "code.filepath"; - -/** - * The method or function name, or equivalent (usually rightmost part of the code unit's name). - */ -static constexpr const char *kCodeFunction = "code.function"; - -/** - * The line number in {@code code.filepath} best representing the operation. It SHOULD point within - * the code unit named in {@code code.function}. - */ -static constexpr const char *kCodeLineno = "code.lineno"; - -/** - * The "namespace" within which {@code code.function} is defined. Usually the qualified - * class or module name, such that {@code code.namespace} + some separator + {@code code.function} - * form a unique identifier for the code unit. - */ -static constexpr const char *kCodeNamespace = "code.namespace"; - /** * The domain identifies the business context for the events. * *

    Notes: -

    • Events across different domains may have same {@code event.name}, yet be -unrelated events.
    +
    • Events across different domains may have same {@code event.name}, yet be unrelated + events.
    */ static constexpr const char *kEventDomain = "event.domain"; @@ -358,9 +208,31 @@ static constexpr const char *kLogFilePath = "log.file.path"; */ static constexpr const char *kLogFilePathResolved = "log.file.path_resolved"; +/** + * This attribute represents the state the application has transitioned into at the occurrence of + the event. + * + *

    Notes: +

    + */ +static constexpr const char *kIosState = "ios.state"; + +/** + * This attribute represents the state the application has transitioned into at the occurrence of + the event. + * + *

    Notes: +

    + */ +static constexpr const char *kAndroidState = "android.state"; + /** * The name of the connection pool; unique within the instrumented application. In case the - * connection pool implementation does not provide a name, then the db.connection_string * should be used */ @@ -474,96 +346,34 @@ static constexpr const char *kSystemNetworkState = "system.network.state"; static constexpr const char *kSystemProcessesStatus = "system.processes.status"; /** - * Local address of the network connection - IP address or Unix domain socket name. - */ -static constexpr const char *kNetworkLocalAddress = "network.local.address"; - -/** - * Local port number of the network connection. - */ -static constexpr const char *kNetworkLocalPort = "network.local.port"; - -/** - * Peer address of the network connection - IP address or Unix domain socket name. - */ -static constexpr const char *kNetworkPeerAddress = "network.peer.address"; - -/** - * Peer port number of the network connection. - */ -static constexpr const char *kNetworkPeerPort = "network.peer.port"; - -/** - * OSI application layer or non-OSI - equivalent. - * - *

    Notes: -

    • The value SHOULD be normalized to lowercase.
    - */ -static constexpr const char *kNetworkProtocolName = "network.protocol.name"; - -/** - * Version of the protocol specified in {@code network.protocol.name}. - * - *

    Notes: -

    • {@code network.protocol.version} refers to the version of the protocol used and might be - different from the protocol client's version. If the HTTP client used has a version of {@code - 0.27.2}, but sends HTTP version {@code 1.1}, this attribute should be set to {@code 1.1}.
    • -
    - */ -static constexpr const char *kNetworkProtocolVersion = "network.protocol.version"; - -/** - * OSI transport layer or inter-process communication -method. - * - *

    Notes: -

    • The value SHOULD be normalized to lowercase.
    • Consider always setting the -transport when setting a port number, since a port number is ambiguous without knowing the -transport, for example different processes could be listening on TCP port 12345 and UDP port -12345.
    - */ -static constexpr const char *kNetworkTransport = "network.transport"; - -/** - * OSI network layer or non-OSI equivalent. - * - *

    Notes: -

    • The value SHOULD be normalized to lowercase.
    - */ -static constexpr const char *kNetworkType = "network.type"; - -/** - * The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. - */ -static constexpr const char *kNetworkCarrierIcc = "network.carrier.icc"; - -/** - * The mobile carrier country code. + * The column number in {@code code.filepath} best representing the operation. It SHOULD point + * within the code unit named in {@code code.function}. */ -static constexpr const char *kNetworkCarrierMcc = "network.carrier.mcc"; +static constexpr const char *kCodeColumn = "code.column"; /** - * The mobile carrier network code. + * The source code file name that identifies the code unit as uniquely as possible (preferably an + * absolute file path). */ -static constexpr const char *kNetworkCarrierMnc = "network.carrier.mnc"; +static constexpr const char *kCodeFilepath = "code.filepath"; /** - * The name of the mobile carrier. + * The method or function name, or equivalent (usually rightmost part of the code unit's name). */ -static constexpr const char *kNetworkCarrierName = "network.carrier.name"; +static constexpr const char *kCodeFunction = "code.function"; /** - * This describes more details regarding the connection.type. It may be the type of cell technology - * connection, but it could be used for describing details about a wifi connection. + * The line number in {@code code.filepath} best representing the operation. It SHOULD point within + * the code unit named in {@code code.function}. */ -static constexpr const char *kNetworkConnectionSubtype = "network.connection.subtype"; +static constexpr const char *kCodeLineno = "code.lineno"; /** - * The internet connection type. + * The "namespace" within which {@code code.function} is defined. Usually the qualified + * class or module name, such that {@code code.namespace} + some separator + {@code code.function} + * form a unique identifier for the code unit. */ -static constexpr const char *kNetworkConnectionType = "network.connection.type"; +static constexpr const char *kCodeNamespace = "code.namespace"; /** * Deprecated, use {@code http.request.method} instead. @@ -574,17 +384,17 @@ OPENTELEMETRY_DEPRECATED static constexpr const char *kHttpMethod = "http.method"; /** - * Deprecated, use {@code http.request.body.size} instead. + * Deprecated, use {@code http.request.header.content-length} instead. * - * @deprecated Deprecated, use `http.request.body.size` instead. + * @deprecated Deprecated, use `http.request.header.content-length` instead. */ OPENTELEMETRY_DEPRECATED static constexpr const char *kHttpRequestContentLength = "http.request_content_length"; /** - * Deprecated, use {@code http.response.body.size} instead. + * Deprecated, use {@code http.response.header.content-length} instead. * - * @deprecated Deprecated, use `http.response.body.size` instead. + * @deprecated Deprecated, use `http.response.header.content-length` instead. */ OPENTELEMETRY_DEPRECATED static constexpr const char *kHttpResponseContentLength = "http.response_content_length"; @@ -622,12 +432,118 @@ OPENTELEMETRY_DEPRECATED static constexpr const char *kHttpUrl = "http.url"; /** - * The size of the request payload body in bytes. This is the number of bytes transferred excluding - * headers and is often, but not always, present as the Content-Length - * header. For requests using transport encoding, this should be the compressed size. + * Deprecated, use {@code server.address}. + * + * @deprecated Deprecated, use `server.address`. */ -static constexpr const char *kHttpRequestBodySize = "http.request.body.size"; +OPENTELEMETRY_DEPRECATED +static constexpr const char *kNetHostName = "net.host.name"; + +/** + * Deprecated, use {@code server.port}. + * + * @deprecated Deprecated, use `server.port`. + */ +OPENTELEMETRY_DEPRECATED +static constexpr const char *kNetHostPort = "net.host.port"; + +/** + * Deprecated, use {@code server.address} on client spans and {@code client.address} on server + * spans. + * + * @deprecated Deprecated, use `server.address` on client spans and `client.address` on server + * spans. + */ +OPENTELEMETRY_DEPRECATED +static constexpr const char *kNetPeerName = "net.peer.name"; + +/** + * Deprecated, use {@code server.port} on client spans and {@code client.port} on server spans. + * + * @deprecated Deprecated, use `server.port` on client spans and `client.port` on server spans. + */ +OPENTELEMETRY_DEPRECATED +static constexpr const char *kNetPeerPort = "net.peer.port"; + +/** + * Deprecated, use {@code network.protocol.name}. + * + * @deprecated Deprecated, use `network.protocol.name`. + */ +OPENTELEMETRY_DEPRECATED +static constexpr const char *kNetProtocolName = "net.protocol.name"; + +/** + * Deprecated, use {@code network.protocol.version}. + * + * @deprecated Deprecated, use `network.protocol.version`. + */ +OPENTELEMETRY_DEPRECATED +static constexpr const char *kNetProtocolVersion = "net.protocol.version"; + +/** + * Deprecated, use {@code network.transport} and {@code network.type}. + * + * @deprecated Deprecated, use `network.transport` and `network.type`. + */ +OPENTELEMETRY_DEPRECATED +static constexpr const char *kNetSockFamily = "net.sock.family"; + +/** + * Deprecated, use {@code network.local.address}. + * + * @deprecated Deprecated, use `network.local.address`. + */ +OPENTELEMETRY_DEPRECATED +static constexpr const char *kNetSockHostAddr = "net.sock.host.addr"; + +/** + * Deprecated, use {@code network.local.port}. + * + * @deprecated Deprecated, use `network.local.port`. + */ +OPENTELEMETRY_DEPRECATED +static constexpr const char *kNetSockHostPort = "net.sock.host.port"; + +/** + * Deprecated, use {@code network.peer.address}. + * + * @deprecated Deprecated, use `network.peer.address`. + */ +OPENTELEMETRY_DEPRECATED +static constexpr const char *kNetSockPeerAddr = "net.sock.peer.addr"; + +/** + * Deprecated, no replacement at this time. + * + * @deprecated Deprecated, no replacement at this time. + */ +OPENTELEMETRY_DEPRECATED +static constexpr const char *kNetSockPeerName = "net.sock.peer.name"; + +/** + * Deprecated, use {@code network.peer.port}. + * + * @deprecated Deprecated, use `network.peer.port`. + */ +OPENTELEMETRY_DEPRECATED +static constexpr const char *kNetSockPeerPort = "net.sock.peer.port"; + +/** + * Deprecated, use {@code network.transport}. + * + * @deprecated Deprecated, use `network.transport`. + */ +OPENTELEMETRY_DEPRECATED +static constexpr const char *kNetTransport = "net.transport"; + +/** + * The size of the request payload body in bytes. This is the number of bytes transferred excluding + * headers and is often, but not always, present as the Content-Length + * header. For requests using transport encoding, this should be the compressed size. + */ +static constexpr const char *kHttpRequestBodySize = "http.request.body.size"; /** * HTTP request method. @@ -664,7 +580,7 @@ static constexpr const char *kHttpRequestMethodOriginal = "http.request.method_o regardless of what was the cause of the resending (e.g. redirection, authorization failure, 503 Server Unavailable, network issues, or any other). */ -static constexpr const char *kHttpResendCount = "http.resend_count"; +static constexpr const char *kHttpRequestResendCount = "http.request.resend_count"; /** * The size of the response payload body in bytes. This is the number of bytes transferred excluding @@ -680,8 +596,8 @@ static constexpr const char *kHttpResponseBodySize = "http.response.body.size"; static constexpr const char *kHttpResponseStatusCode = "http.response.status_code"; /** - * The matched route (path template in the format used by the respective server framework). See note -below + * The matched route, that is, the path template in the format used by the respective server +framework. * *

    Notes:

    • MUST NOT be populated when this is not supported by the HTTP server framework as the @@ -692,878 +608,1036 @@ one.
    static constexpr const char *kHttpRoute = "http.route"; /** - * Server address - domain name if available without reverse DNS lookup, otherwise IP address or -Unix domain socket name. + * The number of messages sent, received, or processed in the scope of the batching operation. * *

    Notes: -

    • When observed from the client side, and when communicating through an intermediary, -{@code server.address} SHOULD represent the server address behind any intermediaries (e.g. proxies) -if it's available.
    +
    • Instrumentations SHOULD NOT set {@code messaging.batch.message_count} on spans that + operate with a single message. When a messaging client library supports both batch and + single-message API for the same operation, instrumentations SHOULD use {@code + messaging.batch.message_count} for batching APIs and SHOULD NOT use it for single-message + APIs.
    */ -static constexpr const char *kServerAddress = "server.address"; +static constexpr const char *kMessagingBatchMessageCount = "messaging.batch.message_count"; /** - * Server port number. - * - *

    Notes: -

    • When observed from the client side, and when communicating through an intermediary, - {@code server.port} SHOULD represent the server port behind any intermediaries (e.g. proxies) if - it's available.
    + * A unique identifier for the client that consumes or produces a message. */ -static constexpr const char *kServerPort = "server.port"; +static constexpr const char *kMessagingClientId = "messaging.client_id"; /** - * A unique id to identify a session. + * A boolean that is true if the message destination is anonymous (could be unnamed or have + * auto-generated name). */ -static constexpr const char *kSessionId = "session.id"; +static constexpr const char *kMessagingDestinationAnonymous = "messaging.destination.anonymous"; /** - * Source address - domain name if available without reverse DNS lookup, otherwise IP address or - Unix domain socket name. + * The message destination name * *

    Notes: -

    • When observed from the destination side, and when communicating through an intermediary, - {@code source.address} SHOULD represent the source address behind any intermediaries (e.g. proxies) - if it's available.
    - */ -static constexpr const char *kSourceAddress = "source.address"; - -/** - * Source port number +
    • Destination name SHOULD uniquely identify a specific queue, topic or other entity within +the broker. If the broker doesn't have such notion, the destination name SHOULD uniquely identify +the broker.
    */ -static constexpr const char *kSourcePort = "source.port"; +static constexpr const char *kMessagingDestinationName = "messaging.destination.name"; /** - * The full invoked ARN as provided on the {@code Context} passed to the function ({@code - Lambda-Runtime-Invoked-Function-Arn} header on the {@code /runtime/invocation/next} applicable). + * Low cardinality representation of the messaging destination name * *

    Notes: -

    • This may be different from {@code cloud.resource_id} if an alias is involved.
    +
    • Destination names could be constructed from templates. An example would be a destination + name involving a user name or product id. Although the destination name in this case is of high + cardinality, the underlying template is of low cardinality and can be effectively used for grouping + and aggregation.
    */ -static constexpr const char *kAwsLambdaInvokedArn = "aws.lambda.invoked_arn"; +static constexpr const char *kMessagingDestinationTemplate = "messaging.destination.template"; /** - * The event_id - * uniquely identifies the event. + * A boolean that is true if the message destination is temporary and might not exist anymore after + * messages are processed. */ -static constexpr const char *kCloudeventsEventId = "cloudevents.event_id"; +static constexpr const char *kMessagingDestinationTemporary = "messaging.destination.temporary"; /** - * The source - * identifies the context in which an event happened. + * A boolean that is true if the publish message destination is anonymous (could be unnamed or have + * auto-generated name). */ -static constexpr const char *kCloudeventsEventSource = "cloudevents.event_source"; +static constexpr const char *kMessagingDestinationPublishAnonymous = + "messaging.destination_publish.anonymous"; /** - * The version of - * the CloudEvents specification which the event uses. + * The name of the original destination the message was published to + * + *

    Notes: +

    • The name SHOULD uniquely identify a specific queue, topic, or other entity within the +broker. If the broker doesn't have such notion, the original destination name SHOULD uniquely +identify the broker.
    */ -static constexpr const char *kCloudeventsEventSpecVersion = "cloudevents.event_spec_version"; +static constexpr const char *kMessagingDestinationPublishName = + "messaging.destination_publish.name"; /** - * The subject of - * the event in the context of the event producer (identified by source). + * Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not + * producers. */ -static constexpr const char *kCloudeventsEventSubject = "cloudevents.event_subject"; +static constexpr const char *kMessagingKafkaConsumerGroup = "messaging.kafka.consumer.group"; /** - * The event_type - * contains a value describing the type of event related to the originating occurrence. + * Partition the message is sent to. */ -static constexpr const char *kCloudeventsEventType = "cloudevents.event_type"; +static constexpr const char *kMessagingKafkaDestinationPartition = + "messaging.kafka.destination.partition"; /** - * Parent-child Reference type + * Message keys in Kafka are used for grouping alike messages to ensure they're processed on the + same partition. They differ from {@code messaging.message.id} in that they're not unique. If the + key is {@code null}, the attribute MUST NOT be set. * *

    Notes: -

    • The causal relationship between a child Span and a parent Span.
    +
    • If the key type is not string, it's string representation has to be supplied for the + attribute. If the key has no unambiguous, canonical string form, don't include its value.
    • +
    */ -static constexpr const char *kOpentracingRefType = "opentracing.ref_type"; +static constexpr const char *kMessagingKafkaMessageKey = "messaging.kafka.message.key"; /** - * The connection string used to connect to the database. It is recommended to remove embedded - * credentials. + * The offset of a record in the corresponding Kafka partition. */ -static constexpr const char *kDbConnectionString = "db.connection_string"; +static constexpr const char *kMessagingKafkaMessageOffset = "messaging.kafka.message.offset"; /** - * The fully-qualified class name of the Java Database Connectivity - * (JDBC) driver used to connect. + * A boolean that is true if the message is a tombstone. */ -static constexpr const char *kDbJdbcDriverClassname = "db.jdbc.driver_classname"; +static constexpr const char *kMessagingKafkaMessageTombstone = "messaging.kafka.message.tombstone"; /** - * This attribute is used to report the name of the database being accessed. For commands that - switch the database, this should be set to the target database (even if the command fails). + * The size of the message body in bytes. * *

    Notes: -

    • In some SQL databases, the database name to be used is called "schema name". In - case there are multiple layers that could be considered for database name (e.g. Oracle instance - name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema - name).
    +
    • This can refer to both the compressed or uncompressed body size. If both sizes are known, +the uncompressed body size should be used.
    */ -static constexpr const char *kDbName = "db.name"; +static constexpr const char *kMessagingMessageBodySize = "messaging.message.body.size"; /** - * The name of the operation being executed, e.g. the MongoDB command - name such as {@code findAndModify}, or the SQL keyword. + * The conversation ID identifying the conversation to which the message belongs, represented as a + * string. Sometimes called "Correlation ID". + */ +static constexpr const char *kMessagingMessageConversationId = "messaging.message.conversation_id"; + +/** + * The size of the message body and metadata in bytes. * *

    Notes: -

    • When setting this to an SQL keyword, it is not recommended to attempt any client-side - parsing of {@code db.statement} just to get this property, but it should be set if the operation - name is provided by the library being instrumented. If the SQL statement has an ambiguous - operation, or performs more than one operation, this value may be omitted.
    +
    • This can refer to both the compressed or uncompressed size. If both sizes are known, the +uncompressed size should be used.
    */ -static constexpr const char *kDbOperation = "db.operation"; +static constexpr const char *kMessagingMessageEnvelopeSize = "messaging.message.envelope.size"; /** - * The database statement being executed. + * A value used by the messaging system as an identifier for the message, represented as a string. */ -static constexpr const char *kDbStatement = "db.statement"; +static constexpr const char *kMessagingMessageId = "messaging.message.id"; /** - * An identifier for the database management system (DBMS) product being used. See below for a list - * of well-known identifiers. + * A string identifying the kind of messaging operation. + * + *

    Notes: +

    • If a custom value is used, it MUST be of low cardinality.
    */ -static constexpr const char *kDbSystem = "db.system"; +static constexpr const char *kMessagingOperation = "messaging.operation"; /** - * Username for accessing the database. + * RabbitMQ message routing key. */ -static constexpr const char *kDbUser = "db.user"; +static constexpr const char *kMessagingRabbitmqDestinationRoutingKey = + "messaging.rabbitmq.destination.routing_key"; /** - * The Microsoft SQL Server instance - name connecting to. This name is used to determine the port of a named instance. - * - *

    Notes: -

    • If setting a {@code db.mssql.instance_name}, {@code server.port} is no longer required - (but still recommended if non-standard).
    + * Name of the RocketMQ producer/consumer group that is handling the message. The client type is + * identified by the SpanKind. */ -static constexpr const char *kDbMssqlInstanceName = "db.mssql.instance_name"; +static constexpr const char *kMessagingRocketmqClientGroup = "messaging.rocketmq.client_group"; /** - * The consistency level of the query. Based on consistency values from CQL. + * Model of message consumption. This only applies to consumer spans. */ -static constexpr const char *kDbCassandraConsistencyLevel = "db.cassandra.consistency_level"; +static constexpr const char *kMessagingRocketmqConsumptionModel = + "messaging.rocketmq.consumption_model"; /** - * The data center of the coordinating node for a query. + * The delay time level for delay message, which determines the message delay time. */ -static constexpr const char *kDbCassandraCoordinatorDc = "db.cassandra.coordinator.dc"; +static constexpr const char *kMessagingRocketmqMessageDelayTimeLevel = + "messaging.rocketmq.message.delay_time_level"; /** - * The ID of the coordinating node for a query. + * The timestamp in milliseconds that the delay message is expected to be delivered to consumer. */ -static constexpr const char *kDbCassandraCoordinatorId = "db.cassandra.coordinator.id"; +static constexpr const char *kMessagingRocketmqMessageDeliveryTimestamp = + "messaging.rocketmq.message.delivery_timestamp"; /** - * Whether or not the query is idempotent. + * It is essential for FIFO message. Messages that belong to the same message group are always + * processed one by one within the same consumer group. */ -static constexpr const char *kDbCassandraIdempotence = "db.cassandra.idempotence"; +static constexpr const char *kMessagingRocketmqMessageGroup = "messaging.rocketmq.message.group"; /** - * The fetch size used for paging, i.e. how many rows will be returned at once. + * Key(s) of message, another way to mark message besides message id. */ -static constexpr const char *kDbCassandraPageSize = "db.cassandra.page_size"; +static constexpr const char *kMessagingRocketmqMessageKeys = "messaging.rocketmq.message.keys"; /** - * The number of times a query was speculatively executed. Not set or {@code 0} if the query was not - * executed speculatively. + * The secondary classifier of message besides topic. */ -static constexpr const char *kDbCassandraSpeculativeExecutionCount = - "db.cassandra.speculative_execution_count"; +static constexpr const char *kMessagingRocketmqMessageTag = "messaging.rocketmq.message.tag"; /** - * The name of the primary table that the operation is acting upon, including the keyspace name (if - applicable). - * - *

    Notes: -

    • This mirrors the db.sql.table attribute but references cassandra rather than sql. It is - not recommended to attempt any client-side parsing of {@code db.statement} just to get this - property, but it should be set if it is provided by the library being instrumented. If the - operation is acting upon an anonymous table, or more than one table, this value MUST NOT be - set.
    + * Type of message. */ -static constexpr const char *kDbCassandraTable = "db.cassandra.table"; +static constexpr const char *kMessagingRocketmqMessageType = "messaging.rocketmq.message.type"; /** - * The index of the database being accessed as used in the {@code SELECT} command, provided as an integer. To be - * used instead of the generic {@code db.name} attribute. + * Namespace of RocketMQ resources, resources in different namespaces are individual. */ -static constexpr const char *kDbRedisDatabaseIndex = "db.redis.database_index"; +static constexpr const char *kMessagingRocketmqNamespace = "messaging.rocketmq.namespace"; /** - * The collection being accessed within the database stated in {@code db.name}. + * A string identifying the messaging system. */ -static constexpr const char *kDbMongodbCollection = "db.mongodb.collection"; +static constexpr const char *kMessagingSystem = "messaging.system"; /** - * Represents the identifier of an Elasticsearch cluster. + * The ISO 3166-1 alpha-2 2-character country code associated with the mobile carrier network. */ -static constexpr const char *kDbElasticsearchClusterName = "db.elasticsearch.cluster.name"; +static constexpr const char *kNetworkCarrierIcc = "network.carrier.icc"; /** - * Represents the human-readable identifier of the node/instance to which a request was routed. + * The mobile carrier country code. */ -static constexpr const char *kDbElasticsearchNodeName = "db.elasticsearch.node.name"; +static constexpr const char *kNetworkCarrierMcc = "network.carrier.mcc"; /** - * The name of the primary table that the operation is acting upon, including the database name (if - applicable). - * - *

    Notes: -

    • It is not recommended to attempt any client-side parsing of {@code db.statement} just to - get this property, but it should be set if it is provided by the library being instrumented. If the - operation is acting upon an anonymous table, or more than one table, this value MUST NOT be - set.
    + * The mobile carrier network code. */ -static constexpr const char *kDbSqlTable = "db.sql.table"; +static constexpr const char *kNetworkCarrierMnc = "network.carrier.mnc"; /** - * Unique Cosmos client instance id. + * The name of the mobile carrier. */ -static constexpr const char *kDbCosmosdbClientId = "db.cosmosdb.client_id"; +static constexpr const char *kNetworkCarrierName = "network.carrier.name"; /** - * Cosmos client connection mode. + * This describes more details regarding the connection.type. It may be the type of cell technology + * connection, but it could be used for describing details about a wifi connection. */ -static constexpr const char *kDbCosmosdbConnectionMode = "db.cosmosdb.connection_mode"; +static constexpr const char *kNetworkConnectionSubtype = "network.connection.subtype"; /** - * Cosmos DB container name. + * The internet connection type. */ -static constexpr const char *kDbCosmosdbContainer = "db.cosmosdb.container"; +static constexpr const char *kNetworkConnectionType = "network.connection.type"; /** - * CosmosDB Operation Type. + * Local address of the network connection - IP address or Unix domain socket name. */ -static constexpr const char *kDbCosmosdbOperationType = "db.cosmosdb.operation_type"; +static constexpr const char *kNetworkLocalAddress = "network.local.address"; /** - * RU consumed for that operation + * Local port number of the network connection. */ -static constexpr const char *kDbCosmosdbRequestCharge = "db.cosmosdb.request_charge"; +static constexpr const char *kNetworkLocalPort = "network.local.port"; /** - * Request payload size in bytes + * Peer address of the network connection - IP address or Unix domain socket name. */ -static constexpr const char *kDbCosmosdbRequestContentLength = "db.cosmosdb.request_content_length"; +static constexpr const char *kNetworkPeerAddress = "network.peer.address"; /** - * Cosmos DB status code. + * Peer port number of the network connection. */ -static constexpr const char *kDbCosmosdbStatusCode = "db.cosmosdb.status_code"; +static constexpr const char *kNetworkPeerPort = "network.peer.port"; /** - * Cosmos DB sub status code. + * OSI application layer or non-OSI + equivalent. + * + *

    Notes: +

    • The value SHOULD be normalized to lowercase.
    */ -static constexpr const char *kDbCosmosdbSubStatusCode = "db.cosmosdb.sub_status_code"; +static constexpr const char *kNetworkProtocolName = "network.protocol.name"; /** - * Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code - * is UNSET. + * Version of the protocol specified in {@code network.protocol.name}. + * + *

    Notes: +

    • {@code network.protocol.version} refers to the version of the protocol used and might be + different from the protocol client's version. If the HTTP client has a version of {@code 0.27.2}, + but sends HTTP version {@code 1.1}, this attribute should be set to {@code 1.1}.
    */ -static constexpr const char *kOtelStatusCode = "otel.status_code"; +static constexpr const char *kNetworkProtocolVersion = "network.protocol.version"; /** - * Description of the Status if it has a value, otherwise not set. + * OSI transport layer or inter-process communication +method. + * + *

    Notes: +

    • The value SHOULD be normalized to lowercase.
    • Consider always setting the +transport when setting a port number, since a port number is ambiguous without knowing the +transport. For example different processes could be listening on TCP port 12345 and UDP port +12345.
    */ -static constexpr const char *kOtelStatusDescription = "otel.status_description"; +static constexpr const char *kNetworkTransport = "network.transport"; /** - * The invocation ID of the current function invocation. + * OSI network layer or non-OSI equivalent. + * + *

    Notes: +

    • The value SHOULD be normalized to lowercase.
    */ -static constexpr const char *kFaasInvocationId = "faas.invocation_id"; +static constexpr const char *kNetworkType = "network.type"; /** - * The name of the source on which the triggering operation was performed. For example, in Cloud - * Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database name. + * The error codes of the Connect + * request. Error codes are always string values. */ -static constexpr const char *kFaasDocumentCollection = "faas.document.collection"; +static constexpr const char *kRpcConnectRpcErrorCode = "rpc.connect_rpc.error_code"; /** - * The document name/table subjected to the operation. For example, in Cloud Storage or S3 is the - * name of the file, and in Cosmos DB the table name. + * The numeric status + * code of the gRPC request. */ -static constexpr const char *kFaasDocumentName = "faas.document.name"; +static constexpr const char *kRpcGrpcStatusCode = "rpc.grpc.status_code"; /** - * Describes the type of the operation that was performed on the data. + * {@code error.code} property of response if it is an error response. */ -static constexpr const char *kFaasDocumentOperation = "faas.document.operation"; +static constexpr const char *kRpcJsonrpcErrorCode = "rpc.jsonrpc.error_code"; /** - * A string containing the time when the data was accessed in the ISO 8601 format expressed in UTC. + * {@code error.message} property of response if it is an error response. */ -static constexpr const char *kFaasDocumentTime = "faas.document.time"; +static constexpr const char *kRpcJsonrpcErrorMessage = "rpc.jsonrpc.error_message"; /** - * A string containing the schedule period as Cron - * Expression. + * {@code id} property of request or response. Since protocol allows id to be int, string, {@code + * null} or missing (for notifications), value is expected to be cast to string for simplicity. Use + * empty string in case of {@code null} value. Omit entirely if this is a notification. */ -static constexpr const char *kFaasCron = "faas.cron"; +static constexpr const char *kRpcJsonrpcRequestId = "rpc.jsonrpc.request_id"; /** - * A string containing the function invocation time in the ISO 8601 format expressed in UTC. + * Protocol version as in {@code jsonrpc} property of request/response. Since JSON-RPC 1.0 doesn't + * specify this, the value can be omitted. */ -static constexpr const char *kFaasTime = "faas.time"; +static constexpr const char *kRpcJsonrpcVersion = "rpc.jsonrpc.version"; /** - * A boolean that is true if the serverless function is executed for the first time (aka - * cold-start). + * The name of the (logical) method being called, must be equal to the $method part in the span + name. + * + *

    Notes: +

    • This is the logical name of the method from the RPC interface perspective, which can be + different from the name of any implementing method/function. The {@code code.function} attribute + may be used to store the latter (e.g., method actually executing the call on the server side, RPC + client stub method on the client side).
    */ -static constexpr const char *kFaasColdstart = "faas.coldstart"; +static constexpr const char *kRpcMethod = "rpc.method"; /** - * The unique identifier of the feature flag. + * The full (logical) name of the service being called, including its package name, if applicable. + * + *

    Notes: +

    • This is the logical name of the service from the RPC interface perspective, which can be + different from the name of any implementing class. The {@code code.namespace} attribute may be used + to store the latter (despite the attribute name, it may include a class name; e.g., class with + method actually executing the call on the server side, RPC client stub class on the client + side).
    */ -static constexpr const char *kFeatureFlagKey = "feature_flag.key"; +static constexpr const char *kRpcService = "rpc.service"; /** - * The name of the service provider that performs the flag evaluation. + * A string identifying the remoting system. See below for a list of well-known identifiers. */ -static constexpr const char *kFeatureFlagProviderName = "feature_flag.provider_name"; +static constexpr const char *kRpcSystem = "rpc.system"; /** - * SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the -value can be used. - * - *

    Notes: -

    • A semantic identifier, commonly referred to as a variant, provides a means -for referring to a value without including the value itself. This can -provide additional context for understanding the meaning behind a value. -For example, the variant {@code red} maybe be used for the value {@code #c05543}.
    • A -stringified version of the value can be used in situations where a semantic identifier is -unavailable. String representation of the value should be determined by the implementer.
    + * Current "managed" thread ID (as opposed to OS thread ID). */ -static constexpr const char *kFeatureFlagVariant = "feature_flag.variant"; +static constexpr const char *kThreadId = "thread.id"; /** - * The AWS request ID as returned in the response headers {@code x-amz-request-id} or {@code - * x-amz-requestid}. + * Current thread name. */ -static constexpr const char *kAwsRequestId = "aws.request_id"; +static constexpr const char *kThreadName = "thread.name"; /** - * The value of the {@code AttributesToGet} request parameter. + * The URI fragment component */ -static constexpr const char *kAwsDynamodbAttributesToGet = "aws.dynamodb.attributes_to_get"; +static constexpr const char *kUrlFragment = "url.fragment"; /** - * The value of the {@code ConsistentRead} request parameter. + * Absolute URL describing a network resource according to RFC3986 + * + *

    Notes: +

    • For network calls, URL usually has {@code scheme://host[:port][path][?query][#fragment]} +format, where the fragment is not transmitted over HTTP, but if it is known, it SHOULD be included +nevertheless. +{@code url.full} MUST NOT contain credentials passed via URL in form of {@code +https://username:password@www.example.com/}. In such case username and password SHOULD be redacted +and attribute's value SHOULD be {@code https://REDACTED:REDACTED@www.example.com/}. +{@code url.full} SHOULD capture the absolute URL when it is available (or can be reconstructed) and +SHOULD NOT be validated or modified except for sanitizing purposes.
    */ -static constexpr const char *kAwsDynamodbConsistentRead = "aws.dynamodb.consistent_read"; +static constexpr const char *kUrlFull = "url.full"; /** - * The JSON-serialized value of each item in the {@code ConsumedCapacity} response field. + * The URI path component */ -static constexpr const char *kAwsDynamodbConsumedCapacity = "aws.dynamodb.consumed_capacity"; +static constexpr const char *kUrlPath = "url.path"; /** - * The value of the {@code IndexName} request parameter. + * The URI query component + * + *

    Notes: +

    • Sensitive content provided in query string SHOULD be scrubbed when instrumentations can + identify it.
    */ -static constexpr const char *kAwsDynamodbIndexName = "aws.dynamodb.index_name"; +static constexpr const char *kUrlQuery = "url.query"; /** - * The JSON-serialized value of the {@code ItemCollectionMetrics} response field. + * The URI scheme component + * identifying the used protocol. */ -static constexpr const char *kAwsDynamodbItemCollectionMetrics = - "aws.dynamodb.item_collection_metrics"; +static constexpr const char *kUrlScheme = "url.scheme"; /** - * The value of the {@code Limit} request parameter. + * Value of the HTTP + * User-Agent header sent by the client. */ -static constexpr const char *kAwsDynamodbLimit = "aws.dynamodb.limit"; +static constexpr const char *kUserAgentOriginal = "user_agent.original"; /** - * The value of the {@code ProjectionExpression} request parameter. + * Server domain name if available without reverse DNS lookup; otherwise, IP address or Unix domain + socket name. + * + *

    Notes: +

    • When observed from the client side, and when communicating through an intermediary, + {@code server.address} SHOULD represent the server address behind any intermediaries, for example + proxies, if it's available.
    */ -static constexpr const char *kAwsDynamodbProjection = "aws.dynamodb.projection"; +static constexpr const char *kServerAddress = "server.address"; /** - * The value of the {@code ProvisionedThroughput.ReadCapacityUnits} request parameter. + * Server port number. + * + *

    Notes: +

    • When observed from the client side, and when communicating through an intermediary, + {@code server.port} SHOULD represent the server port behind any intermediaries, for example + proxies, if it's available.
    */ -static constexpr const char *kAwsDynamodbProvisionedReadCapacity = - "aws.dynamodb.provisioned_read_capacity"; +static constexpr const char *kServerPort = "server.port"; /** - * The value of the {@code ProvisionedThroughput.WriteCapacityUnits} request parameter. + * A unique id to identify a session. */ -static constexpr const char *kAwsDynamodbProvisionedWriteCapacity = - "aws.dynamodb.provisioned_write_capacity"; +static constexpr const char *kSessionId = "session.id"; /** - * The value of the {@code Select} request parameter. + * The previous {@code session.id} for this user, when known. */ -static constexpr const char *kAwsDynamodbSelect = "aws.dynamodb.select"; +static constexpr const char *kSessionPreviousId = "session.previous_id"; /** - * The keys in the {@code RequestItems} object field. + * Source address - domain name if available without reverse DNS lookup; otherwise, IP address or + Unix domain socket name. + * + *

    Notes: +

    • When observed from the destination side, and when communicating through an intermediary, + {@code source.address} SHOULD represent the source address behind any intermediaries, for example + proxies, if it's available.
    */ -static constexpr const char *kAwsDynamodbTableNames = "aws.dynamodb.table_names"; +static constexpr const char *kSourceAddress = "source.address"; /** - * The JSON-serialized value of each item of the {@code GlobalSecondaryIndexes} request field + * Source port number */ -static constexpr const char *kAwsDynamodbGlobalSecondaryIndexes = - "aws.dynamodb.global_secondary_indexes"; +static constexpr const char *kSourcePort = "source.port"; /** - * The JSON-serialized value of each item of the {@code LocalSecondaryIndexes} request field. + * The full invoked ARN as provided on the {@code Context} passed to the function ({@code + Lambda-Runtime-Invoked-Function-Arn} header on the {@code /runtime/invocation/next} applicable). + * + *

    Notes: +

    • This may be different from {@code cloud.resource_id} if an alias is involved.
    */ -static constexpr const char *kAwsDynamodbLocalSecondaryIndexes = - "aws.dynamodb.local_secondary_indexes"; +static constexpr const char *kAwsLambdaInvokedArn = "aws.lambda.invoked_arn"; /** - * The value of the {@code ExclusiveStartTableName} request parameter. + * The event_id + * uniquely identifies the event. */ -static constexpr const char *kAwsDynamodbExclusiveStartTable = "aws.dynamodb.exclusive_start_table"; +static constexpr const char *kCloudeventsEventId = "cloudevents.event_id"; /** - * The the number of items in the {@code TableNames} response parameter. + * The source + * identifies the context in which an event happened. */ -static constexpr const char *kAwsDynamodbTableCount = "aws.dynamodb.table_count"; +static constexpr const char *kCloudeventsEventSource = "cloudevents.event_source"; /** - * The value of the {@code ScanIndexForward} request parameter. + * The version of + * the CloudEvents specification which the event uses. */ -static constexpr const char *kAwsDynamodbScanForward = "aws.dynamodb.scan_forward"; +static constexpr const char *kCloudeventsEventSpecVersion = "cloudevents.event_spec_version"; /** - * The value of the {@code Count} response parameter. + * The subject of + * the event in the context of the event producer (identified by source). */ -static constexpr const char *kAwsDynamodbCount = "aws.dynamodb.count"; +static constexpr const char *kCloudeventsEventSubject = "cloudevents.event_subject"; /** - * The value of the {@code ScannedCount} response parameter. + * The event_type + * contains a value describing the type of event related to the originating occurrence. */ -static constexpr const char *kAwsDynamodbScannedCount = "aws.dynamodb.scanned_count"; +static constexpr const char *kCloudeventsEventType = "cloudevents.event_type"; /** - * The value of the {@code Segment} request parameter. + * Parent-child Reference type + * + *

    Notes: +

    • The causal relationship between a child Span and a parent Span.
    */ -static constexpr const char *kAwsDynamodbSegment = "aws.dynamodb.segment"; +static constexpr const char *kOpentracingRefType = "opentracing.ref_type"; /** - * The value of the {@code TotalSegments} request parameter. + * The connection string used to connect to the database. It is recommended to remove embedded + * credentials. */ -static constexpr const char *kAwsDynamodbTotalSegments = "aws.dynamodb.total_segments"; +static constexpr const char *kDbConnectionString = "db.connection_string"; /** - * The JSON-serialized value of each item in the {@code AttributeDefinitions} request field. + * The fully-qualified class name of the Java Database Connectivity + * (JDBC) driver used to connect. */ -static constexpr const char *kAwsDynamodbAttributeDefinitions = - "aws.dynamodb.attribute_definitions"; +static constexpr const char *kDbJdbcDriverClassname = "db.jdbc.driver_classname"; /** - * The JSON-serialized value of each item in the the {@code GlobalSecondaryIndexUpdates} request - * field. + * This attribute is used to report the name of the database being accessed. For commands that + switch the database, this should be set to the target database (even if the command fails). + * + *

    Notes: +

    • In some SQL databases, the database name to be used is called "schema name". In + case there are multiple layers that could be considered for database name (e.g. Oracle instance + name and schema name), the database name to be used is the more specific layer (e.g. Oracle schema + name).
    */ -static constexpr const char *kAwsDynamodbGlobalSecondaryIndexUpdates = - "aws.dynamodb.global_secondary_index_updates"; +static constexpr const char *kDbName = "db.name"; /** - * The S3 bucket name the request refers to. Corresponds to the {@code --bucket} parameter of the S3 API operations. + * The name of the operation being executed, e.g. the MongoDB command + name such as {@code findAndModify}, or the SQL keyword. * *

    Notes: -

    • The {@code bucket} attribute is applicable to all S3 operations that reference a bucket, -i.e. that require the bucket name as a mandatory parameter. This applies to almost all S3 operations -except {@code list-buckets}.
    +
    • When setting this to an SQL keyword, it is not recommended to attempt any client-side + parsing of {@code db.statement} just to get this property, but it should be set if the operation + name is provided by the library being instrumented. If the SQL statement has an ambiguous + operation, or performs more than one operation, this value may be omitted.
    */ -static constexpr const char *kAwsS3Bucket = "aws.s3.bucket"; +static constexpr const char *kDbOperation = "db.operation"; /** - * The source object (in the form {@code bucket}/{@code key}) for the copy operation. - * - *

    Notes: -

    + * The database statement being executed. */ -static constexpr const char *kAwsS3CopySource = "aws.s3.copy_source"; +static constexpr const char *kDbStatement = "db.statement"; /** - * The delete request container that specifies the objects to be deleted. + * An identifier for the database management system (DBMS) product being used. See below for a list + * of well-known identifiers. + */ +static constexpr const char *kDbSystem = "db.system"; + +/** + * Username for accessing the database. + */ +static constexpr const char *kDbUser = "db.user"; + +/** + * The Microsoft SQL Server instance + name connecting to. This name is used to determine the port of a named instance. * *

    Notes: -

    +
    • If setting a {@code db.mssql.instance_name}, {@code server.port} is no longer required + (but still recommended if non-standard).
    */ -static constexpr const char *kAwsS3Delete = "aws.s3.delete"; +static constexpr const char *kDbMssqlInstanceName = "db.mssql.instance_name"; /** - * The S3 object key the request refers to. Corresponds to the {@code --key} parameter of the S3 API operations. + * The consistency level of the query. Based on consistency values from CQL. + */ +static constexpr const char *kDbCassandraConsistencyLevel = "db.cassandra.consistency_level"; + +/** + * The data center of the coordinating node for a query. + */ +static constexpr const char *kDbCassandraCoordinatorDc = "db.cassandra.coordinator.dc"; + +/** + * The ID of the coordinating node for a query. + */ +static constexpr const char *kDbCassandraCoordinatorId = "db.cassandra.coordinator.id"; + +/** + * Whether or not the query is idempotent. + */ +static constexpr const char *kDbCassandraIdempotence = "db.cassandra.idempotence"; + +/** + * The fetch size used for paging, i.e. how many rows will be returned at once. + */ +static constexpr const char *kDbCassandraPageSize = "db.cassandra.page_size"; + +/** + * The number of times a query was speculatively executed. Not set or {@code 0} if the query was not + * executed speculatively. + */ +static constexpr const char *kDbCassandraSpeculativeExecutionCount = + "db.cassandra.speculative_execution_count"; + +/** + * The name of the primary table that the operation is acting upon, including the keyspace name (if + applicable). * *

    Notes: -

    +
    • This mirrors the db.sql.table attribute but references cassandra rather than sql. It is + not recommended to attempt any client-side parsing of {@code db.statement} just to get this + property, but it should be set if it is provided by the library being instrumented. If the + operation is acting upon an anonymous table, or more than one table, this value MUST NOT be + set.
    */ -static constexpr const char *kAwsS3Key = "aws.s3.key"; +static constexpr const char *kDbCassandraTable = "db.cassandra.table"; /** - * The part number of the part being uploaded in a multipart-upload operation. This is a positive -integer between 1 and 10,000. + * The index of the database being accessed as used in the {@code SELECT} command, provided as an integer. To be + * used instead of the generic {@code db.name} attribute. + */ +static constexpr const char *kDbRedisDatabaseIndex = "db.redis.database_index"; + +/** + * The collection being accessed within the database stated in {@code db.name}. + */ +static constexpr const char *kDbMongodbCollection = "db.mongodb.collection"; + +/** + * Represents the identifier of an Elasticsearch cluster. + */ +static constexpr const char *kDbElasticsearchClusterName = "db.elasticsearch.cluster.name"; + +/** + * Represents the human-readable identifier of the node/instance to which a request was routed. + */ +static constexpr const char *kDbElasticsearchNodeName = "db.elasticsearch.node.name"; + +/** + * The name of the primary table that the operation is acting upon, including the database name (if + applicable). * *

    Notes: -

    +
    • It is not recommended to attempt any client-side parsing of {@code db.statement} just to + get this property, but it should be set if it is provided by the library being instrumented. If the + operation is acting upon an anonymous table, or more than one table, this value MUST NOT be + set.
    + */ +static constexpr const char *kDbSqlTable = "db.sql.table"; + +/** + * Unique Cosmos client instance id. + */ +static constexpr const char *kDbCosmosdbClientId = "db.cosmosdb.client_id"; + +/** + * Cosmos client connection mode. + */ +static constexpr const char *kDbCosmosdbConnectionMode = "db.cosmosdb.connection_mode"; + +/** + * Cosmos DB container name. + */ +static constexpr const char *kDbCosmosdbContainer = "db.cosmosdb.container"; + +/** + * CosmosDB Operation Type. + */ +static constexpr const char *kDbCosmosdbOperationType = "db.cosmosdb.operation_type"; + +/** + * RU consumed for that operation + */ +static constexpr const char *kDbCosmosdbRequestCharge = "db.cosmosdb.request_charge"; + +/** + * Request payload size in bytes + */ +static constexpr const char *kDbCosmosdbRequestContentLength = "db.cosmosdb.request_content_length"; + +/** + * Cosmos DB status code. + */ +static constexpr const char *kDbCosmosdbStatusCode = "db.cosmosdb.status_code"; + +/** + * Cosmos DB sub status code. + */ +static constexpr const char *kDbCosmosdbSubStatusCode = "db.cosmosdb.sub_status_code"; + +/** + * Name of the code, either "OK" or "ERROR". MUST NOT be set if the status code + * is UNSET. + */ +static constexpr const char *kOtelStatusCode = "otel.status_code"; + +/** + * Description of the Status if it has a value, otherwise not set. */ -static constexpr const char *kAwsS3PartNumber = "aws.s3.part_number"; +static constexpr const char *kOtelStatusDescription = "otel.status_description"; /** - * Upload ID that identifies the multipart upload. - * - *

    Notes: -

    + * The invocation ID of the current function invocation. */ -static constexpr const char *kAwsS3UploadId = "aws.s3.upload_id"; +static constexpr const char *kFaasInvocationId = "faas.invocation_id"; /** - * The GraphQL document being executed. - * - *

    Notes: -

    • The value may be sanitized to exclude sensitive information.
    + * The name of the source on which the triggering operation was performed. For example, in Cloud + * Storage or S3 corresponds to the bucket name, and in Cosmos DB to the database name. */ -static constexpr const char *kGraphqlDocument = "graphql.document"; +static constexpr const char *kFaasDocumentCollection = "faas.document.collection"; /** - * The name of the operation being executed. + * The document name/table subjected to the operation. For example, in Cloud Storage or S3 is the + * name of the file, and in Cosmos DB the table name. */ -static constexpr const char *kGraphqlOperationName = "graphql.operation.name"; +static constexpr const char *kFaasDocumentName = "faas.document.name"; /** - * The type of the operation being executed. + * Describes the type of the operation that was performed on the data. */ -static constexpr const char *kGraphqlOperationType = "graphql.operation.type"; +static constexpr const char *kFaasDocumentOperation = "faas.document.operation"; /** - * The size of the message body in bytes. - * - *

    Notes: -

    • This can refer to both the compressed or uncompressed body size. If both sizes are known, -the uncompressed body size should be used.
    + * A string containing the time when the data was accessed in the ISO 8601 format expressed in UTC. */ -static constexpr const char *kMessagingMessageBodySize = "messaging.message.body.size"; +static constexpr const char *kFaasDocumentTime = "faas.document.time"; /** - * The conversation ID identifying the conversation to which the - * message belongs, represented as a string. Sometimes called "Correlation ID". + * A string containing the schedule period as Cron + * Expression. */ -static constexpr const char *kMessagingMessageConversationId = "messaging.message.conversation_id"; +static constexpr const char *kFaasCron = "faas.cron"; /** - * The size of the message body and metadata in bytes. - * - *

    Notes: -

    • This can refer to both the compressed or uncompressed size. If both sizes are known, the -uncompressed size should be used.
    + * A string containing the function invocation time in the ISO 8601 format expressed in UTC. */ -static constexpr const char *kMessagingMessageEnvelopeSize = "messaging.message.envelope.size"; +static constexpr const char *kFaasTime = "faas.time"; /** - * A value used by the messaging system as an identifier for the message, represented as a string. + * A boolean that is true if the serverless function is executed for the first time (aka + * cold-start). */ -static constexpr const char *kMessagingMessageId = "messaging.message.id"; +static constexpr const char *kFaasColdstart = "faas.coldstart"; /** - * A boolean that is true if the message destination is anonymous (could be unnamed or have - * auto-generated name). + * The unique identifier of the feature flag. */ -static constexpr const char *kMessagingDestinationAnonymous = "messaging.destination.anonymous"; +static constexpr const char *kFeatureFlagKey = "feature_flag.key"; /** - * The message destination name - * - *

    Notes: -

    • Destination name SHOULD uniquely identify a specific queue, topic or other entity within -the broker. If the broker does not have such notion, the destination name SHOULD uniquely identify -the broker.
    + * The name of the service provider that performs the flag evaluation. */ -static constexpr const char *kMessagingDestinationName = "messaging.destination.name"; +static constexpr const char *kFeatureFlagProviderName = "feature_flag.provider_name"; /** - * Low cardinality representation of the messaging destination name + * SHOULD be a semantic identifier for a value. If one is unavailable, a stringified version of the +value can be used. * *

    Notes: -

    • Destination names could be constructed from templates. An example would be a destination - name involving a user name or product id. Although the destination name in this case is of high - cardinality, the underlying template is of low cardinality and can be effectively used for grouping - and aggregation.
    +
    • A semantic identifier, commonly referred to as a variant, provides a means +for referring to a value without including the value itself. This can +provide additional context for understanding the meaning behind a value. +For example, the variant {@code red} maybe be used for the value {@code #c05543}.
    • A +stringified version of the value can be used in situations where a semantic identifier is +unavailable. String representation of the value should be determined by the implementer.
    */ -static constexpr const char *kMessagingDestinationTemplate = "messaging.destination.template"; +static constexpr const char *kFeatureFlagVariant = "feature_flag.variant"; /** - * A boolean that is true if the message destination is temporary and might not exist anymore after - * messages are processed. + * The AWS request ID as returned in the response headers {@code x-amz-request-id} or {@code + * x-amz-requestid}. */ -static constexpr const char *kMessagingDestinationTemporary = "messaging.destination.temporary"; +static constexpr const char *kAwsRequestId = "aws.request_id"; /** - * A boolean that is true if the publish message destination is anonymous (could be unnamed or have - * auto-generated name). + * The value of the {@code AttributesToGet} request parameter. */ -static constexpr const char *kMessagingDestinationPublishAnonymous = - "messaging.destination_publish.anonymous"; +static constexpr const char *kAwsDynamodbAttributesToGet = "aws.dynamodb.attributes_to_get"; /** - * The name of the original destination the message was published to - * - *

    Notes: -

    • The name SHOULD uniquely identify a specific queue, topic, or other entity within the -broker. If the broker does not have such notion, the original destination name SHOULD uniquely -identify the broker.
    + * The value of the {@code ConsistentRead} request parameter. */ -static constexpr const char *kMessagingDestinationPublishName = - "messaging.destination_publish.name"; +static constexpr const char *kAwsDynamodbConsistentRead = "aws.dynamodb.consistent_read"; /** - * The number of messages sent, received, or processed in the scope of the batching operation. - * - *

    Notes: -

    • Instrumentations SHOULD NOT set {@code messaging.batch.message_count} on spans that - operate with a single message. When a messaging client library supports both batch and - single-message API for the same operation, instrumentations SHOULD use {@code - messaging.batch.message_count} for batching APIs and SHOULD NOT use it for single-message - APIs.
    + * The JSON-serialized value of each item in the {@code ConsumedCapacity} response field. */ -static constexpr const char *kMessagingBatchMessageCount = "messaging.batch.message_count"; +static constexpr const char *kAwsDynamodbConsumedCapacity = "aws.dynamodb.consumed_capacity"; /** - * A unique identifier for the client that consumes or produces a message. + * The value of the {@code IndexName} request parameter. */ -static constexpr const char *kMessagingClientId = "messaging.client_id"; +static constexpr const char *kAwsDynamodbIndexName = "aws.dynamodb.index_name"; /** - * A string identifying the kind of messaging operation as defined in the Operation names section above. - * - *

    Notes: -

    • If a custom value is used, it MUST be of low cardinality.
    + * The JSON-serialized value of the {@code ItemCollectionMetrics} response field. */ -static constexpr const char *kMessagingOperation = "messaging.operation"; +static constexpr const char *kAwsDynamodbItemCollectionMetrics = + "aws.dynamodb.item_collection_metrics"; /** - * A string identifying the messaging system. + * The value of the {@code Limit} request parameter. */ -static constexpr const char *kMessagingSystem = "messaging.system"; +static constexpr const char *kAwsDynamodbLimit = "aws.dynamodb.limit"; /** - * RabbitMQ message routing key. + * The value of the {@code ProjectionExpression} request parameter. */ -static constexpr const char *kMessagingRabbitmqDestinationRoutingKey = - "messaging.rabbitmq.destination.routing_key"; +static constexpr const char *kAwsDynamodbProjection = "aws.dynamodb.projection"; /** - * Name of the Kafka Consumer Group that is handling the message. Only applies to consumers, not - * producers. + * The value of the {@code ProvisionedThroughput.ReadCapacityUnits} request parameter. */ -static constexpr const char *kMessagingKafkaConsumerGroup = "messaging.kafka.consumer.group"; +static constexpr const char *kAwsDynamodbProvisionedReadCapacity = + "aws.dynamodb.provisioned_read_capacity"; /** - * Partition the message is sent to. + * The value of the {@code ProvisionedThroughput.WriteCapacityUnits} request parameter. */ -static constexpr const char *kMessagingKafkaDestinationPartition = - "messaging.kafka.destination.partition"; +static constexpr const char *kAwsDynamodbProvisionedWriteCapacity = + "aws.dynamodb.provisioned_write_capacity"; /** - * Message keys in Kafka are used for grouping alike messages to ensure they're processed on the - same partition. They differ from {@code messaging.message.id} in that they're not unique. If the - key is {@code null}, the attribute MUST NOT be set. - * - *

    Notes: -

    • If the key type is not string, it's string representation has to be supplied for the - attribute. If the key has no unambiguous, canonical string form, don't include its value.
    • -
    + * The value of the {@code Select} request parameter. */ -static constexpr const char *kMessagingKafkaMessageKey = "messaging.kafka.message.key"; +static constexpr const char *kAwsDynamodbSelect = "aws.dynamodb.select"; /** - * The offset of a record in the corresponding Kafka partition. + * The keys in the {@code RequestItems} object field. */ -static constexpr const char *kMessagingKafkaMessageOffset = "messaging.kafka.message.offset"; +static constexpr const char *kAwsDynamodbTableNames = "aws.dynamodb.table_names"; /** - * A boolean that is true if the message is a tombstone. + * The JSON-serialized value of each item of the {@code GlobalSecondaryIndexes} request field */ -static constexpr const char *kMessagingKafkaMessageTombstone = "messaging.kafka.message.tombstone"; +static constexpr const char *kAwsDynamodbGlobalSecondaryIndexes = + "aws.dynamodb.global_secondary_indexes"; /** - * Name of the RocketMQ producer/consumer group that is handling the message. The client type is - * identified by the SpanKind. + * The JSON-serialized value of each item of the {@code LocalSecondaryIndexes} request field. */ -static constexpr const char *kMessagingRocketmqClientGroup = "messaging.rocketmq.client_group"; +static constexpr const char *kAwsDynamodbLocalSecondaryIndexes = + "aws.dynamodb.local_secondary_indexes"; /** - * Model of message consumption. This only applies to consumer spans. + * The value of the {@code ExclusiveStartTableName} request parameter. */ -static constexpr const char *kMessagingRocketmqConsumptionModel = - "messaging.rocketmq.consumption_model"; +static constexpr const char *kAwsDynamodbExclusiveStartTable = "aws.dynamodb.exclusive_start_table"; /** - * The delay time level for delay message, which determines the message delay time. + * The the number of items in the {@code TableNames} response parameter. */ -static constexpr const char *kMessagingRocketmqMessageDelayTimeLevel = - "messaging.rocketmq.message.delay_time_level"; +static constexpr const char *kAwsDynamodbTableCount = "aws.dynamodb.table_count"; /** - * The timestamp in milliseconds that the delay message is expected to be delivered to consumer. + * The value of the {@code ScanIndexForward} request parameter. */ -static constexpr const char *kMessagingRocketmqMessageDeliveryTimestamp = - "messaging.rocketmq.message.delivery_timestamp"; +static constexpr const char *kAwsDynamodbScanForward = "aws.dynamodb.scan_forward"; /** - * It is essential for FIFO message. Messages that belong to the same message group are always - * processed one by one within the same consumer group. + * The value of the {@code Count} response parameter. */ -static constexpr const char *kMessagingRocketmqMessageGroup = "messaging.rocketmq.message.group"; +static constexpr const char *kAwsDynamodbCount = "aws.dynamodb.count"; /** - * Key(s) of message, another way to mark message besides message id. + * The value of the {@code ScannedCount} response parameter. */ -static constexpr const char *kMessagingRocketmqMessageKeys = "messaging.rocketmq.message.keys"; +static constexpr const char *kAwsDynamodbScannedCount = "aws.dynamodb.scanned_count"; /** - * The secondary classifier of message besides topic. + * The value of the {@code Segment} request parameter. */ -static constexpr const char *kMessagingRocketmqMessageTag = "messaging.rocketmq.message.tag"; +static constexpr const char *kAwsDynamodbSegment = "aws.dynamodb.segment"; /** - * Type of message. + * The value of the {@code TotalSegments} request parameter. */ -static constexpr const char *kMessagingRocketmqMessageType = "messaging.rocketmq.message.type"; +static constexpr const char *kAwsDynamodbTotalSegments = "aws.dynamodb.total_segments"; /** - * Namespace of RocketMQ resources, resources in different namespaces are individual. + * The JSON-serialized value of each item in the {@code AttributeDefinitions} request field. */ -static constexpr const char *kMessagingRocketmqNamespace = "messaging.rocketmq.namespace"; +static constexpr const char *kAwsDynamodbAttributeDefinitions = + "aws.dynamodb.attribute_definitions"; /** - * The name of the (logical) method being called, must be equal to the $method part in the span - name. + * The JSON-serialized value of each item in the the {@code GlobalSecondaryIndexUpdates} request + * field. + */ +static constexpr const char *kAwsDynamodbGlobalSecondaryIndexUpdates = + "aws.dynamodb.global_secondary_index_updates"; + +/** + * The S3 bucket name the request refers to. Corresponds to the {@code --bucket} parameter of the S3 API operations. * *

    Notes: -

    • This is the logical name of the method from the RPC interface perspective, which can be - different from the name of any implementing method/function. The {@code code.function} attribute - may be used to store the latter (e.g., method actually executing the call on the server side, RPC - client stub method on the client side).
    +
    • The {@code bucket} attribute is applicable to all S3 operations that reference a bucket, +i.e. that require the bucket name as a mandatory parameter. This applies to almost all S3 operations +except {@code list-buckets}.
    + */ +static constexpr const char *kAwsS3Bucket = "aws.s3.bucket"; + +/** + * The source object (in the form {@code bucket}/{@code key}) for the copy operation. + * + *

    Notes: +

    */ -static constexpr const char *kRpcMethod = "rpc.method"; +static constexpr const char *kAwsS3CopySource = "aws.s3.copy_source"; /** - * The full (logical) name of the service being called, including its package name, if applicable. + * The delete request container that specifies the objects to be deleted. * *

    Notes: -

    • This is the logical name of the service from the RPC interface perspective, which can be - different from the name of any implementing class. The {@code code.namespace} attribute may be used - to store the latter (despite the attribute name, it may include a class name; e.g., class with - method actually executing the call on the server side, RPC client stub class on the client - side).
    + */ -static constexpr const char *kRpcService = "rpc.service"; +static constexpr const char *kAwsS3Delete = "aws.s3.delete"; /** - * A string identifying the remoting system. See below for a list of well-known identifiers. + * The S3 object key the request refers to. Corresponds to the {@code --key} parameter of the S3 API operations. + * + *

    Notes: +

    */ -static constexpr const char *kRpcSystem = "rpc.system"; +static constexpr const char *kAwsS3Key = "aws.s3.key"; /** - * The numeric status - * code of the gRPC request. + * The part number of the part being uploaded in a multipart-upload operation. This is a positive +integer between 1 and 10,000. + * + *

    Notes: +

    */ -static constexpr const char *kRpcGrpcStatusCode = "rpc.grpc.status_code"; +static constexpr const char *kAwsS3PartNumber = "aws.s3.part_number"; /** - * {@code error.code} property of response if it is an error response. + * Upload ID that identifies the multipart upload. + * + *

    Notes: +

    */ -static constexpr const char *kRpcJsonrpcErrorCode = "rpc.jsonrpc.error_code"; +static constexpr const char *kAwsS3UploadId = "aws.s3.upload_id"; /** - * {@code error.message} property of response if it is an error response. + * The GraphQL document being executed. + * + *

    Notes: +

    • The value may be sanitized to exclude sensitive information.
    */ -static constexpr const char *kRpcJsonrpcErrorMessage = "rpc.jsonrpc.error_message"; +static constexpr const char *kGraphqlDocument = "graphql.document"; /** - * {@code id} property of request or response. Since protocol allows id to be int, string, {@code - * null} or missing (for notifications), value is expected to be cast to string for simplicity. Use - * empty string in case of {@code null} value. Omit entirely if this is a notification. + * The name of the operation being executed. */ -static constexpr const char *kRpcJsonrpcRequestId = "rpc.jsonrpc.request_id"; +static constexpr const char *kGraphqlOperationName = "graphql.operation.name"; /** - * Protocol version as in {@code jsonrpc} property of request/response. Since JSON-RPC 1.0 does not - * specify this, the value can be omitted. + * The type of the operation being executed. */ -static constexpr const char *kRpcJsonrpcVersion = "rpc.jsonrpc.version"; +static constexpr const char *kGraphqlOperationType = "graphql.operation.type"; /** * Compressed size of the message in bytes. @@ -1590,12 +1664,6 @@ static constexpr const char *kMessageType = "message.type"; */ static constexpr const char *kMessageUncompressedSize = "message.uncompressed_size"; -/** - * The error codes of the Connect - * request. Error codes are always string values. - */ -static constexpr const char *kRpcConnectRpcErrorCode = "rpc.connect_rpc.error_code"; - /** * 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. @@ -1615,85 +1683,10 @@ recorded at a time where it was not clear whether the exception will escape.URI fragment component - */ -static constexpr const char *kUrlFragment = "url.fragment"; - -/** - * Absolute URL describing a network resource according to RFC3986 - * - *

    Notes: -

    • For network calls, URL usually has {@code scheme://host[:port][path][?query][#fragment]} -format, where the fragment is not transmitted over HTTP, but if it is known, it should be included -nevertheless. -{@code url.full} MUST NOT contain credentials passed via URL in form of {@code -https://username:password@www.example.com/}. In such case username and password should be redacted -and attribute's value should be {@code https://REDACTED:REDACTED@www.example.com/}. -{@code url.full} SHOULD capture the absolute URL when it is available (or can be reconstructed) and -SHOULD NOT be validated or modified except for sanitizing purposes.
    - */ -static constexpr const char *kUrlFull = "url.full"; - -/** - * The URI path component - * - *

    Notes: -

    • When missing, the value is assumed to be {@code /}
    - */ -static constexpr const char *kUrlPath = "url.path"; - -/** - * The URI query component - * - *

    Notes: -

    • Sensitive content provided in query string SHOULD be scrubbed when instrumentations can - identify it.
    - */ -static constexpr const char *kUrlQuery = "url.query"; - -/** - * The URI scheme component - * identifying the used protocol. - */ -static constexpr const char *kUrlScheme = "url.scheme"; - -/** - * Value of the HTTP - * User-Agent header sent by the client. - */ -static constexpr const char *kUserAgentOriginal = "user_agent.original"; - // Enum definitions -namespace NetSockFamilyValues -{ -/** IPv4 address. */ -static constexpr const char *kInet = "inet"; -/** IPv6 address. */ -static constexpr const char *kInet6 = "inet6"; -/** Unix domain socket path. */ -static constexpr const char *kUnix = "unix"; -} // namespace NetSockFamilyValues - -namespace NetTransportValues -{ -/** ip_tcp. */ -static constexpr const char *kIpTcp = "ip_tcp"; -/** ip_udp. */ -static constexpr const char *kIpUdp = "ip_udp"; -/** Named or anonymous pipe. */ -static constexpr const char *kPipe = "pipe"; -/** In-process communication. */ -static constexpr const char *kInproc = "inproc"; -/** Something else (non IP-based). */ -static constexpr const char *kOther = "other"; -} // namespace NetTransportValues - namespace ErrorTypeValues { -/** A fallback error value to be used when the instrumentation does not define a custom value for - * it. */ +/** A fallback error value to be used when the instrumentation doesn't define a custom value. */ static constexpr const char *kOther = "_OTHER"; } // namespace ErrorTypeValues @@ -1743,6 +1736,35 @@ static constexpr const char *kStdout = "stdout"; static constexpr const char *kStderr = "stderr"; } // namespace LogIostreamValues +namespace IosStateValues +{ +/** The app has become `active`. Associated with UIKit notification `applicationDidBecomeActive`. */ +static constexpr const char *kActive = "active"; +/** The app is now `inactive`. Associated with UIKit notification `applicationWillResignActive`. */ +static constexpr const char *kInactive = "inactive"; +/** The app is now in the background. This value is associated with UIKit notification + * `applicationDidEnterBackground`. */ +static constexpr const char *kBackground = "background"; +/** The app is now in the foreground. This value is associated with UIKit notification + * `applicationWillEnterForeground`. */ +static constexpr const char *kForeground = "foreground"; +/** The app is about to terminate. Associated with UIKit notification `applicationWillTerminate`. */ +static constexpr const char *kTerminate = "terminate"; +} // namespace IosStateValues + +namespace AndroidStateValues +{ +/** Any time before Activity.onResume() or, if the app has no Activity, Context.startService() has + * been called in the app for the first time. */ +static constexpr const char *kCreated = "created"; +/** Any time after Activity.onPause() or, if the app has no Activity, Context.stopService() has been + * called when the app was in the foreground state. */ +static constexpr const char *kBackground = "background"; +/** Any time after Activity.onResume() or, if the app has no Activity, Context.startService() has + * been called when the app was in either the created or background states. */ +static constexpr const char *kForeground = "foreground"; +} // namespace AndroidStateValues + namespace StateValues { /** idle. */ @@ -1779,8 +1801,6 @@ static constexpr const char *kSteal = "steal"; namespace SystemMemoryStateValues { -/** total. */ -static constexpr const char *kTotal = "total"; /** used. */ static constexpr const char *kUsed = "used"; /** free. */ @@ -1899,25 +1919,90 @@ static constexpr const char *kStopped = "stopped"; static constexpr const char *kDefunct = "defunct"; } // namespace SystemProcessesStatusValues -namespace NetworkTransportValues +namespace NetSockFamilyValues { -/** TCP. */ -static constexpr const char *kTcp = "tcp"; -/** UDP. */ -static constexpr const char *kUdp = "udp"; -/** Named or anonymous pipe. See note below. */ -static constexpr const char *kPipe = "pipe"; -/** Unix domain socket. */ +/** IPv4 address. */ +static constexpr const char *kInet = "inet"; +/** IPv6 address. */ +static constexpr const char *kInet6 = "inet6"; +/** Unix domain socket path. */ static constexpr const char *kUnix = "unix"; -} // namespace NetworkTransportValues +} // namespace NetSockFamilyValues -namespace NetworkTypeValues +namespace NetTransportValues { -/** IPv4. */ -static constexpr const char *kIpv4 = "ipv4"; -/** IPv6. */ -static constexpr const char *kIpv6 = "ipv6"; -} // namespace NetworkTypeValues +/** ip_tcp. */ +static constexpr const char *kIpTcp = "ip_tcp"; +/** ip_udp. */ +static constexpr const char *kIpUdp = "ip_udp"; +/** Named or anonymous pipe. */ +static constexpr const char *kPipe = "pipe"; +/** In-process communication. */ +static constexpr const char *kInproc = "inproc"; +/** Something else (non IP-based). */ +static constexpr const char *kOther = "other"; +} // namespace NetTransportValues + +namespace HttpRequestMethodValues +{ +/** CONNECT method. */ +static constexpr const char *kConnect = "CONNECT"; +/** DELETE method. */ +static constexpr const char *kDelete = "DELETE"; +/** GET method. */ +static constexpr const char *kGet = "GET"; +/** HEAD method. */ +static constexpr const char *kHead = "HEAD"; +/** OPTIONS method. */ +static constexpr const char *kOptions = "OPTIONS"; +/** PATCH method. */ +static constexpr const char *kPatch = "PATCH"; +/** POST method. */ +static constexpr const char *kPost = "POST"; +/** PUT method. */ +static constexpr const char *kPut = "PUT"; +/** TRACE method. */ +static constexpr const char *kTrace = "TRACE"; +/** Any HTTP method that the instrumentation has no prior knowledge of. */ +static constexpr const char *kOther = "_OTHER"; +} // namespace HttpRequestMethodValues + +namespace MessagingOperationValues +{ +/** One or more messages are provided for publishing to an intermediary. If a single message is + * published, the context of the "Publish" span can be used as the creation context and no + * "Create" span needs to be created. */ +static constexpr const char *kPublish = "publish"; +/** A message is created. "Create" spans always refer to a single message and are used to + * provide a unique creation context for messages in batch publishing scenarios. */ +static constexpr const char *kCreate = "create"; +/** One or more messages are requested by a consumer. This operation refers to pull-based scenarios, + * where consumers explicitly call methods of messaging SDKs to receive messages. */ +static constexpr const char *kReceive = "receive"; +/** One or more messages are passed to a consumer. This operation refers to push-based scenarios, + * where consumer register callbacks which get called by messaging SDKs. */ +static constexpr const char *kDeliver = "deliver"; +} // namespace MessagingOperationValues + +namespace MessagingRocketmqConsumptionModelValues +{ +/** Clustering consumption model. */ +static constexpr const char *kClustering = "clustering"; +/** Broadcasting consumption model. */ +static constexpr const char *kBroadcasting = "broadcasting"; +} // namespace MessagingRocketmqConsumptionModelValues + +namespace MessagingRocketmqMessageTypeValues +{ +/** Normal message. */ +static constexpr const char *kNormal = "normal"; +/** FIFO message. */ +static constexpr const char *kFifo = "fifo"; +/** Delay message. */ +static constexpr const char *kDelay = "delay"; +/** Transaction message. */ +static constexpr const char *kTransaction = "transaction"; +} // namespace MessagingRocketmqMessageTypeValues namespace NetworkConnectionSubtypeValues { @@ -1979,35 +2064,119 @@ static constexpr const char *kUnavailable = "unavailable"; static constexpr const char *kUnknown = "unknown"; } // namespace NetworkConnectionTypeValues -namespace HttpRequestMethodValues +namespace NetworkTransportValues { -/** CONNECT method. */ -static constexpr const char *kConnect = "CONNECT"; -/** DELETE method. */ -static constexpr const char *kDelete = "DELETE"; -/** GET method. */ -static constexpr const char *kGet = "GET"; -/** HEAD method. */ -static constexpr const char *kHead = "HEAD"; -/** OPTIONS method. */ -static constexpr const char *kOptions = "OPTIONS"; -/** PATCH method. */ -static constexpr const char *kPatch = "PATCH"; -/** POST method. */ -static constexpr const char *kPost = "POST"; -/** PUT method. */ -static constexpr const char *kPut = "PUT"; -/** TRACE method. */ -static constexpr const char *kTrace = "TRACE"; -/** Any HTTP method that the instrumentation has no prior knowledge of. */ -static constexpr const char *kOther = "_OTHER"; -} // namespace HttpRequestMethodValues +/** TCP. */ +static constexpr const char *kTcp = "tcp"; +/** UDP. */ +static constexpr const char *kUdp = "udp"; +/** Named or anonymous pipe. */ +static constexpr const char *kPipe = "pipe"; +/** Unix domain socket. */ +static constexpr const char *kUnix = "unix"; +} // namespace NetworkTransportValues + +namespace NetworkTypeValues +{ +/** IPv4. */ +static constexpr const char *kIpv4 = "ipv4"; +/** IPv6. */ +static constexpr const char *kIpv6 = "ipv6"; +} // namespace NetworkTypeValues + +namespace RpcConnectRpcErrorCodeValues +{ +/** cancelled. */ +static constexpr const char *kCancelled = "cancelled"; +/** unknown. */ +static constexpr const char *kUnknown = "unknown"; +/** invalid_argument. */ +static constexpr const char *kInvalidArgument = "invalid_argument"; +/** deadline_exceeded. */ +static constexpr const char *kDeadlineExceeded = "deadline_exceeded"; +/** not_found. */ +static constexpr const char *kNotFound = "not_found"; +/** already_exists. */ +static constexpr const char *kAlreadyExists = "already_exists"; +/** permission_denied. */ +static constexpr const char *kPermissionDenied = "permission_denied"; +/** resource_exhausted. */ +static constexpr const char *kResourceExhausted = "resource_exhausted"; +/** failed_precondition. */ +static constexpr const char *kFailedPrecondition = "failed_precondition"; +/** aborted. */ +static constexpr const char *kAborted = "aborted"; +/** out_of_range. */ +static constexpr const char *kOutOfRange = "out_of_range"; +/** unimplemented. */ +static constexpr const char *kUnimplemented = "unimplemented"; +/** internal. */ +static constexpr const char *kInternal = "internal"; +/** unavailable. */ +static constexpr const char *kUnavailable = "unavailable"; +/** data_loss. */ +static constexpr const char *kDataLoss = "data_loss"; +/** unauthenticated. */ +static constexpr const char *kUnauthenticated = "unauthenticated"; +} // namespace RpcConnectRpcErrorCodeValues + +namespace RpcGrpcStatusCodeValues +{ +/** OK. */ +static constexpr const int kOk = 0; +/** CANCELLED. */ +static constexpr const int kCancelled = 1; +/** UNKNOWN. */ +static constexpr const int kUnknown = 2; +/** INVALID_ARGUMENT. */ +static constexpr const int kInvalidArgument = 3; +/** DEADLINE_EXCEEDED. */ +static constexpr const int kDeadlineExceeded = 4; +/** NOT_FOUND. */ +static constexpr const int kNotFound = 5; +/** ALREADY_EXISTS. */ +static constexpr const int kAlreadyExists = 6; +/** PERMISSION_DENIED. */ +static constexpr const int kPermissionDenied = 7; +/** RESOURCE_EXHAUSTED. */ +static constexpr const int kResourceExhausted = 8; +/** FAILED_PRECONDITION. */ +static constexpr const int kFailedPrecondition = 9; +/** ABORTED. */ +static constexpr const int kAborted = 10; +/** OUT_OF_RANGE. */ +static constexpr const int kOutOfRange = 11; +/** UNIMPLEMENTED. */ +static constexpr const int kUnimplemented = 12; +/** INTERNAL. */ +static constexpr const int kInternal = 13; +/** UNAVAILABLE. */ +static constexpr const int kUnavailable = 14; +/** DATA_LOSS. */ +static constexpr const int kDataLoss = 15; +/** UNAUTHENTICATED. */ +static constexpr const int kUnauthenticated = 16; +} // namespace RpcGrpcStatusCodeValues + +namespace RpcSystemValues +{ +/** gRPC. */ +static constexpr const char *kGrpc = "grpc"; +/** Java RMI. */ +static constexpr const char *kJavaRmi = "java_rmi"; +/** .NET WCF. */ +static constexpr const char *kDotnetWcf = "dotnet_wcf"; +/** Apache Dubbo. */ +static constexpr const char *kApacheDubbo = "apache_dubbo"; +/** Connect RPC. */ +static constexpr const char *kConnectRpc = "connect_rpc"; +} // namespace RpcSystemValues namespace OpentracingRefTypeValues { /** The parent Span depends on the child Span in some capacity. */ static constexpr const char *kChildOf = "child_of"; -/** The parent Span does not depend in any way on the result of the child Span. */ +/** The parent Span doesn't depend in any way on the result of the child Span. */ static constexpr const char *kFollowsFrom = "follows_from"; } // namespace OpentracingRefTypeValues @@ -2216,88 +2385,6 @@ static constexpr const char *kMutation = "mutation"; static constexpr const char *kSubscription = "subscription"; } // namespace GraphqlOperationTypeValues -namespace MessagingOperationValues -{ -/** publish. */ -static constexpr const char *kPublish = "publish"; -/** receive. */ -static constexpr const char *kReceive = "receive"; -/** process. */ -static constexpr const char *kProcess = "process"; -} // namespace MessagingOperationValues - -namespace MessagingRocketmqConsumptionModelValues -{ -/** Clustering consumption model. */ -static constexpr const char *kClustering = "clustering"; -/** Broadcasting consumption model. */ -static constexpr const char *kBroadcasting = "broadcasting"; -} // namespace MessagingRocketmqConsumptionModelValues - -namespace MessagingRocketmqMessageTypeValues -{ -/** Normal message. */ -static constexpr const char *kNormal = "normal"; -/** FIFO message. */ -static constexpr const char *kFifo = "fifo"; -/** Delay message. */ -static constexpr const char *kDelay = "delay"; -/** Transaction message. */ -static constexpr const char *kTransaction = "transaction"; -} // namespace MessagingRocketmqMessageTypeValues - -namespace RpcSystemValues -{ -/** gRPC. */ -static constexpr const char *kGrpc = "grpc"; -/** Java RMI. */ -static constexpr const char *kJavaRmi = "java_rmi"; -/** .NET WCF. */ -static constexpr const char *kDotnetWcf = "dotnet_wcf"; -/** Apache Dubbo. */ -static constexpr const char *kApacheDubbo = "apache_dubbo"; -/** Connect RPC. */ -static constexpr const char *kConnectRpc = "connect_rpc"; -} // namespace RpcSystemValues - -namespace RpcGrpcStatusCodeValues -{ -/** OK. */ -static constexpr const int kOk = 0; -/** CANCELLED. */ -static constexpr const int kCancelled = 1; -/** UNKNOWN. */ -static constexpr const int kUnknown = 2; -/** INVALID_ARGUMENT. */ -static constexpr const int kInvalidArgument = 3; -/** DEADLINE_EXCEEDED. */ -static constexpr const int kDeadlineExceeded = 4; -/** NOT_FOUND. */ -static constexpr const int kNotFound = 5; -/** ALREADY_EXISTS. */ -static constexpr const int kAlreadyExists = 6; -/** PERMISSION_DENIED. */ -static constexpr const int kPermissionDenied = 7; -/** RESOURCE_EXHAUSTED. */ -static constexpr const int kResourceExhausted = 8; -/** FAILED_PRECONDITION. */ -static constexpr const int kFailedPrecondition = 9; -/** ABORTED. */ -static constexpr const int kAborted = 10; -/** OUT_OF_RANGE. */ -static constexpr const int kOutOfRange = 11; -/** UNIMPLEMENTED. */ -static constexpr const int kUnimplemented = 12; -/** INTERNAL. */ -static constexpr const int kInternal = 13; -/** UNAVAILABLE. */ -static constexpr const int kUnavailable = 14; -/** DATA_LOSS. */ -static constexpr const int kDataLoss = 15; -/** UNAUTHENTICATED. */ -static constexpr const int kUnauthenticated = 16; -} // namespace RpcGrpcStatusCodeValues - namespace MessageTypeValues { /** sent. */ @@ -2306,42 +2393,6 @@ static constexpr const char *kSent = "SENT"; static constexpr const char *kReceived = "RECEIVED"; } // namespace MessageTypeValues -namespace RpcConnectRpcErrorCodeValues -{ -/** cancelled. */ -static constexpr const char *kCancelled = "cancelled"; -/** unknown. */ -static constexpr const char *kUnknown = "unknown"; -/** invalid_argument. */ -static constexpr const char *kInvalidArgument = "invalid_argument"; -/** deadline_exceeded. */ -static constexpr const char *kDeadlineExceeded = "deadline_exceeded"; -/** not_found. */ -static constexpr const char *kNotFound = "not_found"; -/** already_exists. */ -static constexpr const char *kAlreadyExists = "already_exists"; -/** permission_denied. */ -static constexpr const char *kPermissionDenied = "permission_denied"; -/** resource_exhausted. */ -static constexpr const char *kResourceExhausted = "resource_exhausted"; -/** failed_precondition. */ -static constexpr const char *kFailedPrecondition = "failed_precondition"; -/** aborted. */ -static constexpr const char *kAborted = "aborted"; -/** out_of_range. */ -static constexpr const char *kOutOfRange = "out_of_range"; -/** unimplemented. */ -static constexpr const char *kUnimplemented = "unimplemented"; -/** internal. */ -static constexpr const char *kInternal = "internal"; -/** unavailable. */ -static constexpr const char *kUnavailable = "unavailable"; -/** data_loss. */ -static constexpr const char *kDataLoss = "data_loss"; -/** unauthenticated. */ -static constexpr const char *kUnauthenticated = "unauthenticated"; -} // namespace RpcConnectRpcErrorCodeValues - } // namespace SemanticConventions } // namespace trace OPENTELEMETRY_END_NAMESPACE diff --git a/api/include/opentelemetry/trace/span_context_kv_iterable_view.h b/api/include/opentelemetry/trace/span_context_kv_iterable_view.h index 6a21aaf54a..8c4584dc2e 100644 --- a/api/include/opentelemetry/trace/span_context_kv_iterable_view.h +++ b/api/include/opentelemetry/trace/span_context_kv_iterable_view.h @@ -24,7 +24,7 @@ namespace trace namespace detail { template -inline void take_span_context_kv(SpanContext, common::KeyValueIterableView) +inline void take_span_context_kv(SpanContext, opentelemetry::common::KeyValueIterableView) {} template ::value> * = nullptr> diff --git a/api/include/opentelemetry/trace/span_metadata.h b/api/include/opentelemetry/trace/span_metadata.h index 5e615ea537..d2d6a9f85d 100644 --- a/api/include/opentelemetry/trace/span_metadata.h +++ b/api/include/opentelemetry/trace/span_metadata.h @@ -20,7 +20,8 @@ enum class SpanKind }; // The key identifies the active span in the current context. -constexpr char kSpanKey[] = "active_span"; +constexpr char kSpanKey[] = "active_span"; +constexpr char kIsRootSpanKey[] = "is_root_span"; // StatusCode - Represents the canonical set of status codes of a finished Span. enum class StatusCode diff --git a/api/include/opentelemetry/trace/span_startoptions.h b/api/include/opentelemetry/trace/span_startoptions.h index 2180394d72..8a2165b0f0 100644 --- a/api/include/opentelemetry/trace/span_startoptions.h +++ b/api/include/opentelemetry/trace/span_startoptions.h @@ -34,8 +34,31 @@ struct StartSpanOptions // Explicitly set the parent of a Span. // - // This defaults to an invalid span context. In this case, the Span is - // automatically parented to the currently active span. + // The `parent` field is designed to establish parent-child relationships + // in tracing spans. It can be set to either a `SpanContext` or a + // `context::Context` object. + // + // - When set to valid `SpanContext`, it directly assigns a specific Span as the parent + // of the newly created Span. + // + // - Alternatively, setting the `parent` field to a `context::Context` allows for + // more nuanced parent identification: + // 1. If the `Context` contains a Span object, this Span is treated as the parent. + // 2. If the `Context` contains the boolean flag `is_root_span` set to `true`, + // it indicates that the new Span should be treated as a root Span, i.e., it + // does not have a parent Span. + // Example Usage: + // ```cpp + // trace_api::StartSpanOptions options; + // opentelemetry::context::Context root; + // root = root.SetValue(kIsRootSpanKey, true); + // options.parent = root; + // auto root_span = tracer->StartSpan("span root", options); + // ``` + // + // - If the `parent` field is not set, the newly created Span will inherit the + // parent of the currently active Span (if any) in the current context. + // nostd::variant parent = SpanContext::GetInvalid(); // TODO: diff --git a/api/include/opentelemetry/trace/trace_state.h b/api/include/opentelemetry/trace/trace_state.h index f424b01997..8a25f4da5c 100644 --- a/api/include/opentelemetry/trace/trace_state.h +++ b/api/include/opentelemetry/trace/trace_state.h @@ -14,7 +14,7 @@ #include "opentelemetry/nostd/unique_ptr.h" #include "opentelemetry/version.h" -#if defined(OPENTELEMETRY_HAVE_WORKING_REGEX) +#if OPENTELEMETRY_HAVE_WORKING_REGEX # include #endif @@ -246,6 +246,7 @@ class OPENTELEMETRY_EXPORT TraceState return str.substr(left, right - left + 1); } +#if OPENTELEMETRY_HAVE_WORKING_REGEX static bool IsValidKeyRegEx(nostd::string_view key) { static std::regex reg_key("^[a-z0-9][a-z0-9*_\\-/]{0,255}$"); @@ -267,7 +268,7 @@ class OPENTELEMETRY_EXPORT TraceState // Need to benchmark without regex, as a string object is created here. return std::regex_match(std::string(value.data(), value.size()), reg_value); } - +#else static bool IsValidKeyNonRegEx(nostd::string_view key) { if (key.empty() || key.size() > kKeyMaxSize || !IsLowerCaseAlphaOrDigit(key[0])) @@ -307,6 +308,7 @@ class OPENTELEMETRY_EXPORT TraceState } return true; } +#endif static bool IsLowerCaseAlphaOrDigit(char c) { return isdigit(c) || islower(c); } diff --git a/api/include/opentelemetry/version.h b/api/include/opentelemetry/version.h index 79284c1501..7b9fa1da02 100644 --- a/api/include/opentelemetry/version.h +++ b/api/include/opentelemetry/version.h @@ -10,9 +10,9 @@ # define OPENTELEMETRY_ABI_VERSION_NO 1 #endif -#define OPENTELEMETRY_VERSION "1.12.0" +#define OPENTELEMETRY_VERSION "1.13.0" #define OPENTELEMETRY_VERSION_MAJOR 1 -#define OPENTELEMETRY_VERSION_MINOR 12 +#define OPENTELEMETRY_VERSION_MINOR 13 #define OPENTELEMETRY_VERSION_PATCH 0 #define OPENTELEMETRY_ABI_VERSION OPENTELEMETRY_STRINGIFY(OPENTELEMETRY_ABI_VERSION_NO) diff --git a/api/test/nostd/string_view_test.cc b/api/test/nostd/string_view_test.cc index 52c72ea4d8..bbd5cb0648 100644 --- a/api/test/nostd/string_view_test.cc +++ b/api/test/nostd/string_view_test.cc @@ -71,8 +71,8 @@ TEST(StringViewTest, SubstrPortion) TEST(StringViewTest, SubstrOutOfRange) { string_view s = "abc123"; -#if __EXCEPTIONS || ((defined(OPENTELEMETRY_STL_VERSION) && (OPENTELEMETRY_STL_VERSION >= 2020))) - EXPECT_THROW(s.substr(10), std::out_of_range); +#if __EXCEPTIONS || (defined(OPENTELEMETRY_STL_VERSION) && (OPENTELEMETRY_STL_VERSION >= 2017)) + EXPECT_THROW((void)s.substr(10), std::out_of_range); #else EXPECT_DEATH({ s.substr(10); }, ""); #endif diff --git a/api/test/nostd/variant_test.cc b/api/test/nostd/variant_test.cc index cea5c4ee7b..a910106390 100644 --- a/api/test/nostd/variant_test.cc +++ b/api/test/nostd/variant_test.cc @@ -48,7 +48,7 @@ TEST(VariantTest, Get) EXPECT_EQ(nostd::get(w), 12); EXPECT_EQ(*nostd::get_if(&v), 12); EXPECT_EQ(nostd::get_if(&v), nullptr); -#if __EXCEPTIONS +#if __EXCEPTIONS || (defined(OPENTELEMETRY_STL_VERSION) && (OPENTELEMETRY_STL_VERSION >= 2017)) EXPECT_THROW(nostd::get(w), nostd::bad_variant_access); #else EXPECT_DEATH({ nostd::get(w); }, ""); diff --git a/buildscripts/semantic-convention/generate.sh b/buildscripts/semantic-convention/generate.sh index daa5131dc5..1994869439 100755 --- a/buildscripts/semantic-convention/generate.sh +++ b/buildscripts/semantic-convention/generate.sh @@ -18,10 +18,10 @@ ROOT_DIR="${SCRIPT_DIR}/../../" # https://github.com/open-telemetry/opentelemetry-specification # Repository from 1.21.0: # https://github.com/open-telemetry/semantic-conventions -SEMCONV_VERSION=1.22.0 +SEMCONV_VERSION=1.23.1 # repository: https://github.com/open-telemetry/build-tools -GENERATOR_VERSION=0.22.0 +GENERATOR_VERSION=0.23.0 SPEC_VERSION=v$SEMCONV_VERSION SCHEMA_URL=https://opentelemetry.io/schemas/$SEMCONV_VERSION @@ -38,6 +38,19 @@ git fetch origin "$SPEC_VERSION" git reset --hard FETCH_HEAD cd ${SCRIPT_DIR} +# SELINUX +# https://docs.docker.com/storage/bind-mounts/#configure-the-selinux-label + +USE_MOUNT_OPTION="" + +if [ -x "$(command -v getenforce)" ]; then + SELINUXSTATUS=$(getenforce); + if [ "${SELINUXSTATUS}" == "Enforcing" ]; then + echo "Detected SELINUX" + USE_MOUNT_OPTION=":z" + fi; +fi + # echo "Help ..." # docker run --rm otel/semconvgen:$GENERATOR_VERSION -h @@ -45,9 +58,9 @@ cd ${SCRIPT_DIR} echo "Generating semantic conventions for traces ..." docker run --rm \ - -v ${SCRIPT_DIR}/tmp-semconv/model:/source \ - -v ${SCRIPT_DIR}/templates:/templates \ - -v ${ROOT_DIR}/api/include/opentelemetry/trace/:/output \ + -v ${SCRIPT_DIR}/tmp-semconv/model:/source${USE_MOUNT_OPTION} \ + -v ${SCRIPT_DIR}/templates:/templates${USE_MOUNT_OPTION} \ + -v ${ROOT_DIR}/api/include/opentelemetry/trace/:/output${USE_MOUNT_OPTION} \ otel/semconvgen:$GENERATOR_VERSION \ --only span,event,attribute_group,scope \ -f /source code \ @@ -62,9 +75,9 @@ docker run --rm \ echo "Generating semantic conventions for resources ..." docker run --rm \ - -v ${SCRIPT_DIR}/tmp-semconv/model:/source \ - -v ${SCRIPT_DIR}/templates:/templates \ - -v ${ROOT_DIR}/sdk/include/opentelemetry/sdk/resource/:/output \ + -v ${SCRIPT_DIR}/tmp-semconv/model:/source${USE_MOUNT_OPTION} \ + -v ${SCRIPT_DIR}/templates:/templates${USE_MOUNT_OPTION} \ + -v ${ROOT_DIR}/sdk/include/opentelemetry/sdk/resource/:/output${USE_MOUNT_OPTION} \ otel/semconvgen:$GENERATOR_VERSION \ --only resource \ -f /source code \ diff --git a/ci/do_ci.ps1 b/ci/do_ci.ps1 index 0b6cd9513e..a1e8c10014 100644 --- a/ci/do_ci.ps1 +++ b/ci/do_ci.ps1 @@ -112,6 +112,30 @@ switch ($action) { exit $exit } } + "cmake.maintainer.cxx20.stl.test" { + cd "$BUILD_DIR" + cmake $SRC_DIR ` + -DWITH_STL=CXX20 ` + -DCMAKE_CXX_STANDARD=20 ` + -DOTELCPP_MAINTAINER_MODE=ON ` + -DWITH_NO_DEPRECATED_CODE=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 . -j $nproc + $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 b06b5106f1..7be5cfa6a9 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -110,8 +110,6 @@ elif [[ "$1" == "cmake.maintainer.sync.test" ]]; then rm -rf * cmake ${CMAKE_OPTIONS[@]} \ -DWITH_OTLP_HTTP=ON \ - -DWITH_OTLP_HTTP_SSL_PREVIEW=ON \ - -DWITH_OTLP_HTTP_SSL_TLS_PREVIEW=ON \ -DWITH_PROMETHEUS=ON \ -DWITH_EXAMPLES=ON \ -DWITH_EXAMPLES_HTTP=ON \ @@ -132,8 +130,6 @@ elif [[ "$1" == "cmake.maintainer.async.test" ]]; then rm -rf * cmake ${CMAKE_OPTIONS[@]} \ -DWITH_OTLP_HTTP=ON \ - -DWITH_OTLP_HTTP_SSL_PREVIEW=ON \ - -DWITH_OTLP_HTTP_SSL_TLS_PREVIEW=ON \ -DWITH_PROMETHEUS=ON \ -DWITH_EXAMPLES=ON \ -DWITH_EXAMPLES_HTTP=ON \ @@ -155,8 +151,6 @@ elif [[ "$1" == "cmake.maintainer.cpp11.async.test" ]]; then cmake ${CMAKE_OPTIONS[@]} \ -DCMAKE_CXX_STANDARD=11 \ -DWITH_OTLP_HTTP=ON \ - -DWITH_OTLP_HTTP_SSL_PREVIEW=ON \ - -DWITH_OTLP_HTTP_SSL_TLS_PREVIEW=ON \ -DWITH_PROMETHEUS=ON \ -DWITH_EXAMPLES=ON \ -DWITH_EXAMPLES_HTTP=ON \ @@ -176,8 +170,6 @@ elif [[ "$1" == "cmake.maintainer.abiv2.test" ]]; then rm -rf * cmake ${CMAKE_OPTIONS[@]} \ -DWITH_OTLP_HTTP=ON \ - -DWITH_OTLP_HTTP_SSL_PREVIEW=ON \ - -DWITH_OTLP_HTTP_SSL_TLS_PREVIEW=ON \ -DWITH_PROMETHEUS=ON \ -DWITH_EXAMPLES=ON \ -DWITH_EXAMPLES_HTTP=ON \ @@ -484,8 +476,7 @@ elif [[ "$1" == "bazel.asan" ]]; then elif [[ "$1" == "bazel.tsan" ]]; then # TODO - potential race condition in Civetweb server used by prometheus-cpp during shutdown # https://github.com/civetweb/civetweb/issues/861, so removing prometheus from the test -# zpages test failing with tsan. Ignoring the tests for now, as zpages will be removed soon. - bazel $BAZEL_STARTUP_OPTIONS test --config=tsan $BAZEL_TEST_OPTIONS_ASYNC -- //... -//exporters/prometheus/... -//ext/test/zpages/... + bazel $BAZEL_STARTUP_OPTIONS test --config=tsan $BAZEL_TEST_OPTIONS_ASYNC -- //... -//exporters/prometheus/... exit 0 elif [[ "$1" == "bazel.valgrind" ]]; then bazel $BAZEL_STARTUP_OPTIONS build $BAZEL_OPTIONS_ASYNC //... diff --git a/cmake/opentelemetry-build-external-component.cmake b/cmake/opentelemetry-build-external-component.cmake index 2d8d78afbf..74b6515209 100644 --- a/cmake/opentelemetry-build-external-component.cmake +++ b/cmake/opentelemetry-build-external-component.cmake @@ -1,10 +1,19 @@ # Copyright The OpenTelemetry Authors # SPDX-License-Identifier: Apache-2.0 +function(get_directory_name_in_path PATH_VAR RESULT_VAR) + # get_filename_component does not work with paths ending in / or \, so remove it. + string(REGEX REPLACE "[/\\]$" "" PATH_TRIMMED "${PATH_VAR}") + + get_filename_component(DIR_NAME ${PATH_TRIMMED} NAME) + + set(${RESULT_VAR} "${DIR_NAME}" PARENT_SCOPE) +endfunction() + # Enable building external components through otel-cpp build # The config options are -# - OPENTELEMETRY_EXTERNAL_COMPONENT_PATH - Setting local path of the external -# component as env variable +# - OPENTELEMETRY_EXTERNAL_COMPONENT_PATH - Setting local paths of the external +# component as env variable. Multiple paths can be set by separating them with. # - OPENTELEMETRY_EXTERNAL_COMPONENT_URL Setting github-repo of external component # as env variable @@ -13,13 +22,18 @@ if(OPENTELEMETRY_EXTERNAL_COMPONENT_PATH) # Add custom component path to build tree and consolidate binary artifacts in # current project binary output directory. - add_subdirectory(${OPENTELEMETRY_EXTERNAL_COMPONENT_PATH} - ${PROJECT_BINARY_DIR}/external) + foreach(DIR IN LISTS OPENTELEMETRY_EXTERNAL_COMPONENT_PATH) + get_directory_name_in_path(${DIR} EXTERNAL_EXPORTER_DIR_NAME) + add_subdirectory(${DIR} ${PROJECT_BINARY_DIR}/external/${EXTERNAL_EXPORTER_DIR_NAME}) + endforeach() elseif(DEFINED ENV{OPENTELEMETRY_EXTERNAL_COMPONENT_PATH}) # Add custom component path to build tree and consolidate binary artifacts in # current project binary output directory. - add_subdirectory($ENV{OPENTELEMETRY_EXTERNAL_COMPONENT_PATH} - ${PROJECT_BINARY_DIR}/external) + set(OPENTELEMETRY_EXTERNAL_COMPONENT_PATH_VAR $ENV{OPENTELEMETRY_EXTERNAL_COMPONENT_PATH}) + foreach(DIR IN LISTS OPENTELEMETRY_EXTERNAL_COMPONENT_PATH_VAR) + get_directory_name_in_path(${DIR} EXTERNAL_EXPORTER_DIR_NAME) + add_subdirectory(${DIR} ${PROJECT_BINARY_DIR}/external/${EXTERNAL_EXPORTER_DIR_NAME}) + endforeach() elseif(DEFINED $ENV{OPENTELEMETRY_EXTERNAL_COMPONENT_URL}) # This option requires CMake 3.11+: add standard remote repo to build tree. include(FetchContent) diff --git a/cmake/opentelemetry-cpp-config.cmake.in b/cmake/opentelemetry-cpp-config.cmake.in index 5c450c1df6..86098f7d7c 100644 --- a/cmake/opentelemetry-cpp-config.cmake.in +++ b/cmake/opentelemetry-cpp-config.cmake.in @@ -46,7 +46,6 @@ # opentelemetry-cpp::ostream_span_exporter - Imported target of opentelemetry-cpp::ostream_span_exporter # opentelemetry-cpp::elasticsearch_log_record_exporter - Imported target of opentelemetry-cpp::elasticsearch_log_record_exporter # opentelemetry-cpp::etw_exporter - Imported target of opentelemetry-cpp::etw_exporter -# opentelemetry-cpp::zpages - Imported target of opentelemetry-cpp::zpages # opentelemetry-cpp::http_client_curl - Imported target of opentelemetry-cpp::http_client_curl # opentelemetry-cpp::opentracing_shim - Imported target of opentelemetry-cpp::opentracing_shim # @@ -100,7 +99,6 @@ set(_OPENTELEMETRY_CPP_LIBRARIES_TEST_TARGETS prometheus_exporter elasticsearch_log_record_exporter etw_exporter - zpages http_client_curl opentracing_shim) foreach(_TEST_TARGET IN LISTS _OPENTELEMETRY_CPP_LIBRARIES_TEST_TARGETS) diff --git a/cmake/patch-imported-config.cmake b/cmake/patch-imported-config.cmake index ec68d74099..a2d22ed398 100644 --- a/cmake/patch-imported-config.cmake +++ b/cmake/patch-imported-config.cmake @@ -21,8 +21,11 @@ if(TARGET c-ares::cares) endif() # curl targets -if(TARGET CURL::libcurl) - project_build_tools_patch_default_imported_config(CURL::libcurl) +if(TARGET CURL::libcurl + OR TARGET CURL::libcurl_static + OR TARGET CURL::libcurl_shared) + project_build_tools_patch_default_imported_config( + CURL::libcurl CURL::libcurl_static CURL::libcurl_shared) endif() # abseil targets diff --git a/cmake/tools.cmake b/cmake/tools.cmake index ee191121ca..43c1a7b43f 100644 --- a/cmake/tools.cmake +++ b/cmake/tools.cmake @@ -14,7 +14,16 @@ endmacro() if(NOT PATCH_PROTOBUF_SOURCES_OPTIONS_SET) if(MSVC) unset(PATCH_PROTOBUF_SOURCES_OPTIONS CACHE) - set(PATCH_PROTOBUF_SOURCES_OPTIONS /wd4244 /wd4251 /wd4267 /wd4309 /wd4668 /wd4946 /wd6001 /wd6244 /wd6246) + set(PATCH_PROTOBUF_SOURCES_OPTIONS + /wd4244 + /wd4251 + /wd4267 + /wd4309 + /wd4668 + /wd4946 + /wd6001 + /wd6244 + /wd6246) if(MSVC_VERSION GREATER_EQUAL 1922) # see @@ -147,6 +156,11 @@ function(project_build_tools_patch_default_imported_config) continue() endif() + get_target_property(IS_ALIAS_TARGET ${TARGET_NAME} ALIASED_TARGET) + if(IS_ALIAS_TARGET) + continue() + endif() + if(CMAKE_VERSION VERSION_LESS "3.19.0") get_target_property(TARGET_TYPE_NAME ${TARGET_NAME} TYPE) if(TARGET_TYPE_NAME STREQUAL "INTERFACE_LIBRARY") diff --git a/docs/cpp-ostream-exporter-design.md b/docs/cpp-ostream-exporter-design.md index 7deb369ab3..6da8bdd032 100644 --- a/docs/cpp-ostream-exporter-design.md +++ b/docs/cpp-ostream-exporter-design.md @@ -154,7 +154,7 @@ public: return sdktrace::ExportResult::kSuccess; } - bool Shutdown(std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept + bool Shutdown(std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept { isShutdown = true; return true; diff --git a/docs/dependencies.md b/docs/dependencies.md index 2f2f2368f6..da6c584fe8 100644 --- a/docs/dependencies.md +++ b/docs/dependencies.md @@ -92,9 +92,6 @@ Both these dependencies are listed here: - `libcurl` for connecting with Elasticsearch server over HTTP protocol. - `nlohmann/json` for encoding Elastic Search messages. -- [Zpages](/ext/src/zpages): - - None - - [Opentracing](/opentracing-shim) shim: - [`opentracing-cpp`](https://github.com/opentracing/opentracing-cpp) diff --git a/docs/public/conf.py b/docs/public/conf.py index 2375c45924..592f7340fe 100644 --- a/docs/public/conf.py +++ b/docs/public/conf.py @@ -24,7 +24,7 @@ author = 'OpenTelemetry authors' # The full version, including alpha/beta/rc tags -release = "1.12.0" +release = "1.13.0" # Run sphinx on subprojects and copy output # ----------------------------------------- diff --git a/examples/zpages/BUILD b/examples/zpages/BUILD deleted file mode 100644 index 529c839cb7..0000000000 --- a/examples/zpages/BUILD +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -package(default_visibility = ["//visibility:public"]) - -cc_binary( - name = "zpages_example", - srcs = [ - "zpages_example.cc", - ], - linkopts = select({ - "//bazel:windows": [], - "//conditions:default": ["-pthread"], - }), - tags = ["examples"], - deps = [ - "//ext:headers", - "//ext/src/zpages", - "//sdk/src/trace", - ], -) diff --git a/examples/zpages/zpages_example.cc b/examples/zpages/zpages_example.cc deleted file mode 100644 index 2691a73158..0000000000 --- a/examples/zpages/zpages_example.cc +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -/** - * This is a basic example for zpages that helps users get familiar with how to - * use this feature in OpenTelemetery - */ -#include -#include -#include - -#include "opentelemetry/ext/zpages/zpages.h" // Required file include for zpages - -using opentelemetry::common::SteadyTimestamp; -namespace trace_api = opentelemetry::trace; - -int main(int argc, char *argv[]) -{ - - /** - * The following line initializes zPages and starts a webserver at - * http://localhost:30000/tracez/ where spans that are created in the application - * can be viewed. - * Note that the webserver is destroyed after the application ends execution. - */ - ZPages::Initialize(); - auto tracer = trace_api::Provider::GetTracerProvider()->GetTracer(""); - - std::cout << "This example for zPages creates a few types of spans and then " - << "creates a span every second for the duration of the application" - << "\n"; - - // Error span - std::map attribute_map; - attribute_map["completed_search_for"] = "Unknown user"; - tracer->StartSpan("find user", attribute_map) - ->SetStatus(trace_api::StatusCode::kError, "User not found"); - - // Long time duration span - std::map attribute_map2; - attribute_map2["completed_search_for"] = "John Doe"; - trace_api::StartSpanOptions start; - start.start_steady_time = SteadyTimestamp(nanoseconds(1)); - trace_api::EndSpanOptions end; - end.end_steady_time = SteadyTimestamp(nanoseconds(1000000000000)); - tracer->StartSpan("find user", attribute_map2, start)->End(end); - - // Running(deadlock) span - std::map attribute_map3; - attribute_map3["searching_for"] = "Deleted user"; - auto running_span = tracer->StartSpan("find user", attribute_map3); - - // Create a completed span every second till user stops the loop - std::cout << "Presss CTRL+C to stop...\n"; - while (true) - { - std::this_thread::sleep_for(seconds(1)); - tracer->StartSpan("ping user")->End(); - } -} diff --git a/exporters/elasticsearch/include/opentelemetry/exporters/elasticsearch/es_log_record_exporter.h b/exporters/elasticsearch/include/opentelemetry/exporters/elasticsearch/es_log_record_exporter.h index 8579c99138..b72ff4f917 100644 --- a/exporters/elasticsearch/include/opentelemetry/exporters/elasticsearch/es_log_record_exporter.h +++ b/exporters/elasticsearch/include/opentelemetry/exporters/elasticsearch/es_log_record_exporter.h @@ -100,14 +100,14 @@ class ElasticsearchLogRecordExporter final : public opentelemetry::sdk::logs::Lo * @return return true when all data are exported, and false when timeout */ bool ForceFlush( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override; + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override; /** * Shutdown this exporter. * @param timeout The maximum time to wait for the shutdown method to return */ bool Shutdown( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override; + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override; private: // Stores if this exporter had its Shutdown() method called diff --git a/exporters/elasticsearch/src/es_log_record_exporter.cc b/exporters/elasticsearch/src/es_log_record_exporter.cc index c90072e4e4..e167faf3d9 100644 --- a/exporters/elasticsearch/src/es_log_record_exporter.cc +++ b/exporters/elasticsearch/src/es_log_record_exporter.cc @@ -430,7 +430,7 @@ bool ElasticsearchLogRecordExporter::ForceFlush( std::chrono::duration_cast(timeout); if (timeout_steady <= std::chrono::steady_clock::duration::zero()) { - timeout_steady = std::chrono::steady_clock::duration::max(); + timeout_steady = (std::chrono::steady_clock::duration::max)(); } std::unique_lock lk_cv(synchronization_data_->force_flush_cv_m); diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_logger.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_logger.h index 819caf7105..494211ea0b 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_logger.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_logger.h @@ -229,7 +229,7 @@ class Logger : public opentelemetry::logs::Logger opentelemetry::trace::TraceId trace_id, opentelemetry::trace::SpanId span_id, opentelemetry::trace::TraceFlags trace_flags, - common::SystemTimestamp timestamp) noexcept + opentelemetry::common::SystemTimestamp timestamp) noexcept { UNREFERENCED_PARAMETER(trace_flags); @@ -358,11 +358,12 @@ class LoggerProvider : public opentelemetry::logs::LoggerProvider } nostd::shared_ptr GetLogger( - nostd::string_view logger_name, - nostd::string_view library_name, - nostd::string_view version = "", - nostd::string_view schema_url = "", - const common::KeyValueIterable &attributes = common::NoopKeyValueIterable()) override + opentelemetry::nostd::string_view logger_name, + opentelemetry::nostd::string_view library_name, + opentelemetry::nostd::string_view version = "", + opentelemetry::nostd::string_view schema_url = "", + const opentelemetry::common::KeyValueIterable &attributes = + opentelemetry::common::NoopKeyValueIterable()) override { UNREFERENCED_PARAMETER(library_name); UNREFERENCED_PARAMETER(version); diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h index 3cf365c8a0..f35b5f11b4 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h @@ -195,67 +195,67 @@ class PropertyValue : public PropertyVariant * @brief Convert non-owning common::AttributeValue to owning PropertyValue. * @return */ - PropertyValue &FromAttributeValue(const common::AttributeValue &v) + PropertyValue &FromAttributeValue(const opentelemetry::common::AttributeValue &v) { switch (v.index()) { - case common::AttributeType::kTypeBool: + case opentelemetry::common::AttributeType::kTypeBool: PropertyVariant::operator=(nostd::get(v)); break; - case common::AttributeType::kTypeInt: + case opentelemetry::common::AttributeType::kTypeInt: PropertyVariant::operator=(nostd::get(v)); break; - case common::AttributeType::kTypeInt64: + case opentelemetry::common::AttributeType::kTypeInt64: PropertyVariant::operator=(nostd::get(v)); break; - case common::AttributeType::kTypeUInt: + case opentelemetry::common::AttributeType::kTypeUInt: PropertyVariant::operator=(nostd::get(v)); break; - case common::AttributeType::kTypeUInt64: + case opentelemetry::common::AttributeType::kTypeUInt64: PropertyVariant::operator=(nostd::get(v)); break; - case common::AttributeType::kTypeDouble: + case opentelemetry::common::AttributeType::kTypeDouble: PropertyVariant::operator=(nostd::get(v)); break; - case common::AttributeType::kTypeCString: { + case opentelemetry::common::AttributeType::kTypeCString: { PropertyVariant::operator=(nostd::get(v)); break; } - case common::AttributeType::kTypeString: { + case opentelemetry::common::AttributeType::kTypeString: { PropertyVariant::operator= (std::string{nostd::string_view(nostd::get(v)).data()}); break; } - case common::AttributeType::kTypeSpanByte: + case opentelemetry::common::AttributeType::kTypeSpanByte: PropertyVariant::operator=(to_vector(nostd::get>(v))); break; - case common::AttributeType::kTypeSpanBool: + case opentelemetry::common::AttributeType::kTypeSpanBool: PropertyVariant::operator=(to_vector(nostd::get>(v))); break; - case common::AttributeType::kTypeSpanInt: + case opentelemetry::common::AttributeType::kTypeSpanInt: PropertyVariant::operator=(to_vector(nostd::get>(v))); break; - case common::AttributeType::kTypeSpanInt64: + case opentelemetry::common::AttributeType::kTypeSpanInt64: PropertyVariant::operator=(to_vector(nostd::get>(v))); break; - case common::AttributeType::kTypeSpanUInt: + case opentelemetry::common::AttributeType::kTypeSpanUInt: PropertyVariant::operator=(to_vector(nostd::get>(v))); break; - case common::AttributeType::kTypeSpanUInt64: + case opentelemetry::common::AttributeType::kTypeSpanUInt64: PropertyVariant::operator=(to_vector(nostd::get>(v))); break; - case common::AttributeType::kTypeSpanDouble: + case opentelemetry::common::AttributeType::kTypeSpanDouble: PropertyVariant::operator=(to_vector(nostd::get>(v))); break; - case common::AttributeType::kTypeSpanString: + case opentelemetry::common::AttributeType::kTypeSpanString: PropertyVariant::operator=(to_vector(nostd::get>(v))); break; @@ -269,9 +269,9 @@ class PropertyValue : public PropertyVariant * @brief Convert owning PropertyValue to non-owning common::AttributeValue * @param other */ - common::AttributeValue ToAttributeValue() const + opentelemetry::common::AttributeValue ToAttributeValue() const { - common::AttributeValue value; + opentelemetry::common::AttributeValue value; switch (this->index()) { @@ -353,7 +353,7 @@ using PropertyValueMap = std::map; /** * @brief Map of PropertyValue with common::KeyValueIterable interface. */ -class Properties : public common::KeyValueIterable, public PropertyValueMap +class Properties : public opentelemetry::common::KeyValueIterable, public PropertyValueMap { /** @@ -404,19 +404,20 @@ class Properties : public common::KeyValueIterable, public PropertyValueMap * container. * */ - Properties(const common::KeyValueIterable &other) { (*this) = other; } + Properties(const opentelemetry::common::KeyValueIterable &other) { (*this) = other; } /** * @brief PropertyValueMap assignment operator. */ - Properties &operator=(const common::KeyValueIterable &other) + Properties &operator=(const opentelemetry::common::KeyValueIterable &other) { clear(); - other.ForEachKeyValue([&](nostd::string_view key, common::AttributeValue value) noexcept { - std::string k(key.data(), key.length()); - (*this)[k].FromAttributeValue(value); - return true; - }); + other.ForEachKeyValue( + [&](nostd::string_view key, opentelemetry::common::AttributeValue value) noexcept { + std::string k(key.data(), key.length()); + (*this)[k].FromAttributeValue(value); + return true; + }); return (*this); } @@ -431,12 +432,13 @@ class Properties : public common::KeyValueIterable, public PropertyValueMap * the iteration is aborted. * @return true if every key-value pair was iterated over */ - bool ForEachKeyValue(nostd::function_ref - callback) const noexcept override + bool ForEachKeyValue( + nostd::function_ref callback) + const noexcept override { for (const auto &kv : (*this)) { - const common::AttributeValue &value = kv.second.ToAttributeValue(); + const opentelemetry::common::AttributeValue &value = kv.second.ToAttributeValue(); if (!callback(nostd::string_view{kv.first}, value)) { return false; diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h index 51cca03a60..4d7e37a98c 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h @@ -344,7 +344,7 @@ class ETWProvider } # if HAVE_TYPE_GUID // TODO: consider adding UUID/GUID to spec - case common::AttributeType::TYPE_GUID: { + case opentelemetry::common::AttributeType::TYPE_GUID: { auto temp = nostd::get(value); // TODO: add transform from GUID type to string? jObj[name] = temp; diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h index 6601f850df..454f6cff5a 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h @@ -107,7 +107,7 @@ std::string GetName(T &t) * @return Span Start timestamp */ template -common::SystemTimestamp GetStartTime(T &t) +opentelemetry::common::SystemTimestamp GetStartTime(T &t) { return t.GetStartTime(); } @@ -119,7 +119,7 @@ common::SystemTimestamp GetStartTime(T &t) * @return Span Stop timestamp */ template -common::SystemTimestamp GetEndTime(T &t) +opentelemetry::common::SystemTimestamp GetEndTime(T &t) { return t.GetEndTime(); } @@ -161,7 +161,7 @@ void UpdateStatus(T &t, Properties &props) */ class Tracer : public opentelemetry::trace::Tracer, - public std::enable_shared_from_this + public std::enable_shared_from_this { /** @@ -214,16 +214,16 @@ class Tracer : public opentelemetry::trace::Tracer, { size_t idx = 0; std::string linksValue; - links.ForEachKeyValue( - [&](opentelemetry::trace::SpanContext ctx, const common::KeyValueIterable &) { - if (!linksValue.empty()) - { - linksValue += ','; - linksValue += ToLowerBase16(ctx.span_id()); - } - idx++; - return true; - }); + links.ForEachKeyValue([&](opentelemetry::trace::SpanContext ctx, + const opentelemetry::common::KeyValueIterable &) { + if (!linksValue.empty()) + { + linksValue += ','; + linksValue += ToLowerBase16(ctx.span_id()); + } + idx++; + return true; + }); attributes[ETW_FIELD_SPAN_LINKS] = linksValue; } } @@ -414,7 +414,7 @@ class Tracer : public opentelemetry::trace::Tracer, */ nostd::shared_ptr StartSpan( nostd::string_view name, - const common::KeyValueIterable &attributes, + const opentelemetry::common::KeyValueIterable &attributes, const opentelemetry::trace::SpanContextKeyValueIterable &links, const opentelemetry::trace::StartSpanOptions &options = {}) noexcept override { @@ -425,8 +425,9 @@ class Tracer : public opentelemetry::trace::Tracer, Properties evtCopy = attributes; return StartSpan(name, evtCopy, links, options); #else // OPENTELEMETRY_RTTI_ENABLED is defined - common::KeyValueIterable &attribs = const_cast(attributes); - Properties *evt = dynamic_cast(&attribs); + opentelemetry::common::KeyValueIterable &attribs = + const_cast(attributes); + Properties *evt = dynamic_cast(&attribs); if (evt != nullptr) { // Pass as a reference to original modifyable collection without creating a copy @@ -491,8 +492,9 @@ class Tracer : public opentelemetry::trace::Tracer, if (sampling_result.decision == sdk::trace::Decision::DROP) { - auto noopSpan = nostd::shared_ptr{ - new (std::nothrow) trace::NoopSpan(this->shared_from_this(), std::move(spanContext))}; + auto noopSpan = nostd::shared_ptr{ + new (std::nothrow) + opentelemetry::trace::NoopSpan(this->shared_from_this(), std::move(spanContext))}; return noopSpan; } @@ -602,9 +604,9 @@ class Tracer : public opentelemetry::trace::Tracer, * @return */ void AddEvent(opentelemetry::trace::Span &span, - nostd::string_view name, - common::SystemTimestamp timestamp, - const common::KeyValueIterable &attributes) noexcept + opentelemetry::nostd::string_view name, + opentelemetry::common::SystemTimestamp timestamp, + const opentelemetry::common::KeyValueIterable &attributes) noexcept { // If RTTI is enabled by compiler, the below code modifies the attributes object passed as arg, // which is sometime not desirable, set OPENTELEMETRY_NOT_USE_RTTI in application @@ -614,8 +616,9 @@ class Tracer : public opentelemetry::trace::Tracer, Properties evtCopy = attributes; return AddEvent(span, name, timestamp, evtCopy); #else // OPENTELEMETRY_RTTI_ENABLED is defined - common::KeyValueIterable &attribs = const_cast(attributes); - Properties *evt = dynamic_cast(&attribs); + opentelemetry::common::KeyValueIterable &attribs = + const_cast(attributes); + Properties *evt = dynamic_cast(&attribs); if (evt != nullptr) { // Pass as a reference to original modifyable collection without creating a copy @@ -635,8 +638,8 @@ class Tracer : public opentelemetry::trace::Tracer, * @return */ void AddEvent(opentelemetry::trace::Span &span, - nostd::string_view name, - common::SystemTimestamp timestamp, + opentelemetry::nostd::string_view name, + opentelemetry::common::SystemTimestamp timestamp, Properties &evt) noexcept { // TODO: respect originating timestamp. Do we need to reserve @@ -693,8 +696,8 @@ class Tracer : public opentelemetry::trace::Tracer, * @return */ void AddEvent(opentelemetry::trace::Span &span, - nostd::string_view name, - common::SystemTimestamp timestamp) noexcept + opentelemetry::nostd::string_view name, + opentelemetry::common::SystemTimestamp timestamp) noexcept { AddEvent(span, name, timestamp, sdk::GetEmptyAttributes()); } @@ -728,8 +731,8 @@ class Span : public opentelemetry::trace::Span */ Properties attributes_; - common::SystemTimestamp start_time_; - common::SystemTimestamp end_time_; + opentelemetry::common::SystemTimestamp start_time_; + opentelemetry::common::SystemTimestamp end_time_; opentelemetry::trace::StatusCode status_code_{opentelemetry::trace::StatusCode::kUnset}; std::string status_description_; @@ -794,13 +797,13 @@ class Span : public opentelemetry::trace::Span * @brief Get start time of this Span. * @return */ - common::SystemTimestamp GetStartTime() { return start_time_; } + opentelemetry::common::SystemTimestamp GetStartTime() { return start_time_; } /** * @brief Get end time of this Span. * @return */ - common::SystemTimestamp GetEndTime() { return end_time_; } + opentelemetry::common::SystemTimestamp GetEndTime() { return end_time_; } /** * @brief Get Span Name. @@ -849,7 +852,8 @@ class Span : public opentelemetry::trace::Span * @param timestamp * @return */ - void AddEvent(nostd::string_view name, common::SystemTimestamp timestamp) noexcept override + void AddEvent(nostd::string_view name, + opentelemetry::common::SystemTimestamp timestamp) noexcept override { owner_.AddEvent(*this, name, timestamp); } @@ -861,9 +865,9 @@ class Span : public opentelemetry::trace::Span * @param attributes Event attributes. * @return */ - void AddEvent(nostd::string_view name, - common::SystemTimestamp timestamp, - const common::KeyValueIterable &attributes) noexcept override + void AddEvent(opentelemetry::nostd::string_view name, + opentelemetry::common::SystemTimestamp timestamp, + const opentelemetry::common::KeyValueIterable &attributes) noexcept override { owner_.AddEvent(*this, name, timestamp, attributes); } @@ -901,7 +905,8 @@ class Span : public opentelemetry::trace::Span * @param value * @return */ - void SetAttribute(nostd::string_view key, const common::AttributeValue &value) noexcept override + void SetAttribute(nostd::string_view key, + const opentelemetry::common::AttributeValue &value) noexcept override { // don't override fields propagated from span data. if (key == ETW_FIELD_NAME || key == ETW_FIELD_SPAN_ID || key == ETW_FIELD_TRACE_ID || diff --git a/exporters/ostream/include/opentelemetry/exporters/ostream/log_record_exporter.h b/exporters/ostream/include/opentelemetry/exporters/ostream/log_record_exporter.h index 7b196ec9e8..a2897a5f26 100644 --- a/exporters/ostream/include/opentelemetry/exporters/ostream/log_record_exporter.h +++ b/exporters/ostream/include/opentelemetry/exporters/ostream/log_record_exporter.h @@ -47,13 +47,13 @@ class OStreamLogRecordExporter final : public opentelemetry::sdk::logs::LogRecor * @return return true when all data are exported, and false when timeout */ bool ForceFlush( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override; + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override; /** * Marks the OStream Log Exporter as shut down. */ bool Shutdown( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override; + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override; private: // The OStream to send the logs to diff --git a/exporters/ostream/include/opentelemetry/exporters/ostream/span_exporter.h b/exporters/ostream/include/opentelemetry/exporters/ostream/span_exporter.h index 05c8a89982..03c95c23f9 100644 --- a/exporters/ostream/include/opentelemetry/exporters/ostream/span_exporter.h +++ b/exporters/ostream/include/opentelemetry/exporters/ostream/span_exporter.h @@ -44,10 +44,10 @@ class OStreamSpanExporter final : public opentelemetry::sdk::trace::SpanExporter * @return return true when all data are exported, and false when timeout */ bool ForceFlush( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override; + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override; bool Shutdown( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override; + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override; private: std::ostream &sout_; diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_environment.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_environment.h index 3be133b4cf..8234dc913e 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_environment.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_environment.h @@ -99,7 +99,6 @@ std::string GetOtlpDefaultTracesSslClientCertificateString(); std::string GetOtlpDefaultMetricsSslClientCertificateString(); std::string GetOtlpDefaultLogsSslClientCertificateString(); -#ifdef ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW std::string GetOtlpDefaultTracesSslTlsMinVersion(); std::string GetOtlpDefaultMetricsSslTlsMinVersion(); std::string GetOtlpDefaultLogsSslTlsMinVersion(); @@ -117,7 +116,6 @@ std::string GetOtlpDefaultLogsSslTlsCipher(); std::string GetOtlpDefaultTracesSslTlsCipherSuite(); std::string GetOtlpDefaultMetricsSslTlsCipherSuite(); std::string GetOtlpDefaultLogsSslTlsCipherSuite(); -#endif /* ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW */ std::chrono::system_clock::duration GetOtlpDefaultTracesTimeout(); std::chrono::system_clock::duration GetOtlpDefaultMetricsTimeout(); diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter.h index 7aff1e24a5..870e5a043a 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter.h @@ -58,7 +58,7 @@ class OtlpGrpcExporter final : public opentelemetry::sdk::trace::SpanExporter * @return return true when all data are exported, and false when timeout */ bool ForceFlush( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override; + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override; /** * Shut down the exporter. @@ -67,7 +67,7 @@ class OtlpGrpcExporter final : public opentelemetry::sdk::trace::SpanExporter * @return return the status of this operation */ bool Shutdown( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override; + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override; private: // The configuration options associated with this exporter. diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_log_record_exporter.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_log_record_exporter.h index 29333703b1..f1cd96888c 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_log_record_exporter.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_log_record_exporter.h @@ -60,14 +60,14 @@ class OtlpGrpcLogRecordExporter : public opentelemetry::sdk::logs::LogRecordExpo * @return return true when all data are exported, and false when timeout */ bool ForceFlush( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override; + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override; /** * Shutdown this exporter. * @param timeout The maximum time to wait for the shutdown method to return. */ bool Shutdown( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override; + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override; private: // Configuration options for the exporter 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 c41ffb0914..6af73f7e6b 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_client.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_client.h @@ -49,10 +49,8 @@ struct OtlpHttpClientOptions { std::string url; -#ifdef ENABLE_OTLP_HTTP_SSL_PREVIEW /** SSL options. */ ext::http::client::HttpSslOptions ssl_options; -#endif /* ENABLE_OTLP_HTTP_SSL_PREVIEW */ // By default, post json data HttpRequestContentType content_type = HttpRequestContentType::kJson; @@ -83,7 +81,6 @@ struct OtlpHttpClientOptions std::string user_agent; inline OtlpHttpClientOptions(nostd::string_view input_url, -#ifdef ENABLE_OTLP_HTTP_SSL_PREVIEW bool input_ssl_insecure_skip_verify, nostd::string_view input_ssl_ca_cert_path, nostd::string_view input_ssl_ca_cert_string, @@ -91,13 +88,10 @@ struct OtlpHttpClientOptions nostd::string_view input_ssl_client_key_string, nostd::string_view input_ssl_client_cert_path, nostd::string_view input_ssl_client_cert_string, -#endif /* ENABLE_OTLP_HTTP_SSL_PREVIEW */ -#ifdef ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW nostd::string_view input_ssl_min_tls, nostd::string_view input_ssl_max_tls, nostd::string_view input_ssl_cipher, nostd::string_view input_ssl_cipher_suite, -#endif /* ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW */ HttpRequestContentType input_content_type, JsonBytesMappingKind input_json_bytes_mapping, bool input_use_json_name, @@ -108,7 +102,6 @@ struct OtlpHttpClientOptions std::size_t input_max_requests_per_connection = 8, nostd::string_view input_user_agent = GetOtlpDefaultUserAgent()) : url(input_url), -#ifdef ENABLE_OTLP_HTTP_SSL_PREVIEW ssl_options(input_url, input_ssl_insecure_skip_verify, input_ssl_ca_cert_path, @@ -116,16 +109,11 @@ struct OtlpHttpClientOptions input_ssl_client_key_path, input_ssl_client_key_string, input_ssl_client_cert_path, - input_ssl_client_cert_string -# ifdef ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW - , + input_ssl_client_cert_string, input_ssl_min_tls, input_ssl_max_tls, input_ssl_cipher, - input_ssl_cipher_suite -# endif /* ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW */ - ), -#endif /* ENABLE_OTLP_HTTP_SSL_PREVIEW */ + input_ssl_cipher_suite), content_type(input_content_type), json_bytes_mapping(input_json_bytes_mapping), use_json_name(input_use_json_name), diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_exporter.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_exporter.h index 1adbbc70b9..b5faf1a9b8 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_exporter.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_exporter.h @@ -59,7 +59,7 @@ class OPENTELEMETRY_EXPORT OtlpHttpExporter final : public opentelemetry::sdk::t * @return return true when all data are exported, and false when timeout */ bool ForceFlush( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override; + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override; /** * Shut down the exporter. @@ -68,7 +68,7 @@ class OPENTELEMETRY_EXPORT OtlpHttpExporter final : public opentelemetry::sdk::t * @return return the status of this operation */ bool Shutdown( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override; + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override; private: // The configuration options associated with this exporter. diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_exporter_options.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_exporter_options.h index 9200a506b8..f7ed0eb3b9 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_exporter_options.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_exporter_options.h @@ -68,7 +68,6 @@ struct OPENTELEMETRY_EXPORT OtlpHttpExporterOptions std::size_t max_requests_per_connection; #endif -#ifdef ENABLE_OTLP_HTTP_SSL_PREVIEW /** True do disable SSL. */ bool ssl_insecure_skip_verify; @@ -89,9 +88,7 @@ struct OPENTELEMETRY_EXPORT OtlpHttpExporterOptions /** CLIENT CERT, as a string. */ std::string ssl_client_cert_string; -#endif /* ENABLE_OTLP_HTTP_SSL_PREVIEW */ -#ifdef ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW /** Minimum TLS version. */ std::string ssl_min_tls; @@ -103,7 +100,6 @@ struct OPENTELEMETRY_EXPORT OtlpHttpExporterOptions /** TLS cipher suite. */ std::string ssl_cipher_suite; -#endif /* ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW */ }; } // namespace otlp diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_log_record_exporter.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_log_record_exporter.h index 4393345dfd..f481fdab0b 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_log_record_exporter.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_log_record_exporter.h @@ -58,14 +58,14 @@ class OtlpHttpLogRecordExporter final : public opentelemetry::sdk::logs::LogReco * @return return true when all data are exported, and false when timeout */ bool ForceFlush( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override; + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override; /** * Shutdown this exporter. * @param timeout The maximum time to wait for the shutdown method to return */ bool Shutdown( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override; + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override; private: // Configuration options for the exporter diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_log_record_exporter_options.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_log_record_exporter_options.h index e2a6264675..1c34327a3c 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_log_record_exporter_options.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_log_record_exporter_options.h @@ -68,7 +68,6 @@ struct OPENTELEMETRY_EXPORT OtlpHttpLogRecordExporterOptions std::size_t max_requests_per_connection; #endif -#ifdef ENABLE_OTLP_HTTP_SSL_PREVIEW /** True do disable SSL. */ bool ssl_insecure_skip_verify; @@ -89,9 +88,7 @@ struct OPENTELEMETRY_EXPORT OtlpHttpLogRecordExporterOptions /** CLIENT CERT, as a string. */ std::string ssl_client_cert_string; -#endif /* ENABLE_OTLP_HTTP_SSL_PREVIEW */ -#ifdef ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW /** Minimum TLS version. */ std::string ssl_min_tls; @@ -103,7 +100,6 @@ struct OPENTELEMETRY_EXPORT OtlpHttpLogRecordExporterOptions /** TLS cipher suite. */ std::string ssl_cipher_suite; -#endif /* ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW */ }; } // namespace otlp diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_metric_exporter_options.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_metric_exporter_options.h index 38446be73b..4f30451387 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_metric_exporter_options.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_http_metric_exporter_options.h @@ -71,7 +71,6 @@ struct OPENTELEMETRY_EXPORT OtlpHttpMetricExporterOptions std::size_t max_requests_per_connection; #endif -#ifdef ENABLE_OTLP_HTTP_SSL_PREVIEW /** True do disable SSL. */ bool ssl_insecure_skip_verify; @@ -92,9 +91,7 @@ struct OPENTELEMETRY_EXPORT OtlpHttpMetricExporterOptions /** CLIENT CERT, as a string. */ std::string ssl_client_cert_string; -#endif /* ENABLE_OTLP_HTTP_SSL_PREVIEW */ -#ifdef ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW /** Minimum TLS version. */ std::string ssl_min_tls; @@ -106,7 +103,6 @@ struct OPENTELEMETRY_EXPORT OtlpHttpMetricExporterOptions /** TLS cipher suite. */ std::string ssl_cipher_suite; -#endif /* ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW */ }; } // namespace otlp diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_metric_utils.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_metric_utils.h index 1adca861d8..c6e11aeff3 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_metric_utils.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_metric_utils.h @@ -26,7 +26,7 @@ class OtlpMetricUtils { public: static opentelemetry::sdk::metrics::AggregationType GetAggregationType( - const opentelemetry::sdk::metrics::InstrumentType &instrument_type) noexcept; + const opentelemetry::sdk::metrics::MetricData &metric_data) noexcept; static proto::metrics::v1::AggregationTemporality GetProtoAggregationTemporality( const opentelemetry::sdk::metrics::AggregationTemporality &aggregation_temporality) noexcept; diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_recordable.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_recordable.h index bc505a959b..76e8856330 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_recordable.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_recordable.h @@ -38,17 +38,18 @@ class OtlpRecordable final : public opentelemetry::sdk::trace::Recordable void SetIdentity(const opentelemetry::trace::SpanContext &span_context, opentelemetry::trace::SpanId parent_span_id) noexcept override; - void SetAttribute(nostd::string_view key, + void SetAttribute(opentelemetry::nostd::string_view key, const opentelemetry::common::AttributeValue &value) noexcept override; - void AddEvent(nostd::string_view name, - common::SystemTimestamp timestamp, - const common::KeyValueIterable &attributes) noexcept override; + void AddEvent(opentelemetry::nostd::string_view name, + opentelemetry::common::SystemTimestamp timestamp, + const opentelemetry::common::KeyValueIterable &attributes) noexcept override; void AddLink(const opentelemetry::trace::SpanContext &span_context, - const common::KeyValueIterable &attributes) noexcept override; + const opentelemetry::common::KeyValueIterable &attributes) noexcept override; - void SetStatus(trace::StatusCode code, nostd::string_view description) noexcept override; + void SetStatus(opentelemetry::trace::StatusCode code, + nostd::string_view description) noexcept override; void SetName(nostd::string_view name) noexcept override; diff --git a/exporters/otlp/src/otlp_environment.cc b/exporters/otlp/src/otlp_environment.cc index 5324b40213..a355b13162 100644 --- a/exporters/otlp/src/otlp_environment.cc +++ b/exporters/otlp/src/otlp_environment.cc @@ -660,8 +660,6 @@ std::string GetOtlpDefaultLogsSslClientCertificateString() return std::string{}; } -#ifdef ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW - /* EXPERIMENTAL: Environment variable names do not exist in the spec, @@ -872,8 +870,6 @@ std::string GetOtlpDefaultLogsSslTlsCipherSuite() return std::string{}; } -#endif /* ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW */ - std::chrono::system_clock::duration GetOtlpDefaultTracesTimeout() { constexpr char kSignalEnv[] = "OTEL_EXPORTER_OTLP_TRACES_TIMEOUT"; diff --git a/exporters/otlp/src/otlp_http_client.cc b/exporters/otlp/src/otlp_http_client.cc index c6bc1e1122..7814199ef2 100644 --- a/exporters/otlp/src/otlp_http_client.cc +++ b/exporters/otlp/src/otlp_http_client.cc @@ -782,7 +782,7 @@ bool OtlpHttpClient::ForceFlush(std::chrono::microseconds timeout) noexcept std::chrono::duration_cast(timeout); if (timeout_steady <= std::chrono::steady_clock::duration::zero()) { - timeout_steady = std::chrono::steady_clock::duration::max(); + timeout_steady = (std::chrono::steady_clock::duration::max)(); } while (timeout_steady > std::chrono::steady_clock::duration::zero()) @@ -951,9 +951,7 @@ OtlpHttpClient::createSession( request->AddHeader(header.first, header.second); } request->SetUri(http_uri_); -#ifdef ENABLE_OTLP_HTTP_SSL_PREVIEW request->SetSslOptions(options_.ssl_options); -#endif /* ENABLE_OTLP_HTTP_SSL_PREVIEW */ request->SetTimeoutMs(std::chrono::duration_cast(options_.timeout)); request->SetMethod(http_client::Method::Post); request->SetBody(body_vec); diff --git a/exporters/otlp/src/otlp_http_exporter.cc b/exporters/otlp/src/otlp_http_exporter.cc index 6732e31431..6059db36a4 100644 --- a/exporters/otlp/src/otlp_http_exporter.cc +++ b/exporters/otlp/src/otlp_http_exporter.cc @@ -26,7 +26,6 @@ OtlpHttpExporter::OtlpHttpExporter() : OtlpHttpExporter(OtlpHttpExporterOptions( OtlpHttpExporter::OtlpHttpExporter(const OtlpHttpExporterOptions &options) : options_(options), http_client_(new OtlpHttpClient(OtlpHttpClientOptions(options.url, -#ifdef ENABLE_OTLP_HTTP_SSL_PREVIEW options.ssl_insecure_skip_verify, options.ssl_ca_cert_path, options.ssl_ca_cert_string, @@ -34,13 +33,10 @@ OtlpHttpExporter::OtlpHttpExporter(const OtlpHttpExporterOptions &options) options.ssl_client_key_string, options.ssl_client_cert_path, options.ssl_client_cert_string, -#endif /* ENABLE_OTLP_HTTP_SSL_PREVIEW */ -#ifdef ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW options.ssl_min_tls, options.ssl_max_tls, options.ssl_cipher, options.ssl_cipher_suite, -#endif /* ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW */ options.content_type, options.json_bytes_mapping, options.use_json_name, diff --git a/exporters/otlp/src/otlp_http_exporter_options.cc b/exporters/otlp/src/otlp_http_exporter_options.cc index 91121e0c35..3b8c6ad5b8 100644 --- a/exporters/otlp/src/otlp_http_exporter_options.cc +++ b/exporters/otlp/src/otlp_http_exporter_options.cc @@ -29,7 +29,6 @@ OtlpHttpExporterOptions::OtlpHttpExporterOptions() max_requests_per_connection = 8; #endif /* ENABLE_ASYNC_EXPORT */ -#ifdef ENABLE_OTLP_HTTP_SSL_PREVIEW ssl_insecure_skip_verify = false; ssl_ca_cert_path = GetOtlpDefaultTracesSslCertificatePath(); ssl_ca_cert_string = GetOtlpDefaultTracesSslCertificateString(); @@ -37,14 +36,11 @@ OtlpHttpExporterOptions::OtlpHttpExporterOptions() ssl_client_key_string = GetOtlpDefaultTracesSslClientKeyString(); ssl_client_cert_path = GetOtlpDefaultTracesSslClientCertificatePath(); ssl_client_cert_string = GetOtlpDefaultTracesSslClientCertificateString(); -#endif /* ENABLE_OTLP_HTTP_SSL_PREVIEW */ -#ifdef ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW ssl_min_tls = GetOtlpDefaultTracesSslTlsMinVersion(); ssl_max_tls = GetOtlpDefaultTracesSslTlsMaxVersion(); ssl_cipher = GetOtlpDefaultTracesSslTlsCipher(); ssl_cipher_suite = GetOtlpDefaultTracesSslTlsCipherSuite(); -#endif /* ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW */ } OtlpHttpExporterOptions::~OtlpHttpExporterOptions() {} diff --git a/exporters/otlp/src/otlp_http_log_record_exporter.cc b/exporters/otlp/src/otlp_http_log_record_exporter.cc index 9414e2fd76..e16c5d0008 100644 --- a/exporters/otlp/src/otlp_http_log_record_exporter.cc +++ b/exporters/otlp/src/otlp_http_log_record_exporter.cc @@ -29,7 +29,6 @@ OtlpHttpLogRecordExporter::OtlpHttpLogRecordExporter( const OtlpHttpLogRecordExporterOptions &options) : options_(options), http_client_(new OtlpHttpClient(OtlpHttpClientOptions(options.url, -#ifdef ENABLE_OTLP_HTTP_SSL_PREVIEW options.ssl_insecure_skip_verify, options.ssl_ca_cert_path, options.ssl_ca_cert_string, @@ -37,13 +36,10 @@ OtlpHttpLogRecordExporter::OtlpHttpLogRecordExporter( options.ssl_client_key_string, options.ssl_client_cert_path, options.ssl_client_cert_string, -#endif /* ENABLE_OTLP_HTTP_SSL_PREVIEW */ -#ifdef ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW options.ssl_min_tls, options.ssl_max_tls, options.ssl_cipher, options.ssl_cipher_suite, -#endif /* ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW */ options.content_type, options.json_bytes_mapping, options.use_json_name, diff --git a/exporters/otlp/src/otlp_http_log_record_exporter_options.cc b/exporters/otlp/src/otlp_http_log_record_exporter_options.cc index bda37b9730..2f58bce768 100644 --- a/exporters/otlp/src/otlp_http_log_record_exporter_options.cc +++ b/exporters/otlp/src/otlp_http_log_record_exporter_options.cc @@ -29,7 +29,6 @@ OtlpHttpLogRecordExporterOptions::OtlpHttpLogRecordExporterOptions() max_requests_per_connection = 8; #endif -#ifdef ENABLE_OTLP_HTTP_SSL_PREVIEW ssl_insecure_skip_verify = false; ssl_ca_cert_path = GetOtlpDefaultLogsSslCertificatePath(); ssl_ca_cert_string = GetOtlpDefaultLogsSslCertificateString(); @@ -37,14 +36,11 @@ OtlpHttpLogRecordExporterOptions::OtlpHttpLogRecordExporterOptions() ssl_client_key_string = GetOtlpDefaultLogsSslClientKeyString(); ssl_client_cert_path = GetOtlpDefaultLogsSslClientCertificatePath(); ssl_client_cert_string = GetOtlpDefaultLogsSslClientCertificateString(); -#endif /* ENABLE_OTLP_HTTP_SSL_PREVIEW */ -#ifdef ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW ssl_min_tls = GetOtlpDefaultLogsSslTlsMinVersion(); ssl_max_tls = GetOtlpDefaultLogsSslTlsMaxVersion(); ssl_cipher = GetOtlpDefaultLogsSslTlsCipher(); ssl_cipher_suite = GetOtlpDefaultLogsSslTlsCipherSuite(); -#endif /* ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW */ } OtlpHttpLogRecordExporterOptions::~OtlpHttpLogRecordExporterOptions() {} diff --git a/exporters/otlp/src/otlp_http_metric_exporter.cc b/exporters/otlp/src/otlp_http_metric_exporter.cc index e4f667eb3e..816f4eee44 100644 --- a/exporters/otlp/src/otlp_http_metric_exporter.cc +++ b/exporters/otlp/src/otlp_http_metric_exporter.cc @@ -29,7 +29,6 @@ OtlpHttpMetricExporter::OtlpHttpMetricExporter(const OtlpHttpMetricExporterOptio aggregation_temporality_selector_{ OtlpMetricUtils::ChooseTemporalitySelector(options_.aggregation_temporality)}, http_client_(new OtlpHttpClient(OtlpHttpClientOptions(options.url, -#ifdef ENABLE_OTLP_HTTP_SSL_PREVIEW options.ssl_insecure_skip_verify, options.ssl_ca_cert_path, options.ssl_ca_cert_string, @@ -37,13 +36,10 @@ OtlpHttpMetricExporter::OtlpHttpMetricExporter(const OtlpHttpMetricExporterOptio options.ssl_client_key_string, options.ssl_client_cert_path, options.ssl_client_cert_string, -#endif /* ENABLE_OTLP_HTTP_SSL_PREVIEW */ -#ifdef ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW options.ssl_min_tls, options.ssl_max_tls, options.ssl_cipher, options.ssl_cipher_suite, -#endif /* ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW */ options.content_type, options.json_bytes_mapping, options.use_json_name, diff --git a/exporters/otlp/src/otlp_http_metric_exporter_options.cc b/exporters/otlp/src/otlp_http_metric_exporter_options.cc index 4dc0f40631..ffcd502bd4 100644 --- a/exporters/otlp/src/otlp_http_metric_exporter_options.cc +++ b/exporters/otlp/src/otlp_http_metric_exporter_options.cc @@ -30,7 +30,6 @@ OtlpHttpMetricExporterOptions::OtlpHttpMetricExporterOptions() max_requests_per_connection = 8; #endif -#ifdef ENABLE_OTLP_HTTP_SSL_PREVIEW ssl_insecure_skip_verify = false; ssl_ca_cert_path = GetOtlpDefaultMetricsSslCertificatePath(); ssl_ca_cert_string = GetOtlpDefaultMetricsSslCertificateString(); @@ -38,14 +37,11 @@ OtlpHttpMetricExporterOptions::OtlpHttpMetricExporterOptions() ssl_client_key_string = GetOtlpDefaultMetricsSslClientKeyString(); ssl_client_cert_path = GetOtlpDefaultMetricsSslClientCertificatePath(); ssl_client_cert_string = GetOtlpDefaultMetricsSslClientCertificateString(); -#endif /* ENABLE_OTLP_HTTP_SSL_PREVIEW */ -#ifdef ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW ssl_min_tls = GetOtlpDefaultMetricsSslTlsMinVersion(); ssl_max_tls = GetOtlpDefaultMetricsSslTlsMaxVersion(); ssl_cipher = GetOtlpDefaultMetricsSslTlsCipher(); ssl_cipher_suite = GetOtlpDefaultMetricsSslTlsCipherSuite(); -#endif /* ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW */ } OtlpHttpMetricExporterOptions::~OtlpHttpMetricExporterOptions() {} diff --git a/exporters/otlp/src/otlp_metric_utils.cc b/exporters/otlp/src/otlp_metric_utils.cc index 50c5fdd9cc..53e84e7966 100644 --- a/exporters/otlp/src/otlp_metric_utils.cc +++ b/exporters/otlp/src/otlp_metric_utils.cc @@ -25,21 +25,24 @@ proto::metrics::v1::AggregationTemporality OtlpMetricUtils::GetProtoAggregationT } metric_sdk::AggregationType OtlpMetricUtils::GetAggregationType( - const opentelemetry::sdk::metrics::InstrumentType &instrument_type) noexcept + const opentelemetry::sdk::metrics::MetricData &metric_data) noexcept { - - if (instrument_type == metric_sdk::InstrumentType::kCounter || - instrument_type == metric_sdk::InstrumentType::kUpDownCounter || - instrument_type == metric_sdk::InstrumentType::kObservableCounter || - instrument_type == metric_sdk::InstrumentType::kObservableUpDownCounter) + if (metric_data.point_data_attr_.size() == 0) + { + return metric_sdk::AggregationType::kDrop; + } + auto point_data_with_attributes = metric_data.point_data_attr_[0]; + if (nostd::holds_alternative(point_data_with_attributes.point_data)) { return metric_sdk::AggregationType::kSum; } - else if (instrument_type == metric_sdk::InstrumentType::kHistogram) + else if (nostd::holds_alternative( + point_data_with_attributes.point_data)) { return metric_sdk::AggregationType::kHistogram; } - else if (instrument_type == metric_sdk::InstrumentType::kObservableGauge) + else if (nostd::holds_alternative( + point_data_with_attributes.point_data)) { return metric_sdk::AggregationType::kLastValue; } @@ -51,8 +54,9 @@ void OtlpMetricUtils::ConvertSumMetric(const metric_sdk::MetricData &metric_data { sum->set_aggregation_temporality( GetProtoAggregationTemporality(metric_data.aggregation_temporality)); - sum->set_is_monotonic(metric_data.instrument_descriptor.type_ == - metric_sdk::InstrumentType::kCounter); + sum->set_is_monotonic( + (metric_data.instrument_descriptor.type_ == metric_sdk::InstrumentType::kCounter) || + (metric_data.instrument_descriptor.type_ == metric_sdk::InstrumentType::kObservableCounter)); auto start_ts = metric_data.start_ts.time_since_epoch().count(); auto ts = metric_data.end_ts.time_since_epoch().count(); for (auto &point_data_with_attributes : metric_data.point_data_attr_) @@ -188,7 +192,7 @@ void OtlpMetricUtils::PopulateInstrumentInfoMetrics( metric->set_name(metric_data.instrument_descriptor.name_); metric->set_description(metric_data.instrument_descriptor.description_); metric->set_unit(metric_data.instrument_descriptor.unit_); - auto kind = GetAggregationType(metric_data.instrument_descriptor.type_); + auto kind = GetAggregationType(metric_data); switch (kind) { case metric_sdk::AggregationType::kSum: { diff --git a/exporters/otlp/test/otlp_http_exporter_test.cc b/exporters/otlp/test/otlp_http_exporter_test.cc index 1c76ad0d02..63f919c6cc 100644 --- a/exporters/otlp/test/otlp_http_exporter_test.cc +++ b/exporters/otlp/test/otlp_http_exporter_test.cc @@ -61,20 +61,15 @@ OtlpHttpClientOptions MakeOtlpHttpClientOptions(HttpRequestContentType content_t options.http_headers.insert( std::make_pair("Custom-Header-Key", "Custom-Header-Value")); OtlpHttpClientOptions otlp_http_client_options( - options.url, -# ifdef ENABLE_OTLP_HTTP_SSL_PREVIEW - false, /* ssl_insecure_skip_verify */ + options.url, false, /* ssl_insecure_skip_verify */ "", /* ssl_ca_cert_path */ "", /* ssl_ca_cert_string */ "", /* ssl_client_key_path */ "", /* ssl_client_key_string */ "", /* ssl_client_cert_path */ "", /* ssl_client_cert_string */ -# endif /* ENABLE_OTLP_HTTP_SSL_PREVIEW */ -# ifdef ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW - "", /* ssl_min_tls */ - "", /* ssl_max_tls */ - "", /* ssl_cipher */ - "", /* ssl_cipher_suite */ -# endif /* ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW */ + "", /* ssl_min_tls */ + "", /* ssl_max_tls */ + "", /* ssl_cipher */ + "", /* ssl_cipher_suite */ options.content_type, options.json_bytes_mapping, options.use_json_name, options.console_debug, options.timeout, options.http_headers); if (!async_mode) diff --git a/exporters/otlp/test/otlp_http_log_record_exporter_test.cc b/exporters/otlp/test/otlp_http_log_record_exporter_test.cc index 44fa812a35..611bebb541 100644 --- a/exporters/otlp/test/otlp_http_log_record_exporter_test.cc +++ b/exporters/otlp/test/otlp_http_log_record_exporter_test.cc @@ -60,20 +60,15 @@ OtlpHttpClientOptions MakeOtlpHttpClientOptions(HttpRequestContentType content_t options.http_headers.insert( std::make_pair("Custom-Header-Key", "Custom-Header-Value")); OtlpHttpClientOptions otlp_http_client_options( - options.url, -# ifdef ENABLE_OTLP_HTTP_SSL_PREVIEW - false, /* ssl_insecure_skip_verify */ + options.url, false, /* ssl_insecure_skip_verify */ "", /* ssl_ca_cert_path */ "", /* ssl_ca_cert_string */ "", /* ssl_client_key_path */ "", /* ssl_client_key_string */ "", /* ssl_client_cert_path */ "", /* ssl_client_cert_string */ -# endif /* ENABLE_OTLP_HTTP_SSL_PREVIEW */ -# ifdef ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW - "", /* ssl_min_tls */ - "", /* ssl_max_tls */ - "", /* ssl_cipher */ - "", /* ssl_cipher_suite */ -# endif /* ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW */ + "", /* ssl_min_tls */ + "", /* ssl_max_tls */ + "", /* ssl_cipher */ + "", /* ssl_cipher_suite */ options.content_type, options.json_bytes_mapping, options.use_json_name, options.console_debug, options.timeout, options.http_headers); if (!async_mode) diff --git a/exporters/otlp/test/otlp_http_metric_exporter_test.cc b/exporters/otlp/test/otlp_http_metric_exporter_test.cc index 8b7688adc0..def56682d3 100644 --- a/exporters/otlp/test/otlp_http_metric_exporter_test.cc +++ b/exporters/otlp/test/otlp_http_metric_exporter_test.cc @@ -67,20 +67,15 @@ OtlpHttpClientOptions MakeOtlpHttpClientOptions(HttpRequestContentType content_t options.http_headers.insert( std::make_pair("Custom-Header-Key", "Custom-Header-Value")); OtlpHttpClientOptions otlp_http_client_options( - options.url, -#ifdef ENABLE_OTLP_HTTP_SSL_PREVIEW - false, /* ssl_insecure_skip_verify */ + options.url, false, /* ssl_insecure_skip_verify */ "", /* ssl_ca_cert_path */ "", /* ssl_ca_cert_string */ "", /* ssl_client_key_path */ "", /* ssl_client_key_string */ "", /* ssl_client_cert_path */ "", /* ssl_client_cert_string */ -#endif /* ENABLE_OTLP_HTTP_SSL_PREVIEW */ -#ifdef ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW - "", /* ssl_min_tls */ - "", /* ssl_max_tls */ - "", /* ssl_cipher */ - "", /* ssl_cipher_suite */ -#endif /* ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW */ + "", /* ssl_min_tls */ + "", /* ssl_max_tls */ + "", /* ssl_cipher */ + "", /* ssl_cipher_suite */ options.content_type, options.json_bytes_mapping, options.use_json_name, options.console_debug, options.timeout, options.http_headers); if (!async_mode) diff --git a/exporters/otlp/test/otlp_metrics_serialization_test.cc b/exporters/otlp/test/otlp_metrics_serialization_test.cc index ac0f717b25..b945cb28fe 100644 --- a/exporters/otlp/test/otlp_metrics_serialization_test.cc +++ b/exporters/otlp/test/otlp_metrics_serialization_test.cc @@ -130,6 +130,66 @@ static metrics_sdk::MetricData CreateObservableGaugeAggregationData() return data; } +static metrics_sdk::MetricData CreateObservableCounterAggregationData() +{ + metrics_sdk::MetricData data; + data.start_ts = opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now()); + metrics_sdk::InstrumentDescriptor inst_desc = { + "ObservableCounter", "test description", "test unit", + metrics_sdk::InstrumentType::kObservableCounter, metrics_sdk::InstrumentValueType::kDouble}; + metrics_sdk::SumPointData s_data_1, s_data_2; + s_data_1.value_ = 1.23; + s_data_2.value_ = 4.56; + + data.aggregation_temporality = metrics_sdk::AggregationTemporality::kCumulative; + data.end_ts = opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now()); + data.instrument_descriptor = inst_desc; + metrics_sdk::PointDataAttributes point_data_attr_1, point_data_attr_2; + point_data_attr_1.attributes = {{"key1", "value1"}}; + point_data_attr_1.point_data = s_data_1; + + point_data_attr_2.attributes = {{"key2", "value2"}}; + point_data_attr_2.point_data = s_data_2; + std::vector point_data_attr; + point_data_attr.push_back(point_data_attr_1); + point_data_attr.push_back(point_data_attr_2); + data.point_data_attr_ = std::move(point_data_attr); + return data; +} + +static metrics_sdk::MetricData CreateObservableUpDownCounterAggregationData() +{ + metrics_sdk::MetricData data; + data.start_ts = opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now()); + metrics_sdk::InstrumentDescriptor inst_desc = { + "ObservableUpDownCounter", "test description", "test unit", + metrics_sdk::InstrumentType::kObservableUpDownCounter, + metrics_sdk::InstrumentValueType::kDouble}; + metrics_sdk::SumPointData s_data_1, s_data_2, s_data_3; + s_data_1.value_ = 1.23; + s_data_2.value_ = 4.56; + s_data_3.value_ = 2.34; + + data.aggregation_temporality = metrics_sdk::AggregationTemporality::kCumulative; + data.end_ts = opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now()); + data.instrument_descriptor = inst_desc; + metrics_sdk::PointDataAttributes point_data_attr_1, point_data_attr_2, point_data_attr_3; + point_data_attr_1.attributes = {{"key1", "value1"}}; + point_data_attr_1.point_data = s_data_1; + + point_data_attr_2.attributes = {{"key2", "value2"}}; + point_data_attr_2.point_data = s_data_2; + + point_data_attr_3.attributes = {{"key3", "value3"}}; + point_data_attr_3.point_data = s_data_3; + std::vector point_data_attr; + point_data_attr.push_back(point_data_attr_1); + point_data_attr.push_back(point_data_attr_2); + point_data_attr.push_back(point_data_attr_3); + data.point_data_attr_ = std::move(point_data_attr); + return data; +} + TEST(OtlpMetricSerializationTest, Counter) { metrics_sdk::MetricData data = CreateSumAggregationData(); @@ -191,6 +251,37 @@ TEST(OtlpMetricSerializationTest, ObservableGauge) EXPECT_EQ(1, 1); } +TEST(OtlpMetricSerializationTest, ObservableCounter) +{ + metrics_sdk::MetricData data = CreateObservableCounterAggregationData(); + opentelemetry::proto::metrics::v1::Sum sum; + otlp_exporter::OtlpMetricUtils::ConvertSumMetric(data, &sum); + EXPECT_EQ(sum.aggregation_temporality(), + proto::metrics::v1::AggregationTemporality::AGGREGATION_TEMPORALITY_CUMULATIVE); + EXPECT_EQ(sum.is_monotonic(), true); + EXPECT_EQ(sum.data_points_size(), 2); + EXPECT_EQ(sum.data_points(0).as_double(), 1.23); + EXPECT_EQ(sum.data_points(1).as_double(), 4.56); + + EXPECT_EQ(1, 1); +} + +TEST(OtlpMetricSerializationTest, ObservableUpDownCounter) +{ + metrics_sdk::MetricData data = CreateObservableUpDownCounterAggregationData(); + opentelemetry::proto::metrics::v1::Sum sum; + otlp_exporter::OtlpMetricUtils::ConvertSumMetric(data, &sum); + EXPECT_EQ(sum.aggregation_temporality(), + proto::metrics::v1::AggregationTemporality::AGGREGATION_TEMPORALITY_CUMULATIVE); + EXPECT_EQ(sum.is_monotonic(), false); + EXPECT_EQ(sum.data_points_size(), 3); + EXPECT_EQ(sum.data_points(0).as_double(), 1.23); + EXPECT_EQ(sum.data_points(1).as_double(), 4.56); + EXPECT_EQ(sum.data_points(2).as_double(), 2.34); + + EXPECT_EQ(1, 1); +} + } // namespace otlp } // namespace exporter OPENTELEMETRY_END_NAMESPACE diff --git a/exporters/prometheus/include/opentelemetry/exporters/prometheus/collector.h b/exporters/prometheus/include/opentelemetry/exporters/prometheus/collector.h index 5dfa983088..cb94fe7654 100644 --- a/exporters/prometheus/include/opentelemetry/exporters/prometheus/collector.h +++ b/exporters/prometheus/include/opentelemetry/exporters/prometheus/collector.h @@ -31,7 +31,9 @@ class PrometheusCollector : public prometheus_client::Collectable * This constructor initializes the collection for metrics to export * in this class with default capacity */ - explicit PrometheusCollector(sdk::metrics::MetricReader *reader, bool populate_target_info); + explicit PrometheusCollector(sdk::metrics::MetricReader *reader, + bool populate_target_info, + bool without_otel_scope); /** * Collects all metrics data from metricsToCollect collection. @@ -43,6 +45,7 @@ class PrometheusCollector : public prometheus_client::Collectable private: sdk::metrics::MetricReader *reader_; bool populate_target_info_; + bool without_otel_scope_; /* * Lock when operating the metricsToCollect collection diff --git a/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter_options.h b/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter_options.h index 3f36d780ee..5d8b4932fc 100644 --- a/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter_options.h +++ b/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter_options.h @@ -25,6 +25,9 @@ struct PrometheusExporterOptions // Populating target_info bool populate_target_info = true; + + // Populating otel_scope_name/otel_scope_labels attributes + bool without_otel_scope = false; }; } // namespace metrics diff --git a/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter_utils.h b/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter_utils.h index fa3eedd2c4..ccf3d03ff3 100644 --- a/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter_utils.h +++ b/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter_utils.h @@ -28,11 +28,14 @@ class PrometheusExporterUtils * * @param records a collection of metrics in OpenTelemetry * @param populate_target_info whether to populate target_info + * @param without_otel_scope whether to populate otel_scope_name and otel_scope_version + * attributes * @return a collection of translated metrics that is acceptable by Prometheus */ static std::vector<::prometheus::MetricFamily> TranslateToPrometheus( const sdk::metrics::ResourceMetrics &data, - bool populate_target_info = true); + bool populate_target_info = true, + bool without_otel_scope = false); private: /** diff --git a/exporters/prometheus/src/collector.cc b/exporters/prometheus/src/collector.cc index 33b9a9b8c8..53d880ee01 100644 --- a/exporters/prometheus/src/collector.cc +++ b/exporters/prometheus/src/collector.cc @@ -18,8 +18,11 @@ namespace metrics * in this class with default capacity */ PrometheusCollector::PrometheusCollector(sdk::metrics::MetricReader *reader, - bool populate_target_info) - : reader_(reader), populate_target_info_(populate_target_info) + bool populate_target_info, + bool without_otel_scope) + : reader_(reader), + populate_target_info_(populate_target_info), + without_otel_scope_(without_otel_scope) {} /** @@ -41,8 +44,8 @@ std::vector PrometheusCollector::Collect() cons std::vector result; reader_->Collect([&result, this](sdk::metrics::ResourceMetrics &metric_data) { - auto prometheus_metric_data = - PrometheusExporterUtils::TranslateToPrometheus(metric_data, this->populate_target_info_); + auto prometheus_metric_data = PrometheusExporterUtils::TranslateToPrometheus( + metric_data, this->populate_target_info_, this->without_otel_scope_); for (auto &data : prometheus_metric_data) result.emplace_back(data); return true; diff --git a/exporters/prometheus/src/exporter.cc b/exporters/prometheus/src/exporter.cc index 6022c2c33b..eeab82d6bb 100644 --- a/exporters/prometheus/src/exporter.cc +++ b/exporters/prometheus/src/exporter.cc @@ -31,7 +31,7 @@ PrometheusExporter::PrometheusExporter(const PrometheusExporterOptions &options) return; } collector_ = std::shared_ptr( - new PrometheusCollector(this, options_.populate_target_info)); + new PrometheusCollector(this, options_.populate_target_info, options_.without_otel_scope)); exposer_->RegisterCollectable(collector_); } diff --git a/exporters/prometheus/src/exporter_options.cc b/exporters/prometheus/src/exporter_options.cc index 507f119eb7..f2c49f7a57 100644 --- a/exporters/prometheus/src/exporter_options.cc +++ b/exporters/prometheus/src/exporter_options.cc @@ -25,7 +25,34 @@ inline const std::string GetPrometheusDefaultHttpEndpoint() return exists ? endpoint : kPrometheusEndpointDefault; } -PrometheusExporterOptions::PrometheusExporterOptions() : url(GetPrometheusDefaultHttpEndpoint()) {} +inline bool GetPrometheusWithoutOtelScope() +{ + constexpr char kPrometheusWithoutOtelScope[] = "OTEL_CPP_PROMETHEUS_EXPORTER_WITHOUT_OTEL_SCOPE"; + + bool setting; + auto exists = + opentelemetry::sdk::common::GetBoolEnvironmentVariable(kPrometheusWithoutOtelScope, setting); + + return exists ? setting : true; +} + +inline bool GetPrometheusPopulateTargetInfo() +{ + constexpr char kPrometheusPopulateTargetInfo[] = + "OTEL_CPP_PROMETHEUS_EXPORTER_POPULATE_TARGET_INFO"; + + bool setting; + auto exists = opentelemetry::sdk::common::GetBoolEnvironmentVariable( + kPrometheusPopulateTargetInfo, setting); + + return exists ? setting : true; +} + +PrometheusExporterOptions::PrometheusExporterOptions() + : url(GetPrometheusDefaultHttpEndpoint()), + populate_target_info(GetPrometheusPopulateTargetInfo()), + without_otel_scope(GetPrometheusWithoutOtelScope()) +{} } // namespace metrics } // namespace exporter diff --git a/exporters/prometheus/src/exporter_utils.cc b/exporters/prometheus/src/exporter_utils.cc index 4b1ee054c4..1e0d018011 100644 --- a/exporters/prometheus/src/exporter_utils.cc +++ b/exporters/prometheus/src/exporter_utils.cc @@ -1,6 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#include #include #include #include @@ -13,6 +14,7 @@ #include "prometheus/metric_family.h" #include "prometheus/metric_type.h" +#include "opentelemetry/common/macros.h" #include "opentelemetry/exporters/prometheus/exporter_utils.h" #include "opentelemetry/sdk/metrics/export/metric_producer.h" #include "opentelemetry/sdk/resource/resource.h" @@ -105,7 +107,8 @@ std::string SanitizeLabel(std::string label_key) */ std::vector PrometheusExporterUtils::TranslateToPrometheus( const sdk::metrics::ResourceMetrics &data, - bool populate_target_info) + bool populate_target_info, + bool without_otel_scope) { // initialize output vector @@ -126,7 +129,7 @@ std::vector PrometheusExporterUtils::TranslateT { SetTarget(data, data.scope_metric_data_.begin()->metric_data_.begin()->end_ts.time_since_epoch(), - (*data.scope_metric_data_.begin()).scope_, &output); + without_otel_scope ? nullptr : (*data.scope_metric_data_.begin()).scope_, &output); } for (const auto &instrumentation_info : data.scope_metric_data_) @@ -149,6 +152,9 @@ std::vector PrometheusExporterUtils::TranslateT metric_family.name = MapToPrometheusName(metric_data.instrument_descriptor.name_, metric_data.instrument_descriptor.unit_, type); metric_family.type = type; + const opentelemetry::sdk::instrumentationscope::InstrumentationScope *scope = + without_otel_scope ? nullptr : instrumentation_info.scope_; + for (const auto &point_data_attr : metric_data.point_data_attr_) { if (type == prometheus_client::MetricType::Histogram) // Histogram @@ -167,8 +173,7 @@ std::vector PrometheusExporterUtils::TranslateT sum = static_cast(nostd::get(histogram_point_data.sum_)); } SetData(std::vector{sum, (double)histogram_point_data.count_}, boundaries, counts, - point_data_attr.attributes, instrumentation_info.scope_, time, &metric_family, - data.resource_); + point_data_attr.attributes, scope, time, &metric_family, data.resource_); } else if (type == prometheus_client::MetricType::Gauge) { @@ -178,16 +183,16 @@ std::vector PrometheusExporterUtils::TranslateT auto last_value_point_data = nostd::get(point_data_attr.point_data); std::vector values{last_value_point_data.value_}; - SetData(values, point_data_attr.attributes, instrumentation_info.scope_, type, time, - &metric_family, data.resource_); + SetData(values, point_data_attr.attributes, scope, type, time, &metric_family, + data.resource_); } 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, instrumentation_info.scope_, type, time, - &metric_family, data.resource_); + SetData(values, point_data_attr.attributes, scope, type, time, &metric_family, + data.resource_); } else { @@ -203,8 +208,8 @@ std::vector PrometheusExporterUtils::TranslateT auto sum_point_data = nostd::get(point_data_attr.point_data); std::vector values{sum_point_data.value_}; - SetData(values, point_data_attr.attributes, instrumentation_info.scope_, type, time, - &metric_family, data.resource_); + SetData(values, point_data_attr.attributes, scope, type, time, &metric_family, + data.resource_); } else { @@ -277,11 +282,13 @@ std::string PrometheusExporterUtils::SanitizeNames(std::string name) return name; } +#if OPENTELEMETRY_HAVE_WORKING_REGEX std::regex INVALID_CHARACTERS_PATTERN("[^a-zA-Z0-9]"); std::regex CHARACTERS_BETWEEN_BRACES_PATTERN("\\{(.*?)\\}"); std::regex SANITIZE_LEADING_UNDERSCORES("^_+"); std::regex SANITIZE_TRAILING_UNDERSCORES("_+$"); std::regex SANITIZE_CONSECUTIVE_UNDERSCORES("[_]{2,}"); +#endif std::string PrometheusExporterUtils::GetEquivalentPrometheusUnit( const std::string &raw_metric_unit_name) @@ -357,7 +364,32 @@ std::string PrometheusExporterUtils::GetPrometheusPerUnit(const std::string &per std::string PrometheusExporterUtils::RemoveUnitPortionInBraces(const std::string &unit) { +#if OPENTELEMETRY_HAVE_WORKING_REGEX return std::regex_replace(unit, CHARACTERS_BETWEEN_BRACES_PATTERN, ""); +#else + bool in_braces = false; + std::string cleaned_unit; + cleaned_unit.reserve(unit.size()); + for (auto c : unit) + { + if (in_braces) + { + if (c == '}') + { + in_braces = false; + } + } + else if (c == '{') + { + in_braces = true; + } + else + { + cleaned_unit += c; + } + } + return cleaned_unit; +#endif } std::string PrometheusExporterUtils::ConvertRateExpressedToPrometheusUnit( @@ -386,12 +418,74 @@ std::string PrometheusExporterUtils::ConvertRateExpressedToPrometheusUnit( std::string PrometheusExporterUtils::CleanUpString(const std::string &str) { +#if OPENTELEMETRY_HAVE_WORKING_REGEX std::string cleaned_string = std::regex_replace(str, INVALID_CHARACTERS_PATTERN, "_"); cleaned_string = std::regex_replace(cleaned_string, SANITIZE_CONSECUTIVE_UNDERSCORES, "_"); cleaned_string = std::regex_replace(cleaned_string, SANITIZE_TRAILING_UNDERSCORES, ""); cleaned_string = std::regex_replace(cleaned_string, SANITIZE_LEADING_UNDERSCORES, ""); + return cleaned_string; +#else + std::string cleaned_string = str; + if (cleaned_string.empty()) + { + return cleaned_string; + } + std::transform(cleaned_string.begin(), cleaned_string.end(), cleaned_string.begin(), + [](const char c) { + if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) + { + return c; + } + return '_'; + }); + + std::string::size_type trim_start = 0; + std::string::size_type trim_end = 0; + bool previous_underscore = false; + for (std::string::size_type i = 0; i < cleaned_string.size(); ++i) + { + if (cleaned_string[i] == '_') + { + if (previous_underscore) + { + continue; + } + + previous_underscore = true; + } + else + { + previous_underscore = false; + } + + if (trim_end != i) + { + cleaned_string[trim_end] = cleaned_string[i]; + } + ++trim_end; + } + + while (trim_end > 0 && cleaned_string[trim_end - 1] == '_') + { + --trim_end; + } + while (trim_start < trim_end && cleaned_string[trim_start] == '_') + { + ++trim_start; + } + + // All characters are underscore + if (trim_start >= trim_end) + { + return "_"; + } + if (0 != trim_start || cleaned_string.size() != trim_end) + { + return cleaned_string.substr(trim_start, trim_end - trim_start); + } return cleaned_string; +#endif } std::string PrometheusExporterUtils::MapToPrometheusName( diff --git a/exporters/prometheus/test/collector_test.cc b/exporters/prometheus/test/collector_test.cc index 578e01d8f8..63f840bc9a 100644 --- a/exporters/prometheus/test/collector_test.cc +++ b/exporters/prometheus/test/collector_test.cc @@ -73,7 +73,7 @@ TEST(PrometheusCollector, BasicTests) MockMetricReader *reader = new MockMetricReader(); MockMetricProducer *producer = new MockMetricProducer(); reader->SetMetricProducer(producer); - PrometheusCollector collector(reader, true); + PrometheusCollector collector(reader, true, false); auto data = collector.Collect(); // Collection size should be the same as the size diff --git a/exporters/zipkin/include/opentelemetry/exporters/zipkin/recordable.h b/exporters/zipkin/include/opentelemetry/exporters/zipkin/recordable.h index 78079adee7..64894082fd 100644 --- a/exporters/zipkin/include/opentelemetry/exporters/zipkin/recordable.h +++ b/exporters/zipkin/include/opentelemetry/exporters/zipkin/recordable.h @@ -24,15 +24,15 @@ class Recordable final : public sdk::trace::Recordable void SetIdentity(const opentelemetry::trace::SpanContext &span_context, opentelemetry::trace::SpanId parent_span_id) noexcept override; - void SetAttribute(nostd::string_view key, + void SetAttribute(opentelemetry::nostd::string_view key, const opentelemetry::common::AttributeValue &value) noexcept override; - void AddEvent(nostd::string_view name, - common::SystemTimestamp timestamp, - const common::KeyValueIterable &attributes) noexcept override; + void AddEvent(opentelemetry::nostd::string_view name, + opentelemetry::common::SystemTimestamp timestamp, + const opentelemetry::common::KeyValueIterable &attributes) noexcept override; void AddLink(const opentelemetry::trace::SpanContext &span_context, - const common::KeyValueIterable &attributes) noexcept override; + const opentelemetry::common::KeyValueIterable &attributes) noexcept override; void SetStatus(opentelemetry::trace::StatusCode code, nostd::string_view description) noexcept override; diff --git a/exporters/zipkin/include/opentelemetry/exporters/zipkin/zipkin_exporter.h b/exporters/zipkin/include/opentelemetry/exporters/zipkin/zipkin_exporter.h index 2bf12b3a35..4de6513bfb 100644 --- a/exporters/zipkin/include/opentelemetry/exporters/zipkin/zipkin_exporter.h +++ b/exporters/zipkin/include/opentelemetry/exporters/zipkin/zipkin_exporter.h @@ -55,14 +55,14 @@ class ZipkinExporter final : public opentelemetry::sdk::trace::SpanExporter * @return return true when all data are exported, and false when timeout */ bool ForceFlush( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override; + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override; /** * Shut down the exporter. * @param timeout an optional timeout, default to max. */ bool Shutdown( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override; + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override; private: void InitializeLocalEndpoint(); diff --git a/exporters/zipkin/test/zipkin_exporter_test.cc b/exporters/zipkin/test/zipkin_exporter_test.cc index 870ff427e9..adc81c661b 100644 --- a/exporters/zipkin/test/zipkin_exporter_test.cc +++ b/exporters/zipkin/test/zipkin_exporter_test.cc @@ -60,7 +60,6 @@ class ZipkinExporterTestPeer : public ::testing::Test class MockHttpClient : public opentelemetry::ext::http::client::HttpClientSync { public: -# ifdef ENABLE_HTTP_SSL_PREVIEW MOCK_METHOD(ext::http::client::Result, Post, (const nostd::string_view &, @@ -68,28 +67,13 @@ class MockHttpClient : public opentelemetry::ext::http::client::HttpClientSync const ext::http::client::Body &, const ext::http::client::Headers &), (noexcept, override)); -# else - MOCK_METHOD(ext::http::client::Result, - Post, - (const nostd::string_view &, - const ext::http::client::Body &, - const ext::http::client::Headers &), - (noexcept, override)); -# endif /* ENABLE_HTTP_SSL_PREVIEW */ -# ifdef ENABLE_HTTP_SSL_PREVIEW MOCK_METHOD(ext::http::client::Result, Get, (const nostd::string_view &, const ext::http::client::HttpSslOptions &, const ext::http::client::Headers &), (noexcept, override)); -# else - MOCK_METHOD(ext::http::client::Result, - Get, - (const nostd::string_view &, const ext::http::client::Headers &), - (noexcept, override)); -# endif /* ENABLE_HTTP_SSL_PREVIEW */ }; class IsValidMessageMatcher @@ -169,11 +153,7 @@ TEST_F(ZipkinExporterTestPeer, ExportJsonIntegrationTest) auto expected_url = nostd::string_view{"http://localhost:9411/api/v2/spans"}; -# ifdef ENABLE_HTTP_SSL_PREVIEW EXPECT_CALL(*mock_http_client, Post(expected_url, _, IsValidMessage(report_trace_id), _)) -# else - EXPECT_CALL(*mock_http_client, Post(expected_url, IsValidMessage(report_trace_id), _)) -# endif /* ENABLE_HTTP_SSL_PREVIEW */ .Times(Exactly(1)) .WillOnce(Return(ByMove(ext::http::client::Result{ @@ -199,11 +179,7 @@ TEST_F(ZipkinExporterTestPeer, ShutdownTest) // exporter should not be shutdown by default nostd::span> batch_1(&recordable_1, 1); -# ifdef ENABLE_HTTP_SSL_PREVIEW EXPECT_CALL(*mock_http_client, Post(_, _, _, _)) -# else - EXPECT_CALL(*mock_http_client, Post(_, _, _)) -# endif /* ENABLE_HTTP_SSL_PREVIEW */ .Times(Exactly(1)) .WillOnce(Return(ByMove(ext::http::client::Result{ 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 45ee13d55c..93d407f24a 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 @@ -58,12 +58,10 @@ class Request : public opentelemetry::ext::http::client::Request method_ = method; } -#ifdef ENABLE_HTTP_SSL_PREVIEW void SetSslOptions(const HttpSslOptions &ssl_options) noexcept override { ssl_options_ = ssl_options; } -#endif /* ENABLE_HTTP_SSL_PREVIEW */ void SetBody(opentelemetry::ext::http::client::Body &body) noexcept override { @@ -93,11 +91,7 @@ class Request : public opentelemetry::ext::http::client::Request public: opentelemetry::ext::http::client::Method method_; - -#ifdef ENABLE_HTTP_SSL_PREVIEW opentelemetry::ext::http::client::HttpSslOptions ssl_options_; -#endif /* ENABLE_HTTP_SSL_PREVIEW */ - opentelemetry::ext::http::client::Body body_; opentelemetry::ext::http::client::Headers headers_; std::string uri_; @@ -225,18 +219,13 @@ class HttpClientSync : public opentelemetry::ext::http::client::HttpClientSync opentelemetry::ext::http::client::Result Get( const nostd::string_view &url, -#ifdef ENABLE_HTTP_SSL_PREVIEW const opentelemetry::ext::http::client::HttpSslOptions &ssl_options, -#endif /* ENABLE_HTTP_SSL_PREVIEW */ const opentelemetry::ext::http::client::Headers &headers) noexcept override { opentelemetry::ext::http::client::Body body; HttpOperation curl_operation(opentelemetry::ext::http::client::Method::Get, url.data(), -#ifdef ENABLE_HTTP_SSL_PREVIEW - ssl_options, -#endif /* ENABLE_HTTP_SSL_PREVIEW */ - nullptr, headers, body); + ssl_options, nullptr, headers, body); curl_operation.SendSync(); auto session_state = curl_operation.GetSessionState(); @@ -258,17 +247,12 @@ class HttpClientSync : public opentelemetry::ext::http::client::HttpClientSync opentelemetry::ext::http::client::Result Post( const nostd::string_view &url, -#ifdef ENABLE_HTTP_SSL_PREVIEW const opentelemetry::ext::http::client::HttpSslOptions &ssl_options, -#endif /* ENABLE_HTTP_SSL_PREVIEW */ const Body &body, const opentelemetry::ext::http::client::Headers &headers) noexcept override { HttpOperation curl_operation(opentelemetry::ext::http::client::Method::Post, url.data(), -#ifdef ENABLE_HTTP_SSL_PREVIEW - ssl_options, -#endif /* ENABLE_HTTP_SSL_PREVIEW */ - nullptr, headers, body); + ssl_options, nullptr, headers, body); curl_operation.SendSync(); auto session_state = curl_operation.GetSessionState(); if (curl_operation.WasAborted()) diff --git a/ext/include/opentelemetry/ext/http/client/curl/http_operation_curl.h b/ext/include/opentelemetry/ext/http/client/curl/http_operation_curl.h index 48ce11123c..587e74a238 100644 --- a/ext/include/opentelemetry/ext/http/client/curl/http_operation_curl.h +++ b/ext/include/opentelemetry/ext/http/client/curl/http_operation_curl.h @@ -139,9 +139,7 @@ class HttpOperation */ HttpOperation(opentelemetry::ext::http::client::Method method, std::string url, -#ifdef ENABLE_HTTP_SSL_PREVIEW const opentelemetry::ext::http::client::HttpSslOptions &ssl_options, -#endif /* ENABLE_HTTP_SSL_PREVIEW */ opentelemetry::ext::http::client::EventHandler *event_handle, // Default empty headers and empty request body const opentelemetry::ext::http::client::Headers &request_headers = @@ -290,9 +288,7 @@ class HttpOperation opentelemetry::ext::http::client::Method method_; std::string url_; -#ifdef ENABLE_HTTP_SSL_PREVIEW const opentelemetry::ext::http::client::HttpSslOptions &ssl_options_; -#endif /* ENABLE_HTTP_SSL_PREVIEW */ const Headers &request_headers_; const opentelemetry::ext::http::client::Body &request_body_; diff --git a/ext/include/opentelemetry/ext/http/client/http_client.h b/ext/include/opentelemetry/ext/http/client/http_client.h index c3559cb0eb..7fee1beb35 100644 --- a/ext/include/opentelemetry/ext/http/client/http_client.h +++ b/ext/include/opentelemetry/ext/http/client/http_client.h @@ -110,7 +110,6 @@ struct cmp_ic }; using Headers = std::multimap; -#ifdef ENABLE_HTTP_SSL_PREVIEW struct HttpSslOptions { HttpSslOptions() {} @@ -122,15 +121,11 @@ struct HttpSslOptions nostd::string_view input_ssl_client_key_path, nostd::string_view input_ssl_client_key_string, nostd::string_view input_ssl_client_cert_path, - nostd::string_view input_ssl_client_cert_string -# ifdef ENABLE_HTTP_SSL_TLS_PREVIEW - , + nostd::string_view input_ssl_client_cert_string, nostd::string_view input_ssl_min_tls, nostd::string_view input_ssl_max_tls, nostd::string_view input_ssl_cipher, - nostd::string_view input_ssl_cipher_suite -# endif /* ENABLE_HTTP_SSL_TLS_PREVIEW */ - ) + nostd::string_view input_ssl_cipher_suite) : use_ssl(false), ssl_insecure_skip_verify(input_ssl_insecure_skip_verify), ssl_ca_cert_path(input_ssl_ca_cert_path), @@ -138,15 +133,11 @@ struct HttpSslOptions ssl_client_key_path(input_ssl_client_key_path), ssl_client_key_string(input_ssl_client_key_string), ssl_client_cert_path(input_ssl_client_cert_path), - ssl_client_cert_string(input_ssl_client_cert_string) - -# ifdef ENABLE_HTTP_SSL_TLS_PREVIEW - , + ssl_client_cert_string(input_ssl_client_cert_string), ssl_min_tls(input_ssl_min_tls), ssl_max_tls(input_ssl_max_tls), ssl_cipher(input_ssl_cipher), ssl_cipher_suite(input_ssl_cipher_suite) -# endif /* ENABLE_HTTP_SSL_TLS_PREVIEW */ { /* Use SSL if url starts with "https:" */ if (strncmp(url.data(), "https:", 6) == 0) @@ -192,7 +183,6 @@ struct HttpSslOptions */ std::string ssl_client_cert_string{}; -# ifdef ENABLE_HTTP_SSL_TLS_PREVIEW /** Minimum SSL version to use. Valid values are: @@ -230,9 +220,7 @@ struct HttpSslOptions Cipher names depends on the underlying CURL implementation. */ std::string ssl_cipher_suite{}; -# endif /* ENABLE_HTTP_SSL_TLS_PREVIEW */ }; -#endif /* ENABLE_HTTP_SSL_PREVIEW */ class Request { @@ -241,9 +229,7 @@ class Request virtual void SetUri(nostd::string_view uri) noexcept = 0; -#ifdef ENABLE_HTTP_SSL_PREVIEW virtual void SetSslOptions(const HttpSslOptions &options) noexcept = 0; -#endif /* ENABLE_HTTP_SSL_PREVIEW */ virtual void SetBody(Body &body) noexcept = 0; @@ -368,36 +354,24 @@ class HttpClientSync public: Result GetNoSsl(const nostd::string_view &url, const Headers &headers = {{}}) noexcept { -#ifdef ENABLE_HTTP_SSL_PREVIEW static const HttpSslOptions no_ssl; return Get(url, no_ssl, headers); -#else - return Get(url, headers); -#endif /* ENABLE_HTTP_SSL_PREVIEW */ } virtual Result PostNoSsl(const nostd::string_view &url, const Body &body, const Headers &headers = {{"content-type", "application/json"}}) noexcept { -#ifdef ENABLE_HTTP_SSL_PREVIEW static const HttpSslOptions no_ssl; return Post(url, no_ssl, body, headers); -#else - return Post(url, body, headers); -#endif /* ENABLE_HTTP_SSL_PREVIEW */ } virtual Result Get(const nostd::string_view &url, -#ifdef ENABLE_HTTP_SSL_PREVIEW const HttpSslOptions &ssl_options, -#endif /* ENABLE_HTTP_SSL_PREVIEW */ const Headers & = {{}}) noexcept = 0; virtual Result Post(const nostd::string_view &url, -#ifdef ENABLE_HTTP_SSL_PREVIEW const HttpSslOptions &ssl_options, -#endif /* ENABLE_HTTP_SSL_PREVIEW */ const Body &body, const Headers & = {{"content-type", "application/json"}}) noexcept = 0; diff --git a/ext/include/opentelemetry/ext/zpages/latency_boundaries.h b/ext/include/opentelemetry/ext/zpages/latency_boundaries.h deleted file mode 100644 index cc03b169b2..0000000000 --- a/ext/include/opentelemetry/ext/zpages/latency_boundaries.h +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include - -#include "opentelemetry/version.h" - -using std::chrono::microseconds; -using std::chrono::milliseconds; -using std::chrono::nanoseconds; -using std::chrono::seconds; - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace ext -{ -namespace zpages -{ -/** - * kLatencyBoundaries is a constant array that contains the 9 latency - * boundaries. Each value in the array represents the lower limit(inclusive) of - * the boundary(in nano seconds) and the upper limit(exclusive) of the boundary - * is the lower limit of the next one. The upper limit of the last boundary is - * INF. - */ -const std::array kLatencyBoundaries = { - nanoseconds(0), - nanoseconds(microseconds(10)), - nanoseconds(microseconds(100)), - nanoseconds(milliseconds(1)), - nanoseconds(milliseconds(10)), - nanoseconds(milliseconds(100)), - nanoseconds(seconds(1)), - nanoseconds(seconds(10)), - nanoseconds(seconds(100)), -}; - -/** - * LatencyBoundary enum is used to index into the kLatencyBoundaries container. - * Using this enum lets you access the latency boundary at each index without - * using magic numbers - */ -enum LatencyBoundary -{ - k0MicroTo10Micro, - k10MicroTo100Micro, - k100MicroTo1Milli, - k1MilliTo10Milli, - k10MilliTo100Milli, - k100MilliTo1Second, - k1SecondTo10Second, - k10SecondTo100Second, - k100SecondToMax -}; - -} // namespace zpages -} // namespace ext -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/include/opentelemetry/ext/zpages/static/tracez_index.h b/ext/include/opentelemetry/ext/zpages/static/tracez_index.h deleted file mode 100644 index c4c5b4933d..0000000000 --- a/ext/include/opentelemetry/ext/zpages/static/tracez_index.h +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -const char tracez_index[] = - "" - "" - "" - " " - " zPages TraceZ" - " " - " " - " " - " " - "

    zPages TraceZ

    " - " Data last fetched:
    " - "
    " - "

    " - "
    " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - " " - "
    Span NameError SamplesRunningLatency Samples
    " - " " - "
    " - "
    Row count: 0
    " - "
    " - "
    " - "
    " - " " - "
    " - " " - "
    " - "
    Row count: 0
    " - "
    " - " " - ""; diff --git a/ext/include/opentelemetry/ext/zpages/static/tracez_script.h b/ext/include/opentelemetry/ext/zpages/static/tracez_script.h deleted file mode 100644 index b21ceea8ee..0000000000 --- a/ext/include/opentelemetry/ext/zpages/static/tracez_script.h +++ /dev/null @@ -1,293 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -const char tracez_script[] = - "" - "window.onload = () => refreshData();" - "" - "const latencies = [" - " '>0s', '>10µs', '>100µs'," - " '>1ms', '>10ms', '>100ms'," - " '>1s', '>10s', '>100s'," - "];" - "" - "const statusCodeDescriptions = {" - " 'OK': 'The operation completed successfully.'," - " 'CANCELLED': 'The operation was cancelled (typically by the caller).'," - " 'UNKNOWN': `Unknown error. An example of where this error may be returned is if a Status " - "value received" - " from another address space belongs to an error-space that is not known in this " - "address space." - " Also errors raised by APIs that do not return enough error information may be " - "converted to" - " this error.`," - " 'INVALID_ARGUMENT': `Client specified an invalid argument. Note that this differs from " - "FAILED_PRECONDITION." - " INVALID_ARGUMENT indicates arguments that are problematic regardless of the state " - "of the" - " system (e.g., a malformed file name).`," - " 'DEADLINE_EXCEEDED': `Deadline expired before operation could complete. For operations that " - "change the state of the" - " system, this error may be returned even if the operation has completed " - "successfully. For" - " example, a successful response from a server could have been delayed long enough " - "for the" - " deadline to expire.`," - " 'NOT_FOUND' : 'Some requested entity (e.g., file or directory) was not found.'," - " 'ALREADY_EXISTS': 'Some entity that we attempted to create (e.g., file or directory) " - "already exists.'," - " 'PERMISSION_DENIED': `The caller does not have permission to execute the specified " - "operation. PERMISSION_DENIED" - " must not be used for rejections caused by exhausting some resource (use " - "RESOURCE_EXHAUSTED" - " instead for those errors). PERMISSION_DENIED must not be used if the caller cannot " - "be" - " identified (use UNAUTHENTICATED instead for those errors).`," - " 'RESOURCE_EXHAUSTED': `Some resource has been exhausted, perhaps a per-user quota, or " - "perhaps the entire file system" - " is out of space.`," - " 'FAILED_PRECONDITION': `Operation was rejected because the system is not in a state " - "required for the operation's" - " execution. For example, directory to be deleted may be non-empty, an rmdir " - "operation is" - " applied to a non-directory, etc.`," - " 'ABORTED': `The operation was aborted, typically due to a concurrency issue like sequencer " - "check" - " failures, transaction aborts, etc`," - " 'OUT_OF_RANGE': `Operation was attempted past the valid range. E.g., seeking or reading " - "past end of file.`," - " 'UNIMPLEMENTED': 'Operation is not implemented or not supported/enabled in this service.'," - " 'INTERNAL': `Internal errors. Means some invariants expected by underlying system has been " - "broken. If you" - " see one of these errors, something is very broken.`," - " 'UNAVAILABLE': `The service is currently unavailable. This is a most likely a transient " - "condition and may be" - " corrected by retrying with a backoff.`," - " 'DATA_LOSS': 'Unrecoverable data loss or corruption.'," - " 'UNAUTHENTICATED': 'The request does not have valid authentication credentials for the " - "operation.'," - "};" - "" - "const units = {'duration': 'ns'};" - "" - "" - "const details = {'status': statusCodeDescriptions};" - "" - "/* Latency info is returned as an array, so they need to be parsed accordingly */" - "const getLatencyCell = (span, i, h) => `${span[h][i]}`;" - "" - "/* Pretty print a cell with a map */" - "const getKeyValueCell = (span, h) => `" - " ${JSON.stringify(span[h], null, 2)}" - " `;" - "" - "/* Standard categories when checking span details */" - "const idCols = ['spanid', 'parentid', 'traceid'];" - "const detailCols = ['attributes']; /* Columns error, running, and latency spans all share */" - "const dateCols = ['start']; /* Categories to change to date */" - "const numCols = ['duration']; /* Categories to change to num */" - "const clickCols = ['error', 'running']; /* Non-latency clickable cols */" - "const arrayCols = { " - " 'latency': getLatencyCell," - " 'events': getKeyValueCell," - " 'attributes': getKeyValueCell" - "};" - "" - "const base_endpt = '/tracez/get/'; /* For making GET requests */" - "" - "/* Maps table types to their approporiate formatting */" - "const tableFormatting = {" - " 'all': {" - " 'url': base_endpt + 'aggregations'," - " 'html_id': 'overview_table'," - " 'sizing': [" - " {'sz': 'md', 'repeats': 1}," - " {'sz': 'sm', 'repeats': 11}," - " ]," - " 'headings': ['name', ...clickCols, 'latency']," - " 'cell_headings': ['name', ...clickCols, ...latencies]," - " }," - " 'error': {" - " 'url': base_endpt + 'error/'," - " 'html_id': 'name_type_detail_table'," - " 'sizing': [" - " {'sz': 'sm', 'repeats': 5}," - " {'sz': 'sm-md', 'repeats': 1}," - " ]," - " 'headings': [...idCols, ...dateCols, 'status', ...detailCols]," - " 'has_subheading': true," - " }," - " 'running': {" - " 'url': base_endpt + 'running/'," - " 'html_id': 'name_type_detail_table'," - " 'sizing': [" - " {'sz': 'sm', 'repeats': 4}," - " {'sz': 'sm-md', 'repeats': 1}," - " ]," - " 'headings': [...idCols, ...dateCols, ...detailCols]," - " 'has_subheading': true," - " 'status': 'pending'," - " }," - " 'latency': {" - " 'url': base_endpt + 'latency/'," - " 'html_id': 'name_type_detail_table'," - " 'sizing': [" - " {'sz': 'sm', 'repeats': 5}," - " {'sz': 'sm-md', 'repeats': 1}," - " ]," - " 'headings': [...idCols, ...dateCols, ...numCols, ...detailCols]," - " 'has_subheading': true," - " 'status': 'ok'" - " }" - "};" - "const getFormat = group => tableFormatting[group];" - "" - "/* Getters using formatting config variable */" - "const getURL = group => getFormat(group)['url'];" - "const getHeadings = group => getFormat(group)['headings'];" - "const getCellHeadings = group => 'cell_headings' in getFormat(group)" - " ? getFormat(group)['cell_headings'] : getHeadings(group); " - "const getSizing = group => getFormat(group)['sizing'];" - "const getStatus = group => isLatency(group) ? 'ok' : getFormat(group)['status'];" - "const getHTML = group => getFormat(group)['html_id'];" - "" - "const isDate = col => new Set(dateCols).has(col);" - "const isLatency = group => !(new Set(clickCols).has(group)); /* non latency clickable cols, " - "change to include latency? */" - "const isArrayCol = group => (new Set(Object.keys(arrayCols)).has(group));" - "const hasCallback = col => new Set(clickCols).has(col); /* Non-latency cb columns */" - "const hideHeader = h => new Set([...clickCols, 'name']).has(h); /* Headers to not show render " - "twice */" - "const hasSubheading = group => isLatency(group) || 'has_subheading' in getFormat(group); " - "const hasStatus = group => isLatency(group) || 'status' in getFormat(group);" - "" - "const toTitlecase = word => word.charAt(0).toUpperCase() + word.slice(1);" - "const updateLastRefreshStr = () => document.getElementById('lastUpdateTime').innerHTML = new " - "Date().toLocaleString();" - "" - "const getStatusHTML = group => !hasStatus(group) ? ''" - " : `All of these spans have status code ${getStatus(group)}`;" - "" - "/* Returns an HTML string that handlles width formatting" - " for a table group */" - "const tableSizing = group => ''" - " + getSizing(group).map(sz =>" - " (``).repeat(sz['repeats']))" - " .join('')" - " + '';" - "" - "/* Returns an HTML string for a table group's headings," - " hiding headings where needed */" - "const tableHeadings = group => ''" - " + getCellHeadings(group).map(h => `${(hideHeader(h) ? '' : h)}`).join('')" - " + '';" - "" - "/* Returns an HTML string, which represents the formatting for" - " the entire header for a table group. This doesn't change, and" - " includes the width formatting and the actual table headers */" - "const tableHeader = group => tableSizing(group) + tableHeadings(group);" - "" - "/* Return formatting for an array-based value based on its header */" - "const getArrayCells = (h, span) => span[h].length" - " ? (span[h].map((_, i) => arrayCols[h](span, i, h))).join('')" - " : (Object.keys(span[h]).length ? arrayCols[h](span, h) : `${emptyContent()}`);" - "" - "const emptyContent = () => `(not set)`;" - "" - "const dateStr = nanosec => {" - " const mainDate = new Date(nanosec / 1000000).toLocaleString();" - " let lostPrecision = String(nanosec % 1000000);" - " while (lostPrecision.length < 6) lostPrecision = 0 + lostPrecision;" - " const endingLocation = mainDate.indexOf('M') - 2;" - " return `${mainDate.substr(0, " - "endingLocation)}:${lostPrecision}${mainDate.substr(endingLocation)}`;" - "};" - "" - "const detailCell = (h, span) => {" - " const detailKey = Object.keys(details[h])[span[h]];" - " const detailVal = details[h][detailKey];" - " return `" - " ${detailKey}" - " ${detailVal}" - " `;" - "};" - "" - "/* Format cells as needed */" - "const getCellContent = (h, span) => {" - " if (h in details) return detailCell(h, span);" - " else if (h in units) return `${span[h]} ${units[h]}`;" - " else if (span[h] === '') return emptyContent();" - " else if (!isDate(h)) return span[h];" - " return dateStr(span[h]);" - "};" - "" - "/* Create cell based on what header we want to render */" - "const getCell = (h, span) => (isArrayCol(h)) ? getArrayCells(h, span)" - " : `` + `${getCellContent(h, span)}`;" - "" - "/* Returns an HTML string with for a span's aggregated data" - " while columns are ordered according to its table group */" - "const tableRow = (group, span) => ''" - " + getHeadings(group).map(h => getCell(h, span)).join('')" - " + '';" - "" - "/* Returns an HTML string from all the data given as" - " table rows, with each row being a group of spans by name */" - "const tableRows = (group, data) => data.map(span => tableRow(group, span)).join('');" - "" - "/* Overwrite a table on the DOM based on the group given by adding" - " its headers and fetching data for its url */" - "function overwriteTable(group, url_end = '') {" - " fetch(getURL(group) + url_end).then(res => res.json())" - " .then(data => {" - " document.getElementById(getHTML(group))" - " .innerHTML = tableHeader(group)" - " + tableRows(group, data);" - " document.getElementById(getHTML(group) + '_count')" - " .innerHTML = data.length;" - " })" - " .catch(err => console.log(err));" - "};" - "" - "/* Adds a title subheading where needed */" - "function updateSubheading(group, name) {" - " if (hasSubheading(group)) {" - " document.getElementById(getHTML(isLatency(group) ? 'latency' : group) + '_header')" - " .innerHTML = `

    ${name}" - " ${(isLatency(group) ? `${latencies[group]} Bucket` : toTitlecase(group))}" - " Spans

    Showing span details for up to 5 most recent spans. " - " ${getStatusHTML(group)}

    `;" - " }" - "};" - "" - "/* Overwrites a table on the DOM based on the group and also" - " changes the subheader, since this a looking at sampled spans */" - "function overwriteDetailedTable(group, name) {" - " if (isLatency(group)) overwriteTable('latency', group + '/' + name);" - " else overwriteTable(group, name);" - " updateSubheading(group, name);" - "};" - "" - "/* Append to a table on the DOM based on the group given */" - "function addToTable(group, url_end = '') {" - " fetch(getURL(group) + url_end).then(res => res.json())" - " .then(data => {" - " const rowsStr = tableRows(group, data);" - " if (!rowsStr) console.log(`No rows added for ${group} table`);" - " document.getElementById(getHTML(group))" - " .getElementsByTagName('tbody')[0]" - " .innerHTML += rowsStr;" - " })" - " .catch(err => console.log(err));" - "};" - "" - "const refreshData = () => {" - " updateLastRefreshStr();" - " overwriteTable('all');" - "};" - ""; diff --git a/ext/include/opentelemetry/ext/zpages/static/tracez_style.h b/ext/include/opentelemetry/ext/zpages/static/tracez_style.h deleted file mode 100644 index 16b83f897e..0000000000 --- a/ext/include/opentelemetry/ext/zpages/static/tracez_style.h +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -const char tracez_style[] = - "" - "body {" - " color: #252525;" - " text-align: center;" - " font-family: monospace, sans-serif;" - " word-break: break-all;" - " font-size: .9em" - "}" - "" - "code {" - " font-size: 12px;" - "}" - "" - "h1 {" - " margin: 20px 0 0;" - "}" - "" - "table {" - " font-family: monospace, sans-serif;" - " border-collapse: collapse;" - " font-size: 1.05em;" - " width: 100%;" - "}" - "" - ".table-wrap {" - " width: 100%;" - " min-width: 700px;" - " max-width: 2000px;" - " margin: auto;" - "}" - "" - "td, th {" - " word-break: break-word;" - " border: 1px solid #f5f5f5;" - " padding: 6px;" - " text-align: center;" - "}" - "" - "#overview_table th, #overview_table tr {" - " border-top: none;" - "}" - "" - "#headers th, #headers tr {" - " border-bottom: none;" - "}" - "" - "#top-right {" - " text-align: right;" - " position: absolute;" - " top: 10px;" - " right: 10px;" - " text-shadow: .5px .5px .25px #fff;" - "}" - "" - "#top-right button {" - " color: #f6a81c;" - " border: 2px solid #f6a81c;" - " padding: 10px;" - " margin: 10px;" - " text-transform: uppercase;" - " letter-spacing: 1px;" - " background-color: white;" - " border-radius: 10px;" - " font-weight: bold;" - "}" - "" - ".right {" - " text-align: right;" - " padding: 10px;" - "}" - "" - ":hover {" - " transition-duration: .15s;" - "}" - "" - "#top-right button:hover {" - " border-color: #4b5fab;" - " color: #4b5fab;" - " cursor: pointer;" - "}" - "" - "tr:nth-child(even) {" - " background-color: #eee;" - "}" - "" - ".click {" - " text-decoration: underline dotted #4b5fab;" - "}" - "" - "tr:hover, td:hover, .click:hover {" - " color: white;" - " background-color: #4b5fab;" - "}" - "" - "tr:hover {" - " background-color: #4b5fabcb;" - "}" - "" - "th {" - " background-color: white;" - " color: #252525;" - "}" - "" - ".click:hover {" - " cursor: pointer;" - " color: #f6a81ccc;" - "}" - "" - ".empty {" - " color: #999;" - "}" - "" - ".sm {" - " width: 7%;" - "}" - "" - ".sm-md {" - " width: 13%;" - "}" - "" - ".md {" - " width: 23%;" - "}" - "" - ".lg {" - " width: 63%;" - "}" - "" - "img {" - " width: 50%;" - " max-width: 500px;" - "}" - "" - ".subhead-name {" - " color: #4b5fab;" - "}" - "" - ".has-tooltip {" - " text-decoration: underline dotted #f6a81c;" - "}" - "" - ".has-tooltip:hover .tooltip {" - " display: block;" - "}" - "" - ".tooltip {" - " display: none;" - " position: absolute;" - "}" - "" - ".tooltip, .tooltip:hover {" - " background: #ffffffd9;" - " padding: 10px;" - " z-index: 1000;" - " color: #252525 !important;" - " border-radius: 10px;" - " margin: 3px 20px 0 0;" - "}" - ""; diff --git a/ext/include/opentelemetry/ext/zpages/threadsafe_span_data.h b/ext/include/opentelemetry/ext/zpages/threadsafe_span_data.h deleted file mode 100644 index bd1f716ad8..0000000000 --- a/ext/include/opentelemetry/ext/zpages/threadsafe_span_data.h +++ /dev/null @@ -1,249 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include -#include -#include - -#include "opentelemetry/common/timestamp.h" -#include "opentelemetry/nostd/string_view.h" -#include "opentelemetry/sdk/trace/recordable.h" -#include "opentelemetry/sdk/trace/span_data.h" -#include "opentelemetry/trace/span.h" -#include "opentelemetry/trace/span_id.h" -#include "opentelemetry/trace/trace_id.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace ext -{ -namespace zpages -{ - -/** - * This class is a threadsafe version of span data used for zpages in OT - */ -class ThreadsafeSpanData final : public opentelemetry::sdk::trace::Recordable -{ -public: - /** - * Get the trace id for this span - * @return the trace id for this span - */ - opentelemetry::trace::TraceId GetTraceId() const noexcept - { - std::lock_guard lock(mutex_); - return span_context_.trace_id(); - } - - /** - * Get the span id for this span - * @return the span id for this span - */ - opentelemetry::trace::SpanId GetSpanId() const noexcept - { - std::lock_guard lock(mutex_); - return span_context_.span_id(); - } - - /** - * Get the span context for this span - * @return the span context for this span - */ - const opentelemetry::trace::SpanContext &GetSpanContext() const noexcept - { - std::lock_guard lock(mutex_); - return span_context_; - } - - /** - * Get the parent span id for this span - * @return the span id for this span's parent - */ - opentelemetry::trace::SpanId GetParentSpanId() const noexcept - { - std::lock_guard lock(mutex_); - return parent_span_id_; - } - - /** - * Get the name for this span - * @return the name for this span - */ - opentelemetry::nostd::string_view GetName() const noexcept - { - std::lock_guard lock(mutex_); - return name_; - } - - /** - * Get the status for this span - * @return the status for this span - */ - opentelemetry::trace::StatusCode GetStatus() const noexcept - { - std::lock_guard lock(mutex_); - return status_code_; - } - - /** - * Get the status description for this span - * @return the description of the the status of this span - */ - opentelemetry::nostd::string_view GetDescription() const noexcept - { - std::lock_guard lock(mutex_); - return status_desc_; - } - - /** - * Get the start time for this span - * @return the start time for this span - */ - opentelemetry::common::SystemTimestamp GetStartTime() const noexcept - { - std::lock_guard lock(mutex_); - return start_time_; - } - - /** - * Get the duration for this span - * @return the duration for this span - */ - std::chrono::nanoseconds GetDuration() const noexcept - { - std::lock_guard lock(mutex_); - return duration_; - } - - /** - * Get the attributes for this span - * @return the attributes for this span - */ - std::unordered_map GetAttributes() - const noexcept - { - std::lock_guard lock(mutex_); - return attributes_; - } - - void SetIdentity(const opentelemetry::trace::SpanContext &span_context, - opentelemetry::trace::SpanId parent_span_id) noexcept override - { - std::lock_guard lock(mutex_); - span_context_ = span_context; - parent_span_id_ = parent_span_id; - } - - void SetAttribute(nostd::string_view key, const common::AttributeValue &value) noexcept override - { - std::lock_guard lock(mutex_); - attributes_[std::string(key)] = nostd::visit(converter_, value); - } - - void SetStatus(opentelemetry::trace::StatusCode code, - nostd::string_view description) noexcept override - { - std::lock_guard lock(mutex_); - status_code_ = code; - status_desc_ = std::string(description); - } - - void SetName(nostd::string_view name) noexcept override - { - std::lock_guard lock(mutex_); - name_ = std::string(name); - } - - void SetSpanKind(opentelemetry::trace::SpanKind span_kind) noexcept override - { - span_kind_ = span_kind; - } - - void SetResource(const opentelemetry::sdk::resource::Resource & /*resource*/) noexcept override - { - // Not Implemented - } - - void SetStartTime(opentelemetry::common::SystemTimestamp start_time) noexcept override - { - std::lock_guard lock(mutex_); - start_time_ = start_time; - } - - void SetDuration(std::chrono::nanoseconds duration) noexcept override - { - std::lock_guard lock(mutex_); - duration_ = duration; - } - - void SetInstrumentationScope(const opentelemetry::sdk::instrumentationscope::InstrumentationScope - &instrumentation_scope) noexcept override - { - std::lock_guard lock(mutex_); - instrumentation_scope_ = &instrumentation_scope; - } - - void AddLink(const opentelemetry::trace::SpanContext &span_context, - const opentelemetry::common::KeyValueIterable &attributes = - opentelemetry::common::KeyValueIterableView>( - {})) noexcept override - { - std::lock_guard lock(mutex_); - (void)span_context; - (void)attributes; - } - - void AddEvent( - nostd::string_view name, - common::SystemTimestamp timestamp = common::SystemTimestamp(std::chrono::system_clock::now()), - const opentelemetry::common::KeyValueIterable &attributes = - opentelemetry::common::KeyValueIterableView>( - {})) noexcept override - { - std::lock_guard lock(mutex_); - events_.push_back( - opentelemetry::sdk::trace::SpanDataEvent(std::string(name), timestamp, attributes)); - } - - ThreadsafeSpanData() {} - ThreadsafeSpanData(const ThreadsafeSpanData &threadsafe_span_data) - : ThreadsafeSpanData(threadsafe_span_data, - std::lock_guard(threadsafe_span_data.mutex_)) - {} - -private: - ThreadsafeSpanData(const ThreadsafeSpanData &threadsafe_span_data, - const std::lock_guard &) - : span_context_(threadsafe_span_data.span_context_), - parent_span_id_(threadsafe_span_data.parent_span_id_), - start_time_(threadsafe_span_data.start_time_), - duration_(threadsafe_span_data.duration_), - name_(threadsafe_span_data.name_), - status_code_(threadsafe_span_data.status_code_), - status_desc_(threadsafe_span_data.status_desc_), - attributes_(threadsafe_span_data.attributes_), - events_(threadsafe_span_data.events_), - converter_(threadsafe_span_data.converter_), - instrumentation_scope_(threadsafe_span_data.instrumentation_scope_) - {} - - mutable std::mutex mutex_; - opentelemetry::trace::SpanContext span_context_{false, false}; - opentelemetry::trace::SpanId parent_span_id_; - common::SystemTimestamp start_time_; - std::chrono::nanoseconds duration_{0}; - std::string name_; - opentelemetry::trace::SpanKind span_kind_; - opentelemetry::trace::StatusCode status_code_{opentelemetry::trace::StatusCode::kUnset}; - std::string status_desc_; - std::unordered_map attributes_; - std::vector events_; - opentelemetry::sdk::common::AttributeConverter converter_; - const opentelemetry::sdk::instrumentationscope::InstrumentationScope *instrumentation_scope_; -}; -} // namespace zpages -} // namespace ext -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/include/opentelemetry/ext/zpages/tracez_data.h b/ext/include/opentelemetry/ext/zpages/tracez_data.h deleted file mode 100644 index 5f36a6b047..0000000000 --- a/ext/include/opentelemetry/ext/zpages/tracez_data.h +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include -#include -#include - -#include "opentelemetry/ext/zpages/threadsafe_span_data.h" -#include "opentelemetry/nostd/span.h" -#include "opentelemetry/nostd/string_view.h" -#include "opentelemetry/sdk/trace/span_data.h" -#include "opentelemetry/trace/span_id.h" -#include "opentelemetry/trace/trace_id.h" -#include "opentelemetry/version.h" - -using opentelemetry::ext::zpages::ThreadsafeSpanData; -using opentelemetry::trace::SpanId; -using opentelemetry::trace::TraceId; - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace ext -{ -namespace zpages -{ - -/** - * kMaxNumberOfSampleSpans is the maximum number of running, completed or error - * sample spans stored at any given time for a given span name. - * This limit is introduced to reduce memory usage by trimming sample spans - * stored. - */ -const int kMaxNumberOfSampleSpans = 5; - -/** - * TracezData is the data to be displayed for tracez zpages that is stored for - * each span name. - */ -struct TracezData -{ - /** - * TODO: At this time the maximum count is unknown but a larger data type - * might have to be used in the future to store these counts to avoid overflow - */ - unsigned int running_span_count; - unsigned int error_span_count; - - /** - * completed_span_count_per_latency_bucket is an array that stores the count - * of spans for each of the 9 latency buckets. - */ - std::array completed_span_count_per_latency_bucket; - - /** - * sample_latency_spans is an array of lists, each index of the array - * corresponds to a latency boundary(of which there are 9). - * The list in each index stores the sample spans for that latency boundary. - */ - std::array, kLatencyBoundaries.size()> sample_latency_spans; - - /** - * sample_error_spans is a list that stores the error samples for a span name. - */ - std::list sample_error_spans; - - /** - * sample_running_spans is a list that stores the running span samples for a - * span name. - */ - std::list sample_running_spans; - - TracezData() - { - running_span_count = 0; - error_span_count = 0; - completed_span_count_per_latency_bucket.fill(0); - } -}; - -} // namespace zpages -} // namespace ext -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/include/opentelemetry/ext/zpages/tracez_data_aggregator.h b/ext/include/opentelemetry/ext/zpages/tracez_data_aggregator.h deleted file mode 100644 index 5bc7e847db..0000000000 --- a/ext/include/opentelemetry/ext/zpages/tracez_data_aggregator.h +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "opentelemetry/ext/zpages/latency_boundaries.h" -#include "opentelemetry/ext/zpages/tracez_data.h" -#include "opentelemetry/ext/zpages/tracez_shared_data.h" -#include "opentelemetry/nostd/span.h" -#include "opentelemetry/nostd/string_view.h" -#include "opentelemetry/sdk/trace/span_data.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace ext -{ -namespace zpages -{ -/** - * TracezDataAggregator object is responsible for collecting raw data and - * converting it to useful information that can be made available to - * display on the tracez zpage. - * - * When this object is created it starts a thread that calls a function - * periodically to update the aggregated data with new spans. - * - * The only exposed function is a getter that returns a copy of the aggregated - * data when requested. This function is ensured to be called in sequence to the - * aggregate spans function which is called periodically. - * - * TODO: Consider a singleton pattern for this class, not sure if multiple - * instances of this class should exist. - */ -class TracezDataAggregator -{ -public: - /** - * Constructor creates a thread that calls a function to aggregate span data - * at regular intervals. - * @param shared_data is the shared set of spans to expose. - * @param update_interval the time duration for updating the aggregated data. - */ - TracezDataAggregator(std::shared_ptr shared_data, - milliseconds update_interval = milliseconds(10)); - - /** Ends the thread set up in the constructor and destroys the object **/ - ~TracezDataAggregator(); - - /** - * GetAggregatedTracezData returns a copy of the updated data. - * @returns a map with the span name as key and the tracez span data as value. - */ - std::map GetAggregatedTracezData(); - -private: - /** - * AggregateSpans is the function that is called to update the aggregated data - * with newly completed and running span data - */ - void AggregateSpans(); - - /** - * AggregateCompletedSpans is the function that is called to update the - * aggregation with the data of newly completed spans. - * @param completed_spans are the newly completed spans. - */ - void AggregateCompletedSpans(std::vector> &completed_spans); - - /** - * AggregateRunningSpans aggregates the data for all running spans received - * from the span processor. Running spans are not cleared by the span - * processor and multiple calls to this function may contain running spans for - * which data has already been collected in a previous call. Additionally, - * span names can change while span is running and there seems to be - * no trivial to way to know if it is a new or old running span so at every - * call to this function the available running span data is reset and - * recalculated. At this time there is no unique way to identify a span - * object once this is done, there might be some better ways to do this. - * TODO : SpanProcessor is never notified when a span name is changed while it - * is running and that is propogated to the data aggregator. The running span - * name if changed while it is running will not be updated in the data - * aggregator till the span is completed. - * @param running_spans is the running spans to be aggregated. - */ - void AggregateRunningSpans(std::unordered_set &running_spans); - - /** - * AggregateStatusOKSpans is the function called to update the data of spans - * with status code OK. - * @param ok_span is the span who's data is to be aggregated - */ - void AggregateStatusOKSpan(std::unique_ptr &ok_span); - - /** - * AggregateStatusErrorSpans is the function that is called to update the - * data of error spans - * @param error_span is the error span who's data is to be aggregated - */ - void AggregateStatusErrorSpan(std::unique_ptr &error_span); - - /** - * ClearRunningSpanData is a function that is used to clear all running span - * at the beginning of a call to AggregateSpan data. - * Running span data has to be cleared before aggregation because running - * span data is recalculated at every call to AggregateSpans. - */ - void ClearRunningSpanData(); - - /** - * FindLatencyBoundary finds the latency boundary to which the duration of - * the given span_data belongs to - * @ param span_data is the ThreadsafeSpanData whose duration for which the latency - * boundary is to be found - * @ returns LatencyBoundary is the latency boundary that the duration belongs - * to - */ - LatencyBoundary FindLatencyBoundary(std::unique_ptr &ok_span); - - /** - * InsertIntoSampleSpanList is a helper function that is called to insert - * a given span into a sample span list. A function is used for insertion - * because list size is to be limited at a set maximum. - * @param sample_spans the sample span list into which span is to be inserted - * @param span_data the span_data to be inserted into list - */ - void InsertIntoSampleSpanList(std::list &sample_spans, - ThreadsafeSpanData &span_data); - - /** Instance of shared spans used to collect raw data **/ - std::shared_ptr tracez_shared_data_; - - /** - * Tree map with key being the name of the span and value being a unique ptr - * that stores the tracez span data for the given span name - * A tree map is preferred to a hash map because the the data is to be ordered - * in alphabetical order of span name. - * TODO : A possible memory concern if there are too many unique - * span names, one solution could be to implement a LRU cache that trims the - * DS based on frequency of usage of a span name. - */ - std::map aggregated_tracez_data_; - std::mutex mtx_; - - /** A boolean that is set to true in the constructor and false in the - * destructor to start and end execution of aggregate spans **/ - std::atomic execute_{false}; - - /** Thread that executes aggregate spans at regurlar intervals during this - object's lifetime**/ - std::thread aggregate_spans_thread_; - - /** Condition variable that notifies the thread when object is about to be - destroyed **/ - std::condition_variable cv_; -}; - -} // namespace zpages -} // namespace ext -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/include/opentelemetry/ext/zpages/tracez_http_server.h b/ext/include/opentelemetry/ext/zpages/tracez_http_server.h deleted file mode 100644 index eaa3fac8d3..0000000000 --- a/ext/include/opentelemetry/ext/zpages/tracez_http_server.h +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include -#include -#include -#include -#include - -#include "nlohmann/json.hpp" -#include "opentelemetry/ext/zpages/static/tracez_index.h" -#include "opentelemetry/ext/zpages/static/tracez_script.h" -#include "opentelemetry/ext/zpages/static/tracez_style.h" -#include "opentelemetry/ext/zpages/tracez_data_aggregator.h" -#include "opentelemetry/ext/zpages/zpages_http_server.h" - -#define HAVE_HTTP_DEBUG -#define HAVE_CONSOLE_LOG - -using json = nlohmann::json; - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace ext -{ -namespace zpages -{ - -class TracezHttpServer : public opentelemetry::ext::zpages::zPagesHttpServer -{ -public: - /** - * Construct the server by initializing the endpoint for querying TraceZ aggregation data and - * files, along with taking ownership of the aggregator whose data is used to send data to the - * frontend - * @param aggregator is the TraceZ Data Aggregator, which calculates aggregation info - * @param host is the host where the TraceZ webpages will be displayed, default being localhost - * @param port is the port where the TraceZ webpages will be displayed, default being 30000 - */ - TracezHttpServer(std::unique_ptr &&aggregator, - const std::string &host = "localhost", - int port = 30000) - : opentelemetry::ext::zpages::zPagesHttpServer("/tracez", host, port), - data_aggregator_(std::move(aggregator)) - { - InitializeTracezEndpoint(*this); - }; - -private: - /** - * Set the HTTP server to use the "Serve" callback to send the appropriate data when queried - * @param server, which should be an instance of this object - */ - void InitializeTracezEndpoint(TracezHttpServer &server) { server[endpoint_] = Serve; } - - /** - * Updates the stored aggregation data (aggregations_) using the data aggregator - */ - void UpdateAggregations(); - - /** - * First updates the stored aggregations, then translates that data from a C++ map to - * a JSON object - * @returns JSON object of collected spans bucket counts by name - */ - json GetAggregations(); - - /** - * Using the stored aggregations, finds the span group with the right name and returns - * its running span data as a JSON, only grabbing the fields needed for the frontend - * @param name of the span group whose running data we want - * @returns JSON representing running span data with the passed in name - */ - json GetRunningSpansJSON(const std::string &name); - - /** - * Using the stored aggregations, finds the span group with the right name and returns - * its error span data as a JSON, only grabbing the fields needed for the frontend - * @param name of the span group whose running data we want - * @returns JSON representing eoor span data with the passed in name - */ - json GetErrorSpansJSON(const std::string &name); - - /** - * Using the stored aggregations, finds the span group with the right name and bucket index - * returning its latency span data as a JSON, only grabbing the fields needed for the frontend - * @param name of the span group whose latency data we want - * @param index of which latency bucket to grab from - * @returns JSON representing bucket span data with the passed in name and latency range - */ - json GetLatencySpansJSON(const std::string &name, int latency_range_index); - - /** - * Returns attributes, which have varied types, from a span data to convert into JSON - * @param sample current span data, whose attributes we want to extract - * @returns JSON representing attributes for a given threadsafe span data - */ - json GetAttributesJSON(const opentelemetry::ext::zpages::ThreadsafeSpanData &sample); - - /** - * Sets the response object with the TraceZ aggregation data based on the request endpoint - * @param req is the HTTP request, which we use to figure out the response to send - * @param resp is the HTTP response we want to send to the frontend, either webpage or TraceZ - * aggregation data - */ - HTTP_SERVER_NS::HttpRequestCallback Serve{ - [&](HTTP_SERVER_NS::HttpRequest const &req, HTTP_SERVER_NS::HttpResponse &resp) { - std::string query = GetQuery(req.uri); // tracez - - if (StartsWith(query, "get")) - { - resp.headers[HTTP_SERVER_NS::CONTENT_TYPE] = "application/json"; - query = GetAfterSlash(query); - if (StartsWith(query, "latency")) - { - auto queried_latency_name = GetAfterSlash(query); - auto queried_latency_index = std::stoi(GetBeforeSlash(queried_latency_name)); - auto queried_name = GetAfterSlash(queried_latency_name); - ReplaceHtmlChars(queried_name); - resp.body = GetLatencySpansJSON(queried_name, queried_latency_index).dump(); - } - else - { - auto queried_name = GetAfterSlash(query); - ReplaceHtmlChars(queried_name); - if (StartsWith(query, "aggregations")) - { - resp.body = GetAggregations().dump(); - } - else if (StartsWith(query, "running")) - { - resp.body = GetRunningSpansJSON(queried_name).dump(); - } - else if (StartsWith(query, "error")) - { - resp.body = GetErrorSpansJSON(queried_name).dump(); - } - else - { - resp.body = json::array().dump(); - } - } - } - else - { - if (StartsWith(query, "script.js")) - { - resp.headers[HTTP_SERVER_NS::CONTENT_TYPE] = "text/javascript"; - resp.body = tracez_script; - } - else if (StartsWith(query, "style.css")) - { - resp.headers[HTTP_SERVER_NS::CONTENT_TYPE] = "text/css"; - resp.body = tracez_style; - } - else if (query.empty() || query == "/tracez" || StartsWith(query, "index.html")) - { - resp.headers[HTTP_SERVER_NS::CONTENT_TYPE] = "text/html"; - resp.body = tracez_index; - } - else - { - resp.headers[HTTP_SERVER_NS::CONTENT_TYPE] = "text/plain"; - resp.body = "Invalid query: " + query; - } - } - - return 200; - }}; - - std::map aggregated_data_; - std::unique_ptr data_aggregator_; -}; - -} // namespace zpages -} // namespace ext -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/include/opentelemetry/ext/zpages/tracez_processor.h b/ext/include/opentelemetry/ext/zpages/tracez_processor.h deleted file mode 100644 index 081dd41117..0000000000 --- a/ext/include/opentelemetry/ext/zpages/tracez_processor.h +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include -#include -#include -#include -#include - -#include "opentelemetry/ext/zpages/threadsafe_span_data.h" -#include "opentelemetry/ext/zpages/tracez_shared_data.h" -#include "opentelemetry/sdk/trace/processor.h" -#include "opentelemetry/sdk/trace/recordable.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace ext -{ -namespace zpages -{ -/* - * The span processor passes and stores running and completed recordables (casted as span_data) - * to be used by the TraceZ Data Aggregator. - */ -class TracezSpanProcessor : public opentelemetry::sdk::trace::SpanProcessor -{ -public: - /* - * Initialize a span processor. - */ - explicit TracezSpanProcessor(std::shared_ptr shared_data) noexcept - : shared_data_(shared_data) - {} - - /* - * Create a span recordable, which is span_data - * @return a newly initialized recordable - */ - std::unique_ptr MakeRecordable() noexcept override - { - return std::unique_ptr(new ThreadsafeSpanData); - } - - /* - * OnStart is called when a span starts; the recordable is cast to span_data and added to - * running_spans. - * @param span a recordable for a span that was just started - */ - void OnStart(opentelemetry::sdk::trace::Recordable &span, - const opentelemetry::trace::SpanContext &parent_context) noexcept override; - - /* - * OnEnd is called when a span ends; that span_data is moved from running_spans to - * completed_spans - * @param span a recordable for a span that was ended - */ - void OnEnd(std::unique_ptr &&span) noexcept override; - - /* - * For now, does nothing. In the future, it - * may send all ended spans that have not yet been sent to the aggregator. - * @param timeout an optional timeout. Currently, timeout does nothing. - * @return return the status of the operation. - */ - bool ForceFlush(std::chrono::microseconds timeout OPENTELEMETRY_MAYBE_UNUSED = - std::chrono::microseconds::max()) noexcept override - { - return true; - } - - /* - * Shut down the processor and do any cleanup required, which is none. - * After the call to Shutdown, subsequent calls to OnStart, OnEnd, ForceFlush - * or Shutdown will return immediately without doing anything. - * @param timeout an optional timeout, the default timeout of 0 means that no - * timeout is applied. Currently, timeout does nothing. - * @return return the status of the operation. - */ - bool Shutdown(std::chrono::microseconds timeout OPENTELEMETRY_MAYBE_UNUSED = - std::chrono::microseconds::max()) noexcept override - { - return true; - } - -private: - std::shared_ptr shared_data_; -}; -} // namespace zpages -} // namespace ext -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/include/opentelemetry/ext/zpages/tracez_shared_data.h b/ext/include/opentelemetry/ext/zpages/tracez_shared_data.h deleted file mode 100644 index 571661550f..0000000000 --- a/ext/include/opentelemetry/ext/zpages/tracez_shared_data.h +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include -#include -#include -#include -#include - -#include "opentelemetry/ext/zpages/threadsafe_span_data.h" -#include "opentelemetry/sdk/trace/processor.h" -#include "opentelemetry/sdk/trace/recordable.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace ext -{ -namespace zpages -{ -/* - * The span processor passes and stores running and completed recordables (casted as span_data) - * to be used by the TraceZ Data Aggregator. - */ -class TracezSharedData -{ -public: - struct CollectedSpans - { - std::unordered_set running; - std::vector> completed; - }; - - /* - * Initialize a shared data storage. - */ - explicit TracezSharedData() noexcept {} - - /* - * Called when a span has been started. - */ - void OnStart(ThreadsafeSpanData *span) noexcept; - - /* - * Called when a span has ended. - */ - void OnEnd(std::unique_ptr &&span) noexcept; - - /* - * Returns a snapshot of all spans stored. This snapshot has a copy of the - * stored running_spans and gives ownership of completed spans to the caller. - * Stored completed_spans are cleared from the processor. Currently, - * copy-on-write is utilized where possible to minimize contention, but locks - * may be added in the future. - * @return snapshot of all currently running spans and newly completed spans - * (spans never sent while complete) at the time that the function is called - */ - CollectedSpans GetSpanSnapshot() noexcept; - -private: - mutable std::mutex mtx_; - CollectedSpans spans_; -}; -} // namespace zpages -} // namespace ext -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/include/opentelemetry/ext/zpages/zpages.h b/ext/include/opentelemetry/ext/zpages/zpages.h deleted file mode 100644 index f0242d92d7..0000000000 --- a/ext/include/opentelemetry/ext/zpages/zpages.h +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include - -#include "opentelemetry/ext/zpages/tracez_data_aggregator.h" -#include "opentelemetry/ext/zpages/tracez_http_server.h" -#include "opentelemetry/ext/zpages/tracez_processor.h" -#include "opentelemetry/ext/zpages/tracez_shared_data.h" - -#include "opentelemetry/nostd/shared_ptr.h" -#include "opentelemetry/sdk/trace/tracer_provider.h" -#include "opentelemetry/trace/provider.h" - -using opentelemetry::ext::zpages::TracezDataAggregator; -using opentelemetry::ext::zpages::TracezHttpServer; -using opentelemetry::ext::zpages::TracezSharedData; -using opentelemetry::ext::zpages::TracezSpanProcessor; -using std::chrono::microseconds; - -/** - * Wrapper for zPages that initializes all the components required for zPages, - * and starts the HTTP server in the constructor and ends it in the destructor. - * The constructor and destructor for this object is private to prevent - * creation other than by calling the static function Initialize(). This follows the - * meyers singleton pattern and only a single instance of the class is allowed. - */ -class ZPages -{ -public: - /** - * This function is called if the user wishes to include zPages in their - * application. It creates a static instance of this class and replaces the - * global TracerProvider with one that delegates spans to tracez. - */ - static void Initialize() { Instance().ReplaceGlobalProvider(); } - - /** - * Returns the singletone instnace of ZPages, useful for attaching z-pages span processors to - * non-global providers. - * - * Note: This will instantiate the Tracez instance and webserver if it hasn't already been - * instantiated. - */ - static ZPages &Instance() - { - static ZPages instance; - return instance; - } - - /** Replaces the global tracer provider with an instance that exports to tracez. */ - void ReplaceGlobalProvider() - { - // GCC 4.8 can't infer the type coercion. - std::unique_ptr processor( - MakeSpanProcessor().release()); - auto tracez_provider_ = opentelemetry::nostd::shared_ptr( - new opentelemetry::sdk::trace::TracerProvider(std::move(processor))); - opentelemetry::trace::Provider::SetTracerProvider(tracez_provider_); - } - - /** Retruns a new span processor that will output to z-pages. */ - std::unique_ptr MakeSpanProcessor() - { - return std::unique_ptr(new TracezSpanProcessor(tracez_shared_)); - } - -private: - /** - * Constructor is responsible for initializing the tracer, tracez processor, - * tracez data aggregator and the tracez server. The server is also started in - * constructor. - */ - ZPages() - { - // Construct shared data nd start tracez webserver. - tracez_shared_ = std::make_shared(); - auto tracez_aggregator = - std::unique_ptr(new TracezDataAggregator(tracez_shared_)); - tracez_server_ = - std::unique_ptr(new TracezHttpServer(std::move(tracez_aggregator))); - tracez_server_->start(); - } - - ~ZPages() - { - // shut down the server when the object goes out of scope(at the end of the - // program) - tracez_server_->stop(); - } - std::shared_ptr tracez_shared_; - std::unique_ptr tracez_server_; -}; diff --git a/ext/include/opentelemetry/ext/zpages/zpages_http_server.h b/ext/include/opentelemetry/ext/zpages/zpages_http_server.h deleted file mode 100644 index abf6c1a5b4..0000000000 --- a/ext/include/opentelemetry/ext/zpages/zpages_http_server.h +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include -#include -#include -#include -#include - -#include "opentelemetry/ext/http/server/http_server.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace ext -{ -namespace zpages -{ - -class zPagesHttpServer : public HTTP_SERVER_NS::HttpServer -{ -protected: - /** - * Construct the server by initializing the endpoint for serving static files, which show up on - * the web if the user is on the given host:port. Static files can be seen relative to the folder - * where the executable was ran. - * @param host is the host where the TraceZ webpages will be displayed - * @param port is the port where the TraceZ webpages will be displayed - * @param endpoint is where this specific zPage will server files - */ - zPagesHttpServer(const std::string &endpoint, - const std::string &host = "127.0.0.1", - int port = 52620) - : HttpServer(), endpoint_(endpoint) - { - std::ostringstream os; - os << host << ":" << port; - setServerName(os.str()); - addListeningPort(port); - }; - - /** - * Helper function that returns query information by isolating it from the base endpoint - * @param uri is the full query - */ - std::string GetQuery(const std::string &uri) - { - if (endpoint_.length() + 1 > uri.length()) - return uri; - return uri.substr(endpoint_.length() + 1); - } - - /** - * Helper that returns whether a str starts with pre - * @param str is the string we're checking - * @param pre is the prefix we're checking against - */ - bool StartsWith(const std::string &str, const std::string &pre) { return str.rfind(pre, 0) == 0; } - - /** - * Helper that returns the remaining string after the leftmost backslash - * @param str is the string we're extracting from - */ - std::string GetAfterSlash(const std::string &str) - { - std::size_t backslash = str.find("/"); - if (backslash == std::string::npos || backslash == str.length()) - return ""; - return str.substr(backslash + 1); - } - - /** - * Helper that returns the remaining string after the leftmost backslash - * @param str is the string we're extracting from - */ - std::string GetBeforeSlash(const std::string &str) - { - std::size_t backslash = str.find("/"); - if (backslash == std::string::npos || backslash == str.length()) - return str; - return str.substr(0, backslash); - } - - /** - * Helper that replaces all occurrences a string within a string - * @param str string to modify - * @param search substring to remove from str - * @param replacement string to replace search with whenever search is found - */ - void ReplaceAll(std::string &str, const std::string &search, const std::string &replacement) - { - size_t idx = str.find(search, 0); - while (idx != std::string::npos) - { - str.replace(idx, search.length(), replacement); - idx = str.find(search, idx); - } - } - - /** - * Helper that replaces all special HTML/address base encoded characters - * into what they're originally supposed to be - * @param str string to conduct replacements for - */ - void ReplaceHtmlChars(std::string &str) - { - for (const auto &replace_pair : replace_map_) - { - ReplaceAll(str, replace_pair.first, replace_pair.second); - } - } - - const std::string endpoint_; - const std::unordered_map replace_map_ = {{"%20", " "}}; -}; - -} // namespace zpages -} // namespace ext -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/src/CMakeLists.txt b/ext/src/CMakeLists.txt index bc1f614eb9..65aaa307c0 100644 --- a/ext/src/CMakeLists.txt +++ b/ext/src/CMakeLists.txt @@ -1,10 +1,6 @@ # Copyright The OpenTelemetry Authors # SPDX-License-Identifier: Apache-2.0 -if(WITH_ZPAGES) - add_subdirectory(zpages) -endif() - if(WITH_HTTP_CLIENT_CURL) add_subdirectory(http/client/curl) endif() diff --git a/ext/src/http/client/curl/http_client_curl.cc b/ext/src/http/client/curl/http_client_curl.cc index 287059a1c6..872519fb11 100644 --- a/ext/src/http/client/curl/http_client_curl.cc +++ b/ext/src/http/client/curl/http_client_curl.cc @@ -48,10 +48,7 @@ void Session::SendRequest( reuse_connection = session_id_ % http_client_.GetMaxSessionsPerConnection() != 0; } - curl_operation_.reset(new HttpOperation(http_request_->method_, url, -#ifdef ENABLE_HTTP_SSL_PREVIEW - http_request_->ssl_options_, -#endif /* ENABLE_HTTP_SSL_PREVIEW */ + curl_operation_.reset(new HttpOperation(http_request_->method_, url, http_request_->ssl_options_, callback_ptr, http_request_->headers_, http_request_->body_, false, http_request_->timeout_ms_, reuse_connection)); diff --git a/ext/src/http/client/curl/http_operation_curl.cc b/ext/src/http/client/curl/http_operation_curl.cc index 22b2565e6f..f24d3fa53b 100644 --- a/ext/src/http/client/curl/http_operation_curl.cc +++ b/ext/src/http/client/curl/http_operation_curl.cc @@ -235,9 +235,7 @@ void HttpOperation::DispatchEvent(opentelemetry::ext::http::client::SessionState HttpOperation::HttpOperation(opentelemetry::ext::http::client::Method method, std::string url, -#ifdef ENABLE_HTTP_SSL_PREVIEW const HttpSslOptions &ssl_options, -#endif /* ENABLE_HTTP_SSL_PREVIEW */ opentelemetry::ext::http::client::EventHandler *event_handle, // Default empty headers and empty request body const opentelemetry::ext::http::client::Headers &request_headers, @@ -258,9 +256,7 @@ HttpOperation::HttpOperation(opentelemetry::ext::http::client::Method method, event_handle_(event_handle), method_(method), url_(url), -#ifdef ENABLE_HTTP_SSL_PREVIEW ssl_options_(ssl_options), -#endif /* ENABLE_HTTP_SSL_PREVIEW */ // Local vars request_headers_(request_headers), request_body_(request_body), @@ -438,10 +434,9 @@ void HttpOperation::Cleanup() # define HAVE_TLS_VERSION #endif -#ifdef ENABLE_HTTP_SSL_TLS_PREVIEW static long parse_min_ssl_version(std::string version) { -# ifdef HAVE_TLS_VERSION +#ifdef HAVE_TLS_VERSION if (version == "1.0") { return CURL_SSLVERSION_TLSv1_0; @@ -461,14 +456,14 @@ static long parse_min_ssl_version(std::string version) { return CURL_SSLVERSION_TLSv1_3; } -# endif +#endif return 0; } static long parse_max_ssl_version(std::string version) { -# ifdef HAVE_TLS_VERSION +#ifdef HAVE_TLS_VERSION if (version == "1.0") { return CURL_SSLVERSION_MAX_TLSv1_0; @@ -488,11 +483,10 @@ static long parse_max_ssl_version(std::string version) { return CURL_SSLVERSION_MAX_TLSv1_3; } -# endif +#endif return 0; } -#endif /* ENABLE_HTTP_SSL_TLS_PREVIEW */ const char *HttpOperation::GetCurlErrorMessage(CURLcode code) { @@ -601,7 +595,6 @@ CURLcode HttpOperation::Setup() return rc; } -#ifdef ENABLE_HTTP_SSL_PREVIEW if (ssl_options_.use_ssl) { /* 1 - CA CERT */ @@ -618,7 +611,7 @@ CURLcode HttpOperation::Setup() } else if (!ssl_options_.ssl_ca_cert_string.empty()) { -# if LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(7, 77, 0) +#if LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(7, 77, 0) const char *data = ssl_options_.ssl_ca_cert_string.c_str(); size_t data_len = ssl_options_.ssl_ca_cert_string.length(); @@ -632,11 +625,11 @@ CURLcode HttpOperation::Setup() { return rc; } -# else +#else // CURL 7.77.0 required for CURLOPT_CAINFO_BLOB. OTEL_INTERNAL_LOG_ERROR("CURL 7.77.0 required for CA CERT STRING"); return CURLE_UNKNOWN_OPTION; -# endif +#endif } /* 2 - CLIENT KEY */ @@ -659,7 +652,7 @@ CURLcode HttpOperation::Setup() } else if (!ssl_options_.ssl_client_key_string.empty()) { -# if LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(7, 71, 0) +#if LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(7, 71, 0) const char *data = ssl_options_.ssl_client_key_string.c_str(); size_t data_len = ssl_options_.ssl_client_key_string.length(); @@ -679,11 +672,11 @@ CURLcode HttpOperation::Setup() { return rc; } -# else +#else // CURL 7.71.0 required for CURLOPT_SSLKEY_BLOB. OTEL_INTERNAL_LOG_ERROR("CURL 7.71.0 required for CLIENT KEY STRING"); return CURLE_UNKNOWN_OPTION; -# endif +#endif } /* 3 - CLIENT CERT */ @@ -706,7 +699,7 @@ CURLcode HttpOperation::Setup() } else if (!ssl_options_.ssl_client_cert_string.empty()) { -# if LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(7, 71, 0) +#if LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(7, 71, 0) const char *data = ssl_options_.ssl_client_cert_string.c_str(); size_t data_len = ssl_options_.ssl_client_cert_string.length(); @@ -726,21 +719,20 @@ CURLcode HttpOperation::Setup() { return rc; } -# else +#else // CURL 7.71.0 required for CURLOPT_SSLCERT_BLOB. OTEL_INTERNAL_LOG_ERROR("CURL 7.71.0 required for CLIENT CERT STRING"); return CURLE_UNKNOWN_OPTION; -# endif +#endif } -# ifdef ENABLE_HTTP_SSL_TLS_PREVIEW /* 4 - TLS */ long min_ssl_version = 0; if (!ssl_options_.ssl_min_tls.empty()) { -# ifdef HAVE_TLS_VERSION +#ifdef HAVE_TLS_VERSION min_ssl_version = parse_min_ssl_version(ssl_options_.ssl_min_tls); if (min_ssl_version == 0) @@ -748,17 +740,17 @@ CURLcode HttpOperation::Setup() OTEL_INTERNAL_LOG_ERROR("Unknown min TLS version <" << ssl_options_.ssl_min_tls << ">"); return CURLE_UNKNOWN_OPTION; } -# else +#else OTEL_INTERNAL_LOG_ERROR("CURL 7.54.0 required for MIN TLS"); return CURLE_UNKNOWN_OPTION; -# endif +#endif } long max_ssl_version = 0; if (!ssl_options_.ssl_max_tls.empty()) { -# ifdef HAVE_TLS_VERSION +#ifdef HAVE_TLS_VERSION max_ssl_version = parse_max_ssl_version(ssl_options_.ssl_max_tls); if (max_ssl_version == 0) @@ -766,10 +758,10 @@ CURLcode HttpOperation::Setup() OTEL_INTERNAL_LOG_ERROR("Unknown max TLS version <" << ssl_options_.ssl_max_tls << ">"); return CURLE_UNKNOWN_OPTION; } -# else +#else OTEL_INTERNAL_LOG_ERROR("CURL 7.54.0 required for MAX TLS"); return CURLE_UNKNOWN_OPTION; -# endif +#endif } long version_range = min_ssl_version | max_ssl_version; @@ -798,23 +790,22 @@ CURLcode HttpOperation::Setup() if (!ssl_options_.ssl_cipher_suite.empty()) { -# if LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(7, 61, 0) +#if LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(7, 61, 0) /* TLS 1.3 */ const char *cipher_list = ssl_options_.ssl_cipher_suite.c_str(); rc = SetCurlStrOption(CURLOPT_TLS13_CIPHERS, cipher_list); -# else +#else // CURL 7.61.0 required for CURLOPT_TLS13_CIPHERS. OTEL_INTERNAL_LOG_ERROR("CURL 7.61.0 required for CIPHER SUITE"); return CURLE_UNKNOWN_OPTION; -# endif +#endif if (rc != CURLE_OK) { return rc; } } -# endif /* ENABLE_HTTP_SSL_TLS_PREVIEW */ if (ssl_options_.ssl_insecure_skip_verify) { @@ -860,7 +851,6 @@ CURLcode HttpOperation::Setup() } } else -#endif /* ENABLE_HTTP_SSL_PREVIEW */ { rc = SetCurlLongOption(CURLOPT_SSL_VERIFYPEER, 0L); if (rc != CURLE_OK) diff --git a/ext/src/zpages/BUILD b/ext/src/zpages/BUILD deleted file mode 100644 index ce23147df5..0000000000 --- a/ext/src/zpages/BUILD +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -package(default_visibility = ["//visibility:public"]) - -cc_library( - name = "zpages", - srcs = glob(["**/*.cc"]), - hdrs = glob(["**/*.h"]), - include_prefix = "ext/zpages", - deps = [ - "//api", - "//ext:headers", - "//sdk:headers", - "@github_nlohmann_json//:json", - ], -) diff --git a/ext/src/zpages/CMakeLists.txt b/ext/src/zpages/CMakeLists.txt deleted file mode 100644 index 8ff225112b..0000000000 --- a/ext/src/zpages/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -add_library( - opentelemetry_zpages - tracez_processor.cc - tracez_shared_data.cc - tracez_data_aggregator.cc - ../../include/opentelemetry/ext/zpages/tracez_shared_data.h - ../../include/opentelemetry/ext/zpages/tracez_processor.h - ../../include/opentelemetry/ext/zpages/tracez_data_aggregator.h - ../../include/opentelemetry/ext/zpages/tracez_http_server.h) - -set_target_properties(opentelemetry_zpages PROPERTIES EXPORT_NAME zpages) -set_target_version(opentelemetry_zpages) - -target_link_libraries(opentelemetry_zpages PUBLIC opentelemetry_ext - opentelemetry_trace) - -if(OPENTELEMETRY_INSTALL) - install( - TARGETS opentelemetry_zpages - EXPORT "${PROJECT_NAME}-target" - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) -endif() diff --git a/ext/src/zpages/README.md b/ext/src/zpages/README.md deleted file mode 100644 index f182fd43f3..0000000000 --- a/ext/src/zpages/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# zPages - -## Overview - -zPages are a quick and light way to view tracing and metrics information on -standard OpenTelemetry C++ instrumented applications. It requires no external -dependencies or backend setup. See more information in the OTel zPages -experimental -[spec](https://github.com/open-telemetry/opentelemetry-specification/blob/5b86d4b6c42e6d1e47d9155ac1e2e27f0f0b7769/experimental/trace/zpages.md). -OTel C++ currently only offers Tracez; future zPages to potentially add include -TraceConfigz, RPCz, and Statsz. Events and links need to be added to Tracez. - -## Usage - -> TODO: Add CMake instructions - -1: Add the following 2 lines of code - -* `#include opentelemetry/ext/zpages/zpages.h // include zPages` -* `zpages::Initialize; // start up zPages in your app, before any tracing/span - code` - -2: Build and run your application normally - -For example, you can do this for the zPages example while at the root -`opentelemetry-cpp` directory with: - -```sh -bazel build //examples/zpages:zpages_example -bazel-bin/examples/zpages/zpages_example -``` - -If you look at the [zPages example's source -code](https://github.com/open-telemetry/opentelemetry-cpp/blob/main/examples/zpages/zpages_example.cc), -it demonstrates adding zPages, manual application instrumentation (which sends -data to zPages for viewing), and simulated use cases for zPages. - -3: View zPages at `http://localhost:3000/tracez` - -## More Information - -* OTel zPages experimental - [spec](https://github.com/open-telemetry/opentelemetry-specification/blob/5b86d4b6c42e6d1e47d9155ac1e2e27f0f0b7769/experimental/trace/zpages.md) -* [zPages General Direction Spec - (OTEP)](https://github.com/open-telemetry/oteps/blob/main/text/0110-z-pages.md) -* OTel C++ Design Docs - * [Tracez Span - Processor](https://docs.google.com/document/d/1kO4iZARYyr-EGBlY2VNM3ELU3iw6ZrC58Omup_YT-fU/edit#) - * [Tracez Data - Aggregator](https://docs.google.com/document/d/1ziKFgvhXFfRXZjOlAHQRR-TzcNcTXzg1p2I9oPCEIoU/edit?ts=5ef0d177#heading=h.5irk4csrpu0y) - * [Tracez Http - Server](https://docs.google.com/document/d/1U1V8QZ5LtGl4Mich-aJ6KZGLHrMIE8pWyspmzvnIefI/edit#) - * includes reference pictures of the zPages/Tracez UI diff --git a/ext/src/zpages/tracez_data_aggregator.cc b/ext/src/zpages/tracez_data_aggregator.cc deleted file mode 100644 index 993fc182ce..0000000000 --- a/ext/src/zpages/tracez_data_aggregator.cc +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#include "opentelemetry/ext/zpages/tracez_data_aggregator.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace ext -{ -namespace zpages -{ - -TracezDataAggregator::TracezDataAggregator(std::shared_ptr shared_data, - milliseconds update_interval) -{ - tracez_shared_data_ = shared_data; - - // Start a thread that calls AggregateSpans periodically or till notified. - execute_.store(true, std::memory_order_release); - aggregate_spans_thread_ = std::thread([this, update_interval]() { - while (execute_.load(std::memory_order_acquire)) - { - std::unique_lock lock(mtx_); - AggregateSpans(); - cv_.wait_for(lock, update_interval); - } - }); -} - -TracezDataAggregator::~TracezDataAggregator() -{ - // Notify and join the thread so object can be destroyed without wait for wake - if (execute_.load(std::memory_order_acquire)) - { - execute_.store(false, std::memory_order_release); - cv_.notify_one(); - aggregate_spans_thread_.join(); - } -} - -std::map TracezDataAggregator::GetAggregatedTracezData() -{ - std::unique_lock lock(mtx_); - return aggregated_tracez_data_; -} - -LatencyBoundary TracezDataAggregator::FindLatencyBoundary( - std::unique_ptr &span_data) -{ - const auto &span_data_duration = span_data->GetDuration(); - for (unsigned int boundary = 0; boundary < kLatencyBoundaries.size() - 1; boundary++) - { - if (span_data_duration < kLatencyBoundaries[boundary + 1]) - return (LatencyBoundary)boundary; - } - return LatencyBoundary::k100SecondToMax; -} - -void TracezDataAggregator::InsertIntoSampleSpanList(std::list &sample_spans, - ThreadsafeSpanData &span_data) -{ - /** - * Check to see if the sample span list size exceeds the set limit, if it does - * free up memory and remove the earliest inserted sample before appending - */ - if (sample_spans.size() == kMaxNumberOfSampleSpans) - { - sample_spans.pop_front(); - } - sample_spans.push_back(ThreadsafeSpanData(span_data)); -} - -void TracezDataAggregator::ClearRunningSpanData() -{ - auto it = aggregated_tracez_data_.begin(); - while (it != aggregated_tracez_data_.end()) - { - it->second.running_span_count = 0; - it->second.sample_running_spans.clear(); - - // Check if any data exists in the struct, if not delete entry - bool is_completed_span_count_zero = true; - for (const auto &completed_span_count : it->second.completed_span_count_per_latency_bucket) - { - if (completed_span_count > 0) - is_completed_span_count_zero = false; - } - - if (it->second.error_span_count == 0 && is_completed_span_count_zero) - { - it = aggregated_tracez_data_.erase(it); - } - else - { - ++it; - } - } -} - -void TracezDataAggregator::AggregateStatusOKSpan(std::unique_ptr &ok_span) -{ - // Find and update boundary of aggregated data that span belongs - auto boundary_name = FindLatencyBoundary(ok_span); - - // Get the data for name in aggrgation and update count and sample spans - auto &tracez_data = aggregated_tracez_data_.at(ok_span->GetName().data()); - InsertIntoSampleSpanList(tracez_data.sample_latency_spans[boundary_name], *ok_span.get()); - tracez_data.completed_span_count_per_latency_bucket[boundary_name]++; -} - -void TracezDataAggregator::AggregateStatusErrorSpan(std::unique_ptr &error_span) -{ - // Get data for name in aggregation and update count and sample spans - auto &tracez_data = aggregated_tracez_data_.at(error_span->GetName().data()); - InsertIntoSampleSpanList(tracez_data.sample_error_spans, *error_span.get()); - tracez_data.error_span_count++; -} - -void TracezDataAggregator::AggregateCompletedSpans( - std::vector> &completed_spans) -{ - for (auto &completed_span : completed_spans) - { - std::string span_name = completed_span->GetName().data(); - - if (aggregated_tracez_data_.find(span_name) == aggregated_tracez_data_.end()) - { - aggregated_tracez_data_[span_name] = TracezData(); - } - - if (completed_span->GetStatus() == trace::StatusCode::kOk || - completed_span->GetStatus() == trace::StatusCode::kUnset) - AggregateStatusOKSpan(completed_span); - else - AggregateStatusErrorSpan(completed_span); - } -} - -void TracezDataAggregator::AggregateRunningSpans( - std::unordered_set &running_spans) -{ - for (auto &running_span : running_spans) - { - std::string span_name = running_span->GetName().data(); - - if (aggregated_tracez_data_.find(span_name) == aggregated_tracez_data_.end()) - { - aggregated_tracez_data_[span_name] = TracezData(); - } - - auto &tracez_data = aggregated_tracez_data_[span_name]; - InsertIntoSampleSpanList(aggregated_tracez_data_[span_name].sample_running_spans, - *running_span); - tracez_data.running_span_count++; - } -} - -void TracezDataAggregator::AggregateSpans() -{ - auto span_snapshot = tracez_shared_data_->GetSpanSnapshot(); - /** - * TODO: At this time in the project, there is no way of uniquely identifying - * a span(their id's are not being set yet). - * If in the future this is added then clearing of running spans will not bee - * required. - * For now this step of clearing and recalculating running span data is - * required because it is unknown which spans have moved from running to - * completed since the previous call. Additionally, the span name can change - * for spans while they are running. - * - * A better approach for identifying moved spans would have been to map - * span id to span name, find these span names in the aggregated data and then - * delete only this information for running span data as opposed to clearing - * all running span data. However this cannot be done at this time because, - * unique identifiers to span data have not been added yet. - * - * A few things to note: - * i) Duplicate running spans may be received from the span processor in one - * multiple successive calls to this function. - * ii) Only the newly completed spans are received by this function. - * Completed spans will not be seen more than once - **/ - ClearRunningSpanData(); - AggregateCompletedSpans(span_snapshot.completed); - AggregateRunningSpans(span_snapshot.running); -} - -} // namespace zpages -} // namespace ext -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/src/zpages/tracez_http_server.cc b/ext/src/zpages/tracez_http_server.cc deleted file mode 100644 index a5d0072787..0000000000 --- a/ext/src/zpages/tracez_http_server.cc +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#include "opentelemetry/ext/zpages/tracez_http_server.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace ext -{ -namespace zpages -{ -namespace nostd = opentelemetry::nostd; - -json TracezHttpServer::GetAggregations() -{ - aggregated_data_ = data_aggregator_->GetAggregatedTracezData(); - auto counts_json = json::array(); - - for (const auto &aggregation_group : aggregated_data_) - { - const auto &buckets = aggregation_group.second; - const auto &complete_ok_counts = buckets.completed_span_count_per_latency_bucket; - - auto latency_counts = json::array(); - for (unsigned int boundary = 0; boundary < kLatencyBoundaries.size(); boundary++) - { - latency_counts.push_back(complete_ok_counts[boundary]); - } - - counts_json.push_back({{"name", aggregation_group.first}, - {"error", buckets.error_span_count}, - {"running", buckets.running_span_count}, - {"latency", latency_counts}}); - } - return counts_json; -} - -json TracezHttpServer::GetRunningSpansJSON(const std::string &name) -{ - auto running_json = json::array(); - - auto grouping = aggregated_data_.find(name); - - if (grouping != aggregated_data_.end()) - { - const auto &running_samples = grouping->second.sample_running_spans; - for (const auto &sample : running_samples) - { - running_json.push_back({ - {"spanid", std::string(reinterpret_cast(sample.GetSpanId().Id().data()))}, - {"parentid", - std::string(reinterpret_cast(sample.GetParentSpanId().Id().data()))}, - {"traceid", std::string(reinterpret_cast(sample.GetTraceId().Id().data()))}, - {"start", sample.GetStartTime().time_since_epoch().count()}, - {"attributes", GetAttributesJSON(sample)}, - }); - } - } - return running_json; -} - -json TracezHttpServer::GetErrorSpansJSON(const std::string &name) -{ - auto error_json = json::array(); - - auto grouping = aggregated_data_.find(name); - - if (grouping != aggregated_data_.end()) - { - const auto &error_samples = grouping->second.sample_error_spans; - for (const auto &sample : error_samples) - { - error_json.push_back({ - {"spanid", std::string(reinterpret_cast(sample.GetSpanId().Id().data()))}, - {"parentid", - std::string(reinterpret_cast(sample.GetParentSpanId().Id().data()))}, - {"traceid", std::string(reinterpret_cast(sample.GetTraceId().Id().data()))}, - {"start", sample.GetStartTime().time_since_epoch().count()}, - {"status", (unsigned short)sample.GetStatus()}, - {"attributes", GetAttributesJSON(sample)}, - }); - } - } - return error_json; -} - -json TracezHttpServer::GetLatencySpansJSON(const std::string &name, int latency_range_index) -{ - auto latency_json = json::array(); - - auto grouping = aggregated_data_.find(name); - - if (grouping != aggregated_data_.end()) - { - const auto &latency_samples = grouping->second.sample_latency_spans[latency_range_index]; - for (const auto &sample : latency_samples) - { - latency_json.push_back({ - {"spanid", std::string(reinterpret_cast(sample.GetSpanId().Id().data()))}, - {"parentid", - std::string(reinterpret_cast(sample.GetParentSpanId().Id().data()))}, - {"traceid", std::string(reinterpret_cast(sample.GetTraceId().Id().data()))}, - {"start", sample.GetStartTime().time_since_epoch().count()}, - {"duration", sample.GetDuration().count()}, - {"attributes", GetAttributesJSON(sample)}, - }); - } - } - return latency_json; -} - -json TracezHttpServer::GetAttributesJSON( - const opentelemetry::ext::zpages::ThreadsafeSpanData &sample) -{ - auto attributes_json = json::object(); - for (const auto &sample_attribute : sample.GetAttributes()) - { - auto &key = sample_attribute.first; - auto &val = sample_attribute.second; // OwnedAttributeValue - - /* Convert variant types to into their nonvariant form. This is done this way because - the frontend and JSON doesn't care about type, and variant's get function only allows - const integers or literals */ - - switch (val.index()) - { - case 0: - attributes_json[key] = nostd::get<0>(val); - break; - case 1: - attributes_json[key] = nostd::get<1>(val); - break; - case 2: - attributes_json[key] = nostd::get<2>(val); - break; - case 3: - attributes_json[key] = nostd::get<3>(val); - break; - case 4: - attributes_json[key] = nostd::get<4>(val); - break; - case 5: - attributes_json[key] = nostd::get<5>(val); - break; - case 6: - attributes_json[key] = nostd::get<6>(val); - break; - case 7: - attributes_json[key] = nostd::get<7>(val); - break; - case 8: - attributes_json[key] = nostd::get<8>(val); - break; - case 9: - attributes_json[key] = nostd::get<9>(val); - break; - } - } - return attributes_json; -} - -} // namespace zpages -} // namespace ext -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/src/zpages/tracez_processor.cc b/ext/src/zpages/tracez_processor.cc deleted file mode 100644 index e7d68350d7..0000000000 --- a/ext/src/zpages/tracez_processor.cc +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#include "opentelemetry/ext/zpages/tracez_processor.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace ext -{ -namespace zpages -{ -namespace trace_sdk = opentelemetry::sdk::trace; - -void TracezSpanProcessor::OnStart(trace_sdk::Recordable &span, - const opentelemetry::trace::SpanContext & - /* parent_context */) noexcept -{ - shared_data_->OnStart(static_cast(&span)); -} - -void TracezSpanProcessor::OnEnd(std::unique_ptr &&span) noexcept -{ - shared_data_->OnEnd( - std::unique_ptr(static_cast(span.release()))); -} - -} // namespace zpages -} // namespace ext -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/src/zpages/tracez_shared_data.cc b/ext/src/zpages/tracez_shared_data.cc deleted file mode 100644 index 4f4e4f5e91..0000000000 --- a/ext/src/zpages/tracez_shared_data.cc +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#include "opentelemetry/ext/zpages/tracez_shared_data.h" - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace ext -{ -namespace zpages -{ - -void TracezSharedData::OnStart(ThreadsafeSpanData *span) noexcept -{ - std::lock_guard lock(mtx_); - spans_.running.insert(span); -} - -void TracezSharedData::OnEnd(std::unique_ptr &&span) noexcept -{ - std::lock_guard lock(mtx_); - auto span_it = spans_.running.find(span.get()); - if (span_it != spans_.running.end()) - { - spans_.running.erase(span_it); - spans_.completed.push_back(std::unique_ptr(span.release())); - } -} - -TracezSharedData::CollectedSpans TracezSharedData::GetSpanSnapshot() noexcept -{ - CollectedSpans snapshot; - std::lock_guard lock(mtx_); - snapshot.running = spans_.running; - snapshot.completed = std::move(spans_.completed); - spans_.completed.clear(); - return snapshot; -} - -} // namespace zpages -} // namespace ext -OPENTELEMETRY_END_NAMESPACE diff --git a/ext/test/CMakeLists.txt b/ext/test/CMakeLists.txt index 2d2cc0d9fa..cc3d4cd1e1 100644 --- a/ext/test/CMakeLists.txt +++ b/ext/test/CMakeLists.txt @@ -1,9 +1,6 @@ # Copyright The OpenTelemetry Authors # SPDX-License-Identifier: Apache-2.0 -if(WITH_ZPAGES) - add_subdirectory(zpages) -endif() add_subdirectory(http) if(BUILD_W3CTRACECONTEXT_TEST) add_subdirectory(w3c_tracecontext_test) diff --git a/ext/test/http/curl_http_test.cc b/ext/test/http/curl_http_test.cc index 7c66d98b63..c51da784df 100644 --- a/ext/test/http/curl_http_test.cc +++ b/ext/test/http/curl_http_test.cc @@ -290,9 +290,7 @@ TEST_F(BasicCurlHttpTests, RequestTimeout) TEST_F(BasicCurlHttpTests, CurlHttpOperations) { -#ifdef ENABLE_HTTP_SSL_PREVIEW http_client::HttpSslOptions no_ssl; -#endif /* ENABLE_HTTP_SSL_PREVIEW */ GetEventHandler *handler = new GetEventHandler(); @@ -302,25 +300,16 @@ TEST_F(BasicCurlHttpTests, CurlHttpOperations) http_client::Headers headers = { {"name1", "value1_1"}, {"name1", "value1_2"}, {"name2", "value3"}, {"name3", "value3"}}; - curl::HttpOperation http_operations1(http_client::Method::Head, "/get", -#ifdef ENABLE_HTTP_SSL_PREVIEW - no_ssl, -#endif /* ENABLE_HTTP_SSL_PREVIEW */ - handler, headers, body, true); + curl::HttpOperation http_operations1(http_client::Method::Head, "/get", no_ssl, handler, headers, + body, true); http_operations1.Send(); - curl::HttpOperation http_operations2(http_client::Method::Get, "/get", -#ifdef ENABLE_HTTP_SSL_PREVIEW - no_ssl, -#endif /* ENABLE_HTTP_SSL_PREVIEW */ - handler, headers, body, true); + curl::HttpOperation http_operations2(http_client::Method::Get, "/get", no_ssl, handler, headers, + body, true); http_operations2.Send(); - curl::HttpOperation http_operations3(http_client::Method::Get, "/get", -#ifdef ENABLE_HTTP_SSL_PREVIEW - no_ssl, -#endif /* ENABLE_HTTP_SSL_PREVIEW */ - handler, headers, body, false); + curl::HttpOperation http_operations3(http_client::Method::Get, "/get", no_ssl, handler, headers, + body, false); http_operations3.Send(); delete handler; } diff --git a/ext/test/zpages/BUILD b/ext/test/zpages/BUILD deleted file mode 100644 index e3371b8e93..0000000000 --- a/ext/test/zpages/BUILD +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -cc_test( - name = "threadsafe_span_data_tests", - srcs = [ - "threadsafe_span_data_test.cc", - ], - tags = ["test"], - deps = [ - "//ext/src/zpages", - "//sdk/src/trace", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "tracez_data_aggregator_tests", - srcs = [ - "tracez_data_aggregator_test.cc", - ], - tags = ["test"], - deps = [ - "//ext/src/zpages", - "//sdk/src/trace", - "@com_google_googletest//:gtest_main", - ], -) - -cc_test( - name = "tracez_processor_tests", - srcs = [ - "tracez_processor_test.cc", - ], - tags = ["test"], - deps = [ - "//ext/src/zpages", - "//sdk/src/trace", - "@com_google_googletest//:gtest_main", - ], -) diff --git a/ext/test/zpages/CMakeLists.txt b/ext/test/zpages/CMakeLists.txt deleted file mode 100644 index f3ecf5cdf2..0000000000 --- a/ext/test/zpages/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright The OpenTelemetry Authors -# SPDX-License-Identifier: Apache-2.0 - -foreach(testname tracez_processor_test tracez_data_aggregator_test - threadsafe_span_data_test) - add_executable(${testname} "${testname}.cc") - target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT} opentelemetry_zpages) - - gtest_add_tests( - TARGET ${testname} - TEST_PREFIX ext. - TEST_LIST ${testname}) -endforeach() diff --git a/ext/test/zpages/threadsafe_span_data_test.cc b/ext/test/zpages/threadsafe_span_data_test.cc deleted file mode 100644 index cee29672ed..0000000000 --- a/ext/test/zpages/threadsafe_span_data_test.cc +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#include "opentelemetry/ext/zpages/threadsafe_span_data.h" -#include "opentelemetry/nostd/variant.h" -#include "opentelemetry/trace/span_id.h" -#include "opentelemetry/trace/trace_id.h" - -#include -#include - -using opentelemetry::ext::zpages::ThreadsafeSpanData; -using opentelemetry::sdk::common::AttributeConverter; -using opentelemetry::sdk::common::OwnedAttributeValue; - -namespace trace_api = opentelemetry::trace; - -TEST(ThreadsafeSpanData, DefaultValues) -{ - trace_api::SpanContext empty_span_context{false, false}; - trace_api::SpanId zero_span_id; - ThreadsafeSpanData data; - - ASSERT_EQ(data.GetTraceId(), empty_span_context.trace_id()); - ASSERT_EQ(data.GetSpanId(), empty_span_context.span_id()); - ASSERT_EQ(data.GetSpanContext(), empty_span_context); - ASSERT_EQ(data.GetParentSpanId(), zero_span_id); - ASSERT_EQ(data.GetName(), ""); - ASSERT_EQ(data.GetStatus(), trace_api::StatusCode::kUnset); - ASSERT_EQ(data.GetDescription(), ""); - ASSERT_EQ(data.GetStartTime().time_since_epoch(), std::chrono::nanoseconds(0)); - ASSERT_EQ(data.GetDuration(), std::chrono::nanoseconds(0)); - ASSERT_EQ(data.GetAttributes().size(), 0); -} - -TEST(ThreadsafeSpanData, Set) -{ - constexpr uint8_t trace_id_buf[] = {1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8}; - constexpr uint8_t span_id_buf[] = {1, 2, 3, 4, 5, 6, 7, 8}; - constexpr uint8_t parent_span_id_buf[] = {8, 7, 6, 5, 4, 3, 2, 1}; - trace_api::TraceId trace_id{trace_id_buf}; - trace_api::SpanId span_id{span_id_buf}; - trace_api::SpanId parent_span_id{parent_span_id_buf}; - const auto trace_state = trace_api::TraceState::GetDefault()->Set("key1", "value"); - const trace_api::SpanContext span_context{ - trace_id, span_id, trace_api::TraceFlags{trace_api::TraceFlags::kIsSampled}, true, - trace_state}; - opentelemetry::common::SystemTimestamp now(std::chrono::system_clock::now()); - - ThreadsafeSpanData data; - data.SetIdentity(span_context, parent_span_id); - data.SetName("span name"); - data.SetSpanKind(trace_api::SpanKind::kServer); - data.SetStatus(trace_api::StatusCode::kOk, "description"); - data.SetStartTime(now); - data.SetDuration(std::chrono::nanoseconds(1000000)); - data.SetAttribute("attr1", (int64_t)314159); - data.AddEvent("event1", now); - - ASSERT_EQ(data.GetTraceId(), trace_id); - ASSERT_EQ(data.GetSpanId(), span_id); - ASSERT_EQ(data.GetSpanContext(), span_context); - std::string trace_state_key1_value; - ASSERT_EQ(data.GetSpanContext().trace_state()->Get("key1", trace_state_key1_value), true); - ASSERT_EQ(trace_state_key1_value, "value"); - ASSERT_EQ(data.GetParentSpanId(), parent_span_id); - ASSERT_EQ(data.GetName(), "span name"); - ASSERT_EQ(data.GetStatus(), trace_api::StatusCode::kOk); - ASSERT_EQ(data.GetDescription(), "description"); - ASSERT_EQ(data.GetStartTime().time_since_epoch(), now.time_since_epoch()); - ASSERT_EQ(data.GetDuration(), std::chrono::nanoseconds(1000000)); - ASSERT_EQ(opentelemetry::nostd::get(data.GetAttributes().at("attr1")), 314159); -} diff --git a/ext/test/zpages/tracez_data_aggregator_test.cc b/ext/test/zpages/tracez_data_aggregator_test.cc deleted file mode 100644 index 5139c9e914..0000000000 --- a/ext/test/zpages/tracez_data_aggregator_test.cc +++ /dev/null @@ -1,698 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#include "opentelemetry/ext/zpages/tracez_data_aggregator.h" - -#include - -#include "opentelemetry/ext/zpages/tracez_processor.h" -#include "opentelemetry/sdk/resource/resource.h" -#include "opentelemetry/sdk/trace/recordable.h" -#include "opentelemetry/sdk/trace/tracer.h" - -using namespace opentelemetry::sdk::trace; -using namespace opentelemetry::ext::zpages; -namespace nostd = opentelemetry::nostd; -namespace common = opentelemetry::common; -using opentelemetry::common::SteadyTimestamp; -using opentelemetry::trace::Span; - -const std::string span_name1 = "span 1"; -const std::string span_name2 = "span 2"; -const std::string span_name3 = "span 3"; - -/** - * TODO: Due to the absence of way to simulate the passing of time in the - * testing framework, synthetic delays had to be added in the tests to get the - * object in question to perform correctly. Later on if something like this is - * added the tests should be modified accordingly so that there is no external - * dependency. - * Additionally later on it would be better check for the span id(when set) - * rather than span name. - */ - -/** Test fixture for setting up the data aggregator and tracer for each test **/ -class TracezDataAggregatorTest : public ::testing::Test -{ -protected: - void SetUp() override - { - std::shared_ptr shared_data(new TracezSharedData()); - auto resource = opentelemetry::sdk::resource::Resource::Create({}); - std::unique_ptr processor(new TracezSpanProcessor(shared_data)); - std::vector> processors; - processors.push_back(std::move(processor)); - - auto context = std::make_shared(std::move(processors), resource); - tracer = std::shared_ptr(new Tracer(context)); - tracez_data_aggregator = std::unique_ptr( - new TracezDataAggregator(shared_data, milliseconds(10))); - } - - std::unique_ptr tracez_data_aggregator; - std::shared_ptr tracer; -}; - -/** - * Helper function to check if the counts of running, error and latency spans - * match what is expected - */ -void VerifySpanCountsInTracezData( - const std::string &span_name, - const TracezData &aggregated_data, - size_t running_span_count, - size_t error_span_count, - std::array completed_span_count_per_latency_bucket) -{ - // Asserts are needed to check the size of the container because they may need - // to be checked and if size checks fail it must be stopped - EXPECT_EQ(aggregated_data.running_span_count, running_span_count) - << " Count of running spans incorrect for " << span_name << "\n"; - - EXPECT_EQ(aggregated_data.sample_running_spans.size(), - std::min(running_span_count, kMaxNumberOfSampleSpans)) - << " Size of sample running spans incorrect for " << span_name << "\n"; - - EXPECT_EQ(aggregated_data.error_span_count, error_span_count) - << " Count of error spans incorrect for " << span_name << "\n"; - - EXPECT_EQ(aggregated_data.sample_error_spans.size(), - std::min(error_span_count, kMaxNumberOfSampleSpans)) - << " Count of running spans incorrect for " << span_name << "\n"; - - for (unsigned int boundary = 0; boundary < kLatencyBoundaries.size(); boundary++) - { - EXPECT_EQ(aggregated_data.completed_span_count_per_latency_bucket[boundary], - completed_span_count_per_latency_bucket[boundary]) - << " Count of completed spans in latency boundary " << boundary << " incorrect for " - << span_name << "\n"; - EXPECT_EQ(aggregated_data.sample_latency_spans[boundary].size(), - std::min(completed_span_count_per_latency_bucket[boundary], - kMaxNumberOfSampleSpans)) - << " Count of sample completed spans in latency boundary " << boundary << " incorrect for " - << span_name << "\n"; - } -} - -/**************************** No Span Test ************************************/ - -/** Test to check if data aggregator works as expected when there are no spans - * **/ -TEST_F(TracezDataAggregatorTest, NoSpans) -{ - auto data = tracez_data_aggregator->GetAggregatedTracezData(); - ASSERT_EQ(data.size(), 0); -} - -/*********************** Single span tests ************************************/ - -/** Test to check if data aggregator works as expected when there are - * is exactly a single running span **/ -TEST_F(TracezDataAggregatorTest, SingleRunningSpan) -{ - // Start the span get the data - auto span_first = tracer->StartSpan(span_name1); - std::this_thread::sleep_for(milliseconds(500)); - auto data = tracez_data_aggregator->GetAggregatedTracezData(); - - // Check to see if span name exists - ASSERT_EQ(data.size(), 1); - ASSERT_TRUE(data.find(span_name1) != data.end()); - auto &aggregated_data = data.at(span_name1); - - // Verify span counts then content of spans - VerifySpanCountsInTracezData(span_name1, aggregated_data, 1, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0}); - - ASSERT_EQ(aggregated_data.sample_running_spans.size(), 1); - ASSERT_EQ(aggregated_data.sample_running_spans.front().GetName().data(), span_name1); - span_first->End(); -} - -/** Test to check if data aggregator works as expected when there is exactly one - * completed span **/ -TEST_F(TracezDataAggregatorTest, SingleCompletedSpan) -{ - // Start and end the span at a specified times - opentelemetry::trace::StartSpanOptions start; - start.start_steady_time = SteadyTimestamp(nanoseconds(10)); - opentelemetry::trace::EndSpanOptions end; - end.end_steady_time = SteadyTimestamp(nanoseconds(40)); - tracer->StartSpan(span_name1, start)->End(end); - - // Get the data and make sure span name exists in the data - std::this_thread::sleep_for(milliseconds(500)); - auto data = tracez_data_aggregator->GetAggregatedTracezData(); - ASSERT_EQ(data.size(), 1); - ASSERT_TRUE(data.find(span_name1) != data.end()); - - auto &aggregated_data = data.at(span_name1); - // Make sure counts of spans are in order - VerifySpanCountsInTracezData(span_name1, aggregated_data, 0, 0, {1, 0, 0, 0, 0, 0, 0, 0, 0}); - - // Check if the span is correctly updated in the first boundary - ASSERT_EQ(aggregated_data.sample_latency_spans[LatencyBoundary::k0MicroTo10Micro].size(), 1); - ASSERT_EQ(aggregated_data.sample_latency_spans[LatencyBoundary::k0MicroTo10Micro] - .front() - .GetDuration() - .count(), - 30); -} - -/** Test to check if data aggregator works as expected when there is exactly - * one error span **/ -TEST_F(TracezDataAggregatorTest, SingleErrorSpan) -{ - // Start and end a single error span - auto span = tracer->StartSpan(span_name1); - span->SetStatus(opentelemetry::trace::StatusCode::kError, "span cancelled"); - span->End(); - std::this_thread::sleep_for(milliseconds(500)); - auto data = tracez_data_aggregator->GetAggregatedTracezData(); - - // Check to see if span name can be found in aggregation - ASSERT_EQ(data.size(), 1); - ASSERT_TRUE(data.find(span_name1) != data.end()); - - auto &aggregated_data = data.at(span_name1); - // Make sure counts of spans are in order - VerifySpanCountsInTracezData(span_name1, aggregated_data, 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0}); - - // Check the value of the error span introduced - ASSERT_EQ(aggregated_data.sample_error_spans.size(), 1); - ASSERT_EQ(aggregated_data.sample_error_spans.front().GetName().data(), span_name1); -} - -/************************* Multiple span tests ********************************/ - -/** Test to check if multiple running spans behaves as expected**/ -TEST_F(TracezDataAggregatorTest, MultipleRunningSpans) -{ - // A container that maps a span name to the number of spans to start with that - // span name - std::unordered_map running_span_name_to_count({ - {span_name1, 1}, - {span_name2, 2}, - {span_name3, 3}, - }); - - // Start and store spans based on the above map - std::vector> running_span_container; - for (auto span_name : running_span_name_to_count) - { - for (int count = 0; count < span_name.second; count++) - running_span_container.push_back(tracer->StartSpan(span_name.first)); - } - - // give time for aggregation and then get data - std::this_thread::sleep_for(milliseconds(500)); - auto data = tracez_data_aggregator->GetAggregatedTracezData(); - ASSERT_EQ(data.size(), running_span_name_to_count.size()); - - // Check to see if the running span counts were updated correctly - for (auto &span_name : running_span_name_to_count) - { - ASSERT_TRUE(data.find(span_name.first) != data.end()); - - // Make sure counts of spans are in order - VerifySpanCountsInTracezData(span_name.first, data.at(span_name.first), span_name.second, 0, - {0, 0, 0, 0, 0, 0, 0, 0, 0}); - - ASSERT_EQ(data.at(span_name.first).sample_running_spans.size(), span_name.second); - for (auto &span_sample : data.at(span_name.first).sample_running_spans) - { - ASSERT_EQ(span_sample.GetName().data(), span_name.first); - } - } - - for (auto i = running_span_container.begin(); i != running_span_container.end(); i++) - (*i)->End(); -} - -/** Test to check if multiple completed spans updates the aggregated data - * correctly **/ -TEST_F(TracezDataAggregatorTest, MultipleCompletedSpan) -{ - // Start spans with span name and the corresponding durations in one of the 9 - // latency buckets - const std::unordered_map>> - span_name_to_duration( - {{span_name1, {{nanoseconds(10), nanoseconds(4600)}, {}, {}, {}, {}, {}, {}, {}, {}}}, - {span_name2, - {{}, - {nanoseconds(38888), nanoseconds(98768)}, - {nanoseconds(983251)}, - {}, - {}, - {}, - {}, - {}, - {}}}, - {span_name3, - {{}, - {}, - {}, - {nanoseconds(1234567), nanoseconds(1234567)}, - {}, - {}, - {}, - {}, - {nanoseconds(9999999999999)}}}}); - opentelemetry::trace::StartSpanOptions start; - opentelemetry::trace::EndSpanOptions end; - for (auto &span : span_name_to_duration) - { - for (auto &buckets : span.second) - { - for (auto &duration : buckets) - { - long long int end_time = duration.count() + 1; - start.start_steady_time = SteadyTimestamp(nanoseconds(1)); - end.end_steady_time = SteadyTimestamp(nanoseconds(end_time)); - tracer->StartSpan(span.first, start)->End(end); - } - } - } - - // Give time for aggregation and get data - std::this_thread::sleep_for(milliseconds(500)); - auto data = tracez_data_aggregator->GetAggregatedTracezData(); - - ASSERT_EQ(data.size(), span_name_to_duration.size()); - - for (auto &span : span_name_to_duration) - { - ASSERT_TRUE(data.find(span.first) != data.end()); - auto &aggregated_data = data.at(span.first); - - // Make sure counts of spans are in order - VerifySpanCountsInTracezData( - span.first, aggregated_data, 0, 0, - {(unsigned int)span.second[0].size(), (unsigned int)span.second[1].size(), - (unsigned int)span.second[2].size(), (unsigned int)span.second[3].size(), - (unsigned int)span.second[4].size(), (unsigned int)span.second[5].size(), - (unsigned int)span.second[6].size(), (unsigned int)span.second[7].size(), - (unsigned int)span.second[8].size()}); - - for (unsigned int boundary = 0; boundary < kLatencyBoundaries.size(); boundary++) - { - ASSERT_EQ(aggregated_data.sample_latency_spans[boundary].size(), - span.second[boundary].size()); - auto latency_sample = aggregated_data.sample_latency_spans[boundary].begin(); - for (unsigned int idx = 0; idx < span.second[boundary].size(); idx++) - { - ASSERT_EQ(span.second[boundary][idx].count(), latency_sample->GetDuration().count()); - latency_sample = std::next(latency_sample); - } - } - } -} - -/** - * This test checks to see if the aggregated data is updated correctly - * when there are multiple error spans. - * It checks both the count of error spans and the error samples - */ -TEST_F(TracezDataAggregatorTest, MultipleErrorSpans) -{ - // Container to store the span names --> error messges for the span name - std::unordered_map> span_name_to_error( - {{span_name1, {"span 1 error"}}, - {span_name2, {"span 2 error 1", "span 2 error 2"}}, - {span_name3, - {"span 3 error 1", "span 3 error 2", "span 3 error 3", "span 3 error 4", - "span 3 error 5"}}}); - - // Start spans with the error messages based on the map - for (auto &span_error : span_name_to_error) - { - for (auto error_desc : span_error.second) - { - auto span = tracer->StartSpan(span_error.first); - span->SetStatus(opentelemetry::trace::StatusCode::kError, error_desc); - span->End(); - } - } - - // Give some time and then get data - std::this_thread::sleep_for(milliseconds(500)); - auto data = tracez_data_aggregator->GetAggregatedTracezData(); - ASSERT_EQ(data.size(), span_name_to_error.size()); - - // Check if error spans were updated correctly for the different span names - for (auto &span_error : span_name_to_error) - { - // First try to find the span name in aggregation, then check the count of - // the error spans and then check values - ASSERT_TRUE(data.find(span_error.first) != data.end()); - - auto &aggregated_data = data.at(span_error.first); - - // Make sure counts of spans are in order - VerifySpanCountsInTracezData(span_error.first, aggregated_data, 0, span_error.second.size(), - {0, 0, 0, 0, 0, 0, 0, 0, 0}); - ASSERT_EQ(aggregated_data.error_span_count, span_error.second.size()); - - auto error_sample = aggregated_data.sample_error_spans.begin(); - for (unsigned int idx = 0; idx < span_error.second.size(); idx++) - { - ASSERT_EQ(span_error.second[idx], error_sample->GetDescription()); - error_sample = std::next(error_sample); - } - } -} - -/************************ Sample spans tests **********************************/ - -/** - * This test checks to see that the maximum number of running samples(5) for a - * bucket is not exceeded. If there are more spans than this for a single bucket - * it removes the earliest span that was received - */ -TEST_F(TracezDataAggregatorTest, RunningSampleSpansOverCapacity) -{ - int running_span_count = 6; - // Start and store spans based on the above map - std::vector> running_span_container; - for (int count = 0; count < running_span_count; count++) - running_span_container.push_back(tracer->StartSpan(span_name1)); - - std::this_thread::sleep_for(milliseconds(500)); - // Fetch data and check if span name is spresent - auto data = tracez_data_aggregator->GetAggregatedTracezData(); - ASSERT_EQ(data.size(), 1); - ASSERT_TRUE(data.find(span_name1) != data.end()); - - // Check if error spans are updated according to spans started - auto &aggregated_data = data.at(span_name1); - VerifySpanCountsInTracezData(span_name1, aggregated_data, 6, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0}); - - ASSERT_EQ(aggregated_data.sample_running_spans.size(), kMaxNumberOfSampleSpans); - - for (auto i = running_span_container.begin(); i != running_span_container.end(); i++) - { - (*i)->End(); - } -} - -/** - * This test checks to see that the maximum number of error samples(5) for a - * bucket is not exceeded. If there are more spans than this for a single bucket - * it removes the earliest span that was received - */ -TEST_F(TracezDataAggregatorTest, ErrorSampleSpansOverCapacity) -{ - // Create error spans with the descriptions in the vector - std::vector span_error_descriptions = {"error span 1", "error span 2", - "error span 3", "error span 4", - "error span 5", "error span 6"}; - for (auto span_error_description : span_error_descriptions) - { - auto span = tracer->StartSpan(span_name1); - span->SetStatus(opentelemetry::trace::StatusCode::kError, span_error_description); - span->End(); - } - - std::this_thread::sleep_for(milliseconds(500)); - - // Fetch data and check if span name is spresent - auto data = tracez_data_aggregator->GetAggregatedTracezData(); - ASSERT_EQ(data.size(), 1); - ASSERT_TRUE(data.find(span_name1) != data.end()); - - std::this_thread::sleep_for(milliseconds(500)); - - // Check if error spans are updated according to spans started - auto &aggregated_data = data.at(span_name1); - VerifySpanCountsInTracezData(span_name1, aggregated_data, 0, span_error_descriptions.size(), - {0, 0, 0, 0, 0, 0, 0, 0, 0}); - - // Check if the latest 5 error spans exist out of the total 6 that were - // introduced - auto error_sample = aggregated_data.sample_error_spans.begin(); - for (unsigned int idx = 1; idx < span_error_descriptions.size(); idx++) - { - ASSERT_EQ(error_sample->GetDescription(), span_error_descriptions[idx]); - error_sample = std::next(error_sample); - } -} - -/** - * This test checks to see that the maximum number of latency samples(5) for a - * bucket is not exceeded. If there are more spans than this for a single bucket - * it removes the earliest span that was received - */ -TEST_F(TracezDataAggregatorTest, CompletedSampleSpansOverCapacity) -{ - opentelemetry::trace::StartSpanOptions start; - opentelemetry::trace::EndSpanOptions end; - - // Start and end 6 spans with the same name that fall into the first latency - // bucket - std::vector> timestamps = { - make_pair(nanoseconds(10), nanoseconds(100)), - make_pair(nanoseconds(1), nanoseconds(10000)), - make_pair(nanoseconds(1000), nanoseconds(3000)), - make_pair(nanoseconds(12), nanoseconds(12)), - make_pair(nanoseconds(10), nanoseconds(5000)), - make_pair(nanoseconds(10), nanoseconds(60))}; - for (auto timestamp : timestamps) - { - start.start_steady_time = SteadyTimestamp(timestamp.first); - end.end_steady_time = SteadyTimestamp(timestamp.second); - tracer->StartSpan(span_name1, start)->End(end); - } - - // Give some time and get data - std::this_thread::sleep_for(milliseconds(500)); - auto data = tracez_data_aggregator->GetAggregatedTracezData(); - - ASSERT_EQ(data.size(), 1); - ASSERT_TRUE(data.find(span_name1) != data.end()); - - std::this_thread::sleep_for(milliseconds(500)); - auto &aggregated_data = data.at(span_name1); - VerifySpanCountsInTracezData(span_name1, aggregated_data, 0, 0, - {(unsigned int)timestamps.size(), 0, 0, 0, 0, 0, 0, 0, 0}); - - // Check the count of completed spans in the buckets and the samples stored - auto latency_sample = - aggregated_data.sample_latency_spans[LatencyBoundary::k0MicroTo10Micro].begin(); - - // idx starts from 1 and not 0 because there are 6 completed spans in the same - // bucket the and the first one is removed - for (unsigned int idx = 1; idx < timestamps.size(); idx++) - { - ASSERT_EQ(latency_sample->GetDuration().count(), - timestamps[idx].second.count() - timestamps[idx].first.count()); - latency_sample = std::next(latency_sample); - } -} - -/************************* Miscellaneous tests ********************************/ - -/** Test to see if the span names are in alphabetical order **/ -TEST_F(TracezDataAggregatorTest, SpanNameInAlphabeticalOrder) -{ - std::vector span_names = {span_name1, span_name2, span_name3}; - - auto span_first = tracer->StartSpan(span_name2); - tracer->StartSpan(span_name1)->End(); - auto span_third = tracer->StartSpan(span_name3); - span_third->SetStatus(opentelemetry::trace::StatusCode::kError, "span cancelled"); - span_third->End(); - std::this_thread::sleep_for(milliseconds(500)); - // Get data and check if span name exists in aggregation - auto data = tracez_data_aggregator->GetAggregatedTracezData(); - ASSERT_EQ(data.size(), span_names.size()); - - int span_names_idx = 0; - for (auto &spans : data) - { - ASSERT_EQ(spans.first, span_names[span_names_idx]); - span_names_idx++; - } - span_first->End(); -} - -/** This test checks to see that there is no double counting of running spans - * when get aggregated data is called twice**/ -TEST_F(TracezDataAggregatorTest, AdditionToRunningSpans) -{ - // Start a span and check the data - auto span_first = tracer->StartSpan(span_name1); - std::this_thread::sleep_for(milliseconds(500)); - auto data = tracez_data_aggregator->GetAggregatedTracezData(); - ASSERT_EQ(data.size(), 1); - ASSERT_TRUE(data.find(span_name1) != data.end()); - VerifySpanCountsInTracezData(span_name1, data.at(span_name1), 1, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0}); - - // Start another span and check to see if there is no double counting of spans - auto span_second = tracer->StartSpan(span_name1); - - // Give some time and get updated data - std::this_thread::sleep_for(milliseconds(500)); - data = tracez_data_aggregator->GetAggregatedTracezData(); - ASSERT_EQ(data.size(), 1); - ASSERT_TRUE(data.find(span_name1) != data.end()); - auto &aggregated_data = data.at(span_name1); - VerifySpanCountsInTracezData(span_name1, aggregated_data, 2, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0}); - - ASSERT_EQ(aggregated_data.sample_running_spans.size(), 2); - for (auto &sample_span : aggregated_data.sample_running_spans) - { - ASSERT_EQ(sample_span.GetName().data(), span_name1); - } - span_first->End(); - span_second->End(); -} - -/** This test checks to see that once a running span is completed it the - * aggregated data is updated correctly **/ -TEST_F(TracezDataAggregatorTest, RemovalOfRunningSpanWhenCompleted) -{ - opentelemetry::trace::StartSpanOptions start; - start.start_steady_time = SteadyTimestamp(nanoseconds(10)); - opentelemetry::trace::EndSpanOptions end; - end.end_steady_time = SteadyTimestamp(nanoseconds(40)); - - // Start a span and make sure data is updated - auto span_first = tracer->StartSpan(span_name1, start); - std::this_thread::sleep_for(milliseconds(500)); - auto data = tracez_data_aggregator->GetAggregatedTracezData(); - ASSERT_EQ(data.size(), 1); - ASSERT_TRUE(data.find(span_name1) != data.end()); - VerifySpanCountsInTracezData(span_name1, data.at(span_name1), 1, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0}); - ASSERT_EQ(data.at(span_name1).sample_running_spans.front().GetName().data(), span_name1); - // End the span and make sure running span is removed and completed span is - // updated, there should be only one completed span - span_first->End(end); - std::this_thread::sleep_for(milliseconds(500)); - - // Make sure sample span still exists before next aggregation - ASSERT_TRUE(data.find(span_name1) != data.end()); - ASSERT_EQ(data.at(span_name1).sample_running_spans.front().GetName().data(), span_name1); - - data = tracez_data_aggregator->GetAggregatedTracezData(); - - ASSERT_EQ(data.size(), 1); - ASSERT_TRUE(data.find(span_name1) != data.end()); - - // Check if completed span fields are correctly updated - auto &aggregated_data = data.at(span_name1); - VerifySpanCountsInTracezData(span_name1, aggregated_data, 0, 0, {1, 0, 0, 0, 0, 0, 0, 0, 0}); - ASSERT_EQ(aggregated_data.sample_latency_spans[LatencyBoundary::k0MicroTo10Micro] - .front() - .GetDuration() - .count(), - 30); -} - -TEST_F(TracezDataAggregatorTest, RunningSpanChangesNameBeforeCompletion) -{ - opentelemetry::trace::StartSpanOptions start; - start.start_steady_time = SteadyTimestamp(nanoseconds(10)); - opentelemetry::trace::EndSpanOptions end; - end.end_steady_time = SteadyTimestamp(nanoseconds(40)); - - // Start a span and make sure data is updated - auto span_first = tracer->StartSpan(span_name1, start); - std::this_thread::sleep_for(milliseconds(500)); - auto data = tracez_data_aggregator->GetAggregatedTracezData(); - ASSERT_EQ(data.size(), 1); - ASSERT_TRUE(data.find(span_name1) != data.end()); - VerifySpanCountsInTracezData(span_name1, data.at(span_name1), 1, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0}); - ASSERT_EQ(data.at(span_name1).sample_running_spans.front().GetName().data(), span_name1); - - // End the span and make sure running span is removed and completed span is - // updated, there should be only one completed span - span_first->UpdateName(span_name2); - span_first->End(end); - - // Check if sample span is present before fetching updated data - std::this_thread::sleep_for(milliseconds(500)); - ASSERT_TRUE(data.find(span_name1) != data.end()); - ASSERT_EQ(data.at(span_name1).sample_running_spans.front().GetName(), span_name1); - - data = tracez_data_aggregator->GetAggregatedTracezData(); - - ASSERT_EQ(data.size(), 1); - ASSERT_TRUE(data.find(span_name2) != data.end()); - - // Check if completed span fields are correctly updated - auto &aggregated_data = data.at(span_name2); - VerifySpanCountsInTracezData(span_name2, aggregated_data, 0, 0, {1, 0, 0, 0, 0, 0, 0, 0, 0}); - ASSERT_EQ(aggregated_data.sample_latency_spans[LatencyBoundary::k0MicroTo10Micro] - .front() - .GetDuration() - .count(), - 30); -} - -/** Test to check if the span latencies with duration at the edge of boundaries - * fall in the correct bucket **/ -TEST_F(TracezDataAggregatorTest, EdgeSpanLatenciesFallInCorrectBoundaries) -{ - opentelemetry::trace::StartSpanOptions start; - opentelemetry::trace::EndSpanOptions end; - - // Start and end 6 spans with the same name that fall into the first latency - // bucket - std::vector durations = { - nanoseconds(0), nanoseconds(10000), nanoseconds(100000), - nanoseconds(1000000), nanoseconds(10000000), nanoseconds(100000000), - nanoseconds(1000000000), nanoseconds(10000000000), nanoseconds(100000000000)}; - for (auto duration : durations) - { - start.start_steady_time = SteadyTimestamp(nanoseconds(1)); - end.end_steady_time = SteadyTimestamp(nanoseconds(duration.count() + 1)); - tracer->StartSpan(span_name1, start)->End(end); - } - - std::this_thread::sleep_for(milliseconds(500)); - auto data = tracez_data_aggregator->GetAggregatedTracezData(); - ASSERT_EQ(data.size(), 1); - ASSERT_TRUE(data.find(span_name1) != data.end()); - - std::this_thread::sleep_for(milliseconds(500)); - auto &aggregated_data = data.at(span_name1); - VerifySpanCountsInTracezData(span_name1, aggregated_data, 0, 0, {1, 1, 1, 1, 1, 1, 1, 1, 1}); - - // Check if the latency boundary is updated correctly - for (unsigned int boundary = 0; boundary < kLatencyBoundaries.size(); boundary++) - { - ASSERT_EQ(aggregated_data.sample_latency_spans[boundary].front().GetDuration().count(), - durations[boundary].count()); - } -} - -/** This test makes sure that the data is consistent when there are multiple - * calls to the data aggegator with no change in data **/ -TEST_F(TracezDataAggregatorTest, NoChangeInBetweenCallsToAggregator) -{ - opentelemetry::trace::StartSpanOptions start; - start.start_steady_time = SteadyTimestamp(nanoseconds(1)); - - opentelemetry::trace::EndSpanOptions end; - end.end_steady_time = SteadyTimestamp(nanoseconds(1)); - - tracer->StartSpan(span_name1, start)->End(end); - auto running_span = tracer->StartSpan(span_name2); - auto span = tracer->StartSpan(span_name3); - span->SetStatus(opentelemetry::trace::StatusCode::kError, "span cancelled"); - span->End(); - std::this_thread::sleep_for(milliseconds(500)); - auto data = tracez_data_aggregator->GetAggregatedTracezData(); - std::this_thread::sleep_for(milliseconds(500)); - // Get data and check if span name exists in aggregation - data = tracez_data_aggregator->GetAggregatedTracezData(); - ASSERT_TRUE(data.find(span_name1) != data.end()); - VerifySpanCountsInTracezData(span_name1, data.at(span_name1), 0, 0, {1, 0, 0, 0, 0, 0, 0, 0, 0}); - - ASSERT_TRUE(data.find(span_name2) != data.end()); - VerifySpanCountsInTracezData(span_name2, data.at(span_name2), 1, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0}); - - ASSERT_TRUE(data.find(span_name3) != data.end()); - VerifySpanCountsInTracezData(span_name3, data.at(span_name3), 0, 1, {0, 0, 0, 0, 0, 0, 0, 0, 0}); - - running_span->End(); -} diff --git a/ext/test/zpages/tracez_processor_test.cc b/ext/test/zpages/tracez_processor_test.cc deleted file mode 100644 index 6cc3640651..0000000000 --- a/ext/test/zpages/tracez_processor_test.cc +++ /dev/null @@ -1,647 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -#include "opentelemetry/ext/zpages/tracez_processor.h" - -#include - -#include - -#include "opentelemetry/ext/zpages/threadsafe_span_data.h" -#include "opentelemetry/nostd/span.h" -#include "opentelemetry/sdk/resource/resource.h" -#include "opentelemetry/sdk/trace/tracer.h" - -using namespace opentelemetry::sdk::trace; -using namespace opentelemetry::ext::zpages; -using namespace testing; - -//////////////////////////////////// TEST HELPER FUNCTIONS ////////////////////////////// - -/* - * Helper function uses the current processor to update spans contained in completed_spans - * and running_spans. completed_spans contains all spans (cumulative), unless marked otherwise - */ -void UpdateSpans(std::shared_ptr &data, - std::vector> &completed, - std::unordered_set &running, - bool store_only_new_completed = false) -{ - auto spans = data->GetSpanSnapshot(); - running = spans.running; - if (store_only_new_completed) - { - completed.clear(); - completed = std::move(spans.completed); - } - else - { - std::move(spans.completed.begin(), spans.completed.end(), - std::inserter(completed, completed.end())); - } - spans.completed.clear(); -} - -/* - * Returns true if all the span names in the name vector within the given range appears in - * at least the same frequency as they do in running_spans. - * - * If no start value is given, start at index 0 - * If no end value is given, end at name vector end - * If 1-1 correspondance marked, return true if completed has all names in same frequency, - * no more or less - */ -bool ContainsNames(const std::vector &names, - std::unordered_set &running, - size_t name_start = 0, - size_t name_end = 0, - bool one_to_one_correspondence = false) -{ - if (name_end == 0) - name_end = names.size(); - - size_t num_names = name_end - name_start; - - if (num_names > running.size() || // More names than spans, can't have all names - (one_to_one_correspondence && num_names != running.size())) - { - return false; - } - std::vector is_contained(num_names, false); - - // Mark all names that are contained only once - // in the order they appear - for (auto &span : running) - { - for (unsigned int i = 0; i < num_names; i++) - { - if (span->GetName() == names[name_start + i] && !is_contained[i]) - { - is_contained[i] = true; - break; - } - } - } - - for (auto &&b : is_contained) - if (!b) - return false; - - return true; -} - -/* - * Returns true if all the span names in the nam vector within the given range appears in - * at least the same frequency as they do in completed_spans - * - * If no start value is given, start at index 0 - * If no end value is given, end at name vector end - * If 1-1 correspondance marked, return true if completed has all names in same frequency, - * no more or less - */ -bool ContainsNames(const std::vector &names, - std::vector> &completed, - size_t name_start = 0, - size_t name_end = 0, - bool one_to_one_correspondence = false) -{ - - if (name_end == 0) - name_end = names.size(); - - size_t num_names = name_end - name_start; - - if (num_names > completed.size() || (one_to_one_correspondence && num_names != completed.size())) - { - return false; - } - std::vector is_contained(num_names, false); - - for (auto &span : completed) - { - for (unsigned int i = 0; i < num_names; i++) - { - if (span->GetName() == names[name_start + i] && !is_contained[i]) - { - is_contained[i] = true; - break; - } - } - } - - for (auto &&b : is_contained) - if (!b) - return false; - - return true; -} - -/* - * Helper function calls GetSpanSnapshot() i times and does nothing with it - * otherwise. Used for testing thread safety - */ -void GetManySnapshots(std::shared_ptr &data, int i) -{ - for (; i > 0; i--) - data->GetSpanSnapshot(); -} - -/* - * Helper function that creates i spans, which are added into the passed - * in vector. Used for testing thread safety - */ -void StartManySpans( - std::vector> &spans, - std::shared_ptr tracer, - int i) -{ - for (; i > 0; i--) - spans.push_back(tracer->StartSpan("span")); -} - -/* - * Helper function that ends all spans in the passed in span vector. Used - * for testing thread safety - */ -void EndAllSpans(std::vector> &spans) -{ - for (auto &span : spans) - span->End(); -} - -//////////////////////////////// TEST FIXTURE ////////////////////////////////////// - -/* - * Reduce code duplication by having single area with shared setup code - */ -class TracezProcessor : public ::testing::Test -{ -protected: - void SetUp() override - { - shared_data = std::shared_ptr(new TracezSharedData()); - processor = std::shared_ptr(new TracezSpanProcessor(shared_data)); - std::unique_ptr processor2(new TracezSpanProcessor(shared_data)); - std::vector> processors; - processors.push_back(std::move(processor2)); - auto resource = opentelemetry::sdk::resource::Resource::Create({}); - - // Note: we make a *different* processor for the tracercontext. THis is because - // all the tests use shared data, and we want to make sure this works correctly. - auto context = std::make_shared(std::move(processors), resource); - - tracer = std::shared_ptr(new Tracer(context)); - auto spans = shared_data->GetSpanSnapshot(); - running = spans.running; - completed = std::move(spans.completed); - - span_names = {"s0", "s2", "s1", "s1", "s"}; - } - - std::shared_ptr shared_data; - std::shared_ptr processor; - std::shared_ptr tracer; - - std::vector span_names; - std::vector> span_vars; - - std::unordered_set running; - std::vector> completed; -}; - -///////////////////////////////////////// TESTS /////////////////////////////////// - -/* - * Test if both span containers are empty when no spans exist or are added. - * Ensures no rogue spans appear in the containers somehow. - */ -TEST_F(TracezProcessor, NoSpans) -{ - auto recordable = processor->MakeRecordable(); - - EXPECT_EQ(running.size(), 0); - EXPECT_EQ(completed.size(), 0); -} - -/* - * Test if a single span moves from running to completed at expected times. - * All completed spans are stored. Ensures basic functionality and that accumulation - * can happen - */ -TEST_F(TracezProcessor, OneSpanCumulative) -{ - auto span = tracer->StartSpan(span_names[0]); - UpdateSpans(shared_data, completed, running); - - EXPECT_TRUE(ContainsNames(span_names, running, 0, 1, true)); - EXPECT_EQ(running.size(), 1); - EXPECT_EQ(completed.size(), 0); - - span->End(); - UpdateSpans(shared_data, completed, running); - - EXPECT_TRUE(ContainsNames(span_names, completed, 0, 1, true)); - EXPECT_EQ(running.size(), 0); - EXPECT_EQ(completed.size(), 1); -} - -/* - * Test if multiple spans move from running to completed at expected times. Check if - * all are in a container, either running/completed during checks. Ensures basic functionality - * and that accumulation can happen for many spans - * All completed spans are stored. - */ -TEST_F(TracezProcessor, MultipleSpansCumulative) -{ - EXPECT_EQ(running.size(), 0); - EXPECT_EQ(completed.size(), 0); - - // Start and store spans using span_names - for (const auto &name : span_names) - span_vars.push_back(tracer->StartSpan(name)); - UpdateSpans(shared_data, completed, running); - - EXPECT_TRUE(ContainsNames(span_names, running)); // s0 s2 s1 s1 s - EXPECT_EQ(running.size(), span_names.size()); - EXPECT_EQ(completed.size(), 0); - - // End all spans - for (auto &span : span_vars) - span->End(); - UpdateSpans(shared_data, completed, running); - - EXPECT_TRUE(ContainsNames(span_names, completed)); // s0 s2 s1 s1 s - EXPECT_EQ(running.size(), 0); - EXPECT_EQ(completed.size(), span_names.size()); -} - -/* - * Test if multiple spans move from running to completed at expected times, - * running/completed spans are split. Middle spans end first. Ensures basic functionality - * and that accumulation can happen for many spans even spans that start and end non- - * sequentially. All completed spans are stored. - */ -TEST_F(TracezProcessor, MultipleSpansMiddleSplitCumulative) -{ - for (const auto &name : span_names) - span_vars.push_back(tracer->StartSpan(name)); - UpdateSpans(shared_data, completed, running); - - EXPECT_TRUE(ContainsNames(span_names, running)); // s0 s2 s1 s1 s - EXPECT_EQ(running.size(), span_names.size()); - EXPECT_EQ(completed.size(), 0); - - // End 4th span - span_vars[3]->End(); - UpdateSpans(shared_data, completed, running); - - EXPECT_TRUE(ContainsNames(span_names, running, 0, 3)); // s0 s2 s1 - EXPECT_TRUE(ContainsNames(span_names, running, 4)); // + s - EXPECT_TRUE(ContainsNames(span_names, completed, 3, 4)); // s1 - EXPECT_EQ(running.size(), 4); - EXPECT_EQ(completed.size(), 1); - - // End 2nd span - span_vars[1]->End(); - UpdateSpans(shared_data, completed, running); - - EXPECT_TRUE(ContainsNames(span_names, running, 0, 1)); // s0 - EXPECT_TRUE(ContainsNames(span_names, running, 2, 3)); // + s1 - EXPECT_TRUE(ContainsNames(span_names, running, 4)); // + s - EXPECT_TRUE(ContainsNames(span_names, completed, 1, 2)); // s2 - EXPECT_TRUE(ContainsNames(span_names, completed, 3, 4)); // s1 - EXPECT_EQ(running.size(), 3); - EXPECT_EQ(completed.size(), 2); - - // End 3rd span (last middle span) - span_vars[2]->End(); - UpdateSpans(shared_data, completed, running); - - EXPECT_TRUE(ContainsNames(span_names, running, 0, 1)); // s0 - EXPECT_TRUE(ContainsNames(span_names, running, 4)); // + s - EXPECT_TRUE(ContainsNames(span_names, completed, 1, 4)); // s2 s1 s1 - EXPECT_EQ(running.size(), 2); - EXPECT_EQ(completed.size(), 3); - - // End remaining Spans - span_vars[0]->End(); - span_vars[4]->End(); - UpdateSpans(shared_data, completed, running); - - EXPECT_TRUE(ContainsNames(span_names, completed)); // s0 s2 s1 s1 s - EXPECT_EQ(running.size(), 0); - EXPECT_EQ(completed.size(), 5); -} - -/* - * Test if multiple spans move from running to completed at expected times, - * running/completed spans are split. Ensures basic functionality and that - * accumulation can happen for many spans even spans that start and end non- - * sequentially. All completed spans are stored. - */ -TEST_F(TracezProcessor, MultipleSpansOuterSplitCumulative) -{ - for (const auto &name : span_names) - span_vars.push_back(tracer->StartSpan(name)); - - // End last span - span_vars[4]->End(); - UpdateSpans(shared_data, completed, running); - - EXPECT_TRUE(ContainsNames(span_names, running, 0, 4)); // s0 s2 s1 s1 - EXPECT_TRUE(ContainsNames(span_names, completed, 4)); // s - EXPECT_EQ(running.size(), 4); - EXPECT_EQ(completed.size(), 1); - - // End first span - span_vars[0]->End(); - UpdateSpans(shared_data, completed, running); - - EXPECT_TRUE(ContainsNames(span_names, running, 1, 4)); // s2 s1 s1 - EXPECT_TRUE(ContainsNames(span_names, completed, 0, 1)); // s0 - EXPECT_TRUE(ContainsNames(span_names, completed, 4)); // s - EXPECT_EQ(running.size(), 3); - EXPECT_EQ(completed.size(), 2); - - // End remaining Spans - for (int i = 1; i < 4; i++) - span_vars[i]->End(); - UpdateSpans(shared_data, completed, running); - - EXPECT_TRUE(ContainsNames(span_names, completed)); // s0 s2 s1 s1 s - EXPECT_EQ(running.size(), 0); - EXPECT_EQ(completed.size(), 5); -} - -/* - * Test if a single span moves from running to completed at expected times. - * Ensure correct behavior even when spans are discarded. Only new completed - * spans are stored. - */ -TEST_F(TracezProcessor, OneSpanNewOnly) -{ - auto span = tracer->StartSpan(span_names[0]); - UpdateSpans(shared_data, completed, running, true); - - EXPECT_TRUE(ContainsNames(span_names, running, 0, 1, true)); - EXPECT_EQ(running.size(), 1); - EXPECT_EQ(completed.size(), 0); - - span->End(); - UpdateSpans(shared_data, completed, running, true); - - EXPECT_TRUE(ContainsNames(span_names, completed, 0, 1, true)); - EXPECT_EQ(running.size(), 0); - EXPECT_EQ(completed.size(), 1); - - UpdateSpans(shared_data, completed, running, true); - - EXPECT_EQ(running.size(), 0); - EXPECT_EQ(completed.size(), 0); -} - -/* - * Test if multiple spans move from running to completed at expected times, - * running/completed spans are split. Middle spans end first. Ensure correct - * behavior even when multiple spans are discarded, even when span starting and - * ending is non-sequential. Only new completed spans are stored. - */ -TEST_F(TracezProcessor, MultipleSpansMiddleSplitNewOnly) -{ - for (const auto &name : span_names) - span_vars.push_back(tracer->StartSpan(name)); - UpdateSpans(shared_data, completed, running); - - EXPECT_TRUE(ContainsNames(span_names, running, 0, 5, true)); // s0 s2 s1 s1 s - EXPECT_EQ(running.size(), span_names.size()); - EXPECT_EQ(completed.size(), 0); - - // End 4th span - span_vars[3]->End(); - UpdateSpans(shared_data, completed, running, true); - - EXPECT_TRUE(ContainsNames(span_names, running, 0, 3)); // s0 s2 s1 - EXPECT_TRUE(ContainsNames(span_names, running, 4)); // + s - EXPECT_TRUE(ContainsNames(span_names, completed, 3, 4, true)); // s1 - EXPECT_EQ(running.size(), 4); - EXPECT_EQ(completed.size(), 1); - - // End 2nd and 3rd span - span_vars[1]->End(); - span_vars[2]->End(); - UpdateSpans(shared_data, completed, running, true); - - EXPECT_TRUE(ContainsNames(span_names, running, 0, 1)); // s0 - EXPECT_TRUE(ContainsNames(span_names, running, 4)); // + s - EXPECT_TRUE(ContainsNames(span_names, completed, 1, 3, true)); // s2 s1 - EXPECT_EQ(running.size(), 2); - EXPECT_EQ(completed.size(), 2); - - // End remaining Spans - span_vars[0]->End(); - span_vars[4]->End(); - UpdateSpans(shared_data, completed, running, true); - - EXPECT_TRUE(ContainsNames(span_names, completed, 0, 1)); // s0 - EXPECT_TRUE(ContainsNames(span_names, completed, 4)); // s - EXPECT_EQ(running.size(), 0); - EXPECT_EQ(completed.size(), 2); - - UpdateSpans(shared_data, completed, running, true); - - EXPECT_EQ(running.size(), 0); - EXPECT_EQ(completed.size(), 0); -} - -/* - * Test if multiple spans move from running to completed at expected times, - * running/completed spans are split. Ensure correct behavior even when - * multiple spans are discarded, even when span starting and ending is - * non-sequential. Only new completed spans are stored. - */ -TEST_F(TracezProcessor, MultipleSpansOuterSplitNewOnly) -{ - for (const auto &name : span_names) - span_vars.push_back(tracer->StartSpan(name)); - - // End last span - span_vars[4]->End(); - UpdateSpans(shared_data, completed, running, true); - - EXPECT_TRUE(ContainsNames(span_names, running, 0, 4, true)); // s0 s2 s1 s1 - EXPECT_TRUE(ContainsNames(span_names, completed, 4, 5, true)); // s - EXPECT_EQ(running.size(), 4); - EXPECT_EQ(completed.size(), 1); - - // End first span - span_vars[0]->End(); - UpdateSpans(shared_data, completed, running, true); - - EXPECT_TRUE(ContainsNames(span_names, running, 1, 4, true)); // s2 s1 s1 - EXPECT_TRUE(ContainsNames(span_names, completed, 0, 1, true)); // s0 - EXPECT_EQ(running.size(), 3); - EXPECT_EQ(completed.size(), 1); - - // End remaining middle spans - for (int i = 1; i < 4; i++) - span_vars[i]->End(); - UpdateSpans(shared_data, completed, running, true); - - EXPECT_TRUE(ContainsNames(span_names, completed, 1, 4, true)); // s2 s1 s1 - EXPECT_EQ(running.size(), 0); - EXPECT_EQ(completed.size(), 3); - - UpdateSpans(shared_data, completed, running, true); - - EXPECT_EQ(running.size(), 0); - EXPECT_EQ(completed.size(), 0); -} - -/* - * Test for ForceFlush and Shutdown code coverage, which do nothing. - */ -TEST_F(TracezProcessor, FlushShutdown) -{ - auto pre_running_sz = running.size(); - auto pre_completed_sz = completed.size(); - - EXPECT_TRUE(processor->ForceFlush()); - EXPECT_TRUE(processor->Shutdown()); - - UpdateSpans(shared_data, completed, running); - - EXPECT_EQ(pre_running_sz, running.size()); - EXPECT_EQ(pre_completed_sz, completed.size()); -} - -/* - * Test for thread safety when many spans start at the same time. - */ -TEST_F(TracezProcessor, RunningThreadSafety) -{ - std::vector> spans1; - std::vector> spans2; - - std::thread start1(StartManySpans, std::ref(spans1), tracer, 500); - std::thread start2(StartManySpans, std::ref(spans2), tracer, 500); - - start1.join(); - start2.join(); - - EndAllSpans(spans1); - EndAllSpans(spans2); -} - -/* - * Test for thread safety when many spans end at the same time - */ -TEST_F(TracezProcessor, CompletedThreadSafety) -{ - std::vector> spans1; - std::vector> spans2; - - StartManySpans(spans1, tracer, 500); - StartManySpans(spans2, tracer, 500); - - std::thread end1(EndAllSpans, std::ref(spans1)); - std::thread end2(EndAllSpans, std::ref(spans2)); - - end1.join(); - end2.join(); -} - -/* - * Test for thread safety when many snapshots are grabbed at the same time. - */ -TEST_F(TracezProcessor, SnapshotThreadSafety) -{ - std::vector> spans; - - std::thread snap1(GetManySnapshots, std::ref(shared_data), 500); - std::thread snap2(GetManySnapshots, std::ref(shared_data), 500); - - snap1.join(); - snap2.join(); - - StartManySpans(spans, tracer, 500); - - std::thread snap3(GetManySnapshots, std::ref(shared_data), 500); - std::thread snap4(GetManySnapshots, std::ref(shared_data), 500); - - snap3.join(); - snap4.join(); - - EndAllSpans(spans); -} - -/* - * Test for thread safety when many spans start while others are ending. - */ -TEST_F(TracezProcessor, RunningCompletedThreadSafety) -{ - std::vector> spans1; - std::vector> spans2; - - StartManySpans(spans1, tracer, 500); - - std::thread start(StartManySpans, std::ref(spans2), tracer, 500); - std::thread end(EndAllSpans, std::ref(spans1)); - - start.join(); - end.join(); - - EndAllSpans(spans2); -} - -/* - * Test for thread safety when many span start while snapshots are being grabbed. - */ -TEST_F(TracezProcessor, RunningSnapshotThreadSafety) -{ - std::vector> spans; - - std::thread start(StartManySpans, std::ref(spans), tracer, 500); - std::thread snapshots(GetManySnapshots, std::ref(shared_data), 500); - - start.join(); - snapshots.join(); - - EndAllSpans(spans); -} - -/* - * Test for thread safety when many spans end while snapshots are being grabbed. - */ -TEST_F(TracezProcessor, SnapshotCompletedThreadSafety) -{ - std::vector> spans; - - StartManySpans(spans, tracer, 500); - - std::thread snapshots(GetManySnapshots, std::ref(shared_data), 500); - std::thread end(EndAllSpans, std::ref(spans)); - - snapshots.join(); - end.join(); -} - -/* - * Test for thread safety when many spans start and end while snapshots are being grabbed. - */ -TEST_F(TracezProcessor, RunningSnapshotCompletedThreadSafety) -{ - std::vector> spans1; - std::vector> spans2; - - StartManySpans(spans1, tracer, 500); - - std::thread start(StartManySpans, std::ref(spans2), tracer, 500); - std::thread snapshots(GetManySnapshots, std::ref(shared_data), 500); - std::thread end(EndAllSpans, std::ref(spans1)); - - start.join(); - snapshots.join(); - end.join(); - - EndAllSpans(spans2); -} diff --git a/functional/otlp/func_http_main.cc b/functional/otlp/func_http_main.cc index cfe12a2707..98731f1d80 100644 --- a/functional/otlp/func_http_main.cc +++ b/functional/otlp/func_http_main.cc @@ -308,7 +308,6 @@ struct test_case int test_basic(); -#ifdef ENABLE_OTLP_HTTP_SSL_PREVIEW int test_cert_not_found(); int test_cert_invalid(); int test_cert_unreadable(); @@ -321,9 +320,7 @@ int test_client_key_not_found(); int test_client_key_invalid(); int test_client_key_unreadable(); int test_client_key_ok(); -#endif /* ENABLE_OTLP_HTTP_SSL_PREVIEW */ -#ifdef ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW int test_min_tls_unknown(); int test_min_tls_10(); int test_min_tls_11(); @@ -350,10 +347,8 @@ int test_range_tls_12_13(); int test_range_tls_13_10(); int test_range_tls_13_11(); int test_range_tls_13_12(); -#endif /* ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW */ static const test_case all_tests[] = {{"basic", test_basic}, -#ifdef ENABLE_OTLP_HTTP_SSL_PREVIEW {"cert-not-found", test_cert_not_found}, {"cert-invalid", test_cert_invalid}, {"cert-unreadable", test_cert_unreadable}, @@ -366,9 +361,6 @@ static const test_case all_tests[] = {{"basic", test_basic}, {"client-key-invalid", test_client_key_invalid}, {"client-key-unreadable", test_client_key_unreadable}, {"client-key-ok", test_client_key_ok}, -#endif /* ENABLE_OTLP_HTTP_SSL_PREVIEW */ - -#ifdef ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW {"min-tls-unknown", test_min_tls_unknown}, {"min-tls-10", test_min_tls_10}, {"min-tls-11", test_min_tls_11}, @@ -395,7 +387,6 @@ static const test_case all_tests[] = {{"basic", test_basic}, {"range-tls-13-10", test_range_tls_13_10}, {"range-tls-13-11", test_range_tls_13_11}, {"range-tls-13-12", test_range_tls_13_12}, -#endif /* ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW */ {"", nullptr}}; void list_test_cases() @@ -561,8 +552,6 @@ int test_basic() return expect_connection_failed(); } -#ifdef ENABLE_OTLP_HTTP_SSL_PREVIEW - int test_cert_not_found() { otlp::OtlpHttpExporterOptions opts; @@ -908,9 +897,6 @@ int test_client_key_ok() return expect_success(); } -#endif /* ENABLE_OTLP_HTTP_SSL_PREVIEW */ - -#ifdef ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW int test_min_tls_unknown() { @@ -1808,5 +1794,3 @@ int test_range_tls_13_12() // Impossible return expect_connection_failed(); } - -#endif /* ENABLE_OTLP_HTTP_SSL_TLS_PREVIEW */ diff --git a/sdk/include/opentelemetry/sdk/common/global_log_handler.h b/sdk/include/opentelemetry/sdk/common/global_log_handler.h index a36bd4a8a3..14c956b96e 100644 --- a/sdk/include/opentelemetry/sdk/common/global_log_handler.h +++ b/sdk/include/opentelemetry/sdk/common/global_log_handler.h @@ -60,7 +60,7 @@ class LogHandler const char *file, int line, const char *msg, - const sdk::common::AttributeMap &attributes) noexcept = 0; + const opentelemetry::sdk::common::AttributeMap &attributes) noexcept = 0; }; class DefaultLogHandler : public LogHandler @@ -70,7 +70,7 @@ class DefaultLogHandler : public LogHandler const char *file, int line, const char *msg, - const sdk::common::AttributeMap &attributes) noexcept override; + const opentelemetry::sdk::common::AttributeMap &attributes) noexcept override; }; class NoopLogHandler : public LogHandler @@ -80,7 +80,7 @@ class NoopLogHandler : public LogHandler const char *file, int line, const char *msg, - const sdk::common::AttributeMap &error_attributes) noexcept override; + const opentelemetry::sdk::common::AttributeMap &error_attributes) noexcept override; }; /** diff --git a/sdk/include/opentelemetry/sdk/instrumentationscope/instrumentation_scope.h b/sdk/include/opentelemetry/sdk/instrumentationscope/instrumentation_scope.h index 9bae218ba4..35b0dc6863 100644 --- a/sdk/include/opentelemetry/sdk/instrumentationscope/instrumentation_scope.h +++ b/sdk/include/opentelemetry/sdk/instrumentationscope/instrumentation_scope.h @@ -129,7 +129,8 @@ class InstrumentationScope void SetAttribute(nostd::string_view key, const opentelemetry::common::AttributeValue &value) noexcept { - attributes_[std::string(key)] = nostd::visit(common::AttributeConverter(), value); + attributes_[std::string(key)] = + nostd::visit(opentelemetry::sdk::common::AttributeConverter(), value); } private: diff --git a/sdk/include/opentelemetry/sdk/logs/batch_log_record_processor.h b/sdk/include/opentelemetry/sdk/logs/batch_log_record_processor.h index d0b3577491..d6a44df142 100644 --- a/sdk/include/opentelemetry/sdk/logs/batch_log_record_processor.h +++ b/sdk/include/opentelemetry/sdk/logs/batch_log_record_processor.h @@ -72,7 +72,7 @@ class BatchLogRecordProcessor : public LogRecordProcessor * NOTE: Timeout functionality not supported yet. */ bool ForceFlush( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override; + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override; /** * Shuts down the processor and does any cleanup required. Completely drains the buffer/queue of @@ -82,7 +82,7 @@ class BatchLogRecordProcessor : public LogRecordProcessor * NOTE: Timeout functionality not supported yet. */ bool Shutdown( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override; + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override; /** * Class destructor which invokes the Shutdown() method. @@ -143,7 +143,7 @@ class BatchLogRecordProcessor : public LogRecordProcessor const std::chrono::milliseconds scheduled_delay_millis_; const size_t max_export_batch_size_; /* The buffer/queue to which the ended logs are added */ - common::CircularBuffer buffer_; + opentelemetry::sdk::common::CircularBuffer buffer_; std::shared_ptr synchronization_data_; diff --git a/sdk/include/opentelemetry/sdk/logs/exporter.h b/sdk/include/opentelemetry/sdk/logs/exporter.h index bdddc4209c..68c61603fa 100644 --- a/sdk/include/opentelemetry/sdk/logs/exporter.h +++ b/sdk/include/opentelemetry/sdk/logs/exporter.h @@ -62,7 +62,7 @@ class OPENTELEMETRY_EXPORT LogRecordExporter * @return true if the exporter shutdown succeeded, false otherwise */ virtual bool Shutdown( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept = 0; + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept = 0; }; } // namespace logs } // namespace sdk diff --git a/sdk/include/opentelemetry/sdk/logs/logger_context.h b/sdk/include/opentelemetry/sdk/logs/logger_context.h index ee47c56a7f..bab002b231 100644 --- a/sdk/include/opentelemetry/sdk/logs/logger_context.h +++ b/sdk/include/opentelemetry/sdk/logs/logger_context.h @@ -70,7 +70,7 @@ class LoggerContext /** * Shutdown the log processor associated with this tracer provider. */ - bool Shutdown(std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept; + bool Shutdown(std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept; private: // order of declaration is important here - resource object should be destroyed after processor. diff --git a/sdk/include/opentelemetry/sdk/logs/multi_log_record_processor.h b/sdk/include/opentelemetry/sdk/logs/multi_log_record_processor.h index 335da7f668..8ca5cffcca 100644 --- a/sdk/include/opentelemetry/sdk/logs/multi_log_record_processor.h +++ b/sdk/include/opentelemetry/sdk/logs/multi_log_record_processor.h @@ -45,7 +45,7 @@ class MultiLogRecordProcessor : public LogRecordProcessor * @return a result code indicating whether it succeeded, failed or timed out */ bool ForceFlush( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override; + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override; /** * Shuts down the processor and does any cleanup required. @@ -55,7 +55,7 @@ class MultiLogRecordProcessor : public LogRecordProcessor * @return true if the shutdown succeeded, false otherwise */ bool Shutdown( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override; + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override; private: std::vector> processors_; diff --git a/sdk/include/opentelemetry/sdk/logs/processor.h b/sdk/include/opentelemetry/sdk/logs/processor.h index 79a25ff260..57dbdb2130 100644 --- a/sdk/include/opentelemetry/sdk/logs/processor.h +++ b/sdk/include/opentelemetry/sdk/logs/processor.h @@ -46,7 +46,7 @@ class LogRecordProcessor * @return a result code indicating whether it succeeded, failed or timed out */ virtual bool ForceFlush( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept = 0; + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept = 0; /** * Shuts down the processor and does any cleanup required. @@ -56,7 +56,7 @@ class LogRecordProcessor * @return true if the shutdown succeeded, false otherwise */ virtual bool Shutdown( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept = 0; + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept = 0; }; } // namespace logs } // namespace sdk diff --git a/sdk/include/opentelemetry/sdk/logs/simple_log_record_processor.h b/sdk/include/opentelemetry/sdk/logs/simple_log_record_processor.h index e195f89c10..a65c0eb7a9 100644 --- a/sdk/include/opentelemetry/sdk/logs/simple_log_record_processor.h +++ b/sdk/include/opentelemetry/sdk/logs/simple_log_record_processor.h @@ -39,10 +39,10 @@ class SimpleLogRecordProcessor : public LogRecordProcessor void OnEmit(std::unique_ptr &&record) noexcept override; bool ForceFlush( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override; + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override; bool Shutdown( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override; + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override; bool IsShutdown() const noexcept; diff --git a/sdk/include/opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h b/sdk/include/opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h index 4419ee81f3..04293e696f 100644 --- a/sdk/include/opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h +++ b/sdk/include/opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h @@ -93,8 +93,8 @@ void HistogramMerge(HistogramPointData ¤t, merge.record_min_max_ = current.record_min_max_ && delta.record_min_max_; if (merge.record_min_max_) { - merge.min_ = std::min(nostd::get(current.min_), nostd::get(delta.min_)); - merge.max_ = std::max(nostd::get(current.max_), nostd::get(delta.max_)); + merge.min_ = (std::min)(nostd::get(current.min_), nostd::get(delta.min_)); + merge.max_ = (std::max)(nostd::get(current.max_), nostd::get(delta.max_)); } } diff --git a/sdk/include/opentelemetry/sdk/metrics/data/exemplar_data.h b/sdk/include/opentelemetry/sdk/metrics/data/exemplar_data.h index 0420b50aab..efad19b098 100644 --- a/sdk/include/opentelemetry/sdk/metrics/data/exemplar_data.h +++ b/sdk/include/opentelemetry/sdk/metrics/data/exemplar_data.h @@ -26,7 +26,7 @@ using MetricAttributes = opentelemetry::sdk::common::OrderedAttributeMap; class ExemplarData { public: - static ExemplarData Create(std::shared_ptr context, + static ExemplarData Create(std::shared_ptr context, const opentelemetry::common::SystemTimestamp ×tamp, const PointDataAttributes &point_data_attr) { @@ -47,7 +47,7 @@ class ExemplarData * 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_; } + const opentelemetry::trace::SpanContext &GetSpanContext() const noexcept { return context_; } static PointType CreateSumPointData(ValueType value) { @@ -68,13 +68,13 @@ class ExemplarData static PointType CreateDropPointData() { return DropPointData{}; } private: - ExemplarData(std::shared_ptr context, + 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::trace::SpanContext context_; opentelemetry::common::SystemTimestamp timestamp_; PointDataAttributes point_data_attr_; }; 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 index 76f5742ca2..509b2affce 100644 --- a/sdk/include/opentelemetry/sdk/metrics/exemplar/fixed_size_exemplar_reservoir.h +++ b/sdk/include/opentelemetry/sdk/metrics/exemplar/fixed_size_exemplar_reservoir.h @@ -27,7 +27,7 @@ class FixedSizeExemplarReservoir : public ExemplarReservoir FixedSizeExemplarReservoir(size_t size, std::shared_ptr reservoir_cell_selector, std::shared_ptr (ReservoirCell::*map_and_reset_cell)( - const common::OrderedAttributeMap &attributes)) + const opentelemetry::sdk::common::OrderedAttributeMap &attributes)) : storage_(size), reservoir_cell_selector_(reservoir_cell_selector), map_and_reset_cell_(map_and_reset_cell) @@ -96,7 +96,7 @@ class FixedSizeExemplarReservoir : public ExemplarReservoir std::vector storage_; std::shared_ptr reservoir_cell_selector_; std::shared_ptr (ReservoirCell::*map_and_reset_cell_)( - const common::OrderedAttributeMap &attributes); + const opentelemetry::sdk::common::OrderedAttributeMap &attributes); }; } // namespace metrics diff --git a/sdk/include/opentelemetry/sdk/metrics/exemplar/histogram_exemplar_reservoir.h b/sdk/include/opentelemetry/sdk/metrics/exemplar/histogram_exemplar_reservoir.h index bbc032df3b..6f9bf803f0 100644 --- a/sdk/include/opentelemetry/sdk/metrics/exemplar/histogram_exemplar_reservoir.h +++ b/sdk/include/opentelemetry/sdk/metrics/exemplar/histogram_exemplar_reservoir.h @@ -42,7 +42,7 @@ class HistogramExemplarReservoir : public FixedSizeExemplarReservoir HistogramExemplarReservoir(size_t size, std::shared_ptr reservoir_cell_selector, std::shared_ptr (ReservoirCell::*map_and_reset_cell)( - const common::OrderedAttributeMap &attributes)) + const opentelemetry::sdk::common::OrderedAttributeMap &attributes)) : FixedSizeExemplarReservoir(size, reservoir_cell_selector, map_and_reset_cell) {} diff --git a/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir.h b/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir.h index 258e099f0f..3187e0da26 100644 --- a/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir.h +++ b/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir.h @@ -72,7 +72,7 @@ class ExemplarReservoir size_t size, std::shared_ptr reservoir_cell_selector, std::shared_ptr (ReservoirCell::*map_and_reset_cell)( - const common::OrderedAttributeMap &attributes)); + const opentelemetry::sdk::common::OrderedAttributeMap &attributes)); static nostd::shared_ptr GetNoExemplarReservoir(); }; diff --git a/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir_cell.h b/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir_cell.h index 6074393d2d..772c1cc1f1 100644 --- a/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir_cell.h +++ b/sdk/include/opentelemetry/sdk/metrics/exemplar/reservoir_cell.h @@ -137,13 +137,13 @@ class ReservoirCell auto current_ctx = span->GetContext(); if (current_ctx.IsValid()) { - context_.reset(new trace::SpanContext{current_ctx}); + context_.reset(new opentelemetry::trace::SpanContext{current_ctx}); } } } // Cell stores either long or double values, but must not store both - std::shared_ptr context_; + std::shared_ptr context_; nostd::variant value_; opentelemetry::common::SystemTimestamp record_time_; MetricAttributes attributes_; diff --git a/sdk/include/opentelemetry/sdk/metrics/metric_reader.h b/sdk/include/opentelemetry/sdk/metrics/metric_reader.h index 96b34a4427..21249439d6 100644 --- a/sdk/include/opentelemetry/sdk/metrics/metric_reader.h +++ b/sdk/include/opentelemetry/sdk/metrics/metric_reader.h @@ -48,12 +48,12 @@ class MetricReader /** * Shutdown the metric reader. */ - bool Shutdown(std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept; + bool Shutdown(std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept; /** * Force flush the metric read by the reader. */ - bool ForceFlush(std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept; + bool ForceFlush(std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept; /** * Return the status of Metric reader. diff --git a/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h b/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h index 85009a9fcb..8dd820fd95 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/attributes_hashmap.h @@ -28,7 +28,7 @@ const std::string kAggregationCardinalityLimitOverflowError = "Maximum data points for metric stream exceeded. Entry added to overflow"; const std::string kAttributesLimitOverflowKey = "otel.metrics.overflow"; const bool kAttributesLimitOverflowValue = true; -const size_t kOverflowAttributesHash = common::GetHashForAttributeMap( +const size_t kOverflowAttributesHash = opentelemetry::sdk::common::GetHashForAttributeMap( {{kAttributesLimitOverflowKey, kAttributesLimitOverflowValue}}); // precalculated for optimization diff --git a/sdk/include/opentelemetry/sdk/metrics/state/metric_collector.h b/sdk/include/opentelemetry/sdk/metrics/state/metric_collector.h index e94c005ecc..bf0a9ba86b 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/metric_collector.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/metric_collector.h @@ -53,9 +53,9 @@ class MetricCollector : public MetricProducer, public CollectorHandle */ bool Collect(nostd::function_ref callback) noexcept override; - bool ForceFlush(std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept; + bool ForceFlush(std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept; - bool Shutdown(std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept; + bool Shutdown(std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept; private: MeterContext *meter_context_; diff --git a/sdk/include/opentelemetry/sdk/metrics/sync_instruments.h b/sdk/include/opentelemetry/sdk/metrics/sync_instruments.h index 825547a846..f08b629fe2 100644 --- a/sdk/include/opentelemetry/sdk/metrics/sync_instruments.h +++ b/sdk/include/opentelemetry/sdk/metrics/sync_instruments.h @@ -33,61 +33,22 @@ class Synchronous std::unique_ptr storage_; }; -template -class LongCounter : public Synchronous, public opentelemetry::metrics::Counter +class LongCounter : public Synchronous, public opentelemetry::metrics::Counter { public: 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 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, + std::unique_ptr storage); + + void Add(uint64_t value, + const opentelemetry::common::KeyValueIterable &attributes) noexcept override; + + void Add(uint64_t value, const opentelemetry::common::KeyValueIterable &attributes, - 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); - } + const opentelemetry::context::Context &context) noexcept override; + + void Add(uint64_t value) noexcept override; + + void Add(uint64_t value, const opentelemetry::context::Context &context) noexcept override; }; class DoubleCounter : public Synchronous, public opentelemetry::metrics::Counter @@ -139,48 +100,24 @@ class DoubleUpDownCounter : public Synchronous, public opentelemetry::metrics::U void Add(double value, const opentelemetry::context::Context &context) noexcept override; }; -template -class LongHistogram : public Synchronous, public opentelemetry::metrics::Histogram +class LongHistogram : public Synchronous, public opentelemetry::metrics::Histogram { public: 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 Record(T value, + std::unique_ptr storage); + +#if OPENTELEMETRY_ABI_VERSION_NO >= 2 + void Record(uint64_t value, + const opentelemetry::common::KeyValueIterable &attributes) noexcept override; + + void Record(uint64_t value) noexcept override; +#endif + + void Record(uint64_t value, const opentelemetry::common::KeyValueIterable &attributes, - 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); - } + const opentelemetry::context::Context &context) noexcept override; + + void Record(uint64_t value, const opentelemetry::context::Context &context) noexcept override; }; class DoubleHistogram : public Synchronous, public opentelemetry::metrics::Histogram @@ -189,6 +126,13 @@ class DoubleHistogram : public Synchronous, public opentelemetry::metrics::Histo DoubleHistogram(InstrumentDescriptor instrument_descriptor, std::unique_ptr storage); +#if OPENTELEMETRY_ABI_VERSION_NO >= 2 + void Record(double value, + const opentelemetry::common::KeyValueIterable &attributes) noexcept override; + + void Record(double value) noexcept override; +#endif + void Record(double value, const opentelemetry::common::KeyValueIterable &attributes, const opentelemetry::context::Context &context) noexcept override; diff --git a/sdk/include/opentelemetry/sdk/metrics/view/predicate.h b/sdk/include/opentelemetry/sdk/metrics/view/predicate.h index 5346a753ff..cfa1b16eb3 100644 --- a/sdk/include/opentelemetry/sdk/metrics/view/predicate.h +++ b/sdk/include/opentelemetry/sdk/metrics/view/predicate.h @@ -8,7 +8,7 @@ #include "opentelemetry/nostd/string_view.h" #include "opentelemetry/sdk/common/global_log_handler.h" -#if defined(OPENTELEMETRY_HAVE_WORKING_REGEX) +#if OPENTELEMETRY_HAVE_WORKING_REGEX # include #endif diff --git a/sdk/include/opentelemetry/sdk/resource/semantic_conventions.h b/sdk/include/opentelemetry/sdk/resource/semantic_conventions.h index 1b45f80c36..37ad328ae5 100644 --- a/sdk/include/opentelemetry/sdk/resource/semantic_conventions.h +++ b/sdk/include/opentelemetry/sdk/resource/semantic_conventions.h @@ -24,60 +24,7 @@ namespace SemanticConventions /** * The URL of the OpenTelemetry schema for these keys and values. */ -static constexpr const char *kSchemaUrl = "https://opentelemetry.io/schemas/1.22.0"; - -/** - * Uniquely identifies the framework API revision offered by a version ({@code os.version}) of the - * android operating system. More information can be found here. - */ -static constexpr const char *kAndroidOsApiLevel = "android.os.api_level"; - -/** - * Array of brand name and version separated by a space - * - *

    Notes: -

    • This value is intended to be taken from the UA client hints API ({@code - navigator.userAgentData.brands}).
    - */ -static constexpr const char *kBrowserBrands = "browser.brands"; - -/** - * 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 *kBrowserLanguage = "browser.language"; - -/** - * 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 *kBrowserMobile = "browser.mobile"; - -/** - * The platform on which the browser is running - * - *

    Notes: -

    • This value is intended to be taken from the 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 {@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 *kBrowserPlatform = "browser.platform"; +static constexpr const char *kSchemaUrl = "https://opentelemetry.io/schemas/1.23.1"; /** * The cloud account ID the resource is assigned to. @@ -115,7 +62,7 @@ static constexpr const char *kCloudProvider = "cloud.provider"; */ @@ -124,7 +71,7 @@ static constexpr const char *kCloudRegion = "cloud.region"; /** * Cloud provider-specific native identifier of the monitored cloud resource (e.g. an ARN on AWS, a -fully qualified +fully qualified resource ID on Azure, a full resource name on GCP) @@ -142,8 +89,8 @@ the resolved function version, as the same runtime instance may be invokable wit aliases.
  • GCP: The URI of the resource
  • Azure: The Fully Qualified -Resource ID of the invoked function, not the function app, having the form +href="https://docs.microsoft.com/rest/api/resources/resources/get-by-id">Fully Qualified Resource +ID of the invoked function, not the function app, having the form {@code /subscriptions//resourceGroups//providers/Microsoft.Web/sites//functions/}. This means that a span attribute MUST be used, as an Azure function app can host multiple functions @@ -152,6 +99,149 @@ that would usually share a TracerProvider.
  • */ static constexpr const char *kCloudResourceId = "cloud.resource_id"; +/** + * The command used to run the container (i.e. the command name). + * + *

    Notes: +

    • If using embedded credentials or sensitive data, it is recommended to remove them to + prevent potential leakage.
    + */ +static constexpr const char *kContainerCommand = "container.command"; + +/** + * All the command arguments (including the command/executable itself) run by the container. [2] + */ +static constexpr const char *kContainerCommandArgs = "container.command_args"; + +/** + * The full command run by the container as a single string representing the full command. [2] + */ +static constexpr const char *kContainerCommandLine = "container.command_line"; + +/** + * Container ID. Usually a UUID, as for example used to identify Docker + * containers. The UUID might be abbreviated. + */ +static constexpr const char *kContainerId = "container.id"; + +/** + * Runtime specific image identifier. Usually a hash algorithm followed by a UUID. + * + *

    Notes: +

    • Docker defines a sha256 of the image id; {@code container.image.id} corresponds to the +{@code Image} field from the Docker container inspect API +endpoint. K8s defines a link to the container registry repository with digest {@code "imageID": +"registry.azurecr.io +/namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625"}. +The ID is assinged by the container runtime and can vary in different environments. Consider using +{@code oci.manifest.digest} if it is important to identify the same image in different +environments/runtimes.
    + */ +static constexpr const char *kContainerImageId = "container.image.id"; + +/** + * Name of the image the container was built on. + */ +static constexpr const char *kContainerImageName = "container.image.name"; + +/** + * Repo digests of the container image as provided by the container runtime. + * + *

    Notes: +

    • Docker and CRI + report those under the {@code RepoDigests} field.
    + */ +static constexpr const char *kContainerImageRepoDigests = "container.image.repo_digests"; + +/** + * Container image tags. An example can be found in Docker Image + * Inspect. Should be only the {@code } section of the full name for example from {@code + * registry.example.com/my-org/my-image:}. + */ +static constexpr const char *kContainerImageTags = "container.image.tags"; + +/** + * Container name used by container runtime. + */ +static constexpr const char *kContainerName = "container.name"; + +/** + * The container runtime managing this container. + */ +static constexpr const char *kContainerRuntime = "container.runtime"; + +/** + * The digest of the OCI image manifest. For container images specifically is the digest by which +the container image is known. + * + *

    Notes: +

    + */ +static constexpr const char *kOciManifestDigest = "oci.manifest.digest"; + +/** + * Uniquely identifies the framework API revision offered by a version ({@code os.version}) of the + * android operating system. More information can be found here. + */ +static constexpr const char *kAndroidOsApiLevel = "android.os.api_level"; + +/** + * Array of brand name and version separated by a space + * + *

    Notes: +

    • This value is intended to be taken from the UA client hints API ({@code + navigator.userAgentData.brands}).
    + */ +static constexpr const char *kBrowserBrands = "browser.brands"; + +/** + * 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 *kBrowserLanguage = "browser.language"; + +/** + * 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 *kBrowserMobile = "browser.mobile"; + +/** + * The platform on which the browser is running + * + *

    Notes: +

    • This value is intended to be taken from the 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 {@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 *kBrowserPlatform = "browser.platform"; + /** * The ARN of an ECS cluster. @@ -276,83 +366,7 @@ static constexpr const char *kHerokuReleaseCommit = "heroku.release.commit"; static constexpr const char *kHerokuReleaseCreationTimestamp = "heroku.release.creation_timestamp"; /** - * The command used to run the container (i.e. the command name). - * - *

    Notes: -

    • If using embedded credentials or sensitive data, it is recommended to remove them to - prevent potential leakage.
    - */ -static constexpr const char *kContainerCommand = "container.command"; - -/** - * All the command arguments (including the command/executable itself) run by the container. [2] - */ -static constexpr const char *kContainerCommandArgs = "container.command_args"; - -/** - * The full command run by the container as a single string representing the full command. [2] - */ -static constexpr const char *kContainerCommandLine = "container.command_line"; - -/** - * Container ID. Usually a UUID, as for example used to identify Docker - * containers. The UUID might be abbreviated. - */ -static constexpr const char *kContainerId = "container.id"; - -/** - * Runtime specific image identifier. Usually a hash algorithm followed by a UUID. - * - *

    Notes: -

    • Docker defines a sha256 of the image id; {@code container.image.id} corresponds to the -{@code Image} field from the Docker container inspect API -endpoint. K8s defines a link to the container registry repository with digest {@code "imageID": -"registry.azurecr.io -/namespace/service/dockerfile@sha256:bdeabd40c3a8a492eaf9e8e44d0ebbb84bac7ee25ac0cf8a7159d25f62555625"}. -The ID is assinged by the container runtime and can vary in different environments. Consider using -{@code oci.manifest.digest} if it is important to identify the same image in different -environments/runtimes.
    - */ -static constexpr const char *kContainerImageId = "container.image.id"; - -/** - * Name of the image the container was built on. - */ -static constexpr const char *kContainerImageName = "container.image.name"; - -/** - * Repo digests of the container image as provided by the container runtime. - * - *

    Notes: -

    • Docker and CRI - report those under the {@code RepoDigests} field.
    - */ -static constexpr const char *kContainerImageRepoDigests = "container.image.repo_digests"; - -/** - * Container image tags. An example can be found in Docker Image - * Inspect. Should be only the {@code } section of the full name for example from {@code - * registry.example.com/my-org/my-image:}. - */ -static constexpr const char *kContainerImageTags = "container.image.tags"; - -/** - * Container name used by container runtime. - */ -static constexpr const char *kContainerName = "container.name"; - -/** - * The container runtime managing this container. - */ -static constexpr const char *kContainerRuntime = "container.runtime"; - -/** - * Name of the deployment + * Name of the deployment * environment (aka deployment tier). */ static constexpr const char *kDeploymentEnvironment = "deployment.environment"; @@ -499,6 +513,17 @@ static constexpr const char *kHostImageVersion = "host.image.version"; */ static constexpr const char *kHostIp = "host.ip"; +/** + * Available MAC addresses of the host, excluding loopback interfaces. + * + *

    Notes: +

    • MAC Addresses MUST be represented in IEEE RA + hexadecimal form: as hyphen-separated octets in uppercase hexadecimal form from most to least + significant.
    + */ +static constexpr const char *kHostMac = "host.mac"; + /** * Name of the host. On Unix systems, it may contain what the hostname command returns, or the fully * qualified hostname, or another name specified by the user. @@ -555,7 +580,7 @@ static constexpr const char *kK8sClusterName = "k8s.cluster.name"; * A pseudo-ID for the cluster, set to the UID of the {@code kube-system} namespace. * *

    Notes: -

    • K8s does not have support for obtaining a cluster ID. If this is ever +
      • K8s doesn't have support for obtaining a cluster ID. If this is ever added, we will recommend collecting the {@code k8s.cluster.uid} through the official APIs. In the meantime, we are able to use the {@code uid} of the {@code kube-system} namespace as a proxy for cluster ID. Read on for the @@ -672,20 +697,6 @@ static constexpr const char *kK8sCronjobName = "k8s.cronjob.name"; */ static constexpr const char *kK8sCronjobUid = "k8s.cronjob.uid"; -/** - * The digest of the OCI image manifest. For container images specifically is the digest by which -the container image is known. - * - *

        Notes: -

        - */ -static constexpr const char *kOciManifestDigest = "oci.manifest.digest"; - /** * Unique identifier for a particular build or compilation of the operating system. */ diff --git a/sdk/include/opentelemetry/sdk/trace/batch_span_processor.h b/sdk/include/opentelemetry/sdk/trace/batch_span_processor.h index b93631eafa..afbf4486b0 100644 --- a/sdk/include/opentelemetry/sdk/trace/batch_span_processor.h +++ b/sdk/include/opentelemetry/sdk/trace/batch_span_processor.h @@ -69,7 +69,7 @@ class BatchSpanProcessor : public SpanProcessor * NOTE: Timeout functionality not supported yet. */ bool ForceFlush( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override; + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override; /** * Shuts down the processor and does any cleanup required. Completely drains the buffer/queue of @@ -79,7 +79,7 @@ class BatchSpanProcessor : public SpanProcessor * NOTE: Timeout functionality not supported yet. */ bool Shutdown( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override; + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept override; /** * Class destructor which invokes the Shutdown() method. The Shutdown() method is supposed to be @@ -143,7 +143,7 @@ class BatchSpanProcessor : public SpanProcessor const size_t max_export_batch_size_; /* The buffer/queue to which the ended spans are added */ - common::CircularBuffer buffer_; + opentelemetry::sdk::common::CircularBuffer buffer_; std::shared_ptr synchronization_data_; diff --git a/sdk/include/opentelemetry/sdk/trace/exporter.h b/sdk/include/opentelemetry/sdk/trace/exporter.h index f9ed068b64..8795b69837 100644 --- a/sdk/include/opentelemetry/sdk/trace/exporter.h +++ b/sdk/include/opentelemetry/sdk/trace/exporter.h @@ -61,7 +61,7 @@ class OPENTELEMETRY_EXPORT SpanExporter * @return return the status of the operation. */ virtual bool Shutdown( - std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept = 0; + std::chrono::microseconds timeout = (std::chrono::microseconds::max)()) noexcept = 0; }; } // namespace trace } // namespace sdk diff --git a/sdk/include/opentelemetry/sdk/trace/span_data.h b/sdk/include/opentelemetry/sdk/trace/span_data.h index 4e1a52ce5d..ef2c57a092 100644 --- a/sdk/include/opentelemetry/sdk/trace/span_data.h +++ b/sdk/include/opentelemetry/sdk/trace/span_data.h @@ -55,7 +55,8 @@ class SpanDataEvent * Get the attributes for this event * @return the attributes for this event */ - const std::unordered_map &GetAttributes() const noexcept + const std::unordered_map + &GetAttributes() const noexcept { return attribute_map_.GetAttributes(); } @@ -63,7 +64,7 @@ class SpanDataEvent private: std::string name_; opentelemetry::common::SystemTimestamp timestamp_; - common::AttributeMap attribute_map_; + opentelemetry::sdk::common::AttributeMap attribute_map_; }; /** @@ -81,7 +82,8 @@ class SpanDataLink * Get the attributes for this link * @return the attributes for this link */ - const std::unordered_map &GetAttributes() const noexcept + const std::unordered_map + &GetAttributes() const noexcept { return attribute_map_.GetAttributes(); } @@ -94,7 +96,7 @@ class SpanDataLink private: opentelemetry::trace::SpanContext span_context_; - common::AttributeMap attribute_map_; + opentelemetry::sdk::common::AttributeMap attribute_map_; }; /** @@ -210,7 +212,8 @@ class SpanData final : public Recordable * Get the attributes for this span * @return the attributes for this span */ - const std::unordered_map &GetAttributes() const noexcept + const std::unordered_map + &GetAttributes() const noexcept { return attribute_map_.GetAttributes(); } @@ -300,7 +303,7 @@ class SpanData final : public Recordable std::string name_; opentelemetry::trace::StatusCode status_code_{opentelemetry::trace::StatusCode::kUnset}; std::string status_desc_; - common::AttributeMap attribute_map_; + opentelemetry::sdk::common::AttributeMap attribute_map_; std::vector events_; std::vector links_; opentelemetry::trace::SpanKind span_kind_{opentelemetry::trace::SpanKind::kInternal}; diff --git a/sdk/include/opentelemetry/sdk/version/version.h b/sdk/include/opentelemetry/sdk/version/version.h index 16bd121b92..ce34bd399a 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.12.0" +#define OPENTELEMETRY_SDK_VERSION "1.13.0" #include "opentelemetry/version.h" diff --git a/sdk/src/logs/batch_log_record_processor.cc b/sdk/src/logs/batch_log_record_processor.cc index 92536d1c00..44e623e4f7 100644 --- a/sdk/src/logs/batch_log_record_processor.cc +++ b/sdk/src/logs/batch_log_record_processor.cc @@ -104,7 +104,7 @@ bool BatchLogRecordProcessor::ForceFlush(std::chrono::microseconds timeout) noex std::chrono::duration_cast(timeout); if (timeout_steady <= std::chrono::steady_clock::duration::zero()) { - timeout_steady = std::chrono::steady_clock::duration::max(); + timeout_steady = (std::chrono::steady_clock::duration::max)(); } bool result = false; diff --git a/sdk/src/metrics/aggregation/histogram_aggregation.cc b/sdk/src/metrics/aggregation/histogram_aggregation.cc index 3213c27f16..1aa02637ea 100644 --- a/sdk/src/metrics/aggregation/histogram_aggregation.cc +++ b/sdk/src/metrics/aggregation/histogram_aggregation.cc @@ -38,8 +38,8 @@ LongHistogramAggregation::LongHistogramAggregation(const AggregationConfig *aggr 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) @@ -58,8 +58,8 @@ void LongHistogramAggregation::Aggregate(int64_t 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 = BucketBinarySearch(value, point_data_.boundaries_); point_data_.counts_[index] += 1; @@ -118,8 +118,8 @@ DoubleHistogramAggregation::DoubleHistogramAggregation(const AggregationConfig * point_data_.sum_ = 0.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)(); } DoubleHistogramAggregation::DoubleHistogramAggregation(HistogramPointData &&data) @@ -138,8 +138,8 @@ void DoubleHistogramAggregation::Aggregate(double 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 = BucketBinarySearch(value, point_data_.boundaries_); point_data_.counts_[index] += 1; diff --git a/sdk/src/metrics/export/periodic_exporting_metric_reader.cc b/sdk/src/metrics/export/periodic_exporting_metric_reader.cc index dfa4a5ee6b..91f604195e 100644 --- a/sdk/src/metrics/export/periodic_exporting_metric_reader.cc +++ b/sdk/src/metrics/export/periodic_exporting_metric_reader.cc @@ -133,7 +133,7 @@ bool PeriodicExportingMetricReader::OnForceFlush(std::chrono::microseconds timeo std::chrono::duration_cast(wait_timeout); if (timeout_steady <= std::chrono::steady_clock::duration::zero()) { - timeout_steady = std::chrono::steady_clock::duration::max(); + timeout_steady = (std::chrono::steady_clock::duration::max)(); } bool result = false; diff --git a/sdk/src/metrics/instrument_metadata_validator.cc b/sdk/src/metrics/instrument_metadata_validator.cc index ff963c3dd1..0b00404447 100644 --- a/sdk/src/metrics/instrument_metadata_validator.cc +++ b/sdk/src/metrics/instrument_metadata_validator.cc @@ -8,7 +8,7 @@ #include #include -#if defined(OPENTELEMETRY_HAVE_WORKING_REGEX) +#if OPENTELEMETRY_HAVE_WORKING_REGEX # include #endif diff --git a/sdk/src/metrics/meter.cc b/sdk/src/metrics/meter.cc index 4f7c4c1207..0ae3776111 100644 --- a/sdk/src/metrics/meter.cc +++ b/sdk/src/metrics/meter.cc @@ -52,7 +52,7 @@ nostd::unique_ptr> Meter::CreateUInt64Counter( std::string{unit.data(), unit.size()}, InstrumentType::kCounter, InstrumentValueType::kLong}; auto storage = RegisterSyncMetricStorage(instrument_descriptor); return nostd::unique_ptr>( - new LongCounter(instrument_descriptor, std::move(storage))); + new LongCounter(instrument_descriptor, std::move(storage))); } nostd::unique_ptr> Meter::CreateDoubleCounter( @@ -138,7 +138,7 @@ nostd::unique_ptr> Meter::CreateUInt64Histogram( InstrumentValueType::kLong}; auto storage = RegisterSyncMetricStorage(instrument_descriptor); return nostd::unique_ptr>{ - new LongHistogram(instrument_descriptor, std::move(storage))}; + new LongHistogram(instrument_descriptor, std::move(storage))}; } nostd::unique_ptr> Meter::CreateDoubleHistogram( diff --git a/sdk/src/metrics/meter_context.cc b/sdk/src/metrics/meter_context.cc index 7a299bfc63..79f254fa93 100644 --- a/sdk/src/metrics/meter_context.cc +++ b/sdk/src/metrics/meter_context.cc @@ -136,7 +136,7 @@ bool MeterContext::ForceFlush(std::chrono::microseconds timeout) noexcept // Simultaneous flush not allowed. const std::lock_guard locked(forceflush_lock_); // Convert to nanos to prevent overflow - auto timeout_ns = std::chrono::nanoseconds::max(); + auto timeout_ns = (std::chrono::nanoseconds::max)(); if (std::chrono::duration_cast(timeout_ns) > timeout) { timeout_ns = std::chrono::duration_cast(timeout); @@ -144,7 +144,7 @@ bool MeterContext::ForceFlush(std::chrono::microseconds timeout) noexcept 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(); + 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) diff --git a/sdk/src/metrics/sync_instruments.cc b/sdk/src/metrics/sync_instruments.cc index 6fe72b55bf..bdeff150ae 100644 --- a/sdk/src/metrics/sync_instruments.cc +++ b/sdk/src/metrics/sync_instruments.cc @@ -10,27 +10,93 @@ 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 constructing LongCounter." + << "The metric storage is invalid for " << instrument_descriptor.name_); + } +} + +void LongCounter::Add(uint64_t value, + const opentelemetry::common::KeyValueIterable &attributes) noexcept +{ + auto context = opentelemetry::context::Context{}; + if (!storage_) + { + OTEL_INTERNAL_LOG_WARN("[LongCounter::Add(V,A)] Value not recorded - invalid storage for: " + << instrument_descriptor_.name_); + return; + } + return storage_->RecordLong(value, attributes, context); +} + +void LongCounter::Add(uint64_t value, + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept +{ + if (!storage_) + { + OTEL_INTERNAL_LOG_WARN("[LongCounter::Add(V,A,C)] Value not recorded - invalid storage for: " + << instrument_descriptor_.name_); + return; + } + return storage_->RecordLong(value, attributes, context); +} + +void LongCounter::Add(uint64_t value) noexcept +{ + auto context = opentelemetry::context::Context{}; + if (!storage_) + { + OTEL_INTERNAL_LOG_WARN("[LongCounter::Add(V)] Value not recorded - invalid storage for: " + << instrument_descriptor_.name_); + return; + } + return storage_->RecordLong(value, context); +} + +void LongCounter::Add(uint64_t value, const opentelemetry::context::Context &context) noexcept +{ + if (!storage_) + { + OTEL_INTERNAL_LOG_WARN("[LongCounter::Add(V,C)] Value not recorded - invalid storage for: " + << instrument_descriptor_.name_); + return; + } + return storage_->RecordLong(value, context); +} + DoubleCounter::DoubleCounter(InstrumentDescriptor instrument_descriptor, std::unique_ptr storage) : Synchronous(instrument_descriptor, std::move(storage)) { if (!storage_) { - OTEL_INTERNAL_LOG_ERROR( - "[DoubleCounter::DoubleCounter] - Error during constructing DoubleCounter." - << "The metric storage is invalid" - << "No value will be added"); + OTEL_INTERNAL_LOG_ERROR("[DoubleCounter::DoubleCounter] - Error constructing DoubleCounter." + << "The metric storage is invalid for " << instrument_descriptor.name_); } } void DoubleCounter::Add(double value, const opentelemetry::common::KeyValueIterable &attributes) noexcept { - auto context = opentelemetry::context::Context{}; + if (value < 0) + { + OTEL_INTERNAL_LOG_WARN("[DoubleCounter::Add(V,A)] Value not recorded - negative value for: " + << instrument_descriptor_.name_); + return; + } if (!storage_) { + OTEL_INTERNAL_LOG_WARN("[DoubleCounter::Add(V,A)] Value not recorded - invalid storage for: " + << instrument_descriptor_.name_); return; } + auto context = opentelemetry::context::Context{}; return storage_->RecordDouble(value, attributes, context); } @@ -38,8 +104,16 @@ void DoubleCounter::Add(double value, const opentelemetry::common::KeyValueIterable &attributes, const opentelemetry::context::Context &context) noexcept { + if (value < 0) + { + OTEL_INTERNAL_LOG_WARN("[DoubleCounter::Add(V,A,C)] Value not recorded - negative value for: " + << instrument_descriptor_.name_); + return; + } if (!storage_) { + OTEL_INTERNAL_LOG_WARN("[DoubleCounter::Add(V,A,C)] Value not recorded - invalid storage for: " + << instrument_descriptor_.name_); return; } return storage_->RecordDouble(value, attributes, context); @@ -47,18 +121,34 @@ void DoubleCounter::Add(double value, void DoubleCounter::Add(double value) noexcept { - auto context = opentelemetry::context::Context{}; + if (value < 0) + { + OTEL_INTERNAL_LOG_WARN("[DoubleCounter::Add(V)] Value not recorded - negative value for: " + << instrument_descriptor_.name_); + return; + } if (!storage_) { + OTEL_INTERNAL_LOG_WARN("[DoubleCounter::Add(V)] Value not recorded - invalid storage for: " + << instrument_descriptor_.name_); return; } + auto context = opentelemetry::context::Context{}; return storage_->RecordDouble(value, context); } void DoubleCounter::Add(double value, const opentelemetry::context::Context &context) noexcept { + if (value < 0) + { + OTEL_INTERNAL_LOG_WARN("[DoubleCounter::Add(V)] Value not recorded - negative value for: " + << instrument_descriptor_.name_); + return; + } if (!storage_) { + OTEL_INTERNAL_LOG_WARN("[DoubleCounter::Add(V,C)] Value not recorded - invalid storage for: " + << instrument_descriptor_.name_); return; } return storage_->RecordDouble(value, context); @@ -71,9 +161,8 @@ LongUpDownCounter::LongUpDownCounter(InstrumentDescriptor instrument_descriptor, if (!storage_) { OTEL_INTERNAL_LOG_ERROR( - "[LongUpDownCounter::LongUpDownCounter] - Error during constructing LongUpDownCounter." - << "The metric storage is invalid" - << "No value will be added"); + "[LongUpDownCounter::LongUpDownCounter] - Error constructing LongUpDownCounter." + << "The metric storage is invalid for " << instrument_descriptor.name_); } } @@ -83,6 +172,9 @@ void LongUpDownCounter::Add(int64_t value, auto context = opentelemetry::context::Context{}; if (!storage_) { + OTEL_INTERNAL_LOG_WARN( + "[LongUpDownCounter::Add(V,A)] Value not recorded - invalid storage for: " + << instrument_descriptor_.name_); return; } return storage_->RecordLong(value, attributes, context); @@ -94,6 +186,9 @@ void LongUpDownCounter::Add(int64_t value, { if (!storage_) { + OTEL_INTERNAL_LOG_WARN( + "[LongUpDownCounter::Add(V,A,C)] Value not recorded - invalid storage for: " + << instrument_descriptor_.name_); return; } return storage_->RecordLong(value, attributes, context); @@ -104,6 +199,8 @@ void LongUpDownCounter::Add(int64_t value) noexcept auto context = opentelemetry::context::Context{}; if (!storage_) { + OTEL_INTERNAL_LOG_WARN("[LongUpDownCounter::Add(V)] Value not recorded - invalid storage for: " + << instrument_descriptor_.name_); return; } return storage_->RecordLong(value, context); @@ -113,6 +210,9 @@ void LongUpDownCounter::Add(int64_t value, const opentelemetry::context::Context { if (!storage_) { + OTEL_INTERNAL_LOG_WARN( + "[LongUpDownCounter::Add(V,C)] Value not recorded - invalid storage for: " + << instrument_descriptor_.name_); return; } return storage_->RecordLong(value, context); @@ -125,16 +225,20 @@ DoubleUpDownCounter::DoubleUpDownCounter(InstrumentDescriptor instrument_descrip if (!storage_) { OTEL_INTERNAL_LOG_ERROR( - "[DoubleUpDownCounter::DoubleUpDownCounter] - Error during constructing " - "DoubleUpDownCounter." - << "The metric storage is invalid" - << "No value will be added"); + "[DoubleUpDownCounter::DoubleUpDownCounter] - Error constructing DoubleUpDownCounter." + << "The metric storage is invalid for " << instrument_descriptor.name_); } } void DoubleUpDownCounter::Add(double value, const opentelemetry::common::KeyValueIterable &attributes) noexcept { + if (!storage_) + { + OTEL_INTERNAL_LOG_WARN( + "[DoubleUpDownCounter::Add(V,A)] Value not recorded - invalid storage for: " + << instrument_descriptor_.name_); + } auto context = opentelemetry::context::Context{}; return storage_->RecordDouble(value, attributes, context); } @@ -145,6 +249,9 @@ void DoubleUpDownCounter::Add(double value, { if (!storage_) { + OTEL_INTERNAL_LOG_WARN( + "[DoubleUpDownCounter::Add(V,A,C)] Value not recorded - invalid storage for: " + << instrument_descriptor_.name_); return; } return storage_->RecordDouble(value, attributes, context); @@ -154,6 +261,9 @@ void DoubleUpDownCounter::Add(double value) noexcept { if (!storage_) { + OTEL_INTERNAL_LOG_WARN( + "[DoubleUpDownCounter::Add(V)] Value not recorded - invalid storage for: " + << instrument_descriptor_.name_); return; } auto context = opentelemetry::context::Context{}; @@ -164,11 +274,77 @@ void DoubleUpDownCounter::Add(double value, const opentelemetry::context::Contex { if (!storage_) { + OTEL_INTERNAL_LOG_WARN( + "[DoubleUpDownCounter::Add(V,C)] Value not recorded - invalid storage for: " + << instrument_descriptor_.name_); return; } 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 constructing LongHistogram." + << "The metric storage is invalid for " << instrument_descriptor.name_); + } +} + +void LongHistogram::Record(uint64_t value, + const opentelemetry::common::KeyValueIterable &attributes, + const opentelemetry::context::Context &context) noexcept +{ + if (!storage_) + { + OTEL_INTERNAL_LOG_WARN( + "[LongHistogram::Record(V,A,C)] Value not recorded - invalid storage for: " + << instrument_descriptor_.name_); + return; + } + return storage_->RecordLong(value, attributes, context); +} + +void LongHistogram::Record(uint64_t value, const opentelemetry::context::Context &context) noexcept +{ + if (!storage_) + { + OTEL_INTERNAL_LOG_WARN("[LongHistogram::Record(V,C)] Value not recorded - invalid storage for: " + << instrument_descriptor_.name_); + return; + } + return storage_->RecordLong(value, context); +} + +#if OPENTELEMETRY_ABI_VERSION_NO >= 2 +void LongHistogram::Record(uint64_t value, + const opentelemetry::common::KeyValueIterable &attributes) noexcept +{ + if (!storage_) + { + OTEL_INTERNAL_LOG_WARN("[LongHistogram::Record(V,A)] Value not recorded - invalid storage for: " + << instrument_descriptor_.name_); + return; + } + auto context = opentelemetry::context::Context{}; + return storage_->RecordLong(value, attributes, context); +} + +void LongHistogram::Record(uint64_t value) noexcept +{ + if (!storage_) + { + OTEL_INTERNAL_LOG_WARN("[LongHistogram::Record(V)] Value not recorded - invalid storage for: " + << instrument_descriptor_.name_); + return; + } + auto context = opentelemetry::context::Context{}; + return storage_->RecordLong(value, context); +} +#endif + DoubleHistogram::DoubleHistogram(InstrumentDescriptor instrument_descriptor, std::unique_ptr storage) : Synchronous(instrument_descriptor, std::move(storage)) @@ -176,9 +352,8 @@ DoubleHistogram::DoubleHistogram(InstrumentDescriptor instrument_descriptor, if (!storage_) { OTEL_INTERNAL_LOG_ERROR( - "[DoubleHistogram::DoubleHistogram] - Error during constructing DoubleHistogram." - << "The metric storage is invalid" - << "No value will be added"); + "[DoubleHistogram::DoubleHistogram] - Error constructing DoubleHistogram." + << "The metric storage is invalid for " << instrument_descriptor.name_); } } @@ -186,15 +361,17 @@ void DoubleHistogram::Record(double value, const opentelemetry::common::KeyValueIterable &attributes, const opentelemetry::context::Context &context) noexcept { - if (!storage_) + if (value < 0) { + OTEL_INTERNAL_LOG_WARN( + "[DoubleHistogram::Record(V,A,C)] Value not recorded - negative value for: " + << instrument_descriptor_.name_); return; } - if (value < 0 || std::isnan(value) || std::isinf(value)) + if (!storage_) { OTEL_INTERNAL_LOG_WARN( - "[DoubleHistogram::Record(value, attributes)] negative/nan/infinite value provided to " - "histogram Name:" + "[DoubleHistogram::Record(V,A,C)] Value not recorded - invalid storage for: " << instrument_descriptor_.name_); return; } @@ -203,19 +380,63 @@ void DoubleHistogram::Record(double value, void DoubleHistogram::Record(double value, const opentelemetry::context::Context &context) noexcept { + if (value < 0) + { + OTEL_INTERNAL_LOG_WARN( + "[DoubleHistogram::Record(V,C)] Value not recorded - negative value for: " + << instrument_descriptor_.name_); + return; + } if (!storage_) { + OTEL_INTERNAL_LOG_WARN( + "[DoubleHistogram::Record(V,C)] Value not recorded - invalid storage for: " + << instrument_descriptor_.name_); + return; + } + return storage_->RecordDouble(value, context); +} + +#if OPENTELEMETRY_ABI_VERSION_NO >= 2 +void DoubleHistogram::Record(double value, + const opentelemetry::common::KeyValueIterable &attributes) noexcept +{ + if (value < 0) + { + OTEL_INTERNAL_LOG_WARN( + "[DoubleHistogram::Record(V,A)] Value not recorded - negative value for: " + << instrument_descriptor_.name_); return; } - if (value < 0 || std::isnan(value) || std::isinf(value)) + if (!storage_) { OTEL_INTERNAL_LOG_WARN( - "[DoubleHistogram::Record(value)] negative/nan/infinite value provided to histogram Name:" + "[DoubleHistogram::Record(V,A)] Value not recorded - invalid storage for: " << instrument_descriptor_.name_); return; } + auto context = opentelemetry::context::Context{}; + return storage_->RecordDouble(value, attributes, context); +} + +void DoubleHistogram::Record(double value) noexcept +{ + if (value < 0) + { + OTEL_INTERNAL_LOG_WARN("[DoubleHistogram::Record(V)] Value not recorded - negative value for: " + << instrument_descriptor_.name_); + return; + } + if (!storage_) + { + OTEL_INTERNAL_LOG_WARN("[DoubleHistogram::Record(V)] Value not recorded - invalid storage for: " + << instrument_descriptor_.name_); + return; + } + auto context = opentelemetry::context::Context{}; return storage_->RecordDouble(value, context); } +#endif } // namespace metrics } // namespace sdk diff --git a/sdk/src/trace/batch_span_processor.cc b/sdk/src/trace/batch_span_processor.cc index 719a072e64..d5b96f2cc8 100644 --- a/sdk/src/trace/batch_span_processor.cc +++ b/sdk/src/trace/batch_span_processor.cc @@ -102,7 +102,7 @@ bool BatchSpanProcessor::ForceFlush(std::chrono::microseconds timeout) noexcept std::chrono::duration_cast(timeout); if (timeout_steady <= std::chrono::steady_clock::duration::zero()) { - timeout_steady = std::chrono::steady_clock::duration::max(); + timeout_steady = (std::chrono::steady_clock::duration::max)(); } bool result = false; diff --git a/sdk/src/trace/span.h b/sdk/src/trace/span.h index eb603b9025..7fe86bd3f5 100644 --- a/sdk/src/trace/span.h +++ b/sdk/src/trace/span.h @@ -26,7 +26,7 @@ class Span final : public opentelemetry::trace::Span ~Span() override; - // trace::Span + // opentelemetry::trace::Span void SetAttribute(nostd::string_view key, const opentelemetry::common::AttributeValue &value) noexcept override; diff --git a/sdk/src/trace/tracer.cc b/sdk/src/trace/tracer.cc index 6ca7b37df5..c722d60326 100644 --- a/sdk/src/trace/tracer.cc +++ b/sdk/src/trace/tracer.cc @@ -43,6 +43,13 @@ nostd::shared_ptr Tracer::StartSpan( { parent_context = span_context; } + else + { + if (opentelemetry::trace::IsRootSpan(context)) + { + parent_context = opentelemetry::trace::SpanContext{false, false}; + } + } } opentelemetry::trace::TraceId trace_id; diff --git a/sdk/src/version/version.cc b/sdk/src/version/version.cc index fb2db64c30..3154140120 100644 --- a/sdk/src/version/version.cc +++ b/sdk/src/version/version.cc @@ -12,13 +12,13 @@ namespace sdk namespace version { const int major_version = 1; -const int minor_version = 12; +const int minor_version = 13; const int patch_version = 0; const char *pre_release = "NONE"; const char *build_metadata = "NONE"; -const char *short_version = "1.12.0"; -const char *full_version = "1.12.0-NONE-NONE"; -const char *build_date = "Mon 16 Oct 2023 07:42:23 AM UTC"; +const char *short_version = "1.13.0"; +const char *full_version = "1.13.0-NONE-NONE"; +const char *build_date = "Wed Dec 6 00:27:20 UTC 2023"; } // namespace version } // namespace sdk diff --git a/sdk/test/metrics/histogram_test.cc b/sdk/test/metrics/histogram_test.cc index a11a9c1f59..4daceb685b 100644 --- a/sdk/test/metrics/histogram_test.cc +++ b/sdk/test/metrics/histogram_test.cc @@ -13,7 +13,7 @@ #include -#if defined(OPENTELEMETRY_HAVE_WORKING_REGEX) +#if OPENTELEMETRY_HAVE_WORKING_REGEX # include #endif @@ -73,7 +73,7 @@ TEST(Histogram, Double) actual.counts_); } -#if (OPENTELEMETRY_HAVE_WORKING_REGEX) +#if OPENTELEMETRY_HAVE_WORKING_REGEX // FIXME - View Preficate search is only supported through regex TEST(Histogram, DoubleCustomBuckets) { @@ -188,7 +188,7 @@ TEST(Histogram, UInt64) actual.counts_); } -#if (OPENTELEMETRY_HAVE_WORKING_REGEX) +#if OPENTELEMETRY_HAVE_WORKING_REGEX // FIXME - View Preficate search is only supported through regex TEST(Histogram, UInt64CustomBuckets) { diff --git a/sdk/test/metrics/sync_instruments_test.cc b/sdk/test/metrics/sync_instruments_test.cc index a1ff2325e2..723d29f20e 100644 --- a/sdk/test/metrics/sync_instruments_test.cc +++ b/sdk/test/metrics/sync_instruments_test.cc @@ -24,7 +24,7 @@ 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)); + LongCounter counter(instrument_descriptor, std::move(metric_storage)); counter.Add(10); counter.Add(10, opentelemetry::context::Context{}); @@ -71,6 +71,18 @@ TEST(SyncInstruments, LongUpDownCounter) counter.Add(10, opentelemetry::common::KeyValueIterableView({})); counter.Add(10, opentelemetry::common::KeyValueIterableView({}), opentelemetry::context::Context{}); + + // negative values + counter.Add(-10); + counter.Add(-10, opentelemetry::context::Context{}); + + 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(-10, opentelemetry::common::KeyValueIterableView({})); + counter.Add(-10, opentelemetry::common::KeyValueIterableView({}), + opentelemetry::context::Context{}); } TEST(SyncInstruments, DoubleUpDownCounter) @@ -98,9 +110,8 @@ TEST(SyncInstruments, LongHistogram) InstrumentDescriptor instrument_descriptor = { "long_histogram", "description", "1", InstrumentType::kHistogram, InstrumentValueType::kLong}; std::unique_ptr metric_storage(new SyncMultiMetricStorage()); - LongHistogram histogram(instrument_descriptor, std::move(metric_storage)); + LongHistogram histogram(instrument_descriptor, std::move(metric_storage)); histogram.Record(10, opentelemetry::context::Context{}); - histogram.Record(-10, opentelemetry::context::Context{}); // This is ignored histogram.Record(10, opentelemetry::common::KeyValueIterableView({{"abc", "123"}, {"xyz", "456"}}), diff --git a/sdk/test/metrics/view_registry_test.cc b/sdk/test/metrics/view_registry_test.cc index 49e475a9f1..fb188e7124 100644 --- a/sdk/test/metrics/view_registry_test.cc +++ b/sdk/test/metrics/view_registry_test.cc @@ -8,7 +8,7 @@ #include -#if defined(OPENTELEMETRY_HAVE_WORKING_REGEX) +#if OPENTELEMETRY_HAVE_WORKING_REGEX # include #endif diff --git a/sdk/test/trace/tracer_test.cc b/sdk/test/trace/tracer_test.cc index 36cc135a1d..61ad24be1d 100644 --- a/sdk/test/trace/tracer_test.cc +++ b/sdk/test/trace/tracer_test.cc @@ -1008,6 +1008,26 @@ TEST(Tracer, WithActiveSpan) spans = span_data->GetSpans(); ASSERT_EQ(1, spans.size()); EXPECT_EQ("span 2", spans.at(0)->GetName()); + EXPECT_EQ(spans.at(0).get()->GetParentSpanId(), span_first->GetContext().span_id()); + EXPECT_EQ(spans.at(0).get()->GetTraceId(), span_first->GetContext().trace_id()); + + { + trace_api::StartSpanOptions options; + opentelemetry::context::Context c1; + c1 = c1.SetValue(opentelemetry::trace::kIsRootSpanKey, true); + options.parent = c1; + auto root_span = tracer->StartSpan("span root", options); + + spans = span_data->GetSpans(); + ASSERT_EQ(0, spans.size()); + + root_span->End(); + } + spans = span_data->GetSpans(); + ASSERT_EQ(1, spans.size()); + EXPECT_EQ("span root", spans.at(0)->GetName()); + EXPECT_EQ(spans.at(0).get()->GetParentSpanId(), opentelemetry::trace::SpanId()); + EXPECT_NE(spans.at(0).get()->GetTraceId(), span_first->GetContext().trace_id()); span_first->End(); } diff --git a/test_common/include/opentelemetry/test_common/ext/http/client/nosend/http_client_nosend.h b/test_common/include/opentelemetry/test_common/ext/http/client/nosend/http_client_nosend.h index 7dddde13d4..50becac5dc 100644 --- a/test_common/include/opentelemetry/test_common/ext/http/client/nosend/http_client_nosend.h +++ b/test_common/include/opentelemetry/test_common/ext/http/client/nosend/http_client_nosend.h @@ -36,12 +36,10 @@ class Request : public opentelemetry::ext::http::client::Request method_ = method; } -#ifdef ENABLE_HTTP_SSL_PREVIEW void SetSslOptions(const HttpSslOptions &ssl_options) noexcept override { ssl_options_ = ssl_options; } -#endif /* ENABLE_HTTP_SSL_PREVIEW */ void SetBody(opentelemetry::ext::http::client::Body &body) noexcept override { @@ -65,9 +63,7 @@ class Request : public opentelemetry::ext::http::client::Request public: opentelemetry::ext::http::client::Method method_; -#ifdef ENABLE_HTTP_SSL_PREVIEW opentelemetry::ext::http::client::HttpSslOptions ssl_options_; -#endif /* ENABLE_HTTP_SSL_PREVIEW */ opentelemetry::ext::http::client::Body body_; opentelemetry::ext::http::client::Headers headers_; std::string uri_; diff --git a/third_party/googletest b/third_party/googletest index 58d77fa807..b796f7d446 160000 --- a/third_party/googletest +++ b/third_party/googletest @@ -1 +1 @@ -Subproject commit 58d77fa8070e8cec2dc1ed015d66b454c8d78850 +Subproject commit b796f7d44681514f58a683a3a71ff17c94edb0c1 diff --git a/third_party_release b/third_party_release index 9fae12fc31..817d9b728e 100644 --- a/third_party_release +++ b/third_party_release @@ -16,7 +16,7 @@ gRPC=v1.49.2 abseil=20220623.1 benchmark=v1.7.1 -googletest=release-1.13.0 +googletest=1.13.0 ms-gsl=v3.1.0-67-g6f45293 nlohmann-json=v3.11.2 opentelemetry-proto=v1.0.0