Skip to content

Commit c6ca2f0

Browse files
authored
[part 3] refactor!(telemetry): introduce a singleton (#195)
The introduction of a singleton for the telemetry modules allow external usage outside of the tracer API to access the same instance. This change also simplified internal telemetry usage.
1 parent 5013321 commit c6ca2f0

18 files changed

+635
-364
lines changed

BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ cc_library(
55
"src/datadog/telemetry/metrics.cpp",
66
"src/datadog/telemetry/log.h",
77
"src/datadog/telemetry/telemetry.cpp",
8+
"src/datadog/telemetry/telemetry_impl.h",
9+
"src/datadog/telemetry/telemetry_impl.cpp",
810
"src/datadog/baggage.cpp",
911
"src/datadog/base64.cpp",
1012
"src/datadog/cerr_logger.cpp",

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ target_sources(dd_trace_cpp-objects
109109
src/datadog/telemetry/configuration.cpp
110110
src/datadog/telemetry/metrics.cpp
111111
src/datadog/telemetry/telemetry.cpp
112+
src/datadog/telemetry/telemetry_impl.cpp
112113
src/datadog/baggage.cpp
113114
src/datadog/base64.cpp
114115
src/datadog/cerr_logger.cpp

include/datadog/telemetry/metrics.h

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,25 @@ class Metric {
3434
Metric(std::string name, std::string type, std::string scope,
3535
std::vector<std::string> tags, bool common);
3636

37+
Metric(Metric&& rhs)
38+
: name_(std::move(rhs.name_)),
39+
type_(std::move(rhs.type_)),
40+
scope_(std::move(rhs.scope_)),
41+
tags_(std::move(rhs.tags_)) {
42+
rhs.value_.store(value_.exchange(rhs.value_));
43+
}
44+
45+
Metric& operator=(Metric&& rhs) {
46+
if (&rhs != this) {
47+
std::swap(name_, rhs.name_);
48+
std::swap(type_, rhs.type_);
49+
std::swap(scope_, rhs.scope_);
50+
std::swap(tags_, rhs.tags_);
51+
rhs.value_.store(value_.exchange(rhs.value_));
52+
}
53+
return *this;
54+
}
55+
3756
public:
3857
// Accessors for name, type, tags, common and capture_and_reset_value are used
3958
// when producing the JSON message for reporting metrics.
@@ -70,5 +89,58 @@ class GaugeMetric : public Metric {
7089
void sub(uint64_t amount);
7190
};
7291

92+
// This structure contains all the metrics that are exposed by tracer
93+
// telemetry.
94+
struct DefaultMetrics {
95+
struct {
96+
telemetry::CounterMetric spans_created = {
97+
"spans_created", "tracers", {}, true};
98+
telemetry::CounterMetric spans_finished = {
99+
"spans_finished", "tracers", {}, true};
100+
101+
telemetry::CounterMetric trace_segments_created_new = {
102+
"trace_segments_created", "tracers", {"new_continued:new"}, true};
103+
telemetry::CounterMetric trace_segments_created_continued = {
104+
"trace_segments_created", "tracers", {"new_continued:continued"}, true};
105+
telemetry::CounterMetric trace_segments_closed = {
106+
"trace_segments_closed", "tracers", {}, true};
107+
telemetry::CounterMetric baggage_items_exceeded = {
108+
"context_header.truncated",
109+
"tracers",
110+
{{"truncation_reason:baggage_item_count_exceeded"}},
111+
true,
112+
};
113+
telemetry::CounterMetric baggage_bytes_exceeded = {
114+
"context_header.truncated",
115+
"tracers",
116+
{{"truncation_reason:baggage_byte_count_exceeded"}},
117+
true,
118+
};
119+
} tracer;
120+
struct {
121+
telemetry::CounterMetric requests = {
122+
"trace_api.requests", "tracers", {}, true};
123+
124+
telemetry::CounterMetric responses_1xx = {
125+
"trace_api.responses", "tracers", {"status_code:1xx"}, true};
126+
telemetry::CounterMetric responses_2xx = {
127+
"trace_api.responses", "tracers", {"status_code:2xx"}, true};
128+
telemetry::CounterMetric responses_3xx = {
129+
"trace_api.responses", "tracers", {"status_code:3xx"}, true};
130+
telemetry::CounterMetric responses_4xx = {
131+
"trace_api.responses", "tracers", {"status_code:4xx"}, true};
132+
telemetry::CounterMetric responses_5xx = {
133+
"trace_api.responses", "tracers", {"status_code:5xx"}, true};
134+
135+
telemetry::CounterMetric errors_timeout = {
136+
"trace_api.errors", "tracers", {"type:timeout"}, true};
137+
telemetry::CounterMetric errors_network = {
138+
"trace_api.errors", "tracers", {"type:network"}, true};
139+
telemetry::CounterMetric errors_status_code = {
140+
"trace_api.errors", "tracers", {"type:status_code"}, true};
141+
142+
} trace_api;
143+
};
144+
73145
} // namespace telemetry
74146
} // namespace datadog

include/datadog/telemetry/telemetry.h

Lines changed: 66 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -7,143 +7,84 @@
77
#include <datadog/logger.h>
88
#include <datadog/telemetry/configuration.h>
99
#include <datadog/telemetry/metrics.h>
10-
#include <datadog/tracer_signature.h>
1110

1211
#include <memory>
1312
#include <unordered_map>
1413
#include <vector>
1514

16-
namespace datadog {
17-
18-
namespace tracing {
19-
class TracerTelemetry;
20-
} // namespace tracing
21-
22-
namespace telemetry {
23-
24-
/// The telemetry class is responsible for handling internal telemetry data to
15+
/// Telemetry functions are responsibles for handling internal telemetry data to
2516
/// track Datadog product usage. It _can_ collect and report logs and metrics.
2617
///
2718
/// IMPORTANT: This is intended for use only by Datadog Engineers.
28-
class Telemetry final {
29-
// This structure contains all the metrics that are exposed by tracer
30-
// telemetry.
31-
struct {
32-
struct {
33-
telemetry::CounterMetric spans_created = {
34-
"spans_created", "tracers", {}, true};
35-
telemetry::CounterMetric spans_finished = {
36-
"spans_finished", "tracers", {}, true};
37-
38-
telemetry::CounterMetric trace_segments_created_new = {
39-
"trace_segments_created", "tracers", {"new_continued:new"}, true};
40-
telemetry::CounterMetric trace_segments_created_continued = {
41-
"trace_segments_created",
42-
"tracers",
43-
{"new_continued:continued"},
44-
true};
45-
telemetry::CounterMetric trace_segments_closed = {
46-
"trace_segments_closed", "tracers", {}, true};
47-
telemetry::CounterMetric baggage_items_exceeded = {
48-
"context_header.truncated",
49-
"tracers",
50-
{{"truncation_reason:baggage_item_count_exceeded"}},
51-
true,
52-
};
53-
telemetry::CounterMetric baggage_bytes_exceeded = {
54-
"context_header.truncated",
55-
"tracers",
56-
{{"truncation_reason:baggage_byte_count_exceeded"}},
57-
true,
58-
};
59-
} tracer;
60-
struct {
61-
telemetry::CounterMetric requests = {
62-
"trace_api.requests", "tracers", {}, true};
63-
64-
telemetry::CounterMetric responses_1xx = {
65-
"trace_api.responses", "tracers", {"status_code:1xx"}, true};
66-
telemetry::CounterMetric responses_2xx = {
67-
"trace_api.responses", "tracers", {"status_code:2xx"}, true};
68-
telemetry::CounterMetric responses_3xx = {
69-
"trace_api.responses", "tracers", {"status_code:3xx"}, true};
70-
telemetry::CounterMetric responses_4xx = {
71-
"trace_api.responses", "tracers", {"status_code:4xx"}, true};
72-
telemetry::CounterMetric responses_5xx = {
73-
"trace_api.responses", "tracers", {"status_code:5xx"}, true};
74-
75-
telemetry::CounterMetric errors_timeout = {
76-
"trace_api.errors", "tracers", {"type:timeout"}, true};
77-
telemetry::CounterMetric errors_network = {
78-
"trace_api.errors", "tracers", {"type:network"}, true};
79-
telemetry::CounterMetric errors_status_code = {
80-
"trace_api.errors", "tracers", {"type:status_code"}, true};
81-
82-
} trace_api;
83-
} metrics_;
84-
85-
/// Configuration object containing the validated settings for telemetry
86-
FinalizedConfiguration config_;
87-
/// Shared pointer to the user logger instance.
88-
std::shared_ptr<tracing::Logger> logger_;
89-
std::shared_ptr<tracing::TracerTelemetry> tracer_telemetry_;
90-
std::vector<tracing::EventScheduler::Cancel> tasks_;
91-
tracing::HTTPClient::ResponseHandler telemetry_on_response_;
92-
tracing::HTTPClient::ErrorHandler telemetry_on_error_;
93-
tracing::HTTPClient::URL telemetry_endpoint_;
94-
tracing::TracerSignature tracer_signature_;
95-
std::shared_ptr<tracing::HTTPClient> http_client_;
96-
tracing::Clock clock_;
97-
98-
public:
99-
/// Constructor for the Telemetry class
100-
///
101-
/// @param configuration The finalized configuration settings.
102-
/// @param logger User logger instance.
103-
/// @param metrics A vector user metrics to report.
104-
Telemetry(FinalizedConfiguration configuration,
105-
std::shared_ptr<tracing::Logger> logger,
106-
std::shared_ptr<tracing::HTTPClient> client,
107-
std::vector<std::shared_ptr<Metric>> metrics,
108-
tracing::EventScheduler& scheduler,
109-
tracing::HTTPClient::URL agent_url,
110-
tracing::Clock clock = tracing::default_clock);
111-
112-
/// Destructor
113-
///
114-
/// Send last metrics snapshot and `app-closing` event.
115-
~Telemetry();
116-
117-
// Provides access to the telemetry metrics for updating the values.
118-
// This value should not be stored.
119-
inline auto& metrics() { return metrics_; }
120-
121-
/// Capture and report internal error message to Datadog.
122-
///
123-
/// @param message The error message.
124-
void log_error(std::string message);
125-
126-
/// capture and report internal warning message to Datadog.
127-
///
128-
/// @param message The warning message to log.
129-
void log_warning(std::string message);
19+
namespace datadog::telemetry {
13020

131-
void send_app_started(
132-
const std::unordered_map<tracing::ConfigName, tracing::ConfigMetadata>&
133-
config_metadata);
21+
/// Initialize the telemetry module
22+
/// Once initialized, the telemetry module is running for the entier lifecycle
23+
/// of the application.
24+
///
25+
/// @param configuration The finalized configuration settings.
26+
/// @param logger User logger instance.
27+
/// @param metrics A vector user metrics to report.
28+
///
29+
/// NOTE: Make sure to call `init` before calling any of the other telemetry
30+
/// functions.
31+
void init(FinalizedConfiguration configuration,
32+
std::shared_ptr<tracing::Logger> logger,
33+
std::shared_ptr<tracing::HTTPClient> client,
34+
std::vector<std::shared_ptr<Metric>> metrics,
35+
std::shared_ptr<tracing::EventScheduler> event_scheduler,
36+
tracing::HTTPClient::URL agent_url,
37+
tracing::Clock clock = tracing::default_clock);
38+
39+
/// Sends a notification indicating that the application has started.
40+
///
41+
/// This function is responsible for reporting the application has successfully
42+
/// started. It takes a configuration map as a parameter, which contains various
43+
/// configuration settings helping to understand how our product are used.
44+
///
45+
/// @param conf A map containing configuration names and their corresponding
46+
/// metadata.
47+
///
48+
/// @note This function should be called after the application has completed its
49+
/// initialization process to ensure that all components are aware of the
50+
/// application's startup status.
51+
void send_app_started(const std::unordered_map<tracing::ConfigName,
52+
tracing::ConfigMetadata>& conf);
13453

135-
void send_configuration_change();
54+
/// Sends configuration changes.
55+
///
56+
/// This function is responsible for sending reported configuration changes
57+
/// reported by `capture_configuration_change`.
58+
///
59+
/// @note This function should be called _AFTER_ all configuration changes are
60+
/// captures by `capture_configuration_change`.
61+
void send_configuration_change();
13662

137-
void capture_configuration_change(
138-
const std::vector<tracing::ConfigMetadata>& new_configuration);
63+
/// Captures a change in the application's configuration.
64+
///
65+
/// This function is called to report updates to the application's
66+
/// configuration. It takes a vector of new configuration metadata as a
67+
/// parameter, which contains the updated settings.
68+
///
69+
/// @param new_configuration A vector containing the new configuration metadata.
70+
///
71+
/// @note This function should be invoked whenever there is a change in the
72+
/// configuration.
73+
void capture_configuration_change(
74+
const std::vector<tracing::ConfigMetadata>& new_configuration);
13975

140-
void send_app_closing();
76+
/// Provides access to the telemetry metrics for updating the values.
77+
/// This value should not be stored.
78+
DefaultMetrics& metrics();
14179

142-
private:
143-
void send_telemetry(tracing::StringView request_type, std::string payload);
80+
/// Report internal warning message to Datadog.
81+
///
82+
/// @param message The warning message to log.
83+
void report_warning_log(std::string message);
14484

145-
void send_heartbeat_and_telemetry();
146-
};
85+
/// Report internal error message to Datadog.
86+
///
87+
/// @param message The error message.
88+
void report_error_log(std::string message);
14789

148-
} // namespace telemetry
149-
} // namespace datadog
90+
} // namespace datadog::telemetry

include/datadog/trace_segment.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ class TraceSegment {
6161

6262
std::shared_ptr<Logger> logger_;
6363
std::shared_ptr<Collector> collector_;
64-
std::shared_ptr<telemetry::Telemetry> telemetry_;
6564
std::shared_ptr<TraceSampler> trace_sampler_;
6665
std::shared_ptr<SpanSampler> span_sampler_;
6766

@@ -84,7 +83,6 @@ class TraceSegment {
8483
public:
8584
TraceSegment(const std::shared_ptr<Logger>& logger,
8685
const std::shared_ptr<Collector>& collector,
87-
const std::shared_ptr<telemetry::Telemetry>& telemetry,
8886
const std::shared_ptr<TraceSampler>& trace_sampler,
8987
const std::shared_ptr<SpanSampler>& span_sampler,
9088
const std::shared_ptr<const SpanDefaults>& defaults,

include/datadog/tracer.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
// obtained from a `TracerConfig` via the `finalize_config` function. See
1111
// `tracer_config.h`.
1212

13-
#include <datadog/telemetry/telemetry.h>
14-
1513
#include <cstddef>
1614
#include <memory>
1715

@@ -28,7 +26,6 @@
2826
namespace datadog {
2927
namespace tracing {
3028

31-
class TracerTelemetry;
3229
class ConfigManager;
3330
class DictReader;
3431
struct SpanConfig;
@@ -41,7 +38,6 @@ class Tracer {
4138
std::shared_ptr<Logger> logger_;
4239
RuntimeID runtime_id_;
4340
TracerSignature signature_;
44-
std::shared_ptr<telemetry::Telemetry> telemetry_;
4541
std::shared_ptr<ConfigManager> config_manager_;
4642
std::shared_ptr<Collector> collector_;
4743
std::shared_ptr<SpanSampler> span_sampler_;

src/datadog/config_manager.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "config_manager.h"
22

3+
#include <datadog/telemetry/telemetry.h>
4+
35
#include "json_serializer.h"
46
#include "parse_util.h"
57
#include "string_util.h"
@@ -123,17 +125,14 @@ ConfigManager::Update parse_dynamic_config(const nlohmann::json& j) {
123125

124126
namespace rc = datadog::remote_config;
125127

126-
ConfigManager::ConfigManager(
127-
const FinalizedTracerConfig& config,
128-
const std::shared_ptr<telemetry::Telemetry>& telemetry)
128+
ConfigManager::ConfigManager(const FinalizedTracerConfig& config)
129129
: clock_(config.clock),
130130
default_metadata_(config.metadata),
131131
trace_sampler_(
132132
std::make_shared<TraceSampler>(config.trace_sampler, clock_)),
133133
rules_(config.trace_sampler.rules),
134134
span_defaults_(std::make_shared<SpanDefaults>(config.defaults)),
135-
report_traces_(config.report_traces),
136-
telemetry_(telemetry) {}
135+
report_traces_(config.report_traces) {}
137136

138137
rc::Products ConfigManager::get_products() { return rc::product::APM_TRACING; }
139138

@@ -153,15 +152,15 @@ Optional<std::string> ConfigManager::on_update(const Configuration& config) {
153152
auto config_update = parse_dynamic_config(config_json.at("lib_config"));
154153

155154
auto config_metadata = apply_update(config_update);
156-
telemetry_->capture_configuration_change(config_metadata);
155+
telemetry::capture_configuration_change(config_metadata);
157156

158157
// TODO:
159158
return nullopt;
160159
}
161160

162161
void ConfigManager::on_revert(const Configuration&) {
163162
auto config_metadata = apply_update({});
164-
telemetry_->capture_configuration_change(config_metadata);
163+
telemetry::capture_configuration_change(config_metadata);
165164
}
166165

167166
std::shared_ptr<TraceSampler> ConfigManager::trace_sampler() {

0 commit comments

Comments
 (0)