rorvswild 1.5.17 → 1.6.0

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: 6ce241e0d917e560c8a5683bdc210dbd4f5158cd7bf49444ced9548d85b61e5e
4
- data.tar.gz: b354848c0048368c615e4c2dd5231864a164c127af0aaf590fbfcd5c2a1cb36c
3
+ metadata.gz: b40a18c6bc14739968aabfda67d1ce3b68fbd582ef16b66bc35e636ab1cc4137
4
+ data.tar.gz: d90c55f88561d249a723de427ce522e27133cbf2fed8c68639e029b0a7f2a6f1
5
5
  SHA512:
6
- metadata.gz: fc3e48e9328b450bfb3cb7e7e4536e249470bcf7cb1fd2b3c7f67416daa66e1c281e742446a97f868276ac3028a573a84247b80b7f3053fbaeb9f9dfe4209c57
7
- data.tar.gz: eab70d88fd705bdd5d679b625a9b6e06b6612cff6eaa6dc5080d6cd80a38f6f28e1a198f475b683cecdb25be7ac98d54a67eecfb8ee8cea230d987248e846823
6
+ metadata.gz: 5ecb2843e5cf8d0556a4b412011d5facb3fdc9a936ab19836758acf3d0fb7de90ccccdad7cb4f599fc3fe9f1bbb39d112b3674a43aec1d1313d5264a643ea58a
7
+ data.tar.gz: e4bcb64980a094b6a4743c24d35452fc86fe53f347286272129103a321ac34e15e4ebd3fbb6d7fba24f7a77cc7b920b6b9ce626328baf91a671cb9e3382b09e4
@@ -34,12 +34,12 @@ module RorVsWild
34
34
  RorVsWild.logger.debug("Start RorVsWild #{RorVsWild::VERSION}")
35
35
  setup_plugins
36
36
  cleanup_data
37
+ send_deployment
37
38
  end
38
39
 
39
40
  def load_features
40
41
  features = config[:features] || []
41
- features.include?("server_metrics")
42
- require "rorvswild/metrics" if features.include?("server_metrics")
42
+ RorVsWild.logger.info("Server metrics are now monitored enabled by default") if features.include?("server_metrics")
43
43
  end
44
44
 
45
45
  def setup_plugins
@@ -85,7 +85,7 @@ module RorVsWild
85
85
  raise
86
86
  ensure
87
87
  current_data[:runtime] = RorVsWild.clock_milliseconds - current_data[:started_at]
88
- post_job
88
+ queue_job
89
89
  end
90
90
  end
91
91
 
@@ -96,7 +96,7 @@ module RorVsWild
96
96
  def stop_request
97
97
  return unless current_data
98
98
  current_data[:runtime] = RorVsWild.clock_milliseconds - current_data[:started_at]
99
- post_request
99
+ queue_request
100
100
  end
101
101
 
102
102
  def catch_error(extra_details = nil, &block)
@@ -109,7 +109,7 @@ module RorVsWild
109
109
  end
110
110
 
111
111
  def record_error(exception, extra_details = nil)
112
- post_error(exception_to_hash(exception, extra_details))
112
+ send_error(exception_to_hash(exception, extra_details))
113
113
  end
114
114
 
115
115
  def push_exception(exception, options = nil)
@@ -153,21 +153,8 @@ module RorVsWild
153
153
  config[:ignore_jobs].include?(name)
154
154
  end
155
155
 
156
- def os_description
157
- @os_description ||= `uname -sr`
158
- rescue Exception => ex
159
- @os_description = RbConfig::CONFIG["host_os"]
160
- end
161
-
162
- def hostname
163
- if gae_instance = ENV["GAE_INSTANCE"] || ENV["CLOUD_RUN_EXECUTION"]
164
- gae_instance
165
- elsif dyno = ENV["DYNO"] # Heroku
166
- dyno.start_with?("run.") ? "run.*" :
167
- dyno.start_with?("release.") ? "release.*" : dyno
168
- else
169
- Socket.gethostname
170
- end
156
+ def send_deployment
157
+ client.post("/deployments", deployment: Deployment.to_h)
171
158
  end
