Class: Statsd

Inherits:
Object
  • Object
show all
Defined in:
lib/statsd.rb

Overview

Statsd: A DogStatsd client (www.datadoghq.com)

Examples:

Set up a global Statsd client for a server on localhost:8125

require 'statsd'
$statsd = Statsd.new 'localhost', 8125

Send some stats

$statsd.increment 'page.views'
$statsd.timing 'page.load', 320
$statsd.gauge 'users.online', 100

Use #time to time the execution of a block

$statsd.time('account.activate') { @account.activate! }

Create a namespaced statsd client and increment ‘account.activate’

statsd = Statsd.new 'localhost', 8125, :namespace => 'account'
statsd.increment 'activate'

Create a statsd client with global tags

statsd = Statsd.new 'localhost', 8125, :tags => 'tag1:true'

Constant Summary collapse

DEFAULT_HOST =
'127.0.0.1'
DEFAULT_PORT =
8125
OPTS_KEYS =

Create a dictionary to assign a key to every parameter’s name, except for tags (treated differently) Goal: Simple and fast to add some other parameters

[
      ['date_happened', 'd'],
      ['hostname', 'h'],
      ['aggregation_key', 'k'],
      ['priority', 'p'],
      ['source_type_name', 's'],
      ['alert_type', 't']
]
SC_OPT_KEYS =

Service check options

[
      ['timestamp', 'd:'],
      ['hostname', 'h:'],
      ['tags', '#'],
      ['message', 'm:']
]
OK =
0
WARNING =
1
CRITICAL =
2
UNKNOWN =
3

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(host = DEFAULT_HOST, port = DEFAULT_PORT, opts = {}, max_buffer_size = 50) ⇒ Statsd

Returns a new instance of Statsd.

Parameters:

  • host (String) (defaults to: DEFAULT_HOST)

    your statsd host

  • port (Integer) (defaults to: DEFAULT_PORT)

    your statsd port

  • opts (Hash) (defaults to: {})

    a customizable set of options

Options Hash (opts):

  • :namespace (String)

    set a namespace to be prepended to every metric name

  • :tags (Array<String>)

    tags to be added to every metric



79
80
81
82
83
84
85
86
87
88
# File 'lib/statsd.rb', line 79

def initialize(host = DEFAULT_HOST, port = DEFAULT_PORT, opts = {}, max_buffer_size=50)
  self.host, self.port = host, port
  @prefix = nil
  @socket = UDPSocket.new
  self.namespace = opts[:namespace]
  self.tags = opts[:tags]
  @buffer = Array.new
  self.max_buffer_size = max_buffer_size
  alias :send_stat :send_to_socket
end

Class Attribute Details

.loggerObject

Set to a standard logger instance to enable debug logging.



67
68
69
# File 'lib/statsd.rb', line 67

def logger
  @logger
end

Instance Attribute Details

#bufferObject (readonly)

Buffer containing the statsd message before they are sent in batch



60
61
62
# File 'lib/statsd.rb', line 60

def buffer
  @buffer
end

#hostObject

StatsD host. Defaults to 127.0.0.1.



51
52
53
# File 'lib/statsd.rb', line 51

def host
  @host
end

#max_buffer_sizeObject

Maximum number of metrics in the buffer before it is flushed



63
64
65
# File 'lib/statsd.rb', line 63

def max_buffer_size
  @max_buffer_size
end

#namespaceObject

A namespace to prepend to all statsd calls. Defaults to no namespace.



48
49
50
# File 'lib/statsd.rb', line 48

def namespace
  @namespace
end

#portObject

StatsD port. Defaults to 8125.



54
55
56
# File 'lib/statsd.rb', line 54

def port
  @port
end

#tagsObject

Global tags to be added to every statsd call. Defaults to no tags.



57
58
59
# File 'lib/statsd.rb', line 57

def tags
  @tags
end

Class Method Details

.VERSIONObject

Return the current version of the library.



71
72
73
# File 'lib/statsd.rb', line 71

def self.VERSION
  "1.6.0"
end

Instance Method Details

#batch {|_self| ... } ⇒ Object

Send several metrics in the same UDP Packet They will be buffered and flushed when the block finishes

Examples:

Send several metrics in one packet:

$statsd.batch do |s|
   s.gauge('users.online',156)
   s.increment('page.views')
 end

Yields:

  • (_self)

Yield Parameters:

  • _self (Statsd)

    the object that the method was called on



290
291
292
293
294
295
# File 'lib/statsd.rb', line 290

def batch()
  alias :send_stat :send_to_buffer
  yield self
  flush_buffer
  alias :send_stat :send_to_socket
