appsignal 3.0.27-java → 3.1.2-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.
- checksums.yaml +4 -4
- data/.semaphore/semaphore.yml +372 -71
- data/CHANGELOG.md +42 -0
- data/Rakefile +3 -2
- data/appsignal.gemspec +5 -1
- data/build_matrix.yml +18 -1
- data/ext/agent.yml +32 -25
- data/gemfiles/grape.gemfile +1 -1
- data/lib/appsignal/extension/jruby.rb +2 -2
- data/lib/appsignal/probes/helpers.rb +42 -0
- data/lib/appsignal/probes/mri.rb +65 -7
- data/lib/appsignal/probes/sidekiq.rb +11 -23
- data/lib/appsignal/probes.rb +1 -0
- data/lib/appsignal/version.rb +1 -1
- data/script/lint_git +5 -5
- data/spec/lib/appsignal/probes/mri_spec.rb +113 -8
- data/spec/support/helpers/config_helpers.rb +1 -0
- metadata +10 -9
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,47 @@
|
|
|
1
1
|
# AppSignal for Ruby gem Changelog
|
|
2
2
|
|
|
3
|
+
## 3.1.2
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- [1b95bb4c](https://github.com/appsignal/appsignal-ruby/commit/1b95bb4c8df08128cfa2db0d918ffcb909e5ee4c) patch - Report Garbage Collection total time metric as the delta between measurements. This reports a more user friendly metric that doesn't always goes up until the app restarts or gets a new deploy. This metric is reported 0 by default without `GC::Profiler.enable` having been called.
|
|
8
|
+
- [61a78fb0](https://github.com/appsignal/appsignal-ruby/commit/61a78fb028b04ae6f0a4ca1fc469d744f23c5029) patch - Bump agent to 06391fb
|
|
9
|
+
|
|
10
|
+
- Accept "warning" value for the `log_level` config option.
|
|
11
|
+
- Add aarch64 Linux musl build.
|
|
12
|
+
- Improve debug logging from the extension.
|
|
13
|
+
- Fix high CPU issue for appsignal-agent when nothing could be read from the socket.
|
|
14
|
+
|
|
15
|
+
## 3.1.1
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- [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.
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- [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.
|
|
24
|
+
|
|
25
|
+
## 3.1.0
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- [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.
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
|
|
33
|
+
- [114fe4f9](https://github.com/appsignal/appsignal-ruby/commit/114fe4f92e621bc2e771bb0fb608b5c6189f2933) patch - Bump agent to v-d573c9b
|
|
34
|
+
|
|
35
|
+
- Display unsupported OpenTelemetry spans in limited form.
|
|
36
|
+
- Clean up payload storage before sending. Should fix issues with locally queued payloads blocking data from being sent.
|
|
37
|
+
- Add `appsignal_create_opentelemetry_span` function to create spans for further modification, rather than only import them.
|
|
38
|
+
- [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.
|
|
39
|
+
- [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.
|
|
40
|
+
|
|
41
|
+
### Fixed
|
|
42
|
+
|
|
43
|
+
- [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.
|
|
44
|
+
|
|
3
45
|
## 3.0.27
|
|
4
46
|
|
|
5
47
|
### 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/appsignal.gemspec
CHANGED
|
@@ -39,12 +39,16 @@ Gem::Specification.new do |gem| # rubocop:disable Metrics/BlockLength
|
|
|
39
39
|
gem.add_development_dependency "rake", ">= 12"
|
|
40
40
|
gem.add_development_dependency "rspec", "~> 3.8"
|
|
41
41
|
gem.add_development_dependency "timecop"
|
|
42
|
-
gem.add_development_dependency "webmock"
|
|
43
42
|
gem.add_development_dependency "yard", ">= 0.9.20"
|
|
44
43
|
gem.add_development_dependency "pry"
|
|
45
44
|
|
|
46
45
|
# Dependencies that need to be locked to a specific version in developement
|
|
47
46
|
ruby_version = Gem::Version.new(RUBY_VERSION)
|
|
47
|
+
if ruby_version < Gem::Version.new("2.3.0")
|
|
48
|
+
gem.add_development_dependency "webmock", "3.14.0"
|
|
49
|
+
else
|
|
50
|
+
gem.add_development_dependency "webmock"
|
|
51
|
+
end
|
|
48
52
|
if ruby_version > Gem::Version.new("2.5.0")
|
|
49
53
|
# RuboCop dependency parallel depends on Ruby > 2.4
|
|
50
54
|
gem.add_development_dependency "rubocop", "0.50.0"
|
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,99 @@
|
|
|
3
3
|
# appsignal-agent repository.
|
|
4
4
|
# Modifications to this file will be overwritten with the next agent release.
|
|
5
5
|
---
|
|
6
|
-
version:
|
|
6
|
+
version: '06391fb'
|
|
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:
|
|
13
|
+
checksum: 9bf41c183d94c80e980f57ea2e29d08bae97e8097b5284a2b91a5484bf866f8c
|
|
14
14
|
filename: appsignal-x86_64-darwin-all-static.tar.gz
|
|
15
15
|
dynamic:
|
|
16
|
-
checksum:
|
|
16
|
+
checksum: 4d3789e65cf00e446600e883d95d097323ebb3835703c67c8d09f434f09ab496
|
|
17
17
|
filename: appsignal-x86_64-darwin-all-dynamic.tar.gz
|
|
18
18
|
universal-darwin:
|
|
19
19
|
static:
|
|
20
|
-
checksum:
|
|
20
|
+
checksum: 9bf41c183d94c80e980f57ea2e29d08bae97e8097b5284a2b91a5484bf866f8c
|
|
21
21
|
filename: appsignal-x86_64-darwin-all-static.tar.gz
|
|
22
22
|
dynamic:
|
|
23
|
-
checksum:
|
|
23
|
+
checksum: 4d3789e65cf00e446600e883d95d097323ebb3835703c67c8d09f434f09ab496
|
|
24
24
|
filename: appsignal-x86_64-darwin-all-dynamic.tar.gz
|
|
25
25
|
aarch64-darwin:
|
|
26
26
|
static:
|
|
27
|
-
checksum:
|
|
27
|
+
checksum: 74edd7b97995f3314c10e3d84fc832c1b842c236c331ed4f2f77146ad004d179
|
|
28
28
|
filename: appsignal-aarch64-darwin-all-static.tar.gz
|
|
29
29
|
dynamic:
|
|
30
|
-
checksum:
|
|
30
|
+
checksum: 7165bb164a9cd7a2a5f97897d954390412f7034c667e5826b3307ffbd848bff9
|
|
31
31
|
filename: appsignal-aarch64-darwin-all-dynamic.tar.gz
|
|
32
32
|
arm64-darwin:
|
|
33
33
|
static:
|
|
34
|
-
checksum:
|
|
34
|
+
checksum: 74edd7b97995f3314c10e3d84fc832c1b842c236c331ed4f2f77146ad004d179
|
|
35
35
|
filename: appsignal-aarch64-darwin-all-static.tar.gz
|
|
36
36
|
dynamic:
|
|
37
|
-
checksum:
|
|
37
|
+
checksum: 7165bb164a9cd7a2a5f97897d954390412f7034c667e5826b3307ffbd848bff9
|
|
38
38
|
filename: appsignal-aarch64-darwin-all-dynamic.tar.gz
|
|
39
39
|
arm-darwin:
|
|
40
40
|
static:
|
|
41
|
-
checksum:
|
|
41
|
+
checksum: 74edd7b97995f3314c10e3d84fc832c1b842c236c331ed4f2f77146ad004d179
|
|
42
42
|
filename: appsignal-aarch64-darwin-all-static.tar.gz
|
|
43
43
|
dynamic:
|
|
44
|
-
checksum:
|
|
44
|
+
checksum: 7165bb164a9cd7a2a5f97897d954390412f7034c667e5826b3307ffbd848bff9
|
|
45
45
|
filename: appsignal-aarch64-darwin-all-dynamic.tar.gz
|
|
46
46
|
aarch64-linux:
|
|
47
47
|
static:
|
|
48
|
-
checksum:
|
|
48
|
+
checksum: 0f2430e637eb77ce2093f021777087e87cb1e7be7c86a53771172696791c4879
|
|
49
49
|
filename: appsignal-aarch64-linux-all-static.tar.gz
|
|
50
50
|
dynamic:
|
|
51
|
-
checksum:
|
|
51
|
+
checksum: 0e4f9305aeaaa2d7847e83be04227b865723a0591574108d78040b5921a677a7
|
|
52
52
|
filename: appsignal-aarch64-linux-all-dynamic.tar.gz
|
|
53
53
|
i686-linux:
|
|
54
54
|
static:
|
|
55
|
-
checksum:
|
|
55
|
+
checksum: 449ba623aaa1853c2d211bf1e2d3a14e5ae09225a62457cbdbcc0983a5713a52
|
|
56
56
|
filename: appsignal-i686-linux-all-static.tar.gz
|
|
57
57
|
dynamic:
|
|
58
|
-
checksum:
|
|
58
|
+
checksum: dae994292d602eaf0910bd2ce53f0163e19767a4cbb8e5d0db99c0010d6df486
|
|
59
59
|
filename: appsignal-i686-linux-all-dynamic.tar.gz
|
|
60
60
|
x86-linux:
|
|
61
61
|
static:
|
|
62
|
-
checksum:
|
|
62
|
+
checksum: 449ba623aaa1853c2d211bf1e2d3a14e5ae09225a62457cbdbcc0983a5713a52
|
|
63
63
|
filename: appsignal-i686-linux-all-static.tar.gz
|
|
64
64
|
dynamic:
|
|
65
|
-
checksum:
|
|
65
|
+
checksum: dae994292d602eaf0910bd2ce53f0163e19767a4cbb8e5d0db99c0010d6df486
|
|
66
66
|
filename: appsignal-i686-linux-all-dynamic.tar.gz
|
|
67
67
|
x86_64-linux:
|
|
68
68
|
static:
|
|
69
|
-
checksum:
|
|
69
|
+
checksum: 394796c0ddeb4881c9f2e6ce82f840e66bcb69e027324f6c04f6671067445fbb
|
|
70
70
|
filename: appsignal-x86_64-linux-all-static.tar.gz
|
|
71
71
|
dynamic:
|
|
72
|
-
checksum:
|
|
72
|
+
checksum: 9ca4762c464482b0a5a89898a839388597dd57a17a21527a67f3e3db0e540a03
|
|
73
73
|
filename: appsignal-x86_64-linux-all-dynamic.tar.gz
|
|
74
74
|
x86_64-linux-musl:
|
|
75
75
|
static:
|
|
76
|
-
checksum:
|
|
76
|
+
checksum: 673271c8c5fd55053d8a719bcd307f787db4ca4633baf8cf961c442bf1805614
|
|
77
77
|
filename: appsignal-x86_64-linux-musl-all-static.tar.gz
|
|
78
78
|
dynamic:
|
|
79
|
-
checksum:
|
|
79
|
+
checksum: 609d59376d6633652015e838eb649229fe2523d443a5471232b869f48eb99640
|
|
80
80
|
filename: appsignal-x86_64-linux-musl-all-dynamic.tar.gz
|
|
81
|
+
aarch64-linux-musl:
|
|
82
|
+
static:
|
|
83
|
+
checksum: e90ca19bf61596be022ba04897e8902b3401add58f351a40a3d3a7af241d0bbb
|
|
84
|
+
filename: appsignal-aarch64-linux-musl-all-static.tar.gz
|
|
85
|
+
dynamic:
|
|
86
|
+
checksum: afb66c65fb82b672887bc6b6e82d82f09d9855a5497a7abb06b438dadea97aca
|
|
87
|
+
filename: appsignal-aarch64-linux-musl-all-dynamic.tar.gz
|
|
81
88
|
x86_64-freebsd:
|
|
82
89
|
static:
|
|
83
|
-
checksum:
|
|
90
|
+
checksum: cb45da91c51123859e5ef5cea850460c28d6e77dfa08b90375178d9017162ba8
|
|
84
91
|
filename: appsignal-x86_64-freebsd-all-static.tar.gz
|
|
85
92
|
dynamic:
|
|
86
|
-
checksum:
|
|
93
|
+
checksum: 6a03e02c2526e05edaa7fa932b2e764318c63ec93d517c6c00f6b7541bfe71f3
|
|
87
94
|
filename: appsignal-x86_64-freebsd-all-dynamic.tar.gz
|
|
88
95
|
amd64-freebsd:
|
|
89
96
|
static:
|
|
90
|
-
checksum:
|
|
97
|
+
checksum: cb45da91c51123859e5ef5cea850460c28d6e77dfa08b90375178d9017162ba8
|
|
91
98
|
filename: appsignal-x86_64-freebsd-all-static.tar.gz
|
|
92
99
|
dynamic:
|
|
93
|
-
checksum:
|
|
100
|
+
checksum: 6a03e02c2526e05edaa7fa932b2e764318c63ec93d517c6c00f6b7541bfe71f3
|
|
94
101
|
filename: appsignal-x86_64-freebsd-all-dynamic.tar.gz
|
data/gemfiles/grape.gemfile
CHANGED
|
@@ -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,42 @@
|
|
|
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
|
+
# When this method is called, the given value is stored in a cache
|
|
13
|
+
# under the given cache key.
|
|
14
|
+
#
|
|
15
|
+
# A block must be passed to this method. The first time the method
|
|
16
|
+
# is called for a given cache key, the block will not be yielded to.
|
|
17
|
+
# In subsequent calls, the delta between the previously stored value
|
|
18
|
+
# in the cache for that key and the value given in this invocation
|
|
19
|
+
# will be yielded to the block.
|
|
20
|
+
#
|
|
21
|
+
# This is used for absolute counter values which we want to track as
|
|
22
|
+
# gauges.
|
|
23
|
+
#
|
|
24
|
+
# @example
|
|
25
|
+
# gauge_delta :with_block, 10 do |delta|
|
|
26
|
+
# puts "this block will not be yielded to"
|
|
27
|
+
# end
|
|
28
|
+
# gauge_delta :with_block, 15 do |delta|
|
|
29
|
+
# # `delta` has a value of `5`
|
|
30
|
+
# puts "this block will be yielded to with delta = #{delta}"
|
|
31
|
+
# end
|
|
32
|
+
#
|
|
33
|
+
def gauge_delta(cache_key, value)
|
|
34
|
+
previous_value = gauge_delta_cache[cache_key]
|
|
35
|
+
gauge_delta_cache[cache_key] = value
|
|
36
|
+
return unless previous_value
|
|
37
|
+
|
|
38
|
+
yield value - previous_value
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
data/lib/appsignal/probes/mri.rb
CHANGED
|
@@ -1,25 +1,83 @@
|
|
|
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 initialize(appsignal: Appsignal, gc_profiler: Appsignal::GarbageCollectionProfiler.new)
|
|
10
12
|
Appsignal.logger.debug("Initializing VM probe")
|
|
13
|
+
@appsignal = appsignal
|
|
14
|
+
@gc_profiler = gc_profiler
|
|
11
15
|
end
|
|
12
16
|
|
|
13
17
|
# @api private
|
|
14
18
|
def call
|
|
15
19
|
stat = RubyVM.stat
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
|
|
21
|
+
set_gauge(
|
|
22
|
+
"ruby_vm",
|
|
23
|
+
stat[:class_serial],
|
|
24
|
+
:metric => :class_serial
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
set_gauge(
|
|
28
|
+
"ruby_vm",
|
|
29
|
+
stat[:constant_cache] ? stat[:constant_cache].values.sum : stat[:global_constant_state],
|
|
30
|
+
:metric => :global_constant_state
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
set_gauge("thread_count", Thread.list.size)
|
|
34
|
+
gauge_delta(:gc_total_time, @gc_profiler.total_time) do |total_time|
|
|
35
|
+
set_gauge("gc_total_time", total_time) if total_time > 0
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
gc_stats = GC.stat
|
|
39
|
+
gauge_delta(
|
|
40
|
+
:allocated_objects,
|
|
41
|
+
gc_stats[:total_allocated_objects] || gc_stats[:total_allocated_object]
|
|
42
|
+
) do |allocated_objects|
|
|
43
|
+
set_gauge("allocated_objects", allocated_objects)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
gauge_delta(:gc_count, GC.count) do |gc_count|
|
|
47
|
+
set_gauge("gc_count", gc_count, :metric => :gc_count)
|
|
48
|
+
end
|
|
49
|
+
gauge_delta(:minor_gc_count, gc_stats[:minor_gc_count]) do |minor_gc_count|
|
|
50
|
+
set_gauge("gc_count", minor_gc_count, :metric => :minor_gc_count)
|
|
22
51
|
end
|
|
52
|
+
gauge_delta(:major_gc_count, gc_stats[:major_gc_count]) do |major_gc_count|
|
|
53
|
+
set_gauge("gc_count", major_gc_count, :metric => :major_gc_count)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
set_gauge("heap_slots", gc_stats[:heap_live_slots] || gc_stats[:heap_live_slot], :metric => :heap_live)
|
|
57
|
+
set_gauge("heap_slots", gc_stats[:heap_free_slots] || gc_stats[:heap_free_slot], :metric => :heap_free)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
private
|
|
61
|
+
|
|
62
|
+
def set_gauge(metric, value, tags = {})
|
|
63
|
+
@appsignal.set_gauge(metric, value, { :hostname => hostname }.merge(tags))
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def hostname
|
|
67
|
+
return @hostname if defined?(@hostname)
|
|
68
|
+
|
|
69
|
+
config = @appsignal.config
|
|
70
|
+
@hostname =
|
|
71
|
+
if config[:hostname]
|
|
72
|
+
config[:hostname]
|
|
73
|
+
else
|
|
74
|
+
# Auto detect hostname as fallback. May be inaccurate.
|
|
75
|
+
Socket.gethostname
|
|
76
|
+
end
|
|
77
|
+
Appsignal.logger.debug "MRI probe: Using hostname config " \
|
|
78
|
+
"option '#{@hostname.inspect}' as hostname"
|
|
79
|
+
|
|
80
|
+
@hostname
|
|
23
81
|
end
|
|
24
82
|
end
|
|
25
83
|
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,16 @@ 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,
|
|
46
|
-
:status => :processed
|
|
47
|
-
|
|
47
|
+
gauge_delta :jobs_processed, stats.processed do |jobs_processed|
|
|
48
|
+
gauge "job_count", jobs_processed, :status => :processed
|
|
49
|
+
end
|
|
50
|
+
gauge_delta :jobs_failed, stats.failed do |jobs_failed|
|
|
51
|
+
gauge "job_count", jobs_failed, :status => :failed
|
|
52
|
+
end
|
|
48
53
|
gauge "job_count", stats.retry_size, :status => :retry_queue
|
|
49
|
-
gauge_delta :jobs_dead,
|
|
54
|
+
gauge_delta :jobs_dead, stats.dead_size do |jobs_dead|
|
|
55
|
+
gauge "job_count", jobs_dead, :status => :died
|
|
56
|
+
end
|
|
50
57
|
gauge "job_count", stats.scheduled_size, :status => :scheduled
|
|
51
58
|
gauge "job_count", stats.enqueued, :status => :enqueued
|
|
52
59
|
end
|
|
@@ -65,25 +72,6 @@ module Appsignal
|
|
|
65
72
|
Appsignal.set_gauge "sidekiq_#{key}", value, tags
|
|
66
73
|
end
|
|
67
74
|
|
|
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
75
|
def hostname
|
|
88
76
|
return @hostname if defined?(@hostname)
|
|
89
77
|
if config.key?(:hostname)
|
data/lib/appsignal/probes.rb
CHANGED
data/lib/appsignal/version.rb
CHANGED
data/script/lint_git
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
set -eu
|
|
4
4
|
|
|
5
|
-
LINTJE_VERSION="0.
|
|
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,26 @@
|
|
|
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(:
|
|
21
|
+
let(:appsignal_mock) { AppsignalMock.new(:hostname => hostname) }
|
|
22
|
+
let(:gc_profiler_mock) { instance_double("Appsignal::GarbageCollectionProfiler") }
|
|
23
|
+
let(:probe) { described_class.new(:appsignal => appsignal_mock, :gc_profiler => gc_profiler_mock) }
|
|
3
24
|
|
|
4
25
|
describe ".dependencies_present?" do
|
|
5
26
|
if DependencyHelper.running_jruby? || DependencyHelper.running_ruby_2_0?
|
|
@@ -15,19 +36,103 @@ describe Appsignal::Probes::MriProbe do
|
|
|
15
36
|
|
|
16
37
|
unless DependencyHelper.running_jruby? || DependencyHelper.running_ruby_2_0?
|
|
17
38
|
describe "#call" do
|
|
39
|
+
let(:hostname) { nil }
|
|
40
|
+
before do
|
|
41
|
+
allow(gc_profiler_mock).to receive(:total_time)
|
|
42
|
+
end
|
|
43
|
+
|
|
18
44
|
it "should track vm metrics" do
|
|
19
|
-
|
|
20
|
-
|
|
45
|
+
probe.call
|
|
46
|
+
expect_gauge_value("ruby_vm", :tags => { :metric => :class_serial })
|
|
47
|
+
expect_gauge_value("ruby_vm", :tags => { :metric => :global_constant_state })
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "tracks thread counts" do
|
|
51
|
+
probe.call
|
|
52
|
+
expect_gauge_value("thread_count")
|
|
53
|
+
end
|
|
21
54
|
|
|
55
|
+
it "tracks GC total time" do
|
|
56
|
+
expect(gc_profiler_mock).to receive(:total_time).and_return(10, 15)
|
|
57
|
+
probe.call
|
|
22
58
|
probe.call
|
|
59
|
+
expect_gauge_value("gc_total_time", 5)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
context "when GC total time overflows" do
|
|
63
|
+
it "skips one report" do
|
|
64
|
+
expect(gc_profiler_mock).to receive(:total_time).and_return(10, 15, 0, 10)
|
|
65
|
+
probe.call # Normal call, create a cache
|
|
66
|
+
probe.call # Report delta value based on cached value
|
|
67
|
+
probe.call # The value overflows and reports no value. Then stores 0 in the cache
|
|
68
|
+
probe.call # Report new value based on cache of 0
|
|
69
|
+
expect_gauges([["gc_total_time", 5], ["gc_total_time", 10]])
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it "tracks GC run count" do
|
|
74
|
+
expect(GC).to receive(:count).and_return(10, 15)
|
|
75
|
+
expect(GC).to receive(:stat).and_return(
|
|
76
|
+
{ :minor_gc_count => 10, :major_gc_count => 10 },
|
|
77
|
+
:minor_gc_count => 16, :major_gc_count => 17
|
|
78
|
+
)
|
|
79
|
+
probe.call
|
|
80
|
+
probe.call
|
|
81
|
+
expect_gauge_value("gc_count", 5, :tags => { :metric => :gc_count })
|
|
82
|
+
expect_gauge_value("gc_count", 6, :tags => { :metric => :minor_gc_count })
|
|
83
|
+
expect_gauge_value("gc_count", 7, :tags => { :metric => :major_gc_count })
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it "tracks object allocation" do
|
|
87
|
+
expect(GC).to receive(:stat).and_return(
|
|
88
|
+
{ :total_allocated_objects => 10 },
|
|
89
|
+
:total_allocated_objects => 15
|
|
90
|
+
)
|
|
91
|
+
# Only tracks delta value so the needs to be called twice
|
|
92
|
+
probe.call
|
|
93
|
+
probe.call
|
|
94
|
+
expect_gauge_value("allocated_objects", 5)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it "tracks heap slots" do
|
|
98
|
+
probe.call
|
|
99
|
+
expect_gauge_value("heap_slots", :tags => { :metric => :heap_live })
|
|
100
|
+
expect_gauge_value("heap_slots", :tags => { :metric => :heap_free })
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
context "with custom hostname" do
|
|
104
|
+
let(:hostname) { "my hostname" }
|
|
105
|
+
|
|
106
|
+
it "reports custom hostname tag value" do
|
|
107
|
+
probe.call
|
|
108
|
+
expect_gauge_value("heap_slots", :tags => { :metric => :heap_live, :hostname => hostname })
|
|
109
|
+
end
|
|
23
110
|
end
|
|
24
111
|
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def expect_gauge_value(expected_key, expected_value = nil, tags: {})
|
|
115
|
+
expected_tags = { :hostname => Socket.gethostname }.merge(tags)
|
|
116
|
+
expect(appsignal_mock.gauges).to satisfy do |gauges|
|
|
117
|
+
gauges.any? do |distribution_value|
|
|
118
|
+
key, value, tags = distribution_value
|
|
119
|
+
next unless key == expected_key
|
|
120
|
+
next unless expected_value ? expected_value == value : !value.nil?
|
|
121
|
+
next unless tags == expected_tags
|
|
122
|
+
|
|
123
|
+
true
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
25
127
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
128
|
+
def expect_gauges(expected_metrics)
|
|
129
|
+
default_tags = { :hostname => Socket.gethostname }
|
|
130
|
+
keys = expected_metrics.map { |(key)| key }
|
|
131
|
+
metrics = expected_metrics.map do |metric|
|
|
132
|
+
key, value, tags = metric
|
|
133
|
+
[key, value, default_tags.merge(tags || {})]
|
|
31
134
|
end
|
|
135
|
+
found_gauges = appsignal_mock.gauges.select { |(key)| keys.include? key }
|
|
136
|
+
expect(found_gauges).to eq(metrics)
|
|
32
137
|
end
|
|
33
138
|
end
|