appsignal 3.0.27 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # AppSignal for Ruby gem Changelog
2
2
 
3
+ ## 3.1.0
4
+
5
+ ### Added
6
+
7
+ - [d10c3f32](https://github.com/appsignal/appsignal-ruby/commit/d10c3f32facbf399d7afe1d2ddbb5764fb57b008) minor - Add tracking of thread counts, garbage collection runs, heap slots and other garbage collection stats to the default MRI probe. These metrics will be shown in AppSignal.com in a new Ruby VM Magic Dashboard.
8
+
9
+ ### Changed
10
+
11
+ - [114fe4f9](https://github.com/appsignal/appsignal-ruby/commit/114fe4f92e621bc2e771bb0fb608b5c6189f2933) patch - Bump agent to v-d573c9b
12
+
13
+ - Display unsupported OpenTelemetry spans in limited form.
14
+ - Clean up payload storage before sending. Should fix issues with locally queued payloads blocking data from being sent.
15
+ - Add `appsignal_create_opentelemetry_span` function to create spans for further modification, rather than only import them.
16
+ - [dd803449](https://github.com/appsignal/appsignal-ruby/commit/dd803449bd3990ba020c0bec4429166977071c02) patch - Report gauge delta value for allocated objects. This reports a more user friendly metric we can graph with a more stable continuous value in apps with stable memory allocation.
17
+ - [547f925e](https://github.com/appsignal/appsignal-ruby/commit/547f925e392bb9f4f10ba95f371e42ddfe0de5de) patch - Report gauge delta value for Garbage Collection counts. This reports a more user friendly metric that doesn't always goes up until the app restarts or gets a new deploy.
18
+
19
+ ### Fixed
20
+
21
+ - [e555a81a](https://github.com/appsignal/appsignal-ruby/commit/e555a81ab65cc951383f54d0e9a6c57d8cc2ac51) patch - Fix FFI function calls missing arguments for `appsignal_free_transaction` and `appsignal_free_data` extension functions. This fixes a high CPU issue when these function calls would be retried indefinitely.
22
+
3
23
  ## 3.0.27
4
24
 
5
25
  ### Fixed
data/Rakefile CHANGED
@@ -77,11 +77,12 @@ namespace :build_matrix do
77
77
  "name" => "Ruby #{ruby_version} for #{gem["gem"]}",
78
78
  "env_vars" => env + ruby.fetch("env_vars", []),
79
79
  "commands" => [
80
- "./support/bundler_wrapper exec rake test",
81
- "./support/bundler_wrapper exec rake test:failure"
80
+ "./support/bundler_wrapper exec rake test"
82
81
  ]
83
82
  }
84
83
  if gem["gem"] == "no_dependencies"
84
+ # Only test the failure scenarios once per Ruby version
85
+ job["commands"] << "./support/bundler_wrapper exec rake test:failure"
85
86
  ruby_primary_block["task"]["jobs"] << job
86
87
  else
87
88
  ruby_secondary_block["task"]["jobs"] << job
data/build_matrix.yml CHANGED
@@ -33,7 +33,16 @@ semaphore: # Default `.semaphore/semaphore.yml` contents
33
33
  fi
34
34
  - |
35
35
  if [ -n "$RUBY_VERSION" ]; then
36
- sem-version ruby $RUBY_VERSION
36
+ if ! (sem-version ruby "$RUBY_VERSION"); then
37
+ ruby_key="rbenv-ruby-$RUBY_VERSION"
38
+ echo "Attempting to build Ruby $RUBY_VERSION from source"
39
+ git -C "$HOME/.rbenv/plugins/ruby-build" pull
40
+ cache restore "$ruby_key"
41
+ sem-version ruby "$RUBY_VERSION"
42
+ if ! cache has_key "$ruby_key"; then
43
+ cache store "$ruby_key" "$HOME/.rbenv/versions/$RUBY_VERSION"
44
+ fi
45
+ fi
37
46
  ./support/check_versions
38
47
  else
39
48
  echo Skipping Ruby install
@@ -190,11 +199,14 @@ matrix:
190
199
  - ruby: "2.7.5"
191
200
  - ruby: "3.0.3"
192
201
  - ruby: "3.1.1"
202
+ - ruby: "3.2.0-preview1"
193
203
  - ruby: "jruby-9.2.19.0"
194
204
  gems: "minimal"
195
205
  env_vars:
196
206
  - name: "_C_VERSION"
197
207
  value: "8"
208
+ - ruby: "jruby-9.3.6.0"
209
+ gems: "minimal"
198
210
  gems:
199
211
  - gem: "no_dependencies"
200
212
  - gem: "capistrano2"
@@ -206,11 +218,13 @@ matrix:
206
218
  ruby:
207
219
  - "3.0.3"
208
220
  - "3.1.1"
221
+ - "3.2.0-preview1"
209
222
  - gem: "psych-4"
210
223
  only:
211
224
  ruby:
212
225
  - "3.0.3"
213
226
  - "3.1.1"
227
+ - "3.2.0-preview1"
214
228
  - gem: "que"
215
229
  - gem: "que_beta"
216
230
  - gem: "rails-3.2"
@@ -283,13 +297,16 @@ matrix:
283
297
  - "2.7.5"
284
298
  - "3.0.3"
285
299
  - "3.1.1"
300
+ - "3.2.0-preview1"
286
301
  - "jruby-9.2.19.0"
302
+ - "jruby-9.3.6.0"
287
303
  - gem: "rails-7.0"
288
304
  only:
289
305
  ruby:
290
306
  - "2.7.5"
291
307
  - "3.0.3"
292
308
  - "3.1.1"
309
+ - "3.2.0-preview1"
293
310
  - gem: "resque-1"
294
311
  bundler: "1.17.3"
295
312
  only:
data/ext/agent.yml CHANGED
@@ -3,92 +3,92 @@
3
3
  # appsignal-agent repository.
4
4
  # Modifications to this file will be overwritten with the next agent release.
5
5
  ---
6
- version: be3107a
6
+ version: d573c9b
7
7
  mirrors:
8
8
  - https://appsignal-agent-releases.global.ssl.fastly.net
9
9
  - https://d135dj0rjqvssy.cloudfront.net
10
10
  triples:
11
11
  x86_64-darwin:
12
12
  static:
13
- checksum: 31b13af931f26832eb9b5f3283a0dcfc83e327a31570aef47704589de5bd54cc
13
+ checksum: a9a86594e50f22e7f7fd93a050e334048248a6dc971015e66c26150c4a689345
14
14
  filename: appsignal-x86_64-darwin-all-static.tar.gz
15
15
  dynamic:
16
- checksum: e9a8798df3774d3483d5c2b503f53fa797bcd1fe228c293448786773bad6518f
16
+ checksum: 04a69d0b608aa0e834c96c75a3bb226e7ca252fd2c74e439fdd43bf297d6bde2
17
17
  filename: appsignal-x86_64-darwin-all-dynamic.tar.gz
18
18
  universal-darwin:
19
19
  static:
20
- checksum: 31b13af931f26832eb9b5f3283a0dcfc83e327a31570aef47704589de5bd54cc
20
+ checksum: a9a86594e50f22e7f7fd93a050e334048248a6dc971015e66c26150c4a689345
21
21
  filename: appsignal-x86_64-darwin-all-static.tar.gz
22
22
  dynamic:
23
- checksum: e9a8798df3774d3483d5c2b503f53fa797bcd1fe228c293448786773bad6518f
23
+ checksum: 04a69d0b608aa0e834c96c75a3bb226e7ca252fd2c74e439fdd43bf297d6bde2
24
24
  filename: appsignal-x86_64-darwin-all-dynamic.tar.gz
25
25
  aarch64-darwin:
26
26
  static:
27
- checksum: 902649453b5cfe86dee86f053a7dbe7df35bc8bce0b9632bd5619a8c824f02af
27
+ checksum: 92f7f71b685985b310a9f3693a96a5db6b9133b0af807d000b90248e097063c7
28
28
  filename: appsignal-aarch64-darwin-all-static.tar.gz
29
29
  dynamic:
30
- checksum: 8f334e011d9f624782c3a1766b6ffdf987fa58d5d8230ec7d65a1b0cbf43298d
30
+ checksum: ffb54af4c35dd281a4735b57d8e537b8b08e87e08841e5d344caff325948a9e8
31
31
  filename: appsignal-aarch64-darwin-all-dynamic.tar.gz
32
32
  arm64-darwin:
33
33
  static:
34
- checksum: 902649453b5cfe86dee86f053a7dbe7df35bc8bce0b9632bd5619a8c824f02af
34
+ checksum: 92f7f71b685985b310a9f3693a96a5db6b9133b0af807d000b90248e097063c7
35
35
  filename: appsignal-aarch64-darwin-all-static.tar.gz
36
36
  dynamic:
37
- checksum: 8f334e011d9f624782c3a1766b6ffdf987fa58d5d8230ec7d65a1b0cbf43298d
37
+ checksum: ffb54af4c35dd281a4735b57d8e537b8b08e87e08841e5d344caff325948a9e8
38
38
  filename: appsignal-aarch64-darwin-all-dynamic.tar.gz
39
39
  arm-darwin:
40
40
  static:
41
- checksum: 902649453b5cfe86dee86f053a7dbe7df35bc8bce0b9632bd5619a8c824f02af
41
+ checksum: 92f7f71b685985b310a9f3693a96a5db6b9133b0af807d000b90248e097063c7
42
42
  filename: appsignal-aarch64-darwin-all-static.tar.gz
43
43
  dynamic:
44
- checksum: 8f334e011d9f624782c3a1766b6ffdf987fa58d5d8230ec7d65a1b0cbf43298d
44
+ checksum: ffb54af4c35dd281a4735b57d8e537b8b08e87e08841e5d344caff325948a9e8
45
45
  filename: appsignal-aarch64-darwin-all-dynamic.tar.gz
46
46
  aarch64-linux:
47
47
  static:
48
- checksum: 37819d1df9b516d39a3aaf54bcc434f7d77e0067d75a86fff8c89be24cf16c28
48
+ checksum: 79f1e7f9c34ab36c06d5c3d676173ee7c1219af2f51dc77865897598dc01349a
49
49
  filename: appsignal-aarch64-linux-all-static.tar.gz
50
50
  dynamic:
51
- checksum: d453b25ed0752b588aa6895ede513b3cdb1b62060343fff1ad9fb4ea79859888
51
+ checksum: cfd8e98238e2c7cdb10c0e136c47ab8e2dacab0a14d8ccf0e4c6c14946e325f1
52
52
  filename: appsignal-aarch64-linux-all-dynamic.tar.gz
53
53
  i686-linux:
54
54
  static:
55
- checksum: c372daebb69e9795c8dcd60f48cad2af66628e1e3c8211f00526bdc8c880fc97
55
+ checksum: 835c6f823a2c6e9f8fa12704bf0953e3610dc9836355b57d2d6981e6ae412fb4
56
56
  filename: appsignal-i686-linux-all-static.tar.gz
57
57
  dynamic:
58
- checksum: 77e98bbf097148017bd1fd5c6e497e14d30ffb96cb385c7e4ebbaac82d292572
58
+ checksum: febc5d80a7b0fd9644e2d68d068d28c66359bbef9473f01e9f71fb07fd73bcb8
59
59
  filename: appsignal-i686-linux-all-dynamic.tar.gz
60
60
  x86-linux:
61
61
  static:
62
- checksum: c372daebb69e9795c8dcd60f48cad2af66628e1e3c8211f00526bdc8c880fc97
62
+ checksum: 835c6f823a2c6e9f8fa12704bf0953e3610dc9836355b57d2d6981e6ae412fb4
63
63
  filename: appsignal-i686-linux-all-static.tar.gz
64
64
  dynamic:
65
- checksum: 77e98bbf097148017bd1fd5c6e497e14d30ffb96cb385c7e4ebbaac82d292572
65
+ checksum: febc5d80a7b0fd9644e2d68d068d28c66359bbef9473f01e9f71fb07fd73bcb8
66
66
  filename: appsignal-i686-linux-all-dynamic.tar.gz
67
67
  x86_64-linux:
68
68
  static:
69
- checksum: 972a8b02061d747fbe35f3dd8d3d5b7c34bf7a6a38d0526d0ff55b9e70b67f13
69
+ checksum: 6eb6f0df2f8c62a29769bf7f21cefaec92a24ee0ab363acc5bd4f9c2d1241c53
70
70
  filename: appsignal-x86_64-linux-all-static.tar.gz
71
71
  dynamic:
72
- checksum: 96d9303fbc12cd20f227f2e950e1807d56b7d68d1af2069c7d2c77fa2544c589
72
+ checksum: ce710ff2edea2fc7b3b6bafd10af849e95f513abf5d775b9a8361ffed45b70c3
73
73
  filename: appsignal-x86_64-linux-all-dynamic.tar.gz
74
74
  x86_64-linux-musl:
75
75
  static:
76
- checksum: 4821b9d4e9b4501a5002f731b633a64b3991272fb0e6e57a61ce1e2a0b33bcad
76
+ checksum: b16d46074527da5700e10e5a8b176aeb46b7bbb19431653029eda04437bef918
77
77
  filename: appsignal-x86_64-linux-musl-all-static.tar.gz
78
78
  dynamic:
79
- checksum: e11b87a336ea1c51858f488b029335ccf37610a21c9327aecbbc62c3693a1869
79
+ checksum: 261b79ab790e6a12a748d4649a4389e96d5cf7d1f981c3b56ed331f164d1627b
80
80
  filename: appsignal-x86_64-linux-musl-all-dynamic.tar.gz
81
81
  x86_64-freebsd:
82
82
  static:
83
- checksum: 2b8ff925dd40daab892cf66ad3fefb72559cab57433907d8f70ae41722716832
83
+ checksum: e7bfc1dc355ce1237aaee6fdf967c78ecca533db41b09c2b10716e7f8593dbe0
84
84
  filename: appsignal-x86_64-freebsd-all-static.tar.gz
85
85
  dynamic:
86
- checksum: 174e1c7b58b9081383c438ba33d6981a0063ef6d740d6feec7d2ead4e607e769
86
+ checksum: 97af9419cf00e22ea544a2365785a6b5df2a990f17e7735b3bbec1a690b68f0b
87
87
  filename: appsignal-x86_64-freebsd-all-dynamic.tar.gz
88
88
  amd64-freebsd:
89
89
  static:
90
- checksum: 2b8ff925dd40daab892cf66ad3fefb72559cab57433907d8f70ae41722716832
90
+ checksum: e7bfc1dc355ce1237aaee6fdf967c78ecca533db41b09c2b10716e7f8593dbe0
91
91
  filename: appsignal-x86_64-freebsd-all-static.tar.gz
92
92
  dynamic:
93
- checksum: 174e1c7b58b9081383c438ba33d6981a0063ef6d740d6feec7d2ead4e607e769
93
+ checksum: 97af9419cf00e22ea544a2365785a6b5df2a990f17e7735b3bbec1a690b68f0b
94
94
  filename: appsignal-x86_64-freebsd-all-dynamic.tar.gz
@@ -1,6 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'grape', '0.14.0'
3
+ gem 'grape'
4
4
  gem 'activesupport', '~> 4.2'
5
5
 
6
6
  gemspec :path => '../'
@@ -83,7 +83,7 @@ module Appsignal
83
83
 
84
84
  # Transaction methods
85
85
  attach_function :appsignal_free_transaction,
86
- [],
86
+ [:pointer],
87
87
  :void
88
88
  attach_function :appsignal_start_transaction,
89
89
  [:appsignal_string, :appsignal_string, :long],
@@ -191,7 +191,7 @@ module Appsignal
191
191
  :void
192
192
 
193
193
  # Data struct methods
194
- attach_function :appsignal_free_data, [], :void
194
+ attach_function :appsignal_free_data, [:pointer], :void
195
195
  attach_function :appsignal_data_map_new, [], :pointer
196
196
  attach_function :appsignal_data_array_new, [], :pointer
197
197
  attach_function :appsignal_data_map_set_string,
@@ -0,0 +1,29 @@
1
+ module Appsignal
2
+ module Probes
3
+ module Helpers
4
+ private
5
+
6
+ def gauge_delta_cache
7
+ @gauge_delta_cache ||= {}
8
+ end
9
+
10
+ # Calculate the delta of two values for a gauge metric
11
+ #
12
+ # First call will store the data for the metric in the cache and the
13
+ # second call will return the delta of the gauge metric. This is used for
14
+ # absolute counter values which we want to track as gauges.
15
+ #
16
+ # @example
17
+ # gauge_delta :my_cache_key, 10
18
+ # gauge_delta :my_cache_key, 15
19
+ # # Returns a value of `5`
20
+ def gauge_delta(cache_key, value)
21
+ previous_value = gauge_delta_cache[cache_key]
22
+ gauge_delta_cache[cache_key] = value
23
+ return unless previous_value
24
+
25
+ value - previous_value
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,25 +1,66 @@
1
1
  module Appsignal
2
2
  module Probes
3
3
  class MriProbe
4
+ include Helpers
5
+
4
6
  # @api private
5
7
  def self.dependencies_present?
6
8
  defined?(::RubyVM) && ::RubyVM.respond_to?(:stat)
7
9
  end
8
10
 
9
- def initialize
11
+ def self.garbage_collection_profiler
12
+ @garbage_collection_profiler ||= Appsignal::GarbageCollectionProfiler.new
13
+ end
14
+
15
+ def initialize(appsignal = Appsignal)
10
16
  Appsignal.logger.debug("Initializing VM probe")
17
+ @appsignal = appsignal
11
18
  end
12
19
 
13
20
  # @api private
14
21
  def call
15
22
  stat = RubyVM.stat
16
- [:class_serial, :global_constant_state].each do |metric|
17
- Appsignal.add_distribution_value(
18
- "ruby_vm",
19
- stat[metric],
20
- :metric => metric
23
+
24
+ @appsignal.add_distribution_value(
25
+ "ruby_vm",
26
+ stat[:class_serial],
27
+ :metric => :class_serial
28
+ )
29
+
30
+ @appsignal.add_distribution_value(
31
+ "ruby_vm",
32
+ stat[:constant_cache] ? stat[:constant_cache].values.sum : stat[:global_constant_state],
33
+ :metric => :global_constant_state
34
+ )
35
+
36
+ @appsignal.set_gauge("thread_count", Thread.list.size)
37
+ @appsignal.set_gauge("gc_total_time", MriProbe.garbage_collection_profiler.total_time)
38
+
39
+ gc_stats = GC.stat
40
+ allocated_objects =
41
+ gauge_delta(
42
+ :allocated_objects,
43
+ gc_stats[:total_allocated_objects] || gc_stats[:total_allocated_object]
21
44
  )
45
+ if allocated_objects
46
+ @appsignal.set_gauge("allocated_objects", allocated_objects)
47
+ end
48
+
49
+ gc_count = gauge_delta(:gc_count, GC.count)
50
+ if gc_count
51
+ @appsignal.add_distribution_value("gc_count", gc_count, :metric => :gc_count)
22
52
  end
53
+ minor_gc_count = gauge_delta(:minor_gc_count, gc_stats[:minor_gc_count])
54
+ if minor_gc_count
55
+ @appsignal.add_distribution_value("gc_count", minor_gc_count, :metric => :minor_gc_count)
56
+ end
57
+ major_gc_count = gauge_delta(:major_gc_count, gc_stats[:major_gc_count])
58
+ if major_gc_count
59
+ @appsignal.add_distribution_value("gc_count", major_gc_count, :metric => :major_gc_count)
60
+ end
61
+
62
+ @appsignal.add_distribution_value("heap_slots", gc_stats[:heap_live_slots] || gc_stats[:heap_live_slot], :metric => :heap_live)
63
+ @appsignal.add_distribution_value("heap_slots", gc_stats[:heap_free_slots] || gc_stats[:heap_free_slot], :metric => :heap_free)
23
64
  end
24
65
  end
25
66
  end
@@ -1,6 +1,8 @@
1
1
  module Appsignal
2
2
  module Probes
3
3
  class SidekiqProbe
4
+ include Helpers
5
+
4
6
  # @api private
5
7
  attr_reader :config
6
8
 
@@ -42,11 +44,15 @@ module Appsignal
42
44
 
43
45
  gauge "worker_count", stats.workers_size
44
46
  gauge "process_count", stats.processes_size
45
- gauge_delta :jobs_processed, "job_count", stats.processed,
46
- :status => :processed
47
- gauge_delta :jobs_failed, "job_count", stats.failed, :status => :failed
47
+ jobs_processed = gauge_delta :jobs_processed, stats.processed
48
+ if jobs_processed
49
+ gauge "job_count", jobs_processed, :status => :processed
50
+ end
51
+ jobs_failed = gauge_delta :jobs_failed, stats.failed
52
+ gauge "job_count", jobs_failed, :status => :failed if jobs_failed
48
53
  gauge "job_count", stats.retry_size, :status => :retry_queue
49
- gauge_delta :jobs_dead, "job_count", stats.dead_size, :status => :died
54
+ jobs_dead = gauge_delta :jobs_dead, stats.dead_size
55
+ gauge "job_count", jobs_dead, :status => :died if jobs_dead
50
56
  gauge "job_count", stats.scheduled_size, :status => :scheduled
51
57
  gauge "job_count", stats.enqueued, :status => :enqueued
52
58
  end
@@ -65,25 +71,6 @@ module Appsignal
65
71
  Appsignal.set_gauge "sidekiq_#{key}", value, tags
66
72
  end
67
73
 
68
- # Track the delta of two values for a gauge metric
69
- #
70
- # First call will store the data for the metric and the second call will
71
- # set a gauge metric with the difference. This is used for absolute
72
- # counter values which we want to track as gauges.
73
- #
74
- # @example
75
- # gauge_delta :my_cache_key, "my_gauge", 10
76
- # gauge_delta :my_cache_key, "my_gauge", 15
77
- # # Creates a gauge with the value `5`
78
- # @see #gauge
79
- def gauge_delta(cache_key, key, value, tags = {})
80
- previous_value = cache[cache_key]
81
- cache[cache_key] = value
82
- return unless previous_value
83
- new_value = value - previous_value
84
- gauge key, new_value, tags
85
- end
86
-
87
74
  def hostname
88
75
  return @hostname if defined?(@hostname)
89
76
  if config.key?(:hostname)
@@ -3,5 +3,6 @@ module Appsignal
3
3
  end
4
4
  end
5
5
 
6
+ require "appsignal/probes/helpers"
6
7
  require "appsignal/probes/mri"
7
8
  require "appsignal/probes/sidekiq"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Appsignal
4
- VERSION = "3.0.27".freeze
4
+ VERSION = "3.1.0".freeze
5
5
  end
data/script/lint_git CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  set -eu
4
4
 
5
- LINTJE_VERSION="0.6.1"
5
+ LINTJE_VERSION="0.7.1"
6
6
 
7
- mkdir -p $HOME/bin
7
+ mkdir -p "$HOME/bin"
8
8
  cache_key=v1-lintje-$LINTJE_VERSION
9
9
  cache restore $cache_key
10
10
 
@@ -15,8 +15,8 @@ else
15
15
  echo "Downloading Lintje $LINTJE_VERSION"
16
16
  curl -L \
17
17
  https://github.com/tombruijn/lintje/releases/download/v$LINTJE_VERSION/x86_64-unknown-linux-gnu.tar.gz | \
18
- tar -xz --directory $HOME/bin
19
- cache store $cache_key $HOME/bin/lintje
18
+ tar -xz --directory "$HOME/bin"
19
+ cache store $cache_key "$HOME/bin/lintje"
20
20
  fi
21
21
 
22
- $HOME/bin/lintje $SEMAPHORE_GIT_COMMIT_RANGE
22
+ "$HOME/bin/lintje" "$SEMAPHORE_GIT_COMMIT_RANGE"
@@ -1,5 +1,23 @@
1
+ class AppsignalMock
2
+ attr_reader :distribution_values, :gauges
3
+
4
+ def initialize
5
+ @distribution_values = []
6
+ @gauges = []
7
+ end
8
+
9
+ def add_distribution_value(*args)
10
+ @distribution_values << args
11
+ end
12
+
13
+ def set_gauge(*args) # rubocop:disable Naming/AccessorMethodName
14
+ @gauges << args
15
+ end
16
+ end
17
+
1
18
  describe Appsignal::Probes::MriProbe do
2
- let(:probe) { described_class.new }
19
+ let(:appsignal_mock) { AppsignalMock.new }
20
+ let(:probe) { described_class.new(appsignal_mock) }
3
21
 
4
22
  describe ".dependencies_present?" do
5
23
  if DependencyHelper.running_jruby? || DependencyHelper.running_ruby_2_0?
@@ -16,18 +34,71 @@ describe Appsignal::Probes::MriProbe do
16
34
  unless DependencyHelper.running_jruby? || DependencyHelper.running_ruby_2_0?
17
35
  describe "#call" do
18
36
  it "should track vm metrics" do
19
- expect_distribution_value(:class_serial)
20
- expect_distribution_value(:global_constant_state)
37
+ probe.call
38
+ expect_distribution_value("ruby_vm", :class_serial)
39
+ expect_distribution_value("ruby_vm", :global_constant_state)
40
+ end
41
+
42
+ it "tracks thread counts" do
43
+ probe.call
44
+ expect_gauge_value("thread_count")
45
+ end
21
46
 
47
+ it "tracks GC total time" do
22
48
  probe.call
49
+ expect_gauge_value("gc_total_time")
50
+ end
51
+
52
+ it "tracks GC run count" do
53
+ expect(GC).to receive(:count).and_return(10, 15)
54
+ expect(GC).to receive(:stat).and_return(
55
+ { :minor_gc_count => 10, :major_gc_count => 10 },
56
+ :minor_gc_count => 16, :major_gc_count => 17
57
+ )
58
+ probe.call
59
+ probe.call
60
+ expect_distribution_value("gc_count", :gc_count, 5)
61
+ expect_distribution_value("gc_count", :minor_gc_count, 6)
62
+ expect_distribution_value("gc_count", :major_gc_count, 7)
63
+ end
64
+
65
+ it "tracks object allocation" do
66
+ expect(GC).to receive(:stat).and_return(
67
+ { :total_allocated_objects => 10 },
68
+ :total_allocated_objects => 15
69
+ )
70
+ # Only tracks delta value so the needs to be called twice
71
+ probe.call
72
+ probe.call
73
+ expect_gauge_value("allocated_objects", 5)
74
+ end
75
+
76
+ it "tracks heap slots" do
77
+ probe.call
78
+ expect_distribution_value("heap_slots", :heap_live)
79
+ expect_distribution_value("heap_slots", :heap_free)
23
80
  end
24
81
  end
82
+ end
83
+
84
+ def expect_distribution_value(expected_key, metric, expected_value = nil)
85
+ expect(appsignal_mock.distribution_values).to satisfy do |distribution_values|
86
+ distribution_values.any? do |distribution_value|
87
+ key, value, metadata = distribution_value
88
+ next unless key == expected_key
89
+ next unless expected_value ? expected_value == value : !value.nil?
90
+ next unless metadata == { :metric => metric }
25
91
 
26
- def expect_distribution_value(metric)
27
- expect(Appsignal).to receive(:add_distribution_value)
28
- .with("ruby_vm", kind_of(Numeric), :metric => metric)
29
- .and_call_original
30
- .once
92
+ true
93
+ end
94
+ end
95
+ end
96
+
97
+ def expect_gauge_value(expected_key, expected_value = nil)
98
+ expect(appsignal_mock.gauges).to satisfy do |gauges|
99
+ gauges.any? do |(key, value)|
100
+ expected_key == key && expected_value ? expected_value == value : !value.nil?
101
+ end
31
102
  end
32
103
  end
33
104
  end
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: 3.0.27
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Beekman
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2022-05-30 00:00:00.000000000 Z
13
+ date: 2022-07-28 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rack
@@ -255,6 +255,7 @@ files:
255
255
  - lib/appsignal/marker.rb
256
256
  - lib/appsignal/minutely.rb
257
257
  - lib/appsignal/probes.rb
258
+ - lib/appsignal/probes/helpers.rb
258
259
  - lib/appsignal/probes/mri.rb
259
260
  - lib/appsignal/probes/sidekiq.rb
260
261
  - lib/appsignal/rack/generic_instrumentation.rb