end

#count(stat, count, opts = {}) ⇒ Object

Sends an arbitrary count for the given stat to the statsd server.

Parameters:

  • stat (String)

    stat name

  • count (Integer)

    count

  • opts (Hash) (defaults to: {})

    the options to create the metric with

Options Hash (opts):

  • :sample_rate (Numeric)

    sample rate, 1 for always

  • :tags (Array<String>)

    An array of tags



136
137
138
# File 'lib/statsd.rb', line 136

def count(stat, count, opts={})
  send_stats stat, count, :c, opts
end

#decrement(stat, opts = {}) ⇒ Object

Sends a decrement (count = -1) for the given stat to the statsd server.

Parameters:

  • stat (String)

    stat name

  • opts (Hash) (defaults to: {})

    the options to create the metric with

Options Hash (opts):

  • :sample_rate (Numeric)

    sample rate, 1 for always

  • :tags (Array<String>)

    An array of tags

See Also:



125
126
127
# File 'lib/statsd.rb', line 125

def decrement(stat, opts={})
  count stat, -1, opts
end

#event(title, text, opts = {}) ⇒ Object

This end point allows you to post events to the stream. You can tag them, set priority and even aggregate them with other events.

Aggregation in the stream is made on hostname/event_type/source_type/aggregation_key. If there’s no event type, for example, then that won’t matter; it will be grouped with other events that don’t have an event type.

Examples:

Report an awful event:

$statsd.event('Something terrible happened', 'The end is near if we do nothing', :alert_type=>'warning', :tags=>['end_of_times','urgent'])

Parameters:

  • title (String)

    Event title

  • text (String)

    Event text. Supports n

  • opts (Hash) (defaults to: {})

    the additional data about the event

Options Hash (opts):

  • :date_happened (Integer, nil) — default: nil

    Assign a timestamp to the event. Default is now when none

  • :hostname (String, nil) — default: nil

    Assign a hostname to the event.

  • :aggregation_key (String, nil) — default: nil

    Assign an aggregation key to the event, to group it with some others

  • :priority (String, nil) — default: 'normal'

    Can be “normal” or “low”

  • :source_type_name (String, nil) — default: nil

    Assign a source type to the event

  • :alert_type (String, nil) — default: 'info'

    Can be “error”, “warning”, “info” or “success”.

  • :tags (Array<String>)

    tags to be added to every metric



275
276
277
278
279
280
# File 'lib/statsd.rb', line 275

def event(title, text, opts={})
  event_string = format_event(title, text, opts)
  raise "Event #{title} payload is too big (more that 8KB), event discarded" if event_string.length > 8 * 1024

  send_to_socket event_string
end

#format_event(title, text, opts = {}) ⇒ Object



297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
# File 'lib/statsd.rb', line 297

def format_event(title, text, opts={})
  escaped_title = escape_event_content(title)
  escaped_text = escape_event_content(text)
  event_string_data = "_e{#{escaped_title.length},#{escaped_text.length}}:#{escaped_title}|#{escaped_text}"

  # We construct the string to be sent by adding '|key:value' parts to it when needed
  # All pipes ('|') in the metadata are removed. Title and Text can keep theirs
  OPTS_KEYS.each do |name_key|
    if name_key[0] != 'tags' && opts[name_key[0].to_sym]
      value = remove_pipes(opts[name_key[0].to_sym])
      event_string_data << "|#{name_key[1]}:#{value}"
    end
  end
  # Tags are joined and added as last part to the string to be sent
  full_tags = (tags + (opts[:tags] || [])).map {|tag| remove_pipes(tag) }
  unless full_tags.empty?
    event_string_data << "|##{full_tags.join(',')}"
  end

  raise "Event #{title} payload is too big (more that 8KB), event discarded" if event_string_data.length > 8 * 1024
  return event_string_data
end

#format_service_check(name, status, opts = {}) ⇒ Object



235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
# File 'lib/statsd.rb', line 235

def format_service_check(name, status, opts={})
  sc_string = "_sc|#{name}|#{status}"

  SC_OPT_KEYS.each do |name_key|
    if opts[name_key[0].to_sym]
      if name_key[0] == 'tags'
        tags = opts[:tags].map {|tag| remove_pipes(tag) }
        tags = "#{tags.join(",")}" unless tags.empty?
        sc_string << "|##{tags}"
      elsif name_key[0] == 'message'
        message = remove_pipes(opts[:message])
        escaped_message = escape_service_check_message(message)
        sc_string << "|m:#{escaped_message}"
      else
        value = remove_pipes(opts[name_key[0].to_sym])
        sc_string << "|#{name_key[1]}#{value}"
      end
    end
  end
  return sc_string
