inst_statsd 2.2.0 → 3.0.4
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 +4 -4
- data/lib/inst_statsd/block_stat.rb +14 -14
- data/lib/inst_statsd/block_tracking.rb +12 -13
- data/lib/inst_statsd/counter.rb +2 -4
- data/lib/inst_statsd/default_tracking.rb +30 -27
- data/lib/inst_statsd/event.rb +64 -0
- data/lib/inst_statsd/null_logger.rb +3 -4
- data/lib/inst_statsd/request_logger.rb +4 -6
- data/lib/inst_statsd/request_stat.rb +26 -14
- data/lib/inst_statsd/request_tracking.rb +19 -18
- data/lib/inst_statsd/sql_tracker.rb +9 -11
- data/lib/inst_statsd/statsd.rb +63 -52
- data/lib/inst_statsd/version.rb +5 -0
- data/lib/inst_statsd.rb +36 -28
- data/spec/inst_statsd/block_stat_spec.rb +2 -2
- data/spec/inst_statsd/block_tracking_spec.rb +66 -46
- data/spec/inst_statsd/counter_spec.rb +21 -23
- data/spec/inst_statsd/event_spec.rb +160 -0
- data/spec/inst_statsd/inst_statsd_spec.rb +85 -81
- data/spec/inst_statsd/null_logger_spec.rb +11 -13
- data/spec/inst_statsd/request_logger_spec.rb +43 -50
- data/spec/inst_statsd/request_stat_spec.rb +98 -84
- data/spec/inst_statsd/request_tracking_spec.rb +6 -7
- data/spec/inst_statsd/sql_tracker_spec.rb +29 -31
- data/spec/inst_statsd/statsd_spec.rb +126 -87
- data/spec/spec_helper.rb +2 -2
- metadata +67 -35
@@ -1,183 +1,197 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "spec_helper"
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
args = ['name', 1000, 1001, 1234, payload]
|
5
|
+
def create_subject(payload = {}, statsd = nil)
|
6
|
+
args = ["name", 1000, 1001, 1234, payload]
|
8
7
|
args << statsd if statsd
|
9
8
|
InstStatsd::RequestStat.new(*args)
|
10
9
|
end
|
11
10
|
|
12
|
-
|
13
11
|
describe InstStatsd::RequestStat do
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
rs = create_subject({db_runtime: 11.11})
|
12
|
+
describe "#db_runtime" do
|
13
|
+
it "should return the payload db_runtime" do
|
14
|
+
rs = create_subject({ db_runtime: 11.11 })
|
18
15
|
expect(rs.db_runtime).to eq 11.11
|
19
16
|
end
|
20
17
|
|
21
|
-
it
|
18
|
+
it "should return nil when payload db_runtime key doesnt exists" do
|
22
19
|
rs = create_subject
|
23
|
-
expect(rs.db_runtime).to
|
20
|
+
expect(rs.db_runtime).to be_nil
|
24
21
|
end
|
25
22
|
end
|
26
23
|
|
27
|
-
describe
|
28
|
-
it
|
24
|
+
describe "#view_runtime" do
|
25
|
+
it "should return the payload view_runtime" do
|
29
26
|
rs = create_subject(view_runtime: 11.11)
|
30
27
|
expect(rs.view_runtime).to eq 11.11
|
31
28
|
end
|
32
29
|
|
33
|
-
it
|
30
|
+
it "should return nil when payload view_runtime key doesnt exists" do
|
34
31
|
rs = create_subject
|
35
|
-
expect(rs.view_runtime).to
|
32
|
+
expect(rs.view_runtime).to be_nil
|
36
33
|
end
|
37
34
|
end
|
38
35
|
|
39
|
-
describe
|
36
|
+
describe "#controller" do
|
40
37
|
it "should return params['controller']" do
|
41
|
-
rs = create_subject({params: {
|
42
|
-
expect(rs.controller).to eq
|
38
|
+
rs = create_subject({ params: { "controller" => "foo" } })
|
39
|
+
expect(rs.controller).to eq "foo"
|
43
40
|
end
|
44
41
|
|
45
|
-
it
|
42
|
+
it "should return nil if no params are available" do
|
46
43
|
rs = create_subject
|
47
|
-
expect(rs.controller).to
|
44
|
+
expect(rs.controller).to be_nil
|
48
45
|
end
|
49
46
|
|
50
|
-
it
|
51
|
-
rs = create_subject({params: {}})
|
52
|
-
expect(rs.controller).to
|
47
|
+
it "should return nil if no controller is available on params" do
|
48
|
+
rs = create_subject({ params: {} })
|
49
|
+
expect(rs.controller).to be_nil
|
53
50
|
end
|
54
51
|
end
|
55
52
|
|
56
|
-
describe
|
53
|
+
describe "#action" do
|
57
54
|
it "should return params['action']" do
|
58
|
-
rs = create_subject({params: {
|
59
|
-
expect(rs.action).to eq
|
55
|
+
rs = create_subject({ params: { "action" => "index" } })
|
56
|
+
expect(rs.action).to eq "index"
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should return nil if no params are available" do
|
60
|
+
rs = create_subject
|
61
|
+
expect(rs.action).to be_nil
|
60
62
|
end
|
61
63
|
|
62
|
-
it
|
64
|
+
it "should return nil if no action is available on params" do
|
65
|
+
rs = create_subject({ params: {} })
|
66
|
+
expect(rs.action).to be_nil
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "#status" do
|
71
|
+
it "should return nil if status is not defined" do
|
63
72
|
rs = create_subject
|
64
|
-
expect(rs.
|
73
|
+
expect(rs.status).to be_nil
|
65
74
|
end
|
66
75
|
|
67
|
-
it
|
68
|
-
|
69
|
-
expect(
|
76
|
+
it "should return HTTP status group if present" do
|
77
|
+
expect(create_subject({ status: 200 }).status).to eq "2XX"
|
78
|
+
expect(create_subject({ status: 201 }).status).to eq "2XX"
|
79
|
+
expect(create_subject({ status: 302 }).status).to eq "3XX"
|
80
|
+
expect(create_subject({ status: 400 }).status).to eq "4XX"
|
81
|
+
expect(create_subject({ status: 404 }).status).to eq "4XX"
|
82
|
+
expect(create_subject({ status: 503 }).status).to eq "5XX"
|
70
83
|
end
|
71
84
|
end
|
72
85
|
|
73
|
-
describe
|
74
|
-
it
|
75
|
-
rs = create_subject({params: {}})
|
86
|
+
describe "#total" do
|
87
|
+
it "correctly calculates milliseconds from start, finish" do
|
88
|
+
rs = create_subject({ params: {} })
|
76
89
|
# start and finish are in seconds
|
77
90
|
expect(rs.total).to eq 1000
|
78
91
|
end
|
79
92
|
|
80
|
-
it
|
81
|
-
rs = InstStatsd::RequestStat.new(
|
93
|
+
it "defaults to zero if either start or finish are nil" do
|
94
|
+
rs = InstStatsd::RequestStat.new("name", nil, 1001, 1111, { params: {} })
|
82
95
|
expect(rs.total).to eq 0
|
83
|
-
rs = InstStatsd::RequestStat.new(
|
96
|
+
rs = InstStatsd::RequestStat.new("name", 1, nil, 1111, { params: {} })
|
84
97
|
expect(rs.total).to eq 0
|
85
98
|
end
|
86
99
|
end
|
87
100
|
|
88
|
-
describe
|
89
|
-
it
|
101
|
+
describe "#report" do
|
102
|
+
it "doesnt send stats when no controller or action" do
|
90
103
|
statsd = InstStatsd::Statsd
|
91
|
-
rs = create_subject({params: {}}, statsd)
|
92
|
-
expect(statsd).
|
104
|
+
rs = create_subject({ params: {} }, statsd)
|
105
|
+
expect(statsd).not_to receive(:timing).with("request.foo.index", 1000, { short_stat: nil, tags: {} })
|
93
106
|
rs.report
|
94
107
|
end
|
95
108
|
|
96
|
-
it
|
109
|
+
it "sends total timing when controller && action are present, doesnt send db, or view if they are not" do
|
97
110
|
statsd = InstStatsd::Statsd
|
98
111
|
payload = {
|
99
112
|
params: {
|
100
|
-
|
101
|
-
|
113
|
+
"controller" => "foo",
|
114
|
+
"action" => "index"
|
102
115
|
}
|
103
116
|
}
|
104
117
|
rs = create_subject(payload, statsd)
|
105
|
-
expect(statsd).to receive(:timing).with(
|
118
|
+
expect(statsd).to receive(:timing).with("request.foo.index.total", 1000, { short_stat: ".total", tags: {} })
|
106
119
|
rs.report
|
107
120
|
end
|
108
121
|
|
109
|
-
it
|
122
|
+
it "sends total timing when controller && action are present as tags for data dog" do
|
110
123
|
statsd = InstStatsd::Statsd
|
111
124
|
expect(statsd).to receive(:data_dog?).and_return true
|
112
125
|
payload = {
|
113
126
|
params: {
|
114
|
-
|
115
|
-
|
116
|
-
}
|
127
|
+
"controller" => "foo",
|
128
|
+
"action" => "index"
|
129
|
+
},
|
130
|
+
status: 200
|
117
131
|
}
|
118
132
|
rs = create_subject(payload, statsd)
|
119
|
-
expect(statsd).to receive(:timing).with(
|
133
|
+
expect(statsd).to receive(:timing).with("request.total",
|
134
|
+
1000,
|
135
|
+
{ short_stat: "request.total",
|
136
|
+
tags: { action: "index", controller: "foo", status: "2XX" } })
|
120
137
|
rs.report
|
121
138
|
end
|
122
139
|
|
123
|
-
it
|
140
|
+
it "sends view_runtime and db_runtime when present" do
|
124
141
|
statsd = InstStatsd::Statsd
|
125
142
|
payload = {
|
126
143
|
view_runtime: 70.1,
|
127
144
|
db_runtime: 100.2,
|
128
145
|
params: {
|
129
|
-
|
130
|
-
|
146
|
+
"controller" => "foo",
|
147
|
+
"action" => "index"
|
131
148
|
}
|
132
149
|
}
|
133
150
|
rs = create_subject(payload, statsd)
|
134
|
-
allow(statsd).to receive(:timing).with(
|
135
|
-
expect(statsd).to receive(:timing).with(
|
136
|
-
expect(statsd).to receive(:timing).with(
|
151
|
+
allow(statsd).to receive(:timing).with("request.foo.index.total", 1000, { short_stat: ".total", tags: {} })
|
152
|
+
expect(statsd).to receive(:timing).with("request.foo.index.view", 70.1, { short_stat: ".view", tags: {} })
|
153
|
+
expect(statsd).to receive(:timing).with("request.foo.index.db", 100.2, { short_stat: ".db", tags: {} })
|
137
154
|
rs.report
|
138
155
|
end
|
139
156
|
|
140
|
-
|
141
|
-
|
142
|
-
payload = {
|
143
|
-
params: {
|
144
|
-
'controller' => 'foo',
|
145
|
-
'action' => 'index'
|
146
|
-
}
|
147
|
-
}
|
148
|
-
end
|
149
|
-
|
150
|
-
describe 'sql stats' do
|
151
|
-
|
152
|
-
before :each do
|
157
|
+
describe "sql stats" do
|
158
|
+
before do
|
153
159
|
@statsd = InstStatsd::Statsd
|
154
160
|
payload = {
|
155
161
|
params: {
|
156
|
-
|
157
|
-
|
162
|
+
"controller" => "foo",
|
163
|
+
"action" => "index"
|
158
164
|
}
|
159
165
|
}
|
160
166
|
@rs = create_subject(payload, @statsd)
|
161
|
-
@rs.stats[
|
162
|
-
expect(@statsd).to receive(:timing).with(
|
167
|
+
@rs.stats["cache.read"] = 25
|
168
|
+
expect(@statsd).to receive(:timing).with("request.foo.index.cache.read",
|
169
|
+
25,
|
170
|
+
{ short_stat: ".cache.read", tags: {} })
|
163
171
|
end
|
164
172
|
|
165
|
-
it
|
166
|
-
allow(@statsd).to receive(:timing).with(
|
167
|
-
expect(@statsd).
|
168
|
-
|
169
|
-
|
173
|
+
it "doesnt send sql stats when they dont exist" do
|
174
|
+
allow(@statsd).to receive(:timing).with("request.foo.index.total", 1000, { short_stat: nil, tags: {} })
|
175
|
+
expect(@statsd).not_to receive(:timing).with("request.foo.index.sql.read",
|
176
|
+
kind_of(Numeric),
|
177
|
+
{ short_stat: ".sql.read", tags: {} })
|
178
|
+
expect(@statsd).not_to receive(:timing).with("request.foo.index.sql.write",
|
179
|
+
kind_of(Numeric),
|
180
|
+
{ short_stat: ".sql.write", tags: {} })
|
181
|
+
expect(@statsd).not_to receive(:timing).with("request.foo.index.sql.cache",
|
182
|
+
kind_of(Numeric),
|
183
|
+
{ short_stat: ".sql.cache", tags: {} })
|
170
184
|
@rs.report
|
171
185
|
end
|
172
186
|
|
173
|
-
it
|
174
|
-
@rs.stats[
|
175
|
-
allow(@statsd).to receive(:timing).with(
|
176
|
-
expect(@statsd).to receive(:timing).with(
|
187
|
+
it "sends sql_read_count when present" do
|
188
|
+
@rs.stats["sql.read"] = 10
|
189
|
+
allow(@statsd).to receive(:timing).with("request.foo.index.total", 1000, { short_stat: ".total", tags: {} })
|
190
|
+
expect(@statsd).to receive(:timing).with("request.foo.index.sql.read",
|
191
|
+
10,
|
192
|
+
{ short_stat: ".sql.read", tags: {} })
|
177
193
|
@rs.report
|
178
194
|
end
|
179
195
|
end
|
180
|
-
|
181
196
|
end
|
182
|
-
|
183
197
|
end
|
@@ -1,16 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "spec_helper"
|
4
4
|
|
5
5
|
describe InstStatsd::RequestTracking do
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
log_double = double()
|
6
|
+
describe "#enable" do
|
7
|
+
it "should delegate log messages to the optional logger" do
|
8
|
+
log_double = instance_double(Logger)
|
10
9
|
expect(log_double).to receive(:info)
|
11
10
|
InstStatsd::RequestTracking.enable logger: log_double
|
12
|
-
InstStatsd::RequestTracking.start_processing
|
13
|
-
InstStatsd::RequestTracking.finalize_processing
|
11
|
+
InstStatsd::RequestTracking.send(:start_processing)
|
12
|
+
InstStatsd::RequestTracking.send(:finalize_processing, "name", 1000, 10_001, 1234, {})
|
14
13
|
end
|
15
14
|
end
|
16
15
|
end
|
@@ -1,30 +1,29 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "spec_helper"
|
4
4
|
|
5
5
|
module InstStatsd
|
6
6
|
describe SqlTracker do
|
7
|
-
|
8
|
-
|
9
|
-
it 'resets values to zero' do
|
7
|
+
describe "#start" do
|
8
|
+
it "resets values to zero" do
|
10
9
|
subject = SqlTracker.new
|
11
10
|
subject.start
|
12
|
-
subject.track
|
11
|
+
subject.track "CACHE", "SELECT * FROM some_table"
|
13
12
|
cookies = subject.start
|
14
13
|
expect(subject.finalize_counts(cookies)).to eq([0, 0, 0])
|
15
14
|
end
|
16
15
|
end
|
17
16
|
|
18
|
-
describe
|
19
|
-
before
|
17
|
+
describe "#track" do
|
18
|
+
before do
|
20
19
|
@subject = SqlTracker.new
|
21
20
|
@cookies = @subject.start
|
22
21
|
end
|
23
22
|
|
24
23
|
def finish
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
return unless @num_reads.nil?
|
25
|
+
|
26
|
+
@num_reads, @num_writes, @num_caches = @subject.finalize_counts(@cookies)
|
28
27
|
end
|
29
28
|
|
30
29
|
def num_reads
|
@@ -42,57 +41,56 @@ module InstStatsd
|
|
42
41
|
@num_caches
|
43
42
|
end
|
44
43
|
|
45
|
-
it
|
46
|
-
@subject.track
|
44
|
+
it "considers CACHE above all" do
|
45
|
+
@subject.track "CACHE", "SELECT * FROM some_table"
|
47
46
|
expect(num_caches).to eq(1)
|
48
47
|
expect(num_reads).to eq(0)
|
49
48
|
end
|
50
49
|
|
51
|
-
it
|
52
|
-
@subject.track
|
50
|
+
it "marks as read when select is in the first 15 chars of the sql" do
|
51
|
+
@subject.track "LOAD", ' SELECT "context_external_tools".* FROM'
|
53
52
|
expect(num_reads).to eq(1)
|
54
53
|
expect(num_writes).to eq(0)
|
55
54
|
end
|
56
55
|
|
57
|
-
it
|
58
|
-
@subject.track
|
56
|
+
it "marks as read with no select, but a LOAD name" do
|
57
|
+
@subject.track "LOAD", "WITH RECURSIVE t AS"
|
59
58
|
expect(num_reads).to eq(1)
|
60
59
|
expect(num_writes).to eq(0)
|
61
60
|
end
|
62
61
|
|
63
|
-
it
|
64
|
-
tracker = SqlTracker.new(blocked_names: [
|
62
|
+
it "doesnt track names set as blocked" do
|
63
|
+
tracker = SqlTracker.new(blocked_names: ["SCHEMA"])
|
65
64
|
cookies = tracker.start
|
66
|
-
tracker.track
|
65
|
+
tracker.track "SCHEMA", "SELECT * FROM some_table"
|
67
66
|
expect(tracker.finalize_counts(cookies)[0]).to eq(0)
|
68
67
|
end
|
69
68
|
|
70
|
-
it
|
71
|
-
@subject.track nil,
|
72
|
-
@subject.track
|
69
|
+
it "doesnt track nil names or sql values" do
|
70
|
+
@subject.track nil, "SELECT *"
|
71
|
+
@subject.track "CACHE", nil
|
73
72
|
expect(num_reads).to eq(0)
|
74
73
|
end
|
75
74
|
|
76
|
-
it
|
77
|
-
sql =
|
78
|
-
read_counter = double
|
75
|
+
it "passes full sql to counter.track calls for reads" do
|
76
|
+
sql = " SELECT 'context_external_tools'.* FROM"
|
77
|
+
read_counter = double
|
79
78
|
allow(read_counter).to receive(:start)
|
80
79
|
expect(read_counter).to receive(:track).with sql
|
81
80
|
tracker = SqlTracker.new(read_counter: read_counter)
|
82
81
|
tracker.start
|
83
|
-
tracker.track
|
82
|
+
tracker.track "LOAD", sql
|
84
83
|
end
|
85
84
|
|
86
|
-
it
|
87
|
-
sql =
|
88
|
-
write_counter = double
|
85
|
+
it "passes full sql to counter.track calls for writes" do
|
86
|
+
sql = " UPDATE 'context_external_tools'.* FROM"
|
87
|
+
write_counter = double
|
89
88
|
allow(write_counter).to receive(:start)
|
90
89
|
expect(write_counter).to receive(:track).with sql
|
91
90
|
tracker = SqlTracker.new(write_counter: write_counter)
|
92
91
|
tracker.start
|
93
|
-
tracker.track
|
92
|
+
tracker.track "UPDATE", sql
|
94
93
|
end
|
95
94
|
end
|
96
|
-
|
97
95
|
end
|
98
96
|
end
|