From 6bd4aaa6b23caca00413e12ba9b9bebc4e5cc219 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Mon, 11 Jan 2021 23:43:33 -0800 Subject: [PATCH 01/76] Drafts for proper TLD operation. Verified that TLD flow works well with existing ETW tooling. --- CMakeLists.txt | 1 - CMakeSettings.json | 4 ++-- .../opentelemetry/exporters/etw/.gitignore | 1 + .../opentelemetry/exporters/etw/etw_data.h | 18 ++---------------- .../exporters/etw/etw_provider_exporter.h | 13 ++----------- .../exporters/etw/etw_traceloggingdynamic.h | 8 ++++++++ exporters/etw/src/etw_provider_exporter.cc | 5 ----- exporters/etw/src/etw_tracer_exporter.cc | 5 ----- exporters/etw/test/etw_provider_test.cc | 5 ----- exporters/etw/test/etw_tracer_test.cc | 8 ++------ 10 files changed, 17 insertions(+), 51 deletions(-) create mode 100644 exporters/etw/include/opentelemetry/exporters/etw/.gitignore create mode 100644 exporters/etw/include/opentelemetry/exporters/etw/etw_traceloggingdynamic.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e8aeed756..3ac1a6dadd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,7 +88,6 @@ if(WIN32) add_definitions(-DHAVE_MSGPACK) # Option below will be removed once we donate the TraceLoggingDynamic.h to # OSS - add_definitions(-DHAVE_NO_TLD) endif(WITH_ETW) endif(WIN32) diff --git a/CMakeSettings.json b/CMakeSettings.json index e5285d3fad..21b6d41b3d 100644 --- a/CMakeSettings.json +++ b/CMakeSettings.json @@ -4,7 +4,7 @@ "name": "nostd-x64-Debug", "generator": "Ninja", "configurationType": "Debug", - "inheritEnvironments": [ "msvc_x64_x64" ], + "inheritEnvironments": [ "msvc_x64" ], "buildRoot": "${projectDir}\\out\\vs2019\\${name}", "installRoot": "${projectDir}\\out\\vs2019\\${name}\\install", "cmakeCommandArgs": "", @@ -27,7 +27,7 @@ "name": "nostd-x64-Release", "generator": "Ninja", "configurationType": "RelWithDebInfo", - "inheritEnvironments": [ "msvc_x64_x64" ], + "inheritEnvironments": [ "msvc_x64" ], "buildRoot": "${projectDir}\\out\\vs2019\\${name}", "installRoot": "${projectDir}\\out\\vs2019\\${name}\\install", "cmakeCommandArgs": "", diff --git a/exporters/etw/include/opentelemetry/exporters/etw/.gitignore b/exporters/etw/include/opentelemetry/exporters/etw/.gitignore new file mode 100644 index 0000000000..5f4e43c3a0 --- /dev/null +++ b/exporters/etw/include/opentelemetry/exporters/etw/.gitignore @@ -0,0 +1 @@ +TraceLoggingDynamic.h diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_data.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_data.h index 8e589a7d07..f435098355 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_data.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_data.h @@ -157,21 +157,7 @@ class Tracer : public trace::Tracer }); m["name"] = name.data(); -#ifdef HAVE_TLD - if (encoding == ETWProvider::ETW_MANIFEST) - { - etwProvider().writeTld(provHandle, m); - return; - } -#endif - -#ifdef HAVE_MSGPACK - if (encoding == ETWProvider::ETW_MSGPACK) - { - etwProvider().writeMsgPack(provHandle, m); - return; - } -#endif + etwProvider().write(provHandle, m, encoding); }; /// @@ -355,7 +341,7 @@ class TracerProvider : public trace::TracerProvider // "XML" - use XML // "ETW" - use 'classic' Trace Logging Dynamic manifest ETW event // -#if defined(HAVE_NO_TLD) && defined(HAVE_MSGPACK) +#if defined(HAVE_MSGPACK) ETWProvider::EventFormat evtFmt = ETWProvider::EventFormat::ETW_MSGPACK; #else ETWProvider::EventFormat evtFmt = ETWProvider::EventFormat::ETW_MANIFEST; diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider_exporter.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider_exporter.h index e69182b119..221a3e8f09 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider_exporter.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider_exporter.h @@ -36,11 +36,7 @@ # include "nlohmann/json.hpp" #endif -#ifndef HAVE_NO_TLD -// Allow to opt-out from `TraceLoggingDynamic.h` header usage -# define HAVE_TLD -# include "TraceLoggingDynamic.h" -#endif +#include "opentelemetry/exporters/etw/etw_traceloggingdynamic.h" #include #include @@ -107,15 +103,10 @@ class ETWProvider /// /// /// - Handle &open(const std::string &providerId, EventFormat format = EventFormat::ETW_MANIFEST) + Handle &open(const std::string &providerId, EventFormat format = EventFormat::ETW_MSGPACK) { std::lock_guard lock(m_providerMapLock); -#ifdef HAVE_NO_TLD - // Fallback to MessagePack-encoded ETW events - format = EventFormat::ETW_MSGPACK; -#endif - // Check and return if provider is already registered auto it = providers().find(providerId); if (it != providers().end()) diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_traceloggingdynamic.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_traceloggingdynamic.h new file mode 100644 index 0000000000..88914c95e1 --- /dev/null +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_traceloggingdynamic.h @@ -0,0 +1,8 @@ +#pragma once + +#ifdef __has_include +# if __has_include("TraceLoggingDynamic.h") +# include "TraceLoggingDynamic.h" +# define HAVE_TLD +# endif +#endif diff --git a/exporters/etw/src/etw_provider_exporter.cc b/exporters/etw/src/etw_provider_exporter.cc index 3dd9396897..570cd51b33 100644 --- a/exporters/etw/src/etw_provider_exporter.cc +++ b/exporters/etw/src/etw_provider_exporter.cc @@ -1,10 +1,5 @@ #ifdef _WIN32 -/* TODO: this definition needs to be removed when TraceLoggingDynamic.h is OSS */ -# ifndef HAVE_NO_TLD -# define HAVE_NO_TLD -# endif - # include "opentelemetry/exporters/etw/etw_provider_exporter.h" #endif diff --git a/exporters/etw/src/etw_tracer_exporter.cc b/exporters/etw/src/etw_tracer_exporter.cc index 6842a83933..63ef489797 100644 --- a/exporters/etw/src/etw_tracer_exporter.cc +++ b/exporters/etw/src/etw_tracer_exporter.cc @@ -1,10 +1,5 @@ #ifdef _WIN32 -/* TODO: this definition needs to be removed when TraceLoggingDynamic.h is OSS */ -# ifndef HAVE_NO_TLD -# define HAVE_NO_TLD -# endif - # include "opentelemetry/exporters/etw/etw_tracer_exporter.h" #endif diff --git a/exporters/etw/test/etw_provider_test.cc b/exporters/etw/test/etw_provider_test.cc index 1f797c91c8..439d3373a1 100644 --- a/exporters/etw/test/etw_provider_test.cc +++ b/exporters/etw/test/etw_provider_test.cc @@ -17,11 +17,6 @@ # include # include -/* TODO: this definition needs to be removed when TraceLoggingDynamic.h is OSS */ -# ifndef HAVE_NO_TLD -# define HAVE_NO_TLD -# endif - # include "opentelemetry/exporters/etw/etw_provider_exporter.h" using namespace OPENTELEMETRY_NAMESPACE; diff --git a/exporters/etw/test/etw_tracer_test.cc b/exporters/etw/test/etw_tracer_test.cc index c07fa53cd8..050a1f9378 100644 --- a/exporters/etw/test/etw_tracer_test.cc +++ b/exporters/etw/test/etw_tracer_test.cc @@ -17,11 +17,6 @@ # include # include -/* TODO: this definition needs to be removed when TraceLoggingDynamic.h is OSS */ -# ifndef HAVE_NO_TLD -# define HAVE_NO_TLD -# endif - # include "opentelemetry/exporters/etw/etw_tracer_exporter.h" # include "opentelemetry/sdk/trace/simple_processor.h" @@ -35,7 +30,8 @@ TEST(ETWTracer, TracerCheck) std::string eventName = "MyEvent"; exporter::ETW::TracerProvider tp; - auto tracer = tp.GetTracer(providerName); + // TODO: this code should fallback to MsgPack if TLD is not available + auto tracer = tp.GetTracer(providerName, "TLD"); auto span = tracer->StartSpan("MySpan"); ETWEvent event = { From f8a3af1a10d2c6b9a80eeff6bbac823180ecce7a Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 15 Jan 2021 00:32:41 -0800 Subject: [PATCH 02/76] Add CODEOWNERS for ETW exporter --- .github/CODEOWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 9852bcdf5a..3c5a791e5d 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,4 +2,5 @@ # This file controls who is tagged for review for any given pull request. # For anything not explicitly taken by someone else: +/exporters/etw/ @reyang @maxgolov @lalitb @ThomsonTan * @open-telemetry/cpp-approvers From 035d86301f6239e8d67d6e362354c69cdb2fb204 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 15 Jan 2021 00:33:04 -0800 Subject: [PATCH 03/76] Add support for owning Properties container --- .../exporters/etw/etw_properties.h | 472 ++++++++++++++++++ 1 file changed, 472 insertions(+) create mode 100644 exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h new file mode 100644 index 0000000000..330df4ccfe --- /dev/null +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h @@ -0,0 +1,472 @@ +#pragma once + +#include "opentelemetry/version.h" + +#include "opentelemetry/common/key_value_iterable_view.h" + +#include +#include +#include +#include + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace core {}; +namespace trace {}; +namespace exporter +{ +namespace ETW +{ + +/** + * @brief PropertyVariant provides: + * - a constructor to initialize from initializer lists + * - an owning wrapper around `common::AttributeValue` + */ +using PropertyVariant = + nostd::variant, +#endif + std::vector, + std::vector, + std::vector, + std::vector, + std::vector, + std::vector, + std::vector>; + +/** + * @brief PropertyValue class that holds PropertyVariant and + * provides converter for non-owning common::AttributeValue +*/ +class PropertyValue : public PropertyVariant +{ + + /** + * @brief Convert span to vector + * @tparam T + * @param source + * @return + */ + template + static std::vector to_vector(const nostd::span &source) + { + return std::vector(source.begin(), source.end()); + }; + + /** + * @brief Convert span to vector + * @param source + * @return + */ + std::vector static to_vector(const nostd::span &source) + { + std::vector result; + result.reserve(source.size()); + for (const auto &item : source) + { + result.push_back(std::string(item.data())); + } + return result; + }; + + /** + * @brief Convert vector to span. + * @tparam T + * @param std::vector + * @return nostd::span + */ + template ::value, bool> = true> + static nostd::span to_span(const std::vector &vec) + { + nostd::span result(vec.data(), vec.size()); + return result; + }; + + /** + * @brief Convert vector to span. + * @tparam T + * @param std::vector + * @return nostd::span + */ + template ::value, bool> = true> + static nostd::span to_span(const std::vector &vec) + { + nostd::span result(vec.data(), vec.size()); + return result; + }; + +#if 0 + /** + * @brief Convert vector to span. + * FIXME: std::vector is a special compact type that does not have .data() member + * + * @param v + * @return + */ + static nostd::span to_span(const std::vector &vec) + { + nostd::span result(vec.data(), vec.size()); + return result; + }; +#endif + +public: + /** + * @brief PropertyValue from bool + * @param v + * @return + */ + PropertyValue(bool value) : PropertyVariant(value){}; + + /** + * @brief PropertyValue from integral. + * @param v + * @return + */ + template ::value, bool> = true> + PropertyValue(TInteger number) : PropertyVariant(number){}; + + /** + * @brief PropertyValue from floating point. + * @param v + * @return + */ + template ::value, bool> = true> + PropertyValue(TFloat number) : PropertyVariant(double(number)){}; + + /** + * @brief Default PropertyValue (int32_t=0) + * @param v + * @return + */ + PropertyValue() : PropertyVariant(int32_t(0)){}; + + /** + * @brief PropertyValue from array of characters as string. + * + * @param v + * @return + */ + PropertyValue(char value[]) : PropertyVariant(std::string(value)){}; + + /** + * @brief PropertyValue from array of characters as string. + * + * @param v + * @return + */ + PropertyValue(const char *value) : PropertyVariant(value){}; + + /** + * @brief PropertyValue from string. + * + * @param v + * @return + */ + PropertyValue(const std::string &value) : PropertyVariant(value){}; + + /** + * @brief PropertyValue from vector as array. + * @return + */ + template + PropertyValue(std::vector value) : PropertyVariant(value){}; + + /** + * @brief Convert owning PropertyValue to non-owning common::AttributeValue + * @return + */ + PropertyValue &FromAttributeValue(const common::AttributeValue& v) + { + switch (v.index()) + { + case common::AttributeType::TYPE_BOOL: + PropertyVariant::operator=(nostd::get(v)); + break; + case common::AttributeType::TYPE_INT: + PropertyVariant::operator=(nostd::get(v)); + break; + case common::AttributeType::TYPE_INT64: + PropertyVariant::operator=(nostd::get(v)); + break; + case common::AttributeType::TYPE_UINT: + PropertyVariant::operator=(nostd::get(v)); + break; + case common::AttributeType::TYPE_UINT64: + PropertyVariant::operator=(nostd::get(v)); + break; + case common::AttributeType::TYPE_DOUBLE: + PropertyVariant::operator=(nostd::get(v)); + break; + case common::AttributeType::TYPE_STRING: { + PropertyVariant::operator= (nostd::string_view(nostd::get(v)).data()); + break; + }; + +#ifdef HAVE_CSTRING_TYPE + case common::AttributeType::TYPE_CSTRING: + PropertyVariant::operator=(nostd::get(v)); + break; +#endif + +#ifdef HAVE_SPAN_BYTE + case common::AttributeType::TYPE_SPAN_BYTE: + PropertyVariant::operator=(to_vector(nostd::get>(v))); + break; +#endif + + case common::AttributeType::TYPE_SPAN_BOOL: + PropertyVariant::operator=(to_vector(nostd::get>(v))); + break; + + case common::AttributeType::TYPE_SPAN_INT: + PropertyVariant::operator=(to_vector(nostd::get>(v))); + break; + + case common::AttributeType::TYPE_SPAN_INT64: + PropertyVariant::operator=(to_vector(nostd::get>(v))); + break; + + case common::AttributeType::TYPE_SPAN_UINT: + PropertyVariant::operator=(to_vector(nostd::get>(v))); + break; + + case common::AttributeType::TYPE_SPAN_UINT64: + PropertyVariant::operator=(to_vector(nostd::get>(v))); + break; + + case common::AttributeType::TYPE_SPAN_DOUBLE: + PropertyVariant::operator=(to_vector(nostd::get>(v))); + break; + + case common::AttributeType::TYPE_SPAN_STRING: + PropertyVariant::operator=(to_vector(nostd::get>(v))); + break; + + default: + break; + } + return (*this); + } + + /** + * @brief Convert owning PropertyValue to non-owning common::AttributeValue + * @param other + */ + common::AttributeValue ToAttributeValue() const + { + common::AttributeValue value; + + switch (this->index()) + { + case common::AttributeType::TYPE_BOOL: + value = nostd::get(*this); + break; + case common::AttributeType::TYPE_INT: + value = nostd::get(*this); + break; + case common::AttributeType::TYPE_INT64: + value = nostd::get(*this); + break; + case common::AttributeType::TYPE_UINT: + value = nostd::get(*this); + break; + case common::AttributeType::TYPE_UINT64: + value = nostd::get(*this); + break; + case common::AttributeType::TYPE_DOUBLE: + value = nostd::get(*this); + break; + + case common::AttributeType::TYPE_STRING: { + const std::string &str = nostd::get(*this); + return nostd::string_view(str.data(), str.size()); + break; + } + +#ifdef HAVE_CSTRING_TYPE + case common::AttributeType::TYPE_CSTRING: + value = nostd::get(*this); + break; +#endif + +#ifdef HAVE_SPAN_BYTE + case common::AttributeType::TYPE_SPAN_BYTE: + value = to_span(nostd::get>(self)); + break; +#endif + + case common::AttributeType::TYPE_SPAN_BOOL: { + const auto& vec = nostd::get>(*this); + // FIXME: sort out how to remap from vector to span + break; + } + + case common::AttributeType::TYPE_SPAN_INT: + value = to_span(nostd::get>(*this)); + break; + + case common::AttributeType::TYPE_SPAN_INT64: + value = to_span(nostd::get>(*this)); + break; + + case common::AttributeType::TYPE_SPAN_UINT: + value = to_span(nostd::get>(*this)); + break; + + case common::AttributeType::TYPE_SPAN_UINT64: + value = to_span(nostd::get>(*this)); + break; + + case common::AttributeType::TYPE_SPAN_DOUBLE: + value = to_span(nostd::get>(*this)); + break; + + case common::AttributeType::TYPE_SPAN_STRING: + // FIXME: sort out how to remap from vector to span + // value = to_span(nostd::get>(self)); + break; + + default: + break; + } + return value; + } +}; + +/** + * @brief Map of PropertyValue + */ +using PropertyValueMap = std::map; + +/** + * @brief Map of PropertyValue with common::KeyValueIterable interface. + */ +class Properties : public common::KeyValueIterable, public PropertyValueMap +{ + + /** + * @brief Helper tyoe for map constructor. + */ + using PropertyValueType = std::pair; + +public: + + /** + * @brief PropertyValueMap constructor. + */ + Properties() : PropertyValueMap() {}; + + /** + * @brief PropertyValueMap constructor from initializer list. + */ + Properties(const std::initializer_list properties) + : PropertyValueMap() + { + (*this) = (properties); + }; + + /** + * @brief PropertyValueMap assignment operator from initializer list. + */ + Properties &operator=(std::initializer_list properties) + { + PropertyValueMap::operator = (properties); + return (*this); + }; + + /** + * @brief PropertyValueMap constructor from map. + */ + Properties(const PropertyValueMap &properties) : PropertyValueMap() + { + (*this) = properties; + }; + + /** + * @brief PropertyValueMap assignment operator from map. + */ + Properties &operator=(const PropertyValueMap &properties) + { + PropertyValueMap::operator=(properties); + return (*this); + }; + + /** + * @brief PropertyValueMap constructor from KeyValueIterable + * allows to convert non-Owning KeyValueIterable to owning + * container. + * + */ + Properties(const common::KeyValueIterable &other) + { + (*this) = other; + } + + /** + * @brief PropertyValueMap assignment operator. + */ + Properties &operator=(const 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; + }); + return (*this); + }; + + /** + * @brief PropertyValueMap property accessor. + */ + PropertyValue &operator[](const std::string &k) + { + return PropertyValueMap::operator[](k); + } + + /** + * Iterate over key-value pairs + * @param callback a callback to invoke for each key-value. If the callback returns false, + * the iteration is aborted. + * @return true if every key-value pair was iterated over + */ + bool ForEachKeyValue(nostd::function_ref + callback) const noexcept override + { + for (const auto &kv : (*this)) + { + const common::AttributeValue& value = kv.second.ToAttributeValue(); + if (!callback(nostd::string_view{kv.first}, value)) + { + return false; + } + } + return true; + }; + + /** + * @return the number of key-value pairs + */ + size_t size() const noexcept override + { + return PropertyValueMap::size(); + }; + +}; + +} +} // namespace exporter +OPENTELEMETRY_END_NAMESPACE From 1141e29e9a662cf498e08e9b6338e2dfacb4a74f Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 15 Jan 2021 00:33:45 -0800 Subject: [PATCH 04/76] Make SpanContextKeyValueIterable empty container by default --- api/include/opentelemetry/trace/span_context_kv_iterable.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/include/opentelemetry/trace/span_context_kv_iterable.h b/api/include/opentelemetry/trace/span_context_kv_iterable.h index bcc7465b89..9fc78f24b7 100644 --- a/api/include/opentelemetry/trace/span_context_kv_iterable.h +++ b/api/include/opentelemetry/trace/span_context_kv_iterable.h @@ -24,11 +24,11 @@ class SpanContextKeyValueIterable */ virtual bool ForEachKeyValue( nostd::function_ref - callback) const noexcept = 0; + callback) const noexcept { return true; }; /** * @return the number of key-value pairs */ - virtual size_t size() const noexcept = 0; + virtual size_t size() const noexcept { return 0; }; }; } // namespace trace OPENTELEMETRY_END_NAMESPACE From 01cd9ac8861744e78fdfed0b3ed8d0813b27b134 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 15 Jan 2021 00:34:41 -0800 Subject: [PATCH 05/76] is_key_value_iterable does not property test for subclasses of KeyValueIterable: relax this restriction for now --- api/include/opentelemetry/trace/tracer.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/api/include/opentelemetry/trace/tracer.h b/api/include/opentelemetry/trace/tracer.h index 8f1a6ec617..974f0a84e3 100644 --- a/api/include/opentelemetry/trace/tracer.h +++ b/api/include/opentelemetry/trace/tracer.h @@ -43,8 +43,7 @@ class Tracer return this->StartSpan(name, {}, {}, options); } - template ::value> * = nullptr> + template nostd::shared_ptr StartSpan(nostd::string_view name, const T &attributes, const StartSpanOptions &options = {}) noexcept From 01c693c5b57ef6d0adfcdcc1a10ba3e456596722 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 15 Jan 2021 00:35:10 -0800 Subject: [PATCH 06/76] Allow C string type --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ac1a6dadd..7c6106f12f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,8 @@ cmake_policy(SET CMP0057 NEW) project(opentelemetry-cpp) +add_definitions(-DHAVE_CSTRING_TYPE) + file(READ "${CMAKE_CURRENT_LIST_DIR}/api/include/opentelemetry/version.h" OPENTELEMETRY_CPP_HEADER_VERSION_H) if(OPENTELEMETRY_CPP_HEADER_VERSION_H MATCHES From 66b1ee2fac76d21c20f8e1a44f6d3d9fe7b65b50 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 15 Jan 2021 00:35:45 -0800 Subject: [PATCH 07/76] Add ability for vendors to customize their ETW field names --- .../opentelemetry/exporters/etw/etw_fields.h | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 exporters/etw/include/opentelemetry/exporters/etw/etw_fields.h diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_fields.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_fields.h new file mode 100644 index 0000000000..dc8f622ed0 --- /dev/null +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_fields.h @@ -0,0 +1,34 @@ +#pragma once + +#ifdef CUSTOM_ETW_FIELDS_H +#include CUSTOM_ETW_FIELDS_H +#else +/* clang-format off */ + +/* Field name constants */ +# define ETW_FIELD_NAME "name" /* Event name */ +# define ETW_FIELD_TYPE "type" /* Event type (TLD) */ +# define ETW_FIELD_VERSION "ver" /* Event version */ +# define ETW_FIELD_TIME "time" /* Event time */ +# define ETW_FIELD_KIND "kind" /* Event kind (MsgPack) */ + +/* Common TraceId constant to assoc events with trace parent */ +# define ETW_FIELD_TRACE_ID "TraceId" /* OT Trace Id */ + +/* Span constants */ +# define ETW_FIELD_SPAN_ID "SpanId" /* OT Span Id */ +# define ETW_FIELD_SPAN_START "SpanStart" /* ETW for Span Start */ +# define ETW_FIELD_SPAN_END "SpanEnd" /* ETW for Span Start */ +# define ETW_FIELD_SPAN_LINKS "SpanLinks" /* OT Span Links array */ +# define ETW_FIELD_SPAN_ATTRIBS "SpanAttributes" /* OT Span Attribs array */ +# define ETW_FIELD_SPAN_PARENTID "SpanParentId" /* OT Span ParentId */ +# define ETW_FIELD_SPAN_KIND "SpanKind" + +/* Span option constants */ +# define ETW_FIELD_STARTTIME "startTime" /* ETW event startTime */ +# define ETW_FIELD_DURATION "duration" /* OT Span or Op duration */ +# define ETW_FIELD_SUCCESS "success" /* OT Span success */ +# define ETW_FIELD_STATUSCODE "statusCode" /* OT Span status code */ + +/* clang-format on */ +#endif From 90ecfd07d2349b9500b9f77a6f1d5b771c6f3428 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 15 Jan 2021 00:36:59 -0800 Subject: [PATCH 08/76] Code refactor to address outstanding feature parity issues --- exporters/etw/BUILD | 2 +- .../opentelemetry/exporters/etw/etw_data.h | 678 ++++++++++-------- ...etw_provider_exporter.h => etw_provider.h} | 44 +- .../exporters/etw/etw_recordable.h | 215 ++++++ .../exporters/etw/etw_tracer_exporter.h | 17 +- exporters/etw/src/etw_provider_exporter.cc | 2 +- exporters/etw/test/etw_provider_test.cc | 2 +- exporters/etw/test/etw_tracer_test.cc | 135 ++-- 8 files changed, 702 insertions(+), 393 deletions(-) rename exporters/etw/include/opentelemetry/exporters/etw/{etw_provider_exporter.h => etw_provider.h} (95%) create mode 100644 exporters/etw/include/opentelemetry/exporters/etw/etw_recordable.h diff --git a/exporters/etw/BUILD b/exporters/etw/BUILD index 1359906b94..70690815d2 100644 --- a/exporters/etw/BUILD +++ b/exporters/etw/BUILD @@ -6,7 +6,7 @@ cc_library( "src/etw_provider_exporter.cc", ], hdrs = [ - "include/opentelemetry/exporters/etw/etw_provider_exporter.h", + "include/opentelemetry/exporters/etw/etw_provider.h", "include/opentelemetry/exporters/etw/utils.h", "include/opentelemetry/exporters/etw/uuid.h", ], diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_data.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_data.h index f435098355..cd9bf99e49 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_data.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_data.h @@ -5,12 +5,19 @@ #include #include +#include +#include +#include +#include +#include +#include #include "opentelemetry/nostd/shared_ptr.h" #include "opentelemetry/nostd/string_view.h" #include "opentelemetry/nostd/unique_ptr.h" #include "opentelemetry/common/key_value_iterable_view.h" + #include "opentelemetry/trace/span.h" #include "opentelemetry/trace/span_context_kv_iterable_view.h" #include "opentelemetry/trace/span_id.h" @@ -21,225 +28,372 @@ #include "opentelemetry/sdk/trace/recordable.h" #include "opentelemetry/sdk/trace/span_data.h" -#include -#include -#include -#include -#include -#include - -#include "opentelemetry/exporters/etw/etw_provider_exporter.h" - +#include "opentelemetry/exporters/etw/etw_provider.h" +#include "opentelemetry/exporters/etw/etw_fields.h" +#include "opentelemetry/exporters/etw/etw_properties.h" #include "opentelemetry/exporters/etw/utils.h" -namespace core = opentelemetry::core; +namespace core = opentelemetry::core; namespace trace = opentelemetry::trace; OPENTELEMETRY_BEGIN_NAMESPACE - namespace exporter { namespace ETW { class Span; -/// -/// stream::Tracer class that allows to send spans to ETW -/// +/** + * @brief Utility template for Span.GetName() + * @tparam T + * @param t + * @return + */ +template +std::string GetName(T &t) +{ + auto sV = t.GetName(); + return std::string(sV.data(), sV.length()); +} + +/** + * @brief Utility template to convert SpanId or TraceId to hex. + * @param id - value of SpanId or TraceId + * @return Hexadecimal representation of Id as string. + */ +template +static inline std::string ToLowerBase16(const T &id) +{ + char buf[2 * T::kSize] = {0}; + id.ToLowerBase16(buf); + return std::string(buf, sizeof(buf)); +} + +/** + * @brief Tracer class that allows to send spans to ETW Provider. + */ class Tracer : public trace::Tracer { - /// - /// Parent provider of this Tracer - /// + + /** + * @brief Parent provider of this Tracer + */ trace::TracerProvider &parent; - /// - /// Provider Id (Name or GUID) - /// + /** + * @brief ProviderId (Name or GUID) + */ std::string provId; - /// - /// Provider Handle - /// + /** + * @brief Provider Handle + */ ETWProvider::Handle provHandle; - /// - /// Encoding (Manifest, MessagePack or XML) - /// + /** + * @brief Encoding (Manifest, MessagePack or XML) + */ ETWProvider::EventFormat encoding; - /// - /// ETWProvider is a singleton that aggregates all ETW writes. - /// - /// + /** + * @brief ETWProvider is a singleton that aggregates all ETW writes. + * @return + */ static ETWProvider &etwProvider() { - static ETWProvider instance; // C++11 magic static + static ETWProvider instance; // C++11 magic static return instance; }; + /** + * @brief Internal method that allows to populate Links to other Spans. + * This is temporary implementation, that assumes the links are mentioned + * comma-separated in their order of appearance. + * + * @param attributes + * @param links + */ + virtual void DecorateLinks(Properties &attributes, + const trace::SpanContextKeyValueIterable &links) const + { + // Links + size_t idx = 0; + std::string linksValue; + links.ForEachKeyValue([&](trace::SpanContext ctx, + const common::KeyValueIterable &) + { + if (!linksValue.empty()) + { + linksValue += ','; + linksValue += ToLowerBase16(ctx.span_id()); + } + idx++; + return true; + }); + attributes[ETW_FIELD_SPAN_LINKS] = linksValue; + }; + + +#if 0 + // TODO: SpanContext is a temporary implementation that requires revisiting. + // One option for ETW exporter is to respect the existing correlation fields: + // - ActivityId - as current Trace Id + // - RelatedActivityId - as parent Trace Id + virtual trace::SpanContext GetDefaultContext() = 0; +#endif + + /** + * @brief Allow our friendly ETW::Span to end itself on Tracer. + * @param span + * @param + */ + virtual void EndSpan(const Span &span, const trace::EndSpanOptions & = {}) + { + Properties evt; + + auto ctx = (reinterpret_cast(&span))->GetContext(); + evt[ETW_FIELD_NAME] = GetName(span); + evt[ETW_FIELD_TYPE] = ETW_FIELD_SPAN_END; + evt[ETW_FIELD_SPAN_ID] = ToLowerBase16(ctx.span_id()); + + // TODO: check what EndSpanOptions should be supported for this exporter + etwProvider().write(provHandle, evt, encoding); + }; + + friend class Span; + public: - /// - /// Tracer constructor - /// - /// Parent TraceProvider - /// providerId - /// Tracer instance + + /** + * @brief Tracer constructor + * @param parent Parent TraceProvider + * @param providerId ProviderId - Name or GUID + * @param encoding ETW encoding format to use. + */ Tracer(trace::TracerProvider &parent, nostd::string_view providerId = "", ETWProvider::EventFormat encoding = ETWProvider::EventFormat::ETW_MANIFEST) - : trace::Tracer(), - parent(parent), - provId(providerId.data(), providerId.size()), - encoding(encoding) + : trace::Tracer(), + parent(parent), + provId(providerId.data(), providerId.size()), + encoding(encoding) { +#if defined(HAVE_MSGPACK) && !defined(HAVE_TLD) + /* Fallback to MsgPack encoding if TraceLoggingDynamic feature gate is off */ + this->encoding = ETWProvider::EventFormat::ETW_MSGPACK; +#endif provHandle = etwProvider().open(provId, encoding); }; - /// - /// Start Span - /// - /// Span name - /// Span options - /// Span - virtual nostd::shared_ptr StartSpan( + /** + * @brief Start Span + * @param name Span name + * @param attributes Span attributes + * @param links Span links + * @param options Span options + * @return + */ + nostd::shared_ptr StartSpan( nostd::string_view name, const common::KeyValueIterable &attributes, const trace::SpanContextKeyValueIterable &links, const trace::StartSpanOptions &options = {}) noexcept override { - // TODO: support attributes - UNREFERENCED_PARAMETER(attributes); - UNREFERENCED_PARAMETER(links); - return trace::to_span_ptr(this, name, options); + nostd::shared_ptr result = trace::to_span_ptr(this, name, options); + auto spanContext = result->GetContext(); + + // Event properties + Properties evt = attributes; + + // Decorate with additional standard fields + evt[ETW_FIELD_NAME] = name.data(); + evt[ETW_FIELD_TYPE] = ETW_FIELD_SPAN_START; + evt[ETW_FIELD_TRACE_ID] = ToLowerBase16(spanContext.trace_id()); + evt[ETW_FIELD_SPAN_ID] = ToLowerBase16(spanContext.span_id()); + + // Links + DecorateLinks(evt, links); + // NOTE: we neither allow adding attributes nor links after StartSpan. + + // TODO: add support for options + // - options.kind + // - options.parent + // - options.start_steady_time + // - options.start_system_time + etwProvider().write(provHandle, evt, encoding); + return result; }; - /// - /// Force flush data to Tracer, spending up to given amount of microseconds to flush. - /// - /// Allow Tracer to drop data if timeout is reached - /// void - virtual void ForceFlushWithMicroseconds(uint64_t) noexcept override{}; + /** + * @brief Force flush data to Tracer, spending up to given amount of microseconds to flush. + * NOTE: this method has no effect for the realtime streaming Tracer. + * + * @param timeout Allow Tracer to drop data if timeout is reached + * @return + */ + void ForceFlushWithMicroseconds(uint64_t) noexcept override + { + }; - /// - /// Close tracer, spending up to given amount of microseconds to flush and close. - /// - /// Allow Tracer to drop data if timeout is reached - /// - virtual void CloseWithMicroseconds(uint64_t) noexcept override + /** + * @brief Close tracer, spending up to given amount of microseconds to flush and close. + * NOTE: This method closes the current ETW Provider Handle. + * + * @param timeout Allow Tracer to drop data if timeout is reached. + * @return + */ + void CloseWithMicroseconds(uint64_t) noexcept override { etwProvider().close(provHandle); }; - /// - /// Add event data to span associated with tracer - /// - /// - /// - /// - /// - /// - void AddEvent(Span &span, + /** + * @brief Add event data to span associated with tracer. + * @param span Parent span. + * @param name Event name. + * @param timestamp Event timestamp. + * @param attributes Event attributes. + * @return + */ + void AddEvent(trace::Span &span, nostd::string_view name, core::SystemTimestamp timestamp, const common::KeyValueIterable &attributes) noexcept { - // TODO: associate events with span - (void)span; - // TODO: respect original timestamp + // TODO: respect originating timestamp (void)timestamp; - // Unfortunately we copy right now since we don't have the knowledge of original map object :-( - std::map m; - attributes.ForEachKeyValue([&](nostd::string_view key, common::AttributeValue value) noexcept { - m[key] = value; - return true; - }); - m["name"] = name.data(); + // Event properties. + // TODO: if we know that the incoming type is already `Properties`, + // then we could avoid the memcpy by reusing the incoming attributes. + // This would require non-const argument. + Properties evt = attributes; + + evt[ETW_FIELD_NAME] = name.data(); - etwProvider().write(provHandle, m, encoding); + auto spanContext = span.GetContext(); + // Decorate with additional standard fields. This may get expensive + // and should be configurable for traces that deduct their nested + // structure based off built-in `ActivityId` and `RelatedActivityId` + evt[ETW_FIELD_TRACE_ID] = ToLowerBase16(spanContext.trace_id()); + evt[ETW_FIELD_SPAN_ID] = ToLowerBase16(spanContext.span_id()); + + etwProvider().write(provHandle, evt, encoding); }; - /// - /// Add event data to span associated with tracer - /// - /// - /// - /// - /// - void AddEvent(Span &span, nostd::string_view name, core::SystemTimestamp timestamp) noexcept + /** + * @brief Add event data to span associated with tracer. + * @param span Span. + * @param name Event name. + * @param timestamp Event timestamp. + * @return + */ + void AddEvent(trace::Span &span, nostd::string_view name, core::SystemTimestamp timestamp) noexcept { - AddEvent(span, name, timestamp, opentelemetry::sdk::GetEmptyAttributes()); + AddEvent(span, name, timestamp, sdk::GetEmptyAttributes()); }; - /// - /// Add event data to span associated with tracer - /// - /// - /// - void AddEvent(Span &span, nostd::string_view name) + /** + * @brief Add event data to span associated with tracer. + * @param span Spab. + * @param name Event name. + */ + void AddEvent(trace::Span &span, nostd::string_view name) { - AddEvent(span, name, std::chrono::system_clock::now(), - opentelemetry::sdk::GetEmptyAttributes()); + AddEvent(span, name, std::chrono::system_clock::now(), sdk::GetEmptyAttributes()); }; + /** + * @brief Tracer destructor. + */ virtual ~Tracer() { CloseWithMicroseconds(0); }; + }; -/// -/// stream::Span allows to send event data to stream -/// +/** + * @brief ETW::Span allows to send event data to ETW listener. +*/ class Span : public trace::Span { - protected: - /// - /// Parent (Owner) Tracer of this Span - /// + + /** + * @brief Parent (Owner) Tracer of this Span + */ Tracer &owner; + /** + * @brief Span name. + */ + nostd::string_view name_; + + /** + * @brief Attribute indicating that the span has ended. + */ + std::atomic has_ended_{false}; + + /** + * @brief Attribute indicating that the span has started. + */ + std::atomic has_started_{false}; + + public: - /// - /// Span constructor - /// - /// Owner Tracer - /// Span name - /// Span options - /// Span + + /** + * @brief Get Span Name. + * @return Span Name. + */ + nostd::string_view GetName() const + { + return name_; + } + + /** + * @brief Span constructor + * @param owner Owner Tracer + * @param name Span name + * @param options Span options + * @return + */ Span(Tracer &owner, nostd::string_view name, const trace::StartSpanOptions &options) noexcept - : trace::Span(), owner(owner) + : trace::Span(), + owner(owner) { - UNREFERENCED_PARAMETER(name); + name_ = name; UNREFERENCED_PARAMETER(options); }; + /** + * @brief Span Destructor + */ ~Span() { End(); } - /// - /// Add named event with no attributes - /// - /// - /// - virtual void AddEvent(nostd::string_view name) noexcept override { owner.AddEvent(*this, name); } + /** + * @brief Add named event with no attributes. + * @param name Event name. + * @return + */ + void AddEvent(nostd::string_view name) noexcept override { owner.AddEvent(*this, name); } - /// - /// Add named event with custom timestamp - /// - /// - /// - /// - virtual void AddEvent(nostd::string_view name, core::SystemTimestamp timestamp) noexcept override + /** + * @brief Add named event with custom timestamp. + * @param name + * @param timestamp + * @return + */ + void AddEvent(nostd::string_view name, core::SystemTimestamp timestamp) noexcept override { owner.AddEvent(*this, name, timestamp); } - /// - /// Add named event with custom timestamp and attributes - /// - /// - /// - /// - /// + /** + * @brief Add named event with custom timestamp and attributes. + * @param name Event name. + * @param timestamp Event timestamp. + * @param attributes Event attributes. + * @return + */ void AddEvent(nostd::string_view name, core::SystemTimestamp timestamp, const common::KeyValueIterable &attributes) noexcept override @@ -247,64 +401,84 @@ class Span : public trace::Span owner.AddEvent(*this, name, timestamp, attributes); } - /// - /// Set Span status - /// - /// - /// - /// - virtual void SetStatus(trace::CanonicalCode code, - nostd::string_view description) noexcept override + /** + * @brief Set Span status + * @param code Span status code. + * @param description Span description. + * @return + */ + void SetStatus(trace::CanonicalCode code, + nostd::string_view description) noexcept override { // TODO: not implemented UNREFERENCED_PARAMETER(code); UNREFERENCED_PARAMETER(description); }; - // Sets an attribute on the Span. If the Span previously contained a mapping for - // the key, the old value is replaced. - virtual void SetAttribute(nostd::string_view key, - const common::AttributeValue &value) noexcept override + /** + * @brief Sets an attribute on the Span. If the Span previously contained a mapping + * for the key, the old value is replaced. + * + * @param key + * @param value + * @return + */ + void SetAttribute(nostd::string_view key, + const common::AttributeValue &value) noexcept override { // TODO: not implemented UNREFERENCED_PARAMETER(key); UNREFERENCED_PARAMETER(value); }; - /// - /// Update Span name - /// - /// - /// - virtual void UpdateName(nostd::string_view name) noexcept override + /** + * @brief Update Span name. + * + * NOTE: this method is a no-op for streaming implementation. + * We cannot change the Span name after it started streaming. + * + * @param name + * @return + */ + void UpdateName(nostd::string_view) noexcept override { - // TODO: not implemented - UNREFERENCED_PARAMETER(name); + // We can't do that! + // name_ = name; } - /// - /// End Span - /// - /// - virtual void End(const trace::EndSpanOptions & = {}) noexcept override + /** + * @brief End Span. + * @param EndSpanOptions + * @return + */ + void End(const trace::EndSpanOptions &options = {}) noexcept override { - // TODO: signal this to owner + if (!has_ended_.exchange(true)) + { + owner.EndSpan(*this, options); + } } - virtual trace::SpanContext GetContext() const noexcept + /** + * @brief Obtain SpanContext + * @return + */ + trace::SpanContext GetContext() const noexcept override { // TODO: not implemented static trace::SpanContext nullContext{trace::SpanContext::GetInvalid()}; return nullContext; } - /// - /// Check if Span is recording data - /// - /// - virtual bool IsRecording() const noexcept override + /** + * @brief Check if Span is recording data. + * @return + */ + bool IsRecording() const noexcept override { - // TODO: not implemented + // For streaming implementation this should return the state of ETW Listener. + // In certain unprivileged environments, ex. containers, it is impossible + // to determine if a listener is registered. Thus, we always return true. return true; } @@ -333,17 +507,27 @@ class TracerProvider : public trace::TracerProvider /// Tracer Type /// Tracer arguments /// - virtual nostd::shared_ptr GetTracer(nostd::string_view name, - nostd::string_view args = "") + /// + + /** + * @brief Obtain ETW Tracer. + * @param name ProviderId (instrumentation name) - Name or GUID + * + * @param args Additional arguments that controls `codec` of the provider. + * Possible values are: + * - "ETW" - 'classic' Trace Logging Dynamic manifest ETW events. + * - "MSGPACK" - MessagePack-encoded binary payload ETW events. + * - "XML" - XML events (reserved for future use) + * @return + */ + nostd::shared_ptr GetTracer(nostd::string_view name, + nostd::string_view args = "") override { - // TODO: describe possible args. Currently supported: - // "MSGPACK" - use MessagePack - // "XML" - use XML - // "ETW" - use 'classic' Trace Logging Dynamic manifest ETW event - // #if defined(HAVE_MSGPACK) + // Prefer MsgPack over ETW by default ETWProvider::EventFormat evtFmt = ETWProvider::EventFormat::ETW_MSGPACK; #else + // Fallback to ETW TraceLoggingDynamic if MsgPack support is not compiled in ETWProvider::EventFormat evtFmt = ETWProvider::EventFormat::ETW_MANIFEST; #endif @@ -377,144 +561,10 @@ class TracerProvider : public trace::TracerProvider break; } #pragma warning(pop) - return nostd::shared_ptr{new (std::nothrow) Tracer(*this, name, evtFmt)}; - } -}; - -class ETWSpanData final : public sdk::trace::Recordable -{ -public: - ETWSpanData(std::string providerName) { InitTracerProvider(providerName); } - /** - * Get the trace id for this span - * @return the trace id for this span - */ - opentelemetry::trace::TraceId GetTraceId() const noexcept { return trace_id_; } - - /** - * Get the span id for this span - * @return the span id for this span - */ - opentelemetry::trace::SpanId GetSpanId() const noexcept { return span_id_; } - - /** - * Get the parent span id for this span - * @return the span id for this span's parent - */ - opentelemetry::trace::SpanId GetParentSpanId() const noexcept { return parent_span_id_; } - - /** - * Get the name for this span - * @return the name for this span - */ - opentelemetry::nostd::string_view GetName() const noexcept { return name_; } - - /** - * Get the status for this span - * @return the status for this span - */ - opentelemetry::trace::CanonicalCode GetStatus() const noexcept { 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 { return status_desc_; } - - /** - * Get the start time for this span - * @return the start time for this span - */ - opentelemetry::core::SystemTimestamp GetStartTime() const noexcept { return start_time_; } - - /** - * Get the duration for this span - * @return the duration for this span - */ - std::chrono::nanoseconds GetDuration() const noexcept { return duration_; } - - /** - * Get the attributes for this span - * @return the attributes for this span - */ - const std::unordered_map &GetAttributes() const - noexcept - { - return attribute_map_.GetAttributes(); + return nostd::shared_ptr{new(std::nothrow) Tracer(*this, name, evtFmt)}; } - - void SetIds(opentelemetry::trace::TraceId trace_id, - opentelemetry::trace::SpanId span_id, - opentelemetry::trace::SpanId parent_span_id) noexcept override - { - trace_id_ = trace_id; - span_id_ = span_id; - parent_span_id_ = parent_span_id; - } - - void SetAttribute(nostd::string_view key, - const opentelemetry::common::AttributeValue &value) noexcept override - { - attribute_map_.SetAttribute(key, value); - } - - void AddEvent(nostd::string_view name, - core::SystemTimestamp timestamp, - const opentelemetry::common::KeyValueIterable &attributes) noexcept override - { - span_->AddEvent(name, timestamp, attributes); - } - - void AddLink(const opentelemetry::trace::SpanContext &span_context, - const opentelemetry::common::KeyValueIterable &attributes) noexcept override - { - // TODO: Link Implementation for the Span to be implemented - } - - void SetStatus(opentelemetry::trace::CanonicalCode code, - nostd::string_view description) noexcept override - { - status_code_ = code; - status_desc_ = std::string(description); - } - - void SetName(nostd::string_view name) noexcept override { name_ = std::string(name); } - - void SetSpanKind(opentelemetry::trace::SpanKind span_kind) noexcept override - { - span_kind_ = span_kind; - } - - void SetStartTime(opentelemetry::core::SystemTimestamp start_time) noexcept override - { - start_time_ = start_time; - } - - void SetDuration(std::chrono::nanoseconds duration) noexcept override { duration_ = duration; } - - void InitTracerProvider(std::string providerName) - { - exporter::ETW::TracerProvider tracer_provider_; - - tracer_ = tracer_provider_.GetTracer(providerName); - span_ = tracer_->StartSpan(name_); - } - -private: - opentelemetry::trace::TraceId trace_id_; - opentelemetry::trace::SpanId span_id_; - opentelemetry::trace::SpanId parent_span_id_; - core::SystemTimestamp start_time_; - std::chrono::nanoseconds duration_{0}; - std::string name_; - opentelemetry::trace::CanonicalCode status_code_{opentelemetry::trace::CanonicalCode::OK}; - std::string status_desc_; - sdk::common::AttributeMap attribute_map_; - opentelemetry::trace::SpanKind span_kind_{opentelemetry::trace::SpanKind::kInternal}; - nostd::shared_ptr tracer_; - nostd::shared_ptr span_; }; -} // namespace ETW -} // namespace exporter +} // namespace ETW +} // namespace exporter OPENTELEMETRY_END_NAMESPACE diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider_exporter.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h similarity index 95% rename from exporters/etw/include/opentelemetry/exporters/etw/etw_provider_exporter.h rename to exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h index 221a3e8f09..b3ec404048 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider_exporter.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h @@ -30,6 +30,7 @@ #include "opentelemetry/version.h" #include "opentelemetry/exporters/etw/utils.h" +#include "opentelemetry/exporters/etw/etw_fields.h" #ifdef HAVE_MSGPACK // This option requires INCLUDE_DIR=$(ProjectDir)\..\..\third_party\json\include;... @@ -42,6 +43,7 @@ #include #include #include +#include #ifdef HAVE_KRABS_TESTS // krabs.hpp requires this definition of min macro from Windows.h @@ -223,14 +225,14 @@ class ETWProvider return STATUS_ERROR; }; - const std::string EVENT_NAME = "name"; - std::string eventName = "NoName"; - auto nameField = eventData[EVENT_NAME]; + std::string eventName = "NoName"; + auto nameField = eventData[ETW_FIELD_NAME]; + switch (nameField.index()) { case common::AttributeType::TYPE_STRING: eventName = - (char *)(nostd::get(nameField).data()); // must be 0-terminated! + (char *)(nostd::get(nameField).data()); // must be 0-terminated! break; # ifdef HAVE_CSTRING_TYPE case common::AttributeType::TYPE_CSTRING: @@ -246,26 +248,26 @@ class ETWProvider /* clang-format off */ nlohmann::json jObj = { - { "env_name", "Span" }, - { "env_ver", "4.0" }, + { ETW_FIELD_NAME, eventName }, + { ETW_FIELD_VERSION, "4.0" }, // // TODO: compute time in MessagePack-friendly format // TODO: should we consider uint64_t format with Unix timestamps for ELK stack? - { "env_time", + { ETW_FIELD_TIME, { + // TODO: timestamp { "TypeCode", 255 }, { "Body","0xFFFFFC60000000005F752C2C" } } }, - // - - // TODO: follow JSON implementation of OTLP or place protobuf for non-Microsoft flows +#if 0 + // TODO: follow JSON implementation of OTLP { "env_dt_traceId", "6dcdae7b9b0c7643967d74ee54056178" }, { "env_dt_spanId", "5866c4322919e641" }, +#endif // - { "name", eventName }, - { "kind", 0 }, - { "startTime", + { ETW_FIELD_KIND, 0 }, + { ETW_FIELD_STARTTIME, { // TODO: timestamp { "TypeCode", 255 }, @@ -275,12 +277,15 @@ class ETWProvider }; /* clang-format on */ + std::string eventFieldName(ETW_FIELD_NAME); for (auto &kv : eventData) { const char *name = kv.first.data(); - // Don't include event name field in the payload - if (EVENT_NAME == name) + + // Don't include event name field in the Payload section + if (eventFieldName == name) continue; + auto &value = kv.second; switch (value.index()) { @@ -322,8 +327,7 @@ class ETWProvider } case common::AttributeType::TYPE_STRING: { - auto temp = nostd::get(value); - jObj[name] = temp; + jObj[name] = nostd::get(value); break; } # ifdef HAVE_CSTRING_TYPE @@ -344,6 +348,7 @@ class ETWProvider break; } # endif + // TODO: arrays are not supported yet # ifdef HAVE_SPAN_BYTE case common::AttributeType::TYPE_SPAN_BYTE: @@ -458,7 +463,7 @@ class ETWProvider { case common::AttributeType::TYPE_STRING: eventName = - (char *)(nostd::get(nameField).data()); // must be 0-terminated! + (char *)(nostd::get(nameField).data()); break; # ifdef HAVE_CSTRING_TYPE case common::AttributeType::TYPE_CSTRING: @@ -527,8 +532,7 @@ class ETWProvider case common::AttributeType::TYPE_STRING: { builder.AddField(name, tld::TypeUtf8String); - auto temp = nostd::get(value); - dbuilder.AddString(temp.data()); + dbuilder.AddString(nostd::get(value).data()); break; } # ifdef HAVE_CSTRING_TYPE diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_recordable.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_recordable.h new file mode 100644 index 0000000000..40f370c6de --- /dev/null +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_recordable.h @@ -0,0 +1,215 @@ +#pragma once + +#include +#include +#include + +#include "opentelemetry/version.h" + +#include "opentelemetry/common/key_value_iterable_view.h" + +#include +#include +#include +#include + +#include "opentelemetry/nostd/shared_ptr.h" +#include "opentelemetry/nostd/string_view.h" +#include "opentelemetry/nostd/unique_ptr.h" + +#include "opentelemetry/common/key_value_iterable_view.h" +#include "opentelemetry/trace/span.h" +#include "opentelemetry/trace/span_context_kv_iterable_view.h" +#include "opentelemetry/trace/span_id.h" +#include "opentelemetry/trace/trace_id.h" +#include "opentelemetry/trace/tracer_provider.h" + +#include "opentelemetry/sdk/trace/exporter.h" +#include "opentelemetry/sdk/trace/recordable.h" +#include "opentelemetry/sdk/trace/span_data.h" + +#include +#include +#include +#include +#include +#include + +#include "opentelemetry/exporters/etw/etw_fields.h" +#include "opentelemetry/exporters/etw/etw_provider.h" +#include "opentelemetry/exporters/etw/utils.h" + +#include "opentelemetry/exporters/etw/etw_properties.h" + +namespace core = opentelemetry::core; +namespace trace = opentelemetry::trace; + +OPENTELEMETRY_BEGIN_NAMESPACE +namespace exporter +{ +namespace ETW +{ + +class ETWSpanData final : public sdk::trace::Recordable +{ +public: + ETWSpanData(std::string providerName) { InitTracerProvider(providerName); } + + /** + * Get the trace id for this span + * @return the trace id for this span + */ + trace::TraceId GetTraceId() const noexcept { return trace_id_; } + + /** + * Get the span id for this span + * @return the span id for this span + */ + trace::SpanId GetSpanId() const noexcept { return span_id_; } + + /** + * Get the parent span id for this span + * @return the span id for this span's parent + */ + trace::SpanId GetParentSpanId() const noexcept { return parent_span_id_; } + + /** + * Get the name for this span + * @return the name for this span + */ + nostd::string_view GetName() const noexcept { return name_; } + + /** + * Get the status for this span + * @return the status for this span + */ + trace::CanonicalCode GetStatus() const noexcept { return status_code_; } + + /** + * Get the status description for this span + * @return the description of the the status of this span + */ + nostd::string_view GetDescription() const noexcept { return status_desc_; } + + /** + * Get the start time for this span + * @return the start time for this span + */ + core::SystemTimestamp GetStartTime() const noexcept { return start_time_; } + + /** + * Get the duration for this span + * @return the duration for this span + */ + std::chrono::nanoseconds GetDuration() const noexcept { return duration_; } + + /** + * Get the attributes for this span + * @return the attributes for this span + */ + const std::unordered_map &GetAttributes() + const noexcept + { + return attribute_map_.GetAttributes(); + } + + void SetIds(trace::TraceId trace_id, + trace::SpanId span_id, + trace::SpanId parent_span_id) noexcept override + { + trace_id_ = trace_id; + span_id_ = span_id; + parent_span_id_ = parent_span_id; + } + + void SetAttribute(nostd::string_view key, const common::AttributeValue &value) noexcept override + { + attribute_map_.SetAttribute(key, value); + } + + void AddEvent(nostd::string_view name, + core::SystemTimestamp timestamp, + const common::KeyValueIterable &attributes) noexcept override + { + span_->AddEvent(name, timestamp, attributes); + } + + void AddLink(const trace::SpanContext &span_context, + const common::KeyValueIterable &attributes) noexcept override + { + // TODO: Link Implementation for the Span to be implemented + } + + /** + * @brief Set recordable status code and description. + * @param code + * @param description + * @return + */ + void SetStatus(trace::CanonicalCode code, nostd::string_view description) noexcept override + { + status_code_ = code; + status_desc_ = std::string(description); + } + + /** + * @brief Set recordable name. + * @param name + * @return + */ + void SetName(nostd::string_view name) noexcept override { name_ = std::string(name); } + + /** + * @brief Set span kind + * @param span_kind + * @return + */ + void SetSpanKind(trace::SpanKind span_kind) noexcept override { span_kind_ = span_kind; } + + /** + * @brief Set recordable start time. + * @param start_time + * @return + */ + void SetStartTime(core::SystemTimestamp start_time) noexcept override + { + start_time_ = start_time; + } + + /** + * @brief Set recordable duration. + * @param duration + * @return + */ + void SetDuration(std::chrono::nanoseconds duration) noexcept override { duration_ = duration; } + + /** + * @brief Initialize ETW provider by name or GUID. + * @param providerName - Provider Name or GUID that starts with `{` + */ + void InitTracerProvider(std::string providerName) + { + TracerProvider tracer_provider_; + + tracer_ = tracer_provider_.GetTracer(providerName); + span_ = tracer_->StartSpan(name_); + } + +private: + trace::TraceId trace_id_; + trace::SpanId span_id_; + trace::SpanId parent_span_id_; + core::SystemTimestamp start_time_; + std::chrono::nanoseconds duration_{0}; + std::string name_; + trace::CanonicalCode status_code_{trace::CanonicalCode::OK}; + std::string status_desc_; + sdk::common::AttributeMap attribute_map_; + trace::SpanKind span_kind_{trace::SpanKind::kInternal}; + nostd::shared_ptr tracer_; + nostd::shared_ptr span_; +}; + +} // namespace ETW +} // namespace exporter +OPENTELEMETRY_END_NAMESPACE diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer_exporter.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer_exporter.h index 762dd56b22..b379b48a12 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer_exporter.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer_exporter.h @@ -34,7 +34,8 @@ #include "opentelemetry/sdk/trace/recordable.h" #include "opentelemetry/exporters/etw/etw_data.h" -#include "opentelemetry/exporters/etw/etw_provider_exporter.h" +#include "opentelemetry/exporters/etw/etw_recordable.h" +#include "opentelemetry/exporters/etw/etw_provider.h" #include "opentelemetry/exporters/etw/utils.h" @@ -48,6 +49,20 @@ namespace exporter namespace ETW { +/** + * @brief ETW Tracer Exporter. + * + * TODO: this code needs to be reworked because it is not necessary in synchronous + * realtime exporter / streamer scenario. Header-only ETW Tracer can export Span + * and Events without needing to pack data to into another Recordable. API calls + * return right away after the message is passed to ETW sink in realtime. There is + * no packaging or aggregation necessary, and no need for a background async thread. + * + * There is no 100% reliable way to know if ETW events got exported either: + * - if events got accepted, but cannot be processed, then then out-of-buffers + * notification is only sent to receiving listener-end, not to sender. + * + */ class ETWTracerExporter final : public opentelemetry::sdk::trace::SpanExporter { public: diff --git a/exporters/etw/src/etw_provider_exporter.cc b/exporters/etw/src/etw_provider_exporter.cc index 570cd51b33..34eb594730 100644 --- a/exporters/etw/src/etw_provider_exporter.cc +++ b/exporters/etw/src/etw_provider_exporter.cc @@ -1,5 +1,5 @@ #ifdef _WIN32 -# include "opentelemetry/exporters/etw/etw_provider_exporter.h" +# include "opentelemetry/exporters/etw/etw_provider.h" #endif diff --git a/exporters/etw/test/etw_provider_test.cc b/exporters/etw/test/etw_provider_test.cc index 439d3373a1..f967428329 100644 --- a/exporters/etw/test/etw_provider_test.cc +++ b/exporters/etw/test/etw_provider_test.cc @@ -17,7 +17,7 @@ # include # include -# include "opentelemetry/exporters/etw/etw_provider_exporter.h" +# include "opentelemetry/exporters/etw/etw_provider.h" using namespace OPENTELEMETRY_NAMESPACE; diff --git a/exporters/etw/test/etw_tracer_test.cc b/exporters/etw/test/etw_tracer_test.cc index 050a1f9378..b4f4808005 100644 --- a/exporters/etw/test/etw_tracer_test.cc +++ b/exporters/etw/test/etw_tracer_test.cc @@ -16,76 +16,101 @@ # include # include +# include # include "opentelemetry/exporters/etw/etw_tracer_exporter.h" # include "opentelemetry/sdk/trace/simple_processor.h" using namespace OPENTELEMETRY_NAMESPACE; -using ETWEvent = std::map; +using Properties = opentelemetry::exporter::ETW::Properties; +using PropertyValue = opentelemetry::exporter::ETW::PropertyValue; +using PropertyValueMap = opentelemetry::exporter::ETW::PropertyValueMap; -TEST(ETWTracer, TracerCheck) +std::string getTemporaryValue() { - std::string providerName = "OpenTelemetry"; - std::string eventName = "MyEvent"; + return std::string("Value from Temporary std::string"); +} +/* clang-format off */ +TEST(ETWTracer, TracerCheck) +{ + // SDK customer specifies their unique ETW ProviderName. Every component or library + // is assumed to have its own instrumentation name. Traces are routed to dedicated + // provider. Standard hash function maps from ProviderName to ProviderGUID. + // + // Prominent naming examples from `logman query providers` : + // + // [Docker] {a3693192-9ed6-46d2-a981-f8226c8363bd} + // ... + // Intel-Autologger-iclsClient {B8D7E9A0-65D5-40BE-AFEA-83593FC0164E} + // Intel-Autologger-iclsProxy {301B773F-50F3-4C8E-83F0-53BA9590A13E} + // Intel-Autologger-PTTEKRecertification {F33E9E07-8792-47E8-B3FA-2C92AB32C5B3} + // ... + // NodeJS-ETW-provider {77754E9B-264B-4D8D-B981-E4135C1ECB0C} + // ... + // OpenSSH {C4B57D35-0636-4BC3-A262-370F249F9802} + // ... + // Windows Connect Now {C100BECE-D33A-4A4B-BF23-BBEF4663D017} + // Windows Defender Firewall API {28C9F48F-D244-45A8-842F-DC9FBC9B6E92} + // Windows Defender Firewall API - GP {0EFF663F-8B6E-4E6D-8182-087A8EAA29CB} + // Windows Defender Firewall Driver {D5E09122-D0B2-4235-ADC1-C89FAAAF1069} + + std::string providerName = "OpenTelemetry"; // supply unique instrumentation name here exporter::ETW::TracerProvider tp; + // TODO: this code should fallback to MsgPack if TLD is not available auto tracer = tp.GetTracer(providerName, "TLD"); - auto span = tracer->StartSpan("MySpan"); - ETWEvent event = { - {"uint32Key", (uint32_t)123456}, {"uint64Key", (uint64_t)123456}, {"strKey", "someValue"}}; + // Span attributes + Properties attribs = + { + {"attrib1", 1}, + {"attrib2", 2} + }; + + auto outerSpan = tracer->StartSpan("MySpanOuter", attribs); + + // Add first event + std::string eventName1 = "MyEvent1"; + Properties event1 = + { + {"uint32Key", (uint32_t)1234}, + {"uint64Key", (uint64_t)1234567890}, + {"strKey", "someValue"} + }; + EXPECT_NO_THROW(outerSpan->AddEvent(eventName1, event1)); + + // Add second event + std::string eventName2 = "MyEvent2"; + Properties event2 = + { + {"uint32Key", (uint32_t)9876}, + {"uint64Key", (uint64_t)987654321}, + {"strKey", "anotherValue"} + }; + EXPECT_NO_THROW(outerSpan->AddEvent(eventName2, event2)); + + + // Create nested span. Note how we share the attributes here.. + // It is Okay to share or have your own attributes. + auto innerSpan = tracer->StartSpan("MySpanInner", attribs); + std::string eventName3= "MyEvent3"; + Properties event3 = + { + {"uint32Key", (uint32_t)9876}, + {"uint64Key", (uint64_t)987654321}, + // {"int32array", {{-1,0,1,2,3}} }, + {"tempString", getTemporaryValue() } + }; + EXPECT_NO_THROW(innerSpan->AddEvent(eventName3, event3)); + + EXPECT_NO_THROW(innerSpan->End()); // end innerSpan + + EXPECT_NO_THROW(outerSpan->End()); // end outerSpan - EXPECT_NO_THROW(span->AddEvent(eventName, event)); - EXPECT_NO_THROW(span->End()); EXPECT_NO_THROW(tracer->CloseWithMicroseconds(0)); } - -TEST(ETWTracer, ETWTracerTest) -{ - std::string providerName = "OpenTelemetry"; - - auto exporter = std::unique_ptr( - new exporter::ETW::ETWTracerExporter(providerName)); - - auto processor = std::shared_ptr( - new sdk::trace::SimpleSpanProcessor(std::move(exporter))); - - auto recordable = processor->MakeRecordable(); - recordable->SetName("MySpan"); - - // Create stringstream to redirect to - std::stringstream stdoutOutput; - - // Save cout's buffer here - std::streambuf *sbuf = std::cout.rdbuf(); - - // Redirect cout to our stringstream buffer - std::cout.rdbuf(stdoutOutput.rdbuf()); - - processor->OnEnd(std::move(recordable)); - - std::cout.rdbuf(sbuf); - - std::string expectedOutput = "MySpan\n"; - - ASSERT_EQ(stdoutOutput.str(), expectedOutput); -} - -TEST(ETWTracer, ExportUnitTest) -{ - std::string providerName = "OpenTelemetry"; - - auto exporter = std::unique_ptr( - new exporter::ETW::ETWTracerExporter(providerName)); - - auto recordable = exporter->MakeRecordable(); - recordable->SetName("MySpan"); - - nostd::span> batch(&recordable, 1); - auto result = exporter->Export(batch); - EXPECT_EQ(sdk::trace::ExportResult::kSuccess, result); -} +/* clang-format on */ #endif From 5acc2d3a49ee974167c6a7ef161f49a1190a5479 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 15 Jan 2021 00:42:32 -0800 Subject: [PATCH 09/76] Code formatting --- .../trace/span_context_kv_iterable.h | 5 +- .../opentelemetry/exporters/etw/etw_data.h | 171 ++++++++---------- .../opentelemetry/exporters/etw/etw_fields.h | 4 +- .../exporters/etw/etw_properties.h | 75 ++++---- .../exporters/etw/etw_provider.h | 14 +- .../exporters/etw/etw_recordable.h | 6 +- .../exporters/etw/etw_tracer_exporter.h | 2 +- exporters/etw/test/etw_tracer_test.cc | 6 +- 8 files changed, 129 insertions(+), 154 deletions(-) diff --git a/api/include/opentelemetry/trace/span_context_kv_iterable.h b/api/include/opentelemetry/trace/span_context_kv_iterable.h index 9fc78f24b7..521108c754 100644 --- a/api/include/opentelemetry/trace/span_context_kv_iterable.h +++ b/api/include/opentelemetry/trace/span_context_kv_iterable.h @@ -24,7 +24,10 @@ class SpanContextKeyValueIterable */ virtual bool ForEachKeyValue( nostd::function_ref - callback) const noexcept { return true; }; + callback) const noexcept + { + return true; + }; /** * @return the number of key-value pairs */ diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_data.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_data.h index cd9bf99e49..62bbcfb93d 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_data.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_data.h @@ -4,13 +4,13 @@ #include #include -#include #include #include #include +#include #include +#include #include -#include #include "opentelemetry/nostd/shared_ptr.h" #include "opentelemetry/nostd/string_view.h" @@ -28,12 +28,12 @@ #include "opentelemetry/sdk/trace/recordable.h" #include "opentelemetry/sdk/trace/span_data.h" -#include "opentelemetry/exporters/etw/etw_provider.h" #include "opentelemetry/exporters/etw/etw_fields.h" #include "opentelemetry/exporters/etw/etw_properties.h" +#include "opentelemetry/exporters/etw/etw_provider.h" #include "opentelemetry/exporters/etw/utils.h" -namespace core = opentelemetry::core; +namespace core = opentelemetry::core; namespace trace = opentelemetry::trace; OPENTELEMETRY_BEGIN_NAMESPACE @@ -45,9 +45,9 @@ class Span; /** * @brief Utility template for Span.GetName() - * @tparam T - * @param t - * @return + * @tparam T + * @param t + * @return */ template std::string GetName(T &t) @@ -58,7 +58,7 @@ std::string GetName(T &t) /** * @brief Utility template to convert SpanId or TraceId to hex. - * @param id - value of SpanId or TraceId + * @param id - value of SpanId or TraceId * @return Hexadecimal representation of Id as string. */ template @@ -77,31 +77,31 @@ class Tracer : public trace::Tracer /** * @brief Parent provider of this Tracer - */ + */ trace::TracerProvider &parent; /** * @brief ProviderId (Name or GUID) - */ + */ std::string provId; /** * @brief Provider Handle - */ + */ ETWProvider::Handle provHandle; /** * @brief Encoding (Manifest, MessagePack or XML) - */ + */ ETWProvider::EventFormat encoding; /** * @brief ETWProvider is a singleton that aggregates all ETW writes. - * @return - */ + * @return + */ static ETWProvider &etwProvider() { - static ETWProvider instance; // C++11 magic static + static ETWProvider instance; // C++11 magic static return instance; }; @@ -110,8 +110,8 @@ class Tracer : public trace::Tracer * This is temporary implementation, that assumes the links are mentioned * comma-separated in their order of appearance. * - * @param attributes - * @param links + * @param attributes + * @param links */ virtual void DecorateLinks(Properties &attributes, const trace::SpanContextKeyValueIterable &links) const @@ -119,9 +119,7 @@ class Tracer : public trace::Tracer // Links size_t idx = 0; std::string linksValue; - links.ForEachKeyValue([&](trace::SpanContext ctx, - const common::KeyValueIterable &) - { + links.ForEachKeyValue([&](trace::SpanContext ctx, const common::KeyValueIterable &) { if (!linksValue.empty()) { linksValue += ','; @@ -133,7 +131,6 @@ class Tracer : public trace::Tracer attributes[ETW_FIELD_SPAN_LINKS] = linksValue; }; - #if 0 // TODO: SpanContext is a temporary implementation that requires revisiting. // One option for ETW exporter is to respect the existing correlation fields: @@ -144,16 +141,16 @@ class Tracer : public trace::Tracer /** * @brief Allow our friendly ETW::Span to end itself on Tracer. - * @param span - * @param + * @param span + * @param */ virtual void EndSpan(const Span &span, const trace::EndSpanOptions & = {}) { Properties evt; - auto ctx = (reinterpret_cast(&span))->GetContext(); - evt[ETW_FIELD_NAME] = GetName(span); - evt[ETW_FIELD_TYPE] = ETW_FIELD_SPAN_END; + auto ctx = (reinterpret_cast(&span))->GetContext(); + evt[ETW_FIELD_NAME] = GetName(span); + evt[ETW_FIELD_TYPE] = ETW_FIELD_SPAN_END; evt[ETW_FIELD_SPAN_ID] = ToLowerBase16(ctx.span_id()); // TODO: check what EndSpanOptions should be supported for this exporter @@ -163,20 +160,19 @@ class Tracer : public trace::Tracer friend class Span; public: - /** * @brief Tracer constructor * @param parent Parent TraceProvider * @param providerId ProviderId - Name or GUID * @param encoding ETW encoding format to use. - */ + */ Tracer(trace::TracerProvider &parent, nostd::string_view providerId = "", ETWProvider::EventFormat encoding = ETWProvider::EventFormat::ETW_MANIFEST) - : trace::Tracer(), - parent(parent), - provId(providerId.data(), providerId.size()), - encoding(encoding) + : trace::Tracer(), + parent(parent), + provId(providerId.data(), providerId.size()), + encoding(encoding) { #if defined(HAVE_MSGPACK) && !defined(HAVE_TLD) /* Fallback to MsgPack encoding if TraceLoggingDynamic feature gate is off */ @@ -191,8 +187,8 @@ class Tracer : public trace::Tracer * @param attributes Span attributes * @param links Span links * @param options Span options - * @return - */ + * @return + */ nostd::shared_ptr StartSpan( nostd::string_view name, const common::KeyValueIterable &attributes, @@ -203,13 +199,13 @@ class Tracer : public trace::Tracer auto spanContext = result->GetContext(); // Event properties - Properties evt = attributes; + Properties evt = attributes; // Decorate with additional standard fields - evt[ETW_FIELD_NAME] = name.data(); - evt[ETW_FIELD_TYPE] = ETW_FIELD_SPAN_START; + evt[ETW_FIELD_NAME] = name.data(); + evt[ETW_FIELD_TYPE] = ETW_FIELD_SPAN_START; evt[ETW_FIELD_TRACE_ID] = ToLowerBase16(spanContext.trace_id()); - evt[ETW_FIELD_SPAN_ID] = ToLowerBase16(spanContext.span_id()); + evt[ETW_FIELD_SPAN_ID] = ToLowerBase16(spanContext.span_id()); // Links DecorateLinks(evt, links); @@ -229,23 +225,18 @@ class Tracer : public trace::Tracer * NOTE: this method has no effect for the realtime streaming Tracer. * * @param timeout Allow Tracer to drop data if timeout is reached - * @return + * @return */ - void ForceFlushWithMicroseconds(uint64_t) noexcept override - { - }; + void ForceFlushWithMicroseconds(uint64_t) noexcept override{}; /** * @brief Close tracer, spending up to given amount of microseconds to flush and close. * NOTE: This method closes the current ETW Provider Handle. * * @param timeout Allow Tracer to drop data if timeout is reached. - * @return - */ - void CloseWithMicroseconds(uint64_t) noexcept override - { - etwProvider().close(provHandle); - }; + * @return + */ + void CloseWithMicroseconds(uint64_t) noexcept override { etwProvider().close(provHandle); }; /** * @brief Add event data to span associated with tracer. @@ -253,8 +244,8 @@ class Tracer : public trace::Tracer * @param name Event name. * @param timestamp Event timestamp. * @param attributes Event attributes. - * @return - */ + * @return + */ void AddEvent(trace::Span &span, nostd::string_view name, core::SystemTimestamp timestamp, @@ -271,7 +262,7 @@ class Tracer : public trace::Tracer evt[ETW_FIELD_NAME] = name.data(); - auto spanContext = span.GetContext(); + auto spanContext = span.GetContext(); // Decorate with additional standard fields. This may get expensive // and should be configurable for traces that deduct their nested // structure based off built-in `ActivityId` and `RelatedActivityId` @@ -286,9 +277,11 @@ class Tracer : public trace::Tracer * @param span Span. * @param name Event name. * @param timestamp Event timestamp. - * @return - */ - void AddEvent(trace::Span &span, nostd::string_view name, core::SystemTimestamp timestamp) noexcept + * @return + */ + void AddEvent(trace::Span &span, + nostd::string_view name, + core::SystemTimestamp timestamp) noexcept { AddEvent(span, name, timestamp, sdk::GetEmptyAttributes()); }; @@ -297,7 +290,7 @@ class Tracer : public trace::Tracer * @brief Add event data to span associated with tracer. * @param span Spab. * @param name Event name. - */ + */ void AddEvent(trace::Span &span, nostd::string_view name) { AddEvent(span, name, std::chrono::system_clock::now(), sdk::GetEmptyAttributes()); @@ -305,18 +298,16 @@ class Tracer : public trace::Tracer /** * @brief Tracer destructor. - */ + */ virtual ~Tracer() { CloseWithMicroseconds(0); }; - }; /** * @brief ETW::Span allows to send event data to ETW listener. -*/ + */ class Span : public trace::Span { protected: - /** * @brief Parent (Owner) Tracer of this Span */ @@ -337,28 +328,22 @@ class Span : public trace::Span */ std::atomic has_started_{false}; - public: - /** * @brief Get Span Name. * @return Span Name. - */ - nostd::string_view GetName() const - { - return name_; - } + */ + nostd::string_view GetName() const { return name_; } /** * @brief Span constructor * @param owner Owner Tracer * @param name Span name * @param options Span options - * @return - */ + * @return + */ Span(Tracer &owner, nostd::string_view name, const trace::StartSpanOptions &options) noexcept - : trace::Span(), - owner(owner) + : trace::Span(), owner(owner) { name_ = name; UNREFERENCED_PARAMETER(options); @@ -372,15 +357,15 @@ class Span : public trace::Span /** * @brief Add named event with no attributes. * @param name Event name. - * @return + * @return */ void AddEvent(nostd::string_view name) noexcept override { owner.AddEvent(*this, name); } /** * @brief Add named event with custom timestamp. - * @param name - * @param timestamp - * @return + * @param name + * @param timestamp + * @return */ void AddEvent(nostd::string_view name, core::SystemTimestamp timestamp) noexcept override { @@ -392,8 +377,8 @@ class Span : public trace::Span * @param name Event name. * @param timestamp Event timestamp. * @param attributes Event attributes. - * @return - */ + * @return + */ void AddEvent(nostd::string_view name, core::SystemTimestamp timestamp, const common::KeyValueIterable &attributes) noexcept override @@ -405,10 +390,9 @@ class Span : public trace::Span * @brief Set Span status * @param code Span status code. * @param description Span description. - * @return + * @return */ - void SetStatus(trace::CanonicalCode code, - nostd::string_view description) noexcept override + void SetStatus(trace::CanonicalCode code, nostd::string_view description) noexcept override { // TODO: not implemented UNREFERENCED_PARAMETER(code); @@ -419,12 +403,11 @@ class Span : public trace::Span * @brief Sets an attribute on the Span. If the Span previously contained a mapping * for the key, the old value is replaced. * - * @param key - * @param value - * @return + * @param key + * @param value + * @return */ - void SetAttribute(nostd::string_view key, - const common::AttributeValue &value) noexcept override + void SetAttribute(nostd::string_view key, const common::AttributeValue &value) noexcept override { // TODO: not implemented UNREFERENCED_PARAMETER(key); @@ -437,8 +420,8 @@ class Span : public trace::Span * NOTE: this method is a no-op for streaming implementation. * We cannot change the Span name after it started streaming. * - * @param name - * @return + * @param name + * @return */ void UpdateName(nostd::string_view) noexcept override { @@ -448,8 +431,8 @@ class Span : public trace::Span /** * @brief End Span. - * @param EndSpanOptions - * @return + * @param EndSpanOptions + * @return */ void End(const trace::EndSpanOptions &options = {}) noexcept override { @@ -461,7 +444,7 @@ class Span : public trace::Span /** * @brief Obtain SpanContext - * @return + * @return */ trace::SpanContext GetContext() const noexcept override { @@ -472,7 +455,7 @@ class Span : public trace::Span /** * @brief Check if Span is recording data. - * @return + * @return */ bool IsRecording() const noexcept override { @@ -518,7 +501,7 @@ class TracerProvider : public trace::TracerProvider * - "ETW" - 'classic' Trace Logging Dynamic manifest ETW events. * - "MSGPACK" - MessagePack-encoded binary payload ETW events. * - "XML" - XML events (reserved for future use) - * @return + * @return */ nostd::shared_ptr GetTracer(nostd::string_view name, nostd::string_view args = "") override @@ -561,10 +544,10 @@ class TracerProvider : public trace::TracerProvider break; } #pragma warning(pop) - return nostd::shared_ptr{new(std::nothrow) Tracer(*this, name, evtFmt)}; + return nostd::shared_ptr{new (std::nothrow) Tracer(*this, name, evtFmt)}; } }; -} // namespace ETW -} // namespace exporter +} // namespace ETW +} // namespace exporter OPENTELEMETRY_END_NAMESPACE diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_fields.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_fields.h index dc8f622ed0..fe06437cbc 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_fields.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_fields.h @@ -1,7 +1,7 @@ #pragma once #ifdef CUSTOM_ETW_FIELDS_H -#include CUSTOM_ETW_FIELDS_H +# include CUSTOM_ETW_FIELDS_H #else /* clang-format off */ @@ -30,5 +30,5 @@ # define ETW_FIELD_SUCCESS "success" /* OT Span success */ # define ETW_FIELD_STATUSCODE "statusCode" /* OT Span status code */ -/* clang-format on */ +/* clang-format on */ #endif diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h index 330df4ccfe..324aaf4fe6 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h @@ -4,14 +4,16 @@ #include "opentelemetry/common/key_value_iterable_view.h" -#include -#include -#include #include +#include +#include +#include OPENTELEMETRY_BEGIN_NAMESPACE -namespace core {}; -namespace trace {}; +namespace core +{}; +namespace trace +{}; namespace exporter { namespace ETW @@ -49,7 +51,7 @@ using PropertyVariant = /** * @brief PropertyValue class that holds PropertyVariant and * provides converter for non-owning common::AttributeValue -*/ + */ class PropertyValue : public PropertyVariant { @@ -112,8 +114,8 @@ class PropertyValue : public PropertyVariant * @brief Convert vector to span. * FIXME: std::vector is a special compact type that does not have .data() member * - * @param v - * @return + * @param v + * @return */ static nostd::span to_span(const std::vector &vec) { @@ -186,9 +188,9 @@ class PropertyValue : public PropertyVariant /** * @brief Convert owning PropertyValue to non-owning common::AttributeValue - * @return + * @return */ - PropertyValue &FromAttributeValue(const common::AttributeValue& v) + PropertyValue &FromAttributeValue(const common::AttributeValue &v) { switch (v.index()) { @@ -210,8 +212,9 @@ class PropertyValue : public PropertyVariant case common::AttributeType::TYPE_DOUBLE: PropertyVariant::operator=(nostd::get(v)); break; - case common::AttributeType::TYPE_STRING: { - PropertyVariant::operator= (nostd::string_view(nostd::get(v)).data()); + case common::AttributeType::TYPE_STRING: + { + PropertyVariant::operator=(nostd::string_view(nostd::get(v)).data()); break; }; @@ -263,7 +266,7 @@ class PropertyValue : public PropertyVariant /** * @brief Convert owning PropertyValue to non-owning common::AttributeValue - * @param other + * @param other */ common::AttributeValue ToAttributeValue() const { @@ -290,7 +293,8 @@ class PropertyValue : public PropertyVariant value = nostd::get(*this); break; - case common::AttributeType::TYPE_STRING: { + case common::AttributeType::TYPE_STRING: + { const std::string &str = nostd::get(*this); return nostd::string_view(str.data(), str.size()); break; @@ -308,8 +312,9 @@ class PropertyValue : public PropertyVariant break; #endif - case common::AttributeType::TYPE_SPAN_BOOL: { - const auto& vec = nostd::get>(*this); + case common::AttributeType::TYPE_SPAN_BOOL: + { + const auto &vec = nostd::get>(*this); // FIXME: sort out how to remap from vector to span break; } @@ -363,17 +368,15 @@ class Properties : public common::KeyValueIterable, public PropertyValueMap using PropertyValueType = std::pair; public: - /** * @brief PropertyValueMap constructor. */ - Properties() : PropertyValueMap() {}; + Properties() : PropertyValueMap(){}; /** * @brief PropertyValueMap constructor from initializer list. */ - Properties(const std::initializer_list properties) - : PropertyValueMap() + Properties(const std::initializer_list properties) : PropertyValueMap() { (*this) = (properties); }; @@ -383,17 +386,14 @@ class Properties : public common::KeyValueIterable, public PropertyValueMap */ Properties &operator=(std::initializer_list properties) { - PropertyValueMap::operator = (properties); + PropertyValueMap::operator=(properties); return (*this); }; /** * @brief PropertyValueMap constructor from map. */ - Properties(const PropertyValueMap &properties) : PropertyValueMap() - { - (*this) = properties; - }; + Properties(const PropertyValueMap &properties) : PropertyValueMap() { (*this) = properties; }; /** * @brief PropertyValueMap assignment operator from map. @@ -410,10 +410,7 @@ class Properties : public common::KeyValueIterable, public PropertyValueMap * container. * */ - Properties(const common::KeyValueIterable &other) - { - (*this) = other; - } + Properties(const common::KeyValueIterable &other) { (*this) = other; } /** * @brief PropertyValueMap assignment operator. @@ -432,10 +429,7 @@ class Properties : public common::KeyValueIterable, public PropertyValueMap /** * @brief PropertyValueMap property accessor. */ - PropertyValue &operator[](const std::string &k) - { - return PropertyValueMap::operator[](k); - } + PropertyValue &operator[](const std::string &k) { return PropertyValueMap::operator[](k); } /** * Iterate over key-value pairs @@ -443,12 +437,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 common::AttributeValue &value = kv.second.ToAttributeValue(); if (!callback(nostd::string_view{kv.first}, value)) { return false; @@ -460,13 +455,9 @@ class Properties : public common::KeyValueIterable, public PropertyValueMap /** * @return the number of key-value pairs */ - size_t size() const noexcept override - { - return PropertyValueMap::size(); - }; - + size_t size() const noexcept override { return PropertyValueMap::size(); }; }; -} +} // namespace ETW } // namespace exporter OPENTELEMETRY_END_NAMESPACE diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h index b3ec404048..18c297d0d5 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h @@ -29,8 +29,8 @@ #include "opentelemetry/exporters/etw/uuid.h" #include "opentelemetry/version.h" -#include "opentelemetry/exporters/etw/utils.h" #include "opentelemetry/exporters/etw/etw_fields.h" +#include "opentelemetry/exporters/etw/utils.h" #ifdef HAVE_MSGPACK // This option requires INCLUDE_DIR=$(ProjectDir)\..\..\third_party\json\include;... @@ -41,9 +41,9 @@ #include #include +#include #include #include -#include #ifdef HAVE_KRABS_TESTS // krabs.hpp requires this definition of min macro from Windows.h @@ -225,14 +225,13 @@ class ETWProvider return STATUS_ERROR; }; - std::string eventName = "NoName"; - auto nameField = eventData[ETW_FIELD_NAME]; + std::string eventName = "NoName"; + auto nameField = eventData[ETW_FIELD_NAME]; switch (nameField.index()) { case common::AttributeType::TYPE_STRING: - eventName = - (char *)(nostd::get(nameField).data()); // must be 0-terminated! + eventName = (char *)(nostd::get(nameField).data()); // must be 0-terminated! break; # ifdef HAVE_CSTRING_TYPE case common::AttributeType::TYPE_CSTRING: @@ -462,8 +461,7 @@ class ETWProvider switch (nameField.index()) { case common::AttributeType::TYPE_STRING: - eventName = - (char *)(nostd::get(nameField).data()); + eventName = (char *)(nostd::get(nameField).data()); break; # ifdef HAVE_CSTRING_TYPE case common::AttributeType::TYPE_CSTRING: diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_recordable.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_recordable.h index 40f370c6de..eae3ace996 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_recordable.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_recordable.h @@ -41,7 +41,7 @@ #include "opentelemetry/exporters/etw/etw_properties.h" -namespace core = opentelemetry::core; +namespace core = opentelemetry::core; namespace trace = opentelemetry::trace; OPENTELEMETRY_BEGIN_NAMESPACE @@ -107,8 +107,8 @@ class ETWSpanData final : public sdk::trace::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(); } diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer_exporter.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer_exporter.h index b379b48a12..c2d7fa8845 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer_exporter.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer_exporter.h @@ -34,8 +34,8 @@ #include "opentelemetry/sdk/trace/recordable.h" #include "opentelemetry/exporters/etw/etw_data.h" -#include "opentelemetry/exporters/etw/etw_recordable.h" #include "opentelemetry/exporters/etw/etw_provider.h" +#include "opentelemetry/exporters/etw/etw_recordable.h" #include "opentelemetry/exporters/etw/utils.h" diff --git a/exporters/etw/test/etw_tracer_test.cc b/exporters/etw/test/etw_tracer_test.cc index b4f4808005..7498aa325e 100644 --- a/exporters/etw/test/etw_tracer_test.cc +++ b/exporters/etw/test/etw_tracer_test.cc @@ -15,16 +15,16 @@ #ifdef _WIN32 # include -# include # include +# include # include "opentelemetry/exporters/etw/etw_tracer_exporter.h" # include "opentelemetry/sdk/trace/simple_processor.h" using namespace OPENTELEMETRY_NAMESPACE; -using Properties = opentelemetry::exporter::ETW::Properties; -using PropertyValue = opentelemetry::exporter::ETW::PropertyValue; +using Properties = opentelemetry::exporter::ETW::Properties; +using PropertyValue = opentelemetry::exporter::ETW::PropertyValue; using PropertyValueMap = opentelemetry::exporter::ETW::PropertyValueMap; std::string getTemporaryValue() From 013d1fd504c5b59c021b209d41d237d6c34b74e5 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 15 Jan 2021 01:07:17 -0800 Subject: [PATCH 10/76] Fix glob for Bazel build --- exporters/etw/BUILD | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/exporters/etw/BUILD b/exporters/etw/BUILD index 70690815d2..f731550e93 100644 --- a/exporters/etw/BUILD +++ b/exporters/etw/BUILD @@ -5,11 +5,9 @@ cc_library( srcs = [ "src/etw_provider_exporter.cc", ], - hdrs = [ - "include/opentelemetry/exporters/etw/etw_provider.h", - "include/opentelemetry/exporters/etw/utils.h", - "include/opentelemetry/exporters/etw/uuid.h", - ], + hdrs = glob([ + "include/opentelemetry/exporters/etw/*.h" + ]), strip_include_prefix = "include", deps = [ "//api", @@ -31,12 +29,9 @@ cc_library( srcs = [ "src/etw_tracer_exporter.cc", ], - hdrs = [ - "include/opentelemetry/exporters/etw/etw_data.h", - "include/opentelemetry/exporters/etw/etw_tracer_exporter.h", - "include/opentelemetry/exporters/etw/utils.h", - "include/opentelemetry/exporters/etw/uuid.h", - ], + hdrs = glob([ + "include/opentelemetry/exporters/etw/*.h" + ]), strip_include_prefix = "include", deps = [ ":etw_provider_exporter", From 956e38d3c5d8b8173d0e8646f5c0ee18100bc314 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 15 Jan 2021 01:11:15 -0800 Subject: [PATCH 11/76] Fix Bazel formatting issue --- exporters/etw/BUILD | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/exporters/etw/BUILD b/exporters/etw/BUILD index f731550e93..add47971c9 100644 --- a/exporters/etw/BUILD +++ b/exporters/etw/BUILD @@ -6,7 +6,7 @@ cc_library( "src/etw_provider_exporter.cc", ], hdrs = glob([ - "include/opentelemetry/exporters/etw/*.h" + "include/opentelemetry/exporters/etw/*.h", ]), strip_include_prefix = "include", deps = [ @@ -29,8 +29,8 @@ cc_library( srcs = [ "src/etw_tracer_exporter.cc", ], - hdrs = glob([ - "include/opentelemetry/exporters/etw/*.h" + hdrs = glob([ + "include/opentelemetry/exporters/etw/*.h", ]), strip_include_prefix = "include", deps = [ From 846ad7165cabdc167af90d2d3d4ac79a7989be93 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 15 Jan 2021 18:47:01 -0800 Subject: [PATCH 12/76] Wrong #ifdef in test --- api/test/nostd/string_view_test.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/test/nostd/string_view_test.cc b/api/test/nostd/string_view_test.cc index 3673082cca..715e931318 100644 --- a/api/test/nostd/string_view_test.cc +++ b/api/test/nostd/string_view_test.cc @@ -68,7 +68,7 @@ TEST(StringViewTest, SubstrPortion) TEST(StringViewTest, SubstrOutOfRange) { string_view s = "abc123"; -#if __EXCEPTIONS || defined(HAVE_STDLIB_CPP) +#if __EXCEPTIONS || defined(HAVE_CPP_STDLIB) EXPECT_THROW(s.substr(10), std::out_of_range); #else EXPECT_DEATH({ s.substr(10); }, ""); From 16ccb2a73070460aed4d1c2993c062115802b94b Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 15 Jan 2021 18:47:41 -0800 Subject: [PATCH 13/76] Add prometheus to Visual Studio 2019 CMake build configuration --- CMakeSettings.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CMakeSettings.json b/CMakeSettings.json index 21b6d41b3d..9fc1c2aed2 100644 --- a/CMakeSettings.json +++ b/CMakeSettings.json @@ -72,6 +72,11 @@ "name": "WITH_EXAMPLES", "value": "true", "type": "BOOL" + }, + { + "name": "WITH_PROMETHEUS", + "value": "True", + "type": "BOOL" } ] }, @@ -101,6 +106,11 @@ "name": "WITH_EXAMPLES", "value": "true", "type": "BOOL" + }, + { + "name": "WITH_PROMETHEUS", + "value": "True", + "type": "BOOL" } ] } From fc55f3c8c113ae62ab276e80295a73348042261a Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 15 Jan 2021 18:48:27 -0800 Subject: [PATCH 14/76] Add support for span and const char * to OTLP exporter --- exporters/otlp/src/recordable.cc | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/exporters/otlp/src/recordable.cc b/exporters/otlp/src/recordable.cc index 44d04082b4..b24e91f905 100644 --- a/exporters/otlp/src/recordable.cc +++ b/exporters/otlp/src/recordable.cc @@ -6,7 +6,21 @@ namespace exporter namespace otlp { +// +// See `attribute_value.h` for details. +// Expecting to remove the two feature gates for: +// - HAVE_CSTRING_TYPE - follows spec, but adding `const char *` on API surface. +// - HAVE_SPAN_BYTE - proposal for binary type or byte array (uint8_t[]). +// +#if defined(HAVE_CSTRING_TYPE) && defined(HAVE_SPAN_BYTE) +const int kAttributeValueSize = 16; +#elif defined(HAVE_CSTRING_TYPE) +const int kAttributeValueSize = 15; +#elif defined(HAVE_SPAN_BYTE) +const int kAttributeValueSize = 15; +#else const int kAttributeValueSize = 14; +#endif void Recordable::SetIds(trace::TraceId trace_id, trace::SpanId span_id, @@ -64,6 +78,15 @@ void PopulateAttribute(opentelemetry::proto::common::v1::KeyValue *attribute, { attribute->mutable_value()->set_string_value(nostd::get(value)); } +#endif +#ifdef HAVE_SPAN_BYTE + else if (nostd::holds_alternative>(value)) + { + for (const auto &val : nostd::get>(value)) + { + attribute->mutable_value()->mutable_array_value()->add_values()->set_int_value(val); + } + } #endif else if (nostd::holds_alternative>(value)) { From 1b039a8482c1eaa159ec7414641f10ebeedd61d3 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 15 Jan 2021 18:49:50 -0800 Subject: [PATCH 15/76] Sort OwnedAttributeValue in the same order as AttributeValue (for consistency), plus add converter from const char * --- .../sdk/common/attribute_utils.h | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/common/attribute_utils.h b/sdk/include/opentelemetry/sdk/common/attribute_utils.h index 481257c40a..d80dbd177e 100644 --- a/sdk/include/opentelemetry/sdk/common/attribute_utils.h +++ b/sdk/include/opentelemetry/sdk/common/attribute_utils.h @@ -33,22 +33,44 @@ namespace common */ using OwnedAttributeValue = nostd::variant, #endif std::vector, std::vector, - std::vector, std::vector, + std::vector, std::vector, std::vector, std::vector>; +enum OwnedAttributeType +{ + TYPE_BOOL, + TYPE_INT, + TYPE_INT64, + TYPE_UINT, + TYPE_UINT64, + TYPE_DOUBLE, + TYPE_STRING, +#ifdef HAVE_SPAN_BYTE + TYPE_SPAN_BYTE, +#endif + TYPE_SPAN_BOOL, + TYPE_SPAN_INT, + TYPE_SPAN_INT64, + TYPE_SPAN_UINT, + TYPE_SPAN_UINT64, + TYPE_SPAN_DOUBLE, + TYPE_SPAN_STRING +}; + /** * Creates an owned copy (OwnedAttributeValue) of a non-owning AttributeValue. */ @@ -64,6 +86,10 @@ struct AttributeConverter { return OwnedAttributeValue(std::string(v)); } + OwnedAttributeValue operator()(const char *v) + { + return OwnedAttributeValue(std::string(v)); + } #ifdef HAVE_SPAN_BYTE OwnedAttributeValue operator()(nostd::span v) { return convertSpan(v); } #endif From af1718fcb3afc55f8205a5c68996ba29e5036d5f Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 15 Jan 2021 18:50:16 -0800 Subject: [PATCH 16/76] Use enums instead of hardcoded constants --- ext/src/zpages/tracez_http_server.cc | 40 ++++++++++++---------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/ext/src/zpages/tracez_http_server.cc b/ext/src/zpages/tracez_http_server.cc index d44a8939a3..fa7358b72f 100644 --- a/ext/src/zpages/tracez_http_server.cc +++ b/ext/src/zpages/tracez_http_server.cc @@ -116,38 +116,32 @@ json TracezHttpServer::GetAttributesJSON( /* 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] = opentelemetry::nostd::get<0>(val); - break; - case 1: - attributes_json[key] = opentelemetry::nostd::get<1>(val); - break; - case 2: - attributes_json[key] = opentelemetry::nostd::get<2>(val); + case OwnedAttributeType::TYPE_BOOL: + attributes_json[key] = opentelemetry::nostd::get(val); break; - case 3: - attributes_json[key] = opentelemetry::nostd::get<3>(val); + case OwnedAttributeType::TYPE_INT: + attributes_json[key] = opentelemetry::nostd::get(val); break; - case 4: - attributes_json[key] = opentelemetry::nostd::get<4>(val); + case OwnedAttributeType::TYPE_UINT: + attributes_json[key] = opentelemetry::nostd::get(val); break; - case 5: - attributes_json[key] = opentelemetry::nostd::get<5>(val); + case OwnedAttributeType::TYPE_INT64: + attributes_json[key] = opentelemetry::nostd::get(val); break; - case 6: - attributes_json[key] = opentelemetry::nostd::get<6>(val); + case OwnedAttributeType::TYPE_UINT64: + attributes_json[key] = opentelemetry::nostd::get(val); break; - case 7: - attributes_json[key] = opentelemetry::nostd::get<7>(val); + case OwnedAttributeType::TYPE_DOUBLE: + attributes_json[key] = opentelemetry::nostd::get(val); break; - case 8: - attributes_json[key] = opentelemetry::nostd::get<8>(val); + case OwnedAttributeType::TYPE_STRING: + attributes_json[key] = opentelemetry::nostd::get(val); break; - case 9: - attributes_json[key] = opentelemetry::nostd::get<9>(val); + // TODO: arrays support is not implemented + default: break; } } From d1420316dba7700b70f78ce271e0332007adb6c4 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 15 Jan 2021 18:50:37 -0800 Subject: [PATCH 17/76] Add prometheus-cpp to vcpkg build on Windows --- tools/setup-buildtools.cmd | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/setup-buildtools.cmd b/tools/setup-buildtools.cmd index a98b1f125c..77ea10acba 100644 --- a/tools/setup-buildtools.cmd +++ b/tools/setup-buildtools.cmd @@ -52,5 +52,6 @@ vcpkg install nlohmann-json:x64-windows vcpkg install abseil:x64-windows vcpkg install protobuf:x64-windows vcpkg install gRPC:x64-windows +vcpkg install prometheus-cpp:x64-windows popd exit /b 0 From c02a822095238f7cb92c9c138cc98426ed993a83 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 15 Jan 2021 18:57:58 -0800 Subject: [PATCH 18/76] include(CTest) and only then if(BUILD_TESTING) --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c6106f12f..0e7fac7992 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -167,8 +167,8 @@ endif() list(APPEND CMAKE_PREFIX_PATH "${CMAKE_BINARY_DIR}") +include(CTest) if(BUILD_TESTING) - include(CTest) if(EXISTS ${CMAKE_BINARY_DIR}/lib/libgtest.a) # Prefer GTest from build tree. GTest is not always working with # CMAKE_PREFIX_PATH From afd035e934e3450ba3e163e79afa13e2860834d3 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 15 Jan 2021 19:35:59 -0800 Subject: [PATCH 19/76] Fix CI failures --- ext/src/zpages/tracez_http_server.cc | 4 +++- sdk/include/opentelemetry/sdk/common/attribute_utils.h | 5 +---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/ext/src/zpages/tracez_http_server.cc b/ext/src/zpages/tracez_http_server.cc index fa7358b72f..efeebcff77 100644 --- a/ext/src/zpages/tracez_http_server.cc +++ b/ext/src/zpages/tracez_http_server.cc @@ -104,6 +104,8 @@ json TracezHttpServer::GetLatencySpansJSON(const std::string &name, int latency_ return latency_json; } +using OwnedAttributeType = opentelemetry::sdk::common::OwnedAttributeType; + json TracezHttpServer::GetAttributesJSON( const opentelemetry::ext::zpages::ThreadsafeSpanData &sample) { @@ -116,7 +118,7 @@ json TracezHttpServer::GetAttributesJSON( /* 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 OwnedAttributeType::TYPE_BOOL: diff --git a/sdk/include/opentelemetry/sdk/common/attribute_utils.h b/sdk/include/opentelemetry/sdk/common/attribute_utils.h index d80dbd177e..27f0c49b66 100644 --- a/sdk/include/opentelemetry/sdk/common/attribute_utils.h +++ b/sdk/include/opentelemetry/sdk/common/attribute_utils.h @@ -86,10 +86,7 @@ struct AttributeConverter { return OwnedAttributeValue(std::string(v)); } - OwnedAttributeValue operator()(const char *v) - { - return OwnedAttributeValue(std::string(v)); - } + OwnedAttributeValue operator()(const char *v) { return OwnedAttributeValue(std::string(v)); } #ifdef HAVE_SPAN_BYTE OwnedAttributeValue operator()(nostd::span v) { return convertSpan(v); } #endif From a1141e48ad3f9214acd3c6fe772f22ab01646837 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 15 Jan 2021 20:10:47 -0800 Subject: [PATCH 20/76] Add nlohmann/json to CMake build --- CMakeLists.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0e7fac7992..54d06ac7db 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,8 +88,6 @@ if(WIN32) option(WITH_ETW "Whether to include the ETW Exporter in the SDK" ON) if(WITH_ETW) add_definitions(-DHAVE_MSGPACK) - # Option below will be removed once we donate the TraceLoggingDynamic.h to - # OSS endif(WITH_ETW) endif(WIN32) @@ -211,6 +209,9 @@ if(WITH_EXAMPLES) endif() add_subdirectory(ext) +# Add nlohmann/json submodule to include directories +include_directories(third_party/nlohmann-json/single_include) + # Export cmake config and support find_packages(opentelemetry-cpp CONFIG) Write # config file for find_packages(opentelemetry-cpp CONFIG) configure_package_config_file( From 93b248020085a0a871b0de06fd65f19ed1ba8e2e Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 15 Jan 2021 20:11:14 -0800 Subject: [PATCH 21/76] Compile empty stub for writeMsgPack when HAVE_MSGPACK is not defined --- .../etw/include/opentelemetry/exporters/etw/etw_provider.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h index 0872ebff81..f4f164de42 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h @@ -213,11 +213,10 @@ class ETWProvider return STATUS_ERROR; } -#ifdef HAVE_MSGPACK template unsigned long writeMsgPack(Handle &providerData, T eventData) { - +#ifdef HAVE_MSGPACK // Make sure you stop sending event before register unregistering providerData if (providerData.providerHandle == INVALID_HANDLE) { @@ -428,8 +427,10 @@ class ETWProvider return STATUS_EFBIG; }; return (unsigned long)(writeResponse); - } +#else + return STATUS_ERROR; #endif + } /// /// Send event to Provider Id From 897da33f080ef42176fb35d65819e8ae1bdeb335 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 15 Jan 2021 20:11:56 -0800 Subject: [PATCH 22/76] Build Bazel with ETW-MsgPack exporter --- exporters/etw/BUILD | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/exporters/etw/BUILD b/exporters/etw/BUILD index add47971c9..500478a3e9 100644 --- a/exporters/etw/BUILD +++ b/exporters/etw/BUILD @@ -8,6 +8,9 @@ cc_library( hdrs = glob([ "include/opentelemetry/exporters/etw/*.h", ]), + local_defines = [ + "HAVE_MSGPACK", + ], strip_include_prefix = "include", deps = [ "//api", @@ -18,6 +21,9 @@ cc_library( cc_test( name = "etw_provider_test", srcs = ["test/etw_provider_test.cc"], + local_defines = [ + "HAVE_MSGPACK", + ], deps = [ ":etw_provider_exporter", "@com_google_googletest//:gtest_main", @@ -32,6 +38,9 @@ cc_library( hdrs = glob([ "include/opentelemetry/exporters/etw/*.h", ]), + local_defines = [ + "HAVE_MSGPACK", + ], strip_include_prefix = "include", deps = [ ":etw_provider_exporter", @@ -43,6 +52,9 @@ cc_library( cc_test( name = "etw_tracer_test", srcs = ["test/etw_tracer_test.cc"], + local_defines = [ + "HAVE_MSGPACK", + ], deps = [ ":etw_tracer_exporter", "@com_google_googletest//:gtest_main", From 07952beb8c84a1a103ee78c06fc59c32dc1d5b1d Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 15 Jan 2021 21:00:55 -0800 Subject: [PATCH 23/76] Add nlohmann_json to bazel build of ETW exporter --- exporters/etw/BUILD | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/exporters/etw/BUILD b/exporters/etw/BUILD index 500478a3e9..ddea6e2b5b 100644 --- a/exporters/etw/BUILD +++ b/exporters/etw/BUILD @@ -15,6 +15,7 @@ cc_library( deps = [ "//api", "//sdk/src/trace", + "@github_nlohmann_json//:json", ], ) @@ -27,6 +28,7 @@ cc_test( deps = [ ":etw_provider_exporter", "@com_google_googletest//:gtest_main", + "@github_nlohmann_json//:json", ], ) @@ -46,6 +48,7 @@ cc_library( ":etw_provider_exporter", "//api", "//sdk/src/trace", + "@github_nlohmann_json//:json", ], ) @@ -58,5 +61,6 @@ cc_test( deps = [ ":etw_tracer_exporter", "@com_google_googletest//:gtest_main", + "@github_nlohmann_json//:json", ], ) From 8a737c7b85edad02dbeafbdcae09f3c8db52b963 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Tue, 19 Jan 2021 21:27:20 -0800 Subject: [PATCH 24/76] Incremental clean-up and simplify Bazel build --- CMakeSettings.json | 224 +++++++++--------- exporters/etw/BUILD | 31 +-- exporters/etw/CMakeLists.txt | 13 +- .../opentelemetry/exporters/etw/etw_fields.h | 14 ++ .../exporters/etw/etw_properties.h | 13 + .../exporters/etw/etw_provider.h | 2 +- .../exporters/etw/etw_recordable.h | 18 +- .../etw/{etw_data.h => etw_tracer.h} | 21 +- .../exporters/etw/etw_tracer_exporter.h | 7 +- exporters/etw/src/etw_provider_exporter.cc | 5 - exporters/etw/src/etw_tracer_exporter.cc | 5 - exporters/etw/test/etw_tracer_test.cc | 2 +- 12 files changed, 186 insertions(+), 169 deletions(-) rename exporters/etw/include/opentelemetry/exporters/etw/{etw_data.h => etw_tracer.h} (96%) delete mode 100644 exporters/etw/src/etw_provider_exporter.cc delete mode 100644 exporters/etw/src/etw_tracer_exporter.cc diff --git a/CMakeSettings.json b/CMakeSettings.json index 9fc1c2aed2..f374dbeb87 100644 --- a/CMakeSettings.json +++ b/CMakeSettings.json @@ -1,118 +1,126 @@ { - "configurations": [ + "configurations": [ + { + "name": "nostd-x64-Debug", + "generator": "Ninja", + "configurationType": "Debug", + "inheritEnvironments": [ + "msvc_x64_x64" + ], + "buildRoot": "${projectDir}\\out\\vs2019\\${name}", + "installRoot": "${projectDir}\\out\\vs2019\\${name}\\install", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "variables": [ { - "name": "nostd-x64-Debug", - "generator": "Ninja", - "configurationType": "Debug", - "inheritEnvironments": [ "msvc_x64" ], - "buildRoot": "${projectDir}\\out\\vs2019\\${name}", - "installRoot": "${projectDir}\\out\\vs2019\\${name}\\install", - "cmakeCommandArgs": "", - "buildCommandArgs": "", - "ctestCommandArgs": "", - "variables": [ - { - "name": "WITH_OTLP", - "value": "True", - "type": "BOOL" - }, - { - "name": "WITH_EXAMPLES", - "value": "true", - "type": "BOOL" - } - ] + "name": "WITH_OTLP", + "value": "True", + "type": "BOOL" }, { - "name": "nostd-x64-Release", - "generator": "Ninja", - "configurationType": "RelWithDebInfo", - "inheritEnvironments": [ "msvc_x64" ], - "buildRoot": "${projectDir}\\out\\vs2019\\${name}", - "installRoot": "${projectDir}\\out\\vs2019\\${name}\\install", - "cmakeCommandArgs": "", - "buildCommandArgs": "", - "ctestCommandArgs": "", - "cmakeToolchain": "", - "variables": [ - { - "name": "WITH_OTLP", - "value": "True", - "type": "BOOL" - }, - { - "name": "WITH_EXAMPLES", - "value": "true", - "type": "BOOL" - } - ] + "name": "WITH_EXAMPLES", + "value": "true", + "type": "BOOL" + } + ] + }, + { + "name": "nostd-x64-Release", + "generator": "Ninja", + "configurationType": "RelWithDebInfo", + "inheritEnvironments": [ + "msvc_x64_x64" + ], + "buildRoot": "${projectDir}\\out\\vs2019\\${name}", + "installRoot": "${projectDir}\\out\\vs2019\\${name}\\install", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "cmakeToolchain": "", + "variables": [ + { + "name": "WITH_OTLP", + "value": "True", + "type": "BOOL" + }, + { + "name": "WITH_EXAMPLES", + "value": "true", + "type": "BOOL" + } + ] + }, + { + "name": "stdlib-x64-Debug", + "generator": "Ninja", + "configurationType": "Debug", + "inheritEnvironments": [ + "msvc_x64_x64" + ], + "buildRoot": "${projectDir}\\out\\vs2019\\${name}", + "installRoot": "${projectDir}\\out\\vs2019\\${name}\\install", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "variables": [ + { + "name": "WITH_STL", + "value": "True", + "type": "BOOL" + }, + { + "name": "WITH_OTLP", + "value": "True", + "type": "BOOL" + }, + { + "name": "WITH_EXAMPLES", + "value": "true", + "type": "BOOL" + }, + { + "name": "WITH_PROMETHEUS", + "value": "True", + "type": "BOOL" + } + ] + }, + { + "name": "stdlib-x64-Release", + "generator": "Ninja", + "configurationType": "RelWithDebInfo", + "inheritEnvironments": [ + "msvc_x64_x64" + ], + "buildRoot": "${projectDir}\\out\\vs2019\\${name}", + "installRoot": "${projectDir}\\out\\vs2019\\${name}\\install", + "cmakeCommandArgs": "", + "buildCommandArgs": "", + "ctestCommandArgs": "", + "cmakeToolchain": "", + "variables": [ + { + "name": "WITH_STL", + "value": "True", + "type": "BOOL" + }, + { + "name": "WITH_OTLP", + "value": "True", + "type": "BOOL" }, { - "name": "stdlib-x64-Debug", - "generator": "Ninja", - "configurationType": "Debug", - "inheritEnvironments": [ "msvc_x64_x64" ], - "buildRoot": "${projectDir}\\out\\vs2019\\${name}", - "installRoot": "${projectDir}\\out\\vs2019\\${name}\\install", - "cmakeCommandArgs": "", - "buildCommandArgs": "", - "ctestCommandArgs": "", - "variables": [ - { - "name": "WITH_STL", - "value": "True", - "type": "BOOL" - }, - { - "name": "WITH_OTLP", - "value": "True", - "type": "BOOL" - }, - { - "name": "WITH_EXAMPLES", - "value": "true", - "type": "BOOL" - }, - { - "name": "WITH_PROMETHEUS", - "value": "True", - "type": "BOOL" - } - ] + "name": "WITH_EXAMPLES", + "value": "true", + "type": "BOOL" }, { - "name": "stdlib-x64-Release", - "generator": "Ninja", - "configurationType": "RelWithDebInfo", - "inheritEnvironments": [ "msvc_x64_x64" ], - "buildRoot": "${projectDir}\\out\\vs2019\\${name}", - "installRoot": "${projectDir}\\out\\vs2019\\${name}\\install", - "cmakeCommandArgs": "", - "buildCommandArgs": "", - "ctestCommandArgs": "", - "cmakeToolchain": "", - "variables": [ - { - "name": "WITH_STL", - "value": "True", - "type": "BOOL" - }, - { - "name": "WITH_OTLP", - "value": "True", - "type": "BOOL" - }, - { - "name": "WITH_EXAMPLES", - "value": "true", - "type": "BOOL" - }, - { - "name": "WITH_PROMETHEUS", - "value": "True", - "type": "BOOL" - } - ] + "name": "WITH_PROMETHEUS", + "value": "True", + "type": "BOOL" } - ] + ] + } + ] } \ No newline at end of file diff --git a/exporters/etw/BUILD b/exporters/etw/BUILD index ddea6e2b5b..9cff8967c6 100644 --- a/exporters/etw/BUILD +++ b/exporters/etw/BUILD @@ -1,17 +1,14 @@ package(default_visibility = ["//visibility:public"]) cc_library( - name = "etw_provider_exporter", - srcs = [ - "src/etw_provider_exporter.cc", - ], + name = "etw_exporter", hdrs = glob([ "include/opentelemetry/exporters/etw/*.h", ]), + includes = ["include"], local_defines = [ "HAVE_MSGPACK", ], - strip_include_prefix = "include", deps = [ "//api", "//sdk/src/trace", @@ -26,32 +23,12 @@ cc_test( "HAVE_MSGPACK", ], deps = [ - ":etw_provider_exporter", + ":etw_exporter", "@com_google_googletest//:gtest_main", "@github_nlohmann_json//:json", ], ) -cc_library( - name = "etw_tracer_exporter", - srcs = [ - "src/etw_tracer_exporter.cc", - ], - hdrs = glob([ - "include/opentelemetry/exporters/etw/*.h", - ]), - local_defines = [ - "HAVE_MSGPACK", - ], - strip_include_prefix = "include", - deps = [ - ":etw_provider_exporter", - "//api", - "//sdk/src/trace", - "@github_nlohmann_json//:json", - ], -) - cc_test( name = "etw_tracer_test", srcs = ["test/etw_tracer_test.cc"], @@ -59,7 +36,7 @@ cc_test( "HAVE_MSGPACK", ], deps = [ - ":etw_tracer_exporter", + ":etw_exporter", "@com_google_googletest//:gtest_main", "@github_nlohmann_json//:json", ], diff --git a/exporters/etw/CMakeLists.txt b/exporters/etw/CMakeLists.txt index a3d02e6f35..4a492a5080 100644 --- a/exporters/etw/CMakeLists.txt +++ b/exporters/etw/CMakeLists.txt @@ -1,19 +1,14 @@ include_directories(include) -add_library(opentelemetry_exporter_etw_provider src/etw_provider_exporter.cc) -add_library(opentelemetry_exporter_etw_tracer src/etw_tracer_exporter.cc) - if(BUILD_TESTING) add_executable(etw_provider_test test/etw_provider_test.cc) add_executable(etw_tracer_test test/etw_tracer_test.cc) - target_link_libraries( - etw_provider_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} - opentelemetry_exporter_etw_provider) + target_link_libraries(etw_provider_test ${GTEST_BOTH_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT}) - target_link_libraries( - etw_tracer_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} - opentelemetry_exporter_etw_tracer) + target_link_libraries(etw_tracer_test ${GTEST_BOTH_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT}) gtest_add_tests( TARGET etw_provider_test diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_fields.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_fields.h index fe06437cbc..b7599ff3dd 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_fields.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_fields.h @@ -1,3 +1,17 @@ +/* Copyright 2020-2021, OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ #pragma once #ifdef CUSTOM_ETW_FIELDS_H diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h index 324aaf4fe6..753b25ed26 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h @@ -1,3 +1,16 @@ +// Copyright 2021, OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. #pragma once #include "opentelemetry/version.h" diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h index f4f164de42..796b676bdb 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h @@ -1,4 +1,4 @@ -// Copyright 2020, OpenTelemetry Authors +// Copyright 2020-2021, OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_recordable.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_recordable.h index eae3ace996..f6bb381ea1 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_recordable.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_recordable.h @@ -1,3 +1,16 @@ +// Copyright 2021, OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. #pragma once #include @@ -37,6 +50,7 @@ #include "opentelemetry/exporters/etw/etw_fields.h" #include "opentelemetry/exporters/etw/etw_provider.h" +#include "opentelemetry/exporters/etw/etw_tracer.h" #include "opentelemetry/exporters/etw/utils.h" #include "opentelemetry/exporters/etw/etw_properties.h" @@ -50,10 +64,10 @@ namespace exporter namespace ETW { -class ETWSpanData final : public sdk::trace::Recordable +class ETWTraceRecordable final : public sdk::trace::Recordable { public: - ETWSpanData(std::string providerName) { InitTracerProvider(providerName); } + ETWTraceRecordable(std::string providerName) { InitTracerProvider(providerName); } /** * Get the trace id for this span diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_data.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h similarity index 96% rename from exporters/etw/include/opentelemetry/exporters/etw/etw_data.h rename to exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h index 62bbcfb93d..f2f899e722 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_data.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h @@ -1,3 +1,16 @@ +// Copyright 2021, OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. #pragma once #include @@ -131,14 +144,6 @@ class Tracer : public trace::Tracer attributes[ETW_FIELD_SPAN_LINKS] = linksValue; }; -#if 0 - // TODO: SpanContext is a temporary implementation that requires revisiting. - // One option for ETW exporter is to respect the existing correlation fields: - // - ActivityId - as current Trace Id - // - RelatedActivityId - as parent Trace Id - virtual trace::SpanContext GetDefaultContext() = 0; -#endif - /** * @brief Allow our friendly ETW::Span to end itself on Tracer. * @param span diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer_exporter.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer_exporter.h index c2d7fa8845..bcf6cc4460 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer_exporter.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer_exporter.h @@ -33,9 +33,9 @@ #include "opentelemetry/sdk/trace/exporter.h" #include "opentelemetry/sdk/trace/recordable.h" -#include "opentelemetry/exporters/etw/etw_data.h" #include "opentelemetry/exporters/etw/etw_provider.h" #include "opentelemetry/exporters/etw/etw_recordable.h" +#include "opentelemetry/exporters/etw/etw_tracer.h" #include "opentelemetry/exporters/etw/utils.h" @@ -77,7 +77,7 @@ class ETWTracerExporter final : public opentelemetry::sdk::trace::SpanExporter */ std::unique_ptr MakeRecordable() noexcept override { - return std::unique_ptr(new ETWSpanData(providerName_)); + return std::unique_ptr(new ETWTraceRecordable(providerName_)); } /** @@ -90,7 +90,8 @@ class ETWTracerExporter final : public opentelemetry::sdk::trace::SpanExporter { for (auto &recordable : recordables) { - auto span = std::unique_ptr(dynamic_cast(recordable.release())); + auto span = std::unique_ptr( + dynamic_cast(recordable.release())); if (span != nullptr) { std::cout << span->GetName() << std::endl; diff --git a/exporters/etw/src/etw_provider_exporter.cc b/exporters/etw/src/etw_provider_exporter.cc deleted file mode 100644 index 34eb594730..0000000000 --- a/exporters/etw/src/etw_provider_exporter.cc +++ /dev/null @@ -1,5 +0,0 @@ -#ifdef _WIN32 - -# include "opentelemetry/exporters/etw/etw_provider.h" - -#endif diff --git a/exporters/etw/src/etw_tracer_exporter.cc b/exporters/etw/src/etw_tracer_exporter.cc deleted file mode 100644 index 63ef489797..0000000000 --- a/exporters/etw/src/etw_tracer_exporter.cc +++ /dev/null @@ -1,5 +0,0 @@ -#ifdef _WIN32 - -# include "opentelemetry/exporters/etw/etw_tracer_exporter.h" - -#endif diff --git a/exporters/etw/test/etw_tracer_test.cc b/exporters/etw/test/etw_tracer_test.cc index 7498aa325e..5d4a427053 100644 --- a/exporters/etw/test/etw_tracer_test.cc +++ b/exporters/etw/test/etw_tracer_test.cc @@ -44,7 +44,7 @@ TEST(ETWTracer, TracerCheck) // [Docker] {a3693192-9ed6-46d2-a981-f8226c8363bd} // ... // Intel-Autologger-iclsClient {B8D7E9A0-65D5-40BE-AFEA-83593FC0164E} - // Intel-Autologger-iclsProxy {301B773F-50F3-4C8E-83F0-53BA9590A13E} + // Intel-Autologger-iclsProxy {301B773F-50F3-4C8E-83F0-53BA9590A13E} // Intel-Autologger-PTTEKRecertification {F33E9E07-8792-47E8-B3FA-2C92AB32C5B3} // ... // NodeJS-ETW-provider {77754E9B-264B-4D8D-B981-E4135C1ECB0C} From 0c3b16719db8173195a8c9c5083aa44a94a188bf Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Thu, 21 Jan 2021 15:31:19 -0800 Subject: [PATCH 25/76] Update .github/CODEOWNERS Co-authored-by: Johannes Tax --- .github/CODEOWNERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 3c5a791e5d..99eaf7e2c9 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,6 +1,6 @@ # Code owners file. # This file controls who is tagged for review for any given pull request. -# For anything not explicitly taken by someone else: +* @open-telemetry/cpp-approvers + /exporters/etw/ @reyang @maxgolov @lalitb @ThomsonTan -* @open-telemetry/cpp-approvers From b7153eb81635147ac4106c32dd059d0ae690a25f Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Thu, 28 Jan 2021 16:04:51 -0800 Subject: [PATCH 26/76] Allow populating Span from byte buffer --- api/include/opentelemetry/trace/span_id.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/api/include/opentelemetry/trace/span_id.h b/api/include/opentelemetry/trace/span_id.h index c05a4c6829..fb91d6c49b 100644 --- a/api/include/opentelemetry/trace/span_id.h +++ b/api/include/opentelemetry/trace/span_id.h @@ -36,6 +36,8 @@ class SpanId final // Creates a SpanId with the given ID. explicit SpanId(nostd::span id) noexcept { memcpy(rep_, id.data(), kSize); } + explicit SpanId(const uint8_t* data) noexcept { memcpy(rep_, data, kSize); } + // Populates the buffer with the lowercase base16 representation of the ID. void ToLowerBase16(nostd::span buffer) const noexcept { From a09a941185500c86b7d2797e9d5ae5da860a4cc6 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Thu, 28 Jan 2021 16:05:07 -0800 Subject: [PATCH 27/76] Allow populating TraceId from byte buffer --- api/include/opentelemetry/trace/trace_id.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/api/include/opentelemetry/trace/trace_id.h b/api/include/opentelemetry/trace/trace_id.h index fff2160786..039c9fce8a 100644 --- a/api/include/opentelemetry/trace/trace_id.h +++ b/api/include/opentelemetry/trace/trace_id.h @@ -42,6 +42,12 @@ class TraceId final memcpy(rep_, id.data(), kSize); } + // Creates a TraceId with the given ID. + explicit TraceId(const uint8_t* data) noexcept + { + memcpy(rep_, data, kSize); + } + // Populates the buffer with the lowercase base16 representation of the ID. void ToLowerBase16(nostd::span buffer) const noexcept { From 5de423be10fe7f9f34bf264186e0e42b99da755d Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Thu, 28 Jan 2021 16:05:44 -0800 Subject: [PATCH 28/76] Allow populating ActivityId and RelatedActivity based on SpanId and ParentSpanId --- .../exporters/etw/etw_provider.h | 67 +++++++++++++++---- 1 file changed, 54 insertions(+), 13 deletions(-) diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h index 796b676bdb..2f76ef3a5a 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h @@ -19,9 +19,8 @@ #endif #ifdef _MSC_VER -// evntprov.h(838) : warning C4459 : declaration of 'Version' hides global declaration +# pragma warning(push) # pragma warning(disable : 4459) -// needed for Unit Testing with krabs.hpp # pragma warning(disable : 4018) #endif @@ -33,7 +32,6 @@ #include "opentelemetry/exporters/etw/utils.h" #ifdef HAVE_MSGPACK -// This option requires INCLUDE_DIR=$(ProjectDir)\..\..\third_party\json\include;... # include "nlohmann/json.hpp" #endif @@ -214,7 +212,11 @@ class ETWProvider } template - unsigned long writeMsgPack(Handle &providerData, T eventData) + unsigned long writeMsgPack(Handle &providerData, + T eventData, + LPCGUID ActivityId = nullptr, + LPCGUID RelatedActivityId = nullptr, + uint8_t Opcode = 0 /* Information */) { #ifdef HAVE_MSGPACK // Make sure you stop sending event before register unregistering providerData @@ -400,11 +402,27 @@ class ETWProvider std::vector v = nlohmann::json::to_msgpack(l1); EVENT_DESCRIPTOR evtDescriptor; - EventDescCreate(&evtDescriptor, 0, 0x1, 0, 0, 0, 0, 0); + // TODO: event descriptor may be populated with additional values as follows: + // Id - if 0, auto-incremented sequence number that uniquely identifies event in a trace + // Version - event version + // Channel - 11 for TraceLogging + // Level - verbosity level + // Task - TaskId + // Opcode - described in evntprov.h:259 : 0 - info, 1 - activity start, 2 - activity stop. + EventDescCreate(&evtDescriptor, 0, 0x1, 0, 0, 0, Opcode, 0); EVENT_DATA_DESCRIPTOR evtData[1]; EventDataDescCreate(&evtData[0], v.data(), static_cast(v.size())); - auto writeResponse = EventWrite(providerData.providerHandle, &evtDescriptor, 1, evtData); + ULONG writeResponse = 0; + + if ((ActivityId != nullptr) || (RelatedActivityId != nullptr)) + { + EventWriteTransfer(providerData.providerHandle, &evtDescriptor, ActivityId, RelatedActivityId, 1, evtData); + } + else + { + EventWrite(providerData.providerHandle, &evtDescriptor, 1, evtData); + }; switch (writeResponse) { @@ -439,7 +457,11 @@ class ETWProvider /// /// template - unsigned long writeTld(Handle &providerData, T eventData) + unsigned long writeTld(Handle &providerData, + T eventData, + LPCGUID ActivityId = nullptr, + LPCGUID RelatedActivityId = nullptr, + uint8_t Opcode = 0 /* Information */ ) { #ifdef HAVE_TLD // Make sure you stop sending event before register unregistering providerData @@ -577,10 +599,12 @@ class ETWProvider } tld::EventDescriptor eventDescriptor; + eventDescriptor.Opcode = Opcode; + eventDescriptor.Level = 0; /* FIXME: Always on for now */ + // eventDescriptor.Keyword = MICROSOFT_KEYWORD_CRITICAL_DATA; // eventDescriptor.Keyword = MICROSOFT_KEYWORD_TELEMETRY; // eventDescriptor.Keyword = MICROSOFT_KEYWORD_MEASURES; - EVENT_DATA_DESCRIPTOR pDataDescriptors[3]; EventDataDescCreate(&pDataDescriptors[2], byteDataVector.data(), @@ -595,9 +619,19 @@ class ETWProvider // - GUID ActivityId // - GUID RelatedActivityId - HRESULT writeResponse = tld::WriteEvent(providerData.providerHandle, eventDescriptor, - providerData.providerMetaVector.data(), - byteVector.data(), 3, pDataDescriptors); + HRESULT writeResponse = 0; + if ((ActivityId != nullptr) || (RelatedActivityId != nullptr)) + { + tld::WriteEvent(providerData.providerHandle, eventDescriptor, + providerData.providerMetaVector.data(), byteVector.data(), 3, + pDataDescriptors, ActivityId, RelatedActivityId); + } + else + { + tld::WriteEvent(providerData.providerHandle, eventDescriptor, + providerData.providerMetaVector.data(), byteVector.data(), 3, + pDataDescriptors); + }; if (writeResponse == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW)) { @@ -613,15 +647,18 @@ class ETWProvider template unsigned long write(Handle &providerData, T eventData, + LPCGUID ActivityId = nullptr, + LPCGUID RelatedActivityId = nullptr, + uint8_t Opcode = 0, /* Information */ ETWProvider::EventFormat format = ETWProvider::EventFormat::ETW_MANIFEST) { if (format == ETWProvider::EventFormat::ETW_MANIFEST) { - return writeTld(providerData, eventData); + return writeTld(providerData, eventData, ActivityId, RelatedActivityId, Opcode); } if (format == ETWProvider::EventFormat::ETW_MSGPACK) { - return writeMsgPack(providerData, eventData); + return writeMsgPack(providerData, eventData, ActivityId, RelatedActivityId, Opcode); } if (format == ETWProvider::EventFormat::ETW_XML) { @@ -650,3 +687,7 @@ class ETWProvider }; OPENTELEMETRY_END_NAMESPACE + +#ifdef _MSC_VER +# pragma warning(pop) +#endif From 4b5d3b7c5ed668b4e8d18c7135b53197760ce417 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Thu, 28 Jan 2021 16:28:01 -0800 Subject: [PATCH 29/76] Automated context propagation --- .../opentelemetry/exporters/etw/etw_tracer.h | 152 +++++++++++++++--- 1 file changed, 128 insertions(+), 24 deletions(-) diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h index f2f899e722..3d062f76f8 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h @@ -13,6 +13,8 @@ // limitations under the License. #pragma once +#include + #include #include #include @@ -24,6 +26,7 @@ #include #include #include +#include #include "opentelemetry/nostd/shared_ptr.h" #include "opentelemetry/nostd/string_view.h" @@ -54,6 +57,15 @@ namespace exporter { namespace ETW { + +struct ProviderOptions +{ + bool enableTraceId; + bool enableActivityId; + bool enableRelatedActivityId; + bool enableAutoContext; +}; + class Span; /** @@ -69,6 +81,15 @@ std::string GetName(T &t) return std::string(sV.data(), sV.length()); } +static inline GUID ToActivityId(const trace::Span *span) +{ + if (span == nullptr) + { + return GUID({0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}}); + } + return utils::UUID(span->GetContext().span_id().Id().data()).to_GUID(); +}; + /** * @brief Utility template to convert SpanId or TraceId to hex. * @param id - value of SpanId or TraceId @@ -108,6 +129,8 @@ class Tracer : public trace::Tracer */ ETWProvider::EventFormat encoding; + trace::TraceId traceId_; + /** * @brief ETWProvider is a singleton that aggregates all ETW writes. * @return @@ -149,21 +172,43 @@ class Tracer : public trace::Tracer * @param span * @param */ - virtual void EndSpan(const Span &span, const trace::EndSpanOptions & = {}) + virtual void EndSpan(const Span &span, const trace::Span *parent = nullptr, const trace::EndSpanOptions & = {}) { Properties evt; - auto ctx = (reinterpret_cast(&span))->GetContext(); + const trace::Span& spanBase = reinterpret_cast(span); + + auto ctx = spanBase.GetContext(); evt[ETW_FIELD_NAME] = GetName(span); - evt[ETW_FIELD_TYPE] = ETW_FIELD_SPAN_END; - evt[ETW_FIELD_SPAN_ID] = ToLowerBase16(ctx.span_id()); + + // We use ActivityId instead of ETW_FIELD_SPAN_ID below + // evt[ETW_FIELD_SPAN_ID] = ToLowerBase16(ctx.span_id()); + auto ActivityId = ToActivityId(&spanBase); + + // Could be GUID NULL + auto RelatedActivityId = ToActivityId(parent); // TODO: check what EndSpanOptions should be supported for this exporter - etwProvider().write(provHandle, evt, encoding); + etwProvider().write(provHandle, evt, &ActivityId, &RelatedActivityId, 2, encoding); + + { + const std::lock_guard lock(scopes_mutex_); + auto spanId = ToLowerBase16(spanBase.GetContext().span_id()); + scopes_.erase(spanId); + } + + }; + + const trace::TraceId& trace_id() + { + return traceId_; }; friend class Span; + std::mutex scopes_mutex_; // protects scopes_ + std::map> scopes_; + public: /** * @brief Tracer constructor @@ -179,11 +224,18 @@ class Tracer : public trace::Tracer provId(providerId.data(), providerId.size()), encoding(encoding) { + GUID trace_id; + // Generate random GUID + CoCreateGuid(&trace_id); + const auto *traceIdBytes = reinterpret_cast(std::addressof(trace_id)); + // Populate TraceId with that GUID + traceId_ = trace::TraceId(traceIdBytes); + #if defined(HAVE_MSGPACK) && !defined(HAVE_TLD) /* Fallback to MsgPack encoding if TraceLoggingDynamic feature gate is off */ this->encoding = ETWProvider::EventFormat::ETW_MSGPACK; #endif - provHandle = etwProvider().open(provId, encoding); + provHandle = etwProvider().open(provId, encoding); }; /** @@ -200,6 +252,16 @@ class Tracer : public trace::Tracer const trace::SpanContextKeyValueIterable &links, const trace::StartSpanOptions &options = {}) noexcept override { + const auto parent = GetCurrentSpan(); + LPCGUID RelatedActivityIdPtr = nullptr; + GUID RelatedActivityId; + // Propagate parent activity only if parent span (current span) is valid + if (parent->GetContext().IsValid()) + { + RelatedActivityId = ToActivityId(parent.get()); + RelatedActivityIdPtr = &RelatedActivityId; + }; + nostd::shared_ptr result = trace::to_span_ptr(this, name, options); auto spanContext = result->GetContext(); @@ -207,10 +269,12 @@ class Tracer : public trace::Tracer Properties evt = attributes; // Decorate with additional standard fields - evt[ETW_FIELD_NAME] = name.data(); - evt[ETW_FIELD_TYPE] = ETW_FIELD_SPAN_START; + std::string eventName = name.data(); + + evt[ETW_FIELD_NAME] = eventName.data(); evt[ETW_FIELD_TRACE_ID] = ToLowerBase16(spanContext.trace_id()); - evt[ETW_FIELD_SPAN_ID] = ToLowerBase16(spanContext.span_id()); + + auto ActivityId = ToActivityId(result.get()); // Links DecorateLinks(evt, links); @@ -221,7 +285,14 @@ class Tracer : public trace::Tracer // - options.parent // - options.start_steady_time // - options.start_system_time - etwProvider().write(provHandle, evt, encoding); + etwProvider().write(provHandle, evt, &ActivityId, RelatedActivityIdPtr, 1, encoding); + + { + const std::lock_guard lock(scopes_mutex_); + // Use span_id as index + scopes_[ToLowerBase16(result->GetContext().span_id())] = WithActiveSpan(result); + } + return result; }; @@ -268,13 +339,16 @@ class Tracer : public trace::Tracer evt[ETW_FIELD_NAME] = name.data(); auto spanContext = span.GetContext(); + // Decorate with additional standard fields. This may get expensive // and should be configurable for traces that deduct their nested // structure based off built-in `ActivityId` and `RelatedActivityId` - evt[ETW_FIELD_TRACE_ID] = ToLowerBase16(spanContext.trace_id()); + // evt[ETW_FIELD_TRACE_ID] = ToLowerBase16(spanContext.trace_id()); evt[ETW_FIELD_SPAN_ID] = ToLowerBase16(spanContext.span_id()); - etwProvider().write(provHandle, evt, encoding); + auto RelatedActivityId = ToActivityId(&span); + + etwProvider().write(provHandle, evt, nullptr, &RelatedActivityId, encoding); }; /** @@ -314,9 +388,9 @@ class Span : public trace::Span { protected: /** - * @brief Parent (Owner) Tracer of this Span + * @brief Owner Tracer of this Span */ - Tracer &owner; + Tracer &owner_; /** * @brief Span name. @@ -333,7 +407,38 @@ class Span : public trace::Span */ std::atomic has_started_{false}; + /** + * @brief Parent Span of this nested Span (optional) + */ + Span *parent_{nullptr}; + + /** + * @brief Get Parent Span of this nested Span. + * @return Pointer to Parent or nullptr if no Parent. + */ + Span *GetParent() const { return parent_; } + + trace::SpanContext context_; + + const trace::SpanContext CreateContext() + { + GUID activity_id; + // Generate random GUID + CoCreateGuid(&activity_id); + const auto *activityIdBytes = reinterpret_cast(std::addressof(activity_id)); + // Populate SpanId with that GUID + const trace::SpanId spanId(activityIdBytes); + // Inherit trace_id from Tracer + const trace::TraceId traceId{owner_.trace_id()}; + // TODO: TraceFlags are not supported by ETW exporter. + const trace::TraceFlags flags{0}; + // TODO: Remote parent is not supported by ETW exporter. + const bool hasRemoteParent = false; + return trace::SpanContext{traceId, spanId, flags, hasRemoteParent}; + } + public: + /** * @brief Get Span Name. * @return Span Name. @@ -345,10 +450,11 @@ class Span : public trace::Span * @param owner Owner Tracer * @param name Span name * @param options Span options + * @param parent Parent Span (optional) * @return */ - Span(Tracer &owner, nostd::string_view name, const trace::StartSpanOptions &options) noexcept - : trace::Span(), owner(owner) + Span(Tracer &owner, nostd::string_view name, const trace::StartSpanOptions &options, Span* parent = nullptr) noexcept + : trace::Span(), owner_(owner), parent_(parent), context_(CreateContext()) { name_ = name; UNREFERENCED_PARAMETER(options); @@ -364,7 +470,7 @@ class Span : public trace::Span * @param name Event name. * @return */ - void AddEvent(nostd::string_view name) noexcept override { owner.AddEvent(*this, name); } + void AddEvent(nostd::string_view name) noexcept override { owner_.AddEvent(*this, name); } /** * @brief Add named event with custom timestamp. @@ -374,7 +480,7 @@ class Span : public trace::Span */ void AddEvent(nostd::string_view name, core::SystemTimestamp timestamp) noexcept override { - owner.AddEvent(*this, name, timestamp); + owner_.AddEvent(*this, name, timestamp); } /** @@ -388,7 +494,7 @@ class Span : public trace::Span core::SystemTimestamp timestamp, const common::KeyValueIterable &attributes) noexcept override { - owner.AddEvent(*this, name, timestamp, attributes); + owner_.AddEvent(*this, name, timestamp, attributes); } /** @@ -443,7 +549,7 @@ class Span : public trace::Span { if (!has_ended_.exchange(true)) { - owner.EndSpan(*this, options); + owner_.EndSpan(*this, parent_, options); } } @@ -453,9 +559,7 @@ class Span : public trace::Span */ trace::SpanContext GetContext() const noexcept override { - // TODO: not implemented - static trace::SpanContext nullContext{trace::SpanContext::GetInvalid()}; - return nullContext; + return context_; } /** @@ -480,7 +584,7 @@ class Span : public trace::Span /// Get Owner tracer of this Span /// /// - trace::Tracer &tracer() const noexcept { return this->owner; }; + trace::Tracer &tracer() const noexcept { return this->owner_; }; }; /// From fdda4da3a0fc4799fd400bfee68ce404db851818 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Thu, 28 Jan 2021 16:29:03 -0800 Subject: [PATCH 30/76] Include headers for CoCreateGuid --- exporters/etw/include/opentelemetry/exporters/etw/utils.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/exporters/etw/include/opentelemetry/exporters/etw/utils.h b/exporters/etw/include/opentelemetry/exporters/etw/utils.h index 079d4e5592..e29d767a74 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/utils.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/utils.h @@ -32,6 +32,8 @@ # include # pragma comment(lib, "Advapi32.lib") # pragma comment(lib, "Rpcrt4.lib") +# include +# pragma comment(lib, "Ole32.Lib") #endif OPENTELEMETRY_BEGIN_NAMESPACE From ee14876644c6710cdac0f45fc24ff5525dea8aed Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Thu, 28 Jan 2021 16:30:14 -0800 Subject: [PATCH 31/76] Added 3-level deep spans to test --- exporters/etw/test/etw_tracer_test.cc | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/exporters/etw/test/etw_tracer_test.cc b/exporters/etw/test/etw_tracer_test.cc index 5d4a427053..6fc9c6163a 100644 --- a/exporters/etw/test/etw_tracer_test.cc +++ b/exporters/etw/test/etw_tracer_test.cc @@ -69,7 +69,14 @@ TEST(ETWTracer, TracerCheck) {"attrib2", 2} }; - auto outerSpan = tracer->StartSpan("MySpanOuter", attribs); + auto topSpan = tracer->StartSpan("MySpanTop"); + std::this_thread::sleep_for (std::chrono::seconds(1)); + + auto outerSpan = tracer->StartSpan("MySpanL2", attribs); + + // Create nested span. Note how we share the attributes here. + // It is Okay to either reuse/share or have your own attributes. + auto innerSpan = tracer->StartSpan("MySpanL3", attribs); // Add first event std::string eventName1 = "MyEvent1"; @@ -80,6 +87,7 @@ TEST(ETWTracer, TracerCheck) {"strKey", "someValue"} }; EXPECT_NO_THROW(outerSpan->AddEvent(eventName1, event1)); + std::this_thread::sleep_for (std::chrono::seconds(1)); // Add second event std::string eventName2 = "MyEvent2"; @@ -90,24 +98,25 @@ TEST(ETWTracer, TracerCheck) {"strKey", "anotherValue"} }; EXPECT_NO_THROW(outerSpan->AddEvent(eventName2, event2)); + std::this_thread::sleep_for (std::chrono::seconds(2)); - - // Create nested span. Note how we share the attributes here.. - // It is Okay to share or have your own attributes. - auto innerSpan = tracer->StartSpan("MySpanInner", attribs); std::string eventName3= "MyEvent3"; Properties event3 = { + /* Extra metadata that allows event to flow to A.I. pipeline */ + {"metadata", "ai_event"}, {"uint32Key", (uint32_t)9876}, {"uint64Key", (uint64_t)987654321}, // {"int32array", {{-1,0,1,2,3}} }, {"tempString", getTemporaryValue() } }; EXPECT_NO_THROW(innerSpan->AddEvent(eventName3, event3)); + std::this_thread::sleep_for (std::chrono::seconds(1)); EXPECT_NO_THROW(innerSpan->End()); // end innerSpan EXPECT_NO_THROW(outerSpan->End()); // end outerSpan + EXPECT_NO_THROW(topSpan->End()); // end topSpan EXPECT_NO_THROW(tracer->CloseWithMicroseconds(0)); } From 44f0ce299792485901412aa4292bdbf30c675263 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Tue, 2 Feb 2021 12:18:16 -0800 Subject: [PATCH 32/76] Reformat code --- CMakeLists.txt | 11 ++- api/include/opentelemetry/trace/span_id.h | 2 +- api/include/opentelemetry/trace/trace_id.h | 5 +- api/test/context/CMakeLists.txt | 5 +- api/test/core/CMakeLists.txt | 6 +- api/test/logs/CMakeLists.txt | 6 +- api/test/metrics/CMakeLists.txt | 5 +- api/test/nostd/CMakeLists.txt | 5 +- api/test/plugin/CMakeLists.txt | 6 +- api/test/trace/CMakeLists.txt | 6 +- api/test/trace/propagation/CMakeLists.txt | 5 +- exporters/elasticsearch/CMakeLists.txt | 6 +- exporters/etw/CMakeLists.txt | 12 +-- .../exporters/etw/etw_properties.h | 14 ++-- .../exporters/etw/etw_provider.h | 73 +++++++------------ .../exporters/etw/etw_recordable.h | 10 +-- .../opentelemetry/exporters/etw/etw_tracer.h | 50 ++++++------- exporters/memory/CMakeLists.txt | 12 +-- exporters/ostream/CMakeLists.txt | 22 ++---- exporters/otlp/CMakeLists.txt | 6 +- exporters/prometheus/test/CMakeLists.txt | 6 +- ext/test/http/CMakeLists.txt | 6 +- ext/test/zpages/CMakeLists.txt | 5 +- sdk/test/common/CMakeLists.txt | 5 +- sdk/test/logs/CMakeLists.txt | 5 +- sdk/test/metrics/CMakeLists.txt | 5 +- sdk/test/resource/CMakeLists.txt | 6 +- sdk/test/trace/CMakeLists.txt | 5 +- 28 files changed, 114 insertions(+), 196 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 91257ba966..1e2bfeee19 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -220,9 +220,14 @@ set(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_INCLUDEDIR}") configure_package_config_file( "${CMAKE_CURRENT_LIST_DIR}/opentelemetry-cpp-config.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake/${PROJECT_NAME}/${PROJECT_NAME}-config.cmake" - INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" - PATH_VARS OPENTELEMETRY_ABI_VERSION_NO OPENTELEMETRY_VERSION PROJECT_NAME - INCLUDE_INSTALL_DIR CMAKE_INSTALL_LIBDIR + INSTALL_DESTINATION + "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" + PATH_VARS + OPENTELEMETRY_ABI_VERSION_NO + OPENTELEMETRY_VERSION + PROJECT_NAME + INCLUDE_INSTALL_DIR + CMAKE_INSTALL_LIBDIR NO_CHECK_REQUIRED_COMPONENTS_MACRO) # Write version file for find_packages(opentelemetry-cpp CONFIG) diff --git a/api/include/opentelemetry/trace/span_id.h b/api/include/opentelemetry/trace/span_id.h index 54c42ddc0e..c8d6cdb40f 100644 --- a/api/include/opentelemetry/trace/span_id.h +++ b/api/include/opentelemetry/trace/span_id.h @@ -36,7 +36,7 @@ class SpanId final // Creates a SpanId with the given ID. explicit SpanId(nostd::span id) noexcept { memcpy(rep_, id.data(), kSize); } - explicit SpanId(const uint8_t* data) noexcept { memcpy(rep_, data, kSize); } + explicit SpanId(const uint8_t *data) noexcept { memcpy(rep_, data, kSize); } // Populates the buffer with the lowercase base16 representation of the ID. void ToLowerBase16(nostd::span buffer) const noexcept diff --git a/api/include/opentelemetry/trace/trace_id.h b/api/include/opentelemetry/trace/trace_id.h index 039c9fce8a..54a6e9123e 100644 --- a/api/include/opentelemetry/trace/trace_id.h +++ b/api/include/opentelemetry/trace/trace_id.h @@ -43,10 +43,7 @@ class TraceId final } // Creates a TraceId with the given ID. - explicit TraceId(const uint8_t* data) noexcept - { - memcpy(rep_, data, kSize); - } + explicit TraceId(const uint8_t *data) noexcept { memcpy(rep_, data, kSize); } // Populates the buffer with the lowercase base16 representation of the ID. void ToLowerBase16(nostd::span buffer) const noexcept diff --git a/api/test/context/CMakeLists.txt b/api/test/context/CMakeLists.txt index 2c9da11191..15d91c689b 100644 --- a/api/test/context/CMakeLists.txt +++ b/api/test/context/CMakeLists.txt @@ -5,8 +5,5 @@ foreach(testname context_test runtime_context_test) target_link_libraries( ${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests( - TARGET ${testname} - TEST_PREFIX context. - TEST_LIST ${testname}) + gtest_add_tests(TARGET ${testname} TEST_PREFIX context. TEST_LIST ${testname}) endforeach() diff --git a/api/test/core/CMakeLists.txt b/api/test/core/CMakeLists.txt index 0d59831bb4..79d3a1e331 100644 --- a/api/test/core/CMakeLists.txt +++ b/api/test/core/CMakeLists.txt @@ -4,7 +4,5 @@ add_executable(timestamp_test timestamp_test.cc) target_link_libraries( timestamp_test ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) -gtest_add_tests( - TARGET timestamp_test - TEST_PREFIX trace. - TEST_LIST timestamp_test) +gtest_add_tests(TARGET timestamp_test TEST_PREFIX trace. TEST_LIST + timestamp_test) diff --git a/api/test/logs/CMakeLists.txt b/api/test/logs/CMakeLists.txt index a5f9c04084..174d3d60e1 100644 --- a/api/test/logs/CMakeLists.txt +++ b/api/test/logs/CMakeLists.txt @@ -2,8 +2,6 @@ foreach(testname provider_test logger_test) add_executable(logs_api_${testname} "${testname}.cc") target_link_libraries(logs_api_${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests( - TARGET logs_api_${testname} - TEST_PREFIX logs. - TEST_LIST logs_api_${testname}) + gtest_add_tests(TARGET logs_api_${testname} TEST_PREFIX logs. TEST_LIST + logs_api_${testname}) endforeach() diff --git a/api/test/metrics/CMakeLists.txt b/api/test/metrics/CMakeLists.txt index f20a46c094..b73b772ce3 100644 --- a/api/test/metrics/CMakeLists.txt +++ b/api/test/metrics/CMakeLists.txt @@ -3,8 +3,5 @@ foreach(testname noop_instrument_test meter_provider_test noop_metrics_test) target_link_libraries( ${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests( - TARGET ${testname} - TEST_PREFIX metrics. - TEST_LIST ${testname}) + gtest_add_tests(TARGET ${testname} TEST_PREFIX metrics. TEST_LIST ${testname}) endforeach() diff --git a/api/test/nostd/CMakeLists.txt b/api/test/nostd/CMakeLists.txt index 21c2197ced..53b01d2a52 100644 --- a/api/test/nostd/CMakeLists.txt +++ b/api/test/nostd/CMakeLists.txt @@ -6,8 +6,5 @@ foreach(testname function_ref_test string_view_test unique_ptr_test target_link_libraries( ${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests( - TARGET ${testname} - TEST_PREFIX nostd. - TEST_LIST ${testname}) + gtest_add_tests(TARGET ${testname} TEST_PREFIX nostd. TEST_LIST ${testname}) endforeach() diff --git a/api/test/plugin/CMakeLists.txt b/api/test/plugin/CMakeLists.txt index 29a75b6b84..114f26ab7a 100644 --- a/api/test/plugin/CMakeLists.txt +++ b/api/test/plugin/CMakeLists.txt @@ -5,7 +5,5 @@ target_link_libraries( dynamic_load_test ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) target_link_libraries(dynamic_load_test ${CMAKE_DL_LIBS}) -gtest_add_tests( - TARGET dynamic_load_test - TEST_PREFIX plugin. - TEST_LIST dynamic_load_test) +gtest_add_tests(TARGET dynamic_load_test TEST_PREFIX plugin. TEST_LIST + dynamic_load_test) diff --git a/api/test/trace/CMakeLists.txt b/api/test/trace/CMakeLists.txt index 90f077c364..bc0f887caf 100644 --- a/api/test/trace/CMakeLists.txt +++ b/api/test/trace/CMakeLists.txt @@ -15,10 +15,8 @@ foreach( target_link_libraries( api_${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests( - TARGET api_${testname} - TEST_PREFIX trace. - TEST_LIST api_${testname}) + gtest_add_tests(TARGET api_${testname} TEST_PREFIX trace. TEST_LIST + api_${testname}) endforeach() add_executable(span_id_benchmark span_id_benchmark.cc) diff --git a/api/test/trace/propagation/CMakeLists.txt b/api/test/trace/propagation/CMakeLists.txt index 99de61f1c4..b465e2dc57 100644 --- a/api/test/trace/propagation/CMakeLists.txt +++ b/api/test/trace/propagation/CMakeLists.txt @@ -3,8 +3,5 @@ foreach(testname http_text_format_test b3_propagation_test) target_link_libraries( ${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests( - TARGET ${testname} - TEST_PREFIX trace. - TEST_LIST ${testname}) + gtest_add_tests(TARGET ${testname} TEST_PREFIX trace. TEST_LIST ${testname}) endforeach() diff --git a/exporters/elasticsearch/CMakeLists.txt b/exporters/elasticsearch/CMakeLists.txt index 3fc96fea57..1c20caf813 100644 --- a/exporters/elasticsearch/CMakeLists.txt +++ b/exporters/elasticsearch/CMakeLists.txt @@ -10,8 +10,6 @@ if(BUILD_TESTING) es_log_exporter_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_exporter_elasticsearch_logs) - gtest_add_tests( - TARGET es_log_exporter_test - TEST_PREFIX exporter. - TEST_LIST es_log_exporter_test) + gtest_add_tests(TARGET es_log_exporter_test TEST_PREFIX exporter. TEST_LIST + es_log_exporter_test) endif() # BUILD_TESTING diff --git a/exporters/etw/CMakeLists.txt b/exporters/etw/CMakeLists.txt index 4a492a5080..fc0ad0cb85 100644 --- a/exporters/etw/CMakeLists.txt +++ b/exporters/etw/CMakeLists.txt @@ -10,12 +10,8 @@ if(BUILD_TESTING) target_link_libraries(etw_tracer_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) - gtest_add_tests( - TARGET etw_provider_test - TEST_PREFIX exporter. - TEST_LIST etw_provider_test) - gtest_add_tests( - TARGET etw_tracer_test - TEST_PREFIX exporter. - TEST_LIST etw_tracer_test) + gtest_add_tests(TARGET etw_provider_test TEST_PREFIX exporter. TEST_LIST + etw_provider_test) + gtest_add_tests(TARGET etw_tracer_test TEST_PREFIX exporter. TEST_LIST + etw_tracer_test) endif() # BUILD_TESTING diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h index 753b25ed26..03fae33a78 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h @@ -225,8 +225,7 @@ class PropertyValue : public PropertyVariant case common::AttributeType::TYPE_DOUBLE: PropertyVariant::operator=(nostd::get(v)); break; - case common::AttributeType::TYPE_STRING: - { + case common::AttributeType::TYPE_STRING: { PropertyVariant::operator=(nostd::string_view(nostd::get(v)).data()); break; }; @@ -306,8 +305,7 @@ class PropertyValue : public PropertyVariant value = nostd::get(*this); break; - case common::AttributeType::TYPE_STRING: - { + case common::AttributeType::TYPE_STRING: { const std::string &str = nostd::get(*this); return nostd::string_view(str.data(), str.size()); break; @@ -325,8 +323,7 @@ class PropertyValue : public PropertyVariant break; #endif - case common::AttributeType::TYPE_SPAN_BOOL: - { + case common::AttributeType::TYPE_SPAN_BOOL: { const auto &vec = nostd::get>(*this); // FIXME: sort out how to remap from vector to span break; @@ -450,9 +447,8 @@ 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)) { diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h index 2f76ef3a5a..dd75dae471 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h @@ -134,8 +134,7 @@ class ETWProvider { #ifdef HAVE_TLD // Register with TraceLoggingDynamic facility - dynamic manifest ETW events. - case EventFormat::ETW_MANIFEST: - { + case EventFormat::ETW_MANIFEST: { tld::ProviderMetadataBuilder> providerMetaBuilder( data.providerMetaVector); @@ -162,8 +161,7 @@ class ETWProvider #ifdef HAVE_MSGPACK // Register for MsgPack payload ETW events. - case EventFormat::ETW_MSGPACK: - { + case EventFormat::ETW_MSGPACK: { REGHANDLE hProvider = 0; if (EventRegister(&data.providerGuid, NULL, NULL, &hProvider) != ERROR_SUCCESS) { @@ -214,9 +212,9 @@ class ETWProvider template unsigned long writeMsgPack(Handle &providerData, T eventData, - LPCGUID ActivityId = nullptr, + LPCGUID ActivityId = nullptr, LPCGUID RelatedActivityId = nullptr, - uint8_t Opcode = 0 /* Information */) + uint8_t Opcode = 0 /* Information */) { #ifdef HAVE_MSGPACK // Make sure you stop sending event before register unregistering providerData @@ -289,50 +287,42 @@ class ETWProvider auto &value = kv.second; switch (value.index()) { - case common::AttributeType::TYPE_BOOL: - { + case common::AttributeType::TYPE_BOOL: { UINT8 temp = static_cast(nostd::get(value)); jObj[name] = temp; break; } - case common::AttributeType::TYPE_INT: - { + case common::AttributeType::TYPE_INT: { auto temp = nostd::get(value); jObj[name] = temp; break; } - case common::AttributeType::TYPE_INT64: - { + case common::AttributeType::TYPE_INT64: { auto temp = nostd::get(value); jObj[name] = temp; break; } - case common::AttributeType::TYPE_UINT: - { + case common::AttributeType::TYPE_UINT: { auto temp = nostd::get(value); jObj[name] = temp; break; } - case common::AttributeType::TYPE_UINT64: - { + case common::AttributeType::TYPE_UINT64: { auto temp = nostd::get(value); jObj[name] = temp; break; } - case common::AttributeType::TYPE_DOUBLE: - { + case common::AttributeType::TYPE_DOUBLE: { auto temp = nostd::get(value); jObj[name] = temp; break; } - case common::AttributeType::TYPE_STRING: - { + case common::AttributeType::TYPE_STRING: { jObj[name] = nostd::get(value); break; } # ifdef HAVE_CSTRING_TYPE - case common::AttributeType::TYPE_CSTRING: - { + case common::AttributeType::TYPE_CSTRING: { auto temp = nostd::get(value); jObj[name] = temp; break; @@ -340,8 +330,7 @@ class ETWProvider # endif # if HAVE_TYPE_GUID // TODO: consider adding UUID/GUID to spec - case common::AttributeType::TYPE_GUID: - { + case common::AttributeType::TYPE_GUID: { auto temp = nostd::get(value); // TODO: add transform from GUID type to string? jObj[name] = temp; @@ -417,7 +406,8 @@ class ETWProvider if ((ActivityId != nullptr) || (RelatedActivityId != nullptr)) { - EventWriteTransfer(providerData.providerHandle, &evtDescriptor, ActivityId, RelatedActivityId, 1, evtData); + EventWriteTransfer(providerData.providerHandle, &evtDescriptor, ActivityId, RelatedActivityId, + 1, evtData); } else { @@ -461,7 +451,7 @@ class ETWProvider T eventData, LPCGUID ActivityId = nullptr, LPCGUID RelatedActivityId = nullptr, - uint8_t Opcode = 0 /* Information */ ) + uint8_t Opcode = 0 /* Information */) { #ifdef HAVE_TLD // Make sure you stop sending event before register unregistering providerData @@ -508,57 +498,49 @@ class ETWProvider auto &value = kv.second; switch (value.index()) { - case common::AttributeType::TYPE_BOOL: - { + case common::AttributeType::TYPE_BOOL: { builder.AddField(name, tld::TypeBool8); UINT8 temp = static_cast(nostd::get(value)); dbuilder.AddByte(temp); break; } - case common::AttributeType::TYPE_INT: - { + case common::AttributeType::TYPE_INT: { builder.AddField(name, tld::TypeInt32); auto temp = nostd::get(value); dbuilder.AddValue(temp); break; } - case common::AttributeType::TYPE_INT64: - { + case common::AttributeType::TYPE_INT64: { builder.AddField(name, tld::TypeInt64); auto temp = nostd::get(value); dbuilder.AddValue(temp); break; } - case common::AttributeType::TYPE_UINT: - { + case common::AttributeType::TYPE_UINT: { builder.AddField(name, tld::TypeUInt32); auto temp = nostd::get(value); dbuilder.AddValue(temp); break; } - case common::AttributeType::TYPE_UINT64: - { + case common::AttributeType::TYPE_UINT64: { builder.AddField(name, tld::TypeUInt64); auto temp = nostd::get(value); dbuilder.AddValue(temp); break; } - case common::AttributeType::TYPE_DOUBLE: - { + case common::AttributeType::TYPE_DOUBLE: { builder.AddField(name, tld::TypeDouble); auto temp = nostd::get(value); dbuilder.AddValue(temp); break; } - case common::AttributeType::TYPE_STRING: - { + case common::AttributeType::TYPE_STRING: { builder.AddField(name, tld::TypeUtf8String); dbuilder.AddString(nostd::get(value).data()); break; } # ifdef HAVE_CSTRING_TYPE - case common::AttributeType::TYPE_CSTRING: - { + case common::AttributeType::TYPE_CSTRING: { builder.AddField(name, tld::TypeUtf8String); auto temp = nostd::get(value); dbuilder.AddString(temp); @@ -567,8 +549,7 @@ class ETWProvider # endif # if HAVE_TYPE_GUID // TODO: consider adding UUID/GUID to spec - case common::AttributeType::TYPE_GUID: - { + case common::AttributeType::TYPE_GUID: { builder.AddField(name.c_str(), TypeGuid); auto temp = nostd::get(value); dbuilder.AddBytes(&temp, sizeof(GUID)); @@ -647,8 +628,8 @@ class ETWProvider template unsigned long write(Handle &providerData, T eventData, - LPCGUID ActivityId = nullptr, - LPCGUID RelatedActivityId = nullptr, + LPCGUID ActivityId = nullptr, + LPCGUID RelatedActivityId = nullptr, uint8_t Opcode = 0, /* Information */ ETWProvider::EventFormat format = ETWProvider::EventFormat::ETW_MANIFEST) { diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_recordable.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_recordable.h index f6bb381ea1..681015719e 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_recordable.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_recordable.h @@ -97,7 +97,7 @@ class ETWTraceRecordable final : public sdk::trace::Recordable * Get the status for this span * @return the status for this span */ - trace::CanonicalCode GetStatus() const noexcept { return status_code_; } + trace::StatusCode GetStatus() const noexcept { return status_code_; } /** * Get the status description for this span @@ -121,8 +121,8 @@ class ETWTraceRecordable final : public sdk::trace::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(); } @@ -160,7 +160,7 @@ class ETWTraceRecordable final : public sdk::trace::Recordable * @param description * @return */ - void SetStatus(trace::CanonicalCode code, nostd::string_view description) noexcept override + void SetStatus(trace::StatusCode code, nostd::string_view description) noexcept override { status_code_ = code; status_desc_ = std::string(description); @@ -216,7 +216,7 @@ class ETWTraceRecordable final : public sdk::trace::Recordable core::SystemTimestamp start_time_; std::chrono::nanoseconds duration_{0}; std::string name_; - trace::CanonicalCode status_code_{trace::CanonicalCode::OK}; + trace::StatusCode status_code_ { trace::StatusCode::kOk }; std::string status_desc_; sdk::common::AttributeMap attribute_map_; trace::SpanKind span_kind_{trace::SpanKind::kInternal}; diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h index 3d062f76f8..bd25c77ed7 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h @@ -13,6 +13,7 @@ // limitations under the License. #pragma once +#include #include #include @@ -172,14 +173,16 @@ class Tracer : public trace::Tracer * @param span * @param */ - virtual void EndSpan(const Span &span, const trace::Span *parent = nullptr, const trace::EndSpanOptions & = {}) + virtual void EndSpan(const Span &span, + const trace::Span *parent = nullptr, + const trace::EndSpanOptions & = {}) { Properties evt; - const trace::Span& spanBase = reinterpret_cast(span); + const trace::Span &spanBase = reinterpret_cast(span); - auto ctx = spanBase.GetContext(); - evt[ETW_FIELD_NAME] = GetName(span); + auto ctx = spanBase.GetContext(); + evt[ETW_FIELD_NAME] = GetName(span); // We use ActivityId instead of ETW_FIELD_SPAN_ID below // evt[ETW_FIELD_SPAN_ID] = ToLowerBase16(ctx.span_id()); @@ -196,13 +199,9 @@ class Tracer : public trace::Tracer auto spanId = ToLowerBase16(spanBase.GetContext().span_id()); scopes_.erase(spanId); } - }; - const trace::TraceId& trace_id() - { - return traceId_; - }; + const trace::TraceId &trace_id() { return traceId_; }; friend class Span; @@ -224,18 +223,18 @@ class Tracer : public trace::Tracer provId(providerId.data(), providerId.size()), encoding(encoding) { - GUID trace_id; - // Generate random GUID - CoCreateGuid(&trace_id); - const auto *traceIdBytes = reinterpret_cast(std::addressof(trace_id)); - // Populate TraceId with that GUID - traceId_ = trace::TraceId(traceIdBytes); + GUID trace_id; + // Generate random GUID + CoCreateGuid(&trace_id); + const auto *traceIdBytes = reinterpret_cast(std::addressof(trace_id)); + // Populate TraceId with that GUID + traceId_ = trace::TraceId(traceIdBytes); #if defined(HAVE_MSGPACK) && !defined(HAVE_TLD) /* Fallback to MsgPack encoding if TraceLoggingDynamic feature gate is off */ this->encoding = ETWProvider::EventFormat::ETW_MSGPACK; #endif - provHandle = etwProvider().open(provId, encoding); + provHandle = etwProvider().open(provId, encoding); }; /** @@ -252,7 +251,7 @@ class Tracer : public trace::Tracer const trace::SpanContextKeyValueIterable &links, const trace::StartSpanOptions &options = {}) noexcept override { - const auto parent = GetCurrentSpan(); + const auto parent = GetCurrentSpan(); LPCGUID RelatedActivityIdPtr = nullptr; GUID RelatedActivityId; // Propagate parent activity only if parent span (current span) is valid @@ -269,7 +268,7 @@ class Tracer : public trace::Tracer Properties evt = attributes; // Decorate with additional standard fields - std::string eventName = name.data(); + std::string eventName = name.data(); evt[ETW_FIELD_NAME] = eventName.data(); evt[ETW_FIELD_TRACE_ID] = ToLowerBase16(spanContext.trace_id()); @@ -344,7 +343,7 @@ class Tracer : public trace::Tracer // and should be configurable for traces that deduct their nested // structure based off built-in `ActivityId` and `RelatedActivityId` // evt[ETW_FIELD_TRACE_ID] = ToLowerBase16(spanContext.trace_id()); - evt[ETW_FIELD_SPAN_ID] = ToLowerBase16(spanContext.span_id()); + evt[ETW_FIELD_SPAN_ID] = ToLowerBase16(spanContext.span_id()); auto RelatedActivityId = ToActivityId(&span); @@ -438,7 +437,6 @@ class Span : public trace::Span } public: - /** * @brief Get Span Name. * @return Span Name. @@ -453,7 +451,10 @@ class Span : public trace::Span * @param parent Parent Span (optional) * @return */ - Span(Tracer &owner, nostd::string_view name, const trace::StartSpanOptions &options, Span* parent = nullptr) noexcept + Span(Tracer &owner, + nostd::string_view name, + const trace::StartSpanOptions &options, + Span *parent = nullptr) noexcept : trace::Span(), owner_(owner), parent_(parent), context_(CreateContext()) { name_ = name; @@ -503,7 +504,7 @@ class Span : public trace::Span * @param description Span description. * @return */ - void SetStatus(trace::CanonicalCode code, nostd::string_view description) noexcept override + void SetStatus(trace::StatusCode code, nostd::string_view description) noexcept override { // TODO: not implemented UNREFERENCED_PARAMETER(code); @@ -557,10 +558,7 @@ class Span : public trace::Span * @brief Obtain SpanContext * @return */ - trace::SpanContext GetContext() const noexcept override - { - return context_; - } + trace::SpanContext GetContext() const noexcept override { return context_; } /** * @brief Check if Span is recording data. diff --git a/exporters/memory/CMakeLists.txt b/exporters/memory/CMakeLists.txt index 870e932730..c35c9c5697 100644 --- a/exporters/memory/CMakeLists.txt +++ b/exporters/memory/CMakeLists.txt @@ -36,12 +36,8 @@ if(BUILD_TESTING) in_memory_span_exporter_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_exporter_in_memory) - gtest_add_tests( - TARGET in_memory_span_data_test - TEST_PREFIX exporter. - TEST_LIST in_memory_span_data_test) - gtest_add_tests( - TARGET in_memory_span_exporter_test - TEST_PREFIX exporter. - TEST_LIST in_memory_span_exporter_test) + gtest_add_tests(TARGET in_memory_span_data_test TEST_PREFIX exporter. + TEST_LIST in_memory_span_data_test) + gtest_add_tests(TARGET in_memory_span_exporter_test TEST_PREFIX exporter. + TEST_LIST in_memory_span_exporter_test) endif() diff --git a/exporters/ostream/CMakeLists.txt b/exporters/ostream/CMakeLists.txt index b9797b2974..838b0cd265 100644 --- a/exporters/ostream/CMakeLists.txt +++ b/exporters/ostream/CMakeLists.txt @@ -61,19 +61,13 @@ if(BUILD_TESTING) target_link_libraries(ostream_log_test ${GTEST_BOTH_LIBRARIES} opentelemetry_exporter_ostream_logs) - gtest_add_tests( - TARGET ostream_log_test - TEST_PREFIX exporter. - TEST_LIST ostream_log_test) - - gtest_add_tests( - TARGET ostream_metrics_test - TEST_PREFIX exporter. - TEST_LIST ostream_metrics_test) - - gtest_add_tests( - TARGET ostream_span_test - TEST_PREFIX exporter. - TEST_LIST ostream_span_test) + gtest_add_tests(TARGET ostream_log_test TEST_PREFIX exporter. TEST_LIST + ostream_log_test) + + gtest_add_tests(TARGET ostream_metrics_test TEST_PREFIX exporter. TEST_LIST + ostream_metrics_test) + + gtest_add_tests(TARGET ostream_span_test TEST_PREFIX exporter. TEST_LIST + ostream_span_test) endif() # BUILD_TESTING diff --git a/exporters/otlp/CMakeLists.txt b/exporters/otlp/CMakeLists.txt index e4b2999f6d..039a9066b6 100644 --- a/exporters/otlp/CMakeLists.txt +++ b/exporters/otlp/CMakeLists.txt @@ -29,8 +29,6 @@ if(BUILD_TESTING) target_link_libraries( recordable_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_exporter_otprotocol protobuf::libprotobuf gRPC::grpc++) - gtest_add_tests( - TARGET recordable_test - TEST_PREFIX exporter. - TEST_LIST recordable_test) + gtest_add_tests(TARGET recordable_test TEST_PREFIX exporter. TEST_LIST + recordable_test) endif() # BUILD_TESTING diff --git a/exporters/prometheus/test/CMakeLists.txt b/exporters/prometheus/test/CMakeLists.txt index 4168c6d3e4..c57f900347 100644 --- a/exporters/prometheus/test/CMakeLists.txt +++ b/exporters/prometheus/test/CMakeLists.txt @@ -3,8 +3,6 @@ foreach(testname prometheus_collector_test prometheus_exporter_utils_test) target_link_libraries( ${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} prometheus_exporter prometheus-cpp::pull) - gtest_add_tests( - TARGET ${testname} - TEST_PREFIX exporter. - TEST_LIST ${testname}) + gtest_add_tests(TARGET ${testname} TEST_PREFIX exporter. TEST_LIST + ${testname}) endforeach() diff --git a/ext/test/http/CMakeLists.txt b/ext/test/http/CMakeLists.txt index 221f901b1d..cfd3e88835 100644 --- a/ext/test/http/CMakeLists.txt +++ b/ext/test/http/CMakeLists.txt @@ -12,8 +12,6 @@ if(CURL_FOUND) include_directories(${CURL_INCLUDE_DIRS}) target_link_libraries(${FILENAME} ${CURL_LIBRARIES} http_client_curl) endif() - gtest_add_tests( - TARGET ${FILENAME} - TEST_PREFIX ext.http.curl. - TEST_LIST ${FILENAME}) + gtest_add_tests(TARGET ${FILENAME} TEST_PREFIX ext.http.curl. TEST_LIST + ${FILENAME}) endif() diff --git a/ext/test/zpages/CMakeLists.txt b/ext/test/zpages/CMakeLists.txt index c7d0d837c8..34c3637316 100644 --- a/ext/test/zpages/CMakeLists.txt +++ b/ext/test/zpages/CMakeLists.txt @@ -4,8 +4,5 @@ foreach(testname tracez_processor_test tracez_data_aggregator_test target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_zpages) - gtest_add_tests( - TARGET ${testname} - TEST_PREFIX ext. - TEST_LIST ${testname}) + gtest_add_tests(TARGET ${testname} TEST_PREFIX ext. TEST_LIST ${testname}) endforeach() diff --git a/sdk/test/common/CMakeLists.txt b/sdk/test/common/CMakeLists.txt index 647cd42ea1..478a242bd7 100644 --- a/sdk/test/common/CMakeLists.txt +++ b/sdk/test/common/CMakeLists.txt @@ -7,10 +7,7 @@ foreach(testname ${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${CORE_RUNTIME_LIBS} opentelemetry_common opentelemetry_trace) - gtest_add_tests( - TARGET ${testname} - TEST_PREFIX trace. - TEST_LIST ${testname}) + gtest_add_tests(TARGET ${testname} TEST_PREFIX trace. TEST_LIST ${testname}) endforeach() add_executable(random_fork_test random_fork_test.cc) diff --git a/sdk/test/logs/CMakeLists.txt b/sdk/test/logs/CMakeLists.txt index 84b865d226..60e02b8b50 100644 --- a/sdk/test/logs/CMakeLists.txt +++ b/sdk/test/logs/CMakeLists.txt @@ -3,8 +3,5 @@ foreach(testname logger_provider_sdk_test logger_sdk_test log_record_test add_executable(${testname} "${testname}.cc") target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_logs) - gtest_add_tests( - TARGET ${testname} - TEST_PREFIX logs. - TEST_LIST ${testname}) + gtest_add_tests(TARGET ${testname} TEST_PREFIX logs. TEST_LIST ${testname}) endforeach() diff --git a/sdk/test/metrics/CMakeLists.txt b/sdk/test/metrics/CMakeLists.txt index a33ccbf64b..e518dbdd1e 100644 --- a/sdk/test/metrics/CMakeLists.txt +++ b/sdk/test/metrics/CMakeLists.txt @@ -13,8 +13,5 @@ foreach( add_executable(${testname} "${testname}.cc") target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_metrics) - gtest_add_tests( - TARGET ${testname} - TEST_PREFIX metrics. - TEST_LIST ${testname}) + gtest_add_tests(TARGET ${testname} TEST_PREFIX metrics. TEST_LIST ${testname}) endforeach() diff --git a/sdk/test/resource/CMakeLists.txt b/sdk/test/resource/CMakeLists.txt index 514b98680b..ef00bb74a7 100644 --- a/sdk/test/resource/CMakeLists.txt +++ b/sdk/test/resource/CMakeLists.txt @@ -2,8 +2,6 @@ foreach(testname resource_test) add_executable(${testname} "${testname}.cc") target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_resources) - gtest_add_tests( - TARGET ${testname} - TEST_PREFIX resources. - TEST_LIST ${testname}) + gtest_add_tests(TARGET ${testname} TEST_PREFIX resources. TEST_LIST + ${testname}) endforeach() diff --git a/sdk/test/trace/CMakeLists.txt b/sdk/test/trace/CMakeLists.txt index 8a39c10a29..ab5251dde2 100644 --- a/sdk/test/trace/CMakeLists.txt +++ b/sdk/test/trace/CMakeLists.txt @@ -19,10 +19,7 @@ foreach( opentelemetry_trace opentelemetry_resources opentelemetry_exporter_in_memory) - gtest_add_tests( - TARGET ${testname} - TEST_PREFIX trace. - TEST_LIST ${testname}) + gtest_add_tests(TARGET ${testname} TEST_PREFIX trace. TEST_LIST ${testname}) endforeach() add_executable(sampler_benchmark sampler_benchmark.cc) From 6d70f6dfdb5dc4ffee296e2bbfd7deb43fc5fb61 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Wed, 24 Feb 2021 21:04:13 -0800 Subject: [PATCH 33/76] Build Release without debug info --- CMakeSettings.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeSettings.json b/CMakeSettings.json index f374dbeb87..4890a66411 100644 --- a/CMakeSettings.json +++ b/CMakeSettings.json @@ -28,7 +28,7 @@ { "name": "nostd-x64-Release", "generator": "Ninja", - "configurationType": "RelWithDebInfo", + "configurationType": "Release", "inheritEnvironments": [ "msvc_x64_x64" ], @@ -89,7 +89,7 @@ { "name": "stdlib-x64-Release", "generator": "Ninja", - "configurationType": "RelWithDebInfo", + "configurationType": "Release", "inheritEnvironments": [ "msvc_x64_x64" ], From 9475c164a811f1fcc9de071b8f48f37f5e5b5dd1 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Thu, 11 Mar 2021 13:35:18 -0800 Subject: [PATCH 34/76] Rename test provider to OpenTelemetry-ETW-Provider --- exporters/etw/test/etw_provider_test.cc | 8 ++++---- exporters/etw/test/etw_tracer_test.cc | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/exporters/etw/test/etw_provider_test.cc b/exporters/etw/test/etw_provider_test.cc index f967428329..24faf8e51e 100644 --- a/exporters/etw/test/etw_provider_test.cc +++ b/exporters/etw/test/etw_provider_test.cc @@ -23,7 +23,7 @@ using namespace OPENTELEMETRY_NAMESPACE; TEST(ETWProvider, ProviderIsRegisteredSuccessfully) { - std::string providerName = "OpenTelemetry"; + std::string providerName = "OpenTelemetry-ETW-Provider"; static ETWProvider etw; auto handle = etw.open(providerName.c_str()); @@ -33,7 +33,7 @@ TEST(ETWProvider, ProviderIsRegisteredSuccessfully) TEST(ETWProvider, ProviderIsNotRegisteredSuccessfully) { - std::string providerName = "Telemetry"; + std::string providerName = "OpenTelemetry-ETW-Provider-NULL"; static ETWProvider etw; bool registered = etw.is_registered(providerName); @@ -42,7 +42,7 @@ TEST(ETWProvider, ProviderIsNotRegisteredSuccessfully) TEST(ETWProvider, CheckOpenGUIDDataSuccessfully) { - std::string providerName = "OpenTelemetry"; + std::string providerName = "OpenTelemetry-ETW-Provider"; // get GUID from the handle returned static ETWProvider etw; @@ -61,7 +61,7 @@ TEST(ETWProvider, CheckOpenGUIDDataSuccessfully) TEST(ETWProvider, CheckCloseSuccess) { - std::string providerName = "OpenTelemetry"; + std::string providerName = "OpenTelemetry-ETW-Provider"; static ETWProvider etw; auto handle = etw.open(providerName.c_str()); diff --git a/exporters/etw/test/etw_tracer_test.cc b/exporters/etw/test/etw_tracer_test.cc index 6fc9c6163a..13263ae5f7 100644 --- a/exporters/etw/test/etw_tracer_test.cc +++ b/exporters/etw/test/etw_tracer_test.cc @@ -56,7 +56,7 @@ TEST(ETWTracer, TracerCheck) // Windows Defender Firewall API - GP {0EFF663F-8B6E-4E6D-8182-087A8EAA29CB} // Windows Defender Firewall Driver {D5E09122-D0B2-4235-ADC1-C89FAAAF1069} - std::string providerName = "OpenTelemetry"; // supply unique instrumentation name here + std::string providerName = "OpenTelemetry-ETW-Provider"; // supply unique instrumentation name here exporter::ETW::TracerProvider tp; // TODO: this code should fallback to MsgPack if TLD is not available From e159b2c48b3c8239b4ff5ae6c9512b56b84137b7 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Thu, 11 Mar 2021 15:45:31 -0800 Subject: [PATCH 35/76] Reformat code using latest formatter --- CMakeLists.txt | 11 +++------- api/test/context/CMakeLists.txt | 5 ++++- api/test/core/CMakeLists.txt | 6 +++-- api/test/logs/CMakeLists.txt | 6 +++-- api/test/metrics/CMakeLists.txt | 5 ++++- api/test/nostd/CMakeLists.txt | 5 ++++- api/test/plugin/CMakeLists.txt | 6 +++-- api/test/trace/CMakeLists.txt | 6 +++-- api/test/trace/propagation/CMakeLists.txt | 5 ++++- exporters/elasticsearch/CMakeLists.txt | 6 +++-- exporters/etw/CMakeLists.txt | 12 ++++++---- .../exporters/etw/etw_recordable.h | 2 +- .../opentelemetry/exporters/etw/etw_tracer.h | 2 +- exporters/memory/CMakeLists.txt | 12 ++++++---- exporters/ostream/CMakeLists.txt | 22 ++++++++++++------- exporters/otlp/CMakeLists.txt | 6 +++-- exporters/prometheus/test/CMakeLists.txt | 6 +++-- ext/test/http/CMakeLists.txt | 6 +++-- ext/test/zpages/CMakeLists.txt | 5 ++++- sdk/test/common/CMakeLists.txt | 5 ++++- sdk/test/logs/CMakeLists.txt | 5 ++++- sdk/test/metrics/CMakeLists.txt | 5 ++++- sdk/test/resource/CMakeLists.txt | 6 +++-- sdk/test/trace/CMakeLists.txt | 5 ++++- 24 files changed, 107 insertions(+), 53 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3435e35b09..2f5968b3ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -221,14 +221,9 @@ set(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_INCLUDEDIR}") configure_package_config_file( "${CMAKE_CURRENT_LIST_DIR}/opentelemetry-cpp-config.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake/${PROJECT_NAME}/${PROJECT_NAME}-config.cmake" - INSTALL_DESTINATION - "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" - PATH_VARS - OPENTELEMETRY_ABI_VERSION_NO - OPENTELEMETRY_VERSION - PROJECT_NAME - INCLUDE_INSTALL_DIR - CMAKE_INSTALL_LIBDIR + INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" + PATH_VARS OPENTELEMETRY_ABI_VERSION_NO OPENTELEMETRY_VERSION PROJECT_NAME + INCLUDE_INSTALL_DIR CMAKE_INSTALL_LIBDIR NO_CHECK_REQUIRED_COMPONENTS_MACRO) # Write version file for find_packages(opentelemetry-cpp CONFIG) diff --git a/api/test/context/CMakeLists.txt b/api/test/context/CMakeLists.txt index 15d91c689b..2c9da11191 100644 --- a/api/test/context/CMakeLists.txt +++ b/api/test/context/CMakeLists.txt @@ -5,5 +5,8 @@ foreach(testname context_test runtime_context_test) target_link_libraries( ${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests(TARGET ${testname} TEST_PREFIX context. TEST_LIST ${testname}) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX context. + TEST_LIST ${testname}) endforeach() diff --git a/api/test/core/CMakeLists.txt b/api/test/core/CMakeLists.txt index 79d3a1e331..0d59831bb4 100644 --- a/api/test/core/CMakeLists.txt +++ b/api/test/core/CMakeLists.txt @@ -4,5 +4,7 @@ add_executable(timestamp_test timestamp_test.cc) target_link_libraries( timestamp_test ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) -gtest_add_tests(TARGET timestamp_test TEST_PREFIX trace. TEST_LIST - timestamp_test) +gtest_add_tests( + TARGET timestamp_test + TEST_PREFIX trace. + TEST_LIST timestamp_test) diff --git a/api/test/logs/CMakeLists.txt b/api/test/logs/CMakeLists.txt index 174d3d60e1..a5f9c04084 100644 --- a/api/test/logs/CMakeLists.txt +++ b/api/test/logs/CMakeLists.txt @@ -2,6 +2,8 @@ foreach(testname provider_test logger_test) add_executable(logs_api_${testname} "${testname}.cc") target_link_libraries(logs_api_${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests(TARGET logs_api_${testname} TEST_PREFIX logs. TEST_LIST - logs_api_${testname}) + gtest_add_tests( + TARGET logs_api_${testname} + TEST_PREFIX logs. + TEST_LIST logs_api_${testname}) endforeach() diff --git a/api/test/metrics/CMakeLists.txt b/api/test/metrics/CMakeLists.txt index b73b772ce3..f20a46c094 100644 --- a/api/test/metrics/CMakeLists.txt +++ b/api/test/metrics/CMakeLists.txt @@ -3,5 +3,8 @@ foreach(testname noop_instrument_test meter_provider_test noop_metrics_test) target_link_libraries( ${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests(TARGET ${testname} TEST_PREFIX metrics. TEST_LIST ${testname}) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX metrics. + TEST_LIST ${testname}) endforeach() diff --git a/api/test/nostd/CMakeLists.txt b/api/test/nostd/CMakeLists.txt index 53b01d2a52..21c2197ced 100644 --- a/api/test/nostd/CMakeLists.txt +++ b/api/test/nostd/CMakeLists.txt @@ -6,5 +6,8 @@ foreach(testname function_ref_test string_view_test unique_ptr_test target_link_libraries( ${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests(TARGET ${testname} TEST_PREFIX nostd. TEST_LIST ${testname}) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX nostd. + TEST_LIST ${testname}) endforeach() diff --git a/api/test/plugin/CMakeLists.txt b/api/test/plugin/CMakeLists.txt index 114f26ab7a..29a75b6b84 100644 --- a/api/test/plugin/CMakeLists.txt +++ b/api/test/plugin/CMakeLists.txt @@ -5,5 +5,7 @@ target_link_libraries( dynamic_load_test ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) target_link_libraries(dynamic_load_test ${CMAKE_DL_LIBS}) -gtest_add_tests(TARGET dynamic_load_test TEST_PREFIX plugin. TEST_LIST - dynamic_load_test) +gtest_add_tests( + TARGET dynamic_load_test + TEST_PREFIX plugin. + TEST_LIST dynamic_load_test) diff --git a/api/test/trace/CMakeLists.txt b/api/test/trace/CMakeLists.txt index fe6b3b3699..bd587ad893 100644 --- a/api/test/trace/CMakeLists.txt +++ b/api/test/trace/CMakeLists.txt @@ -16,8 +16,10 @@ foreach( target_link_libraries( api_${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests(TARGET api_${testname} TEST_PREFIX trace. TEST_LIST - api_${testname}) + gtest_add_tests( + TARGET api_${testname} + TEST_PREFIX trace. + TEST_LIST api_${testname}) endforeach() add_executable(span_id_benchmark span_id_benchmark.cc) diff --git a/api/test/trace/propagation/CMakeLists.txt b/api/test/trace/propagation/CMakeLists.txt index ec7147e53d..6a666fcaec 100644 --- a/api/test/trace/propagation/CMakeLists.txt +++ b/api/test/trace/propagation/CMakeLists.txt @@ -4,5 +4,8 @@ foreach(testname http_text_format_test b3_propagation_test target_link_libraries( ${testname} ${GTEST_BOTH_LIBRARIES} ${CORE_RUNTIME_LIBS} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_api) - gtest_add_tests(TARGET ${testname} TEST_PREFIX trace. TEST_LIST ${testname}) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX trace. + TEST_LIST ${testname}) endforeach() diff --git a/exporters/elasticsearch/CMakeLists.txt b/exporters/elasticsearch/CMakeLists.txt index 1c20caf813..3fc96fea57 100644 --- a/exporters/elasticsearch/CMakeLists.txt +++ b/exporters/elasticsearch/CMakeLists.txt @@ -10,6 +10,8 @@ if(BUILD_TESTING) es_log_exporter_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_exporter_elasticsearch_logs) - gtest_add_tests(TARGET es_log_exporter_test TEST_PREFIX exporter. TEST_LIST - es_log_exporter_test) + gtest_add_tests( + TARGET es_log_exporter_test + TEST_PREFIX exporter. + TEST_LIST es_log_exporter_test) endif() # BUILD_TESTING diff --git a/exporters/etw/CMakeLists.txt b/exporters/etw/CMakeLists.txt index 8e7fe36ce8..63b6205fbe 100644 --- a/exporters/etw/CMakeLists.txt +++ b/exporters/etw/CMakeLists.txt @@ -11,8 +11,12 @@ if(BUILD_TESTING) target_link_libraries(etw_tracer_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) - gtest_add_tests(TARGET etw_provider_test TEST_PREFIX exporter. TEST_LIST - etw_provider_test) - gtest_add_tests(TARGET etw_tracer_test TEST_PREFIX exporter. TEST_LIST - etw_tracer_test) + gtest_add_tests( + TARGET etw_provider_test + TEST_PREFIX exporter. + TEST_LIST etw_provider_test) + gtest_add_tests( + TARGET etw_tracer_test + TEST_PREFIX exporter. + TEST_LIST etw_tracer_test) endif() # BUILD_TESTING diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_recordable.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_recordable.h index 681015719e..2b1d473a47 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_recordable.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_recordable.h @@ -216,7 +216,7 @@ class ETWTraceRecordable final : public sdk::trace::Recordable core::SystemTimestamp start_time_; std::chrono::nanoseconds duration_{0}; std::string name_; - trace::StatusCode status_code_ { trace::StatusCode::kOk }; + trace::StatusCode status_code_{trace::StatusCode::kOk}; std::string status_desc_; sdk::common::AttributeMap attribute_map_; trace::SpanKind span_kind_{trace::SpanKind::kInternal}; diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h index bd25c77ed7..89be41234a 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h @@ -13,8 +13,8 @@ // limitations under the License. #pragma once -#include #include +#include #include #include diff --git a/exporters/memory/CMakeLists.txt b/exporters/memory/CMakeLists.txt index c35c9c5697..870e932730 100644 --- a/exporters/memory/CMakeLists.txt +++ b/exporters/memory/CMakeLists.txt @@ -36,8 +36,12 @@ if(BUILD_TESTING) in_memory_span_exporter_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_exporter_in_memory) - gtest_add_tests(TARGET in_memory_span_data_test TEST_PREFIX exporter. - TEST_LIST in_memory_span_data_test) - gtest_add_tests(TARGET in_memory_span_exporter_test TEST_PREFIX exporter. - TEST_LIST in_memory_span_exporter_test) + gtest_add_tests( + TARGET in_memory_span_data_test + TEST_PREFIX exporter. + TEST_LIST in_memory_span_data_test) + gtest_add_tests( + TARGET in_memory_span_exporter_test + TEST_PREFIX exporter. + TEST_LIST in_memory_span_exporter_test) endif() diff --git a/exporters/ostream/CMakeLists.txt b/exporters/ostream/CMakeLists.txt index 838b0cd265..b9797b2974 100644 --- a/exporters/ostream/CMakeLists.txt +++ b/exporters/ostream/CMakeLists.txt @@ -61,13 +61,19 @@ if(BUILD_TESTING) target_link_libraries(ostream_log_test ${GTEST_BOTH_LIBRARIES} opentelemetry_exporter_ostream_logs) - gtest_add_tests(TARGET ostream_log_test TEST_PREFIX exporter. TEST_LIST - ostream_log_test) - - gtest_add_tests(TARGET ostream_metrics_test TEST_PREFIX exporter. TEST_LIST - ostream_metrics_test) - - gtest_add_tests(TARGET ostream_span_test TEST_PREFIX exporter. TEST_LIST - ostream_span_test) + gtest_add_tests( + TARGET ostream_log_test + TEST_PREFIX exporter. + TEST_LIST ostream_log_test) + + gtest_add_tests( + TARGET ostream_metrics_test + TEST_PREFIX exporter. + TEST_LIST ostream_metrics_test) + + gtest_add_tests( + TARGET ostream_span_test + TEST_PREFIX exporter. + TEST_LIST ostream_span_test) endif() # BUILD_TESTING diff --git a/exporters/otlp/CMakeLists.txt b/exporters/otlp/CMakeLists.txt index 039a9066b6..e4b2999f6d 100644 --- a/exporters/otlp/CMakeLists.txt +++ b/exporters/otlp/CMakeLists.txt @@ -29,6 +29,8 @@ if(BUILD_TESTING) target_link_libraries( recordable_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_exporter_otprotocol protobuf::libprotobuf gRPC::grpc++) - gtest_add_tests(TARGET recordable_test TEST_PREFIX exporter. TEST_LIST - recordable_test) + gtest_add_tests( + TARGET recordable_test + TEST_PREFIX exporter. + TEST_LIST recordable_test) endif() # BUILD_TESTING diff --git a/exporters/prometheus/test/CMakeLists.txt b/exporters/prometheus/test/CMakeLists.txt index c57f900347..4168c6d3e4 100644 --- a/exporters/prometheus/test/CMakeLists.txt +++ b/exporters/prometheus/test/CMakeLists.txt @@ -3,6 +3,8 @@ foreach(testname prometheus_collector_test prometheus_exporter_utils_test) target_link_libraries( ${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} prometheus_exporter prometheus-cpp::pull) - gtest_add_tests(TARGET ${testname} TEST_PREFIX exporter. TEST_LIST - ${testname}) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX exporter. + TEST_LIST ${testname}) endforeach() diff --git a/ext/test/http/CMakeLists.txt b/ext/test/http/CMakeLists.txt index cd0388d74b..13b7c8206e 100644 --- a/ext/test/http/CMakeLists.txt +++ b/ext/test/http/CMakeLists.txt @@ -12,8 +12,10 @@ if(CURL_FOUND) include_directories(${CURL_INCLUDE_DIRS}) target_link_libraries(${FILENAME} ${CURL_LIBRARIES} http_client_curl) endif() - gtest_add_tests(TARGET ${FILENAME} TEST_PREFIX ext.http.curl. TEST_LIST - ${FILENAME}) + gtest_add_tests( + TARGET ${FILENAME} + TEST_PREFIX ext.http.curl. + TEST_LIST ${FILENAME}) endif() set(URL_PARSER_FILENAME url_parser_test) add_executable(${URL_PARSER_FILENAME} ${URL_PARSER_FILENAME}.cc) diff --git a/ext/test/zpages/CMakeLists.txt b/ext/test/zpages/CMakeLists.txt index 34c3637316..c7d0d837c8 100644 --- a/ext/test/zpages/CMakeLists.txt +++ b/ext/test/zpages/CMakeLists.txt @@ -4,5 +4,8 @@ foreach(testname tracez_processor_test tracez_data_aggregator_test target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_zpages) - gtest_add_tests(TARGET ${testname} TEST_PREFIX ext. TEST_LIST ${testname}) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX ext. + TEST_LIST ${testname}) endforeach() diff --git a/sdk/test/common/CMakeLists.txt b/sdk/test/common/CMakeLists.txt index 478a242bd7..647cd42ea1 100644 --- a/sdk/test/common/CMakeLists.txt +++ b/sdk/test/common/CMakeLists.txt @@ -7,7 +7,10 @@ foreach(testname ${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${CORE_RUNTIME_LIBS} opentelemetry_common opentelemetry_trace) - gtest_add_tests(TARGET ${testname} TEST_PREFIX trace. TEST_LIST ${testname}) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX trace. + TEST_LIST ${testname}) endforeach() add_executable(random_fork_test random_fork_test.cc) diff --git a/sdk/test/logs/CMakeLists.txt b/sdk/test/logs/CMakeLists.txt index 60e02b8b50..84b865d226 100644 --- a/sdk/test/logs/CMakeLists.txt +++ b/sdk/test/logs/CMakeLists.txt @@ -3,5 +3,8 @@ foreach(testname logger_provider_sdk_test logger_sdk_test log_record_test add_executable(${testname} "${testname}.cc") target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_logs) - gtest_add_tests(TARGET ${testname} TEST_PREFIX logs. TEST_LIST ${testname}) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX logs. + TEST_LIST ${testname}) endforeach() diff --git a/sdk/test/metrics/CMakeLists.txt b/sdk/test/metrics/CMakeLists.txt index e518dbdd1e..a33ccbf64b 100644 --- a/sdk/test/metrics/CMakeLists.txt +++ b/sdk/test/metrics/CMakeLists.txt @@ -13,5 +13,8 @@ foreach( add_executable(${testname} "${testname}.cc") target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_metrics) - gtest_add_tests(TARGET ${testname} TEST_PREFIX metrics. TEST_LIST ${testname}) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX metrics. + TEST_LIST ${testname}) endforeach() diff --git a/sdk/test/resource/CMakeLists.txt b/sdk/test/resource/CMakeLists.txt index ef00bb74a7..514b98680b 100644 --- a/sdk/test/resource/CMakeLists.txt +++ b/sdk/test/resource/CMakeLists.txt @@ -2,6 +2,8 @@ foreach(testname resource_test) add_executable(${testname} "${testname}.cc") target_link_libraries(${testname} ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} opentelemetry_resources) - gtest_add_tests(TARGET ${testname} TEST_PREFIX resources. TEST_LIST - ${testname}) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX resources. + TEST_LIST ${testname}) endforeach() diff --git a/sdk/test/trace/CMakeLists.txt b/sdk/test/trace/CMakeLists.txt index ab5251dde2..8a39c10a29 100644 --- a/sdk/test/trace/CMakeLists.txt +++ b/sdk/test/trace/CMakeLists.txt @@ -19,7 +19,10 @@ foreach( opentelemetry_trace opentelemetry_resources opentelemetry_exporter_in_memory) - gtest_add_tests(TARGET ${testname} TEST_PREFIX trace. TEST_LIST ${testname}) + gtest_add_tests( + TARGET ${testname} + TEST_PREFIX trace. + TEST_LIST ${testname}) endforeach() add_executable(sampler_benchmark sampler_benchmark.cc) From c9f1efaa6162dcd3f9d429aadcdf092a70189cbb Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 19 Mar 2021 21:14:40 -0700 Subject: [PATCH 36/76] define HAVE_TLD only if it hasn't been defined yet --- .../opentelemetry/exporters/etw/etw_traceloggingdynamic.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_traceloggingdynamic.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_traceloggingdynamic.h index 88914c95e1..db52e41f93 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_traceloggingdynamic.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_traceloggingdynamic.h @@ -3,6 +3,8 @@ #ifdef __has_include # if __has_include("TraceLoggingDynamic.h") # include "TraceLoggingDynamic.h" -# define HAVE_TLD +# ifndef HAVE_TLD +# define HAVE_TLD +# endif # endif #endif From ec0ef2e1cf64af163f4882bc8c8f6a2227e65cd3 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 19 Mar 2021 21:15:16 -0700 Subject: [PATCH 37/76] Fix C++17 issue regarding deprecated C++11 codecvt --- .../etw/include/opentelemetry/exporters/etw/utils.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/exporters/etw/include/opentelemetry/exporters/etw/utils.h b/exporters/etw/include/opentelemetry/exporters/etw/utils.h index e29d767a74..757343ab1f 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/utils.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/utils.h @@ -127,18 +127,21 @@ static inline bool sha1(const BYTE *pData, DWORD nData, BYTE *pHashedData, DWORD /// /// Convert UTF-8 string to UTF-16 wide string. /// -/// FIXME: this conversion is marked deprecated after C++17: -/// https://en.cppreference.com/w/cpp/locale/codecvt_utf8_utf16 -/// It works well with Visual C++, but may not work with clang. -/// Best long-term solution is to use Win32 API instead. -/// /// /// /// static inline std::wstring to_utf16_string(const std::string &in) { +#ifdef _WIN32 + int in_length = static_cast(in.size()); + int out_length = MultiByteToWideChar(CP_UTF8, 0, &in[0], in_length, NULL, 0); + std::wstring result(out_length, '\0'); + MultiByteToWideChar(CP_UTF8, 0, &in[0], in_length, &result[0], out_length); + return result; +#else std::wstring_convert, wchar_t> converter; return converter.from_bytes(in); +#endif } /// From 48adeea52dc5075eecdcf1f54bd788466cff2898 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 19 Mar 2021 21:15:52 -0700 Subject: [PATCH 38/76] Add tests for detailed decorator and min decorator --- exporters/etw/test/etw_tracer_test.cc | 82 +++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/exporters/etw/test/etw_tracer_test.cc b/exporters/etw/test/etw_tracer_test.cc index 13263ae5f7..a13c26c6b5 100644 --- a/exporters/etw/test/etw_tracer_test.cc +++ b/exporters/etw/test/etw_tracer_test.cc @@ -120,6 +120,88 @@ TEST(ETWTracer, TracerCheck) EXPECT_NO_THROW(tracer->CloseWithMicroseconds(0)); } + +// Lowest decoration level -> smaller ETW event size. +// Expected output in C# listener on the other side: +// no ActivityID GUID, no SpanId, no TraceId. +/* +{ + "Timestamp": "2021-03-19T21:04:38.411193-07:00", + "ProviderName": "OpenTelemetry-ETW-Provider", + "Id": 13, + "Message": null, + "ProcessId": 15120, + "Level": "Always", + "Keywords": "0x0000000000000000", + "EventName": "C.min/Stop", + "ActivityID": null, + "RelatedActivityID": null, + "Payload": {} +} +*/ +TEST(ETWTracer, TracerCheckMinDecoration) +{ + std::string providerName = "OpenTelemetry-ETW-Provider"; + exporter::ETW::TracerProvider tp + ({ + {"enableTraceId", false}, + {"enableSpanId", false}, + {"enableActivityId", false}, + {"enableRelatedActivityId", false}, + {"enableAutoParent", false} + }); + auto tracer = tp.GetTracer(providerName, "TLD"); + auto aSpan = tracer->StartSpan("A.min"); + auto bSpan = tracer->StartSpan("B.min"); + auto cSpan = tracer->StartSpan("C.min"); + cSpan->End(); + bSpan->End(); + aSpan->End(); + tracer->CloseWithMicroseconds(0); +} + +// Highest decoration level -> larger ETW event size +// Expected output in C# listener on the other side: +// ActivityID GUID (==SpanId), SpanId, TraceId. +/* +{ + "Timestamp": "2021-03-19T21:04:38.4120274-07:00", + "ProviderName": "OpenTelemetry-ETW-Provider", + "Id": 21, + "Message": null, + "ProcessId": 15120, + "Level": "Always", + "Keywords": "0x0000000000000000", + "EventName": "C.max/Stop", + "ActivityID": "d55a2c25-8033-40ab-0000-000000000000", + "RelatedActivityID": null, + "Payload": { + "SpanId": "252c5ad53380ab40", + "TraceId": "4dea2a63c188894ea5ab979e5cd7ec36" + } +} +*/ +TEST(ETWTracer, TracerCheckMaxDecoration) +{ + std::string providerName = "OpenTelemetry-ETW-Provider"; + exporter::ETW::TracerProvider tp + ({ + {"enableTraceId", true}, + {"enableSpanId", true}, + {"enableActivityId", true}, + {"enableRelatedActivityId", true}, + {"enableAutoParent", true} + }); + auto tracer = tp.GetTracer(providerName, "TLD"); + auto aSpan = tracer->StartSpan("A.max"); + auto bSpan = tracer->StartSpan("B.max"); + auto cSpan = tracer->StartSpan("C.max"); + cSpan->End(); + bSpan->End(); + aSpan->End(); + tracer->CloseWithMicroseconds(0); +} + /* clang-format on */ #endif From c3d0dc82ef176f0688a8cc855a455ed3add67230 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 19 Mar 2021 21:18:44 -0700 Subject: [PATCH 39/76] Add smarter ref-counting logic to ETW provider, allowing multiple tracers to reuse the same provider more efficiently --- .../exporters/etw/etw_provider.h | 62 ++++++++++++------- 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h index dd75dae471..d71ef5f2e1 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h @@ -74,6 +74,7 @@ class ETWProvider /// struct Handle { + uint64_t refCount; REGHANDLE providerHandle; std::vector providerMetaVector; GUID providerGuid; @@ -113,6 +114,7 @@ class ETWProvider { if (it->second.providerHandle != INVALID_HANDLE) { + it->second.refCount++; return it->second; } } @@ -149,10 +151,12 @@ class ETWProvider tld::RegisterProvider(&hProvider, &data.providerGuid, data.providerMetaVector.data())) { // There was an error registering the ETW provider + data.refCount = 0; data.providerHandle = INVALID_HANDLE; } else { + data.refCount = 1; data.providerHandle = hProvider; }; }; @@ -166,10 +170,12 @@ class ETWProvider if (EventRegister(&data.providerGuid, NULL, NULL, &hProvider) != ERROR_SUCCESS) { // There was an error registering the ETW provider + data.refCount = 0; data.providerHandle = INVALID_HANDLE; } else { + data.refCount = 1; data.providerHandle = hProvider; } }; @@ -186,12 +192,12 @@ class ETWProvider return data; } - /// - /// Unregister Provider - /// - /// - /// - unsigned long close(Handle data) + /** + * @brief Unregister provider + * @param data Provider Handle + * @return status code + */ + unsigned long close(Handle handle) { std::lock_guard lock(m_providerMapLock); @@ -199,10 +205,31 @@ class ETWProvider auto it = m.begin(); while (it != m.end()) { - if (it->second.providerHandle == data.providerHandle) + if (it->second.providerHandle == handle.providerHandle) { - auto result = EventUnregister(data.providerHandle); - m.erase(it); + // reference to item in the map of open provider handles + auto &data = it->second; + unsigned long result = STATUS_OK; + + data.refCount--; + if (data.refCount == 0) + { +#ifdef HAVE_TLD + if (data.providerMetaVector.size()) + { + // ETW/TraceLoggingDynamic provider + result = tld::UnregisterProvider(data.providerHandle); + } + else +#endif + { + // Other provider types, e.g. ETW/MsgPack + result = EventUnregister(data.providerHandle); + } + + it->second.providerHandle = INVALID_HANDLE; + m.erase(it); + } return result; } }; @@ -583,37 +610,26 @@ class ETWProvider eventDescriptor.Opcode = Opcode; eventDescriptor.Level = 0; /* FIXME: Always on for now */ - // eventDescriptor.Keyword = MICROSOFT_KEYWORD_CRITICAL_DATA; - // eventDescriptor.Keyword = MICROSOFT_KEYWORD_TELEMETRY; - // eventDescriptor.Keyword = MICROSOFT_KEYWORD_MEASURES; EVENT_DATA_DESCRIPTOR pDataDescriptors[3]; - EventDataDescCreate(&pDataDescriptors[2], byteDataVector.data(), static_cast(byteDataVector.size())); - // Event size detection is needed - int64_t eventByteSize = byteDataVector.size() + byteVector.size(); - int64_t eventKBSize = (eventByteSize + 1024 - 1) / 1024; - // bool isLargeEvent = eventKBSize >= LargeEventSizeKB; - - // TODO: extract - // - GUID ActivityId - // - GUID RelatedActivityId HRESULT writeResponse = 0; if ((ActivityId != nullptr) || (RelatedActivityId != nullptr)) { - tld::WriteEvent(providerData.providerHandle, eventDescriptor, + writeResponse = tld::WriteEvent(providerData.providerHandle, eventDescriptor, providerData.providerMetaVector.data(), byteVector.data(), 3, pDataDescriptors, ActivityId, RelatedActivityId); } else { - tld::WriteEvent(providerData.providerHandle, eventDescriptor, + writeResponse = tld::WriteEvent(providerData.providerHandle, eventDescriptor, providerData.providerMetaVector.data(), byteVector.data(), 3, pDataDescriptors); }; + // Event is larger than ETW max sized of 64KB if (writeResponse == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW)) { return STATUS_EFBIG; From 753521b621a6aee71563d24ef87e58939bab2d60 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 19 Mar 2021 21:21:44 -0700 Subject: [PATCH 40/76] ETW Tracer improvements: - configuration API surface for ETW TracerProvider - OPTIONAL support for native ETW correlation techniques (ActivityId, RelatedActivityId) - OPTIONAL support for min-size vs detailed events (stamping TraceId, SpanId, SpanParentId) --- .../opentelemetry/exporters/etw/etw_tracer.h | 389 +++++++++++++----- 1 file changed, 294 insertions(+), 95 deletions(-) diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h index 89be41234a..bbc1741aa8 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h @@ -32,6 +32,7 @@ #include "opentelemetry/nostd/shared_ptr.h" #include "opentelemetry/nostd/string_view.h" #include "opentelemetry/nostd/unique_ptr.h" +#include "opentelemetry/nostd/variant.h" #include "opentelemetry/common/key_value_iterable_view.h" @@ -59,15 +60,53 @@ namespace exporter namespace ETW { -struct ProviderOptions +/** + * @brief TracerProvider Options passed via SDK API. + */ +using TracerProviderOptions = + std::map>; + +/** + * @brief TracerProvider runtime configuration class. Internal representation + * of TracerProviderOptions used by various components of SDK. + */ +typedef struct { - bool enableTraceId; - bool enableActivityId; - bool enableRelatedActivityId; - bool enableAutoContext; -}; + bool enableTraceId; // Set `TraceId` on ETW events + bool enableSpanId; // Set `SpanId` on ETW events + bool enableActivityId; // Assign `SpanId` to `ActivityId` + bool enableRelatedActivityId; // Assign parent `SpanId` to `RelatedActivityId` + bool enableAutoParent; // Start new spans as children of current active span +} TracerProviderConfiguration; + +/** + * @brief Helper template to convert a variant value from TracerProviderOptions to TracerProviderConfiguration + * + * @param options TracerProviderOptions passed on API surface + * @param key Option name + * @param value Reference to destination value + * @param defaultValue Default value if option is not supplied +*/ +template +static inline void GetOption(const TracerProviderOptions &options, + const char *key, + T &value, + T defaultValue) +{ + auto it = options.find(key); + if (it != options.end()) + { + auto val = it->second; + value = nostd::get(val); + } + else + { + value = defaultValue; + } +} class Span; +class TracerProvider; /** * @brief Utility template for Span.GetName() @@ -82,13 +121,34 @@ std::string GetName(T &t) return std::string(sV.data(), sV.length()); } -static inline GUID ToActivityId(const trace::Span *span) +/** + * @brief Utility template for forward-declaration of ETW::TracerProvider._config + * + * @tparam T ETW::TracerProvider + * @param t ETW::TracerProvider ref + * @return TracerProviderConfiguration ref +*/ +template +TracerProviderConfiguration& GetConfiguration(T& t) { - if (span == nullptr) + return t.config_; +} + +/** + * @brief Utility method to convert SppanContext.span_id() (8 byte) to ActivityId GUID (16 bytes) + * @param span OpenTelemetry Span pointer + * @return GUID struct containing 8-bytes of SpanId + 8 NUL bytes. +*/ +static inline bool CopySpanIdToActivityId(const trace::SpanContext& spanContext, GUID & outGuid ) +{ + memset(&outGuid, 0, sizeof(outGuid)); + if (!spanContext.IsValid()) { - return GUID({0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}}); + return false; } - return utils::UUID(span->GetContext().span_id().Id().data()).to_GUID(); + auto spanId = spanContext.span_id().Id().data(); + std::copy(spanId, spanId + 8, reinterpret_cast(&outGuid)); + return true; }; /** @@ -113,7 +173,7 @@ class Tracer : public trace::Tracer /** * @brief Parent provider of this Tracer */ - trace::TracerProvider &parent; + ETW::TracerProvider &tracerProvider_; /** * @brief ProviderId (Name or GUID) @@ -121,17 +181,19 @@ class Tracer : public trace::Tracer std::string provId; /** - * @brief Provider Handle + * @brief Encoding (Manifest, MessagePack or XML) */ - ETWProvider::Handle provHandle; + ETWProvider::EventFormat encoding; /** - * @brief Encoding (Manifest, MessagePack or XML) + * @brief Provider Handle */ - ETWProvider::EventFormat encoding; + ETWProvider::Handle& provHandle; trace::TraceId traceId_; + std::atomic isClosed_{true}; + /** * @brief ETWProvider is a singleton that aggregates all ETW writes. * @return @@ -144,8 +206,8 @@ class Tracer : public trace::Tracer /** * @brief Internal method that allows to populate Links to other Spans. - * This is temporary implementation, that assumes the links are mentioned - * comma-separated in their order of appearance. + * Span links are in hexadecimal representation, comma-separated in their + * order of appearance. * * @param attributes * @param links @@ -153,19 +215,22 @@ class Tracer : public trace::Tracer virtual void DecorateLinks(Properties &attributes, const trace::SpanContextKeyValueIterable &links) const { - // Links - size_t idx = 0; - std::string linksValue; - links.ForEachKeyValue([&](trace::SpanContext ctx, const common::KeyValueIterable &) { - if (!linksValue.empty()) - { - linksValue += ','; - linksValue += ToLowerBase16(ctx.span_id()); - } - idx++; - return true; - }); - attributes[ETW_FIELD_SPAN_LINKS] = linksValue; + // Add `SpanLinks` attribute if the list is not empty + if (links.size()) + { + size_t idx = 0; + std::string linksValue; + links.ForEachKeyValue([&](trace::SpanContext ctx, const common::KeyValueIterable &) { + if (!linksValue.empty()) + { + linksValue += ','; + linksValue += ToLowerBase16(ctx.span_id()); + } + idx++; + return true; + }); + attributes[ETW_FIELD_SPAN_LINKS] = linksValue; + } }; /** @@ -174,27 +239,57 @@ class Tracer : public trace::Tracer * @param */ virtual void EndSpan(const Span &span, - const trace::Span *parent = nullptr, + const trace::Span *parentSpan = nullptr, const trace::EndSpanOptions & = {}) { - Properties evt; - + const auto &cfg = GetConfiguration(tracerProvider_); const trace::Span &spanBase = reinterpret_cast(span); + auto spanContext = spanBase.GetContext(); - auto ctx = spanBase.GetContext(); + Properties evt; evt[ETW_FIELD_NAME] = GetName(span); - // We use ActivityId instead of ETW_FIELD_SPAN_ID below - // evt[ETW_FIELD_SPAN_ID] = ToLowerBase16(ctx.span_id()); - auto ActivityId = ToActivityId(&spanBase); + if (cfg.enableSpanId) + { + evt[ETW_FIELD_SPAN_ID] = ToLowerBase16(spanContext.span_id()); + } - // Could be GUID NULL - auto RelatedActivityId = ToActivityId(parent); + if (cfg.enableTraceId) + { + evt[ETW_FIELD_TRACE_ID] = ToLowerBase16(spanContext.trace_id()); + } - // TODO: check what EndSpanOptions should be supported for this exporter - etwProvider().write(provHandle, evt, &ActivityId, &RelatedActivityId, 2, encoding); + // Populate ActivityId if enabled + GUID ActivityId; + LPGUID ActivityIdPtr = nullptr; + if (cfg.enableActivityId) + { + if (CopySpanIdToActivityId(spanBase.GetContext(), ActivityId)) + { + ActivityIdPtr = &ActivityId; + } + } + // Populate RelatedActivityId if enabled + GUID RelatedActivityId; + LPGUID RelatedActivityIdPtr = nullptr; + if (cfg.enableRelatedActivityId) { + if (parentSpan != nullptr) + { + if (CopySpanIdToActivityId(parentSpan->GetContext(), RelatedActivityId)) + { + RelatedActivityIdPtr = &RelatedActivityId; + } + } + } + + // TODO: check what EndSpanOptions should be supported for this exporter. + // The only option available currently (end_steady_time) does not apply. + etwProvider().write(provHandle, evt, ActivityIdPtr, RelatedActivityIdPtr, 2, encoding); + + { + // Atomically remove the span from list of spans const std::lock_guard lock(scopes_mutex_); auto spanId = ToLowerBase16(spanBase.GetContext().span_id()); scopes_.erase(spanId); @@ -208,33 +303,43 @@ class Tracer : public trace::Tracer std::mutex scopes_mutex_; // protects scopes_ std::map> scopes_; -public: + /** + * @brief Init a reference to ETW::ProviderHandle + * @return Provider Handle + */ + ETWProvider::Handle& initProvHandle() + { +#if defined(HAVE_MSGPACK) && !defined(HAVE_TLD) + /* Fallback to MsgPack encoding if TraceLoggingDynamic feature gate is off */ + encoding = ETWProvider::EventFormat::ETW_MSGPACK; +#endif + isClosed_ = false; + return etwProvider().open(provId, encoding); + } + + public: + /** * @brief Tracer constructor * @param parent Parent TraceProvider * @param providerId ProviderId - Name or GUID * @param encoding ETW encoding format to use. */ - Tracer(trace::TracerProvider &parent, + Tracer(ETW::TracerProvider &parent, nostd::string_view providerId = "", ETWProvider::EventFormat encoding = ETWProvider::EventFormat::ETW_MANIFEST) : trace::Tracer(), - parent(parent), + tracerProvider_(parent), provId(providerId.data(), providerId.size()), - encoding(encoding) + encoding(encoding), + provHandle(initProvHandle()) { - GUID trace_id; // Generate random GUID + GUID trace_id; CoCreateGuid(&trace_id); + // Populate TraceId of the Tracer with that random GUID const auto *traceIdBytes = reinterpret_cast(std::addressof(trace_id)); - // Populate TraceId with that GUID traceId_ = trace::TraceId(traceIdBytes); - -#if defined(HAVE_MSGPACK) && !defined(HAVE_TLD) - /* Fallback to MsgPack encoding if TraceLoggingDynamic feature gate is off */ - this->encoding = ETWProvider::EventFormat::ETW_MSGPACK; -#endif - provHandle = etwProvider().open(provId, encoding); }; /** @@ -251,40 +356,75 @@ class Tracer : public trace::Tracer const trace::SpanContextKeyValueIterable &links, const trace::StartSpanOptions &options = {}) noexcept override { - const auto parent = GetCurrentSpan(); - LPCGUID RelatedActivityIdPtr = nullptr; + const auto &cfg = GetConfiguration(tracerProvider_); + + // Parent Context: + // - either use current span + // - or attach to parent SpanContext specified in options + const auto parentContext = (options.parent.IsValid()) ? options.parent : GetCurrentSpan()->GetContext(); + + // Copy Span attributes to event Payload + Properties evt = attributes; + + // Populate Etw.RelatedActivityId at envelope level if enabled GUID RelatedActivityId; - // Propagate parent activity only if parent span (current span) is valid - if (parent->GetContext().IsValid()) + LPCGUID RelatedActivityIdPtr = nullptr; + if (cfg.enableAutoParent) { - RelatedActivityId = ToActivityId(parent.get()); - RelatedActivityIdPtr = &RelatedActivityId; - }; + if (cfg.enableRelatedActivityId) + { + if (CopySpanIdToActivityId(parentContext, RelatedActivityId)) + { + RelatedActivityIdPtr = &RelatedActivityId; + } + } + } nostd::shared_ptr result = trace::to_span_ptr(this, name, options); auto spanContext = result->GetContext(); - // Event properties - Properties evt = attributes; - // Decorate with additional standard fields std::string eventName = name.data(); - evt[ETW_FIELD_NAME] = eventName.data(); - evt[ETW_FIELD_TRACE_ID] = ToLowerBase16(spanContext.trace_id()); + // Populate Etw.EventName attribute at envelope level + evt[ETW_FIELD_NAME] = eventName; + + // Populate Payload["SpanId"] attribute + // Populate Payload["ParentSpanId"] attribute if parent Span is valid + if (cfg.enableSpanId) + { + if (parentContext.IsValid()) + { + evt[ETW_FIELD_SPAN_PARENTID] = ToLowerBase16(parentContext.span_id()); + } + evt[ETW_FIELD_SPAN_ID] = ToLowerBase16(spanContext.span_id()); + } + + // Populate Etw.Payload["TraceId"] attribute + if (cfg.enableTraceId) + { + evt[ETW_FIELD_TRACE_ID] = ToLowerBase16(spanContext.trace_id()); + } - auto ActivityId = ToActivityId(result.get()); + // Populate Etw.ActivityId at envelope level if enabled + GUID ActivityId; + LPCGUID ActivityIdPtr = nullptr; + if (cfg.enableActivityId) + { + if (CopySpanIdToActivityId(result.get()->GetContext(), ActivityId)) + { + ActivityIdPtr = &ActivityId; + } + } // Links DecorateLinks(evt, links); - // NOTE: we neither allow adding attributes nor links after StartSpan. - // TODO: add support for options + // TODO: add support for options that are presently ignored : // - options.kind - // - options.parent // - options.start_steady_time // - options.start_system_time - etwProvider().write(provHandle, evt, &ActivityId, RelatedActivityIdPtr, 1, encoding); + etwProvider().write(provHandle, evt, ActivityIdPtr, RelatedActivityIdPtr, 1, encoding); { const std::lock_guard lock(scopes_mutex_); @@ -306,12 +446,20 @@ class Tracer : public trace::Tracer /** * @brief Close tracer, spending up to given amount of microseconds to flush and close. - * NOTE: This method closes the current ETW Provider Handle. + * NOTE: This method decrements the reference count on current ETW Provider Handle and + * closes it if reference count on that provider handle is zero. * * @param timeout Allow Tracer to drop data if timeout is reached. * @return */ - void CloseWithMicroseconds(uint64_t) noexcept override { etwProvider().close(provHandle); }; + void CloseWithMicroseconds(uint64_t) noexcept override + { + // Close once only + if (!isClosed_.exchange(true)) + { + etwProvider().close(provHandle); + } + }; /** * @brief Add event data to span associated with tracer. @@ -326,28 +474,45 @@ class Tracer : public trace::Tracer core::SystemTimestamp timestamp, const common::KeyValueIterable &attributes) noexcept { - // TODO: respect originating timestamp + // TODO: respect originating timestamp. Do we need to reserve + // a special 'Timestamp' field or is it an overkill? The delta + // between when `AddEvent` API is called and when ETW layer + // timestamp is appended is nanos- to micros-, thus handling + // the explicitly provided timestamp is only necessary in case + // if a process wants to submit back-dated or future-dated + // timestamp. Unless there is a strong ask from any ETW customer + // to have it, this feature (custom timestamp) remains unimplemented. (void)timestamp; - // Event properties. - // TODO: if we know that the incoming type is already `Properties`, - // then we could avoid the memcpy by reusing the incoming attributes. - // This would require non-const argument. + const auto &cfg = GetConfiguration(tracerProvider_); + + // OPTIMIZATION OPPORTUNITY: Event properties assigned from attributes. + // If we know that the parameter is of non-const container type `Properties`, + // then we can append more to container and avoid the memcpy entirely. Properties evt = attributes; evt[ETW_FIELD_NAME] = name.data(); - auto spanContext = span.GetContext(); + const auto &spanContext = span.GetContext(); + if (cfg.enableSpanId) + { + evt[ETW_FIELD_SPAN_ID] = ToLowerBase16(spanContext.span_id()); + } - // Decorate with additional standard fields. This may get expensive - // and should be configurable for traces that deduct their nested - // structure based off built-in `ActivityId` and `RelatedActivityId` - // evt[ETW_FIELD_TRACE_ID] = ToLowerBase16(spanContext.trace_id()); - evt[ETW_FIELD_SPAN_ID] = ToLowerBase16(spanContext.span_id()); + if (cfg.enableTraceId) + { + evt[ETW_FIELD_TRACE_ID] = ToLowerBase16(spanContext.trace_id()); + } - auto RelatedActivityId = ToActivityId(&span); + LPGUID ActivityIdPtr = nullptr; + GUID ActivityId; + if (cfg.enableActivityId) + { + CopySpanIdToActivityId(spanContext, ActivityId); + ActivityIdPtr = &ActivityId; + } - etwProvider().write(provHandle, evt, nullptr, &RelatedActivityId, encoding); + etwProvider().write(provHandle, evt, ActivityIdPtr, nullptr, encoding); }; /** @@ -585,19 +750,53 @@ class Span : public trace::Span trace::Tracer &tracer() const noexcept { return this->owner_; }; }; -/// -/// stream::TraceProvider -/// +/** + * @brief ETW TracerProvider +*/ class TracerProvider : public trace::TracerProvider { public: - /// - /// Obtain a Tracer of given type (name) and supply extra argument arg2 to it. - /// - /// Tracer Type - /// Tracer arguments - /// - /// + + /** + * @brief TracerProvider options supplied during initialization. + */ + TracerProviderConfiguration config_; + + /** + * @brief Construct instance of TracerProvider with given options + * @param options Configuration options + */ + TracerProvider(TracerProviderOptions options) : trace::TracerProvider() + { + // By default we ensure that all events carry their with TraceId and SpanId + GetOption(options, "enableTraceId", config_.enableTraceId, true); + GetOption(options, "enableSpanId", config_.enableSpanId, true); + + // Backwards-compatibility option that allows to reuse ETW-specific parenting described here: + // https://docs.microsoft.com/en-us/uwp/api/windows.foundation.diagnostics.loggingoptions.relatedactivityid + // https://docs.microsoft.com/en-us/windows/win32/api/evntprov/nf-evntprov-eventwritetransfer + + // Map current `SpanId` to ActivityId - GUID that uniquely identifies this activity. If NULL, + // ETW gets the identifier from the thread local storage. For details on getting this identifier, + // see EventActivityIdControl. + GetOption(options, "enableActivityId", config_.enableActivityId, false); + + // Map parent `SpanId` to RelatedActivityId - Activity identifier from the previous component. + // Use this parameter to link your component's events to the previous component's events. + GetOption(options, "enableRelatedActivityId", config_.enableRelatedActivityId, false); + + // When a new Span is started, the current span automatically becomes its parent. + GetOption(options, "enableAutoParent", config_.enableAutoParent, false); + } + + TracerProvider() : trace::TracerProvider() + { + config_.enableTraceId = true; + config_.enableSpanId = true; + config_.enableActivityId = false; + config_.enableRelatedActivityId = false; + config_.enableAutoParent = false; + } /** * @brief Obtain ETW Tracer. From 5ed213c5f8899d95e5a6786a609f2a408f15f64c Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 19 Mar 2021 21:28:16 -0700 Subject: [PATCH 41/76] Code formatting changes --- .../exporters/etw/etw_provider.h | 19 +++--- .../opentelemetry/exporters/etw/etw_tracer.h | 60 +++++++++---------- .../opentelemetry/exporters/etw/utils.h | 8 +-- 3 files changed, 43 insertions(+), 44 deletions(-) diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h index d71ef5f2e1..54810420bc 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h @@ -151,12 +151,12 @@ class ETWProvider tld::RegisterProvider(&hProvider, &data.providerGuid, data.providerMetaVector.data())) { // There was an error registering the ETW provider - data.refCount = 0; + data.refCount = 0; data.providerHandle = INVALID_HANDLE; } else { - data.refCount = 1; + data.refCount = 1; data.providerHandle = hProvider; }; }; @@ -170,12 +170,12 @@ class ETWProvider if (EventRegister(&data.providerGuid, NULL, NULL, &hProvider) != ERROR_SUCCESS) { // There was an error registering the ETW provider - data.refCount = 0; + data.refCount = 0; data.providerHandle = INVALID_HANDLE; } else { - data.refCount = 1; + data.refCount = 1; data.providerHandle = hProvider; } }; @@ -208,7 +208,7 @@ class ETWProvider if (it->second.providerHandle == handle.providerHandle) { // reference to item in the map of open provider handles - auto &data = it->second; + auto &data = it->second; unsigned long result = STATUS_OK; data.refCount--; @@ -614,19 +614,18 @@ class ETWProvider EventDataDescCreate(&pDataDescriptors[2], byteDataVector.data(), static_cast(byteDataVector.size())); - HRESULT writeResponse = 0; if ((ActivityId != nullptr) || (RelatedActivityId != nullptr)) { writeResponse = tld::WriteEvent(providerData.providerHandle, eventDescriptor, - providerData.providerMetaVector.data(), byteVector.data(), 3, - pDataDescriptors, ActivityId, RelatedActivityId); + providerData.providerMetaVector.data(), byteVector.data(), 3, + pDataDescriptors, ActivityId, RelatedActivityId); } else { writeResponse = tld::WriteEvent(providerData.providerHandle, eventDescriptor, - providerData.providerMetaVector.data(), byteVector.data(), 3, - pDataDescriptors); + providerData.providerMetaVector.data(), byteVector.data(), 3, + pDataDescriptors); }; // Event is larger than ETW max sized of 64KB diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h index bbc1741aa8..2ccf39e751 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h @@ -80,18 +80,19 @@ typedef struct } TracerProviderConfiguration; /** - * @brief Helper template to convert a variant value from TracerProviderOptions to TracerProviderConfiguration - * + * @brief Helper template to convert a variant value from TracerProviderOptions to + * TracerProviderConfiguration + * * @param options TracerProviderOptions passed on API surface * @param key Option name * @param value Reference to destination value * @param defaultValue Default value if option is not supplied -*/ -template + */ +template static inline void GetOption(const TracerProviderOptions &options, - const char *key, - T &value, - T defaultValue) + const char *key, + T &value, + T defaultValue) { auto it = options.find(key); if (it != options.end()) @@ -127,9 +128,9 @@ std::string GetName(T &t) * @tparam T ETW::TracerProvider * @param t ETW::TracerProvider ref * @return TracerProviderConfiguration ref -*/ + */ template -TracerProviderConfiguration& GetConfiguration(T& t) +TracerProviderConfiguration &GetConfiguration(T &t) { return t.config_; } @@ -138,15 +139,15 @@ TracerProviderConfiguration& GetConfiguration(T& t) * @brief Utility method to convert SppanContext.span_id() (8 byte) to ActivityId GUID (16 bytes) * @param span OpenTelemetry Span pointer * @return GUID struct containing 8-bytes of SpanId + 8 NUL bytes. -*/ -static inline bool CopySpanIdToActivityId(const trace::SpanContext& spanContext, GUID & outGuid ) + */ +static inline bool CopySpanIdToActivityId(const trace::SpanContext &spanContext, GUID &outGuid) { memset(&outGuid, 0, sizeof(outGuid)); if (!spanContext.IsValid()) { return false; } - auto spanId = spanContext.span_id().Id().data(); + auto spanId = spanContext.span_id().Id().data(); std::copy(spanId, spanId + 8, reinterpret_cast(&outGuid)); return true; }; @@ -188,7 +189,7 @@ class Tracer : public trace::Tracer /** * @brief Provider Handle */ - ETWProvider::Handle& provHandle; + ETWProvider::Handle &provHandle; trace::TraceId traceId_; @@ -239,12 +240,12 @@ class Tracer : public trace::Tracer * @param */ virtual void EndSpan(const Span &span, - const trace::Span *parentSpan = nullptr, + const trace::Span *parentSpan = nullptr, const trace::EndSpanOptions & = {}) { - const auto &cfg = GetConfiguration(tracerProvider_); + const auto &cfg = GetConfiguration(tracerProvider_); const trace::Span &spanBase = reinterpret_cast(span); - auto spanContext = spanBase.GetContext(); + auto spanContext = spanBase.GetContext(); Properties evt; evt[ETW_FIELD_NAME] = GetName(span); @@ -306,8 +307,8 @@ class Tracer : public trace::Tracer /** * @brief Init a reference to ETW::ProviderHandle * @return Provider Handle - */ - ETWProvider::Handle& initProvHandle() + */ + ETWProvider::Handle &initProvHandle() { #if defined(HAVE_MSGPACK) && !defined(HAVE_TLD) /* Fallback to MsgPack encoding if TraceLoggingDynamic feature gate is off */ @@ -317,8 +318,7 @@ class Tracer : public trace::Tracer return etwProvider().open(provId, encoding); } - public: - +public: /** * @brief Tracer constructor * @param parent Parent TraceProvider @@ -339,7 +339,7 @@ class Tracer : public trace::Tracer CoCreateGuid(&trace_id); // Populate TraceId of the Tracer with that random GUID const auto *traceIdBytes = reinterpret_cast(std::addressof(trace_id)); - traceId_ = trace::TraceId(traceIdBytes); + traceId_ = trace::TraceId(traceIdBytes); }; /** @@ -356,12 +356,13 @@ class Tracer : public trace::Tracer const trace::SpanContextKeyValueIterable &links, const trace::StartSpanOptions &options = {}) noexcept override { - const auto &cfg = GetConfiguration(tracerProvider_); + const auto &cfg = GetConfiguration(tracerProvider_); // Parent Context: // - either use current span // - or attach to parent SpanContext specified in options - const auto parentContext = (options.parent.IsValid()) ? options.parent : GetCurrentSpan()->GetContext(); + const auto parentContext = + (options.parent.IsValid()) ? options.parent : GetCurrentSpan()->GetContext(); // Copy Span attributes to event Payload Properties evt = attributes; @@ -387,7 +388,7 @@ class Tracer : public trace::Tracer std::string eventName = name.data(); // Populate Etw.EventName attribute at envelope level - evt[ETW_FIELD_NAME] = eventName; + evt[ETW_FIELD_NAME] = eventName; // Populate Payload["SpanId"] attribute // Populate Payload["ParentSpanId"] attribute if parent Span is valid @@ -752,20 +753,19 @@ class Span : public trace::Span /** * @brief ETW TracerProvider -*/ + */ class TracerProvider : public trace::TracerProvider { public: - /** * @brief TracerProvider options supplied during initialization. - */ + */ TracerProviderConfiguration config_; /** * @brief Construct instance of TracerProvider with given options * @param options Configuration options - */ + */ TracerProvider(TracerProviderOptions options) : trace::TracerProvider() { // By default we ensure that all events carry their with TraceId and SpanId @@ -777,8 +777,8 @@ class TracerProvider : public trace::TracerProvider // https://docs.microsoft.com/en-us/windows/win32/api/evntprov/nf-evntprov-eventwritetransfer // Map current `SpanId` to ActivityId - GUID that uniquely identifies this activity. If NULL, - // ETW gets the identifier from the thread local storage. For details on getting this identifier, - // see EventActivityIdControl. + // ETW gets the identifier from the thread local storage. For details on getting this + // identifier, see EventActivityIdControl. GetOption(options, "enableActivityId", config_.enableActivityId, false); // Map parent `SpanId` to RelatedActivityId - Activity identifier from the previous component. diff --git a/exporters/etw/include/opentelemetry/exporters/etw/utils.h b/exporters/etw/include/opentelemetry/exporters/etw/utils.h index 757343ab1f..3ae81dc91c 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/utils.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/utils.h @@ -132,16 +132,16 @@ static inline bool sha1(const BYTE *pData, DWORD nData, BYTE *pHashedData, DWORD /// static inline std::wstring to_utf16_string(const std::string &in) { -#ifdef _WIN32 - int in_length = static_cast(in.size()); +# ifdef _WIN32 + int in_length = static_cast(in.size()); int out_length = MultiByteToWideChar(CP_UTF8, 0, &in[0], in_length, NULL, 0); std::wstring result(out_length, '\0'); MultiByteToWideChar(CP_UTF8, 0, &in[0], in_length, &result[0], out_length); return result; -#else +# else std::wstring_convert, wchar_t> converter; return converter.from_bytes(in); -#endif +# endif } /// From 1d46f7606828b602951ff690553b6295bee9d3b8 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Tue, 23 Mar 2021 00:59:12 -0700 Subject: [PATCH 42/76] Add time routines to utils --- .../opentelemetry/exporters/etw/utils.h | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/exporters/etw/include/opentelemetry/exporters/etw/utils.h b/exporters/etw/include/opentelemetry/exporters/etw/utils.h index 3ae81dc91c..b76c95f2c1 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/utils.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/utils.h @@ -210,6 +210,39 @@ static inline GUID GetProviderGuid(const char *providerName) } #endif +int64_t getUtcSystemTimeMs() +{ +#ifdef _WIN32 + ULARGE_INTEGER now; + ::GetSystemTimeAsFileTime(reinterpret_cast(&now)); + return (now.QuadPart - 116444736000000000ull) / 10000; +#else + return std::chrono::system_clock::now().time_since_epoch() / std::chrono::milliseconds(1); +#endif +} + +int64_t getUtcSystemTimeinTicks() +{ +#ifdef _WIN32 + FILETIME tocks; + ::GetSystemTimeAsFileTime(&tocks); + ULONGLONG ticks = (ULONGLONG(tocks.dwHighDateTime) << 32) | tocks.dwLowDateTime; + // number of days from beginning to 1601 multiplied by ticks per day + return ticks + 0x701ce1722770000ULL; +#else + // On Un*x systems system_clock de-facto contains UTC time. Ref: + // https://en.cppreference.com/w/cpp/chrono/system_clock + // This UTC epoch contract has been signed in blood since C++20 + std::chrono::time_point now = std::chrono::system_clock::now(); + auto duration = now.time_since_epoch(); + auto millis = std::chrono::duration_cast(duration).count(); + uint64_t ticks = millis; + ticks *= 10000; // convert millis to ticks (1 tick = 100ns) + ticks += 0x89F7FF5F7B58000ULL; // UTC time 0 in .NET ticks + return ticks; +#endif +} + }; // namespace utils OPENTELEMETRY_END_NAMESPACE From 131f8016ca1032bb3473d68edd56eee6811e463c Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Tue, 23 Mar 2021 00:59:47 -0700 Subject: [PATCH 43/76] Fix bug in format passing --- exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h index 2ccf39e751..0eb6404f27 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h @@ -513,7 +513,7 @@ class Tracer : public trace::Tracer ActivityIdPtr = &ActivityId; } - etwProvider().write(provHandle, evt, ActivityIdPtr, nullptr, encoding); + etwProvider().write(provHandle, evt, ActivityIdPtr, nullptr, 0, encoding); }; /** From 51bea3618de4f69fb38d2793c12f8943fbd8742e Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Tue, 23 Mar 2021 01:00:39 -0700 Subject: [PATCH 44/76] Add separate tests for TLD (TraceLoggingDynamic) encoding and MsgPack encoding --- exporters/etw/test/etw_tracer_test.cc | 43 ++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/exporters/etw/test/etw_tracer_test.cc b/exporters/etw/test/etw_tracer_test.cc index a13c26c6b5..14171ad5d7 100644 --- a/exporters/etw/test/etw_tracer_test.cc +++ b/exporters/etw/test/etw_tracer_test.cc @@ -56,7 +56,7 @@ TEST(ETWTracer, TracerCheck) // Windows Defender Firewall API - GP {0EFF663F-8B6E-4E6D-8182-087A8EAA29CB} // Windows Defender Firewall Driver {D5E09122-D0B2-4235-ADC1-C89FAAAF1069} - std::string providerName = "OpenTelemetry-ETW-Provider"; // supply unique instrumentation name here + std::string providerName = "OpenTelemetry-ETW-TLD"; // supply unique instrumentation name here exporter::ETW::TracerProvider tp; // TODO: this code should fallback to MsgPack if TLD is not available @@ -141,7 +141,7 @@ TEST(ETWTracer, TracerCheck) */ TEST(ETWTracer, TracerCheckMinDecoration) { - std::string providerName = "OpenTelemetry-ETW-Provider"; + std::string providerName = "OpenTelemetry-ETW-TLD"; exporter::ETW::TracerProvider tp ({ {"enableTraceId", false}, @@ -183,7 +183,7 @@ TEST(ETWTracer, TracerCheckMinDecoration) */ TEST(ETWTracer, TracerCheckMaxDecoration) { - std::string providerName = "OpenTelemetry-ETW-Provider"; + std::string providerName = "OpenTelemetry-ETW-TLD"; exporter::ETW::TracerProvider tp ({ {"enableTraceId", true}, @@ -192,7 +192,7 @@ TEST(ETWTracer, TracerCheckMaxDecoration) {"enableRelatedActivityId", true}, {"enableAutoParent", true} }); - auto tracer = tp.GetTracer(providerName, "TLD"); + auto tracer = tp.GetTracer(providerName, "TLD" ); auto aSpan = tracer->StartSpan("A.max"); auto bSpan = tracer->StartSpan("B.max"); auto cSpan = tracer->StartSpan("C.max"); @@ -202,6 +202,41 @@ TEST(ETWTracer, TracerCheckMaxDecoration) tracer->CloseWithMicroseconds(0); } +TEST(ETWTracer, TracerCheckMsgPack) +{ + std::string providerName = "OpenTelemetry-ETW-MsgPack"; + exporter::ETW::TracerProvider tp + ({ + {"enableTraceId", true}, + {"enableSpanId", true}, + {"enableActivityId", true}, + {"enableRelatedActivityId", true}, + {"enableAutoParent", true} + }); + auto tracer = tp.GetTracer(providerName, "MsgPack" ); + { + auto aSpan = tracer->StartSpan("A.max"); + { + auto bSpan = tracer->StartSpan("B.max"); + { + auto cSpan = tracer->StartSpan("C.max"); + std::string eventName = "MyMsgPackEvent"; + Properties event = + { + {"uint32Key", (uint32_t)1234}, + {"uint64Key", (uint64_t)1234567890}, + {"strKey", "someValue"} + }; + cSpan->AddEvent(eventName, event); + cSpan->End(); + } + bSpan->End(); + } + aSpan->End(); + } + tracer->CloseWithMicroseconds(0); +} + /* clang-format on */ #endif From 4543a47c2d6d56c0bdc77f6541542a8eaacc09ee Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Tue, 23 Mar 2021 01:01:30 -0700 Subject: [PATCH 45/76] Clean-up field names for ETW notation (common field names used for both ETW/TLD and ETW/MsgPack) --- .../opentelemetry/exporters/etw/etw_fields.h | 46 +++++++++++-------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_fields.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_fields.h index b7599ff3dd..9fcb6b694e 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_fields.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_fields.h @@ -14,35 +14,43 @@ */ #pragma once +#include + +#include "opentelemetry/exporters/etw/utils.h" + +/* clang-format off */ #ifdef CUSTOM_ETW_FIELDS_H # include CUSTOM_ETW_FIELDS_H #else -/* clang-format off */ -/* Field name constants */ +/* ETW constants at envelope level that would be appended at different spot depending + * on what serializer used to encode the payload + */ # define ETW_FIELD_NAME "name" /* Event name */ -# define ETW_FIELD_TYPE "type" /* Event type (TLD) */ +# define ETW_FIELD_TYPE "type" /* Event type */ # define ETW_FIELD_VERSION "ver" /* Event version */ -# define ETW_FIELD_TIME "time" /* Event time */ -# define ETW_FIELD_KIND "kind" /* Event kind (MsgPack) */ +# define ETW_FIELD_TIME "time" /* Event time at envelope */ +# define ETW_FIELD_KIND "kind" /* Event kind */ -/* Common TraceId constant to assoc events with trace parent */ -# define ETW_FIELD_TRACE_ID "TraceId" /* OT Trace Id */ +/* Common TraceId constant to associate events with a trace */ +# define ETW_FIELD_TRACE_ID "TraceId" /* Trace Id */ /* Span constants */ -# define ETW_FIELD_SPAN_ID "SpanId" /* OT Span Id */ -# define ETW_FIELD_SPAN_START "SpanStart" /* ETW for Span Start */ -# define ETW_FIELD_SPAN_END "SpanEnd" /* ETW for Span Start */ -# define ETW_FIELD_SPAN_LINKS "SpanLinks" /* OT Span Links array */ -# define ETW_FIELD_SPAN_ATTRIBS "SpanAttributes" /* OT Span Attribs array */ -# define ETW_FIELD_SPAN_PARENTID "SpanParentId" /* OT Span ParentId */ -# define ETW_FIELD_SPAN_KIND "SpanKind" +# define ETW_FIELD_SPAN_ID "SpanId" /* SpanId */ +# define ETW_FIELD_SPAN_KIND "SpanKind" /* SpanKind */ +# define ETW_FIELD_SPAN_LINKS "Links" /* Span Links array */ +# define ETW_FIELD_SPAN_PARENTID "ParentId" /* Span ParentId */ /* Span option constants */ -# define ETW_FIELD_STARTTIME "startTime" /* ETW event startTime */ -# define ETW_FIELD_DURATION "duration" /* OT Span or Op duration */ -# define ETW_FIELD_SUCCESS "success" /* OT Span success */ -# define ETW_FIELD_STATUSCODE "statusCode" /* OT Span status code */ +# define ETW_FIELD_STARTTIME "Time" /* Operation start time */ +# define ETW_FIELD_DURATION "Duration" /* Operation duration */ +# define ETW_FIELD_STATUSCODE "SpanStatusCode" /* OT Span status code */ + +/* Value constants */ +# define ETW_VALUE_SPAN_START "SpanStart" /* ETW for Span Start */ +# define ETW_VALUE_SPAN_END "SpanEnd" /* ETW for Span Start */ +# define ETW_VALUE_SUCCESS "Success" /* OT Span success */ -/* clang-format on */ #endif + +/* clang-format on */ From 48991c05032cbac31e29c700261761c01598aa8c Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Tue, 23 Mar 2021 01:05:23 -0700 Subject: [PATCH 46/76] ETW/MsgPack: Chunk Span Start, Span Event, Span Stop as individual ETW events instead of consolidating in a single tree. This is much more appropriate for heavily multi-threaded C++ apps, and provides predictable flow that may be subsequently reconstructed / consolidated into a single tree of spans by out-of-proc listener agent, e.g. by Azure Diagnostics EventFlow. --- .../exporters/etw/etw_provider.h | 99 +++++-------------- 1 file changed, 26 insertions(+), 73 deletions(-) diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h index 54810420bc..072af1a386 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h @@ -241,10 +241,10 @@ class ETWProvider T eventData, LPCGUID ActivityId = nullptr, LPCGUID RelatedActivityId = nullptr, - uint8_t Opcode = 0 /* Information */) + uint8_t Opcode = 0) { #ifdef HAVE_MSGPACK - // Make sure you stop sending event before register unregistering providerData + // Events can only be sent if provider is registered if (providerData.providerHandle == INVALID_HANDLE) { // Provider not registered! @@ -254,6 +254,19 @@ class ETWProvider std::string eventName = "NoName"; auto nameField = eventData[ETW_FIELD_NAME]; +# ifdef HAVE_FIELD_TIME + // Event time is appended by ETW layer itself by default. This code allows + // to override the timestamp by millisecond timestamp, in case if it has + // not been already provided by the upper layer. + if (!eventData.count(ETW_FIELD_TIME)) + { + // TODO: if nanoseconds resolution is required, then we can populate it in 96-bit MsgPack + // spec. auto nanos = + // std::chrono::duration_cast(now.time_since_epoch()).count(); + eventData[ETW_FIELD_TIME] = opentelemetry::utils::getUtcSystemTimeMs(); + } +# endif + switch (nameField.index()) { case common::AttributeType::TYPE_STRING: @@ -265,8 +278,7 @@ class ETWProvider break; # endif default: - // This is user error. Invalid event name! - // We supply default 'NoName' event name in this case. + // If invalid event name is supplied, then we replace it with 'NoName' break; } @@ -274,31 +286,7 @@ class ETWProvider nlohmann::json jObj = { { ETW_FIELD_NAME, eventName }, - { ETW_FIELD_VERSION, "4.0" }, - // - // TODO: compute time in MessagePack-friendly format - // TODO: should we consider uint64_t format with Unix timestamps for ELK stack? - { ETW_FIELD_TIME, - { - // TODO: timestamp - { "TypeCode", 255 }, - { "Body","0xFFFFFC60000000005F752C2C" } - } - }, -#if 0 - // TODO: follow JSON implementation of OTLP - { "env_dt_traceId", "6dcdae7b9b0c7643967d74ee54056178" }, - { "env_dt_spanId", "5866c4322919e641" }, -#endif - // - { ETW_FIELD_KIND, 0 }, - { ETW_FIELD_STARTTIME, - { - // TODO: timestamp - { "TypeCode", 255 }, - { "Body", "0xFFFF87CC000000005F752C2C" } - } - } + { ETW_FIELD_KIND, Opcode } }; /* clang-format on */ @@ -382,40 +370,7 @@ class ETWProvider } }; - // Layer 1 - nlohmann::json l1 = nlohmann::json::array(); - // Layer 2 - nlohmann::json l2 = nlohmann::json::array(); - // Layer 3 - nlohmann::json l3 = nlohmann::json::array(); - - l1.push_back("Span"); - - { - // TODO: clarify why this is needed - // TODO: fix time here - nlohmann::json j; - j["TypeCode"] = 255; - j["Body"] = "0xFFFFFC60000000005F752C2C"; - l3.push_back(j); - }; - - // Actual value object goes here - l3.push_back(jObj); - - l2.push_back(l3); - l1.push_back(l2); - - { - // Another time field again, but at the top - // TODO: fix time here - nlohmann::json j; - j["TypeCode"] = 255; - j["Body"] = "0xFFFFFC60000000005F752C2C"; - l1.push_back(j); - }; - - std::vector v = nlohmann::json::to_msgpack(l1); + std::vector v = nlohmann::json::to_msgpack(jObj); EVENT_DESCRIPTOR evtDescriptor; // TODO: event descriptor may be populated with additional values as follows: @@ -428,17 +383,15 @@ class ETWProvider EventDescCreate(&evtDescriptor, 0, 0x1, 0, 0, 0, Opcode, 0); EVENT_DATA_DESCRIPTOR evtData[1]; EventDataDescCreate(&evtData[0], v.data(), static_cast(v.size())); - ULONG writeResponse = 0; - if ((ActivityId != nullptr) || (RelatedActivityId != nullptr)) { - EventWriteTransfer(providerData.providerHandle, &evtDescriptor, ActivityId, RelatedActivityId, - 1, evtData); + writeResponse = EventWriteTransfer(providerData.providerHandle, &evtDescriptor, ActivityId, + RelatedActivityId, 1, evtData); } else { - EventWrite(providerData.providerHandle, &evtDescriptor, 1, evtData); + writeResponse = EventWrite(providerData.providerHandle, &evtDescriptor, 1, evtData); }; switch (writeResponse) @@ -495,7 +448,7 @@ class ETWProvider tld::EventMetadataBuilder> builder(byteVector); tld::EventDataBuilder> dbuilder(byteDataVector); - const std::string EVENT_NAME = "name"; + const std::string EVENT_NAME = ETW_FIELD_NAME; std::string eventName = "NoName"; auto nameField = eventData[EVENT_NAME]; switch (nameField.index()) @@ -643,10 +596,10 @@ class ETWProvider template unsigned long write(Handle &providerData, T eventData, - LPCGUID ActivityId = nullptr, - LPCGUID RelatedActivityId = nullptr, - uint8_t Opcode = 0, /* Information */ - ETWProvider::EventFormat format = ETWProvider::EventFormat::ETW_MANIFEST) + LPCGUID ActivityId, + LPCGUID RelatedActivityId, + uint8_t Opcode, + ETWProvider::EventFormat format) { if (format == ETWProvider::EventFormat::ETW_MANIFEST) { From 665422eaa8d7f34435ab25a10c62ad05d7f1df60 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 26 Mar 2021 14:06:04 -0700 Subject: [PATCH 47/76] Fix GMock linkage error on Windows Fix GMock linkage error on Windows. --- exporters/otlp/CMakeLists.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/exporters/otlp/CMakeLists.txt b/exporters/otlp/CMakeLists.txt index 876465ff0b..6fe35ec0c3 100644 --- a/exporters/otlp/CMakeLists.txt +++ b/exporters/otlp/CMakeLists.txt @@ -33,7 +33,14 @@ if(BUILD_TESTING) TARGET recordable_test TEST_PREFIX exporter.otlp. TEST_LIST recordable_test) - find_library(GMOCK_LIB gmock PATH_SUFFIXES lib) + if(MSVC) + add_definitions(-DGTEST_LINKED_AS_SHARED_LIBRARY=1) + endif() + if(MSVC AND CMAKE_BUILD_TYPE STREQUAL "Debug") + find_library(GMOCK_LIB gmockd PATH_SUFFIXES lib) + else() + find_library(GMOCK_LIB gmock PATH_SUFFIXES lib) + endif() if(GMOCK_LIB) add_executable(otlp_exporter_test test/otlp_exporter_test.cc) target_link_libraries( From f459bd3d94b47e3e3314855e824de5518be98ba9 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 26 Mar 2021 21:53:34 -0700 Subject: [PATCH 48/76] Addressing code review comments --- .github/CODEOWNERS | 6 +- .../common/key_value_iterable_view.h | 17 ++++- .../trace/span_context_kv_iterable.h | 24 +++++-- api/include/opentelemetry/trace/tracer.h | 10 ++- .../exporters/etw/etw_properties.h | 40 +++--------- .../opentelemetry/exporters/etw/etw_tracer.h | 62 ++++++++++++++++--- .../opentelemetry/exporters/etw/utils.h | 16 +++++ 7 files changed, 128 insertions(+), 47 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 99eaf7e2c9..7a40cd0b0e 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,6 +1,8 @@ # Code owners file. # This file controls who is tagged for review for any given pull request. -* @open-telemetry/cpp-approvers +# For ETW exporter +exporters/etw/* @reyang @maxgolov @lalitb @ThomsonTan @open-telemetry/cpp-approvers -/exporters/etw/ @reyang @maxgolov @lalitb @ThomsonTan +# For anything not explicitly taken by someone else: +* @open-telemetry/cpp-approvers diff --git a/api/include/opentelemetry/common/key_value_iterable_view.h b/api/include/opentelemetry/common/key_value_iterable_view.h index 837ec7b314..7ab4dac4bd 100644 --- a/api/include/opentelemetry/common/key_value_iterable_view.h +++ b/api/include/opentelemetry/common/key_value_iterable_view.h @@ -15,6 +15,12 @@ namespace detail { inline void take_key_value(nostd::string_view, common::AttributeValue) {} +template ::value>> +auto is_key_value_iterable_impl(T iterable) -> std::true_type{}; + +template ::value>> +auto is_key_value_iterable_impl(T iterable) -> std::true_type{}; + template auto is_key_value_iterable_impl(T iterable) -> decltype(take_key_value(std::begin(iterable)->first, std::begin(iterable)->second), @@ -30,10 +36,19 @@ struct is_key_value_iterable }; } // namespace detail +/** + * @brief Container for key-value pairs that can transform every value in it to one of types + * listed in common::AttributeValue. It may contain value types that are not directly map'able + * to primitive value types. In that case the `ForEachKeyValue` method acts as a transform to + * convert the value type to one listed under AtributeValue (bool, int32_t, int64_t, uint32_t, + * uint64_t, double, nostd::string_view, or arrays of primite types). For example, if UUID, + * GUID, or UTF-16 string type is passed as one of values stored inside this container, the + * container itself may provide a custom implementation of `ForEachKeyValue` to transform the + * 'non-standard' type to one of the standard types. + */ template class KeyValueIterableView final : public KeyValueIterable { - static_assert(detail::is_key_value_iterable::value, "Must be a key-value iterable"); public: explicit KeyValueIterableView(const T &container) noexcept : container_{&container} {} diff --git a/api/include/opentelemetry/trace/span_context_kv_iterable.h b/api/include/opentelemetry/trace/span_context_kv_iterable.h index 521108c754..ea316caf97 100644 --- a/api/include/opentelemetry/trace/span_context_kv_iterable.h +++ b/api/include/opentelemetry/trace/span_context_kv_iterable.h @@ -24,14 +24,28 @@ class SpanContextKeyValueIterable */ virtual bool ForEachKeyValue( nostd::function_ref - callback) const noexcept - { - return true; - }; + callback) const noexcept = 0; /** * @return the number of key-value pairs */ - virtual size_t size() const noexcept { return 0; }; + virtual size_t size() const noexcept = 0; }; + +/** + * @brief Null Span context that does not carry any information. + */ +class NullSpanContext : public SpanContextKeyValueIterable +{ +public: + bool ForEachKeyValue( + nostd::function_ref + callback) const noexcept override + { + return false; + } + + size_t size() const noexcept override { return 0; }; +}; + } // namespace trace OPENTELEMETRY_END_NAMESPACE diff --git a/api/include/opentelemetry/trace/tracer.h b/api/include/opentelemetry/trace/tracer.h index 974f0a84e3..e358100f4f 100644 --- a/api/include/opentelemetry/trace/tracer.h +++ b/api/include/opentelemetry/trace/tracer.h @@ -43,7 +43,8 @@ class Tracer return this->StartSpan(name, {}, {}, options); } - template + template ::value> * = nullptr> nostd::shared_ptr StartSpan(nostd::string_view name, const T &attributes, const StartSpanOptions &options = {}) noexcept @@ -51,6 +52,13 @@ class Tracer return this->StartSpan(name, attributes, {}, options); } + nostd::shared_ptr StartSpan(nostd::string_view name, + const common::KeyValueIterable &attributes, + const StartSpanOptions &options = {}) noexcept + { + return this->StartSpan(name, attributes, NullSpanContext(), options); + } + template ::value> * = nullptr, diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h index 03fae33a78..3443bc46ad 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h @@ -23,10 +23,6 @@ #include OPENTELEMETRY_BEGIN_NAMESPACE -namespace core -{}; -namespace trace -{}; namespace exporter { namespace ETW @@ -75,20 +71,19 @@ class PropertyValue : public PropertyVariant * @return */ template - static std::vector to_vector(const nostd::span &source) + static std::vector to_vector(const nostd::span &source) { return std::vector(source.begin(), source.end()); }; /** * @brief Convert span to vector - * @param source - * @return + * @param source Span of non-owning string views. + * @return Vector of owned strings. */ std::vector static to_vector(const nostd::span &source) { - std::vector result; - result.reserve(source.size()); + std::vector result(source.size()); for (const auto &item : source) { result.push_back(std::string(item.data())); @@ -98,9 +93,9 @@ class PropertyValue : public PropertyVariant /** * @brief Convert vector to span. - * @tparam T - * @param std::vector - * @return nostd::span + * @tparam T Integral type + * @param vec Vector of integral type primitives to convert to span. + * @return Span of integral type primitives. */ template ::value, bool> = true> static nostd::span to_span(const std::vector &vec) @@ -111,9 +106,9 @@ class PropertyValue : public PropertyVariant /** * @brief Convert vector to span. - * @tparam T - * @param std::vector - * @return nostd::span + * @tparam T Float type + * @param vec Vector of float type primitives to convert to span. + * @return Span of float type primitives. */ template ::value, bool> = true> static nostd::span to_span(const std::vector &vec) @@ -122,21 +117,6 @@ class PropertyValue : public PropertyVariant return result; }; -#if 0 - /** - * @brief Convert vector to span. - * FIXME: std::vector is a special compact type that does not have .data() member - * - * @param v - * @return - */ - static nostd::span to_span(const std::vector &vec) - { - nostd::span result(vec.data(), vec.size()); - return result; - }; -#endif - public: /** * @brief PropertyValue from bool diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h index 0eb6404f27..404386d062 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h @@ -356,6 +356,33 @@ class Tracer : public trace::Tracer const trace::SpanContextKeyValueIterable &links, const trace::StartSpanOptions &options = {}) noexcept override { +#ifdef RTTI_ENABLED + 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 + return StartSpan(name, *evt, links, options); + } +#endif + Properties evtCopy = attributes; + return StartSpan(name, evtCopy, links, options); + } + + /** + * @brief Start Span + * @param name Span name + * @param attributes Span attributes + * @param links Span links + * @param options Span options + * @return + */ + virtual nostd::shared_ptr StartSpan( + nostd::string_view name, + Properties &evt, + const trace::SpanContextKeyValueIterable &links, + const trace::StartSpanOptions &options = {}) noexcept + { const auto &cfg = GetConfiguration(tracerProvider_); // Parent Context: @@ -364,9 +391,6 @@ class Tracer : public trace::Tracer const auto parentContext = (options.parent.IsValid()) ? options.parent : GetCurrentSpan()->GetContext(); - // Copy Span attributes to event Payload - Properties evt = attributes; - // Populate Etw.RelatedActivityId at envelope level if enabled GUID RelatedActivityId; LPCGUID RelatedActivityIdPtr = nullptr; @@ -475,6 +499,33 @@ class Tracer : public trace::Tracer core::SystemTimestamp timestamp, const common::KeyValueIterable &attributes) noexcept { +#ifdef RTTI_ENABLED + 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 + return AddEvent(span, name, timestamp, *evt); + } +#endif + // Pass a copy converted to Properties object on stack + Properties evtCopy = attributes; + return AddEvent(span, name, timestamp, evtCopy); + } + + /** + * @brief Add event data to span associated with tracer. + * @param span Parent span. + * @param name Event name. + * @param timestamp Event timestamp. + * @param attributes Event attributes. + * @return + */ + void AddEvent(trace::Span &span, + nostd::string_view name, + core::SystemTimestamp timestamp, + Properties &evt) noexcept + { // TODO: respect originating timestamp. Do we need to reserve // a special 'Timestamp' field or is it an overkill? The delta // between when `AddEvent` API is called and when ETW layer @@ -487,11 +538,6 @@ class Tracer : public trace::Tracer const auto &cfg = GetConfiguration(tracerProvider_); - // OPTIMIZATION OPPORTUNITY: Event properties assigned from attributes. - // If we know that the parameter is of non-const container type `Properties`, - // then we can append more to container and avoid the memcpy entirely. - Properties evt = attributes; - evt[ETW_FIELD_NAME] = name.data(); const auto &spanContext = span.GetContext(); diff --git a/exporters/etw/include/opentelemetry/exporters/etw/utils.h b/exporters/etw/include/opentelemetry/exporters/etw/utils.h index b76c95f2c1..384357fb93 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/utils.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/utils.h @@ -36,6 +36,22 @@ # pragma comment(lib, "Ole32.Lib") #endif +#ifndef RTTI_ENABLED +# if defined(__clang__) +# if __has_feature(cxx_rtti) +# define RTTI_ENABLED +# endif +# elif defined(__GNUG__) +# if defined(__GXX_RTTI) +# define RTTI_ENABLED +# endif +# elif defined(_MSC_VER) +# if defined(_CPPRTTI) +# define RTTI_ENABLED +# endif +# endif +#endif + OPENTELEMETRY_BEGIN_NAMESPACE namespace utils From 4fd552881355e33dce37f8580a08811b03232e2e Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 26 Mar 2021 22:22:20 -0700 Subject: [PATCH 49/76] Remove unused templates --- api/include/opentelemetry/common/key_value_iterable_view.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/api/include/opentelemetry/common/key_value_iterable_view.h b/api/include/opentelemetry/common/key_value_iterable_view.h index 7ab4dac4bd..25734fff6d 100644 --- a/api/include/opentelemetry/common/key_value_iterable_view.h +++ b/api/include/opentelemetry/common/key_value_iterable_view.h @@ -15,12 +15,6 @@ namespace detail { inline void take_key_value(nostd::string_view, common::AttributeValue) {} -template ::value>> -auto is_key_value_iterable_impl(T iterable) -> std::true_type{}; - -template ::value>> -auto is_key_value_iterable_impl(T iterable) -> std::true_type{}; - template auto is_key_value_iterable_impl(T iterable) -> decltype(take_key_value(std::begin(iterable)->first, std::begin(iterable)->second), From da56e3e21974920c5e5320e52b003601a3c328e8 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Mon, 29 Mar 2021 19:31:53 -0700 Subject: [PATCH 50/76] Add benchmark to compare Properties vs initializer list vs unordered_map events --- exporters/etw/CMakeLists.txt | 5 + exporters/etw/test/etw_perf_test.cc | 202 ++++++++++++++++++++++++++++ 2 files changed, 207 insertions(+) create mode 100644 exporters/etw/test/etw_perf_test.cc diff --git a/exporters/etw/CMakeLists.txt b/exporters/etw/CMakeLists.txt index 63b6205fbe..dab76bc5b6 100644 --- a/exporters/etw/CMakeLists.txt +++ b/exporters/etw/CMakeLists.txt @@ -4,6 +4,7 @@ include_directories(include if(BUILD_TESTING) add_executable(etw_provider_test test/etw_provider_test.cc) add_executable(etw_tracer_test test/etw_tracer_test.cc) + add_executable(etw_perf_test test/etw_perf_test.cc) target_link_libraries(etw_provider_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) @@ -11,6 +12,9 @@ if(BUILD_TESTING) target_link_libraries(etw_tracer_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) + target_link_libraries(etw_perf_test benchmark::benchmark + ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) + gtest_add_tests( TARGET etw_provider_test TEST_PREFIX exporter. @@ -19,4 +23,5 @@ if(BUILD_TESTING) TARGET etw_tracer_test TEST_PREFIX exporter. TEST_LIST etw_tracer_test) + endif() # BUILD_TESTING diff --git a/exporters/etw/test/etw_perf_test.cc b/exporters/etw/test/etw_perf_test.cc new file mode 100644 index 0000000000..92a7e082ba --- /dev/null +++ b/exporters/etw/test/etw_perf_test.cc @@ -0,0 +1,202 @@ +// Copyright 2021, OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifdef _WIN32 + +# include +# include +# include +# include +# include + +# include "opentelemetry/exporters/etw/etw_tracer_exporter.h" +# include "opentelemetry/sdk/trace/simple_processor.h" + +using namespace OPENTELEMETRY_NAMESPACE; + +using Properties = opentelemetry::exporter::ETW::Properties; +using PropertyValue = opentelemetry::exporter::ETW::PropertyValue; +using PropertyValueMap = opentelemetry::exporter::ETW::PropertyValueMap; + +namespace +{ +static constexpr const char *providerName = "OpenTelemetry-ETW-StressTest"; + +static exporter::ETW::TracerProviderOptions providerOptions = {{"enableTraceId", false}, + {"enableSpanId", false}, + {"enableActivityId", false}, + {"enableRelatedActivityId", false}, + {"enableAutoParent", false}}; + +class ETWProviderStressTest +{ + exporter::ETW::TracerProvider provider_; + std::string mode_; + nostd::shared_ptr tracer_; + nostd::shared_ptr span_; + +public: + /** + * @brief Construct ETW Provider stress test object + * @param mode Operational mode: "TLD" or "MsgPack" + */ + ETWProviderStressTest(std::string mode = "TLD") : mode_(mode), provider_(providerOptions) {} + + /** + * @brief Initializer tracer and start a Span + */ + void Initialize() + { + tracer_ = provider_.GetTracer(providerName, mode_); + span_ = tracer_->StartSpan("Span"); + } + + /** + * @brief Obtain the tracer + */ + nostd::shared_ptr GetTracer() { return tracer_; } + + /** + * @brief Add event using Properties container + */ + bool AddProperties() + { + std::string eventName = "MyEvent"; + Properties event = {{"uint32Key", (uint32_t)1234}, + {"uint64Key", (uint64_t)1234567890}, + {"strKey", "someValue"}}; + span_->AddEvent(eventName, event); + return true; + } + + /** + * @brief Add event using static preallocated "reusable" Properties container. + * This approach works well for single-threaded flows, but may not be safe in + * some multithreaded scenarios in case if reusable `Properties` get concurrently + * modified by different threads (writes to Properties are not thread-safe). + */ + bool AddPropertiesStatic() + { + std::string eventName = "MyEvent"; + static Properties event = {{"uint32Key", (uint32_t)1234}, + {"uint64Key", (uint64_t)1234567890}, + {"strKey", "someValue"}}; + span_->AddEvent(eventName, event); + return true; + } + + /** + * @brief Add event using initializer list + */ + bool AddInitList() + { + std::string eventName = "MyEvent"; + span_->AddEvent(eventName, {{"uint32Key", (uint32_t)1234}, + {"uint64Key", (uint64_t)1234567890}, + {"strKey", "someValue"}}); + return true; + } + + /** + * @brief Add event using unordered_map + */ + bool AddMap() + { + std::string eventName = "MyEvent"; + std::unordered_map m = { + {"uint32Key", (uint32_t)1234}, + {"uint64Key", (uint64_t)1234567890}, + {"strKey", "someValue"}}; + span_->AddEvent(eventName, m); + return true; + } + + /** + * @brief End Span and close tracer. + */ + void Teardown() + { + span_->End(); + tracer_->CloseWithMicroseconds(0); + } +}; + +ETWProviderStressTest provider; + +/** + * @brief Create Properties and AddEvent(Properties) to Tracer + * @param state Benchmark state. + */ +void BM_AddPropertiesToTracer(benchmark::State &state) +{ + provider.Initialize(); + while (state.KeepRunning()) + { + benchmark::DoNotOptimize(provider.AddProperties()); + }; + provider.Teardown(); +} +BENCHMARK(BM_AddPropertiesToTracer); + +/** + * @brief Create static Properties and AddEvent(Properties) to Tracer + * @param state Benchmark state. + */ +void BM_AddPropertiesStaticToTracer(benchmark::State &state) +{ + provider.Initialize(); + while (state.KeepRunning()) + { + benchmark::DoNotOptimize(provider.AddPropertiesStatic()); + }; + provider.Teardown(); +} +BENCHMARK(BM_AddPropertiesStaticToTracer); + +/** + * @brief Create event via initializer list and AddEvent({...}) to Tracer + * @param state Benchmark state. + */ +void BM_AddInitListToTracer(benchmark::State &state) +{ + provider.Initialize(); + while (state.KeepRunning()) + { + benchmark::DoNotOptimize(provider.AddInitList()); + }; + provider.Teardown(); +} +BENCHMARK(BM_AddInitListToTracer); + +/** + * @brief Create event as `std::map` + * and AddEvent(event) to Tracer. + * @param state Benchmark state. + */ +void BM_AddMapToTracer(benchmark::State &state) +{ + provider.Initialize(); + while (state.KeepRunning()) + { + benchmark::DoNotOptimize(provider.AddMap()); + }; + provider.Teardown(); +} +BENCHMARK(BM_AddMapToTracer); + +} // namespace + +BENCHMARK_MAIN(); + +#endif \ No newline at end of file From 127f14968208e893f83b3e47fcc21e3523c336dc Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Wed, 31 Mar 2021 09:28:40 -0700 Subject: [PATCH 51/76] Update exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h Co-authored-by: Tom Tan --- .../etw/include/opentelemetry/exporters/etw/etw_provider.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h index 072af1a386..f8ecbb630e 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h @@ -579,7 +579,7 @@ class ETWProvider writeResponse = tld::WriteEvent(providerData.providerHandle, eventDescriptor, providerData.providerMetaVector.data(), byteVector.data(), 3, pDataDescriptors); - }; + } // Event is larger than ETW max sized of 64KB if (writeResponse == HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW)) From b78797fa9ab39e52a49d41146920b4052ecb49b5 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Wed, 31 Mar 2021 21:58:43 -0700 Subject: [PATCH 52/76] Revert "Find GTest via CONFIG mode to reference gmock (#640)" This reverts commit 3ddda3ccfb844f480026dc0a9a6c6d0f07ac88ab. --- CMakeLists.txt | 16 ++++++---------- exporters/otlp/CMakeLists.txt | 31 +++++++++++++++++++++++-------- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f34548c59c..2f5968b3ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -180,21 +180,17 @@ if(BUILD_TESTING) ${CMAKE_BINARY_DIR}/lib/libgmock.a) elseif(WIN32) # Make sure we are always bootsrapped with vcpkg on Windows - find_package(GTest CONFIG) - if(NOT GTest_FOUND) + find_package(GTest) + if(NOT GTEST_FOUND) install_windows_deps() - find_package(GTest CONFIG REQUIRED) + find_package(GTest REQUIRED) endif() - set(GTEST_BOTH_LIBRARIES GTest::gtest GTest::gtest_main GTest::gmock) else() # Prefer GTest installed by OS distro, brew or vcpkg package manager - find_package(GTest CONFIG REQUIRED) - set(GTEST_BOTH_LIBRARIES GTest::gtest GTest::gtest_main GTest::gmock) - endif() - if(GTEST_INCLUDE_DIRS) - include_directories(SYSTEM ${GTEST_INCLUDE_DIRS}) - message("GTEST_INCLUDE_DIRS = ${GTEST_INCLUDE_DIRS}") + find_package(GTest REQUIRED) endif() + include_directories(SYSTEM ${GTEST_INCLUDE_DIRS}) + message("GTEST_INCLUDE_DIRS = ${GTEST_INCLUDE_DIRS}") message("GTEST_BOTH_LIBRARIES = ${GTEST_BOTH_LIBRARIES}") enable_testing() # Benchmark respects the CMAKE_PREFIX_PATH diff --git a/exporters/otlp/CMakeLists.txt b/exporters/otlp/CMakeLists.txt index daf93be9d0..6fe35ec0c3 100644 --- a/exporters/otlp/CMakeLists.txt +++ b/exporters/otlp/CMakeLists.txt @@ -33,12 +33,27 @@ if(BUILD_TESTING) TARGET recordable_test TEST_PREFIX exporter.otlp. TEST_LIST recordable_test) - add_executable(otlp_exporter_test test/otlp_exporter_test.cc) - target_link_libraries( - otlp_exporter_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} - opentelemetry_exporter_otprotocol protobuf::libprotobuf gRPC::grpc++) - gtest_add_tests( - TARGET otlp_exporter_test - TEST_PREFIX exporter.otlp. - TEST_LIST otlp_exporter_test) + if(MSVC) + add_definitions(-DGTEST_LINKED_AS_SHARED_LIBRARY=1) + endif() + if(MSVC AND CMAKE_BUILD_TYPE STREQUAL "Debug") + find_library(GMOCK_LIB gmockd PATH_SUFFIXES lib) + else() + find_library(GMOCK_LIB gmock PATH_SUFFIXES lib) + endif() + if(GMOCK_LIB) + add_executable(otlp_exporter_test test/otlp_exporter_test.cc) + target_link_libraries( + otlp_exporter_test + ${GTEST_BOTH_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT} + opentelemetry_exporter_otprotocol + ${GMOCK_LIB} + protobuf::libprotobuf + gRPC::grpc++) + gtest_add_tests( + TARGET otlp_exporter_test + TEST_PREFIX exporter.otlp. + TEST_LIST otlp_exporter_test) + endif() endif() # BUILD_TESTING From a683ed5308cce84675d6e2c2f39ed22403218adf Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Wed, 31 Mar 2021 23:26:50 -0700 Subject: [PATCH 53/76] Add time formatting utility --- .../opentelemetry/exporters/etw/utils.h | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/exporters/etw/include/opentelemetry/exporters/etw/utils.h b/exporters/etw/include/opentelemetry/exporters/etw/utils.h index 384357fb93..6ffdcd1ae0 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/utils.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/utils.h @@ -259,6 +259,35 @@ int64_t getUtcSystemTimeinTicks() #endif } +std::string formatUtcTimestampMsAsISO8601(int64_t timestampMs) +{ + char buf[sizeof("YYYY-MM-DDTHH:MM:SS.sssZ") + 1] = {0}; +#ifdef _WIN32 + __time64_t seconds = static_cast<__time64_t>(timestampMs / 1000); + int milliseconds = static_cast(timestampMs % 1000); + tm tm; + if (::_gmtime64_s(&tm, &seconds) != 0) + { + memset(&tm, 0, sizeof(tm)); + } + ::_snprintf_s(buf, _TRUNCATE, "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", 1900 + tm.tm_year, + 1 + tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, milliseconds); +#else + time_t seconds = static_cast(timestampMs / 1000); + int milliseconds = static_cast(timestampMs % 1000); + tm tm; + bool valid = (gmtime_r(&seconds, &tm) != NULL); + if (!valid) + { + memset(&tm, 0, sizeof(tm)); + } + (void)snprintf(buf, sizeof(buf), "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", 1900 + tm.tm_year, + 1 + tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, milliseconds); +#endif + return buf; +} + + }; // namespace utils OPENTELEMETRY_END_NAMESPACE From 1db003ecdeaab41d54d0a0ede56d6c424e2f0a0b Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Wed, 31 Mar 2021 23:27:53 -0700 Subject: [PATCH 54/76] Rename 'kind' field to 'OpCode' (start or stop) --- .../etw/include/opentelemetry/exporters/etw/etw_provider.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h index f8ecbb630e..6150029c8c 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h @@ -286,7 +286,7 @@ class ETWProvider nlohmann::json jObj = { { ETW_FIELD_NAME, eventName }, - { ETW_FIELD_KIND, Opcode } + { ETW_FIELD_OPCODE, Opcode } }; /* clang-format on */ From 3a7831ac1022c8092b4e7ab170c0955bd93a1730 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Thu, 1 Apr 2021 01:27:36 -0700 Subject: [PATCH 55/76] Tests are no longer included in Windows build --- CMakeLists.txt | 2 +- exporters/otlp/CMakeLists.txt | 23 ++++++++--------------- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f5968b3ba..8a9b387ba9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -181,7 +181,7 @@ if(BUILD_TESTING) elseif(WIN32) # Make sure we are always bootsrapped with vcpkg on Windows find_package(GTest) - if(NOT GTEST_FOUND) + if(NOT (GTEST_FOUND OR GTest_FOUND)) install_windows_deps() find_package(GTest REQUIRED) endif() diff --git a/exporters/otlp/CMakeLists.txt b/exporters/otlp/CMakeLists.txt index 6fe35ec0c3..538ae8ea5f 100644 --- a/exporters/otlp/CMakeLists.txt +++ b/exporters/otlp/CMakeLists.txt @@ -41,19 +41,12 @@ if(BUILD_TESTING) else() find_library(GMOCK_LIB gmock PATH_SUFFIXES lib) endif() - if(GMOCK_LIB) - add_executable(otlp_exporter_test test/otlp_exporter_test.cc) - target_link_libraries( - otlp_exporter_test - ${GTEST_BOTH_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT} - opentelemetry_exporter_otprotocol - ${GMOCK_LIB} - protobuf::libprotobuf - gRPC::grpc++) - gtest_add_tests( - TARGET otlp_exporter_test - TEST_PREFIX exporter.otlp. - TEST_LIST otlp_exporter_test) - endif() + add_executable(otlp_exporter_test test/otlp_exporter_test.cc) + target_link_libraries( + otlp_exporter_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${GMOCK_LIB} + opentelemetry_exporter_otprotocol protobuf::libprotobuf gRPC::grpc++) + gtest_add_tests( + TARGET otlp_exporter_test + TEST_PREFIX exporter.otlp. + TEST_LIST otlp_exporter_test) endif() # BUILD_TESTING From b0c31bf9af0132c61ad52ded592dcdb43997bf8d Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Thu, 1 Apr 2021 01:29:36 -0700 Subject: [PATCH 56/76] New feature to consolidate all Span info on end of Span into separate `Span` event --- .../opentelemetry/exporters/etw/etw_fields.h | 115 ++++++++-- .../opentelemetry/exporters/etw/etw_tracer.h | 210 ++++++++++++++++-- exporters/etw/test/etw_tracer_test.cc | 1 + 3 files changed, 288 insertions(+), 38 deletions(-) diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_fields.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_fields.h index 9fcb6b694e..017d3e4cfe 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_fields.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_fields.h @@ -20,36 +20,111 @@ /* clang-format off */ #ifdef CUSTOM_ETW_FIELDS_H +/* Customers may redefine the default field names by including CUSTOM_ETW_FIELDS_H header */ # include CUSTOM_ETW_FIELDS_H #else -/* ETW constants at envelope level that would be appended at different spot depending - * on what serializer used to encode the payload +/** + + List of configurable Field Name constants: + + Version - Schema version (optional for ETW exporter). + _name - Built-in ETW name at envelope level (dedicated ETW field). + _time - Built-in ETW time at envelope level (dedicated ETW field). + SpanId - OT SpanId + TraceId - OT TraceId + StartTime - OT Span start time + Kind - OT Span kind + Name - OT Span name in ETW 'Payload["Name"]' + ParentId - OT Span parentId + Links - OT Span links array + + Other standard fields (reserved names) that may be appended by ETW channel: + + Level - a 1-byte integer that enables filtering based on the severity or verbosity of events + ProviderGuid - ETW Provider Guid + ProviderName - ETW Provider Name + OpcodeName - Name of Opcode (e.g. Start, Stop) + KeywordName - Name of Keyword + TaskName - TaskName, could be handled as an alias to Payload['name'] + ChannelName - ETW Channel Name + EventMessage - ETW Event Message string for unstructured events + ActivityId - ActivityId for EventSource parenting (current event) + RelatedActivityId - RelatedActivityId for EventSource parenting (parent event) + Pid - Process Id + Tid - Thread Id + + Example "Span" as shown in Visual Studio "Diagnostic Events" view. EventName="Span": + + { + "Timestamp": "2021-04-01T00:33:25.5876605-07:00", + "ProviderName": "OpenTelemetry-ETW-TLD", + "Id": 20, + "Message": null, + "ProcessId": 10424, + "Level": "Always", + "Keywords": "0x0000000000000000", + "EventName": "Span", + "ActivityID": "56f2366b-5475-496f-0000-000000000000", + "RelatedActivityID": null, + "Payload": { + "Duration": 0, + "Name": "B.max", + "ParentId": "8ad900d0587fad4a", + "SpanId": "6b36f25675546f49", + "StartTime": "2021-04-01T07:33:25.587Z", + "TraceId": "8f8ac710c37c5a419f0fe574f335e986" + } + } + + Example named Event on Span. Note that EventName="MyEvent2" in this case: + + { + "Timestamp": "2021-04-01T00:33:22.5848789-07:00", + "ProviderName": "OpenTelemetry-ETW-TLD", + "Id": 15, + "Message": null, + "ProcessId": 10424, + "Level": "Always", + "Keywords": "0x0000000000000000", + "EventName": "MyEvent2", + "ActivityID": null, + "RelatedActivityID": null, + "Payload": { + "SpanId": "0da9f6bf7524a449", + "TraceId": "7715c9d490f54f44a5d0c6b62570f1b2", + "strKey": "anotherValue", + "uint32Key": 9876, + "uint64Key": 987654321 + } + } + */ -# define ETW_FIELD_NAME "name" /* Event name */ -# define ETW_FIELD_TYPE "type" /* Event type */ -# define ETW_FIELD_VERSION "ver" /* Event version */ -# define ETW_FIELD_TIME "time" /* Event time at envelope */ -# define ETW_FIELD_KIND "kind" /* Event kind */ +# define ETW_FIELD_VERSION "Version" /* Event version */ +# define ETW_FIELD_TYPE "Type" /* Event type */ +# define ETW_FIELD_NAME "_name" /* Event name */ +# define ETW_FIELD_TIME "_time" /* Event time */ +# define ETW_FIELD_OPCODE "OpCode" /* OpCode for TraceLogging */ -/* Common TraceId constant to associate events with a trace */ -# define ETW_FIELD_TRACE_ID "TraceId" /* Trace Id */ +# define ETW_FIELD_TRACE_ID "TraceId" /* Trace Id */ +# define ETW_FIELD_SPAN_ID "SpanId" /* Span Id */ +# define ETW_FIELD_SPAN_PARENTID "ParentId" /* Span ParentId */ +# define ETW_FIELD_SPAN_KIND "Kind" /* Span Kind */ +# define ETW_FIELD_SPAN_LINKS "Links" /* Span Links array */ -/* Span constants */ -# define ETW_FIELD_SPAN_ID "SpanId" /* SpanId */ -# define ETW_FIELD_SPAN_KIND "SpanKind" /* SpanKind */ -# define ETW_FIELD_SPAN_LINKS "Links" /* Span Links array */ -# define ETW_FIELD_SPAN_PARENTID "ParentId" /* Span ParentId */ +# define ETW_FIELD_PAYLOAD_NAME "Name" /* ETW Payload["Name"] */ /* Span option constants */ -# define ETW_FIELD_STARTTIME "Time" /* Operation start time */ -# define ETW_FIELD_DURATION "Duration" /* Operation duration */ -# define ETW_FIELD_STATUSCODE "SpanStatusCode" /* OT Span status code */ +# define ETW_FIELD_STARTTIME "StartTime" /* Operation start time */ +# define ETW_FIELD_DURATION "Duration" /* Operation duration */ +# define ETW_FIELD_STATUSCODE "StatusCode" /* Span status code */ +# define ETW_FIELD_STATUSMESSAGE "StatusMessage" /* Span status message */ +# define ETW_FIELD_SUCCESS "Success" /* Span success */ /* Value constants */ -# define ETW_VALUE_SPAN_START "SpanStart" /* ETW for Span Start */ -# define ETW_VALUE_SPAN_END "SpanEnd" /* ETW for Span Start */ -# define ETW_VALUE_SUCCESS "Success" /* OT Span success */ +# define ETW_VALUE_SPAN "Span" /* ETW event name for Span */ +# define ETW_VALUE_SPAN_START "SpanStart" /* ETW for Span Start */ +# define ETW_VALUE_SPAN_END "SpanEnd" /* ETW for Span Start */ #endif diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h index 404386d062..97324b60f3 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h @@ -75,6 +75,7 @@ typedef struct bool enableTraceId; // Set `TraceId` on ETW events bool enableSpanId; // Set `SpanId` on ETW events bool enableActivityId; // Assign `SpanId` to `ActivityId` + bool enableActivityTracking; // Emit TraceLogging events for Span/Start and Span/Stop bool enableRelatedActivityId; // Assign parent `SpanId` to `RelatedActivityId` bool enableAutoParent; // Start new spans as children of current active span } TracerProviderConfiguration; @@ -107,13 +108,42 @@ static inline void GetOption(const TracerProviderOptions &options, } class Span; + +/** + * @brief Template that allows to instantiate new Span object for header-only forward-declared ETW::Span type + * + * @tparam SpanType Expected to be ETW::Span + * @tparam TracerType expected to be ETW::Tracer + * @param objPtr Pointer to parent + * @param name Span Name + * @param options Span Options + * @return Span instance +*/ +template +SpanType* new_span(TracerType *objPtr, nostd::string_view name, const trace::StartSpanOptions &options) +{ + return new (std::nothrow) SpanType{*objPtr, name, options}; +} + +/** + * @brief Template that allows to convert ETW::Span pointer to smart shared pointer to `trace::Span` + * @tparam SpanType Expected to be ETW::Span + * @param ptr Pointer to ETW::Span + * @return Smart shared pointer to `trace::Span` +*/ +template +nostd::shared_ptr to_span_ptr(SpanType *ptr) +{ + return nostd::shared_ptr{ptr}; +} + class TracerProvider; /** - * @brief Utility template for Span.GetName() - * @tparam T - * @param t - * @return + * @brief Utility template for obtaining Span Name + * @tparam T ETW::Span + * @param t instance of ETW::Span + * @return Span Name */ template std::string GetName(T &t) @@ -123,7 +153,57 @@ std::string GetName(T &t) } /** - * @brief Utility template for forward-declaration of ETW::TracerProvider._config + * @brief Utility template to obtain Span start time + * @tparam T ETW::Span + * @param t instance of ETW::Span + * @return Span Start timestamp +*/ +template +core::SystemTimestamp GetStartTime(T &t) +{ + return t.GetStartTime(); +} + +/** + * @brief Utility template to obtain Span end time + * @tparam T ETW::Span + * @param t instance of ETW::Span + * @return Span Stop timestamp +*/ +template +core::SystemTimestamp GetEndTime(T &t) +{ + return t.GetEndTime(); +} + +class Properties; + +/** + * @brief Utility template to store Attributes on Span + * @tparam T ETW::Span + * @param instance instance of ETW::Span + * @param t Properties to store as Attributes +*/ +template +void SetSpanAttributes(T& instance, Properties &t) +{ + instance.SetAttributes(t); +} + +/** + * @brief Utility template to obtain Span Attributes + * @tparam T ETW::Span + * @param instance instance of ETW::Span + * @return ref to Span Attributes +*/ +template +Properties& GetSpanAttributes(T &instance) +{ + return instance.GetAttributes(); +} + +/** + * @brief Utility template to obtain ETW::TracerProvider._config * * @tparam T ETW::TracerProvider * @param t ETW::TracerProvider ref @@ -247,7 +327,9 @@ class Tracer : public trace::Tracer const trace::Span &spanBase = reinterpret_cast(span); auto spanContext = spanBase.GetContext(); - Properties evt; + // Populate Span with presaved attributes + Span ¤tSpan = const_cast(span); + Properties evt = GetSpanAttributes(currentSpan); evt[ETW_FIELD_NAME] = GetName(span); if (cfg.enableSpanId) @@ -285,9 +367,40 @@ class Tracer : public trace::Tracer } } - // TODO: check what EndSpanOptions should be supported for this exporter. - // The only option available currently (end_steady_time) does not apply. - etwProvider().write(provHandle, evt, ActivityIdPtr, RelatedActivityIdPtr, 2, encoding); + if (cfg.enableActivityTracking) + { + // TODO: check what EndSpanOptions should be supported for this exporter. + // The only option available currently (end_steady_time) does not apply. + // + // This event on Span Stop enables generation of "non-transactional" + // OpCode=Stop in alignment with TraceLogging Activity "EventSource" + // spec. + etwProvider().write(provHandle, evt, ActivityIdPtr, RelatedActivityIdPtr, 2, encoding); + } + + { + // Now since the span has ended, we need to emit the "Span" event that + // contains the entire span information, attributes, time, etc. on it. + evt[ETW_FIELD_NAME] = ETW_VALUE_SPAN; + evt[ETW_FIELD_PAYLOAD_NAME] = GetName(span); + + // Add timing details in ISO8601 format, which adequately represents + // the actual time, taking Timezone into consideration. This is NOT + // local time, but rather UTC time (Z=0). + std::chrono::system_clock::time_point startTime = GetStartTime(currentSpan); + std::chrono::system_clock::time_point endTime = GetEndTime(currentSpan); + int64_t startTimeMs = std::chrono::duration_cast(startTime.time_since_epoch()).count(); + int64_t endTimeMs = std::chrono::duration_cast(endTime.time_since_epoch()).count(); + + // It may be more optimal to enable passing timestamps as UTC milliseconds + // since Unix epoch instead of string, but that implies additional tooling + // is needed to convert it, rendering it NOT human-readable. + evt[ETW_FIELD_STARTTIME] = utils::formatUtcTimestampMsAsISO8601(startTimeMs); + + // Duration of Span in milliseconds + evt[ETW_FIELD_DURATION] = endTimeMs - startTimeMs; + etwProvider().write(provHandle, evt, ActivityIdPtr, RelatedActivityIdPtr, 0, encoding); + } { // Atomically remove the span from list of spans @@ -405,8 +518,12 @@ class Tracer : public trace::Tracer } } - nostd::shared_ptr result = trace::to_span_ptr(this, name, options); - auto spanContext = result->GetContext(); + // This template pattern allows us to forward-declare the ETW::Span, + // create an instance of it, then assign it to tracer::Span result. + auto currentSpan = new_span(this, name, options); + nostd::shared_ptr result = to_span_ptr(currentSpan); + + auto spanContext = result->GetContext(); // Decorate with additional standard fields std::string eventName = name.data(); @@ -445,11 +562,17 @@ class Tracer : public trace::Tracer // Links DecorateLinks(evt, links); - // TODO: add support for options that are presently ignored : - // - options.kind - // - options.start_steady_time - // - options.start_system_time - etwProvider().write(provHandle, evt, ActivityIdPtr, RelatedActivityIdPtr, 1, encoding); + // Remember Span attributes to be passed down to ETW on Span end + SetSpanAttributes(*currentSpan, evt); + + if (cfg.enableActivityTracking) + { + // TODO: add support for options that are presently ignored : + // - options.kind + // - options.start_steady_time + // - options.start_system_time + etwProvider().write(provHandle, evt, ActivityIdPtr, RelatedActivityIdPtr, 1, encoding); + }; { const std::lock_guard lock(scopes_mutex_); @@ -598,6 +721,17 @@ class Tracer : public trace::Tracer class Span : public trace::Span { protected: + + friend class Tracer; + + /** + * @brief Span properties are attached on "Span" event on end of Span. + */ + Properties attributes_; + + core::SystemTimestamp start_time_; + core::SystemTimestamp end_time_; + /** * @brief Owner Tracer of this Span */ @@ -649,6 +783,19 @@ class Span : public trace::Span } public: + + /** + * @brief Get start time of this Span. + * @return + */ + core::SystemTimestamp GetStartTime() { return start_time_; } + + /** + * @brief Get end time of this Span. + * @return + */ + core::SystemTimestamp GetEndTime() { return end_time_; } + /** * @brief Get Span Name. * @return Span Name. @@ -667,7 +814,11 @@ class Span : public trace::Span nostd::string_view name, const trace::StartSpanOptions &options, Span *parent = nullptr) noexcept - : trace::Span(), owner_(owner), parent_(parent), context_(CreateContext()) + : trace::Span(), + owner_(owner), + parent_(parent), + context_(CreateContext()), + start_time_(std::chrono::system_clock::now()) { name_ = name; UNREFERENCED_PARAMETER(options); @@ -721,7 +872,23 @@ class Span : public trace::Span // TODO: not implemented UNREFERENCED_PARAMETER(code); UNREFERENCED_PARAMETER(description); - }; + } + + void SetAttributes(Properties attributes) + { + attributes_ = attributes; + } + + /** + * @brief Obtain span attributes specified at Span start. + * NOTE: please consider that this method is NOT thread-safe. + * + * @return ref to Properties collection + */ + Properties& GetAttributes() + { + return attributes_; + } /** * @brief Sets an attribute on the Span. If the Span previously contained a mapping @@ -760,6 +927,8 @@ class Span : public trace::Span */ void End(const trace::EndSpanOptions &options = {}) noexcept override { + end_time_ = std::chrono::system_clock::now(); + if (!has_ended_.exchange(true)) { owner_.EndSpan(*this, parent_, options); @@ -822,6 +991,10 @@ class TracerProvider : public trace::TracerProvider // https://docs.microsoft.com/en-us/uwp/api/windows.foundation.diagnostics.loggingoptions.relatedactivityid // https://docs.microsoft.com/en-us/windows/win32/api/evntprov/nf-evntprov-eventwritetransfer + // Emit separate events compatible with TraceLogging Activity/Start and Activity/Stop + // format for every Span emitted. + GetOption(options, "enableActivityTracking", config_.enableActivityTracking, false); + // Map current `SpanId` to ActivityId - GUID that uniquely identifies this activity. If NULL, // ETW gets the identifier from the thread local storage. For details on getting this // identifier, see EventActivityIdControl. @@ -840,6 +1013,7 @@ class TracerProvider : public trace::TracerProvider config_.enableTraceId = true; config_.enableSpanId = true; config_.enableActivityId = false; + config_.enableActivityTracking = false; config_.enableRelatedActivityId = false; config_.enableAutoParent = false; } diff --git a/exporters/etw/test/etw_tracer_test.cc b/exporters/etw/test/etw_tracer_test.cc index 14171ad5d7..63553972a7 100644 --- a/exporters/etw/test/etw_tracer_test.cc +++ b/exporters/etw/test/etw_tracer_test.cc @@ -147,6 +147,7 @@ TEST(ETWTracer, TracerCheckMinDecoration) {"enableTraceId", false}, {"enableSpanId", false}, {"enableActivityId", false}, + {"enableActivityTracking", true}, {"enableRelatedActivityId", false}, {"enableAutoParent", false} }); From bcf7325317c835011087248e2702959e7a11c0bd Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Thu, 1 Apr 2021 01:36:05 -0700 Subject: [PATCH 57/76] Apply code formatting rules --- .../opentelemetry/exporters/etw/etw_fields.h | 10 ++-- .../opentelemetry/exporters/etw/etw_tracer.h | 60 +++++++++---------- .../opentelemetry/exporters/etw/utils.h | 1 - exporters/otlp/CMakeLists.txt | 9 ++- 4 files changed, 41 insertions(+), 39 deletions(-) diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_fields.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_fields.h index 017d3e4cfe..301f25a7a2 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_fields.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_fields.h @@ -25,9 +25,9 @@ #else /** - + List of configurable Field Name constants: - + Version - Schema version (optional for ETW exporter). _name - Built-in ETW name at envelope level (dedicated ETW field). _time - Built-in ETW time at envelope level (dedicated ETW field). @@ -38,9 +38,9 @@ Name - OT Span name in ETW 'Payload["Name"]' ParentId - OT Span parentId Links - OT Span links array - + Other standard fields (reserved names) that may be appended by ETW channel: - + Level - a 1-byte integer that enables filtering based on the severity or verbosity of events ProviderGuid - ETW Provider Guid ProviderName - ETW Provider Name @@ -53,7 +53,7 @@ RelatedActivityId - RelatedActivityId for EventSource parenting (parent event) Pid - Process Id Tid - Thread Id - + Example "Span" as shown in Visual Studio "Diagnostic Events" view. EventName="Span": { diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h index 97324b60f3..ac906e2922 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h @@ -110,17 +110,20 @@ static inline void GetOption(const TracerProviderOptions &options, class Span; /** - * @brief Template that allows to instantiate new Span object for header-only forward-declared ETW::Span type - * + * @brief Template that allows to instantiate new Span object for header-only forward-declared + * ETW::Span type + * * @tparam SpanType Expected to be ETW::Span * @tparam TracerType expected to be ETW::Tracer * @param objPtr Pointer to parent * @param name Span Name * @param options Span Options * @return Span instance -*/ + */ template -SpanType* new_span(TracerType *objPtr, nostd::string_view name, const trace::StartSpanOptions &options) +SpanType *new_span(TracerType *objPtr, + nostd::string_view name, + const trace::StartSpanOptions &options) { return new (std::nothrow) SpanType{*objPtr, name, options}; } @@ -130,7 +133,7 @@ SpanType* new_span(TracerType *objPtr, nostd::string_view name, const trace::Sta * @tparam SpanType Expected to be ETW::Span * @param ptr Pointer to ETW::Span * @return Smart shared pointer to `trace::Span` -*/ + */ template nostd::shared_ptr to_span_ptr(SpanType *ptr) { @@ -157,7 +160,7 @@ std::string GetName(T &t) * @tparam T ETW::Span * @param t instance of ETW::Span * @return Span Start timestamp -*/ + */ template core::SystemTimestamp GetStartTime(T &t) { @@ -169,7 +172,7 @@ core::SystemTimestamp GetStartTime(T &t) * @tparam T ETW::Span * @param t instance of ETW::Span * @return Span Stop timestamp -*/ + */ template core::SystemTimestamp GetEndTime(T &t) { @@ -183,9 +186,9 @@ class Properties; * @tparam T ETW::Span * @param instance instance of ETW::Span * @param t Properties to store as Attributes -*/ + */ template -void SetSpanAttributes(T& instance, Properties &t) +void SetSpanAttributes(T &instance, Properties &t) { instance.SetAttributes(t); } @@ -194,10 +197,10 @@ void SetSpanAttributes(T& instance, Properties &t) * @brief Utility template to obtain Span Attributes * @tparam T ETW::Span * @param instance instance of ETW::Span - * @return ref to Span Attributes -*/ + * @return ref to Span Attributes + */ template -Properties& GetSpanAttributes(T &instance) +Properties &GetSpanAttributes(T &instance) { return instance.GetAttributes(); } @@ -389,8 +392,11 @@ class Tracer : public trace::Tracer // local time, but rather UTC time (Z=0). std::chrono::system_clock::time_point startTime = GetStartTime(currentSpan); std::chrono::system_clock::time_point endTime = GetEndTime(currentSpan); - int64_t startTimeMs = std::chrono::duration_cast(startTime.time_since_epoch()).count(); - int64_t endTimeMs = std::chrono::duration_cast(endTime.time_since_epoch()).count(); + int64_t startTimeMs = + std::chrono::duration_cast(startTime.time_since_epoch()) + .count(); + int64_t endTimeMs = + std::chrono::duration_cast(endTime.time_since_epoch()).count(); // It may be more optimal to enable passing timestamps as UTC milliseconds // since Unix epoch instead of string, but that implies additional tooling @@ -398,7 +404,7 @@ class Tracer : public trace::Tracer evt[ETW_FIELD_STARTTIME] = utils::formatUtcTimestampMsAsISO8601(startTimeMs); // Duration of Span in milliseconds - evt[ETW_FIELD_DURATION] = endTimeMs - startTimeMs; + evt[ETW_FIELD_DURATION] = endTimeMs - startTimeMs; etwProvider().write(provHandle, evt, ActivityIdPtr, RelatedActivityIdPtr, 0, encoding); } @@ -520,7 +526,7 @@ class Tracer : public trace::Tracer // This template pattern allows us to forward-declare the ETW::Span, // create an instance of it, then assign it to tracer::Span result. - auto currentSpan = new_span(this, name, options); + auto currentSpan = new_span(this, name, options); nostd::shared_ptr result = to_span_ptr(currentSpan); auto spanContext = result->GetContext(); @@ -721,12 +727,11 @@ class Tracer : public trace::Tracer class Span : public trace::Span { protected: - friend class Tracer; /** * @brief Span properties are attached on "Span" event on end of Span. - */ + */ Properties attributes_; core::SystemTimestamp start_time_; @@ -783,11 +788,10 @@ class Span : public trace::Span } public: - /** * @brief Get start time of this Span. - * @return - */ + * @return + */ core::SystemTimestamp GetStartTime() { return start_time_; } /** @@ -874,21 +878,15 @@ class Span : public trace::Span UNREFERENCED_PARAMETER(description); } - void SetAttributes(Properties attributes) - { - attributes_ = attributes; - } + void SetAttributes(Properties attributes) { attributes_ = attributes; } /** * @brief Obtain span attributes specified at Span start. * NOTE: please consider that this method is NOT thread-safe. - * + * * @return ref to Properties collection - */ - Properties& GetAttributes() - { - return attributes_; - } + */ + Properties &GetAttributes() { return attributes_; } /** * @brief Sets an attribute on the Span. If the Span previously contained a mapping diff --git a/exporters/etw/include/opentelemetry/exporters/etw/utils.h b/exporters/etw/include/opentelemetry/exporters/etw/utils.h index 6ffdcd1ae0..3c75355901 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/utils.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/utils.h @@ -287,7 +287,6 @@ std::string formatUtcTimestampMsAsISO8601(int64_t timestampMs) return buf; } - }; // namespace utils OPENTELEMETRY_END_NAMESPACE diff --git a/exporters/otlp/CMakeLists.txt b/exporters/otlp/CMakeLists.txt index 538ae8ea5f..0529436ac6 100644 --- a/exporters/otlp/CMakeLists.txt +++ b/exporters/otlp/CMakeLists.txt @@ -43,8 +43,13 @@ if(BUILD_TESTING) endif() add_executable(otlp_exporter_test test/otlp_exporter_test.cc) target_link_libraries( - otlp_exporter_test ${GTEST_BOTH_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${GMOCK_LIB} - opentelemetry_exporter_otprotocol protobuf::libprotobuf gRPC::grpc++) + otlp_exporter_test + ${GTEST_BOTH_LIBRARIES} + ${CMAKE_THREAD_LIBS_INIT} + ${GMOCK_LIB} + opentelemetry_exporter_otprotocol + protobuf::libprotobuf + gRPC::grpc++) gtest_add_tests( TARGET otlp_exporter_test TEST_PREFIX exporter.otlp. From 1561bd0d2e043f8dad20f1bf641fc1a9e9ba72f9 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Thu, 1 Apr 2021 02:03:28 -0700 Subject: [PATCH 58/76] Add support for const char* and byte arrays under feature gate in Zipkin exporter --- exporters/zipkin/src/recordable.cc | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/exporters/zipkin/src/recordable.cc b/exporters/zipkin/src/recordable.cc index eca372e032..25f793802b 100644 --- a/exporters/zipkin/src/recordable.cc +++ b/exporters/zipkin/src/recordable.cc @@ -24,7 +24,21 @@ namespace exporter namespace zipkin { +// +// See `attribute_value.h` for details. +// Expecting to remove the two feature gates for: +// - HAVE_CSTRING_TYPE - follows spec, but adding `const char *` on API surface. +// - HAVE_SPAN_BYTE - proposal for binary type or byte array (uint8_t[]). +// +#if defined(HAVE_CSTRING_TYPE) && defined(HAVE_SPAN_BYTE) +const int kAttributeValueSize = 16; +#elif defined(HAVE_CSTRING_TYPE) +const int kAttributeValueSize = 15; +#elif defined(HAVE_SPAN_BYTE) +const int kAttributeValueSize = 15; +#else const int kAttributeValueSize = 14; +#endif void Recordable::SetIds(trace::TraceId trace_id, trace::SpanId span_id, @@ -80,6 +94,22 @@ void PopulateAttribute(nlohmann::json &attribute, attribute[key.data()] = nostd::string_view(nostd::get(value).data(), nostd::get(value).size()); } +#ifdef HAVE_CSTRING_TYPE + else if (nostd::holds_alternative(value)) + { + attribute[key.data()] = nostd::get(value); + } +#endif +#ifdef HAVE_SPAN_BYTE + else if (nostd::holds_alternative>(value)) + { + attribute[key.data()] = {}; + for (const auto &val : nostd::get>(value)) + { + attribute[key.data()].push_back(val); + } + } +#endif else if (nostd::holds_alternative>(value)) { attribute[key.data()] = {}; From b51cd39b6691853efbb7f8a940ec459a39001d30 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 2 Apr 2021 01:16:07 -0700 Subject: [PATCH 59/76] Rename type to Google coding style kTypeString --- sdk/include/opentelemetry/sdk/metrics/instrument.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/include/opentelemetry/sdk/metrics/instrument.h b/sdk/include/opentelemetry/sdk/metrics/instrument.h index 41257541f3..b1a4c49009 100644 --- a/sdk/include/opentelemetry/sdk/metrics/instrument.h +++ b/sdk/include/opentelemetry/sdk/metrics/instrument.h @@ -242,7 +242,7 @@ inline void print_value(std::stringstream &ss, { switch (value.index()) { - case common::AttributeType::TYPE_STRING: + case common::AttributeType::kTypeString: ss << nostd::get(value); From 61b2f7cc90864f9cc97c3968e2ca26e6dc11e38a Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 2 Apr 2021 01:18:59 -0700 Subject: [PATCH 60/76] Addressing code review comments: remove api change --- api/include/opentelemetry/trace/span_id.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/api/include/opentelemetry/trace/span_id.h b/api/include/opentelemetry/trace/span_id.h index c8d6cdb40f..e282a2021a 100644 --- a/api/include/opentelemetry/trace/span_id.h +++ b/api/include/opentelemetry/trace/span_id.h @@ -36,8 +36,6 @@ class SpanId final // Creates a SpanId with the given ID. explicit SpanId(nostd::span id) noexcept { memcpy(rep_, id.data(), kSize); } - explicit SpanId(const uint8_t *data) noexcept { memcpy(rep_, data, kSize); } - // Populates the buffer with the lowercase base16 representation of the ID. void ToLowerBase16(nostd::span buffer) const noexcept { From 467f8232cbbee2e2bc9b1c7bbf67011e580f1f6e Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 2 Apr 2021 01:19:34 -0700 Subject: [PATCH 61/76] Addressing code review comments: rename namespace from ETW to etw --- exporters/etw/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exporters/etw/README.md b/exporters/etw/README.md index ae2a71087f..7c665ac915 100644 --- a/exporters/etw/README.md +++ b/exporters/etw/README.md @@ -49,12 +49,12 @@ and emitting a span named `MySpan` with attributes on it, as well as `MyEvent` w #include "opentelemetry/exporters/etw/etw_tracer_exporter.h" using namespace OPENTELEMETRY_NAMESPACE; -using namespace opentelemetry::exporter::ETW; +using namespace opentelemetry::exporter::etw; // Supply unique instrumentation name (ETW Provider Name) here: std::string providerName = "OpenTelemetry-ETW-Provider"; -exporter::ETW::TracerProvider tp; +exporter::etw::TracerProvider tp; int main(int argc, const char* argv[]) { From 576d510fae83439531282853e4d38080b0893a98 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 2 Apr 2021 01:20:03 -0700 Subject: [PATCH 62/76] Remove ETW recordable class as it is not needed --- .../exporters/etw/etw_recordable.h | 229 ------------------ 1 file changed, 229 deletions(-) delete mode 100644 exporters/etw/include/opentelemetry/exporters/etw/etw_recordable.h diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_recordable.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_recordable.h deleted file mode 100644 index 2b1d473a47..0000000000 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_recordable.h +++ /dev/null @@ -1,229 +0,0 @@ -// Copyright 2021, OpenTelemetry Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#pragma once - -#include -#include -#include - -#include "opentelemetry/version.h" - -#include "opentelemetry/common/key_value_iterable_view.h" - -#include -#include -#include -#include - -#include "opentelemetry/nostd/shared_ptr.h" -#include "opentelemetry/nostd/string_view.h" -#include "opentelemetry/nostd/unique_ptr.h" - -#include "opentelemetry/common/key_value_iterable_view.h" -#include "opentelemetry/trace/span.h" -#include "opentelemetry/trace/span_context_kv_iterable_view.h" -#include "opentelemetry/trace/span_id.h" -#include "opentelemetry/trace/trace_id.h" -#include "opentelemetry/trace/tracer_provider.h" - -#include "opentelemetry/sdk/trace/exporter.h" -#include "opentelemetry/sdk/trace/recordable.h" -#include "opentelemetry/sdk/trace/span_data.h" - -#include -#include -#include -#include -#include -#include - -#include "opentelemetry/exporters/etw/etw_fields.h" -#include "opentelemetry/exporters/etw/etw_provider.h" -#include "opentelemetry/exporters/etw/etw_tracer.h" -#include "opentelemetry/exporters/etw/utils.h" - -#include "opentelemetry/exporters/etw/etw_properties.h" - -namespace core = opentelemetry::core; -namespace trace = opentelemetry::trace; - -OPENTELEMETRY_BEGIN_NAMESPACE -namespace exporter -{ -namespace ETW -{ - -class ETWTraceRecordable final : public sdk::trace::Recordable -{ -public: - ETWTraceRecordable(std::string providerName) { InitTracerProvider(providerName); } - - /** - * Get the trace id for this span - * @return the trace id for this span - */ - trace::TraceId GetTraceId() const noexcept { return trace_id_; } - - /** - * Get the span id for this span - * @return the span id for this span - */ - trace::SpanId GetSpanId() const noexcept { return span_id_; } - - /** - * Get the parent span id for this span - * @return the span id for this span's parent - */ - trace::SpanId GetParentSpanId() const noexcept { return parent_span_id_; } - - /** - * Get the name for this span - * @return the name for this span - */ - nostd::string_view GetName() const noexcept { return name_; } - - /** - * Get the status for this span - * @return the status for this span - */ - trace::StatusCode GetStatus() const noexcept { return status_code_; } - - /** - * Get the status description for this span - * @return the description of the the status of this span - */ - nostd::string_view GetDescription() const noexcept { return status_desc_; } - - /** - * Get the start time for this span - * @return the start time for this span - */ - core::SystemTimestamp GetStartTime() const noexcept { return start_time_; } - - /** - * Get the duration for this span - * @return the duration for this span - */ - std::chrono::nanoseconds GetDuration() const noexcept { return duration_; } - - /** - * Get the attributes for this span - * @return the attributes for this span - */ - const std::unordered_map &GetAttributes() - const noexcept - { - return attribute_map_.GetAttributes(); - } - - void SetIds(trace::TraceId trace_id, - trace::SpanId span_id, - trace::SpanId parent_span_id) noexcept override - { - trace_id_ = trace_id; - span_id_ = span_id; - parent_span_id_ = parent_span_id; - } - - void SetAttribute(nostd::string_view key, const common::AttributeValue &value) noexcept override - { - attribute_map_.SetAttribute(key, value); - } - - void AddEvent(nostd::string_view name, - core::SystemTimestamp timestamp, - const common::KeyValueIterable &attributes) noexcept override - { - span_->AddEvent(name, timestamp, attributes); - } - - void AddLink(const trace::SpanContext &span_context, - const common::KeyValueIterable &attributes) noexcept override - { - // TODO: Link Implementation for the Span to be implemented - } - - /** - * @brief Set recordable status code and description. - * @param code - * @param description - * @return - */ - void SetStatus(trace::StatusCode code, nostd::string_view description) noexcept override - { - status_code_ = code; - status_desc_ = std::string(description); - } - - /** - * @brief Set recordable name. - * @param name - * @return - */ - void SetName(nostd::string_view name) noexcept override { name_ = std::string(name); } - - /** - * @brief Set span kind - * @param span_kind - * @return - */ - void SetSpanKind(trace::SpanKind span_kind) noexcept override { span_kind_ = span_kind; } - - /** - * @brief Set recordable start time. - * @param start_time - * @return - */ - void SetStartTime(core::SystemTimestamp start_time) noexcept override - { - start_time_ = start_time; - } - - /** - * @brief Set recordable duration. - * @param duration - * @return - */ - void SetDuration(std::chrono::nanoseconds duration) noexcept override { duration_ = duration; } - - /** - * @brief Initialize ETW provider by name or GUID. - * @param providerName - Provider Name or GUID that starts with `{` - */ - void InitTracerProvider(std::string providerName) - { - TracerProvider tracer_provider_; - - tracer_ = tracer_provider_.GetTracer(providerName); - span_ = tracer_->StartSpan(name_); - } - -private: - trace::TraceId trace_id_; - trace::SpanId span_id_; - trace::SpanId parent_span_id_; - core::SystemTimestamp start_time_; - std::chrono::nanoseconds duration_{0}; - std::string name_; - trace::StatusCode status_code_{trace::StatusCode::kOk}; - std::string status_desc_; - sdk::common::AttributeMap attribute_map_; - trace::SpanKind span_kind_{trace::SpanKind::kInternal}; - nostd::shared_ptr tracer_; - nostd::shared_ptr span_; -}; - -} // namespace ETW -} // namespace exporter -OPENTELEMETRY_END_NAMESPACE From a1653b4f85d1fa5316748037a760e19695cea1db Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 2 Apr 2021 01:20:35 -0700 Subject: [PATCH 63/76] Remove HAVE_CSTRING_TYPE build option --- CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8a9b387ba9..83dbfacfbf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,8 +6,6 @@ cmake_policy(SET CMP0057 NEW) project(opentelemetry-cpp) -add_definitions(-DHAVE_CSTRING_TYPE) - file(READ "${CMAKE_CURRENT_LIST_DIR}/api/include/opentelemetry/version.h" OPENTELEMETRY_CPP_HEADER_VERSION_H) if(OPENTELEMETRY_CPP_HEADER_VERSION_H MATCHES From 57ab55bacff50dbee08f330c65eac2b099f0ea70 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 2 Apr 2021 01:21:21 -0700 Subject: [PATCH 64/76] Remove API changes --- api/include/opentelemetry/trace/trace_id.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/api/include/opentelemetry/trace/trace_id.h b/api/include/opentelemetry/trace/trace_id.h index 54a6e9123e..fff2160786 100644 --- a/api/include/opentelemetry/trace/trace_id.h +++ b/api/include/opentelemetry/trace/trace_id.h @@ -42,9 +42,6 @@ class TraceId final memcpy(rep_, id.data(), kSize); } - // Creates a TraceId with the given ID. - explicit TraceId(const uint8_t *data) noexcept { memcpy(rep_, data, kSize); } - // Populates the buffer with the lowercase base16 representation of the ID. void ToLowerBase16(nostd::span buffer) const noexcept { From 1b0baf762e4c39318ea56c62a04e2be85e0b089d Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 2 Apr 2021 01:22:04 -0700 Subject: [PATCH 65/76] Rename namespace from ETW to etw --- exporters/etw/test/etw_perf_test.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/exporters/etw/test/etw_perf_test.cc b/exporters/etw/test/etw_perf_test.cc index 92a7e082ba..cdc5c88e1d 100644 --- a/exporters/etw/test/etw_perf_test.cc +++ b/exporters/etw/test/etw_perf_test.cc @@ -25,15 +25,15 @@ using namespace OPENTELEMETRY_NAMESPACE; -using Properties = opentelemetry::exporter::ETW::Properties; -using PropertyValue = opentelemetry::exporter::ETW::PropertyValue; -using PropertyValueMap = opentelemetry::exporter::ETW::PropertyValueMap; +using Properties = opentelemetry::exporter::etw::Properties; +using PropertyValue = opentelemetry::exporter::etw::PropertyValue; +using PropertyValueMap = opentelemetry::exporter::etw::PropertyValueMap; namespace { static constexpr const char *providerName = "OpenTelemetry-ETW-StressTest"; -static exporter::ETW::TracerProviderOptions providerOptions = {{"enableTraceId", false}, +static exporter::etw::TracerProviderOptions providerOptions = {{"enableTraceId", false}, {"enableSpanId", false}, {"enableActivityId", false}, {"enableRelatedActivityId", false}, @@ -41,7 +41,7 @@ static exporter::ETW::TracerProviderOptions providerOptions = {{"enableTraceId", class ETWProviderStressTest { - exporter::ETW::TracerProvider provider_; + exporter::etw::TracerProvider provider_; std::string mode_; nostd::shared_ptr tracer_; nostd::shared_ptr span_; From e37cee5f545e45668e8100c144c85a13e787313a Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 2 Apr 2021 01:22:29 -0700 Subject: [PATCH 66/76] Rename namespace from ETW to etw --- exporters/etw/test/etw_tracer_test.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/exporters/etw/test/etw_tracer_test.cc b/exporters/etw/test/etw_tracer_test.cc index 63553972a7..9bef0cf68a 100644 --- a/exporters/etw/test/etw_tracer_test.cc +++ b/exporters/etw/test/etw_tracer_test.cc @@ -23,9 +23,9 @@ using namespace OPENTELEMETRY_NAMESPACE; -using Properties = opentelemetry::exporter::ETW::Properties; -using PropertyValue = opentelemetry::exporter::ETW::PropertyValue; -using PropertyValueMap = opentelemetry::exporter::ETW::PropertyValueMap; +using Properties = opentelemetry::exporter::etw::Properties; +using PropertyValue = opentelemetry::exporter::etw::PropertyValue; +using PropertyValueMap = opentelemetry::exporter::etw::PropertyValueMap; std::string getTemporaryValue() { @@ -57,7 +57,7 @@ TEST(ETWTracer, TracerCheck) // Windows Defender Firewall Driver {D5E09122-D0B2-4235-ADC1-C89FAAAF1069} std::string providerName = "OpenTelemetry-ETW-TLD"; // supply unique instrumentation name here - exporter::ETW::TracerProvider tp; + exporter::etw::TracerProvider tp; // TODO: this code should fallback to MsgPack if TLD is not available auto tracer = tp.GetTracer(providerName, "TLD"); @@ -142,7 +142,7 @@ TEST(ETWTracer, TracerCheck) TEST(ETWTracer, TracerCheckMinDecoration) { std::string providerName = "OpenTelemetry-ETW-TLD"; - exporter::ETW::TracerProvider tp + exporter::etw::TracerProvider tp ({ {"enableTraceId", false}, {"enableSpanId", false}, @@ -185,7 +185,7 @@ TEST(ETWTracer, TracerCheckMinDecoration) TEST(ETWTracer, TracerCheckMaxDecoration) { std::string providerName = "OpenTelemetry-ETW-TLD"; - exporter::ETW::TracerProvider tp + exporter::etw::TracerProvider tp ({ {"enableTraceId", true}, {"enableSpanId", true}, @@ -206,7 +206,7 @@ TEST(ETWTracer, TracerCheckMaxDecoration) TEST(ETWTracer, TracerCheckMsgPack) { std::string providerName = "OpenTelemetry-ETW-MsgPack"; - exporter::ETW::TracerProvider tp + exporter::etw::TracerProvider tp ({ {"enableTraceId", true}, {"enableSpanId", true}, From 63f793dec7f894bf5e41cefce9eb930cda18b5e5 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 2 Apr 2021 01:23:42 -0700 Subject: [PATCH 67/76] Address code review comment: rename enum types to follow Google coding style --- .../exporters/elasticsearch/es_log_recordable.h | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/exporters/elasticsearch/include/opentelemetry/exporters/elasticsearch/es_log_recordable.h b/exporters/elasticsearch/include/opentelemetry/exporters/elasticsearch/es_log_recordable.h index 4e9d9aaabb..09225b9dbd 100644 --- a/exporters/elasticsearch/include/opentelemetry/exporters/elasticsearch/es_log_recordable.h +++ b/exporters/elasticsearch/include/opentelemetry/exporters/elasticsearch/es_log_recordable.h @@ -49,28 +49,25 @@ class ElasticSearchRecordable final : public sdk::logs::Recordable { switch (value.index()) { - case common::AttributeType::TYPE_BOOL: + case common::AttributeType::kTypeBool: json_[name][key.data()] = opentelemetry::nostd::get(value) ? true : false; return; - case common::AttributeType::TYPE_INT: + case common::AttributeType::kTypeInt: json_[name][key.data()] = opentelemetry::nostd::get(value); return; - case common::AttributeType::TYPE_INT64: + case common::AttributeType::kTypeInt64: json_[name][key.data()] = opentelemetry::nostd::get(value); return; - case common::AttributeType::TYPE_UINT: + case common::AttributeType::kTypeUInt: json_[name][key.data()] = opentelemetry::nostd::get(value); return; - case common::AttributeType::TYPE_UINT64: + case common::AttributeType::kTypeUInt64: json_[name][key.data()] = opentelemetry::nostd::get(value); return; - case common::AttributeType::TYPE_DOUBLE: + case common::AttributeType::kTypeDouble: json_[name][key.data()] = opentelemetry::nostd::get(value); return; - case common::AttributeType::TYPE_STRING: -#ifdef HAVE_CSTRING_TYPE - case common::AttributeType::TYPE_CSTRING: -#endif + case common::AttributeType::kTypeString: json_[name][key.data()] = opentelemetry::nostd::get(value).data(); return; From a8afc39b08a936daa678e3aa97059ea35ec051ad Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 2 Apr 2021 01:24:15 -0700 Subject: [PATCH 68/76] Remove HAVE_CSTRING_TYPE --- exporters/otlp/src/recordable.cc | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/exporters/otlp/src/recordable.cc b/exporters/otlp/src/recordable.cc index a2b8ef2ab0..c4e5ee57a8 100644 --- a/exporters/otlp/src/recordable.cc +++ b/exporters/otlp/src/recordable.cc @@ -12,11 +12,7 @@ namespace otlp // - HAVE_CSTRING_TYPE - follows spec, but adding `const char *` on API surface. // - HAVE_SPAN_BYTE - proposal for binary type or byte array (uint8_t[]). // -#if defined(HAVE_CSTRING_TYPE) && defined(HAVE_SPAN_BYTE) -const int kAttributeValueSize = 16; -#elif defined(HAVE_CSTRING_TYPE) -const int kAttributeValueSize = 15; -#elif defined(HAVE_SPAN_BYTE) +#if defined(HAVE_SPAN_BYTE) const int kAttributeValueSize = 15; #else const int kAttributeValueSize = 14; @@ -73,12 +69,6 @@ void PopulateAttribute(opentelemetry::proto::common::v1::KeyValue *attribute, attribute->mutable_value()->set_string_value(nostd::get(value).data(), nostd::get(value).size()); } -#ifdef HAVE_CSTRING_TYPE - else if (nostd::holds_alternative(value)) - { - attribute->mutable_value()->set_string_value(nostd::get(value)); - } -#endif #ifdef HAVE_SPAN_BYTE else if (nostd::holds_alternative>(value)) { From 18b2f9bb6070d8f5a77a0887e7d8a9eaa595bb13 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 2 Apr 2021 01:25:17 -0700 Subject: [PATCH 69/76] Rename enum types to follow Google coding style --- .../sdk/common/attribute_utils.h | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/sdk/include/opentelemetry/sdk/common/attribute_utils.h b/sdk/include/opentelemetry/sdk/common/attribute_utils.h index baa05811f5..3308be3bb4 100644 --- a/sdk/include/opentelemetry/sdk/common/attribute_utils.h +++ b/sdk/include/opentelemetry/sdk/common/attribute_utils.h @@ -38,7 +38,6 @@ using OwnedAttributeValue = nostd::variant, #endif @@ -52,23 +51,23 @@ using OwnedAttributeValue = nostd::variant Date: Fri, 2 Apr 2021 01:37:51 -0700 Subject: [PATCH 70/76] Remove HAVE_CSTRING_TYPE build option --- exporters/etw/README.md | 1 - exporters/otlp/src/recordable.cc | 1 - exporters/zipkin/src/recordable.cc | 11 ----------- 3 files changed, 13 deletions(-) diff --git a/exporters/etw/README.md b/exporters/etw/README.md index 7c665ac915..06053a2f89 100644 --- a/exporters/etw/README.md +++ b/exporters/etw/README.md @@ -111,7 +111,6 @@ These options affect how "embedded in application" OpenTelemetry C++ SDK code is | HAVE_GSL | Use [Microsoft GSL](https://github.com/microsoft/GSL) for `gsl::span` implementation. Library must be in include path. Microsoft GSL claims to be the most feature-complete implementation of `std::span`. It may be used instead of `nostd::span` implementation in projects that statically link OpenTelemetry SDK. | | HAVE_ABSEIL_VARIANT | Use `absl::variant` instead of `nostd::variant`. `nostd::variant` is incompatible with Visual Studio 2015. `absl::variant` should be used instead if targeting Visual Studio 2015. | | HAVE_TLD | Use ETW/TraceLogging Dynamic protocol. This is the default implementation compatible with existing C# "listeners" / "decoders" of ETW events. This option requires an additional optional Microsoft MIT-licensed `TraceLoggingDynamic.h` header. | -| HAVE_CSTRING_TYPE | Allow passing C-string type `const char *` to API calls. In several scenarios (e.g. integration with C code) it is more performant to construct `nostd::string_view` from original C-string instead of constructing it from `std::string` copy of the C-string, thus avoiding unnecessary `memcpy`. | ## Debugging diff --git a/exporters/otlp/src/recordable.cc b/exporters/otlp/src/recordable.cc index c4e5ee57a8..637b1a95fc 100644 --- a/exporters/otlp/src/recordable.cc +++ b/exporters/otlp/src/recordable.cc @@ -9,7 +9,6 @@ namespace otlp // // See `attribute_value.h` for details. // Expecting to remove the two feature gates for: -// - HAVE_CSTRING_TYPE - follows spec, but adding `const char *` on API surface. // - HAVE_SPAN_BYTE - proposal for binary type or byte array (uint8_t[]). // #if defined(HAVE_SPAN_BYTE) diff --git a/exporters/zipkin/src/recordable.cc b/exporters/zipkin/src/recordable.cc index 25f793802b..550925d63f 100644 --- a/exporters/zipkin/src/recordable.cc +++ b/exporters/zipkin/src/recordable.cc @@ -27,13 +27,8 @@ namespace zipkin // // See `attribute_value.h` for details. // Expecting to remove the two feature gates for: -// - HAVE_CSTRING_TYPE - follows spec, but adding `const char *` on API surface. // - HAVE_SPAN_BYTE - proposal for binary type or byte array (uint8_t[]). // -#if defined(HAVE_CSTRING_TYPE) && defined(HAVE_SPAN_BYTE) -const int kAttributeValueSize = 16; -#elif defined(HAVE_CSTRING_TYPE) -const int kAttributeValueSize = 15; #elif defined(HAVE_SPAN_BYTE) const int kAttributeValueSize = 15; #else @@ -94,12 +89,6 @@ void PopulateAttribute(nlohmann::json &attribute, attribute[key.data()] = nostd::string_view(nostd::get(value).data(), nostd::get(value).size()); } -#ifdef HAVE_CSTRING_TYPE - else if (nostd::holds_alternative(value)) - { - attribute[key.data()] = nostd::get(value); - } -#endif #ifdef HAVE_SPAN_BYTE else if (nostd::holds_alternative>(value)) { From bf8a3d4d83a4ed889b5f02aa5fb41482965c9e25 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 2 Apr 2021 01:38:26 -0700 Subject: [PATCH 71/76] Remove HAVE_CSTRING_TYPE option and rename enums to follow Google Coding style --- .../opentelemetry/common/attribute_value.h | 37 ++++++++----------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/api/include/opentelemetry/common/attribute_value.h b/api/include/opentelemetry/common/attribute_value.h index 6cb399842a..59a5618316 100644 --- a/api/include/opentelemetry/common/attribute_value.h +++ b/api/include/opentelemetry/common/attribute_value.h @@ -18,10 +18,6 @@ using AttributeValue = uint64_t, double, nostd::string_view, -#ifdef HAVE_CSTRING_TYPE - // TODO: add C-string as possible value on API surface - const char *, -#endif #ifdef HAVE_SPAN_BYTE // TODO: 8-bit byte arrays / binary blobs are not part of OT spec yet! // Ref: https://github.com/open-telemetry/opentelemetry-specification/issues/780 @@ -37,26 +33,23 @@ using AttributeValue = enum AttributeType { - TYPE_BOOL, - TYPE_INT, - TYPE_INT64, - TYPE_UINT, - TYPE_UINT64, - TYPE_DOUBLE, - TYPE_STRING, -#ifdef HAVE_CSTRING_TYPE - TYPE_CSTRING, -#endif + kTypeBool, + kTypeInt, + kTypeInt64, + kTypeUInt, + kTypeUInt64, + kTypeDouble, + kTypeString, #ifdef HAVE_SPAN_BYTE - TYPE_SPAN_BYTE, + kTypeSpanByte, #endif - TYPE_SPAN_BOOL, - TYPE_SPAN_INT, - TYPE_SPAN_INT64, - TYPE_SPAN_UINT, - TYPE_SPAN_UINT64, - TYPE_SPAN_DOUBLE, - TYPE_SPAN_STRING + kTypeSpanBool, + kTypeSpanInt, + kTypeSpanInt64, + kTypeSpanUInt, + kTypeSpanUInt64, + kTypeSpanDouble, + kTypeSpanString }; } // namespace common From 8feee53291bb1cc1eb06be9634b80cb36da334f2 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 2 Apr 2021 01:46:27 -0700 Subject: [PATCH 72/76] Rename namespace from ETW to etw --- .../exporters/etw/etw_properties.h | 107 ++++++++++-------- .../exporters/etw/etw_provider.h | 94 +++++++-------- .../opentelemetry/exporters/etw/etw_tracer.h | 72 ++++++------ .../exporters/etw/etw_tracer_exporter.h | 78 ------------- 4 files changed, 139 insertions(+), 212 deletions(-) diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h index 3443bc46ad..542951fb6a 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_properties.h @@ -25,7 +25,7 @@ OPENTELEMETRY_BEGIN_NAMESPACE namespace exporter { -namespace ETW +namespace etw { /** @@ -41,9 +41,7 @@ using PropertyVariant = uint64_t, double, std::string, -#ifdef HAVE_CSTRING_TYPE const char *, -#endif #ifdef HAVE_SPAN_BYTE // TODO: 8-bit byte arrays / binary blobs are not part of OT spec yet! // Ref: https://github.com/open-telemetry/opentelemetry-specification/issues/780 @@ -57,6 +55,28 @@ using PropertyVariant = std::vector, std::vector>; +enum PropertyType +{ + kTypeBool, + kTypeInt, + kTypeInt64, + kTypeUInt, + kTypeUInt64, + kTypeDouble, + kTypeString, + kTypeCString, +#ifdef HAVE_SPAN_BYTE + kTypeSpanByte, +#endif + kTypeSpanBool, + kTypeSpanInt, + kTypeSpanInt64, + kTypeSpanUInt, + kTypeSpanUInt64, + kTypeSpanDouble, + kTypeSpanString +}; + /** * @brief PropertyValue class that holds PropertyVariant and * provides converter for non-owning common::AttributeValue @@ -187,66 +207,58 @@ class PropertyValue : public PropertyVariant { switch (v.index()) { - case common::AttributeType::TYPE_BOOL: + case common::AttributeType::kTypeBool: PropertyVariant::operator=(nostd::get(v)); break; - case common::AttributeType::TYPE_INT: + case common::AttributeType::kTypeInt: PropertyVariant::operator=(nostd::get(v)); break; - case common::AttributeType::TYPE_INT64: + case common::AttributeType::kTypeInt64: PropertyVariant::operator=(nostd::get(v)); break; - case common::AttributeType::TYPE_UINT: + case common::AttributeType::kTypeUInt: PropertyVariant::operator=(nostd::get(v)); break; - case common::AttributeType::TYPE_UINT64: + case common::AttributeType::kTypeUInt64: PropertyVariant::operator=(nostd::get(v)); break; - case common::AttributeType::TYPE_DOUBLE: + case common::AttributeType::kTypeDouble: PropertyVariant::operator=(nostd::get(v)); break; - case common::AttributeType::TYPE_STRING: { + case common::AttributeType::kTypeString: { PropertyVariant::operator=(nostd::string_view(nostd::get(v)).data()); break; }; - -#ifdef HAVE_CSTRING_TYPE - case common::AttributeType::TYPE_CSTRING: - PropertyVariant::operator=(nostd::get(v)); - break; -#endif - #ifdef HAVE_SPAN_BYTE - case common::AttributeType::TYPE_SPAN_BYTE: + case common::AttributeType::kTypeSpanByte: PropertyVariant::operator=(to_vector(nostd::get>(v))); break; #endif - - case common::AttributeType::TYPE_SPAN_BOOL: + case common::AttributeType::kTypeSpanBool: PropertyVariant::operator=(to_vector(nostd::get>(v))); break; - case common::AttributeType::TYPE_SPAN_INT: + case common::AttributeType::kTypeSpanInt: PropertyVariant::operator=(to_vector(nostd::get>(v))); break; - case common::AttributeType::TYPE_SPAN_INT64: + case common::AttributeType::kTypeSpanInt64: PropertyVariant::operator=(to_vector(nostd::get>(v))); break; - case common::AttributeType::TYPE_SPAN_UINT: + case common::AttributeType::kTypeSpanUInt: PropertyVariant::operator=(to_vector(nostd::get>(v))); break; - case common::AttributeType::TYPE_SPAN_UINT64: + case common::AttributeType::kTypeSpanUInt64: PropertyVariant::operator=(to_vector(nostd::get>(v))); break; - case common::AttributeType::TYPE_SPAN_DOUBLE: + case common::AttributeType::kTypeSpanDouble: PropertyVariant::operator=(to_vector(nostd::get>(v))); break; - case common::AttributeType::TYPE_SPAN_STRING: + case common::AttributeType::kTypeSpanString: PropertyVariant::operator=(to_vector(nostd::get>(v))); break; @@ -266,70 +278,67 @@ class PropertyValue : public PropertyVariant switch (this->index()) { - case common::AttributeType::TYPE_BOOL: + case PropertyType::kTypeBool: value = nostd::get(*this); break; - case common::AttributeType::TYPE_INT: + case PropertyType::kTypeInt: value = nostd::get(*this); break; - case common::AttributeType::TYPE_INT64: + case PropertyType::kTypeInt64: value = nostd::get(*this); break; - case common::AttributeType::TYPE_UINT: + case PropertyType::kTypeUInt: value = nostd::get(*this); break; - case common::AttributeType::TYPE_UINT64: + case PropertyType::kTypeUInt64: value = nostd::get(*this); break; - case common::AttributeType::TYPE_DOUBLE: + case PropertyType::kTypeDouble: value = nostd::get(*this); break; - - case common::AttributeType::TYPE_STRING: { + case PropertyType::kTypeString: { const std::string &str = nostd::get(*this); return nostd::string_view(str.data(), str.size()); break; } - -#ifdef HAVE_CSTRING_TYPE - case common::AttributeType::TYPE_CSTRING: - value = nostd::get(*this); + case PropertyType::kTypeCString: { + const char *data = nostd::get(*this); + return nostd::string_view(data, (data) ? strlen(data) : 0); break; -#endif + } #ifdef HAVE_SPAN_BYTE - case common::AttributeType::TYPE_SPAN_BYTE: + case common::AttributeType::kTypeSpanByte: value = to_span(nostd::get>(self)); break; #endif - case common::AttributeType::TYPE_SPAN_BOOL: { + case PropertyType::kTypeSpanBool: { const auto &vec = nostd::get>(*this); // FIXME: sort out how to remap from vector to span break; } - - case common::AttributeType::TYPE_SPAN_INT: + case PropertyType::kTypeSpanInt: value = to_span(nostd::get>(*this)); break; - case common::AttributeType::TYPE_SPAN_INT64: + case PropertyType::kTypeSpanInt64: value = to_span(nostd::get>(*this)); break; - case common::AttributeType::TYPE_SPAN_UINT: + case PropertyType::kTypeSpanUInt: value = to_span(nostd::get>(*this)); break; - case common::AttributeType::TYPE_SPAN_UINT64: + case PropertyType::kTypeSpanUInt64: value = to_span(nostd::get>(*this)); break; - case common::AttributeType::TYPE_SPAN_DOUBLE: + case PropertyType::kTypeSpanDouble: value = to_span(nostd::get>(*this)); break; - case common::AttributeType::TYPE_SPAN_STRING: + case PropertyType::kTypeSpanString: // FIXME: sort out how to remap from vector to span // value = to_span(nostd::get>(self)); break; @@ -447,6 +456,6 @@ class Properties : public common::KeyValueIterable, public PropertyValueMap size_t size() const noexcept override { return PropertyValueMap::size(); }; }; -} // namespace ETW +} // namespace etw } // namespace exporter OPENTELEMETRY_END_NAMESPACE diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h index 6150029c8c..0493f818c7 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h @@ -24,7 +24,7 @@ # pragma warning(disable : 4018) #endif -#include "opentelemetry/common/attribute_value.h" +#include "opentelemetry/exporters/etw/etw_properties.h" #include "opentelemetry/exporters/etw/uuid.h" #include "opentelemetry/version.h" @@ -54,6 +54,9 @@ OPENTELEMETRY_BEGIN_NAMESPACE +using Properties = exporter::etw::Properties; +using PropertyType = exporter::etw::PropertyType; + class ETWProvider { @@ -236,9 +239,8 @@ class ETWProvider return STATUS_ERROR; } - template unsigned long writeMsgPack(Handle &providerData, - T eventData, + exporter::etw::Properties &eventData, LPCGUID ActivityId = nullptr, LPCGUID RelatedActivityId = nullptr, uint8_t Opcode = 0) @@ -269,14 +271,12 @@ class ETWProvider switch (nameField.index()) { - case common::AttributeType::TYPE_STRING: + case PropertyType::kTypeString: eventName = (char *)(nostd::get(nameField).data()); // must be 0-terminated! break; -# ifdef HAVE_CSTRING_TYPE - case common::AttributeType::TYPE_CSTRING: + case PropertyType::kTypeCString: eventName = (char *)(nostd::get(nameField)); break; -# endif default: // If invalid event name is supplied, then we replace it with 'NoName' break; @@ -302,47 +302,45 @@ class ETWProvider auto &value = kv.second; switch (value.index()) { - case common::AttributeType::TYPE_BOOL: { + case PropertyType::kTypeBool: { UINT8 temp = static_cast(nostd::get(value)); jObj[name] = temp; break; } - case common::AttributeType::TYPE_INT: { + case PropertyType::kTypeInt: { auto temp = nostd::get(value); jObj[name] = temp; break; } - case common::AttributeType::TYPE_INT64: { + case PropertyType::kTypeInt64: { auto temp = nostd::get(value); jObj[name] = temp; break; } - case common::AttributeType::TYPE_UINT: { + case PropertyType::kTypeUInt: { auto temp = nostd::get(value); jObj[name] = temp; break; } - case common::AttributeType::TYPE_UINT64: { + case PropertyType::kTypeUInt64: { auto temp = nostd::get(value); jObj[name] = temp; break; } - case common::AttributeType::TYPE_DOUBLE: { + case PropertyType::kTypeDouble: { auto temp = nostd::get(value); jObj[name] = temp; break; } - case common::AttributeType::TYPE_STRING: { + case PropertyType::kTypeString: { jObj[name] = nostd::get(value); break; } -# ifdef HAVE_CSTRING_TYPE - case common::AttributeType::TYPE_CSTRING: { + case PropertyType::kTypeCString: { auto temp = nostd::get(value); jObj[name] = temp; break; } -# endif # if HAVE_TYPE_GUID // TODO: consider adding UUID/GUID to spec case common::AttributeType::TYPE_GUID: { @@ -357,13 +355,13 @@ class ETWProvider # ifdef HAVE_SPAN_BYTE case common::AttributeType::TYPE_SPAN_BYTE: # endif - case common::AttributeType::TYPE_SPAN_BOOL: - case common::AttributeType::TYPE_SPAN_INT: - case common::AttributeType::TYPE_SPAN_INT64: - case common::AttributeType::TYPE_SPAN_UINT: - case common::AttributeType::TYPE_SPAN_UINT64: - case common::AttributeType::TYPE_SPAN_DOUBLE: - case common::AttributeType::TYPE_SPAN_STRING: + case PropertyType::kTypeSpanBool: + case PropertyType::kTypeSpanInt: + case PropertyType::kTypeSpanInt64: + case PropertyType::kTypeSpanUInt: + case PropertyType::kTypeSpanUInt64: + case PropertyType::kTypeSpanDouble: + case PropertyType::kTypeSpanString: default: // TODO: unsupported type break; @@ -426,9 +424,8 @@ class ETWProvider /// /// /// - template unsigned long writeTld(Handle &providerData, - T eventData, + Properties &eventData, LPCGUID ActivityId = nullptr, LPCGUID RelatedActivityId = nullptr, uint8_t Opcode = 0 /* Information */) @@ -453,14 +450,12 @@ class ETWProvider auto nameField = eventData[EVENT_NAME]; switch (nameField.index()) { - case common::AttributeType::TYPE_STRING: + case PropertyType::kTypeString: eventName = (char *)(nostd::get(nameField).data()); break; -# ifdef HAVE_CSTRING_TYPE - case common::AttributeType::TYPE_CSTRING: + case PropertyType::kTypeCString: eventName = (char *)(nostd::get(nameField)); break; -# endif default: // This is user error. Invalid event name! // We supply default 'NoName' event name in this case. @@ -478,58 +473,56 @@ class ETWProvider auto &value = kv.second; switch (value.index()) { - case common::AttributeType::TYPE_BOOL: { + case PropertyType::kTypeBool: { builder.AddField(name, tld::TypeBool8); UINT8 temp = static_cast(nostd::get(value)); dbuilder.AddByte(temp); break; } - case common::AttributeType::TYPE_INT: { + case PropertyType::kTypeInt: { builder.AddField(name, tld::TypeInt32); auto temp = nostd::get(value); dbuilder.AddValue(temp); break; } - case common::AttributeType::TYPE_INT64: { + case PropertyType::kTypeInt64: { builder.AddField(name, tld::TypeInt64); auto temp = nostd::get(value); dbuilder.AddValue(temp); break; } - case common::AttributeType::TYPE_UINT: { + case PropertyType::kTypeUInt: { builder.AddField(name, tld::TypeUInt32); auto temp = nostd::get(value); dbuilder.AddValue(temp); break; } - case common::AttributeType::TYPE_UINT64: { + case PropertyType::kTypeUInt64: { builder.AddField(name, tld::TypeUInt64); auto temp = nostd::get(value); dbuilder.AddValue(temp); break; } - case common::AttributeType::TYPE_DOUBLE: { + case PropertyType::kTypeDouble: { builder.AddField(name, tld::TypeDouble); auto temp = nostd::get(value); dbuilder.AddValue(temp); break; } - case common::AttributeType::TYPE_STRING: { + case PropertyType::kTypeString: { builder.AddField(name, tld::TypeUtf8String); dbuilder.AddString(nostd::get(value).data()); break; } -# ifdef HAVE_CSTRING_TYPE - case common::AttributeType::TYPE_CSTRING: { + case PropertyType::kTypeCString: { builder.AddField(name, tld::TypeUtf8String); auto temp = nostd::get(value); dbuilder.AddString(temp); break; } -# endif # if HAVE_TYPE_GUID // TODO: consider adding UUID/GUID to spec - case common::AttributeType::TYPE_GUID: { + case PropertyType::kGUID: { builder.AddField(name.c_str(), TypeGuid); auto temp = nostd::get(value); dbuilder.AddBytes(&temp, sizeof(GUID)); @@ -539,15 +532,15 @@ class ETWProvider // TODO: arrays are not supported # ifdef HAVE_SPAN_BYTE - case common::AttributeType::TYPE_SPAN_BYTE: + case PropertyType::kTypeSpanByte: # endif - case common::AttributeType::TYPE_SPAN_BOOL: - case common::AttributeType::TYPE_SPAN_INT: - case common::AttributeType::TYPE_SPAN_INT64: - case common::AttributeType::TYPE_SPAN_UINT: - case common::AttributeType::TYPE_SPAN_UINT64: - case common::AttributeType::TYPE_SPAN_DOUBLE: - case common::AttributeType::TYPE_SPAN_STRING: + case PropertyType::kTypeSpanBool: + case PropertyType::kTypeSpanInt: + case PropertyType::kTypeSpanInt64: + case PropertyType::kTypeSpanUInt: + case PropertyType::kTypeSpanUInt64: + case PropertyType::kTypeSpanDouble: + case PropertyType::kTypeSpanString: default: // TODO: unsupported type break; @@ -593,9 +586,8 @@ class ETWProvider #endif } - template unsigned long write(Handle &providerData, - T eventData, + Properties &eventData, LPCGUID ActivityId, LPCGUID RelatedActivityId, uint8_t Opcode, diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h index ac906e2922..d0cdb2c4a5 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer.h @@ -43,8 +43,6 @@ #include "opentelemetry/trace/tracer_provider.h" #include "opentelemetry/sdk/trace/exporter.h" -#include "opentelemetry/sdk/trace/recordable.h" -#include "opentelemetry/sdk/trace/span_data.h" #include "opentelemetry/exporters/etw/etw_fields.h" #include "opentelemetry/exporters/etw/etw_properties.h" @@ -57,7 +55,7 @@ namespace trace = opentelemetry::trace; OPENTELEMETRY_BEGIN_NAMESPACE namespace exporter { -namespace ETW +namespace etw { /** @@ -111,10 +109,10 @@ class Span; /** * @brief Template that allows to instantiate new Span object for header-only forward-declared - * ETW::Span type + * etw::Span type * - * @tparam SpanType Expected to be ETW::Span - * @tparam TracerType expected to be ETW::Tracer + * @tparam SpanType Expected to be etw::Span + * @tparam TracerType expected to be etw::Tracer * @param objPtr Pointer to parent * @param name Span Name * @param options Span Options @@ -129,9 +127,9 @@ SpanType *new_span(TracerType *objPtr, } /** - * @brief Template that allows to convert ETW::Span pointer to smart shared pointer to `trace::Span` - * @tparam SpanType Expected to be ETW::Span - * @param ptr Pointer to ETW::Span + * @brief Template that allows to convert etw::Span pointer to smart shared pointer to `trace::Span` + * @tparam SpanType Expected to be etw::Span + * @param ptr Pointer to etw::Span * @return Smart shared pointer to `trace::Span` */ template @@ -144,8 +142,8 @@ class TracerProvider; /** * @brief Utility template for obtaining Span Name - * @tparam T ETW::Span - * @param t instance of ETW::Span + * @tparam T etw::Span + * @param t instance of etw::Span * @return Span Name */ template @@ -157,8 +155,8 @@ std::string GetName(T &t) /** * @brief Utility template to obtain Span start time - * @tparam T ETW::Span - * @param t instance of ETW::Span + * @tparam T etw::Span + * @param t instance of etw::Span * @return Span Start timestamp */ template @@ -169,8 +167,8 @@ core::SystemTimestamp GetStartTime(T &t) /** * @brief Utility template to obtain Span end time - * @tparam T ETW::Span - * @param t instance of ETW::Span + * @tparam T etw::Span + * @param t instance of etw::Span * @return Span Stop timestamp */ template @@ -183,8 +181,8 @@ class Properties; /** * @brief Utility template to store Attributes on Span - * @tparam T ETW::Span - * @param instance instance of ETW::Span + * @tparam T etw::Span + * @param instance instance of etw::Span * @param t Properties to store as Attributes */ template @@ -195,8 +193,8 @@ void SetSpanAttributes(T &instance, Properties &t) /** * @brief Utility template to obtain Span Attributes - * @tparam T ETW::Span - * @param instance instance of ETW::Span + * @tparam T etw::Span + * @param instance instance of etw::Span * @return ref to Span Attributes */ template @@ -206,10 +204,10 @@ Properties &GetSpanAttributes(T &instance) } /** - * @brief Utility template to obtain ETW::TracerProvider._config + * @brief Utility template to obtain etw::TracerProvider._config * - * @tparam T ETW::TracerProvider - * @param t ETW::TracerProvider ref + * @tparam T etw::TracerProvider + * @param t etw::TracerProvider ref * @return TracerProviderConfiguration ref */ template @@ -257,7 +255,7 @@ class Tracer : public trace::Tracer /** * @brief Parent provider of this Tracer */ - ETW::TracerProvider &tracerProvider_; + etw::TracerProvider &tracerProvider_; /** * @brief ProviderId (Name or GUID) @@ -318,7 +316,7 @@ class Tracer : public trace::Tracer }; /** - * @brief Allow our friendly ETW::Span to end itself on Tracer. + * @brief Allow our friendly etw::Span to end itself on Tracer. * @param span * @param */ @@ -424,7 +422,7 @@ class Tracer : public trace::Tracer std::map> scopes_; /** - * @brief Init a reference to ETW::ProviderHandle + * @brief Init a reference to etw::ProviderHandle * @return Provider Handle */ ETWProvider::Handle &initProvHandle() @@ -444,7 +442,7 @@ class Tracer : public trace::Tracer * @param providerId ProviderId - Name or GUID * @param encoding ETW encoding format to use. */ - Tracer(ETW::TracerProvider &parent, + Tracer(etw::TracerProvider &parent, nostd::string_view providerId = "", ETWProvider::EventFormat encoding = ETWProvider::EventFormat::ETW_MANIFEST) : trace::Tracer(), @@ -456,9 +454,11 @@ class Tracer : public trace::Tracer // Generate random GUID GUID trace_id; CoCreateGuid(&trace_id); - // Populate TraceId of the Tracer with that random GUID - const auto *traceIdBytes = reinterpret_cast(std::addressof(trace_id)); - traceId_ = trace::TraceId(traceIdBytes); + // Populate TraceId of the Tracer with the above GUID + const auto *traceIdPtr = reinterpret_cast(std::addressof(trace_id)); + nostd::span traceIdBytes( + traceIdPtr, traceIdPtr + trace::TraceId::kSize); + traceId_ = trace::TraceId(traceIdBytes); }; /** @@ -524,7 +524,7 @@ class Tracer : public trace::Tracer } } - // This template pattern allows us to forward-declare the ETW::Span, + // This template pattern allows us to forward-declare the etw::Span, // create an instance of it, then assign it to tracer::Span result. auto currentSpan = new_span(this, name, options); nostd::shared_ptr result = to_span_ptr(currentSpan); @@ -722,7 +722,7 @@ class Tracer : public trace::Tracer }; /** - * @brief ETW::Span allows to send event data to ETW listener. + * @brief etw::Span allows to send event data to ETW listener. */ class Span : public trace::Span { @@ -775,9 +775,13 @@ class Span : public trace::Span GUID activity_id; // Generate random GUID CoCreateGuid(&activity_id); - const auto *activityIdBytes = reinterpret_cast(std::addressof(activity_id)); + const auto *activityIdPtr = reinterpret_cast(std::addressof(activity_id)); + // Populate SpanId with that GUID - const trace::SpanId spanId(activityIdBytes); + nostd::span spanIdBytes( + activityIdPtr, activityIdPtr + trace::SpanId::kSize); + const trace::SpanId spanId(spanIdBytes); + // Inherit trace_id from Tracer const trace::TraceId traceId{owner_.trace_id()}; // TODO: TraceFlags are not supported by ETW exporter. @@ -1072,6 +1076,6 @@ class TracerProvider : public trace::TracerProvider } }; -} // namespace ETW +} // namespace etw } // namespace exporter OPENTELEMETRY_END_NAMESPACE diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer_exporter.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer_exporter.h index bcf6cc4460..107254e026 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer_exporter.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_tracer_exporter.h @@ -31,89 +31,11 @@ #include "opentelemetry/trace/tracer_provider.h" #include "opentelemetry/sdk/trace/exporter.h" -#include "opentelemetry/sdk/trace/recordable.h" #include "opentelemetry/exporters/etw/etw_provider.h" -#include "opentelemetry/exporters/etw/etw_recordable.h" #include "opentelemetry/exporters/etw/etw_tracer.h" #include "opentelemetry/exporters/etw/utils.h" namespace core = opentelemetry::core; namespace trace = opentelemetry::trace; - -OPENTELEMETRY_BEGIN_NAMESPACE - -namespace exporter -{ -namespace ETW -{ - -/** - * @brief ETW Tracer Exporter. - * - * TODO: this code needs to be reworked because it is not necessary in synchronous - * realtime exporter / streamer scenario. Header-only ETW Tracer can export Span - * and Events without needing to pack data to into another Recordable. API calls - * return right away after the message is passed to ETW sink in realtime. There is - * no packaging or aggregation necessary, and no need for a background async thread. - * - * There is no 100% reliable way to know if ETW events got exported either: - * - if events got accepted, but cannot be processed, then then out-of-buffers - * notification is only sent to receiving listener-end, not to sender. - * - */ -class ETWTracerExporter final : public opentelemetry::sdk::trace::SpanExporter -{ -public: - /** - * @param providerName - * @param eventName - */ - ETWTracerExporter(std::string providerName) : providerName_(providerName) {} - - /** - * @return Returns a unique pointer to an empty recordable object - */ - std::unique_ptr MakeRecordable() noexcept override - { - return std::unique_ptr(new ETWTraceRecordable(providerName_)); - } - - /** - * @param recordables a required span containing unique pointers to the data - * to add to the ETWTracerExporter - * @return Returns the result of the operation - */ - sdk::trace::ExportResult Export( - const nostd::span> &recordables) noexcept override - { - for (auto &recordable : recordables) - { - auto span = std::unique_ptr( - dynamic_cast(recordable.release())); - if (span != nullptr) - { - std::cout << span->GetName() << std::endl; - } - } - - return sdk::trace::ExportResult::kSuccess; - } - - /** - * @param timeout an optional value containing the timeout of the exporter - * note: passing custom timeout values is not currently supported for this exporter - */ - bool Shutdown(std::chrono::microseconds timeout = std::chrono::microseconds(0)) noexcept override - { - return true; - }; - -private: - std::string providerName_; -}; -} // namespace ETW -} // namespace exporter - -OPENTELEMETRY_END_NAMESPACE From 888a040d0df69cd19a31a793bfe05c213f3b0425 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 2 Apr 2021 01:52:48 -0700 Subject: [PATCH 73/76] Rename types to match Google coding style --- ext/src/zpages/tracez_http_server.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ext/src/zpages/tracez_http_server.cc b/ext/src/zpages/tracez_http_server.cc index efeebcff77..ded5e544c1 100644 --- a/ext/src/zpages/tracez_http_server.cc +++ b/ext/src/zpages/tracez_http_server.cc @@ -121,25 +121,25 @@ json TracezHttpServer::GetAttributesJSON( switch (val.index()) { - case OwnedAttributeType::TYPE_BOOL: + case OwnedAttributeType::kTypeBool: attributes_json[key] = opentelemetry::nostd::get(val); break; - case OwnedAttributeType::TYPE_INT: + case OwnedAttributeType::kTypeInt: attributes_json[key] = opentelemetry::nostd::get(val); break; - case OwnedAttributeType::TYPE_UINT: + case OwnedAttributeType::kTypeUInt: attributes_json[key] = opentelemetry::nostd::get(val); break; - case OwnedAttributeType::TYPE_INT64: + case OwnedAttributeType::kTypeInt64: attributes_json[key] = opentelemetry::nostd::get(val); break; - case OwnedAttributeType::TYPE_UINT64: + case OwnedAttributeType::kTypeUInt64: attributes_json[key] = opentelemetry::nostd::get(val); break; - case OwnedAttributeType::TYPE_DOUBLE: + case OwnedAttributeType::kTypeDouble: attributes_json[key] = opentelemetry::nostd::get(val); break; - case OwnedAttributeType::TYPE_STRING: + case OwnedAttributeType::kTypeString: attributes_json[key] = opentelemetry::nostd::get(val); break; // TODO: arrays support is not implemented From 69c5e6681add527e5faa13065e3d5aea221e8756 Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 2 Apr 2021 01:54:59 -0700 Subject: [PATCH 74/76] Fix mismatched ifdef --- exporters/zipkin/src/recordable.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exporters/zipkin/src/recordable.cc b/exporters/zipkin/src/recordable.cc index 550925d63f..3f440d72d4 100644 --- a/exporters/zipkin/src/recordable.cc +++ b/exporters/zipkin/src/recordable.cc @@ -29,7 +29,7 @@ namespace zipkin // Expecting to remove the two feature gates for: // - HAVE_SPAN_BYTE - proposal for binary type or byte array (uint8_t[]). // -#elif defined(HAVE_SPAN_BYTE) +#if defined(HAVE_SPAN_BYTE) const int kAttributeValueSize = 15; #else const int kAttributeValueSize = 14; From 80512b5c0a2a5781a79514b6a4cec3a4d4a7167e Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 2 Apr 2021 02:10:46 -0700 Subject: [PATCH 75/76] Revert changes to TraceZ --- ext/src/zpages/tracez_http_server.cc | 40 +++++++++++++++------------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/ext/src/zpages/tracez_http_server.cc b/ext/src/zpages/tracez_http_server.cc index ded5e544c1..d44a8939a3 100644 --- a/ext/src/zpages/tracez_http_server.cc +++ b/ext/src/zpages/tracez_http_server.cc @@ -104,8 +104,6 @@ json TracezHttpServer::GetLatencySpansJSON(const std::string &name, int latency_ return latency_json; } -using OwnedAttributeType = opentelemetry::sdk::common::OwnedAttributeType; - json TracezHttpServer::GetAttributesJSON( const opentelemetry::ext::zpages::ThreadsafeSpanData &sample) { @@ -121,29 +119,35 @@ json TracezHttpServer::GetAttributesJSON( switch (val.index()) { - case OwnedAttributeType::kTypeBool: - attributes_json[key] = opentelemetry::nostd::get(val); + case 0: + attributes_json[key] = opentelemetry::nostd::get<0>(val); + break; + case 1: + attributes_json[key] = opentelemetry::nostd::get<1>(val); + break; + case 2: + attributes_json[key] = opentelemetry::nostd::get<2>(val); break; - case OwnedAttributeType::kTypeInt: - attributes_json[key] = opentelemetry::nostd::get(val); + case 3: + attributes_json[key] = opentelemetry::nostd::get<3>(val); break; - case OwnedAttributeType::kTypeUInt: - attributes_json[key] = opentelemetry::nostd::get(val); + case 4: + attributes_json[key] = opentelemetry::nostd::get<4>(val); break; - case OwnedAttributeType::kTypeInt64: - attributes_json[key] = opentelemetry::nostd::get(val); + case 5: + attributes_json[key] = opentelemetry::nostd::get<5>(val); break; - case OwnedAttributeType::kTypeUInt64: - attributes_json[key] = opentelemetry::nostd::get(val); + case 6: + attributes_json[key] = opentelemetry::nostd::get<6>(val); break; - case OwnedAttributeType::kTypeDouble: - attributes_json[key] = opentelemetry::nostd::get(val); + case 7: + attributes_json[key] = opentelemetry::nostd::get<7>(val); break; - case OwnedAttributeType::kTypeString: - attributes_json[key] = opentelemetry::nostd::get(val); + case 8: + attributes_json[key] = opentelemetry::nostd::get<8>(val); break; - // TODO: arrays support is not implemented - default: + case 9: + attributes_json[key] = opentelemetry::nostd::get<9>(val); break; } } From 550f2d85dfa8887815f2d0d56b3003360936723a Mon Sep 17 00:00:00 2001 From: Max Golovanov Date: Fri, 2 Apr 2021 11:24:48 -0700 Subject: [PATCH 76/76] true should be returned from Null object pattern to indicate success --- api/include/opentelemetry/trace/span_context_kv_iterable.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/include/opentelemetry/trace/span_context_kv_iterable.h b/api/include/opentelemetry/trace/span_context_kv_iterable.h index ea316caf97..d0111083ff 100644 --- a/api/include/opentelemetry/trace/span_context_kv_iterable.h +++ b/api/include/opentelemetry/trace/span_context_kv_iterable.h @@ -41,7 +41,7 @@ class NullSpanContext : public SpanContextKeyValueIterable nostd::function_ref callback) const noexcept override { - return false; + return true; } size_t size() const noexcept override { return 0; };