Skip to content

Commit

Permalink
Add OTLP/HTTP+JSON Protocol exporter (#810)
Browse files Browse the repository at this point in the history
  • Loading branch information
owent authored Jun 8, 2021
1 parent 12946c8 commit f65b07a
Show file tree
Hide file tree
Showing 22 changed files with 1,267 additions and 102 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ Increment the:

## [Unreleased]

* [EXPORTER] Add OTLP/HTTP+JSON Protocol exporter ([#810](https://github.com/open-telemetry/opentelemetry-cpp/pull/810))
* [EXPORTER] Rename `OtlpExporter` to `OtlpGrpcExporter`, rename `otlp_exporter.h` to `otlp_grpc_exporter.h` ([#810](https://github.com/open-telemetry/opentelemetry-cpp/pull/810))

## [1.0.0-rc1] 2021-06-04

* [BUILD] Enable Jaeger exporter build in Windows ([#815](https://github.com/open-telemetry/opentelemetry-cpp/pull/815))
Expand Down
13 changes: 11 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ if(WITH_OTLP)
find_package(Protobuf REQUIRED)
endif()
if(NOT gRPC_FOUND)
find_package(gRPC REQUIRED)
find_package(gRPC)
endif()
if(WIN32)
# Always use x64 protoc.exe
Expand All @@ -221,6 +221,15 @@ if(WITH_OTLP)
message("PROTOBUF_PROTOC_EXECUTABLE=${PROTOBUF_PROTOC_EXECUTABLE}")

include(cmake/opentelemetry-proto.cmake)
include(CMakeDependentOption)
find_package(CURL)
find_package(nlohmann_json)
cmake_dependent_option(
WITH_OTLP_GRPC "Whether to include the OTLP gRPC exporter in the SDK" ON
"gRPC_FOUND" OFF)
cmake_dependent_option(
WITH_OTLP_HTTP "Whether to include the OTLP http exporter in the SDK" ON
"CURL_FOUND;nlohmann_json_FOUND" OFF)
endif()

list(APPEND CMAKE_PREFIX_PATH "${CMAKE_BINARY_DIR}")
Expand Down Expand Up @@ -268,11 +277,11 @@ if(NOT WITH_API_ONLY)
include_directories(ext/include)

add_subdirectory(sdk)
add_subdirectory(ext)
add_subdirectory(exporters)
if(WITH_EXAMPLES)
add_subdirectory(examples)
endif()
add_subdirectory(ext)
endif()

# Add nlohmann/json submodule to include directories
Expand Down
4 changes: 2 additions & 2 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ load("@com_github_grpc_grpc//bazel:grpc_extra_deps.bzl", "grpc_extra_deps")

grpc_extra_deps()

load("@upb//bazel:repository_defs.bzl", "bazel_version_repository")
load("@upb//bazel:workspace_deps.bzl", "upb_deps")

bazel_version_repository(name = "upb_bazel_version")
upb_deps()

# Load prometheus C++ dependencies.
load("@com_github_jupp0r_prometheus_cpp//bazel:repositories.bzl", "prometheus_cpp_repositories")
Expand Down
16 changes: 13 additions & 3 deletions bazel/repository.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,23 @@ def opentelemetry_cpp_deps():
)

# Load gRPC dependency
maybe(
http_archive,
name = "com_github_grpc_grpc_legacy",
sha256 = "2060769f2d4b0d3535ba594b2ab614d7f68a492f786ab94b4318788d45e3278a",
strip_prefix = "grpc-1.33.2",
urls = [
"https://github.com/grpc/grpc/archive/v1.33.2.tar.gz",
],
)

maybe(
http_archive,
name = "com_github_grpc_grpc",
sha256 = "d6277f77e0bb922d3f6f56c0f93292bb4cfabfc3c92b31ee5ccea0e100303612",
strip_prefix = "grpc-1.28.0",
sha256 = "2060769f2d4b0d3535ba594b2ab614d7f68a492f786ab94b4318788d45e3278a",
strip_prefix = "grpc-1.33.2",
urls = [
"https://github.com/grpc/grpc/archive/v1.28.0.tar.gz",
"https://github.com/grpc/grpc/archive/v1.33.2.tar.gz",
],
)

Expand Down
2 changes: 1 addition & 1 deletion examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
if(WITH_OTLP)
if(WITH_OTLP_GRPC OR WITH_OTLP_HTTP)
add_subdirectory(otlp)
add_subdirectory(grpc)
endif()
Expand Down
19 changes: 16 additions & 3 deletions examples/otlp/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,27 @@ cc_library(
)

cc_binary(
name = "example_otlp",
name = "example_otlp_grpc",
srcs = [
"main.cc",
"grpc_main.cc",
],
deps = [
":foo_library",
"//api",
"//exporters/otlp:otlp_exporter",
"//exporters/otlp:otlp_grpc_exporter",
"//sdk/src/trace",
],
)

cc_binary(
name = "example_otlp_http",
srcs = [
"http_main.cc",
],
deps = [
":foo_library",
"//api",
"//exporters/otlp:otlp_http_exporter",
"//sdk/src/trace",
],
)
27 changes: 18 additions & 9 deletions examples/otlp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,21 @@ add_library(otlp_foo_library foo_library/foo_library.cc)
target_link_libraries(otlp_foo_library ${CMAKE_THREAD_LIBS_INIT}
${CORE_RUNTIME_LIBS} opentelemetry_api)

add_executable(example_otlp main.cc)
target_link_libraries(
example_otlp
${CMAKE_THREAD_LIBS_INIT}
otlp_foo_library
opentelemetry_trace
${CORE_RUNTIME_LIBS}
opentelemetry_exporter_otprotocol
gRPC::grpc++)
if(WITH_OTLP_GRPC)
add_executable(example_otlp_grpc grpc_main.cc)
target_link_libraries(
example_otlp_grpc
${CMAKE_THREAD_LIBS_INIT}
otlp_foo_library
opentelemetry_trace
${CORE_RUNTIME_LIBS}
opentelemetry_exporter_otlp_grpc
gRPC::grpc++)
endif()

if(WITH_OTLP_HTTP)
add_executable(example_otlp_http http_main.cc)
target_link_libraries(
example_otlp_http ${CMAKE_THREAD_LIBS_INIT} otlp_foo_library
opentelemetry_trace ${CORE_RUNTIME_LIBS} opentelemetry_exporter_otlp_http)
endif()
14 changes: 8 additions & 6 deletions examples/otlp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@ This is an example of how to use the [OpenTelemetry
Protocol](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/README.md)
(OTLP) exporter.

The application in `main.cc` initializes an `OtlpExporter` instance and uses it
to register a tracer provider from the [OpenTelemetry
The application in `grpc_main.cc` initializes an `OtlpGrpcExporter` instance and
the application in `http_main.cc` initializes an `OtlpHttpExporter` instance
and they 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).

To enable TLS authentication for OTLP grpc exporter, SslCredentials can be used
by specifying the path to client certificate pem file, or the string containing
this certificate via OtlpExporterOptions. The path to such a .pem file can be
this certificate via OtlpGrpcExporterOptions. The path to such a .pem file can be
provided as a command-line argument alongwith the collector endpoint to the main
binary invocation above.

Expand All @@ -31,18 +32,19 @@ OpenTelemetry Collector with an OTLP receiver by running:
- On Unix based systems use:

```console
docker run --rm -it -p 4317:4317 -v $(pwd)/examples/otlp:/cfg otel/opentelemetry-collector:0.19.0 --config=/cfg/opentelemetry-collector-config/config.dev.yaml
docker run --rm -it -p 4317:4317 -p 55681:55681 -v $(pwd)/examples/otlp:/cfg otel/opentelemetry-collector:0.19.0 --config=/cfg/opentelemetry-collector-config/config.dev.yaml
```

- On Windows use:

```console
docker run --rm -it -p 4317:4317 -v "%cd%/examples/otlp":/cfg otel/opentelemetry-collector:0.19.0 --config=/cfg/opentelemetry-collector-config/config.dev.yaml
docker run --rm -it -p 4317:4317 -p 55681:55681 -v "%cd%/examples/otlp":/cfg otel/opentelemetry-collector:0.19.0 --config=/cfg/opentelemetry-collector-config/config.dev.yaml
```

Note that the OTLP exporter connects to the Collector at `localhost:4317` by
default. This can be changed with first argument from command-line, for example:
`./example_otlp gateway.docker.internal:4317`.
`./example_otlp_grpc gateway.docker.internal:4317` and
`./example_otlp_http gateway.docker.internal:55681/v1/traces`.

Once you have the Collector running, see
[CONTRIBUTING.md](../../CONTRIBUTING.md) for instructions on building and
Expand Down
6 changes: 3 additions & 3 deletions examples/otlp/main.cc → examples/otlp/grpc_main.cc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#include "opentelemetry/exporters/otlp/otlp_exporter.h"
#include "opentelemetry/exporters/otlp/otlp_grpc_exporter.h"
#include "opentelemetry/sdk/trace/simple_processor.h"
#include "opentelemetry/sdk/trace/tracer_provider.h"
#include "opentelemetry/trace/provider.h"
Expand All @@ -15,11 +15,11 @@ namespace otlp = opentelemetry::exporter::otlp;

namespace
{
opentelemetry::exporter::otlp::OtlpExporterOptions opts;
opentelemetry::exporter::otlp::OtlpGrpcExporterOptions opts;
void InitTracer()
{
// Create OTLP exporter instance
auto exporter = std::unique_ptr<sdktrace::SpanExporter>(new otlp::OtlpExporter(opts));
auto exporter = std::unique_ptr<sdktrace::SpanExporter>(new otlp::OtlpGrpcExporter(opts));
auto processor = std::unique_ptr<sdktrace::SpanProcessor>(
new sdktrace::SimpleSpanProcessor(std::move(exporter)));
auto provider =
Expand Down
58 changes: 58 additions & 0 deletions examples/otlp/http_main.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#include "opentelemetry/exporters/otlp/otlp_http_exporter.h"
#include "opentelemetry/sdk/trace/simple_processor.h"
#include "opentelemetry/sdk/trace/tracer_provider.h"
#include "opentelemetry/trace/provider.h"

#include <string>

#include "foo_library/foo_library.h"

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

namespace
{
opentelemetry::exporter::otlp::OtlpHttpExporterOptions opts;
void InitTracer()
{
// Create OTLP exporter instance
auto exporter = std::unique_ptr<sdktrace::SpanExporter>(new otlp::OtlpHttpExporter(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 > 1)
{
opts.url = argv[1];
if (argc > 2)
{
std::string debug = argv[2];
opts.console_debug = debug != "" && debug != "0" && debug != "no";
}

if (argc > 3)
{
std::string binary_mode = argv[3];
if (binary_mode.size() >= 3 && binary_mode.substr(0, 3) == "bin")
{
opts.content_type = opentelemetry::exporter::otlp::HttpRequestContentType::kBinary;
}
}
}
// Removing this line will leave the default noop TracerProvider in place.
InitTracer();

foo_library();
}
4 changes: 4 additions & 0 deletions examples/otlp/opentelemetry-collector-config/config.dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ receivers:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: "0.0.0.0:55681"
cors_allowed_origins:
- '*'
service:
pipelines:
traces:
Expand Down
58 changes: 49 additions & 9 deletions exporters/otlp/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ cc_library(
)

cc_library(
name = "otlp_exporter",
name = "otlp_grpc_exporter",
srcs = [
"src/otlp_exporter.cc",
"src/otlp_grpc_exporter.cc",
],
hdrs = [
"include/opentelemetry/exporters/otlp/otlp_exporter.h",
"include/opentelemetry/exporters/otlp/otlp_grpc_exporter.h",
"include/opentelemetry/exporters/otlp/protobuf_include_prefix.h",
"include/opentelemetry/exporters/otlp/protobuf_include_suffix.h",
],
Expand All @@ -55,6 +55,36 @@ cc_library(
],
)

cc_library(
name = "otlp_http_exporter",
srcs = [
"src/otlp_http_exporter.cc",
],
hdrs = [
"include/opentelemetry/exporters/otlp/otlp_http_exporter.h",
"include/opentelemetry/exporters/otlp/protobuf_include_prefix.h",
"include/opentelemetry/exporters/otlp/protobuf_include_suffix.h",
],
copts = [
"-DCURL_STATICLIB",
],
linkopts = select({
"//bazel:windows": [
"-DEFAULTLIB:advapi32.lib",
"-DEFAULTLIB:crypt32.lib",
],
"//conditions:default": [],
}),
strip_include_prefix = "include",
deps = [
":otlp_recordable",
"//ext/src/http/client/curl:http_client_curl",
"//sdk/src/trace",
"@com_github_opentelemetry_proto//:trace_service_proto_cc",
"@github_nlohmann_json//:json",
],
)

cc_test(
name = "otlp_recordable_test",
srcs = ["test/otlp_recordable_test.cc"],
Expand All @@ -65,19 +95,29 @@ cc_test(
)

cc_test(
name = "otlp_exporter_test",
srcs = ["test/otlp_exporter_test.cc"],
name = "otlp_grpc_exporter_test",
srcs = ["test/otlp_grpc_exporter_test.cc"],
deps = [
":otlp_grpc_exporter",
"//api",
"@com_google_googletest//:gtest_main",
],
)

cc_test(
name = "otlp_http_exporter_test",
srcs = ["test/otlp_http_exporter_test.cc"],
deps = [
":otlp_exporter",
":otlp_http_exporter",
"//api",
"@com_google_googletest//:gtest_main",
],
)

otel_cc_benchmark(
name = "otlp_exporter_benchmark",
srcs = ["test/otlp_exporter_benchmark.cc"],
name = "otlp_grpc_exporter_benchmark",
srcs = ["test/otlp_grpc_exporter_benchmark.cc"],
deps = [
":otlp_exporter",
":otlp_grpc_exporter",
],
)
Loading

0 comments on commit f65b07a

Please sign in to comment.