end

#gauge(stat, value, opts = {}) ⇒ Object

Sends an arbitary gauge value for the given stat to the statsd server.

This is useful for recording things like available disk space, memory usage, and the like, which have different semantics than counters.

Examples:

Report the current user count:

$statsd.gauge('user.count', User.count)

Parameters:

  • stat (String)

    stat name.

  • value (Numeric)

    gauge value.

  • opts (Hash) (defaults to: {})

    the options to create the metric with

Options Hash (opts):

  • :sample_rate (Numeric)

    sample rate, 1 for always

  • :tags (Array<String>)

    An array of tags



153
154
155
# File 'lib/statsd.rb', line 153

def gauge(stat, value, opts={})
  send_stats stat, value, :g, opts
end

#histogram(stat, value, opts = {}) ⇒ Object

Sends a value to be tracked as a histogram to the statsd server.

Examples:

Report the current user count:

$statsd.histogram('user.count', User.count)

Parameters:

  • stat (String)

    stat name.

  • value (Numeric)

    histogram value.

  • opts (Hash) (defaults to: {})

    the options to create the metric with

Options Hash (opts):

  • :sample_rate (Numeric)

    sample rate, 1 for always

  • :tags (Array<String>)

    An array of tags



166
167
168
# File 'lib/statsd.rb', line 166

def histogram(stat, value, opts={})
  send_stats stat, value, :h, opts
end

#increment(stat, opts = {}) ⇒ Object

Sends an increment (count = 1) for the given stat to the statsd server.

Parameters:

  • stat (String)

    stat name

  • opts (Hash) (defaults to: {})

    the options to create the metric with

Options Hash (opts):

  • :sample_rate (Numeric)

    sample rate, 1 for always

  • :tags (Array<String>)

    An array of tags

See Also:



114
115
116
# File 'lib/statsd.rb', line 114

def increment(stat, opts={})
  count stat, 1, opts
end

#service_check(name, status, opts = {}) ⇒ Object

Examples:

Report a critical service check status

$statsd.service_check('my.service.check', Statsd::CRITICAL, :tags=>['urgent'])


231
232
233
234
# File 'lib/statsd.rb', line 231

def service_check(name, status, opts={})
  service_check_string = format_service_check(name, status, opts)
  send_to_socket service_check_string
end

#set(stat, value, opts = {}) ⇒ Object

Sends a value to be tracked as a set to the statsd server.

Examples:

Record a unique visitory by id:

$statsd.set('visitors.uniques', User.id)

Parameters:

  • stat (String)

    stat name.

  • value (Numeric)

    set value.

  • opts (Hash) (defaults to: {})

    the options to create the metric with

Options Hash (opts):

  • :sample_rate (Numeric)

    sample rate, 1 for always

  • :tags (Array<String>)

    An array of tags



215
216
217
# File 'lib/statsd.rb', line 215

def set(stat, value, opts={})
  send_stats stat, value, :s, opts
end

#time(stat, opts = {}) { ... } ⇒ Object

Reports execution time of the provided block using #timing.

If the block fails, the stat is still reported, then the error is reraised

Examples:

Report the time (in ms) taken to activate an account

$statsd.time('account.activate') { @account.activate! }

Parameters:

  • stat (String)

    stat name

  • opts (Hash) (defaults to: {})

    the options to create the metric with

Options Hash (opts):

  • :sample_rate (Numeric)

    sample rate, 1 for always

  • :tags (Array<String>)

    An array of tags

Yields:

  • The operation to be timed

See Also:



197
198
199
200
201
202
203
204
205
# File 'lib/statsd.rb', line 197

def time(stat, opts={})
  start = Time.now
  result = yield
  time_since(stat, start, opts)
  result
rescue
  time_since(stat, start, opts)
  raise
end

#timing(stat, ms, opts = {}) ⇒ Object

Sends a timing (in ms) for the given stat to the statsd server. The sample_rate determines what percentage of the time this report is sent. The statsd server then uses the sample_rate to correctly track the average timing for the stat.

Parameters:

  • stat (String)

    stat name

  • ms (Integer)

    timing in milliseconds

  • opts (Hash) (defaults to: {})

    the options to create the metric with

Options Hash (opts):

  • :sample_rate (Numeric)

    sample rate, 1 for always

  • :tags (Array<String>)

    An array of tags



180
181
182
# File 'lib/statsd.rb', line 180

def timing(stat, ms, opts={})
  send_stats stat, ms, :ms, opts
end