appsignal 3.0.26-java → 3.1.1-java

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.
data/CHANGELOG.md CHANGED
@@ -1,5 +1,41 @@
1
1
  # AppSignal for Ruby gem Changelog
2
2
 
3
+ ## 3.1.1
4
+
5
+ ### Changed
6
+
7
+ - [e225c798](https://github.com/appsignal/appsignal-ruby/commit/e225c798c65aef6085bb689597b7f3359fe138f7) patch - Report all Ruby VM metrics as gauges. We previously reported some metrics as distributions, but all fields for those distributions would report the same values.
8
+
9
+ ### Fixed
10
+
11
+ - [31fd19c6](https://github.com/appsignal/appsignal-ruby/commit/31fd19c6019db2c68b359f1fc4ed3d5e4843e349) patch - Add hostname tag for Ruby VM metrics. This allows us to graph every host separately and multiple hosts won't overwrite each other metrics.
12
+
13
+ ## 3.1.0
14
+
15
+ ### Added
16
+
17
+ - [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.
18
+
19
+ ### Changed
20
+
21
+ - [114fe4f9](https://github.com/appsignal/appsignal-ruby/commit/114fe4f92e621bc2e771bb0fb608b5c6189f2933) patch - Bump agent to v-d573c9b
22
+
23
+ - Display unsupported OpenTelemetry spans in limited form.
24
+ - Clean up payload storage before sending. Should fix issues with locally queued payloads blocking data from being sent.
25
+ - Add `appsignal_create_opentelemetry_span` function to create spans for further modification, rather than only import them.
26
+ - [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.
27
+ - [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.
28
+
29
+ ### Fixed
30
+
31
+ - [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.
32
+
33
+ ## 3.0.27
34
+
35
+ ### Fixed
36
+
37
+ - [7032dc4b](https://github.com/appsignal/appsignal-ruby/commit/7032dc4b45c150c58a7a97c44b17e1092934c1ec) patch - Use `Dir.pwd` to determine the current directory in the Capistrano 3 integration. It previously relied on `ENV["pwd"]` which returned `nil` in some scenarios.
38
+
3
39
  ## 3.0.26
4
40
 
5
41
  ### Removed
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: f57e6cb
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: dd1ae8d7897edf3112741381226e3622e91553dede6eeae48ca07aae84ac050d
13
+ checksum: a9a86594e50f22e7f7fd93a050e334048248a6dc971015e66c26150c4a689345
14
14
  filename: appsignal-x86_64-darwin-all-static.tar.gz
15
15
  dynamic:
16
- checksum: a523a85f76bdb37ffcacbf14279c3c7fed0378fbcfd20886ab66ee7602766e72
16
+ checksum: 04a69d0b608aa0e834c96c75a3bb226e7ca252fd2c74e439fdd43bf297d6bde2
17
17
  filename: appsignal-x86_64-darwin-all-dynamic.tar.gz
18
18
  universal-darwin:
19
19
  static:
20
- checksum: dd1ae8d7897edf3112741381226e3622e91553dede6eeae48ca07aae84ac050d
20
+ checksum: a9a86594e50f22e7f7fd93a050e334048248a6dc971015e66c26150c4a689345
21
21
  filename: appsignal-x86_64-darwin-all-static.tar.gz
22
22
  dynamic:
23
- checksum: a523a85f76bdb37ffcacbf14279c3c7fed0378fbcfd20886ab66ee7602766e72
23
+ checksum: 04a69d0b608aa0e834c96c75a3bb226e7ca252fd2c74e439fdd43bf297d6bde2
24
24
  filename: appsignal-x86_64-darwin-all-dynamic.tar.gz
25
25
  aarch64-darwin:
26
26
  static:
27
- checksum: cd5175979ec293d0471c71de1fdd00817bea75f800603a1b87931b19471495f3
27
+ checksum: 92f7f71b685985b310a9f3693a96a5db6b9133b0af807d000b90248e097063c7
28
28
  filename: appsignal-aarch64-darwin-all-static.tar.gz
29
29
  dynamic:
30
- checksum: 77503ee5debad5f503719d5fe653f30c3b3bb6624694f48ef03352f575af97c0
30
+ checksum: ffb54af4c35dd281a4735b57d8e537b8b08e87e08841e5d344caff325948a9e8
31
31
  filename: appsignal-aarch64-darwin-all-dynamic.tar.gz
32
32
  arm64-darwin:
33
33
  static:
34
- checksum: cd5175979ec293d0471c71de1fdd00817bea75f800603a1b87931b19471495f3
34
+ checksum: 92f7f71b685985b310a9f3693a96a5db6b9133b0af807d000b90248e097063c7
35
35
  filename: appsignal-aarch64-darwin-all-static.tar.gz
36
36
  dynamic:
37
- checksum: 77503ee5debad5f503719d5fe653f30c3b3bb6624694f48ef03352f575af97c0
37
+ checksum: ffb54af4c35dd281a4735b57d8e537b8b08e87e08841e5d344caff325948a9e8
38
38
  filename: appsignal-aarch64-darwin-all-dynamic.tar.gz
39
39
  arm-darwin:
40
40
  static:
41
- checksum: cd5175979ec293d0471c71de1fdd00817bea75f800603a1b87931b19471495f3
41
+ checksum: 92f7f71b685985b310a9f3693a96a5db6b9133b0af807d000b90248e097063c7
42
42
  filename: appsignal-aarch64-darwin-all-static.tar.gz
43
43
  dynamic:
44
- checksum: 77503ee5debad5f503719d5fe653f30c3b3bb6624694f48ef03352f575af97c0
44
+ checksum: ffb54af4c35dd281a4735b57d8e537b8b08e87e08841e5d344caff325948a9e8
45
45
  filename: appsignal-aarch64-darwin-all-dynamic.tar.gz
46
46
  aarch64-linux:
47
47
  static:
48
- checksum: ae899aba4fa260c1aa1d21cc8f2bf379a2b52596ef2979e9b9b70f0cd54872d4
48
+ checksum: 79f1e7f9c34ab36c06d5c3d676173ee7c1219af2f51dc77865897598dc01349a
49
49
  filename: appsignal-aarch64-linux-all-static.tar.gz
50
50
  dynamic:
51
- checksum: 848ab3df66cac4122133145738a380d3e4763e0bcb324cb0d7c0423741751d80
51
+ checksum: cfd8e98238e2c7cdb10c0e136c47ab8e2dacab0a14d8ccf0e4c6c14946e325f1
52
52
  filename: appsignal-aarch64-linux-all-dynamic.tar.gz
53
53
  i686-linux:
54
54
  static:
55
- checksum: 3934810379bade5096a5f055450ddd38f60c1bb2fbc05bebcea92f8f7250a81e
55
+ checksum: 835c6f823a2c6e9f8fa12704bf0953e3610dc9836355b57d2d6981e6ae412fb4
56
56
  filename: appsignal-i686-linux-all-static.tar.gz
57
57
  dynamic:
58
- checksum: 2bd5207d0930f9ce262adcb955582c2a022de8872022a0ddd1ea15391339eb55
58
+ checksum: febc5d80a7b0fd9644e2d68d068d28c66359bbef9473f01e9f71fb07fd73bcb8
59
59
  filename: appsignal-i686-linux-all-dynamic.tar.gz
60
60
  x86-linux:
61
61
  static:
62
- checksum: 3934810379bade5096a5f055450ddd38f60c1bb2fbc05bebcea92f8f7250a81e
62
+ checksum: 835c6f823a2c6e9f8fa12704bf0953e3610dc9836355b57d2d6981e6ae412fb4
63
63
  filename: appsignal-i686-linux-all-static.tar.gz
64
64
  dynamic:
65
- checksum: 2bd5207d0930f9ce262adcb955582c2a022de8872022a0ddd1ea15391339eb55
65
+ checksum: febc5d80a7b0fd9644e2d68d068d28c66359bbef9473f01e9f71fb07fd73bcb8
66
66
  filename: appsignal-i686-linux-all-dynamic.tar.gz
67
67
  x86_64-linux:
68
68
  static:
69
- checksum: 956288a49717ea61ec303ef4ab52e7bfafea6e575a8bb9839df24b947d22d988
69
+ checksum: 6eb6f0df2f8c62a29769bf7f21cefaec92a24ee0ab363acc5bd4f9c2d1241c53
70
70
  filename: appsignal-x86_64-linux-all-static.tar.gz
71
71
  dynamic:
72
- checksum: abf290aa7ad7be1af54889c9dd70cf2f71902359cfc5f5ce64b53b8421914a51
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: 5f96744692b6b079bd2b97ac6d8d5900123f108a27237664c88a49782b7ba433
76
+ checksum: b16d46074527da5700e10e5a8b176aeb46b7bbb19431653029eda04437bef918
77
77
  filename: appsignal-x86_64-linux-musl-all-static.tar.gz
78
78
  dynamic:
79
- checksum: c0a06de99d88a2e045b60d53319e1bbb8633127667fbe9f09e52f2bbaf6fb54d
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: 23ea3fdcc5ae7dfdc85214c872ef928ed702c029b05c059db614583f689b9304
83
+ checksum: e7bfc1dc355ce1237aaee6fdf967c78ecca533db41b09c2b10716e7f8593dbe0
84
84
  filename: appsignal-x86_64-freebsd-all-static.tar.gz
85
85
  dynamic:
86
- checksum: 683cc20296ef05257c4209b3c5d86ef32b76be6ea75a1d1ec76db0163e729a38
86
+ checksum: 97af9419cf00e22ea544a2365785a6b5df2a990f17e7735b3bbec1a690b68f0b
87
87
  filename: appsignal-x86_64-freebsd-all-dynamic.tar.gz
88
88
  amd64-freebsd:
89
89
  static:
90
- checksum: 23ea3fdcc5ae7dfdc85214c872ef928ed702c029b05c059db614583f689b9304
90
+ checksum: e7bfc1dc355ce1237aaee6fdf967c78ecca533db41b09c2b10716e7f8593dbe0
91
91
  filename: appsignal-x86_64-freebsd-all-static.tar.gz
92
92
  dynamic:
93
- checksum: 683cc20296ef05257c4209b3c5d86ef32b76be6ea75a1d1ec76db0163e729a38
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 => '../'
@@ -1,6 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'sequel', '< 4.35'
3
+ gem 'sequel'
4
4
  if RUBY_PLATFORM == "java"
5
5
  gem 'jdbc-sqlite3'
6
6
  else
@@ -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,
@@ -5,7 +5,7 @@ namespace :appsignal do
5
5
  revision = fetch(:appsignal_revision, fetch(:current_revision))
6
6
 
7
7
  appsignal_config = Appsignal::Config.new(
8
- ENV["PWD"],
8
+ Dir.pwd,
9
9
  appsignal_env,
10
10
  {},
11
11
  Logger.new(StringIO.new)
@@ -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,85 @@
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
+ set_gauge(
25
+ "ruby_vm",
26
+ stat[:class_serial],
27
+ :metric => :class_serial
28
+ )
29
+
30
+ set_gauge(
31
+ "ruby_vm",
32
+ stat[:constant_cache] ? stat[:constant_cache].values.sum : stat[:global_constant_state],
33
+ :metric => :global_constant_state
34
+ )
35
+
36
+ set_gauge("thread_count", Thread.list.size)
37
+ 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
+ set_gauge("allocated_objects", allocated_objects) if allocated_objects
46
+
47
+ gc_count = gauge_delta(:gc_count, GC.count)
48
+ set_gauge("gc_count", gc_count, :metric => :gc_count) if gc_count
49
+ minor_gc_count = gauge_delta(:minor_gc_count, gc_stats[:minor_gc_count])
50
+ if minor_gc_count
51
+ set_gauge("gc_count", minor_gc_count, :metric => :minor_gc_count)
52
+ end
53
+ major_gc_count = gauge_delta(:major_gc_count, gc_stats[:major_gc_count])
54
+ if major_gc_count
55
+ set_gauge("gc_count", major_gc_count, :metric => :major_gc_count)
22
56
  end
57
+
58
+ set_gauge("heap_slots", gc_stats[:heap_live_slots] || gc_stats[:heap_live_slot], :metric => :heap_live)
59
+ set_gauge("heap_slots", gc_stats[:heap_free_slots] || gc_stats[:heap_free_slot], :metric => :heap_free)
60
+ end
61
+
62
+ private
63
+
64
+ def set_gauge(metric, value, tags = {})
65
+ @appsignal.set_gauge(metric, value, { :hostname => hostname }.merge(tags))
66
+ end
67
+
68
+ def hostname
69
+ return @hostname if defined?(@hostname)
70
+
71
+ config = @appsignal.config
72
+ @hostname =
73
+ if config[:hostname]
74
+ config[:hostname]
75
+ else
76
+ # Auto detect hostname as fallback. May be inaccurate.
77
+ Socket.gethostname
78
+ end
79
+ Appsignal.logger.debug "MRI probe: Using hostname config " \
80
+ "option '#{@hostname.inspect}' as hostname"
81
+
82
+ @hostname
23
83
  end
24
84
  end
25
85
  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.26".freeze
4
+ VERSION = "3.1.1".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"
@@ -42,7 +42,11 @@ if DependencyHelper.capistrano3_present?
42
42
  describe "appsignal:deploy task" do
43
43
  before do
44
44
  ENV["USER"] = "batman"
45
- ENV["PWD"] = project_fixture_path
45
+ end
46
+ around do |example|
47
+ Dir.chdir project_fixture_path do
48
+ example.run
49
+ end
46
50
  end
47
51
 
48
52
  context "config" do
@@ -1,5 +1,25 @@
1
+ class AppsignalMock
2
+ attr_reader :gauges
3
+
4
+ def initialize(hostname: nil)
5
+ @hostname = hostname
6
+ @gauges = []
7
+ end
8
+
9
+ def config
10
+ ConfigHelpers.project_fixture_config.tap do |conf|
11
+ conf[:hostname] = @hostname if @hostname
12
+ end
13
+ end
14
+
15
+ def set_gauge(*args) # rubocop:disable Naming/AccessorMethodName
16
+ @gauges << args
17
+ end
18
+ end
19
+
1
20
  describe Appsignal::Probes::MriProbe do
2
- let(:probe) { described_class.new }
21
+ let(:appsignal_mock) { AppsignalMock.new(:hostname => hostname) }
22
+ let(:probe) { described_class.new(appsignal_mock) }
3
23
 
4
24
  describe ".dependencies_present?" do
5
25
  if DependencyHelper.running_jruby? || DependencyHelper.running_ruby_2_0?
@@ -15,19 +35,76 @@ describe Appsignal::Probes::MriProbe do
15
35
 
16
36
  unless DependencyHelper.running_jruby? || DependencyHelper.running_ruby_2_0?
17
37
  describe "#call" do
38
+ let(:hostname) { nil }
39
+
18
40
  it "should track vm metrics" do
19
- expect_distribution_value(:class_serial)
20
- expect_distribution_value(:global_constant_state)
41
+ probe.call
42
+ expect_gauge_value("ruby_vm", :tags => { :metric => :class_serial })
43
+ expect_gauge_value("ruby_vm", :tags => { :metric => :global_constant_state })
44
+ end
45
+
46
+ it "tracks thread counts" do
47
+ probe.call
48
+ expect_gauge_value("thread_count")
49
+ end
50
+
51
+ it "tracks GC total time" do
52
+ probe.call
53
+ expect_gauge_value("gc_total_time")
54
+ end
55
+
56
+ it "tracks GC run count" do
57
+ expect(GC).to receive(:count).and_return(10, 15)
58
+ expect(GC).to receive(:stat).and_return(
59
+ { :minor_gc_count => 10, :major_gc_count => 10 },
60
+ :minor_gc_count => 16, :major_gc_count => 17
61
+ )
62
+ probe.call
63
+ probe.call
64
+ expect_gauge_value("gc_count", 5, :tags => { :metric => :gc_count })
65
+ expect_gauge_value("gc_count", 6, :tags => { :metric => :minor_gc_count })
66
+ expect_gauge_value("gc_count", 7, :tags => { :metric => :major_gc_count })
67
+ end
68
+
69
+ it "tracks object allocation" do
70
+ expect(GC).to receive(:stat).and_return(
71
+ { :total_allocated_objects => 10 },
72
+ :total_allocated_objects => 15
73
+ )
74
+ # Only tracks delta value so the needs to be called twice
75
+ probe.call
76
+ probe.call
77
+ expect_gauge_value("allocated_objects", 5)
78
+ end
21
79
 
80
+ it "tracks heap slots" do
22
81
  probe.call
82
+ expect_gauge_value("heap_slots", :tags => { :metric => :heap_live })
83
+ expect_gauge_value("heap_slots", :tags => { :metric => :heap_free })
84
+ end
85
+
86
+ context "with custom hostname" do
87
+ let(:hostname) { "my hostname" }
88
+
89
+ it "reports custom hostname tag value" do
90
+ probe.call
91
+ expect_gauge_value("heap_slots", :tags => { :metric => :heap_live, :hostname => hostname })
92
+ end
23
93
  end
24
94
  end
95
+ end
25
96
 
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
97
+ def expect_gauge_value(expected_key, expected_value = nil, tags: {})
98
+ expected_tags = { :hostname => Socket.gethostname }.merge(tags)
99
+ expect(appsignal_mock.gauges).to satisfy do |gauges|
100
+ gauges.any? do |distribution_value|
101
+ key, value, tags = distribution_value
102
+ next unless key == expected_key
103
+ next unless expected_value ? expected_value == value : !value.nil?
104
+ next unless tags == expected_tags
105
+
106
+ true
107
+ end
31
108
  end
32
109
  end
33
110
  end
@@ -15,7 +15,8 @@ describe Appsignal::Span do
15
15
  expect(root.to_h["span_id"].length).to eq 8
16
16
  expect(root.to_h["parent_span_id"]).to be_empty
17
17
  expect(root.to_h["name"]).to be_empty
18
- expect(root.to_h["start_time"]).to be > 1_600_000_000
18
+ expect(root.to_h["start_time_seconds"]).to be > 1_600_000_000
19
+ expect(root.to_h["start_time_nanoseconds"]).to be_kind_of(Numeric)
19
20
  expect(root.to_h["closed"]).to be false
20
21
  end
21
22
  end
@@ -29,7 +30,8 @@ describe Appsignal::Span do
29
30
  expect(child.to_h["span_id"].length).to eq 8
30
31
  expect(child.to_h["parent_span_id"]).to eq root.to_h["span_id"]
31
32
  expect(child.to_h["name"]).to be_empty
32
- expect(child.to_h["start_time"]).to be > 1_600_000_000
33
+ expect(root.to_h["start_time_seconds"]).to be > 1_600_000_000
34
+ expect(root.to_h["start_time_nanoseconds"]).to be_kind_of(Numeric)
33
35
  expect(child.to_h["closed"]).to be false
34
36
  end
35
37
  end
@@ -14,6 +14,7 @@ module ConfigHelpers
14
14
  config_file
15
15
  )
16
16
  end
17
+ module_function :project_fixture_config, :project_fixture_path
17
18
 
18
19
  def start_agent(env = "production")
19
20
  Appsignal.config = project_fixture_config(env)