Skip to content

Commit

Permalink
ETW Log Exporter (#1006)
Browse files Browse the repository at this point in the history
  • Loading branch information
lalitb authored Oct 6, 2021
1 parent 2f462a5 commit aa63e61
Show file tree
Hide file tree
Showing 9 changed files with 602 additions and 176 deletions.
9 changes: 9 additions & 0 deletions exporters/etw/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ install(
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_logger_test test/etw_logger_test.cc)

add_executable(etw_perf_test test/etw_perf_test.cc)

target_link_libraries(etw_provider_test ${GTEST_BOTH_LIBRARIES}
Expand All @@ -35,6 +37,9 @@ if(BUILD_TESTING)
target_link_libraries(etw_tracer_test ${GTEST_BOTH_LIBRARIES}
opentelemetry_exporter_etw ${CMAKE_THREAD_LIBS_INIT})

target_link_libraries(etw_logger_test ${GTEST_BOTH_LIBRARIES}
opentelemetry_exporter_etw ${CMAKE_THREAD_LIBS_INIT})

target_link_libraries(
etw_perf_test benchmark::benchmark ${GTEST_BOTH_LIBRARIES}
opentelemetry_exporter_etw ${CMAKE_THREAD_LIBS_INIT})
Expand All @@ -47,5 +52,9 @@ if(BUILD_TESTING)
TARGET etw_tracer_test
TEST_PREFIX exporter.
TEST_LIST etw_tracer_test)
gtest_add_tests(
TARGET etw_logger_test
TEST_PREFIX exporter.
TEST_LIST etw_logger_test)

endif() # BUILD_TESTING
186 changes: 186 additions & 0 deletions exporters/etw/include/opentelemetry/exporters/etw/etw_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#pragma once
#include <map>

#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/trace/span_id.h"

#include "opentelemetry/exporters/etw/etw_provider.h"

OPENTELEMETRY_BEGIN_NAMESPACE
namespace exporter
{
namespace etw
{
/**
* @brief TelemetryProvider Options passed via SDK API.
*/
using TelemetryProviderOptions =
std::map<std::string, nostd::variant<std::string, uint64_t, float, bool>>;

/**
* @brief TelemetryProvider runtime configuration class. Internal representation
* of TelemetryProviderOptions used by various components of SDK.
*/
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 Not used
// for Logs
bool enableRelatedActivityId; // Assign parent `SpanId` to `RelatedActivityId`
bool enableAutoParent; // Start new spans as children of current active span, Not used for Logs
ETWProvider::EventFormat
encoding; // Event encoding to use for this provider (TLD, MsgPack, XML, etc.).
} TelemetryProviderConfiguration;

/**
* @brief Helper template to convert a variant value from TelemetryProviderOptions to
* LoggerProviderConfiguration
*
* @param options TelemetryProviderOptions passed on API surface
* @param key Option name
* @param value Reference to destination value
* @param defaultValue Default value if option is not supplied
*/
template <typename T>
static inline void GetOption(const TelemetryProviderOptions &options,
const char *key,
T &value,
T defaultValue)
{
auto it = options.find(key);
if (it != options.end())
{
auto val = it->second;
value = nostd::get<T>(val);
}
else
{
value = defaultValue;
}
}

/**
* @brief Helper template to convert encoding config option to EventFormat.
* Configuration option passed as `options["encoding"] = "MsgPack"`.
* Default encoding is TraceLogging Dynamic Manifest (TLD).
*
* Valid encoding names listed below.
*
* For MessagePack encoding:
* - "MSGPACK"
* - "MsgPack"
* - "MessagePack"
*
* For XML encoding:
* - "XML"
* - "xml"
*
* For TraceLogging Dynamic encoding:
* - "TLD"
* - "tld"
*
*/
static inline ETWProvider::EventFormat GetEncoding(const TelemetryProviderOptions &options)
{
ETWProvider::EventFormat evtFmt = ETWProvider::EventFormat::ETW_MANIFEST;

auto it = options.find("encoding");
if (it != options.end())
{
auto varValue = it->second;
std::string val = nostd::get<std::string>(varValue);

#pragma warning(push)
#pragma warning(disable : 4307) /* Integral constant overflow - OK while computing hash */
auto h = utils::hashCode(val.c_str());
switch (h)
{
case CONST_HASHCODE(MSGPACK):
// nobrk
case CONST_HASHCODE(MsgPack):
// nobrk
case CONST_HASHCODE(MessagePack):
evtFmt = ETWProvider::EventFormat::ETW_MSGPACK;
break;

case CONST_HASHCODE(XML):
// nobrk
case CONST_HASHCODE(xml):
evtFmt = ETWProvider::EventFormat::ETW_XML;
break;

case CONST_HASHCODE(TLD):
// nobrk
case CONST_HASHCODE(tld):
// nobrk
evtFmt = ETWProvider::EventFormat::ETW_MANIFEST;
break;

default:
break;
}
#pragma warning(pop)
}

return evtFmt;
}

/**
* @brief Utility template to obtain etw::TracerProvider._config or etw::LoggerProvider._config
*
* @tparam T etw::TracerProvider
* @param t etw::TracerProvider ref
* @return TelemetryProviderConfiguration ref
*/
template <class T>
TelemetryProviderConfiguration &GetConfiguration(T &t)
{
return t.config_;
}

/**
* @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 <class T>
static inline std::string ToLowerBase16(const T &id)
{
char buf[2 * T::kSize] = {0};
id.ToLowerBase16(buf);
return std::string(buf, sizeof(buf));
}

/**
* @brief Utility method to convert span_id (8 byte) to ActivityId GUID (16 bytes)
* @param span OpenTelemetry Span Id object
* @return GUID struct containing 8-bytes of SpanId + 8 NUL bytes.
*/
static inline bool CopySpanIdToActivityId(const opentelemetry::trace::SpanId &span_id,
GUID &outGuid)
{
memset(&outGuid, 0, sizeof(outGuid));
if (!span_id.IsValid())
{
return false;
}
auto spanId = span_id.Id().data();
uint8_t *guidPtr = reinterpret_cast<uint8_t *>(&outGuid);
for (size_t i = 0; i < 8; i++)
{
guidPtr[i] = spanId[i];
}
return true;
}

} // namespace etw
} // namespace exporter
OPENTELEMETRY_END_NAMESPACE
10 changes: 10 additions & 0 deletions exporters/etw/include/opentelemetry/exporters/etw/etw_fields.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,22 @@
# define ETW_FIELD_STATUSCODE "StatusCode" /* Span status code */
# define ETW_FIELD_STATUSMESSAGE "StatusMessage" /* Span status message */
# define ETW_FIELD_SUCCESS "Success" /* Span success */
# define ETW_FIELD_TIMESTAMP "Timestamp" /* Log timestamp */

/* Value constants */
# define ETW_VALUE_SPAN "Span" /* ETW event name for Span */
# define ETW_VALUE_LOG "Log" /* ETW event name for Log */

# define ETW_VALUE_SPAN_START "SpanStart" /* ETW for Span Start */
# define ETW_VALUE_SPAN_END "SpanEnd" /* ETW for Span Start */


/* Log specific */
# define ETW_FIELD_LOG_BODY "body" /* Log body */
# define ETW_FIELD_LOG_SEVERITY_TEXT "severityText" /* Sev text */
# define ETW_FIELD_LOG_SEVERITY_NUM "severityNumber" /* Sev num */


#endif

/* clang-format on */
Loading

0 comments on commit aa63e61

Please sign in to comment.