172
159
 
173
160
  #######################
@@ -177,7 +164,12 @@ module RorVsWild
177
164
  private
178
165
 
179
166
  def initialize_data
180
- Thread.current[:rorvswild_data] = {sections: [], section_stack: [], started_at: RorVsWild.clock_milliseconds}
167
+ Thread.current[:rorvswild_data] = {
168
+ sections: [],
169
+ section_stack: [],
170
+ environment: Host.to_h,
171
+ started_at: RorVsWild.clock_milliseconds,
172
+ }
181
173
  end
182
174
 
183
175
  def cleanup_data
@@ -186,15 +178,15 @@ module RorVsWild
186
178
  result
187
179
  end
188
180
 
189
- def post_request
181
+ def queue_request
190
182
  (data = cleanup_data) && data[:name] && queue.push_request(data)
191
183
  end
192
184
 
193
- def post_job
185
+ def queue_job
194
186
  queue.push_job(cleanup_data)
195
187
  end
196
188
 
197
- def post_error(hash)
189
+ def send_error(hash)
198
190
  client.post_async("/errors".freeze, error: hash)
199
191
  end
200
192
 
@@ -208,15 +200,7 @@ module RorVsWild
208
200
  backtrace: exception.backtrace || ["No backtrace"],
209
201
  exception: exception.class.to_s,
210
202
  extra_details: context,
211
- environment: {
212
- os: os_description,
213
- user: Etc.getlogin,
214
- host: Socket.gethostname,
215
- ruby: RUBY_DESCRIPTION,
216
- pid: Process.pid,
217
- cwd: Dir.pwd,
218
- lib_paths: locator.lib_paths,
219
- },
203
+ environment: Host.to_h,
220
204
  }
221
205
  end
