Skip to content

Commit

Permalink
Refactored: Runtime::Metrics into Metrics class.
Browse files Browse the repository at this point in the history
  • Loading branch information
delner committed Mar 20, 2019
1 parent 50bd8a3 commit 16dac13
Show file tree
Hide file tree
Showing 12 changed files with 234 additions and 78 deletions.
19 changes: 8 additions & 11 deletions docs/GettingStarted.md
Original file line number Diff line number Diff line change
Expand Up @@ -1757,20 +1757,17 @@ If metrics are configured, the trace library will automatically collect and send

These include:

| Name | Type | Description |
| ------------------------------------- | ------- | ---------------------------------- |
| `datadog.tracer.runtime.class_count` | `gauge` | Number of classes in memory space. |
| `datadog.tracer.runtime.heap_size`. | `gauge` | Size of memory heap, in bytes. |
| `datadog.tracer.runtime.thread_count` | `gauge` | Number of threads. |
| Name | Type | Description |
| -------------------------- | ------- | -------------------------------------------------------- |
| `runtime.ruby.class_count` | `gauge` | Number of classes in memory space. |
| `runtime.ruby.thread_count` | `gauge` | Number of threads. |
| `runtime.ruby.gc.*`. | `gauge` | Garbage collection statistics (one per value in GC.stat) |

In addition, all metrics will include the following tags:

| Name | Description |
| --------------------------------- | ------------------------------------------------------------------- |
| `datadog.tracer.lang` | Programming language traced. (e.g. `ruby`) |
| `datadog.tracer.lang_interpreter` | Language interpreter used, if available. (e.g. `ruby-x86_64-linux`) |
| `datadog.tracer.lang_version` | Version of language traced. (e.g. `2.3.7`) |
| `datadog.tracer.version` | Version of tracer library/module. (e.g. `0.16.1` ) |
| Name | Description |
| ---------- | ------------------------------------------ |
| `language` | Programming language traced. (e.g. `ruby`) |

### OpenTracing

Expand Down
4 changes: 4 additions & 0 deletions lib/ddtrace/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ def metrics
configuration.metrics
end

def runtime_metrics
configuration.runtime_metrics
end

def tracer
configuration.tracer
end
Expand Down
11 changes: 11 additions & 0 deletions lib/ddtrace/configuration/settings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class Settings
lazy: true

option :metrics, default: Metrics.new
option :runtime_metrics, default: Runtime::Metrics.new
option :tracer, default: Tracer.new

def initialize(options = {})
Expand All @@ -32,14 +33,24 @@ def configure(options = {})
yield(self) if block_given?
end

remove_method :metrics
def metrics(options = nil)
metrics = get_option(:metrics)
return metrics if options.nil?

metrics.configure(options)
end

remove_method :runtime_metrics
def runtime_metrics(options = nil)
runtime_metrics = get_option(:runtime_metrics)
return runtime_metrics if options.nil?

runtime_metrics.configure(options)
end

# Backwards compatibility for configuring tracer e.g. `c.tracer debug: true`
remove_method :tracer
def tracer(options = nil)
tracer = options && options.key?(:instance) ? set_option(:tracer, options[:instance]) : get_option(:tracer)

Expand Down
13 changes: 10 additions & 3 deletions lib/ddtrace/ext/runtime.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,17 @@ module Runtime
LANG_VERSION = RUBY_VERSION
TRACER_VERSION = Datadog::VERSION::STRING

TAG_LANG = 'language'.freeze
TAG_RUNTIME_ID = 'runtime-id'.freeze

# Metrics
METRIC_CLASS_COUNT = 'datadog.tracer.runtime.class_count'.freeze
METRIC_HEAP_SIZE = 'datadog.tracer.runtime.heap_size'.freeze
METRIC_THREAD_COUNT = 'datadog.tracer.runtime.thread_count'.freeze
module Metrics
METRIC_CLASS_COUNT = 'runtime.ruby.class_count'.freeze
METRIC_GC_PREFIX = 'runtime.ruby.gc'.freeze
METRIC_THREAD_COUNT = 'runtime.ruby.thread_count'.freeze

TAG_SERVICE = 'service'.freeze
end
end
end
end
1 change: 1 addition & 0 deletions lib/ddtrace/metrics.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require 'ddtrace/ext/metrics'

require 'set'
require 'ddtrace/utils/time'
require 'ddtrace/runtime/identity'

Expand Down
16 changes: 16 additions & 0 deletions lib/ddtrace/runtime/gc.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module Datadog
module Runtime
# Retrieves garbage collection statistics
module GC
module_function

