librato-rack 0.1.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.
- data/LICENSE +24 -0
- data/README.md +176 -0
- data/Rakefile +25 -0
- data/lib/librato-rack.rb +1 -0
- data/lib/librato/collector.rb +48 -0
- data/lib/librato/collector/aggregator.rb +97 -0
- data/lib/librato/collector/counter_cache.rb +113 -0
- data/lib/librato/collector/group.rb +29 -0
- data/lib/librato/rack.rb +116 -0
- data/lib/librato/rack/configuration.rb +61 -0
- data/lib/librato/rack/errors.rb +7 -0
- data/lib/librato/rack/logger.rb +71 -0
- data/lib/librato/rack/tracker.rb +137 -0
- data/lib/librato/rack/validating_queue.rb +41 -0
- data/lib/librato/rack/version.rb +5 -0
- data/lib/librato/rack/worker.rb +49 -0
- data/test/apps/basic.ru +20 -0
- data/test/apps/custom.ru +27 -0
- data/test/apps/heroku.ru +27 -0
- data/test/integration/custom_test.rb +59 -0
- data/test/integration/heroku_test.rb +36 -0
- data/test/integration/request_test.rb +69 -0
- data/test/remote/tracker_test.rb +198 -0
- data/test/test_helper.rb +22 -0
- data/test/unit/collector/aggregator_test.rb +69 -0
- data/test/unit/collector/counter_cache_test.rb +96 -0
- data/test/unit/collector/group_test.rb +53 -0
- data/test/unit/collector_test.rb +23 -0
- data/test/unit/rack/configuration_test.rb +86 -0
- data/test/unit/rack/logger_test.rb +91 -0
- data/test/unit/rack/tracker_test.rb +44 -0
- data/test/unit/rack/worker_test.rb +36 -0
- metadata +132 -0
data/test/test_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler.setup
|
3
|
+
|
4
|
+
require 'pry'
|
5
|
+
require 'minitest/autorun'
|
6
|
+
# require 'mocha/setup'
|
7
|
+
|
8
|
+
# Configure Rails Environment
|
9
|
+
ENV["RAILS_ENV"] = "test"
|
10
|
+
|
11
|
+
require 'librato/rack'
|
12
|
+
|
13
|
+
# require File.expand_path("../dummy/config/environment.rb", __FILE__)
|
14
|
+
# require "rails/test_help"
|
15
|
+
|
16
|
+
# Configure capybara
|
17
|
+
# require 'capybara/rails'
|
18
|
+
# Capybara.default_driver = :rack_test
|
19
|
+
# Capybara.default_selector = :css
|
20
|
+
|
21
|
+
# Load support files
|
22
|
+
#Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Librato
|
4
|
+
class Collector
|
5
|
+
class AggregatorTest < MiniTest::Unit::TestCase
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@agg = Aggregator.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_adding_timings
|
12
|
+
@agg.timing 'request.time.total', 23.7
|
13
|
+
@agg.timing 'request.time.db', 5.3
|
14
|
+
@agg.timing 'request.time.total', 64.3
|
15
|
+
|
16
|
+
assert_equal 2, @agg['request.time.total'][:count]
|
17
|
+
assert_equal 88.0, @agg['request.time.total'][:sum]
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_block_timing
|
21
|
+
@agg.timing 'my.task' do
|
22
|
+
sleep 0.2
|
23
|
+
end
|
24
|
+
assert_in_delta @agg['my.task'][:sum], 200, 50
|
25
|
+
|
26
|
+
@agg.timing('another.task') { sleep 0.1 }
|
27
|
+
assert_in_delta @agg['another.task'][:sum], 100, 50
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_return_values
|
31
|
+
simple = @agg.timing 'simple', 20
|
32
|
+
assert_equal nil, simple
|
33
|
+
|
34
|
+
timing = @agg.timing 'foo' do
|
35
|
+
sleep 0.1
|
36
|
+
'bar'
|
37
|
+
end
|
38
|
+
assert_equal 'bar', timing
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_custom_source
|
42
|
+
# sources are kept separate
|
43
|
+
@agg.measure 'meaning.of.life', 1
|
44
|
+
@agg.measure 'meaning.of.life', 42, :source => 'douglas_adams'
|
45
|
+
assert_equal 1.0, @agg.fetch('meaning.of.life')[:sum]
|
46
|
+
assert_equal 42.0, @agg.fetch('meaning.of.life', :source => 'douglas_adams')[:sum]
|
47
|
+
|
48
|
+
# sources work with time blocks
|
49
|
+
@agg.timing 'mytiming', :source => 'mine' do
|
50
|
+
sleep 0.02
|
51
|
+
end
|
52
|
+
assert_in_delta @agg.fetch('mytiming', :source => 'mine')[:sum], 20, 10
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_flush
|
56
|
+
@agg.measure 'meaning.of.life', 1
|
57
|
+
@agg.measure 'meaning.of.life', 42, :source => 'douglas_adams'
|
58
|
+
|
59
|
+
q = Librato::Metrics::Queue.new
|
60
|
+
@agg.flush_to(q)
|
61
|
+
expected = Set.new([
|
62
|
+
{:name=>"meaning.of.life", :count=>1, :sum=>1.0, :min=>1.0, :max=>1.0},
|
63
|
+
{:name=>"meaning.of.life", :count=>1, :sum=>42.0, :min=>42.0, :max=>42.0, :source=>"douglas_adams"}])
|
64
|
+
assert_equal expected, Set.new(q.queued[:gauges])
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Librato
|
4
|
+
class Collector
|
5
|
+
class CounterCacheTest < MiniTest::Unit::TestCase
|
6
|
+
|
7
|
+
def test_basic_operations
|
8
|
+
cc = CounterCache.new
|
9
|
+
cc.increment :foo
|
10
|
+
assert_equal 1, cc[:foo]
|
11
|
+
|
12
|
+
# accepts optional argument
|
13
|
+
cc.increment :foo, :by => 5
|
14
|
+
assert_equal 6, cc[:foo]
|
15
|
+
|
16
|
+
# legacy style
|
17
|
+
cc.increment :foo, 2
|
18
|
+
assert_equal 8, cc[:foo]
|
19
|
+
|
20
|
+
# strings or symbols work
|
21
|
+
cc.increment 'foo'
|
22
|
+
assert_equal 9, cc['foo']
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_custom_sources
|
26
|
+
cc = CounterCache.new
|
27
|
+
|
28
|
+
cc.increment :foo, :source => 'bar'
|
29
|
+
assert_equal 1, cc.fetch(:foo, :source => 'bar')
|
30
|
+
|
31
|
+
# symbols also work
|
32
|
+
cc.increment :foo, :source => :baz
|
33
|
+
assert_equal 1, cc.fetch(:foo, :source => :baz)
|
34
|
+
|
35
|
+
# strings and symbols are interchangable
|
36
|
+
cc.increment :foo, :source => :bar
|
37
|
+
assert_equal 2, cc.fetch(:foo, :source => 'bar')
|
38
|
+
|
39
|
+
# custom source and custom increment
|
40
|
+
cc.increment :foo, :source => 'boombah', :by => 10
|
41
|
+
assert_equal 10, cc.fetch(:foo, :source => 'boombah')
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_sporadic
|
45
|
+
cc = CounterCache.new
|
46
|
+
|
47
|
+
cc.increment :foo
|
48
|
+
cc.increment :foo, :source => 'bar'
|
49
|
+
|
50
|
+
cc.increment :baz, :sporadic => true
|
51
|
+
cc.increment :baz, :source => 118, :sporadic => true
|
52
|
+
assert_equal 1, cc[:baz]
|
53
|
+
assert_equal 1, cc.fetch(:baz, :source => 118)
|
54
|
+
|
55
|
+
# persist values once
|
56
|
+
cc.flush_to(Librato::Metrics::Queue.new)
|
57
|
+
|
58
|
+
# normal values persist
|
59
|
+
assert_equal 0, cc[:foo]
|
60
|
+
assert_equal 0, cc.fetch(:foo, :source => 'bar')
|
61
|
+
|
62
|
+
# sporadic do not
|
63
|
+
assert_equal nil, cc[:baz]
|
64
|
+
assert_equal nil, cc.fetch(:baz, :source => 118)
|
65
|
+
|
66
|
+
# add a different sporadic metric
|
67
|
+
cc.increment :bazoom, :sporadic => true
|
68
|
+
assert_equal 1, cc[:bazoom]
|
69
|
+
|
70
|
+
# persist values again
|
71
|
+
cc.flush_to(Librato::Metrics::Queue.new)
|
72
|
+
assert_equal nil, cc[:bazoom]
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_flushing
|
76
|
+
cc = CounterCache.new
|
77
|
+
|
78
|
+
cc.increment :foo
|
79
|
+
cc.increment :bar, :by => 2
|
80
|
+
cc.increment :foo, :source => 'foobar'
|
81
|
+
cc.increment :foo, :source => 'foobar', :by => 3
|
82
|
+
|
83
|
+
q = Librato::Metrics::Queue.new
|
84
|
+
cc.flush_to(q)
|
85
|
+
|
86
|
+
expected = Set.new [{:name=>"foo", :value=>1},
|
87
|
+
{:name=>"foo", :value=>4, :source=>"foobar"},
|
88
|
+
{:name=>"bar", :value=>2}]
|
89
|
+
queued = Set.new(q.gauges)
|
90
|
+
queued.each { |hash| hash.delete(:measure_time) }
|
91
|
+
assert_equal queued, expected
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Librato
|
4
|
+
class Collector
|
5
|
+
class GroupTest < MiniTest::Unit::TestCase
|
6
|
+
|
7
|
+
def test_increment
|
8
|
+
collector = Collector.new
|
9
|
+
collector.group 'foo' do |g|
|
10
|
+
g.increment :bar
|
11
|
+
end
|
12
|
+
assert_equal 1, collector.counters['foo.bar']
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_measure
|
16
|
+
collector = Collector.new
|
17
|
+
collector.group 'foo' do |g|
|
18
|
+
g.measure :baz, 23
|
19
|
+
end
|
20
|
+
assert_equal 23, collector.aggregate['foo.baz'][:sum]
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_timing
|
24
|
+
collector = Collector.new
|
25
|
+
collector.group 'foo' do |g|
|
26
|
+
g.timing :bam, 32.0
|
27
|
+
end
|
28
|
+
assert_equal 32.0, collector.aggregate['foo.bam'][:sum]
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_timing_block
|
32
|
+
collector = Collector.new
|
33
|
+
collector.group 'foo' do |g|
|
34
|
+
g.timing :bak do
|
35
|
+
sleep 0.01
|
36
|
+
end
|
37
|
+
end
|
38
|
+
assert_in_delta 10.0, collector.aggregate['foo.bak'][:sum], 2
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_nesting
|
42
|
+
collector = Collector.new
|
43
|
+
collector.group 'foo' do |g|
|
44
|
+
g.group :bar do |b|
|
45
|
+
b.increment :baz, 2
|
46
|
+
end
|
47
|
+
end
|
48
|
+
assert_equal 2, collector.counters['foo.bar.baz']
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Librato
|
4
|
+
class CollectorTest < MiniTest::Unit::TestCase
|
5
|
+
|
6
|
+
def test_proxy_object_access
|
7
|
+
collector = Collector.new
|
8
|
+
assert collector.aggregate, 'should have aggregate object'
|
9
|
+
assert collector.counters, 'should have counter object'
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_basic_grouping
|
13
|
+
collector = Collector.new
|
14
|
+
collector.group 'foo' do |g|
|
15
|
+
g.increment :bar
|
16
|
+
g.measure :baz, 23
|
17
|
+
end
|
18
|
+
assert_equal 1, collector.counters['foo.bar']
|
19
|
+
assert_equal 23, collector.aggregate['foo.baz'][:sum]
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Librato
|
4
|
+
class Rack
|
5
|
+
class ConfigurationTest < MiniTest::Unit::TestCase
|
6
|
+
|
7
|
+
def setup
|
8
|
+
clear_env_vars
|
9
|
+
end
|
10
|
+
|
11
|
+
def teardown
|
12
|
+
clear_env_vars
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_defaults
|
16
|
+
config = Configuration.new
|
17
|
+
assert_equal 60, config.flush_interval
|
18
|
+
assert_equal Librato::Metrics.api_endpoint, config.api_endpoint
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_environment_variable_config
|
22
|
+
ENV['LIBRATO_USER'] = 'foo@bar.com'
|
23
|
+
ENV['LIBRATO_TOKEN'] = 'api_key'
|
24
|
+
ENV['LIBRATO_SOURCE'] = 'source'
|
25
|
+
config = Configuration.new
|
26
|
+
assert_equal 'foo@bar.com', config.user
|
27
|
+
assert_equal 'api_key', config.token
|
28
|
+
assert_equal 'source', config.source
|
29
|
+
#assert Librato::Rails.explicit_source, 'source is explicit'
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_legacy_env_variable_config
|
33
|
+
ENV['LIBRATO_METRICS_USER'] = 'foo@bar.com'
|
34
|
+
ENV['LIBRATO_METRICS_TOKEN'] = 'api_key'
|
35
|
+
ENV['LIBRATO_METRICS_SOURCE'] = 'source'
|
36
|
+
config = Configuration.new
|
37
|
+
assert_equal 'foo@bar.com', config.user
|
38
|
+
assert_equal 'api_key', config.token
|
39
|
+
assert_equal 'source', config.source
|
40
|
+
# assert Librato::Rails.explicit_source, 'source is explicit'
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_explicit_source
|
44
|
+
config = Configuration.new
|
45
|
+
assert !config.explicit_source?
|
46
|
+
config.source = 'tessaract'
|
47
|
+
assert config.explicit_source?
|
48
|
+
config.source = nil
|
49
|
+
assert !config.explicit_source?, 'source should no long be explicit when reset'
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_prefix_change_notification
|
53
|
+
config = Configuration.new
|
54
|
+
listener = listener_object
|
55
|
+
config.register_listener(listener)
|
56
|
+
config.prefix = 'newfoo'
|
57
|
+
assert_equal 'newfoo', listener.prefix
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def clear_env_vars
|
63
|
+
ENV.delete('LIBRATO_USER')
|
64
|
+
ENV.delete('LIBRATO_TOKEN')
|
65
|
+
ENV.delete('LIBRATO_SOURCE')
|
66
|
+
ENV.delete('LIBRATO_LOG_LEVEL')
|
67
|
+
# legacy
|
68
|
+
ENV.delete('LIBRATO_METRICS_USER')
|
69
|
+
ENV.delete('LIBRATO_METRICS_TOKEN')
|
70
|
+
ENV.delete('LIBRATO_METRICS_SOURCE')
|
71
|
+
end
|
72
|
+
|
73
|
+
def listener_object
|
74
|
+
listener = Object.new
|
75
|
+
def listener.prefix=(prefix)
|
76
|
+
@prefix = prefix
|
77
|
+
end
|
78
|
+
def listener.prefix
|
79
|
+
@prefix
|
80
|
+
end
|
81
|
+
listener
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
module Librato
|
5
|
+
class Rack
|
6
|
+
class LoggerTest < MiniTest::Unit::TestCase
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@buffer = StringIO.new
|
10
|
+
#log_object = ::Logger.new(@buffer) # stdlib logger
|
11
|
+
@logger = Logger.new(@buffer) # rack logger
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_log_levels
|
15
|
+
assert_equal :info, @logger.log_level, 'should default to info'
|
16
|
+
|
17
|
+
@logger.log_level = :debug
|
18
|
+
assert_equal :debug, @logger.log_level, 'should accept symbols'
|
19
|
+
|
20
|
+
@logger.log_level = 'trace'
|
21
|
+
assert_equal :trace, @logger.log_level, 'should accept strings'
|
22
|
+
|
23
|
+
assert_raises(InvalidLogLevel) { @logger.log_level = :foo }
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_simple_logging
|
27
|
+
@logger.log_level = :info
|
28
|
+
|
29
|
+
# logging at log level
|
30
|
+
@logger.log :info, 'a log message'
|
31
|
+
assert_equal 1, buffer_lines.length, 'should have added a line'
|
32
|
+
assert buffer_lines[0].index('a log message'), 'should log message'
|
33
|
+
|
34
|
+
# logging above level
|
35
|
+
@logger.log :error, 'an error message'
|
36
|
+
assert_equal 2, buffer_lines.length, 'should have added a line'
|
37
|
+
assert buffer_lines[1].index('an error message'), 'should log message'
|
38
|
+
|
39
|
+
# logging below level
|
40
|
+
@logger.log :debug, 'a debug message'
|
41
|
+
assert_equal 2, buffer_lines.length, 'should not have added a line'
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_logging_through_stdlib_logger_object
|
45
|
+
stdlib_logger = ::Logger.new(@buffer)
|
46
|
+
@logger = Logger.new(stdlib_logger)
|
47
|
+
|
48
|
+
@logger.log_level = :info
|
49
|
+
|
50
|
+
# logging at log level
|
51
|
+
@logger.log :info, 'a log message'
|
52
|
+
assert_equal 1, buffer_lines.length, 'should have added a line'
|
53
|
+
assert buffer_lines[0].index('a log message'), 'should log message'
|
54
|
+
|
55
|
+
# logging above level
|
56
|
+
@logger.log :error, 'an error message'
|
57
|
+
assert_equal 2, buffer_lines.length, 'should have added a line'
|
58
|
+
assert buffer_lines[1].index('an error message'), 'should log message'
|
59
|
+
|
60
|
+
# logging below level
|
61
|
+
@logger.log :debug, 'a debug message'
|
62
|
+
assert_equal 2, buffer_lines.length, 'should not have added a line'
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_block_logging
|
66
|
+
@logger.log_level = :info
|
67
|
+
|
68
|
+
# logging at log level
|
69
|
+
@logger.log(:info) { "log statement" }
|
70
|
+
assert_equal 1, buffer_lines.length, 'should have added a line'
|
71
|
+
assert buffer_lines[0].index('log statement'), 'should log message'
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_log_prefix
|
75
|
+
assert_equal '[librato-rack] ', @logger.prefix
|
76
|
+
|
77
|
+
@logger.prefix = '[test prefix] '
|
78
|
+
@logger.log :error, 'an error message'
|
79
|
+
assert buffer_lines[0].index('[test prefix] '), 'should use prefix'
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def buffer_lines
|
85
|
+
@buffer.rewind
|
86
|
+
@buffer.readlines
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|