opbeat 2.0.0 → 3.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.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -3
  3. data/.travis.yml +19 -28
  4. data/.yardopts +3 -0
  5. data/Gemfile +4 -2
  6. data/HISTORY.md +3 -0
  7. data/LICENSE +7 -196
  8. data/README.md +96 -177
  9. data/Rakefile +19 -13
  10. data/gemfiles/Gemfile.base +28 -0
  11. data/gemfiles/Gemfile.rails-3.2.x +3 -0
  12. data/gemfiles/Gemfile.rails-4.0.x +3 -0
  13. data/gemfiles/Gemfile.rails-4.1.x +3 -0
  14. data/gemfiles/Gemfile.rails-4.2.x +3 -0
  15. data/lib/opbeat.rb +113 -93
  16. data/lib/opbeat/capistrano.rb +3 -4
  17. data/lib/opbeat/client.rb +243 -82
  18. data/lib/opbeat/configuration.rb +51 -64
  19. data/lib/opbeat/data_builders.rb +16 -0
  20. data/lib/opbeat/data_builders/error.rb +27 -0
  21. data/lib/opbeat/data_builders/transactions.rb +85 -0
  22. data/lib/opbeat/error.rb +1 -2
  23. data/lib/opbeat/error_message.rb +71 -0
  24. data/lib/opbeat/error_message/exception.rb +12 -0
  25. data/lib/opbeat/error_message/http.rb +62 -0
  26. data/lib/opbeat/error_message/stacktrace.rb +75 -0
  27. data/lib/opbeat/error_message/user.rb +23 -0
  28. data/lib/opbeat/filter.rb +53 -43
  29. data/lib/opbeat/http_client.rb +141 -0
  30. data/lib/opbeat/injections.rb +83 -0
  31. data/lib/opbeat/injections/json.rb +19 -0
  32. data/lib/opbeat/injections/net_http.rb +43 -0
  33. data/lib/opbeat/injections/redis.rb +23 -0
  34. data/lib/opbeat/injections/sequel.rb +32 -0
  35. data/lib/opbeat/injections/sinatra.rb +56 -0
  36. data/lib/opbeat/{capistrano → integration}/capistrano2.rb +6 -6
  37. data/lib/opbeat/{capistrano → integration}/capistrano3.rb +3 -3
  38. data/lib/opbeat/{integrations → integration}/delayed_job.rb +6 -11
  39. data/lib/opbeat/integration/rails/inject_exceptions_catcher.rb +23 -0
  40. data/lib/opbeat/integration/railtie.rb +53 -0
  41. data/lib/opbeat/integration/resque.rb +16 -0
  42. data/lib/opbeat/integration/sidekiq.rb +38 -0
  43. data/lib/opbeat/line_cache.rb +21 -0
  44. data/lib/opbeat/logging.rb +37 -0
  45. data/lib/opbeat/middleware.rb +59 -0
  46. data/lib/opbeat/normalizers.rb +65 -0
  47. data/lib/opbeat/normalizers/action_controller.rb +21 -0
  48. data/lib/opbeat/normalizers/action_view.rb +71 -0
  49. data/lib/opbeat/normalizers/active_record.rb +41 -0
  50. data/lib/opbeat/sql_summarizer.rb +27 -0
  51. data/lib/opbeat/subscriber.rb +80 -0
  52. data/lib/opbeat/tasks.rb +20 -18
  53. data/lib/opbeat/trace.rb +47 -0
  54. data/lib/opbeat/trace_helpers.rb +29 -0
  55. data/lib/opbeat/transaction.rb +99 -0
  56. data/lib/opbeat/util.rb +26 -0
  57. data/lib/opbeat/util/constantize.rb +54 -0
  58. data/lib/opbeat/util/inspector.rb +75 -0
  59. data/lib/opbeat/version.rb +1 -1
  60. data/lib/opbeat/worker.rb +55 -0
  61. data/opbeat.gemspec +6 -14
  62. data/spec/opbeat/client_spec.rb +216 -29
  63. data/spec/opbeat/configuration_spec.rb +34 -38
  64. data/spec/opbeat/data_builders/error_spec.rb +43 -0
  65. data/spec/opbeat/data_builders/transactions_spec.rb +51 -0
  66. data/spec/opbeat/error_message/exception_spec.rb +22 -0
  67. data/spec/opbeat/error_message/http_spec.rb +65 -0
  68. data/spec/opbeat/error_message/stacktrace_spec.rb +56 -0
  69. data/spec/opbeat/error_message/user_spec.rb +28 -0
  70. data/spec/opbeat/error_message_spec.rb +78 -0
  71. data/spec/opbeat/filter_spec.rb +21 -99
  72. data/spec/opbeat/http_client_spec.rb +64 -0
  73. data/spec/opbeat/injections/net_http_spec.rb +37 -0
  74. data/spec/opbeat/injections/sequel_spec.rb +33 -0
  75. data/spec/opbeat/injections/sinatra_spec.rb +13 -0
  76. data/spec/opbeat/injections_spec.rb +49 -0
  77. data/spec/opbeat/integration/delayed_job_spec.rb +35 -0
  78. data/spec/opbeat/integration/json_spec.rb +41 -0
  79. data/spec/opbeat/integration/rails_spec.rb +88 -0
  80. data/spec/opbeat/integration/redis_spec.rb +20 -0
  81. data/spec/opbeat/integration/resque_spec.rb +42 -0
  82. data/spec/opbeat/integration/sidekiq_spec.rb +40 -0
  83. data/spec/opbeat/integration/sinatra_spec.rb +66 -0
  84. data/spec/opbeat/line_cache_spec.rb +38 -0
  85. data/spec/opbeat/logging_spec.rb +47 -0
  86. data/spec/opbeat/middleware_spec.rb +32 -0
  87. data/spec/opbeat/normalizers/action_controller_spec.rb +32 -0
  88. data/spec/opbeat/normalizers/action_view_spec.rb +77 -0
  89. data/spec/opbeat/normalizers/active_record_spec.rb +70 -0
  90. data/spec/opbeat/normalizers_spec.rb +16 -0
  91. data/spec/opbeat/sql_summarizer_spec.rb +6 -0
  92. data/spec/opbeat/subscriber_spec.rb +83 -0
  93. data/spec/opbeat/trace_spec.rb +43 -0
  94. data/spec/opbeat/transaction_spec.rb +98 -0
  95. data/spec/opbeat/util/inspector_spec.rb +40 -0
  96. data/spec/opbeat/util_spec.rb +20 -0
  97. data/spec/opbeat/worker_spec.rb +54 -0
  98. data/spec/opbeat_spec.rb +49 -0
  99. data/spec/spec_helper.rb +79 -6
  100. metadata +89 -149
  101. data/Makefile +0 -3
  102. data/gemfiles/rails30.gemfile +0 -9
  103. data/gemfiles/rails31.gemfile +0 -9
  104. data/gemfiles/rails32.gemfile +0 -9
  105. data/gemfiles/rails40.gemfile +0 -9
  106. data/gemfiles/rails41.gemfile +0 -9
  107. data/gemfiles/rails42.gemfile +0 -9
  108. data/gemfiles/ruby192_rails31.gemfile +0 -10
  109. data/gemfiles/ruby192_rails32.gemfile +0 -10
  110. data/gemfiles/sidekiq31.gemfile +0 -11
  111. data/lib/opbeat/better_attr_accessor.rb +0 -44
  112. data/lib/opbeat/event.rb +0 -223
  113. data/lib/opbeat/integrations/resque.rb +0 -22
  114. data/lib/opbeat/integrations/sidekiq.rb +0 -32
  115. data/lib/opbeat/interfaces.rb +0 -35
  116. data/lib/opbeat/interfaces/exception.rb +0 -16
  117. data/lib/opbeat/interfaces/http.rb +0 -57
  118. data/lib/opbeat/interfaces/message.rb +0 -19
  119. data/lib/opbeat/interfaces/stack_trace.rb +0 -50
  120. data/lib/opbeat/linecache.rb +0 -25
  121. data/lib/opbeat/logger.rb +0 -21
  122. data/lib/opbeat/rack.rb +0 -46
  123. data/lib/opbeat/rails/middleware/debug_exceptions_catcher.rb +0 -22
  124. data/lib/opbeat/railtie.rb +0 -26
  125. data/spec/opbeat/better_attr_accessor_spec.rb +0 -99
  126. data/spec/opbeat/event_spec.rb +0 -138
  127. data/spec/opbeat/integrations/delayed_job_spec.rb +0 -38
  128. data/spec/opbeat/logger_spec.rb +0 -55
  129. data/spec/opbeat/opbeat_spec.rb +0 -64
  130. data/spec/opbeat/rack_spec.rb +0 -117
