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

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