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.
- 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
|