@@ -0,0 +1,26 @@
1
+ module Opbeat
2
+ # @api private
3
+ module Util
4
+ def self.nearest_minute
5
+ now = Time.now.utc
6
+ now - now.to_i % 60
7
+ end
8
+
9
+ def self.nanos
10
+ now = Time.now.utc
11
+ now.to_i * 1_000_000_000 + now.usec * 1_000
12
+ end
13
+ end
14
+
15
+ require 'opbeat/util/inspector'
16
+ end
17
+
18
+ # TODO: Maybe move this some place more explicit as we're extending
19
+ # a pretty widely used class. Or maybe don't extend at all.
20
+ if RUBY_VERSION.to_i <= 1
21
+ class Struct
22
+ def to_h
23
+ Hash[self.each_pair.to_a]
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,54 @@
1
+ module Opbeat
2
+ module Util
3
+ # From https://github.com/rails/rails/blob/861b70e92f4a1fc0e465ffcf2ee62680519c8f6f/activesupport/lib/active_support/inflector/methods.rb#L249
4
+ #
5
+ # Tries to find a constant with the name specified in the argument string.
6
+ #
7
+ # 'Module'.constantize # => Module
8
+ # 'Test::Unit'.constantize # => Test::Unit
9
+ #
10
+ # The name is assumed to be the one of a top-level constant, no matter
11
+ # whether it starts with "::" or not. No lexical context is taken into
12
+ # account:
13
+ #
14
+ # C = 'outside'
15
+ # module M
16
+ # C = 'inside'
17
+ # C # => 'inside'
18
+ # 'C'.constantize # => 'outside', same as ::C
19
+ # end
20
+ #
21
+ # NameError is raised when the name is not in CamelCase or the constant is
22
+ # unknown.
23
+ def self.constantize(camel_cased_word)
24
+ names = camel_cased_word.split('::')
25
+
26
+ # Trigger a built-in NameError exception including the ill-formed constant in the message.
27
+ Object.const_get(camel_cased_word) if names.empty?
28
+
29
+ # Remove the first blank element in case of '::ClassName' notation.
30
+ names.shift if names.size > 1 && names.first.empty?
31
+
32
+ names.inject(Object) do |constant, name|
33
+ if constant == Object
34
+ constant.const_get(name)
35
+ else
36
+ candidate = constant.const_get(name)
37
+ next candidate if constant.const_defined?(name, false)
38
+ next candidate unless Object.const_defined?(name)
39
+
40
+ # Go down the ancestors to check if it is owned directly. The check
41
+ # stops when we reach Object or the end of ancestors tree.
42
+ constant = constant.ancestors.inject do |const, ancestor|
43
+ break const if ancestor == Object
44
+ break ancestor if ancestor.const_defined?(name, false)
45
+ const
46
+ end
47
+
48
+ # owner is in Object, so raise
49
+ constant.const_get(name, false)
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,75 @@
1
+ # encoding: utf-8
2
+
3
+ module Opbeat
4
+ module Util
5
+ class Inspector
6
+
7
+ DEFAULTS = {
8
+ width: 120
9
+ }.freeze
10
+
11
+ NEWLINE = "\n".freeze
12
+ SPACE = " ".freeze
13
+
14
+ def initialize config = {}
15
+ @config = DEFAULTS.merge(config)
16
+ end
17
+
18
+ def ms nanos
19
+ nanos.to_f / 1_000_000
20
+ end
21
+
22
+ def transaction transaction, opts = {}
23
+ w = @config[:width].to_f
24
+ f = w / ms(transaction.duration)
25
+
26
+ traces = transaction.traces
27
+
28
+ traces = traces.reduce([]) do |state, trace|
29
+ descriptions = [
30
+ "#{trace.signature} - #{trace.kind}",
31
+ "transaction:#{trace.transaction.endpoint}"
32
+ ]
33
+
34
+ if opts[:include_parents]
35
+ descriptions << "parents:#{trace.parents.map(&:signature).join(',')}"
36
+ end
37
+
38
+ descriptions << "duration:#{ms trace.duration}ms - rel:#{ms trace.relative_start}ms"
39
+
40
+ start_diff = ms(trace.start_time) - ms(transaction.start_time)
41
+ indent = (start_diff.floor * f).to_i
42
+
43
+ longest_desc_length = descriptions.map(&:length).max
44
+ desc_indent = [[indent, w - longest_desc_length].min, 0].max
45
+
46
+ lines = descriptions.map do |desc|
47
+ "#{SPACE * desc_indent}#{desc}"
48
+ end
49
+
50
+ if trace.duration
51
+ span = (ms(trace.duration) * f).ceil.to_i
52
+ lines << "#{SPACE * indent}+#{"-" * [(span - 2), 0].max}+"
53
+ else
54
+ lines << "#{SPACE * indent}UNFINISHED"
55
+ end
56
+
57
+ state << lines.join("\n")
58
+ state
59
+ end.join("\n")
60
+
61
+ <<-STR.gsub(/^\s{8}/, '')
62
+ \n#{"=" * (w.to_i)}
63
+ #{transaction.endpoint} - kind:#{transaction.kind} - #{transaction.duration.to_f / 1_000_000}ms
64
+ +#{"-" * (w.to_i - 2)}+
65
+ #{traces}
66
+ STR
67
+ rescue => e
68
+ puts e
69
+ puts e.backtrace.join("\n")
70
+ transaction.inspect
71
+ end
72
+
73
+ end
74
+ end
75
+ end
@@ -1,3 +1,3 @@
1
1
  module Opbeat
