class Datadog::Metrics

Acts as client for sending metrics (via Statsd) Wraps a Statsd client with default tags and additional configuration.

Constants

IGNORED_STATSD_ONLY_ONCE
Metric

Attributes

statsd[R]

Public Class Methods

new(statsd: nil, enabled: true, **_) click to toggle source
# File lib/ddtrace/metrics.rb, line 17
def initialize(statsd: nil, enabled: true, **_)
  @statsd =
    if supported?
      statsd || default_statsd_client
    else
      ignored_statsd_warning if statsd
      nil
    end
  @enabled = enabled
end

Public Instance Methods

close() click to toggle source
# File lib/ddtrace/metrics.rb, line 148
def close
  @statsd.close if @statsd && @statsd.respond_to?(:close)
end
configure(options = {}) click to toggle source
# File lib/ddtrace/metrics.rb, line 75
def configure(options = {})
  @statsd = options[:statsd] if options.key?(:statsd)
  self.enabled = options[:enabled] if options.key?(:enabled)
end
count(stat, value = nil, options = nil) { || ... } click to toggle source
# File lib/ddtrace/metrics.rb, line 84
def count(stat, value = nil, options = nil, &block)
  return unless send_stats? && statsd.respond_to?(:count)

  value, options = yield if block
  raise ArgumentError if value.nil?

  statsd.count(stat, value, metric_options(options))
rescue StandardError => e
  Datadog.logger.error("Failed to send count stat. Cause: #{e.message} Source: #{Array(e.backtrace).first}")
end
default_hostname() click to toggle source
# File lib/ddtrace/metrics.rb, line 45
def default_hostname
  ENV.fetch(Datadog::Ext::Metrics::ENV_DEFAULT_HOST, Datadog::Ext::Metrics::DEFAULT_HOST)
end
default_port() click to toggle source
# File lib/ddtrace/metrics.rb, line 49
def default_port
  ENV.fetch(Datadog::Ext::Metrics::ENV_DEFAULT_PORT, Datadog::Ext::Metrics::DEFAULT_PORT).to_i
end
default_statsd_client() click to toggle source
# File lib/ddtrace/metrics.rb, line 53
def default_statsd_client
  require 'datadog/statsd'

  # Create a StatsD client that points to the agent.
  #
  # We use `single_thread: true`, as dogstatsd-ruby >= 5.0 creates a background thread
  # by default, but does not handle forks correctly, causing resource leaks.
  #
  # Using dogstatsd-ruby >= 5.0 is still valuable, as it supports
  # transparent batch metric submission, which reduces submission
  # overhead.
  #
  # Versions < 5.0 are always single-threaded, but do not have the kwarg option.
  options = if dogstatsd_version >= Gem::Version.new('5.2')
              { single_thread: true }
            else
              {}
            end

  Datadog::Statsd.new(default_hostname, default_port, **options)
end
distribution(stat, value = nil, options = nil) { || ... } click to toggle source
# File lib/ddtrace/metrics.rb, line 95
def distribution(stat, value = nil, options = nil, &block)
  return unless send_stats? && statsd.respond_to?(:distribution)

  value, options = yield if block
  raise ArgumentError if value.nil?

  statsd.distribution(stat, value, metric_options(options))
rescue StandardError => e
  Datadog.logger.error("Failed to send distribution stat. Cause: #{e.message} Source: #{Array(e.backtrace).first}")
end
enabled=(enabled) click to toggle source
# File lib/ddtrace/metrics.rb, line 41
def enabled=(enabled)
  @enabled = (enabled == true)
end
enabled?() click to toggle source
# File lib/ddtrace/metrics.rb, line 37
def enabled?
  @enabled
end
gauge(stat, value = nil, options = nil) { || ... } click to toggle source
# File lib/ddtrace/metrics.rb, line 116
def gauge(stat, value = nil, options = nil, &block)
  return unless send_stats? && statsd.respond_to?(:gauge)

  value, options = yield if block
  raise ArgumentError if value.nil?

  statsd.gauge(stat, value, metric_options(options))
rescue StandardError => e
  Datadog.logger.error("Failed to send gauge stat. Cause: #{e.message} Source: #{Array(e.backtrace).first}")
end
increment(stat, options = nil) { || ... } click to toggle source
# File lib/ddtrace/metrics.rb, line 106
def increment(stat, options = nil)
  return unless send_stats? && statsd.respond_to?(:increment)

  options = yield if block_given?

  statsd.increment(stat, metric_options(options))
rescue StandardError => e
  Datadog.logger.error("Failed to send increment stat. Cause: #{e.message} Source: #{Array(e.backtrace).first}")
end
send_metrics(metrics) click to toggle source
# File lib/ddtrace/metrics.rb, line 144
def send_metrics(metrics)
  metrics.each { |m| send(m.type, *[m.name, m.value, m.options].compact) }
end
send_stats?() click to toggle source
# File lib/ddtrace/metrics.rb, line 80
def send_stats?
  enabled? && !statsd.nil?
end
supported?() click to toggle source
# File lib/ddtrace/metrics.rb, line 28
def supported?
  version = dogstatsd_version

  !version.nil? && version >= Gem::Version.new('3.3.0') &&
    # dogstatsd-ruby >= 5.0 & < 5.2.0 has known issues with process forks
    # and do not support the single thread mode we use to avoid this problem.
    !(version >= Gem::Version.new('5.0') && version < Gem::Version.new('5.2'))
end
time(stat, options = nil) { || ... } click to toggle source
# File lib/ddtrace/metrics.rb, line 127
def time(stat, options = nil)
  return yield unless send_stats?

  # Calculate time, send it as a distribution.
  start = Utils::Time.get_time
  yield
ensure
  begin
    if send_stats? && !start.nil?
      finished = Utils::Time.get_time
      distribution(stat, ((finished - start) * 1000), options)
    end
  rescue StandardError => e
    Datadog.logger.error("Failed to send time stat. Cause: #{e.message} Source: #{Array(e.backtrace).first}")
  end
end

Private Instance Methods

dogstatsd_version() click to toggle source
# File lib/ddtrace/metrics.rb, line 257
def dogstatsd_version
  return @dogstatsd_version if instance_variable_defined?(:@dogstatsd_version)

  @dogstatsd_version = (
    defined?(Datadog::Statsd::VERSION) &&
      Datadog::Statsd::VERSION &&
      Gem::Version.new(Datadog::Statsd::VERSION)
  ) || (
    Gem.loaded_specs['dogstatsd-ruby'] &&
      Gem.loaded_specs['dogstatsd-ruby'].version
  )
end
ignored_statsd_warning() click to toggle source
# File lib/ddtrace/metrics.rb, line 273
def ignored_statsd_warning
  IGNORED_STATSD_ONLY_ONCE.run do
    Datadog.logger.warn(
      'Ignoring user-supplied statsd instance as currently-installed version of dogstastd-ruby is incompatible. ' \
      "To fix this, ensure that you have `gem 'dogstatsd-ruby', '~> 5.2'` on your Gemfile or gems.rb file."
    )
  end
end