rorvswild 1.5.17 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/rorvswild/agent.rb +17 -33
- data/lib/rorvswild/deployment.rb +88 -0
- data/lib/rorvswild/host.rb +54 -0
- data/lib/rorvswild/local/javascript/local.js +2 -2
- data/lib/rorvswild/local/local.html.erb +1 -1
- data/lib/rorvswild/local/stylesheet/local.css +4 -0
- data/lib/rorvswild/metrics/cpu.rb +47 -16
- data/lib/rorvswild/metrics/memory.rb +1 -1
- data/lib/rorvswild/metrics.rb +11 -12
- data/lib/rorvswild/plugin/net_http.rb +1 -1
- data/lib/rorvswild/queue.rb +2 -2
- data/lib/rorvswild/version.rb +1 -1
- data/lib/rorvswild.rb +3 -0
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b40a18c6bc14739968aabfda67d1ce3b68fbd582ef16b66bc35e636ab1cc4137
|
4
|
+
data.tar.gz: d90c55f88561d249a723de427ce522e27133cbf2fed8c68639e029b0a7f2a6f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5ecb2843e5cf8d0556a4b412011d5facb3fdc9a936ab19836758acf3d0fb7de90ccccdad7cb4f599fc3fe9f1bbb39d112b3674a43aec1d1313d5264a643ea58a
|
7
|
+
data.tar.gz: e4bcb64980a094b6a4743c24d35452fc86fe53f347286272129103a321ac34e15e4ebd3fbb6d7fba24f7a77cc7b920b6b9ce626328baf91a671cb9e3382b09e4
|
data/lib/rorvswild/agent.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
157
|
-
|
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] = {
|
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
|
181
|
+
def queue_request
|
190
182
|
(data = cleanup_data) && data[:name] && queue.push_request(data)
|
191
183
|
end
|
192
184
|
|
193
|
-
def
|
185
|
+
def queue_job
|
194
186
|
queue.push_job(cleanup_data)
|
195
187
|
end
|
196
188
|
|
197
|
-
def
|
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.
|
80
|
+
RorVsWild.Local.prototype.containerClass = function() {
|
81
81
|
if (!this.active)
|
82
|
-
return
|
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
|
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">
|
@@ -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
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
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
|
-
|
17
|
-
|
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
|
-
|
20
|
-
|
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
|
-
|
25
|
-
|
26
|
-
|
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])
|
data/lib/rorvswild/metrics.rb
CHANGED
@@ -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
|
-
|
15
|
-
|
16
|
-
|
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
|
23
|
-
|
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:
|
29
|
-
os:
|
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
|
data/lib/rorvswild/queue.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module RorVsWild
|
2
2
|
class Queue
|
3
|
-
SLEEP_TIME =
|
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.
|
55
|
+
@metrics && @metrics.update_every_minute && @metrics.to_h
|
56
56
|
end
|
57
57
|
|
58
58
|
def flush_indefinetely
|
data/lib/rorvswild/version.rb
CHANGED
data/lib/rorvswild.rb
CHANGED
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.
|
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:
|
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: []
|