2
- VERSION = "2.0.0"
2
+ VERSION = "3.0.0"
3
3
  end
@@ -0,0 +1,55 @@
1
+ module Opbeat
2
+ # @api private
3
+ class Worker
4
+ include Logging
5
+
6
+ class PostRequest < Struct.new(:path, :data)
7
+ # require all parameters
8
+ def initialize path, data
9
+ super(path, data)
10
+ end
11
+ end
12
+
13
+ class StopMessage; end
14
+
15
+ def initialize config, queue, http_client
16
+ @config = config
17
+ @queue = queue
18
+ @http_client = http_client
19
+ end
20
+
21
+ attr_reader :config
22
+
23
+ def run
24
+ loop do
25
+ while action = @queue.pop
26
+ case action
27
+ when PostRequest
28
+ process_request action
29
+ when StopMessage
30
+ Thread.exit
31
+ else
32
+ raise Error.new("Unknown entity in worker queue: #{action.inspect}")
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def process_request req
41
+ unless config.validate!
42
+ info "Invalid config - Skipping posting to Opbeat"
43
+ return
44
+ end
45
+
46
+ begin
47
+ @http_client.post(req.path, req.data)
48
+ rescue => e
49
+ fatal "Failed POST: #{e.inspect}"
50
+ debug e.backtrace.join("\n")
51
+ end
52
+ end
53
+
54
+ end
55
+ end
data/opbeat.gemspec CHANGED
@@ -1,28 +1,20 @@
1
1
  # coding: utf-8
