Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EXPORTER] Fix forward protocol encoding for ETW exporter #2473

Merged
merged 12 commits into from
Jan 17, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -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 <map>
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -286,7 +282,6 @@ class ETWProvider
/* clang-format off */
nlohmann::json jObj =
{
{ ETW_FIELD_NAME, eventName },
{ ETW_FIELD_OPCODE, Opcode }
};
/* clang-format on */
Expand Down Expand Up @@ -367,7 +362,18 @@ class ETWProvider
}
}

std::vector<uint8_t> 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<uint8_t> v = nlohmann::json::to_msgpack(forwardMessage);

EVENT_DESCRIPTOR evtDescriptor;
// TODO: event descriptor may be populated with additional values as follows:
Expand All @@ -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<ULONG>(v.size()));
ULONG writeResponse = 0;
Expand Down
49 changes: 46 additions & 3 deletions exporters/etw/include/opentelemetry/exporters/etw/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <string>

#include "opentelemetry/common/macros.h"
#include "opentelemetry/common/timestamp.h"
#include "opentelemetry/exporters/etw/uuid.h"
#include "opentelemetry/version.h"

Expand All @@ -27,11 +28,12 @@
# include <codecvt>
#endif

#if defined(ENABLE_ENV_PROPERTIES)

#if defined(ENABLE_ENV_PROPERTIES) || defined(HAVE_MSGPACK)
# include <nlohmann/json.hpp>
# include "etw_properties.h"
#endif

#if defined(ENABLE_ENV_PROPERTIES)
# include "etw_properties.h"
#endif

OPENTELEMETRY_BEGIN_NAMESPACE
Expand Down Expand Up @@ -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<std::vector<std::uint8_t>>
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<int32_t>(std::chrono::duration_cast<std::chrono::seconds>(duration).count());
nanoseconds = static_cast<int32_t>(
std::chrono::duration_cast<std::chrono::nanoseconds>(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<std::vector<std::uint8_t>> ts{std::vector<uint8_t>(8)};

*reinterpret_cast<uint64_t *>(ts.data()) = timestamp;
ts.set_subtype(0x00);

return ts;
}

static inline nlohmann::byte_container_with_subtype<std::vector<std::uint8_t>>
GetMsgPackEventTimeFromSystemTimestamp(opentelemetry::common::SystemTimestamp timestamp) noexcept
{
return get_msgpack_eventtimeext(
// Add all whole seconds to the event time
static_cast<int32_t>(
std::chrono::duration_cast<std::chrono::seconds>(timestamp.time_since_epoch()).count()),
// Add any remaining nanoseconds past the last whole second
std::chrono::duration_cast<std::chrono::nanoseconds>(timestamp.time_since_epoch()).count() %
1000000000);
}

#endif // defined(HAVE_MSGPACK)

}; // namespace utils

OPENTELEMETRY_END_NAMESPACE
Loading