appsignal 0.12.rc.9 → 0.12.rc.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 17f4e46dd0c600079ccdb20831f64e73451749b4
4
- data.tar.gz: 723ed8e27a02f660f8dc5135c8d4982a909c2bf6
3
+ metadata.gz: 693aa4f235ee31447feb2a8b1f33a70df69fee2c
4
+ data.tar.gz: d52a48f030ed7a0b816b315365e0a71a26a77436
5
5
  SHA512:
6
- metadata.gz: 33d094d086f748d6932e93960bb1ebfd3cf1dcc3a77be03c68a3f32fca800caf35bb73551141c084702e6ecac3352cdad2f5d271dc083a74c9b3c8aca3fd16c7
7
- data.tar.gz: ee504d004f15bab3e1786ef0b5241e8efa661d67883266559f81fc658b2e488c6d2904a53de91a01f54e0f72b0880577532002115d56411ca3b8c7b301e94daf
6
+ metadata.gz: 20ba8304f8ac2b8969b34f869e7cd0f9ea43c9ba007112dd6d1195e2bcbcfc9d1b0210acba9ceb529b4b7cc576ce4b34c3c5f5fd3737023ff8d8b086cd1ca74c
7
+ data.tar.gz: 8909aa17bfec6253d49c4ad7bdff01d57f8cc66c4c8b4a905ced96e5be942f918e8681788f209fbe8073d806288bc342954013eb89980eeb02cc46caa515f877
data/README.md CHANGED
@@ -8,81 +8,22 @@ applications and sends it to [AppSignal](https://appsignal.com)
8
8
  [![Gem Version](https://badge.fury.io/rb/appsignal.svg)](http://badge.fury.io/rb/appsignal)
9
9
  [![Code Climate](https://codeclimate.com/github/appsignal/appsignal.png)](https://codeclimate.com/github/appsignal/appsignal)
10
10
 
11
- ## Pull requests / issues
12
-
13
- New features should be made in an issue or pullrequest. Title format is as follows:
14
-
15
- name [request_count]
16
-
17
- example
18
-
19
- tagging [2]
20
-
21
- ## Postprocessing middleware
22
-
23
- Appsignal sends Rails
24
- [ActiveSupport::Notification](http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html)-events
25
- to AppSignal over SSL. These events contain basic metadata such as a name
26
- and timestamps, and additional 'payload' log data. Appsignal uses a postprocessing
27
- middleware stack to clean up events before they get sent to appsignal.com. You
28
- can add your own middleware to this stack in `config/environment/my_env.rb`.
29
-
30
- ### Examples
31
-
32
- #### Minimal template
33
-
34
- ```ruby
35
- class MiddlewareTemplate
36
- def call(event)
37
- # modify the event in place
38
- yield # pass control to the next middleware
39
- # modify the event some more
40
- end
41
- end
42
-
43
- Appsignal.post_processing_middleware.add MiddlewareTemplate
44
- ```
45
-
46
- #### Remove boring payloads
47
-
48
- ```ruby
49
- class RemoveBoringPayload
50
- def call(event)
51
- event.payload.clear unless event.name == 'interesting'
52
- yield
53
- end
54
- end
55
- ```
56
-
57
11
  ## Development
58
12
 
59
- Run rake bundle or, or run bundle install for all Gemfiles:
60
-
61
- ```
62
- bundle --gemfile gemfiles/capistrano2.gemfile
63
- bundle --gemfile gemfiles/capistrano3.gemfile
64
- bundle --gemfile gemfiles/no_dependencies.gemfile
65
- bundle --gemfile gemfiles/rails-3.0.gemfile
66
- bundle --gemfile gemfiles/rails-3.1.gemfile
67
- bundle --gemfile gemfiles/rails-3.2.gemfile
68
- bundle --gemfile gemfiles/rails-4.0.gemfile
69
- bundle --gemfile gemfiles/rails-4.1.gemfile
70
- bundle --gemfile gemfiles/rails-4.2.gemfile
71
- bundle --gemfile gemfiles/sinatra.gemfile
72
- ```
73
-
74
- To run the spec suite with a specific Gemfile:
13
+ Run `rake install`, then run the spec suite with a specific Gemfile:
75
14
 
76
15
  ```
77
16
  BUNDLE_GEMFILE=gemfiles/capistrano2.gemfile bundle exec rspec
78
17
  BUNDLE_GEMFILE=gemfiles/capistrano3.gemfile bundle exec rspec
79
18
  BUNDLE_GEMFILE=gemfiles/no_dependencies.gemfile bundle exec rspec
19
+ BUNDLE_GEMFILE=gemfiles/padrino.gemfile bundle exec rspec
80
20
  BUNDLE_GEMFILE=gemfiles/rails-3.0.gemfile bundle exec rspec
81
21
  BUNDLE_GEMFILE=gemfiles/rails-3.1.gemfile bundle exec rspec
82
22
  BUNDLE_GEMFILE=gemfiles/rails-3.2.gemfile bundle exec rspec
83
23
  BUNDLE_GEMFILE=gemfiles/rails-4.0.gemfile bundle exec rspec
84
24
  BUNDLE_GEMFILE=gemfiles/rails-4.1.gemfile bundle exec rspec
85
25
  BUNDLE_GEMFILE=gemfiles/rails-4.2.gemfile bundle exec rspec
26
+ BUNDLE_GEMFILE=gemfiles/sequel.gemfile bundle exec rspec
86
27
  BUNDLE_GEMFILE=gemfiles/sinatra.gemfile bundle exec rspec
87
28
  ```
88
29
 
data/Rakefile CHANGED
@@ -93,7 +93,8 @@ task :publish do
93
93
  end
94
94
  end
95
95
 
96
- task :bundle do
96
+ task :install do
97
+ system 'cd ext && rm -f libappsignal.a && ruby extconf.rb && make clean && make && cd ..'
97
98
  GEMFILES.each do |gemfile|
98
99
  system "bundle --gemfile gemfiles/#{gemfile}.gemfile"
99
100
  end
@@ -119,7 +120,7 @@ task :generate_bundle_and_spec_all do
119
120
  RUBY_VERSIONS.each do |version|
120
121
  out << "echo 'Switching to #{version}'"
121
122
  out << "#{switch_command} #{version} || { echo 'Switching Ruby failed'; exit 1; }"
122
- out << 'cd ext && ruby extconf.rb && make clean && make && cd ..'
123
+ out << 'cd ext && rm -f libappsignal.a && ruby extconf.rb && make clean && make && cd ..'
123
124
  GEMFILES.each do |gemfile|
124
125
  out << "echo 'Bundling #{gemfile} in #{version}'"
125
126
  out << "bundle --quiet --gemfile gemfiles/#{gemfile}.gemfile || { echo 'Bundling failed'; exit 1; }"
@@ -1,15 +1,15 @@
1
1
  ---
2
- :version: 526bdf1
2
+ :version: ae85df1
3
3
  :triples:
4
4
  x86_64-linux:
5
- :checksum: d5d83c289af971b40f23dc41a41567e0d41e98d2754eeed4427b7b2473881818
6
- :download_url: https://appsignal-agent-releases.global.ssl.fastly.net/526bdf1/appsignal-agent-x86_64-linux-static.tar.gz
5
+ :checksum: f5b31b2e487a9865bf660ef244142e38f18d90b7ff91d538fff9d3d9b386c044
6
+ :download_url: https://appsignal-agent-releases.global.ssl.fastly.net/ae85df1/appsignal-agent-x86_64-linux-static.tar.gz
7
7
  :lib_filename: libappsignal.a
8
8
  i686-linux:
9
- :checksum: b8b3bf1a5ae67e97ff623e1252c6f0299306951033e4fb93478aa76dc95218f1
10
- :download_url: https://appsignal-agent-releases.global.ssl.fastly.net/526bdf1/appsignal-agent-i686-linux-static.tar.gz
9
+ :checksum: 6a053ed939a6f9c36271ac4b421674d01e2ea4d6b962914cec5fbb36f64675bd
10
+ :download_url: https://appsignal-agent-releases.global.ssl.fastly.net/ae85df1/appsignal-agent-i686-linux-static.tar.gz
11
11
  :lib_filename: libappsignal.a
12
12
  x86_64-darwin:
13
- :checksum: 4eab82317a874d4d3b7fc666ce562fa7e5f346cda22707d556a236894269a838
14
- :download_url: https://appsignal-agent-releases.global.ssl.fastly.net/526bdf1/appsignal-agent-x86_64-darwin-static.tar.gz
13
+ :checksum: 91fe3a509541a9d18c1cc41821df21d3b09bf6e0bbcbd52e30b49674c348cd32
14
+ :download_url: https://appsignal-agent-releases.global.ssl.fastly.net/ae85df1/appsignal-agent-x86_64-darwin-static.tar.gz
15
15
  :lib_filename: libappsignal.a
@@ -41,25 +41,27 @@ static VALUE finish_event(VALUE self, VALUE transaction_index, VALUE name, VALUE
41
41
  return Qnil;
42
42
  }
43
43
 
44
- static VALUE set_transaction_error(VALUE self, VALUE transaction_index, VALUE name, VALUE message) {
44
+ static VALUE set_transaction_error(VALUE self, VALUE transaction_index, VALUE name, VALUE message, VALUE backtrace) {
45
45
  Check_Type(transaction_index, T_FIXNUM);
46
46
  Check_Type(name, T_STRING);
47
47
  Check_Type(message, T_STRING);
48
+ Check_Type(backtrace, T_STRING);
48
49
 
49
50
  appsignal_set_transaction_error(
50
51
  FIX2INT(transaction_index),
51
52
  StringValueCStr(name),
52
- StringValueCStr(message)
53
+ StringValueCStr(message),
54
+ StringValueCStr(backtrace)
53
55
  );
54
56
  return Qnil;
55
57
  }
56
58
 
57
- static VALUE set_transaction_error_data(VALUE self, VALUE transaction_index, VALUE key, VALUE payload) {
59
+ static VALUE set_transaction_sample_data(VALUE self, VALUE transaction_index, VALUE key, VALUE payload) {
58
60
  Check_Type(transaction_index, T_FIXNUM);
59
61
  Check_Type(key, T_STRING);
60
62
  Check_Type(payload, T_STRING);
61
63
 
62
- appsignal_set_transaction_error_data(
64
+ appsignal_set_transaction_sample_data(
63
65
  FIX2INT(transaction_index),
64
66
  StringValueCStr(key),
65
67
  StringValueCStr(payload)
@@ -105,7 +107,14 @@ static VALUE set_transaction_metadata(VALUE self, VALUE transaction_index, VALUE
105
107
  static VALUE finish_transaction(VALUE self, VALUE transaction_index) {
106
108
  Check_Type(transaction_index, T_FIXNUM);
107
109
 
108
- appsignal_finish_transaction(FIX2INT(transaction_index));
110
+ int sample = appsignal_finish_transaction(FIX2INT(transaction_index));
111
+ return sample == 1 ? Qtrue : Qfalse;
112
+ }
113
+
114
+ static VALUE complete_transaction(VALUE self, VALUE transaction_index) {
115
+ Check_Type(transaction_index, T_FIXNUM);
116
+
117
+ appsignal_complete_transaction(FIX2INT(transaction_index));
109
118
  return Qnil;
110
119
  }
111
120
 
@@ -228,12 +237,13 @@ void Init_appsignal_extension(void) {
228
237
  rb_define_singleton_method(Extension, "start_transaction", start_transaction, 2);
229
238
  rb_define_singleton_method(Extension, "start_event", start_event, 1);
230
239
  rb_define_singleton_method(Extension, "finish_event", finish_event, 4);
231
- rb_define_singleton_method(Extension, "set_transaction_error", set_transaction_error, 3);
232
- rb_define_singleton_method(Extension, "set_transaction_error_data", set_transaction_error_data, 3);
240
+ rb_define_singleton_method(Extension, "set_transaction_error", set_transaction_error, 4);
241
+ rb_define_singleton_method(Extension, "set_transaction_sample_data", set_transaction_sample_data, 3);
233
242
  rb_define_singleton_method(Extension, "set_transaction_action", set_transaction_action, 2);
234
243
  rb_define_singleton_method(Extension, "set_transaction_queue_start", set_transaction_queue_start, 2);
235
244
  rb_define_singleton_method(Extension, "set_transaction_metadata", set_transaction_metadata, 3);
236
245
  rb_define_singleton_method(Extension, "finish_transaction", finish_transaction, 1);
246
+ rb_define_singleton_method(Extension, "complete_transaction", complete_transaction, 1);
237
247
 
238
248
  // Event hook installation
239
249
  rb_define_singleton_method(Extension, "install_allocation_event_hook", install_allocation_event_hook, 0);
@@ -169,7 +169,7 @@ module Appsignal
169
169
  Appsignal::Extension.set_process_gauge(key, value.to_f)
170
170
  end
171
171
 
172
- def increment_counter(key, value)
172
+ def increment_counter(key, value=1)
173
173
  Appsignal::Extension.increment_counter(key, value)
174
174
  end
175
175
 
@@ -20,7 +20,8 @@ module Appsignal
20
20
  :enable_frontend_error_catching => false,
21
21
  :frontend_error_catching_path => '/appsignal_error_catcher',
22
22
  :enable_allocation_tracking => true,
23
- :enable_gc_instrumentation => true
23
+ :enable_gc_instrumentation => true,
24
+ :running_in_container => false
24
25
  }.freeze
25
26
 
26
27
  ENV_TO_KEY_MAPPING = {
@@ -40,7 +41,8 @@ module Appsignal
40
41
  'APPSIGNAL_IGNORE_ACTIONS' => :ignore_actions,
41
42
  'APPSIGNAL_HTTP_PROXY' => :http_proxy,
42
43
  'APPSIGNAL_ENABLE_ALLOCATION_TRACKING' => :enable_allocation_tracking,
43
- 'APPSIGNAL_ENABLE_GC_INSTRUMENTATION' => :enable_gc_instrumentation
44
+ 'APPSIGNAL_ENABLE_GC_INSTRUMENTATION' => :enable_gc_instrumentation,
45
+ 'APPSIGNAL_RUNNING_IN_CONTAINER' => :running_in_container
44
46
  }.freeze
45
47
 
46
48
  attr_reader :root_path, :env, :initial_config, :config_hash
@@ -75,8 +77,7 @@ module Appsignal
75
77
  path = config_hash[:log_path] || root_path
76
78
  File.join(File.realpath(path), 'appsignal.log')
77
79
  rescue Errno::ENOENT
78
- puts "appsignal: WARNING: log file path '#{path}' does not exist or is not writable"
79
- nil
80
+ '/tmp/appsignal.log'
80
81
  end
81
82
 
82
83
  def valid?
@@ -101,6 +102,7 @@ module Appsignal
101
102
  ENV['APPSIGNAL_APP_NAME'] = config_hash[:name]
102
103
  ENV['APPSIGNAL_HTTP_PROXY'] = config_hash[:http_proxy]
103
104
  ENV['APPSIGNAL_IGNORE_ACTIONS'] = config_hash[:ignore_actions].join(',')
105
+ ENV['APPSIGNAL_RUNNING_IN_CONTAINER'] = config_hash[:running_in_container].to_s
104
106
  end
105
107
 
106
108
  protected
@@ -151,7 +153,8 @@ module Appsignal
151
153
  # Configuration with boolean type
152
154
  %w(APPSIGNAL_ACTIVE APPSIGNAL_DEBUG APPSIGNAL_INSTRUMENT_NET_HTTP
153
155
  APPSIGNAL_SKIP_SESSION_DATA APPSIGNAL_ENABLE_FRONTEND_ERROR_CATCHING
154
- APPSIGNAL_ENABLE_ALLOCATION_TRACKING APPSIGNAL_ENABLE_GC_INSTRUMENTATION).each do |var|
156
+ APPSIGNAL_ENABLE_ALLOCATION_TRACKING APPSIGNAL_ENABLE_GC_INSTRUMENTATION
157
+ APPSIGNAL_RUNNING_IN_CONTAINER).each do |var|
155
158
  if env_var = ENV[var]
156
159
  config[ENV_TO_KEY_MAPPING[var]] = env_var == 'true'
157
160
  end
@@ -45,6 +45,44 @@ module Appsignal
45
45
  raise NotImplementedError
46
46
  end
47
47
  end
48
+
49
+ module Helpers
50
+
51
+ def self.included(base)
52
+ base.extend(ClassMethods)
53
+ end
54
+
55
+ module ClassMethods
56
+ def truncate(text)
57
+ Appsignal::Hooks::Helpers.truncate(text)
58
+ end
59
+
60
+ def string_or_inspect(string_or_other)
61
+ Appsignal::Hooks::Helpers.string_or_inspect(string_or_other)
62
+ end
63
+ end
64
+
65
+ def string_or_inspect(string_or_other)
66
+ Appsignal::Hooks::Helpers.string_or_inspect(string_or_other)
67
+ end
68
+
69
+ def truncate(text)
70
+ Appsignal::Hooks::Helpers.truncate(text)
71
+ end
72
+
73
+ def self.string_or_inspect(string_or_other)
74
+ if string_or_other.is_a?(String)
75
+ string_or_other
76
+ else
77
+ string_or_other.inspect
78
+ end
79
+ end
80
+
81
+ def self.truncate(text)
82
+ text.size > 200 ? "#{text[0...197]}..." : text
83
+ end
84
+ end
85
+
48
86
  end
49
87
  end
50
88
 
@@ -1,6 +1,8 @@
1
1
  module Appsignal
2
2
  class Hooks
3
3
  class SidekiqPlugin
4
+ include Appsignal::Hooks::Helpers
5
+
4
6
  def job_keys
5
7
  @job_keys ||= Set.new(%w(
6
8
  class args retried_at failed_at
@@ -30,23 +32,11 @@ module Appsignal
30
32
  end
31
33
  end
32
34
 
33
- def string_or_inspect(string_or_other)
34
- if string_or_other.is_a?(String)
35
- string_or_other
36
- else
37
- string_or_other.inspect
38
- end
39
- end
40
-
41
35
  def format_args(args)
42
36
  args.map do |arg|
43
37
  truncate(string_or_inspect(arg))
44
38
  end
45
39
  end
46
-
47
- def truncate(text)
48
- text.size > 200 ? "#{text[0...197]}..." : text
49
- end
50
40
  end
51
41
 
52
42
  class SidekiqHook < Appsignal::Hooks::Hook
@@ -1,6 +1,8 @@
1
1
  module Appsignal
2
2
  class Hooks
3
3
  class DelayedJobPlugin < ::Delayed::Plugin
4
+ include Appsignal::Hooks::Helpers
5
+
4
6
  callbacks do |lifecycle|
5
7
  lifecycle.around(:invoke_job) do |job, &block|
6
8
  invoke_with_instrumentation(job, block)
@@ -29,11 +31,18 @@ module Appsignal
29
31
  :priority => job.priority || 0,
30
32
  :attempts => job.attempts || 0
31
33
  },
34
+ :params => format_args(job.payload_object.args),
32
35
  :queue_start => job.created_at
33
36
  ) do
34
37
  block.call(job)
35
38
  end
36
39
  end
40
+
41
+ def self.format_args(args)
42
+ args.map do |arg|
43
+ self.truncate(self.string_or_inspect(arg))
44
+ end
45
+ end
37
46
  end
38
47
  end
39
48
  end
@@ -10,7 +10,7 @@ module Appsignal
10
10
  set_action
11
11
  set_metadata
12
12
  set_error
13
- set_error_data
13
+ set_sample_data
14
14
  end
15
15
 
16
16
  def set_action
@@ -27,20 +27,20 @@ module Appsignal
27
27
  Appsignal::Extension.set_transaction_error(
28
28
  @transaction_index,
29
29
  @data['name'],
30
- @data['message']
30
+ @data['message'],
31
+ JSON.generate(@data['backtrace'])
31
32
  )
32
33
  end
33
34
 
34
- def set_error_data
35
+ def set_sample_data
35
36
  {
36
37
  :params => @data['params'],
37
38
  :environment => @data['environment'],
38
- :backtrace => @data['backtrace'],
39
39
  :tags => @data['tags']
40
40
  }.each do |key, data|
41
41
  next unless data.is_a?(Array) || data.is_a?(Hash)
42
42
  begin
43
- Appsignal::Extension.set_transaction_error_data(
43
+ Appsignal::Extension.set_transaction_sample_data(
44
44
  @transaction_index,
45
45
  key.to_s,
46
46
  JSON.generate(data)
@@ -26,7 +26,7 @@ module Appsignal
26
26
 
27
27
  def complete_current!
28
28
  if current
29
- Appsignal::Extension.finish_transaction(current.transaction_index)
29
+ current.complete
30
30
  Thread.current[:appsignal_transaction] = nil
31
31
  else
32
32
  Appsignal.logger.error('Trying to complete current, but no transaction present')
@@ -49,6 +49,13 @@ module Appsignal
49
49
  @transaction_index = Appsignal::Extension.start_transaction(@transaction_id, @namespace)
50
50
  end
51
51
 
52
+ def complete
53
+ if Appsignal::Extension.finish_transaction(transaction_index)
54
+ sample_data
55
+ end
56
+ Appsignal::Extension.complete_transaction(transaction_index)
57
+ end
58
+
52
59
  def pause!
53
60
  @paused = true
54
61
  end
@@ -97,36 +104,43 @@ module Appsignal
97
104
  Appsignal::Extension.set_transaction_metadata(transaction_index, key, value)
98
105
  end
99
106
 
100
- def set_error(error)
101
- return unless error
102
- return if Appsignal.is_ignored_error?(error)
103
-
104
- Appsignal.logger.debug("Adding #{error.class.name} to transaction: #{transaction_id}")
105
- Appsignal::Extension.set_transaction_error(
107
+ def set_sample_data(key, data)
108
+ return unless key && data && (data.is_a?(Array) || data.is_a?(Hash))
109
+ Appsignal::Extension.set_transaction_sample_data(
106
110
  transaction_index,
107
- error.class.name,
108
- error.message
111
+ key.to_s,
112
+ JSON.generate(data)
109
113
  )
114
+ rescue JSON::GeneratorError=>e
115
+ Appsignal.logger.error("JSON generate error (#{e.message}) for '#{data.inspect}'")
116
+ end
110
117
 
118
+ def sample_data
111
119
  {
112
120
  :params => sanitized_params,
113
121
  :environment => sanitized_environment,
114
122
  :session_data => sanitized_session_data,
115
- :backtrace => cleaned_backtrace(error.backtrace),
116
123
  :tags => sanitized_tags
117
124
  }.each do |key, data|
118
- next unless data.is_a?(Array) || data.is_a?(Hash)
119
- begin
120
- Appsignal::Extension.set_transaction_error_data(
121
- transaction_index,
122
- key.to_s,
123
- JSON.generate(data)
124
- )
125
- rescue JSON::GeneratorError=>e
126
- Appsignal.logger.error("JSON generate error (#{e.message}) for '#{data.inspect}'")
127
- end
125
+ set_sample_data(key, data)
128
126
  end
129
127
  end
128
+
129
+ def set_error(error)
130
+ return unless error
131
+ return if Appsignal.is_ignored_error?(error)
132
+
133
+ Appsignal.logger.debug("Adding #{error.class.name} to transaction: #{transaction_id}")
134
+ backtrace = cleaned_backtrace(error.backtrace)
135
+ Appsignal::Extension.set_transaction_error(
136
+ transaction_index,
137
+ error.class.name,
138
+ error.message,
139
+ backtrace ? JSON.generate(backtrace) : ''
140
+ )
141
+ rescue JSON::GeneratorError=>e
142
+ Appsignal.logger.error("JSON generate error (#{e.message}) for '#{backtrace.inspect}'")
143
+ end
130
144
  alias_method :add_exception, :set_error
131
145
 
132
146
  class GenericRequest
@@ -145,8 +159,7 @@ module Appsignal
145
159
 
146
160
  def background_queue_start
147
161
  return unless request.env
148
- queue_start = request.env[:queue_start]
149
- return unless queue_start
162
+ return unless queue_start = request.env[:queue_start]
150
163
  (queue_start.to_f * 1000.0).to_i
151
164
  end
152
165
 
@@ -1,5 +1,5 @@
1
1
  require 'yaml'
2
2
 
3
3
  module Appsignal
4
- VERSION = '0.12.rc.9'
4
+ VERSION = '0.12.rc.10'
5
5
  end
@@ -32,7 +32,8 @@ describe Appsignal::Config do
32
32
  :enable_frontend_error_catching => false,
33
33
  :frontend_error_catching_path => '/appsignal_error_catcher',
34
34
  :enable_allocation_tracking => true,
35
- :enable_gc_instrumentation => true
35
+ :enable_gc_instrumentation => true,
36
+ :running_in_container => false
36
37
  }
37
38
  end
38
39
 
@@ -40,6 +41,12 @@ describe Appsignal::Config do
40
41
  let(:config) { project_fixture_config('production', :log_path => '/tmp') }
41
42
 
42
43
  its(:log_file_path) { should end_with('/tmp/appsignal.log') }
44
+
45
+ context "if it is not writable" do
46
+ let(:config) { project_fixture_config('production', :log_path => '/root') }
47
+
48
+ its(:log_file_path) { should == '/tmp/appsignal.log' }
49
+ end
43
50
  end
44
51
 
45
52
  context "when there is a pre 0.12 style endpoint" do
@@ -90,6 +97,7 @@ describe Appsignal::Config do
90
97
  ENV['APPSIGNAL_LANGUAGE_INTEGRATION_VERSION'].should == Appsignal::VERSION
91
98
  ENV['APPSIGNAL_HTTP_PROXY'].should == 'http://localhost'
92
99
  ENV['APPSIGNAL_IGNORE_ACTIONS'].should == 'action1,action2'
100
+ ENV['APPSIGNAL_RUNNING_IN_CONTAINER'].should == 'false'
93
101
  end
94
102
  end
95
103
 
@@ -50,11 +50,11 @@ describe "extension loading and operation" do
50
50
  end
51
51
 
52
52
  it "should have a set_transaction_error method" do
53
- subject.set_transaction_error(1, 'name', 'message')
53
+ subject.set_transaction_error(1, 'name', 'message', '[backtrace]')
54
54
  end
55
55
 
56
- it "should have a set_transaction_error_data method" do
57
- subject.set_transaction_error_data(1, 'params', '{}')
56
+ it "should have a set_transaction_sample_data method" do
57
+ subject.set_transaction_sample_data(1, 'params', '{}')
58
58
  end
59
59
 
60
60
  it "should have a set_transaction_action method" do
@@ -36,7 +36,7 @@ describe Appsignal::Hooks::DelayedJobHook do
36
36
  :attempts => 1,
37
37
  :queue => 'default',
38
38
  :created_at => time - 60_000,
39
- :payload_object => double
39
+ :payload_object => double(:args => ['argument']),
40
40
  )
41
41
  end
42
42
  let(:invoked_block) { Proc.new { } }
@@ -54,6 +54,7 @@ describe Appsignal::Hooks::DelayedJobHook do
54
54
  :queue => 'default',
55
55
  :id => 123
56
56
  },
57
+ :params => ['argument'],
57
58
  :queue_start => time - 60_000,
58
59
  )
59
60
 
@@ -66,14 +67,15 @@ describe Appsignal::Hooks::DelayedJobHook do
66
67
  let(:job) do
67
68
  double(
68
69
  :payload_object => double(
69
- :appsignal_name => 'CustomClass#perform'
70
+ :appsignal_name => 'CustomClass#perform',
71
+ :args => ['argument']
70
72
  ),
71
- :id => 123,
72
- :name => 'TestClass#perform',
73
- :priority => 1,
74
- :attempts => 1,
75
- :queue => 'default',
76
- :created_at => time - 60_000
73
+ :id => 123,
74
+ :name => 'TestClass#perform',
75
+ :priority => 1,
76
+ :attempts => 1,
77
+ :queue => 'default',
78
+ :created_at => time - 60_000
77
79
  )
78
80
  end
79
81
  it "should wrap in a transaction with the correct params" do
@@ -87,6 +89,7 @@ describe Appsignal::Hooks::DelayedJobHook do
87
89
  :queue => 'default',
88
90
  :id => 123
89
91
  },
92
+ :params => ['argument'],
90
93
  :queue_start => time - 60_000
91
94
  )
92
95
 
@@ -107,38 +107,6 @@ describe Appsignal::Hooks::SidekiqPlugin do
107
107
  plugin.format_args(args).should == ['Model', '1', object.inspect]
108
108
  end
109
109
  end
110
-
111
- describe "#truncate" do
112
- let(:very_long_text) do
113
- "a" * 400
114
- end
115
-
116
- it "should truncate the text to 200 chars max" do
117
- plugin.truncate(very_long_text).should == "#{'a' * 197}..."
118
- end
119
- end
120
-
121
- describe "#string_or_inspect" do
122
- context "when string" do
123
- it "should return the string" do
124
- plugin.string_or_inspect('foo').should == 'foo'
125
- end
126
- end
127
-
128
- context "when integer" do
129
- it "should return the string" do
130
- plugin.string_or_inspect(1).should == '1'
131
- end
132
- end
133
-
134
- context "when object" do
135
- let(:object) { Object.new }
136
-
137
- it "should return the string" do
138
- plugin.string_or_inspect(object).should == object.inspect
139
- end
140
- end
141
- end
142
110
  end
143
111
 
144
112
  describe Appsignal::Hooks::SidekiqHook do
@@ -74,3 +74,79 @@ describe Appsignal::Hooks do
74
74
  Appsignal::Hooks.hooks[:mock_error_hook].installed?.should be_false
75
75
  end
76
76
  end
77
+
78
+ describe Appsignal::Hooks::Helpers do
79
+ class ClassWithHelpers
80
+ include Appsignal::Hooks::Helpers
81
+ end
82
+
83
+ let(:class_with_helpers) { ClassWithHelpers.new }
84
+
85
+ describe "#truncate" do
86
+ it "should call the class method helper" do
87
+ expect( Appsignal::Hooks::Helpers ).to receive(:truncate).with('text')
88
+
89
+ class_with_helpers.truncate('text')
90
+ end
91
+ end
92
+
93
+ describe "#string_or_inspect" do
94
+ it "should call the class method helper" do
95
+ expect( Appsignal::Hooks::Helpers ).to receive(:string_or_inspect)
96
+ .with('string')
97
+
98
+ class_with_helpers.string_or_inspect('string')
99
+ end
100
+ end
101
+
102
+ describe Appsignal::Hooks::Helpers::ClassMethods do
103
+ describe "#truncate" do
104
+ it "should call the class method helper" do
105
+ expect( Appsignal::Hooks::Helpers ).to receive(:truncate).with('text')
106
+
107
+ ClassWithHelpers.truncate('text')
108
+ end
109
+ end
110
+
111
+ describe "#string_or_inspect" do
112
+ it "should call the class method helper" do
113
+ expect( Appsignal::Hooks::Helpers ).to receive(:string_or_inspect)
114
+ .with('string')
115
+
116
+ ClassWithHelpers.string_or_inspect('string')
117
+ end
118
+ end
119
+ end
120
+
121
+ describe ".truncate" do
122
+ let(:very_long_text) do
123
+ "a" * 400
124
+ end
125
+
126
+ it "should truncate the text to 200 chars max" do
127
+ Appsignal::Hooks::Helpers.truncate(very_long_text).should == "#{'a' * 197}..."
128
+ end
129
+ end
130
+
131
+ describe ".string_or_inspect" do
132
+ context "when string" do
133
+ it "should return the string" do
134
+ Appsignal::Hooks::Helpers.string_or_inspect('foo').should == 'foo'
135
+ end
136
+ end
137
+
138
+ context "when integer" do
139
+ it "should return the string" do
140
+ Appsignal::Hooks::Helpers.string_or_inspect(1).should == '1'
141
+ end
142
+ end
143
+
144
+ context "when object" do
145
+ let(:object) { Object.new }
146
+
147
+ it "should return the string" do
148
+ Appsignal::Hooks::Helpers.string_or_inspect(object).should == object.inspect
149
+ end
150
+ end
151
+ end
152
+ end
@@ -14,6 +14,9 @@ describe Appsignal::JSExceptionTransaction do
14
14
  'backtrace' => [
15
15
  'foo.bar/js:11:1',
16
16
  'foo.bar/js:22:2',
17
+ ],
18
+ 'tags' => [
19
+ 'tag1'
17
20
  ]
18
21
  }
19
22
  end
@@ -25,7 +28,7 @@ describe Appsignal::JSExceptionTransaction do
25
28
  expect( transaction ).to receive(:set_action)
26
29
  expect( transaction ).to receive(:set_metadata)
27
30
  expect( transaction ).to receive(:set_error)
28
- expect( transaction ).to receive(:set_error_data)
31
+ expect( transaction ).to receive(:set_sample_data)
29
32
 
30
33
  transaction.send :initialize, data
31
34
 
@@ -61,22 +64,23 @@ describe Appsignal::JSExceptionTransaction do
61
64
  expect( Appsignal::Extension ).to receive(:set_transaction_error).with(
62
65
  kind_of(Integer),
63
66
  'TypeError',
64
- 'foo is not a valid method'
67
+ 'foo is not a valid method',
68
+ "[\"foo.bar/js:11:1\",\"foo.bar/js:22:2\"]"
65
69
  )
66
70
 
67
71
  transaction.set_error
68
72
  end
69
73
  end
70
74
 
71
- describe "#set_error_data" do
75
+ describe "#set_sample_data" do
72
76
  it "should call `Appsignal::Extension.set_transaction_error_data`" do
73
- expect( Appsignal::Extension ).to receive(:set_transaction_error_data).with(
77
+ expect( Appsignal::Extension ).to receive(:set_transaction_sample_data).with(
74
78
  kind_of(Integer),
75
- 'backtrace',
76
- '["foo.bar/js:11:1","foo.bar/js:22:2"]'
79
+ 'tags',
80
+ '["tag1"]'
77
81
  )
78
82
 
79
- transaction.set_error_data
83
+ transaction.set_sample_data
80
84
  end
81
85
  end
82
86
 
@@ -71,6 +71,24 @@ describe Appsignal::Transaction do
71
71
  end
72
72
  end
73
73
 
74
+ describe "#complete" do
75
+ it "should sample data if it needs to be sampled" do
76
+ Appsignal::Extension.should_receive(:finish_transaction).and_return(true)
77
+ Appsignal::Extension.should_receive(:complete_transaction)
78
+ transaction.should_receive(:sample_data)
79
+
80
+ transaction.complete
81
+ end
82
+
83
+ it "should not sample data if it does not need to be sampled" do
84
+ Appsignal::Extension.should_receive(:finish_transaction).and_return(false)
85
+ Appsignal::Extension.should_receive(:complete_transaction)
86
+ transaction.should_not_receive(:sample_data)
87
+
88
+ transaction.complete
89
+ end
90
+ end
91
+
74
92
  context "pausing" do
75
93
  describe "#pause!" do
76
94
  it "should change the pause flag to true" do
@@ -243,6 +261,62 @@ describe Appsignal::Transaction do
243
261
  end
244
262
  end
245
263
 
264
+ describe "set_sample_data" do
265
+ it "should generate json and set the data" do
266
+ Appsignal::Extension.should_receive(:set_transaction_sample_data).with(
267
+ kind_of(Integer),
268
+ 'params',
269
+ '{"controller":"blog_posts","action":"show","id":"1"}'
270
+ ).once
271
+
272
+ transaction.set_sample_data(
273
+ 'params',
274
+ {
275
+ :controller => 'blog_posts',
276
+ :action => 'show',
277
+ :id => '1'
278
+ }
279
+ )
280
+ end
281
+
282
+ it "should do nothing if the data cannot be converted to json" do
283
+ Appsignal::Extension.should_not_receive(:set_transaction_sample_data).with(
284
+ kind_of(Integer),
285
+ 'params',
286
+ kind_of(String)
287
+ )
288
+
289
+ transaction.set_sample_data('params', 'string')
290
+ end
291
+ end
292
+
293
+ describe "#sample_data" do
294
+ it "should sample data" do
295
+ Appsignal::Extension.should_receive(:set_transaction_sample_data).with(
296
+ kind_of(Integer),
297
+ 'environment',
298
+ "{\"CONTENT_LENGTH\":\"0\",\"REQUEST_METHOD\":\"GET\",\"SERVER_NAME\":\"example.org\",\"SERVER_PORT\":\"80\",\"PATH_INFO\":\"/blog\"}"
299
+ ).once
300
+ Appsignal::Extension.should_receive(:set_transaction_sample_data).with(
301
+ kind_of(Integer),
302
+ 'session_data',
303
+ "{}"
304
+ ).once
305
+ Appsignal::Extension.should_receive(:set_transaction_sample_data).with(
306
+ kind_of(Integer),
307
+ 'params',
308
+ '{"controller":"blog_posts","action":"show","id":"1"}'
309
+ ).once
310
+ Appsignal::Extension.should_receive(:set_transaction_sample_data).with(
311
+ kind_of(Integer),
312
+ 'tags',
313
+ "{}"
314
+ ).once
315
+
316
+ transaction.sample_data
317
+ end
318
+ end
319
+
246
320
  describe '#set_error' do
247
321
  let(:env) { http_request_env_with_data }
248
322
  let(:error) { double(:error, :message => 'test message', :backtrace => ['line 1']) }
@@ -259,58 +333,13 @@ describe Appsignal::Transaction do
259
333
  end
260
334
 
261
335
  context "for a http request" do
262
- it "should set an error and it's data in native" do
336
+ it "should set an error in the extension" do
263
337
  Appsignal::Extension.should_receive(:set_transaction_error).with(
264
338
  kind_of(Integer),
265
339
  'RSpec::Mocks::Mock',
266
- 'test message'
267
- )
268
- Appsignal::Extension.should_receive(:set_transaction_error_data).with(
269
- kind_of(Integer),
270
- 'environment',
271
- "{\"CONTENT_LENGTH\":\"0\",\"REQUEST_METHOD\":\"GET\",\"SERVER_NAME\":\"example.org\",\"SERVER_PORT\":\"80\",\"PATH_INFO\":\"/blog\"}"
272
- ).once
273
- Appsignal::Extension.should_receive(:set_transaction_error_data).with(
274
- kind_of(Integer),
275
- 'session_data',
276
- "{}"
277
- ).once
278
- Appsignal::Extension.should_receive(:set_transaction_error_data).with(
279
- kind_of(Integer),
280
- 'backtrace',
340
+ 'test message',
281
341
  "[\"line 1\"]"
282
- ).once
283
- Appsignal::Extension.should_receive(:set_transaction_error_data).with(
284
- kind_of(Integer),
285
- 'params',
286
- '{"controller":"blog_posts","action":"show","id":"1"}'
287
- ).once
288
- Appsignal::Extension.should_receive(:set_transaction_error_data).with(
289
- kind_of(Integer),
290
- 'tags',
291
- "{}"
292
- ).once
293
-
294
- transaction.set_error(error)
295
- end
296
- end
297
-
298
- context "with a non-json convertable type" do
299
- before do
300
- transaction.stub(:sanitized_params => 'a string')
301
- end
302
-
303
- it "should skip the field" do
304
- Appsignal::Extension.should_not_receive(:set_transaction_error_data).with(
305
- kind_of(Integer),
306
- 'params',
307
- kind_of(String)
308
342
  )
309
- Appsignal::Extension.should_receive(:set_transaction_error_data).with(
310
- kind_of(Integer),
311
- kind_of(String),
312
- kind_of(String)
313
- ).exactly(4).times
314
343
 
315
344
  transaction.set_error(error)
316
345
  end
@@ -401,7 +401,12 @@ describe Appsignal do
401
401
  describe ".increment_counter" do
402
402
  it "should call increment_counter on the extension" do
403
403
  Appsignal::Extension.should_receive(:increment_counter).with('key', 1)
404
- Appsignal.increment_counter('key', 1)
404
+ Appsignal.increment_counter('key')
405
+ end
406
+
407
+ it "should call increment_counter on the extension with a count" do
408
+ Appsignal::Extension.should_receive(:increment_counter).with('key', 5)
409
+ Appsignal.increment_counter('key', 5)
405
410
  end
406
411
  end
407
412
 
@@ -453,17 +458,6 @@ describe Appsignal do
453
458
  end
454
459
  end
455
460
 
456
- context "when the log path is not writable" do
457
- let(:log_path) { '/nonsense/log' }
458
-
459
- it "should log to stdout" do
460
- Appsignal.start_logger
461
- Appsignal.logger.error('Log to stdout')
462
- out_stream.string.should include 'appsignal: Log to stdout'
463
- out_stream.string.should include 'Log something'
464
- end
465
- end
466
-
467
461
  context "when we're on Heroku" do
468
462
  before do
469
463
  ENV['DYNO'] = 'dyno1'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appsignal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.rc.9
4
+ version: 0.12.rc.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Beekman
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-11-25 00:00:00.000000000 Z
12
+ date: 2015-12-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack