fluent-plugin-amqp2 0.0.1

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,3 @@
1
+ Gemfile.lock
2
+ .rvmrc
3
+ */pkg
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rake'
4
+
5
+ # Specify your gem's dependencies in fluent-plugin-amqp.gemspec
6
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Restorando
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,52 @@
1
+ # AMQP output plugin for Fluentd
2
+
3
+ Fluentd output plugin to publish events to an amqp broker.
4
+
5
+ Events are published one by one using the Fluentd tag as the routing key, in JSON format like:
6
+
7
+ ```javascript
8
+ { "key": "fluentd-tag", "timestamp": "fluentd-timestamp", "payload": "event-payload" }
9
+ ```
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ gem 'fluent-plugin-amqp2'
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install fluent-plugin-amqp2
24
+
25
+ ## Configuration
26
+
27
+ ```
28
+ <match pattern>
29
+ type amqp
30
+
31
+ # Set broker host and port
32
+ host localhost
33
+ port 5672
34
+
35
+ # Set user and password for authentication
36
+ user guest
37
+ password guest
38
+
39
+ # Configure amqp entities vhost, exchange id and type
40
+ vhost /
41
+ exchange my_exchange
42
+ exchange_type topic
43
+ </match>
44
+ ```
45
+
46
+ ## Contributing
47
+
48
+ 1. Fork it
49
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
50
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
51
+ 4. Push to the branch (`git push origin my-new-feature`)
52
+ 5. Create new Pull Request
@@ -0,0 +1,12 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require "rake/testtask"
4
+
5
+ Rake::TestTask.new(:test) do |test|
6
+ test.libs << 'lib' << 'test'
7
+ test.test_files = FileList['test/*.rb']
8
+ test.verbose = true
9
+ end
10
+
11
+ task :default => [:build]
12
+
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = "fluent-plugin-amqp2"
7
+ gem.version = "0.0.1"
8
+ gem.authors = ["Augusto Becciu", "Juan Manuel Barreneche"]
9
+ gem.email = ["devs@restorando.com"]
10
+
11
+ gem.description = %q{AMQP output plugin for Fluent}
12
+ gem.summary = %q{AMQP output plugin for Fluent}
13
+ gem.homepage = "https://github.com/restorando/fluent-plugin-amqp"
14
+
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)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency "fluentd", "~> 0.10.0"
21
+ gem.add_dependency "bunny", ">= 0.9.0.pre11"
22
+ gem.add_dependency "yajl-ruby", "~> 1.0"
23
+
24
+ gem.add_development_dependency "rake", ">= 0.9.2"
25
+ gem.add_development_dependency "mocha"
26
+ end
@@ -0,0 +1,88 @@
1
+ module Fluent
2
+
3
+ class AmqpOutput < Fluent::BufferedOutput
4
+ # First, register the plugin. NAME is the name of this plugin
5
+ # and identifies the plugin in the configuration file.
6
+ Fluent::Plugin.register_output('amqp', self)
7
+
8
+ config_param :host, :string, default: "127.0.0.1"
9
+ config_param :port, :integer, default: 5672
10
+ config_param :user, :string, default: "guest"
11
+ config_param :password, :string, default: "guest"
12
+ config_param :vhost, :string, default: "/"
13
+ config_param :exchange, :string, default: ""
14
+ config_param :exchange_type, :string, default: "topic"
15
+
16
+ def initialize(*)
17
+ super
18
+ require "bunny"
19
+ require "yajl"
20
+ end
21
+
22
+ # This method is called before starting.
23
+ # 'conf' is a Hash that includes configuration parameters.
24
+ # If the configuration is invalid, raise Fluent::ConfigError.
25
+ def configure(conf)
26
+ super
27
+
28
+ raise Fluent::ConfigError, "missing host infromation" unless @host
29
+ raise Fluent::ConfigError, "missing exchange" unless @exchange
30
+
31
+ @exchange_name = @exchange
32
+ end
33
+
34
+ # This method is called when starting.
35
+ # Open sockets or files here.
36
+ def start
37
+ super
38
+
39
+ begin
40
+ get_or_create_exchange
41
+ rescue => e
42
+ $log.error "AMQP error", error: e.to_s
43
+ $log.warn_backtrace e.backtrace
44
+ end
45
+ end
46
+
47
+ # This method is called when shutting down.
48
+ # Shutdown the thread and close sockets or files here.
49
+ def shutdown
50
+ super
51
+ @amqp_conn && @amqp_conn.stop
52
+ end
53
+
54
+ def format(tag, time, record)
55
+ [tag, time, record].to_msgpack
56
+ end
57
+
58
+ # This method is called every flush interval. Write the buffer chunk
59
+ # to files or databases here.
60
+ # 'chunk' is a buffer chunk that includes multiple formatted
61
+ # events. You can use 'data = chunk.read' to get all events and
62
+ # 'chunk.open {|io| ... }' to get IO objects.
63
+ def write(chunk)
64
+ chunk.msgpack_each do |(tag, time, record)|
65
+ event = { "key" => tag, "timestamp" => time, "payload" => record }
66
+ get_or_create_exchange.publish Yajl.dump(event), routing_key: tag
67
+ end
68
+ end
69
+
70
+ private
71
+
72
+ def get_or_create_exchange
73
+ @amqp_conn ||= Bunny.new(host: @host, vhost: @vhost, port: @port,
74
+ user: @user, password: @password, threaded: false, automatically_recover: false)
75
+
76
+ @amqp_conn.start unless @amqp_conn.open?
77
+
78
+ unless @amqp_channel && @amqp_channel.open?
79
+ @amqp_channel = @amqp_conn.create_channel
80
+ @amqp_exchange = Bunny::Exchange.new(@amqp_channel, @exchange_type.to_sym, @exchange_name, durable: true)
81
+ end
82
+
83
+ @amqp_exchange
84
+ end
85
+
86
+ end
87
+
88
+ end
@@ -0,0 +1,85 @@
1
+ require 'test/unit'
2
+ require 'mocha/setup'
3
+
4
+ require 'fluent/test'
5
+ require 'fluent/plugin/out_amqp'
6
+
7
+ class AmqpOutputTest < Test::Unit::TestCase
8
+
9
+ def setup
10
+ require 'bunny'
11
+ require 'yajl'
12
+ Fluent::Test.setup
13
+ end
14
+
15
+ CONFIG = %[
16
+ host localhost
17
+ port 3333
18
+ user test
19
+ password test
20
+ vhost /test
21
+ exchange test-exchange
22
+ exchange_type topic
23
+ buffert_type memory
24
+ ]
25
+
26
+ def create_driver(conf = CONFIG)
27
+ Fluent::Test::BufferedOutputTestDriver.new(Fluent::AmqpOutput).configure(conf)
28
+ end
29
+
30
+ def test_configure
31
+ d = create_driver
32
+ assert_equal "localhost", d.instance.host
33
+ assert_equal 3333, d.instance.port
34
+ assert_equal "test", d.instance.user
35
+ assert_equal "test", d.instance.password
36
+ assert_equal "/test", d.instance.vhost
37
+ assert_equal "test-exchange", d.instance.exchange
38
+ assert_equal "topic", d.instance.exchange_type
39
+ end
40
+
41
+ def test_start_and_shutdown
42
+ d = create_driver
43
+
44
+ amqp_conn_mock = mock()
45
+ amqp_exchange_mock = mock()
46
+ Bunny.stubs(:new).returns(amqp_conn_mock)
47
+
48
+ amqp_conn_mock.stubs(:open?).returns(false)
49
+ amqp_conn_mock.expects(:start)
50
+ amqp_conn_mock.expects(:stop)
51
+
52
+ amqp_conn_mock.expects(:create_channel)
53
+ Bunny::Exchange.expects(:new).returns(amqp_exchange_mock)
54
+
55
+ d.instance.start
56
+ # wait until thread starts
57
+ 10.times { sleep 0.05 }
58
+ d.instance.shutdown
59
+ end
60
+
61
+ def test_flush
62
+ d = create_driver
63
+
64
+ amqp_conn_mock = mock()
65
+ amqp_exchange_mock = mock()
66
+ Bunny.stubs(:new).returns(amqp_conn_mock)
67
+ amqp_conn_mock.stubs(:open?).returns(true)
68
+ amqp_conn_mock.stubs(:create_channel)
69
+ amqp_conn_mock.stubs(:stop)
70
+ Bunny::Exchange.stubs(:new).returns(amqp_exchange_mock)
71
+
72
+ t = Time.now.to_i
73
+ d.emit({"a" => 1}, t)
74
+ d.emit({"a" => 2}, t)
75
+
76
+ ev1 = Yajl.dump({"key" => "test", "timestamp" => t, "payload" => {"a"=>1}})
77
+ ev2 = Yajl.dump({"key" => "test", "timestamp" => t, "payload" => {"a"=>2}})
78
+ amqp_exchange_mock.expects(:publish).with(ev1, { routing_key: "test" })
79
+ amqp_exchange_mock.expects(:publish).with(ev2, { routing_key: "test" })
80
+
81
+ d.run
82
+ end
83
+
84
+ end
85
+
metadata ADDED
@@ -0,0 +1,141 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-amqp2
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Augusto Becciu
9
+ - Juan Manuel Barreneche
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2013-05-27 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: fluentd
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: 0.10.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ version: 0.10.0
31
+ - !ruby/object:Gem::Dependency
32
+ name: bunny
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: 0.9.0.pre11
39
+ type: :runtime
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: 0.9.0.pre11
47
+ - !ruby/object:Gem::Dependency
48
+ name: yajl-ruby
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '1.0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ~>
61
+ - !ruby/object:Gem::Version
62
+ version: '1.0'
63
+ - !ruby/object:Gem::Dependency
64
+ name: rake
65
+ requirement: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: 0.9.2
71
+ type: :development
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: 0.9.2
79
+ - !ruby/object:Gem::Dependency
80
+ name: mocha
81
+ requirement: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ type: :development
88
+ prerelease: false
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ! '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ description: AMQP output plugin for Fluent
96
+ email:
97
+ - devs@restorando.com
98
+ executables: []
99
+ extensions: []
100
+ extra_rdoc_files: []
101
+ files:
102
+ - .gitignore
103
+ - Gemfile
104
+ - LICENSE
105
+ - README.md
106
+ - Rakefile
107
+ - fluent-plugin-amqp2.gemspec
108
+ - lib/fluent/plugin/out_amqp.rb
109
+ - test/out_amqp.rb
110
+ homepage: https://github.com/restorando/fluent-plugin-amqp
111
+ licenses: []
112
+ post_install_message:
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ none: false
118
+ requirements:
119
+ - - ! '>='
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ segments:
123
+ - 0
124
+ hash: -856591938817169192
125
+ required_rubygems_version: !ruby/object:Gem::Requirement
126
+ none: false
127
+ requirements:
128
+ - - ! '>='
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ segments:
132
+ - 0
133
+ hash: -856591938817169192
134
+ requirements: []
135
+ rubyforge_project:
136
+ rubygems_version: 1.8.24
137
+ signing_key:
138
+ specification_version: 3
139
+ summary: AMQP output plugin for Fluent
140
+ test_files:
141
+ - test/out_amqp.rb