appsignal 0.11.18 → 0.12.beta.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. data/.gitignore +6 -0
  2. data/CHANGELOG.md +4 -38
  3. data/Rakefile +14 -6
  4. data/appsignal.gemspec +3 -1
  5. data/benchmark.rake +12 -16
  6. data/ext/appsignal_extension.c +183 -0
  7. data/ext/extconf.rb +39 -0
  8. data/gemfiles/capistrano2.gemfile +0 -1
  9. data/gemfiles/capistrano3.gemfile +0 -1
  10. data/gemfiles/rails-4.2.gemfile +1 -1
  11. data/lib/appsignal.rb +23 -61
  12. data/lib/appsignal/capistrano.rb +1 -2
  13. data/lib/appsignal/config.rb +13 -1
  14. data/lib/appsignal/event_formatter.rb +67 -0
  15. data/lib/appsignal/event_formatter/action_view/render_formatter.rb +23 -0
  16. data/lib/appsignal/event_formatter/active_record/sql_formatter.rb +74 -0
  17. data/lib/appsignal/event_formatter/moped/query_formatter.rb +80 -0
  18. data/lib/appsignal/event_formatter/net_http/request_formatter.rb +13 -0
  19. data/lib/appsignal/instrumentations/net_http.rb +6 -4
  20. data/lib/appsignal/integrations/resque.rb +2 -10
  21. data/lib/appsignal/integrations/sidekiq.rb +2 -2
  22. data/lib/appsignal/integrations/sinatra.rb +1 -0
  23. data/lib/appsignal/js_exception_transaction.rb +44 -28
  24. data/lib/appsignal/marker.rb +11 -13
  25. data/lib/appsignal/params_sanitizer.rb +5 -8
  26. data/lib/appsignal/rack/instrumentation.rb +2 -0
  27. data/lib/appsignal/rack/js_exception_catcher.rb +1 -0
  28. data/lib/appsignal/rack/listener.rb +1 -1
  29. data/lib/appsignal/rack/sinatra_instrumentation.rb +2 -12
  30. data/lib/appsignal/subscriber.rb +59 -0
  31. data/lib/appsignal/transaction.rb +117 -174
  32. data/lib/appsignal/transmitter.rb +8 -37
  33. data/lib/appsignal/version.rb +2 -1
  34. data/spec/lib/appsignal/config_spec.rb +25 -4
  35. data/spec/lib/appsignal/event_formatter/action_view/render_formatter_spec.rb +42 -0
  36. data/spec/lib/appsignal/{aggregator/middleware/active_record_sanitizer_spec.rb → event_formatter/active_record/sql_formatter_spec.rb} +61 -61
  37. data/spec/lib/appsignal/{event/moped_event_spec.rb → event_formatter/moped/query_formatter_spec.rb} +32 -78
  38. data/spec/lib/appsignal/event_formatter/net_http/request_formatter_spec.rb +26 -0
  39. data/spec/lib/appsignal/event_formatter_spec.rb +102 -0
  40. data/spec/lib/appsignal/extension_spec.rb +75 -0
  41. data/spec/lib/appsignal/instrumentations/net_http_spec.rb +20 -4
  42. data/spec/lib/appsignal/integrations/delayed_job_spec.rb +3 -2
  43. data/spec/lib/appsignal/integrations/rails_spec.rb +0 -7
  44. data/spec/lib/appsignal/integrations/resque_spec.rb +51 -55
  45. data/spec/lib/appsignal/integrations/sequel_spec.rb +8 -3
  46. data/spec/lib/appsignal/integrations/sidekiq_spec.rb +4 -21
  47. data/spec/lib/appsignal/integrations/sinatra_spec.rb +0 -6
  48. data/spec/lib/appsignal/js_exception_transaction_spec.rb +57 -60
  49. data/spec/lib/appsignal/params_sanitizer_spec.rb +11 -27
  50. data/spec/lib/appsignal/rack/listener_spec.rb +6 -6
  51. data/spec/lib/appsignal/rack/sinatra_instrumentation_spec.rb +2 -43
  52. data/spec/lib/appsignal/subscriber_spec.rb +162 -0
  53. data/spec/lib/appsignal/transaction_spec.rb +283 -615
  54. data/spec/lib/appsignal/transmitter_spec.rb +3 -32
  55. data/spec/lib/appsignal_spec.rb +41 -90
  56. data/spec/lib/generators/appsignal/appsignal_generator_spec.rb +0 -17
  57. data/spec/spec_helper.rb +18 -22
  58. data/spec/support/helpers/notification_helpers.rb +1 -1
  59. data/spec/support/helpers/time_helpers.rb +11 -0
  60. data/spec/support/helpers/transaction_helpers.rb +6 -18
  61. data/spec/support/project_fixture/config/appsignal.yml +1 -2
  62. metadata +68 -78
  63. checksums.yaml +0 -7
  64. data/gemfiles/padrino-0.13.gemfile +0 -7
  65. data/gemfiles/resque.gemfile +0 -5
  66. data/lib/appsignal/agent.rb +0 -217
  67. data/lib/appsignal/aggregator.rb +0 -67
  68. data/lib/appsignal/aggregator/middleware.rb +0 -4
  69. data/lib/appsignal/aggregator/middleware/action_view_sanitizer.rb +0 -23
  70. data/lib/appsignal/aggregator/middleware/active_record_sanitizer.rb +0 -65
  71. data/lib/appsignal/aggregator/middleware/chain.rb +0 -101
  72. data/lib/appsignal/aggregator/middleware/delete_blanks.rb +0 -16
  73. data/lib/appsignal/aggregator/post_processor.rb +0 -32
  74. data/lib/appsignal/event.rb +0 -20
  75. data/lib/appsignal/event/moped_event.rb +0 -90
  76. data/lib/appsignal/integrations/padrino.rb +0 -64
  77. data/lib/appsignal/integrations/passenger.rb +0 -13
  78. data/lib/appsignal/integrations/rake.rb +0 -29
  79. data/lib/appsignal/integrations/unicorn.rb +0 -25
  80. data/lib/appsignal/ipc.rb +0 -68
  81. data/lib/appsignal/transaction/formatter.rb +0 -85
  82. data/lib/appsignal/transaction/params_sanitizer.rb +0 -4
  83. data/lib/appsignal/zipped_payload.rb +0 -37
  84. data/spec/lib/appsignal/agent_spec.rb +0 -592
  85. data/spec/lib/appsignal/aggregator/middleware/action_view_sanitizer_spec.rb +0 -44
  86. data/spec/lib/appsignal/aggregator/middleware/chain_spec.rb +0 -168
  87. data/spec/lib/appsignal/aggregator/middleware/delete_blanks_spec.rb +0 -37
  88. data/spec/lib/appsignal/aggregator/post_processor_spec.rb +0 -99
  89. data/spec/lib/appsignal/aggregator_spec.rb +0 -186
  90. data/spec/lib/appsignal/event_spec.rb +0 -48
  91. data/spec/lib/appsignal/integrations/padrino_spec.rb +0 -171
  92. data/spec/lib/appsignal/integrations/passenger_spec.rb +0 -22
  93. data/spec/lib/appsignal/integrations/rake_spec.rb +0 -92
  94. data/spec/lib/appsignal/integrations/unicorn_spec.rb +0 -48
  95. data/spec/lib/appsignal/ipc_spec.rb +0 -128
  96. data/spec/lib/appsignal/transaction/formatter_spec.rb +0 -247
  97. data/spec/lib/appsignal/zipped_payload_spec.rb +0 -42
