opbeat 2.0.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -3
- data/.travis.yml +19 -28
- data/.yardopts +3 -0
- data/Gemfile +4 -2
- data/HISTORY.md +3 -0
- data/LICENSE +7 -196
- data/README.md +96 -177
- data/Rakefile +19 -13
- data/gemfiles/Gemfile.base +28 -0
- data/gemfiles/Gemfile.rails-3.2.x +3 -0
- data/gemfiles/Gemfile.rails-4.0.x +3 -0
- data/gemfiles/Gemfile.rails-4.1.x +3 -0
- data/gemfiles/Gemfile.rails-4.2.x +3 -0
- data/lib/opbeat.rb +113 -93
- data/lib/opbeat/capistrano.rb +3 -4
- data/lib/opbeat/client.rb +243 -82
- data/lib/opbeat/configuration.rb +51 -64
- data/lib/opbeat/data_builders.rb +16 -0
- data/lib/opbeat/data_builders/error.rb +27 -0
- data/lib/opbeat/data_builders/transactions.rb +85 -0
- data/lib/opbeat/error.rb +1 -2
- data/lib/opbeat/error_message.rb +71 -0
- data/lib/opbeat/error_message/exception.rb +12 -0
- data/lib/opbeat/error_message/http.rb +62 -0
- data/lib/opbeat/error_message/stacktrace.rb +75 -0
- data/lib/opbeat/error_message/user.rb +23 -0
- data/lib/opbeat/filter.rb +53 -43
- data/lib/opbeat/http_client.rb +141 -0
- data/lib/opbeat/injections.rb +83 -0
- data/lib/opbeat/injections/json.rb +19 -0
- data/lib/opbeat/injections/net_http.rb +43 -0
- data/lib/opbeat/injections/redis.rb +23 -0
- data/lib/opbeat/injections/sequel.rb +32 -0
- data/lib/opbeat/injections/sinatra.rb +56 -0
- data/lib/opbeat/{capistrano → integration}/capistrano2.rb +6 -6
- data/lib/opbeat/{capistrano → integration}/capistrano3.rb +3 -3
- data/lib/opbeat/{integrations → integration}/delayed_job.rb +6 -11
- data/lib/opbeat/integration/rails/inject_exceptions_catcher.rb +23 -0
- data/lib/opbeat/integration/railtie.rb +53 -0
- data/lib/opbeat/integration/resque.rb +16 -0
- data/lib/opbeat/integration/sidekiq.rb +38 -0
- data/lib/opbeat/line_cache.rb +21 -0
- data/lib/opbeat/logging.rb +37 -0
- data/lib/opbeat/middleware.rb +59 -0
- data/lib/opbeat/normalizers.rb +65 -0
- data/lib/opbeat/normalizers/action_controller.rb +21 -0
- data/lib/opbeat/normalizers/action_view.rb +71 -0
- data/lib/opbeat/normalizers/active_record.rb +41 -0
- data/lib/opbeat/sql_summarizer.rb +27 -0
- data/lib/opbeat/subscriber.rb +80 -0
- data/lib/opbeat/tasks.rb +20 -18
- data/lib/opbeat/trace.rb +47 -0
- data/lib/opbeat/trace_helpers.rb +29 -0
- data/lib/opbeat/transaction.rb +99 -0
- data/lib/opbeat/util.rb +26 -0
- data/lib/opbeat/util/constantize.rb +54 -0
- data/lib/opbeat/util/inspector.rb +75 -0
- data/lib/opbeat/version.rb +1 -1
- data/lib/opbeat/worker.rb +55 -0
- data/opbeat.gemspec +6 -14
- data/spec/opbeat/client_spec.rb +216 -29
- data/spec/opbeat/configuration_spec.rb +34 -38
- data/spec/opbeat/data_builders/error_spec.rb +43 -0
- data/spec/opbeat/data_builders/transactions_spec.rb +51 -0
- data/spec/opbeat/error_message/exception_spec.rb +22 -0
- data/spec/opbeat/error_message/http_spec.rb +65 -0
- data/spec/opbeat/error_message/stacktrace_spec.rb +56 -0
- data/spec/opbeat/error_message/user_spec.rb +28 -0
- data/spec/opbeat/error_message_spec.rb +78 -0
- data/spec/opbeat/filter_spec.rb +21 -99
- data/spec/opbeat/http_client_spec.rb +64 -0
- data/spec/opbeat/injections/net_http_spec.rb +37 -0
- data/spec/opbeat/injections/sequel_spec.rb +33 -0
- data/spec/opbeat/injections/sinatra_spec.rb +13 -0
- data/spec/opbeat/injections_spec.rb +49 -0
- data/spec/opbeat/integration/delayed_job_spec.rb +35 -0
- data/spec/opbeat/integration/json_spec.rb +41 -0
- data/spec/opbeat/integration/rails_spec.rb +88 -0
- data/spec/opbeat/integration/redis_spec.rb +20 -0
- data/spec/opbeat/integration/resque_spec.rb +42 -0
- data/spec/opbeat/integration/sidekiq_spec.rb +40 -0
- data/spec/opbeat/integration/sinatra_spec.rb +66 -0
- data/spec/opbeat/line_cache_spec.rb +38 -0
- data/spec/opbeat/logging_spec.rb +47 -0
- data/spec/opbeat/middleware_spec.rb +32 -0
- data/spec/opbeat/normalizers/action_controller_spec.rb +32 -0
- data/spec/opbeat/normalizers/action_view_spec.rb +77 -0
- data/spec/opbeat/normalizers/active_record_spec.rb +70 -0
- data/spec/opbeat/normalizers_spec.rb +16 -0
- data/spec/opbeat/sql_summarizer_spec.rb +6 -0
- data/spec/opbeat/subscriber_spec.rb +83 -0
- data/spec/opbeat/trace_spec.rb +43 -0
- data/spec/opbeat/transaction_spec.rb +98 -0
- data/spec/opbeat/util/inspector_spec.rb +40 -0
- data/spec/opbeat/util_spec.rb +20 -0
- data/spec/opbeat/worker_spec.rb +54 -0
- data/spec/opbeat_spec.rb +49 -0
- data/spec/spec_helper.rb +79 -6
- metadata +89 -149
- data/Makefile +0 -3
- data/gemfiles/rails30.gemfile +0 -9
- data/gemfiles/rails31.gemfile +0 -9
- data/gemfiles/rails32.gemfile +0 -9
- data/gemfiles/rails40.gemfile +0 -9
- data/gemfiles/rails41.gemfile +0 -9
- data/gemfiles/rails42.gemfile +0 -9
- data/gemfiles/ruby192_rails31.gemfile +0 -10
- data/gemfiles/ruby192_rails32.gemfile +0 -10
- data/gemfiles/sidekiq31.gemfile +0 -11
- data/lib/opbeat/better_attr_accessor.rb +0 -44
- data/lib/opbeat/event.rb +0 -223
- data/lib/opbeat/integrations/resque.rb +0 -22
- data/lib/opbeat/integrations/sidekiq.rb +0 -32
- data/lib/opbeat/interfaces.rb +0 -35
- data/lib/opbeat/interfaces/exception.rb +0 -16
- data/lib/opbeat/interfaces/http.rb +0 -57
- data/lib/opbeat/interfaces/message.rb +0 -19
- data/lib/opbeat/interfaces/stack_trace.rb +0 -50
- data/lib/opbeat/linecache.rb +0 -25
- data/lib/opbeat/logger.rb +0 -21
- data/lib/opbeat/rack.rb +0 -46
- data/lib/opbeat/rails/middleware/debug_exceptions_catcher.rb +0 -22
- data/lib/opbeat/railtie.rb +0 -26
- data/spec/opbeat/better_attr_accessor_spec.rb +0 -99
- data/spec/opbeat/event_spec.rb +0 -138
- data/spec/opbeat/integrations/delayed_job_spec.rb +0 -38
- data/spec/opbeat/logger_spec.rb +0 -55
- data/spec/opbeat/opbeat_spec.rb +0 -64
- data/spec/opbeat/rack_spec.rb +0 -117
data/lib/opbeat/util.rb
ADDED
@@ -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
|
data/lib/opbeat/version.rb
CHANGED
@@ -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
|
-
|
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 = ["
|
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/
|
13
|
-
gem.license = "
|
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
|
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
|
data/spec/opbeat/client_spec.rb
CHANGED
@@ -1,35 +1,222 @@
|
|
1
|
-
require
|
2
|
-
require 'opbeat'
|
3
|
-
require 'faraday'
|
1
|
+
require 'spec_helper'
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
stub.get('/') { |env| [ 200, {}, 'foo' ]}
|
8
|
-
end
|
9
|
-
end
|
3
|
+
module Opbeat
|
4
|
+
RSpec.describe Client do
|
10
5
|
|
11
|
-
|
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
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
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
|