librato-rails 1.4.2 → 2.0.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.tar.gz.sig +0 -0
- data/CHANGELOG.md +3 -0
- data/README.md +52 -73
- data/lib/librato/rails/configuration.rb +22 -3
- data/lib/librato/rails/railtie.rb +1 -2
- data/lib/librato/rails/subscribers/cache.rb +5 -3
- data/lib/librato/rails/subscribers/controller.rb +15 -12
- data/lib/librato/rails/subscribers/job.rb +17 -8
- data/lib/librato/rails/subscribers/mail.rb +11 -8
- data/lib/librato/rails/subscribers/method.rb +7 -9
- data/lib/librato/rails/subscribers/render.rb +13 -9
- data/lib/librato/rails/subscribers/sql.rb +11 -11
- data/lib/librato/rails/subscribers/status.rb +7 -9
- data/lib/librato/rails/tracker.rb +1 -1
- data/lib/librato/rails/version.rb +1 -1
- data/test/dummy/app/controllers/instrument_action_controller.rb +4 -0
- data/test/dummy/app/mailers/user_mailer.rb +5 -1
- data/test/dummy/config/routes.rb +1 -0
- data/test/fixtures/config/empty.yml +1 -1
- data/test/fixtures/config/librato.yml +4 -3
- data/test/fixtures/config/simple.yml +0 -2
- data/test/integration/cache_test.rb +5 -5
- data/test/integration/custom_test.rb +4 -4
- data/test/integration/instrument_action_test.rb +71 -23
- data/test/integration/job_test.rb +13 -3
- data/test/integration/mail_test.rb +9 -1
- data/test/integration/render_test.rb +12 -12
- data/test/integration/request_test.rb +40 -25
- data/test/integration/sql_test.rb +17 -7
- data/test/support/integration_case.rb +5 -1
- data/test/unit/configuration_test.rb +16 -11
- metadata +80 -55
- metadata.gz.sig +0 -0
- checksums.yaml +0 -7
- checksums.yaml.gz.sig +0 -0
- data/lib/librato/rails/subscribers/action.rb +0 -39
@@ -4,21 +4,21 @@ module Librato
|
|
4
4
|
|
5
5
|
# SQL
|
6
6
|
|
7
|
-
ActiveSupport::Notifications.subscribe
|
7
|
+
ActiveSupport::Notifications.subscribe "sql.active_record" do |*args|
|
8
|
+
|
8
9
|
payload = args.last
|
10
|
+
sql = payload[:sql].strip
|
9
11
|
|
10
12
|
collector.group "rails.sql" do |s|
|
11
|
-
|
12
|
-
s.increment
|
13
|
+
s.increment "queries"
|
14
|
+
s.increment "selects" if sql.starts_with?("SELECT")
|
15
|
+
s.increment "inserts" if sql.starts_with?("INSERT")
|
16
|
+
s.increment "updates" if sql.starts_with?("UPDATE")
|
17
|
+
s.increment "deletes" if sql.starts_with?("DELETE")
|
18
|
+
end # end group
|
13
19
|
|
14
|
-
|
15
|
-
s.increment 'selects' if sql.starts_with?('SELECT')
|
16
|
-
s.increment 'inserts' if sql.starts_with?('INSERT')
|
17
|
-
s.increment 'updates' if sql.starts_with?('UPDATE')
|
18
|
-
s.increment 'deletes' if sql.starts_with?('DELETE')
|
19
|
-
end
|
20
|
-
end
|
20
|
+
end # end subscribe
|
21
21
|
|
22
22
|
end
|
23
23
|
end
|
24
|
-
end
|
24
|
+
end
|
@@ -2,19 +2,17 @@ module Librato
|
|
2
2
|
module Rails
|
3
3
|
module Subscribers
|
4
4
|
|
5
|
-
#
|
5
|
+
# ActionController Status
|
6
6
|
|
7
|
-
ActiveSupport::Notifications.subscribe
|
7
|
+
ActiveSupport::Notifications.subscribe "process_action.action_controller" do |*args|
|
8
8
|
|
9
9
|
event = ActiveSupport::Notifications::Event.new(*args)
|
10
|
-
|
10
|
+
tags = { status: event.payload[:status] }
|
11
11
|
|
12
|
-
unless status.blank?
|
13
|
-
collector.group "rails.request
|
14
|
-
s.increment status
|
15
|
-
s.
|
16
|
-
s.timing "#{status}.time", event.duration
|
17
|
-
s.timing "#{status.to_s[0]}xx.time", event.duration
|
12
|
+
unless tags[:status].blank?
|
13
|
+
collector.group "rails.request" do |s|
|
14
|
+
s.increment "status", tags: tags, inherit_tags: true
|
15
|
+
s.timing "status.time", event.duration, tags: tags, inherit_tags: true
|
18
16
|
end # end group
|
19
17
|
end
|
20
18
|
|
data/test/dummy/config/routes.rb
CHANGED
@@ -19,6 +19,7 @@ Dummy::Application.routes.draw do
|
|
19
19
|
|
20
20
|
get 'instrument/inst' => 'instrument_action#inst', :as => :instrument_action
|
21
21
|
get 'instrument/not' => 'instrument_action#not', :as => :not_instrumented
|
22
|
+
get '/invalid_format' => 'instrument_action#invalid_format'
|
22
23
|
|
23
24
|
get 'base/action_1' => 'base#action_1', :as => :base_action_1
|
24
25
|
get 'base/action_2' => 'base#action_2', :as => :base_action_2
|
@@ -3,11 +3,12 @@ test:
|
|
3
3
|
token: <%= 'test api key' %>
|
4
4
|
prefix: 'rails-test'
|
5
5
|
flush_interval: 30
|
6
|
-
|
7
|
-
|
6
|
+
tags:
|
7
|
+
region: "us-east-1"
|
8
|
+
az: "b"
|
8
9
|
proxy: 'http://localhost:8080'
|
9
10
|
suites: all
|
10
|
-
|
11
|
+
|
11
12
|
production:
|
12
13
|
user: 'live@bar.com'
|
13
14
|
token: 'live api key'
|
@@ -5,35 +5,35 @@ class CacheTest < ActiveSupport::IntegrationCase
|
|
5
5
|
test 'cache read' do
|
6
6
|
visit cache_read_path
|
7
7
|
|
8
|
-
assert_equal 1, counters["rails.cache.read"]
|
8
|
+
assert_equal 1, counters["rails.cache.read"][:value]
|
9
9
|
assert_equal 1, aggregate["rails.cache.read.time"][:count]
|
10
10
|
end
|
11
11
|
|
12
12
|
test 'cache write' do
|
13
13
|
visit cache_write_path
|
14
14
|
|
15
|
-
assert_equal 1, counters["rails.cache.write"]
|
15
|
+
assert_equal 1, counters["rails.cache.write"][:value]
|
16
16
|
assert_equal 1, aggregate["rails.cache.write.time"][:count]
|
17
17
|
end
|
18
18
|
|
19
19
|
test 'cache fetch_hit' do
|
20
20
|
visit cache_fetch_hit_path
|
21
21
|
|
22
|
-
assert_equal 1, counters["rails.cache.fetch_hit"]
|
22
|
+
assert_equal 1, counters["rails.cache.fetch_hit"][:value]
|
23
23
|
assert_equal 1, aggregate["rails.cache.fetch_hit.time"][:count]
|
24
24
|
end
|
25
25
|
|
26
26
|
test 'cache generate' do
|
27
27
|
visit cache_generate_path
|
28
28
|
|
29
|
-
assert_equal 1, counters["rails.cache.generate"]
|
29
|
+
assert_equal 1, counters["rails.cache.generate"][:value]
|
30
30
|
assert_equal 1, aggregate["rails.cache.generate.time"][:count]
|
31
31
|
end
|
32
32
|
|
33
33
|
test 'cache delete' do
|
34
34
|
visit cache_delete_path
|
35
35
|
|
36
|
-
assert_equal 1, counters["rails.cache.delete"]
|
36
|
+
assert_equal 1, counters["rails.cache.delete"][:value]
|
37
37
|
assert_equal 1, aggregate["rails.cache.delete.time"][:count]
|
38
38
|
end
|
39
39
|
|
@@ -5,8 +5,8 @@ class CustomTest < ActiveSupport::IntegrationCase
|
|
5
5
|
test 'controller access' do
|
6
6
|
visit custom_path
|
7
7
|
|
8
|
-
assert_equal 1, counters['custom.visits']
|
9
|
-
assert_equal 3, counters['custom.events']
|
8
|
+
assert_equal 1, counters['custom.visits'][:value]
|
9
|
+
assert_equal 3, counters['custom.events'][:value]
|
10
10
|
|
11
11
|
assert_equal 12, aggregate['custom.timing'][:sum]
|
12
12
|
assert_equal 2, aggregate['custom.timing'][:count]
|
@@ -15,7 +15,7 @@ class CustomTest < ActiveSupport::IntegrationCase
|
|
15
15
|
test 'model class access' do
|
16
16
|
visit custom_path
|
17
17
|
|
18
|
-
assert_equal 3, counters['custom.model.lookups']
|
18
|
+
assert_equal 3, counters['custom.model.lookups'][:value]
|
19
19
|
assert_equal 19.0, aggregate['custom.model.search'][:sum]
|
20
20
|
assert_equal 2, aggregate['custom.model.search'][:count]
|
21
21
|
end
|
@@ -23,7 +23,7 @@ class CustomTest < ActiveSupport::IntegrationCase
|
|
23
23
|
test 'model instance access' do
|
24
24
|
visit custom_path
|
25
25
|
|
26
|
-
assert_equal 1, counters['custom.model.touch']
|
26
|
+
assert_equal 1, counters['custom.model.touch'][:value]
|
27
27
|
end
|
28
28
|
|
29
29
|
end
|
@@ -2,51 +2,99 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
class InstrumentActionTest < ActiveSupport::IntegrationCase
|
4
4
|
|
5
|
-
test
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
test "instrument controller action" do
|
6
|
+
tags = {
|
7
|
+
controller: "InstrumentActionController",
|
8
|
+
action: "inst",
|
9
|
+
format: "html"
|
10
|
+
}.merge(default_tags)
|
10
11
|
|
11
|
-
|
12
|
+
visit instrument_action_path
|
12
13
|
|
13
|
-
base =
|
14
|
+
base = "rails.request"
|
14
15
|
timings = %w{time time.db time.view}
|
15
16
|
timings.each do |t|
|
16
|
-
assert_equal 1, aggregate.fetch("#{base}.#{t}",
|
17
|
+
assert_equal 1, aggregate.fetch("#{base}.#{t}", tags: tags)[:count]
|
17
18
|
end
|
18
19
|
|
19
|
-
assert_equal 1, counters.fetch("#{base}.total",
|
20
|
+
assert_equal 1, counters.fetch("#{base}.total", tags: tags)[:value]
|
20
21
|
end
|
21
22
|
|
22
|
-
test
|
23
|
+
test "instrument all controller actions" do
|
23
24
|
visit base_action_1_path
|
24
25
|
visit base_action_2_path
|
25
26
|
|
26
|
-
metric =
|
27
|
-
|
28
|
-
assert_equal 1, aggregate.fetch(metric,
|
29
|
-
|
27
|
+
metric = "rails.request.time"
|
28
|
+
|
29
|
+
assert_equal 1, aggregate.fetch(metric,
|
30
|
+
tags: {
|
31
|
+
controller: "BaseController",
|
32
|
+
action: "action_1",
|
33
|
+
format: "html"
|
34
|
+
}.merge(default_tags))[:count]
|
35
|
+
assert_equal 1, aggregate.fetch(metric,
|
36
|
+
tags: {
|
37
|
+
controller: "BaseController",
|
38
|
+
action: "action_2",
|
39
|
+
format: "html"
|
40
|
+
}.merge(default_tags))[:count]
|
30
41
|
end
|
31
42
|
|
32
|
-
test
|
43
|
+
test "instrument all controller actions for inherited controllers" do
|
33
44
|
visit intermediate_action_1_path
|
34
45
|
visit derived_action_1_path
|
35
46
|
visit derived_action_2_path
|
36
47
|
|
37
|
-
metric =
|
38
|
-
|
39
|
-
assert_equal 1, aggregate.fetch(metric,
|
40
|
-
|
41
|
-
|
48
|
+
metric = "rails.request.time"
|
49
|
+
|
50
|
+
assert_equal 1, aggregate.fetch(metric,
|
51
|
+
tags: {
|
52
|
+
controller: "IntermediateController",
|
53
|
+
action: "action_1",
|
54
|
+
format: "html"
|
55
|
+
}.merge(default_tags))[:count]
|
56
|
+
assert_equal 1, aggregate.fetch(metric,
|
57
|
+
tags: {
|
58
|
+
controller: "DerivedController",
|
59
|
+
action: "action_1",
|
60
|
+
format: "html"
|
61
|
+
}.merge(default_tags))[:count]
|
62
|
+
assert_equal 1, aggregate.fetch(metric,
|
63
|
+
tags: {
|
64
|
+
controller: "DerivedController",
|
65
|
+
action: "action_2",
|
66
|
+
format: "html"
|
67
|
+
}.merge(default_tags))[:count]
|
42
68
|
end
|
43
69
|
|
44
|
-
test
|
70
|
+
test "instrument all controller actions for all controllers" do
|
45
71
|
visit not_instrumented_path
|
46
72
|
|
47
|
-
metric =
|
73
|
+
metric = "rails.request.time"
|
74
|
+
|
75
|
+
assert_equal 1, aggregate.fetch(metric,
|
76
|
+
tags: {
|
77
|
+
controller: "InstrumentActionController",
|
78
|
+
action: "not",
|
79
|
+
format: "html"
|
80
|
+
}.merge(default_tags))[:count]
|
81
|
+
end
|
82
|
+
|
83
|
+
test "instrument invalid format" do
|
84
|
+
Capybara.current_session.driver.header "Accept", "*/*"
|
85
|
+
|
86
|
+
visit "/invalid_format"
|
87
|
+
|
88
|
+
metric = "rails.request.time"
|
89
|
+
|
90
|
+
assert_equal 1, aggregate.fetch(metric,
|
91
|
+
tags: {
|
92
|
+
controller: "InstrumentActionController",
|
93
|
+
action: "invalid_format",
|
94
|
+
format: "all"
|
95
|
+
}.merge(default_tags))[:count]
|
48
96
|
|
49
|
-
|
97
|
+
Capybara.current_session.driver.header "Accept", nil
|
50
98
|
end
|
51
99
|
|
52
100
|
end
|
@@ -3,16 +3,26 @@ require 'test_helper'
|
|
3
3
|
class JobTest < ActiveSupport::IntegrationCase
|
4
4
|
Librato::Rails::VersionSpecifier.supported(min: '4.2') do
|
5
5
|
test 'jobs performed' do
|
6
|
+
tags = {
|
7
|
+
adapter: "inline_adapter",
|
8
|
+
job: "dummy_job"
|
9
|
+
}.merge(default_tags)
|
10
|
+
|
6
11
|
DummyJob.perform_now
|
7
12
|
|
8
|
-
assert_equal 1, counters
|
9
|
-
assert_equal 1, aggregate.fetch(
|
13
|
+
assert_equal 1, counters.fetch("rails.job.perform", tags: tags)[:value]
|
14
|
+
assert_equal 1, aggregate.fetch("rails.job.perform.time", tags: tags)[:count]
|
10
15
|
end
|
11
16
|
|
12
17
|
test 'jobs enqueued' do
|
18
|
+
tags = {
|
19
|
+
adapter: "inline_adapter",
|
20
|
+
job: "dummy_job"
|
21
|
+
}.merge(default_tags)
|
22
|
+
|
13
23
|
DummyJob.perform_later
|
14
24
|
|
15
|
-
assert_equal 1, counters
|
25
|
+
assert_equal 1, counters.fetch("rails.job.enqueue", tags: tags)[:value]
|
16
26
|
end
|
17
27
|
end
|
18
28
|
end
|
@@ -4,8 +4,16 @@ class MailTest < ActiveSupport::IntegrationCase
|
|
4
4
|
|
5
5
|
test 'mail sent' do
|
6
6
|
user = User.create!(:email => 'foo@foo.com', :password => 'wow')
|
7
|
+
tags = { mailer: "UserMailer" }.merge(default_tags)
|
7
8
|
UserMailer.welcome_email(user).deliver
|
8
|
-
assert_equal 1, counters
|
9
|
+
assert_equal 1, counters.fetch("rails.mail.sent", tags: tags)[:value]
|
10
|
+
end
|
11
|
+
|
12
|
+
test "mail received" do
|
13
|
+
user = User.create!(email: "foo@foo.com", password: "foobar")
|
14
|
+
tags = { mailer: "UserMailer" }.merge(default_tags)
|
15
|
+
UserMailer.receive(user.email)
|
16
|
+
assert_equal 1, counters.fetch("rails.mail.received", tags: tags)[:value]
|
9
17
|
end
|
10
18
|
|
11
19
|
end
|
@@ -5,23 +5,23 @@ class RenderTest < ActiveSupport::IntegrationCase
|
|
5
5
|
test 'render partial' do
|
6
6
|
visit render_partial_path
|
7
7
|
|
8
|
-
assert_equal 1, counters.fetch("rails.view.
|
9
|
-
|
10
|
-
assert_equal 1, counters.fetch("rails.view.
|
11
|
-
|
12
|
-
assert_equal 1, aggregate.fetch("rails.view.
|
13
|
-
|
14
|
-
assert_equal 1, aggregate.fetch("rails.view.
|
15
|
-
|
8
|
+
assert_equal 1, counters.fetch("rails.view.render.partial",
|
9
|
+
tags: { partial: "render:first.html.erb" }.merge(default_tags))[:value]
|
10
|
+
assert_equal 1, counters.fetch("rails.view.render.partial",
|
11
|
+
tags: { partial: "render:second.html.erb" }.merge(default_tags))[:value]
|
12
|
+
assert_equal 1, aggregate.fetch("rails.view.render.partial.time",
|
13
|
+
tags: { partial: "render:first.html.erb" }.merge(default_tags))[:count]
|
14
|
+
assert_equal 1, aggregate.fetch("rails.view.render.partial.time",
|
15
|
+
tags: { partial: "render:second.html.erb" }.merge(default_tags))[:count]
|
16
16
|
end
|
17
17
|
|
18
18
|
test 'render template' do
|
19
19
|
visit render_template_path
|
20
20
|
|
21
|
-
assert_equal 1, counters.fetch("rails.view.
|
22
|
-
|
23
|
-
assert_equal 1, aggregate.fetch("rails.view.
|
24
|
-
|
21
|
+
assert_equal 1, counters.fetch("rails.view.render.template",
|
22
|
+
tags: { template: "render:template.html.erb" }.merge(default_tags))[:value]
|
23
|
+
assert_equal 1, aggregate.fetch("rails.view.render.template.time",
|
24
|
+
tags: { template: "render:template.html.erb" }.merge(default_tags))[:count]
|
25
25
|
end
|
26
26
|
|
27
27
|
end
|
@@ -5,52 +5,67 @@ class RequestTest < ActiveSupport::IntegrationCase
|
|
5
5
|
# Each request
|
6
6
|
|
7
7
|
test 'increment total and status' do
|
8
|
+
tags_1 = {
|
9
|
+
controller: "HomeController",
|
10
|
+
action: "index",
|
11
|
+
format: "html"
|
12
|
+
}.merge(default_tags)
|
13
|
+
|
8
14
|
visit root_path
|
9
15
|
|
10
|
-
assert_equal 1, counters
|
11
|
-
assert_equal 1, counters
|
12
|
-
assert_equal 1, counters
|
13
|
-
|
16
|
+
assert_equal 1, counters.fetch("rails.request.total", tags: tags_1)[:value]
|
17
|
+
assert_equal 1, counters.fetch("rails.request.status", tags: { status: 200 }.merge(default_tags))[:value]
|
18
|
+
assert_equal 1, counters.fetch("rails.request.method", tags: { method: "get" }.merge(default_tags))[:value]
|
19
|
+
|
20
|
+
visit root_path
|
21
|
+
|
22
|
+
assert_equal 2, counters.fetch("rails.request.total", tags: tags_1)[:value]
|
23
|
+
|
24
|
+
tags_2 = {
|
25
|
+
controller: "StatusController",
|
26
|
+
action: "index",
|
27
|
+
format: "html"
|
28
|
+
}.merge(default_tags)
|
14
29
|
|
15
30
|
visit '/status/204'
|
16
31
|
|
17
|
-
assert_equal
|
18
|
-
assert_equal 1, counters
|
19
|
-
assert_equal 1, counters["rails.request.status.204"]
|
20
|
-
assert_equal 2, counters["rails.request.status.2xx"]
|
32
|
+
assert_equal 1, counters.fetch("rails.request.total", tags: tags_2)[:value]
|
33
|
+
assert_equal 1, counters.fetch("rails.request.status", tags: { status: 204 }.merge(default_tags))[:value]
|
21
34
|
end
|
22
35
|
|
23
36
|
test 'request times' do
|
37
|
+
tags = {
|
38
|
+
controller: "HomeController",
|
39
|
+
action: "index",
|
40
|
+
format: "html"
|
41
|
+
}.merge(default_tags)
|
42
|
+
|
24
43
|
visit root_path
|
25
44
|
|
26
45
|
# common for all paths
|
27
|
-
assert_equal 1, aggregate
|
46
|
+
assert_equal 1, aggregate.fetch("rails.request.time", tags: tags)[:count],
|
28
47
|
'should record total time'
|
29
|
-
assert_equal 1, aggregate
|
48
|
+
assert_equal 1, aggregate.fetch("rails.request.time.db", tags: tags)[:count],
|
30
49
|
'should record db time'
|
31
|
-
assert_equal 1, aggregate
|
50
|
+
assert_equal 1, aggregate.fetch("rails.request.time.view", tags: tags)[:count],
|
32
51
|
'should record view time'
|
33
52
|
|
34
53
|
# status specific
|
35
|
-
assert_equal 1, aggregate
|
36
|
-
assert_equal 1, aggregate["rails.request.status.2xx.time"][:count]
|
54
|
+
assert_equal 1, aggregate.fetch("rails.request.status.time", tags: { status: 200 }.merge(default_tags))[:count]
|
37
55
|
|
38
56
|
# http method specific
|
39
|
-
assert_equal 1, aggregate
|
40
|
-
end
|
41
|
-
|
42
|
-
test 'track exceptions' do
|
43
|
-
begin
|
44
|
-
visit exception_path #rescue nil
|
45
|
-
rescue RuntimeError => e
|
46
|
-
raise unless e.message == 'test exception!'
|
47
|
-
end
|
48
|
-
assert_equal 1, counters["rails.request.exceptions"]
|
57
|
+
assert_equal 1, aggregate.fetch("rails.request.method.time", tags: { method: "get" }.merge(default_tags))[:count]
|
49
58
|
end
|
50
59
|
|
51
60
|
test 'track slow requests' do
|
61
|
+
tags = {
|
62
|
+
controller: "HomeController",
|
63
|
+
action: "slow",
|
64
|
+
format: "html"
|
65
|
+
}.merge(default_tags)
|
66
|
+
|
52
67
|
visit slow_path
|
53
|
-
assert_equal 1, counters
|
68
|
+
assert_equal 1, counters.fetch("rails.request.slow", tags: tags)[:value]
|
54
69
|
end
|
55
70
|
|
56
|
-
end
|
71
|
+
end
|