Skip to content

Commit

Permalink
adds configuration entry point for telemetry metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
GustavoCaso committed Oct 27, 2023
1 parent e38c8b5 commit 1cdfec3
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 22 deletions.
3 changes: 3 additions & 0 deletions lib/datadog/core/configuration/components.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,16 @@ def build_runtime_metrics_worker(settings)

def build_telemetry(settings, agent_settings, logger)
enabled = settings.telemetry.enabled
metrics_enabled = settings.telemetry.metrics

if agent_settings.adapter != Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER
enabled = false
logger.debug { "Telemetry disabled. Agent network adapter not supported: #{agent_settings.adapter}" }
end

Telemetry::Client.new(
enabled: enabled,
metrics_enabled: metrics_enabled,
heartbeat_interval_seconds: settings.telemetry.heartbeat_interval_seconds
)
end
Expand Down
16 changes: 16 additions & 0 deletions lib/datadog/core/configuration/settings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,22 @@ def initialize(*_)
o.type :bool
end

option :metrics do |o|
o.env Core::Telemetry::Ext::ENV_METRICS_ENABLED
o.default do
if Datadog::Core::Environment::Execution.development?
Datadog.logger.debug do
'Development environment detected, disabling Telemetry. ' \
'You can enable it with DD_TELEMETRY_METRICS_ENABLED=true.'
end
false
else
true
end
end
o.type :bool
end

# The interval in seconds when telemetry must be sent.
#
# This method is used internally, for testing purposes only.
Expand Down
17 changes: 10 additions & 7 deletions lib/datadog/core/telemetry/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class Client
attr_reader \
:emitter,
:enabled,
:metrics_enabled,
:unsupported,
:worker,
:metrics_worker
Expand All @@ -23,8 +24,9 @@ class Client

# @param enabled [Boolean] Determines whether telemetry events should be sent to the API
# @param heartbeat_interval_seconds [Float] How frequently heartbeats will be reported, in seconds.
def initialize(heartbeat_interval_seconds:, enabled: true)
def initialize(heartbeat_interval_seconds:, metrics_enabled:, enabled: true)
@enabled = enabled
@metrics_enabled = metrics_enabled
@emitter = Emitter.new
@stopped = false
@unsupported = false
Expand All @@ -37,7 +39,7 @@ def initialize(heartbeat_interval_seconds:, enabled: true)
@metric_queue = MetricQueue.new

@metrics_worker = Telemetry::MetricWorker.new(
enabled: @enabled,
enabled: @metrics_enabled,
heartbeat_interval_seconds: heartbeat_interval_seconds
) do
flush_metrics!
Expand All @@ -46,6 +48,7 @@ def initialize(heartbeat_interval_seconds:, enabled: true)

def disable!
@enabled = false
@metrics_enabled = false
@worker.enabled = false
@metrics_worker.enabled = false
end
Expand Down Expand Up @@ -92,25 +95,25 @@ def client_configuration_change!(changes)
end

def add_count_metric(namespace, name, value, tags)
return if !@enabled || forked?
return if !@metrics_enabled || forked?

@metric_queue.add_metric(namespace, name, value, tags, Metric::Count)
end

def add_rate_metric(namespace, name, value, tags)
return if !@enabled || forked?
return if !@metrics_enabled || forked?

@metric_queue.add_metric(namespace, name, value, tags, Metric::Rate)
end

def add_gauge_metric(namespace, name, value, tags)
return if !@enabled || forked?
return if !@metrics_enabled || forked?

@metric_queue.add_metric(namespace, name, value, tags, Metric::Gauge)
end

def add_distribution_metric(namespace, name, value, tags)
return if !@enabled || forked?
return if !@metrics_enabled || forked?

@metric_queue.add_metric(namespace, name, value, tags, Metric::Distribution)
end
Expand All @@ -124,7 +127,7 @@ def heartbeat!
end

def flush_metrics!
return if !@enabled || forked?
return if !@metrics_enabled || forked?

