notable 0.1.0 → 0.2.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/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
|