222
206
 
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RorVsWild
4
+ module Deployment
5
+ def self.revision
6
+ read_once && @revision
7
+ end
8
+
9
+ def self.description
10
+ read_once && @description
11
+ end
12
+
13
+ def self.author
14
+ read_once && @author
15
+ end
16
+
17
+ def self.email
18
+ read_once && @email
19
+ end
20
+
21
+ def self.ruby
22
+ RUBY_VERSION
23
+ end
24
+
25
+ def self.rails
26
+ Rails.version if defined?(Rails)
27
+ end
28
+
29
+ def self.rorvswild
30
+ RorVsWild::VERSION
31
+ end
32
+
33
+ def self.to_h
34
+ @to_h ||= {revision: revision, description: description, author: author, email: email, ruby: ruby, rails: rails, rorvswild: rorvswild}.compact
35
+ end
36
+
37
+ def self.read
38
+ read_from_heroku || read_from_scalingo || read_from_git || read_from_capistrano
39
+ end
40
+
41
+ def self.read_once
42
+ @already_read || read
43
+ @already_read = true
44
+ end
45
+
46
+ private
47
+
48
+ def self.read_from_heroku
49
+ return unless ENV["HEROKU_SLUG_COMMIT"]
50
+ @revision = ENV["HEROKU_SLUG_COMMIT"]
51
+ @description = ENV["HEROKU_SLUG_DESCRIPTION"]
52
+ end
53
+
54
+ def self.read_from_scalingo
55
+ return unless ENV["SOURCE_VERSION"]
56
+ @revision = ENV["SOURCE_VERSION"]
57
+ end
58
+
59
+ def self.read_from_git
60
+ @revision = normalize_string(`git rev-parse HEAD`) rescue nil
61
+ return unless @revision
62
+ lines = `git log -1 --pretty=%an%n%ae%n%B`.lines rescue nil
63
+ return unless lines
64
+ @author = normalize_string(lines[0])
65
+ @email = normalize_string(lines[1])
66
+ @description = lines[2..-1] && normalize_string(lines[2..-1].join)
67
+ @revision
68
+ end
69
+
70
+ def self.read_from_capistrano
71
+ return unless File.readable?("REVISION")
72
+ return unless @revision = File.read("REVISION")
73
+ lines = `git --git-dir ../../repo log --format=%an%n%ae%n%B -n 1 #{@revision}`.lines rescue nil
74
+ return unless lines
75
+ @author = normalize_string(lines[0])
76
+ @email = normalize_string(lines[1])
77
+ @description = lines[2..-1] && normalize_string(lines[2..-1].join)
78
+ @revision
79
+ end
80
+
81
+ def self.normalize_string(string)
82
+ if string
83
+ string = string.strip
84
+ string.empty? ? nil : string
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RorVsWild
4
+ module Host
5
+ def self.os
6
+ @os_description ||= `uname -sr`.strip
7
+ rescue Exception => ex
8
+ @os_description = RbConfig::CONFIG["host_os"]
9
+ end
10
+
11
+ def self.user
12
+ Etc.getlogin
13
+ end
14
+
15
+ def self.ruby
16
+ RUBY_DESCRIPTION
17
+ end
18
+
19
+ def self.rails
20
+ Rails.version if defined?(Rails)
21
+ end
22
+
23
+ def self.name
24
+ if gae_instance = ENV["GAE_INSTANCE"] || ENV["CLOUD_RUN_EXECUTION"]
25
+ gae_instance
26
+ elsif dyno = ENV["DYNO"] # Heroku
27
+ dyno.start_with?("run.") ? "run.*" :
28
+ dyno.start_with?("release.") ? "release.*" : dyno
29
+ else
30
+ Socket.gethostname
31
+ end
32
+ end
33
+
34
+ def self.pid
35
+ Process.pid
36
+ end
37
+
38
+ def self.cwd
39
+ Dir.pwd
40
+ end
41
+
42
+ def self.revision
43
+ Deployment.revision
44
+ end
45
+
46
+ def self.revision_description
47
+ Deployment.description
48
+ end
49
+
50
+ def self.to_h
51
+ @to_h ||= {os: os, user: user, host: name, ruby: ruby, rails: rails, pid: pid, cwd: cwd, revision: revision}.compact
52
+ end
53
+ end
54
+ end
@@ -77,9 +77,9 @@ RorVsWild.Local.prototype.goToHistory = function(event) {
77
77
  this.render()
78
78
  }
79
79
 
