harness 0.9.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -0
  3. data/README.md +108 -323
  4. data/harness.gemspec +3 -12
  5. data/lib/harness.rb +69 -68
  6. data/lib/harness/async_queue.rb +29 -0
  7. data/lib/harness/fake_collector.rb +40 -0
  8. data/lib/harness/instrumentation.rb +21 -6
  9. data/lib/harness/null_collector.rb +23 -0
  10. data/lib/harness/subscription.rb +7 -0
  11. data/lib/harness/sync_queue.rb +14 -0
  12. data/lib/harness/version.rb +1 -1
  13. data/test/acceptance_test.rb +20 -0
  14. data/test/active_support_notifications_test.rb +93 -0
  15. data/test/async_queue_test.rb +14 -0
  16. data/test/instrumentation_test.rb +54 -0
  17. data/test/null_collector_test.rb +29 -0
  18. data/test/test_helper.rb +38 -34
  19. metadata +21 -196
  20. data/lib/harness/adapters/librato_adapter.rb +0 -90
  21. data/lib/harness/adapters/memory_adapter.rb +0 -27
  22. data/lib/harness/adapters/null_adapter.rb +0 -11
  23. data/lib/harness/adapters/stathat_adapter.rb +0 -75
  24. data/lib/harness/adapters/statsd_adapter.rb +0 -50
  25. data/lib/harness/consumer.rb +0 -35
  26. data/lib/harness/counter.rb +0 -29
  27. data/lib/harness/gauge.rb +0 -23
  28. data/lib/harness/integration/action_controller.rb +0 -9
  29. data/lib/harness/integration/action_mailer.rb +0 -9
  30. data/lib/harness/integration/action_view.rb +0 -9
  31. data/lib/harness/integration/active_model_serializers.rb +0 -9
  32. data/lib/harness/integration/active_support.rb +0 -9
  33. data/lib/harness/integration/sidekiq.rb +0 -47
  34. data/lib/harness/job.rb +0 -23
  35. data/lib/harness/measurement.rb +0 -43
  36. data/lib/harness/queues/delayed_job_queue.rb +0 -7
  37. data/lib/harness/queues/resque_queue.rb +0 -29
  38. data/lib/harness/queues/sidekiq_queue.rb +0 -31
  39. data/lib/harness/queues/synchronous_queue.rb +0 -18
  40. data/lib/harness/railtie.rb +0 -71
  41. data/lib/harness/tasks.rake +0 -6
  42. data/test/integration/counters_with_redis_test.rb +0 -67
  43. data/test/integration/instrumentation_test.rb +0 -50
  44. data/test/integration/integrations/action_controller_test.rb +0 -51
  45. data/test/integration/integrations/action_mailer_test.rb +0 -22
  46. data/test/integration/integrations/action_view_test.rb +0 -32
  47. data/test/integration/integrations/active_model_serializers_test.rb +0 -22
  48. data/test/integration/integrations/active_support_test.rb +0 -41
  49. data/test/integration/integrations/sidekiq_test.rb +0 -54
  50. data/test/integration/logging_test.rb +0 -17
  51. data/test/integration/queues/delayed_job_test.rb +0 -59
  52. data/test/integration/queues/resque_test.rb +0 -24
  53. data/test/integration/queues/sidekiq_test.rb +0 -34
  54. data/test/integration/railtie_test.rb +0 -26
  55. data/test/unit/adapters/librato_adapter_test.rb +0 -169
  56. data/test/unit/adapters/memory_adapter_test.rb +0 -22
  57. data/test/unit/adapters/stathat_adapter_test.rb +0 -144
  58. data/test/unit/adapters/statsd_adapter_test.rb +0 -74
  59. data/test/unit/counter_test.rb +0 -84
  60. data/test/unit/gauge_test.rb +0 -93
  61. data/test/unit/harness_test.rb +0 -39
  62. data/test/unit/measurement_test.rb +0 -76
