Skip to content

Commit

Permalink
Telemetry::Component API for tracking metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
anmarchenko committed Jul 9, 2024
1 parent aa5e328 commit 593f9aa
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 8 deletions.
61 changes: 61 additions & 0 deletions lib/datadog/core/telemetry/component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require_relative 'emitter'
require_relative 'event'
require_relative 'metrics_manager'
require_relative 'worker'
require_relative '../utils/forking'

Expand Down Expand Up @@ -29,6 +30,11 @@ def initialize(
@enabled = enabled
@stopped = false

@metrics_manager = MetricsManager.new(
enabled: enabled && metrics_enabled,
aggregation_interval: metrics_aggregation_interval_seconds
)

@worker = Telemetry::Worker.new(
enabled: @enabled,
heartbeat_interval_seconds: heartbeat_interval_seconds,
Expand Down Expand Up @@ -69,6 +75,61 @@ def client_configuration_change!(changes)

@worker.enqueue(Event::AppClientConfigurationChange.new(changes, 'remote_config'))
end

# Increments a count metric.
# @param namespace [String] metric namespace (per product, such as 'civisibility', 'tracers', 'profilers')
# @param metric_name [String] metric name
# @param value [Float] metric value
# @param tags [Array<String>|Hash{String=>String}] metric tags as hash of tag:value pairs or array of "tag:val"
# strings
# @param common [Boolean] true if the metric is common for all languages, false for Ruby-specific metric
def inc(namespace, metric_name, value, tags: {}, common: true)
@metrics_manager.inc(namespace, metric_name, value, tags: tags, common: common)
end

# Decremenets a count metric.
# @param namespace [String] metric namespace (per product, such as 'civisibility', 'tracers', 'profilers')
# @param metric_name [String] metric name
# @param value [Float] metric value
# @param tags [Array<String>|Hash{String=>String}] metric tags as hash of tag:value pairs or array of "tag:val"
# strings
# @param common [Boolean] true if the metric is common for all languages, false for Ruby-specific metric
def dec(namespace, metric_name, value, tags: {}, common: true)
@metrics_manager.dec(namespace, metric_name, value, tags: tags, common: common)
end

# Tracks gauge metric.
# @param namespace [String] metric namespace (per product, such as 'civisibility', 'tracers', 'profilers')
# @param metric_name [String] metric name
# @param value [Float] metric value
# @param tags [Array<String>|Hash{String=>String}] metric tags as hash of tag:value pairs or array of "tag:val"
# strings
# @param common [Boolean] true if the metric is common for all languages, false for Ruby-specific metric
def gauge(namespace, metric_name, value, tags: {}, common: true)
@metrics_manager.gauge(namespace, metric_name, value, tags: tags, common: common)
end

# Tracks rate metric.
# @param namespace [String] metric namespace (per product, such as 'civisibility', 'tracers', 'profilers')
# @param metric_name [String] metric name
# @param value [Float] metric value
# @param tags [Array<String>|Hash{String=>String}] metric tags as hash of tag:value pairs or array of "tag:val"
# strings
# @param common [Boolean] true if the metric is common for all languages, false for Ruby-specific metric
def rate(namespace, metric_name, value, tags: {}, common: true)
@metrics_manager.rate(namespace, metric_name, value, tags: tags, common: common)
end

# Tracks distribution metric.
# @param namespace [String] metric namespace (per product, such as 'civisibility', 'tracers', 'profilers')
# @param metric_name [String] metric name
# @param value [Float] metric value
# @param tags [Array<String>|Hash{String=>String}] metric tags as hash of tag:value pairs or array of "tag:val"
# strings
# @param common [Boolean] true if the metric is common for all languages, false for Ruby-specific metric
def distribution(namespace, metric_name, value, tags: {}, common: true)
@metrics_manager.distribution(namespace, metric_name, value, tags: tags, common: common)
end
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/datadog/core/telemetry/metric.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Base
attr_reader :name, :tags, :values, :common

# @param name [String] metric name
# @param tags [Array<String>|Hash{String=>String}] metric tags as hash of array of "tag:val" strings
# @param tags [Array<String>|Hash{String=>String}] metric tags as hash or array of "tag:val" strings
# @param common [Boolean] true if the metric is common for all languages, false for Ruby-specific metric
def initialize(name, tags: {}, common: true)
@name = name
Expand Down
1 change: 1 addition & 0 deletions sig/datadog/core/telemetry/component.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ module Datadog
class Component
@enabled: bool
@stopped: bool
@metrics_manager: Datadog::Core::Telemetry::MetricsManager
@worker: Datadog::Core::Telemetry::Worker

attr_reader enabled: bool
Expand Down
6 changes: 3 additions & 3 deletions sig/datadog/core/telemetry/metric.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,11 @@ module Datadog
end

class IntervalMetric < Base
@interval: Integer
@interval: Float

attr_reader interval: Integer
attr_reader interval: Float

def initialize: (String name, ?tags: tags_input, ?common: bool, interval: Integer) -> void
def initialize: (String name, ?tags: tags_input, ?common: bool, interval: Float) -> void
end

class Count < Base
Expand Down
4 changes: 2 additions & 2 deletions sig/datadog/core/telemetry/metrics_collection.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module Datadog

@namespace: String

@interval: Integer
@interval: Float

@mutex: Thread::Mutex

Expand All @@ -18,7 +18,7 @@ module Datadog

attr_reader namespace: String

def initialize: (String namespace, aggregation_interval: Integer) -> void
def initialize: (String namespace, aggregation_interval: Float) -> void

def inc: (String metric_name, Datadog::Core::Telemetry::Metric::input_value value, ?tags: Datadog::Core::Telemetry::Metric::tags_input, ?common: bool) -> void

Expand Down
4 changes: 2 additions & 2 deletions sig/datadog/core/telemetry/metrics_manager.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module Datadog
def enqueue: (Datadog::Core::Telemetry::Event::Base event) -> void
end

@interval: Integer
@interval: Float

@enabled: bool

Expand All @@ -16,7 +16,7 @@ module Datadog

attr_reader enabled: bool

def initialize: (aggregation_interval: Integer, enabled: bool) -> void
def initialize: (aggregation_interval: Float, enabled: bool) -> void

def inc: (String namespace, String metric_name, Datadog::Core::Telemetry::Metric::input_value value, ?tags: Datadog::Core::Telemetry::Metric::tags_input, ?common: bool) -> void

Expand Down
75 changes: 75 additions & 0 deletions spec/datadog/core/telemetry/component_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -210,4 +210,79 @@
end
end
end

context 'metrics support' do
let(:metrics_manager) { spy(:metrics_manager) }
let(:namespace) { double('namespace') }
let(:metric_name) { double('metric_name') }
let(:value) { double('value') }
let(:tags) { double('tags') }
let(:common) { double('common') }
before do
expect(Datadog::Core::Telemetry::MetricsManager).to receive(:new).with(
aggregation_interval: metrics_aggregation_interval_seconds,
enabled: enabled && metrics_enabled
).and_return(metrics_manager)
end

describe '#inc' do
subject(:inc) { telemetry.inc(namespace, metric_name, value, tags: tags, common: common) }

it do
inc

expect(metrics_manager).to have_received(:inc).with(
namespace, metric_name, value, tags: tags, common: common
)
end
end

describe '#dec' do
subject(:dec) { telemetry.dec(namespace, metric_name, value, tags: tags, common: common) }

it do
dec

expect(metrics_manager).to have_received(:dec).with(
namespace, metric_name, value, tags: tags, common: common
)
end
end

describe '#gauge' do
subject(:gauge) { telemetry.gauge(namespace, metric_name, value, tags: tags, common: common) }

it do
gauge

expect(metrics_manager).to have_received(:gauge).with(
namespace, metric_name, value, tags: tags, common: common
)
end
end

describe '#rate' do
subject(:rate) { telemetry.rate(namespace, metric_name, value, tags: tags, common: common) }

it do
rate

expect(metrics_manager).to have_received(:rate).with(
namespace, metric_name, value, tags: tags, common: common
)
end
end

describe '#distribution' do
subject(:distribution) { telemetry.distribution(namespace, metric_name, value, tags: tags, common: common) }

it do
distribution

expect(metrics_manager).to have_received(:distribution).with(
namespace, metric_name, value, tags: tags, common: common
)
end
end
end
end

0 comments on commit 593f9aa

Please sign in to comment.