80
- RorVsWild.Local.prototype.containerStyle = function() {
80
+ RorVsWild.Local.prototype.containerClass = function() {
81
81
  if (!this.active)
82
- return 'display: none !important;'
82
+ return "is-hidden"
83
83
  }
84
84
 
85
85
  RorVsWild.Local.kindToLanguage = function(kind) {
@@ -4,7 +4,7 @@
4
4
  </div>
5
5
 
6
6
  <script type="x-tmpl-mustache" data-partial="RorVsWild.Local">
7
- <div id="rorvswild-local-requests" class="rorvswild-local-panel" style="{{containerStyle}}">
7
+ <div id="rorvswild-local-requests" class="rorvswild-local-panel {{containerClass}}">
8
8
 
9
9
  <div class="rorvswild-local-panel__header">
10
10
  <a href="https://www.rorvswild.com" class="rorvswild-local-panel__logo">
@@ -76,6 +76,10 @@
76
76
  flex-direction: column !important;
77
77
  }
78
78
 
79
+ .rorvswild-local-panel.is-hidden {
80
+ display: none !important;
81
+ }
82
+
79
83
  .rorvswild-local-panel * {
80
84
  font-family: inherit !important;
81
85
  font-size: inherit !important;
@@ -1,30 +1,61 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RorVsWild
2
4
  class Metrics
3
5
  class Cpu
4
6
  attr_reader :user, :system, :idle, :waiting, :stolen
5
7
  attr_reader :load_average, :count
6
8
 
9
+ def initialize
10
+ @old_stat = Stat.read
11
+ end
12
+
7
13
  def update
8
- if vmstat = execute(:vmstat)
9
- vmstat = vmstat.split("\n").last.split
10
- @user = vmstat[12].to_i
11
- @system = vmstat[13].to_i
12
- @idle = vmstat[14].to_i
13
- @waiting = vmstat[15].to_i
14
- @stolen = vmstat[16].to_i
14
+ if @old_stat && (new_stat = Stat.read)
15
+ if (total = new_stat.total - @old_stat.total) > 0
16
+ @user = (new_stat.user - @old_stat.user) * 100 / total
17
+ @system = (new_stat.system - @old_stat.system) * 100 / total
18
+ @idle = (new_stat.idle - @old_stat.idle) * 100 / total
19
+ @waiting = (new_stat.iowait - @old_stat.iowait) * 100 / total
20
+ @stolen = (new_stat.steal - @old_stat.steal) * 100 / total
21
+ @old_stat = new_stat
22
+ end
15
23
  end
16
- if uptime = execute(:uptime)
17
- @load_average = uptime.split[-3].to_f
24
+ @load_average = File.read("/proc/loadavg").to_f if File.readable?("/proc/loadavg")
25
+ @count = `nproc`.to_i rescue nil
26
+ end
27
+
28
+ class Stat
29
+ attr_reader :user, :nice, :system, :idle, :iowait, :irq, :softirq, :steal, :guest, :guest_nice, :total
30
+
31
+ def initialize(user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice)
32
+ @user = user
33
+ @nice = nice
34
+ @system = system
35
+ @idle = idle
36
+ @iowait = iowait
37
+ @irq = irq
38
+ @softirq = softirq
39
+ @steal = steal
40
+ @guest = guest
41
+ @guest_nice = guest_nice
42
+ @total = user + nice + system + idle + iowait + irq + softirq + steal + guest + guest_nice
18
43
  end
19
- if nproc = execute(:nproc)
20
- @count = nproc.to_i
44
+
45
+ def self.parse(string)
46
+ for row in string.lines
47
+ if row.start_with?("cpu ")
48
+ array = row.split[1..-1].map(&:to_i)[0,10]
49
+ array.fill(0, array.size, 10 - array.size) if array.size < 10
50
+ return new(*array)
51
+ end
52
+ end
53
+ nil
21
54
  end
22
- end
23
55
 
24
- def execute(command)
25
- `#{command}`
26
- rescue => ex
27
- nil
56
+ def self.read
57
+ parse(File.read("/proc/stat")) if File.readable?("/proc/stat")
58
+ end
28
59
  end
29
60
  end
30
61
  end
@@ -23,7 +23,7 @@ module RorVsWild
23
23
  SWAP_FREE = "SwapFree" # Amount of swap space that is currently unused.
24
24
 
25
25
  def update
26
- info = read_meminfo
26
+ return unless info = read_meminfo
27
27
  @ram_total = convert_to_bytes(info[MEM_TOTAL])
28
28
  @ram_free = convert_to_bytes(info[MEM_FREE])
29
29
  @ram_available = convert_to_bytes(info[MEM_AVAILABLE])
@@ -1,7 +1,5 @@
1
1
  module RorVsWild
2
2
  class Metrics
3
- UPDATE_INTERVAL_MS = 60_000 # One metric every minute
4
-
5
3
  attr_reader :cpu, :memory, :storage, :updated_at
6
4
 
7
5
  def initialize
@@ -11,22 +9,23 @@ module RorVsWild
11
9
  end
12
10
 
13
11
  def update
14
- if staled?
15
- cpu.update
16
- memory.update
17
- storage.update
18
- @updated_at = RorVsWild.clock_milliseconds
19
- end
12
+ cpu.update
13
+ memory.update
14
+ storage.update
20
15
  end
21
16
 
22
- def staled?
23
- !updated_at || RorVsWild.clock_milliseconds - updated_at > UPDATE_INTERVAL_MS
17
+ def update_every_minute
18
+ return unless Host.os.include?("Linux")
19
+ if !@updated_at || @updated_at.min != Time.now.min
20
+ @updated_at = Time.now
21
+ update
22
+ end
24
23
  end
25
24
 
26
25
  def to_h
27
26
  {
28
- hostname: RorVsWild.agent.hostname,
29
- os: RorVsWild.agent.os_description,
27
+ hostname: Host.name,
28
+ os: Host.os,
30
29
  cpu_user: cpu.user,
31
30
  cpu_system: cpu.system,
32
31
  cpu_idle: cpu.idle,
@@ -19,7 +19,7 @@ module RorVsWild
19
19
  end
20
20
 
21
21
  def request_with_rorvswild(req, body = nil, &block)
22
- return request_without_rorvswild(req, body, &block) if request_called_twice?
22
+ return request_without_rorvswild(req, body, &block) if !RorVsWild.agent || request_called_twice?
23
23
  RorVsWild.agent.measure_section("#{req.method} #{address}", kind: HTTP) do
24
24
  request_without_rorvswild(req, body, &block)
25
25
  end
@@ -1,6 +1,6 @@
1
1
  module RorVsWild
2
2
  class Queue
3
- SLEEP_TIME = 30
3
+ SLEEP_TIME = 10
4
4
  FLUSH_TRESHOLD = 10
5
5
 
6
6
  attr_reader :mutex, :thread, :client
@@ -52,7 +52,7 @@ module RorVsWild
52
52
  end
53
53
 
54
54
  def pull_server_metrics
55
- @metrics && @metrics.update && @metrics.to_h
55
+ @metrics && @metrics.update_every_minute && @metrics.to_h
56
56
  end
57
57
 
58
58
  def flush_indefinetely
@@ -1,3 +1,3 @@
1
1
  module RorVsWild
2
- VERSION = "1.5.17".freeze
2
+ VERSION = "1.6.0".freeze
3
3
  end
data/lib/rorvswild.rb CHANGED
@@ -1,4 +1,7 @@
1
1
  require "rorvswild/version"
2
+ require "rorvswild/host"
3
+ require "rorvswild/metrics"
4
+ require "rorvswild/deployment"
2
5
  require "rorvswild/locator"
3
6
  require "rorvswild/section"
4
7
  require "rorvswild/client"
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rorvswild
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.17
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexis Bernard
8
8
  - Antoine Marguerie
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-10-25 00:00:00.000000000 Z
12
+ date: 2023-01-27 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Performances and errors insights for rails developers.
15
15
  email:
@@ -27,6 +27,8 @@ files:
27
27
  - lib/rorvswild.rb
28
28
  - lib/rorvswild/agent.rb
29
29
  - lib/rorvswild/client.rb
30
+ - lib/rorvswild/deployment.rb
31
+ - lib/rorvswild/host.rb
30
32
  - lib/rorvswild/installer.rb
31
33
  - lib/rorvswild/local.rb
32
34
  - lib/rorvswild/local/javascript/application.js
@@ -69,7 +71,7 @@ licenses:
69
71
  metadata:
70
72
  source_code_uri: https://github.com/BaseSecrete/rorvswild
71
73
  changelog_uri: https://github.com/BaseSecrete/rorvswild/blob/master/CHANGELOG.md
72
- post_install_message:
74
+ post_install_message:
73
75
  rdoc_options: []
74
76
  require_paths:
75
77
  - lib
@@ -85,7 +87,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
85
87
  version: '0'
86
88
  requirements: []
87
89
  rubygems_version: 3.2.22
88
- signing_key:
90
+ signing_key:
89
91
  specification_version: 4
90
92
  summary: Ruby on Rails applications monitoring
91
93
  test_files: []