# Send metrics
@metric_queue.build_metrics_payload do |metric_type, payload|
Expand Down
1 change: 1 addition & 0 deletions lib/datadog/core/telemetry/ext.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module Core
module Telemetry
module Ext
ENV_ENABLED = 'DD_INSTRUMENTATION_TELEMETRY_ENABLED'
ENV_METRICS_ENABLED = 'DD_TELEMETRY_METRICS_ENABLED'
ENV_HEARTBEAT_INTERVAL = 'DD_TELEMETRY_HEARTBEAT_INTERVAL'
end
end
Expand Down
30 changes: 24 additions & 6 deletions sig/datadog/core/telemetry/client.rbs
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
module Datadog
module Core
module Telemetry
# Telemetry entrypoint, coordinates sending telemetry events at various points in app lifecycle.
class Client
attr_reader emitter: untyped
@metric_queue: untyped

attr_reader enabled: untyped
attr_reader emitter: Core::Telemetry::Emitter

attr_reader unsupported: untyped
attr_reader enabled: boolean

attr_reader metrics_enabled: boolean

attr_reader unsupported: boolean

attr_reader worker: untyped

attr_reader metrics_worker: untyped

include Core::Utils::Forking
def initialize: (?enabled: bool) -> void

def disable!: () -> untyped
def initialize: (heartbeat_interval_seconds: untyped, metrics_enabled: boolean, ?enabled: bool) -> void

def client_configuration_change!: (Enumerable[[String, Numeric | bool | String]] changes) -> void
def disable!: () -> untyped

def started!: () -> (nil | untyped)

Expand All @@ -25,9 +31,21 @@ module Datadog

def integrations_change!: () -> (nil | untyped)

def client_configuration_change!: (untyped changes) -> (nil | untyped)

def add_count_metric: (untyped namespace, untyped name, untyped value, untyped tags) -> (nil | untyped)

def add_rate_metric: (untyped namespace, untyped name, untyped value, untyped tags) -> (nil | untyped)

def add_gauge_metric: (untyped namespace, untyped name, untyped value, untyped tags) -> (nil | untyped)

def add_distribution_metric: (untyped namespace, untyped name, untyped value, untyped tags) -> (nil | untyped)

private

def heartbeat!: () -> (nil | untyped)

def flush_metrics!: () -> (nil | untyped)
end
end
end
Expand Down
9 changes: 7 additions & 2 deletions spec/datadog/core/configuration/components_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,11 @@

context 'given settings' do
let(:telemetry_client) { instance_double(Datadog::Core::Telemetry::Client) }
let(:expected_options) { { enabled: enabled, heartbeat_interval_seconds: heartbeat_interval_seconds } }
let(:expected_options) do
{ enabled: enabled, metrics_enabled: metrics_enabled, heartbeat_interval_seconds: heartbeat_interval_seconds }
end
let(:enabled) { true }
let(:metrics_enabled) { true }
let(:heartbeat_interval_seconds) { 60 }

before do
Expand All @@ -239,7 +242,9 @@
it { is_expected.to be(telemetry_client) }

context 'and :unix agent adapter' do
let(:expected_options) { { enabled: false, heartbeat_interval_seconds: heartbeat_interval_seconds } }
let(:expected_options) do
{ enabled: false, metrics_enabled: metrics_enabled, heartbeat_interval_seconds: heartbeat_interval_seconds }
end
let(:agent_settings) do
instance_double(Datadog::Core::Configuration::AgentSettingsResolver::AgentSettings, adapter: :unix)
end
Expand Down
41 changes: 41 additions & 0 deletions spec/datadog/core/configuration/settings_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1208,6 +1208,47 @@
end
end

describe '#metrics' do
subject(:metrics) { settings.telemetry.metrics }
let(:env_var_name) { 'DD_TELEMETRY_METRICS_ENABLED' }

context 'when DD_TELEMETRY_METRICS_ENABLED' do
context 'is not defined' do
let(:env_var_value) { nil }

context 'in a development environment' do
it { is_expected.to be false }
end

context 'not in a development environment' do
include_context 'non-development execution environment'

