notable 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +8 -10
- data/lib/notable/engine.rb +4 -3
- data/lib/notable/job_extensions.rb +14 -0
- data/lib/notable/middleware.rb +48 -55
- data/lib/notable/unverified_request.rb +1 -1
- data/lib/notable/version.rb +1 -1
- data/lib/notable.rb +56 -45
- data/notable.gemspec +1 -1
- metadata +7 -8
- data/lib/notable/job_backends/delayed_job.rb +0 -15
- data/lib/notable/job_backends/sidekiq.rb +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c4d9ade6391e626b6456ce4fbbea37d0978327c1
|
4
|
+
data.tar.gz: 3c5baf92e0867ae2e94790613a28ab843217ecb0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2b46b38463983747feb4521469f6896c20a682b5c41a465743548ab6a6fcb811c991270039dc9b631086984273eee8b1f43560c5de23d1667bafc32df979ad4e
|
7
|
+
data.tar.gz: 07573eecf3ea2442f48ef5cd22e00130b815e866e36e1bcbc3062ac1bdae56b1c719590f46f9deba10f9cce6525759edb38381eb309efcdab015587a79ccd97f
|
data/CHANGELOG.md
ADDED
data/README.md
CHANGED
@@ -35,7 +35,7 @@ And run:
|
|
35
35
|
|
36
36
|
```sh
|
37
37
|
rails generate notable:requests
|
38
|
-
rails generate notable:jobs
|
38
|
+
rails generate notable:jobs
|
39
39
|
rake db:migrate
|
40
40
|
```
|
41
41
|
|
@@ -68,8 +68,6 @@ A `Notable::Job` is created for:
|
|
68
68
|
- slow jobs
|
69
69
|
- validation failures
|
70
70
|
|
71
|
-
Currently works with Delayed Job and Sidekiq.
|
72
|
-
|
73
71
|
## Manual Tracking
|
74
72
|
|
75
73
|
```ruby
|
@@ -101,23 +99,23 @@ Notable.slow_request_threshold = 5 # seconds (default)
|
|
101
99
|
Custom user method
|
102
100
|
|
103
101
|
```ruby
|
104
|
-
Notable.user_method =
|
102
|
+
Notable.user_method = -> (env) {
|
105
103
|
env["warden"].try(:user) || env["action_controller.instance"].try(:current_visit)
|
106
|
-
|
104
|
+
}
|
107
105
|
```
|
108
106
|
|
109
107
|
Custom track method
|
110
108
|
|
111
109
|
```ruby
|
112
|
-
Notable.track_request_method =
|
110
|
+
Notable.track_request_method = -> (data, env) {
|
113
111
|
Notable::Request.create!(data)
|
114
|
-
|
112
|
+
}
|
115
113
|
```
|
116
114
|
|
117
115
|
Skip tracking CSRF failures
|
118
116
|
|
119
117
|
```ruby
|
120
|
-
|
118
|
+
skip_before_action :track_unverified_request
|
121
119
|
```
|
122
120
|
|
123
121
|
### Jobs
|
@@ -131,9 +129,9 @@ Notable.slow_job_threshold = 60 # seconds (default)
|
|
131
129
|
Custom track method
|
132
130
|
|
133
131
|
```ruby
|
134
|
-
Notable.track_job_method =
|
132
|
+
Notable.track_job_method = -> (data) {
|
135
133
|
Notable::Job.create!(data)
|
136
|
-
|
134
|
+
}
|
137
135
|
```
|
138
136
|
|
139
137
|
## TODO
|
data/lib/notable/engine.rb
CHANGED
@@ -3,9 +3,10 @@ module Notable
|
|
3
3
|
isolate_namespace Notable
|
4
4
|
|
5
5
|
initializer "notable" do |app|
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
if Notable.requests_enabled?
|
7
|
+
app.config.middleware.insert_after RequestStore::Middleware, Notable::Middleware
|
8
|
+
ActionDispatch::DebugExceptions.send(:prepend, Notable::DebugExceptions)
|
9
|
+
end
|
9
10
|
end
|
10
11
|
end
|
11
12
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Notable
|
2
|
+
module JobExtensions
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
around_perform do |job, block|
|
7
|
+
# no way to get queued_at time :(
|
8
|
+
Notable.track_job(job.class.name, job.job_id, job.queue_name, nil) do
|
9
|
+
block.call
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/notable/middleware.rb
CHANGED
@@ -6,71 +6,64 @@ module Notable
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def call(env)
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
request_time = Time.now - start_time
|
9
|
+
start_time = Time.now
|
10
|
+
status, headers, body = @app.call(env)
|
11
|
+
request_time = Time.now - start_time
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
13
|
+
Safely.safely do
|
14
|
+
if env["action_dispatch.exception"]
|
15
|
+
e = env["action_dispatch.exception"]
|
16
|
+
message =
|
17
|
+
case status.to_i
|
18
|
+
when 404
|
19
|
+
"Not Found"
|
20
|
+
when 503
|
21
|
+
"Timeout"
|
22
|
+
else
|
23
|
+
"Error"
|
24
|
+
end
|
25
|
+
Notable.track message, "#{e.class.name}: #{e.message}"
|
26
|
+
elsif (!status or status.to_i >= 400) and !Notable.notes.any?
|
27
|
+
Notable.track Rack::Utils::HTTP_STATUS_CODES[status.to_i]
|
28
|
+
end
|
30
29
|
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
if request_time > Notable.slow_request_threshold and status.to_i != 503
|
31
|
+
Notable.track "Slow Request"
|
32
|
+
end
|
34
33
|
|
35
|
-
|
36
|
-
|
37
|
-
|
34
|
+
notes = Notable.notes
|
35
|
+
if notes.any?
|
36
|
+
request = ActionDispatch::Request.new(env)
|
38
37
|
|
39
|
-
|
40
|
-
# and we don't want to modify env
|
41
|
-
url = request.base_url + request.script_name + env["REQUEST_PATH"]
|
42
|
-
url << "?#{request.query_string}" unless request.query_string.empty?
|
38
|
+
url = request.original_url
|
43
39
|
|
44
|
-
|
45
|
-
|
46
|
-
|
40
|
+
controller = env["action_controller.instance"]
|
41
|
+
action = controller && "#{controller.params["controller"]}##{controller.params["action"]}"
|
42
|
+
params = controller && controller.request.filtered_parameters.except("controller", "action")
|
47
43
|
|
48
|
-
|
44
|
+
user = Notable.user_method.call(env)
|
49
45
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
end
|
46
|
+
notes.each do |note|
|
47
|
+
data = {
|
48
|
+
note_type: note[:note_type],
|
49
|
+
note: note[:note],
|
50
|
+
user: user,
|
51
|
+
action: action,
|
52
|
+
status: status,
|
53
|
+
params: params,
|
54
|
+
request_id: request.uuid,
|
55
|
+
ip: request.remote_ip,
|
56
|
+
user_agent: request.user_agent,
|
57
|
+
url: url,
|
58
|
+
referrer: request.referer,
|
59
|
+
request_time: request_time
|
60
|
+
}
|
61
|
+
Notable.track_request_method.call(data, env)
|
67
62
|
end
|
68
63
|
end
|
69
|
-
|
70
|
-
[status, headers, body]
|
71
|
-
else
|
72
|
-
@app.call(env)
|
73
64
|
end
|
65
|
+
|
66
|
+
[status, headers, body]
|
74
67
|
end
|
75
68
|
|
76
69
|
end
|
data/lib/notable/version.rb
CHANGED
data/lib/notable.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require "notable/version"
|
2
2
|
|
3
3
|
require "request_store"
|
4
|
-
require "
|
4
|
+
require "safely/core"
|
5
5
|
require "action_dispatch/middleware/debug_exceptions"
|
6
6
|
|
7
7
|
# middleware
|
@@ -15,13 +15,11 @@ require "notable/validation_errors"
|
|
15
15
|
require "notable/debug_exceptions"
|
16
16
|
require "notable/throttle"
|
17
17
|
|
18
|
-
# jobs
|
19
|
-
require "notable/job_backends/sidekiq" if defined?(Sidekiq)
|
20
|
-
require "notable/job_backends/delayed_job" if defined?(Delayed::Job)
|
21
|
-
|
22
18
|
module Notable
|
23
19
|
class << self
|
24
20
|
attr_accessor :enabled
|
21
|
+
attr_accessor :requests_enabled
|
22
|
+
attr_accessor :jobs_enabled
|
25
23
|
|
26
24
|
# requests
|
27
25
|
attr_accessor :track_request_method
|
@@ -33,14 +31,24 @@ module Notable
|
|
33
31
|
attr_accessor :slow_job_threshold
|
34
32
|
end
|
35
33
|
self.enabled = true
|
34
|
+
self.requests_enabled = true
|
35
|
+
self.jobs_enabled = true
|
36
|
+
|
37
|
+
def self.requests_enabled?
|
38
|
+
enabled && requests_enabled
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.jobs_enabled?
|
42
|
+
enabled && jobs_enabled
|
43
|
+
end
|
36
44
|
|
37
45
|
# requests
|
38
|
-
self.track_request_method =
|
39
|
-
self.user_method =
|
46
|
+
self.track_request_method = -> (data, env) { Notable::Request.create!(data) }
|
47
|
+
self.user_method = -> (env) { env["warden"].user if env["warden"] }
|
40
48
|
self.slow_request_threshold = 5
|
41
49
|
|
42
50
|
# jobs
|
43
|
-
self.track_job_method =
|
51
|
+
self.track_job_method = -> (data) { Notable::Job.create!(data) }
|
44
52
|
self.slow_job_threshold = 60
|
45
53
|
|
46
54
|
def self.track(note_type, note = nil)
|
@@ -59,44 +67,47 @@ module Notable
|
|
59
67
|
RequestStore.store.delete(:notable_notes)
|
60
68
|
end
|
61
69
|
|
62
|
-
def self.track_job(job, job_id, queue, created_at
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
begin
|
69
|
-
yield
|
70
|
-
rescue Exception => e
|
71
|
-
exception = e
|
72
|
-
track_error(e)
|
73
|
-
ensure
|
74
|
-
notes = Notable.notes
|
75
|
-
Notable.clear_notes
|
76
|
-
end
|
77
|
-
runtime = Time.now - start_time
|
78
|
-
|
79
|
-
safely do
|
80
|
-
notes << {note_type: "Slow Job"} if runtime > Notable.slow_job_threshold
|
81
|
-
|
82
|
-
notes.each do |note|
|
83
|
-
data = {
|
84
|
-
note_type: note[:note_type],
|
85
|
-
note: note[:note],
|
86
|
-
job: job,
|
87
|
-
job_id: job_id,
|
88
|
-
queue: queue,
|
89
|
-
runtime: runtime,
|
90
|
-
queued_time: queued_time
|
91
|
-
}
|
92
|
-
|
93
|
-
Notable.track_job_method.call(data)
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
raise exception if exception
|
98
|
-
else
|
70
|
+
def self.track_job(job, job_id, queue, created_at)
|
71
|
+
exception = nil
|
72
|
+
notes = nil
|
73
|
+
start_time = Time.now
|
74
|
+
queued_time = created_at ? start_time - created_at : nil
|
75
|
+
begin
|
99
76
|
yield
|
77
|
+
rescue Exception => e
|
78
|
+
exception = e
|
79
|
+
track_error(e)
|
80
|
+
ensure
|
81
|
+
notes = Notable.notes
|
82
|
+
Notable.clear_notes
|
83
|
+
end
|
84
|
+
runtime = Time.now - start_time
|
85
|
+
|
86
|
+
Safely.safely do
|
87
|
+
notes << {note_type: "Slow Job"} if runtime > Notable.slow_job_threshold
|
88
|
+
|
89
|
+
notes.each do |note|
|
90
|
+
data = {
|
91
|
+
note_type: note[:note_type],
|
92
|
+
note: note[:note],
|
93
|
+
job: job,
|
94
|
+
job_id: job_id,
|
95
|
+
queue: queue,
|
96
|
+
runtime: runtime,
|
97
|
+
queued_time: queued_time
|
98
|
+
}
|
99
|
+
|
100
|
+
Notable.track_job_method.call(data)
|
101
|
+
end
|
100
102
|
end
|
103
|
+
|
104
|
+
raise exception if exception
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
ActiveSupport.on_load(:active_job) do
|
109
|
+
if Notable.jobs_enabled?
|
110
|
+
require "notable/job_extensions"
|
111
|
+
include Notable::JobExtensions
|
101
112
|
end
|
102
113
|
end
|
data/notable.gemspec
CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
21
|
spec.add_dependency "request_store"
|
22
|
-
spec.add_dependency "safely_block"
|
22
|
+
spec.add_dependency "safely_block", ">= 0.1.1"
|
23
23
|
|
24
24
|
spec.add_development_dependency "bundler", "~> 1.7"
|
25
25
|
spec.add_development_dependency "rake", "~> 10.0"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: notable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-01-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: request_store
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 0.1.1
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 0.1.1
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: bundler
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -74,6 +74,7 @@ extensions: []
|
|
74
74
|
extra_rdoc_files: []
|
75
75
|
files:
|
76
76
|
- ".gitignore"
|
77
|
+
- CHANGELOG.md
|
77
78
|
- Gemfile
|
78
79
|
- LICENSE.txt
|
79
80
|
- README.md
|
@@ -87,8 +88,7 @@ files:
|
|
87
88
|
- lib/notable.rb
|
88
89
|
- lib/notable/debug_exceptions.rb
|
89
90
|
- lib/notable/engine.rb
|
90
|
-
- lib/notable/
|
91
|
-
- lib/notable/job_backends/sidekiq.rb
|
91
|
+
- lib/notable/job_extensions.rb
|
92
92
|
- lib/notable/middleware.rb
|
93
93
|
- lib/notable/throttle.rb
|
94
94
|
- lib/notable/unpermitted_parameters.rb
|
@@ -116,9 +116,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
116
116
|
version: '0'
|
117
117
|
requirements: []
|
118
118
|
rubyforge_project:
|
119
|
-
rubygems_version: 2.
|
119
|
+
rubygems_version: 2.6.8
|
120
120
|
signing_key:
|
121
121
|
specification_version: 4
|
122
122
|
summary: Track notable requests and background jobs
|
123
123
|
test_files: []
|
124
|
-
has_rdoc:
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module Notable
|
2
|
-
module JobBackends
|
3
|
-
class DelayedJob < Delayed::Plugin
|
4
|
-
callbacks do |lifecycle|
|
5
|
-
lifecycle.around(:invoke_job) do |job, *args, &block|
|
6
|
-
Notable.track_job job.name, job.id, job.queue, job.created_at do
|
7
|
-
block.call(job, *args)
|
8
|
-
end
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
Delayed::Worker.plugins << Notable::JobBackends::DelayedJob
|
@@ -1,26 +0,0 @@
|
|
1
|
-
module Notable
|
2
|
-
module JobBackends
|
3
|
-
class Sidekiq
|
4
|
-
WRAPPER_CLASSES = Set.new(["ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper"])
|
5
|
-
|
6
|
-
def call(_worker, job, queue)
|
7
|
-
name =
|
8
|
-
if WRAPPER_CLASSES.include?(job["class"])
|
9
|
-
job["args"].first["job_class"]
|
10
|
-
else
|
11
|
-
job["class"]
|
12
|
-
end
|
13
|
-
|
14
|
-
Notable.track_job name, job["jid"], queue, Time.at(job["enqueued_at"]) do
|
15
|
-
yield
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
Sidekiq.configure_server do |config|
|
23
|
-
config.server_middleware do |chain|
|
24
|
-
chain.add Notable::JobBackends::Sidekiq
|
25
|
-
end
|
26
|
-
end
|