Class: Metriks::Reporter::DogStatsd

Inherits:
Object
  • Object
show all
Defined in:
lib/metriks/reporter/dogstatsd.rb,
lib/metriks/reporter/dogstatsd/version.rb

Overview

Adapter class for dogstatsd-ruby and the metriks metric collection system.

Defined Under Namespace

Modules: Version

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(host, port, options = {}) ⇒ DogStatsd

Returns a new instance of DogStatsd.



10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/metriks/reporter/dogstatsd.rb', line 10

def initialize host, port, options={}

  @client = Statsd.new(host, port)

  @prefix = options[:prefix]

  @registry = options[:registry] || Metriks::Registry.default
  @interval = options[:interval] || 60 # Seconds
  @timeout_seconds = options[:timeout_seconds] || 45 # Seconds
  @on_error = options[:on_error] || proc{|exception| } # by default, do nothing and just reconnect to the backend
  Statsd.logger = options[:logger]

end

Instance Attribute Details

#clientObject (readonly)

Returns the value of attribute client.



8
9
10
# File 'lib/metriks/reporter/dogstatsd.rb', line 8

def client
  @client
end

Instance Method Details

#restartObject

Restart the backend thread. This is implemented as a plain stop, followed by a plain start



71
72
73
74
# File 'lib/metriks/reporter/dogstatsd.rb', line 71

def restart
  stop
  start
end

#socketObject

Get the socket reference to the backend server. This is broken out to simplify testing.



26
27
28
# File 'lib/metriks/reporter/dogstatsd.rb', line 26

def socket
  @client.instance_variable_get(:@socket)
end

#socket=(io) ⇒ Object

Set the socket reference to the backend server. This is broken out to simplify testing.



32
33
34
# File 'lib/metriks/reporter/dogstatsd.rb', line 32

def socket= io
  @client.instance_variable_set(:@socket, io)
end

#spawn_threaded_write_systemObject



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/metriks/reporter/dogstatsd.rb', line 47

def spawn_threaded_write_system
  Thread.new do
    begin
      Timeout::timeout(@timeout_seconds) do
        write
      end

    # Yes, this is dumb, but I need to asynchronously pass the
    # exception up the thread stack and reconnect to the server seamlessly
    rescue Exception => ex
      @on_error.call(ex)
    end

  end
end

#startObject

Start the backend thread. The backend thread handles connections to the dogstatsd daemon.



38
39
40
41
42
43
44
45
# File 'lib/metriks/reporter/dogstatsd.rb', line 38

def start
  @thread ||= Thread.new do
    loop do
      sleep @interval # don't peg the cpu or wakeup continuously
      spawn_threaded_write_system
    end
  end
end

#stopObject

Kill and release the backend thread.



64
65
66
67
# File 'lib/metriks/reporter/dogstatsd.rb', line 64

def stop
  @thread.kill if @thread
  @thread = nil
end

#writeObject

Flush the metrics being aggregated by the registry to the statistics collection backend



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/metriks/reporter/dogstatsd.rb', line 78

def write
  @registry.each do |name, metric|
    case metric # handle all potential metric types
      when Metriks::Meter
        write_metric name, metric, :meter, [
          # derived metrics
          :count, :one_minute_rate, :five_minute_rate, :fifteen_minute_rate, :mean_rate
        ]
      when Metriks::Counter
        write_metric name, metric, :counter, [
          :count
        ]
      when Metriks::UtilizationTimer
        write_metric name, metric, :utilization_timer, [
          :count, :one_minute_rate, :five_minute_rate, :fifteen_minute_rate, :mean_rate, :min, :max, :mean, :stddev
        ], [
          # snapshot metrics
          :median, :get_95th_percentile
        ]
      when Metriks::Timer
        write_metric name, metric, :timer, [
          :count, :one_minute_rate, :five_minute_rate, :fifteen_minute_rate, :mean_rate, :min, :max, :mean, :stddev
        ], [
          :median, :get_95th_percentile
        ]
      when Metriks::Histogram
        write_metric name, metric, :histogram, [
          :count, :min, :max, :mean, :stddev
        ], [
          :median, :get_95th_percentile
        ]
    end
  end
end

#write_metric(base_name, metric, type, keys, snapshot_keys = []) ⇒ Object



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/metriks/reporter/dogstatsd.rb', line 113

def write_metric(base_name, metric, type, keys, snapshot_keys = [])
  # squash all metrics base name whitespace to underscores
  # the backend system doesn't do whitespace
  base_name = base_name.to_s.gsub(/ +/, '_')

  #prefix the base_name if we've got one set
  base_name = "#{@prefix}.#{base_name}" if @prefix

  keys.flatten.each do |key|
    name = key.to_s.gsub(/^get_/, '')
    value = metric.send(key)
    if key == :count
      case type
        when :meter, :counter
          @client.count(base_name, value)
        when :timer, :utilization_timer, :histogram
          @client.histogram("#{base_name}.#{name}", value)
      end
    else
      @client.gauge("#{base_name}.#{name}", value)
    end
  end

  unless snapshot_keys.empty?
    snapshot = metric.snapshot
    snapshot_keys.flatten.each do |key|
      name = key.to_s.gsub(/^get_/, '')
      value = snapshot.send(key)
      @client.gauge("#{base_name}.#{name}", value)
    end
  end

end