fluent-plugin-zmq-pub 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fluent-plugin-zmq-pub.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Hironori Ogibayashi
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.
data/README.rdoc ADDED
@@ -0,0 +1,80 @@
1
+ = fluent-plugin-zmq-pub
2
+
3
+ == Overview
4
+
5
+ Fluentd plugin to publish records to ZeroMQ.
6
+
7
+ == Why this plugin was created?
8
+
9
+ Sometimes I wanted to 'sniff' fluentd stream -- running my own programs to the stream without changing fluentd configuration and restarting fluentd. With this plugin, fluentd records are always published to ZeroMQ regardless of the existance of subscriber. After that I can start and stop my subcriber programs at any time.
10
+
11
+ == Configuration
12
+
13
+ <match zmq.**>
14
+ type zmq_pub
15
+ pubkey ${tag}:${key1}
16
+ bindaddr tcp://*:5556
17
+ flush_interval 1s
18
+ </match>
19
+
20
+ * 'pubkey' specifies the publish key to ZeroMQ.
21
+ * '${tag}' is replace by fluentd tag. '${name}' is replaced by fluentd record['name'].
22
+ * Actual record to be published is '<pubkey> <reocord.to_msgpack>'.
23
+ * Subscriber can subscribe by '<pubkey>'.
24
+ * 'bindaddr' is the address to which ZeroMQ publisher socket to be bound.
25
+
26
+ == Example usage
27
+
28
+ Put the configuration above to fluentd.conf, and save this sample code as 'sample_sub.rb'.
29
+
30
+ #!/usr/bin/env ruby
31
+
32
+ require 'zmq'
33
+ require 'msgpack'
34
+
35
+ context = ZMQ::Context.new(1)
36
+ subscriber = context.socket(ZMQ::SUB)
37
+ subscriber.connect("tcp://localhost:5556")
38
+
39
+ if ARGV.length > 0
40
+ ARGV.each{|s|
41
+ subscriber.setsockopt(ZMQ::SUBSCRIBE,s)
42
+ }
43
+ else
44
+ subscriber.setsockopt(ZMQ::SUBSCRIBE,"")
45
+ end
46
+
47
+ while true
48
+ if msg = subscriber.recv(ZMQ::NOBLOCK)
49
+ (tag, time, record) = MessagePack.unpack(msg.split(" ",2)[1])
50
+ puts "tag: #{tag}"
51
+ puts "time: #{time}"
52
+ puts "record: #{record.to_s}"
53
+ end
54
+ sleep(0.1)
55
+ end
56
+
57
+ Run sample_sub.rb. Argument is the key to subscribe. (Correspond to 'pubkey' in zmq_pub configuration). If you give no arguments, all key will be subscribed.
58
+
59
+ % ./sample_sub.rb zmq.test.tag:aaa
60
+
61
+ Submit records to fluentd.
62
+
63
+ % echo '{"key1": "aaa", "key2":"foo"}' | fluent-cat zmq.test.tag
64
+ % echo '{"key1": "bbb", "key2":"foo"}' | fluent-cat zmq.test.tag
65
+
66
+ Then you will get the following output from sample_sub.rb
67
+
68
+ tag: zmq.test.tag
69
+ time: 1376033265
70
+ record: {"key1"=>"aaa", "key2"=>"foo"}
71
+
72
+ (You should not get the second record("key1":"bbb") because the publish key to zmq was "zmq.test.tag:bbb" and specified subscibe key was "zmq.test.tag:aaa")
73
+
74
+ The nice thing is that once you put this plugin to your fluentd.conf and start fluentd, you can start and stop any subscriber programs without changing fluentd configuration.
75
+
76
+ == Copyright
77
+
78
+ * Copyright (c) 2013- OGIBAYASHI Hironori (@angostura11)
79
+ * License
80
+ * Apache License, Version 2.0
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require 'rake/testtask'
5
+ Rake::TestTask.new(:test) do |test|
6
+ test.libs << 'lib' << 'test'
7
+ test.pattern = 'test/**/test_*.rb'
8
+ test.verbose = true
9
+ end
10
+
11
+ task :default => :test
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["OGIBAYASHI Hironori"]
6
+ gem.email = ["ogibayashi@gmail.com"]
7
+ gem.description = %q{0MQ publisher plugin for fluentd}
8
+ gem.summary = %q{0MQ publisher plugin for fluentd}
9
+ gem.homepage = ""
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "fluent-plugin-zmq-pub"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = "0.0.1"
17
+ gem.add_development_dependency "fluentd"
18
+ gem.add_runtime_dependency "fluentd"
19
+ gem.add_development_dependency "zmq"
20
+ gem.add_runtime_dependency "zmq"
21
+ end
@@ -0,0 +1,53 @@
1
+ module Fluent
2
+ class Fluent::ZmqPubOutput < Fluent::BufferedOutput
3
+ Fluent::Plugin.register_output('zmq_pub', self)
4
+
5
+ config_param :pubkey, :string
6
+ config_param :bindaddr, :string, :default => 'tcp://*:5556'
7
+
8
+ def initialize
9
+ super
10
+ require 'zmq'
11
+ end
12
+
13
+ def configure(conf)
14
+ super
15
+ end
16
+
17
+ def start
18
+ super
19
+ @context = ZMQ::Context.new(1)
20
+ @publisher = @context.socket(ZMQ::PUB)
21
+ @publisher.bind(@bindaddr)
22
+ end
23
+
24
+ def format(tag, time, record)
25
+ [tag,time,record].to_msgpack
26
+ end
27
+
28
+ def write(chunk)
29
+ chunk.msgpack_each{ |record|
30
+ pubkey_replaced = @pubkey.gsub(/\${(.*?)}/){ |s|
31
+ case $1
32
+ when 'tag'
33
+ record[0]
34
+ else
35
+ record[2][$1]
36
+ end
37
+ }
38
+
39
+ # to_msgpack in format, unpack in write, then to_msgpack again... better way?
40
+ @publisher.send(pubkey_replaced + " " + record.to_msgpack)
41
+ }
42
+
43
+ end
44
+
45
+ def shutdown
46
+ super
47
+ @publisher.close
48
+ @context.close
49
+ end
50
+
51
+ end
52
+
53
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,28 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+
12
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
13
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
14
+ require 'fluent/test'
15
+ unless ENV.has_key?('VERBOSE')
16
+ nulllogger = Object.new
17
+ nulllogger.instance_eval {|obj|
18
+ def method_missing(method, *args)
19
+ # pass
20
+ end
21
+ }
22
+ $log = nulllogger
23
+ end
24
+
25
+ require 'fluent/plugin/out_zmq_pub'
26
+
27
+ class Test::Unit::TestCase
28
+ end
@@ -0,0 +1,65 @@
1
+ require 'helper'
2
+ require 'zmq'
3
+
4
+ class ZmqPubOutputTest < Test::Unit::TestCase
5
+ def setup
6
+ Fluent::Test.setup
7
+ @context = ZMQ::Context.new(1)
8
+ @subscriber = @context.socket(ZMQ::SUB)
9
+ @subscriber.connect('tcp://localhost:5556')
10
+ end
11
+
12
+ def teardown
13
+ @subscriber.close
14
+ @context.close
15
+ end
16
+
17
+ CONFIG = %[
18
+ pubkey ${tag}:${key1}
19
+ bindaddr tcp://*:5556
20
+ ]
21
+
22
+ def create_driver(conf = CONFIG, tag='test')
23
+ Fluent::Test::BufferedOutputTestDriver.new(Fluent::ZmqPubOutput, tag).configure(conf)
24
+ end
25
+
26
+ def test_configure
27
+ d = create_driver
28
+
29
+ assert_equal '${tag}:${key1}', d.instance.pubkey
30
+ assert_equal 'tcp://*:5556', d.instance.bindaddr
31
+ end
32
+
33
+ def test_format
34
+ d = create_driver
35
+
36
+ time = Time.parse("2011-01-02 13:14:15 UTC").to_i
37
+ d.emit({"key1"=>"aaa"}, time)
38
+ d.emit({"key1"=>"bbb", "key2"=>3}, time)
39
+
40
+ d.expect_format ["test",time.to_i,{ "key1" => "aaa"}].to_msgpack
41
+ d.expect_format ["test",time.to_i,{ "key1" => "bbb", "key2" => 3}].to_msgpack
42
+
43
+ d.run
44
+ end
45
+
46
+ def test_write
47
+ d = create_driver
48
+ @subscriber.setsockopt(ZMQ::SUBSCRIBE,"test:aaa")
49
+
50
+ time = Time.parse("2011-01-02 13:14:15 UTC").to_i
51
+ d.emit({"key1"=>"aaa"}, time)
52
+ d.emit({"key1"=>"bbb", "key2"=>3}, time)
53
+
54
+ d.run
55
+ sleep 1
56
+
57
+ msg = @subscriber.recv(ZMQ::NOBLOCK)
58
+ (key, record) = msg.split(" ",2)
59
+ assert_equal ["test",time.to_i,{ "key1" => "aaa"}].to_msgpack, record
60
+
61
+ end
62
+
63
+ end
64
+
65
+
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-zmq-pub
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - OGIBAYASHI Hironori
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2013-08-09 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: fluentd
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ type: :development
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: fluentd
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ type: :runtime
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: zmq
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ type: :development
47
+ version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
49
+ name: zmq
50
+ prerelease: false
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ type: :runtime
58
+ version_requirements: *id004
59
+ description: 0MQ publisher plugin for fluentd
60
+ email:
61
+ - ogibayashi@gmail.com
62
+ executables: []
63
+
64
+ extensions: []
65
+
66
+ extra_rdoc_files: []
67
+
68
+ files:
69
+ - .gitignore
70
+ - Gemfile
71
+ - LICENSE
72
+ - README.rdoc
73
+ - Rakefile
74
+ - fluent-plugin-zmq-pub.gemspec
75
+ - lib/fluent/plugin/out_zmq_pub.rb
76
+ - test/helper.rb
77
+ - test/plugin/test_out_zeromq_pub.rb
78
+ homepage: ""
79
+ licenses: []
80
+
81
+ post_install_message:
82
+ rdoc_options: []
83
+
84
+ require_paths:
85
+ - lib
86
+ required_ruby_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: "0"
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: "0"
98
+ requirements: []
99
+
100
+ rubyforge_project:
101
+ rubygems_version: 1.8.25
102
+ signing_key:
103
+ specification_version: 3
104
+ summary: 0MQ publisher plugin for fluentd
105
+ test_files:
106
+ - test/helper.rb
107
+ - test/plugin/test_out_zeromq_pub.rb