2
2
  lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ $:.unshift(lib) unless $:.include?(lib)
4
4
  require 'opbeat/version'
5
5
 
6
6
  Gem::Specification.new do |gem|
7
7
  gem.name = "opbeat"
8
8
  gem.version = Opbeat::VERSION
9
- gem.authors = ["Thomas Watson Steen", "Ron Cohen", "Noah Kantrowitz"]
9
+ gem.authors = ["Mikkel Malmberg"]
10
10
  gem.email = "support@opbeat.com"
11
- gem.summary = "The official Opbeat Ruby client"
12
- gem.homepage = "https://github.com/opbeat/opbeat_ruby"
13
- gem.license = "Apache-2.0"
11
+ gem.summary = "The official Opbeat Ruby client library"
12
+ gem.homepage = "https://github.com/opbeat/opbeat-ruby"
13
+ gem.license = "BSD-3-Clause"
14
14
 
15
15
  gem.files = `git ls-files -z`.split("\x0")
16
16
  gem.require_paths = ["lib"]
17
17
  gem.extra_rdoc_files = ["README.md", "LICENSE"]
18
18
 
19
- gem.add_dependency "faraday", [">= 0.7.6", "< 0.10"]
20
- gem.add_dependency "multi_json", "~> 1.0"
21
-
22
- gem.add_development_dependency "bundler", "~> 1.7"
23
- gem.add_development_dependency "rake", "~> 10.0"
24
- gem.add_development_dependency "rspec", ">= 2.14"
25
- gem.add_development_dependency "simplecov"
26
- gem.add_development_dependency "delayed_job"
27
- gem.add_development_dependency "sidekiq", "~> 2.17.0"
19
+ gem.add_dependency('activesupport', '>= 3.0.0')
28
20
  end
