From 0a3320ecdf92090d9e9db4aaaa89af5a8ceec87e Mon Sep 17 00:00:00 2001
From: David Li
Date: Thu, 24 Jun 2021 15:05:38 -0400
Subject: [PATCH 01/11] Rename bswap_64 to otel_bswap_64 to avoid clash with
macro (#875) (#876)
---
.../opentelemetry/exporters/jaeger/recordable.h | 4 ++--
exporters/jaeger/src/recordable.cc | 8 ++++----
exporters/jaeger/test/jaeger_recordable_test.cc | 10 +++++-----
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/exporters/jaeger/include/opentelemetry/exporters/jaeger/recordable.h b/exporters/jaeger/include/opentelemetry/exporters/jaeger/recordable.h
index c5ce57c3c4..01a4bb0d79 100644
--- a/exporters/jaeger/include/opentelemetry/exporters/jaeger/recordable.h
+++ b/exporters/jaeger/include/opentelemetry/exporters/jaeger/recordable.h
@@ -29,13 +29,13 @@ namespace jaeger
# if defined(__clang__) || \
(defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || __GNUC__ >= 5))
-inline uint64_t bswap_64(uint64_t host_int)
+inline uint64_t otel_bswap_64(uint64_t host_int)
{
return __builtin_bswap64(host_int);
}
# elif defined(_MSC_VER)
-inline uint64_t bswap_64(uint64_t host_int)
+inline uint64_t otel_bswap_64(uint64_t host_int)
{
return _byteswap_uint64(host_int);
}
diff --git a/exporters/jaeger/src/recordable.cc b/exporters/jaeger/src/recordable.cc
index 3e3661623e..c9425b963b 100644
--- a/exporters/jaeger/src/recordable.cc
+++ b/exporters/jaeger/src/recordable.cc
@@ -46,13 +46,13 @@ void Recordable::SetIdentity(const trace::SpanContext &span_context,
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/sdk_exporters/jaeger.md#ids
#if JAEGER_IS_LITTLE_ENDIAN == 1
span_->__set_traceIdHigh(
- bswap_64(*(reinterpret_cast(span_context.trace_id().Id().data()))));
+ otel_bswap_64(*(reinterpret_cast(span_context.trace_id().Id().data()))));
span_->__set_traceIdLow(
- bswap_64(*(reinterpret_cast(span_context.trace_id().Id().data()) + 1)));
+ otel_bswap_64(*(reinterpret_cast(span_context.trace_id().Id().data()) + 1)));
span_->__set_spanId(
- bswap_64(*(reinterpret_cast(span_context.span_id().Id().data()))));
+ otel_bswap_64(*(reinterpret_cast(span_context.span_id().Id().data()))));
span_->__set_parentSpanId(
- bswap_64(*(reinterpret_cast(parent_span_id.Id().data()))));
+ otel_bswap_64(*(reinterpret_cast(parent_span_id.Id().data()))));
#else
span_->__set_traceIdLow(
*(reinterpret_cast(span_context.trace_id().Id().data())));
diff --git a/exporters/jaeger/test/jaeger_recordable_test.cc b/exporters/jaeger/test/jaeger_recordable_test.cc
index 2692096213..2289a53ab9 100644
--- a/exporters/jaeger/test/jaeger_recordable_test.cc
+++ b/exporters/jaeger/test/jaeger_recordable_test.cc
@@ -43,10 +43,10 @@ TEST(JaegerSpanRecordable, SetIdentity)
std::unique_ptr span{rec.Span()};
#if JAEGER_IS_LITTLE_ENDIAN == 1
- EXPECT_EQ(span->traceIdLow, opentelemetry::exporter::jaeger::bswap_64(trace_id_val[1]));
- EXPECT_EQ(span->traceIdHigh, opentelemetry::exporter::jaeger::bswap_64(trace_id_val[0]));
- EXPECT_EQ(span->spanId, opentelemetry::exporter::jaeger::bswap_64(span_id_val));
- EXPECT_EQ(span->parentSpanId, opentelemetry::exporter::jaeger::bswap_64(parent_span_id_val));
+ EXPECT_EQ(span->traceIdLow, opentelemetry::exporter::jaeger::otel_bswap_64(trace_id_val[1]));
+ EXPECT_EQ(span->traceIdHigh, opentelemetry::exporter::jaeger::otel_bswap_64(trace_id_val[0]));
+ EXPECT_EQ(span->spanId, opentelemetry::exporter::jaeger::otel_bswap_64(span_id_val));
+ EXPECT_EQ(span->parentSpanId, opentelemetry::exporter::jaeger::otel_bswap_64(parent_span_id_val));
#else
EXPECT_EQ(span->traceIdLow, trace_id_val[0]);
EXPECT_EQ(span->traceIdHigh, trace_id_val[1]);
@@ -143,4 +143,4 @@ TEST(JaegerSpanRecordable, SetInstrumentationLibrary)
EXPECT_EQ(tags[1].key, "otel.library.version");
EXPECT_EQ(tags[1].vType, thrift::TagType::STRING);
EXPECT_EQ(tags[1].vStr, library_version);
-}
\ No newline at end of file
+}
From b5dd914c9d7a36342a8b9e4d1c014354e983f917 Mon Sep 17 00:00:00 2001
From: Max Golovanov
Date: Wed, 30 Jun 2021 09:23:32 -0700
Subject: [PATCH 02/11] Clarify the strategy to avoid conflict between two
different versions of Abseil (#883)
---
examples/otlp/README.md | 15 +++++++++++++++
examples/otlp/grpc_main.cc | 3 +++
2 files changed, 18 insertions(+)
diff --git a/examples/otlp/README.md b/examples/otlp/README.md
index 03325cd681..cd85a392a1 100644
--- a/examples/otlp/README.md
+++ b/examples/otlp/README.md
@@ -49,3 +49,18 @@ default. This can be changed with first argument from command-line, for example:
Once you have the Collector running, see
[CONTRIBUTING.md](../../CONTRIBUTING.md) for instructions on building and
running the example.
+
+## Additional notes regarding Abseil library
+
+gRPC internally uses a different version of Abseil than OpenTelemetry C++ SDK.
+
+One option to optimize your code is to build the SDK with system-provided
+Abseil library. If you are using CMake, then `-DWITH_ABSEIL=ON` may be passed
+during the build of SDK to reuse the same Abseil library as gRPC.
+
+If you do not want to pursue the above option, and in case if you run into
+conflict between Abseil library and OpenTelemetry C++ `absl::variant`
+implementation, please include either `grpcpp/grpcpp.h` or
+`opentelemetry/exporters/otlp/otlp_grpc_exporter.h` BEFORE any other API
+headers. This approach efficiently avoids the conflict between the two different
+versions of Abseil.
diff --git a/examples/otlp/grpc_main.cc b/examples/otlp/grpc_main.cc
index 7df891ad0a..7789457909 100644
--- a/examples/otlp/grpc_main.cc
+++ b/examples/otlp/grpc_main.cc
@@ -1,6 +1,9 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
+// Make sure to include GRPC exporter first because otherwise Abseil may create
+// ambiguity with `nostd::variant`. See issue:
+// https://github.com/open-telemetry/opentelemetry-cpp/issues/880
#include "opentelemetry/exporters/otlp/otlp_grpc_exporter.h"
#include "opentelemetry/sdk/trace/simple_processor.h"
#include "opentelemetry/sdk/trace/tracer_provider.h"
From 47859cc37e977f70515bbaaf6c4a560899b0ffcd Mon Sep 17 00:00:00 2001
From: Max Golovanov
Date: Wed, 30 Jun 2021 19:37:27 -0700
Subject: [PATCH 03/11] ETW example and tests clean-up (#882)
---
.../opentelemetry/context/runtime_context.h | 2 +-
examples/CMakeLists.txt | 3 +
examples/etw_threads/CMakeLists.txt | 6 +
examples/etw_threads/README.md | 32 ++++
examples/etw_threads/main.cc | 154 ++++++++++++++++++
exporters/etw/test/etw_tracer_test.cc | 151 +++++++++++++++--
6 files changed, 337 insertions(+), 11 deletions(-)
create mode 100644 examples/etw_threads/CMakeLists.txt
create mode 100644 examples/etw_threads/README.md
create mode 100644 examples/etw_threads/main.cc
diff --git a/api/include/opentelemetry/context/runtime_context.h b/api/include/opentelemetry/context/runtime_context.h
index 400b3de544..afefa93e7d 100644
--- a/api/include/opentelemetry/context/runtime_context.h
+++ b/api/include/opentelemetry/context/runtime_context.h
@@ -169,7 +169,7 @@ inline Token::~Token()
}
// The ThreadLocalContextStorage class is a derived class from
-// RuntimeContextStorage and provides a wrapper for propogating context through
+// RuntimeContextStorage and provides a wrapper for propagating context through
// cpp thread locally. This file must be included to use the RuntimeContext
// class if another implementation has not been registered.
class ThreadLocalContextStorage : public RuntimeContextStorage
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 9ea0a544fb..782f20d18e 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -2,6 +2,9 @@ if(WITH_OTLP_GRPC OR WITH_OTLP_HTTP)
add_subdirectory(otlp)
add_subdirectory(grpc)
endif()
+if(WITH_ETW)
+ add_subdirectory(etw_threads)
+endif()
if(WITH_JAEGER)
add_subdirectory(jaeger)
endif()
diff --git a/examples/etw_threads/CMakeLists.txt b/examples/etw_threads/CMakeLists.txt
new file mode 100644
index 0000000000..fd6ac76443
--- /dev/null
+++ b/examples/etw_threads/CMakeLists.txt
@@ -0,0 +1,6 @@
+project(etw_threadpool)
+
+add_executable(etw_threadpool main.cc)
+
+target_link_libraries(etw_threadpool ${CMAKE_THREAD_LIBS_INIT}
+ opentelemetry_api opentelemetry_exporter_etw)
diff --git a/examples/etw_threads/README.md b/examples/etw_threads/README.md
new file mode 100644
index 0000000000..a004a9f55b
--- /dev/null
+++ b/examples/etw_threads/README.md
@@ -0,0 +1,32 @@
+# ETW Exporter multithreaded context propagation example
+
+## Preface
+
+This example shows how to pass context from main dispatcher thread to worker threads.
+While this example is convenient to run in Visual Studio with ETW exporter, the same
+logic should apply to any other exporter. Only the initial portion that obtains ETW
+Tracer is unique to ETW, the rest can be reused.
+
+## How to debug events in Visual Studio 2019 or newer
+
+Specify your component instrumentation name, which should match the destination ETW
+Provider Name or GUID. Example uses "OpenTelemetry-ETW-TLD" for the instrument /
+instrumentation name.
+
+In Visual Studio IDE:
+
+- navigate to `View -> Other Windows -> Diagnostic Events...`
+- click `Configure...` gear on top.
+- specify `OpenTelemetry-ETW-TLD` in the list of providers to monitor.
+- run example.
+- `Diagnostic Events` view shows you the event flow in realtime.
+
+## Explanation of the code flow
+
+`main` function acts as a dispatcher to manage thread pool called `pool`. `beep_bop`
+span is started in the `main`. Then in a loop up to `kMaxThreads` get started
+concurrently. Each thread executing `beep` function with a parent scope of `main`.
+`beep` subsequently calls into `bop` function, with a parent scope of `beep` span.
+Entire execution of all threads is grouped under the main span called `beep_bop`.
+At the end of execution, the `main` function joins all pending threads and ends
+the main span.
diff --git a/examples/etw_threads/main.cc b/examples/etw_threads/main.cc
new file mode 100644
index 0000000000..d25883d1d1
--- /dev/null
+++ b/examples/etw_threads/main.cc
@@ -0,0 +1,154 @@
+// Copyright The OpenTelemetry Authors
+// SPDX-License-Identifier: Apache-2.0
+
+// Include common Trace Provider API and processor
+#include "opentelemetry/sdk/trace/simple_processor.h"
+#include "opentelemetry/sdk/trace/tracer_provider.h"
+#include "opentelemetry/trace/provider.h"
+
+#include "opentelemetry/exporters/etw/etw_tracer_exporter.h"
+
+#include
+#include
+
+#include
+#ifndef LOG_DEBUG
+# include
+
+/**
+ * @brief Thread-safe logger routine.
+ * @param format
+ * @param args
+ * @return
+ */
+static inline int log_vprintf(const char *format, va_list args)
+{
+ static std::mutex cout_mutex;
+ std::lock_guard lk(cout_mutex);
+ return vprintf(format, args);
+};
+
+/**
+ * @brief Thread-safe logger routine.
+ * @param format
+ * @param
+ * @return
+ */
+static inline int log_printf(const char *format, ...)
+{
+ int result;
+ va_list ap;
+ va_start(ap, format);
+ result = log_vprintf(format, ap);
+ va_end(ap);
+ return result;
+};
+
+// Debug macros
+# define LOG_DEBUG(fmt_, ...) log_printf(" " fmt_ "\n", ##__VA_ARGS__)
+# define LOG_TRACE(fmt_, ...) log_printf(" " fmt_ "\n", ##__VA_ARGS__)
+# define LOG_INFO(fmt_, ...) log_printf(" " fmt_ "\n", ##__VA_ARGS__)
+# define LOG_WARN(fmt_, ...) log_printf(" " fmt_ "\n", ##__VA_ARGS__)
+# define LOG_ERROR(fmt_, ...) log_printf(" " fmt_ "\n", ##__VA_ARGS__)
+#endif
+
+using namespace OPENTELEMETRY_NAMESPACE;
+
+using namespace opentelemetry::exporter::etw;
+
+// Specify destination ETW Provider Name or GUID.
+//
+// In Visual Studio:
+// - View -> Other Windows -> Diagnostic Events...
+// - Click Configure (gear on top).
+// - Specify "OpenTelemetry-ETW-TLD" in the list of providers.
+//
+// Event view shows event flow in realtime.
+const char *kGlobalProviderName = "OpenTelemetry-ETW-TLD";
+
+std::string providerName = kGlobalProviderName;
+
+// One provider can be used to associate with different destinations.
+exporter::etw::TracerProvider provider;
+
+// Code below is generic and may be reused with any other TracerProvider.
+// In ETW provider case - instrumentation name must match destination
+// ETW provider name.
+nostd::shared_ptr tracer = provider.GetTracer(providerName, "1.0");
+
+// Obtain numeric thread id
+static inline uint64_t gettid()
+{
+ std::stringstream ss;
+ ss << std::this_thread::get_id();
+ uint64_t id = std::stoull(ss.str());
+ return id;
+}
+
+// bop gets called by beep.
+void bop()
+{
+ LOG_TRACE("bop worker tid=%u", gettid());
+ auto span = tracer->StartSpan("bop");
+ span->AddEvent("BopEvent", {{"tid", gettid()}});
+ span->SetAttribute("attrib", 2);
+ span->End();
+}
+
+// beep gets called in its own thread.
+// It is running in a thread pool, invoked via lambda by dispatcher.
+void beep()
+{
+ LOG_TRACE("beep worker tid=%u", gettid());
+ auto span = tracer->StartSpan("beep");
+ span->AddEvent("BeepEvent", {{"tid", gettid()}});
+ span->SetAttribute("attrib", 1);
+ {
+ auto bopScope = tracer->WithActiveSpan(span);
+ bop();
+ }
+ span->End();
+}
+
+// Max number of threads to spawn
+constexpr int kMaxThreads = 10;
+
+int main(int arc, char **argv)
+{
+ std::thread pool[kMaxThreads];
+
+ // Main dispatcher span: parent of all child thread spans.
+ auto mainSpan = tracer->StartSpan("beep_bop");
+ mainSpan->SetAttribute("attrib", 0);
+
+ // Start several threads to perform beep-bop actions.
+ LOG_TRACE("beep-boop dispatcher tid=%u", gettid());
+ for (auto i = 0; i < kMaxThreads; i++)
+ {
+ pool[i] = std::thread([&]() {
+ // This code runs in its own worker thread.
+ auto beepScope = tracer->WithActiveSpan(mainSpan);
+ // call beep -> bop
+ beep();
+ });
+ };
+
+ // Join all worker threads in the pool
+ for (auto &th : pool)
+ {
+ try
+ {
+ if (th.joinable())
+ th.join();
+ }
+ catch (...)
+ {
+ // thread might have been gracefully terminated already
+ }
+ }
+
+ // End span
+ mainSpan->End();
+
+ return 0;
+}
diff --git a/exporters/etw/test/etw_tracer_test.cc b/exporters/etw/test/etw_tracer_test.cc
index 45d49356c8..400099bbe7 100644
--- a/exporters/etw/test/etw_tracer_test.cc
+++ b/exporters/etw/test/etw_tracer_test.cc
@@ -14,6 +14,8 @@ using namespace OPENTELEMETRY_NAMESPACE;
using namespace opentelemetry::exporter::etw;
+const char *kGlobalProviderName = "OpenTelemetry-ETW-TLD";
+
std::string getTemporaryValue()
{
return std::string("Value from Temporary std::string");
@@ -43,11 +45,10 @@ 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-TLD"; // supply unique instrumentation name here
+ std::string providerName = kGlobalProviderName; // 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 tracer = tp.GetTracer(providerName);
// Span attributes
Properties attribs =
@@ -117,7 +118,7 @@ TEST(ETWTracer, TracerCheck)
/*
{
"Timestamp": "2021-03-19T21:04:38.411193-07:00",
- "ProviderName": "OpenTelemetry-ETW-Provider",
+ "ProviderName": "OpenTelemetry-ETW-TLD",
"Id": 13,
"Message": null,
"ProcessId": 15120,
@@ -131,7 +132,7 @@ TEST(ETWTracer, TracerCheck)
*/
TEST(ETWTracer, TracerCheckMinDecoration)
{
- std::string providerName = "OpenTelemetry-ETW-TLD";
+ std::string providerName = kGlobalProviderName;
exporter::etw::TracerProvider tp
({
{"enableTraceId", false},
@@ -141,7 +142,7 @@ TEST(ETWTracer, TracerCheckMinDecoration)
{"enableRelatedActivityId", false},
{"enableAutoParent", false}
});
- auto tracer = tp.GetTracer(providerName, "TLD");
+ auto tracer = tp.GetTracer(providerName);
{
auto aSpan = tracer->StartSpan("A.min");
auto aScope = tracer->WithActiveSpan(aSpan);
@@ -166,7 +167,7 @@ TEST(ETWTracer, TracerCheckMinDecoration)
/*
{
"Timestamp": "2021-03-19T21:04:38.4120274-07:00",
- "ProviderName": "OpenTelemetry-ETW-Provider",
+ "ProviderName": "OpenTelemetry-ETW-TLD",
"Id": 21,
"Message": null,
"ProcessId": 15120,
@@ -183,7 +184,7 @@ TEST(ETWTracer, TracerCheckMinDecoration)
*/
TEST(ETWTracer, TracerCheckMaxDecoration)
{
- std::string providerName = "OpenTelemetry-ETW-TLD";
+ std::string providerName = kGlobalProviderName;
exporter::etw::TracerProvider tp
({
{"enableTraceId", true},
@@ -192,7 +193,7 @@ TEST(ETWTracer, TracerCheckMaxDecoration)
{"enableRelatedActivityId", true},
{"enableAutoParent", true}
});
- auto tracer = tp.GetTracer(providerName, "TLD" );
+ auto tracer = tp.GetTracer(providerName);
{
auto aSpan = tracer->StartSpan("A.max");
auto aScope = tracer->WithActiveSpan(aSpan);
@@ -222,7 +223,7 @@ TEST(ETWTracer, TracerCheckMsgPack)
{"enableRelatedActivityId", true},
{"enableAutoParent", true}
});
- auto tracer = tp.GetTracer(providerName, "MsgPack" );
+ auto tracer = tp.GetTracer(providerName);
{
auto aSpan = tracer->StartSpan("A.max");
auto aScope = tracer->WithActiveSpan(aSpan);
@@ -249,6 +250,136 @@ TEST(ETWTracer, TracerCheckMsgPack)
tracer->CloseWithMicroseconds(0);
}
+/**
+ * @brief Global Tracer singleton may be placed in .h header and
+ * shared across different compilation units. All would get the
+ * same object.
+ *
+ * @return Single global tracer instance.
+*/
+static OPENTELEMETRY_NAMESPACE::trace::TracerProvider& GetGlobalTracerProvider()
+{
+ static exporter::etw::TracerProvider tp
+ ({
+ {"enableTraceId", true},
+ {"enableSpanId", true},
+ {"enableActivityId", true},
+ {"enableRelatedActivityId", true},
+ {"enableAutoParent", true}
+ });
+ return tp;
+}
+
+static OPENTELEMETRY_NAMESPACE::trace::Tracer& GetGlobalTracer()
+{
+ static auto tracer = GetGlobalTracerProvider().GetTracer(kGlobalProviderName);
+ return (*tracer.get());
+}
+
+TEST(ETWTracer, GlobalSingletonTracer)
+{
+ // Obtain a global tracer using C++11 magic static.
+ auto& globalTracer = GetGlobalTracer();
+ auto s1 = globalTracer.StartSpan("Span1");
+ auto traceId1 = s1->GetContext().trace_id();
+ s1->End();
+/* === Span 1 - "TraceId": "182a64258fb1864ca4e1a542eecbd9bf"
+{
+ "Timestamp": "2021-05-10T11:45:27.028827-07:00",
+ "ProviderName": "OpenTelemetry-ETW-TLD",
+ "Id": 5,
+ "Message": null,
+ "ProcessId": 23712,
+ "Level": "Always",
+ "Keywords": "0x0000000000000000",
+ "EventName": "Span",
+ "ActivityID": "6ed94703-6b0a-4e76-0000-000000000000",
+ "RelatedActivityID": null,
+ "Payload": {
+ "Duration": 0,
+ "Kind": 1,
+ "Name": "Span1",
+ "SpanId": "0347d96e0a6b764e",
+ "StartTime": "2021-05-10T18:45:27.028000Z",
+ "StatusCode": 0,
+ "StatusMessage": "",
+ "Success": "True",
+ "TraceId": "182a64258fb1864ca4e1a542eecbd9bf",
+ "_name": "Span"
+ }
+}
+*/
+
+ // Obtain a different tracer withs its own trace-id.
+ auto localTracer = GetGlobalTracerProvider().GetTracer(kGlobalProviderName);
+ auto s2 = localTracer->StartSpan("Span2");
+ auto traceId2 = s2->GetContext().trace_id();
+ s2->End();
+/* === Span 2 - "TraceId": "334bf9a1eed98d40a873a606295a9368"
+{
+ "Timestamp": "2021-05-10T11:45:27.0289654-07:00",
+ "ProviderName": "OpenTelemetry-ETW-TLD",
+ "Id": 5,
+ "Message": null,
+ "ProcessId": 23712,
+ "Level": "Always",
+ "Keywords": "0x0000000000000000",
+ "EventName": "Span",
+ "ActivityID": "3b7b2ecb-2e84-4903-0000-000000000000",
+ "RelatedActivityID": null,
+ "Payload": {
+ "Duration": 0,
+ "Kind": 1,
+ "Name": "Span2",
+ "SpanId": "cb2e7b3b842e0349",
+ "StartTime": "2021-05-10T18:45:27.028000Z",
+ "StatusCode": 0,
+ "StatusMessage": "",
+ "Success": "True",
+ "TraceId": "334bf9a1eed98d40a873a606295a9368",
+ "_name": "Span"
+ }
+}
+*/
+
+ // Obtain the same global tracer with the same trace-id as before.
+ auto& globalTracer2 = GetGlobalTracer();
+ auto s3 = globalTracer2.StartSpan("Span3");
+ auto traceId3 = s3->GetContext().trace_id();
+ s3->End();
+/* === Span 3 - "TraceId": "182a64258fb1864ca4e1a542eecbd9bf"
+{
+ "Timestamp": "2021-05-10T11:45:27.0290936-07:00",
+ "ProviderName": "OpenTelemetry-ETW-TLD",
+ "Id": 5,
+ "Message": null,
+ "ProcessId": 23712,
+ "Level": "Always",
+ "Keywords": "0x0000000000000000",
+ "EventName": "Span",
+ "ActivityID": "0a970247-ba0e-4d4b-0000-000000000000",
+ "RelatedActivityID": null,
+ "Payload": {
+ "Duration": 1,
+ "Kind": 1,
+ "Name": "Span3",
+ "SpanId": "4702970a0eba4b4d",
+ "StartTime": "2021-05-10T18:45:27.028000Z",
+ "StatusCode": 0,
+ "StatusMessage": "",
+ "Success": "True",
+ "TraceId": "182a64258fb1864ca4e1a542eecbd9bf",
+ "_name": "Span"
+ }
+}
+*/
+ EXPECT_NE(traceId1, traceId2);
+ EXPECT_EQ(traceId1, traceId3);
+
+ localTracer->CloseWithMicroseconds(0);
+ globalTracer.CloseWithMicroseconds(0);
+}
+
/* clang-format on */
#endif
From 85564852048e908e7d579374c52f6214e9dca1a6 Mon Sep 17 00:00:00 2001
From: Lalit Kumar Bhasin
Date: Thu, 1 Jul 2021 08:43:50 +0530
Subject: [PATCH 04/11] Few minor fixes for zipkin exporter (#886)
---
.../opentelemetry/exporters/zipkin/zipkin_exporter.h | 6 +++---
exporters/zipkin/src/recordable.cc | 2 +-
exporters/zipkin/test/zipkin_recordable_test.cc | 12 +++++-------
3 files changed, 9 insertions(+), 11 deletions(-)
diff --git a/exporters/zipkin/include/opentelemetry/exporters/zipkin/zipkin_exporter.h b/exporters/zipkin/include/opentelemetry/exporters/zipkin/zipkin_exporter.h
index a69eaf9caf..cb244867d7 100644
--- a/exporters/zipkin/include/opentelemetry/exporters/zipkin/zipkin_exporter.h
+++ b/exporters/zipkin/include/opentelemetry/exporters/zipkin/zipkin_exporter.h
@@ -17,11 +17,11 @@ namespace exporter
namespace zipkin
{
-const char *kZipkinEndpointDefault = "http://localhost:9411/api/v2/spans";
-
-static const std::string GetDefaultZipkinEndpoint()
+inline const std::string GetDefaultZipkinEndpoint()
{
const char *otel_exporter_zipkin_endpoint_env = "OTEL_EXPORTER_ZIPKIN_ENDPOINT";
+ const char *kZipkinEndpointDefault = "http://localhost:9411/api/v2/spans";
+
#if defined(_MSC_VER)
// avoid calling std::getenv which is deprecated in MSVC.
size_t required_size = 0;
diff --git a/exporters/zipkin/src/recordable.cc b/exporters/zipkin/src/recordable.cc
index bbdc85c548..07d9b09c9d 100644
--- a/exporters/zipkin/src/recordable.cc
+++ b/exporters/zipkin/src/recordable.cc
@@ -225,7 +225,7 @@ void Recordable::SetStartTime(opentelemetry::common::SystemTimestamp start_time)
void Recordable::SetDuration(std::chrono::nanoseconds duration) noexcept
{
- span_["duration"] = duration.count();
+ span_["duration"] = std::chrono::duration_cast(duration).count();
}
void Recordable::SetSpanKind(opentelemetry::trace::SpanKind span_kind) noexcept
diff --git a/exporters/zipkin/test/zipkin_recordable_test.cc b/exporters/zipkin/test/zipkin_recordable_test.cc
index 51ba1024b6..7a5feb8bdb 100644
--- a/exporters/zipkin/test/zipkin_recordable_test.cc
+++ b/exporters/zipkin/test/zipkin_recordable_test.cc
@@ -12,8 +12,6 @@
#include "opentelemetry/common/timestamp.h"
#include "opentelemetry/exporters/zipkin/recordable.h"
-#include
-
#include
namespace trace = opentelemetry::trace;
@@ -69,16 +67,16 @@ TEST(ZipkinSpanRecordable, SetStartTime)
TEST(ZipkinSpanRecordable, SetDuration)
{
- json j_span = {{"duration", 10}, {"timestamp", 0}};
+ std::chrono::nanoseconds durationNS(1000000000); // in ns
+ std::chrono::microseconds durationMS =
+ std::chrono::duration_cast(durationNS); // in ms
+ json j_span = {{"duration", durationMS.count()}, {"timestamp", 0}};
opentelemetry::exporter::zipkin::Recordable rec;
// Start time is 0
opentelemetry::common::SystemTimestamp start_timestamp;
- std::chrono::nanoseconds duration(10);
- uint64_t unix_end = duration.count();
-
rec.SetStartTime(start_timestamp);
- rec.SetDuration(duration);
+ rec.SetDuration(durationNS);
EXPECT_EQ(rec.span(), j_span);
}
From 2383d99d4d80310999b152cfdff69f3dc1b6f1b7 Mon Sep 17 00:00:00 2001
From: Lalit Kumar Bhasin
Date: Thu, 1 Jul 2021 09:11:50 +0530
Subject: [PATCH 05/11] Associate valid SpanId/SpanContext with Spans
irrespective of the Sampling decision. (#879)
---
api/include/opentelemetry/trace/noop.h | 11 +++++--
api/test/trace/noop_test.cc | 43 +++++++++++++++++++-------
sdk/src/trace/tracer.cc | 22 +++++++------
sdk/test/trace/tracer_test.cc | 8 ++++-
4 files changed, 59 insertions(+), 25 deletions(-)
diff --git a/api/include/opentelemetry/trace/noop.h b/api/include/opentelemetry/trace/noop.h
index ad7f05273a..76c0fe0749 100644
--- a/api/include/opentelemetry/trace/noop.h
+++ b/api/include/opentelemetry/trace/noop.h
@@ -29,7 +29,12 @@ class NoopSpan final : public Span
{
public:
explicit NoopSpan(const std::shared_ptr &tracer) noexcept
- : tracer_{tracer}, span_context_{SpanContext::GetInvalid()}
+ : tracer_{tracer}, span_context_{new SpanContext(false, false)}
+ {}
+
+ explicit NoopSpan(const std::shared_ptr &tracer,
+ nostd::unique_ptr span_context) noexcept
+ : tracer_{tracer}, span_context_{std::move(span_context)}
{}
void SetAttribute(nostd::string_view /*key*/,
@@ -55,11 +60,11 @@ class NoopSpan final : public Span
bool IsRecording() const noexcept override { return false; }
- SpanContext GetContext() const noexcept override { return span_context_; }
+ SpanContext GetContext() const noexcept override { return *span_context_.get(); }
private:
std::shared_ptr tracer_;
- SpanContext span_context_;
+ nostd::unique_ptr span_context_;
};
/**
diff --git a/api/test/trace/noop_test.cc b/api/test/trace/noop_test.cc
index 5414a5c726..b17faf64d4 100644
--- a/api/test/trace/noop_test.cc
+++ b/api/test/trace/noop_test.cc
@@ -10,14 +10,13 @@
#include
-using opentelemetry::common::SystemTimestamp;
-using opentelemetry::trace::NoopTracer;
-using opentelemetry::trace::SpanContext;
-using opentelemetry::trace::Tracer;
+namespace trace_api = opentelemetry::trace;
+namespace nonstd = opentelemetry::nostd;
+namespace common = opentelemetry::common;
TEST(NoopTest, UseNoopTracers)
{
- std::shared_ptr tracer{new NoopTracer{}};
+ std::shared_ptr tracer{new trace_api::NoopTracer{}};
auto s1 = tracer->StartSpan("abc");
std::map attributes1;
@@ -41,7 +40,7 @@ TEST(NoopTest, UseNoopTracers)
s1->UpdateName("test_name");
- SystemTimestamp t1;
+ common::SystemTimestamp t1;
s1->AddEvent("test_time_stamp", t1);
s1->GetContext();
@@ -49,12 +48,34 @@ TEST(NoopTest, UseNoopTracers)
TEST(NoopTest, StartSpan)
{
- std::shared_ptr tracer{new NoopTracer{}};
+ std::shared_ptr tracer{new trace_api::NoopTracer{}};
- std::map attrs = {{"a", "3"}};
- std::vector>> links = {
- {SpanContext(false, false), attrs}};
+ std::map attrs = {{"a", "3"}};
+ std::vector>> links = {
+ {trace_api::SpanContext(false, false), attrs}};
auto s1 = tracer->StartSpan("abc", attrs, links);
- auto s2 = tracer->StartSpan("efg", {{"a", 3}}, {{SpanContext(false, false), {{"b", 4}}}});
+ auto s2 =
+ tracer->StartSpan("efg", {{"a", 3}}, {{trace_api::SpanContext(false, false), {{"b", 4}}}});
+}
+
+TEST(NoopTest, CreateSpanValidSpanContext)
+{
+ // Create valid spancontext for NoopSpan
+
+ constexpr uint8_t buf_span[] = {1, 2, 3, 4, 5, 6, 7, 8};
+ constexpr uint8_t buf_trace[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
+ auto trace_id = trace_api::TraceId{buf_trace};
+ auto span_id = trace_api::SpanId{buf_span};
+ auto span_context = nonstd::unique_ptr(
+ new trace_api::SpanContext{trace_id, span_id, trace_api::TraceFlags{true}, false});
+ std::shared_ptr tracer{new trace_api::NoopTracer{}};
+ auto s1 =
+ nonstd::shared_ptr(new trace_api::NoopSpan(tracer, std::move(span_context)));
+ auto stored_span_context = s1->GetContext();
+ EXPECT_EQ(stored_span_context.span_id(), span_id);
+ EXPECT_EQ(stored_span_context.trace_id(), trace_id);
+
+ s1->AddEvent("even1"); // noop
+ s1->End(); // noop
}
diff --git a/sdk/src/trace/tracer.cc b/sdk/src/trace/tracer.cc
index 149684bc8e..c84d847bd9 100644
--- a/sdk/src/trace/tracer.cc
+++ b/sdk/src/trace/tracer.cc
@@ -46,25 +46,27 @@ nostd::shared_ptr Tracer::StartSpan(
auto sampling_result = context_->GetSampler().ShouldSample(parent_context, trace_id, name,
options.kind, attributes, links);
+ auto trace_flags = sampling_result.decision == Decision::DROP
+ ? trace_api::TraceFlags{}
+ : trace_api::TraceFlags{trace_api::TraceFlags::kIsSampled};
+
+ auto span_context = std::unique_ptr(new trace_api::SpanContext(
+ trace_id, span_id, trace_flags, false,
+ sampling_result.trace_state ? sampling_result.trace_state
+ : is_parent_span_valid ? parent_context.trace_state()
+ : trace_api::TraceState::GetDefault()));
if (sampling_result.decision == Decision::DROP)
{
- // Don't allocate a no-op span for every DROP decision, but use a static
- // singleton for this case.
- static nostd::shared_ptr noop_span(
- new trace_api::NoopSpan{this->shared_from_this()});
+ // create no-op span with valid span-context.
+ auto noop_span = nostd::shared_ptr{
+ new (std::nothrow) trace_api::NoopSpan(this->shared_from_this(), std::move(span_context))};
return noop_span;
}
else
{
- auto span_context = std::unique_ptr(new trace_api::SpanContext(
- trace_id, span_id, trace_api::TraceFlags{trace_api::TraceFlags::kIsSampled}, false,
- sampling_result.trace_state ? sampling_result.trace_state
- : is_parent_span_valid ? parent_context.trace_state()
- : trace_api::TraceState::GetDefault()));
-
auto span = nostd::shared_ptr{
new (std::nothrow) Span{this->shared_from_this(), name, attributes, links, options,
parent_context, std::move(span_context)}};
diff --git a/sdk/test/trace/tracer_test.cc b/sdk/test/trace/tracer_test.cc
index 0c5cc397d8..2e9dd73413 100644
--- a/sdk/test/trace/tracer_test.cc
+++ b/sdk/test/trace/tracer_test.cc
@@ -165,8 +165,14 @@ TEST(Tracer, StartSpanSampleOff)
auto tracer_off = initTracer(std::move(exporter), new AlwaysOffSampler());
// This span will not be recorded.
- tracer_off->StartSpan("span 2")->End();
+ auto span = tracer_off->StartSpan("span 2");
+ // Always generate a valid span-context (span-id)
+ auto context = span->GetContext();
+ EXPECT_TRUE(context.IsValid());
+ EXPECT_FALSE(context.IsSampled());
+
+ span->End();
// The span doesn't write any span data because the sampling decision is alway
// DROP.
ASSERT_EQ(0, span_data->GetSpans().size());
From 6add2e09b65d4f06ffa75856ae55c1f5620cdbab Mon Sep 17 00:00:00 2001
From: Lalit Kumar Bhasin
Date: Fri, 2 Jul 2021 02:03:34 +0530
Subject: [PATCH 06/11] update zoom link (#887)
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 890021c589..743032d17d 100644
--- a/README.md
+++ b/README.md
@@ -63,7 +63,7 @@ contributors' availability. Check the [OpenTelemetry community
calendar](https://calendar.google.com/calendar/embed?src=google.com_b79e3e90j7bbsa2n2p5an5lf60%40group.calendar.google.com)
for specific dates.
-Meetings take place via [Zoom video conference](https://zoom.us/j/8203130519).
+Meetings take place via [Zoom video conference](https://zoom.us/j/6729396170).
The passcode is _77777_.
Meeting notes are available as a public [Google
From fdade9a4b43ba880d22065a09a3ef1e37986b60a Mon Sep 17 00:00:00 2001
From: Lalit Kumar Bhasin
Date: Fri, 2 Jul 2021 10:09:53 +0530
Subject: [PATCH 07/11] Otlp Exporter : Handling InstrumentationLibrary, and
Link's trace state (#823)
---
exporters/jaeger/test/jaeger_recordable_test.cc | 2 +-
.../exporters/otlp/otlp_recordable.h | 4 ++++
exporters/otlp/src/otlp_grpc_exporter.cc | 3 ++-
exporters/otlp/src/otlp_recordable.cc | 17 ++++++++++++++---
exporters/otlp/test/otlp_recordable_test.cc | 17 ++++++++++++++++-
exporters/zipkin/test/zipkin_recordable_test.cc | 2 +-
.../instrumentation_library.h | 2 +-
sdk/include/opentelemetry/sdk/trace/tracer.h | 2 +-
sdk/src/trace/tracer_provider.cc | 2 +-
.../instrumentationlibrary_test.cc | 2 +-
10 files changed, 42 insertions(+), 11 deletions(-)
diff --git a/exporters/jaeger/test/jaeger_recordable_test.cc b/exporters/jaeger/test/jaeger_recordable_test.cc
index 2289a53ab9..73a089556e 100644
--- a/exporters/jaeger/test/jaeger_recordable_test.cc
+++ b/exporters/jaeger/test/jaeger_recordable_test.cc
@@ -129,7 +129,7 @@ TEST(JaegerSpanRecordable, SetInstrumentationLibrary)
std::string library_name = "opentelemetry-cpp";
std::string library_version = "0.1.0";
- auto instrumentation_library = InstrumentationLibrary::create(library_name, library_version);
+ auto instrumentation_library = InstrumentationLibrary::Create(library_name, library_version);
rec.SetInstrumentationLibrary(*instrumentation_library);
diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_recordable.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_recordable.h
index b5b73e36d8..a2e9c83ae3 100644
--- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_recordable.h
+++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_recordable.h
@@ -25,6 +25,8 @@ class OtlpRecordable final : public sdk::trace::Recordable
/** Dynamically converts the resource of this span into a proto. */
proto::resource::v1::Resource ProtoResource() const noexcept;
+ proto::common::v1::InstrumentationLibrary GetProtoInstrumentationLibrary() const noexcept;
+
void SetIdentity(const opentelemetry::trace::SpanContext &span_context,
opentelemetry::trace::SpanId parent_span_id) noexcept override;
@@ -57,6 +59,8 @@ class OtlpRecordable final : public sdk::trace::Recordable
private:
proto::trace::v1::Span span_;
const opentelemetry::sdk::resource::Resource *resource_ = nullptr;
+ const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary
+ *instrumentation_library_ = nullptr;
};
} // namespace otlp
} // namespace exporter
diff --git a/exporters/otlp/src/otlp_grpc_exporter.cc b/exporters/otlp/src/otlp_grpc_exporter.cc
index e0aaa0a0ab..42c0b5d300 100644
--- a/exporters/otlp/src/otlp_grpc_exporter.cc
+++ b/exporters/otlp/src/otlp_grpc_exporter.cc
@@ -31,7 +31,8 @@ void PopulateRequest(const nostd::span>
for (auto &recordable : spans)
{
auto rec = std::unique_ptr(static_cast(recordable.release()));
- *instrumentation_lib->add_spans() = std::move(rec->span());
+ *instrumentation_lib->add_spans() = std::move(rec->span());
+ *instrumentation_lib->mutable_instrumentation_library() = rec->GetProtoInstrumentationLibrary();
if (!has_resource)
{
diff --git a/exporters/otlp/src/otlp_recordable.cc b/exporters/otlp/src/otlp_recordable.cc
index 53e92d8d76..1227850858 100644
--- a/exporters/otlp/src/otlp_recordable.cc
+++ b/exporters/otlp/src/otlp_recordable.cc
@@ -237,6 +237,18 @@ proto::resource::v1::Resource OtlpRecordable::ProtoResource() const noexcept
return proto;
}
+proto::common::v1::InstrumentationLibrary OtlpRecordable::GetProtoInstrumentationLibrary()
+ const noexcept
+{
+ proto::common::v1::InstrumentationLibrary instrumentation_library;
+ if (instrumentation_library_)
+ {
+ instrumentation_library.set_name(instrumentation_library_->GetName());
+ instrumentation_library.set_version(instrumentation_library_->GetVersion());
+ }
+ return instrumentation_library;
+}
+
void OtlpRecordable::SetResource(const opentelemetry::sdk::resource::Resource &resource) noexcept
{
resource_ = &resource;
@@ -271,12 +283,11 @@ void OtlpRecordable::AddLink(const opentelemetry::trace::SpanContext &span_conte
trace::TraceId::kSize);
link->set_span_id(reinterpret_cast(span_context.span_id().Id().data()),
trace::SpanId::kSize);
+ link->set_trace_state(span_context.trace_state()->ToHeader());
attributes.ForEachKeyValue([&](nostd::string_view key, common::AttributeValue value) noexcept {
PopulateAttribute(link->add_attributes(), key, value);
return true;
});
-
- // TODO: Populate trace_state when it is supported by SpanContext
}
void OtlpRecordable::SetStatus(trace::StatusCode code, nostd::string_view description) noexcept
@@ -347,7 +358,7 @@ void OtlpRecordable::SetInstrumentationLibrary(
const opentelemetry::sdk::instrumentationlibrary::InstrumentationLibrary
&instrumentation_library) noexcept
{
- // TODO: add instrumentation library to OTLP exporter.
+ instrumentation_library_ = &instrumentation_library;
}
} // namespace otlp
diff --git a/exporters/otlp/test/otlp_recordable_test.cc b/exporters/otlp/test/otlp_recordable_test.cc
index f6e0858a8a..9d34cd26a4 100644
--- a/exporters/otlp/test/otlp_recordable_test.cc
+++ b/exporters/otlp/test/otlp_recordable_test.cc
@@ -53,6 +53,16 @@ TEST(OtlpRecordable, SetSpanKind)
opentelemetry::proto::trace::v1::Span_SpanKind::Span_SpanKind_SPAN_KIND_SERVER);
}
+TEST(OtlpRecordable, SetInstrumentationLibrary)
+{
+ OtlpRecordable rec;
+ auto inst_lib = opentelemetry::sdk::trace::InstrumentationLibrary::Create("test", "v1");
+ rec.SetInstrumentationLibrary(*inst_lib);
+ auto proto_instr_libr = rec.GetProtoInstrumentationLibrary();
+ EXPECT_EQ(proto_instr_libr.name(), inst_lib->GetName());
+ EXPECT_EQ(proto_instr_libr.version(), inst_lib->GetVersion());
+}
+
TEST(OtlpRecordable, SetStartTime)
{
OtlpRecordable rec;
@@ -141,11 +151,16 @@ TEST(OtlpRecordable, AddLink)
auto trace_id = rec.span().trace_id();
auto span_id = rec.span().span_id();
- rec.AddLink(trace::SpanContext(false, false),
+ trace::TraceFlags flags;
+ std::string trace_state_header = "k1=v1,k2=v2";
+ auto ts = trace::TraceState::FromHeader(trace_state_header);
+
+ rec.AddLink(trace::SpanContext(trace::TraceId(), trace::SpanId(), flags, false, ts),
common::KeyValueIterableView>(attributes));
EXPECT_EQ(rec.span().trace_id(), trace_id);
EXPECT_EQ(rec.span().span_id(), span_id);
+ EXPECT_EQ(rec.span().links(0).trace_state(), trace_state_header);
for (int i = 0; i < kNumAttributes; i++)
{
EXPECT_EQ(rec.span().links(0).attributes(i).key(), keys[i]);
diff --git a/exporters/zipkin/test/zipkin_recordable_test.cc b/exporters/zipkin/test/zipkin_recordable_test.cc
index 7a5feb8bdb..9b51c46c29 100644
--- a/exporters/zipkin/test/zipkin_recordable_test.cc
+++ b/exporters/zipkin/test/zipkin_recordable_test.cc
@@ -90,7 +90,7 @@ TEST(ZipkinSpanRecordable, SetInstrumentationLibrary)
{"tags", {{"otel.library.name", library_name}, {"otel.library.version", library_version}}}};
opentelemetry::exporter::zipkin::Recordable rec;
- rec.SetInstrumentationLibrary(*InstrumentationLibrary::create(library_name, library_version));
+ rec.SetInstrumentationLibrary(*InstrumentationLibrary::Create(library_name, library_version));
EXPECT_EQ(rec.span(), j_span);
}
diff --git a/sdk/include/opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h b/sdk/include/opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h
index 20d62eba16..e4f7f78ef1 100644
--- a/sdk/include/opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h
+++ b/sdk/include/opentelemetry/sdk/instrumentationlibrary/instrumentation_library.h
@@ -25,7 +25,7 @@ class InstrumentationLibrary
* @param version version of the instrumentation library.
* @returns the newly created InstrumentationLibrary.
*/
- static nostd::unique_ptr create(nostd::string_view name,
+ static nostd::unique_ptr Create(nostd::string_view name,
nostd::string_view version = "")
{
return nostd::unique_ptr(
diff --git a/sdk/include/opentelemetry/sdk/trace/tracer.h b/sdk/include/opentelemetry/sdk/trace/tracer.h
index 4b6c1de796..6aeb19fa57 100644
--- a/sdk/include/opentelemetry/sdk/trace/tracer.h
+++ b/sdk/include/opentelemetry/sdk/trace/tracer.h
@@ -29,7 +29,7 @@ class Tracer final : public trace_api::Tracer, public std::enable_shared_from_th
/** Construct a new Tracer with the given context pipeline. */
explicit Tracer(std::shared_ptr context,
std::unique_ptr instrumentation_library =
- InstrumentationLibrary::create("")) noexcept;
+ InstrumentationLibrary::Create("")) noexcept;
nostd::shared_ptr StartSpan(
nostd::string_view name,
diff --git a/sdk/src/trace/tracer_provider.cc b/sdk/src/trace/tracer_provider.cc
index 13b41d73b6..ed6853be67 100644
--- a/sdk/src/trace/tracer_provider.cc
+++ b/sdk/src/trace/tracer_provider.cc
@@ -55,7 +55,7 @@ nostd::shared_ptr TracerProvider::GetTracer(
}
}
- auto lib = InstrumentationLibrary::create(library_name, library_version);
+ auto lib = InstrumentationLibrary::Create(library_name, library_version);
tracers_.push_back(std::shared_ptr(
new sdk::trace::Tracer(context_, std::move(lib))));
return nostd::shared_ptr{tracers_.back()};
diff --git a/sdk/test/instrumentationlibrary/instrumentationlibrary_test.cc b/sdk/test/instrumentationlibrary/instrumentationlibrary_test.cc
index d21f113580..b6ac69df1f 100644
--- a/sdk/test/instrumentationlibrary/instrumentationlibrary_test.cc
+++ b/sdk/test/instrumentationlibrary/instrumentationlibrary_test.cc
@@ -16,7 +16,7 @@ TEST(InstrumentationLibrary, CreateInstrumentationLibrary)
std::string library_name = "opentelemetry-cpp";
std::string library_version = "0.1.0";
- auto instrumentation_library = InstrumentationLibrary::create(library_name, library_version);
+ auto instrumentation_library = InstrumentationLibrary::Create(library_name, library_version);
EXPECT_EQ(instrumentation_library->GetName(), library_name);
EXPECT_EQ(instrumentation_library->GetVersion(), library_version);
From 98013c2563c4dbd2fa25a00ad3bc63d1db176e0f Mon Sep 17 00:00:00 2001
From: Lalit Kumar Bhasin
Date: Fri, 2 Jul 2021 10:47:22 +0530
Subject: [PATCH 08/11] Support for TextMapPropagator::Fields method (#799)
---
.../baggage/propagation/baggage_propagator.h | 5 +++++
.../context/propagation/composite_propagator.h | 15 +++++++++++++++
.../context/propagation/noop_propagator.h | 5 +++++
.../context/propagation/text_map_propagator.h | 17 +++++++++++++++--
.../trace/propagation/b3_propagator.h | 10 ++++++++++
.../trace/propagation/http_trace_context.h | 5 +++++
.../opentelemetry/trace/propagation/jaeger.h | 11 ++++++++---
.../propagation/baggage_propagator_test.cc | 8 ++++++++
.../propagation/composite_propagator_test.cc | 10 ++++++++++
.../trace/propagation/http_text_format_test.cc | 9 +++++++++
.../propagation/jaeger_propagation_test.cc | 8 ++++++++
11 files changed, 98 insertions(+), 5 deletions(-)
diff --git a/api/include/opentelemetry/baggage/propagation/baggage_propagator.h b/api/include/opentelemetry/baggage/propagation/baggage_propagator.h
index 74db10ea59..aa669dd1d9 100644
--- a/api/include/opentelemetry/baggage/propagation/baggage_propagator.h
+++ b/api/include/opentelemetry/baggage/propagation/baggage_propagator.h
@@ -46,6 +46,11 @@ class BaggagePropagator : public context::propagation::TextMapPropagator
auto baggage = Baggage::FromHeader(baggage_str);
return SetBaggage(context, baggage);
}
+
+ bool Fields(nostd::function_ref callback) const noexcept override
+ {
+ return callback(kBaggageHeader);
+ }
};
} // namespace propagation
} // namespace baggage
diff --git a/api/include/opentelemetry/context/propagation/composite_propagator.h b/api/include/opentelemetry/context/propagation/composite_propagator.h
index 52c05ae56f..85ad97b0fc 100644
--- a/api/include/opentelemetry/context/propagation/composite_propagator.h
+++ b/api/include/opentelemetry/context/propagation/composite_propagator.h
@@ -67,6 +67,21 @@ class CompositePropagator : public TextMapPropagator
return propagators_.size() ? tmp_context : context;
}
+ /**
+ * Invoke callback with fields set to carrier by `inject` method for all the
+ * configured propagators
+ * Returns true if all invocation return true
+ */
+ bool Fields(nostd::function_ref callback) const noexcept override
+ {
+ bool status = true;
+ for (auto &p : propagators_)
+ {
+ status = status && p->Fields(callback);
+ }
+ return status;
+ }
+
private:
std::vector> propagators_;
};
diff --git a/api/include/opentelemetry/context/propagation/noop_propagator.h b/api/include/opentelemetry/context/propagation/noop_propagator.h
index ece0229ae8..7c5edc5f8a 100644
--- a/api/include/opentelemetry/context/propagation/noop_propagator.h
+++ b/api/include/opentelemetry/context/propagation/noop_propagator.h
@@ -27,6 +27,11 @@ class NoOpPropagator : public TextMapPropagator
/** Noop inject function does nothing */
void Inject(TextMapCarrier & /*carrier*/, const context::Context &context) noexcept override {}
+
+ bool Fields(nostd::function_ref callback) const noexcept override
+ {
+ return true;
+ }
};
} // namespace propagation
} // namespace context
diff --git a/api/include/opentelemetry/context/propagation/text_map_propagator.h b/api/include/opentelemetry/context/propagation/text_map_propagator.h
index efa2686441..7efdc4919d 100644
--- a/api/include/opentelemetry/context/propagation/text_map_propagator.h
+++ b/api/include/opentelemetry/context/propagation/text_map_propagator.h
@@ -18,11 +18,19 @@ namespace propagation
class TextMapCarrier
{
public:
- /*returns the value associated with the passed key.*/
+ // returns the value associated with the passed key.
virtual nostd::string_view Get(nostd::string_view key) const noexcept = 0;
- /*stores the key-value pair.*/
+ // stores the key-value pair.
virtual void Set(nostd::string_view key, nostd::string_view value) noexcept = 0;
+
+ /* list of all the keys in the carrier.
+ By default, it returns true without invoking callback */
+ virtual bool Keys(nostd::function_ref callback) const noexcept
+ {
+ return true;
+ }
+ virtual ~TextMapCarrier() = default;
};
// The TextMapPropagator class provides an interface that enables extracting and injecting
@@ -40,6 +48,11 @@ class TextMapPropagator
// Sets the context for carrier with self defined rules.
virtual void Inject(TextMapCarrier &carrier, const context::Context &context) noexcept = 0;
+
+ // Gets the fields set in the carrier by the `inject` method
+ virtual bool Fields(nostd::function_ref callback) const noexcept = 0;
+
+ virtual ~TextMapPropagator() = default;
};
} // namespace propagation
} // namespace context
diff --git a/api/include/opentelemetry/trace/propagation/b3_propagator.h b/api/include/opentelemetry/trace/propagation/b3_propagator.h
index 9aac90f03e..f9485bd619 100644
--- a/api/include/opentelemetry/trace/propagation/b3_propagator.h
+++ b/api/include/opentelemetry/trace/propagation/b3_propagator.h
@@ -150,6 +150,11 @@ class B3Propagator : public B3PropagatorExtractor
carrier.Set(kB3CombinedHeader, nostd::string_view(trace_identity, sizeof(trace_identity)));
}
+
+ bool Fields(nostd::function_ref callback) const noexcept override
+ {
+ return callback(kB3CombinedHeader);
+ }
};
class B3PropagatorMultiHeader : public B3PropagatorExtractor
@@ -173,6 +178,11 @@ class B3PropagatorMultiHeader : public B3PropagatorExtractor
carrier.Set(kB3SpanIdHeader, nostd::string_view(span_id, sizeof(span_id)));
carrier.Set(kB3SampledHeader, nostd::string_view(trace_flags + 1, 1));
}
+
+ bool Fields(nostd::function_ref callback) const noexcept override
+ {
+ return callback(kB3TraceIdHeader) && callback(kB3SpanIdHeader) && callback(kB3SampledHeader);
+ }
};
} // namespace propagation
diff --git a/api/include/opentelemetry/trace/propagation/http_trace_context.h b/api/include/opentelemetry/trace/propagation/http_trace_context.h
index 5bee19c9b7..41c6b1e61d 100644
--- a/api/include/opentelemetry/trace/propagation/http_trace_context.h
+++ b/api/include/opentelemetry/trace/propagation/http_trace_context.h
@@ -160,6 +160,11 @@ class HttpTraceContext : public opentelemetry::context::propagation::TextMapProp
return ExtractContextFromTraceHeaders(trace_parent, trace_state);
}
+
+ bool Fields(nostd::function_ref callback) const noexcept override
+ {
+ return (callback(kTraceParent) && callback(kTraceState));
+ }
};
} // namespace propagation
} // namespace trace
diff --git a/api/include/opentelemetry/trace/propagation/jaeger.h b/api/include/opentelemetry/trace/propagation/jaeger.h
index f1a842bdeb..6203752b91 100644
--- a/api/include/opentelemetry/trace/propagation/jaeger.h
+++ b/api/include/opentelemetry/trace/propagation/jaeger.h
@@ -15,7 +15,7 @@ namespace trace
namespace propagation
{
-static const nostd::string_view kTraceHeader = "uber-trace-id";
+static const nostd::string_view kJaegerTraceHeader = "uber-trace-id";
class JaegerPropagator : public context::propagation::TextMapPropagator
{
@@ -45,7 +45,7 @@ class JaegerPropagator : public context::propagation::TextMapPropagator
trace_identity[trace_id_length + span_id_length + 4] = '0';
trace_identity[trace_id_length + span_id_length + 5] = span_context.IsSampled() ? '1' : '0';
- carrier.Set(kTraceHeader, nostd::string_view(trace_identity, sizeof(trace_identity)));
+ carrier.Set(kJaegerTraceHeader, nostd::string_view(trace_identity, sizeof(trace_identity)));
}
context::Context Extract(const context::propagation::TextMapCarrier &carrier,
@@ -56,6 +56,11 @@ class JaegerPropagator : public context::propagation::TextMapPropagator
return SetSpan(context, sp);
}
+ bool Fields(nostd::function_ref callback) const noexcept override
+ {
+ return callback(kJaegerTraceHeader);
+ }
+
private:
static constexpr uint8_t kIsSampled = 0x01;
@@ -67,7 +72,7 @@ class JaegerPropagator : public context::propagation::TextMapPropagator
static SpanContext ExtractImpl(const context::propagation::TextMapCarrier &carrier)
{
- nostd::string_view trace_identity = carrier.Get(kTraceHeader);
+ nostd::string_view trace_identity = carrier.Get(kJaegerTraceHeader);
const size_t trace_field_count = 4;
nostd::string_view trace_fields[trace_field_count];
diff --git a/api/test/baggage/propagation/baggage_propagator_test.cc b/api/test/baggage/propagation/baggage_propagator_test.cc
index 25f340bd3a..ad54c841ae 100644
--- a/api/test/baggage/propagation/baggage_propagator_test.cc
+++ b/api/test/baggage/propagation/baggage_propagator_test.cc
@@ -67,5 +67,13 @@ TEST(BaggagePropagatorTest, ExtractAndInjectBaggage)
BaggageCarrierTest carrier2;
format.Inject(carrier2, ctx2);
EXPECT_EQ(carrier2.headers_[kBaggageHeader.data()], baggage.second);
+
+ std::vector fields;
+ format.Fields([&fields](nostd::string_view field) {
+ fields.push_back(field.data());
+ return true;
+ });
+ EXPECT_EQ(fields.size(), 1);
+ EXPECT_EQ(fields[0], kBaggageHeader.data());
}
}
diff --git a/api/test/context/propagation/composite_propagator_test.cc b/api/test/context/propagation/composite_propagator_test.cc
index 5168cec989..d516fe17d2 100644
--- a/api/test/context/propagation/composite_propagator_test.cc
+++ b/api/test/context/propagation/composite_propagator_test.cc
@@ -111,4 +111,14 @@ TEST_F(CompositePropagatorTest, Inject)
EXPECT_EQ(carrier.headers_["traceparent"],
"00-0102030405060708090a0b0c0d0e0f10-0102030405060708-01");
EXPECT_EQ(carrier.headers_["b3"], "0102030405060708090a0b0c0d0e0f10-0102030405060708-1");
+
+ std::vector fields;
+ composite_propagator_->Fields([&fields](nostd::string_view field) {
+ fields.push_back(field.data());
+ return true;
+ });
+ EXPECT_EQ(fields.size(), 3);
+ EXPECT_EQ(fields[0], opentelemetry::trace::propagation::kTraceParent);
+ EXPECT_EQ(fields[1], opentelemetry::trace::propagation::kTraceState);
+ EXPECT_EQ(fields[2], opentelemetry::trace::propagation::kB3CombinedHeader);
}
diff --git a/api/test/trace/propagation/http_text_format_test.cc b/api/test/trace/propagation/http_text_format_test.cc
index a775c3a9ac..497d716bb9 100644
--- a/api/test/trace/propagation/http_text_format_test.cc
+++ b/api/test/trace/propagation/http_text_format_test.cc
@@ -198,4 +198,13 @@ TEST(GlobalPropagator, SetAndGet)
EXPECT_TRUE(carrier.headers_.count("traceparent") > 0);
EXPECT_TRUE(carrier.headers_.count("tracestate") > 0);
EXPECT_EQ(carrier.headers_["tracestate"], trace_state_value);
+
+ std::vector fields;
+ propagator->Fields([&fields](nostd::string_view field) {
+ fields.push_back(field.data());
+ return true;
+ });
+ EXPECT_EQ(fields.size(), 2);
+ EXPECT_EQ(fields[0], opentelemetry::trace::propagation::kTraceParent);
+ EXPECT_EQ(fields[1], opentelemetry::trace::propagation::kTraceState);
}
diff --git a/api/test/trace/propagation/jaeger_propagation_test.cc b/api/test/trace/propagation/jaeger_propagation_test.cc
index 85a126e663..a0e0ade270 100644
--- a/api/test/trace/propagation/jaeger_propagation_test.cc
+++ b/api/test/trace/propagation/jaeger_propagation_test.cc
@@ -147,6 +147,14 @@ TEST(JaegerPropagatorTest, InjectsContext)
format.Inject(carrier, context::RuntimeContext::GetCurrent());
EXPECT_EQ(carrier.headers_["uber-trace-id"],
"0102030405060708090a0b0c0d0e0f10:0102030405060708:0:01");
+
+ std::vector fields;
+ format.Fields([&fields](nostd::string_view field) {
+ fields.push_back(field.data());
+ return true;
+ });
+ EXPECT_EQ(fields.size(), 1);
+ EXPECT_EQ(fields[0], opentelemetry::trace::propagation::kJaegerTraceHeader);
}
TEST(JaegerPropagatorTest, DoNotInjectInvalidContext)
From 8695e8a1f3e64e69aa5d1aa70ea1b131322b6447 Mon Sep 17 00:00:00 2001
From: iocumine
Date: Fri, 2 Jul 2021 20:34:35 +0200
Subject: [PATCH 09/11] nlohmann_json::nlohmann_json added (#888)
---
exporters/otlp/CMakeLists.txt | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/exporters/otlp/CMakeLists.txt b/exporters/otlp/CMakeLists.txt
index 3af587b4a8..1ca788af58 100644
--- a/exporters/otlp/CMakeLists.txt
+++ b/exporters/otlp/CMakeLists.txt
@@ -33,8 +33,10 @@ if(WITH_OTLP_HTTP)
set_target_properties(opentelemetry_exporter_otlp_http
PROPERTIES EXPORT_NAME otlp_http_exporter)
- target_link_libraries(opentelemetry_exporter_otlp_http
- PUBLIC opentelemetry_otlp_recordable http_client_curl)
+ target_link_libraries(
+ opentelemetry_exporter_otlp_http
+ PUBLIC opentelemetry_otlp_recordable http_client_curl
+ nlohmann_json::nlohmann_json)
list(APPEND OPENTELEMETRY_OTLP_TARGETS opentelemetry_exporter_otlp_http)
endif()
From 016bb8553b2918eb0058a7e87f70717b38846d2b Mon Sep 17 00:00:00 2001
From: Tom Tan
Date: Fri, 2 Jul 2021 21:43:09 -0700
Subject: [PATCH 10/11] Remove meeting link in contributing doc (#891)
---
CONTRIBUTING.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 9f0aea79af..ee3cca52f2 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -141,8 +141,8 @@ on each other), the owner should try to get people aligned by:
split it up.
If none of the above worked and the PR has been stuck for more than 2 weeks, the
-owner should bring it to the [OpenTelemetry C++ SIG
-meeting](https://zoom.us/j/8203130519). The meeting passcode is _77777_.
+owner should bring it to the OpenTelemetry C++ SIG meeting. See
+[README.md](README.md#contributing) for the meeting link.
## Useful Resources
From 4292a57fb438283a222d2a4b19d84e7fd6ea15ee Mon Sep 17 00:00:00 2001
From: Tom Tan
Date: Sat, 3 Jul 2021 00:12:50 -0700
Subject: [PATCH 11/11] Fix assertion to check the correct attribute value type
(#890)
---
exporters/otlp/src/otlp_recordable.cc | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/exporters/otlp/src/otlp_recordable.cc b/exporters/otlp/src/otlp_recordable.cc
index 1227850858..a17419df7e 100644
--- a/exporters/otlp/src/otlp_recordable.cc
+++ b/exporters/otlp/src/otlp_recordable.cc
@@ -138,9 +138,9 @@ void PopulateAttribute(opentelemetry::proto::common::v1::KeyValue *attribute,
{
// Assert size of variant to ensure that this method gets updated if the variant
// definition changes
- static_assert(nostd::variant_size::value ==
- kOwnedAttributeValueSize + 1,
- "AttributeValue contains unknown type");
+ static_assert(
+ nostd::variant_size::value == kOwnedAttributeValueSize,
+ "OwnedAttributeValue contains unknown type");
attribute->set_key(key.data(), key.size());