logstasher 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MmUyOWU0M2UwMGY1YzRjZDU0ZDRmNGExM2E2YTZjZDVhMGEyYWRjMQ==
4
+ YjJhNTIyM2IxMDc5NDU0ZmZjZTNlMzhlZTg1MTRkNzE4NDNkMDQ2OQ==
5
5
  data.tar.gz: !binary |-
6
- NGI2M2M3NGNjYjc2OGZjMWI0NGU3MTM3ZjljMDY5ZGNhYTk5OTYxNQ==
6
+ OWI5OTI4ZDUzYThmMTM3NGJjNjUzY2VhYTc3ZTcwNWExMzFhNzdhZg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- YjM5YzhmMGU0YTcyYTAxMWMxYzAxZWE5NTgyN2RmYTM3MWM0ZDE0MTY1YWQ2
10
- YzIzOWQ4MjFkODA0NDMwNDk3YWY4MmNkYzY1M2ViNmU4NjZmYzdjMDZlMGU2
11
- ZGM2MGY0ZmNjYzk3NTYwODRiMTc3ZDg1OTYzZWFiMTgzNmEyZjA=
9
+ Y2FlMTgzZGMxMjk3MDFmOTE2NzM4YTc4ZjJmNTgwMGFmZmVhMTYyYzk5ZjM3
10
+ YzM1NDVlYjUxYWM5ZGE4OTJkOWU0ZTgxZjEzMWJlNGZhZTYxMzk0NDcxNTJl
11
+ MDcwMjgzMDQ0NTVmODVhYTEwZDE2ODFiNWJkYTg5NTgwYTMzYmM=
12
12
  data.tar.gz: !binary |-
13
- NTk2MDFmNGM4MDFlOGE2OGI1NjE3MDMwZmZmYjRlZTM0NDQwMTU1OGZiMzBl
14
- N2VlYzViNzQ2MDFjODk4OWYyYThhZGRjNzUyMDRhNzBiZjU3YTdhM2E0ZjJj
15
- ZTRlYTA2Y2UyM2UzN2M0YTY5MDFkY2IyNzk1NmY5MzM5MjJlOGQ=
13
+ N2E4ZGM1NzU4MTIwZjZlM2RiNzY1NDhiMzE0ZjY1Yjg1YTQxMjA4YTcxNzMx
14
+ NmEwNTQwZWY0ODYxYzBmNzEwNzZlMDNlZTVkZjExYjlhZjRmYTY1YzcyNzVk
15
+ YzFhOTQwY2FhNjlkNmVkYzAyYmU0ZGE5ZDYxODI2OTJhYmQwNmM=
@@ -109,7 +109,12 @@ module LogStasher
109
109
  process_event(event, ['mailer', 'process'])
110
110
  end
111
111
 
112
+ def logger
113
+ LogStasher.logger
114
+ end
115
+
112
116
  private
117
+
113
118
  def process_event(event, tags)
114
119
  data = LogStasher.request_context.merge(extract_metadata(event.payload))
115
120
  event = LogStash::Event.new('@source' => LogStasher.source, '@fields' => data, '@tags' => tags)
@@ -119,9 +124,5 @@ module LogStasher
119
124
  def extract_metadata(payload)
120
125
  payload.slice(*MAILER_FIELDS)
121
126
  end
122
-
123
- def logger
124
- LogStasher.logger
125
- end
126
127
  end
127
128
  end
@@ -1,3 +1,3 @@
1
1
  module LogStasher
2
- VERSION = "0.6.0"
2
+ VERSION = "0.6.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstasher
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shadab Ahmed
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-22 00:00:00.000000000 Z
11
+ date: 2014-09-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logstash-event
@@ -87,13 +87,6 @@ executables: []
87
87
  extensions: []
88
88
  extra_rdoc_files: []
89
89
  files:
90
- - .gitignore
91
- - .rspec
92
- - .travis.yml
93
- - Gemfile
94
- - Guardfile
95
- - README.md
96
- - Rakefile
97
90
  - lib/logstasher.rb
98
91
  - lib/logstasher/device/redis.rb
99
92
  - lib/logstasher/log_subscriber.rb
@@ -101,16 +94,9 @@ files:
101
94
  - lib/logstasher/rails_ext/rack/logger.rb
102
95
  - lib/logstasher/railtie.rb
103
96
  - lib/logstasher/version.rb
104
- - logstasher.gemspec
105
- - sample_logstash_configurations/quickstart.conf
106
- - spec/lib/logstasher/device/redis_spec.rb
107
- - spec/lib/logstasher/instrumentation_spec.rb
108
- - spec/lib/logstasher/log_subscriber_spec.rb
109
- - spec/lib/logstasher_spec.rb
110
- - spec/spec_helper.rb
111
- - spec/support/sample_mailer.rb
112
97
  homepage: https://github.com/shadabahmed/logstasher
113
- licenses: []
98
+ licenses:
99
+ - MIT
114
100
  metadata: {}
115
101
  post_install_message:
116
102
  rdoc_options: []
@@ -127,15 +113,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
127
113
  - !ruby/object:Gem::Version
128
114
  version: '0'
129
115
  requirements: []
130
- rubyforge_project: logstasher
116
+ rubyforge_project:
131
117
  rubygems_version: 2.2.2
132
118
  signing_key:
133
119
  specification_version: 4
134
120
  summary: Awesome rails logs
