Skip to content

Commit f452d7d

Browse files
committed
WIP: OpenTelemetry integration refactoring
1 parent aba976e commit f452d7d

File tree

10 files changed

+212
-93
lines changed

10 files changed

+212
-93
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ set(couchbase_cxx_client_FILES
400400
core/search_query_options.cxx
401401
core/seed_config.cxx
402402
core/topology/configuration.cxx
403+
core/tracing/otel_tracer.cxx
403404
core/tracing/threshold_logging_tracer.cxx
404405
core/tracing/tracer_wrapper.cxx
405406
core/transactions/active_transaction_record.cxx
@@ -522,6 +523,7 @@ foreach(TARGET ${couchbase_cxx_client_LIBRARIES})
522523
snappy
523524
jsonsl
524525
couchbase_backtrace
526+
opentelemetry_api
525527
hdr_histogram_static)
526528

527529
if(WIN32)

cmake/ThirdPartyDependencies.cmake

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,29 @@ if(NOT TARGET spdlog::spdlog)
5858
"SPDLOG_FMT_EXTERNAL ON")
5959
endif()
6060

61+
if(NOT TARGET opentelemetry_api)
62+
# https://github.com/open-telemetry/opentelemetry-cpp/releases
63+
cpmaddpackage(
64+
NAME
65+
opentelemetry
66+
VERSION
67+
1.17.0
68+
GITHUB_REPOSITORY
69+
"open-telemetry/opentelemetry-cpp"
70+
EXCLUDE_FROM_ALL ON
71+
OPTIONS
72+
"OPENTELEMETRY_INSTALL OFF"
73+
# "WITH_API_ONLY ON"
74+
"WITH_OTLP_HTTP ON"
75+
"WITH_BENCHMARK OFF"
76+
"BUILD_TESTING OFF"
77+
"BUILD_SHARED_LIBS OFF"
78+
"CMAKE_C_VISIBILITY_PRESET hidden"
79+
"CMAKE_CXX_VISIBILITY_PRESET hidden"
80+
"CMAKE_POSITION_INDEPENDENT_CODE ON")
81+
endif()
82+
83+
6184
if(NOT TARGET Microsoft.GSL::GSL)
6285
# https://github.com/microsoft/GSL/releases
6386
cpmaddpackage(

core/tracing/noop_tracer.hxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class noop_span : public couchbase::tracing::request_span
3939
/* do nothing */
4040
}
4141

42-
auto uses_tags() const -> bool override
42+
[[nodiscard]] auto uses_tags() const -> bool override
4343
{
4444
return false;
4545
}

core/tracing/otel_tracer.cxx

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2+
/*
3+
* Copyright 2021 Couchbase, Inc.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#include "otel_tracer.hxx"
19+
20+
#include "../meta/version.hxx"
21+
22+
#if defined(__GNUC__)
23+
#pragma GCC diagnostic push
24+
#pragma GCC diagnostic ignored "-Wsign-conversion"
25+
#endif
26+
#include <opentelemetry/trace/provider.h>
27+
#include <opentelemetry/trace/tracer.h>
28+
#if defined(__GNUC__)
29+
#pragma GCC diagnostic pop
30+
#endif
31+
32+
namespace couchbase::core::tracing
33+
{
34+
namespace
35+
{
36+
class otel_request_span : public couchbase::tracing::request_span
37+
{
38+
public:
39+
explicit otel_request_span(opentelemetry::nostd::shared_ptr<opentelemetry::trace::Span> span)
40+
: span_(std::move(span))
41+
{
42+
}
43+
44+
void add_tag(const std::string& name, const std::string& value) override
45+
{
46+
span_->SetAttribute(name, value);
47+
}
48+
49+
void add_tag(const std::string& name, std::uint64_t value) override
50+
{
51+
span_->SetAttribute(name, value);
52+
}
53+
54+
void end() override
55+
{
56+
span_->End();
57+
}
58+
59+
auto wrapped_span() -> opentelemetry::nostd::shared_ptr<opentelemetry::trace::Span>
60+
{
61+
return span_;
62+
}
63+
64+
private:
65+
opentelemetry::nostd::shared_ptr<opentelemetry::trace::Span> span_;
66+
};
67+
68+
} // namespace
69+
70+
class otel_request_tracer_impl
71+
{
72+
friend otel_request_tracer;
73+
74+
public:
75+
otel_request_tracer_impl()
76+
: tracer_{
77+
opentelemetry::trace::Provider::GetTracerProvider()->GetTracer("couchbase_cxx_sdk",
78+
meta::sdk_semver()),
79+
}
80+
{
81+
}
82+
83+
private:
84+
opentelemetry::nostd::shared_ptr<opentelemetry::trace::Tracer> tracer_;
85+
};
86+
87+
otel_request_tracer::otel_request_tracer()
88+
: impl_{ std::make_unique<otel_request_tracer_impl>() }
89+
{
90+
}
91+
92+
otel_request_tracer::~otel_request_tracer() = default;
93+
94+
95+
auto
96+
otel_request_tracer::start_span(std::string name,
97+
std::shared_ptr<couchbase::tracing::request_span> parent)
98+
-> std::shared_ptr<couchbase::tracing::request_span>
99+
{
100+
auto wrapped_parent = std::dynamic_pointer_cast<otel_request_span>(parent);
101+
if (wrapped_parent) {
102+
opentelemetry::trace::StartSpanOptions opts;
103+
opts.parent = wrapped_parent->wrapped_span()->GetContext();
104+
return std::make_shared<otel_request_span>(impl_->tracer_->StartSpan(name, opts));
105+
}
106+
return std::make_shared<otel_request_span>(impl_->tracer_->StartSpan(name));
107+
}
108+
109+
} // namespace couchbase::core::tracing

core/tracing/otel_tracer.hxx

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2+
/*
3+
* Copyright 2021 Couchbase, Inc.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#pragma once
19+
20+
#include <couchbase/tracing/request_tracer.hxx>
21+
22+
namespace couchbase::core::tracing
23+
{
24+
25+
class otel_request_tracer_impl;
26+
27+
class otel_request_tracer : public couchbase::tracing::request_tracer
28+
{
29+
public:
30+
otel_request_tracer();
31+
otel_request_tracer(const otel_request_tracer&) = delete;
32+
otel_request_tracer(otel_request_tracer&&) noexcept = default;
33+
auto operator=(const otel_request_tracer&) = delete;
34+
auto operator=(otel_request_tracer&&) -> otel_request_tracer& = default;
35+
~otel_request_tracer() override;
36+
37+
auto start_span(std::string name, std::shared_ptr<couchbase::tracing::request_span> parent)
38+
-> std::shared_ptr<couchbase::tracing::request_span> override;
39+
40+
private:
41+
std::unique_ptr<otel_request_tracer_impl> impl_;
42+
};
43+
} // namespace couchbase::core::tracing

couchbase/tracing/otel_tracer.hxx

Lines changed: 0 additions & 86 deletions
This file was deleted.

couchbase/tracing/request_tracer.hxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public:
5151
/* do nothing */
5252
}
5353

