rorvswild 1.6.0 → 1.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b40a18c6bc14739968aabfda67d1ce3b68fbd582ef16b66bc35e636ab1cc4137
4
- data.tar.gz: d90c55f88561d249a723de427ce522e27133cbf2fed8c68639e029b0a7f2a6f1
3
+ metadata.gz: 34fc75a952dcdd5b7291e2227f2f59da531413338f0fb91ea64a61245b9368af
4
+ data.tar.gz: daab97444a9876ef871ca0c2832afd667cfb986fc1e101c36c97f3880f700b1a
5
5
  SHA512:
6
- metadata.gz: 5ecb2843e5cf8d0556a4b412011d5facb3fdc9a936ab19836758acf3d0fb7de90ccccdad7cb4f599fc3fe9f1bbb39d112b3674a43aec1d1313d5264a643ea58a
7
- data.tar.gz: e4bcb64980a094b6a4743c24d35452fc86fe53f347286272129103a321ac34e15e4ebd3fbb6d7fba24f7a77cc7b920b6b9ce626328baf91a671cb9e3382b09e4
6
+ metadata.gz: 3986c7c35162a29f6f4173fa4ce6728fea1eac8d2c4293fc275f850b885fb0eb472c4a3be85a473761295322aa10c490f2ad1e4ae198b4528075033eb8c977db
7
+ data.tar.gz: 94ecd7c5f04ecbf7608f5fd37467ebfa5d49e8f6f5e50d2be4822d4cb695c65e15daa325c8843a2f04b6c841803040dfdb020e055bb961f6122101119e1e04df
data/README.md CHANGED
@@ -155,12 +155,15 @@ From the configuration file, you can tell RorVsWild to skip monitoring some requ
155
155
  production:
156
156
  api_key: API_KEY
157
157
  ignore_requests:
158
- - SecretController#index
158
+ - HeartbeatController#show
159
+ - !ruby/regexp /SecretController/ # Ignore the entire controller
159
160
  ignore_jobs:
160
161
  - SecretJob
162
+ - !ruby/regexp /Secret::/ # Ignore the entire Secret namespace
161
163
  ignore_exceptions:
162
164
  - ActionController::RoutingError # Ignore by default any 404
163
165
  - ZeroDivisionError
166
+ - !ruby/regexp /Secret::/ # Ignore all secret errors
164
167
  ignore_plugins:
165
168
  - Sidekiq # If you don't want to monitor your Sidekiq jobs
166
169
  ```
@@ -171,9 +174,9 @@ Here is the equivalent if you prefer initialising RorVsWild manually.
171
174
  # config/initializers/rorvswild.rb
172
175
  RorVsWild.start(
173
176
  api_key: "API_KEY",
174
- ignore_requests: ["SecretController#index"],
175
- ignore_jobs: ["SecretJob"],
176
- ignore_exceptions: ["ActionController::RoutingError", "ZeroDivisionError"],
177
+ ignore_requests: ["ApplicationController#heartbeat", /SecretController/],
178
+ ignore_jobs: ["SecretJob", /Secret::/],
179
+ ignore_exceptions: ["ActionController::RoutingError", "ZeroDivisionError", /Secret::/],
177
180
  ignore_plugins: ["Sidekiq"])
178
181
  ```
179
182
 
@@ -218,30 +221,71 @@ In the case you want a custom logger such as Syslog, you can only do it by initi
218
221
  RorVsWild.start(api_key: "API_KEY", logger: Logger::Syslog.new)
219
222
  ```
220
223
 
221
- #### Server metrics monitoring
224
+ ### Deployment tracking
222
225
 
223
- We are adding server metrics as a beta feature.
224
- It monitors load average, CPU, memory, swap and disk space.
225
- For now, only Linux is supported.
226
- It has to be explicitly enabled with a feature flag :
226
+ Since version 1.6.0, RorVsWild compares performances between each deployment.
227
+ That is convenient to detect quickly a performance deterioration.
228
+
229
+ It is working without any actions from your part if the application is :
230
+
231
+ - Deployed via Capistrano
232
+ - Inside a Git repositoriy
233
+ - Hosted on Heroku if [Dyno metadata](https://devcenter.heroku.com/articles/dyno-metadata) is enabled
234
+ - Hosted on Scalingo
235
+
236
+ Because we are not aware of all cloud hosting providers, there is a generic method to provide these data via the configuration :
227
237
 
228
238
  ```yaml