def stat
::GC.stat
end

def available?
defined?(::GC) && ::GC.respond_to?(:stat)
end
end
end
end
16 changes: 0 additions & 16 deletions lib/ddtrace/runtime/heap_size.rb

This file was deleted.

82 changes: 74 additions & 8 deletions lib/ddtrace/runtime/metrics.rb
Original file line number Diff line number Diff line change
@@ -1,26 +1,92 @@
require 'ddtrace/ext/runtime'

require 'ddtrace/metrics'
require 'ddtrace/runtime/class_count'
require 'ddtrace/runtime/heap_size'
require 'ddtrace/runtime/gc'
require 'ddtrace/runtime/identity'
require 'ddtrace/runtime/thread_count'

module Datadog
module Runtime
# For generating runtime metrics
module Metrics
module_function
class Metrics < Datadog::Metrics
def initialize(*args)
super

# Initialize service list
@services = Set.new
@service_tags = nil
end

# Flush all runtime metrics to a Datadog::Metrics instance.
def flush(metrics = Datadog.metrics)
try_flush { metrics.gauge(Ext::Runtime::METRIC_CLASS_COUNT, ClassCount.value) if ClassCount.available? }
try_flush { metrics.gauge(Ext::Runtime::METRIC_HEAP_SIZE, HeapSize.value) if HeapSize.available? }
try_flush { metrics.gauge(Ext::Runtime::METRIC_THREAD_COUNT, ThreadCount.value) if ThreadCount.available? }
def associate_with_span(span)
return if span.nil?

# Register service as associated with metrics
register_service(span.service) unless span.service.nil?

# Tag span with language and runtime ID for association with metrics
span.set_metric(Ext::Runtime::TAG_LANG, Runtime::Identity.lang)
span.set_metric(Ext::Runtime::TAG_RUNTIME_ID, Runtime::Identity.id)
end

# Associate service with runtime metrics
def register_service(service)
return if service.nil?

service = service.to_s

unless @services.include?(service)
# Add service to list and update services tag
services << service

# Recompile the service tags
compile_service_tags!
end
end

# Flush all runtime metrics to Statsd client
def flush
try_flush { gauge(Ext::Runtime::Metrics::METRIC_CLASS_COUNT, ClassCount.value) if ClassCount.available? }
try_flush { gauge(Ext::Runtime::Metrics::METRIC_THREAD_COUNT, ThreadCount.value) if ThreadCount.available? }
try_flush { gc_metrics.each { |metric, value| gauge(metric, value) } if GC.available? }
end

def gc_metrics
Hash[
GC.stat.map do |k, v|
["#{Ext::Runtime::Metrics::METRIC_GC_PREFIX}.#{k}", v]
end
]
end

def try_flush
yield
rescue StandardError => e
Datadog::Tracer.log.error("Error while sending runtime metric. Cause: #{e.message}")
end

def default_metric_options
# Return dupes, so that the constant isn't modified,
# and defaults are unfrozen for mutation in Statsd.
super.tap do |options|
options[:tags] = options[:tags].dup

# Add services dynamically because they might change during runtime.
options[:tags].concat(service_tags) unless service_tags.nil?
end
end

private

attr_reader \
:service_tags,
:services

def compile_service_tags!
@service_tags = services.to_a.collect do |service|
"#{Ext::Runtime::Metrics::TAG_SERVICE}:#{service}".freeze
end
end
end
end
end
4 changes: 2 additions & 2 deletions lib/ddtrace/workers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ def callback_services
end

def callback_runtime_metrics
return true unless Datadog.metrics.send_stats?
return true unless Datadog.runtime_metrics.send_stats?

begin
Datadog::Runtime::Metrics.flush(Datadog.metrics)
Datadog.runtime_metrics.flush
rescue StandardError => e
# ensures that the thread will not die because of an exception.
# TODO[manu]: findout the reason and reschedule the send if it's not
Expand Down
16 changes: 16 additions & 0 deletions spec/ddtrace/runtime/gc_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# encoding: utf-8

require 'spec_helper'
require 'ddtrace/runtime/gc'

RSpec.describe Datadog::Runtime::GC do
describe '::stat' do
subject(:stat) { described_class.stat }
it { is_expected.to be_a_kind_of(Hash) }
end

describe '::available?' do
subject(:available?) { described_class.available? }
it { is_expected.to be true }
end
end
16 changes: 0 additions & 16 deletions spec/ddtrace/runtime/heap_size_spec.rb

This file was deleted.

Loading

0 comments on commit 16dac13

Please sign in to comment.