io_monitor 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 +7 -0
- data/CHANGELOG.md +14 -0
- data/LICENSE.txt +21 -0
- data/README.md +121 -0
- data/lib/io_monitor/adapters/active_record_adapter.rb +38 -0
- data/lib/io_monitor/adapters/base_adapter.rb +15 -0
- data/lib/io_monitor/adapters/net_http_adapter.rb +24 -0
- data/lib/io_monitor/aggregator.rb +46 -0
- data/lib/io_monitor/configuration.rb +54 -0
- data/lib/io_monitor/controller.rb +27 -0
- data/lib/io_monitor/patches/abstract_adapter_patch.rb +11 -0
- data/lib/io_monitor/patches/action_controller_base_patch.rb +19 -0
- data/lib/io_monitor/patches/future_result_patch.rb +15 -0
- data/lib/io_monitor/patches/net_http_adapter_patch.rb +13 -0
- data/lib/io_monitor/publishers/base_publisher.rb +31 -0
- data/lib/io_monitor/publishers/logs_publisher.rb +16 -0
- data/lib/io_monitor/publishers/notifications_publisher.rb +25 -0
- data/lib/io_monitor/railtie.rb +22 -0
- data/lib/io_monitor/version.rb +5 -0
- data/lib/io_monitor.rb +38 -0
- metadata +84 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 55da4008002fc3ddd2846fda47f10c76910a29b370754f02772e33635c73d156
|
4
|
+
data.tar.gz: be06ae7bf31a7051a7e0e113cf16f1c2a55300bf4519d083d400e948e2b4a760
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4120f7fad9b19fe8ef2be71a5c14fd54fca42141ed205cdd468086956b4232bb401fca94d47c906fa2fc371df3288f16b6b46ee2a520ef023d9fdf9fbe61a7d2
|
7
|
+
data.tar.gz: 5eab6fe8f0e5eb4072d8c9e092259896cadb8034dbf4baf8ec99460febbc0fe3bb592f7e0f120e14fdf6f1ed0e4f2684df54b2cd27830281b37eabe36c31a3d4
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# Change log
|
2
|
+
|
3
|
+
## main
|
4
|
+
|
5
|
+
## 0.1.0 (2022-05-24)
|
6
|
+
|
7
|
+
- [PR#7](https://github.com/DmitryTsepelev/io_monitor/pull/7) Add HTTP adapter ([@maxshend])
|
8
|
+
- [PR#6](https://github.com/DmitryTsepelev/io_monitor/pull/6) Add support for ActiveRecord::Relation#load_async method ([@maxshend])
|
9
|
+
- [PR#5](https://github.com/DmitryTsepelev/io_monitor/pull/5) Use ActiveSupport::CurrentAttributes to store input payload ([@maxshend])
|
10
|
+
- [PR#2](https://github.com/DmitryTsepelev/io_monitor/pull/2), [PR#3](https://github.com/DmitryTsepelev/io_monitor/pull/3), [PR#4](https://github.com/DmitryTsepelev/io_monitor/pull/4) Initial implementation ([@prog-supdex], [@maxshend], [@baygeldin])
|
11
|
+
|
12
|
+
[@baygeldin]: https://github.com/baygeldin
|
13
|
+
[@prog-supdex]: https://github.com/prog-supdex
|
14
|
+
[@maxshend]: https://github.com/maxshend
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2022 DmitryTsepelev
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
# IoMonitor
|
2
|
+
|
3
|
+
A gem that helps to detect potential memory bloats.
|
4
|
+
|
5
|
+
When your controller loads a lot of data to the memory but returns a small response to the client it might mean that you're using the IO in the non–optimal way. In this case, you'll see the following message in your logs:
|
6
|
+
|
7
|
+
```
|
8
|
+
Completed 200 OK in 349ms (Views: 2.1ms | ActiveRecord: 38.7ms | ActiveRecord Payload: 866.00 B | Response Payload: 25.00 B | Allocations: 72304)
|
9
|
+
```
|
10
|
+
|
11
|
+
<p align="center">
|
12
|
+
<a href="https://evilmartians.com/?utm_source=io_monitor">
|
13
|
+
<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54">
|
14
|
+
</a>
|
15
|
+
</p>
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
Add this line to your application's Gemfile:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
gem 'io_monitor'
|
23
|
+
```
|
24
|
+
|
25
|
+
Change configuration in an initializer if you need:
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
IoMonitor.configure do |config|
|
29
|
+
config.publish = :notifications # defaults to :logs
|
30
|
+
config.warn_threshold = 0.8 # defaults to 0
|
31
|
+
config.adapters = [:active_record, :net_http] # defaults to [:active_record]
|
32
|
+
end
|
33
|
+
```
|
34
|
+
|
35
|
+
Then include the concern into your controller:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
class MyController < ApplicationController
|
39
|
+
include IoMonitor::Controller
|
40
|
+
end
|
41
|
+
```
|
42
|
+
|
43
|
+
Depending on configuration when IO payload size to response payload size ratio reaches the threshold either a `warn_threshold_reached.io_monitor` notification will be sent or a following warning will be logged:
|
44
|
+
|
45
|
+
```
|
46
|
+
ActiveRecord I/O to response payload ratio is 0.1, while threshold is 0.8
|
47
|
+
```
|
48
|
+
|
49
|
+
In addition, if `publish` is set to logs, additional data will be logged on each request:
|
50
|
+
|
51
|
+
```
|
52
|
+
Completed 200 OK in 349ms (Views: 2.1ms | ActiveRecord: 38.7ms | ActiveRecord Payload: 866.00 B | Response Payload: 25.00 B | Allocations: 72304)
|
53
|
+
```
|
54
|
+
|
55
|
+
If you want to inspect payload sizes, check out payload data for the `process_action.action_controller` event:
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
ActiveSupport::Notifications.subscribe("process_action.action_controller") do |name, start, finish, id, payload|
|
59
|
+
payload[:io_monitor] # { active_record: 866, response: 25 }
|
60
|
+
end
|
61
|
+
```
|
62
|
+
|
63
|
+
## Custom publishers
|
64
|
+
|
65
|
+
Implement your custom publisher by inheriting from `BasePublisher`:
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
class MyPublisher < IoMonitor::BasePublisher
|
69
|
+
def publish(source, ratio)
|
70
|
+
puts "Warn threshold reched for #{source} at #{ratio}!"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
```
|
74
|
+
|
75
|
+
Then specify it in the configuration:
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
IoMonitor.configure do |config|
|
79
|
+
config.publish = MyPublisher.new
|
80
|
+
end
|
81
|
+
```
|
82
|
+
|
83
|
+
## Custom adapters
|
84
|
+
|
85
|
+
Implement your custom adapter by inheriting from `BaseAdapter`:
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
class MyAdapter < IoMonitor::BaseAdapter
|
89
|
+
def self.kind
|
90
|
+
:my_source
|
91
|
+
end
|
92
|
+
|
93
|
+
def initialize!
|
94
|
+
# Take a look at `AbstractAdapterPatch` for an example.
|
95
|
+
end
|
96
|
+
end
|
97
|
+
```
|
98
|
+
|
99
|
+
Then specify it in the configuration:
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
IoMonitor.configure do |config|
|
103
|
+
config.adapters = [:active_record, MyAdapter.new]
|
104
|
+
end
|
105
|
+
```
|
106
|
+
|
107
|
+
## Development
|
108
|
+
|
109
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests.
|
110
|
+
|
111
|
+
## Contributing
|
112
|
+
|
113
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/DmitryTsepelev/io_monitor.
|
114
|
+
|
115
|
+
## License
|
116
|
+
|
117
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
118
|
+
|
119
|
+
## Credits
|
120
|
+
|
121
|
+
Thanks to [@prog-supdex](https://github.com/prog-supdex) and [@maxshend](https://github.com/maxshend) for building the initial implementations (see [PR#2](https://github.com/DmitryTsepelev/io_monitor/pull/2) and [PR#3](https://github.com/DmitryTsepelev/io_monitor/pull/3)).
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "io_monitor/patches/abstract_adapter_patch"
|
4
|
+
require "io_monitor/patches/future_result_patch"
|
5
|
+
|
6
|
+
module IoMonitor
|
7
|
+
class ActiveRecordAdapter < BaseAdapter
|
8
|
+
class << self
|
9
|
+
def kind
|
10
|
+
:active_record
|
11
|
+
end
|
12
|
+
|
13
|
+
def aggregate_result(rows:)
|
14
|
+
return unless IoMonitor.aggregator.active?
|
15
|
+
|
16
|
+
# `.flatten.join.bytesize` would look prettier,
|
17
|
+
# but it makes a lot of unnecessary allocations.
|
18
|
+
io_payload_size = rows.sum(0) do |row|
|
19
|
+
row.sum(0) do |val|
|
20
|
+
(String === val ? val : val.to_s).bytesize
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
IoMonitor.aggregator.increment(kind, io_payload_size)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize!
|
29
|
+
ActiveSupport.on_load(:active_record) do
|
30
|
+
ActiveRecord::ConnectionAdapters::AbstractAdapter.prepend(AbstractAdapterPatch)
|
31
|
+
|
32
|
+
if Rails::VERSION::MAJOR >= 7
|
33
|
+
ActiveRecord::FutureResult.prepend(FutureResultPatch)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "net/http"
|
4
|
+
require "io_monitor/patches/net_http_adapter_patch"
|
5
|
+
|
6
|
+
module IoMonitor
|
7
|
+
class NetHttpAdapter < BaseAdapter
|
8
|
+
def self.kind
|
9
|
+
:net_http
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize!
|
13
|
+
ActiveSupport.on_load(:after_initialize) do
|
14
|
+
Net::HTTP.prepend(NetHttpAdapterPatch)
|
15
|
+
|
16
|
+
if defined?(::WebMock)
|
17
|
+
WebMock::HttpLibAdapters::NetHttpAdapter
|
18
|
+
.instance_variable_get(:@webMockNetHTTP)
|
19
|
+
.prepend(NetHttpAdapterPatch)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module IoMonitor
|
4
|
+
# Thread-safe payload size aggregator.
|
5
|
+
class Aggregator
|
6
|
+
def initialize(sources)
|
7
|
+
@sources = sources
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :sources
|
11
|
+
|
12
|
+
def active?
|
13
|
+
InputPayload.active.present?
|
14
|
+
end
|
15
|
+
|
16
|
+
def start!
|
17
|
+
InputPayload.active = true
|
18
|
+
end
|
19
|
+
|
20
|
+
def stop!
|
21
|
+
InputPayload.active = false
|
22
|
+
end
|
23
|
+
|
24
|
+
def increment(source, val)
|
25
|
+
return unless active?
|
26
|
+
|
27
|
+
InputPayload.state ||= empty_state
|
28
|
+
InputPayload.state[source.to_sym] += val
|
29
|
+
end
|
30
|
+
|
31
|
+
def get(source)
|
32
|
+
InputPayload.state ||= empty_state
|
33
|
+
InputPayload.state[source.to_sym]
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def empty_state
|
39
|
+
sources.map { |kind| [kind, 0] }.to_h
|
40
|
+
end
|
41
|
+
|
42
|
+
class InputPayload < ActiveSupport::CurrentAttributes
|
43
|
+
attribute :state, :active
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module IoMonitor
|
4
|
+
class Configuration
|
5
|
+
DEFAULT_WARN_THRESHOLD = 0.0
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@publisher = LogsPublisher.new
|
9
|
+
@adapters = [ActiveRecordAdapter.new]
|
10
|
+
@warn_threshold = DEFAULT_WARN_THRESHOLD
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_reader :publisher, :adapters, :warn_threshold
|
14
|
+
|
15
|
+
def publish=(value)
|
16
|
+
if value.is_a?(BasePublisher)
|
17
|
+
@publisher = value
|
18
|
+
elsif (publisher_type = resolve(IoMonitor::PUBLISHERS, value))
|
19
|
+
@publisher = publisher_type.new
|
20
|
+
else
|
21
|
+
supported = IoMonitor::PUBLISHERS.map(&:kind)
|
22
|
+
raise ArgumentError, "Only the following publishers are supported: #{supported}."
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def adapters=(value)
|
27
|
+
@adapters = [*value].map do |adapter|
|
28
|
+
if adapter.is_a?(BaseAdapter)
|
29
|
+
adapter
|
30
|
+
elsif (adapter_type = resolve(IoMonitor::ADAPTERS, adapter))
|
31
|
+
adapter_type.new
|
32
|
+
else
|
33
|
+
supported = IoMonitor::ADAPTERS.map(&:kind)
|
34
|
+
raise ArgumentError, "Only the following adapters are supported: #{supported}."
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def warn_threshold=(value)
|
40
|
+
case value
|
41
|
+
when 0..1
|
42
|
+
@warn_threshold = value.to_f
|
43
|
+
else
|
44
|
+
raise ArgumentError, "Warn threshold should be within 0..1 range."
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def resolve(list, kind)
|
51
|
+
list.find { |p| p.kind == kind }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module IoMonitor
|
4
|
+
module Controller
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
def process_action(*)
|
8
|
+
IoMonitor.aggregator.start!
|
9
|
+
|
10
|
+
super
|
11
|
+
|
12
|
+
IoMonitor.aggregator.stop!
|
13
|
+
end
|
14
|
+
|
15
|
+
def append_info_to_payload(payload)
|
16
|
+
super
|
17
|
+
|
18
|
+
data = payload[IoMonitor::NAMESPACE] = {}
|
19
|
+
|
20
|
+
IoMonitor.aggregator.sources.each do |source|
|
21
|
+
data[source] = IoMonitor.aggregator.get(source)
|
22
|
+
end
|
23
|
+
|
24
|
+
data[:response] = payload[:response]&.body&.bytesize || 0
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module IoMonitor
|
4
|
+
module ActionControllerBasePatch
|
5
|
+
def log_process_action(payload)
|
6
|
+
super.tap do |messages|
|
7
|
+
next unless IoMonitor.config.publisher.is_a?(LogsPublisher)
|
8
|
+
|
9
|
+
data = payload[IoMonitor::NAMESPACE]
|
10
|
+
next unless data
|
11
|
+
|
12
|
+
data.each do |source, bytes|
|
13
|
+
size = ActiveSupport::NumberHelper.number_to_human_size(bytes)
|
14
|
+
messages << "#{source.to_s.camelize} Payload: #{size}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module IoMonitor
|
4
|
+
module FutureResultPatch
|
5
|
+
def result
|
6
|
+
# @event_buffer is used to send ActiveSupport notifications related to async queries
|
7
|
+
return super unless @event_buffer
|
8
|
+
|
9
|
+
res = super
|
10
|
+
ActiveRecordAdapter.aggregate_result rows: res.rows
|
11
|
+
|
12
|
+
res
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module IoMonitor
|
4
|
+
module NetHttpAdapterPatch
|
5
|
+
def request(*args, &block)
|
6
|
+
super do |response|
|
7
|
+
if response.body && IoMonitor.aggregator.active?
|
8
|
+
IoMonitor.aggregator.increment(NetHttpAdapter.kind, response.body.bytesize)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module IoMonitor
|
4
|
+
class BasePublisher
|
5
|
+
# :nocov:
|
6
|
+
def self.kind
|
7
|
+
raise NotImplementedError
|
8
|
+
end
|
9
|
+
|
10
|
+
def publish(source, ratio)
|
11
|
+
raise NotImplementedError
|
12
|
+
end
|
13
|
+
# :nocov:
|
14
|
+
|
15
|
+
def process_action(payload)
|
16
|
+
(payload.keys - [:response]).each do |source|
|
17
|
+
ratio = ratio(payload[:response], payload[source])
|
18
|
+
|
19
|
+
if ratio < IoMonitor.config.warn_threshold
|
20
|
+
publish(source, ratio)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def ratio(response_size, io_size)
|
28
|
+
response_size.to_f / io_size.to_f
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module IoMonitor
|
4
|
+
class LogsPublisher < BasePublisher
|
5
|
+
def self.kind
|
6
|
+
:logs
|
7
|
+
end
|
8
|
+
|
9
|
+
def publish(source, ratio)
|
10
|
+
Rails.logger.warn <<~HEREDOC.squish
|
11
|
+
#{source.to_s.camelize} I/O to response payload ratio is #{ratio},
|
12
|
+
while threshold is #{IoMonitor.config.warn_threshold}
|
13
|
+
HEREDOC
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module IoMonitor
|
4
|
+
class NotificationsPublisher < BasePublisher
|
5
|
+
WARN_THRESHOLD_REACHED_EVENT = "warn_threshold_reached"
|
6
|
+
|
7
|
+
def self.kind
|
8
|
+
:notifications
|
9
|
+
end
|
10
|
+
|
11
|
+
def publish(source, ratio)
|
12
|
+
ActiveSupport::Notifications.instrument(
|
13
|
+
full_event_name(WARN_THRESHOLD_REACHED_EVENT),
|
14
|
+
source: source,
|
15
|
+
ratio: ratio
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def full_event_name(event_name)
|
22
|
+
"#{event_name}.#{IoMonitor::NAMESPACE}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "io_monitor/patches/action_controller_base_patch"
|
4
|
+
|
5
|
+
module IoMonitor
|
6
|
+
class Railtie < Rails::Railtie
|
7
|
+
config.after_initialize do
|
8
|
+
IoMonitor.config.adapters.each(&:initialize!)
|
9
|
+
|
10
|
+
ActiveSupport.on_load(:action_controller) do
|
11
|
+
ActionController::Base.singleton_class.prepend(ActionControllerBasePatch)
|
12
|
+
end
|
13
|
+
|
14
|
+
ActiveSupport::Notifications.subscribe("process_action.action_controller") do |*args|
|
15
|
+
payload = args.last[IoMonitor::NAMESPACE]
|
16
|
+
next unless payload
|
17
|
+
|
18
|
+
IoMonitor.config.publisher.process_action(payload)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/io_monitor.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "io_monitor/version"
|
4
|
+
require "io_monitor/configuration"
|
5
|
+
require "io_monitor/aggregator"
|
6
|
+
require "io_monitor/controller"
|
7
|
+
|
8
|
+
require "io_monitor/adapters/base_adapter"
|
9
|
+
require "io_monitor/adapters/active_record_adapter"
|
10
|
+
require "io_monitor/adapters/net_http_adapter"
|
11
|
+
|
12
|
+
require "io_monitor/publishers/base_publisher"
|
13
|
+
require "io_monitor/publishers/logs_publisher"
|
14
|
+
require "io_monitor/publishers/notifications_publisher"
|
15
|
+
|
16
|
+
require "io_monitor/railtie"
|
17
|
+
|
18
|
+
module IoMonitor
|
19
|
+
NAMESPACE = :io_monitor
|
20
|
+
ADAPTERS = [ActiveRecordAdapter, NetHttpAdapter].freeze
|
21
|
+
PUBLISHERS = [LogsPublisher, NotificationsPublisher].freeze
|
22
|
+
|
23
|
+
class << self
|
24
|
+
def aggregator
|
25
|
+
@aggregator ||= Aggregator.new(
|
26
|
+
config.adapters.map { |a| a.class.kind }
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
def config
|
31
|
+
@config ||= Configuration.new
|
32
|
+
end
|
33
|
+
|
34
|
+
def configure
|
35
|
+
yield config
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: io_monitor
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- baygeldin
|
8
|
+
- prog-supdex
|
9
|
+
- maxshend
|
10
|
+
- DmitryTsepelev
|
11
|
+
autorequire:
|
12
|
+
bindir: bin
|
13
|
+
cert_chain: []
|
14
|
+
date: 2022-05-23 00:00:00.000000000 Z
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: rails
|
18
|
+
requirement: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '6.0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '6.0'
|
30
|
+
description:
|
31
|
+
email:
|
32
|
+
- dmitry.a.tsepelev@gmail.com
|
33
|
+
executables: []
|
34
|
+
extensions: []
|
35
|
+
extra_rdoc_files: []
|
36
|
+
files:
|
37
|
+
- CHANGELOG.md
|
38
|
+
- LICENSE.txt
|
39
|
+
- README.md
|
40
|
+
- lib/io_monitor.rb
|
41
|
+
- lib/io_monitor/adapters/active_record_adapter.rb
|
42
|
+
- lib/io_monitor/adapters/base_adapter.rb
|
43
|
+
- lib/io_monitor/adapters/net_http_adapter.rb
|
44
|
+
- lib/io_monitor/aggregator.rb
|
45
|
+
- lib/io_monitor/configuration.rb
|
46
|
+
- lib/io_monitor/controller.rb
|
47
|
+
- lib/io_monitor/patches/abstract_adapter_patch.rb
|
48
|
+
- lib/io_monitor/patches/action_controller_base_patch.rb
|
49
|
+
- lib/io_monitor/patches/future_result_patch.rb
|
50
|
+
- lib/io_monitor/patches/net_http_adapter_patch.rb
|
51
|
+
- lib/io_monitor/publishers/base_publisher.rb
|
52
|
+
- lib/io_monitor/publishers/logs_publisher.rb
|
53
|
+
- lib/io_monitor/publishers/notifications_publisher.rb
|
54
|
+
- lib/io_monitor/railtie.rb
|
55
|
+
- lib/io_monitor/version.rb
|
56
|
+
homepage: https://github.com/DmitryTsepelev/io_monitor
|
57
|
+
licenses:
|
58
|
+
- MIT
|
59
|
+
metadata:
|
60
|
+
bug_tracker_uri: https://github.com/DmitryTsepelev/io_monitor/issues
|
61
|
+
changelog_uri: https://github.com/DmitryTsepelev/io_monitor/blob/master/CHANGELOG.md
|
62
|
+
documentation_uri: https://github.com/DmitryTsepelev/io_monitor/blob/master/README.md
|
63
|
+
homepage_uri: https://github.com/DmitryTsepelev/io_monitor
|
64
|
+
source_code_uri: https://github.com/DmitryTsepelev/io_monitor
|
65
|
+
post_install_message:
|
66
|
+
rdoc_options: []
|
67
|
+
require_paths:
|
68
|
+
- lib
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: 2.6.0
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
requirements: []
|
80
|
+
rubygems_version: 3.2.33
|
81
|
+
signing_key:
|
82
|
+
specification_version: 4
|
83
|
+
summary: A gem that helps to detect potential memory bloats
|
84
|
+
test_files: []
|