inst_statsd 2.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,167 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ def create_subject(payload={}, statsd=nil)
5
+ args = ['name', 1000, 1001, 1234, payload]
6
+ args << statsd if statsd
7
+ InstStatsd::RequestStat.new(*args)
8
+ end
9
+
10
+
11
+ describe InstStatsd::RequestStat do
12
+
13
+ describe '#db_runtime' do
14
+ it 'should return the payload db_runtime' do
15
+ rs = create_subject({db_runtime: 11.11})
16
+ expect(rs.db_runtime).to eq 11.11
17
+ end
18
+
19
+ it 'should return nil when payload db_runtime key doesnt exists' do
20
+ rs = create_subject
21
+ expect(rs.db_runtime).to eq nil
22
+ end
23
+ end
24
+
25
+ describe '#view_runtime' do
26
+ it 'should return the payload view_runtime' do
27
+ rs = create_subject(view_runtime: 11.11)
28
+ expect(rs.view_runtime).to eq 11.11
29
+ end
30
+
31
+ it 'should return nil when payload view_runtime key doesnt exists' do
32
+ rs = create_subject
33
+ expect(rs.view_runtime).to eq nil
34
+ end
35
+ end
36
+
37
+ describe '#controller' do
38
+ it "should return params['controller']" do
39
+ rs = create_subject({params: {'controller' => 'foo'}})
40
+ expect(rs.controller).to eq 'foo'
41
+ end
42
+
43
+ it 'should return nil if no params are available' do
44
+ rs = create_subject
45
+ expect(rs.controller).to eq nil
46
+ end
47
+
48
+ it 'should return nil if no controller is available on params' do
49
+ rs = create_subject({params: {}})
50
+ expect(rs.controller).to eq nil
51
+ end
52
+ end
53
+
54
+ describe '#action' do
55
+ it "should return params['action']" do
56
+ rs = create_subject({params: {'action' => 'index'}})
57
+ expect(rs.action).to eq 'index'
58
+ end
59
+
60
+ it 'should return nil if no params are available' do
61
+ rs = create_subject
62
+ expect(rs.action).to eq nil
63
+ end
64
+
65
+ it 'should return nil if no action is available on params' do
66
+ rs = create_subject({params: {}})
67
+ expect(rs.action).to eq nil
68
+ end
69
+ end
70
+
71
+ describe '#total' do
72
+ it 'correctly calcuates milliseconds from start, finish' do
73
+ rs = create_subject({params: {}})
74
+ # start and finish are in seconds
75
+ expect(rs.total).to eq 1000
76
+ end
77
+
78
+ it 'defaults to zero if either start or finish are nil' do
79
+ rs = InstStatsd::RequestStat.new('name', nil, 1001, 1111, {params: {}})
80
+ expect(rs.total).to eq 0
81
+ rs = InstStatsd::RequestStat.new('name', 1, nil, 1111, {params: {}})
82
+ expect(rs.total).to eq 0
83
+ end
84
+ end
85
+
86
+ describe '#report' do
87
+ it 'doesnt send stats when no controller or action' do
88
+ statsd = double
89
+ rs = create_subject({params: {}}, statsd)
90
+ expect(statsd).to_not receive(:timing).with('request.foo.index', 1000)
91
+ rs.report
92
+ end
93
+
94
+ it 'sends total timing when controller && action are present, doesnt send db, or view if they are not' do
95
+ statsd = double
96
+ payload = {
97
+ params: {
98
+ 'controller' => 'foo',
99
+ 'action' => 'index'
100
+ }
101
+ }
102
+ rs = create_subject(payload, statsd)
103
+ expect(statsd).to receive(:timing).with('request.foo.index.total', 1000)
104
+ rs.report
105
+ end
106
+
107
+ it 'sends view_runtime and db_runtime when present' do
108
+ statsd = double
109
+ payload = {
110
+ view_runtime: 70.1,
111
+ db_runtime: 100.2,
112
+ params: {
113
+ 'controller' => 'foo',
114
+ 'action' => 'index'
115
+ }
116
+ }
117
+ rs = create_subject(payload, statsd)
118
+ allow(statsd).to receive(:timing).with('request.foo.index.total', 1000)
119
+ expect(statsd).to receive(:timing).with('request.foo.index.view', 70.1)
120
+ expect(statsd).to receive(:timing).with('request.foo.index.db', 100.2)
121
+ rs.report
122
+ end
123
+
124
+ it 'sends cache_read_count when present' do
125
+ statsd = double
126
+ payload = {
127
+ params: {
128
+ 'controller' => 'foo',
129
+ 'action' => 'index'
130
+ }
131
+ }
132
+ end
133
+
134
+ describe 'sql stats' do
135
+
136
+ before :each do
137
+ @statsd = double
138
+ payload = {
139
+ params: {
140
+ 'controller' => 'foo',
141
+ 'action' => 'index'
142
+ }
143
+ }
144
+ @rs = create_subject(payload, @statsd)
145
+ @rs.stats['cache.read'] = 25
146
+ expect(@statsd).to receive(:timing).with('request.foo.index.cache.read', 25)
147
+ end
148
+
149
+ it 'doesnt send sql stats when they dont exist' do
150
+ allow(@statsd).to receive(:timing).with('request.foo.index.total', 1000)
151
+ expect(@statsd).to_not receive(:timing).with('request.foo.index.sql.read', kind_of(Numeric))
152
+ expect(@statsd).to_not receive(:timing).with('request.foo.index.sql.write', kind_of(Numeric))
153
+ expect(@statsd).to_not receive(:timing).with('request.foo.index.sql.cache', kind_of(Numeric))
154
+ @rs.report
155
+ end
156
+
157
+ it 'sends sql_read_count when present' do
158
+ @rs.stats['sql.read'] = 10
159
+ allow(@statsd).to receive(:timing).with('request.foo.index.total', 1000)
160
+ expect(@statsd).to receive(:timing).with('request.foo.index.sql.read', 10)
161
+ @rs.report
162
+ end
163
+ end
164
+
165
+ end
166
+
167
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe InstStatsd::RequestTracking do
4
+
5
+ describe '#enable' do
6
+ it 'should delegate log messages to the optional logger' do
7
+ log_double = double()
8
+ expect(log_double).to receive(:info)
9
+ InstStatsd::RequestTracking.enable logger: log_double
10
+ InstStatsd::RequestTracking.start_processing
11
+ InstStatsd::RequestTracking.finalize_processing('name', 1000, 10001, 1234, {})
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+
3
+ module InstStatsd
4
+ describe SqlTracker do
5
+
6
+ describe '#start' do
7
+ it 'resets values to zero' do
8
+ subject = SqlTracker.new
9
+ subject.start
10
+ subject.track 'CACHE', 'SELECT * FROM some_table'
11
+ cookies = subject.start
12
+ expect(subject.finalize_counts(cookies)).to eq([0, 0, 0])
13
+ end
14
+ end
15
+
16
+ describe '#track' do
17
+ before :each do
18
+ @subject = SqlTracker.new
19
+ @cookies = @subject.start
20
+ end
21
+
22
+ def finish
23
+ if @num_reads.nil?
24
+ @num_reads, @num_writes, @num_caches = @subject.finalize_counts(@cookies)
25
+ end
26
+ end
27
+
28
+ def num_reads
29
+ finish
30
+ @num_reads
31
+ end
32
+
33
+ def num_writes
34
+ finish
35
+ @num_writes
36
+ end
37
+
38
+ def num_caches
39
+ finish
40
+ @num_caches
41
+ end
42
+
43
+ it 'considers CACHE above all' do
44
+ @subject.track 'CACHE', 'SELECT * FROM some_table'
45
+ expect(num_caches).to eq(1)
46
+ expect(num_reads).to eq(0)
47
+ end
48
+
49
+ it 'marks as read when select is in the first 15 chars of the sql' do
50
+ @subject.track 'LOAD', ' SELECT "context_external_tools".* FROM'
51
+ expect(num_reads).to eq(1)
52
+ expect(num_writes).to eq(0)
53
+ end
54
+
55
+ it 'marks as read with no select, but a LOAD name' do
56
+ @subject.track 'LOAD', 'WITH RECURSIVE t AS'
57
+ expect(num_reads).to eq(1)
58
+ expect(num_writes).to eq(0)
59
+ end
60
+
61
+ it 'doesnt track names set as blocked' do
62
+ tracker = SqlTracker.new(blocked_names: ['SCHEMA'])
63
+ cookies = tracker.start
64
+ tracker.track 'SCHEMA', 'SELECT * FROM some_table'
65
+ expect(tracker.finalize_counts(cookies)[0]).to eq(0)
66
+ end
67
+
68
+ it 'doesnt track nil names or sql values' do
69
+ @subject.track nil, 'SELECT *'
70
+ @subject.track 'CACHE', nil
71
+ expect(num_reads).to eq(0)
72
+ end
73
+
74
+ it 'passes full sql to counter.track calls for reads' do
75
+ sql = ' SELECT \'context_external_tools\'.* FROM'
76
+ read_counter = double()
77
+ allow(read_counter).to receive(:start)
78
+ expect(read_counter).to receive(:track).with sql
79
+ tracker = SqlTracker.new(read_counter: read_counter)
80
+ tracker.start
81
+ tracker.track 'LOAD', sql
82
+ end
83
+
84
+ it 'passes full sql to counter.track calls for writes' do
85
+ sql = ' UPDATE \'context_external_tools\'.* FROM'
86
+ write_counter = double()
87
+ allow(write_counter).to receive(:start)
88
+ expect(write_counter).to receive(:track).with sql
89
+ tracker = SqlTracker.new(write_counter: write_counter)
90
+ tracker.start
91
+ tracker.track 'UPDATE', sql
92
+ end
93
+ end
94
+
95
+ end
96
+ end
@@ -0,0 +1,98 @@
1
+ require 'spec_helper'
2
+
3
+ describe InstStatsd::Statsd do
4
+ METHODS = %w[increment decrement count gauge timing].freeze
5
+
6
+ after do
7
+ InstStatsd.settings = {}
8
+ InstStatsd::Statsd.reset_instance
9
+ end
10
+
11
+ it 'appends the hostname to stat names by default' do
12
+ allow(InstStatsd::Statsd).to receive(:hostname).and_return('testhost')
13
+ statsd = double
14
+ allow(InstStatsd::Statsd).to receive(:instance).and_return(statsd)
15
+ allow(InstStatsd::Statsd).to receive(:append_hostname?).and_return(true)
16
+ METHODS.each do |method|
17
+ expect(statsd).to receive(method).with('test.name.testhost', 'test')
18
+ InstStatsd::Statsd.send(method, 'test.name', 'test')
19
+ end
20
+ expect(statsd).to receive('timing').with('test.name.testhost', anything, anything)
21
+ expect(InstStatsd::Statsd.time('test.name') { 'test' }).to eq 'test'
22
+ end
23
+
24
+ it 'omits hostname if specified in config' do
25
+ expect(InstStatsd::Statsd).to receive(:hostname).never
26
+ statsd = double
27
+ allow(InstStatsd::Statsd).to receive(:instance).and_return(statsd)
28
+ allow(InstStatsd::Statsd).to receive(:append_hostname?).and_return(false)
29
+ METHODS.each do |method|
30
+ expect(statsd).to receive(method).with('test.name', 'test')
31
+ InstStatsd::Statsd.send(method, 'test.name', 'test')
32
+ end
33
+ expect(statsd).to receive('timing').with('test.name', anything, anything)
34
+ expect(InstStatsd::Statsd.time('test.name') { 'test' }).to eq 'test'
35
+ end
36
+
37
+ it "ignores all calls if statsd isn't enabled" do
38
+ allow(InstStatsd::Statsd).to receive(:instance).and_return(nil)
39
+ METHODS.each do |method|
40
+ expect(InstStatsd::Statsd.send(method, 'test.name')).to be_nil
41
+ end
42
+ expect(InstStatsd::Statsd.time('test.name') { 'test' }).to eq 'test'
43
+ end
44
+
45
+ it 'configures a statsd instance' do
46
+ expect(InstStatsd::Statsd.instance).to be_nil
47
+
48
+ InstStatsd.settings = { host: 'localhost', namespace: 'test', port: 1234 }
49
+ InstStatsd::Statsd.reset_instance
50
+
51
+ instance = InstStatsd::Statsd.instance
52
+ expect(instance).to be_a ::Statsd
53
+ expect(instance.host).to eq 'localhost'
54
+ expect(instance.port).to eq 1234
55
+ expect(instance.namespace).to eq 'test'
56
+ end
57
+
58
+ describe '.batch' do
59
+ it 'is properly reentrant' do
60
+ InstStatsd.settings = { host: 'localhost', namespace: 'test', port: 1234 }
61
+ InstStatsd::Statsd.reset_instance
62
+
63
+ statsd = InstStatsd::Statsd.instance
64
+ InstStatsd::Statsd.batch do
65
+ batch1 = InstStatsd::Statsd.instance
66
+ InstStatsd::Statsd.batch do
67
+ batch2 = InstStatsd::Statsd.instance
68
+ expect(statsd).to be_a ::Statsd
69
+ expect(batch1).to be_a ::Statsd::Batch
70
+ expect(batch2).to be_a ::Statsd::Batch
71
+ expect(batch1).not_to eq batch2
72
+ end
73
+ expect(InstStatsd::Statsd.instance).to eq batch1
74
+ end
75
+ expect(InstStatsd::Statsd.instance).to eq statsd
76
+ end
77
+ end
78
+
79
+ describe '.escape' do
80
+ it 'replaces any dots in str with a _ when no replacment given' do
81
+ result = InstStatsd::Statsd.escape('lots.of.dots')
82
+ expect(result).to eq 'lots_of_dots'
83
+ end
84
+
85
+ it 'replaces any dots in str with replacement arg' do
86
+ result = InstStatsd::Statsd.escape('lots.of.dots', '/')
87
+ expect(result).to eq 'lots/of/dots'
88
+ end
89
+
90
+ it 'returns str when given a str that doesnt respond to gsub' do
91
+ result = InstStatsd::Statsd.escape(nil)
92
+ expect(result).to eq nil
93
+ hash = { foo: 'bar' }
94
+ result = InstStatsd::Statsd.escape(hash)
95
+ expect(result).to eq hash
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,10 @@
1
+ require 'inst_statsd'
2
+
3
+ RSpec.configure do |config|
4
+ config.run_all_when_everything_filtered = true
5
+ config.filter_run :focus
6
+
7
+ config.raise_errors_for_deprecations!
8
+
9
+ config.order = 'random'
10
+ end
File without changes
data/test.sh ADDED
@@ -0,0 +1,16 @@
1
+ #!/bin/bash
2
+ result=0
3
+
4
+ echo "################ inst_statsd ################"
5
+ echo "################ Running tests against Rails 3 ################"
6
+ bundle check || bundle install
7
+ bundle exec rspec spec
8
+ let result=$result+$?
9
+
10
+ if [ $result -eq 0 ]; then
11
+ echo "SUCCESS"
12
+ else
13
+ echo "FAILURE"
14
+ fi
15
+
16
+ exit $result
metadata ADDED
@@ -0,0 +1,166 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: inst_statsd
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.4
5
+ platform: ruby
6
+ authors:
7
+ - Nick Cloward
8
+ - Jason Madsen
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2017-09-07 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: statsd-ruby
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.0'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '1.0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: aroi
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: 0.0.4
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: 0.0.4
42
+ - !ruby/object:Gem::Dependency
43
+ name: bundler
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '1.5'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '1.5'
56
+ - !ruby/object:Gem::Dependency
57
+ name: byebug
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: rake
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: rspec
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ description:
99
+ email:
100
+ - ncloward@instructure.com
101
+ - jmadsen@instructure.com
102
+ executables: []
103
+ extensions: []
104
+ extra_rdoc_files: []
105
+ files:
106
+ - lib/inst_statsd.rb
107
+ - lib/inst_statsd/block_stat.rb
108
+ - lib/inst_statsd/block_tracking.rb
109
+ - lib/inst_statsd/counter.rb
110
+ - lib/inst_statsd/default_tracking.rb
111
+ - lib/inst_statsd/null_logger.rb
112
+ - lib/inst_statsd/request_logger.rb
113
+ - lib/inst_statsd/request_stat.rb
114
+ - lib/inst_statsd/request_tracking.rb
115
+ - lib/inst_statsd/sql_tracker.rb
116
+ - lib/inst_statsd/statsd.rb
117
+ - spec/inst_statsd/block_stat_spec.rb
118
+ - spec/inst_statsd/block_tracking_spec.rb
119
+ - spec/inst_statsd/counter_spec.rb
120
+ - spec/inst_statsd/inst_statsd_spec.rb
121
+ - spec/inst_statsd/null_logger_spec.rb
122
+ - spec/inst_statsd/request_logger_spec.rb
123
+ - spec/inst_statsd/request_stat_spec.rb
124
+ - spec/inst_statsd/request_tracking_spec.rb
125
+ - spec/inst_statsd/sql_tracker_spec.rb
126
+ - spec/inst_statsd/statsd_spec.rb
127
+ - spec/spec_helper.rb
128
+ - spec/support/test.log
129
+ - test.sh
130
+ homepage: https://github.com/instructure/inst_statsd
131
+ licenses:
132
+ - MIT
133
+ metadata: {}
134
+ post_install_message:
135
+ rdoc_options: []
136
+ require_paths:
137
+ - lib
138
+ required_ruby_version: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ version: '2.3'
143
+ required_rubygems_version: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: '0'
148
+ requirements: []
149
+ rubyforge_project:
150
+ rubygems_version: 2.6.12
151
+ signing_key:
152
+ specification_version: 4
153
+ summary: Statsd for Instructure
154
+ test_files:
155
+ - spec/inst_statsd/block_stat_spec.rb
156
+ - spec/inst_statsd/block_tracking_spec.rb
157
+ - spec/inst_statsd/counter_spec.rb
158
+ - spec/inst_statsd/inst_statsd_spec.rb
159
+ - spec/inst_statsd/null_logger_spec.rb
160
+ - spec/inst_statsd/request_logger_spec.rb
161
+ - spec/inst_statsd/request_stat_spec.rb
162
+ - spec/inst_statsd/request_tracking_spec.rb
163
+ - spec/inst_statsd/sql_tracker_spec.rb
164
+ - spec/inst_statsd/statsd_spec.rb
165
+ - spec/spec_helper.rb
166
+ - spec/support/test.log