From f3132e5304d9f1a049ffde82b57622c826b70f74 Mon Sep 17 00:00:00 2001 From: Tom Tan Date: Wed, 17 Jan 2024 00:11:06 -0800 Subject: [PATCH] [EXPORTER] Fix forward protocol encoding for ETW exporter (#2473) --- .../exporters/etw/etw_provider.h | 22 ++++++--- .../opentelemetry/exporters/etw/utils.h | 49 +++++++++++++++++-- 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h index 4d7e37a98c..0ffccebc0b 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/etw_provider.h @@ -33,10 +33,6 @@ #include "opentelemetry/exporters/etw/etw_fields.h" #include "opentelemetry/exporters/etw/utils.h" -#ifdef HAVE_MSGPACK -# include "nlohmann/json.hpp" -#endif - #include "opentelemetry/exporters/etw/etw_traceloggingdynamic.h" #include @@ -241,7 +237,7 @@ class ETWProvider } unsigned long writeMsgPack(Handle &providerData, - exporter::etw::Properties &eventData, + Properties &eventData, LPCGUID ActivityId = nullptr, LPCGUID RelatedActivityId = nullptr, uint8_t Opcode = 0) @@ -286,7 +282,6 @@ class ETWProvider /* clang-format off */ nlohmann::json jObj = { - { ETW_FIELD_NAME, eventName }, { ETW_FIELD_OPCODE, Opcode } }; /* clang-format on */ @@ -367,7 +362,18 @@ class ETWProvider } } - std::vector v = nlohmann::json::to_msgpack(jObj); + // forwardMessage.push_back(nameField); + nlohmann::json payloadPair = nlohmann::json::array(); + + payloadPair.push_back( + utils::GetMsgPackEventTimeFromSystemTimestamp(std::chrono::system_clock::now())); + payloadPair.push_back(jObj); + + nlohmann::json payloadArray = nlohmann::json::array({payloadPair}); + + nlohmann::json forwardMessage = nlohmann::json::array({eventName, payloadArray}); + + std::vector v = nlohmann::json::to_msgpack(forwardMessage); EVENT_DESCRIPTOR evtDescriptor; // TODO: event descriptor may be populated with additional values as follows: @@ -377,7 +383,7 @@ class ETWProvider // 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); + EventDescCreate(&evtDescriptor, 100, 0x1, 0, 0, 0, Opcode, 0); EVENT_DATA_DESCRIPTOR evtData[1]; EventDataDescCreate(&evtData[0], v.data(), static_cast(v.size())); ULONG writeResponse = 0; diff --git a/exporters/etw/include/opentelemetry/exporters/etw/utils.h b/exporters/etw/include/opentelemetry/exporters/etw/utils.h index 6a887b6831..f3665efc80 100644 --- a/exporters/etw/include/opentelemetry/exporters/etw/utils.h +++ b/exporters/etw/include/opentelemetry/exporters/etw/utils.h @@ -12,6 +12,7 @@ #include #include "opentelemetry/common/macros.h" +#include "opentelemetry/common/timestamp.h" #include "opentelemetry/exporters/etw/uuid.h" #include "opentelemetry/version.h" @@ -27,11 +28,12 @@ # include #endif -#if defined(ENABLE_ENV_PROPERTIES) - +#if defined(ENABLE_ENV_PROPERTIES) || defined(HAVE_MSGPACK) # include -# include "etw_properties.h" +#endif +#if defined(ENABLE_ENV_PROPERTIES) +# include "etw_properties.h" #endif OPENTELEMETRY_BEGIN_NAMESPACE @@ -383,6 +385,47 @@ static inline void PopulateAttribute(nlohmann::json &attribute, #endif // defined(ENABLE_ENV_PROPERTIES) +#if defined(HAVE_MSGPACK) + +static inline nlohmann::byte_container_with_subtype> +get_msgpack_eventtimeext(int32_t seconds = 0, int32_t nanoseconds = 0) +{ + if ((seconds == 0) && (nanoseconds == 0)) + { + std::chrono::system_clock::time_point tp = std::chrono::system_clock::now(); + auto duration = tp.time_since_epoch(); + seconds = + static_cast(std::chrono::duration_cast(duration).count()); + nanoseconds = static_cast( + std::chrono::duration_cast(duration).count() % 1000000000); + } + + uint64_t timestamp = + ((seconds / 100) & ((1ull << 34) - 1)) | + (((seconds % 100 * 10000000 + nanoseconds / 100) & ((1ull << 30) - 1)) << 34); + + nlohmann::byte_container_with_subtype> ts{std::vector(8)}; + + *reinterpret_cast(ts.data()) = timestamp; + ts.set_subtype(0x00); + + return ts; +} + +static inline nlohmann::byte_container_with_subtype> +GetMsgPackEventTimeFromSystemTimestamp(opentelemetry::common::SystemTimestamp timestamp) noexcept +{ + return get_msgpack_eventtimeext( + // Add all whole seconds to the event time + static_cast( + std::chrono::duration_cast(timestamp.time_since_epoch()).count()), + // Add any remaining nanoseconds past the last whole second + std::chrono::duration_cast(timestamp.time_since_epoch()).count() % + 1000000000); +} + +#endif // defined(HAVE_MSGPACK) + }; // namespace utils OPENTELEMETRY_END_NAMESPACE