@@ -1,44 +0,0 @@
1
- require 'spec_helper'
2
-
3
- if rails_present?
4
- require 'action_view'
5
- require 'appsignal/aggregator/middleware/action_view_sanitizer'
6
-
7
- describe Appsignal::Aggregator::Middleware::ActionViewSanitizer do
8
- let(:klass) { Appsignal::Aggregator::Middleware::ActionViewSanitizer }
9
- let(:sanitizer) { klass.new }
10
-
11
- describe "#call" do
12
- before { Rails.root.stub(:to_s => '/var/www/app/20130101') }
13
- let(:event) do
14
- notification_event(
15
- :name => 'render_partial.action_view',
16
- :payload => create_payload(payload)
17
- )
18
- end
19
- let(:payload) do
20
- {
21
- :identifier => '/var/www/app/20130101/app/views/home/index/html.erb'
22
- }
23
- end
24
- subject { event.payload }
25
- before { sanitizer.call(event) { } }
26
-
27
- it "should strip Rails root from the path" do
28
- subject[:identifier].should == 'app/views/home/index/html.erb'
29
- end
30
-
31
- context "with a frozen identifier" do
32
- let(:payload) do
33
- {
34
- :identifier => '/var/www/app/20130101/app/views/home/index/html.erb'.freeze
35
- }
36
- end
37
-
38
- it "should strip Rails root from the path" do
39
- subject[:identifier].should == 'app/views/home/index/html.erb'
40
- end
41
- end
42
- end
43
- end
44
- end
@@ -1,168 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Appsignal::Aggregator::Middleware do
4
- let(:chain_klass) { Appsignal::Aggregator::Middleware::Chain }
5
- let(:entry_klass) { Appsignal::Aggregator::Middleware::Entry }
6
- let(:chain) { chain_klass.new }
7
- let(:entry) { entry_klass.new(object, {:foo => :bar}) }
8
-
9
- describe Appsignal::Aggregator::Middleware::Chain do
10
- let(:object) { double(:object) }
11
- let(:other_object) { double(:other_object) }
12
-
13
- describe "#initialize" do
14
- it "yields itself when passing a block" do
15
- chain_klass.new { |o| o.should be_instance_of chain_klass }
16
- end
17
- end
18
-
19
- describe "#remove" do
20
- subject { chain.remove(object) }
21
- before { chain.add(other_object) }
22
-
23
- context "when it doesn't find the object" do
24
- specify { expect { subject }.to_not raise_error }
25
- end
26
-
27
- context "when it finds the object" do
28
- before { chain.add(object) }
29
-
30
- specify { expect { subject }.to change(chain.entries, :count).by(-1) }
31
- end
32
- end
33
-
34
- describe "#add" do
35
- subject { chain.add(object) }
36
-
37
- context "adding a new object" do
38
- specify { expect { subject }.to change(chain.entries, :count).by(1) }
39
- end
40
-
41
- context "trying to add a duplicate (even with different arguments)" do
42
- before { chain.add(object, :some_arguments) }
43
-
44
- specify { expect { subject }.to_not change(chain.entries, :count).by(1) }
45
- end
46
- end
47
-
48
- context "with a chain holding three items" do
49
- subject { chain.entries.map(&:klass) }
50
- before { [:first, :second, :third].each { |o| chain.add(o) } }
51
-
52
- describe "#insert_before" do
53
-
54
- context "before the second" do
55
- before { chain.insert_before(:second, :object) }
56
-
57
- it { should == [:first, :object, :second, :third] }
58
- end
59
-
60
- context "before the first" do
61
- before { chain.insert_before(:first, :object) }
62
-
63
- it { should == [:object, :first, :second, :third] }
64
- end
65
- end
66
-
67
- describe "#insert_after" do
68
-
69
- context "after the second" do
70
- before { chain.insert_after(:second, :object) }
71
-
72
- it { should == [:first, :second, :object, :third] }
73
- end
74
-
75
- context "after the third" do
76
- before { chain.insert_after(:third, :object) }
77
-
78
- it { should == [:first, :second, :third, :object] }
79
- end
80
- end
81
-
82
- describe "#exists?" do
83
- subject { chain.exists?(object) }
84
-
85
- context "when it is in the chain" do
86
- let(:object) { :first }
87
-
88
- it { should be_true }
89
- end
90
-
91
- context "when it is not" do
92
- let(:object) { :unknown }
93
-
94
- it { should be_false }
95
- end
96
- end
97
-
98
- describe "#retrieve" do
99
- specify { chain.entries.each { |o| o.should_receive(:make_new) } }
100
-
101
- after { chain.retrieve }
102
- end
103
-
104
- describe "#clear" do
105
- before { chain.clear }
106
- subject { chain.entries }
107
-
108
- it { should be_empty }
109
- end
110
- end
111
-
112
- describe "#invoke" do
113
- let(:recorder) { [] }
114
- subject { chain.invoke(:unsused) }
115
- before(:all) do
116
- TestInvoker1 = Struct.new(:id, :recorder) do
117
- def call(event)
118
- recorder << "Before#{id}"
119
- yield
120
- recorder << "After#{id}"
121
- end
122
- end
123
- TestInvoker3 = Class.new(TestInvoker1)
124
- end
125
-
126
- context "all yielding entries" do
127
- before do
128
- TestInvoker2 = Class.new(TestInvoker1)
129
-
130
- chain.add(TestInvoker1, 1, recorder)
131
- chain.add(TestInvoker2, 2, recorder)
132
- chain.add(TestInvoker3, 3, recorder)
133
- end
134
-
135
- it { should == %w(Before1 Before2 Before3 After3 After2 After1) }
136
- end
137
-
138
- context "a non yielding entry" do
139
- before do
140
- TestBlocker = Struct.new(:recorder) do
141
- def call(event)
142
- recorder << 'End-of-the-line!'
143
- end
144
- end
145
-
146
- chain.add(TestInvoker1, 1, recorder)
147
- chain.add(TestBlocker, recorder)
148
- chain.add(TestInvoker3, 3, recorder)
149
- end
150
-
151
- it { should == %w(Before1 End-of-the-line! After1) }
152
- end
153
- end
154
- end
155
-
156
- describe Appsignal::Aggregator::Middleware::Entry do
157
-
158
- describe "#make_new" do
159
- let(:object) { double }
160
- subject { entry.make_new }
161
-
162
- it "initializes the passed object" do
163
- object.should_receive(:new)
164
- subject
165
- end
166
- end
167
- end
168
- end
@@ -1,37 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Appsignal::Aggregator::Middleware::DeleteBlanks do
4
- let(:klass) { Appsignal::Aggregator::Middleware::DeleteBlanks }
5
- let(:delete_blanks) { klass.new }
6
-
7
- describe "#call" do
8
- let(:event) do
9
- notification_event(
10
- :name => 'something',
11
- :payload => create_payload(payload)
12
- )
13
- end
14
- let(:payload) do
15
- {
16
- :string => 'not empty',
17
- :array => ['something'],
18
- :hash => {'something' => 'something'},
19
- :empty_string => '',
20
- :empty_array => [],
21
- :empty_hash => {},
22
- :nil => nil
23
- }
24
- end
25
- subject { event.payload }
26
- before { delete_blanks.call(event) { } }
27
-
28
- it { should have_key(:string) }
29
- it { should have_key(:array) }
30
- it { should have_key(:hash) }
31
-
32
- it { should_not have_key(:empty_string) }
33
- it { should_not have_key(:empty_array) }
34
- it { should_not have_key(:empty_hash) }
35
- it { should_not have_key(:nil) }
36
- end
37
- end
@@ -1,99 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Appsignal::Aggregator::PostProcessor do
4
- before :all do
5
- start_agent
6
- end
7
-
8
- let(:klass) { Appsignal::Aggregator::PostProcessor }
9
- let(:post_processor) { klass.new(transactions) }
10
-
11
- describe "#initialize" do
12
- subject { klass.new(:foo) }
13
-
14
- its(:transactions) { should == :foo }
15
- end
16
-
17
- describe "#post_processed_queue!" do
18
- let(:first_transaction) { regular_transaction }
19
- let(:second_transaction) do
20
- slow_transaction(
21
- :events => [
22
- notification_event(
23
- :payload => {
24
- :set_value => 'set value',
25
- :nil_value => nil
26
- }
27
- )
28
- ]
29
- )
30
- end
31
- let(:transactions) { [first_transaction, second_transaction] }
32
- let(:processed_queue) { post_processor.post_processed_queue! }
33
- subject { processed_queue }
34
-
35
- it { should have(2).items }
36
-
37
- context "the first transaction" do
38
- subject { processed_queue[0] }
39
-
40
- it { should_not have_key(:events) }
41
-
42
- context "log entry" do
43
- subject { processed_queue[0][:log_entry] }
44
-
45
- it { should have_key(:duration) }
46
- it { should have_key(:end) }
47
- it { should_not have_key(:events) }
48
- end
49
- end
50
-
51
- context "the second transaction" do
52
- context "log entry" do
53
- subject { processed_queue[1][:log_entry] }
54
-
55
- it { should have_key(:duration) }
56
- it { should have_key(:end) }
57
- end
58
-
59
- context "first event" do
60
- subject { processed_queue[1][:events][0] }
61
-
62
- it { should_not be_nil }
63
- it { should have_key(:name) }
64
-
65
- it "should have the set value in the payload" do
66
- subject[:payload][:set_value].should == 'set value'
67
- end
68
-
69
- it "should not have the nil value in the payload"\
70
- "since delete blanks is in the middle ware stack" do
71
- subject[:payload].should_not have_key(:nil_value)
72
- end
73
- end
74
- end
75
- end
76
-
77
- describe ".default_middleware" do
78
- subject { klass.default_middleware }
79
-
80
- it { should be_instance_of Appsignal::Aggregator::Middleware::Chain }
81
-
82
- it "should include the default middleware stack" do
83
- subject.exists?(Appsignal::Aggregator::Middleware::DeleteBlanks).should be_true
84
- if rails_present?
85
- subject.exists?(Appsignal::Aggregator::Middleware::ActionViewSanitizer).should be_true
86
-
87
- if active_record_present?
88
- subject.exists?(Appsignal::Aggregator::Middleware::ActiveRecordSanitizer).should be_true
89
- end
90
- else
91
- subject.exists?(Appsignal::Aggregator::Middleware::ActionViewSanitizer).should be_false
92
-
93
- if active_record_present?
94
- subject.exists?(Appsignal::Aggregator::Middleware::ActiveRecordSanitizer).should be_false
95
- end
96
- end
97
- end
98
- end
99
- end
@@ -1,186 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Appsignal::Aggregator do
4
- before :all do
5
- start_agent
6
- end
7
-
8
- let(:aggregator) { Appsignal::Aggregator.new }
9
-
10
- describe "#add" do
11
- subject { aggregator.add(transaction) }
12
-
13
- context "adding a regular transaction" do
14
- let(:transaction) { regular_transaction }
15
-
16
- specify { transaction.should_receive(:truncate!) }
17
- end
18
-
19
- context "adding a slow transaction" do
20
- let(:transaction) { slow_transaction }
21
-
22
- specify {
23
- aggregator.should_receive(:pre_process_slowness!).with(transaction)
24
- }
25
- end
26
-
27
- context "adding a transaction with an exception" do
28
- let(:transaction) { transaction_with_exception }
29
-
30
- specify { transaction.should_receive(:clear_events!) }
31
- specify { transaction.should_receive(:convert_values_to_primitives!) }
32
- end
33
-
34
- after { subject }
35
- end
36
-
37
- describe "#has_transactions?" do
38
- subject { aggregator.has_transactions? }
39
-
40
- context "with an empty queue" do
41
- it { should be_false }
42
- end
43
-
44
- context "with an non empty queue" do
45
- before { aggregator.add(regular_transaction) }
46
-
47
- it { should be_true }
48
- end
49
- end
50
-
51
- describe "#post_processed_queue!" do
52
- let(:transaction) { slow_transaction }
53
- let(:other_transaction) { regular_transaction }
54
- subject { aggregator.post_processed_queue! }
55
- before do
56
- aggregator.add(transaction)
57
- aggregator.add(other_transaction)
58
- end
59
-
60
- it { should be_a Array }
61
-
62
- it "calls to_hash on each transaction in the queue" do
63
- transaction.should_receive(:to_hash)
64
- other_transaction.should_receive(:to_hash)
65
- subject
66
- end
67
- end
68
-
69
- # protected
70
-
71
- describe "#similar_slowest" do
72
- subject { aggregator.send(:similar_slowest, transaction) }
73
- before { aggregator.add(other_transaction) }
74
-
75
- context "passing a transaction concerning a different action" do
76
- let(:transaction) { slow_transaction }
77
- let(:other_transaction) do
78
- time = Time.parse('01-01-2001 10:01:00')
79
- appsignal_transaction(
80
- :process_action_event => notification_event(
81
- :payload => create_payload(
82
- :action => 'show',
83
- :controller => 'SomeOtherController'
84
- )
85
- )
86
- )
87
- end
88
-
89
- it { should be_nil }
90
- end
91
-
92
- context "passing concerning the same action" do
93
- let(:transaction) { slow_transaction }
94
- let(:other_transaction) { slower_transaction }
95
-
96
- it { should == other_transaction }
97
- end
98
- end
99
-
100
- describe "#pre_process_slowness!" do
101
- subject { aggregator.send(:pre_process_slowness!, transaction) }
102
-
103
- context "without a similar slow transaction" do
104
- let(:transaction) { slow_transaction }
105
-
106
- it "calls convert_values_to_primitives on transaction" do
107
- transaction.should_receive(:convert_values_to_primitives!)
108
- subject
109
- end
110
-
111
- it "indexes the slow transaction" do
112
- expect { subject }.to change(aggregator, :slowness_index).
113
- to({transaction.action => transaction})
114
- end
115
- end
116
-
117
- context "with a non similar slow transaction" do
118
- let(:transaction) { slow_transaction }
119
- let(:other_transaction) do
120
- time = Time.parse('01-01-2001 10:01:00')
121
- appsignal_transaction(
122
- :process_action_event => notification_event(
123
- :action => 'foooo',
124
- :start => time,
125
- :ending => time + Appsignal.config[:slow_request_threshold] / 500.0
126
- )
127
- )
128
- end
129
-
130
- it "calls convert_values_to_primitives on transaction" do
131
- transaction.should_receive(:convert_values_to_primitives!)
132
- subject
133
- end
134
-
135
- it "indexes the slow transaction" do
136
- expect { subject }.to change(aggregator, :slowness_index).to({
137
- other_transaction.action => other_transaction,
138
- transaction.action => transaction
139
- })
140
- end
141
- end
142
-
143
- context "with a similar but slower transaction" do
144
- let(:transaction) { slow_transaction }
145
- let(:slower) { slower_transaction }
146
- before { aggregator.add(slower) }
147
-
148
- it "calls truncate on the transaction" do
149
- transaction.should_receive(:truncate!)
150
- transaction.should_not_receive(:convert_values_to_primitives!)
151
- subject
152
- end
153
-
154
- it "does not index the slow transaction" do
155
- expect { subject }.to_not change(aggregator, :slowness_index)
156
- end
157
-
158
- it "does not modify the slow transaction" do
159
- slower.should_not_receive(:truncate!)
160
- slower.should_not_receive(:convert_values_to_primitives!)
161
- subject
162
- end
163
- end
164
-
165
- context "with a similar but faster transaction" do
166
- let(:transaction) { slower_transaction }
167
- let(:faster_transaction) { slow_transaction }
168
- before { aggregator.add(faster_transaction) }
169
-
170
- it "calls truncate on the faster transaction" do
171
- faster_transaction.should_receive(:truncate!)
172
- subject
173
- end
174
-
175
- it "calls convert_values_to_primitives on the (slower) transaction" do
176
- transaction.should_receive(:convert_values_to_primitives!)
177
- subject
178
- end
179
-
180
- it "indexes the slow transaction" do
181
- expect { subject }.to change(aggregator, :slowness_index).
182
- to({faster_transaction.action => transaction})
183
- end
184
- end
185
- end
186
- end