logstasher 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.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 1.9.2
5
+ script: bundle exec rspec
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in logstasher.gemspec
4
+ gemspec
5
+
6
+ group :test do
7
+ gem 'actionpack'
8
+ gem 'logstash-event'
9
+ end
@@ -0,0 +1,9 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec', :version => 2 do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ end
9
+
@@ -0,0 +1,3 @@
1
+ Logstasher - Awesome rails logs
2
+ =======
3
+
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,52 @@
1
+ require 'logstasher/version'
2
+ require 'logstasher/log_subscriber'
3
+ require 'active_support/core_ext/module/attribute_accessors'
4
+ require 'active_support/core_ext/string/inflections'
5
+ require 'active_support/ordered_options'
6
+
7
+ module Logstasher
8
+ # Logger for the logstash logs
9
+ mattr_accessor :logger, :enabled
10
+
11
+ # Set the options for the adding cutom data to payload
12
+ mattr_accessor :payload_appender
13
+
14
+ def self.append_payload(&block)
15
+ self.payload_appender = block
16
+ end
17
+
18
+ def self.remove_existing_log_subscriptions
19
+ ActiveSupport::LogSubscriber.log_subscribers.each do |subscriber|
20
+ case subscriber
21
+ when ActionView::LogSubscriber
22
+ unsubscribe(:action_view, subscriber)
23
+ when ActionController::LogSubscriber
24
+ unsubscribe(:action_controller, subscriber)
25
+ end
26
+ end
27
+ end
28
+
29
+ def self.unsubscribe(component, subscriber)
30
+ events = subscriber.public_methods(false).reject{ |method| method.to_s == 'call' }
31
+ events.each do |event|
32
+ ActiveSupport::Notifications.notifier.listeners_for("#{event}.#{component}").each do |listener|
33
+ if listener.instance_variable_get('@delegate') == subscriber
34
+ ActiveSupport::Notifications.unsubscribe listener
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ def self.setup(app)
41
+ Logstasher.enabled = true
42
+ app.config.action_dispatch.rack_cache[:verbose] = false if app.config.action_dispatch.rack_cache
43
+ require 'logstasher/rails_ext/rack/logger'
44
+ require 'logstasher/rails_ext/action_controller/metal/instrumentation'
45
+ require 'logstash/event'
46
+ Logstasher.remove_existing_log_subscriptions
47
+ Logstasher::RequestLogSubscriber.attach_to :action_controller
48
+ self.logger = app.config.logstasher.logger || Logger.new("#{Rails.root}/log/logstash.log")
49
+ end
50
+ end
51
+
52
+ require 'logstasher/railtie' if defined?(Rails)
@@ -0,0 +1,92 @@
1
+ require 'active_support/core_ext/class/attribute'
2
+ require 'active_support/log_subscriber'
3
+
4
+ module Logstasher
5
+ class RequestLogSubscriber < ActiveSupport::LogSubscriber
6
+ def process_action(event)
7
+ payload = event.payload
8
+
9
+ data = extract_request(payload)
10
+ data.merge! extract_status(payload)
11
+ data.merge! runtimes(event)
12
+ data.merge! location(event)
13
+ data.merge! extract_exception(payload)
14
+ data.merge! extract_appended_params(payload)
15
+
16
+ event = LogStash::Event.new("@fields" => data)
17
+ Logstasher.logger.info event.to_json
18
+ end
19
+
20
+ def redirect_to(event)
21
+ Thread.current[:logstasher_location] = event.payload[:location]
22
+ end
23
+
24
+ private
25
+
26
+ def extract_request(payload)
27
+ {
28
+ :method => payload[:method],
29
+ :path => extract_path(payload),
30
+ :format => extract_format(payload),
31
+ :controller => payload[:controller],
32
+ :action => payload[:action]
33
+ }
34
+ end
35
+
36
+ def extract_path(payload)
37
+ payload[:path].split("?").first
38
+ end
39
+
40
+ def extract_format(payload)
41
+ if ::ActionPack::VERSION::MAJOR == 3 && ::ActionPack::VERSION::MINOR == 0
42
+ payload[:formats].first
43
+ else
44
+ payload[:format]
45
+ end
46
+ end
47
+
48
+ def extract_status(payload)
49
+ if payload[:status]
50
+ { :status => payload[:status].to_i }
51
+ else
52
+ {}
53
+ end
54
+ end
55
+
56
+ def runtimes(event)
57
+ {
58
+ :duration => event.duration,
59
+ :view => event.payload[:view_runtime],
60
+ :db => event.payload[:db_runtime]
61
+ }.inject({}) do |runtimes, (name, runtime)|
62
+ runtimes[name] = runtime.to_f.round(2) if runtime
63
+ runtimes
64
+ end
65
+ end
66
+
67
+ def location(event)
68
+ if location = Thread.current[:logstasher_location]
69
+ Thread.current[:logstasher_location] = nil
70
+ { :location => location }
71
+ else
72
+ {}
73
+ end
74
+ end
75
+
76
+ # Monkey patching to enable exception logging
77
+ def extract_exception(payload)
78
+ if payload[:exception]
79
+ exception, message = payload[:exception]
80
+ message = "#{exception} : #{message}\n #{($!.backtrace.join("\n"))}"
81
+ { :status => 500, :error => message }
82
+ else
83
+ {}
84
+ end
85
+ end
86
+
87
+ def extract_appended_params(payload)
88
+ appended_keys = payload.delete(:log_stasher_appended_param_keys)
89
+ (appended_keys && payload.extract!(*appended_keys)) || {}
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,31 @@
1
+ module ActionController
2
+ module Instrumentation
3
+ def process_action(*args)
4
+ raw_payload = {
5
+ :controller => self.class.name,
6
+ :action => self.action_name,
7
+ :params => request.filtered_parameters,
8
+ :format => request.format.try(:ref),
9
+ :method => request.method,
10
+ :path => (request.fullpath rescue "unknown")
11
+ }
12
+
13
+ if Logstasher.payload_appender
14
+ before_keys = raw_payload.keys.clone
15
+ Logstasher.payload_appender.call(self, request, raw_payload)
16
+ after_keys = raw_payload.keys
17
+ raw_payload[:log_stasher_appended_param_keys] = after_keys - before_keys
18
+ end
19
+
20
+ ActiveSupport::Notifications.instrument("start_processing.action_controller", raw_payload.dup)
21
+
22
+ ActiveSupport::Notifications.instrument("process_action.action_controller", raw_payload) do |payload|
23
+ result = super
24
+ payload[:status] = response.status
25
+ append_info_to_payload(payload)
26
+ result
27
+ end
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,24 @@
1
+ require 'rails/rack/logger'
2
+
3
+ module Rails
4
+ module Rack
5
+ # Overwrites defaults of Rails::Rack::Logger that cause
6
+ # unnecessary logging.
7
+ # This effectively removes the log lines from the log
8
+ # that say:
9
+ # Started GET / for 192.168.2.1...
10
+ class Logger
11
+ # Overwrites Rails 3.2 code that logs new requests
12
+ def call_app(*args)
13
+ env = args.last
14
+ @app.call(env)
15
+ ensure
16
+ ActiveSupport::LogSubscriber.flush_all!
17
+ end
18
+
19
+ # Overwrites Rails 3.0/3.1 code that logs new requests
20
+ def before_dispatch(env)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,14 @@
1
+ require 'rails/railtie'
2
+ require 'action_view/log_subscriber'
3
+ require 'action_controller/log_subscriber'
4
+
5
+ module Logstasher
6
+ class Railtie < Rails::Railtie
7
+ config.logstasher = ActiveSupport::OrderedOptions.new
8
+ config.logstasher.enabled = false
9
+
10
+ initializer :logstasher do |app|
11
+ Logstasher.setup(app) if app.config.logstasher.enabled
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ module Logstasher
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "logstasher/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "logstasher"
7
+ s.version = Logstasher::VERSION
8
+ s.authors = ["Shadab Ahmed"]
9
+ s.email = ["shadab.ansari@gmail.com"]
10
+ s.homepage = "https://github.com/shadabahmed/logstasher"
11
+ s.summary = %q{Awesome rails logs}
12
+ s.description = %q{Awesome rails logs}
13
+
14
+ s.rubyforge_project = "logstasher"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+ s.add_runtime_dependency "logstash-event"
21
+
22
+ # specify any dependencies here; for example:
23
+ s.add_development_dependency "rspec"
24
+ s.add_development_dependency "guard-rspec"
25
+ s.add_runtime_dependency "activesupport"
26
+ s.add_runtime_dependency "actionpack"
27
+ end
@@ -0,0 +1,350 @@
1
+ require 'spec_helper'
2
+ require 'logstasher'
3
+ require 'logstasher/log_subscriber'
4
+ require 'active_support/notifications'
5
+ require 'active_support/core_ext/string'
6
+ require 'logger'
7
+
8
+ describe Logstasher::RequestLogSubscriber do
9
+ let(:log_output) {StringIO.new}
10
+ let(:logger) {
11
+ logger = Logger.new(log_output)
12
+ logger.formatter = ->(_, _, _, msg) {
13
+ msg
14
+ }
15
+ logger
16
+ }
17
+ before do
18
+ Logstasher::RequestLogSubscriber.logger = logger
19
+ end
20
+
21
+ let(:subscriber) {Logstasher::RequestLogSubscriber.new}
22
+ let(:event) {
23
+ ActiveSupport::Notifications::Event.new(
24
+ 'process_action.action_controller', Time.now, Time.now, 2, {
25
+ status: 200, format: 'application/json', method: 'GET', path: '/home?foo=bar', params: {
26
+ 'controller' => 'home', 'action' => 'index', 'foo' => 'bar'
27
+ }, db_runtime: 0.02, view_runtime: 0.01
28
+ }
29
+ )
30
+ }
31
+
32
+ let(:redirect) {
33
+ ActiveSupport::Notifications::Event.new(
34
+ 'redirect_to.action_controller', Time.now, Time.now, 1, location: 'http://example.com', status: 302
35
+ )
36
+ }
37
+
38
+ describe "when processing an action with logstasher output" do
39
+ before do
40
+ Logstasher::log_format = :logstasher
41
+ end
42
+
43
+ it "should include the URL in the log output" do
44
+ subscriber.process_action(event)
45
+ log_output.string.should include('/home')
46
+ end
47
+
48
+ it "should not include the query string in the url" do
49
+ subscriber.process_action(event)
50
+ log_output.string.should_not include('?foo=bar')
51
+ end
52
+
53
+ it "should start the log line with the HTTP method" do
54
+ subscriber.process_action(event)
55
+ log_output.string.starts_with?('method=GET ').should == true
56
+ end
57
+
58
+ it "should include the status code" do
59
+ subscriber.process_action(event)
60
+ log_output.string.should include('status=200 ')
61
+ end
62
+
63
+ it "should include the controller and action" do
64
+ subscriber.process_action(event)
65
+ log_output.string.should include('controller=home action=index')
66
+ end
67
+
68
+ it "should include the duration" do
69
+ subscriber.process_action(event)
70
+ log_output.string.should =~ /duration=[\.0-9]{4,4} /
71
+ end
72
+
73
+ it "should include the view rendering time" do
74
+ subscriber.process_action(event)
75
+ log_output.string.should =~ /view=0.01 /
76
+ end
77
+
78
+ it "should include the database rendering time" do
79
+ subscriber.process_action(event)
80
+ log_output.string.should =~ /db=0.02/
81
+ end
82
+
83
+ it "should add a 500 status when an exception occurred" do
84
+ event.payload[:status] = nil
85
+ event.payload[:exception] = ['AbstractController::ActionNotFound', 'Route not found']
86
+ subscriber.process_action(event)
87
+ log_output.string.should =~ /status=500 /
88
+ log_output.string.should =~ /error='AbstractController::ActionNotFound:Route not found' /
89
+ end
90
+
91
+ it "should return an unknown status when no status or exception is found" do
92
+ event.payload[:status] = nil
93
+ event.payload[:exception] = nil
94
+ subscriber.process_action(event)
95
+ log_output.string.should =~ /status=0 /
96
+ end
97
+
98
+ describe "with a redirect" do
99
+ before do
100
+ Thread.current[:logstasher_location] = "http://www.example.com"
101
+ end
102
+
103
+ it "should add the location to the log line" do
104
+ subscriber.process_action(event)
105
+ log_output.string.should =~ %r{ location=http://www.example.com}
106
+ end
107
+
108
+ it "should remove the thread local variable" do
109
+ subscriber.process_action(event)
110
+ Thread.current[:logstasher_location].should == nil
111
+ end
112
+ end
113
+
114
+ it "should not include a location by default" do
115
+ subscriber.process_action(event)
116
+ log_output.string.should_not =~ /location=/
117
+ end
118
+ end
119
+
120
+ describe "when processing an action with logstash output" do
121
+ before do
122
+ require 'logstash-event'
123
+ Logstasher::log_format = :logstash
124
+ end
125
+
126
+ it "should include the URL in the log output" do
127
+ subscriber.process_action(event)
128
+ log_output.string.should include('/home')
129
+ end
130
+
131
+ it "should start include the HTTP method" do
132
+ subscriber.process_action(event)
133
+ log_output.string.should include('"method":"GET"')
134
+ end
135
+
136
+ it "should include the status code" do
137
+ subscriber.process_action(event)
138
+ log_output.string.should include('"status":200')
139
+ end
140
+
141
+ it "should include the controller and action" do
142
+ subscriber.process_action(event)
143
+ log_output.string.should include('"controller":"home"')
144
+ log_output.string.should include('"action":"index"')
145
+ end
146
+
147
+ it "should include the duration" do
148
+ subscriber.process_action(event)
149
+ log_output.string.should =~ /"duration":\d+\.\d{0,2}/
150
+ end
151
+
152
+ it "should include the view rendering time" do
153
+ subscriber.process_action(event)
154
+ log_output.string.should =~ /"view":0.01/
155
+ end
156
+
157
+ it "should include the database rendering time" do
158
+ subscriber.process_action(event)
159
+ log_output.string.should =~ /"db":0.02/
160
+ end
161
+
162
+ it "should add a 500 status when an exception occurred" do
163
+ event.payload[:status] = nil
164
+ event.payload[:exception] = ['AbstractController::ActionNotFound', 'Route not found']
165
+ subscriber.process_action(event)
166
+ log_output.string.should =~ /"status":500/
167
+ log_output.string.should =~ /"error":"AbstractController::ActionNotFound:Route not found"/
168
+ end
169
+
170
+ it "should return an unknown status when no status or exception is found" do
171
+ event.payload[:status] = nil
172
+ event.payload[:exception] = nil
173
+ subscriber.process_action(event)
174
+ log_output.string.should =~ /"status":0/
175
+ end
176
+
177
+ describe "with a redirect" do
178
+ before do
179
+ Thread.current[:logstasher_location] = "http://www.example.com"
180
+ end
181
+
182
+ it "should add the location to the log line" do
183
+ subscriber.process_action(event)
184
+ log_output.string.should =~ %r{"location":"http://www.example.com"}
185
+ end
186
+
187
+ it "should remove the thread local variable" do
188
+ subscriber.process_action(event)
189
+ Thread.current[:logstasher_location].should == nil
190
+ end
191
+ end
192
+
193
+ it "should not include a location by default" do
194
+ subscriber.process_action(event)
195
+ log_output.string.should_not =~ /"location":/
196
+ end
197
+ end
198
+
199
+ describe "when processing an action with graylog2 output" do
200
+ before do
201
+ Logstasher::log_format = :graylog2
202
+ end
203
+
204
+ it "should include the URL in the log output" do
205
+ subscriber.process_action(event)
206
+ log_output.string.should include(':_path=>"/home"')
207
+ end
208
+
209
+ it "should start include the HTTP method" do
210
+ subscriber.process_action(event)
211
+ log_output.string.should include(':_method=>"GET"')
212
+ end
213
+
214
+ it "should include the status code" do
215
+ subscriber.process_action(event)
216
+ log_output.string.should include(':_status=>200') end
217
+
218
+ it "should include the controller and action" do
219
+ subscriber.process_action(event)
220
+ log_output.string.should include(':_controller=>"home"')
221
+ log_output.string.should include(':_action=>"index"')
222
+ end
223
+
224
+ it "should include the duration" do
225
+ subscriber.process_action(event)
226
+ log_output.string.should =~ /:_duration=>\d+\.\d{0,2}/
227
+ end
228
+
229
+ it "should include the view rendering time" do
230
+ subscriber.process_action(event)
231
+ log_output.string.should include(':_view=>0.01')
232
+ end
233
+
234
+ it "should include the database rendering time" do
235
+ subscriber.process_action(event)
236
+ log_output.string.should include(':_db=>0.02')
237
+ end
238
+
239
+ it "should add a 500 status when an exception occurred" do
240
+ event.payload[:status] = nil
241
+ event.payload[:exception] = ['AbstractController::ActionNotFound', 'Route not found']
242
+ subscriber.process_action(event)
243
+ log_output.string.should include(':_status=>500')
244
+ log_output.string.should include(':_error=>"AbstractController::ActionNotFound:Route not found"')
245
+ end
246
+
247
+ it "should return an unknown status when no status or exception is found" do
248
+ event.payload[:status] = nil
249
+ event.payload[:exception] = nil
250
+ subscriber.process_action(event)
251
+ log_output.string.should include(':_status=>0')
252
+ end
253
+
254
+ describe "with a redirect" do
255
+ before do
256
+ Thread.current[:logstasher_location] = "http://www.example.com"
257
+ end
258
+
259
+ it "should add the location to the log line" do
260
+ subscriber.process_action(event)
261
+ log_output.string.should include(':_location=>"http://www.example.com"')
262
+ end
263
+
264
+ it "should remove the thread local variable" do
265
+ subscriber.process_action(event)
266
+ Thread.current[:logstasher_location].should == nil
267
+ end
268
+ end
269
+
270
+ it "should not include a location by default" do
271
+ subscriber.process_action(event)
272
+ log_output.string.should_not =~ /"location":/
273
+ end
274
+ end
275
+
276
+ describe "with custom_options configured for graylog2 output" do
277
+ before do
278
+ Logstasher::log_format = :graylog2
279
+ end
280
+
281
+ it "should combine the hash properly for the output" do
282
+ Logstasher.custom_options = {:data => "value"}
283
+ subscriber.process_action(event)
284
+ log_output.string.should include(':_data=>"value"')
285
+ end
286
+
287
+ it "should combine the output of a lambda properly" do
288
+ Logstasher.custom_options = lambda {|event| {:data => "value"}}
289
+ subscriber.process_action(event)
290
+ log_output.string.should include(':_data=>"value"')
291
+ end
292
+
293
+ it "should work if the method returns nil" do
294
+ Logstasher.custom_options = lambda {|event| nil}
295
+ subscriber.process_action(event)
296
+ log_output.string.should be_present
297
+ end
298
+ end
299
+
300
+ describe "with custom_options configured for logstasher output" do
301
+ before do
302
+ Logstasher::log_format = :logstasher
303
+ end
304
+
305
+ it "should combine the hash properly for the output" do
306
+ Logstasher.custom_options = {:data => "value"}
307
+ subscriber.process_action(event)
308
+ log_output.string.should =~ / data=value/
309
+ end
310
+ it "should combine the output of a lambda properly" do
311
+ Logstasher.custom_options = lambda {|event| {:data => "value"}}
312
+ subscriber.process_action(event)
313
+ log_output.string.should =~ / data=value/
314
+ end
315
+ it "should work if the method returns nil" do
316
+ Logstasher.custom_options = lambda {|event| nil}
317
+ subscriber.process_action(event)
318
+ log_output.string.should be_present
319
+ end
320
+ end
321
+
322
+ describe "with custom_options configured for logstash output" do
323
+ before do
324
+ Logstasher::log_format = :logstash
325
+ end
326
+
327
+ it "should combine the hash properly for the output" do
328
+ Logstasher.custom_options = {:data => "value"}
329
+ subscriber.process_action(event)
330
+ log_output.string.should =~ /"data":"value"/
331
+ end
332
+ it "should combine the output of a lambda properly" do
333
+ Logstasher.custom_options = lambda {|event| {:data => "value"}}
334
+ subscriber.process_action(event)
335
+ log_output.string.should =~ /"data":"value"/
336
+ end
337
+ it "should work if the method returns nil" do
338
+ Logstasher.custom_options = lambda {|event| nil}
339
+ subscriber.process_action(event)
340
+ log_output.string.should be_present
341
+ end
342
+ end
343
+
344
+ describe "when processing a redirect" do
345
+ it "should store the location in a thread local variable" do
346
+ subscriber.redirect_to(redirect)
347
+ Thread.current[:logstasher_location].should == "http://example.com"
348
+ end
349
+ end
350
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+ require 'logstasher'
3
+ require 'active_support/notifications'
4
+ require 'active_support/core_ext/string'
5
+ require 'active_support/log_subscriber'
6
+ require 'action_controller/log_subscriber'
7
+ require 'action_view/log_subscriber'
8
+
9
+ describe Logstasher do
10
+ describe "when removing Rails' log subscribers" do
11
+ after do
12
+ ActionController::LogSubscriber.attach_to :action_controller
13
+ ActionView::LogSubscriber.attach_to :action_view
14
+ end
15
+
16
+ it "should remove subscribers for controller events" do
17
+ expect {
18
+ Logstasher.remove_existing_log_subscriptions
19
+ }.to change {
20
+ ActiveSupport::Notifications.notifier.listeners_for('process_action.action_controller')
21
+ }
22
+ end
23
+
24
+ it "should remove subscribers for all events" do
25
+ expect {
26
+ Logstasher.remove_existing_log_subscriptions
27
+ }.to change {
28
+ ActiveSupport::Notifications.notifier.listeners_for('render_template.action_view')
29
+ }
30
+ end
31
+
32
+ it "shouldn't remove subscribers that aren't from Rails" do
33
+ blk = -> {}
34
+ ActiveSupport::Notifications.subscribe("process_action.action_controller", &blk)
35
+ Logstasher.remove_existing_log_subscriptions
36
+ listeners = ActiveSupport::Notifications.notifier.listeners_for('process_action.action_controller')
37
+ listeners.size.should > 0
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,13 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper.rb"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ require 'action_pack'
8
+
9
+ RSpec.configure do |config|
10
+ config.treat_symbols_as_metadata_keys_with_true_values = true
11
+ config.run_all_when_everything_filtered = true
12
+ config.filter_run :focus
13
+ end
metadata ADDED
@@ -0,0 +1,145 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logstasher
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Shadab Ahmed
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-04-06 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: logstash-event
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: guard-rspec
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: activesupport
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: actionpack
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ description: Awesome rails logs
95
+ email:
96
+ - shadab.ansari@gmail.com
97
+ executables: []
98
+ extensions: []
99
+ extra_rdoc_files: []
100
+ files:
101
+ - .gitignore
102
+ - .rspec
103
+ - .travis.yml
104
+ - Gemfile
105
+ - Guardfile
106
+ - README.md
107
+ - Rakefile
108
+ - lib/logstasher.rb
109
+ - lib/logstasher/log_subscriber.rb
110
+ - lib/logstasher/rails_ext/action_controller/metal/instrumentation.rb
111
+ - lib/logstasher/rails_ext/rack/logger.rb
112
+ - lib/logstasher/railtie.rb
113
+ - lib/logstasher/version.rb
114
+ - logstasher.gemspec
115
+ - spec/logstasher_logsubscriber_spec.rb
116
+ - spec/logstasher_spec.rb
117
+ - spec/spec_helper.rb
118
+ homepage: https://github.com/shadabahmed/logstasher
119
+ licenses: []
120
+ post_install_message:
121
+ rdoc_options: []
122
+ require_paths:
123
+ - lib
124
+ required_ruby_version: !ruby/object:Gem::Requirement
125
+ none: false
126
+ requirements:
127
+ - - ! '>='
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ required_rubygems_version: !ruby/object:Gem::Requirement
131
+ none: false
132
+ requirements:
133
+ - - ! '>='
134
+ - !ruby/object:Gem::Version
135
+ version: '0'
136
+ requirements: []
137
+ rubyforge_project: logstasher
138
+ rubygems_version: 1.8.25
139
+ signing_key:
140
+ specification_version: 3
141
+ summary: Awesome rails logs
142
+ test_files:
143
+ - spec/logstasher_logsubscriber_spec.rb
144
+ - spec/logstasher_spec.rb
145
+ - spec/spec_helper.rb