Skip to content

Commit

Permalink
Support for multiple processors (#692)
Browse files Browse the repository at this point in the history
  • Loading branch information
lalitb authored Apr 29, 2021
1 parent a3755f4 commit a987f0a
Show file tree
Hide file tree
Showing 22 changed files with 623 additions and 59 deletions.
1 change: 1 addition & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ add_subdirectory(simple)
add_subdirectory(batch)
add_subdirectory(metrics_simple)
add_subdirectory(multithreaded)
add_subdirectory(multi_processor)
add_subdirectory(http)
8 changes: 5 additions & 3 deletions examples/http/tracer_common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include "opentelemetry/sdk/trace/tracer_provider.h"
#include "opentelemetry/trace/provider.h"

#include <iostream>
#include <vector>

namespace {

Expand All @@ -13,8 +13,10 @@ void initTracer() {
new opentelemetry::exporter::trace::OStreamSpanExporter);
auto processor = std::unique_ptr<sdktrace::SpanProcessor>(
new sdktrace::SimpleSpanProcessor(std::move(exporter)));
std::vector<std::unique_ptr<sdktrace::SpanProcessor>> processors;
processors.push_back(std::move(processor));
// Default is an always-on sampler.
auto context = std::make_shared<sdktrace::TracerContext>(std::move(processor));
auto context = std::make_shared<sdktrace::TracerContext>(std::move(processors));
auto provider = nostd::shared_ptr<opentelemetry::trace::TracerProvider>(
new sdktrace::TracerProvider(context));
// Set the global trace provider
Expand All @@ -27,4 +29,4 @@ nostd::shared_ptr<opentelemetry::trace::Tracer> get_tracer(std::string tracer_na
return provider->GetTracer(tracer_name);
}

}
}
26 changes: 26 additions & 0 deletions examples/multi_processor/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
cc_library(
name = "foo_multi_library",
srcs = [
"foo_library/foo_library.cc",
],
hdrs = [
"foo_library/foo_library.h",
],
deps = [
"//api",
],
)

cc_binary(
name = "example_multi_processor",
srcs = [
"main.cc",
],
deps = [
":foo_multi_library",
"//api",
"//exporters/memory:in_memory_span_exporter",
"//exporters/ostream:ostream_span_exporter",
"//sdk/src/trace",
],
)
10 changes: 10 additions & 0 deletions examples/multi_processor/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
include_directories(${CMAKE_SOURCE_DIR}/exporters/ostream/include
${CMAKE_SOURCE_DIR}/exporters/memory/include)

add_library(foo_multi_library foo_library/foo_library.cc)
target_link_libraries(foo_multi_library opentelemetry_exporter_ostream_span
${CMAKE_THREAD_LIBS_INIT} opentelemetry_api)

add_executable(example_multi_processor main.cc)
target_link_libraries(example_multi_processor ${CMAKE_THREAD_LIBS_INIT}
foo_multi_library opentelemetry_trace)
14 changes: 14 additions & 0 deletions examples/multi_processor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Multi Processor Trace Example