229
239
  # config/rorvswild.yml
230
240
  production:
231
241
  api_key: API_KEY
232
- features:
233
- - server_metrics
242
+ deployment:
243
+ revision: <%= "Anything that will return the deployment version" %> # Mandatory
244
+ description: <%= "Eventually if you have a description such as a Git message" %>
245
+ author: <%= "Author's name of the deployment" %>
246
+ email: <%= "emailOf@theAuthor.com" %>
234
247
  ```
235
248
 
236
249
  Here is the equivalent if you prefer initialising RorVsWild manually :
237
250
 
238
251
  ```ruby
239
252
  # config/initializers/rorvswild.rb
240
- RorVsWild.start(api_key: "API_KEY", features: ["server_metrics"])
253
+ RorVsWild.start(api_key: "API_KEY", deployment: {
254
+ revision: "Unique version number such as Git commit ID",
255
+ description: "Message such as in Git",
256
+ author: "Deployer's name",
257
+ email: "Deployer's email"
258
+ })
241
259
  ```
242
260
 
261
+ Only the revision is mandatory, but it's better if you are able to provide more information.
262
+
263
+
264
+ #### Server metrics monitoring
265
+
266
+ Since version 1.6.0 RorVsWild monitors server metrics such as load average, CPU, memory, swap and disk space.
267
+ For now, only Linux is supported.
243
268
  The data are available in a server tab beside requests and jobs.
244
269
 
270
+ Metrics are grouped by hostnames.
271
+ Cloud providers give random hostnames which change on every deployment.
272
+ You can manually define them:
273
+
274
+ ```yaml
275
+ # config/rorvswild.yml
276
+ production:
277
+ api_key: API_KEY
278
+ server:
279
+ name: <%= "Some code that return a relevant hostname" %>
280
+ ```
281
+
282
+ Here is the equivalent if you prefer initialising RorVsWild manually :
283
+
284
+ ```ruby
285
+ # config/initializers/rorvswild.rb
286
+ RorVsWild.start(api_key: "API_KEY", server: {name: "host.name"})
287
+ ```
288
+
245
289
  ## Contributing
246
290
 
247
291
  1. Fork it ( https://github.com/[my-github-username]/rorvswild/fork )
@@ -30,6 +30,8 @@ module RorVsWild
30
30
  @client = Client.new(@config)
31
31
  @queue = config[:queue] || Queue.new(client)
32
32
  @locator = RorVsWild::Locator.new
33
+ Host.load_config(config)
34
+ Deployment.load_config(config)
33
35
 
34
36
  RorVsWild.logger.debug("Start RorVsWild #{RorVsWild::VERSION}")
35
37
  setup_plugins
@@ -99,17 +101,17 @@ module RorVsWild
99
101
  queue_request
100
102
  end
101
103
 
102
- def catch_error(extra_details = nil, &block)
104
+ def catch_error(context = nil, &block)
103
105
  begin
104
106
  block.call
105
107
  rescue Exception => ex
106
- record_error(ex, extra_details) if !ignored_exception?(ex)
108
+ record_error(ex, context)
107
109
  ex
108
110
  end
109
111
  end
110
112
 
111
- def record_error(exception, extra_details = nil)
112
- send_error(exception_to_hash(exception, extra_details))
113
+ def record_error(exception, context = nil)
114
+ send_error(exception_to_hash(exception, context)) if !ignored_exception?(exception)
113
115
  end
114
116
 
115
117
  def push_exception(exception, options = nil)
@@ -146,11 +148,16 @@ module RorVsWild
146
148
  end
147
149
 
148
150
  def ignored_request?(name)
149
- (config[:ignore_actions] || config[:ignore_requests]).include?(name)
151
+ config[:ignore_requests].any? { |str_or_regex| str_or_regex === name }
150
152
  end
151
153
 
152
154
  def ignored_job?(name)
153
- config[:ignore_jobs].include?(name)
155
+ config[:ignore_jobs].any? { |str_or_regex| str_or_regex === name }
156
+ end
157
+
158
+ def ignored_exception?(exception)
159
+ return false unless config[:ignore_exceptions]
160
+ config[:ignore_exceptions].any? { |str_or_regex| str_or_regex === exception.class.to_s }
154
161
  end
155
162
 
156
163
  def send_deployment
@@ -199,13 +206,9 @@ module RorVsWild
199
206
  message: exception.message,
200
207
  backtrace: exception.backtrace || ["No backtrace"],
201
208
  exception: exception.class.to_s,
202
- extra_details: context,
209
+ context: context,
203
210
  environment: Host.to_h,
204
211
  }
205
212
  end
206
-
207
- def ignored_exception?(exception)
208
- (config[:ignored_exceptions] || config[:ignore_exceptions]).include?(exception.class.to_s)
209
- end
210
213
  end
211
214
  end
@@ -2,20 +2,30 @@
2
2
 
3
3
  module RorVsWild
4
4
  module Deployment
5
+ def self.load_config(config)
6
+ read
7
+ if hash = config[:deployment]
8
+ @description = hash[:description]
9
+ @revision = hash[:revision]
10
+ @author = hash[:author]
11
+ @email = hash[:email]
12
+ end
13
+ end
14
+
5
15
  def self.revision
6
- read_once && @revision
16
+ @revision
7
17
  end
8
18
 
9
19
  def self.description
10
- read_once && @description
20
+ @description
11
21
  end
12
22
 
13
23
  def self.author
14
- read_once && @author
24
+ @author
15
25
  end
16
26
 
17
27
  def self.email
18
- read_once && @email
28
+ @email
19
29
  end
20
30
 
21
31
  def self.ruby
@@ -38,11 +48,6 @@ module RorVsWild
38
48
  read_from_heroku || read_from_scalingo || read_from_git || read_from_capistrano
39
49
  end
40
50
 
41
- def self.read_once
42
- @already_read || read
43
- @already_read = true
44
- end
45
-
46
51
  private
47
52
 
48
53
  def self.read_from_heroku
@@ -2,6 +2,10 @@
2
2
 
3
3
  module RorVsWild
4
4
  module Host
5
+ def self.load_config(config)
6
+ @name = config.dig(:server, :name)
7
+ end
8
+
5
9
  def self.os
6
10
  @os_description ||= `uname -sr`.strip
7
11
  rescue Exception => ex
@@ -21,7 +25,7 @@ module RorVsWild
21
25
  end
22
26
 
23
27
  def self.name
24
- if gae_instance = ENV["GAE_INSTANCE"] || ENV["CLOUD_RUN_EXECUTION"]
28
+ @name ||= if gae_instance = ENV["GAE_INSTANCE"] || ENV["CLOUD_RUN_EXECUTION"]
25
29
  gae_instance
26
30
  elsif dyno = ENV["DYNO"] # Heroku
27
31
  dyno.start_with?("run.") ? "run.*" :
@@ -4,7 +4,7 @@ module RorVsWild
4
4
 
5
5
  def self.create_rails_config(api_key)
6
6
  if File.directory?("config")
7
- if !File.exists?(PATH)
7
+ if !File.exist?(PATH)
8
8
  File.write(PATH, template(api_key))
9
9
  puts "File #{PATH} has been created. Restart / deploy your app to start collecting data."
10
10
  else
@@ -19,26 +19,34 @@ module RorVsWild
19
19
  <<YAML
20
20
  production:
21
21
  api_key: #{api_key}
22
- # ignore_requests: # Do not monitor the following actions
23
- # - SecretController#index
24
- # ignore_jobs: # Do not monitor the following jobs
25
- # - SecretJob
26
- # ignore_exceptions: # Do not record the following exceptions
27
- # - ActionController::RoutingError # By default to ignore 404
28
- # ignore_plugins:
29
- # - ActionController
30
- # - ActionMailer
31
- # - ActionView
32
- # - ActiveJob
33
- # - ActiveRecord
34
- # - DelayedJob
35
- # - Elasticsearch
36
- # - Mongo
37
- # - NetHttp
38
- # - Redis
39
- # - Resque
40
- # - Sidekiq
41
- # logger: log/rorvswild.log # By default it uses Rails.logger or Logger.new(STDOUT)
22
+ # ignore_requests: # Do not monitor the following actions
23
+ # - SecretController#index
24
+ # ignore_jobs: # Do not monitor the following jobs
25
+ # - SecretJob
26
+ # ignore_exceptions: # Do not record the following exceptions
27
+ # - ActionController::RoutingError # By default to ignore 404
28
+ # ignore_plugins:
29
+ # - ActionController
30
+ # - ActionMailer
31
+ # - ActionView
32
+ # - ActiveJob
33
+ # - ActiveRecord
34
+ # - DelayedJob
35
+ # - Elasticsearch
36
+ # - Mongo
37
+ # - NetHttp
38
+ # - Redis
39
+ # - Resque
40
+ # - Sidekiq
41
+ # logger: log/rorvswild.log # By default it uses Rails.logger or Logger.new(STDOUT)
42
+ # # Deployment tracking is working without any actions from your part if the Rails app
43
+ # # is inside a Git repositoriy, is deployed via Capistrano.
44
+ # # In the other cases, you can provide the following details.
45
+ # deployment:
46
+ # revision: <%= "Anything that will return the deployment version" %> # Mandatory
47
+ # description: <%= "Eventually if you have a description such as a Git message" %>
48
+ # author: <%= "Author's name of the deployment" %>
49
+ # email: <%= "emailOf@theAuthor.com" %>
42
50
  YAML
43
51
  end
44
52
  end
@@ -20,8 +20,9 @@ module RorVsWild
20
20
 
21
21
  def self.load_config
22
22
  if (path = Rails.root.join("config/rorvswild.yml")).exist?
23
- hash = YAML.load(ERB.new(path.read).result)[Rails.env]
24
- hash && hash.deep_symbolize_keys
23
+ yaml = ERB.new(path.read).result
24
+ hash = YAML.safe_load(yaml, permitted_classes: [Regexp])
25
+ hash[Rails.env] && hash[Rails.env].deep_symbolize_keys
25
26
  end
26
27
  end
27
28
  end
@@ -1,3 +1,3 @@
1
1
  module RorVsWild
2
- VERSION = "1.6.0".freeze
2
+ VERSION = "1.6.2".freeze
3
3
  end
data/lib/rorvswild.rb CHANGED
@@ -38,12 +38,12 @@ module RorVsWild
38
38
  agent ? agent.measure_block(name , &block) : block.call
39
39
  end
40
40
 
41
- def self.catch_error(extra_details = nil, &block)
42
- agent ? agent.catch_error(extra_details, &block) : block.call
41
+ def self.catch_error(context = nil, &block)
42
+ agent ? agent.catch_error(context, &block) : block.call
43
43
  end
44
44
 
45
- def self.record_error(exception, extra_details = nil)
46
- agent.record_error(exception, extra_details) if agent
45
+ def self.record_error(exception, context = nil)
46
+ agent.record_error(exception, context) if agent
47
47
  end
48
48
 
49
49
  def self.merge_error_context(hash)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rorvswild
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.0
4
+ version: 1.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexis Bernard
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-01-27 00:00:00.000000000 Z
12
+ date: 2023-02-23 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Performances and errors insights for rails developers.
15
15
  email: