-
Notifications
You must be signed in to change notification settings - Fork 0
/
accumulator.rb
95 lines (83 loc) · 2.78 KB
/
accumulator.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
module Graphiterb
# An accumulator that uses a Redis database as a fast store.
#
# a = Accumulator.new
# a.increment('my_value')
#
# It's assumed that the Redis database is local and on the default
# port, but pass in :host or :port (or any other options Redis.new
# understands) to change this.
#
# By default incrementing 'my_value' which actually increment a
# counter stored at the key
# 'graphiterb_accumulator:my_value:GRAPHITE_IDENTIFIER'.
#
# See Graphiterb::Monitors::AccumulationsConsumer for the periodic
# monitor that will consume the accumulated counts.
class Accumulator
# The Redis database.
attr_accessor :redis
# The name of the Redis namespace (a string) in which
# accumulations are stored (defaults to 'graphiterb')
attr_accessor :namespace
# The Redis namespace (an object) used for the accumulators.
attr_accessor :accumulators
# The top-level Graphite scope inserted for each record.
attr_accessor :main_scope
# Provides methods for finding out about the node this code is
# running on.
include Graphiterb::Utils::SystemInfo
# Initialize a new Accumulator.
#
# Takes the same options as Redis.new.
#
# Also takes the :namespace option to change where the
# accumulations are stored. Different applications can use
# different accumulators with different namespaces in a single,
# shared Redis.
#
# @param [String] main_scope
# @param [Hash] options
def initialize main_scope, options={}
require 'redis'
begin
require 'redis-namespace'
rescue LoadError
require 'redis/namespace'
end
@main_scope = main_scope
@redis = Redis.new(options)
@namespace = options[:namespace] || 'graphiterb'
@accumulators = Redis::Namespace.new(namespace, :redis => redis)
end
# Increment the Graphite target +args+ by the given +amount+.
#
# The target will be automatically scoped, see Accumulator#scope.
#
# @param [Integer] amount
# @param [Array<String>, String] args
def increment_by amount, *args
accumulators.incrby(scope(*args), amount)
end
# Increment the Graphite target +args+.
#
# @param [Array<String>, String] args
def increment *args
accumulators.incr(scope(*args))
end
# Return the scoped accumulator name.
#
# This will be a valid string target that can be passed directly
# to Graphite.
#
# a = Accumulator.new('scrapers')
# a.scope('foo.bar', 'baz')
# #=> 'scrapers.foo.bar.baz.ip-120.112.4.383'
#
# @param [Array<String>, String] args
# @return [String]
def scope *args
[main_scope, args, graphite_identifier].flatten.compact.map(&:to_s).join('.')
end
end
end