@@ -1,35 +1,222 @@
1
- require File::expand_path('../../spec_helper', __FILE__)
2
- require 'opbeat'
3
- require 'faraday'
1
+ require 'spec_helper'
4
2
 
5
- http = Faraday.new do |builder|
6
- builder.adapter :test do |stub|
7
- stub.get('/') { |env| [ 200, {}, 'foo' ]}
8
- end
9
- end
3
+ module Opbeat
4
+ RSpec.describe Client do
10
5
 
11
- describe Opbeat::Client do
12
- before do
13
- @configuration = Opbeat::Configuration.new
14
- @configuration.environments = ["test"]
15
- @configuration.current_environment = :test
16
- @configuration.secret_token = 'test'
17
- @configuration.organization_id = 'test'
18
- @configuration.app_id = 'test'
19
- @client = Opbeat::Client.new(@configuration)
20
- allow(@client).to receive(:send)
21
- end
6
+ let(:config) { Configuration.new app_id: 'x', organization_id: 'y', secret_token: 'z' }
22
7
 
23
- it 'send_release should send' do
24
- message = "Test message"
25
- expect(@client).to receive(:send).with("/releases/", message)
26
- @client.send_release(message)
27
- end
8
+ describe ".start!" do
9
+ it "set's up an instance and only one" do
10
+ first_instance = Client.start! config
11
+ expect(Client.inst).to_not be_nil
12
+ expect(Client.start! config).to be first_instance
13
+ end
14
+ end
15
+
16
+ describe ".stop!" do
17
+ it "kills the instance but flushes before" do
18
+ Client.start! config
19
+ Client.inst.submit_transaction Transaction.new(Client.inst, 'Test').done(200)
20
+ Client.stop!
21
+ expect(WebMock).to have_requested(:post, %r{/transactions/$})
22
+ expect(Client.inst).to be_nil
23
+ end
24
+ end
25
+
26
+ context "without worker spec setting", start_without_worker: true do
27
+ it "doesn't start a Worker" do
28
+ expect(Thread).to_not receive(:new)
29
+ Client.start! config
30
+ expect(Client.inst).to_not be_nil
31
+ end
32
+ end
33
+
34
+ context "with a running client", start_without_worker: true do
35
+ subject { Client.inst }
36
+
37
+ describe "#transaction" do
38
+ it "returns a new transaction and sets it as current" do
39
+ transaction = subject.transaction 'Test'
40
+ expect(transaction).to_not be_nil
41
+ expect(subject.current_transaction).to be transaction
42
+ end
43
+ it "returns the current transaction if present" do
44
+ transaction = subject.transaction 'Test'
45
+ expect(subject.transaction 'Test').to eq transaction
46
+ end
47
+ context "with a block" do
48
+ it "yields transaction" do
49
+ blck = lambda { |*args| }
50
+ allow(blck).to receive(:call)
51
+ subject.transaction('Test') { |t| blck.(t) }
52
+ expect(blck).to have_received(:call).with(Transaction)
53
+ end
54
+ it "returns transaction" do
55
+ result = subject.transaction('Test') { "DON'T RETURN ME" }
56
+ expect(result).to be_a Transaction
57
+ end
58
+ end
59
+ end
60
+
61
+ describe "#trace" do
62
+ it "delegates to current transaction" do
63
+ subject.current_transaction = double('transaction', trace: true)
64
+ subject.trace 1, 2, 3
65
+ expect(subject.current_transaction).to have_received(:trace).with(1, 2, 3)
66
+ subject.current_transaction = nil
67
+ end
68
+
69
+ it "ignores when outside transaction" do
70
+ blk = Proc.new {}
71
+ allow(blk).to receive(:call)
72
+ subject.trace { blk.call }
73
+ expect(blk).to have_received(:call)
74
+ end
75
+ end
76
+
77
+ describe "#submit_transaction" do
78
+ it "doesn't send right away" do
79
+ transaction = Transaction.new(subject, 'test')
80
+
81
+ subject.submit_transaction transaction
82
+
83
+ expect(subject.queue.length).to be 0
84
+ expect(WebMock).to_not have_requested(:post, %r{/transactions/$})
85
+ end
86
+
87
+ it "sends if it's long enough ago that we sent last" do
88
+ transaction = Transaction.new(subject, 'test')
89
+ subject.instance_variable_set :@last_sent_transactions, Time.now.utc - 61
90
+
91
+ subject.submit_transaction transaction
92
+
93
+ expect(subject.queue.length).to be 1
94
+ expect(subject.queue.pop).to be_a Worker::PostRequest
95
+ end
96
+
97
+ it "sends if interval is disabled" do
98
+ transaction = Transaction.new(subject, 'test')
99
+ subject.config.transaction_post_interval = nil
100
+ subject.submit_transaction transaction
101
+ expect(subject.queue.length).to be 1
102
+ end
103
+ end
104
+
105
+ describe "#report" do
106
+ it "builds and posts an exception" do
107
+ exception = Exception.new('BOOM')
108
+
109
+ subject.report exception
110
+
111
+ expect(subject.queue.length).to be 1
112
+ expect(subject.queue.pop).to be_a Worker::PostRequest
113
+ end
114
+
115
+ it "skips nil exceptions" do
116
+ subject.report nil
117
+ expect(WebMock).to_not have_requested(:post, %r{/errors/$})
118
+ end
119
+ end
120
+
121
+ describe "#report_message" do
122
+ it "builds and posts an exception" do
123
+ subject.report_message "Massage message"
124
+
125
+ expect(subject.queue.length).to be 1
126
+ expect(subject.queue.pop).to be_a Worker::PostRequest
127
+ end
128
+ end
129
+
130
+ describe "#capture" do
131
+ it "captures exceptions and sends them off then raises them again" do
132
+ exception = Exception.new("BOOM")
133
+
134
+ expect do
135
+ subject.capture do
136
+ raise exception
137
+ end
138
+ end.to raise_exception(Exception)
139
+
140
+ expect(subject.queue.length).to be 1
141
+ expect(subject.queue.pop).to be_a Worker::PostRequest
142
+ end
143
+ end
144
+
145
+ describe "#release" do
146
+ it "notifies Opbeat of a release" do
147
+ release = { rev: "abc123", status: 'completed' }
148
+
149
+ subject.release release
150
+
151
+ expect(subject.queue.length).to be 1
152
+ expect(subject.queue.pop).to be_a Worker::PostRequest
153
+ end
154
+
155
+ it "may send inline" do
156
+ release = { rev: "abc123", status: 'completed' }
157
+
158
+ subject.release release, inline: true
159
+
160
+ expect(WebMock).to have_requested(:post, %r{/releases/$}).with(body: release)
161
+ end
162
+ end
163
+ end
164
+
165
+ context "with performance disabled" do
166
+ subject do
167
+ Opbeat::Client.inst
168
+ end
169
+
170
+ before do
171
+ config.disable_performance = true
172
+ Opbeat.start! config
173
+ end
174
+ after { Opbeat.stop! }
175
+
176
+ describe "#transaction" do
177
+ it "yields" do
178
+ block = lambda { }
179
+ expect(block).to receive(:call)
180
+ Client.inst.transaction('Test') { block.call }
181
+ end
182
+ it "returns nil" do
183
+ expect(Client.inst.transaction 'Test').to be_nil
184
+ end
185
+ end
186
+
187
+ describe "#trace" do
188
+ it "yields" do
189
+ block = lambda { }
190
+ expect(block).to receive(:call)
191
+ Client.inst.trace('Test', 'trace') { block.call }
192
+ end
193
+ it "returns nil" do
194
+ expect(Client.inst.trace 'Test', 'test').to be_nil
195
+ end
196
+ end
197
+ end
198
+
199
+ context "with errors disabled" do
200
+ subject do
201
+ Opbeat::Client.inst
202
+ end
203
+
204
+ before do
205
+ config.disable_errors = true
206
+ Opbeat.start! config
207
+ end
208
+ after { Opbeat.stop! }
209
+
210
+ describe "#report" do
211
+ it "doesn't do anything" do
212
+ exception = Exception.new('BOOM')
213
+
214
+ Client.inst.report exception
215
+
216
+ expect(Client.inst.queue.length).to be 0
217
+ end
218
+ end
219
+ end
28
220
 
29
- it 'send_message should send' do
30
- event = Opbeat::Event.new :message => "my message"
31
- req = http.get '/'
32
- expect(@client).to receive(:send).with("/errors/", event).and_return(req)
33
- @client.send_event(event)
34
221
  end
35
222
  end