Skip to content

Commit

Permalink
Add Jaeger exporter (#534)
Browse files Browse the repository at this point in the history
  • Loading branch information
ThomsonTan authored May 11, 2021
1 parent e901a36 commit 5914160
Show file tree
Hide file tree
Showing 43 changed files with 7,190 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Increment the:

## [Unreleased]

* [EXPORTER] Add Jaeger exporter ([#534](https://github.com/open-telemetry/opentelemetry-cpp/pull/534))
* [SDK] Add instrumentation library and multiple tracer support ([#693](https://github.com/open-telemetry/opentelemetry-cpp/pull/693))

## [0.5.0] 2021-04-26
Expand Down
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ option(WITH_PROMETHEUS "Whether to include the Prometheus Client in the SDK"
option(WITH_ELASTICSEARCH
"Whether to include the Elasticsearch Client in the SDK" OFF)

option(WITH_JAEGER "Whether to include the Jaeger exporter" OFF)

option(BUILD_TESTING "Whether to enable tests" ON)
if(WIN32)
option(WITH_ETW "Whether to include the ETW Exporter in the SDK" ON)
Expand Down
3 changes: 3 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
if(WITH_OTLP)
add_subdirectory(otlp)
endif()
if(WITH_JAEGER)
add_subdirectory(jaeger)
endif()
add_subdirectory(plugin)
add_subdirectory(simple)
add_subdirectory(batch)
Expand Down
26 changes: 26 additions & 0 deletions examples/jaeger/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
cc_library(
name = "foo_library",
srcs = [
"foo_library/foo_library.cc",
],
hdrs = [
"foo_library/foo_library.h",
],
deps = [
"//api",
],
)

# TODO: enable bazel build
# cc_binary(
# name = "example_jaeger",
# srcs = [
# "main.cc",
# ],
# deps = [
# ":foo_library",
# "//api",
# "//exporters/jaeger:jaeger_exporter",
# "//sdk/src/trace",
# ],
# )
10 changes: 10 additions & 0 deletions examples/jaeger/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
include_directories(${CMAKE_SOURCE_DIR}/exporters/jaeger/include)

add_library(jaeger_foo_library foo_library/foo_library.cc)
target_link_libraries(jaeger_foo_library ${CMAKE_THREAD_LIBS_INIT}
${CORE_RUNTIME_LIBS} opentelemetry_api)

add_executable(example_jaeger main.cc)
target_link_libraries(
example_jaeger ${CMAKE_THREAD_LIBS_INIT} jaeger_foo_library
opentelemetry_trace ${CORE_RUNTIME_LIBS} jaeger_trace_exporter)
18 changes: 18 additions & 0 deletions examples/jaeger/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Jaeger Exporter Example

This is an example of how to use the Jaeger exporter.

The application in `main.cc` initializes an `JaegerExporter` instance and uses it
to register a tracer provider from the [OpenTelemetry
SDK](https://github.com/open-telemetry/opentelemetry-cpp). 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 spans are exported to the Jaeger agent using the Jaeger exporter.

Note that the Jaeger exporter connects to the agent at `localhost:6831` by
default.

Once you have the Collector running, see
[CONTRIBUTING.md](../../CONTRIBUTING.md) for instructions on building and
running the example.
33 changes: 33 additions & 0 deletions examples/jaeger/foo_library/foo_library.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#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 scoped_span = trace::Scope(get_tracer()->StartSpan("f1"));
}

void f2()
{
auto scoped_span = trace::Scope(get_tracer()->StartSpan("f2"));

f1();
f1();
}
} // namespace

void foo_library()
{
auto scoped_span = trace::Scope(get_tracer()->StartSpan("library"));

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

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

#include "foo_library/foo_library.h"

namespace trace = opentelemetry::trace;
namespace nostd = opentelemetry::nostd;
namespace sdktrace = opentelemetry::sdk::trace;
namespace jaeger = opentelemetry::exporter::jaeger;

namespace
{
opentelemetry::exporter::jaeger::JaegerExporterOptions opts;
void InitTracer()
{
// Create Jaeger exporter instance
auto exporter = std::unique_ptr<sdktrace::SpanExporter>(new jaeger::JaegerExporter(opts));
auto processor = std::unique_ptr<sdktrace::SpanProcessor>(
new sdktrace::SimpleSpanProcessor(std::move(exporter)));
auto provider =
nostd::shared_ptr<trace::TracerProvider>(new sdktrace::TracerProvider(std::move(processor)));
// Set the global trace provider
trace::Provider::SetTracerProvider(provider);
}
} // namespace

int main(int argc, char *argv[])
{
if (argc == 2)
{
opts.server_addr = argv[1];
}
// Removing this line will leave the default noop TracerProvider in place.
InitTracer();

foo_library();
}
4 changes: 4 additions & 0 deletions exporters/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,7 @@ endif()
if(WITH_ETW)
add_subdirectory(etw)
endif()

if(WITH_JAEGER)
add_subdirectory(jaeger)
endif()
38 changes: 38 additions & 0 deletions exporters/jaeger/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
include_directories(include)
include_directories(thrift-gen)

find_package(Thrift REQUIRED)

set(JAEGER_THRIFT_GENCPP_SOURCES
thrift-gen/Agent.cpp thrift-gen/jaeger_types.cpp thrift-gen/Collector.cpp
thrift-gen/zipkincore_types.cpp)

set(JAEGER_EXPORTER_SOURCES
src/jaeger_exporter.cc src/thrift_sender.cc src/udp_transport.cc
src/recordable.cc src/TUDPTransport.cc)

add_library(jaeger_trace_exporter ${JAEGER_EXPORTER_SOURCES}
${JAEGER_THRIFT_GENCPP_SOURCES})
target_link_libraries(
jaeger_trace_exporter
PUBLIC opentelemetry_resources
PRIVATE thrift::thrift)

if(MSVC)
target_compile_definitions(jaeger_trace_exporter PUBLIC NOMINMAX)
if(NOT BUILD_SHARED_LIBS)
target_compile_definitions(jaeger_trace_exporter
PUBLIC THRIFT_STATIC_DEFINE)
endif()
endif()

if(BUILD_TESTING)
add_executable(jaeger_recordable_test test/jaeger_recordable_test.cc)
target_link_libraries(jaeger_recordable_test ${GTEST_BOTH_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT} jaeger_trace_exporter)

gtest_add_tests(
TARGET jaeger_recordable_test
TEST_PREFIX exporter.
TEST_LIST jaeger_recordable_test)
endif() # BUILD_TESTING
56 changes: 56 additions & 0 deletions exporters/jaeger/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Jaeger Exporter for OpenTelemetry C++

## Prerequisite

* [Get Jaeger](https://www.jaegertracing.io/docs/getting-started/) and run
Jaeger agent.

## Installation

## CMake Installation Instructions

Refer to install instructions
[INSTALL.md](../../INSTALL.md#building-as-standalone-cmake-project). Modify step
2 to create `cmake` build configuration for compiling with Jaeger exporter as
below:

```console
$ cmake -DWITH_JAEGER=ON ..
-- The C compiler identification is GNU 9.3.0
-- The CXX compiler identification is GNU 9.3.0
...
-- Configuring done
-- Generating done
-- Build files have been written to: /home/<user>/source/opentelemetry-cpp/build
$
```

### Bazel install Instructions

TODO

## Usage

Install the exporter on your application and pass the options.

```cpp
opentelemetry::exporter::jaeger::JaegerExporterOptions options;
options.server_addr = "localhost";
options.server_port = 6831;
options.transport_format = TransportFormat::kThriftUdpCompact;

auto exporter = std::unique_ptr<opentelemetry::sdk::trace::SpanExporter>(
new opentelemetry::exporter::jaeger::JaegerExporter(options));
auto processor = std::shared_ptr<sdktrace::SpanProcessor>(
new sdktrace::SimpleSpanProcessor(std::move(exporter)));
auto provider = nostd::shared_ptr<opentelemetry::trace::TracerProvider>(
new sdktrace::TracerProvider(processor));

// Set the global trace provider
opentelemetry::trace::Provider::SetTracerProvider(provider);

```
## Viewing your traces
Please visit the Jaeger UI endpoint <http://localhost:16686>.
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Copyright 2021, OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include <opentelemetry/sdk/trace/exporter.h>

OPENTELEMETRY_BEGIN_NAMESPACE
namespace exporter
{
namespace jaeger
{
enum class TransportFormat
{
kThriftUdp,
kThriftUdpCompact,
kThriftHttp,
kProtobufGrpc,
};

class ThriftSender;

/**
* Struct to hold Jaeger exporter options.
*/
struct JaegerExporterOptions
{
// The endpoint to export to.
std::string server_addr = "localhost";
uint16_t server_port = 6831;
TransportFormat transport_format = TransportFormat::kThriftUdpCompact;
};

namespace trace_sdk = opentelemetry::sdk::trace;
namespace sdk_common = opentelemetry::sdk::common;

class JaegerExporter final : public trace_sdk::SpanExporter
{
public:
/**
* Create a JaegerExporter using all default options.
*/
JaegerExporter();

/**
* Create a JaegerExporter using the given options.
*/
explicit JaegerExporter(const JaegerExporterOptions &options);

/**
* Create a span recordable.
* @return a new initialized Recordable object.
*/
std::unique_ptr<trace_sdk::Recordable> MakeRecordable() noexcept override;

/**
* Export a batch of spans.
* @param spans a span of unique pointers to span recordables.
*/
sdk_common::ExportResult Export(
const nostd::span<std::unique_ptr<trace_sdk::Recordable>> &spans) noexcept override;

/**
* Shutdown the exporter.
* @param timeout an option timeout, default to max.
*/
bool Shutdown(
std::chrono::microseconds timeout = std::chrono::microseconds::max()) noexcept override
{
return true;
}

private:
void InitializeEndpoint();

private:
// The configuration options associated with this exporter.
bool is_shutdown_ = false;
JaegerExporterOptions options_;
std::unique_ptr<ThriftSender> sender_;
};

} // namespace jaeger
} // namespace exporter
OPENTELEMETRY_END_NAMESPACE
Loading

0 comments on commit 5914160

Please sign in to comment.