diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index b40b8e5a73..000a0eb0d0 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -23,10 +23,10 @@ jobs: sudo ./ci/setup_cmake.sh sudo ./ci/setup_ci_environment.sh - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v2 with: languages: cpp - name: Autobuild - uses: github/codeql-action/autobuild@v1 + uses: github/codeql-action/autobuild@v2 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v2 diff --git a/api/include/opentelemetry/baggage/baggage.h b/api/include/opentelemetry/baggage/baggage.h index 7f904f09a7..259fd7f3b6 100644 --- a/api/include/opentelemetry/baggage/baggage.h +++ b/api/include/opentelemetry/baggage/baggage.h @@ -249,7 +249,9 @@ class Baggage }; auto from_hex = [](char c) -> char { - return std::isdigit(c) ? c - '0' : std::toupper(c) - 'A' + 10; + // c - '0' produces integer type which could trigger error/warning when casting to char, + // but the cast is safe here. + return static_cast(std::isdigit(c) ? c - '0' : std::toupper(c) - 'A' + 10); }; std::string ret; diff --git a/api/include/opentelemetry/context/propagation/composite_propagator.h b/api/include/opentelemetry/context/propagation/composite_propagator.h index 85ad97b0fc..d7a6cbda17 100644 --- a/api/include/opentelemetry/context/propagation/composite_propagator.h +++ b/api/include/opentelemetry/context/propagation/composite_propagator.h @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +#pragma once + #include #include #include diff --git a/ci/do_ci.sh b/ci/do_ci.sh index 008e983842..14749500ec 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -222,8 +222,8 @@ elif [[ "$1" == "bazel.legacy.test" ]]; then elif [[ "$1" == "bazel.noexcept" ]]; then # there are some exceptions and error handling code from the Prometheus and Jaeger Clients # that make this test always fail. ignore Prometheus and Jaeger exporters in the noexcept here. - bazel $BAZEL_STARTUP_OPTIONS build --copt=-fno-exceptions --build_tag_filters=-jaeger $BAZEL_OPTIONS -- //... -//exporters/prometheus/... -//exporters/jaeger/... - bazel $BAZEL_STARTUP_OPTIONS test --copt=-fno-exceptions --build_tag_filters=-jaeger $BAZEL_TEST_OPTIONS -- //... -//exporters/prometheus/... -//exporters/jaeger/... + bazel $BAZEL_STARTUP_OPTIONS build --copt=-fno-exceptions --build_tag_filters=-jaeger $BAZEL_OPTIONS -- //... -//exporters/prometheus/... -//exporters/jaeger/... -//examples/prometheus/... + bazel $BAZEL_STARTUP_OPTIONS test --copt=-fno-exceptions --build_tag_filters=-jaeger $BAZEL_TEST_OPTIONS -- //... -//exporters/prometheus/... -//exporters/jaeger/... -//examples/prometheus/... exit 0 elif [[ "$1" == "bazel.nortti" ]]; then # there are some exceptions and error handling code from the Prometheus and Jaeger Clients diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index db0fe159be..2367918c7e 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -15,6 +15,9 @@ endif() if(WITH_ZIPKIN) add_subdirectory(zipkin) endif() +if(WITH_PROMETHEUS AND NOT WITH_METRICS_PREVIEW) + add_subdirectory(prometheus) +endif() add_subdirectory(plugin) add_subdirectory(simple) add_subdirectory(batch) diff --git a/examples/prometheus/BUILD b/examples/prometheus/BUILD new file mode 100644 index 0000000000..edbfde61e6 --- /dev/null +++ b/examples/prometheus/BUILD @@ -0,0 +1,14 @@ +cc_binary( + name = "prometheus_example", + srcs = [ + "main.cc", + ], + linkopts = ["-pthread"], + tags = ["ostream"], + deps = [ + "//api", + "//examples/common/metrics_foo_library:common_metrics_foo_library", + "//exporters/prometheus:prometheus_exporter", + "//sdk/src/metrics", + ], +) diff --git a/examples/prometheus/CMakeLists.txt b/examples/prometheus/CMakeLists.txt new file mode 100644 index 0000000000..b377920dee --- /dev/null +++ b/examples/prometheus/CMakeLists.txt @@ -0,0 +1,5 @@ +include_directories(${CMAKE_SOURCE_DIR}/exporters/prometheus/include) +add_executable(prometheus_example main.cc) +target_link_libraries( + prometheus_example ${CMAKE_THREAD_LIBS_INIT} opentelemetry_metrics + prometheus_exporter opentelemetry_resources common_metrics_foo_library) diff --git a/examples/prometheus/main.cc b/examples/prometheus/main.cc new file mode 100644 index 0000000000..77a648f55d --- /dev/null +++ b/examples/prometheus/main.cc @@ -0,0 +1,118 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#ifndef ENABLE_METRICS_PREVIEW +# include +# include +# include "opentelemetry/exporters/prometheus/exporter.h" +# include "opentelemetry/metrics/provider.h" +# include "opentelemetry/sdk/metrics/aggregation/default_aggregation.h" +# include "opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h" +# include "opentelemetry/sdk/metrics/export/periodic_exporting_metric_reader.h" +# include "opentelemetry/sdk/metrics/meter.h" +# include "opentelemetry/sdk/metrics/meter_provider.h" + +# ifdef BAZEL_BUILD +# include "examples/common/metrics_foo_library/foo_library.h" +# else +# include "metrics_foo_library/foo_library.h" +# endif + +namespace metrics_sdk = opentelemetry::sdk::metrics; +namespace nostd = opentelemetry::nostd; +namespace common = opentelemetry::common; +namespace metrics_exporter = opentelemetry::exporter::metrics; +namespace metrics_api = opentelemetry::metrics; + +namespace +{ + +void initMetrics(const std::string &name, const std::string &addr) +{ + metrics_exporter::PrometheusExporterOptions opts; + if (!addr.empty()) + { + opts.url = addr; + } + std::puts("PrometheusExporter example program running ..."); + + std::unique_ptr exporter{ + new metrics_exporter::PrometheusExporter(opts)}; + + std::string version{"1.2.0"}; + std::string schema{"https://opentelemetry.io/schemas/1.2.0"}; + + // Initialize and set the global MeterProvider + metrics_sdk::PeriodicExportingMetricReaderOptions options; + options.export_interval_millis = std::chrono::milliseconds(1000); + options.export_timeout_millis = std::chrono::milliseconds(500); + std::unique_ptr reader{ + new metrics_sdk::PeriodicExportingMetricReader(std::move(exporter), options)}; + auto provider = std::shared_ptr(new metrics_sdk::MeterProvider()); + auto p = std::static_pointer_cast(provider); + p->AddMetricReader(std::move(reader)); + + // counter view + std::string counter_name = name + "_counter"; + std::unique_ptr instrument_selector{ + new metrics_sdk::InstrumentSelector(metrics_sdk::InstrumentType::kCounter, counter_name)}; + std::unique_ptr meter_selector{ + new metrics_sdk::MeterSelector(name, version, schema)}; + std::unique_ptr sum_view{ + new metrics_sdk::View{name, "description", metrics_sdk::AggregationType::kSum}}; + p->AddView(std::move(instrument_selector), std::move(meter_selector), std::move(sum_view)); + + // histogram view + std::string histogram_name = name + "_histogram"; + std::unique_ptr histogram_instrument_selector{ + new metrics_sdk::InstrumentSelector(metrics_sdk::InstrumentType::kHistogram, histogram_name)}; + std::unique_ptr histogram_meter_selector{ + new metrics_sdk::MeterSelector(name, version, schema)}; + std::unique_ptr histogram_view{ + new metrics_sdk::View{name, "description", metrics_sdk::AggregationType::kHistogram}}; + p->AddView(std::move(histogram_instrument_selector), std::move(histogram_meter_selector), + std::move(histogram_view)); + metrics_api::Provider::SetMeterProvider(provider); +} +} // namespace + +int main(int argc, char **argv) +{ + std::string example_type; + std::string addr{"localhost:8080"}; + if (argc == 1) + { + std::puts("usage: $prometheus_example "); + } + + if (argc >= 2) + { + example_type = argv[1]; + } + if (argc > 2) + { + addr = argv[2]; + } + + std::string name{"prometheus_metric_example"}; + initMetrics(name, addr); + + if (example_type == "counter") + { + foo_library::counter_example(name); + } + else if (example_type == "histogram") + { + foo_library::histogram_example(name); + } + else + { + std::thread counter_example{&foo_library::counter_example, name}; + std::thread histogram_example{&foo_library::histogram_example, name}; + counter_example.join(); + histogram_example.join(); + } +} +#else +int main() {} +#endif diff --git a/examples/prometheus/prometheus.yml b/examples/prometheus/prometheus.yml new file mode 100644 index 0000000000..3f415d39dc --- /dev/null +++ b/examples/prometheus/prometheus.yml @@ -0,0 +1,16 @@ +global: + scrape_interval: 5s + scrape_timeout: 2s + evaluation_interval: 5s +alerting: + alertmanagers: + - follow_redirects: true + scheme: http + timeout: 5s + api_version: v2 + static_configs: + - targets: [localhost:8080] +scrape_configs: + - job_name: otel + static_configs: + - targets: ['localhost:8080'] \ No newline at end of file diff --git a/examples/prometheus/run.sh b/examples/prometheus/run.sh new file mode 100644 index 0000000000..412c6ef454 --- /dev/null +++ b/examples/prometheus/run.sh @@ -0,0 +1 @@ +docker run -p 9090:9090 -v $(pwd):/etc/prometheus --network="host" prom/prometheus \ No newline at end of file diff --git a/exporters/etw/include/opentelemetry/exporters/etw/LICENSE b/exporters/etw/include/opentelemetry/exporters/etw/LICENSE new file mode 100644 index 0000000000..cfc21fd2cc --- /dev/null +++ b/exporters/etw/include/opentelemetry/exporters/etw/LICENSE @@ -0,0 +1,23 @@ +TraceLogging Dynamic for Windows + +Copyright (c) Microsoft Corporation. All rights reserved. + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/exporters/etw/include/opentelemetry/exporters/etw/TraceLoggingDynamic.h b/exporters/etw/include/opentelemetry/exporters/etw/TraceLoggingDynamic.h index 5d493b319a..17ee108c64 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/TraceLoggingDynamic.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/TraceLoggingDynamic.h @@ -691,7 +691,7 @@ namespace tld } void AddBytes( - _In_bytecount_(cb) void const* p, + _In_reads_bytes_(cb) void const* p, unsigned cb) { auto pb = static_cast(p); @@ -2064,7 +2064,7 @@ namespace tld void AddTrait( ProviderTraitType type, - _In_bytecount_(cbData) void const* pData, + _In_reads_bytes_(cbData) void const* pData, unsigned cbData) { this->AddU16(static_cast(cbData + 3)); @@ -2232,6 +2232,7 @@ namespace tld return this->BaseEnd(); } + // Note: Do not create structs with 0 fields. template EventMetadataBuilder AddStruct( _In_z_ CharTy const* szUtfStructName, @@ -2242,6 +2243,7 @@ namespace tld return EventMetadataBuilder(this->GetBuffer(), bookmark); } + // Note: Do not create structs with 0 fields. template UINT32 AddStructRaw( _In_z_ CharTy const* szUtfStructName, @@ -2252,6 +2254,7 @@ namespace tld return bookmark; } + // Note: Do not create structs with 0 fields. template EventMetadataBuilder AddStructArray( _In_z_ CharTy const* szUtfStructName, @@ -2262,6 +2265,8 @@ namespace tld return EventMetadataBuilder(this->GetBuffer(), bookmark); } + // Note: Do not use 0 for itemCount. + // Note: Do not create structs with 0 fields. template EventMetadataBuilder AddStructFixedArray( _In_z_ CharTy const* szUtfStructName, @@ -2294,6 +2299,7 @@ namespace tld AddFieldInfo(InMetaVcount, type, fieldTags); } + // Note: Do not use 0 for itemCount. template void AddFieldFixedArray( _In_z_ CharTy const* szUtfFieldName, @@ -2400,7 +2406,7 @@ namespace tld Note: should only be used for blittable POD types with no padding. */ template - void AddValues(_In_count_(cValues) T const* pValues, unsigned cValues) + void AddValues(_In_reads_(cValues) T const* pValues, unsigned cValues) { AddBytes(pValues, sizeof(T) * cValues); } @@ -2917,6 +2923,7 @@ namespace tld of the nested struct. Note: do not call any Add methods on this builder object until you are done calling Add methods on the nested builder object. + Note: Do not create structs with 0 fields. */ template EventBuilder AddStruct( @@ -2933,6 +2940,7 @@ namespace tld of the nested struct. Note: do not call any Add methods on this builder object until you are done calling Add methods on the nested builder object. + Note: Do not create structs with 0 fields. */ template EventBuilder AddStructArray( @@ -2949,6 +2957,8 @@ namespace tld of the nested struct. Note: do not call any Add methods on this builder object until you are done calling Add methods on the nested builder object. + Note: Do not use 0 for itemCount. + Note: Do not create structs with 0 fields. */ template EventBuilder AddStructFixedArray( @@ -2992,6 +3002,7 @@ namespace tld Adds a fixed-length array field to the event's metadata. The length (item count) is encoded in the metadata, so it does not need to be included in the event's payload. + Note: Do not use 0 for itemCount. */ template void AddFieldFixedArray( @@ -3061,7 +3072,7 @@ namespace tld e.g. INT32, FILETIME, GUID, not for strings or structs. */ template - void AddValues(_In_count_(cValues) T const* pValues, unsigned cValues) + void AddValues(_In_reads_(cValues) T const* pValues, unsigned cValues) { m_dataBuilder.AddValues(pValues, cValues); } diff --git a/exporters/etw/include/opentelemetry/exporters/etw/utils.h b/exporters/etw/include/opentelemetry/exporters/etw/utils.h index 8b0a015821..4d38c1fb6f 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/utils.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/utils.h @@ -5,7 +5,6 @@ #include #include -#include #include #include #include @@ -24,6 +23,8 @@ # pragma comment(lib, "Rpcrt4.lib") # include # pragma comment(lib, "Ole32.Lib") +#else +# include #endif OPENTELEMETRY_BEGIN_NAMESPACE @@ -193,8 +194,8 @@ static inline GUID GetProviderGuid(const char *providerName) guid.Data4[6] = buffer2[14]; guid.Data4[7] = buffer2[15]; - delete buffer; - delete buffer2; + delete[] buffer; + delete[] buffer2; return guid; } diff --git a/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter.h b/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter.h index 6945f09bb9..151244928f 100644 --- a/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter.h +++ b/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter.h @@ -31,7 +31,7 @@ namespace metrics inline const std::string GetOtlpDefaultHttpEndpoint() { constexpr char kPrometheusEndpointEnv[] = "PROMETHEUS_EXPORTER_ENDPOINT"; - constexpr char kPrometheusEndpointDefault[] = "http://localhost:8080"; + constexpr char kPrometheusEndpointDefault[] = "localhost:8080"; auto endpoint = opentelemetry::sdk::common::GetEnvironmentVariable(kPrometheusEndpointEnv); return endpoint.size() ? endpoint : kPrometheusEndpointDefault;