it { is_expected.to be true }
end
end

[true, false].each do |value|
context "is defined as #{value}" do
let(:env_var_value) { value.to_s }

it { is_expected.to be value }
end
end
end
end

describe '#metrics=' do
let(:env_var_name) { 'DD_TELEMETRY_METRICS_ENABLED' }
let(:env_var_value) { 'true' }

it 'updates the #metrics setting' do
expect { settings.telemetry.metrics = false }
.to change { settings.telemetry.metrics }
.from(true)
.to(false)
end
end

describe '#heartbeat_interval' do
subject(:heartbeat_interval_seconds) { settings.telemetry.heartbeat_interval_seconds }
let(:env_var_name) { 'DD_TELEMETRY_HEARTBEAT_INTERVAL' }
Expand Down
33 changes: 26 additions & 7 deletions spec/datadog/core/telemetry/client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@
require 'datadog/core/telemetry/client'

RSpec.describe Datadog::Core::Telemetry::Client do
subject(:client) { described_class.new(enabled: enabled, heartbeat_interval_seconds: heartbeat_interval_seconds) }
subject(:client) do
described_class.new(
enabled: enabled,
metrics_enabled: metrics_enabled,
heartbeat_interval_seconds: heartbeat_interval_seconds
)
end
let(:enabled) { true }
let(:metrics_enabled) { true }
let(:heartbeat_interval_seconds) { 1.3 }
let(:emitter) { double(Datadog::Core::Telemetry::Emitter) }
let(:response) { double(Datadog::Core::Telemetry::Http::Adapters::Net::Response) }
Expand All @@ -25,7 +32,9 @@
end

context 'with default parameters' do
subject(:client) { described_class.new(heartbeat_interval_seconds: heartbeat_interval_seconds) }
subject(:client) do
described_class.new(heartbeat_interval_seconds: heartbeat_interval_seconds, metrics_enabled: metrics_enabled)
end
it { is_expected.to be_a_kind_of(described_class) }
it { expect(client.enabled).to be(true) }
it { expect(client.emitter).to be(emitter) }
Expand All @@ -41,7 +50,6 @@
it { is_expected.to be_a_kind_of(described_class) }
it { expect(client.enabled).to be(false) }
it { expect(client.worker.enabled?).to be(false) }
it { expect(client.metrics_worker.enabled?).to be(false) }
end

context 'when enabled' do
Expand All @@ -50,6 +58,17 @@
it { is_expected.to be_a_kind_of(described_class) }
it { expect(client.enabled).to be(true) }
it { expect(client.worker.enabled?).to be(true) }
end

context 'when metrics is disabled' do
let(:metrics_enabled) { false }

it { expect(client.metrics_worker.enabled?).to be(false) }
end

context 'when metrics is enabled' do
let(:metrics_enabled) { true }

it { expect(client.metrics_worker.enabled?).to be(true) }
end
end
Expand Down Expand Up @@ -312,14 +331,14 @@
[:add_distribution_metric, Datadog::Core::Telemetry::Metric::Distribution],
].each do |metric_method, metric_klass|
context 'when disabled' do
let(:enabled) { false }
let(:metrics_enabled) { false }
it do
expect(client.send(metric_method, 'test_namespace', 'name', 1, {})).to be_nil
end
end

context 'when enabled' do
let(:enabled) { true }
let(:metrics_enabled) { true }
it do
expect_any_instance_of(Datadog::Core::Telemetry::MetricQueue).to receive(:add_metric).with(
'test_namespace',
Expand All @@ -342,14 +361,14 @@
end

context 'when disabled' do
let(:enabled) { false }
let(:metrics_enabled) { false }
it do
expect(client.send(:flush_metrics!)).to be_nil
end
end

context 'when enabled' do
let(:enabled) { true }
let(:metrics_enabled) { true }
it 'send metrics to the emitter and reset the metric_queue' do
old_metric_queue = client.instance_variable_get(:@metric_queue)

Expand Down

0 comments on commit 1cdfec3

Please sign in to comment.