rorvswild 0.5.1 → 0.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 +4 -4
- data/lib/rorvswild/client.rb +23 -5
- data/lib/rorvswild/plugin/mongo.rb +37 -0
- data/lib/rorvswild/plugin/net_http.rb +22 -0
- data/lib/rorvswild/plugin/redis.rb +24 -0
- data/lib/rorvswild/version.rb +1 -1
- data/lib/rorvswild.rb +3 -0
- data/test/helper.rb +7 -0
- data/test/plugin/mongo_test.rb +35 -0
- data/test/plugin/net_http_test.rb +41 -0
- data/test/plugin/redis_test.rb +42 -0
- data/test/ror_vs_wild_test.rb +6 -13
- data/test/run.rb +3 -0
- metadata +15 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 802001256223c866089c33029d0e0b5b4a396bb0
|
4
|
+
data.tar.gz: 501c456458c29d982882775b6d106456a1f23483
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d49be58f9ec73146b3fd62c437c863cbccca35187ccb0668e2ed072fdd0dea733fe1b09cca4a8d2ae77105132fd8483ba94efcb4e2787ed9de00ca506a811237
|
7
|
+
data.tar.gz: 4c1afafbc9312d1e4589f0fc20d478e968267cab12534398a03be2cf74b73c83c676479e3918325ae6ba58c7870eebe97200aed69eee2c5adeabf140dcea44a3
|
data/lib/rorvswild/client.rb
CHANGED
@@ -58,8 +58,11 @@ module RorVsWild
|
|
58
58
|
ActionController::Base.rescue_from(StandardError) { |exception| client.after_exception(exception, self) }
|
59
59
|
end
|
60
60
|
|
61
|
+
Plugin::Redis.setup
|
62
|
+
Plugin::Mongo.setup
|
61
63
|
Plugin::Resque.setup
|
62
64
|
Plugin::Sidekiq.setup
|
65
|
+
Plugin::NetHttp.setup
|
63
66
|
Kernel.at_exit(&method(:at_exit))
|
64
67
|
ActiveJob::Base.around_perform(&method(:around_active_job)) if defined?(ActiveJob::Base)
|
65
68
|
Delayed::Worker.lifecycle.around(:invoke_job, &method(:around_delayed_job)) if defined?(Delayed::Worker)
|
@@ -86,7 +89,7 @@ module RorVsWild
|
|
86
89
|
file, line, method = extract_most_relevant_location(caller)
|
87
90
|
runtime, sql = compute_duration(start, finish), payload[:sql]
|
88
91
|
plan = runtime >= explain_sql_threshold ? explain(payload[:sql], payload[:binds]) : nil
|
89
|
-
push_query(file: file, line: line, method: method,
|
92
|
+
push_query(kind: "sql", file: file, line: line, method: method, command: sql, plan: plan, runtime: runtime)
|
90
93
|
rescue => exception
|
91
94
|
log_error(exception)
|
92
95
|
end
|
@@ -143,6 +146,20 @@ module RorVsWild
|
|
143
146
|
end
|
144
147
|
end
|
145
148
|
|
149
|
+
def measure_query(kind, command, &block)
|
150
|
+
return block.call if @query_started_at # Prevent from recursive queries
|
151
|
+
@query_started_at = Time.now.utc
|
152
|
+
begin
|
153
|
+
result = block.call
|
154
|
+
runtime = (Time.now.utc - @query_started_at) * 1000
|
155
|
+
file, line, method = extract_most_relevant_location(caller)
|
156
|
+
push_query(kind: kind, command: command, file: file, line: line, method: method, runtime: runtime)
|
157
|
+
result
|
158
|
+
ensure
|
159
|
+
@query_started_at = nil
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
146
163
|
def catch_error(extra_details = nil, &block)
|
147
164
|
begin
|
148
165
|
block.call
|
@@ -194,12 +211,13 @@ module RorVsWild
|
|
194
211
|
MEANINGLESS_QUERIES = %w[BEGIN COMMIT].freeze
|
195
212
|
|
196
213
|
def push_query(query)
|
197
|
-
|
198
|
-
queries
|
214
|
+
return if !queries
|
215
|
+
hash = queries.find { |hash| hash[:line] == query[:line] && hash[:file] == query[:file] && hash[:kind] == query[:kind] }
|
216
|
+
queries << hash = {kind: query[:kind], file: query[:file], line: query[:line], runtime: 0, times: 0} if !hash
|
199
217
|
hash[:runtime] += query[:runtime]
|
200
|
-
if !MEANINGLESS_QUERIES.include?(query[:
|
218
|
+
if !MEANINGLESS_QUERIES.include?(query[:command])
|
201
219
|
hash[:times] += 1
|
202
|
-
hash[:
|
220
|
+
hash[:command] ||= query[:command]
|
203
221
|
hash[:plan] ||= query[:plan] if query[:plan]
|
204
222
|
end
|
205
223
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module RorVsWild
|
2
|
+
module Plugin
|
3
|
+
class Mongo
|
4
|
+
def self.setup
|
5
|
+
return if @installed
|
6
|
+
return if !defined?(::Mongo::Monitoring::Global)
|
7
|
+
::Mongo::Monitoring::Global.subscribe(::Mongo::Monitoring::COMMAND, Mongo.new)
|
8
|
+
@installed = true
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :commands
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@commands = {}
|
15
|
+
end
|
16
|
+
|
17
|
+
def started(event)
|
18
|
+
commands[event.request_id] = event.command
|
19
|
+
end
|
20
|
+
|
21
|
+
def failed(event)
|
22
|
+
after_query(event)
|
23
|
+
end
|
24
|
+
|
25
|
+
def succeeded(event)
|
26
|
+
after_query(event)
|
27
|
+
end
|
28
|
+
|
29
|
+
def after_query(event)
|
30
|
+
runtime = event.duration * 1000
|
31
|
+
command = commands.delete(event.request_id).to_s
|
32
|
+
file, line, method = RorVsWild.client.extract_most_relevant_location(caller)
|
33
|
+
RorVsWild.client.send(:push_query, kind: "mongo", command: command, file: file, line: line, method: method, runtime: runtime)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module RorVsWild
|
2
|
+
module Plugin
|
3
|
+
class NetHttp
|
4
|
+
def self.setup
|
5
|
+
return if !defined?(Net::HTTP)
|
6
|
+
return if Net::HTTP.method_defined?(:request_without_rorvswild)
|
7
|
+
|
8
|
+
Net::HTTP.class_eval do
|
9
|
+
alias_method :request_without_rorvswild, :request
|
10
|
+
|
11
|
+
def request(req, body = nil, &block)
|
12
|
+
scheme = use_ssl? ? "https".freeze : "http".freeze
|
13
|
+
url = "#{req.method} #{scheme}://#{address}#{req.path}"
|
14
|
+
RorVsWild.client.measure_query("http".freeze, url) do
|
15
|
+
request_without_rorvswild(req, body = nil, &block)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module RorVsWild
|
2
|
+
module Plugin
|
3
|
+
class Redis
|
4
|
+
def self.setup
|
5
|
+
return if !defined?(::Redis)
|
6
|
+
return if ::Redis::Client.method_defined?(:process_without_rorvswild)
|
7
|
+
::Redis::Client.class_eval do
|
8
|
+
alias_method :process_without_rorvswild, :process
|
9
|
+
|
10
|
+
def process(commands, &block)
|
11
|
+
string = RorVsWild::Plugin::Redis.commands_to_string(commands)
|
12
|
+
RorVsWild.client.measure_query("redis".freeze, string) do
|
13
|
+
process_without_rorvswild(commands, &block)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.commands_to_string(commands)
|
20
|
+
commands.map { |c| c[0] == :auth ? "auth *****" : c.join(" ".freeze) }.join("\n".freeze)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/rorvswild/version.rb
CHANGED
data/lib/rorvswild.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
require "rorvswild/version"
|
2
2
|
require "rorvswild/location"
|
3
|
+
require "rorvswild/plugin/redis"
|
4
|
+
require "rorvswild/plugin/mongo"
|
3
5
|
require "rorvswild/plugin/resque"
|
4
6
|
require "rorvswild/plugin/sidekiq"
|
7
|
+
require "rorvswild/plugin/net_http"
|
5
8
|
require "rorvswild/client"
|
6
9
|
|
7
10
|
module RorVsWild
|
data/test/helper.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.expand_path("#{File.dirname(__FILE__)}/../helper")
|
2
|
+
|
3
|
+
require "mongo"
|
4
|
+
|
5
|
+
class RorVsWild::Plugin::MongoTest < Minitest::Test
|
6
|
+
Mongo::Logger.logger.level = ::Logger::FATAL
|
7
|
+
|
8
|
+
def test_callback
|
9
|
+
mountains = [
|
10
|
+
{name: "Mont Blanc", altitude: 4807},
|
11
|
+
{name: "Mont Cervin", altitude: 4478},
|
12
|
+
]
|
13
|
+
client.measure_block("mongo") do
|
14
|
+
client = Mongo::Client.new('mongodb://127.0.0.1:27017/test')
|
15
|
+
mountains.each { |m| client[:mountains].insert_one(m) }
|
16
|
+
end
|
17
|
+
assert_equal(1, client.send(:queries).size)
|
18
|
+
assert_equal(2, client.send(:queries)[0][:times])
|
19
|
+
assert_equal("mongo", client.send(:queries)[0][:kind])
|
20
|
+
assert_match('{"insert"=>"mountains", "documents"=>', client.send(:queries)[0][:command])
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def client
|
26
|
+
@client ||= initialize_client(app_root: "/rails/root")
|
27
|
+
end
|
28
|
+
|
29
|
+
def initialize_client(options = {})
|
30
|
+
client = RorVsWild::Client.new(options)
|
31
|
+
client.stubs(:post_request)
|
32
|
+
client.stubs(:post_job)
|
33
|
+
client
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require File.expand_path("#{File.dirname(__FILE__)}/../helper")
|
2
|
+
|
3
|
+
require "net/http"
|
4
|
+
|
5
|
+
class RorVsWild::Plugin::NetHttpTest < Minitest::Test
|
6
|
+
def test_callback
|
7
|
+
client.measure_block("test") { Net::HTTP.get("ruby-lang.org", "/index.html") }
|
8
|
+
assert_equal(1, client.send(:queries).size)
|
9
|
+
assert_equal(1, client.send(:queries)[0][:times])
|
10
|
+
assert_equal("http", client.send(:queries)[0][:kind])
|
11
|
+
assert_match("GET http://ruby-lang.org/index.html", client.send(:queries)[0][:command])
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_callback_with_https
|
15
|
+
client.measure_block("test") { Net::HTTP.get(URI("https://www.ruby-lang.org/index.html")) }
|
16
|
+
assert_match("GET https://www.ruby-lang.org/index.html", client.send(:queries)[0][:command])
|
17
|
+
assert_equal("http", client.send(:queries)[0][:kind])
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_nested_query_because_net_http_request_is_recursive_when_connection_is_not_started
|
21
|
+
client.measure_block("test") do
|
22
|
+
uri = URI("http://www.ruby-lang.org/index.html")
|
23
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
24
|
+
http.request(Net::HTTP::Get.new(uri.path))
|
25
|
+
end
|
26
|
+
assert_equal(1, client.send(:queries)[0][:times])
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def client
|
32
|
+
@client ||= initialize_client(app_root: "/rails/root")
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize_client(options = {})
|
36
|
+
client = RorVsWild::Client.new(options)
|
37
|
+
client.stubs(:post_request)
|
38
|
+
client.stubs(:post_job)
|
39
|
+
client
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require File.expand_path("#{File.dirname(__FILE__)}/../helper")
|
2
|
+
|
3
|
+
require "redis"
|
4
|
+
|
5
|
+
class RorVsWild::Plugin::RedisTest < Minitest::Test
|
6
|
+
def test_callback
|
7
|
+
client.measure_code("::Redis.new.get('foo')")
|
8
|
+
assert_equal(1, client.send(:queries).size)
|
9
|
+
assert_equal("redis", client.send(:queries)[0][:kind])
|
10
|
+
assert_equal("get foo", client.send(:queries)[0][:command])
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_callback_with_pipeline
|
14
|
+
skip
|
15
|
+
client.measure_block("pipeline") do
|
16
|
+
redis = ::Redis.new
|
17
|
+
redis.get("foo")
|
18
|
+
redis.set("foo", "bar")
|
19
|
+
end
|
20
|
+
assert_equal(2, client.send(:queries).size)
|
21
|
+
assert_equal("redis", client.send(:queries)[0][:kind])
|
22
|
+
assert_equal("get foo", client.send(:queries)[0][:command])
|
23
|
+
assert_equal("set foo bar", client.send(:queries)[1][:command])
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_commands_to_string_hide_auth_password
|
27
|
+
assert_equal("auth *****", RorVsWild::Plugin::Redis.commands_to_string([[:auth, "SECRET"]]))
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def client
|
33
|
+
@client ||= initialize_client(app_root: "/rails/root")
|
34
|
+
end
|
35
|
+
|
36
|
+
def initialize_client(options = {})
|
37
|
+
client ||= RorVsWild::Client.new(options)
|
38
|
+
client.stubs(:post_request)
|
39
|
+
client.stubs(:post_job)
|
40
|
+
client
|
41
|
+
end
|
42
|
+
end
|
data/test/ror_vs_wild_test.rb
CHANGED
@@ -1,11 +1,4 @@
|
|
1
|
-
|
2
|
-
$LOAD_PATH.unshift(root_path + "/lib")
|
3
|
-
|
4
|
-
require "rorvswild"
|
5
|
-
|
6
|
-
require "minitest/autorun"
|
7
|
-
require 'mocha/mini_test'
|
8
|
-
require "top_tests"
|
1
|
+
require File.expand_path("#{File.dirname(__FILE__)}/helper")
|
9
2
|
|
10
3
|
class RorVsWildTest < Minitest::Test
|
11
4
|
include TopTests
|
@@ -117,11 +110,11 @@ class RorVsWildTest < Minitest::Test
|
|
117
110
|
def test_push_query
|
118
111
|
client = initialize_client
|
119
112
|
client.send(:data)[:queries] = []
|
120
|
-
client.send(:push_query, {file: "file", line: 123,
|
121
|
-
client.send(:push_query, {file: "file", line: 123,
|
122
|
-
client.send(:push_query, {file: "file", line: 123,
|
123
|
-
client.send(:push_query, {file: "file", line: 123,
|
124
|
-
assert_equal([{file: "file", line: 123,
|
113
|
+
client.send(:push_query, {kind: "sql", file: "file", line: 123, command: "BEGIN", runtime: 10})
|
114
|
+
client.send(:push_query, {kind: "sql", file: "file", line: 123, command: "SELECT 1", runtime: 10})
|
115
|
+
client.send(:push_query, {kind: "sql", file: "file", line: 123, command: "SELECT 1", runtime: 10})
|
116
|
+
client.send(:push_query, {kind: "sql", file: "file", line: 123, command: "COMMIT", runtime: 10})
|
117
|
+
assert_equal([{kind: "sql", file: "file", line: 123, command: "SELECT 1", runtime: 40, times: 2}], client.send(:queries))
|
125
118
|
end
|
126
119
|
|
127
120
|
def test_after_exception
|
data/test/run.rb
ADDED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rorvswild
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexis Bernard
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-02-
|
11
|
+
date: 2017-02-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -43,12 +43,20 @@ files:
|
|
43
43
|
- lib/rorvswild/client.rb
|
44
44
|
- lib/rorvswild/installer.rb
|
45
45
|
- lib/rorvswild/location.rb
|
46
|
+
- lib/rorvswild/plugin/mongo.rb
|
47
|
+
- lib/rorvswild/plugin/net_http.rb
|
48
|
+
- lib/rorvswild/plugin/redis.rb
|
46
49
|
- lib/rorvswild/plugin/resque.rb
|
47
50
|
- lib/rorvswild/plugin/sidekiq.rb
|
48
51
|
- lib/rorvswild/rails_loader.rb
|
49
52
|
- lib/rorvswild/version.rb
|
50
53
|
- rorvswild.gemspec
|
54
|
+
- test/helper.rb
|
55
|
+
- test/plugin/mongo_test.rb
|
56
|
+
- test/plugin/net_http_test.rb
|
57
|
+
- test/plugin/redis_test.rb
|
51
58
|
- test/ror_vs_wild_test.rb
|
59
|
+
- test/run.rb
|
52
60
|
homepage: https://www.rorvswild.com
|
53
61
|
licenses:
|
54
62
|
- MIT
|
@@ -74,5 +82,10 @@ signing_key:
|
|
74
82
|
specification_version: 4
|
75
83
|
summary: Ruby on Rails app monitoring
|
76
84
|
test_files:
|
85
|
+
- test/helper.rb
|
86
|
+
- test/plugin/mongo_test.rb
|
87
|
+
- test/plugin/net_http_test.rb
|
88
|
+
- test/plugin/redis_test.rb
|
77
89
|
- test/ror_vs_wild_test.rb
|
90
|
+
- test/run.rb
|
78
91
|
has_rdoc:
|