kenny 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 39b86e8b4853fcce4fcb7d38127b6f59321c5b17
4
+ data.tar.gz: c75ef30aede10e34de737316384e5d5b4badc120
5
+ SHA512:
6
+ metadata.gz: ba32367e5f63c0f2577cb0895ac85d8a5dc97bfc99669bc7bcb08eca0082c6bda5a383784cd2d131a3ead4c66803a6281eb08fd54cf3c327d15f4802ab8e6126
7
+ data.tar.gz: c66a0f075bb3369eef09529e632b71ea6d3f56b076f05e3c8286358662bcbff9b23cbde9233511a5d655e77f2e427df82a9b24e1dc84d2944442ad1f6a3a0154
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (C) 2016 FromAtoB.com http://fromatob.com
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7
+ of the Software, and to permit persons to whom the Software is furnished to do
8
+ so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,184 @@
1
+ # Kenny
2
+ Inspired by [lograge](https://github.com/roidrage/lograge), but without the rage. And logs are optional.
3
+
4
+ Lograge does a great job in suppressing Rails' log output, it does so by:
5
+ - overriding Rails' default behaviour for instrumentations/subscriptions
6
+ - being very opinionated, hence removing a lot of data from your log.
7
+
8
+ As a result, even though Lograge is great for cleaning your production.log, it is neither meant for collecting metrics nor great for plugging into any instrumentation event that you want.
9
+
10
+ Kenny attempts to leave implementations to the user and provide a more modular way to monitor instrumentation events.
11
+ It allows the user to decide:
12
+ - which instrumentations to monitor
13
+ - what to do when the specified instrumentation event occurs
14
+ - where to log the data to (or no logging to file at all)
15
+ - whether or not to unsubscribe from Rails' default instrumentations (although not recommended)
16
+
17
+ Apart from that, it was also created with the idea of keeping all subscribed events in one place. So it will keep your code clean and provide a nice overview of all event-triggered actions.
18
+
19
+ Best to be explained with an example.
20
+
21
+ ## Installation
22
+
23
+ Gemfile:
24
+
25
+ ```ruby
26
+ gem 'kenny'
27
+ ```
28
+
29
+ And then execute:
30
+
31
+ $ bundle
32
+
33
+ Or command line:
34
+
35
+ $ gem install kenny
36
+
37
+ ## Usage
38
+ Kenny can be configured through an initializer (`config/initializers/kenny.rb`) or within the configuration file of your environment `development|test|staging|production.rb`.
39
+ This depends on whether you want to have the same behaviour or different behaviours accross environments.
40
+
41
+ If you do configure Kenny through an initializer, then it would give you the advantage of keeping all your instrumentation configurations in one place.
42
+
43
+ Here is an example, its details will be explained in the following paragraphs.
44
+
45
+ ```ruby
46
+ # Example
47
+ MyApp::Application.configure do
48
+ # Define a logger-instance with formatter to be used later
49
+ request_logger = ActiveSupport::Logger.new( File.join(Rails.root, "log", "process_action.log") )
50
+ log_stash_formatter = Kenny::Formatters::LogStashFormatter.new
51
+ request_logger.formatter = log_stash_formatter
52
+
53
+ config.kenny.unsubscribe_rails_defaults = false
54
+ config.kenny.suppress_rack_logger = true
55
+ config.kenny.instrumentations = [
56
+ { name: 'process_action.action_controller',
57
+ block: lambda do |event|
58
+ data = MyDataBuilder.build(event)
59
+ logger.info("#{event.name}: #{data}")
60
+ end,
61
+ logger: request_logger
62
+ },
63
+ { name: 'sql.active_record',
64
+ block: lambda do |event|
65
+ data = event.payload
66
+ Rails.logger.info("#{event.name}: #{data}")
67
+ end
68
+ }
69
+ ]
70
+
71
+ end
72
+
73
+ ```
74
+
75
+
76
+ ### `kenny.instrumentations` configuration
77
+ Before proceeding, have a look at [Active Support Instrumentation](http://edgeguides.rubyonrails.org/active_support_instrumentation.html) and [LogSubscriber](http://api.rubyonrails.org/classes/ActiveSupport/LogSubscriber.html)
78
+
79
+ The `kenny.instrumentations` configuration takes an array of hashes. Each hash represents a Rails instrumentation event that you want to subscribe to.
80
+
81
+ Each of these hashes requires a `:name` (name of instrumentation event), a `:block` (what to do when that event occurs) and *optionally* a `:logger` (which logger to use in order to write these events to a file).
82
+
83
+ In the example above, we setup Kenny to monitor two instrumentation events, `process_action.action_controller` and `sql.active_record`.
84
+
85
+ Behind the scenes, it defines an anonymous class (< ActiveSupport::LogSubscriber) for each of the specified instrumentations.
86
+
87
+ The first one gets method `def process_action` defined and `def logger` *redefined*.
88
+
89
+ The body of `def process_action` is the `:block` that has been supplied to the configuration.
90
+ Hence, `:block` must be a Lambda or a Proc.
91
+ (Lambda will raise errors with wrong number of arguments, Proc won't)
92
+
93
+ The `def logger` method (in ActiveSupport::LogSubscriber) gets overridden and will return the logger-instance that you have provided to the configuration. (In this case, it's the logger instance `request_logger` that you have defined at the top of your config).
94
+
95
+ This class is then attached to :action_controller, by looking up the event name 'process_action.action_controller'
96
+
97
+ The idea of redefining `def logger` may sound a bit scary, but this is necessary to keep events from
98
+ different instrumentation channels on different log files. If `:logger` option is not provided, then that LogSubscriber class will use the default Rails logger (and hence write to your production.log etc)
99
+
100
+ The second LogSubscriber class will have method `def start_processing` defined and the method body is again what has been supplied in the :block configuration.
101
+
102
+ The difference is that `:logger` has not been provided, hence it won't override the logger method for this LogSubscriber. In Rails, this means it will fall back to the default `Rails.logger`.
103
+ Mind you that even though a LogSubscriber has access to a logger, it does not mean you have to use it! There is nothing wrong with subscribing to an event and not log its data to file at all! There are other things you could do with this data.
104
+ At the end, this class gets attached to :active_record, by looking up the event name 'sql.active_record'
105
+
106
+ #### Be careful with variable scopes and lambdas
107
+ Since lambdas are used to define method bodies, be careful with context of variables.
108
+ Take the example below:
109
+
110
+ ``` Ruby
111
+ # Somewhere above the instrumentation configurations
112
+ logger = ActiveSupport::Logger.new( File.join(Rails.root, "log", "process_action.log") )
113
+
114
+ # Then within the instrumentation configuration
115
+ config.kenny.instrumentations = [
116
+ { name: 'sql.active_record',
117
+ block: lambda do |event|
118
+ data = event.payload
119
+ logger.info("#{event.name}: #{data}")
120
+ end
121
+ }
122
+ ]
123
+ ```
124
+
125
+ You might think that since no `:logger` option has been provided for 'sql.active_record' events, the default logger will be used..... But that is not true.
126
+ Since `logger` is within scope at the time when the lambda was defined, this instance of ActiveSupport::Logger will be used to invoke `#info` when 'sql.active_record' occurs. So just avoid creating a local variable that have the same name as variables in your block.
127
+
128
+
129
+ ### `kenny.unsubscribe_rails_defaults` configuration
130
+ Kenny can also used to unsubscribe all Rails LogSubscribers from their subscribed instrumentation events.
131
+ You can do that by setting `:unsubscribe_rails_defaults` to true:
132
+
133
+ ``` Ruby
134
+ config.kenny.unsubscribe_rails_defaults = true
135
+ config.kenny.instrumentations = [{
136
+ # your stuff
137
+ }]
138
+ }
139
+ ```
140
+
141
+ By doing so, your `development|test|staging|production.log` will not have any of the default log messages. This is not an approach I would recommend, unless you are desperate to have all messages from your specified instrumentation events all logged into one `development|test|staging|production.log`.
142
+
143
+
144
+ ### `kenny.suppress_rack_logger` configuration
145
+ By default, your rails app logs messages like these to your environment's log:
146
+
147
+ ```
148
+ Started GET "/my_path" for 10.0.2.2 at 2016-07-12 10:06:48 +0000
149
+ Started GET "/assets/sh/my_styles.css?body=1" for 10.0.2.2 at 2016-07-12 10:06:49 +0000
150
+ ```
151
+
152
+ You can suppress these messages by setting kenny.suppress_rack_logger to true.
153
+ This setting will not have any effects on the log files that you create separately with the `:logger` option within your specified instrumentation.
154
+
155
+ ## Open-to-Implementation approach
156
+ As you might have seen from the example, the `:block` allows you to define your own implementation.
157
+ The idea behind writing this gem is to free up users from the tedious task of defining LogSubscriber classes and to allow them to define whatever they wants to do with the event data, be it something like:
158
+
159
+ ```Ruby
160
+ config.kenny.instrumentations = [
161
+ { name: 'process_action.action_controller',
162
+ block: lambda do |event|
163
+ data = MyDataBuilder.build(event)
164
+ # Use Fluent to send data to another server
165
+ Fluent::Logger::FluentLogger.open(nil, :host=>MY_SERVER, :port=>24224)
166
+ Fluent::Logger.post('web_requests', data)
167
+ end
168
+ },
169
+ { name: 'sql.active_record',
170
+ block: lambda do |event|
171
+ data = MyDataBuilder.build(event)
172
+ # Do something asynchronously, maybe send to an external service
173
+ Something.async.process_and_forward(data)
174
+ end
175
+ }
176
+ ]
177
+ ```
178
+
179
+ Again, there is no requirement for you to write messages to log files. It is all up to you.
180
+
181
+ ## Formatters
182
+ Apart from subscribing to instrumentation events and logging, Kenny also provides formatters, which you can attach to a logger.
183
+
184
+ Currently, it only comes with a LogStashFormatter, but feel free to add more Formatters to make this project great.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,30 @@
1
+ require 'logger'
2
+ require 'logstash-event'
3
+ require 'active_support'
4
+
5
+ module Kenny
6
+ module Formatters
7
+ class LogStashFormatter < ::Logger::Formatter
8
+
9
+ include ActiveSupport::TaggedLogging::Formatter
10
+
11
+ def call(severity, time, progname, msg)
12
+ msg = { 'message' => msg.is_a?(String) ? msg : msg.inspect } unless msg.is_a?(Hash)
13
+
14
+ msg['severity'] = severity if severity
15
+ msg['progname'] = progname if progname
16
+
17
+ tags = current_tags
18
+
19
+ if tags.size > 0
20
+ msg['type'] ||= tags.first
21
+ msg['tags'] = tags
22
+ end
23
+
24
+ event = LogStash::Event.new(msg)
25
+
26
+ "%s\n" % event.to_json
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,11 @@
1
+ ##
2
+ # This class is meant to be inherited by anonymous classes,
3
+ # created through Kenny.define_log_subscriber_class.
4
+ #
5
+ # By inserting this class into the inheritance tree,
6
+ # we can verify in test-environment whether the LogSubscribers
7
+ # we created are indeed attached to the instrumentations we specified.
8
+ module Kenny
9
+ class LogSubscriber < ActiveSupport::LogSubscriber
10
+ end
11
+ end
@@ -0,0 +1,25 @@
1
+ require 'active_support/concern'
2
+ require 'rails/rack/logger'
3
+
4
+ module Rails
5
+ module Rack
6
+ # Overwrites defaults of Rails::Rack::Logger that cause
7
+ # unnecessary logging.
8
+ # This effectively removes the log lines from the log
9
+ # that say:
10
+ # Started GET / for 192.168.2.1...
11
+ class Logger
12
+ # Overwrites Rails 3.2 code that logs new requests
13
+ def call_app(*args)
14
+ env = args.last
15
+ @app.call(env)
16
+ ensure
17
+ ActiveSupport::LogSubscriber.flush_all!
18
+ end
19
+
20
+ # Overwrites Rails 3.0/3.1 code that logs new requests
21
+ def before_dispatch(_env)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,27 @@
1
+ require 'rails/railtie'
2
+ require 'action_view/log_subscriber'
3
+ require 'action_controller/log_subscriber'
4
+ require 'active_record/log_subscriber'
5
+ require 'action_mailer/log_subscriber'
6
+
7
+ module Kenny
8
+ class Railtie < Rails::Railtie
9
+ config.kenny = Kenny.configs
10
+
11
+ config.after_initialize do |app|
12
+ Kenny.application = app
13
+
14
+ # Define anonymous classes that inherit from ActiveSupport::LogSubscriber.
15
+ # Within that anonymous class, define methods that
16
+ # perform the user-defined actions when that instrumentation occurs.
17
+ # If desired, user can define a specific logger for the specified instrumentation.
18
+ Kenny.attach_to_instrumentations
19
+
20
+ # Unsubscribe all default Rails LogSubscribers if demanded
21
+ Kenny.unsubscribe_from_rails_defaults
22
+
23
+ # Suppress Rails::Rack::Logger's output
24
+ Kenny.suppress_rack_logger
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,60 @@
1
+ ##
2
+ # Module to unsubscribe all Rails default LogSubscribers from their events.
3
+ module Kenny
4
+ module Unsubscriber
5
+ DEFAULT_RAILS_LOG_SUBSCRIBER_CLASSES = [
6
+ ActionView::LogSubscriber,
7
+ ActionController::LogSubscriber,
8
+ ActiveRecord::LogSubscriber,
9
+ ActionMailer::LogSubscriber
10
+ ]
11
+
12
+ ##
13
+ # By default, a Rails app instantiates the LogSubscribers listed above and
14
+ # are actively listening to instrumentations listed in:
15
+ # http://edgeguides.rubyonrails.org/active_support_instrumentation.html
16
+ #
17
+ # Unsubscribing is not recommended, unless you want to modify the output
18
+ # to your standard rails logs (development|test|staging|production).log
19
+ #
20
+ # It would be safer to write your chosen instrumentation data to a separate file,
21
+ # setup by the [:logger] configuration (see Readme). In that case, the [:unsubscribe_rails_defaults]
22
+ # field in Kenny's config won't need to be set.
23
+ def self.unsubscribe_from_rails_defaults
24
+ default_rails_log_subscribers.each do |subscriber|
25
+ subscribed_events_for(subscriber).each do |event|
26
+ unsubscribe_listeners_for_event(subscriber, event)
27
+ end
28
+ end
29
+ end
30
+
31
+ def self.default_rails_log_subscribers
32
+ ActiveSupport::LogSubscriber.log_subscribers.select do |subscriber|
33
+ DEFAULT_RAILS_LOG_SUBSCRIBER_CLASSES.include? subscriber.class
34
+ end
35
+ end
36
+ private_class_method :default_rails_log_subscribers
37
+
38
+ def self.listeners_for(event, subscriber_namespace)
39
+ ActiveSupport::Notifications.notifier.listeners_for("#{event}.#{subscriber_namespace}")
40
+ end
41
+ private_class_method :listeners_for
42
+
43
+ def self.unsubscribe_listeners_for_event(subscriber, event)
44
+ subscriber_namespace = subscriber.class.send :namespace
45
+ listeners_for(event, subscriber_namespace).each do |listener|
46
+ if listener.instance_variable_get('@delegate') == subscriber
47
+ ActiveSupport::Notifications.unsubscribe listener
48
+ end
49
+ end
50
+ end
51
+ private_class_method :unsubscribe_listeners_for_event
52
+
53
+ def self.subscribed_events_for(subscriber)
54
+ error_msg = "Expected #{subscriber} to be inherited from ActiveSupport::LogSubscriber"
55
+ raise error_msg if subscriber.class.superclass != ActiveSupport::LogSubscriber
56
+ subscriber.public_methods(false).reject { |method| method.to_s == 'call' }
57
+ end
58
+ private_class_method :subscribed_events_for
59
+ end
60
+ end
data/lib/kenny.rb ADDED
@@ -0,0 +1,84 @@
1
+ ##
2
+ # Kenny module does three things:
3
+ # - Holds reference to the Rails application (set through Railtie)
4
+ # - Unsubscribe all Rails' LogSubscribers from the default instrumentation channels
5
+ # - Create LogSubscriber-classes which will be attached to the user-specified instrumentations
6
+
7
+ module Kenny
8
+
9
+ def self.configs
10
+ Struct.new(
11
+ :unsubscribe_rails_defaults,
12
+ :suppress_rack_logger,
13
+ :instrumentations
14
+ ).new
15
+ end
16
+
17
+ def self.application=(app)
18
+ @@application = app
19
+ end
20
+
21
+ def self.application
22
+ @@application
23
+ end
24
+
25
+ ##
26
+ # Define LogSubscriber-classes and Attach to user-specified instrumentations
27
+ # if the configurations have been set.
28
+ def self.attach_to_instrumentations
29
+ if @@application.config.kenny[:instrumentations]
30
+ @@application.config.kenny[:instrumentations].each do |instr_config|
31
+ define_log_subscriber_class(instr_config)
32
+ end
33
+ end
34
+ end
35
+
36
+ ##
37
+ # Unsubscribe all Rails' default LogSubscribers from the default Rails instrumentations,
38
+ # by delegating to Kenny::Unsubscriber.
39
+ # See http://edgeguides.rubyonrails.org/active_support_instrumentation.html
40
+ def self.unsubscribe_from_rails_defaults
41
+ if @@application.config.kenny[:unsubscribe_rails_defaults]
42
+ Kenny::Unsubscriber.unsubscribe_from_rails_defaults
43
+ end
44
+ end
45
+
46
+ ##
47
+ # Suppress Rails::Rack::Logger's output à la
48
+ # Started GET "/my_path" for 10.0.2.2 at 2016-07-12 10:06:48 +0000
49
+ def self.suppress_rack_logger
50
+ if @@application.config.kenny[:suppress_rack_logger]
51
+ require "kenny/rails_ext/rack/logger"
52
+ end
53
+ end
54
+
55
+ ##
56
+ # Create LogSubscriber-classes which will be attached to the user-specified instrumentations
57
+ # These classes are anonymous, but inherit from Kenny::LogSubscriber to simplify testing
58
+ #
59
+ # Within these classes, methods (and potentially `def logger`) are defined based on the
60
+ # instrumentations-configs provided by the user.
61
+ def self.define_log_subscriber_class(instr_config)
62
+ klass = Class.new(Kenny::LogSubscriber) do |k|
63
+ define_method( instr_config[:name].split(".")[0], instr_config[:block] )
64
+
65
+ if instr_config[:logger]
66
+ # Following assignment needed as we don't want to have
67
+ # the lambda being re-evaluated and possibly return
68
+ # a new logger instance everytime the .logger method is invoked.
69
+ defined_logger = instr_config[:logger]
70
+ define_method(:logger, lambda{defined_logger})
71
+ end
72
+
73
+ end
74
+ klass.attach_to instr_config[:name].split(".")[1].to_sym
75
+ end
76
+ private_class_method :define_log_subscriber_class
77
+
78
+ end
79
+
80
+ require "kenny/railtie"
81
+
82
+ require "kenny/formatters/log_stash_formatter"
83
+ require "kenny/unsubscriber"
84
+ require "kenny/log_subscriber"
metadata ADDED
@@ -0,0 +1,219 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kenny
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Mathias Rüdiger, Alex Fong
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-07-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.12'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.12'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.10'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.10'
69
+ - !ruby/object:Gem::Dependency
70
+ name: actionpack
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '4.2'
76
+ - - "<"
77
+ - !ruby/object:Gem::Version
78
+ version: '5.1'
79
+ type: :runtime
80
+ prerelease: false
81
+ version_requirements: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: '4.2'
86
+ - - "<"
87
+ - !ruby/object:Gem::Version
88
+ version: '5.1'
89
+ - !ruby/object:Gem::Dependency
90
+ name: activerecord
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '4.2'
96
+ - - "<"
97
+ - !ruby/object:Gem::Version
98
+ version: '5.1'
99
+ type: :runtime
100
+ prerelease: false
101
+ version_requirements: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '4.2'
106
+ - - "<"
107
+ - !ruby/object:Gem::Version
108
+ version: '5.1'
109
+ - !ruby/object:Gem::Dependency
110
+ name: actionmailer
111
+ requirement: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: '4.2'
116
+ - - "<"
117
+ - !ruby/object:Gem::Version
118
+ version: '5.1'
119
+ type: :runtime
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '4.2'
126
+ - - "<"
127
+ - !ruby/object:Gem::Version
128
+ version: '5.1'
129
+ - !ruby/object:Gem::Dependency
130
+ name: activesupport
131
+ requirement: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - "~>"
134
+ - !ruby/object:Gem::Version
135
+ version: '4.2'
136
+ type: :runtime
137
+ prerelease: false
138
+ version_requirements: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - "~>"
141
+ - !ruby/object:Gem::Version
142
+ version: '4.2'
143
+ - !ruby/object:Gem::Dependency
144
+ name: railties
145
+ requirement: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - ">="
148
+ - !ruby/object:Gem::Version
149
+ version: '4.2'
150
+ - - "<"
151
+ - !ruby/object:Gem::Version
152
+ version: '5.1'
153
+ type: :runtime
154
+ prerelease: false
155
+ version_requirements: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '4.2'
160
+ - - "<"
161
+ - !ruby/object:Gem::Version
162
+ version: '5.1'
163
+ - !ruby/object:Gem::Dependency
164
+ name: logstash-event
165
+ requirement: !ruby/object:Gem::Requirement
166
+ requirements:
167
+ - - '='
168
+ - !ruby/object:Gem::Version
169
+ version: 1.2.02
170
+ type: :runtime
171
+ prerelease: false
172
+ version_requirements: !ruby/object:Gem::Requirement
173
+ requirements:
174
+ - - '='
175
+ - !ruby/object:Gem::Version
176
+ version: 1.2.02
177
+ description: Kenny acts as a one-stop destination for defining which Rails instrumentations
178
+ you want to monitor and what to do when they occur.
179
+ email:
180
+ - mathias.ruediger@fromatob.com, alex.fong@fromatob.com
181
+ executables: []
182
+ extensions: []
183
+ extra_rdoc_files: []
184
+ files:
185
+ - Gemfile
186
+ - LICENSE
187
+ - README.md
188
+ - Rakefile
189
+ - lib/kenny.rb
190
+ - lib/kenny/formatters/log_stash_formatter.rb
191
+ - lib/kenny/log_subscriber.rb
192
+ - lib/kenny/rails_ext/rack/logger.rb
193
+ - lib/kenny/railtie.rb
194
+ - lib/kenny/unsubscriber.rb
195
+ homepage: https://github.com/fromAtoB/kenny
196
+ licenses:
197
+ - MIT
198
+ metadata: {}
199
+ post_install_message:
200
+ rdoc_options: []
201
+ require_paths:
202
+ - lib
203
+ required_ruby_version: !ruby/object:Gem::Requirement
204
+ requirements:
205
+ - - ">="
206
+ - !ruby/object:Gem::Version
207
+ version: '0'
208
+ required_rubygems_version: !ruby/object:Gem::Requirement
209
+ requirements:
210
+ - - ">="
211
+ - !ruby/object:Gem::Version
212
+ version: '0'
213
+ requirements: []
214
+ rubyforge_project:
215
+ rubygems_version: 2.5.1
216
+ signing_key:
217
+ specification_version: 4
218
+ summary: Monitor and act upon Rails instrumentation events.
219
+ test_files: []