-
Notifications
You must be signed in to change notification settings - Fork 375
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3742 from DataDog/anmarchenko/metrics_collection
[SDTEST-409] Add metrics management capabilities
- Loading branch information
Showing
9 changed files
with
918 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
# frozen_string_literal: true | ||
|
||
require_relative 'event' | ||
require_relative 'metric' | ||
|
||
module Datadog | ||
module Core | ||
module Telemetry | ||
# MetricsCollection is a thread-safe collection of metrics per namespace | ||
class MetricsCollection | ||
attr_reader :namespace, :interval | ||
|
||
def initialize(namespace, aggregation_interval:) | ||
@namespace = namespace | ||
@interval = aggregation_interval | ||
|
||
@mutex = Mutex.new | ||
|
||
@metrics = {} | ||
@distributions = {} | ||
end | ||
|
||
def inc(metric_name, value, tags: {}, common: true) | ||
metric = Metric::Count.new(metric_name, tags: tags, common: common) | ||
fetch_or_add_metric(metric, value) | ||
end | ||
|
||
def dec(metric_name, value, tags: {}, common: true) | ||
metric = Metric::Count.new(metric_name, tags: tags, common: common) | ||
fetch_or_add_metric(metric, -value) | ||
end | ||
|
||
def gauge(metric_name, value, tags: {}, common: true) | ||
metric = Metric::Gauge.new(metric_name, tags: tags, common: common, interval: @interval) | ||
fetch_or_add_metric(metric, value) | ||
end | ||
|
||
def rate(metric_name, value, tags: {}, common: true) | ||
metric = Metric::Rate.new(metric_name, tags: tags, common: common, interval: @interval) | ||
fetch_or_add_metric(metric, value) | ||
end | ||
|
||
def distribution(metric_name, value, tags: {}, common: true) | ||
metric = Metric::Distribution.new(metric_name, tags: tags, common: common) | ||
fetch_or_add_distribution(metric, value) | ||
end | ||
|
||
def flush!(queue) | ||
@mutex.synchronize do | ||
queue.enqueue(Event::GenerateMetrics.new(@namespace, @metrics.values)) if @metrics.any? | ||
queue.enqueue(Event::Distributions.new(@namespace, @distributions.values)) if @distributions.any? | ||
|
||
@metrics = {} | ||
@distributions = {} | ||
end | ||
nil | ||
end | ||
|
||
private | ||
|
||
def fetch_or_add_metric(metric, value) | ||
@mutex.synchronize do | ||
m = (@metrics[metric.id] ||= metric) | ||
m.track(value) | ||
end | ||
nil | ||
end | ||
|
||
def fetch_or_add_distribution(metric, value) | ||
@mutex.synchronize do | ||
m = (@distributions[metric.id] ||= metric) | ||
m.track(value) | ||
end | ||
nil | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
# frozen_string_literal: true | ||
|
||
require_relative 'metrics_collection' | ||
|
||
module Datadog | ||
module Core | ||
module Telemetry | ||
# MetricsManager aggregates and flushes metrics and distributions | ||
class MetricsManager | ||
attr_reader :enabled | ||
|
||
def initialize(aggregation_interval:, enabled:) | ||
@interval = aggregation_interval | ||
@enabled = enabled | ||
@mutex = Mutex.new | ||
|
||
@collections = {} | ||
end | ||
|
||
def inc(namespace, metric_name, value, tags: {}, common: true) | ||
return unless @enabled | ||
|
||
# collection is thread-safe internally | ||
collection = fetch_or_create_collection(namespace) | ||
collection.inc(metric_name, value, tags: tags, common: common) | ||
end | ||
|
||
def dec(namespace, metric_name, value, tags: {}, common: true) | ||
return unless @enabled | ||
|
||
# collection is thread-safe internally | ||
collection = fetch_or_create_collection(namespace) | ||
collection.dec(metric_name, value, tags: tags, common: common) | ||
end | ||
|
||
def gauge(namespace, metric_name, value, tags: {}, common: true) | ||
return unless @enabled | ||
|
||
# collection is thread-safe internally | ||
collection = fetch_or_create_collection(namespace) | ||
collection.gauge(metric_name, value, tags: tags, common: common) | ||
end | ||
|
||
def rate(namespace, metric_name, value, tags: {}, common: true) | ||
return unless @enabled | ||
|
||
# collection is thread-safe internally | ||
collection = fetch_or_create_collection(namespace) | ||
collection.rate(metric_name, value, tags: tags, common: common) | ||
end | ||
|
||
def distribution(namespace, metric_name, value, tags: {}, common: true) | ||
return unless @enabled | ||
|
||
# collection is thread-safe internally | ||
collection = fetch_or_create_collection(namespace) | ||
collection.distribution(metric_name, value, tags: tags, common: common) | ||
end | ||
|
||
def flush!(queue) | ||
return unless @enabled | ||
|
||
collections = @mutex.synchronize { @collections.values } | ||
collections.each { |col| col.flush!(queue) } | ||
|
||
nil | ||
end | ||
|
||
def disable! | ||
@enabled = false | ||
end | ||
|
||
private | ||
|
||
def fetch_or_create_collection(namespace) | ||
@mutex.synchronize do | ||
@collections[namespace] ||= MetricsCollection.new(namespace, aggregation_interval: @interval) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.