In this example, the application in `main.cc` initializes and registers a tracer
provider from the [OpenTelemetry
SDK](https://github.com/open-telemetry/opentelemetry-cpp). The `TracerProvider` is connected
to two `processor-exporter` pipelines - for exporting simultaneously to `StdoutSpanExporter`
and `InMemorySpanExporter`. The application then
calls a `foo_library` which has been instrumented using the [OpenTelemetry
API](https://github.com/open-telemetry/opentelemetry-cpp/tree/main/api).
Resulting telemetry is directed to stdout through the StdoutSpanExporter, and saved as a
variable (vector of spans) through `InMemorySpanExporter`.

See [CONTRIBUTING.md](../../CONTRIBUTING.md) for instructions on building and
running the example.
42 changes: 42 additions & 0 deletions examples/multi_processor/foo_library/foo_library.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include "opentelemetry/trace/provider.h"

namespace trace = opentelemetry::trace;
namespace nostd = opentelemetry::nostd;

namespace
{
nostd::shared_ptr<trace::Tracer> get_tracer()
{
auto provider = trace::Provider::GetTracerProvider();
return provider->GetTracer("foo_library");
}

void f1()
{
auto span = get_tracer()->StartSpan("f1");
auto scope = get_tracer()->WithActiveSpan(span);

span->End();
}

void f2()
{
auto span = get_tracer()->StartSpan("f2");
auto scope = get_tracer()->WithActiveSpan(span);

f1();
f1();

span->End();
}
} // namespace

void foo_library()
{
auto span = get_tracer()->StartSpan("library");
auto scope = get_tracer()->WithActiveSpan(span);

f2();

span->End();
}
3 changes: 3 additions & 0 deletions examples/multi_processor/foo_library/foo_library.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#pragma once

void foo_library();
79 changes: 79 additions & 0 deletions examples/multi_processor/main.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#include "opentelemetry/sdk/trace/simple_processor.h"
#include "opentelemetry/sdk/trace/tracer_context.h"
#include "opentelemetry/sdk/trace/tracer_provider.h"
#include "opentelemetry/trace/provider.h"

// Using an exporter that simply dumps span data to stdout.
#include "foo_library/foo_library.h"
#include "opentelemetry/exporters/memory/in_memory_span_exporter.h"
#include "opentelemetry/exporters/ostream/span_exporter.h"

using opentelemetry::exporter::memory::InMemorySpanExporter;

InMemorySpanExporter *memory_span_exporter;

namespace
{
void initTracer()
{
auto exporter1 = std::unique_ptr<sdktrace::SpanExporter>(
new opentelemetry::exporter::trace::OStreamSpanExporter);
auto processor1 = std::unique_ptr<sdktrace::SpanProcessor>(
new sdktrace::SimpleSpanProcessor(std::move(exporter1)));

auto exporter2 = std::unique_ptr<sdktrace::SpanExporter>(new InMemorySpanExporter());

// fetch the exporter for dumping data later
memory_span_exporter = dynamic_cast<InMemorySpanExporter *>(exporter2.get());

auto processor2 = std::unique_ptr<sdktrace::SpanProcessor>(
new sdktrace::SimpleSpanProcessor(std::move(exporter2)));

auto provider = nostd::shared_ptr<opentelemetry::sdk::trace::TracerProvider>(
new sdktrace::TracerProvider(std::move(processor1)));
provider->AddProcessor(std::move(processor2));
// Set the global trace provider
opentelemetry::trace::Provider::SetTracerProvider(std::move(provider));
}

void dumpSpans(std::vector<std::unique_ptr<opentelemetry::sdk::trace::SpanData>> &spans)
{
char span_buf[opentelemetry::trace::SpanId::kSize * 2];
char trace_buf[opentelemetry::trace::TraceId::kSize * 2];
char parent_span_buf[opentelemetry::trace::SpanId::kSize * 2];
std::cout << "\nSpans from memory :" << std::endl;

for (auto &span : spans)
{
std::cout << "\n\tSpan: " << std::endl;
std::cout << "\t\tName: " << span->GetName() << std::endl;
span->GetSpanId().ToLowerBase16(span_buf);
span->GetTraceId().ToLowerBase16(trace_buf);
span->GetParentSpanId().ToLowerBase16(parent_span_buf);
std::cout << "\t\tTraceId: " << std::string(trace_buf, sizeof(trace_buf)) << std::endl;
std::cout << "\t\tSpanId: " << std::string(span_buf, sizeof(span_buf)) << std::endl;
std::cout << "\t\tParentSpanId: " << std::string(parent_span_buf, sizeof(parent_span_buf))
<< std::endl;

std::cout << "\t\tDescription: " << span->GetDescription() << std::endl;
std::cout << "\t\tSpan kind:"
<< static_cast<typename std::underlying_type<opentelemetry::trace::SpanKind>::type>(
span->GetSpanKind())
<< std::endl;
std::cout << "\t\tSpan Status: "
<< static_cast<typename std::underlying_type<opentelemetry::trace::StatusCode>::type>(
span->GetStatus())
<< std::endl;
}
}
} // namespace

int main()
{
// Removing this line will leave the default noop TracerProvider in place.
initTracer();

foo_library();
auto memory_spans = memory_span_exporter->GetData()->GetSpans();
dumpSpans(memory_spans);
}
4 changes: 3 additions & 1 deletion ext/test/w3c_tracecontext_test/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ void initTracer()
new opentelemetry::exporter::trace::OStreamSpanExporter);
auto processor = std::unique_ptr<sdktrace::SpanProcessor>(
new sdktrace::SimpleSpanProcessor(std::move(exporter)));
auto context = std::make_shared<sdktrace::TracerContext>(std::move(processor));
std::vector<std::unique_ptr<sdktrace::SpanProcessor>> processors;
processors.push_back(std::move(processor));
auto context = std::make_shared<sdktrace::TracerContext>(std::move(processors));
auto provider = nostd::shared_ptr<opentelemetry::trace::TracerProvider>(
new sdktrace::TracerProvider(context));
// Set the global trace provider
Expand Down
7 changes: 5 additions & 2 deletions ext/test/zpages/tracez_data_aggregator_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,11 @@ class TracezDataAggregatorTest : public ::testing::Test
{
std::shared_ptr<TracezSharedData> shared_data(new TracezSharedData());
auto resource = opentelemetry::sdk::resource::Resource::Create({});
auto context = std::make_shared<TracerContext>(
std::unique_ptr<SpanProcessor>(new TracezSpanProcessor(shared_data)), resource);
std::unique_ptr<SpanProcessor> processor(new TracezSpanProcessor(shared_data));
std::vector<std::unique_ptr<SpanProcessor>> processors;
processors.push_back(std::move(processor));

auto context = std::make_shared<TracerContext>(std::move(processors), resource);
tracer = std::shared_ptr<opentelemetry::trace::Tracer>(new Tracer(context));
tracez_data_aggregator = std::unique_ptr<TracezDataAggregator>(
new TracezDataAggregator(shared_data, milliseconds(10)));
Expand Down
11 changes: 7 additions & 4 deletions ext/test/zpages/tracez_processor_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -175,13 +175,16 @@ class TracezProcessor : public ::testing::Test
protected:
void SetUp() override
{
shared_data = std::shared_ptr<TracezSharedData>(new TracezSharedData());
processor = std::shared_ptr<TracezSpanProcessor>(new TracezSpanProcessor(shared_data));
shared_data = std::shared_ptr<TracezSharedData>(new TracezSharedData());
processor = std::shared_ptr<TracezSpanProcessor>(new TracezSpanProcessor(shared_data));
std::unique_ptr<SpanProcessor> processor2(new TracezSpanProcessor(shared_data));
std::vector<std::unique_ptr<SpanProcessor>> processors;
processors.push_back(std::move(processor2));
auto resource = opentelemetry::sdk::resource::Resource::Create({});

// Note: we make a *different* processor for the tracercontext. THis is because
// all the tests use shared data, and we want to make sure this works correctly.
auto context = std::make_shared<TracerContext>(
std::unique_ptr<SpanProcessor>(new TracezSpanProcessor(shared_data)), resource);
auto context = std::make_shared<TracerContext>(std::move(processors), resource);

tracer = std::shared_ptr<opentelemetry::trace::Tracer>(new Tracer(context));
auto spans = shared_data->GetSpanSnapshot();
Expand Down
Loading

0 comments on commit a987f0a

Please sign in to comment.