diff --git a/.gitattributes b/.gitattributes index 03f42e5e1f..ca2467b474 100644 --- a/.gitattributes +++ b/.gitattributes @@ -41,3 +41,7 @@ LICENSE* text ## git files .gitignore text eol=lf .gitattributes text eol=lf + +## bazel files +WORKSPACE text eol=lf +BUILD text eol=lf diff --git a/CHANGELOG.md b/CHANGELOG.md index 0bf750cd54..934320ee2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ Increment the: * [EXPORTER] OTLP http exporter allow concurrency session ([#1209](https://github.com/open-telemetry/opentelemetry-cpp/pull/1209)) * [EXT] `curl::HttpClient` use `curl_multi_handle` instead of creating a thread for every request and it's able to reuse connections now. ([#1317](https://github.com/open-telemetry/opentelemetry-cpp/pull/1317)) +* [METRICS] Only record non-negative / finite / Non-NAN histogram values([#1427](https://github.com/open-telemetry/opentelemetry-cpp/pull/1427)) ## [1.4.0] 2022-05-17 diff --git a/RELEASING.md b/RELEASING.md index 892d2214f5..2725298a7f 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -89,5 +89,5 @@ should include all the release notes from the Changelog for this release. ## Post Release Update the OpenTelemetry.io document -[here](https://github.com/open-telemetry/opentelemetry.io/tree/main/content/en/docs/cpp) +[here](https://github.com/open-telemetry/opentelemetry.io/tree/main/content/en/docs/instrumentation/cpp) by sending a Pull Request. diff --git a/api/include/opentelemetry/metrics/meter.h b/api/include/opentelemetry/metrics/meter.h index 6a19911390..e0454e360b 100644 --- a/api/include/opentelemetry/metrics/meter.h +++ b/api/include/opentelemetry/metrics/meter.h @@ -47,24 +47,26 @@ class Meter nostd::string_view unit = "") noexcept = 0; /** - * Creates a Asynchronouse (Observable) counter with the passed characteristics and returns a + * Creates a Asynchronous (Observable) counter with the passed characteristics and returns a * shared_ptr to that Observable Counter * * @param name the name of the new Observable Counter. + * @param callback the function to be observed by the instrument. * @param description a brief description of what the Observable Counter is used for. * @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html. - * @param callback the function to be observed by the instrument. - * @return a shared pointer to the created Observable Counter. + * @param state to be passed back to callback */ virtual void CreateLongObservableCounter(nostd::string_view name, - void (*callback)(ObserverResult &), + void (*callback)(ObserverResult &, void *), nostd::string_view description = "", - nostd::string_view unit = "") noexcept = 0; + nostd::string_view unit = "", + void *state = nullptr) noexcept = 0; virtual void CreateDoubleObservableCounter(nostd::string_view name, - void (*callback)(ObserverResult &), + void (*callback)(ObserverResult &, void *), nostd::string_view description = "", - nostd::string_view unit = "") noexcept = 0; + nostd::string_view unit = "", + void *state = nullptr) noexcept = 0; /** * Creates a Histogram with the passed characteristics and returns a shared_ptr to that Histogram. @@ -89,20 +91,22 @@ class Meter * shared_ptr to that Observable Counter * * @param name the name of the new Observable Gauge. + * @param callback the function to be observed by the instrument. * @param description a brief description of what the Observable Gauge is used for. * @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html. - * @param callback the function to be observed by the instrument. - * @return a shared pointer to the created Observable Gauge. + * @param state to be passed back to callback */ virtual void CreateLongObservableGauge(nostd::string_view name, - void (*callback)(ObserverResult &), + void (*callback)(ObserverResult &, void *), nostd::string_view description = "", - nostd::string_view unit = "") noexcept = 0; + nostd::string_view unit = "", + void *state = nullptr) noexcept = 0; virtual void CreateDoubleObservableGauge(nostd::string_view name, - void (*callback)(ObserverResult &), + void (*callback)(ObserverResult &, void *), nostd::string_view description = "", - nostd::string_view unit = "") noexcept = 0; + nostd::string_view unit = "", + void *state = nullptr) noexcept = 0; /** * Creates an UpDownCounter with the passed characteristics and returns a shared_ptr to that @@ -128,20 +132,23 @@ class Meter * a shared_ptr to that Observable UpDownCounter * * @param name the name of the new Observable UpDownCounter. + * @param callback the function to be observed by the instrument. * @param description a brief description of what the Observable UpDownCounter is used for. * @param unit the unit of metric values following https://unitsofmeasure.org/ucum.html. - * @param callback the function to be observed by the instrument. - * @return a shared pointer to the created Observable UpDownCounter. + * @param state to be passed back to callback */ virtual void CreateLongObservableUpDownCounter(nostd::string_view name, - void (*callback)(ObserverResult &), + void (*callback)(ObserverResult &, void *), nostd::string_view description = "", - nostd::string_view unit = "") noexcept = 0; + nostd::string_view unit = "", + void *state = nullptr) noexcept = 0; virtual void CreateDoubleObservableUpDownCounter(nostd::string_view name, - void (*callback)(ObserverResult &), + void (*callback)(ObserverResult &, + void *), nostd::string_view description = "", - nostd::string_view unit = "") noexcept = 0; + nostd::string_view unit = "", + void *state = nullptr) noexcept = 0; }; } // namespace metrics OPENTELEMETRY_END_NAMESPACE diff --git a/api/include/opentelemetry/metrics/noop.h b/api/include/opentelemetry/metrics/noop.h index 0fbda060b9..c47f7489f0 100644 --- a/api/include/opentelemetry/metrics/noop.h +++ b/api/include/opentelemetry/metrics/noop.h @@ -138,15 +138,17 @@ class NoopMeter final : public Meter } void CreateLongObservableCounter(nostd::string_view name, - void (*callback)(ObserverResult &), + void (*callback)(ObserverResult &, void *), nostd::string_view description = "", - nostd::string_view unit = "") noexcept override + nostd::string_view unit = "", + void *state = nullptr) noexcept override {} void CreateDoubleObservableCounter(nostd::string_view name, - void (*callback)(ObserverResult &), + void (*callback)(ObserverResult &, void *), nostd::string_view description = "", - nostd::string_view unit = "") noexcept override + nostd::string_view unit = "", + void *state = nullptr) noexcept override {} nostd::shared_ptr> CreateLongHistogram( @@ -166,15 +168,17 @@ class NoopMeter final : public Meter } void CreateLongObservableGauge(nostd::string_view name, - void (*callback)(ObserverResult &), + void (*callback)(ObserverResult &, void *), nostd::string_view description = "", - nostd::string_view unit = "") noexcept override + nostd::string_view unit = "", + void *state = nullptr) noexcept override {} void CreateDoubleObservableGauge(nostd::string_view name, - void (*callback)(ObserverResult &), + void (*callback)(ObserverResult &, void *), nostd::string_view description = "", - nostd::string_view unit = "") noexcept override + nostd::string_view unit = "", + void *state = nullptr) noexcept override {} nostd::shared_ptr> CreateLongUpDownCounter( @@ -196,15 +200,17 @@ class NoopMeter final : public Meter } void CreateLongObservableUpDownCounter(nostd::string_view name, - void (*callback)(ObserverResult &), + void (*callback)(ObserverResult &, void *), nostd::string_view description = "", - nostd::string_view unit = "") noexcept override + nostd::string_view unit = "", + void *state = nullptr) noexcept override {} void CreateDoubleObservableUpDownCounter(nostd::string_view name, - void (*callback)(ObserverResult &), + void (*callback)(ObserverResult &, void *), nostd::string_view description = "", - nostd::string_view unit = "") noexcept override + nostd::string_view unit = "", + void *state = nullptr) noexcept override {} }; diff --git a/api/include/opentelemetry/trace/span_context.h b/api/include/opentelemetry/trace/span_context.h index ca13a8df60..e19bb99001 100644 --- a/api/include/opentelemetry/trace/span_context.h +++ b/api/include/opentelemetry/trace/span_context.h @@ -81,7 +81,7 @@ class SpanContext final bool IsRemote() const noexcept { return is_remote_; } - static SpanContext GetInvalid() { return SpanContext(false, false); } + static SpanContext GetInvalid() noexcept { return SpanContext(false, false); } bool IsSampled() const noexcept { return trace_flags_.IsSampled(); } diff --git a/bazel/repository.bzl b/bazel/repository.bzl index 7d50e12d31..30a34fb2fd 100644 --- a/bazel/repository.bzl +++ b/bazel/repository.bzl @@ -10,6 +10,19 @@ filegroup( ) """ +# +# MAINTAINER +# +# This file is used for the Bazel build. +# +# When changing (add, upgrade, remove) dependencies +# please update: +# - the CMake build, see file +# /third_party_release +# - git submodule, see command +# git submodule status +# + def opentelemetry_cpp_deps(): """Loads dependencies need to compile the opentelemetry-cpp library.""" @@ -86,9 +99,9 @@ def opentelemetry_cpp_deps(): http_archive, name = "github_nlohmann_json", build_file = "@io_opentelemetry_cpp//bazel:nlohmann_json.BUILD", - sha256 = "69cc88207ce91347ea530b227ff0776db82dcb8de6704e1a3d74f4841bc651cf", + sha256 = "b94997df68856753b72f0d7a3703b7d484d4745c567f3584ef97c96c25a5798e", urls = [ - "https://github.com/nlohmann/json/releases/download/v3.6.1/include.zip", + "https://github.com/nlohmann/json/releases/download/v3.10.5/include.zip", ], ) diff --git a/cmake/nlohmann-json.cmake b/cmake/nlohmann-json.cmake index 7e057ee602..b5b4355e45 100644 --- a/cmake/nlohmann-json.cmake +++ b/cmake/nlohmann-json.cmake @@ -26,7 +26,7 @@ ExternalProject_Add(nlohmann_json_download ) ExternalProject_Get_Property(nlohmann_json_download INSTALL_DIR) -SET(NLOHMANN_JSON_INCLUDE_DIR ${INSTALL_DIR}/third_party/src/nlohmann_json_download/single_include) +SET(NLOHMANN_JSON_INCLUDE_DIR ${INSTALL_DIR}/src/nlohmann_json_download/single_include) add_library(nlohmann_json_ INTERFACE) target_include_directories(nlohmann_json_ INTERFACE "$" diff --git a/docs/public/sdk/GettingStarted.rst b/docs/public/sdk/GettingStarted.rst index 6486d46463..4abfac4668 100644 --- a/docs/public/sdk/GettingStarted.rst +++ b/docs/public/sdk/GettingStarted.rst @@ -50,9 +50,9 @@ OpenTelemetry offers six tracing exporters out of the box: opentelemetry::exporter::jaeger::JaegerExporterOptions opts; opts.transport_format = opentelemetry::exporter::jaeger::TransportFormat::kThriftHttp; opts.endpoint = "localhost"; - opts.server_port = 6831; + opts.server_port = 14268; opts.headers = {{}}; // optional headers - auto jaeger_udp_exporter = + auto jaeger_http_exporter = std::unique_ptr(new opentelemetry::exporter::jaeger::JaegerExporter(opts)); diff --git a/examples/common/logs_foo_library/foo_library.cc b/examples/common/logs_foo_library/foo_library.cc index daba9191bc..9e41584067 100644 --- a/examples/common/logs_foo_library/foo_library.cc +++ b/examples/common/logs_foo_library/foo_library.cc @@ -33,6 +33,7 @@ void foo_library() auto ctx = span->GetContext(); auto logger = get_logger(); logger->Log(opentelemetry::logs::Severity::kDebug, "body", {}, ctx.trace_id(), ctx.span_id(), - ctx.trace_flags(), opentelemetry::common::SystemTimestamp()); + ctx.trace_flags(), + opentelemetry::common::SystemTimestamp(std::chrono::system_clock::now())); } #endif diff --git a/examples/common/metrics_foo_library/foo_library.cc b/examples/common/metrics_foo_library/foo_library.cc index da8a99d91c..b895331d7e 100644 --- a/examples/common/metrics_foo_library/foo_library.cc +++ b/examples/common/metrics_foo_library/foo_library.cc @@ -29,7 +29,7 @@ std::map get_random_attr() class MeasurementFetcher { public: - static void Fetcher(opentelemetry::metrics::ObserverResult &observer_result) + static void Fetcher(opentelemetry::metrics::ObserverResult &observer_result, void *state) { double val = (rand() % 700) + 1.1; std::map labels = get_random_attr(); diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_logger_exporter.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_logger_exporter.h index 936fe15ca5..9b96cb27a5 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_logger_exporter.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_logger_exporter.h @@ -15,7 +15,7 @@ # include "opentelemetry/common/key_value_iterable_view.h" -# include "opentelemetry/logs/tracer_provider.h" +# include "opentelemetry/logs/logger_provider.h" # include "opentelemetry/trace/span_id.h" # include "opentelemetry/trace/trace_id.h" diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h index 04ad86130f..3cf365c8a0 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h @@ -192,7 +192,7 @@ class PropertyValue : public PropertyVariant {} /** - * @brief Convert owning PropertyValue to non-owning common::AttributeValue + * @brief Convert non-owning common::AttributeValue to owning PropertyValue. * @return */ PropertyValue &FromAttributeValue(const common::AttributeValue &v) @@ -222,7 +222,8 @@ class PropertyValue : public PropertyVariant break; } case common::AttributeType::kTypeString: { - PropertyVariant::operator=(nostd::string_view(nostd::get(v)).data()); + PropertyVariant::operator= + (std::string{nostd::string_view(nostd::get(v)).data()}); break; } diff --git a/exporters/etw/test/etw_logger_test.cc b/exporters/etw/test/etw_logger_test.cc index 99d5b3a9b8..4e2210118f 100644 --- a/exporters/etw/test/etw_logger_test.cc +++ b/exporters/etw/test/etw_logger_test.cc @@ -8,7 +8,7 @@ # include # include -# include "opentelemetry/exporters/etw/etw_logger.h" +# include "opentelemetry/exporters/etw/etw_logger_exporter.h" # include "opentelemetry/sdk/trace/simple_processor.h" using namespace OPENTELEMETRY_NAMESPACE; diff --git a/exporters/jaeger/BUILD b/exporters/jaeger/BUILD index d373aa35b5..cc1babae06 100644 --- a/exporters/jaeger/BUILD +++ b/exporters/jaeger/BUILD @@ -180,6 +180,7 @@ cc_library( tags = ["jaeger"], deps = [ ":jaeger_exporter", + "//sdk/src/common:global_log_handler", ], ) diff --git a/exporters/ostream/BUILD b/exporters/ostream/BUILD index cca74d6693..917b70450f 100644 --- a/exporters/ostream/BUILD +++ b/exporters/ostream/BUILD @@ -6,6 +6,7 @@ cc_library( "src/log_exporter.cc", ], hdrs = [ + "include/opentelemetry/exporters/ostream/common_utils.h", "include/opentelemetry/exporters/ostream/log_exporter.h", ], strip_include_prefix = "include", @@ -49,6 +50,7 @@ cc_library( "src/metric_exporter.cc", ], hdrs = [ + "include/opentelemetry/exporters/ostream/common_utils.h", "include/opentelemetry/exporters/ostream/metric_exporter.h", ], strip_include_prefix = "include", @@ -93,6 +95,7 @@ cc_library( "src/span_exporter.cc", ], hdrs = [ + "include/opentelemetry/exporters/ostream/common_utils.h", "include/opentelemetry/exporters/ostream/span_exporter.h", ], strip_include_prefix = "include", diff --git a/exporters/ostream/include/opentelemetry/exporters/ostream/common_utils.h b/exporters/ostream/include/opentelemetry/exporters/ostream/common_utils.h new file mode 100644 index 0000000000..cfebfe8fce --- /dev/null +++ b/exporters/ostream/include/opentelemetry/exporters/ostream/common_utils.h @@ -0,0 +1,80 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include "opentelemetry/nostd/variant.h" +#include "opentelemetry/sdk/common/attribute_utils.h" + +#pragma once +OPENTELEMETRY_BEGIN_NAMESPACE +namespace exporter +{ +namespace ostream_common +{ +/* + print_value is used to print out the value of an attribute within a vector. + These values are held in a variant which makes the process of printing them much more + complicated. +*/ + +template +void print_value(const T &item, std::ostream &sout) +{ + sout << item; +} + +template +void print_value(const std::vector &vec, std::ostream &sout) +{ + sout << '['; + size_t i = 1; + size_t sz = vec.size(); + for (auto v : vec) + { + sout << v; + if (i != sz) + sout << ','; + i++; + }; + sout << ']'; +} + +// Prior to C++14, generic lambda is not available so fallback to functor. +#if __cplusplus < 201402L + +class OwnedAttributeValueVisitor +{ +public: + OwnedAttributeValueVisitor(std::ostream &sout) : sout_(sout) {} + + template + void operator()(T &&arg) + { + print_value(arg, sout_); + } + +private: + std::ostream &sout_; +}; + +#endif + +void print_value(const opentelemetry::sdk::common::OwnedAttributeValue &value, std::ostream &sout) +{ +#if __cplusplus < 201402L + opentelemetry::nostd::visit(OwnedAttributeValueVisitor(sout), value); +#else + opentelemetry::nostd::visit( + [&sout](auto &&arg) { + /* explicit this is needed by some gcc versions (observed with v5.4.0)*/ + print_value(arg, sout); + }, + value); +#endif +} + +} // namespace ostream_common +} // namespace exporter +OPENTELEMETRY_END_NAMESPACE \ No newline at end of file diff --git a/exporters/ostream/include/opentelemetry/exporters/ostream/log_exporter.h b/exporters/ostream/include/opentelemetry/exporters/ostream/log_exporter.h index 65969a40a9..c263ac63ae 100644 --- a/exporters/ostream/include/opentelemetry/exporters/ostream/log_exporter.h +++ b/exporters/ostream/include/opentelemetry/exporters/ostream/log_exporter.h @@ -61,6 +61,9 @@ class OStreamLogExporter final : public opentelemetry::sdk::logs::LogExporter bool is_shutdown_ = false; mutable opentelemetry::common::SpinLockMutex lock_; bool isShutdown() const noexcept; + void printAttributes( + const std::unordered_map &map, + const std::string prefix = "\n\t"); }; } // namespace logs } // namespace exporter diff --git a/exporters/ostream/include/opentelemetry/exporters/ostream/metric_exporter.h b/exporters/ostream/include/opentelemetry/exporters/ostream/metric_exporter.h index 56b6c577b0..e34332d77c 100644 --- a/exporters/ostream/include/opentelemetry/exporters/ostream/metric_exporter.h +++ b/exporters/ostream/include/opentelemetry/exporters/ostream/metric_exporter.h @@ -59,6 +59,7 @@ class OStreamMetricExporter final : public opentelemetry::sdk::metrics::MetricEx void printInstrumentationInfoMetricData( const sdk::metrics::InstrumentationInfoMetrics &info_metrics); void printPointData(const opentelemetry::sdk::metrics::PointType &point_data); + void printPointAttributes(const opentelemetry::sdk::metrics::PointAttributes &point_attributes); }; } // namespace metrics } // namespace exporter diff --git a/exporters/ostream/include/opentelemetry/exporters/ostream/span_exporter.h b/exporters/ostream/include/opentelemetry/exporters/ostream/span_exporter.h index 334c4d6419..2bc7a9da97 100644 --- a/exporters/ostream/include/opentelemetry/exporters/ostream/span_exporter.h +++ b/exporters/ostream/include/opentelemetry/exporters/ostream/span_exporter.h @@ -58,68 +58,6 @@ class OStreamSpanExporter final : public opentelemetry::sdk::trace::SpanExporter // Mapping status number to the string from api/include/opentelemetry/trace/canonical_code.h std::map statusMap{{0, "Unset"}, {1, "Ok"}, {2, "Error"}}; - /* - print_value is used to print out the value of an attribute within a vector. - These values are held in a variant which makes the process of printing them much more - complicated. - */ - - template - void print_value(const T &item) - { - sout_ << item; - } - - template - void print_value(const std::vector &vec) - { - sout_ << '['; - size_t i = 1; - size_t sz = vec.size(); - for (auto v : vec) - { - sout_ << v; - if (i != sz) - sout_ << ','; - i++; - }; - sout_ << ']'; - } - -// Prior to C++14, generic lambda is not available so fallback to functor. -#if __cplusplus < 201402L - - class OwnedAttributeValueVisitor - { - public: - OwnedAttributeValueVisitor(OStreamSpanExporter &exporter) : exporter_(exporter) {} - - template - void operator()(T &&arg) - { - exporter_.print_value(arg); - } - - private: - OStreamSpanExporter &exporter_; - }; - -#endif - - void print_value(const opentelemetry::sdk::common::OwnedAttributeValue &value) - { -#if __cplusplus < 201402L - opentelemetry::nostd::visit(OwnedAttributeValueVisitor(*this), value); -#else - opentelemetry::nostd::visit( - [this](auto &&arg) { - /* explicit this is needed by some gcc versions (observed with v5.4.0)*/ - this->print_value(arg); - }, - value); -#endif - } - // various print helpers void printAttributes( const std::unordered_map &map, diff --git a/exporters/ostream/src/log_exporter.cc b/exporters/ostream/src/log_exporter.cc index acd507980e..2396101930 100644 --- a/exporters/ostream/src/log_exporter.cc +++ b/exporters/ostream/src/log_exporter.cc @@ -4,97 +4,20 @@ #ifdef ENABLE_LOGS_PREVIEW # include "opentelemetry/exporters/ostream/log_exporter.h" # include +# include "opentelemetry/exporters/ostream/common_utils.h" # include "opentelemetry/sdk_config.h" # include # include -namespace nostd = opentelemetry::nostd; -namespace sdklogs = opentelemetry::sdk::logs; - +namespace nostd = opentelemetry::nostd; +namespace sdklogs = opentelemetry::sdk::logs; +namespace sdkcommon = opentelemetry::sdk::common; OPENTELEMETRY_BEGIN_NAMESPACE namespace exporter { namespace logs { -/*********************** Helper functions ************************/ - -/* - print_value is used to print out the value of an attribute within a vector. - These values are held in a variant which makes the process of printing them much more - complicated. -*/ - -template -void print_value(const T &item, std::ostream &sout) -{ - sout << item; -} - -template -void print_value(const std::vector &vec, std::ostream &sout) -{ - sout << '['; - size_t i = 1; - size_t sz = vec.size(); - for (auto v : vec) - { - sout << v; - if (i != sz) - sout << ',' << ' '; - i++; - }; - sout << ']'; -} - -// Prior to C++14, generic lambda is not available so fallback to functor. -# if __cplusplus < 201402L - -class OwnedAttributeValueVisitor -{ -public: - OwnedAttributeValueVisitor(std::ostream &sout) : sout_(sout) {} - - template - void operator()(T &&arg) - { - print_value(arg, sout_); - } - -private: - // The OStream to send the logs to - std::ostream &sout_; -}; - -# endif - -void print_value(sdk::common::OwnedAttributeValue &value, std::ostream &sout) -{ -# if __cplusplus < 201402L - nostd::visit(OwnedAttributeValueVisitor(sout), value); -# else - nostd::visit([&sout](auto &&arg) { print_value(arg, sout); }, value); -# endif -} - -void printMap(std::unordered_map map, - std::ostream &sout) -{ - sout << "{"; - size_t size = map.size(); - size_t i = 1; - for (auto kv : map) - { - sout << "{" << kv.first << ": "; - print_value(kv.second, sout); - sout << "}"; - - if (i != size) - sout << ", "; - i++; - } - sout << "}"; -} /*********************** Constructor ***********************/ @@ -162,12 +85,12 @@ sdk::common::ExportResult OStreamLogExporter::Export( sout_ << " body : " << log_record->GetBody() << "\n" << " resource : "; - printMap(log_record->GetResource().GetAttributes(), sout_); + printAttributes(log_record->GetResource().GetAttributes()); sout_ << "\n" << " attributes : "; - printMap(log_record->GetAttributes(), sout_); + printAttributes(log_record->GetAttributes()); sout_ << "\n" << " trace_id : " << std::string(trace_id, trace_id_len) << "\n" @@ -203,6 +126,17 @@ bool OStreamLogExporter::isShutdown() const noexcept return is_shutdown_; } +void OStreamLogExporter::printAttributes( + const std::unordered_map &map, + const std::string prefix) +{ + for (const auto &kv : map) + { + sout_ << prefix << kv.first << ": "; + opentelemetry::exporter::ostream_common::print_value(kv.second, sout_); + } +} + } // namespace logs } // namespace exporter OPENTELEMETRY_END_NAMESPACE diff --git a/exporters/ostream/src/metric_exporter.cc b/exporters/ostream/src/metric_exporter.cc index 18e73a310c..2e90e0845b 100644 --- a/exporters/ostream/src/metric_exporter.cc +++ b/exporters/ostream/src/metric_exporter.cc @@ -4,6 +4,7 @@ #include #ifndef ENABLE_METRICS_PREVIEW # include +# include "opentelemetry/exporters/ostream/common_utils.h" # include "opentelemetry/exporters/ostream/metric_exporter.h" # include "opentelemetry/sdk/metrics/aggregation/default_aggregation.h" # include "opentelemetry/sdk/metrics/aggregation/histogram_aggregation.h" @@ -102,7 +103,11 @@ void OStreamMetricExporter::printInstrumentationInfoMetricData( for (const auto &pd : record.point_data_attr_) { - printPointData(pd.point_data); + if (!nostd::holds_alternative(pd.point_data)) + { + printPointData(pd.point_data); + printPointAttributes(pd.attributes); + } } } sout_ << "\n}\n"; @@ -171,8 +176,17 @@ void OStreamMetricExporter::printPointData(const opentelemetry::sdk::metrics::Po sout_ << nostd::get(last_point_data.value_); } } - else if (nostd::holds_alternative(point_data)) - {} +} + +void OStreamMetricExporter::printPointAttributes( + const opentelemetry::sdk::metrics::PointAttributes &point_attributes) +{ + sout_ << "\n attributes\t\t: "; + for (const auto &kv : point_attributes) + { + sout_ << "\n\t" << kv.first << ": "; + opentelemetry::exporter::ostream_common::print_value(kv.second, sout_); + } } bool OStreamMetricExporter::ForceFlush(std::chrono::microseconds timeout) noexcept diff --git a/exporters/ostream/src/span_exporter.cc b/exporters/ostream/src/span_exporter.cc index 67c1a51a4b..00a36c2144 100644 --- a/exporters/ostream/src/span_exporter.cc +++ b/exporters/ostream/src/span_exporter.cc @@ -2,6 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 #include "opentelemetry/exporters/ostream/span_exporter.h" +#include "opentelemetry/exporters/ostream/common_utils.h" + #include #include #include "opentelemetry/sdk_config.h" @@ -125,7 +127,7 @@ void OStreamSpanExporter::printAttributes( for (const auto &kv : map) { sout_ << prefix << kv.first << ": "; - print_value(kv.second); + opentelemetry::exporter::ostream_common::print_value(kv.second, sout_); } } diff --git a/exporters/ostream/test/ostream_log_test.cc b/exporters/ostream/test/ostream_log_test.cc index 7fa51c18a9..91d8fbf245 100644 --- a/exporters/ostream/test/ostream_log_test.cc +++ b/exporters/ostream/test/ostream_log_test.cc @@ -80,11 +80,11 @@ TEST(OstreamLogExporter, DefaultLogRecordToCout) " severity_num : 0\n" " severity_text : INVALID\n" " body : \n", - " resource : {", - "{telemetry.sdk.version: " OPENTELEMETRY_VERSION "}", - "{telemetry.sdk.name: opentelemetry}", - "{telemetry.sdk.language: cpp}", - " attributes : {}\n" + " resource : \n", + "telemetry.sdk.version: " OPENTELEMETRY_VERSION "\n", + "telemetry.sdk.name: opentelemetry\n", + "telemetry.sdk.language: cpp\n", + " attributes : \n" " trace_id : 00000000000000000000000000000000\n" " span_id : 0000000000000000\n" " trace_flags : 00\n" @@ -132,11 +132,11 @@ TEST(OStreamLogExporter, SimpleLogToCout) " severity_num : 1\n" " severity_text : TRACE\n" " body : Message\n", - " resource : {", - "{telemetry.sdk.version: " OPENTELEMETRY_VERSION "}", - "{telemetry.sdk.name: opentelemetry}", - "{telemetry.sdk.language: cpp}", - " attributes : {}\n" + " resource : \n", + "telemetry.sdk.version: " OPENTELEMETRY_VERSION "\n", + "telemetry.sdk.name: opentelemetry\n", + "telemetry.sdk.language: cpp\n", + " attributes : \n" " trace_id : 00000000000000000000000000000000\n" " span_id : 0000000000000000\n" " trace_flags : 00\n" @@ -185,13 +185,14 @@ TEST(OStreamLogExporter, LogWithStringAttributesToCerr) " severity_num : 0\n" " severity_text : INVALID\n" " body : \n", - " resource : {", - "{telemetry.sdk.version: " OPENTELEMETRY_VERSION "}", - "{telemetry.sdk.name: opentelemetry}", - "{telemetry.sdk.language: cpp}", - "{service.name: unknown_service}", - "{key1: val1}", - " attributes : {{a: 1}}\n" + " resource : \n", + "telemetry.sdk.version: " OPENTELEMETRY_VERSION "\n", + "telemetry.sdk.name: opentelemetry\n", + "telemetry.sdk.language: cpp\n", + "service.name: unknown_service\n", + "key1: val1\n", + " attributes : \n", + "\ta: 1\n", " trace_id : 00000000000000000000000000000000\n" " span_id : 0000000000000000\n" " trace_flags : 00\n" @@ -246,13 +247,14 @@ TEST(OStreamLogExporter, LogWithVariantTypesToClog) " severity_num : 0\n" " severity_text : INVALID\n" " body : \n", - " resource : {", - "{service.name: unknown_service}", - "{telemetry.sdk.version: " OPENTELEMETRY_VERSION "}", - "{telemetry.sdk.name: opentelemetry}", - "{telemetry.sdk.language: cpp}", - "{res1: [1, 2, 3]}", - " attributes : {{attr1: [0, 1, 0]}}\n" + " resource : \n", + "service.name: unknown_service\n", + "telemetry.sdk.version: " OPENTELEMETRY_VERSION "\n", + "telemetry.sdk.name: opentelemetry\n", + "telemetry.sdk.language: cpp\n", + "res1: [1,2,3]\n", + "attributes : \n", + "\tattr1: [0,1,0]\n" " trace_id : 00000000000000000000000000000000\n" " span_id : 0000000000000000\n" " trace_flags : 00\n" @@ -305,12 +307,12 @@ TEST(OStreamLogExporter, IntegrationTest) " severity_num : 5\n" " severity_text : DEBUG\n" " body : Hello\n", - " resource : {", - "{telemetry.sdk.version: " OPENTELEMETRY_VERSION "}", - "{service.name: unknown_service}", - "{telemetry.sdk.name: opentelemetry}", - "{telemetry.sdk.language: cpp}", - " attributes : {}\n" + " resource : \n", + "telemetry.sdk.version: " OPENTELEMETRY_VERSION "\n", + "service.name: unknown_service\n", + "telemetry.sdk.name: opentelemetry\n", + "telemetry.sdk.language: cpp\n", + " attributes : \n" " trace_id : 00000000000000000000000000000000\n" " span_id : 0000000000000000\n" " trace_flags : 00\n" diff --git a/exporters/ostream/test/ostream_metric_test.cc b/exporters/ostream/test/ostream_metric_test.cc index 82c1be2bc7..45d6d8f882 100644 --- a/exporters/ostream/test/ostream_metric_test.cc +++ b/exporters/ostream/test/ostream_metric_test.cc @@ -50,8 +50,8 @@ TEST(OStreamMetricsExporter, ExportSumPointData) metric_sdk::InstrumentValueType::kDouble}, opentelemetry::common::SystemTimestamp{}, opentelemetry::common::SystemTimestamp{}, std::vector{ - {metric_sdk::PointAttributes{}, sum_point_data}, - {metric_sdk::PointAttributes{}, sum_point_data2}}}; + {metric_sdk::PointAttributes{{"a1", "b1"}}, sum_point_data}, + {metric_sdk::PointAttributes{{"a1", "b1"}}, sum_point_data2}}}; data.instrumentation_info_metric_data_ = std::vector{ {instrumentation_library.get(), std::vector{metric_data}}}; @@ -75,8 +75,12 @@ TEST(OStreamMetricsExporter, ExportSumPointData) "\n unit\t\t: unit" "\n type\t\t: SumPointData" "\n value\t\t: 10" + "\n attributes\t\t: " + "\n\ta1: b1" "\n type\t\t: SumPointData" "\n value\t\t: 20" + "\n attributes\t\t: " + "\n\ta1: b1" "\n}\n"; ASSERT_EQ(stdoutOutput.str(), expected_output); } @@ -109,8 +113,8 @@ TEST(OStreamMetricsExporter, ExportHistogramPointData) metric_sdk::InstrumentValueType::kDouble}, opentelemetry::common::SystemTimestamp{}, opentelemetry::common::SystemTimestamp{}, std::vector{ - {metric_sdk::PointAttributes{}, histogram_point_data}, - {metric_sdk::PointAttributes{}, histogram_point_data2}}}; + {metric_sdk::PointAttributes{{"a1", "b1"}, {"a2", "b2"}}, histogram_point_data}, + {metric_sdk::PointAttributes{{"a1", "b1"}}, histogram_point_data2}}}; data.instrumentation_info_metric_data_ = std::vector{ {instrumentation_library.get(), std::vector{metric_data}}}; @@ -137,11 +141,16 @@ TEST(OStreamMetricsExporter, ExportHistogramPointData) "\n sum : 900.5" "\n buckets : [10.1, 20.2, 30.2, ]" "\n counts : [200, 300, 400, 500, ]" + "\n attributes\t\t: " + "\n\ta1: b1" + "\n\ta2: b2" "\n type : HistogramPointData" "\n count : 3" "\n sum : 900" "\n buckets : [10, 20, 30, ]" "\n counts : [200, 300, 400, 500, ]" + "\n attributes\t\t: " + "\n\ta1: b1" "\n}\n"; ASSERT_EQ(stdoutOutput.str(), expected_output); } @@ -199,10 +208,12 @@ TEST(OStreamMetricsExporter, ExportLastValuePointData) "\n timestamp : 0" "\n valid : true" "\n value : 10" + "\n attributes\t\t: " "\n type : LastValuePointData" "\n timestamp : 0" "\n valid : true" "\n value : 20" + "\n attributes\t\t: " "\n}\n"; ASSERT_EQ(stdoutOutput.str(), expected_output); } diff --git a/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter_utils.h b/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter_utils.h index cfbbb9c48b..c8df4f6cfd 100644 --- a/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter_utils.h +++ b/exporters/prometheus/include/opentelemetry/exporters/prometheus/exporter_utils.h @@ -57,7 +57,7 @@ class PrometheusExporterUtils */ template static void SetData(std::vector values, - const std::string &labels, + const opentelemetry::sdk::metrics::PointAttributes &labels, ::prometheus::MetricType type, std::chrono::nanoseconds time, ::prometheus::MetricFamily *metric_family); @@ -70,7 +70,7 @@ class PrometheusExporterUtils static void SetData(std::vector values, const opentelemetry::sdk::metrics::ListType &boundaries, const std::vector &counts, - const std::string &labels, + const opentelemetry::sdk::metrics::PointAttributes &labels, std::chrono::nanoseconds time, ::prometheus::MetricFamily *metric_family); @@ -79,14 +79,13 @@ class PrometheusExporterUtils */ static void SetMetricBasic(::prometheus::ClientMetric &metric, std::chrono::nanoseconds time, - const std::string &labels); + const opentelemetry::sdk::metrics::PointAttributes &labels); /** - * Parse a string of labels (key:value) into a vector of pairs - * {,} - * {l1:v1,l2:v2,...,} + * Convert attribute value to string */ - static std::vector> ParseLabel(std::string labels); + static std::string AttributeValueToString( + const opentelemetry::sdk::common::OwnedAttributeValue &value); /** * Handle Counter and Gauge. diff --git a/exporters/prometheus/src/exporter_utils.cc b/exporters/prometheus/src/exporter_utils.cc index 9979c9bebd..383925f988 100644 --- a/exporters/prometheus/src/exporter_utils.cc +++ b/exporters/prometheus/src/exporter_utils.cc @@ -10,6 +10,8 @@ # include "opentelemetry/exporters/prometheus/exporter_utils.h" # include "opentelemetry/sdk/metrics/export/metric_producer.h" +# include "opentelemetry/sdk/common/global_log_handler.h" + namespace prometheus_client = ::prometheus; namespace metric_sdk = opentelemetry::sdk::metrics; @@ -62,14 +64,14 @@ std::vector PrometheusExporterUtils::TranslateT auto counts = histogram_point_data.counts_; SetData(std::vector{nostd::get(histogram_point_data.sum_), (double)histogram_point_data.count_}, - boundaries, counts, "", time, &metric_family); + boundaries, counts, point_data_attr.attributes, time, &metric_family); } else // Counter, Untyped { auto sum_point_data = nostd::get(point_data_attr.point_data); std::vector values{sum_point_data.value_}; - SetData(values, "", type, time, &metric_family); + SetData(values, point_data_attr.attributes, type, time, &metric_family); } } output.emplace_back(metric_family); @@ -98,6 +100,7 @@ std::string PrometheusExporterUtils::SanitizeNames(std::string name) metric_sdk::AggregationType PrometheusExporterUtils::getAggregationType( const metric_sdk::PointType &point_type) { + if (nostd::holds_alternative(point_type)) { return metric_sdk::AggregationType::kSum; @@ -140,7 +143,7 @@ prometheus_client::MetricType PrometheusExporterUtils::TranslateType( */ template void PrometheusExporterUtils::SetData(std::vector values, - const std::string &labels, + const metric_sdk::PointAttributes &labels, prometheus_client::MetricType type, std::chrono::nanoseconds time, prometheus_client::MetricFamily *metric_family) @@ -159,7 +162,7 @@ template void PrometheusExporterUtils::SetData(std::vector values, const opentelemetry::sdk::metrics::ListType &boundaries, const std::vector &counts, - const std::string &labels, + const metric_sdk::PointAttributes &labels, std::chrono::nanoseconds time, prometheus_client::MetricFamily *metric_family) { @@ -181,59 +184,62 @@ void PrometheusExporterUtils::SetData(std::vector values, */ void PrometheusExporterUtils::SetMetricBasic(prometheus_client::ClientMetric &metric, std::chrono::nanoseconds time, - const std::string &labels) + const metric_sdk::PointAttributes &labels) { metric.timestamp_ms = time.count() / 1000000; - auto label_pairs = ParseLabel(labels); - if (!label_pairs.empty()) + // auto label_pairs = ParseLabel(labels); + if (!labels.empty()) { - metric.label.resize(label_pairs.size()); - for (size_t i = 0; i < label_pairs.size(); ++i) + metric.label.resize(labels.size()); + size_t i = 0; + for (auto const &label : labels) { - auto origin_name = label_pairs[i].first; - auto sanitized = SanitizeNames(origin_name); - metric.label[i].name = sanitized; - metric.label[i].value = label_pairs[i].second; + auto sanitized = SanitizeNames(label.first); + metric.label[i].name = sanitized; + metric.label[i++].value = AttributeValueToString(label.second); } } }; -/** - * Parse a string of labels (key:value) into a vector of pairs - * {,} - * {l1:v1,l2:v2,...,} - */ -std::vector> PrometheusExporterUtils::ParseLabel( - std::string labels) +std::string PrometheusExporterUtils::AttributeValueToString( + const opentelemetry::sdk::common::OwnedAttributeValue &value) { - if (labels.size() < 3) + std::string result; + if (nostd::holds_alternative(value)) { - return {}; + result = nostd::get(value) ? "true" : "false"; } - labels = labels.substr(1, labels.size() - 2); - - std::vector paired_labels; - std::stringstream s_stream(labels); - while (s_stream.good()) + else if (nostd::holds_alternative(value)) { - std::string substr; - getline(s_stream, substr, ','); // get first string delimited by comma - if (!substr.empty()) - { - paired_labels.push_back(substr); - } + result = std::to_string(nostd::get(value)); } - - std::vector> result; - for (auto &paired : paired_labels) + else if (nostd::holds_alternative(value)) { - std::size_t split_index = paired.find(':'); - std::string label = paired.substr(0, split_index); - std::string value = paired.substr(split_index + 1); - result.emplace_back(std::pair(label, value)); + result = std::to_string(nostd::get(value)); + } + else if (nostd::holds_alternative(value)) + { + result = std::to_string(nostd::get(value)); + } + else if (nostd::holds_alternative(value)) + { + result = std::to_string(nostd::get(value)); + } + else if (nostd::holds_alternative(value)) + { + result = std::to_string(nostd::get(value)); + } + else if (nostd::holds_alternative(value)) + { + result = nostd::get(value); + } + else + { + OTEL_INTERNAL_LOG_WARN( + "[Prometheus Exporter] AttributeValueToString - " + " Nested attributes not supported - ignored"); } - return result; } 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 393d6393ed..57d0d2129f 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 @@ -17,6 +17,7 @@ # include # include #else +# include # include #endif #include diff --git a/sdk/CMakeLists.txt b/sdk/CMakeLists.txt index 1a824fe09b..ca5af6334d 100644 --- a/sdk/CMakeLists.txt +++ b/sdk/CMakeLists.txt @@ -14,7 +14,7 @@ install( ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) install( - DIRECTORY include/opentelemetry + DIRECTORY include/opentelemetry/ DESTINATION include/opentelemetry FILES_MATCHING PATTERN "*config.h") diff --git a/sdk/include/opentelemetry/sdk/common/global_log_handler.h b/sdk/include/opentelemetry/sdk/common/global_log_handler.h index 612d21eca5..99cf48b820 100644 --- a/sdk/include/opentelemetry/sdk/common/global_log_handler.h +++ b/sdk/include/opentelemetry/sdk/common/global_log_handler.h @@ -55,7 +55,7 @@ inline std::string LevelToString(LogLevel level) class LogHandler { public: - virtual ~LogHandler() = default; + virtual ~LogHandler(); virtual void Handle(LogLevel level, const char *file, @@ -71,22 +71,7 @@ class DefaultLogHandler : public LogHandler const char *file, int line, const char *msg, - const sdk::common::AttributeMap &attributes) noexcept override - { - std::stringstream output_s; - output_s << "[" << LevelToString(level) << "] "; - if (file != nullptr) - { - output_s << "File: " << file << ":" << line; - } - if (msg != nullptr) - { - output_s << msg; - } - output_s << std::endl; - // TBD - print attributes - std::cout << output_s.str(); // thread safe. - } + const sdk::common::AttributeMap &attributes) noexcept override; }; class NoopLogHandler : public LogHandler @@ -96,10 +81,7 @@ class NoopLogHandler : public LogHandler const char *file, int line, const char *msg, - const sdk::common::AttributeMap &error_attributes) noexcept override - { - // ignore the log message - } + const sdk::common::AttributeMap &error_attributes) noexcept override; }; /** @@ -113,7 +95,7 @@ class GlobalLogHandler * * By default, a default LogHandler is returned. */ - static const nostd::shared_ptr &GetLogHandler() noexcept + static inline const nostd::shared_ptr &GetLogHandler() noexcept { return GetHandlerAndLevel().first; } @@ -123,7 +105,7 @@ class GlobalLogHandler * This should be called once at the start of application before creating any Provider * instance. */ - static void SetLogHandler(nostd::shared_ptr eh) noexcept + static inline void SetLogHandler(nostd::shared_ptr eh) noexcept { GetHandlerAndLevel().first = eh; } @@ -133,22 +115,17 @@ class GlobalLogHandler * * By default, a default log level is returned. */ - static LogLevel GetLogLevel() noexcept { return GetHandlerAndLevel().second; } + static inline LogLevel GetLogLevel() noexcept { return GetHandlerAndLevel().second; } /** * Changes the singleton Log level. * This should be called once at the start of application before creating any Provider * instance. */ - static void SetLogLevel(LogLevel level) noexcept { GetHandlerAndLevel().second = level; } + static inline void SetLogLevel(LogLevel level) noexcept { GetHandlerAndLevel().second = level; } private: - static std::pair, LogLevel> &GetHandlerAndLevel() noexcept - { - static std::pair, LogLevel> handler_and_level{ - nostd::shared_ptr(new DefaultLogHandler), LogLevel::Warning}; - return handler_and_level; - } + static std::pair, LogLevel> &GetHandlerAndLevel() noexcept; }; } // namespace internal_log diff --git a/sdk/include/opentelemetry/sdk/metrics/meter.h b/sdk/include/opentelemetry/sdk/metrics/meter.h index 9d9595f660..44e54adf18 100644 --- a/sdk/include/opentelemetry/sdk/metrics/meter.h +++ b/sdk/include/opentelemetry/sdk/metrics/meter.h @@ -43,15 +43,18 @@ class Meter final : public opentelemetry::metrics::Meter nostd::string_view unit = "") noexcept override; void CreateLongObservableCounter(nostd::string_view name, - void (*callback)(opentelemetry::metrics::ObserverResult &), + void (*callback)(opentelemetry::metrics::ObserverResult &, + void *), nostd::string_view description = "", - nostd::string_view unit = "") noexcept override; + nostd::string_view unit = "", + void *state = nullptr) noexcept override; void CreateDoubleObservableCounter( nostd::string_view name, - void (*callback)(opentelemetry::metrics::ObserverResult &), + void (*callback)(opentelemetry::metrics::ObserverResult &, void *), nostd::string_view description = "", - nostd::string_view unit = "") noexcept override; + nostd::string_view unit = "", + void *state = nullptr) noexcept override; nostd::shared_ptr> CreateLongHistogram( nostd::string_view name, @@ -64,15 +67,18 @@ class Meter final : public opentelemetry::metrics::Meter nostd::string_view unit = "") noexcept override; void CreateLongObservableGauge(nostd::string_view name, - void (*callback)(opentelemetry::metrics::ObserverResult &), + void (*callback)(opentelemetry::metrics::ObserverResult &, + void *), nostd::string_view description = "", - nostd::string_view unit = "") noexcept override; + nostd::string_view unit = "", + void *state = nullptr) noexcept override; void CreateDoubleObservableGauge( nostd::string_view name, - void (*callback)(opentelemetry::metrics::ObserverResult &), + void (*callback)(opentelemetry::metrics::ObserverResult &, void *), nostd::string_view description = "", - nostd::string_view unit = "") noexcept override; + nostd::string_view unit = "", + void *state = nullptr) noexcept override; nostd::shared_ptr> CreateLongUpDownCounter( nostd::string_view name, @@ -86,15 +92,17 @@ class Meter final : public opentelemetry::metrics::Meter void CreateLongObservableUpDownCounter( nostd::string_view name, - void (*callback)(opentelemetry::metrics::ObserverResult &), + void (*callback)(opentelemetry::metrics::ObserverResult &, void *), nostd::string_view description = "", - nostd::string_view unit = "") noexcept override; + nostd::string_view unit = "", + void *state = nullptr) noexcept override; void CreateDoubleObservableUpDownCounter( nostd::string_view name, - void (*callback)(opentelemetry::metrics::ObserverResult &), + void (*callback)(opentelemetry::metrics::ObserverResult &, void *), nostd::string_view description = "", - nostd::string_view unit = "") noexcept override; + nostd::string_view unit = "", + void *state = nullptr) noexcept override; /** Returns the associated instruementation library */ const sdk::instrumentationlibrary::InstrumentationLibrary *GetInstrumentationLibrary() @@ -117,18 +125,26 @@ class Meter final : public opentelemetry::metrics::Meter template void RegisterAsyncMetricStorage(InstrumentDescriptor &instrument_descriptor, - void (*callback)(opentelemetry::metrics::ObserverResult &)) + void (*callback)(opentelemetry::metrics::ObserverResult &, + void *), + void *state = nullptr) { auto view_registry = meter_context_->GetViewRegistry(); auto success = view_registry->FindViews( instrument_descriptor, *instrumentation_library_, - [this, &instrument_descriptor, callback](const View &view) { - auto view_instr_desc = instrument_descriptor; - view_instr_desc.name_ = view.GetName(); - view_instr_desc.description_ = view.GetDescription(); - auto storage = std::shared_ptr>( + [this, &instrument_descriptor, callback, state](const View &view) { + auto view_instr_desc = instrument_descriptor; + if (!view.GetName().empty()) + { + view_instr_desc.name_ = view.GetName(); + } + if (!view.GetDescription().empty()) + { + view_instr_desc.description_ = view.GetDescription(); + } + auto storage = std::shared_ptr>( new AsyncMetricStorage(view_instr_desc, view.GetAggregationType(), callback, - &view.GetAttributesProcessor())); + &view.GetAttributesProcessor(), state)); storage_registry_[instrument_descriptor.name_] = storage; return true; }); diff --git a/sdk/include/opentelemetry/sdk/metrics/state/async_metric_storage.h b/sdk/include/opentelemetry/sdk/metrics/state/async_metric_storage.h index e4c20e4010..e5dcbc2738 100644 --- a/sdk/include/opentelemetry/sdk/metrics/state/async_metric_storage.h +++ b/sdk/include/opentelemetry/sdk/metrics/state/async_metric_storage.h @@ -27,12 +27,15 @@ class AsyncMetricStorage : public MetricStorage public: AsyncMetricStorage(InstrumentDescriptor instrument_descriptor, const AggregationType aggregation_type, - void (*measurement_callback)(opentelemetry::metrics::ObserverResult &), - const AttributesProcessor *attributes_processor) + void (*measurement_callback)(opentelemetry::metrics::ObserverResult &, + void *), + const AttributesProcessor *attributes_processor, + void *state = nullptr) : instrument_descriptor_(instrument_descriptor), aggregation_type_{aggregation_type}, measurement_collection_callback_{measurement_callback}, attributes_processor_{attributes_processor}, + state_{state}, cumulative_hash_map_(new AttributesHashMap()), temporal_metric_storage_(instrument_descriptor) {} @@ -46,7 +49,7 @@ class AsyncMetricStorage : public MetricStorage opentelemetry::sdk::metrics::ObserverResult ob_res(attributes_processor_); // read the measurement using configured callback - measurement_collection_callback_(ob_res); + measurement_collection_callback_(ob_res, state_); std::shared_ptr delta_hash_map(new AttributesHashMap()); // process the read measurements - aggregate and store in hashmap for (auto &measurement : ob_res.GetMeasurements()) @@ -79,8 +82,9 @@ class AsyncMetricStorage : public MetricStorage private: InstrumentDescriptor instrument_descriptor_; AggregationType aggregation_type_; - void (*measurement_collection_callback_)(opentelemetry::metrics::ObserverResult &); + void (*measurement_collection_callback_)(opentelemetry::metrics::ObserverResult &, void *); const AttributesProcessor *attributes_processor_; + void *state_; std::unique_ptr cumulative_hash_map_; TemporalMetricStorage temporal_metric_storage_; }; diff --git a/sdk/src/common/BUILD b/sdk/src/common/BUILD index b0724c3810..b8369fc6f4 100644 --- a/sdk/src/common/BUILD +++ b/sdk/src/common/BUILD @@ -27,6 +27,18 @@ cc_library( include_prefix = "src/common", deps = [ "//api", + "//sdk:headers", "//sdk/src/common/platform:fork", ], ) + +cc_library( + name = "global_log_handler", + srcs = [ + "global_log_handler.cc", + ], + deps = [ + "//api", + "//sdk:headers", + ], +) diff --git a/sdk/src/common/CMakeLists.txt b/sdk/src/common/CMakeLists.txt index debffef495..d8674353b6 100644 --- a/sdk/src/common/CMakeLists.txt +++ b/sdk/src/common/CMakeLists.txt @@ -1,4 +1,4 @@ -set(COMMON_SRCS random.cc core.cc) +set(COMMON_SRCS random.cc core.cc global_log_handler.cc) if(WIN32) list(APPEND COMMON_SRCS platform/fork_windows.cc) else() diff --git a/sdk/src/common/global_log_handler.cc b/sdk/src/common/global_log_handler.cc index e69de29bb2..c86b652c70 100644 --- a/sdk/src/common/global_log_handler.cc +++ b/sdk/src/common/global_log_handler.cc @@ -0,0 +1,57 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#include "opentelemetry/sdk/common/global_log_handler.h" + +#include +#include + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace sdk +{ +namespace common +{ +namespace internal_log +{ + +LogHandler::~LogHandler() {} + +void DefaultLogHandler::Handle(LogLevel level, + const char *file, + int line, + const char *msg, + const sdk::common::AttributeMap &attributes) noexcept +{ + std::stringstream output_s; + output_s << "[" << LevelToString(level) << "] "; + if (file != nullptr) + { + output_s << "File: " << file << ":" << line; + } + if (msg != nullptr) + { + output_s << msg; + } + output_s << std::endl; + // TBD - print attributes + std::cout << output_s.str(); // thread safe. +} + +void NoopLogHandler::Handle(LogLevel, + const char *, + int, + const char *, + const sdk::common::AttributeMap &) noexcept +{} + +std::pair, LogLevel> &GlobalLogHandler::GetHandlerAndLevel() noexcept +{ + static std::pair, LogLevel> handler_and_level{ + nostd::shared_ptr(new DefaultLogHandler), LogLevel::Warning}; + return handler_and_level; +} + +} // namespace internal_log +} // namespace common +} // namespace sdk +OPENTELEMETRY_END_NAMESPACE diff --git a/sdk/src/logs/BUILD b/sdk/src/logs/BUILD index ac51799125..53465cb8be 100644 --- a/sdk/src/logs/BUILD +++ b/sdk/src/logs/BUILD @@ -22,6 +22,7 @@ cc_library( deps = [ "//api", "//sdk:headers", + "//sdk/src/common:global_log_handler", "//sdk/src/resource", ], ) diff --git a/sdk/src/metrics/BUILD b/sdk/src/metrics/BUILD index d21daa765c..e75ba6a1ac 100644 --- a/sdk/src/metrics/BUILD +++ b/sdk/src/metrics/BUILD @@ -22,6 +22,7 @@ cc_library( deps = [ "//api", "//sdk:headers", + "//sdk/src/common:global_log_handler", "//sdk/src/resource", ], ) diff --git a/sdk/src/metrics/meter.cc b/sdk/src/metrics/meter.cc index 30725bdccf..600bae9863 100644 --- a/sdk/src/metrics/meter.cc +++ b/sdk/src/metrics/meter.cc @@ -58,27 +58,30 @@ nostd::shared_ptr> Meter::CreateDoubleCounter( } void Meter::CreateLongObservableCounter(nostd::string_view name, - void (*callback)(metrics::ObserverResult &), + void (*callback)(metrics::ObserverResult &, void *), nostd::string_view description, - nostd::string_view unit) noexcept + nostd::string_view unit, + void *state) noexcept { InstrumentDescriptor instrument_descriptor = { std::string{name.data(), name.size()}, std::string{description.data(), description.size()}, std::string{unit.data(), unit.size()}, InstrumentType::kObservableCounter, InstrumentValueType::kLong}; - RegisterAsyncMetricStorage(instrument_descriptor, callback); + RegisterAsyncMetricStorage(instrument_descriptor, callback, state); } void Meter::CreateDoubleObservableCounter(nostd::string_view name, - void (*callback)(metrics::ObserverResult &), + void (*callback)(metrics::ObserverResult &, + void *), nostd::string_view description, - nostd::string_view unit) noexcept + nostd::string_view unit, + void *state) noexcept { InstrumentDescriptor instrument_descriptor = { std::string{name.data(), name.size()}, std::string{description.data(), description.size()}, std::string{unit.data(), unit.size()}, InstrumentType::kObservableCounter, InstrumentValueType::kDouble}; - RegisterAsyncMetricStorage(instrument_descriptor, callback); + RegisterAsyncMetricStorage(instrument_descriptor, callback, state); } nostd::shared_ptr> Meter::CreateLongHistogram( @@ -110,27 +113,29 @@ nostd::shared_ptr> Meter::CreateDoubleHistogram( } void Meter::CreateLongObservableGauge(nostd::string_view name, - void (*callback)(metrics::ObserverResult &), + void (*callback)(metrics::ObserverResult &, void *), nostd::string_view description, - nostd::string_view unit) noexcept + nostd::string_view unit, + void *state) noexcept { InstrumentDescriptor instrument_descriptor = { std::string{name.data(), name.size()}, std::string{description.data(), description.size()}, std::string{unit.data(), unit.size()}, InstrumentType::kObservableGauge, InstrumentValueType::kLong}; - RegisterAsyncMetricStorage(instrument_descriptor, callback); + RegisterAsyncMetricStorage(instrument_descriptor, callback, state); } void Meter::CreateDoubleObservableGauge(nostd::string_view name, - void (*callback)(metrics::ObserverResult &), + void (*callback)(metrics::ObserverResult &, void *), nostd::string_view description, - nostd::string_view unit) noexcept + nostd::string_view unit, + void *state) noexcept { InstrumentDescriptor instrument_descriptor = { std::string{name.data(), name.size()}, std::string{description.data(), description.size()}, std::string{unit.data(), unit.size()}, InstrumentType::kObservableGauge, InstrumentValueType::kDouble}; - RegisterAsyncMetricStorage(instrument_descriptor, callback); + RegisterAsyncMetricStorage(instrument_descriptor, callback, state); } nostd::shared_ptr> Meter::CreateLongUpDownCounter( @@ -162,27 +167,31 @@ nostd::shared_ptr> Meter::CreateDoubleUpDownCount } void Meter::CreateLongObservableUpDownCounter(nostd::string_view name, - void (*callback)(metrics::ObserverResult &), + void (*callback)(metrics::ObserverResult &, + void *), nostd::string_view description, - nostd::string_view unit) noexcept + nostd::string_view unit, + void *state) noexcept { InstrumentDescriptor instrument_descriptor = { std::string{name.data(), name.size()}, std::string{description.data(), description.size()}, std::string{unit.data(), unit.size()}, InstrumentType::kObservableUpDownCounter, InstrumentValueType::kLong}; - RegisterAsyncMetricStorage(instrument_descriptor, callback); + RegisterAsyncMetricStorage(instrument_descriptor, callback, state); } void Meter::CreateDoubleObservableUpDownCounter(nostd::string_view name, - void (*callback)(metrics::ObserverResult &), + void (*callback)(metrics::ObserverResult &, + void *), nostd::string_view description, - nostd::string_view unit) noexcept + nostd::string_view unit, + void *state) noexcept { InstrumentDescriptor instrument_descriptor = { std::string{name.data(), name.size()}, std::string{description.data(), description.size()}, std::string{unit.data(), unit.size()}, InstrumentType::kObservableUpDownCounter, InstrumentValueType::kDouble}; - RegisterAsyncMetricStorage(instrument_descriptor, callback); + RegisterAsyncMetricStorage(instrument_descriptor, callback, state); } const sdk::instrumentationlibrary::InstrumentationLibrary *Meter::GetInstrumentationLibrary() diff --git a/sdk/src/metrics/sync_instruments.cc b/sdk/src/metrics/sync_instruments.cc index 5c94ae6f24..7cf9034cdc 100644 --- a/sdk/src/metrics/sync_instruments.cc +++ b/sdk/src/metrics/sync_instruments.cc @@ -4,6 +4,9 @@ #ifndef ENABLE_METRICS_PREVIEW # include "opentelemetry/sdk/metrics/sync_instruments.h" # include "opentelemetry/sdk/metrics/state/metric_storage.h" +# include "opentelemetry/sdk_config.h" + +# include OPENTELEMETRY_BEGIN_NAMESPACE namespace sdk @@ -139,11 +142,25 @@ void LongHistogram::Record(long value, const opentelemetry::common::KeyValueIterable &attributes, const opentelemetry::context::Context &context) noexcept { + if (value < 0) + { + OTEL_INTERNAL_LOG_WARN( + "[LongHistogram::Record(value, attributes)] negative value provided to histogram Name:" + << instrument_descriptor_.name_ << " Value:" << value); + return; + } return storage_->RecordLong(value, attributes, context); } void LongHistogram::Record(long value, const opentelemetry::context::Context &context) noexcept { + if (value < 0) + { + OTEL_INTERNAL_LOG_WARN( + "[LongHistogram::Record(value)] negative value provided to histogram Name:" + << instrument_descriptor_.name_ << " Value:" << value); + return; + } return storage_->RecordLong(value, context); } @@ -156,11 +173,26 @@ void DoubleHistogram::Record(double value, const opentelemetry::common::KeyValueIterable &attributes, const opentelemetry::context::Context &context) noexcept { + if (value < 0 || std::isnan(value) || std::isinf(value)) + { + OTEL_INTERNAL_LOG_WARN( + "[DoubleHistogram::Record(value, attributes)] negative/nan/infinite value provided to " + "histogram Name:" + << instrument_descriptor_.name_); + return; + } return storage_->RecordDouble(value, attributes, context); } void DoubleHistogram::Record(double value, const opentelemetry::context::Context &context) noexcept { + if (value < 0 || std::isnan(value) || std::isinf(value)) + { + OTEL_INTERNAL_LOG_WARN( + "[DoubleHistogram::Record(value)] negative/nan/infinite value provided to histogram Name:" + << instrument_descriptor_.name_); + return; + } return storage_->RecordDouble(value, context); } diff --git a/sdk/src/trace/BUILD b/sdk/src/trace/BUILD index 34ec5108d2..362680b744 100644 --- a/sdk/src/trace/BUILD +++ b/sdk/src/trace/BUILD @@ -22,6 +22,7 @@ cc_library( deps = [ "//api", "//sdk:headers", + "//sdk/src/common:global_log_handler", "//sdk/src/common:random", "//sdk/src/resource", ], diff --git a/sdk/test/common/BUILD b/sdk/test/common/BUILD index 8a98e5617d..91d56996fb 100644 --- a/sdk/test/common/BUILD +++ b/sdk/test/common/BUILD @@ -124,6 +124,7 @@ cc_test( deps = [ "//api", "//sdk:headers", + "//sdk/src/common:global_log_handler", "@com_google_googletest//:gtest_main", ], ) diff --git a/sdk/test/metrics/async_metric_storage_test.cc b/sdk/test/metrics/async_metric_storage_test.cc index a4decaaa79..2be5332a8d 100644 --- a/sdk/test/metrics/async_metric_storage_test.cc +++ b/sdk/test/metrics/async_metric_storage_test.cc @@ -39,7 +39,8 @@ class WritableMetricStorageTestFixture : public ::testing::TestWithParam &observer_result) + static void Fetcher(opentelemetry::metrics::ObserverResult &observer_result, + void * /*state*/) { fetch_count++; if (fetch_count == 1) diff --git a/sdk/test/metrics/sync_instruments_test.cc b/sdk/test/metrics/sync_instruments_test.cc index e029821d41..1a590d8d26 100644 --- a/sdk/test/metrics/sync_instruments_test.cc +++ b/sdk/test/metrics/sync_instruments_test.cc @@ -9,6 +9,8 @@ # include "opentelemetry/sdk/metrics/state/multi_metric_storage.h" # include +# include +# include using namespace opentelemetry; using namespace opentelemetry::sdk::instrumentationlibrary; @@ -103,7 +105,7 @@ TEST(SyncInstruments, LongHistogram) std::unique_ptr metric_storage(new MultiMetricStorage()); LongHistogram counter(instrument_descriptor, std::move(metric_storage)); EXPECT_NO_THROW(counter.Record(10l, opentelemetry::context::Context{})); - EXPECT_NO_THROW(counter.Record(10l, opentelemetry::context::Context{})); + EXPECT_NO_THROW(counter.Record(-10l, opentelemetry::context::Context{})); // This is ignored EXPECT_NO_THROW(counter.Record( 10l, opentelemetry::common::KeyValueIterableView({{"abc", "123"}, {"xyz", "456"}}), @@ -120,7 +122,11 @@ TEST(SyncInstruments, DoubleHistogram) std::unique_ptr metric_storage(new MultiMetricStorage()); DoubleHistogram counter(instrument_descriptor, std::move(metric_storage)); EXPECT_NO_THROW(counter.Record(10.10, opentelemetry::context::Context{})); - EXPECT_NO_THROW(counter.Record(10.10, opentelemetry::context::Context{})); + EXPECT_NO_THROW(counter.Record(-10.10, opentelemetry::context::Context{})); // This is ignored. + EXPECT_NO_THROW(counter.Record(std::numeric_limits::quiet_NaN(), + opentelemetry::context::Context{})); // This is ignored too + EXPECT_NO_THROW(counter.Record(std::numeric_limits::infinity(), + opentelemetry::context::Context{})); // This is ignored too EXPECT_NO_THROW(counter.Record( 10.10, opentelemetry::common::KeyValueIterableView({{"abc", "123"}, {"xyz", "456"}}), diff --git a/third_party/nlohmann-json b/third_party/nlohmann-json index db78ac1d77..4f8fba1406 160000 --- a/third_party/nlohmann-json +++ b/third_party/nlohmann-json @@ -1 +1 @@ -Subproject commit db78ac1d7716f56fc9f1b030b715f872f93964e4 +Subproject commit 4f8fba14066156b73f1189a2b8bd568bde5284c5 diff --git a/third_party_release b/third_party_release index 964cbfb871..e8ad402c06 100644 --- a/third_party_release +++ b/third_party_release @@ -1,10 +1,23 @@ +# +# MAINTAINER +# +# This file is used for the CMake build. +# +# When changing (add, upgrade, remove) dependencies +# please update: +# - the Bazel build, see file +# /bazel/repository.bzl +# - git submodule, see command +# git submodule status +# + gRPC=v1.43.2 thrift=0.14.1 abseil=20210324.0 benchmark=v1.5.3 googletest=release-1.10.0-459-ga6dfd3ac ms-gsl=v3.1.0-67-g6f45293 -nlohmann-json=v3.9.1 +nlohmann-json=v3.10.5 opentelemetry-proto=v0.17.0 prometheus-cpp=v1.0.0 vcpkg=2022.04.12