dry-monitor 0.0.3 → 0.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/.travis.yml +6 -9
- data/CHANGELOG.md +10 -0
- data/Gemfile +2 -0
- data/dry-monitor.gemspec +1 -0
- data/lib/dry/monitor/notifications.rb +9 -31
- data/lib/dry/monitor/rack/logger.rb +12 -13
- data/lib/dry/monitor/rack/middleware.rb +6 -4
- data/lib/dry/monitor/sql/logger.rb +5 -2
- data/lib/dry/monitor/version.rb +1 -1
- data/spec/integration/instrumentation_spec.rb +10 -18
- data/spec/integration/rack_middleware_spec.rb +3 -3
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ea5ea283589f7fcf5e657a51044c7085348464de
|
4
|
+
data.tar.gz: 70cb63d6bea9a42c7002b90cd994bd4a6cc549d9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5383bf2d033695ea44b7404bbc04f59bb412bf0cde5449e1b279aa9be147044205ab1d027b746345f837db25d9975975068c0a2e041cb580cfeccaa3205e25d1
|
7
|
+
data.tar.gz: 1b3952264e029600d2aba9baf9c96bae93766a420c87492f31c0734a8e479a00879cf796467bccac584f4d809482b4e73ea4500e4a42fd70e25ff490648f0b1f
|
data/.travis.yml
CHANGED
@@ -1,20 +1,17 @@
|
|
1
1
|
language: ruby
|
2
|
-
dist: trusty
|
3
|
-
sudo: required
|
4
2
|
cache: bundler
|
5
|
-
bundler_args: --without
|
3
|
+
bundler_args: --without benchmarks console tools
|
6
4
|
script: "bundle exec rake ci"
|
5
|
+
before_install: gem update --system
|
7
6
|
after_success:
|
8
7
|
- '[ "${TRAVIS_JOB_NUMBER#*.}" = "1" ] && [ "$TRAVIS_BRANCH" = "master" ] && bundle exec codeclimate-test-reporter'
|
9
8
|
rvm:
|
10
|
-
- 2.
|
11
|
-
- 2.3
|
12
|
-
- 2.
|
13
|
-
-
|
14
|
-
- jruby
|
9
|
+
- 2.5.0
|
10
|
+
- 2.4.3
|
11
|
+
- 2.3.6
|
12
|
+
- jruby-9.1.9.0
|
15
13
|
env:
|
16
14
|
global:
|
17
|
-
- JRUBY_OPTS='--dev -J-Xmx1024M'
|
18
15
|
- COVERAGE='true'
|
19
16
|
notifications:
|
20
17
|
webhooks:
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/dry-monitor.gemspec
CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.add_runtime_dependency 'rouge', '~> 2.0', '>= 2.2.1'
|
19
19
|
spec.add_runtime_dependency 'dry-equalizer', '~> 0.2'
|
20
20
|
spec.add_runtime_dependency 'dry-configurable', '~> 0.5'
|
21
|
+
spec.add_runtime_dependency 'dry-events', '~> 0.1'
|
21
22
|
|
22
23
|
spec.add_development_dependency 'bundler'
|
23
24
|
spec.add_development_dependency 'rake'
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'dry/events/publisher'
|
2
|
+
|
1
3
|
module Dry
|
2
4
|
module Monitor
|
3
5
|
class Clock
|
@@ -15,40 +17,18 @@ module Dry
|
|
15
17
|
|
16
18
|
CLOCK = Clock.new
|
17
19
|
|
18
|
-
class Event
|
19
|
-
attr_reader :id
|
20
|
-
|
21
|
-
attr_reader :info
|
22
|
-
|
23
|
-
def initialize(id, info = {})
|
24
|
-
@id = id
|
25
|
-
@info = info
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
20
|
class Notifications
|
21
|
+
include Events::Publisher['Dry::Monitor::Notifications']
|
22
|
+
|
30
23
|
attr_reader :id
|
31
|
-
|
32
|
-
attr_reader :listeners
|
24
|
+
|
33
25
|
attr_reader :clock
|
34
26
|
|
35
27
|
def initialize(id)
|
36
28
|
@id = id
|
37
|
-
@listeners = Hash.new { |h, k| h[k] = [] }
|
38
|
-
@events = {}
|
39
29
|
@clock = CLOCK
|
40
30
|
end
|
41
31
|
|
42
|
-
def event(id, info = {})
|
43
|
-
events[id] = Event.new(id, info) unless events.key?(id)
|
44
|
-
self
|
45
|
-
end
|
46
|
-
|
47
|
-
def subscribe(event_id, listener = nil, &block)
|
48
|
-
listeners[event_id] << (listener || block)
|
49
|
-
self
|
50
|
-
end
|
51
|
-
|
52
32
|
def start(event_id, payload)
|
53
33
|
instrument(event_id, payload)
|
54
34
|
end
|
@@ -57,18 +37,16 @@ module Dry
|
|
57
37
|
instrument(event_id, payload)
|
58
38
|
end
|
59
39
|
|
60
|
-
def instrument(event_id, payload =
|
61
|
-
event = events[event_id]
|
62
|
-
|
40
|
+
def instrument(event_id, payload = EMPTY_HASH, &block)
|
63
41
|
if block
|
64
42
|
result, time = clock.measure(&block)
|
65
43
|
end
|
66
44
|
|
67
|
-
|
45
|
+
process(event_id, payload) do |event, listener|
|
68
46
|
if time
|
69
|
-
listener.(
|
47
|
+
listener.(event.payload(payload.merge(time: time)))
|
70
48
|
else
|
71
|
-
listener.(event
|
49
|
+
listener.(event)
|
72
50
|
end
|
73
51
|
end
|
74
52
|
|
@@ -11,12 +11,10 @@ module Dry
|
|
11
11
|
REQUEST_METHOD = 'REQUEST_METHOD'.freeze
|
12
12
|
PATH_INFO = 'PATH_INFO'.freeze
|
13
13
|
REMOTE_ADDR = 'REMOTE_ADDR'.freeze
|
14
|
-
|
15
|
-
QUERY_PARAMS = 'QUERY_PARAMS'.freeze
|
14
|
+
QUERY_STRING = 'QUERY_STRING'.freeze
|
16
15
|
|
17
16
|
START_MSG = %(Started %s "%s" for %s at %s).freeze
|
18
17
|
STOP_MSG = %(Finished %s "%s" for %s in %sms [Status: %s]\n).freeze
|
19
|
-
PARAMS_MSG = %( Parameters %s).freeze
|
20
18
|
QUERY_MSG = %( Query parameters %s).freeze
|
21
19
|
FILTERED = '[FILTERED]'.freeze
|
22
20
|
|
@@ -30,22 +28,22 @@ module Dry
|
|
30
28
|
end
|
31
29
|
|
32
30
|
def attach(rack_monitor)
|
33
|
-
rack_monitor.on(:start) do |
|
34
|
-
log_start_request(
|
31
|
+
rack_monitor.on(:start) do |env:|
|
32
|
+
log_start_request(env)
|
35
33
|
end
|
36
34
|
|
37
|
-
rack_monitor.on(:stop) do |
|
38
|
-
log_stop_request(
|
35
|
+
rack_monitor.on(:stop) do |env:, status:, time:|
|
36
|
+
log_stop_request(env, status, time)
|
39
37
|
end
|
40
38
|
|
41
|
-
rack_monitor.on(:error) do |
|
42
|
-
log_exception(
|
39
|
+
rack_monitor.on(:error) do |exception:|
|
40
|
+
log_exception(exception)
|
43
41
|
end
|
44
42
|
end
|
45
43
|
|
46
|
-
def log_exception(e
|
44
|
+
def log_exception(e)
|
47
45
|
logger.error e.message
|
48
|
-
logger.error filter_backtrace(e.backtrace
|
46
|
+
logger.error filter_backtrace(e.backtrace).join("\n")
|
49
47
|
end
|
50
48
|
|
51
49
|
def log_start_request(request)
|
@@ -69,7 +67,7 @@ module Dry
|
|
69
67
|
end
|
70
68
|
|
71
69
|
def log_request_params(request)
|
72
|
-
with_http_params(request[
|
70
|
+
with_http_params(request[QUERY_STRING]) do |params|
|
73
71
|
info QUERY_MSG % [params.inspect]
|
74
72
|
end
|
75
73
|
end
|
@@ -80,12 +78,13 @@ module Dry
|
|
80
78
|
|
81
79
|
def with_http_params(params)
|
82
80
|
params = ::Rack::Utils.parse_nested_query(params)
|
81
|
+
|
83
82
|
if params.size > 0
|
84
83
|
yield(filter_params(params))
|
85
84
|
end
|
86
85
|
end
|
87
86
|
|
88
|
-
def filter_backtrace(backtrace
|
87
|
+
def filter_backtrace(backtrace)
|
89
88
|
# TODO: what do we want to do with this?
|
90
89
|
backtrace.reject { |l| l.include?('gems') }
|
91
90
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'rack/utils'
|
2
|
+
require 'dry/monitor/notifications'
|
2
3
|
|
3
4
|
module Dry
|
4
5
|
module Monitor
|
@@ -8,15 +9,16 @@ module Dry
|
|
8
9
|
REQUEST_STOP = :'rack.request.stop'
|
9
10
|
REQUEST_ERROR = :'rack.request.error'
|
10
11
|
|
12
|
+
Notifications.register_event(REQUEST_START)
|
13
|
+
Notifications.register_event(REQUEST_STOP)
|
14
|
+
Notifications.register_event(REQUEST_ERROR)
|
15
|
+
|
11
16
|
attr_reader :app
|
17
|
+
|
12
18
|
attr_reader :notifications
|
13
19
|
|
14
20
|
def initialize(*args)
|
15
21
|
@notifications, @app = *args
|
16
|
-
|
17
|
-
notifications.event(REQUEST_START)
|
18
|
-
notifications.event(REQUEST_STOP)
|
19
|
-
notifications.event(REQUEST_ERROR)
|
20
22
|
end
|
21
23
|
|
22
24
|
def new(app)
|
@@ -1,8 +1,11 @@
|
|
1
1
|
require 'dry-configurable'
|
2
2
|
require 'rouge'
|
3
|
+
require 'dry/monitor/notifications'
|
3
4
|
|
4
5
|
module Dry
|
5
6
|
module Monitor
|
7
|
+
Notifications.register_event(:sql)
|
8
|
+
|
6
9
|
module SQL
|
7
10
|
class Logger
|
8
11
|
extend Dry::Configurable
|
@@ -26,8 +29,8 @@ module Dry
|
|
26
29
|
end
|
27
30
|
|
28
31
|
def subscribe(notifications)
|
29
|
-
notifications.
|
30
|
-
log_query(time,
|
32
|
+
notifications.subscribe(:sql) do |time:, name:, query:|
|
33
|
+
log_query(time, name, query)
|
31
34
|
end
|
32
35
|
end
|
33
36
|
|
data/lib/dry/monitor/version.rb
CHANGED
@@ -3,45 +3,37 @@ require 'spec_helper'
|
|
3
3
|
RSpec.describe 'Subscribing to instrumentation events' do
|
4
4
|
subject(:notifications) { Dry::Monitor::Notifications.new(:app) }
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
captured = []
|
10
|
-
listener = -> id, payload { captured << [id, payload] }
|
11
|
-
|
12
|
-
notifications.event(:sql, { name: 'rom[sql]' }).subscribe(:sql, listener)
|
13
|
-
|
14
|
-
notifications.instrument(:sql, payload)
|
15
|
-
|
16
|
-
expect(captured).to eql([[:sql, { name: 'rom[sql]', query: 'SELECT 1 FROM users'}]])
|
17
|
-
end
|
6
|
+
before do
|
7
|
+
Dry::Monitor::Notifications.register_event(:sql, { name: 'rom[sql]' })
|
8
|
+
end
|
18
9
|
|
10
|
+
describe '#instrument' do
|
19
11
|
it 'allows subscribing via block' do
|
20
12
|
captured = []
|
21
13
|
payload = { query: 'SELECT 1 FROM users' }
|
22
14
|
|
23
|
-
notifications.
|
24
|
-
captured << [id,
|
15
|
+
notifications.subscribe(:sql) do |event|
|
16
|
+
captured << [event.id, event[:query]]
|
25
17
|
end
|
26
18
|
|
27
19
|
notifications.instrument(:sql, payload)
|
28
20
|
|
29
|
-
expect(captured).to eql([[:sql,
|
21
|
+
expect(captured).to eql([[:sql, 'SELECT 1 FROM users']])
|
30
22
|
end
|
31
23
|
|
32
24
|
it 'allows instrumenting via block' do
|
33
25
|
captured = []
|
34
26
|
payload = { query: 'SELECT 1 FROM users' }
|
35
27
|
|
36
|
-
notifications.
|
37
|
-
captured << [id,
|
28
|
+
notifications.subscribe(:sql) do |event|
|
29
|
+
captured << [event.id, event[:query]]
|
38
30
|
end
|
39
31
|
|
40
32
|
notifications.instrument(:sql, payload) do
|
41
33
|
payload
|
42
34
|
end
|
43
35
|
|
44
|
-
expect(captured).to eql([[:sql,
|
36
|
+
expect(captured).to eql([[:sql, 'SELECT 1 FROM users']])
|
45
37
|
end
|
46
38
|
end
|
47
39
|
end
|
@@ -21,7 +21,7 @@ RSpec.describe Dry::Monitor::Rack::Middleware do
|
|
21
21
|
|
22
22
|
describe '#call' do
|
23
23
|
let(:env) do
|
24
|
-
{ 'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/hello-world', 'REMOTE_ADDR' => '0.0.0.0', '
|
24
|
+
{ 'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/hello-world', 'REMOTE_ADDR' => '0.0.0.0', 'QUERY_STRING' => query_params }
|
25
25
|
end
|
26
26
|
|
27
27
|
let(:query_params) do
|
@@ -53,8 +53,8 @@ RSpec.describe Dry::Monitor::Rack::Middleware do
|
|
53
53
|
it 'subscribe a listener to a specific request event' do
|
54
54
|
captured = []
|
55
55
|
|
56
|
-
middleware.on(:error) do |
|
57
|
-
captured << payload
|
56
|
+
middleware.on(:error) do |event|
|
57
|
+
captured << event.payload
|
58
58
|
end
|
59
59
|
|
60
60
|
middleware.instrument(:error, exception: 'oops')
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dry-monitor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Solnica
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-01-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rouge
|
@@ -58,6 +58,20 @@ dependencies:
|
|
58
58
|
- - "~>"
|
59
59
|
- !ruby/object:Gem::Version
|
60
60
|
version: '0.5'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: dry-events
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0.1'
|
68
|
+
type: :runtime
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0.1'
|
61
75
|
- !ruby/object:Gem::Dependency
|
62
76
|
name: bundler
|
63
77
|
requirement: !ruby/object:Gem::Requirement
|