logstash_rails 0.0.7 → 0.0.8

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.
data/.rspec ADDED
@@ -0,0 +1,5 @@
1
+ --require spec_helper
2
+ --order random
3
+ --colour
4
+ --format nested
5
+ -b
data/Gemfile CHANGED
@@ -10,7 +10,6 @@ group :development do
10
10
  end
11
11
 
12
12
  group :test do
13
- gem 'minitest', require: 'minitest/autorun'
13
+ gem 'rspec'
14
14
  gem 'fakeredis'
15
- gem 'mocha', require: false
16
15
  end
data/README.md CHANGED
@@ -1,49 +1,86 @@
1
- # LogstashRails [![Code Climate](https://codeclimate.com/github/cmertz/logstash_rails.png)](https://codeclimate.com/github/cmertz/logstash_rails) [![Build Status](https://secure.travis-ci.org/cmertz/logstash_rails.png)](http://travis-ci.org/cmertz/logstash_rails) [![Dependency Status](https://gemnasium.com/cmertz/logstash_rails.png)](https://gemnasium.com/cmertz/logstash_rails) [![Coverage Status](https://coveralls.io/repos/cmertz/logstash_rails/badge.png)](https://coveralls.io/r/cmertz/logstash_rails)
1
+ # LogstashRails
2
+ [![Gem Version](https://badge.fury.io/rb/logstash_rails.png)](http://badge.fury.io/rb/logstash_rails)
3
+ [![Build Status](https://secure.travis-ci.org/cmertz/logstash_rails.png)](http://travis-ci.org/cmertz/logstash_rails)
4
+ [![Coverage Status](https://coveralls.io/repos/cmertz/logstash_rails/badge.png)](https://coveralls.io/r/cmertz/logstash_rails)
5
+ [![Code Climate](https://codeclimate.com/github/cmertz/logstash_rails.png)](https://codeclimate.com/github/cmertz/logstash_rails)
6
+ [![Dependency Status](https://gemnasium.com/cmertz/logstash_rails.png)](https://gemnasium.com/cmertz/logstash_rails)
2
7
 
3
- Send Logstash events from a Rails application to Redis.
8
+ Send events from Rails to Logstash without logger foo.
4
9
 
5
- ## Installation
10
+ ## Contents
6
11
 
7
- In your applications Gemfile:
12
+ * [Usage](#usage)
13
+ * [Configuration](#configurtion)
14
+ * [Examples](#examples)
15
+ * [Contributing](#contributing)
8
16
 
9
- ```ruby
10
- gem 'logstash_rails'
11
- ```
12
17
 
13
- For the latest version:
18
+ ## Usage
19
+
20
+ Add logstash-rails to your applications `Gemfile`
14
21
 
15
22
  ```ruby
16
- gem 'logstash_rails', github: 'cmertz/logstash_rails'
23
+ gem 'logstash_rails'
17
24
  ```
18
25
 
19
- Provide an initializer (e.g. config/initializers/logstash_rails.rb) for
20
- specific configuration.
26
+ and provide an initializer for configuration.
27
+
21
28
 
22
29
  ### Configuration
23
30
 
24
- **LogstashRails.config** takes a redis connection, the redis key for the list
25
- to push to and a flag that enables to catch all events (i.e. /.\*/)
31
+ `LogstashRails.config` takes an options hash with the following options:
32
+
33
+ * __transport__
34
+
35
+ redis is the only available transport atm
36
+
37
+ * __logger__
38
+
39
+ logger to use in case of exceptions while pushing events to the transport
40
+
41
+ * __events__
42
+
43
+ list of event name patterns to subscribe to. `Regex` and `String` is
44
+ supported.
45
+
46
+ * __transport options__
47
+
48
+ transport specific options e.g. _host_, _port_ and *redis_key*
49
+
50
+
51
+ ### Examples
26
52
 
27
53
  The most basic configuration looks like:
28
54
 
29
55
  ```ruby
30
- LogstashRails.config(Redis.new)
56
+ LogstashRails.config(transport: :redis)
31
57
  ```
32
58
 
33
- This will connect to the redis server on localhost, use 'logstash' (default) as
34
- key for the redis list to push to and subscribe to all events.
59
+ This will will connect to a redis server on _localhost:6379_, use _logstash_ as
60
+ key for the redis list to push to and subscribe to _all events_.
35
61
 
36
62
  A more complete example looks like:
37
63
 
38
64
  ```ruby
39
65
  if Rails.env.production?
40
- redis = Redis.new(host: '1.2.3.4', port: 12345)
41
- LogstashRails.config(redis, 'my_key', false)
42
- LogstashRails.subscribe('process_action.action_controller')
66
+ LogstashRails.config(
67
+ transport: redis,
68
+ host: '1.2.3.4',
69
+ port: 12345,
70
+ redis_key: 'my_key',
71
+ events: [/action_controller/]
72
+ )
43
73
  end
44
74
  ```
45
75
 
76
+ This will only subscribe to events from `ActionController`.
77
+
46
78
 
47
- ## TODO
79
+ ## Contributing
48
80
 
49
- * more independent from Rails i.e. check defined?(Rails) and provide fallbacks (for logger and application name)
81
+ 1. Fork it.
82
+ 2. Create a branch (`git checkout -b my_feature`)
83
+ 3. Commit your changes (`git commit -am "Added ..."`)
84
+ 4. Push to the branch (`git push origin my_feature`)
85
+ 5. Open a Pull Request
86
+ 6. Enjoy a refreshing Diet Coke and wait
data/Rakefile CHANGED
@@ -1,13 +1,8 @@
1
1
  require 'bundler/gem_tasks'
2
- require 'rake/testtask'
3
2
  require 'yard/rake/yardoc_task'
3
+ require 'rspec/core/rake_task'
4
4
 
5
- Rake::TestTask.new do |t|
6
- t.libs.push "lib"
7
- t.libs.push "spec"
8
- t.test_files = FileList['spec/*_spec.rb']
9
- t.verbose = false
10
- end
5
+ RSpec::Core::RakeTask.new(:test)
11
6
 
12
7
  YARD::Rake::YardocTask.new do |t|
13
8
  t.name = 'doc'
@@ -1,64 +1,20 @@
1
- require 'logstash_rails/formatter'
2
1
  require 'active_support'
2
+ require 'active_support/core_ext/string'
3
3
 
4
- module LogstashRails
5
- class << self
6
-
7
- # configures LogstashRails
8
- #
9
- # @param redis
10
- # @param key [String]
11
- # @param handle_all [Boolean]
12
- #
13
- def config(redis, key = 'logstash', handle_all = true)
14
- unless handle_all.is_a?(TrueClass) || handle_all.is_a?(FalseClass)
15
- raise ArgumentError
16
- end
17
-
18
- raise ArgumentError unless key.is_a?(String)
19
-
20
- raise ArgumentError unless redis
21
-
22
- @redis = redis
23
- @key = key
24
-
25
- subscribe(/.*/) if handle_all
26
- end
4
+ require 'logstash_rails/configuration_base'
27
5
 
28
- # subscribes LogstashRails to an ActiveSupport notification
29
- #
30
- # @param event_type [String|Regexp]
31
- #
32
- def subscribe(event_type)
33
- @subscriptions ||= {}
34
-
35
- @subscriptions[event_type] = ActiveSupport::Notifications.subscribe(event_type) do |*args|
36
- push(*args)
37
- end
38
- end
39
-
40
- # unsubscribe LogstashRails form an ActiveSupport notification
41
- #
42
- # @param event_type [String|Regexp] this must be the equal to the event_type that was subscribed with
43
- #
44
- def unsubscribe(event_type)
45
- ActiveSupport::Notifications.unsubscribe(@subscriptions[event_type])
46
- end
47
-
48
- private
6
+ Dir[File.join(File.dirname(__FILE__), 'logstash_rails', '*.rb')].each do |file|
7
+ require file
8
+ end
49
9
 
50
- def push(event_type, *args)
51
- begin
52
- @redis.rpush(@key, Formatter.format(event_type, *args))
53
- rescue
54
- log $!
55
- end
56
- end
10
+ module LogstashRails
11
+ extend self
57
12
 
58
- def log(exception)
59
- msg = exception.message + "\n " + exception.backtrace.join("\n ")
60
- Rails.logger.error(msg)
61
- end
13
+ def config(options)
14
+ transport = options.fetch(:transport)
15
+ transport = transport.to_s.camelize.to_sym
62
16
 
17
+ LogstashRails::Transport.const_get(transport).new(options)
63
18
  end
19
+
64
20
  end
@@ -0,0 +1,45 @@
1
+ module LogstashRails
2
+ class ConfigurationBase
3
+
4
+ def initialize(options)
5
+ @events = options[:events] || [/.*/]
6
+ @logger = options[:logger]
7
+
8
+ if defined?(Rails)
9
+ @logger ||= Rails.logger
10
+ end
11
+
12
+ subscribe
13
+ end
14
+
15
+ def destroy
16
+ return unless @subscriptions
17
+
18
+ @subscriptions.each do |subscription|
19
+ ActiveSupport::Notifications.unsubscribe(subscription)
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def subscribe
26
+ @subscriptions = @events.map do |event|
27
+ ActiveSupport::Notifications.subscribe(event) do |*args|
28
+ json_event = Formatter.format(*args)
29
+
30
+ begin
31
+ push(json_event)
32
+ rescue
33
+ log($!)
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ def log(exception)
40
+ msg = exception.message + "\n " + exception.backtrace.join("\n ")
41
+ @logger.error(msg) if @logger
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,12 @@
1
+ Dir[File.join(File.dirname(__FILE__), 'transport', '*.rb')].each do |file|
2
+ require file
3
+ end
4
+
5
+ module LogstashRails
6
+ module Transport
7
+ def self.get(transport)
8
+ constant_name = transport.to_s.camelize.to_sym
9
+ LogstashRails::Transport.const_get(constant_name)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,25 @@
1
+ module LogstashRails
2
+ module Transport
3
+ class LogstashTcp < ConfigurationBase
4
+
5
+ def initialize(options)
6
+ super
7
+
8
+ host = options[:host] || 'localhost'
9
+ port = options.fetch(:port)
10
+
11
+ @socket = TCPSocket.new(host, port)
12
+ end
13
+
14
+ def push(json_event)
15
+ @socket.write(json_event)
16
+ end
17
+
18
+ def destroy
19
+ super
20
+ @socket.close
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,20 @@
1
+ module LogstashRails
2
+ module Transport
3
+ class LogstashUdp < ConfigurationBase
4
+
5
+ def initialize(options = {})
6
+ super
7
+
8
+ host = options[:host] || 'localhost'
9
+ port = options[:port] || 9999
10
+
11
+ @socket = UDPSocket.new.tap{|s| s.connect(host, port) }
12
+ end
13
+
14
+ def push(json_event)
15
+ @socket.write(json_event)
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,24 @@
1
+ module LogstashRails
2
+ module Transport
3
+ class Redis < LogstashRails::ConfigurationBase
4
+
5
+ def initialize(options)
6
+ host = options[:host] || '127.0.0.1'
7
+ port = options[:port] || 6379
8
+ redis_key = options[:redis_key] || 'logstash'
9
+
10
+ @redis = ::Redis.new(host: host, port: port)
11
+ @redis_key = redis_key
12
+
13
+ super
14
+ end
15
+
16
+ def push(json_event)
17
+ unless @redis.rpush(@redis_key, json_event)
18
+ raise "could not send event to redis"
19
+ end
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -1,3 +1,3 @@
1
1
  module LogstashRails
2
- VERSION = "0.0.7"
2
+ VERSION = "0.0.8"
3
3
  end
@@ -7,14 +7,13 @@ Gem::Specification.new do |gem|
7
7
  gem.version = LogstashRails::VERSION
8
8
  gem.authors = ["cmertz"]
9
9
  gem.email = ["chris@nimel.de"]
10
- gem.description = %q{Send Logstash events from a Rails application to Redis}
11
- gem.summary = %q{Send Logstash events from a Rails application to Redis}
12
- gem.homepage = ""
10
+ gem.summary = %q{Send events from Rails to Logstash without logger foo.}
11
+ gem.description = %q{Send events from Rails to Logstash without logger foo.}
12
+ gem.homepage = "https://github.com/cmertz/logstash_rails"
13
13
  gem.license = "GPL"
14
14
 
15
15
  gem.files = `git ls-files`.split($/)
16
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
16
+ gem.test_files = gem.files.grep(%r{^spec/})
18
17
  gem.require_paths = ["lib"]
19
18
 
20
19
  gem.add_dependency('logstash-event')
@@ -0,0 +1,33 @@
1
+ describe LogstashRails::ConfigurationBase do
2
+
3
+ subject do
4
+ LogstashRails
5
+ end
6
+
7
+ it 'raises if no transport is specified' do
8
+ expect { subject.config({}) }.to raise_error(KeyError)
9
+ end
10
+
11
+ it 'handles all events by default' do
12
+ config = subject.config(transport: :redis)
13
+
14
+ config.should_receive(:push)
15
+
16
+ ActiveSupport::Notifications.instrument('foobar_event')
17
+
18
+ config.destroy
19
+ end
20
+
21
+ it 'logs exceptions if a logger is given' do
22
+ logger = mock(:logger)
23
+ config = subject.config(transport: :redis, logger: logger)
24
+ config.stub(:push).and_raise(ArgumentError.new)
25
+
26
+ logger.should_receive(:error)
27
+
28
+ ActiveSupport::Notifications.instrument('foobar_event')
29
+
30
+ config.destroy
31
+ end
32
+
33
+ end
@@ -1,23 +1,17 @@
1
- require 'spec_helper'
2
-
3
1
  describe 'generated logstash event' do
4
2
 
5
3
  before do
6
4
  Redis::Connection::Memory.reset_all_databases
7
- LogstashRails.config(redis)
5
+ LogstashRails.config(transport: :redis, redis: Redis.new, redis_key: 'logstash')
8
6
  ActiveSupport::Notifications.instrument("process_action.action_controller")
9
7
  end
10
8
 
11
- def redis
12
- Redis.new
13
- end
14
-
15
9
  it 'is parsebale json' do
16
- JSON.parse(redis.lpop('logstash'))
10
+ JSON.parse(Redis.new.lpop('logstash'))
17
11
  end
18
12
 
19
13
  it 'has the event type as message' do
20
- JSON.parse(redis.lpop('logstash'))['@message'].must_equal "process_action.action_controller"
14
+ JSON.parse(Redis.new.lpop('logstash'))['@message'].should eq "process_action.action_controller"
21
15
  end
22
16
 
23
17
  end
@@ -0,0 +1,31 @@
1
+ describe LogstashRails::Transport::LogstashTcp do
2
+
3
+ before do
4
+ @server = TCPServer.new(9000)
5
+
6
+ @thread = Thread.new do
7
+ client = @server.accept
8
+ @received = client.gets
9
+ client.close
10
+ end
11
+ end
12
+
13
+ after do
14
+ @server.close
15
+ end
16
+
17
+ let :logstash_tcp do
18
+ LogstashRails::Transport::LogstashTcp.new(port: 9000)
19
+ end
20
+
21
+ it do
22
+ logstash_tcp.should respond_to :push
23
+ end
24
+
25
+ it 'sends data over tcp' do
26
+ logstash_tcp.push 'toto'
27
+ logstash_tcp.destroy
28
+ @thread.join
29
+ @received.should eq 'toto'
30
+ end
31
+ end
@@ -0,0 +1,7 @@
1
+ describe LogstashRails::Transport::LogstashUdp do
2
+ subject do
3
+ LogstashRails::Transport::LogstashUdp.new
4
+ end
5
+
6
+ it { should respond_to :push }
7
+ end
@@ -0,0 +1,22 @@
1
+ describe LogstashRails::Transport::Redis do
2
+
3
+ before do
4
+ Redis::Connection::Memory.reset_all_databases
5
+ end
6
+
7
+ subject do
8
+ LogstashRails::Transport::Redis.new(
9
+ redis: Redis.new,
10
+ redis_key: 'logstash'
11
+ )
12
+ end
13
+
14
+ it { should respond_to :push }
15
+
16
+ it 'writes events to a redis list' do
17
+ subject.push('foobar_event')
18
+
19
+ Redis.new.lpop('logstash').should eq 'foobar_event'
20
+ end
21
+
22
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-06-05 00:00:00.000000000 Z
12
+ date: 2013-06-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: logstash-event
@@ -59,7 +59,7 @@ dependencies:
59
59
  - - ! '>='
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
- description: Send Logstash events from a Rails application to Redis
62
+ description: Send events from Rails to Logstash without logger foo.
63
63
  email:
64
64
  - chris@nimel.de
65
65
  executables: []
@@ -67,21 +67,28 @@ extensions: []
67
67
  extra_rdoc_files: []
68
68
  files:
69
69
  - .gitignore
70
+ - .rspec
70
71
  - .travis.yml
71
72
  - Gemfile
72
73
  - LICENSE.txt
73
74
  - README.md
74
75
  - Rakefile
75
76
  - lib/logstash_rails.rb
77
+ - lib/logstash_rails/configuration_base.rb
76
78
  - lib/logstash_rails/formatter.rb
79
+ - lib/logstash_rails/transport.rb
80
+ - lib/logstash_rails/transport/logstash_tcp.rb
81
+ - lib/logstash_rails/transport/logstash_udp.rb
82
+ - lib/logstash_rails/transport/redis.rb
77
83
  - lib/logstash_rails/version.rb
78
84
  - logstash_rails.gemspec
79
- - spec/config_spec.rb
80
- - spec/error_spec.rb
81
- - spec/event_spec.rb
85
+ - spec/lib/logstash_rails/configuration_spec.rb
86
+ - spec/lib/logstash_rails/formatter_spec.rb
87
+ - spec/lib/logstash_rails/transport/logstash_tcp_spec.rb
88
+ - spec/lib/logstash_rails/transport/logstash_udp_spec.rb
89
+ - spec/lib/logstash_rails/transport/redis_spec.rb
82
90
  - spec/spec_helper.rb
83
- - spec/subscription_spec.rb
84
- homepage: ''
91
+ homepage: https://github.com/cmertz/logstash_rails
85
92
  licenses:
86
93
  - GPL
87
94
  post_install_message:
@@ -96,7 +103,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
96
103
  version: '0'
97
104
  segments:
98
105
  - 0
99
- hash: -4390785812541147448
106
+ hash: 133620392481037059
100
107
  required_rubygems_version: !ruby/object:Gem::Requirement
101
108
  none: false
102
109
  requirements:
@@ -105,17 +112,18 @@ required_rubygems_version: !ruby/object:Gem::Requirement
105
112
  version: '0'
106
113
  segments:
107
114
  - 0
108
- hash: -4390785812541147448
115
+ hash: 133620392481037059
109
116
  requirements: []
110
117
  rubyforge_project:
111
118
  rubygems_version: 1.8.25
112
119
  signing_key:
113
120
  specification_version: 3
114
- summary: Send Logstash events from a Rails application to Redis
121
+ summary: Send events from Rails to Logstash without logger foo.
115
122
  test_files:
116
- - spec/config_spec.rb
117
- - spec/error_spec.rb
118
- - spec/event_spec.rb
123
+ - spec/lib/logstash_rails/configuration_spec.rb
124
+ - spec/lib/logstash_rails/formatter_spec.rb
125
+ - spec/lib/logstash_rails/transport/logstash_tcp_spec.rb
126
+ - spec/lib/logstash_rails/transport/logstash_udp_spec.rb
127
+ - spec/lib/logstash_rails/transport/redis_spec.rb
119
128
  - spec/spec_helper.rb
120
- - spec/subscription_spec.rb
121
129
  has_rdoc:
data/spec/config_spec.rb DELETED
@@ -1,27 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'LogstashRails.config' do
4
-
5
- def redis
6
- Redis.new
7
- end
8
-
9
- it 'raises an ArgumentError if the handle_all flag is not a boolean' do
10
- lambda do
11
- LogstashRails.config(redis, 'fookey', 'somerandomstring')
12
- end.must_raise(ArgumentError)
13
- end
14
-
15
- it 'raises an ArgumentError if the key is not a string' do
16
- lambda do
17
- LogstashRails.config(redis, 123, true)
18
- end.must_raise(ArgumentError)
19
- end
20
-
21
- it 'raises an ArgumentError if redis is nil' do
22
- lambda do
23
- LogstashRails.config(nil, 'fookey', true)
24
- end.must_raise(ArgumentError)
25
- end
26
-
27
- end
data/spec/error_spec.rb DELETED
@@ -1,16 +0,0 @@
1
- require 'spec_helper'
2
- require 'mocha/setup'
3
-
4
- describe 'error behaviour' do
5
-
6
- it 'logs exception traces to the Rails logger' do
7
- logger = MiniTest::Mock.new
8
- logger.expect(:error, nil, [String])
9
- LogstashRails.stubs(:log).returns(logger)
10
-
11
- LogstashRails.config(1)
12
-
13
- ActiveSupport::Notifications.instrument("process_action.action_controller")
14
- end
15
-
16
- end
@@ -1,57 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe LogstashRails do
4
-
5
- before do
6
- Redis::Connection::Memory.reset_all_databases
7
- end
8
-
9
- def redis
10
- Redis.new
11
- end
12
-
13
- it 'handles all events by default' do
14
- LogstashRails.config(redis)
15
-
16
- ActiveSupport::Notifications.instrument("process_action.action_controller")
17
-
18
- redis.lpop('logstash').wont_be_nil
19
- end
20
-
21
- it 'does not handle events unless told to' do
22
- LogstashRails.config(redis, 'logtstash', false)
23
-
24
- ActiveSupport::Notifications.instrument("process_action.action_controller")
25
-
26
- redis.lpop('logstash').must_be_nil
27
- end
28
-
29
- it 'handles events explicitly subscribed to' do
30
- LogstashRails.config(redis, 'logstash', false)
31
- LogstashRails.subscribe("process_action.action_controller")
32
-
33
- ActiveSupport::Notifications.instrument("process_action.action_controller")
34
-
35
- redis.lpop('logstash').wont_be_nil
36
- end
37
-
38
- it 'can be unsubscribed from events' do
39
- LogstashRails.config(redis, 'logtstash', false)
40
- LogstashRails.subscribe("process_action.action_controller")
41
- LogstashRails.unsubscribe("process_action.action_controller")
42
-
43
- ActiveSupport::Notifications.instrument("process_action.action_controller")
44
-
45
- redis.lpop('logstash').must_be_nil
46
- end
47
-
48
- it 'uses the provided redis key' do
49
- LogstashRails.config(redis, 'foorediskey', false)
50
- LogstashRails.subscribe("process_action.action_controller")
51
-
52
- ActiveSupport::Notifications.instrument("process_action.action_controller")
53
-
54
- redis.lpop('foorediskey').wont_be_nil
55
- end
56
-
57
- end