harness 0.9.1 → 1.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.
- checksums.yaml +4 -4
- data/.travis.yml +2 -0
- data/README.md +108 -323
- data/harness.gemspec +3 -12
- data/lib/harness.rb +69 -68
- data/lib/harness/async_queue.rb +29 -0
- data/lib/harness/fake_collector.rb +40 -0
- data/lib/harness/instrumentation.rb +21 -6
- data/lib/harness/null_collector.rb +23 -0
- data/lib/harness/subscription.rb +7 -0
- data/lib/harness/sync_queue.rb +14 -0
- data/lib/harness/version.rb +1 -1
- data/test/acceptance_test.rb +20 -0
- data/test/active_support_notifications_test.rb +93 -0
- data/test/async_queue_test.rb +14 -0
- data/test/instrumentation_test.rb +54 -0
- data/test/null_collector_test.rb +29 -0
- data/test/test_helper.rb +38 -34
- metadata +21 -196
- data/lib/harness/adapters/librato_adapter.rb +0 -90
- data/lib/harness/adapters/memory_adapter.rb +0 -27
- data/lib/harness/adapters/null_adapter.rb +0 -11
- data/lib/harness/adapters/stathat_adapter.rb +0 -75
- data/lib/harness/adapters/statsd_adapter.rb +0 -50
- data/lib/harness/consumer.rb +0 -35
- data/lib/harness/counter.rb +0 -29
- data/lib/harness/gauge.rb +0 -23
- data/lib/harness/integration/action_controller.rb +0 -9
- data/lib/harness/integration/action_mailer.rb +0 -9
- data/lib/harness/integration/action_view.rb +0 -9
- data/lib/harness/integration/active_model_serializers.rb +0 -9
- data/lib/harness/integration/active_support.rb +0 -9
- data/lib/harness/integration/sidekiq.rb +0 -47
- data/lib/harness/job.rb +0 -23
- data/lib/harness/measurement.rb +0 -43
- data/lib/harness/queues/delayed_job_queue.rb +0 -7
- data/lib/harness/queues/resque_queue.rb +0 -29
- data/lib/harness/queues/sidekiq_queue.rb +0 -31
- data/lib/harness/queues/synchronous_queue.rb +0 -18
- data/lib/harness/railtie.rb +0 -71
- data/lib/harness/tasks.rake +0 -6
- data/test/integration/counters_with_redis_test.rb +0 -67
- data/test/integration/instrumentation_test.rb +0 -50
- data/test/integration/integrations/action_controller_test.rb +0 -51
- data/test/integration/integrations/action_mailer_test.rb +0 -22
- data/test/integration/integrations/action_view_test.rb +0 -32
- data/test/integration/integrations/active_model_serializers_test.rb +0 -22
- data/test/integration/integrations/active_support_test.rb +0 -41
- data/test/integration/integrations/sidekiq_test.rb +0 -54
- data/test/integration/logging_test.rb +0 -17
- data/test/integration/queues/delayed_job_test.rb +0 -59
- data/test/integration/queues/resque_test.rb +0 -24
- data/test/integration/queues/sidekiq_test.rb +0 -34
- data/test/integration/railtie_test.rb +0 -26
- data/test/unit/adapters/librato_adapter_test.rb +0 -169
- data/test/unit/adapters/memory_adapter_test.rb +0 -22
- data/test/unit/adapters/stathat_adapter_test.rb +0 -144
- data/test/unit/adapters/statsd_adapter_test.rb +0 -74
- data/test/unit/counter_test.rb +0 -84
- data/test/unit/gauge_test.rb +0 -93
- data/test/unit/harness_test.rb +0 -39
- data/test/unit/measurement_test.rb +0 -76
@@ -1,22 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
require 'harness/integration/active_model_serializers'
|
3
|
-
|
4
|
-
class ActiveModelSerializerIntegration < IntegrationTest
|
5
|
-
def test_serializable_hash_is_logged
|
6
|
-
instrument "serializable_hash"
|
7
|
-
|
8
|
-
assert_gauge_logged "serializable_hash.serializer"
|
9
|
-
end
|
10
|
-
|
11
|
-
def test_serializing_associations_is_logged
|
12
|
-
instrument "associations"
|
13
|
-
|
14
|
-
assert_gauge_logged "associations.serializer"
|
15
|
-
end
|
16
|
-
|
17
|
-
def instrument(event)
|
18
|
-
ActiveSupport::Notifications.instrument "#{event}.serializer" do |*args|
|
19
|
-
# nada
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
@@ -1,41 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class ActiveSupportIntegration < IntegrationTest
|
4
|
-
def test_logs_cache_read
|
5
|
-
instrument "cache_read"
|
6
|
-
|
7
|
-
assert_gauge_logged "cache_read.active_support"
|
8
|
-
end
|
9
|
-
|
10
|
-
def test_logs_cache_generate
|
11
|
-
instrument "cache_generate"
|
12
|
-
|
13
|
-
assert_gauge_logged "cache_generate.active_support"
|
14
|
-
end
|
15
|
-
|
16
|
-
def test_logs_cache_fetch_hit
|
17
|
-
instrument "cache_fetch_hit"
|
18
|
-
|
19
|
-
assert_gauge_logged "cache_fetch_hit.active_support"
|
20
|
-
end
|
21
|
-
|
22
|
-
def test_logs_cache_write
|
23
|
-
instrument "cache_write"
|
24
|
-
|
25
|
-
assert_gauge_logged "cache_write.active_support"
|
26
|
-
end
|
27
|
-
|
28
|
-
def test_logs_cache_delete
|
29
|
-
instrument "cache_delete"
|
30
|
-
|
31
|
-
assert_gauge_logged "cache_delete.active_support"
|
32
|
-
end
|
33
|
-
|
34
|
-
private
|
35
|
-
def instrument(event)
|
36
|
-
require 'harness/integration/active_support'
|
37
|
-
ActiveSupport::Notifications.instrument "#{event}.active_support" do |*args|
|
38
|
-
# nada
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
@@ -1,54 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
require 'sidekiq'
|
3
|
-
require 'harness/integration/sidekiq'
|
4
|
-
|
5
|
-
class SidekiqIntegrationTest < IntegrationTest
|
6
|
-
def middleware
|
7
|
-
Sidekiq::Middleware::Server::HarnessInstrumentation.new
|
8
|
-
end
|
9
|
-
|
10
|
-
def tests_logs_job_performance_stats
|
11
|
-
middleware.call("report", nil, nil) { }
|
12
|
-
|
13
|
-
assert_gauge_logged "report.sidekiq"
|
14
|
-
assert_counter_logged "reports.sidekiq"
|
15
|
-
end
|
16
|
-
|
17
|
-
def tests_logs_a_counter_of_all_jobs
|
18
|
-
middleware.call("reports", nil, nil) { }
|
19
|
-
|
20
|
-
assert_counter_logged "job.sidekiq"
|
21
|
-
end
|
22
|
-
|
23
|
-
def test_ignores_harness_jobs
|
24
|
-
middleware.call("Harness::SidekiqQueue::SendCounter", nil, nil) { }
|
25
|
-
|
26
|
-
assert_empty counters
|
27
|
-
assert_empty gauges
|
28
|
-
|
29
|
-
middleware.call("Harness::SidekiqQueue::SendGauge", nil, nil) { }
|
30
|
-
|
31
|
-
assert_empty counters
|
32
|
-
assert_empty gauges
|
33
|
-
|
34
|
-
middleware.call(Harness::SidekiqQueue::SendCounter, nil, nil) { }
|
35
|
-
|
36
|
-
assert_empty counters
|
37
|
-
assert_empty gauges
|
38
|
-
|
39
|
-
middleware.call(Harness::SidekiqQueue::SendGauge, nil, nil) { }
|
40
|
-
|
41
|
-
assert_empty counters
|
42
|
-
assert_empty gauges
|
43
|
-
|
44
|
-
middleware.call(Harness::SidekiqQueue::SendCounter.new, nil, nil) { }
|
45
|
-
|
46
|
-
assert_empty counters
|
47
|
-
assert_empty gauges
|
48
|
-
|
49
|
-
middleware.call(Harness::SidekiqQueue::SendGauge.new, nil, nil) { }
|
50
|
-
|
51
|
-
assert_empty counters
|
52
|
-
assert_empty gauges
|
53
|
-
end
|
54
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class HarnessTest < IntegrationTest
|
4
|
-
def test_gauges_are_logged
|
5
|
-
gauge = Harness::Gauge.new :name => 'minitest'
|
6
|
-
gauge.log
|
7
|
-
|
8
|
-
assert_includes gauges, gauge
|
9
|
-
end
|
10
|
-
|
11
|
-
def test_counters_are_logged
|
12
|
-
counter = Harness::Counter.new :name => 'minitest'
|
13
|
-
counter.log
|
14
|
-
|
15
|
-
assert_includes counters, counter
|
16
|
-
end
|
17
|
-
end
|
@@ -1,59 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
require 'harness/queues/delayed_job_queue'
|
3
|
-
require 'fileutils'
|
4
|
-
|
5
|
-
class DelayedJobTest < IntegrationTest
|
6
|
-
def setup
|
7
|
-
super
|
8
|
-
|
9
|
-
tmp = File.expand_path('../../../tmp', __FILE__)
|
10
|
-
db = File.join(tmp, 'db.sqlite3')
|
11
|
-
|
12
|
-
FileUtils.mkdir_p tmp
|
13
|
-
FileUtils.rm_f db
|
14
|
-
|
15
|
-
ActiveRecord::Base.establish_connection(
|
16
|
-
:adapter => "sqlite3",
|
17
|
-
:database => db
|
18
|
-
)
|
19
|
-
|
20
|
-
Class.new(ActiveRecord::Migration) do
|
21
|
-
def self.up
|
22
|
-
suppress_messages do
|
23
|
-
create_table :delayed_jobs, :force => true do |table|
|
24
|
-
table.integer :priority, :default => 0 # Allows some jobs to jump to the front of the queue
|
25
|
-
table.integer :attempts, :default => 0 # Provides for retries, but still fail eventually.
|
26
|
-
table.text :handler # YAML-encoded string of the object that will do work
|
27
|
-
table.text :last_error # reason for last failure (See Note below)
|
28
|
-
table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future.
|
29
|
-
table.datetime :locked_at # Set when a client is working on this object
|
30
|
-
table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead)
|
31
|
-
table.string :locked_by # Who is working on this object (if locked)
|
32
|
-
table.string :queue # The name of the queue this job is in
|
33
|
-
table.timestamps
|
34
|
-
end
|
35
|
-
|
36
|
-
add_index :delayed_jobs, [:priority, :run_at], :name => 'delayed_jobs_priority'
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end.up
|
40
|
-
|
41
|
-
Delayed::Worker.delay_jobs = false
|
42
|
-
|
43
|
-
Harness.config.queue = :delayed_job
|
44
|
-
end
|
45
|
-
|
46
|
-
def test_a_gauge_is_logged
|
47
|
-
instrument "test-gauge", :gauge => true
|
48
|
-
|
49
|
-
assert_gauge_logged "test-gauge"
|
50
|
-
end
|
51
|
-
|
52
|
-
def test_a_counter_is_logged
|
53
|
-
instrument "test-counter", :counter => true
|
54
|
-
|
55
|
-
assert_counter_logged "test-counter"
|
56
|
-
|
57
|
-
assert_equal 1, counters.first.value
|
58
|
-
end
|
59
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
require 'harness/queues/resque_queue'
|
3
|
-
|
4
|
-
class ResqueTest < IntegrationTest
|
5
|
-
def setup
|
6
|
-
super
|
7
|
-
Resque.inline = true
|
8
|
-
Harness.config.queue = :resque
|
9
|
-
end
|
10
|
-
|
11
|
-
def test_a_gauge_is_logged
|
12
|
-
instrument "test-gauge", :gauge => true
|
13
|
-
|
14
|
-
assert_gauge_logged "test-gauge"
|
15
|
-
end
|
16
|
-
|
17
|
-
def test_a_counter_is_logged
|
18
|
-
instrument "test-counter", :counter => true
|
19
|
-
|
20
|
-
assert_counter_logged "test-counter"
|
21
|
-
|
22
|
-
assert_equal 1, counters.first.value
|
23
|
-
end
|
24
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
require 'harness/queues/sidekiq_queue'
|
3
|
-
require 'sidekiq/testing'
|
4
|
-
|
5
|
-
class SidekiqTest < IntegrationTest
|
6
|
-
def setup
|
7
|
-
super
|
8
|
-
Harness.config.queue = :sidekiq
|
9
|
-
end
|
10
|
-
|
11
|
-
def test_a_gauge_is_logged
|
12
|
-
instrument "test-gauge", :gauge => true
|
13
|
-
|
14
|
-
refute_empty Harness::SidekiqQueue::SendGauge.jobs
|
15
|
-
|
16
|
-
args = Harness::SidekiqQueue::SendGauge.jobs.first['args'].first
|
17
|
-
Harness::SidekiqQueue::SendGauge.new.perform args
|
18
|
-
|
19
|
-
assert_gauge_logged "test-gauge"
|
20
|
-
end
|
21
|
-
|
22
|
-
def test_a_counter_is_logged
|
23
|
-
instrument "test-counter", :counter => true
|
24
|
-
|
25
|
-
refute_empty Harness::SidekiqQueue::SendCounter.jobs
|
26
|
-
|
27
|
-
args = Harness::SidekiqQueue::SendCounter.jobs.first['args'].first
|
28
|
-
Harness::SidekiqQueue::SendCounter.new.perform args
|
29
|
-
|
30
|
-
assert_counter_logged "test-counter"
|
31
|
-
|
32
|
-
assert_equal 1, counters.first.value
|
33
|
-
end
|
34
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
require 'rails'
|
3
|
-
require 'action_controller/railtie'
|
4
|
-
require 'harness/railtie'
|
5
|
-
|
6
|
-
class TestRailsApp < Rails::Application
|
7
|
-
config.active_support.deprecation = proc { |message, stack| }
|
8
|
-
initialize!
|
9
|
-
end
|
10
|
-
|
11
|
-
class RailtieTest < MiniTest::Unit::TestCase
|
12
|
-
def app
|
13
|
-
TestRailsApp
|
14
|
-
end
|
15
|
-
|
16
|
-
def test_configures_instrumentation
|
17
|
-
assert app.config.harness.instrument.action_controller
|
18
|
-
assert app.config.harness.instrument.action_mailer
|
19
|
-
assert app.config.harness.instrument.action_view
|
20
|
-
refute app.config.harness.instrument.active_support
|
21
|
-
end
|
22
|
-
|
23
|
-
def test_configures_queue
|
24
|
-
assert_kind_of Harness::SynchronousQueue, app.config.harness.queue
|
25
|
-
end
|
26
|
-
end
|
@@ -1,169 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class LibratoAdapterTest < MiniTest::Unit::TestCase
|
4
|
-
def setup
|
5
|
-
@adapter = Harness::LibratoAdapter.new
|
6
|
-
|
7
|
-
@gauge = Harness::Gauge.new
|
8
|
-
@gauge.id = "fake-gauge"
|
9
|
-
@gauge.name = "Fake Gauge"
|
10
|
-
@gauge.source = "minitest"
|
11
|
-
@gauge.time = Time.now
|
12
|
-
@gauge.value = 55
|
13
|
-
|
14
|
-
@counter = Harness::Counter.new
|
15
|
-
@counter.id = "fake-counter"
|
16
|
-
@counter.name = "Fake Counter"
|
17
|
-
@counter.source = "minitest"
|
18
|
-
@counter.time = Time.now
|
19
|
-
@counter.value = 55
|
20
|
-
@counter.units = :bytes
|
21
|
-
|
22
|
-
Harness::LibratoAdapter.config.email = email
|
23
|
-
Harness::LibratoAdapter.config.token = token
|
24
|
-
Harness.config.namespace = nil
|
25
|
-
end
|
26
|
-
|
27
|
-
def test_gauge_is_logged
|
28
|
-
json = {
|
29
|
-
:gauges => [{
|
30
|
-
:name => @gauge.id,
|
31
|
-
:display_name => @gauge.name,
|
32
|
-
:value => @gauge.value,
|
33
|
-
:measure_time => @gauge.time.to_i,
|
34
|
-
:source => @gauge.source,
|
35
|
-
:attributes => { :display_units_short => @gauge.units }
|
36
|
-
}]
|
37
|
-
}.to_json
|
38
|
-
|
39
|
-
expected_request = stub_request(:post, "https://#{email}:#{token}@metrics-api.librato.com/v1/metrics").
|
40
|
-
with(:body => json, :headers => {"Content-Type" => "application/json"}).
|
41
|
-
to_return(:status => 200)
|
42
|
-
|
43
|
-
assert @adapter.log_gauge(@gauge)
|
44
|
-
assert_requested expected_request
|
45
|
-
end
|
46
|
-
|
47
|
-
def test_gauge_is_logged_with_namespace
|
48
|
-
Harness.config.namespace = :foo
|
49
|
-
|
50
|
-
json = {
|
51
|
-
:gauges => [{
|
52
|
-
:name => "#{@gauge.id}.foo",
|
53
|
-
:display_name => @gauge.name,
|
54
|
-
:value => @gauge.value,
|
55
|
-
:measure_time => @gauge.time.to_i,
|
56
|
-
:source => @gauge.source,
|
57
|
-
:attributes => { :display_units_short => @gauge.units }
|
58
|
-
}]
|
59
|
-
}.to_json
|
60
|
-
|
61
|
-
expected_request = stub_request(:post, "https://#{email}:#{token}@metrics-api.librato.com/v1/metrics").
|
62
|
-
with(:body => json, :headers => {"Content-Type" => "application/json"}).
|
63
|
-
to_return(:status => 200)
|
64
|
-
|
65
|
-
assert @adapter.log_gauge(@gauge)
|
66
|
-
assert_requested expected_request
|
67
|
-
end
|
68
|
-
|
69
|
-
def test_logging_gauge_raises_an_exception
|
70
|
-
stub_request(:post, %r{metrics}).to_return(:status => 500, :body => "message")
|
71
|
-
|
72
|
-
assert_raises Harness::LoggingError do
|
73
|
-
@adapter.log_gauge @gauge
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
def test_logging_gauge_raises_an_exception_when_id_is_too_long
|
78
|
-
@gauge.id = "f" * 64
|
79
|
-
|
80
|
-
assert_raises Harness::LibratoAdapter::NameTooLong do
|
81
|
-
@adapter.log_gauge @gauge
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
def test_logging_gauge_raises_an_exception_when_not_configured
|
86
|
-
Harness::LibratoAdapter.config.email = nil
|
87
|
-
Harness::LibratoAdapter.config.token = nil
|
88
|
-
|
89
|
-
assert_raises RuntimeError do
|
90
|
-
@adapter.log_gauge @gauge
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
def test_counter_is_logged
|
95
|
-
json = {
|
96
|
-
:counters => [{
|
97
|
-
:name => @counter.id,
|
98
|
-
:display_name => @counter.name,
|
99
|
-
:value => @counter.value,
|
100
|
-
:measure_time => @counter.time.to_i,
|
101
|
-
:source => @counter.source,
|
102
|
-
:attributes => { :display_units_short => @counter.units }
|
103
|
-
}]
|
104
|
-
}.to_json
|
105
|
-
|
106
|
-
expected_request = stub_request(:post, "https://#{email}:#{token}@metrics-api.librato.com/v1/metrics").
|
107
|
-
with(:body => json, :headers => {"Content-Type" => "application/json"}).
|
108
|
-
to_return(:status => 200)
|
109
|
-
|
110
|
-
assert @adapter.log_counter(@counter)
|
111
|
-
assert_requested expected_request
|
112
|
-
end
|
113
|
-
|
114
|
-
def test_counter_is_logged_with_namespace
|
115
|
-
Harness.config.namespace = :foo
|
116
|
-
|
117
|
-
json = {
|
118
|
-
:counters => [{
|
119
|
-
:name => "#{@counter.id}.foo",
|
120
|
-
:display_name => @counter.name,
|
121
|
-
:value => @counter.value,
|
122
|
-
:measure_time => @counter.time.to_i,
|
123
|
-
:source => @counter.source,
|
124
|
-
:attributes => { :display_units_short => @counter.units }
|
125
|
-
}]
|
126
|
-
}.to_json
|
127
|
-
|
128
|
-
expected_request = stub_request(:post, "https://#{email}:#{token}@metrics-api.librato.com/v1/metrics").
|
129
|
-
with(:body => json, :headers => {"Content-Type" => "application/json"}).
|
130
|
-
to_return(:status => 200)
|
131
|
-
|
132
|
-
assert @adapter.log_counter(@counter)
|
133
|
-
assert_requested expected_request
|
134
|
-
end
|
135
|
-
|
136
|
-
def test_logging_counter_raises_an_exception
|
137
|
-
stub_request(:post, %r{metrics}).to_return(:status => 500, :body => "message")
|
138
|
-
|
139
|
-
assert_raises Harness::LoggingError do
|
140
|
-
@adapter.log_counter @counter
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
def test_logging_counter_raises_an_exception_when_not_configured
|
145
|
-
Harness::LibratoAdapter.config.email = nil
|
146
|
-
Harness::LibratoAdapter.config.token = nil
|
147
|
-
|
148
|
-
assert_raises RuntimeError do
|
149
|
-
@adapter.log_counter @counter
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
def test_logging_counter_raises_an_exception_when_id_is_too_long
|
154
|
-
@counter.id = "f" * 64
|
155
|
-
|
156
|
-
assert_raises Harness::LibratoAdapter::NameTooLong do
|
157
|
-
@adapter.log_counter @counter
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
|
-
private
|
162
|
-
def email
|
163
|
-
'example@example.com'
|
164
|
-
end
|
165
|
-
|
166
|
-
def token
|
167
|
-
'a-complete-api-token'
|
168
|
-
end
|
169
|
-
end
|