135
- test_files:
136
- - spec/lib/logstasher/device/redis_spec.rb
137
- - spec/lib/logstasher/instrumentation_spec.rb
138
- - spec/lib/logstasher/log_subscriber_spec.rb
139
- - spec/lib/logstasher_spec.rb
140
- - spec/spec_helper.rb
141
- - spec/support/sample_mailer.rb
121
+ test_files: []
data/.gitignore DELETED
@@ -1,5 +0,0 @@
1
- *.gem
2
- .bundle
3
- Gemfile.lock
4
- pkg/*
5
- .idea
data/.rspec DELETED
@@ -1,2 +0,0 @@
1
- --color
2
- --format progress
data/.travis.yml DELETED
@@ -1,12 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 1.9.3
4
- - 2.0.0
5
-
6
- env:
7
- - "RAILS_VERSION=4.0"
8
- - "RAILS_VERSION=3.2"
9
- - "RAILS_VERSION=3.1"
10
- - "RAILS_VERSION=3.0"
11
-
12
- script: bundle exec rspec
data/Gemfile DELETED
@@ -1,15 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- # Specify your gem's dependencies in logstasher.gemspec
4
- gemspec
5
-
6
- group :test do
7
- gem 'growl'
8
- gem 'guard'
9
- gem 'guard-rspec'
10
- gem 'rails', "~> #{ENV["RAILS_VERSION"] || "3.2.0"}"
11
- gem 'rb-fsevent', '~> 0.9'
12
- gem 'rcov', :platforms => :mri_18
13
- gem 'redis', :require => false
14
- gem 'simplecov', :platforms => :mri_19, :require => false
15
- end
data/Guardfile DELETED
@@ -1,10 +0,0 @@
1
- # A sample Guardfile
2
- # More info at https://github.com/guard/guard#readme
3
- interactor :simple
4
-
5
- guard 'rspec', :version => 2 do
6
- watch(%r{^spec/.+_spec\.rb$})
7
- watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
8
- watch('spec/spec_helper.rb') { "spec" }
9
- end
10
-
data/README.md DELETED
@@ -1,162 +0,0 @@
1
- # Logstasher [![Gem Version](https://badge.fury.io/rb/logstasher.png)](http://badge.fury.io/rb/logstasher) [![Build Status](https://secure.travis-ci.org/shadabahmed/logstasher.png)](https://secure.travis-ci.org/shadabahmed/logstasher)
2
- ### Awesome Logging for Rails !!
3
-
4
- This gem is heavily inspired from [lograge](https://github.com/roidrage/lograge), but it's focused on one thing and one thing only. That's making your logs awesome like this:
5
-
6
- [![Awesome Logs](https://f.cloud.github.com/assets/830679/2407078/dcde03e8-aa82-11e3-85ac-8c5b3a86676e.png)](https://f.cloud.github.com/assets/830679/2407078/dcde03e8-aa82-11e3-85ac-8c5b3a86676e.png)
7
-
8
- How it's done ?
9
-
10
- By, using these awesome tools:
11
- * [Logstash](http://logstash.net) - Store and index your logs
12
- * [Kibana](http://kibana.org/) - for awesome visualization. This is optional though, and you can use any other visualizer
13
-
14
- Update: Logstash now includes Kibana build in, so no need to separately install. Logstasher has been test with **logstash version 1.3.3**
15
-
16
- See [quickstart](#quick-setup-for-logstash) for quickly setting up logstash
17
-
18
- ## About logstasher
19
-
20
- This gem purely focuses on how to generate logstash compatible logs i.e. *logstash json event format*, without any overhead. Infact, logstasher logs to a separate log file named `logstash_<environment>.log`.
21
- The reason for this separation:
22
- * To have a pure json log file
23
- * Prevent any logger messages(e.g. info) getting into our pure json logs
24
-
25
- Before **logstasher** :
26
-
27
- ```
28
- Started GET "/login" for 10.109.10.135 at 2013-04-30 08:59:01 -0400
29
- Processing by SessionsController#new as HTML
30
- Rendered sessions/new.html.haml within layouts/application (4.3ms)
31
- Rendered shared/_javascript.html.haml (0.6ms)
32
- Rendered shared/_flashes.html.haml (0.2ms)
33
- Rendered shared/_header.html.haml (52.9ms)
34
- Rendered shared/_title.html.haml (0.2ms)
35
- Rendered shared/_footer.html.haml (0.2ms)
36
- Completed 200 OK in 532ms (Views: 62.4ms | ActiveRecord: 0.0ms | ND API: 0.0ms)
37
- ```
38
-
39
- After **logstasher**:
40
-
41
- ```
42
- {"@source":"unknown","@tags":["request"],"@fields":{"method":"GET","path":"/","format":"html","controller":"file_servers"
43
- ,"action":"index","status":200,"duration":28.34,"view":25.96,"db":0.88,"ip":"127.0.0.1","route":"file_servers#index",
44
- "parameters":"","ndapi_time":null,"uuid":"e81ecd178ed3b591099f4d489760dfb6","user":"shadab_ahmed@abc.com",
45
- "site":"internal"},"@timestamp":"2013-04-30T13:00:46.354500+00:00"}
46
- ```
47
-
48
- By default, the older format rails request logs are disabled, though you can enable them.
49
-
50
- ## Installation
51
-
52
- In your Gemfile:
53
-
54
- gem 'logstasher'
55
-
56
- ### Configure your `<environment>.rb` e.g. `development.rb`
57
-
58
- # Enable the logstasher logs for the current environment
59
- config.logstasher.enabled = true
60
-
61
- # This line is optional if you do not want to suppress app logs in your <environment>.log
62
- config.logstasher.suppress_app_log = false
63
-
64
- # This line is optional, it allows you to set a custom value for the @source field of the log event
65
- config.logstasher.source = 'your.arbitrary.source'
66
-
67
- ## Logging params hash
68
-
69
- Logstasher can be configured to log the contents of the params hash. When enabled, the contents of the params hash (minus the ActionController internal params)
70
- will be added to the log as a deep hash. This can cause conflicts within the Elasticsearch mappings though, so should be enabled with care. Conflicts will occur
71
- if different actions (or even different applications logging to the same Elasticsearch cluster) use the same params key, but with a different data type (e.g. a
72
- string vs. a hash). This can lead to lost log entries. Enabling this can also significantly increase the size of the Elasticsearch indexes.
73
-
74
- To enable this, add the following to your `<environment>.rb`
75
-
76
- # Enable logging of controller params
77
- config.logstasher.log_controller_parameters = true
78
-
79
- ## Adding custom fields to the log
80
-
81
- Since some fields are very specific to your application for e.g. *user_name*, so it is left upto you, to add them. Here's how to add those fields to the logs:
82
-
83
- # Create a file - config/initializers/logstasher.rb
84
-
85
- if LogStasher.enabled
86
- LogStasher.add_custom_fields do |fields|
87
- # This block is run in application_controller context,
88
- # so you have access to all controller methods
89
- fields[:user] = current_user && current_user.mail
90
- fields[:site] = request.path =~ /^\/api/ ? 'api' : 'user'
91
-
92
- # If you are using custom instrumentation, just add it to logstasher custom fields
93
- LogStasher.custom_fields << :myapi_runtime
94
- end
95
- end
96
-
97
- ## Logging ActionMailer events
98
-
99
- Logstasher can easily log messages from `ActionMailer`, such as incoming/outgoing e-mails and e-mail content generation (Rails >= 4.1).
100
- This functionality is automatically enabled. Since the relationship between a concrete HTTP request and a mailer invocation is lost
101
- once in an `ActionMailer` instance method, global (per-request) state is kept to correlate HTTP requests and events from other parts
102
- of rails, such as `ActionMailer`. Every time a request is invoked, a `request_id` key is added which is present on every `ActionMailer` event.
103
-
104
- Note: Since mailers are executed within the lifetime of a request, they will show up in logs prior to the actual request.
105
-
106
- ## Listening to `ActiveSupport::Notifications` events
107
-
108
- It is possible to listen to any `ActiveSupport::Notifications` events and store arbitrary data to be included in the final JSON log entry:
109
-
110
- # In config/initializers/logstasher.rb
111
-
112
- # Watch calls the block with the same arguments than any ActiveSupport::Notification, plus a store
113
- LogStasher.watch('some.activesupport.notification') do |name, start, finish, id, payload, store|
114
- # Do something
115
- store[:count] = 42
116
- end
117
-
118
- Would change the log entry to:
119
-
120
- ```
121
- {"@source":"unknown","@tags":["request"],"@fields":{"method":"GET","path":"/","format":"html","controller":"file_servers","action":"index","status":200,"duration":28.34,"view":25.96,"db":0.88,"ip":"127.0.0.1","route":"file_servers#index", "parameters":"","ndapi_time":null,"uuid":"e81ecd178ed3b591099f4d489760dfb6","user":"shadab_ahmed@abc.com", "site":"internal","some.activesupport.notification":{"count":42}},"@timestamp":"2013-04-30T13:00:46.354500+00:00"}
122
- ```
123
-
124
- The store exposed to the blocked passed to `watch` is thread-safe, and reset after each request.
125
- By default, the store is only shared between occurences of the same event.
126
- You can easily share the same store between different types of notifications, by assigning them to the same event group:
127
-
128
- # In config/initializers/logstasher.rb
129
-
130
- LogStasher.watch('foo.notification', event_group: 'notification') do |*args, store|
131
- # Shared store with 'bar.notification'
132
- end
133
-
134
- LogStasher.watch('bar.notification', event_group: 'notification') do |*args, store|
135
- # Shared store with 'foo.notification'
136
- end
137
-
138
- ## Quick Setup for Logstash
139
-
140
- * Download logstash from [logstash.net](http://www.logstash.net/)
141
- * Use this sample config file: [quickstart.conf](https://github.com/shadabahmed/logstasher/raw/master/sample_logstash_configurations/quickstart.conf)
142
- * Start logstash with the following command:
143
- ```
144
- java -jar logstash-1.3.3-flatjar.jar agent -f quickstart.conf -- web
145
- ```
146
- * Visit http://localhost:9292/ to see the Kibana interface and your parsed logs
147
- * For advanced options see the latest logstash documentation at [logstash.net](http://www.logstash.net/) or visit my blog at [shadabahmed.com](http://shadabahmed.com/blog/2013/04/30/logstasher-for-awesome-rails-logging) (slightly outdated but will sure give you ideas for distributed setup etc.)
148
-
149
- ## Versions
150
- All versions require Rails 3.0.x and higher and Ruby 1.9.2+. Tested on Rails 4 and Ruby 2.0
151
-
152
- ## Development
153
- - Run tests - `rake`
154
- - Generate test coverage report - `rake coverage`. Coverage report path - coverage/index.html
155
-
156
- ## Copyright
157
-
158
- Copyright (c) 2013 Shadab Ahmed, released under the MIT license
159
-
160
-
161
- [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/shadabahmed/logstasher/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
162
-
data/Rakefile DELETED
@@ -1,50 +0,0 @@
1
- require "bundler/gem_tasks"
2
- require 'rspec/core/rake_task'
3
-
4
- # Add default task. When you type just rake command this would run. Travis CI runs this. Making this run spec
5
- desc 'Default: run specs.'
6
- task :default => :spec
7
-
8
- # Defining spec task for running spec
9
- desc "Run specs"
10
- RSpec::Core::RakeTask.new('spec') do |spec|
11
- # Pattern filr for spec files to run. This is default btw.
12
- spec.pattern = "./spec/**/*_spec.rb"
13
- end
14
-
15
- # Run the rdoc task to generate rdocs for this gem
16
- require 'rdoc/task'
17
- RDoc::Task.new do |rdoc|
18
- require "logstasher/version"
19
- version = LogStasher::VERSION
20
-
21
- rdoc.rdoc_dir = 'rdoc'
22
- rdoc.title = "logstasher #{version}"
23
- rdoc.rdoc_files.include('README*')
24
- rdoc.rdoc_files.include('lib/**/*.rb')
25
- end
26
-
27
- # Code coverage tasks. Different for Ruby 1.8 vs 1.9
28
- if RUBY_VERSION =~ /^1\.8/
29
- # Ruby 1.8 uses rcov for code coverage
30
- RSpec::Core::RakeTask.new(:coverage) do |spec|
31
- spec.pattern = 'spec/**/*_spec.rb'
32
- spec.rcov = true
33
- spec.rcov_opts = %w{--exclude pkg\/,spec\/,features\/}
34
- end
35
- else
36
- # Ruby 1.9+ using simplecov. Note: Simplecov config defined in spec_helper
37
- desc "Code coverage detail"
38
- task :coverage do
39
- ENV['COVERAGE'] = "true"
40
- Rake::Task['spec'].execute
41
- end
42
- end
43
-
44
- task :console do
45
- require 'irb'
46
- require 'irb/completion'
47
- require 'logstasher'
48
- ARGV.clear
49
- IRB.start
50
- end
data/logstasher.gemspec DELETED
@@ -1,27 +0,0 @@
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", ["~> 1.1.0"]
21
- s.add_runtime_dependency "request_store"
22
-
23
- # specify any dependencies here; for example:
24
- s.add_development_dependency "rspec", [">= 2.14"]
25
- s.add_development_dependency("bundler", [">= 1.0.0"])
26
- s.add_development_dependency("rails", [">= 3.0"])
27
- end
@@ -1,23 +0,0 @@
1
- input {
2
- file {
3
- type => "rails logs"
4
- path => "/Users/shadab/test_project/logstash_development.log"
5
- codec => json {
6
- charset => "UTF-8"
7
- }
8
- }
9
- }
10
-
11
- output {
12
- # Print each event to stdout.
13
- stdout {
14
- codec => rubydebug
15
- }
16
-
17
- elasticsearch {
18
- # Setting 'embedded' will run a real elasticsearch server inside logstash.
19
- # This option below saves you from having to run a separate process just
20
- # for ElasticSearch, so you can get started quicker!
21
- embedded => true
22
- }
23
- }
@@ -1,79 +0,0 @@
1
- require 'spec_helper'
2
-
3
- require 'logstasher/device/redis'
4
-
5
- describe LogStasher::Device::Redis do
6
-
7
- let(:redis_mock) { double('Redis') }
8
-
9
- let(:default_options) {{
10
- key: 'logstash',
11
- data_type: 'list'
12
- }}
13
-
14
- it 'has default options' do
15
- device = LogStasher::Device::Redis.new
16
- expect(device.options).to eq(default_options)
17
- end
18
-
19
- it 'creates a redis instance' do
20
- expect(::Redis).to receive(:new).with({})
21
- LogStasher::Device::Redis.new()
22
- end
23
-
24
- it 'assumes unknown options are for redis' do
25
- expect(::Redis).to receive(:new).with(hash_including(db: '0'))
26
- device = LogStasher::Device::Redis.new(db: '0')
27
- expect(device.redis_options).to eq(db: '0')
28
- end
29
-
30
- it 'has a key' do
31
- device = LogStasher::Device::Redis.new(key: 'the_key')
32
- expect(device.key).to eq('the_key')
33
- end
34
-
35
- it 'has a data_type' do
36
- device = LogStasher::Device::Redis.new(data_type: 'channel')
37
- expect(device.data_type).to eq('channel')
38
- end
39
-
40
- it 'does not allow unsupported data types' do
41
- expect {
42
- device = LogStasher::Device::Redis.new(data_type: 'blargh')
43
- }.to raise_error()
44
- end
45
-
46
- it 'quits the redis connection on #close' do
47
- device = LogStasher::Device::Redis.new
48
- expect(device.redis).to receive(:quit)
49
- device.close
50
- end
51
-
52
- it 'works as a logger device' do
53
- device = LogStasher::Device::Redis.new
54
- expect(device).to receive(:write).with('blargh')
55
- logger = Logger.new(device)
56
- logger << 'blargh'
57
- end
58
-
59
- describe '#write' do
60
- it "rpushes logs onto a list" do
61
- device = LogStasher::Device::Redis.new(data_type: 'list')
62
- expect(device.redis).to receive(:rpush).with('logstash', 'the log')
63
- device.write('the log')
64
- end
65
-
66
- it "rpushes logs onto a custom key" do
67
- device = LogStasher::Device::Redis.new(data_type: 'list', key: 'custom')
68
- expect(device.redis).to receive(:rpush).with('custom', 'the log')
69
- device.write('the log')
70
- end
71
-
72
- it "publishes logs onto a channel" do
73
- device = LogStasher::Device::Redis.new(data_type: 'channel', key: 'custom')
74
- expect(device.redis).to receive(:publish).with('custom', 'the log')
75
- device.write('the log')
76
- end
77
- end
78
-
79
- end
@@ -1,62 +0,0 @@
1
- require 'spec_helper'
2
- require 'logstasher/rails_ext/action_controller/metal/instrumentation'
3
-
4
- describe ActionController::Base do
5
- before :each do
6
- subject.request = ActionDispatch::TestRequest.new
7
- subject.response = ActionDispatch::TestResponse.new
8
-
9
- def subject.index(*args)
10
- render text: 'OK'
11
- end
12
- end
13
-
14
- describe ".process_action" do
15
- it "adds default fields to payload" do
16
- expect(LogStasher).to receive(:add_default_fields_to_payload).once
17
- expect(LogStasher).to receive(:add_default_fields_to_request_context).once
18
- subject.process_action(:index)
19
- end
20
-
21
- it "creates the request context before processing" do
22
- LogStasher.request_context[:some_key] = 'value'
23
- expect(LogStasher).to receive(:clear_request_context).once.and_call_original
24
- expect {
25
- subject.process_action(:index)
26
- }.to change { LogStasher.request_context }
27
- end
28
-
29
- it "notifies rails of a request coming in" do
30
- expect(ActiveSupport::Notifications).to receive(:instrument).with("start_processing.action_controller", anything).once
31
- expect(ActiveSupport::Notifications).to receive(:instrument).with("process_action.action_controller", anything).once
32
- subject.process_action(:index)
33
- end
34
-
35
- context "request context has custom fields defined" do
36
- before :each do
37
- LogStasher.add_custom_fields_to_request_context do |fields|
38
- fields[:some_field] = 'value'
39
- end
40
-
41
- ActiveSupport::Notifications.subscribe('process_action.action_controller') do |_, _, _, _, payload|
42
- @payload = payload
43
- end
44
- end
45
-
46
- it "should retain the value in the request context" do
47
- subject.process_action(:index)
48
- end
49
-
50
- after :each do
51
- expect(@payload[:some_field]).to eq('value')
52
-
53
- ActionController::Metal.class_eval do
54
- undef logstasher_add_custom_fields_to_request_context
55
- end
56
- ActionController::Base.class_eval do
57
- undef logstasher_add_custom_fields_to_request_context
58
- end
59
- end
60
- end
61
- end
62
- end
@@ -1,265 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe LogStasher::RequestLogSubscriber do
4
- let(:log_output) {StringIO.new}
5
- let(:logger) {
6
- logger = Logger.new(log_output)
7
- logger.formatter = ->(_, _, _, msg) {
8
- msg
9
- }
10
- def log_output.json
11
- JSON.parse! self.string
12
- end
13
- logger
14
- }
15
- before do
16
- LogStasher.logger = logger
17
- LogStasher.log_controller_parameters = true
18
- LogStasher.custom_fields = []
19
- end
20
- after do
21
- LogStasher.log_controller_parameters = false
22
- end
23
-
24
- let(:subscriber) {LogStasher::RequestLogSubscriber.new}
25
- let(:event) {
26
- ActiveSupport::Notifications::Event.new(
27
- 'process_action.action_controller', Time.now, Time.now, 2, {
28
- status: 200, format: 'application/json', method: 'GET', path: '/home?foo=bar', params: {
29
- :controller => 'home', :action => 'index', 'foo' => 'bar'
30
- }.with_indifferent_access, db_runtime: 0.02, view_runtime: 0.01
31
- }
32
- )
33
- }
34
-
35
- let(:redirect) {
36
- ActiveSupport::Notifications::Event.new(
37
- 'redirect_to.action_controller', Time.now, Time.now, 1, location: 'http://example.com', status: 302
38
- )
39
- }
40
-
41
- describe '.process_action' do
42
- let!(:request_subscriber) { @request_subscriber ||= LogStasher::RequestLogSubscriber.new() }
43
- let(:payload) { {} }
44
- let(:event) { double(:payload => payload) }
45
- let(:logger) { double }
46
- let(:json) { "{\"@source\":\"unknown\",\"@tags\":[\"request\"],\"@fields\":{\"request\":true,\"status\":true,\"runtimes\":true,\"location\":true,\"exception\":true,\"custom\":true},\"@timestamp\":\"timestamp\"}\n" }
47
- before do
48
- allow(LogStasher).to receive(:logger).and_return(logger)
49
- allow(LogStash::Time).to receive(:now).and_return('timestamp')
50
- end
51
- it 'calls all extractors and outputs the json' do
52
- expect(request_subscriber).to receive(:extract_request).with(payload).and_return({:request => true})
53
- expect(request_subscriber).to receive(:extract_status).with(payload).and_return({:status => true})
54
- expect(request_subscriber).to receive(:runtimes).with(event).and_return({:runtimes => true})
55
- expect(request_subscriber).to receive(:location).with(event).and_return({:location => true})
56
- expect(request_subscriber).to receive(:extract_exception).with(payload).and_return({:exception => true})
57
- expect(request_subscriber).to receive(:extract_custom_fields).with(payload).and_return({:custom => true})
58
- expect(LogStasher.logger).to receive(:<<).with(json)
59
- request_subscriber.process_action(event)
60
- end
61
- end
62
-
63
- describe 'logstasher output' do
64
-
65
- it "should contain request tag" do
66
- subscriber.process_action(event)
67
- expect(log_output.json['@tags']).to include 'request'
68
- end
69
-
70
- it "should contain HTTP method" do
71
- subscriber.process_action(event)
72
- expect(log_output.json['@fields']['method']).to eq 'GET'
73
- end
74
-
75
- it "should include the path in the log output" do
76
- subscriber.process_action(event)
77
- expect(log_output.json['@fields']['path']).to eq '/home'
78
- end
79
-
80
- it "should include the format in the log output" do
81
- subscriber.process_action(event)
82
- expect(log_output.json['@fields']['format']).to eq 'application/json'
83
- end
84
-
85
- it "should include the status code" do
86
- subscriber.process_action(event)
87
- expect(log_output.json['@fields']['status']).to eq 200
88
- end
89
-
90
- it "should include the controller" do
91
- subscriber.process_action(event)
92
- expect(log_output.json['@fields']['controller']).to eq 'home'
93
- end
94
-
95
- it "should include the action" do
96
- subscriber.process_action(event)
97
- expect(log_output.json['@fields']['action']).to eq 'index'
98
- end
99
-
100
- it "should include the view rendering time" do
101
- subscriber.process_action(event)
102
- expect(log_output.json['@fields']['view']).to eq 0.01
103
- end
104
-
105
- it "should include the database rendering time" do
106
- subscriber.process_action(event)
107
- expect(log_output.json['@fields']['db']).to eq 0.02
108
- end
109
-
110
- it "should add a valid status when an exception occurred" do
111
- begin
112
- raise AbstractController::ActionNotFound.new('Could not find an action')
113
- # working this in rescue to get access to $! variable
114
- rescue
115
- event.payload[:status] = nil
116
- event.payload[:exception] = ['AbstractController::ActionNotFound', 'Route not found']
117
- subscriber.process_action(event)
118
- expect(log_output.json['@fields']['status']).to be >= 400
119
- expect(log_output.json['@fields']['error']).to be =~ /AbstractController::ActionNotFound.*Route not found.*logstasher\/spec\/lib\/logstasher\/log_subscriber_spec\.rb/m
120
- expect(log_output.json['@tags']).to include 'request'
121
- expect(log_output.json['@tags']).to include 'exception'
122
- end
123
- end
124
-
125
- it "should return an unknown status when no status or exception is found" do
126
- event.payload[:status] = nil
127
- event.payload[:exception] = nil
128
- subscriber.process_action(event)
129
- expect(log_output.json['@fields']['status']).to eq 0
130
- end
131
-
132
- describe "with a redirect" do
133
- before do
134
- Thread.current[:logstasher_location] = "http://www.example.com"
135
- end
136
-
137
- it "should add the location to the log line" do
138
- subscriber.process_action(event)
139
- expect(log_output.json['@fields']['location']).to eq 'http://www.example.com'
140
- end
141
-
142
- it "should remove the thread local variable" do
143
- subscriber.process_action(event)
144
- expect(Thread.current[:logstasher_location]).to be_nil
145
- end
146
- end
147
-
148
- it "should not include a location by default" do
149
- subscriber.process_action(event)
150
- expect(log_output.json['@fields']['location']).to be_nil
151
- end
152
- end
153
-
154
- describe "with append_custom_params block specified" do
155
- let(:request) { double(:remote_ip => '10.0.0.1', :env => {})}
156
- it "should add default custom data to the output" do
157
- allow(request).to receive_messages(:params => event.payload[:params])
158
- LogStasher.add_default_fields_to_payload(event.payload, request)
159
- subscriber.process_action(event)
160
- expect(log_output.json['@fields']['ip']).to eq '10.0.0.1'
161
- expect(log_output.json['@fields']['route']).to eq'home#index'
162
- expect(log_output.json['@fields']['parameters']).to eq 'foo' => 'bar'
163
- end
164
- end
165
-
166
- describe "with append_custom_params block specified" do
167
- before do
168
- allow(LogStasher).to receive(:add_custom_fields) do |&block|
169
- @block = block
170
- end
171
- LogStasher.add_custom_fields do |payload|
172
- payload[:user] = 'user'
173
- end
174
- LogStasher.custom_fields += [:user]
175
- end
176
-
177
- it "should add the custom data to the output" do
178
- @block.call(event.payload)
179
- subscriber.process_action(event)
180
- expect(log_output.json['@fields']['user']).to eq 'user'
181
- end
182
- end
183
-
184
- describe "when processing a redirect" do
185
- it "should store the location in a thread local variable" do
186
- subscriber.redirect_to(redirect)
187
- expect(Thread.current[:logstasher_location]).to eq "http://example.com"
188
- end
189
- end
190
- end
191
-
192
- describe LogStasher::MailerLogSubscriber do
193
- let(:log_output) {StringIO.new}
194
- let(:logger) {
195
- logger = Logger.new(log_output)
196
- logger.formatter = ->(_, _, _, msg) {
197
- msg
198
- }
199
- def log_output.json
200
- JSON.parse!(self.string.split("\n").last)
201
- end
202
- logger
203
- }
204
-
205
- before :all do
206
- SampleMailer.delivery_method = :test
207
- LogStasher::MailerLogSubscriber.attach_to(:action_mailer)
208
- end
209
-
210
- before do
211
- LogStasher.logger = logger
212
- expect(LogStasher.request_context).to receive(:merge).at_most(2).times.and_call_original
213
- end
214
-
215
- let :message do
216
- Mail.new do
217
- from 'some-dude@example.com'
218
- to 'some-other-dude@example.com'
219
- subject 'Goodbye'
220
- body 'LOL'
221
- end
222
- end
223
-
224
- it 'receive an e-mail' do
225
- SampleMailer.receive(message.encoded)
226
- log_output.json.tap do |json|
227
- expect(json['@source']).to eq(LogStasher.source)
228
- expect(json['@tags']).to eq(['mailer', 'receive'])
229
- json['@fields'].tap do |fields|
230
- expect(fields['mailer']).to eq('SampleMailer')
231
- expect(fields['from']).to eq(['some-dude@example.com'])
232
- expect(fields['to']).to eq(['some-other-dude@example.com'])
233
- expect(fields['message_id']).to eq(message.message_id)
234
- end
235
- end
236
- end
237
-
238
- it 'deliver an outgoing e-mail' do
239
- email = SampleMailer.welcome
240
-
241
- if version = ENV['RAILS_VERSION'] and version >= '4.1'
242
- log_output.json.tap do |json|
243
- expect(json['@source']).to eq(LogStasher.source)
244
- expect(json['@tags']).to eq(['mailer', 'process'])
245
- json['@fields'].tap do |fields|
246
- expect(fields['mailer']).to eq('SampleMailer')
247
- expect(fields['action']).to eq('welcome')
248
- end
249
- end
250
- end
251
-
252
- email.deliver
253
- log_output.json.tap do |json|
254
- expect(json['@source']).to eq(LogStasher.source)
255
- expect(json['@tags']).to eq(['mailer', 'deliver'])
256
- json['@fields'].tap do |fields|
257
- expect(fields['mailer']).to eq('SampleMailer')
258
- expect(fields['from']).to eq(['some-dude@example.com'])
259
- expect(fields['to']).to eq(['some-other-dude@example.com'])
260
- # Message-Id appears not to be yet available at this point in time.
261
- expect(fields['message_id']).to be_nil
262
- end
263
- end
264
- end
265
- end
@@ -1,263 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe LogStasher do
4
- describe "when removing Rails' log subscribers" do
5
- after do
6
- ActionController::LogSubscriber.attach_to :action_controller
7
- ActionView::LogSubscriber.attach_to :action_view
8
- ActionMailer::LogSubscriber.attach_to :action_mailer
9
- end
10
-
11
- it "should remove subscribers for controller events" do
12
- expect {
13
- LogStasher.remove_existing_log_subscriptions
14
- }.to change {
15
- ActiveSupport::Notifications.notifier.listeners_for('process_action.action_controller')
16
- }
17
- end
18
-
19
- it "should remove subscribers for all events" do
20
- expect {
21
- LogStasher.remove_existing_log_subscriptions
22
- }.to change {
23
- ActiveSupport::Notifications.notifier.listeners_for('render_template.action_view')
24
- }
25
- end
26
-
27
- it "should remove subscribsers for mailer events" do
28
- expect {
29
- LogStasher.remove_existing_log_subscriptions
30
- }.to change {
31
- ActiveSupport::Notifications.notifier.listeners_for('deliver.action_mailer')
32
- }
33
- end
34
-
35
- it "shouldn't remove subscribers that aren't from Rails" do
36
- blk = -> {}
37
- ActiveSupport::Notifications.subscribe("process_action.action_controller", &blk)
38
- LogStasher.remove_existing_log_subscriptions
39
- listeners = ActiveSupport::Notifications.notifier.listeners_for('process_action.action_controller')
40
- expect(listeners).to_not be_empty
41
- end
42
- end
43
-
44
- describe '.appened_default_info_to_payload' do
45
- let(:params) { {'a' => '1', 'b' => 2, 'action' => 'action', 'controller' => 'test'}.with_indifferent_access }
46
- let(:payload) { {:params => params} }
47
- let(:request) { double(:params => params, :remote_ip => '10.0.0.1', :env => {})}
48
- after do
49
- LogStasher.custom_fields = []
50
- LogStasher.log_controller_parameters = false
51
- end
52
- it 'appends default parameters to payload' do
53
- LogStasher.log_controller_parameters = true
54
- LogStasher.custom_fields = []
55
- LogStasher.add_default_fields_to_payload(payload, request)
56
- expect(payload[:ip]).to eq '10.0.0.1'
57
- expect(payload[:route]).to eq 'test#action'
58
- expect(payload[:parameters]).to eq 'a' => '1', 'b' => 2
59
- expect(LogStasher.custom_fields).to eq [:ip, :route, :request_id, :parameters]
60
- end
61
-
62
- it 'does not include parameters when not configured to' do
63
- LogStasher.custom_fields = []
64
- LogStasher.add_default_fields_to_payload(payload, request)
65
- expect(payload).to_not have_key(:parameters)
66
- expect(LogStasher.custom_fields).to eq [:ip, :route, :request_id]
67
- end
68
- end
69
-
70
- describe '.append_custom_params' do
71
- let(:block) { ->(_, _){} }
72
- it 'defines a method in ActionController::Base' do
73
- expect(ActionController::Base).to receive(:send).with(:define_method, :logtasher_add_custom_fields_to_payload, &block)
74
- LogStasher.add_custom_fields(&block)
75
- end
76
- end
77
-
78
- describe '.add_custom_fields_to_request_context' do
79
- let(:block) { ->(_, _){} }
80
- it 'defines a method in ActionController::Base' do
81
- expect(ActionController::Base).to receive(:send).with(:define_method, :logstasher_add_custom_fields_to_request_context, &block)
82
- expect(ActionController::Metal).to receive(:send).with(:define_method, :logstasher_add_custom_fields_to_request_context, &block)
83
- LogStasher.add_custom_fields_to_request_context(&block)
84
- end
85
- end
86
-
87
- describe '.add_default_fields_to_request_context' do
88
- it 'adds a request_id to the request context' do
89
- LogStasher.clear_request_context
90
- LogStasher.add_default_fields_to_request_context(double(env: {'action_dispatch.request_id' => 'lol'}))
91
- expect(LogStasher.request_context).to eq({ request_id: 'lol' })
92
- end
93
- end
94
-
95
- shared_examples 'setup' do
96
- let(:logstasher_source) { nil }
97
- let(:logstasher_config) { double(:logger => logger, :log_level => 'warn', :log_controller_parameters => nil, :source => logstasher_source, :logger_path => logger_path) }
98
- let(:config) { double(:logstasher => logstasher_config) }
99
- let(:app) { double(:config => config) }
100
- before do
101
- @previous_source = LogStasher.source
102
- allow(config).to receive_messages(:action_dispatch => double(:rack_cache => false))
103
- allow_message_expectations_on_nil
104
- end
105
- after { LogStasher.source = @previous_source } # Need to restore old source for specs
106
- it 'defines a method in ActionController::Base' do
107
- expect(LogStasher).to receive(:require).with('logstasher/rails_ext/action_controller/metal/instrumentation')
108
- expect(LogStasher).to receive(:require).with('logstash-event')
109
- expect(LogStasher).to receive(:suppress_app_logs).with(app)
110
- expect(LogStasher::RequestLogSubscriber).to receive(:attach_to).with(:action_controller)
111
- expect(LogStasher::MailerLogSubscriber).to receive(:attach_to).with(:action_mailer)
112
- expect(logger).to receive(:level=).with('warn')
113
- LogStasher.setup(app)
114
- expect(LogStasher.source).to eq (logstasher_source || 'unknown')
115
- expect(LogStasher).to be_enabled
116
- expect(LogStasher.custom_fields).to be_empty
117
- expect(LogStasher.log_controller_parameters).to eq false
118
- end
119
- end
120
-
121
- describe '.setup' do
122
- let(:logger) { double }
123
- let(:logger_path) { nil }
124
-
125
- describe 'with source set' do
126
- let(:logstasher_source) { 'foo' }
127
- it_behaves_like 'setup'
128
- end
129
-
130
- describe 'without source set (default behaviour)' do
131
- let(:logstasher_source) { nil }
132
- it_behaves_like 'setup'
133
- end
134
-
135
- describe 'with customized logging' do
136
- let(:logger) { nil }
137
-
138
- context 'with no logger passed in' do
139
- before { expect(LogStasher).to receive(:new_logger).with('/log/logstash_test.log') }
140
- it_behaves_like 'setup'
141
- end
142
-
143
- context 'with custom logger path passed in' do
144
- let(:logger_path) { double }
145
-
146
- before { expect(LogStasher).to receive(:new_logger).with(logger_path) }
147
- it_behaves_like 'setup'
148
- end
149
- end
150
- end
151
-
152
- describe '.suppress_app_logs' do
153
- let(:logstasher_config){ double(:logstasher => double(:suppress_app_log => true))}
154
- let(:app){ double(:config => logstasher_config)}
155
- it 'removes existing subscription if enabled' do
156
- expect(LogStasher).to receive(:require).with('logstasher/rails_ext/rack/logger')
157
- expect(LogStasher).to receive(:remove_existing_log_subscriptions)
158
- LogStasher.suppress_app_logs(app)
159
- end
160
-
161
- context 'when disabled' do
162
- let(:logstasher_config){ double(:logstasher => double(:suppress_app_log => false)) }
163
- it 'does not remove existing subscription' do
164
- expect(LogStasher).to_not receive(:remove_existing_log_subscriptions)
165
- LogStasher.suppress_app_logs(app)
166
- end
167
-
168
- describe "backward compatibility" do
169
- context 'with spelling "supress_app_log"' do
170
- let(:logstasher_config){ double(:logstasher => double(:suppress_app_log => nil, :supress_app_log => false)) }
171
- it 'does not remove existing subscription' do
172
- expect(LogStasher).to_not receive(:remove_existing_log_subscriptions)
173
- LogStasher.suppress_app_logs(app)
174
- end
175
- end
176
- end
177
- end
178
- end
179
-
180
- describe '.appended_params' do
181
- it 'returns the stored var in current thread' do
182
- Thread.current[:logstasher_custom_fields] = :test
183
- expect(LogStasher.custom_fields).to eq :test
184
- end
185
- end
186
-
187
- describe '.appended_params=' do
188
- it 'returns the stored var in current thread' do
189
- LogStasher.custom_fields = :test
190
- expect(Thread.current[:logstasher_custom_fields]).to eq :test
191
- end
192
- end
193
-
194
- describe '.log' do
195
- let(:logger) { double() }
196
- before do
197
- LogStasher.logger = logger
198
- allow(LogStash::Time).to receive_messages(:now => 'timestamp')
199
- allow_message_expectations_on_nil
200
- end
201
- it 'adds to log with specified level' do
202
- expect(logger).to receive(:send).with('warn?').and_return(true)
203
- expect(logger).to receive(:send).with('warn',"{\"@source\":\"unknown\",\"@tags\":[\"log\"],\"@fields\":{\"message\":\"WARNING\",\"level\":\"warn\"},\"@timestamp\":\"timestamp\"}")
204
- LogStasher.log('warn', 'WARNING')
205
- end
206
- context 'with a source specified' do
207
- before :each do
208
- LogStasher.source = 'foo'
209
- end
210
- it 'sets the correct source' do
211
- expect(logger).to receive(:send).with('warn?').and_return(true)
212
- expect(logger).to receive(:send).with('warn',"{\"@source\":\"foo\",\"@tags\":[\"log\"],\"@fields\":{\"message\":\"WARNING\",\"level\":\"warn\"},\"@timestamp\":\"timestamp\"}")
213
- LogStasher.log('warn', 'WARNING')
214
- end
215
- end
216
- end
217
-
218
- %w( fatal error warn info debug unknown ).each do |severity|
219
- describe ".#{severity}" do
220
- let(:message) { "This is a #{severity} message" }
221
- it 'should log with specified level' do
222
- expect(LogStasher).to receive(:log).with(severity.to_sym, message)
223
- LogStasher.send(severity, message )
224
- end
225
- end
226
- end
227
-
228
- describe '.store' do
229
- it "returns a new Hash for each key" do
230
- expect(LogStasher.store['a'].object_id).to_not be(LogStasher.store['b'].object_id)
231
- end
232
-
233
- it "returns the same store if called several time with the same key" do
234
- expect(LogStasher.store['a'].object_id).to be(LogStasher.store['a'].object_id)
235
- end
236
-
237
- end
238
-
239
- describe ".watch" do
240
- before(:each) { LogStasher.custom_fields = [] }
241
-
242
- it "subscribes to the required event" do
243
- expect(ActiveSupport::Notifications).to receive(:subscribe).with('event_name')
244
- LogStasher.watch('event_name')
245
- end
246
-
247
- it 'executes the block when receiving an event' do
248
- probe = lambda {}
249
- LogStasher.watch('custom.event.foo', &probe)
250
- expect(probe).to receive(:call)
251
- ActiveSupport::Notifications.instrument('custom.event.foo', {})
252
- end
253
-
254
- describe "store" do
255
- it 'stores the events in a store with the event\'s name' do
256
- probe = lambda { |*args, store| store[:foo] = :bar }
257
- LogStasher.watch('custom.event.bar', &probe)
258
- ActiveSupport::Notifications.instrument('custom.event.bar', {})
259
- expect(LogStasher.store['custom.event.bar']).to eq :foo => :bar
260
- end
261
- end
262
- end
263
- end
data/spec/spec_helper.rb DELETED
@@ -1,52 +0,0 @@
1
- # Notice there is a .rspec file in the root folder. It defines rspec arguments
2
-
3
- # Ruby 1.9 uses simplecov. The ENV['COVERAGE'] is set when rake coverage is run in ruby 1.9
4
- if ENV['COVERAGE']
5
- require 'simplecov'
6
- SimpleCov.start do
7
- # Remove the spec folder from coverage. By default all code files are included. For more config options see
8
- # https://github.com/colszowka/simplecov
9
- add_filter File.expand_path('../../spec', __FILE__)
10
- end
11
- end
12
-
13
- # Modify load path so you can require 'ogstasher directly.
14
- $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
15
-
16
- require 'rubygems'
17
- # Loads bundler setup tasks. Now if I run spec without installing gems then it would say gem not installed and
18
- # do bundle install instead of ugly load error on require.
19
- require 'bundler/setup'
20
-
21
- # This will require me all the gems automatically for the groups. If I do only .setup then I will have to require gems
22
- # manually. Note that you have still have to require some gems if they are part of bigger gem like ActiveRecord which is
23
- # part of Rails. You can say :require => false in gemfile to always use explicit requiring
24
- Bundler.require(:default, :test)
25
-
26
- Dir[File.join("./spec/support/**/*.rb")].each { |f| require f }
27
-
28
- # Set Rails environment as test
29
- ENV['RAILS_ENV'] = 'test'
30
-
31
- require 'action_pack'
32
- require 'action_controller'
33
- require 'logstasher'
34
- require 'active_support/notifications'
35
- require 'active_support/core_ext/string'
36
- require 'active_support/log_subscriber'
37
- require 'action_controller/log_subscriber'
38
- require 'action_view/log_subscriber'
39
- require 'active_support/core_ext/hash/except'
40
- require 'active_support/core_ext/hash/indifferent_access'
41
- require 'active_support/core_ext/hash/slice'
42
- require 'active_support/core_ext/string'
43
- require 'active_support/core_ext/time/zones'
44
- require 'abstract_controller/base'
45
- require 'action_mailer'
46
- require 'logger'
47
- require 'logstash-event'
48
-
49
- RSpec.configure do |config|
50
- config.run_all_when_everything_filtered = true
51
- config.filter_run :focus
52
- end
@@ -1,16 +0,0 @@
1
- require 'action_mailer'
2
-
3
- class SampleMailer < ActionMailer::Base
4
- def welcome
5
- mail(from: 'some-dude@example.com', to: 'some-other-dude@example.com', subject: 'Hello, there') do |format|
6
- format.text { render plain: 'OK' }
7
- end
8
- end
9
-
10
- def receive(email)
11
- end
12
-
13
- def _render_template(_)
14
- ""
15
- end
16
- end