appsignal 3.3.6 → 3.3.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -0
- data/ext/agent.rb +27 -27
- data/lib/appsignal/cli/demo.rb +2 -2
- data/lib/appsignal/cli/diagnose.rb +1 -1
- data/lib/appsignal/cli/install.rb +5 -5
- data/lib/appsignal/config.rb +7 -0
- data/lib/appsignal/helpers/instrumentation.rb +9 -9
- data/lib/appsignal/hooks/gvl.rb +22 -0
- data/lib/appsignal/hooks.rb +1 -0
- data/lib/appsignal/marker.rb +1 -1
- data/lib/appsignal/probes/gvl.rb +47 -0
- data/lib/appsignal/probes/helpers.rb +21 -0
- data/lib/appsignal/probes/mri.rb +12 -35
- data/lib/appsignal/probes.rb +1 -0
- data/lib/appsignal/transaction.rb +2 -2
- data/lib/appsignal/version.rb +1 -1
- data/lib/appsignal.rb +2 -2
- data/resources/appsignal.yml.erb +1 -1
- data/spec/lib/appsignal/cli/diagnose_spec.rb +33 -0
- data/spec/lib/appsignal/cli/install_spec.rb +4 -4
- data/spec/lib/appsignal/config_spec.rb +2 -0
- data/spec/lib/appsignal/hooks/gvl_spec.rb +140 -0
- data/spec/lib/appsignal/probes/gvl_spec.rb +39 -0
- data/spec/lib/appsignal/probes/mri_spec.rb +0 -19
- data/spec/support/fixtures/projects/valid/config/appsignal.yml +6 -0
- data/spec/support/mocks/appsignal_mock.rb +18 -0
- data/spec/support/mocks/fake_gvl_tools.rb +36 -0
- metadata +15 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a589c3f722ba5db3195ee2b9609e635b046790f296ff5985a8974f20f9b6c28f
|
4
|
+
data.tar.gz: 6b8e85945c4517cedff96f03d304e945f70dbc5f0ee53afb153fe0ed35a8bcdd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4beb87ea596e6c189b1ed6042fbfe202ce15e519e2e311c82cf2625a6feb7fa70aecbf4c367bfebec01088215fd1b8c1228204f9b684e8bb4ccc96cd531a78c9
|
7
|
+
data.tar.gz: 0b50957a4ba08682831a8f21c7b589f0a2658ed388b17fb6b9980802a8c83f181b8464976cc8a64ab16648a2d776dfe8c723f2cda227dc6c7d954eacd75ab09d
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,28 @@
|
|
1
1
|
# AppSignal for Ruby gem Changelog
|
2
2
|
|
3
|
+
## 3.3.8
|
4
|
+
|
5
|
+
### Added
|
6
|
+
|
7
|
+
- [2fc6ba85](https://github.com/appsignal/appsignal-ruby/commit/2fc6ba85be1e0cabc2bb8fb26469ad47d1c60243) patch - Support "warning" value for `log_level` config option. This option was documented, but wasn't accepted and fell back on the "info" log level if used. Now it works to configure it to the "warn"/"warning" log level.
|
8
|
+
- [c04f7783](https://github.com/appsignal/appsignal-ruby/commit/c04f778332048aeaad9f75c131247caa29e504fa) patch - Add global VM lock metrics. If the `gvltools` library is installed, AppSignal for Ruby will report metrics on the global VM lock and the number of waiting threads in your application.
|
9
|
+
|
10
|
+
## 3.3.7
|
11
|
+
|
12
|
+
### Added
|
13
|
+
|
14
|
+
- [a815b298](https://github.com/appsignal/appsignal-ruby/commit/a815b29826a84f430384e7e735f79c8c312f1abf) patch - Support cgroups v2. Used by newer Docker engines to report host metrics. Upgrade if you receive no host metrics for Docker containers.
|
15
|
+
|
16
|
+
### Changed
|
17
|
+
|
18
|
+
- [8e67159e](https://github.com/appsignal/appsignal-ruby/commit/8e67159e2a57d3b697a07fadd8eb0e0234db9124) patch - Configure AppSignal with the RACK_ENV or RAILS_ENV environment variable in diagnose CLI, if present. Makes it easier to run the diagnose CLI in production, without having to always specify the environment with the `--environment` CLI option.
|
19
|
+
- [a815b298](https://github.com/appsignal/appsignal-ruby/commit/a815b29826a84f430384e7e735f79c8c312f1abf) patch - Allow transaction events to have a duration up to 48 hours before being discarded.
|
20
|
+
|
21
|
+
### Fixed
|
22
|
+
|
23
|
+
- [a815b298](https://github.com/appsignal/appsignal-ruby/commit/a815b29826a84f430384e7e735f79c8c312f1abf) patch - Remove trailing comments in SQL queries, ensuring queries are grouped consistently.
|
24
|
+
- [a815b298](https://github.com/appsignal/appsignal-ruby/commit/a815b29826a84f430384e7e735f79c8c312f1abf) patch - Fix an issue where events longer than forty-eight minutes would be shown as having a zero-second duration.
|
25
|
+
|
3
26
|
## 3.3.6
|
4
27
|
|
5
28
|
### Changed
|
data/ext/agent.rb
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
# Modifications to this file will be overwritten with the next agent release.
|
5
5
|
|
6
6
|
APPSIGNAL_AGENT_CONFIG = {
|
7
|
-
"version" => "
|
7
|
+
"version" => "dee4fcb",
|
8
8
|
"mirrors" => [
|
9
9
|
"https://appsignal-agent-releases.global.ssl.fastly.net",
|
10
10
|
"https://d135dj0rjqvssy.cloudfront.net"
|
@@ -12,131 +12,131 @@ APPSIGNAL_AGENT_CONFIG = {
|
|
12
12
|
"triples" => {
|
13
13
|
"x86_64-darwin" => {
|
14
14
|
"static" => {
|
15
|
-
"checksum" => "
|
15
|
+
"checksum" => "d45bfc2eb38138c317b501c3156459b8dbbb15a59910f1e2ec3d2d02e461a147",
|
16
16
|
"filename" => "appsignal-x86_64-darwin-all-static.tar.gz"
|
17
17
|
},
|
18
18
|
"dynamic" => {
|
19
|
-
"checksum" => "
|
19
|
+
"checksum" => "a126901650046ae1c40affd386ab5dfcda5cb89f9bd05cf0a3087faff1d2d77d",
|
20
20
|
"filename" => "appsignal-x86_64-darwin-all-dynamic.tar.gz"
|
21
21
|
}
|
22
22
|
},
|
23
23
|
"universal-darwin" => {
|
24
24
|
"static" => {
|
25
|
-
"checksum" => "
|
25
|
+
"checksum" => "d45bfc2eb38138c317b501c3156459b8dbbb15a59910f1e2ec3d2d02e461a147",
|
26
26
|
"filename" => "appsignal-x86_64-darwin-all-static.tar.gz"
|
27
27
|
},
|
28
28
|
"dynamic" => {
|
29
|
-
"checksum" => "
|
29
|
+
"checksum" => "a126901650046ae1c40affd386ab5dfcda5cb89f9bd05cf0a3087faff1d2d77d",
|
30
30
|
"filename" => "appsignal-x86_64-darwin-all-dynamic.tar.gz"
|
31
31
|
}
|
32
32
|
},
|
33
33
|
"aarch64-darwin" => {
|
34
34
|
"static" => {
|
35
|
-
"checksum" => "
|
35
|
+
"checksum" => "1cd875e74ba18c2bc81533437a9eebdf08f624e0201427c13326c2be00f22907",
|
36
36
|
"filename" => "appsignal-aarch64-darwin-all-static.tar.gz"
|
37
37
|
},
|
38
38
|
"dynamic" => {
|
39
|
-
"checksum" => "
|
39
|
+
"checksum" => "d2243146bf4e5839a4cf4430870b7b87d6553e1da4dc631c9fb396bba094cea4",
|
40
40
|
"filename" => "appsignal-aarch64-darwin-all-dynamic.tar.gz"
|
41
41
|
}
|
42
42
|
},
|
43
43
|
"arm64-darwin" => {
|
44
44
|
"static" => {
|
45
|
-
"checksum" => "
|
45
|
+
"checksum" => "1cd875e74ba18c2bc81533437a9eebdf08f624e0201427c13326c2be00f22907",
|
46
46
|
"filename" => "appsignal-aarch64-darwin-all-static.tar.gz"
|
47
47
|
},
|
48
48
|
"dynamic" => {
|
49
|
-
"checksum" => "
|
49
|
+
"checksum" => "d2243146bf4e5839a4cf4430870b7b87d6553e1da4dc631c9fb396bba094cea4",
|
50
50
|
"filename" => "appsignal-aarch64-darwin-all-dynamic.tar.gz"
|
51
51
|
}
|
52
52
|
},
|
53
53
|
"arm-darwin" => {
|
54
54
|
"static" => {
|
55
|
-
"checksum" => "
|
55
|
+
"checksum" => "1cd875e74ba18c2bc81533437a9eebdf08f624e0201427c13326c2be00f22907",
|
56
56
|
"filename" => "appsignal-aarch64-darwin-all-static.tar.gz"
|
57
57
|
},
|
58
58
|
"dynamic" => {
|
59
|
-
"checksum" => "
|
59
|
+
"checksum" => "d2243146bf4e5839a4cf4430870b7b87d6553e1da4dc631c9fb396bba094cea4",
|
60
60
|
"filename" => "appsignal-aarch64-darwin-all-dynamic.tar.gz"
|
61
61
|
}
|
62
62
|
},
|
63
63
|
"aarch64-linux" => {
|
64
64
|
"static" => {
|
65
|
-
"checksum" => "
|
65
|
+
"checksum" => "72fbfaa1c6ed72defea9eca59679372f53ddeab845a9b2f75d9d165e4983d69e",
|
66
66
|
"filename" => "appsignal-aarch64-linux-all-static.tar.gz"
|
67
67
|
},
|
68
68
|
"dynamic" => {
|
69
|
-
"checksum" => "
|
69
|
+
"checksum" => "bf31b4836c84ceaa87a52aa85f296d40e32cfd784a8aa5b19ec5ca3a4aa5c8eb",
|
70
70
|
"filename" => "appsignal-aarch64-linux-all-dynamic.tar.gz"
|
71
71
|
}
|
72
72
|
},
|
73
73
|
"i686-linux" => {
|
74
74
|
"static" => {
|
75
|
-
"checksum" => "
|
75
|
+
"checksum" => "c504a7233512c9285274a7ba0142ab91cf4637c6f5f57c58c6890137ba0f82de",
|
76
76
|
"filename" => "appsignal-i686-linux-all-static.tar.gz"
|
77
77
|
},
|
78
78
|
"dynamic" => {
|
79
|
-
"checksum" => "
|
79
|
+
"checksum" => "19091f50e98afed547b73bc220770bdafce737e152ab9345dabe03e284219cc1",
|
80
80
|
"filename" => "appsignal-i686-linux-all-dynamic.tar.gz"
|
81
81
|
}
|
82
82
|
},
|
83
83
|
"x86-linux" => {
|
84
84
|
"static" => {
|
85
|
-
"checksum" => "
|
85
|
+
"checksum" => "c504a7233512c9285274a7ba0142ab91cf4637c6f5f57c58c6890137ba0f82de",
|
86
86
|
"filename" => "appsignal-i686-linux-all-static.tar.gz"
|
87
87
|
},
|
88
88
|
"dynamic" => {
|
89
|
-
"checksum" => "
|
89
|
+
"checksum" => "19091f50e98afed547b73bc220770bdafce737e152ab9345dabe03e284219cc1",
|
90
90
|
"filename" => "appsignal-i686-linux-all-dynamic.tar.gz"
|
91
91
|
}
|
92
92
|
},
|
93
93
|
"x86_64-linux" => {
|
94
94
|
"static" => {
|
95
|
-
"checksum" => "
|
95
|
+
"checksum" => "f9e68dbbee7d38b255c5b9bc0cb75226764f79cd51421e4e00a9e7454b0c6ccb",
|
96
96
|
"filename" => "appsignal-x86_64-linux-all-static.tar.gz"
|
97
97
|
},
|
98
98
|
"dynamic" => {
|
99
|
-
"checksum" => "
|
99
|
+
"checksum" => "58e3192c87903a2abce6540b893c9d25a69f43e37fd2367df45c2c22c26068ba",
|
100
100
|
"filename" => "appsignal-x86_64-linux-all-dynamic.tar.gz"
|
101
101
|
}
|
102
102
|
},
|
103
103
|
"x86_64-linux-musl" => {
|
104
104
|
"static" => {
|
105
|
-
"checksum" => "
|
105
|
+
"checksum" => "8fa1d110d2544502509cc66ba8ec6685010d8c6d8373f4f14ebe721d4be157e0",
|
106
106
|
"filename" => "appsignal-x86_64-linux-musl-all-static.tar.gz"
|
107
107
|
},
|
108
108
|
"dynamic" => {
|
109
|
-
"checksum" => "
|
109
|
+
"checksum" => "fc46dd29864165968d96bb78fde1c8970903488d80d97056e630636c736cf86f",
|
110
110
|
"filename" => "appsignal-x86_64-linux-musl-all-dynamic.tar.gz"
|
111
111
|
}
|
112
112
|
},
|
113
113
|
"aarch64-linux-musl" => {
|
114
114
|
"static" => {
|
115
|
-
"checksum" => "
|
115
|
+
"checksum" => "a43895183baf017879332885a904208773befc14b9bd628efae6d1513052b782",
|
116
116
|
"filename" => "appsignal-aarch64-linux-musl-all-static.tar.gz"
|
117
117
|
},
|
118
118
|
"dynamic" => {
|
119
|
-
"checksum" => "
|
119
|
+
"checksum" => "7e96b29348be655066cf162ae5c15248bba7d7177663e35e60a6c5ad243937d0",
|
120
120
|
"filename" => "appsignal-aarch64-linux-musl-all-dynamic.tar.gz"
|
121
121
|
}
|
122
122
|
},
|
123
123
|
"x86_64-freebsd" => {
|
124
124
|
"static" => {
|
125
|
-
"checksum" => "
|
125
|
+
"checksum" => "1b992f770bdbced09f7b5f18d7aa721710218d4a76a131adc7affe44d68684f0",
|
126
126
|
"filename" => "appsignal-x86_64-freebsd-all-static.tar.gz"
|
127
127
|
},
|
128
128
|
"dynamic" => {
|
129
|
-
"checksum" => "
|
129
|
+
"checksum" => "300b718986c10ff65f237e1d74086e9cc0f7079d7b531e3b6f9a64752f1aa6ee",
|
130
130
|
"filename" => "appsignal-x86_64-freebsd-all-dynamic.tar.gz"
|
131
131
|
}
|
132
132
|
},
|
133
133
|
"amd64-freebsd" => {
|
134
134
|
"static" => {
|
135
|
-
"checksum" => "
|
135
|
+
"checksum" => "1b992f770bdbced09f7b5f18d7aa721710218d4a76a131adc7affe44d68684f0",
|
136
136
|
"filename" => "appsignal-x86_64-freebsd-all-static.tar.gz"
|
137
137
|
},
|
138
138
|
"dynamic" => {
|
139
|
-
"checksum" => "
|
139
|
+
"checksum" => "300b718986c10ff65f237e1d74086e9cc0f7079d7b531e3b6f9a64752f1aa6ee",
|
140
140
|
"filename" => "appsignal-x86_64-freebsd-all-dynamic.tar.gz"
|
141
141
|
}
|
142
142
|
}
|
data/lib/appsignal/cli/demo.rb
CHANGED
@@ -35,9 +35,9 @@ module Appsignal
|
|
35
35
|
# @since 2.0.0
|
36
36
|
# @see Appsignal::Demo
|
37
37
|
# @see Appsignal::CLI::Install
|
38
|
-
# @see
|
38
|
+
# @see https://docs.appsignal.com/ruby/command-line/demo.html
|
39
39
|
# AppSignal demo documentation
|
40
|
-
# @see
|
40
|
+
# @see https://docs.appsignal.com/support/debugging.html
|
41
41
|
# Debugging AppSignal guide
|
42
42
|
# @api private
|
43
43
|
class Demo
|
@@ -196,7 +196,7 @@ module Appsignal
|
|
196
196
|
|
197
197
|
Appsignal.config = Appsignal::Config.new(
|
198
198
|
current_path,
|
199
|
-
options
|
199
|
+
options.fetch(:environment, ENV.fetch("RACK_ENV", ENV.fetch("RAILS_ENV", nil))),
|
200
200
|
initial_config
|
201
201
|
)
|
202
202
|
Appsignal.config.write_to_environment
|
@@ -126,7 +126,7 @@ module Appsignal
|
|
126
126
|
puts " require 'appsignal/integrations/sinatra'"
|
127
127
|
puts
|
128
128
|
puts " You can find more information in the documentation:"
|
129
|
-
puts "
|
129
|
+
puts " https://docs.appsignal.com/ruby/integrations/sinatra.html"
|
130
130
|
press_any_key
|
131
131
|
done_notice
|
132
132
|
end
|
@@ -144,7 +144,7 @@ module Appsignal
|
|
144
144
|
puts " require 'appsignal/integrations/padrino"
|
145
145
|
puts
|
146
146
|
puts " You can find more information in the documentation:"
|
147
|
-
puts "
|
147
|
+
puts " https://docs.appsignal.com/ruby/integrations/padrino.html"
|
148
148
|
press_any_key
|
149
149
|
done_notice
|
150
150
|
end
|
@@ -159,7 +159,7 @@ module Appsignal
|
|
159
159
|
|
160
160
|
puts "Manual Grape configuration needed"
|
161
161
|
puts " See the installation instructions at:"
|
162
|
-
puts "
|
162
|
+
puts " https://docs.appsignal.com/ruby/integrations/grape.html"
|
163
163
|
press_any_key
|
164
164
|
done_notice
|
165
165
|
end
|
@@ -177,7 +177,7 @@ module Appsignal
|
|
177
177
|
puts " require 'appsignal/integrations/hanami'"
|
178
178
|
puts
|
179
179
|
puts " You can find more information in the documentation:"
|
180
|
-
puts "
|
180
|
+
puts " https://docs.appsignal.com/ruby/integrations/hanami.html"
|
181
181
|
press_any_key
|
182
182
|
done_notice
|
183
183
|
end
|
@@ -234,7 +234,7 @@ module Appsignal
|
|
234
234
|
end
|
235
235
|
puts
|
236
236
|
puts " See the documentation for more configuration options:"
|
237
|
-
puts "
|
237
|
+
puts " https://docs.appsignal.com/gem-settings/configuration.html"
|
238
238
|
press_any_key
|
239
239
|
break
|
240
240
|
end
|
data/lib/appsignal/config.rb
CHANGED
@@ -19,6 +19,8 @@ module Appsignal
|
|
19
19
|
:enable_minutely_probes => true,
|
20
20
|
:enable_statsd => true,
|
21
21
|
:enable_nginx_metrics => false,
|
22
|
+
:enable_gvl_global_timer => true,
|
23
|
+
:enable_gvl_waiting_threads => true,
|
22
24
|
:endpoint => "https://push.appsignal.com",
|
23
25
|
:files_world_accessible => true,
|
24
26
|
:filter_parameters => [],
|
@@ -53,6 +55,7 @@ module Appsignal
|
|
53
55
|
LOG_LEVEL_MAP = {
|
54
56
|
"error" => ::Logger::ERROR,
|
55
57
|
"warn" => ::Logger::WARN,
|
58
|
+
"warning" => ::Logger::WARN,
|
56
59
|
"info" => ::Logger::INFO,
|
57
60
|
"debug" => ::Logger::DEBUG,
|
58
61
|
"trace" => ::Logger::DEBUG
|
@@ -69,6 +72,8 @@ module Appsignal
|
|
69
72
|
"APPSIGNAL_ENABLE_MINUTELY_PROBES" => :enable_minutely_probes,
|
70
73
|
"APPSIGNAL_ENABLE_STATSD" => :enable_statsd,
|
71
74
|
"APPSIGNAL_ENABLE_NGINX_METRICS" => :enable_nginx_metrics,
|
75
|
+
"APPSIGNAL_ENABLE_GVL_GLOBAL_TIMER" => :enable_gvl_global_timer,
|
76
|
+
"APPSIGNAL_ENABLE_GVL_WAITING_THREADS" => :enable_gvl_waiting_threads,
|
72
77
|
"APPSIGNAL_FILES_WORLD_ACCESSIBLE" => :files_world_accessible,
|
73
78
|
"APPSIGNAL_FILTER_PARAMETERS" => :filter_parameters,
|
74
79
|
"APPSIGNAL_FILTER_SESSION_DATA" => :filter_session_data,
|
@@ -123,6 +128,8 @@ module Appsignal
|
|
123
128
|
APPSIGNAL_ENABLE_MINUTELY_PROBES
|
124
129
|
APPSIGNAL_ENABLE_STATSD
|
125
130
|
APPSIGNAL_ENABLE_NGINX_METRICS
|
131
|
+
APPSIGNAL_ENABLE_GVL_GLOBAL_TIMER
|
132
|
+
APPSIGNAL_ENABLE_GVL_WAITING_THREADS
|
126
133
|
APPSIGNAL_FILES_WORLD_ACCESSIBLE
|
127
134
|
APPSIGNAL_INSTRUMENT_HTTP_RB
|
128
135
|
APPSIGNAL_INSTRUMENT_NET_HTTP
|
@@ -197,9 +197,9 @@ module Appsignal
|
|
197
197
|
# used to send the error.
|
198
198
|
# @return [void]
|
199
199
|
#
|
200
|
-
# @see
|
200
|
+
# @see https://docs.appsignal.com/ruby/instrumentation/exception-handling.html
|
201
201
|
# Exception handling guide
|
202
|
-
# @see
|
202
|
+
# @see https://docs.appsignal.com/ruby/instrumentation/tagging.html
|
203
203
|
# Tagging guide
|
204
204
|
# @since 0.6.0
|
205
205
|
def send_error(
|
@@ -296,7 +296,7 @@ module Appsignal
|
|
296
296
|
# @return [void]
|
297
297
|
#
|
298
298
|
# @see Transaction#set_error
|
299
|
-
# @see
|
299
|
+
# @see https://docs.appsignal.com/ruby/instrumentation/exception-handling.html
|
300
300
|
# Exception handling guide
|
301
301
|
# @since 0.6.6
|
302
302
|
def set_error(exception, tags = nil, namespace = nil)
|
@@ -435,7 +435,7 @@ module Appsignal
|
|
435
435
|
# @return [void]
|
436
436
|
#
|
437
437
|
# @see Transaction.set_tags
|
438
|
-
# @see
|
438
|
+
# @see https://docs.appsignal.com/ruby/instrumentation/tagging.html
|
439
439
|
# Tagging guide
|
440
440
|
def tag_request(tags = {})
|
441
441
|
return unless active?
|
@@ -468,7 +468,7 @@ module Appsignal
|
|
468
468
|
# @return [void]
|
469
469
|
#
|
470
470
|
# @see Transaction#add_breadcrumb
|
471
|
-
# @see
|
471
|
+
# @see https://docs.appsignal.com/ruby/instrumentation/breadcrumbs.html
|
472
472
|
# Breadcrumb reference
|
473
473
|
# @since 2.12.0
|
474
474
|
def add_breadcrumb(category, action, message = "", metadata = {}, time = Time.now.utc)
|
@@ -513,9 +513,9 @@ module Appsignal
|
|
513
513
|
#
|
514
514
|
# @see Appsignal::Transaction#instrument
|
515
515
|
# @see .instrument_sql
|
516
|
-
# @see
|
516
|
+
# @see https://docs.appsignal.com/ruby/instrumentation/instrumentation.html
|
517
517
|
# AppSignal custom instrumentation guide
|
518
|
-
# @see
|
518
|
+
# @see https://docs.appsignal.com/api/event-names.html
|
519
519
|
# AppSignal event naming guide
|
520
520
|
# @since 1.3.0
|
521
521
|
def instrument(
|
@@ -557,9 +557,9 @@ module Appsignal
|
|
557
557
|
# @return [Object] Returns the block's return value.
|
558
558
|
#
|
559
559
|
# @see .instrument
|
560
|
-
# @see
|
560
|
+
# @see https://docs.appsignal.com/ruby/instrumentation/instrumentation.html
|
561
561
|
# AppSignal custom instrumentation guide
|
562
|
-
# @see
|
562
|
+
# @see https://docs.appsignal.com/api/event-names.html
|
563
563
|
# AppSignal event naming guide
|
564
564
|
# @since 2.0.0
|
565
565
|
def instrument_sql(name, title = nil, body = nil, &block)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Appsignal
|
2
|
+
class Hooks
|
3
|
+
# @api private
|
4
|
+
class GvlHook < Appsignal::Hooks::Hook
|
5
|
+
register :gvl
|
6
|
+
|
7
|
+
def dependencies_present?
|
8
|
+
return false if Appsignal::System.jruby?
|
9
|
+
require "gvltools"
|
10
|
+
Appsignal.config && Appsignal::Probes::GvlProbe.dependencies_present?
|
11
|
+
rescue LoadError
|
12
|
+
false
|
13
|
+
end
|
14
|
+
|
15
|
+
def install
|
16
|
+
Appsignal::Minutely.probes.register :gvl, Appsignal::Probes::GvlProbe
|
17
|
+
::GVLTools::GlobalTimer.enable if Appsignal.config[:enable_gvl_global_timer]
|
18
|
+
::GVLTools::WaitingThreads.enable if Appsignal.config[:enable_gvl_waiting_threads]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/appsignal/hooks.rb
CHANGED
@@ -94,6 +94,7 @@ require "appsignal/hooks/active_job"
|
|
94
94
|
require "appsignal/hooks/active_support_notifications"
|
95
95
|
require "appsignal/hooks/celluloid"
|
96
96
|
require "appsignal/hooks/delayed_job"
|
97
|
+
require "appsignal/hooks/gvl"
|
97
98
|
require "appsignal/hooks/http"
|
98
99
|
require "appsignal/hooks/mri"
|
99
100
|
require "appsignal/hooks/net_http"
|
data/lib/appsignal/marker.rb
CHANGED
@@ -18,7 +18,7 @@ module Appsignal
|
|
18
18
|
# Set config does not override data set in {#marker_data}.
|
19
19
|
#
|
20
20
|
# @see Appsignal::CLI::NotifyOfDeploy
|
21
|
-
# @see
|
21
|
+
# @see https://docs.appsignal.com/appsignal/terminology.html#markers
|
22
22
|
# Terminology: Deploy marker
|
23
23
|
# @api private
|
24
24
|
class Marker
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Appsignal
|
2
|
+
module Probes
|
3
|
+
class GvlProbe
|
4
|
+
include Helpers
|
5
|
+
|
6
|
+
# @api private
|
7
|
+
def self.dependencies_present?
|
8
|
+
defined?(::GVLTools) && gvltools_0_2_or_newer? && ruby_3_2_or_newer? && !Appsignal::System.jruby?
|
9
|
+
end
|
10
|
+
|
11
|
+
# @api private
|
12
|
+
def self.gvltools_0_2_or_newer?
|
13
|
+
Gem::Version.new(::GVLTools::VERSION) >= Gem::Version.new("0.2.0")
|
14
|
+
end
|
15
|
+
|
16
|
+
# @api private
|
17
|
+
def self.ruby_3_2_or_newer?
|
18
|
+
Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("3.2.0")
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize(appsignal: Appsignal, gvl_tools: ::GVLTools)
|
22
|
+
Appsignal.logger.debug("Initializing GVL probe")
|
23
|
+
@appsignal = appsignal
|
24
|
+
@gvl_tools = gvl_tools
|
25
|
+
end
|
26
|
+
|
27
|
+
def call
|
28
|
+
probe_global_timer if @gvl_tools::GlobalTimer.enabled?
|
29
|
+
probe_waiting_threads if @gvl_tools::WaitingThreads.enabled?
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def probe_global_timer
|
35
|
+
monotonic_time_ns = @gvl_tools::GlobalTimer.monotonic_time
|
36
|
+
gauge_delta :gvl_global_timer, monotonic_time_ns do |time_delta_ns|
|
37
|
+
time_delta_ms = time_delta_ns / 1_000_000
|
38
|
+
set_gauge_with_hostname("gvl_global_timer", time_delta_ms)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def probe_waiting_threads
|
43
|
+
set_gauge_with_hostname("gvl_waiting_threads", @gvl_tools::WaitingThreads.count)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -37,6 +37,27 @@ module Appsignal
|
|
37
37
|
|
38
38
|
yield value - previous_value
|
39
39
|
end
|
40
|
+
|
41
|
+
def hostname
|
42
|
+
return @hostname if defined?(@hostname)
|
43
|
+
|
44
|
+
config = @appsignal.config
|
45
|
+
@hostname =
|
46
|
+
if config[:hostname]
|
47
|
+
config[:hostname]
|
48
|
+
else
|
49
|
+
# Auto detect hostname as fallback. May be inaccurate.
|
50
|
+
Socket.gethostname
|
51
|
+
end
|
52
|
+
Appsignal.logger.debug "Probe helper: Using hostname config " \
|
53
|
+
"option '#{@hostname.inspect}' as hostname"
|
54
|
+
|
55
|
+
@hostname
|
56
|
+
end
|
57
|
+
|
58
|
+
def set_gauge_with_hostname(metric, value, tags = {})
|
59
|
+
@appsignal.set_gauge(metric, value, { :hostname => hostname }.merge(tags))
|
60
|
+
end
|
40
61
|
end
|
41
62
|
end
|
42
63
|
end
|
data/lib/appsignal/probes/mri.rb
CHANGED
@@ -20,7 +20,7 @@ module Appsignal
|
|
20
20
|
|
21
21
|
constant_cache_invalidations = stat[:constant_cache_invalidations]
|
22
22
|
if constant_cache_invalidations
|
23
|
-
|
23
|
+
set_gauge_with_hostname(
|
24
24
|
"ruby_vm",
|
25
25
|
constant_cache_invalidations,
|
26
26
|
:metric => :constant_cache_invalidations
|
@@ -29,7 +29,7 @@ module Appsignal
|
|
29
29
|
|
30
30
|
constant_cache_misses = stat[:constant_cache_misses]
|
31
31
|
if constant_cache_misses
|
32
|
-
|
32
|
+
set_gauge_with_hostname(
|
33
33
|
"ruby_vm",
|
34
34
|
constant_cache_misses,
|
35
35
|
:metric => :constant_cache_misses
|
@@ -38,23 +38,23 @@ module Appsignal
|
|
38
38
|
|
39
39
|
class_serial = stat[:class_serial]
|
40
40
|
if class_serial
|
41
|
-
|
41
|
+
set_gauge_with_hostname("ruby_vm", class_serial, :metric => :class_serial)
|
42
42
|
end
|
43
43
|
|
44
44
|
global_constant_state =
|
45
45
|
stat[:constant_cache] ? stat[:constant_cache].values.sum : stat[:global_constant_state]
|
46
46
|
if global_constant_state
|
47
|
-
|
47
|
+
set_gauge_with_hostname(
|
48
48
|
"ruby_vm",
|
49
49
|
global_constant_state,
|
50
50
|
:metric => :global_constant_state
|
51
51
|
)
|
52
52
|
end
|
53
53
|
|
54
|
-
|
54
|
+
set_gauge_with_hostname("thread_count", Thread.list.size)
|
55
55
|
if Appsignal::GarbageCollection.enabled?
|
56
56
|
gauge_delta(:gc_time, @gc_profiler.total_time) do |gc_time|
|
57
|
-
|
57
|
+
set_gauge_with_hostname("gc_time", gc_time) if gc_time > 0
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
@@ -63,44 +63,21 @@ module Appsignal
|
|
63
63
|
:allocated_objects,
|
64
64
|
gc_stats[:total_allocated_objects] || gc_stats[:total_allocated_object]
|
65
65
|
) do |allocated_objects|
|
66
|
-
|
66
|
+
set_gauge_with_hostname("allocated_objects", allocated_objects)
|
67
67
|
end
|
68
68
|
|
69
69
|
gauge_delta(:gc_count, GC.count) do |gc_count|
|
70
|
-
|
70
|
+
set_gauge_with_hostname("gc_count", gc_count, :metric => :gc_count)
|
71
71
|
end
|
72
72
|
gauge_delta(:minor_gc_count, gc_stats[:minor_gc_count]) do |minor_gc_count|
|
73
|
-
|
73
|
+
set_gauge_with_hostname("gc_count", minor_gc_count, :metric => :minor_gc_count)
|
74
74
|
end
|
75
75
|
gauge_delta(:major_gc_count, gc_stats[:major_gc_count]) do |major_gc_count|
|
76
|
-
|
76
|
+
set_gauge_with_hostname("gc_count", major_gc_count, :metric => :major_gc_count)
|
77
77
|
end
|
78
78
|
|
79
|
-
|
80
|
-
|
81
|
-
end
|
82
|
-
|
83
|
-
private
|
84
|
-
|
85
|
-
def set_gauge(metric, value, tags = {})
|
86
|
-
@appsignal.set_gauge(metric, value, { :hostname => hostname }.merge(tags))
|
87
|
-
end
|
88
|
-
|
89
|
-
def hostname
|
90
|
-
return @hostname if defined?(@hostname)
|
91
|
-
|
92
|
-
config = @appsignal.config
|
93
|
-
@hostname =
|
94
|
-
if config[:hostname]
|
95
|
-
config[:hostname]
|
96
|
-
else
|
97
|
-
# Auto detect hostname as fallback. May be inaccurate.
|
98
|
-
Socket.gethostname
|
99
|
-
end
|
100
|
-
Appsignal.logger.debug "MRI probe: Using hostname config " \
|
101
|
-
"option '#{@hostname.inspect}' as hostname"
|
102
|
-
|
103
|
-
@hostname
|
79
|
+
set_gauge_with_hostname("heap_slots", gc_stats[:heap_live_slots] || gc_stats[:heap_live_slot], :metric => :heap_live)
|
80
|
+
set_gauge_with_hostname("heap_slots", gc_stats[:heap_free_slots] || gc_stats[:heap_free_slot], :metric => :heap_free)
|
104
81
|
end
|
105
82
|
end
|
106
83
|
end
|
data/lib/appsignal/probes.rb
CHANGED
@@ -159,7 +159,7 @@ module Appsignal
|
|
159
159
|
# @return [void]
|
160
160
|
#
|
161
161
|
# @see Appsignal.tag_request
|
162
|
-
# @see
|
162
|
+
# @see https://docs.appsignal.com/ruby/instrumentation/tagging.html
|
163
163
|
# Tagging guide
|
164
164
|
def set_tags(given_tags = {})
|
165
165
|
@tags.merge!(given_tags)
|
@@ -177,7 +177,7 @@ module Appsignal
|
|
177
177
|
# @return [void]
|
178
178
|
#
|
179
179
|
# @see Appsignal.add_breadcrumb
|
180
|
-
# @see
|
180
|
+
# @see https://docs.appsignal.com/ruby/instrumentation/breadcrumbs.html
|
181
181
|
# Breadcrumb reference
|
182
182
|
def add_breadcrumb(category, action, message = "", metadata = {}, time = Time.now.utc)
|
183
183
|
@breadcrumbs.push(
|
data/lib/appsignal/version.rb
CHANGED
data/lib/appsignal.rb
CHANGED
@@ -74,8 +74,8 @@ module Appsignal
|
|
74
74
|
# This is not required for the automatic integrations AppSignal offers, but
|
75
75
|
# this is required for all non-automatic integrations and pure Ruby
|
76
76
|
# applications. For more information, see our [integrations
|
77
|
-
# list](
|
78
|
-
# AppSignal](
|
77
|
+
# list](https://docs.appsignal.com/ruby/integrations/) and our [Integrating
|
78
|
+
# AppSignal](https://docs.appsignal.com/ruby/instrumentation/integrating-appsignal.html)
|
79
79
|
# guide.
|
80
80
|
#
|
81
81
|
# To start the logger see {.start_logger}.
|
data/resources/appsignal.yml.erb
CHANGED
@@ -26,7 +26,7 @@ default: &defaults
|
|
26
26
|
# - SystemExit
|
27
27
|
# - SystemStackError
|
28
28
|
|
29
|
-
# See
|
29
|
+
# See https://docs.appsignal.com/ruby/configuration/options.html for
|
30
30
|
# all configuration options.
|
31
31
|
|
32
32
|
# Configuration per environment, leave out an environment or set active
|
@@ -802,6 +802,39 @@ describe Appsignal::CLI::Diagnose, :api_stub => true, :send_report => :yes_cli_i
|
|
802
802
|
end
|
803
803
|
end
|
804
804
|
|
805
|
+
context "when the source is the RACK_ENV env variable", :send_report => :no_cli_option do
|
806
|
+
let(:config) { project_fixture_config("rack_env") }
|
807
|
+
let(:options) { {} }
|
808
|
+
before do
|
809
|
+
ENV["RACK_ENV"] = "rack_env"
|
810
|
+
run
|
811
|
+
end
|
812
|
+
after { ENV.delete("RACK_ENV") }
|
813
|
+
|
814
|
+
it "outputs the RACK_ENV variable value" do
|
815
|
+
expect(output).to include(
|
816
|
+
%(environment: "rack_env" (Loaded from: initial)\n)
|
817
|
+
)
|
818
|
+
end
|
819
|
+
end
|
820
|
+
|
821
|
+
context "when the source is the RAILS_ENV env variable", :send_report => :no_cli_option do
|
822
|
+
let(:config) { project_fixture_config("rails_env") }
|
823
|
+
let(:options) { {} }
|
824
|
+
before do
|
825
|
+
ENV.delete("RACK_ENV")
|
826
|
+
ENV["RAILS_ENV"] = "rails_env"
|
827
|
+
run
|
828
|
+
end
|
829
|
+
after { ENV.delete("RAILS_ENV") }
|
830
|
+
|
831
|
+
it "outputs the RAILS_ENV variable value" do
|
832
|
+
expect(output).to include(
|
833
|
+
%(environment: "rails_env" (Loaded from: initial)\n)
|
834
|
+
)
|
835
|
+
end
|
836
|
+
end
|
837
|
+
|
805
838
|
context "when the source is multiple sources" do
|
806
839
|
let(:options) { { :environment => "development" } }
|
807
840
|
before do
|
@@ -469,7 +469,7 @@ describe Appsignal::CLI::Install do
|
|
469
469
|
"Installing for Sinatra",
|
470
470
|
"Sinatra requires some manual configuration.",
|
471
471
|
"require 'appsignal/integrations/sinatra'",
|
472
|
-
"
|
472
|
+
"https://docs.appsignal.com/ruby/integrations/sinatra.html"
|
473
473
|
]
|
474
474
|
end
|
475
475
|
let(:app_name) { "Test app" }
|
@@ -536,7 +536,7 @@ describe Appsignal::CLI::Install do
|
|
536
536
|
[
|
537
537
|
"Installing for Padrino",
|
538
538
|
"Padrino requires some manual configuration.",
|
539
|
-
"
|
539
|
+
"https://docs.appsignal.com/ruby/integrations/padrino.html"
|
540
540
|
]
|
541
541
|
end
|
542
542
|
let(:app_name) { "Test app" }
|
@@ -603,7 +603,7 @@ describe Appsignal::CLI::Install do
|
|
603
603
|
[
|
604
604
|
"Installing for Grape",
|
605
605
|
"Manual Grape configuration needed",
|
606
|
-
"
|
606
|
+
"https://docs.appsignal.com/ruby/integrations/grape.html"
|
607
607
|
]
|
608
608
|
end
|
609
609
|
let(:app_name) { "Test app" }
|
@@ -670,7 +670,7 @@ describe Appsignal::CLI::Install do
|
|
670
670
|
[
|
671
671
|
"Installing for Hanami",
|
672
672
|
"Hanami requires some manual configuration.",
|
673
|
-
"
|
673
|
+
"https://docs.appsignal.com/ruby/integrations/hanami.html"
|
674
674
|
]
|
675
675
|
end
|
676
676
|
let(:app_name) { "Test app" }
|
@@ -156,6 +156,8 @@ describe Appsignal::Config do
|
|
156
156
|
:debug => false,
|
157
157
|
:dns_servers => [],
|
158
158
|
:enable_allocation_tracking => true,
|
159
|
+
:enable_gvl_global_timer => true,
|
160
|
+
:enable_gvl_waiting_threads => true,
|
159
161
|
:enable_host_metrics => true,
|
160
162
|
:enable_minutely_probes => true,
|
161
163
|
:enable_statsd => true,
|
@@ -0,0 +1,140 @@
|
|
1
|
+
describe Appsignal::Hooks::GvlHook do
|
2
|
+
if DependencyHelper.running_jruby?
|
3
|
+
context "running JRuby" do
|
4
|
+
it "does not attempt to require GVLTools" do
|
5
|
+
expect_any_instance_of(described_class).not_to receive(:require).with("gvltools")
|
6
|
+
expect(described_class.new.dependencies_present?).to be_falsy
|
7
|
+
end
|
8
|
+
end
|
9
|
+
else
|
10
|
+
before(:context) do
|
11
|
+
Appsignal.config = project_fixture_config
|
12
|
+
end
|
13
|
+
|
14
|
+
def expect_gvltools_require
|
15
|
+
expect_any_instance_of(described_class).to receive(:require).with("gvltools").and_return(true)
|
16
|
+
end
|
17
|
+
|
18
|
+
context "without GVLTools" do
|
19
|
+
describe "#dependencies_present?" do
|
20
|
+
context "if requiring gvltools fails" do
|
21
|
+
it "is false" do
|
22
|
+
expect(described_class.new.dependencies_present?).to be_falsy
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it "is false" do
|
27
|
+
expect_gvltools_require
|
28
|
+
expect(described_class.new.dependencies_present?).to be_falsy
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "with old versions of GVLTools" do
|
34
|
+
before(:context) do
|
35
|
+
module GVLTools
|
36
|
+
VERSION = "0.1.0".freeze
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
after(:context) { Object.send(:remove_const, :GVLTools) }
|
41
|
+
|
42
|
+
before(:each) { expect_gvltools_require }
|
43
|
+
|
44
|
+
describe "#dependencies_present?" do
|
45
|
+
it "is false" do
|
46
|
+
expect(described_class.new.dependencies_present?).to be_falsy
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "with new versions of GVLTools" do
|
52
|
+
before(:context) do
|
53
|
+
module GVLTools
|
54
|
+
VERSION = "0.2.0".freeze
|
55
|
+
|
56
|
+
module GlobalTimer
|
57
|
+
def self.enable
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
module WaitingThreads
|
62
|
+
def self.enable
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
after(:context) { Object.send(:remove_const, :GVLTools) }
|
69
|
+
|
70
|
+
describe "#dependencies_present?" do
|
71
|
+
before(:each) { expect_gvltools_require }
|
72
|
+
|
73
|
+
if DependencyHelper.ruby_3_2_or_newer?
|
74
|
+
it "is true" do
|
75
|
+
expect(described_class.new.dependencies_present?).to be_truthy
|
76
|
+
end
|
77
|
+
else
|
78
|
+
it "is false" do
|
79
|
+
expect(described_class.new.dependencies_present?).to be_falsy
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
if DependencyHelper.ruby_3_2_or_newer?
|
85
|
+
describe "Appsignal::Hooks.load_hooks" do
|
86
|
+
before(:each) { expect_gvltools_require }
|
87
|
+
|
88
|
+
# After installing a hook once, it is marked as already installed,
|
89
|
+
# and subsequent calls to `load_hooks` silently do nothing.
|
90
|
+
# Because of this, only one of the tests for the installation uses
|
91
|
+
# `load_hooks`, while the rest call the `install` method directly.
|
92
|
+
|
93
|
+
it "is added to minutely probes" do
|
94
|
+
Appsignal::Hooks.load_hooks
|
95
|
+
|
96
|
+
expect(Appsignal::Minutely.probes[:gvl]).to be Appsignal::Probes::GvlProbe
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "#install" do
|
102
|
+
context "with enable_gvl_global_timer" do
|
103
|
+
it "enables the GVL global timer" do
|
104
|
+
Appsignal.config[:enable_gvl_global_timer] = true
|
105
|
+
expect(::GVLTools::GlobalTimer).to receive(:enable)
|
106
|
+
|
107
|
+
described_class.new.install
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context "without enable_gvl_global_timer" do
|
112
|
+
it "does not enable the GVL global timer" do
|
113
|
+
Appsignal.config[:enable_gvl_global_timer] = false
|
114
|
+
expect(::GVLTools::GlobalTimer).not_to receive(:enable)
|
115
|
+
|
116
|
+
described_class.new.install
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context "with enable_gvl_waiting_threads" do
|
121
|
+
it "enables the GVL waiting threads" do
|
122
|
+
Appsignal.config[:enable_gvl_global_timer] = true
|
123
|
+
expect(::GVLTools::WaitingThreads).to receive(:enable)
|
124
|
+
|
125
|
+
described_class.new.install
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context "without enable_gvl_waiting_threads" do
|
130
|
+
it "does not enable the GVL waiting threads" do
|
131
|
+
Appsignal.config[:enable_gvl_waiting_threads] = false
|
132
|
+
expect(::GVLTools::WaitingThreads).not_to receive(:enable)
|
133
|
+
|
134
|
+
described_class.new.install
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
describe Appsignal::Probes::GvlProbe do
|
2
|
+
let(:appsignal_mock) { AppsignalMock.new(:hostname => hostname) }
|
3
|
+
let(:probe) { described_class.new(:appsignal => appsignal_mock, :gvl_tools => FakeGVLTools) }
|
4
|
+
|
5
|
+
let(:hostname) { "some-host" }
|
6
|
+
|
7
|
+
after(:each) { FakeGVLTools.reset }
|
8
|
+
|
9
|
+
context "with global timer enabled" do
|
10
|
+
before(:each) { FakeGVLTools::GlobalTimer.enabled = true }
|
11
|
+
|
12
|
+
it "gauges the global timer delta" do
|
13
|
+
FakeGVLTools::GlobalTimer.monotonic_time = 100_000_000
|
14
|
+
probe.call
|
15
|
+
|
16
|
+
expect(appsignal_mock.gauges).to be_empty
|
17
|
+
|
18
|
+
FakeGVLTools::GlobalTimer.monotonic_time = 300_000_000
|
19
|
+
probe.call
|
20
|
+
|
21
|
+
expect(appsignal_mock.gauges).to eq [
|
22
|
+
["gvl_global_timer", 200, { :hostname => hostname }]
|
23
|
+
]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "with waiting threads enabled" do
|
28
|
+
before(:each) { FakeGVLTools::WaitingThreads.enabled = true }
|
29
|
+
|
30
|
+
it "gauges the waiting threads count" do
|
31
|
+
FakeGVLTools::WaitingThreads.count = 3
|
32
|
+
probe.call
|
33
|
+
|
34
|
+
expect(appsignal_mock.gauges).to eq [
|
35
|
+
["gvl_waiting_threads", 3, { :hostname => hostname }]
|
36
|
+
]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -1,22 +1,3 @@
|
|
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
|
-
|
20
1
|
describe Appsignal::Probes::MriProbe do
|
21
2
|
let(:appsignal_mock) { AppsignalMock.new(:hostname => hostname) }
|
22
3
|
let(:gc_profiler_mock) { instance_double("Appsignal::GarbageCollectionProfiler") }
|
@@ -0,0 +1,18 @@
|
|
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
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module FakeGVLTools
|
2
|
+
def self.reset
|
3
|
+
self::GlobalTimer.enabled = false
|
4
|
+
self::GlobalTimer.monotonic_time = 0
|
5
|
+
self::WaitingThreads.enabled = false
|
6
|
+
self::WaitingThreads.count = 0
|
7
|
+
end
|
8
|
+
|
9
|
+
module GlobalTimer
|
10
|
+
@enabled = false
|
11
|
+
@monotonic_time = 0
|
12
|
+
|
13
|
+
class << self
|
14
|
+
attr_writer :enabled
|
15
|
+
attr_accessor :monotonic_time
|
16
|
+
|
17
|
+
def enabled?
|
18
|
+
@enabled
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module WaitingThreads
|
24
|
+
@enabled = false
|
25
|
+
@count = 0
|
26
|
+
|
27
|
+
class << self
|
28
|
+
attr_writer :enabled
|
29
|
+
attr_accessor :count
|
30
|
+
|
31
|
+
def enabled?
|
32
|
+
@enabled
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
metadata
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: appsignal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.3.
|
4
|
+
version: 3.3.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Beekman
|
8
8
|
- Thijs Cadier
|
9
9
|
- Tom de Bruijn
|
10
|
-
autorequire:
|
10
|
+
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2023-
|
13
|
+
date: 2023-03-30 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rack
|
@@ -218,6 +218,7 @@ files:
|
|
218
218
|
- lib/appsignal/hooks/data_mapper.rb
|
219
219
|
- lib/appsignal/hooks/delayed_job.rb
|
220
220
|
- lib/appsignal/hooks/excon.rb
|
221
|
+
- lib/appsignal/hooks/gvl.rb
|
221
222
|
- lib/appsignal/hooks/http.rb
|
222
223
|
- lib/appsignal/hooks/mongo_ruby_driver.rb
|
223
224
|
- lib/appsignal/hooks/mri.rb
|
@@ -260,6 +261,7 @@ files:
|
|
260
261
|
- lib/appsignal/marker.rb
|
261
262
|
- lib/appsignal/minutely.rb
|
262
263
|
- lib/appsignal/probes.rb
|
264
|
+
- lib/appsignal/probes/gvl.rb
|
263
265
|
- lib/appsignal/probes/helpers.rb
|
264
266
|
- lib/appsignal/probes/mri.rb
|
265
267
|
- lib/appsignal/probes/sidekiq.rb
|
@@ -323,6 +325,7 @@ files:
|
|
323
325
|
- spec/lib/appsignal/hooks/data_mapper_spec.rb
|
324
326
|
- spec/lib/appsignal/hooks/delayed_job_spec.rb
|
325
327
|
- spec/lib/appsignal/hooks/excon_spec.rb
|
328
|
+
- spec/lib/appsignal/hooks/gvl_spec.rb
|
326
329
|
- spec/lib/appsignal/hooks/http_spec.rb
|
327
330
|
- spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb
|
328
331
|
- spec/lib/appsignal/hooks/mri_spec.rb
|
@@ -354,6 +357,7 @@ files:
|
|
354
357
|
- spec/lib/appsignal/logger_spec.rb
|
355
358
|
- spec/lib/appsignal/marker_spec.rb
|
356
359
|
- spec/lib/appsignal/minutely_spec.rb
|
360
|
+
- spec/lib/appsignal/probes/gvl_spec.rb
|
357
361
|
- spec/lib/appsignal/probes/mri_spec.rb
|
358
362
|
- spec/lib/appsignal/probes/sidekiq_spec.rb
|
359
363
|
- spec/lib/appsignal/rack/generic_instrumentation_spec.rb
|
@@ -402,7 +406,9 @@ files:
|
|
402
406
|
- spec/support/matchers/be_completed.rb
|
403
407
|
- spec/support/matchers/contains_log.rb
|
404
408
|
- spec/support/matchers/have_colorized_text.rb
|
409
|
+
- spec/support/mocks/appsignal_mock.rb
|
405
410
|
- spec/support/mocks/fake_gc_profiler.rb
|
411
|
+
- spec/support/mocks/fake_gvl_tools.rb
|
406
412
|
- spec/support/mocks/mock_probe.rb
|
407
413
|
- spec/support/rails/my_app.rb
|
408
414
|
- spec/support/shared_examples/instrument.rb
|
@@ -422,7 +428,7 @@ metadata:
|
|
422
428
|
documentation_uri: https://docs.appsignal.com/ruby/
|
423
429
|
homepage_uri: https://docs.appsignal.com/ruby/
|
424
430
|
source_code_uri: https://github.com/appsignal/appsignal-ruby
|
425
|
-
post_install_message:
|
431
|
+
post_install_message:
|
426
432
|
rdoc_options: []
|
427
433
|
require_paths:
|
428
434
|
- lib
|
@@ -439,7 +445,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
439
445
|
version: '0'
|
440
446
|
requirements: []
|
441
447
|
rubygems_version: 3.1.6
|
442
|
-
signing_key:
|
448
|
+
signing_key:
|
443
449
|
specification_version: 4
|
444
450
|
summary: Logs performance and exception data from your app to appsignal.com
|
445
451
|
test_files:
|
@@ -480,6 +486,7 @@ test_files:
|
|
480
486
|
- spec/lib/appsignal/hooks/data_mapper_spec.rb
|
481
487
|
- spec/lib/appsignal/hooks/delayed_job_spec.rb
|
482
488
|
- spec/lib/appsignal/hooks/excon_spec.rb
|
489
|
+
- spec/lib/appsignal/hooks/gvl_spec.rb
|
483
490
|
- spec/lib/appsignal/hooks/http_spec.rb
|
484
491
|
- spec/lib/appsignal/hooks/mongo_ruby_driver_spec.rb
|
485
492
|
- spec/lib/appsignal/hooks/mri_spec.rb
|
@@ -511,6 +518,7 @@ test_files:
|
|
511
518
|
- spec/lib/appsignal/logger_spec.rb
|
512
519
|
- spec/lib/appsignal/marker_spec.rb
|
513
520
|
- spec/lib/appsignal/minutely_spec.rb
|
521
|
+
- spec/lib/appsignal/probes/gvl_spec.rb
|
514
522
|
- spec/lib/appsignal/probes/mri_spec.rb
|
515
523
|
- spec/lib/appsignal/probes/sidekiq_spec.rb
|
516
524
|
- spec/lib/appsignal/rack/generic_instrumentation_spec.rb
|
@@ -559,7 +567,9 @@ test_files:
|
|
559
567
|
- spec/support/matchers/be_completed.rb
|
560
568
|
- spec/support/matchers/contains_log.rb
|
561
569
|
- spec/support/matchers/have_colorized_text.rb
|
570
|
+
- spec/support/mocks/appsignal_mock.rb
|
562
571
|
- spec/support/mocks/fake_gc_profiler.rb
|
572
|
+
- spec/support/mocks/fake_gvl_tools.rb
|
563
573
|
- spec/support/mocks/mock_probe.rb
|
564
574
|
- spec/support/rails/my_app.rb
|
565
575
|
- spec/support/shared_examples/instrument.rb
|