From ace43e7ad27326992348fa2e43150add3ec3ed7b Mon Sep 17 00:00:00 2001 From: Tom Tan Date: Fri, 14 May 2021 20:32:34 -0700 Subject: [PATCH 1/6] Populate resource to OTLP span --- examples/otlp/README.md | 43 ++++++++----------- .../config.dev.yaml | 15 +++++++ .../opentelemetry/exporters/otlp/recordable.h | 4 +- exporters/otlp/src/otlp_exporter.cc | 12 +++++- exporters/otlp/src/recordable.cc | 6 +-- 5 files changed, 49 insertions(+), 31 deletions(-) create mode 100644 examples/otlp/opentelemetry-collector-config/config.dev.yaml diff --git a/examples/otlp/README.md b/examples/otlp/README.md index 1f246053f4..daa0c6ebd9 100644 --- a/examples/otlp/README.md +++ b/examples/otlp/README.md @@ -10,38 +10,33 @@ 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 provided as a command-line argument alongwith the collector endpoint -to the main binary invocation above. +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 +provided as a command-line argument alongwith the collector endpoint to the main +binary invocation above. Resulting spans are exported to the **OpenTelemetry Collector** using the OTLP exporter. The OpenTelemetry Collector can be configured to export to other backends (see list of [supported backends](https://github.com/open-telemetry/opentelemetry-collector/blob/main/exporter/README.md)). -For instructions on downloading and running the OpenTelemetry Collector, see -[Getting Started](https://opentelemetry.io/docs/collector/about/). - -Here is an example of a Collector `config.yaml` file that can be used to export -to [Zipkin](https://zipkin.io/) via the Collector using the OTLP exporter: - -```yml -receivers: - otlp: - protocols: - grpc: - endpoint: localhost:4317 -exporters: - zipkin: - endpoint: "http://localhost:9411/api/v2/spans" -service: - pipelines: - traces: - receivers: [otlp] - exporters: [zipkin] +Follow below command to run the **OpenTelemetry Collector** with OTLP receiver +in docker which dumps the received data into console. See [Getting +Started](https://opentelemetry.io/docs/collector/about/) for more information. + +Open a terminal window at the root directory of this repo and launch the +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=--config=/cfg/opentelemetry-collector-config/config.dev.yaml ``` +- On Windows use: 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 + 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`. diff --git a/examples/otlp/opentelemetry-collector-config/config.dev.yaml b/examples/otlp/opentelemetry-collector-config/config.dev.yaml new file mode 100644 index 0000000000..b94bfa38ce --- /dev/null +++ b/examples/otlp/opentelemetry-collector-config/config.dev.yaml @@ -0,0 +1,15 @@ +exporters: + logging: + loglevel: DEBUG +receivers: + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:4317 +service: + pipelines: + traces: + receivers: + - otlp + exporters: + - logging diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/recordable.h b/exporters/otlp/include/opentelemetry/exporters/otlp/recordable.h index 53fc5f4d55..820fa991c9 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/recordable.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/recordable.h @@ -20,7 +20,7 @@ class Recordable final : public sdk::trace::Recordable const proto::trace::v1::Span &span() const noexcept { return span_; } /** Dynamically converts the resource of this span into a proto. */ - proto::resource::v1::Resource ProtoResource() const noexcept; + void PopulateProtoResource(proto::resource::v1::Resource *resource) const noexcept; void SetIdentity(const opentelemetry::trace::SpanContext &span_context, opentelemetry::trace::SpanId parent_span_id) noexcept override; @@ -53,7 +53,7 @@ class Recordable final : public sdk::trace::Recordable private: proto::trace::v1::Span span_; - const opentelemetry::sdk::resource::Resource *resource_; + const opentelemetry::sdk::resource::Resource *resource_ = nullptr; }; } // namespace otlp } // namespace exporter diff --git a/exporters/otlp/src/otlp_exporter.cc b/exporters/otlp/src/otlp_exporter.cc index 74e1a71bd4..9f96b298d4 100644 --- a/exporters/otlp/src/otlp_exporter.cc +++ b/exporters/otlp/src/otlp_exporter.cc @@ -28,8 +28,18 @@ void PopulateRequest(const nostd::span> for (auto &recordable : spans) { auto rec = std::unique_ptr(static_cast(recordable.release())); - // TODO - Handle Resource *instrumentation_lib->add_spans() = std::move(rec->span()); + + if (!has_resource) + { + std::unique_ptr proto_resource{ + new proto::resource::v1::Resource}; + + rec->PopulateProtoResource(proto_resource.get()); + + resource_span->set_allocated_resource(proto_resource.release()); + has_resource = true; + } } } diff --git a/exporters/otlp/src/recordable.cc b/exporters/otlp/src/recordable.cc index a973bad994..08220f0be9 100644 --- a/exporters/otlp/src/recordable.cc +++ b/exporters/otlp/src/recordable.cc @@ -216,17 +216,15 @@ void PopulateAttribute(opentelemetry::proto::common::v1::KeyValue *attribute, } } -proto::resource::v1::Resource Recordable::ProtoResource() const noexcept +void Recordable::PopulateProtoResource(proto::resource::v1::Resource *proto) const noexcept { - proto::resource::v1::Resource proto; if (resource_) { for (const auto &kv : resource_->GetAttributes()) { - PopulateAttribute(proto.add_attributes(), kv.first, kv.second); + PopulateAttribute(proto->add_attributes(), kv.first, kv.second); } } - return proto; } void Recordable::SetResource(const opentelemetry::sdk::resource::Resource &resource) noexcept From 6239fd3499631b39b63e3db76aa672d9680bee9e Mon Sep 17 00:00:00 2001 From: Tom Tan Date: Fri, 14 May 2021 20:48:17 -0700 Subject: [PATCH 2/6] Update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 532c08eafe..a45feac7c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ Increment the: ## [Unreleased] +* [EXPORTER] Populate resource to OTLP proto data ([#758](https://github.com/open-telemetry/opentelemetry-cpp/pull/758)) + ## [0.6.0] 2021-05-11 * [EXPORTER] Add Jaeger exporter ([#534](https://github.com/open-telemetry/opentelemetry-cpp/pull/534)) From dd7719415deb47376876614ccb7b9bf82bf0550f Mon Sep 17 00:00:00 2001 From: Tom Tan Date: Fri, 14 May 2021 21:02:45 -0700 Subject: [PATCH 3/6] Format --- .../config.dev.yaml | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/examples/otlp/opentelemetry-collector-config/config.dev.yaml b/examples/otlp/opentelemetry-collector-config/config.dev.yaml index b94bfa38ce..6807000f01 100644 --- a/examples/otlp/opentelemetry-collector-config/config.dev.yaml +++ b/examples/otlp/opentelemetry-collector-config/config.dev.yaml @@ -1,15 +1,15 @@ -exporters: - logging: - loglevel: DEBUG -receivers: - otlp: - protocols: - grpc: - endpoint: 0.0.0.0:4317 -service: - pipelines: - traces: - receivers: - - otlp - exporters: - - logging +exporters: + logging: + loglevel: DEBUG +receivers: + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:4317 +service: + pipelines: + traces: + receivers: + - otlp + exporters: + - logging From 8766d4ce44bd984ef375a95672f8f9221065af52 Mon Sep 17 00:00:00 2001 From: Tom Tan Date: Fri, 14 May 2021 21:15:30 -0700 Subject: [PATCH 4/6] Markdownlint doesn't allow long line console command --- .markdownlintignore | 1 + examples/otlp/README.md | 11 +++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.markdownlintignore b/.markdownlintignore index c3dbab2a0e..f0cec48dba 100644 --- a/.markdownlintignore +++ b/.markdownlintignore @@ -1,2 +1,3 @@ third_party/** tools/** +examples/otlp/README.md diff --git a/examples/otlp/README.md b/examples/otlp/README.md index daa0c6ebd9..e4750ef875 100644 --- a/examples/otlp/README.md +++ b/examples/otlp/README.md @@ -29,13 +29,16 @@ Open a terminal window at the root directory of this repo and launch the 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=--config=/cfg/opentelemetry-collector-config/config.dev.yaml +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 ``` -- On Windows use: 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 +- 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 +``` 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: From b99dbbc731aa601f8431643f15f64d76fcbabfb5 Mon Sep 17 00:00:00 2001 From: Tom Tan Date: Sat, 15 May 2021 20:52:45 -0700 Subject: [PATCH 5/6] Simplify code with ResourceSpan.mutable_resource --- .../include/opentelemetry/exporters/otlp/recordable.h | 2 +- exporters/otlp/src/otlp_exporter.cc | 9 ++------- exporters/otlp/src/recordable.cc | 7 +++++-- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/recordable.h b/exporters/otlp/include/opentelemetry/exporters/otlp/recordable.h index 820fa991c9..6ebe0511aa 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/recordable.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/recordable.h @@ -20,7 +20,7 @@ class Recordable final : public sdk::trace::Recordable const proto::trace::v1::Span &span() const noexcept { return span_; } /** Dynamically converts the resource of this span into a proto. */ - void PopulateProtoResource(proto::resource::v1::Resource *resource) const noexcept; + proto::resource::v1::Resource ProtoResource() const noexcept; void SetIdentity(const opentelemetry::trace::SpanContext &span_context, opentelemetry::trace::SpanId parent_span_id) noexcept override; diff --git a/exporters/otlp/src/otlp_exporter.cc b/exporters/otlp/src/otlp_exporter.cc index 9f96b298d4..7a1a56c26c 100644 --- a/exporters/otlp/src/otlp_exporter.cc +++ b/exporters/otlp/src/otlp_exporter.cc @@ -32,13 +32,8 @@ void PopulateRequest(const nostd::span> if (!has_resource) { - std::unique_ptr proto_resource{ - new proto::resource::v1::Resource}; - - rec->PopulateProtoResource(proto_resource.get()); - - resource_span->set_allocated_resource(proto_resource.release()); - has_resource = true; + *resource_span->mutable_resource() = rec->ProtoResource(); + has_resource = true; } } } diff --git a/exporters/otlp/src/recordable.cc b/exporters/otlp/src/recordable.cc index 08220f0be9..666a370574 100644 --- a/exporters/otlp/src/recordable.cc +++ b/exporters/otlp/src/recordable.cc @@ -216,15 +216,18 @@ void PopulateAttribute(opentelemetry::proto::common::v1::KeyValue *attribute, } } -void Recordable::PopulateProtoResource(proto::resource::v1::Resource *proto) const noexcept +proto::resource::v1::Resource Recordable::ProtoResource() const noexcept { + proto::resource::v1::Resource proto; if (resource_) { for (const auto &kv : resource_->GetAttributes()) { - PopulateAttribute(proto->add_attributes(), kv.first, kv.second); + PopulateAttribute(proto.add_attributes(), kv.first, kv.second); } } + + return proto; } void Recordable::SetResource(const opentelemetry::sdk::resource::Resource &resource) noexcept From bb95dd10f172d4cd6efc5b318dc3a475525eb3d1 Mon Sep 17 00:00:00 2001 From: Tom Tan Date: Sat, 15 May 2021 21:58:43 -0700 Subject: [PATCH 6/6] Add Resource test to OTLP recordable test case --- exporters/otlp/test/recordable_test.cc | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/exporters/otlp/test/recordable_test.cc b/exporters/otlp/test/recordable_test.cc index 5ea4e03031..b4ceef03e8 100644 --- a/exporters/otlp/test/recordable_test.cc +++ b/exporters/otlp/test/recordable_test.cc @@ -150,6 +150,28 @@ TEST(Recordable, AddLink) } } +TEST(Recordable, SetResource) +{ + Recordable rec; + const std::string service_name_key = "service.name"; + std::string service_name = "test-otlp"; + auto resource = + opentelemetry::sdk::resource::Resource::Create({{service_name_key, service_name}}); + rec.SetResource(resource); + + auto proto_resource = rec.ProtoResource(); + bool found_service_name = false; + for (size_t i = 0; i < proto_resource.attributes_size(); i++) + { + auto attr = proto_resource.attributes(static_cast(i)); + if (attr.key() == service_name_key && attr.value().string_value() == service_name) + { + found_service_name = true; + } + } + EXPECT_TRUE(found_service_name); +} + // Test non-int single types. Int single types are tested using templates (see IntAttributeTest) TEST(Recordable, SetSingleAtrribute) {