fluent-plugin-resque-ex 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ /fluent/
2
+ /pkg/
3
+ /coverage/
4
+ /vendor/
5
+ Gemfile.lock
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ rvm:
2
+ - 1.9.2
3
+ - 1.9.3
4
+
5
+ script: bundle exec rake test
data/AUTHORS ADDED
@@ -0,0 +1 @@
1
+ Yuichi Tateno <hotchpotch _at_ gmail.com>
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source :rubygems
2
+
3
+ gemspec
4
+
5
+ gem "simplecov", :require => false
data/README.rdoc ADDED
@@ -0,0 +1,26 @@
1
+ = Fluent event to Resque queue plugin
2
+
3
+ = Installation
4
+
5
+ $ fluent-gem install fluent-plugin-resque-ex
6
+
7
+ = Usage
8
+
9
+ <match resque>
10
+ type resque
11
+ redis hostname:port/namespace
12
+ queue file_serve
13
+ worker_class_name_tag class # default class
14
+ </match>
15
+
16
+ fluent_logger.post('resque', {
17
+ :class => 'Worker::MyClass',
18
+ :user_id => xxx,
19
+ :body => yyy
20
+ })
21
+ #=> enqueue ('file_serve', 'Worker::MyClass', {:user_id => xxx, :body => yyy})
22
+
23
+ = Copyright
24
+
25
+ Copyright:: Copyright (c) 2012- Yuichi Tateno
26
+ License:: Apache License, Version 2.0
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rake/testtask'
5
+
6
+ Rake::TestTask.new(:test) do |test|
7
+ test.libs << 'lib' << 'test'
8
+ test.test_files = FileList['test/plugin/*.rb']
9
+ test.verbose = true
10
+ end
11
+
12
+ task :coverage do |t|
13
+ ENV['SIMPLE_COV'] = '1'
14
+ Rake::Task["test"].invoke
15
+ end
16
+
17
+ task :default => [:build]
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = "fluent-plugin-resque-ex"
6
+ gem.description = "Resque-ex enqueue plugin"
7
+ gem.homepage = "https://github.com/iyagi15/fluent-plugin-resque-ex"
8
+ gem.summary = gem.description
9
+ gem.version = File.read("VERSION").strip
10
+ gem.authors = ["Yuichi Tateno"]
11
+ gem.email = "hotchpotch@gmail.com"
12
+ gem.has_rdoc = false
13
+ gem.files = `git ls-files`.split("\n")
14
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
+ gem.require_paths = ['lib']
17
+
18
+ gem.add_dependency "fluentd", ">= 0.10.8"
19
+ gem.add_dependency "multi_json", "~> 1.0"
20
+ gem.add_dependency "redis-namespace", "~> 1.0.2"
21
+
22
+ gem.add_development_dependency "rake", ">= 0.9.2"
23
+ gem.add_development_dependency "simplecov", ">= 0.5.4"
24
+ gem.add_development_dependency "rr", ">= 1.0.0"
25
+ end
@@ -0,0 +1,90 @@
1
+ module Fluent
2
+ class ResqueExOutput < BufferedOutput
3
+ Fluent::Plugin.register_output('resque_ex', self)
4
+
5
+ include SetTagKeyMixin
6
+ config_set_default :include_tag_key, false
7
+
8
+ include SetTimeKeyMixin
9
+ config_set_default :include_time_key, true
10
+
11
+ config_param :queue, :string
12
+ config_param :redis, :string, :default => nil
13
+ config_param :worker_class_name_tag, :string, :default => 'class'
14
+
15
+ def initialize
16
+ super
17
+ require 'multi_json'
18
+ require 'redis'
19
+ require 'redis-namespace'
20
+ require 'uuidtools'
21
+ require 'digest/md5'
22
+ end
23
+
24
+ def configure(conf)
25
+ super
26
+
27
+ @worker_class_name_tag = conf['worker_class_name_tag'] || 'class'
28
+ self.redis = conf['redis'] if conf['redis']
29
+ end
30
+
31
+ # code from resque.rb
32
+ def redis=(server)
33
+ case server
34
+ when String
35
+ if server =~ /redis\:\/\//
36
+ redis = Redis.connect(:url => server, :thread_safe => true)
37
+ else
38
+ server, namespace = server.split('/', 2)
39
+ host, port, db = server.split(':')
40
+ redis = Redis.new(:host => host, :port => port,
41
+ :thread_safe => true, :db => db)
42
+ end
43
+ namespace ||= :resque
44
+
45
+ @redis = Redis::Namespace.new(namespace, :redis => redis)
46
+ when Redis::Namespace
47
+ @redis = server
48
+ else
49
+ @redis = Redis::Namespace.new(:resque, :redis => server)
50
+ end
51
+ end
52
+
53
+ def redis
54
+ return @redis if @redis && !@redis.kind_of?(String)
55
+ self.redis = Redis.respond_to?(:connect) ? Redis.connect : "localhost:6379"
56
+ self.redis
57
+ end
58
+
59
+ def enqueue(queue, klass, args)
60
+ id = Digest::MD5.hexdigest(UUIDTools::UUID.random_create.to_s)
61
+ redis.sadd(:queues, queue.to_s)
62
+ redis.rpush("queue:#{queue}", ::MultiJson.encode(:class => klass, :id => id, :args => [args]))
63
+ end
64
+
65
+ def start
66
+ super
67
+ end
68
+
69
+ def shutdown
70
+ super
71
+ end
72
+
73
+ def format(tag, time, record)
74
+ [tag, time, record].to_msgpack
75
+ end
76
+
77
+ def write(chunk)
78
+ queue_name = @queue_mapped ? chunk.key : @queue
79
+
80
+ chunk.msgpack_each {|tag, time, record|
81
+ klass = record.delete(@worker_class_name_tag)
82
+ if klass && !klass.empty?
83
+ enqueue(queue_name, klass, record)
84
+ else
85
+ $log.error("record have not #{@worker_class_name_tag} key.")
86
+ end
87
+ }
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,63 @@
1
+ require 'test_helper'
2
+ require 'fluent/plugin/out_resque'
3
+ require 'multi_json'
4
+
5
+ class ResqueOutputTest < Test::Unit::TestCase
6
+ def setup
7
+ super
8
+ Fluent::Test.setup
9
+ @subject = Object.new
10
+ any_instance_of(Fluent::ResqueOutput, :redis= => lambda {}, :redis => @subject)
11
+ end
12
+
13
+ CONFIG = %[
14
+ type resque
15
+ queue test_queue
16
+ time_format %y-%m-%d %H:%M:%S
17
+ ]
18
+
19
+ def create_driver(conf = CONFIG)
20
+ Fluent::Test::BufferedOutputTestDriver.new(Fluent::ResqueOutput) {
21
+ }.configure(conf)
22
+ end
23
+
24
+ def check_enqueue(queue, klass, args)
25
+ mock(@subject).sadd(:queues, "test_queue").any_times
26
+ mock(@subject).rpush("queue:#{queue}", ::MultiJson.encode(:class => klass, :args => [args]))
27
+ end
28
+
29
+ def test_write
30
+ d = create_driver
31
+ time = Time.at(Time.now.to_i).utc
32
+ d.emit({'a' => 1, "class" => "WorkerTest"}, time)
33
+ d.emit({'b' => 2, "class" => "WorkerTest"}, time)
34
+ check_enqueue("test_queue", "WorkerTest", {"a" => 1, "time" => time.strftime("%y-%m-%d %H:%M:%S")})
35
+ check_enqueue("test_queue", "WorkerTest", {"b" => 2, "time" => time.strftime("%y-%m-%d %H:%M:%S")})
36
+ d.run
37
+ assert_equal true, true
38
+ end
39
+
40
+ def test_write_except_time_key
41
+ d = create_driver(CONFIG + "\ninclude_time_key false")
42
+ time = Time.at(Time.now.to_i).utc
43
+ d.emit({'a' => 1, 'class' => 'WorkerTest'}, time)
44
+ check_enqueue("test_queue", "WorkerTest", {"a" => 1})
45
+ d.run
46
+ end
47
+
48
+ def test_write_include_tag_key
49
+ d = create_driver(CONFIG + "\ninclude_tag_key true")
50
+ time = Time.at(Time.now.to_i).utc
51
+ d.emit({'a' => 1, 'class' => 'WorkerTest'}, time)
52
+ check_enqueue("test_queue", "WorkerTest", {"a" => 1, "tag" => 'test', "time" => time.strftime("%y-%m-%d %H:%M:%S")})
53
+ d.run
54
+ end
55
+
56
+ def test_write_change_worker_class_name_tag
57
+ d = create_driver(CONFIG + "\nworker_class_name_tag klass")
58
+ time = Time.at(Time.now.to_i).utc
59
+ d.emit({'a' => 1, 'klass' => 'WorkerTest::Test'}, time)
60
+ check_enqueue("test_queue", "WorkerTest::Test", {"a" => 1, "time" => time.strftime("%y-%m-%d %H:%M:%S")})
61
+ d.run
62
+ end
63
+ end
@@ -0,0 +1,20 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+
4
+ require 'rr'
5
+ require 'test/unit'
6
+ class Test::Unit::TestCase
7
+ include RR::Adapters::TestUnit
8
+ end
9
+
10
+ if ENV['SIMPLE_COV']
11
+ require 'simplecov'
12
+ SimpleCov.start do
13
+ add_filter 'test/'
14
+ add_filter 'pkg/'
15
+ add_filter 'vendor/'
16
+ end
17
+ end
18
+
19
+ require 'test/unit'
20
+ require 'fluent/test'
metadata ADDED
@@ -0,0 +1,153 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-resque-ex
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Yuichi Tateno
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-04-21 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: fluentd
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 0.10.8
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.10.8
30
+ - !ruby/object:Gem::Dependency
31
+ name: multi_json
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '1.0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '1.0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: redis-namespace
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 1.0.2
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 1.0.2
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: 0.9.2
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: 0.9.2
78
+ - !ruby/object:Gem::Dependency
79
+ name: simplecov
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: 0.5.4
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: 0.5.4
94
+ - !ruby/object:Gem::Dependency
95
+ name: rr
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: 1.0.0
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: 1.0.0
110
+ description: Resque-ex enqueue plugin
111
+ email: hotchpotch@gmail.com
112
+ executables: []
113
+ extensions: []
114
+ extra_rdoc_files: []
115
+ files:
116
+ - .gitignore
117
+ - .travis.yml
118
+ - AUTHORS
119
+ - Gemfile
120
+ - README.rdoc
121
+ - Rakefile
122
+ - VERSION
123
+ - fluent-plugin-resque-ex.gemspec
124
+ - lib/fluent/plugin/out_resque_ex.rb
125
+ - test/plugin/out_resque.rb
126
+ - test/test_helper.rb
127
+ homepage: https://github.com/iyagi15/fluent-plugin-resque-ex
128
+ licenses: []
129
+ post_install_message:
130
+ rdoc_options: []
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ none: false
135
+ requirements:
136
+ - - ! '>='
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ required_rubygems_version: !ruby/object:Gem::Requirement
140
+ none: false
141
+ requirements:
142
+ - - ! '>='
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ requirements: []
146
+ rubyforge_project:
147
+ rubygems_version: 1.8.23
148
+ signing_key:
149
+ specification_version: 3
150
+ summary: Resque-ex enqueue plugin
151
+ test_files:
152
+ - test/plugin/out_resque.rb
153
+ - test/test_helper.rb