54-
virtual auto start_span(std::string name, std::shared_ptr<request_span> parent = {})
54+
virtual auto start_span(std::string name, std::shared_ptr<request_span> parent)
5555
-> std::shared_ptr<request_span> = 0;
5656
};
5757

tools/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ target_link_libraries(
4141
fmt::fmt
4242
spdlog::spdlog
4343
hdr_histogram_static
44-
asio)
44+
asio
45+
opentelemetry_trace
46+
opentelemetry_exporter_otlp_http)
4547

4648
if(COUCHBASE_CXX_CLIENT_STATIC_BORINGSSL AND WIN32)
4749
# Ignore the `LNK4099: PDB ['crypto.pdb'|'ssl.pdb'] was not found` warnings, as we don't (atm) keep track fo the *.PDB

tools/cbc.cxx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626

2727
#include <fmt/core.h>
2828

29-
int
30-
main(int argc, const char** argv)
29+
auto
30+
main(int argc, const char** argv) -> int
3131
{
3232
CLI::App app{ "Talk to Couchbase Server.", "cbc" };
3333
app.set_version_flag("--version", fmt::format("cbc {}", couchbase::core::meta::sdk_semver()));

tools/get.cxx

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,23 @@
1919
#include "utils.hxx"
2020

2121
#include <core/logger/logger.hxx>
22+
#include <core/tracing/otel_tracer.hxx>
23+
2224
#include <couchbase/cluster.hxx>
2325
#include <couchbase/codec/raw_binary_transcoder.hxx>
2426
#include <couchbase/codec/tao_json_serializer.hxx>
2527
#include <couchbase/fmt/cas.hxx>
2628
#include <couchbase/fmt/error.hxx>
2729

30+
#include <opentelemetry/exporters/otlp/otlp_environment.h>
31+
#include <opentelemetry/exporters/otlp/otlp_http.h>
32+
#include <opentelemetry/exporters/otlp/otlp_http_exporter_factory.h>
33+
#include <opentelemetry/exporters/otlp/otlp_http_exporter_options.h>
34+
#include <opentelemetry/sdk/trace/simple_processor_factory.h>
35+
#include <opentelemetry/sdk/trace/tracer_provider_factory.h>
36+
#include <opentelemetry/trace/provider.h>
37+
#include <opentelemetry/trace/tracer_provider.h>
38+
2839
#include <fmt/chrono.h>
2940
#include <spdlog/fmt/bin_to_hex.h>
3041
#include <tao/json.hpp>
@@ -71,7 +82,7 @@ class get_app : public CLI::App
7182
allow_extras(true);
7283
}
7384

74-
[[nodiscard]] int execute() const
85+
[[nodiscard]] auto execute() const -> int
7586
{
7687
apply_logger_options(common_options_.logger);
7788

@@ -87,10 +98,25 @@ class get_app : public CLI::App
8798

8899
const auto connection_string = common_options_.connection.connection_string;
89100

101+
{
102+
opentelemetry::exporter::otlp::OtlpHttpExporterOptions opts;
103+
auto exporter = opentelemetry::exporter::otlp::OtlpHttpExporterFactory::Create(opts);
104+
auto processor =
105+
opentelemetry::sdk::trace::SimpleSpanProcessorFactory::Create(std::move(exporter));
106+
auto resource = opentelemetry::sdk::resource::Resource::Create({ { "service.name", "cbc" } });
107+
auto provider =
108+
opentelemetry::sdk::trace::TracerProviderFactory::Create(std::move(processor), resource);
109+
opentelemetry::trace::Provider::SetTracerProvider(
110+
std::shared_ptr<opentelemetry::trace::TracerProvider>{ std::move(provider) });
111+
}
112+
113+
cluster_options.tracing().tracer(
114+
std::make_shared<couchbase::core::tracing::otel_request_tracer>());
115+
116+
90117
auto [connect_err, cluster] =
91118
couchbase::cluster::connect(connection_string, cluster_options).get();
92119
if (connect_err) {
93-
94120
fail(fmt::format(
95121
"Failed to connect to the cluster at \"{}\": {}", connection_string, connect_err));
96122
}

0 commit comments

Comments
 (0)