@@ -1,90 +0,0 @@
1
- require 'uri'
2
- require 'net/http'
3
-
4
- module Harness
5
- class LibratoAdapter
6
- class NameTooLong < Harness::LoggingError
7
- def to_s
8
- "Name cannot be more than 63 characters long"
9
- end
10
- end
11
-
12
- class Config
13
- attr_accessor :email, :token
14
- end
15
-
16
- def self.config
17
- @config ||= Config.new
18
- end
19
-
20
- def log_gauge(gauge)
21
- raise NameTooLong if gauge.id.length > 63
22
-
23
- post({:gauges => [{
24
- :name => sanitize(gauge.id),
25
- :display_name => gauge.name,
26
- :value => gauge.value,
27
- :measure_time => gauge.time.to_i,
28
- :source => gauge.source,
29
- :attributes => { :display_units_short => gauge.units }
30
- }]})
31
- end
32
-
33
- def log_counter(counter)
34
- raise NameTooLong if counter.id.length > 63
35
-
36
- post({:counters => [{
37
- :name => sanitize(counter.id),
38
- :display_name => counter.name,
39
- :value => counter.value,
40
- :measure_time => counter.time.to_i,
41
- :source => counter.source,
42
- :attributes => { :display_units_short => counter.units }
43
- }]})
44
- end
45
-
46
- private
47
- def post(params)
48
- unless config.email && config.token
49
- raise "Adapter not configured. Ensure email and token are set."
50
- end
51
-
52
- uri = URI.parse('https://metrics-api.librato.com/v1/metrics')
53
-
54
- Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
55
- request = Net::HTTP::Post.new uri.request_uri
56
-
57
- request.basic_auth config.email, config.token
58
- request['Content-Type'] = 'application/json'
59
- request.body = MultiJson.dump params
60
-
61
- response = http.request request
62
-
63
- if response.code.to_i != 200
64
- text = %Q{
65
- Server Said: #{response.body}
66
- Sent: #{params.inspect}
67
- }
68
-
69
- raise Harness::LoggingError, text
70
- end
71
- end
72
-
73
- true
74
- end
75
-
76
- def config
77
- self.class.config
78
- end
79
-
80
- def sanitize(name)
81
- if Harness.config.namespace
82
- key = "#{name}.#{Harness.config.namespace}"
83
- else
84
- key = name
85
- end
86
-
87
- key.gsub('/', '.')
88
- end
89
- end
90
- end
@@ -1,27 +0,0 @@
1
- module Harness
2
- class MemoryAdapter
3
- def self.gauges
4
- @gauges ||= []
5
- end
6
-
7
- def self.counters
8
- @counters ||= []
9
- end
10
-
11
- def log_gauge(gauge)
12
- gauges << gauge
13
- end
14
-
15
- def log_counter(counter)
16
- counters << counter
17
- end
18
-
19
- def counters
20
- self.class.counters
21
- end
22
-
23
- def gauges
24
- self.class.gauges
25
- end
26
- end
27
- end
@@ -1,11 +0,0 @@
1
- module Harness
2
- class NullAdapter
3
- def log_gauge(gauge)
4
-
5
- end
6
-
7
- def log_counter(counter)
8
-
9
- end
10
- end
11
- end
@@ -1,75 +0,0 @@
1
- require 'uri'
2
- require 'net/http'
3
-
4
- module Harness
5
- class StathatAdapter
6
- class Config
7
- attr_accessor :ezkey
8
- end
9
-
10
- def self.config
11
- @config ||= Config.new
12
- end
13
-
14
- def log_gauge(gauge)
15
- raise Harness::LoggingError if gauge.id.length > 255
16
-
17
- post({
18
- :stat => sanitize(gauge.id),
19
- :value => gauge.value,
20
- })
21
- end
22
-
23
- def log_counter(counter)
24
- raise Harness::LoggingError if counter.id.length > 255
25
-
26
- post({
27
- :stat => sanitize(counter.id),
28
- :count => counter.value,
29
- })
30
- end
31
-
32
- private
33
-
34
- def post(params)
35
- unless config.ezkey
36
- raise "Adapter not configured. Ensure ezkey is set."
37
- end
38
-
39
- uri = URI.parse('https://api.stathat.com/ez')
40
-
41
- Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
42
- request = Net::HTTP::Post.new uri.request_uri
43
-
44
- request.set_form_data params.merge(:ezkey => config.ezkey)
45
-
46
- response = http.request request
47
-
48
- unless response.code.to_i == 200
49
- text = %Q{
50
- Server Said: #{response.body}
51
- Sent: #{params.inspect}
52
- }
53
-
54
- raise Harness::LoggingError, text
55
- end
56
- end
57
-
58
- true
59
- end
60
-
61
- def config
62
- self.class.config
63
- end
64
-
65
- def sanitize(name)
66
- if Harness.config.namespace
67
- key = "#{name}.#{Harness.config.namespace}"
68
- else
69
- key = name
70
- end
71
-
72
- key.gsub('/', '.')
73
- end
74
- end
75
- end
@@ -1,50 +0,0 @@
1
- require 'statsd-instrument'
2
-
3
- module Harness
4
- class StatsdAdapter
5
- class Config
6
- delegate :host, :port, :default_sample_rate, :mode, :logger, :to => :backend
7
- delegate :host=, :port=, :default_sample_rate=, :mode=, :logger=, :to => :backend
8
-
9
- def backend=(value)
10
- @backend = value
11
- end
12
-
13
- def backend
14
- @backend ||= StatsD
15
- end
16
- end
17
-
18
- def self.config
19
- @config ||= Config.new
20
- end
21
-
22
- def log_gauge(gauge)
23
- validate!
24
- backend.gauge sanitize(gauge.id), gauge.value
25
- end
26
-
27
- def log_counter(counter)
28
- validate!
29
- backend.increment sanitize(counter.id), counter.value
30
- end
31
-
32
- private
33
- def validate!
34
- raise "Adapter not configured. Ensure host and port are set." unless config.host and config.port
35
- end
36
-
37
- def sanitize(name)
38
- key = Harness.config.namespace ? "#{Harness.config.namespace}.#{name}" : name
39
- key.gsub(%r{[^a-z0-9]}, '.')
40
- end
41
-
42
- def backend
43
- config.backend
44
- end
45
-
46
- def config
47
- self.class.config
48
- end
49
- end
50
- end
@@ -1,35 +0,0 @@
1
- module Harness
2
- class Consumer
3
- def consume
4
- Thread.new do
5
- while measurement = queue.pop
6
- begin
7
- ensure
8
- mutex.synchronize { @finished = queue.empty? }
9
- end
10
- end
11
- end
12
- end
13
-
14
- def finished?
15
- @finished
16
- end
17
-
18
- private
19
- def queue
20
- Harness.queue
21
- end
22
-
23
- def adapter
24
- Harness.config.adapter
25
- end
26
-
27
- def mutex
28
- Harness.mutex
29
- end
30
-
31
- def logger
32
- Harness.logger
33
- end
34
- end
35
- end
@@ -1,29 +0,0 @@
1
- require 'securerandom'
2
-
3
- module Harness
4
- class Counter < Measurement
5
- def self.from_event(event)
6
- if event.payload[:counter].is_a? Hash
7
- counter = new event.payload[:counter]
8
- elsif event.payload[:counter].is_a?(Symbol) || event.payload[:counter].is_a?(String)
9
- counter = new :id => event.payload[:counter].to_s
10
- else
11
- counter = new
12
- end
13
-
14
- counter.id ||= event.name
15
-
16
- if event.payload[:counter].is_a? Fixnum
17
- counter.value = event.payload[:counter]
18
- end
19
-
20
- if counter.value
21
- Harness.redis.set "counters/#{counter.id}", counter.value
22
- else
23
- counter.value = Harness.redis.incr("counters/#{counter.id}").to_i
24
- end
25
-
26
- counter
27
- end
28
- end
29
- end
data/lib/harness/gauge.rb DELETED
@@ -1,23 +0,0 @@
1
- module Harness
2
- class Gauge < Measurement
3
- def initialize(attributes = {})
4
- super
5
- self.units ||= :ms
6
- end
7
-
8
- def self.from_event(event)
9
- if event.payload[:gauge].is_a? Hash
10
- gauge = new event.payload[:gauge]
11
- elsif event.payload[:gauge].is_a?(Symbol) || event.payload[:gauge].is_a?(String)
12
- gauge = new :id => event.payload[:gauge].to_s
13
- else
14
- gauge = new
15
- end
16
-
17
- gauge.id ||= event.name
18
- gauge.value ||= event.duration
19
-
20
- gauge
21
- end
22
- end
23
- end
@@ -1,9 +0,0 @@
1
- events = %w(write_fragment read_fragment expire_fragment write_page expire_page process_action send_file)
2
-
3
- events.each do |name|
4
- ActiveSupport::Notifications.subscribe "#{name}.action_controller" do |*args|
5
- event = ActiveSupport::Notifications::Event.new(*args)
6
- gauge = Harness::Gauge.from_event event
7
- gauge.log
8
- end
9
- end
@@ -1,9 +0,0 @@
1
- events = %w(receive deliver)
2
-
3
- events.each do |name|
4
- ActiveSupport::Notifications.subscribe "#{name}.action_mailer" do |*args|
5
- event = ActiveSupport::Notifications::Event.new(*args)
6
- gauge = Harness::Gauge.from_event event
7
- gauge.log
8
- end
9
- end
@@ -1,9 +0,0 @@
1
- events = %w(render_template render_partial)
2
-
3
- events.each do |name|
4
- ActiveSupport::Notifications.subscribe "#{name}.action_view" do |*args|
5
- event = ActiveSupport::Notifications::Event.new(*args)
6
- gauge = Harness::Gauge.from_event event
7
- gauge.log
8
- end
9
- end
@@ -1,9 +0,0 @@
1
- events = %w(serializable_hash associations)
2
-
3
- events.each do |name|
4
- ActiveSupport::Notifications.subscribe %r{^#{name}.*\.serializer$} do |*args|
5
- event = ActiveSupport::Notifications::Event.new(*args)
6
- gauge = Harness::Gauge.from_event event
7
- gauge.log
8
- end
9
- end
@@ -1,9 +0,0 @@
1
- events = %w(cache_read cache_generate cache_fetch_hit cache_write cache_delete)
2
-
3
- events.each do |name|
4
- ActiveSupport::Notifications.subscribe "#{name}.active_support" do |*args|
5
- event = ActiveSupport::Notifications::Event.new(*args)
6
- gauge = Harness::Gauge.from_event event
7
- gauge.log
8
- end
9
- end
@@ -1,47 +0,0 @@
1
- module Sidekiq
2
- module Middleware
3
- module Server
4
- class HarnessInstrumentation
5
- def call(worker_class, item, queue)
6
- if instrument? worker_class
7
- logger.debug "Instrumenting: #{worker_class.inspect}"
8
-
9
- options = {}
10
- options[:gauge] = "#{worker_class.class.to_s.underscore}.sidekiq"
11
- options[:counter] = "#{worker_class.class.to_s.pluralize.underscore}.sidekiq"
12
-
13
- ActiveSupport::Notifications.instrument "#{worker_class.class.to_s.underscore}.sidekiq", options do
14
- yield
15
- end
16
-
17
- ActiveSupport::Notifications.instrument "job.sidekiq", :counter => true
18
- else
19
- logger.debug "Skipped Instrumenting: #{worker_class.inspect}"
20
- yield
21
- end
22
- end
23
-
24
- private
25
- def instrument?(worker_class)
26
- if worker_class.is_a? Harness::SidekiqQueue::SendCounter
27
- false
28
- elsif worker_class.is_a? Harness::SidekiqQueue::SendGauge
29
- false
30
- else
31
- worker_class.to_s !~ /^harness/i
32
- end
33
- end
34
-
35
- def logger
36
- Sidekiq.logger
37
- end
38
- end
39
- end
40
- end
41
- end
42
-
43
- Sidekiq.configure_server do |config|
44
- config.server_middleware do |chain|
45
- chain.add Sidekiq::Middleware::Server::HarnessInstrumentation
46
- end
47
- end