rorvswild 1.0.1 → 1.1.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/Gemfile +2 -0
- data/lib/rorvswild/agent.rb +11 -10
- data/lib/rorvswild/plugin/active_job.rb +1 -1
- data/lib/rorvswild/plugin/delayed_job.rb +1 -1
- data/lib/rorvswild/plugin/resque.rb +1 -1
- data/lib/rorvswild/plugin/sidekiq.rb +2 -1
- data/lib/rorvswild/queue.rb +71 -0
- data/lib/rorvswild/version.rb +1 -1
- data/lib/rorvswild.rb +17 -0
- data/test/measure_nested_sections_test.rb +0 -1
- data/test/plugin/active_job_test.rb +13 -2
- data/test/plugin/delayed_job_test.rb +19 -10
- data/test/plugin/resque_test.rb +32 -0
- data/test/plugin/sidekiq_test.rb +36 -0
- data/test/queue_test.rb +52 -0
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 97aed7e941905d99050aa05b33a2d318b49e1e74
|
4
|
+
data.tar.gz: ed86f80358c77f008f3e72301f99c175de6988d3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b2fd50627532be3543aeb2b1279bcb2e513f1a459749d53e59efd08a434bf5a863167279e446e8a574bc2d608e842f4f862cd50a8f23bbdb6eedebfa3251c192
|
7
|
+
data.tar.gz: c6ce663a5ba4c0e15b3da29b875a13ec607aada3d2de8855fb8ed305b6da1d0246579234405aa7e9570b1fb6f3a017f96f265eca32f6980c57929558fa45830e
|
data/Gemfile
CHANGED
data/lib/rorvswild/agent.rb
CHANGED
@@ -6,33 +6,32 @@ module RorVsWild
|
|
6
6
|
|
7
7
|
def self.default_config
|
8
8
|
{
|
9
|
-
api_url: "https://www.rorvswild.com/api",
|
9
|
+
api_url: "https://www.rorvswild.com/api/v1",
|
10
10
|
ignored_exceptions: [],
|
11
11
|
}
|
12
12
|
end
|
13
13
|
|
14
14
|
attr_reader :api_url, :api_key, :app_id, :app_root, :ignored_exceptions
|
15
15
|
|
16
|
-
attr_reader :app_root_regex, :client
|
16
|
+
attr_reader :app_root_regex, :client, :queue
|
17
17
|
|
18
18
|
def initialize(config)
|
19
19
|
config = self.class.default_config.merge(config)
|
20
20
|
@ignored_exceptions = config[:ignored_exceptions]
|
21
21
|
@app_root = config[:app_root]
|
22
|
-
@logger = config[:logger]
|
23
22
|
@client = Client.new(config)
|
23
|
+
@queue = Queue.new(client)
|
24
24
|
cleanup_data
|
25
25
|
|
26
26
|
if defined?(Rails)
|
27
|
-
@logger ||= Rails.logger
|
28
27
|
@app_root ||= Rails.root.to_s
|
29
28
|
config = Rails.application.config
|
30
29
|
@ignored_exceptions ||= %w[ActionController::RoutingError] + config.action_dispatch.rescue_responses.map { |(key,value)| key }
|
31
30
|
end
|
32
31
|
|
33
|
-
@logger ||= Logger.new(STDERR)
|
34
32
|
@app_root_regex = app_root ? /\A#{app_root}/ : nil
|
35
33
|
|
34
|
+
RorVsWild.logger.info("Start RorVsWild #{RorVsWild::VERSION} from #{app_root}")
|
36
35
|
setup_plugins
|
37
36
|
end
|
38
37
|
|
@@ -75,13 +74,13 @@ module RorVsWild
|
|
75
74
|
end
|
76
75
|
end
|
77
76
|
|
78
|
-
def measure_job(name, &block)
|
77
|
+
def measure_job(name, parameters: nil, &block)
|
79
78
|
return block.call if data[:name] # Prevent from recursive jobs
|
80
79
|
initialize_data(name)
|
81
80
|
begin
|
82
81
|
block.call
|
83
82
|
rescue Exception => ex
|
84
|
-
|
83
|
+
push_exception(ex, parameters: parameters)
|
85
84
|
raise
|
86
85
|
ensure
|
87
86
|
data[:runtime] = (Time.now - data[:started_at]) * 1000
|
@@ -114,9 +113,11 @@ module RorVsWild
|
|
114
113
|
post_error(exception_to_hash(exception, extra_details))
|
115
114
|
end
|
116
115
|
|
117
|
-
def push_exception(exception)
|
116
|
+
def push_exception(exception, options = nil)
|
118
117
|
return if ignored_exception?(exception)
|
119
118
|
data[:error] = exception_to_hash(exception)
|
119
|
+
data[:error].merge!(options) if options
|
120
|
+
data[:error]
|
120
121
|
end
|
121
122
|
|
122
123
|
def data
|
@@ -152,11 +153,11 @@ module RorVsWild
|
|
152
153
|
end
|
153
154
|
|
154
155
|
def post_request
|
155
|
-
|
156
|
+
queue.push_request(cleanup_data)
|
156
157
|
end
|
157
158
|
|
158
159
|
def post_job
|
159
|
-
|
160
|
+
queue.push_job(cleanup_data)
|
160
161
|
end
|
161
162
|
|
162
163
|
def post_error(hash)
|
@@ -11,7 +11,8 @@ module RorVsWild
|
|
11
11
|
|
12
12
|
def call(worker, item, queue, &block)
|
13
13
|
# Wrapped contains the real class name of the ActiveJob wrapper
|
14
|
-
|
14
|
+
name = item["wrapped".freeze] || item["class".freeze]
|
15
|
+
RorVsWild.agent.measure_job(name, parameters: item["args".freeze], &block)
|
15
16
|
end
|
16
17
|
end
|
17
18
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module RorVsWild
|
2
|
+
class Queue
|
3
|
+
SLEEP_TIME = 10
|
4
|
+
FLUSH_TRESHOLD = 10
|
5
|
+
|
6
|
+
attr_reader :mutex, :thread, :client
|
7
|
+
attr_reader :requests, :jobs
|
8
|
+
|
9
|
+
def initialize(client)
|
10
|
+
@jobs = []
|
11
|
+
@requests = []
|
12
|
+
@client = client
|
13
|
+
@mutex = Mutex.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def push_job(data)
|
17
|
+
push_to(jobs, data)
|
18
|
+
end
|
19
|
+
|
20
|
+
def push_request(data)
|
21
|
+
push_to(requests, data)
|
22
|
+
end
|
23
|
+
|
24
|
+
def push_to(array, data)
|
25
|
+
mutex.synchronize do
|
26
|
+
wakeup_thread if array.push(data).size >= FLUSH_TRESHOLD
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def pull_jobs
|
31
|
+
mutex.synchronize do
|
32
|
+
if jobs.size > 0
|
33
|
+
result = jobs
|
34
|
+
@jobs = []
|
35
|
+
return result
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def pull_requests
|
41
|
+
mutex.synchronize do
|
42
|
+
if requests.size > 0
|
43
|
+
result = requests
|
44
|
+
@requests = []
|
45
|
+
return result
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def flush_indefinetely
|
51
|
+
sleep(SLEEP_TIME) and flush while true
|
52
|
+
rescue Exception => ex
|
53
|
+
RorVsWild.logger.error(ex)
|
54
|
+
raise
|
55
|
+
end
|
56
|
+
|
57
|
+
def flush
|
58
|
+
RorVsWild.logger.info("flush")
|
59
|
+
data = pull_jobs and client.post("/jobs", jobs: data)
|
60
|
+
data = pull_requests and client.post("/requests", requests: data)
|
61
|
+
end
|
62
|
+
|
63
|
+
def start_thread
|
64
|
+
@thread = Thread.new { flush_indefinetely }
|
65
|
+
end
|
66
|
+
|
67
|
+
def wakeup_thread
|
68
|
+
(thread && thread.alive?) ? thread.wakeup : start_thread
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/rorvswild/version.rb
CHANGED
data/lib/rorvswild.rb
CHANGED
@@ -3,17 +3,26 @@ require "rorvswild/location"
|
|
3
3
|
require "rorvswild/section"
|
4
4
|
require "rorvswild/client"
|
5
5
|
require "rorvswild/plugins"
|
6
|
+
require "rorvswild/queue"
|
6
7
|
require "rorvswild/agent"
|
7
8
|
|
8
9
|
module RorVsWild
|
9
10
|
def self.start(config)
|
11
|
+
@logger = initialize_logger(config[:logger])
|
10
12
|
@agent = Agent.new(config)
|
13
|
+
rescue Exception => ex
|
14
|
+
logger.error(ex)
|
15
|
+
raise
|
11
16
|
end
|
12
17
|
|
13
18
|
def self.agent
|
14
19
|
@agent
|
15
20
|
end
|
16
21
|
|
22
|
+
def self.logger
|
23
|
+
@logger ||= Logger.new(STDOUT)
|
24
|
+
end
|
25
|
+
|
17
26
|
def self.measure_code(code)
|
18
27
|
agent ? agent.measure_code(code) : eval(code)
|
19
28
|
end
|
@@ -29,6 +38,14 @@ module RorVsWild
|
|
29
38
|
def self.record_error(exception, extra_details = nil)
|
30
39
|
agent.record_error(exception, extra_details) if agent
|
31
40
|
end
|
41
|
+
|
42
|
+
def self.initialize_logger(destination)
|
43
|
+
if destination
|
44
|
+
Logger.new(destination)
|
45
|
+
elsif defined?(Rails)
|
46
|
+
Logger.new(Rails.root + "log/rorvswild.log")
|
47
|
+
end
|
48
|
+
end
|
32
49
|
end
|
33
50
|
|
34
51
|
if defined?(Rails)
|
@@ -8,14 +8,25 @@ class RorVsWild::Plugin::ActiveJobTest < Minitest::Test
|
|
8
8
|
class SampleJob < ::ActiveJob::Base
|
9
9
|
queue_as :default
|
10
10
|
|
11
|
-
def perform
|
11
|
+
def perform(arg)
|
12
|
+
raise "Exception" unless arg
|
12
13
|
end
|
13
14
|
end
|
14
15
|
|
15
16
|
def test_callback
|
16
17
|
ActiveJob::Base.logger = Logger.new("/dev/null")
|
17
18
|
agent.expects(:post_job)
|
18
|
-
SampleJob.perform_now
|
19
|
+
SampleJob.perform_now(1)
|
20
|
+
assert_equal("RorVsWild::Plugin::ActiveJobTest::SampleJob", agent.data[:name])
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_callback_on_exception
|
24
|
+
ActiveJob::Base.logger = Logger.new("/dev/null")
|
25
|
+
agent.expects(:post_job)
|
26
|
+
SampleJob.perform_now(false)
|
27
|
+
rescue
|
28
|
+
ensure
|
29
|
+
assert_equal([false], agent.data[:error][:parameters])
|
19
30
|
end
|
20
31
|
end
|
21
32
|
|
@@ -6,30 +6,39 @@ class RorVsWild::Plugin::DelayedJobTest < Minitest::Test
|
|
6
6
|
include RorVsWildAgentHelper
|
7
7
|
|
8
8
|
class SampleJob
|
9
|
+
def initialize(arg)
|
10
|
+
@arg = arg
|
11
|
+
end
|
12
|
+
|
9
13
|
def perform
|
14
|
+
raise "Exception" unless @arg
|
10
15
|
end
|
11
16
|
end
|
12
17
|
|
18
|
+
Delayed::Worker.delay_jobs = false
|
19
|
+
|
13
20
|
class SampleBackend
|
14
21
|
include Delayed::Backend::Base
|
15
22
|
|
16
|
-
attr_accessor :
|
23
|
+
attr_accessor :handler
|
17
24
|
|
18
25
|
def initialize(options)
|
19
|
-
|
20
|
-
|
21
|
-
def payload_object
|
22
|
-
SampleJob.new
|
23
|
-
end
|
24
|
-
|
25
|
-
def destroy
|
26
|
+
@payload_object = options[:payload_object]
|
26
27
|
end
|
27
28
|
end
|
28
29
|
|
29
30
|
def test_callback
|
30
31
|
agent.expects(:post_job)
|
31
|
-
|
32
|
-
|
32
|
+
SampleBackend.enqueue(SampleJob.new(true))
|
33
|
+
assert_equal("RorVsWild::Plugin::DelayedJobTest::SampleJob", agent.data[:name])
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_callback_on_exception
|
37
|
+
agent.expects(:post_job)
|
38
|
+
SampleBackend.enqueue(job = SampleJob.new(false))
|
39
|
+
rescue
|
40
|
+
ensure
|
41
|
+
assert_equal(job, agent.data[:error][:parameters])
|
33
42
|
end
|
34
43
|
end
|
35
44
|
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.expand_path("#{File.dirname(__FILE__)}/../helper")
|
2
|
+
|
3
|
+
require "resque"
|
4
|
+
|
5
|
+
class RorVsWild::Plugin::ResqueTest < Minitest::Test
|
6
|
+
include RorVsWildAgentHelper
|
7
|
+
|
8
|
+
Resque.inline = true
|
9
|
+
|
10
|
+
class SampleJob < Resque::Job
|
11
|
+
@queue = :default
|
12
|
+
|
13
|
+
def self.perform(arg)
|
14
|
+
raise "Exception" unless arg
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_callback
|
19
|
+
agent.expects(:post_job)
|
20
|
+
Resque.enqueue(SampleJob, true)
|
21
|
+
assert_equal("RorVsWild::Plugin::ResqueTest::SampleJob", agent.data[:name])
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_callback_on_exception
|
25
|
+
agent.expects(:post_job)
|
26
|
+
Resque.enqueue(SampleJob, false)
|
27
|
+
rescue
|
28
|
+
ensure
|
29
|
+
assert_equal([false], agent.data[:error][:parameters])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require File.expand_path("#{File.dirname(__FILE__)}/../helper")
|
2
|
+
|
3
|
+
require "sidekiq"
|
4
|
+
require "sidekiq/testing"
|
5
|
+
|
6
|
+
class RorVsWild::Plugin::SidekiqTest < Minitest::Test
|
7
|
+
include RorVsWildAgentHelper
|
8
|
+
|
9
|
+
Sidekiq::Testing.server_middleware do |chain|
|
10
|
+
chain.add(RorVsWild::Plugin::Sidekiq)
|
11
|
+
end
|
12
|
+
|
13
|
+
class SampleJob
|
14
|
+
include ::Sidekiq::Worker
|
15
|
+
|
16
|
+
# SampleSidekiqJob.perform_async(1)
|
17
|
+
def perform(arg)
|
18
|
+
raise "Exception" unless arg
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_callback
|
23
|
+
agent.expects(:post_job)
|
24
|
+
Sidekiq::Testing.inline! { SampleJob.perform_async(1) }
|
25
|
+
assert_equal("RorVsWild::Plugin::SidekiqTest::SampleJob", agent.data[:name])
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_callback_on_exception
|
29
|
+
agent.expects(:post_job)
|
30
|
+
Sidekiq::Testing.inline! { SampleJob.perform_async(false) }
|
31
|
+
rescue
|
32
|
+
ensure
|
33
|
+
assert_equal([false], agent.data[:error][:parameters])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
data/test/queue_test.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.expand_path("#{File.dirname(__FILE__)}/helper")
|
2
|
+
|
3
|
+
class QueueTest < Minitest::Test
|
4
|
+
def test_push_job
|
5
|
+
queue.thread.expects(:wakeup)
|
6
|
+
10.times { queue.push_job(1) }
|
7
|
+
assert_equal(10, queue.jobs.size)
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_push_request
|
11
|
+
queue.thread.expects(:wakeup)
|
12
|
+
10.times { queue.push_request(1) }
|
13
|
+
assert_equal(10, queue.requests.size)
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_pull_jobs
|
17
|
+
queue.push_job(1)
|
18
|
+
assert_equal([1], queue.pull_jobs)
|
19
|
+
refute(queue.pull_jobs)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_pull_requests
|
23
|
+
queue.push_request(1)
|
24
|
+
assert_equal([1], queue.pull_requests)
|
25
|
+
refute(queue.pull_requests)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_flush_when_jobs_are_present
|
29
|
+
queue.client.expects(:post)
|
30
|
+
queue.push_job(1)
|
31
|
+
queue.flush
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_flush_when_requests_are_present
|
35
|
+
queue.client.expects(:post)
|
36
|
+
queue.push_request(1)
|
37
|
+
queue.flush
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_flush_when_empty
|
41
|
+
queue.client.expects(:post).never
|
42
|
+
queue.flush
|
43
|
+
end
|
44
|
+
|
45
|
+
def queue
|
46
|
+
@queue ||= RorVsWild::Queue.new(client)
|
47
|
+
end
|
48
|
+
|
49
|
+
def client
|
50
|
+
@client ||= RorVsWild::Client.new({})
|
51
|
+
end
|
52
|
+
end
|
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: 1.0
|
4
|
+
version: 1.1.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-
|
11
|
+
date: 2017-08-02 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Performances and quality insights for rails developers.
|
14
14
|
email:
|
@@ -42,6 +42,7 @@ files:
|
|
42
42
|
- lib/rorvswild/plugin/resque.rb
|
43
43
|
- lib/rorvswild/plugin/sidekiq.rb
|
44
44
|
- lib/rorvswild/plugins.rb
|
45
|
+
- lib/rorvswild/queue.rb
|
45
46
|
- lib/rorvswild/rails_loader.rb
|
46
47
|
- lib/rorvswild/section.rb
|
47
48
|
- lib/rorvswild/version.rb
|
@@ -57,6 +58,9 @@ files:
|
|
57
58
|
- test/plugin/mongo_test.rb
|
58
59
|
- test/plugin/net_http_test.rb
|
59
60
|
- test/plugin/redis_test.rb
|
61
|
+
- test/plugin/resque_test.rb
|
62
|
+
- test/plugin/sidekiq_test.rb
|
63
|
+
- test/queue_test.rb
|
60
64
|
- test/rorvswild_test.rb
|
61
65
|
- test/run.rb
|
62
66
|
- test/section_test.rb
|
@@ -96,6 +100,9 @@ test_files:
|
|
96
100
|
- test/plugin/mongo_test.rb
|
97
101
|
- test/plugin/net_http_test.rb
|
98
102
|
- test/plugin/redis_test.rb
|
103
|
+
- test/plugin/resque_test.rb
|
104
|
+
- test/plugin/sidekiq_test.rb
|
105
|
+
- test/queue_test.rb
|
99
106
|
- test/rorvswild_test.rb
|
100
107
|
- test/run.rb
|
101
108
|
- test/section_test.rb
|