lookout-statsd 0.7.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/.gitignore +4 -0
- data/Gemfile +5 -0
- data/Guardfile +24 -0
- data/bin/statsd +5 -4
- data/config.yml +16 -1
- data/lib/statsd.rb +8 -1
- data/lib/statsd/{server.rb → aggregator.rb} +2 -31
- data/lib/statsd/daemon.rb +78 -0
- data/lib/statsd/forwarder.rb +52 -0
- data/lib/statsd/test.rb +1 -1
- data/spec/spec_helper.rb +0 -1
- data/spec/statsd/{server_spec.rb → aggregator_spec.rb} +3 -4
- data/spec/statsd/daemon_spec.rb +47 -0
- data/spec/statsd/forwarder_spec.rb +51 -0
- data/spec/statsd/rails/action_timer_filter_spec.rb +33 -0
- data/stats.rb +2 -6
- data/statsd.gemspec +2 -2
- metadata +60 -73
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
YjhiMDk4OTZmNWJkNjgzZmVhMGU5YzgxYzA4ZjZkYTExM2ZiZWRlMw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
NGFmMzljMDhhZTE2MzkzYzZhYTJjZTBhYmFlYjE4MjNjY2I2ZTc2ZQ==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YWQwNmUzMTIwZjkwNGFkNzRjNDQ2YjEyNTA5ZGVhOGJkOTZkYTBjMmJhZjkz
|
10
|
+
YWY1MzUzMzVlZGI1OWY4OTBkNTIxODhhNmQ4MDMyZjU3OGYwNTdhZjRjMTZl
|
11
|
+
N2RjZjQxN2RiYzdhN2EwYTEzMDgxZDU0NTM1YzliMjNlYjc3YTc=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
YWI2ODM0NzUxODhmNjZkYzAxNWU5NGNjOTRlNmQ2ZmY0MDc5NDUyOGFlNjUw
|
14
|
+
MTE2ZDgwMTgwYThiNzgwYWNmY2RkMzE3OWQ0MTVlZWI1ZWQyYzYwMjMzNDEw
|
15
|
+
ZThiMjRhZDVkZmUwOGJmZTczNDRhY2UxNDIxOWM2OTJiMmRhNDY=
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/Guardfile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard :rspec, :cli => '--color --format nested --fail-fast' do
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
8
|
+
|
9
|
+
# Rails example
|
10
|
+
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
11
|
+
watch(%r{^app/(.*)(\.erb|\.haml|\.slim)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
|
12
|
+
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
|
13
|
+
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
14
|
+
watch('config/routes.rb') { "spec/routing" }
|
15
|
+
watch('app/controllers/application_controller.rb') { "spec/controllers" }
|
16
|
+
|
17
|
+
# Capybara features specs
|
18
|
+
watch(%r{^app/views/(.+)/.*\.(erb|haml|slim)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
|
19
|
+
|
20
|
+
# Turnip features and steps
|
21
|
+
watch(%r{^spec/acceptance/(.+)\.feature$})
|
22
|
+
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
|
23
|
+
end
|
24
|
+
|
data/bin/statsd
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
|
4
4
|
require 'yaml'
|
5
5
|
require 'optparse'
|
6
|
+
require 'rubygems'
|
7
|
+
require 'pry'
|
6
8
|
|
7
9
|
begin
|
8
10
|
ORIGINAL_ARGV = ARGV.dup
|
@@ -15,7 +17,7 @@ begin
|
|
15
17
|
opts.separator "Options:"
|
16
18
|
|
17
19
|
opts.on("-cCONFIG", "--config-file CONFIG", "Configuration file") do |x|
|
18
|
-
options[:
|
20
|
+
options[:config_file] = x
|
19
21
|
end
|
20
22
|
|
21
23
|
opts.on("-h", "--help", "Show this message") do
|
@@ -27,12 +29,11 @@ begin
|
|
27
29
|
parser.parse!
|
28
30
|
|
29
31
|
# dispatch
|
30
|
-
if !options[:
|
32
|
+
if !options[:config_file]
|
31
33
|
puts parser.help
|
32
34
|
else
|
33
35
|
require 'statsd'
|
34
|
-
|
35
|
-
Statsd::Server::Daemon.new.run(options)
|
36
|
+
Statsd::Daemon.new.run(options)
|
36
37
|
end
|
37
38
|
rescue Exception => e
|
38
39
|
if e.instance_of?(SystemExit)
|
data/config.yml
CHANGED
@@ -1,10 +1,25 @@
|
|
1
1
|
---
|
2
|
+
# Accept incoming Statsd UDP messages.
|
2
3
|
bind: 127.0.0.1
|
3
4
|
port: 8125
|
4
5
|
|
5
6
|
# Flush interval should be your finest retention in seconds
|
6
|
-
flush_interval:
|
7
|
+
flush_interval: 5
|
7
8
|
|
8
9
|
# Graphite
|
9
10
|
graphite_host: localhost
|
10
11
|
graphite_port: 2003
|
12
|
+
|
13
|
+
# Forwarding sends copies of incoming UDP statsd messages to other
|
14
|
+
# destinations.
|
15
|
+
# This allows for bundling of many senders into one UDP flow/stream, or
|
16
|
+
# directs stats to redundant carbon caches.
|
17
|
+
#
|
18
|
+
forwarding: true
|
19
|
+
forwarding_socket_lifetime: 10
|
20
|
+
# Example destinations:
|
21
|
+
forwarding_destinations:
|
22
|
+
- hostname: localhost
|
23
|
+
port: 9000
|
24
|
+
- hostname: 127.0.0.1
|
25
|
+
port: 9001
|
data/lib/statsd.rb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
require 'socket'
|
2
2
|
require 'resolv'
|
3
|
+
require 'statsd/daemon'
|
4
|
+
require 'statsd/graphite'
|
5
|
+
require 'statsd/aggregator'
|
6
|
+
require 'statsd/forwarder'
|
7
|
+
require 'statsd/test'
|
3
8
|
|
4
9
|
module Statsd
|
5
10
|
# initialize singleton instance in an initializer
|
@@ -116,7 +121,9 @@ module Statsd
|
|
116
121
|
# use "around_filter Statsd::Rails::ActionTimerFilter"
|
117
122
|
class ActionTimerFilter
|
118
123
|
def self.filter(controller, &block)
|
119
|
-
|
124
|
+
# Use params[:controller] insted of controller.controller_name to get full path.
|
125
|
+
controller_name = controller.params[:controller].gsub("/", ".")
|
126
|
+
key = "requests.#{controller_name}.#{controller.params[:action]}"
|
120
127
|
Statsd.instance.timing(key, &block)
|
121
128
|
end
|
122
129
|
end
|
@@ -1,11 +1,5 @@
|
|
1
|
-
require 'eventmachine'
|
2
|
-
require 'yaml'
|
3
|
-
require 'erb'
|
4
|
-
|
5
|
-
require 'statsd/graphite'
|
6
|
-
|
7
1
|
module Statsd
|
8
|
-
module
|
2
|
+
module Aggregator
|
9
3
|
Version = '0.5.5'
|
10
4
|
|
11
5
|
FLUSH_INTERVAL = 10
|
@@ -27,7 +21,7 @@ module Statsd
|
|
27
21
|
[counters,timers,gauges]
|
28
22
|
end
|
29
23
|
|
30
|
-
def receive_data(msg)
|
24
|
+
def self.receive_data(msg)
|
31
25
|
msg.split("\n").each do |row|
|
32
26
|
bits = row.split(':')
|
33
27
|
key = bits.shift.gsub(/\s+/, '_').gsub(/\//, '-').gsub(/[^a-zA-Z_\-0-9\.]/, '')
|
@@ -55,28 +49,5 @@ module Statsd
|
|
55
49
|
end
|
56
50
|
end
|
57
51
|
|
58
|
-
class Daemon
|
59
|
-
def run(options)
|
60
|
-
config = YAML::load(ERB.new(IO.read(options[:config])).result)
|
61
|
-
|
62
|
-
EventMachine::run do
|
63
|
-
EventMachine::open_datagram_socket(config['bind'], config['port'], Statsd::Server)
|
64
|
-
puts "Listening on #{config['bind']}:#{config['port']}"
|
65
|
-
|
66
|
-
# Periodically Flush
|
67
|
-
EventMachine::add_periodic_timer(config['flush_interval']) do
|
68
|
-
counters,timers = Statsd::Server.get_and_clear_stats!
|
69
|
-
|
70
|
-
EventMachine.connect config['graphite_host'], config['graphite_port'], Statsd::Graphite do |conn|
|
71
|
-
conn.counters = counters
|
72
|
-
conn.timers = timers
|
73
|
-
conn.flush_interval = config['flush_interval']
|
74
|
-
conn.flush_stats
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
52
|
end
|
82
53
|
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'eventmachine'
|
2
|
+
require 'yaml'
|
3
|
+
require 'erb'
|
4
|
+
|
5
|
+
module Statsd
|
6
|
+
class MessageDispatchDaemon < EventMachine::Connection
|
7
|
+
# Methods to be called when a statsd message comes in.
|
8
|
+
@@receivers = []
|
9
|
+
# Register a Module implementing an EventMachine::Connection -like
|
10
|
+
# interface.
|
11
|
+
#
|
12
|
+
# receive_data methods on all registered modules will get called, but for
|
13
|
+
# any other EM::Connection methods, the last registered module/method will
|
14
|
+
# take precedence.
|
15
|
+
def self.register_receiver(mod)
|
16
|
+
begin
|
17
|
+
method = mod.method('receive_data')
|
18
|
+
@@receivers << method unless @@receivers.include?(method)
|
19
|
+
rescue NameError
|
20
|
+
raise ArgumentError.new("The passed module #{mod} doesn't implement a receive_data method.")
|
21
|
+
end
|
22
|
+
include mod
|
23
|
+
end
|
24
|
+
def self.receivers=(list)
|
25
|
+
raise ArgumentError unless list.is_a?(Array)
|
26
|
+
@@receivers = list
|
27
|
+
end
|
28
|
+
def self.receivers
|
29
|
+
@@receivers
|
30
|
+
end
|
31
|
+
def receive_data(msg)
|
32
|
+
@@receivers.each do |method|
|
33
|
+
method.call(msg)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
class Daemon
|
38
|
+
def run(options)
|
39
|
+
config = if options[:config] and options[:config].is_a?(Hash)
|
40
|
+
options[:config]
|
41
|
+
elsif options[:config_file] and options[:config_file].is_a?(String)
|
42
|
+
YAML::load(ERB.new(IO.read(options[:config_file])).result)
|
43
|
+
end
|
44
|
+
|
45
|
+
EventMachine::run do
|
46
|
+
## statsd->graphite aggregation
|
47
|
+
if config['graphite_host']
|
48
|
+
MessageDispatchDaemon.register_receiver(Statsd::Aggregator)
|
49
|
+
EventMachine::add_periodic_timer(config['flush_interval']) do
|
50
|
+
counters,timers = Statsd::Aggregator.get_and_clear_stats!
|
51
|
+
EventMachine.connect config['graphite_host'], config['graphite_port'], Statsd::Graphite do |conn|
|
52
|
+
conn.counters = counters
|
53
|
+
conn.timers = timers
|
54
|
+
conn.flush_interval = config['flush_interval']
|
55
|
+
conn.flush_stats
|
56
|
+
end
|
57
|
+
end
|
58
|
+
##
|
59
|
+
|
60
|
+
## statsd->statsd data relay
|
61
|
+
if config['forwarding']
|
62
|
+
Statsd::Forwarder.set_destinations(config['forwarding_destinations'])
|
63
|
+
MessageDispatchDaemon.register_receiver(Statsd::Forwarder)
|
64
|
+
|
65
|
+
Statsd::Forwarder.build_fresh_sockets
|
66
|
+
EventMachine::add_periodic_timer(config['forwarding_socket_lifetime']) do
|
67
|
+
Statsd::Forwarder.build_fresh_sockets
|
68
|
+
end
|
69
|
+
end
|
70
|
+
##
|
71
|
+
|
72
|
+
puts "Going to listen on #{config['bind']}:#{config['port']}"
|
73
|
+
EventMachine::open_datagram_socket(config['bind'], config['port'], MessageDispatchDaemon)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
module Statsd
|
4
|
+
module Forwarder
|
5
|
+
@@sockets = {}
|
6
|
+
@@destinations = []
|
7
|
+
|
8
|
+
def self.sockets; @@sockets; end
|
9
|
+
def self.sockets=(hash)
|
10
|
+
raise ArgumentError unless hash.is_a?(Hash)
|
11
|
+
@@sockets = hash
|
12
|
+
end
|
13
|
+
def self.destinations; @@destinations; end
|
14
|
+
def self.destinations=(list)
|
15
|
+
raise ArgumentError unless list.is_a?(Array)
|
16
|
+
@@destinations = list
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.receive_data(msg)
|
20
|
+
# Broadcast the incoming message to all the forwarding destinations.
|
21
|
+
@@sockets.each do |destination, socket|
|
22
|
+
begin
|
23
|
+
socket.send(msg, 0)
|
24
|
+
rescue SocketError, Errno::ECONNREFUSED => e
|
25
|
+
puts "ERROR: Couldn't send message to #{destination}. Stopping this output.(#{e.inspect})"
|
26
|
+
@@sockets.delete(destination)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
def self.build_fresh_sockets
|
31
|
+
# Reset destinations to those destinations for which we could
|
32
|
+
# actually get a socket going.
|
33
|
+
@@sockets.clear
|
34
|
+
@@destinations = @@destinations.select do |destination|
|
35
|
+
begin
|
36
|
+
s = UDPSocket.new(Socket::AF_INET)
|
37
|
+
s.connect destination['hostname'], destination['port']
|
38
|
+
@@sockets[destination] = s
|
39
|
+
true
|
40
|
+
rescue SocketError => e
|
41
|
+
puts "ERROR: Couldn't create a socket to #{destination['hostname']}/#{destination['port']}. Pruning destination from Forwarder. (#{e.inspect})"
|
42
|
+
false
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
def self.set_destinations(destinations)
|
47
|
+
raise ArgumentError unless destinations.is_a?(Array)
|
48
|
+
raise ArgumentError unless destinations.map { |d| d.keys }.flatten.uniq.sort == ['hostname', 'port']
|
49
|
+
@@destinations = destinations
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/statsd/test.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
include Statsd::Server
|
3
|
+
describe Statsd::Aggregator do
|
4
|
+
#include Statsd::Aggregator
|
6
5
|
|
7
6
|
describe :receive_data do
|
8
7
|
it 'should not vomit on bad data' do
|
9
8
|
bad_data = "dev.rwygand.app.flexd.exception.no action responded to index. actions: authenticate, authentication_request, authorization, bubble_stacktrace?, decode_credentials, encode_credentials, not_found, and user_name_and_password:1|c"
|
10
9
|
|
11
10
|
expect {
|
12
|
-
receive_data(bad_data)
|
11
|
+
Statsd::Aggregator.receive_data(bad_data)
|
13
12
|
}.not_to raise_error
|
14
13
|
end
|
15
14
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Statsd::Daemon do
|
4
|
+
describe :new do
|
5
|
+
before(:each) do
|
6
|
+
EventMachine.should_receive(:run) { |&block| block.call }
|
7
|
+
EventMachine.should_receive(:open_datagram_socket).and_return true
|
8
|
+
EventMachine.should_receive(:add_periodic_timer).at_least(:once) { |delay, &block| block.call }
|
9
|
+
EventMachine.should_receive(:connect).and_return true
|
10
|
+
Statsd::MessageDispatchDaemon.receivers = []
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'Should extend MessageDispatchDaemon with an Aggregator if "carbon_cache" is configured' do
|
14
|
+
config = {
|
15
|
+
"bind"=>"127.0.0.1",
|
16
|
+
"port"=>8125,
|
17
|
+
"flush_interval"=>5,
|
18
|
+
"graphite_host"=>"localhost",
|
19
|
+
"graphite_port"=>2003,
|
20
|
+
"forwarding"=>false,
|
21
|
+
}
|
22
|
+
|
23
|
+
Statsd::Daemon.new.run(:config => config)
|
24
|
+
Statsd::MessageDispatchDaemon.receivers.should eq([Statsd::Aggregator.method(:receive_data)])
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'Should extend MessageDispatchDaemon with an Aggregator and Forwarder if "carbon_cache" is configured and forwarding is enabled' do
|
28
|
+
config = {
|
29
|
+
"bind"=>"127.0.0.1",
|
30
|
+
"port"=>8125,
|
31
|
+
"flush_interval"=>5,
|
32
|
+
"graphite_host"=>"localhost",
|
33
|
+
"graphite_port"=>2003,
|
34
|
+
"forwarding"=>true,
|
35
|
+
"forwarding_destinations"=>
|
36
|
+
[
|
37
|
+
{"port"=>9000, "hostname"=>"localhost"},
|
38
|
+
{"port"=>9001, "hostname"=>"127.0.0.1"}
|
39
|
+
]
|
40
|
+
}
|
41
|
+
|
42
|
+
Statsd::Daemon.new.run(:config => config)
|
43
|
+
Statsd::MessageDispatchDaemon.receivers.should eq([Statsd::Aggregator.method(:receive_data), Statsd::Forwarder.method(:receive_data)])
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'timeout'
|
3
|
+
|
4
|
+
describe Statsd::Forwarder do
|
5
|
+
let(:destinations) do
|
6
|
+
[ {'hostname'=>'localhost', 'port'=>9000},
|
7
|
+
{'hostname'=>'127.0.0.1', 'port'=>9001} ]
|
8
|
+
end
|
9
|
+
before(:each) do
|
10
|
+
Statsd::Forwarder.sockets = {}
|
11
|
+
expect { Statsd::Forwarder.set_destinations(destinations) }.not_to raise_error
|
12
|
+
end
|
13
|
+
it 'Should accept a list of destinations to forward to.' do
|
14
|
+
Statsd::Forwarder.destinations.should eq(destinations)
|
15
|
+
end
|
16
|
+
it 'Should create sockets to the destinations with #build_fresh_sockets' do
|
17
|
+
Statsd::Forwarder.sockets.should eq({})
|
18
|
+
Statsd::Forwarder.build_fresh_sockets
|
19
|
+
Statsd::Forwarder.sockets.should be_a_kind_of(Hash)
|
20
|
+
Statsd::Forwarder.sockets.keys.length.should eq(destinations.length)
|
21
|
+
Statsd::Forwarder.sockets.values.each { |socket| socket.should be_a_kind_of(UDPSocket) }
|
22
|
+
end
|
23
|
+
describe 'Replicating incoming messages' do
|
24
|
+
let(:socket_one) do
|
25
|
+
u = UDPSocket.new
|
26
|
+
u.bind('127.0.0.1', 0)
|
27
|
+
#let(:socket_one_port) { u.local_address.ip_port }
|
28
|
+
u
|
29
|
+
end
|
30
|
+
let(:socket_two) do
|
31
|
+
u = UDPSocket.new
|
32
|
+
u.bind('127.0.0.1', 0)
|
33
|
+
u
|
34
|
+
end
|
35
|
+
let(:test_stat) { "app.thing.speed:10|ms\n" }
|
36
|
+
it 'Registers two local receivers, Gets an incoming message, both receivers get it' do
|
37
|
+
Statsd::Forwarder.set_destinations([{'hostname' => '127.0.0.1', 'port' => socket_one.addr[1] },
|
38
|
+
{'hostname' => '127.0.0.1', 'port' => socket_two.addr[1] }])
|
39
|
+
Statsd::Forwarder.build_fresh_sockets
|
40
|
+
Statsd::Forwarder.receive_data(test_stat)
|
41
|
+
|
42
|
+
Timeout.timeout(3) do
|
43
|
+
msg, _, _ = socket_one.recv(4_096)
|
44
|
+
msg.should eq(test_stat)
|
45
|
+
|
46
|
+
msg, _, _ = socket_two.recv(4_096)
|
47
|
+
msg.should eq(test_stat)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Statsd::Rails::ActionTimerFilter do
|
4
|
+
|
5
|
+
describe ".filter" do
|
6
|
+
before(:all) do
|
7
|
+
Statsd.create_instance
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should log the appropriate data with simple controller" do
|
11
|
+
controller = mock_controller('control', 'act')
|
12
|
+
Statsd.instance.should_receive(:timing).with("requests.control.act")
|
13
|
+
Statsd::Rails::ActionTimerFilter.filter(controller) {}
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should log the appropriate data with complex controller" do
|
17
|
+
controller = mock_controller('api/v1/control', 'act')
|
18
|
+
Statsd.instance.should_receive(:timing).with("requests.api.v1.control.act")
|
19
|
+
Statsd::Rails::ActionTimerFilter.filter(controller) {}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Create a mock controller with the given name and action
|
24
|
+
def mock_controller(name, action)
|
25
|
+
controller = double("MyController")
|
26
|
+
params = {
|
27
|
+
:controller => name,
|
28
|
+
:action => action,
|
29
|
+
}
|
30
|
+
controller.stub(:params).and_return(params)
|
31
|
+
controller
|
32
|
+
end
|
33
|
+
end
|
data/stats.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
require 'eventmachine'
|
2
2
|
require 'statsd'
|
3
|
-
require 'statsd/server'
|
4
|
-
require 'statsd/graphite'
|
5
3
|
|
6
4
|
require 'yaml'
|
7
5
|
require 'erb'
|
@@ -11,9 +9,9 @@ APP_CONFIG = YAML::load(ERB.new(IO.read(File.join(ROOT,'config.yml'))).result)
|
|
11
9
|
|
12
10
|
# Start the server
|
13
11
|
EventMachine::run do
|
14
|
-
EventMachine::open_datagram_socket('127.0.0.1', 8125, Statsd::
|
12
|
+
EventMachine::open_datagram_socket('127.0.0.1', 8125, Statsd::Aggregator)
|
15
13
|
EventMachine::add_periodic_timer(APP_CONFIG['flush_interval']) do
|
16
|
-
counters,timers = Statsd::
|
14
|
+
counters,timers = Statsd::Aggregator.get_and_clear_stats!
|
17
15
|
|
18
16
|
# Graphite
|
19
17
|
EventMachine.connect APP_CONFIG['graphite_host'], APP_CONFIG['graphite_port'], Statsd::Graphite do |conn|
|
@@ -23,6 +21,4 @@ EventMachine::run do
|
|
23
21
|
conn.flush_stats
|
24
22
|
end
|
25
23
|
end
|
26
|
-
|
27
|
-
|
28
24
|
end
|
data/statsd.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = "lookout-statsd"
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.9.0"
|
6
6
|
s.platform = Gem::Platform::RUBY
|
7
7
|
|
8
8
|
s.authors = ['R. Tyler Croy', 'Andrew Coldham', 'Ben VandenBos']
|
@@ -14,7 +14,7 @@ Gem::Specification.new do |s|
|
|
14
14
|
|
15
15
|
s.required_rubygems_version = ">= 1.3.6"
|
16
16
|
|
17
|
-
s.add_dependency "eventmachine", ">= 0.12.10"
|
17
|
+
s.add_dependency "eventmachine", ">= 0.12.10", "< 0.15.2"
|
18
18
|
s.add_dependency "erubis", ">= 2.6.6"
|
19
19
|
|
20
20
|
s.files = `git ls-files`.split("\n")
|
metadata
CHANGED
@@ -1,117 +1,104 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: lookout-statsd
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 7
|
9
|
-
- 1
|
10
|
-
version: 0.7.1
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.0
|
11
5
|
platform: ruby
|
12
|
-
authors:
|
6
|
+
authors:
|
13
7
|
- R. Tyler Croy
|
14
8
|
- Andrew Coldham
|
15
9
|
- Ben VandenBos
|
16
10
|
autorequire:
|
17
11
|
bindir: bin
|
18
12
|
cert_chain: []
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
- !ruby/object:Gem::Dependency
|
23
|
-
type: :runtime
|
13
|
+
date: 2013-12-04 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
24
16
|
name: eventmachine
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
hash: 59
|
31
|
-
segments:
|
32
|
-
- 0
|
33
|
-
- 12
|
34
|
-
- 10
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
35
21
|
version: 0.12.10
|
36
|
-
|
37
|
-
|
38
|
-
|
22
|
+
- - <
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 0.15.2
|
39
25
|
type: :runtime
|
26
|
+
prerelease: false
|
27
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
|
+
requirements:
|
29
|
+
- - ! '>='
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: 0.12.10
|
32
|
+
- - <
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 0.15.2
|
35
|
+
- !ruby/object:Gem::Dependency
|
40
36
|
name: erubis
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
hash: 27
|
47
|
-
segments:
|
48
|
-
- 2
|
49
|
-
- 6
|
50
|
-
- 6
|
37
|
+
requirement: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ! '>='
|
40
|
+
- !ruby/object:Gem::Version
|
51
41
|
version: 2.6.6
|
52
|
-
|
42
|
+
type: :runtime
|
53
43
|
prerelease: false
|
54
|
-
|
55
|
-
|
44
|
+
version_requirements: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ! '>='
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: 2.6.6
|
49
|
+
description: A network daemon for aggregating statistics (counters and timers), rolling
|
50
|
+
them up, then sending them to graphite.
|
51
|
+
email:
|
56
52
|
- rtyler.croy@mylookout.com
|
57
|
-
executables:
|
53
|
+
executables:
|
58
54
|
- statsd
|
59
55
|
extensions: []
|
60
|
-
|
61
56
|
extra_rdoc_files: []
|
62
|
-
|
63
|
-
files:
|
57
|
+
files:
|
64
58
|
- .gitignore
|
65
59
|
- Gemfile
|
60
|
+
- Guardfile
|
66
61
|
- README.md
|
67
62
|
- Rakefile
|
68
63
|
- bin/statsd
|
69
64
|
- config.yml
|
70
65
|
- lib/statsd.rb
|
66
|
+
- lib/statsd/aggregator.rb
|
67
|
+
- lib/statsd/daemon.rb
|
71
68
|
- lib/statsd/echos.rb
|
69
|
+
- lib/statsd/forwarder.rb
|
72
70
|
- lib/statsd/graphite.rb
|
73
|
-
- lib/statsd/server.rb
|
74
71
|
- lib/statsd/test.rb
|
75
72
|
- netcat-example.sh
|
76
73
|
- spec/spec_helper.rb
|
77
|
-
- spec/statsd/
|
74
|
+
- spec/statsd/aggregator_spec.rb
|
75
|
+
- spec/statsd/daemon_spec.rb
|
76
|
+
- spec/statsd/forwarder_spec.rb
|
77
|
+
- spec/statsd/rails/action_timer_filter_spec.rb
|
78
78
|
- spec/statsd_spec.rb
|
79
79
|
- stats.rb
|
80
80
|
- statsd.gemspec
|
81
81
|
homepage: https://github.com/lookout/statsd
|
82
82
|
licenses: []
|
83
|
-
|
83
|
+
metadata: {}
|
84
84
|
post_install_message:
|
85
85
|
rdoc_options: []
|
86
|
-
|
87
|
-
require_paths:
|
86
|
+
require_paths:
|
88
87
|
- lib
|
89
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
|
-
none: false
|
100
|
-
requirements:
|
101
|
-
- - ">="
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
hash: 23
|
104
|
-
segments:
|
105
|
-
- 1
|
106
|
-
- 3
|
107
|
-
- 6
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ! '>='
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ! '>='
|
96
|
+
- !ruby/object:Gem::Version
|
108
97
|
version: 1.3.6
|
109
98
|
requirements: []
|
110
|
-
|
111
99
|
rubyforge_project:
|
112
|
-
rubygems_version: 1.
|
100
|
+
rubygems_version: 2.1.11
|
113
101
|
signing_key:
|
114
|
-
specification_version:
|
102
|
+
specification_version: 4
|
115
103
|
summary: Ruby version of statsd.
|
116
104
|
test_files: []
|
117
|
-
|