(2012/02/21追è¨: bundle gem ãã¦ä½æããæé ããã£ã¡ã«æ¸ãã http://d.hatena.ne.jp/tagomoris/20120221/1329815126 )
fluentdãããæãã§ããã©ã¼ãã³ã¹ã«ãåé¡ãªãç¶æ³ã«ãªã£ã¦ããããã«è¦ããã®ã§ããã£ãããã£ã¡ããã©ã°ã¤ã³ã§ãæ¸ããï¼ ã¨æã£ããã®ã®ãªãã¸ããªãgithubã«ä½ã£ãã¯ãããã³ã¼ãæ¸ãã¦ãã¹ããã¦gemã¨ãã¦ãªãªã¼ã¹ããã¾ã§ã«ã¯æ§ã ã«ããã©ããããã¨ããã gem ã¨ãä½ã£ããã¨ãªãèªå*1ã«ã¯æ©è¨¶ä¸æè°ãªãããããããåºãã£ã¦ãã¦ã³ã¼ãæ¸ãã¨ããã«è¾¿ãã¤ãã¾ã§ãé·éããã¨ãããã端çã«è¨ã£ã¦ãã¡ãã¡ã«æ£å¨ããæ å ±ãéããã®ã«å¿ è¦ãªæéã¨ã¨ãã«ããæ°ãã¨ãã©ãªãæµåºãã¦ãã£ã¦ããã ãã ã¨ããæ°åã«ãªãã
ã¨ãããããªä¸»æ¨ã®tweetããã¦ã¿ããã®ã®ã©ãã«ããªãããã§ããªãã®ã§ã試è¡é¯èª¤ããªããããã«ã¡ã¢ã£ã¨ããããããã»ãããããï¼ ã¨ãã話ããã£ãããã²æãã¦ã»ããã
â¦â¦ã¨æã£ããã俺ã¯ã©ããæ ¹æ¬ããééã£ã¦ããããã ã
ruby のGemパッケージを作る方法.その2 - それマグで!
ããããã¼ã¹ã«æ¹æ³ãçµã¿ç«ã¦ç´ãã¦ã¿ããèªåã®æå 㧠fluent-plugin-hoop ãã©ã°ã¤ã³ãä½ã£ã¦ããã®ã§ããã®æé ãã®ã¾ã¾ãã¨ããããBufferedOutputãã©ã°ã¤ã³ãä½ãã®ã§ãã®æé ã«ãªã£ã¦ããã¨ã«æ³¨æã
jewelerã使ãæºåã¨ãã£ã¬ã¯ããªããªã¼ããªãã¸ããªã®ä½æ
ã¾ã jewelerã¨gemcutterãå ¥ãããã¾ãæè¿ã¯ã©ãã常èã£ã½ãã®ã§ãã¾ã å ¥ã£ã¦ãªããã° bundle ãã¤ã³ã¹ãã¼ã«ãã¦ãããã
gem install jeweler gem install gemcutter gem install bundle
ãããããã£ã¬ã¯ããªããªã¼ã®åæç¶æ ãããã³githubã®ãªãã¸ããªãã¾ã¨ãã¦ä½ããgithubã®è¨å®ãè¡ããã¦ããªãå ´åã«ã¯è¦åãåºãã®ã§ãã®éãã®ã³ãã³ããå©ãã¦ãããªãã©ã¤ããã°ãããgithubã®API Keyã¯githubã®ã¢ã«ã¦ã³ãè¨å®ãã¼ã¸ã«ããã
$ jeweler --create-repo fluent-plugin-hoop create .gitignore create Rakefile create Gemfile create LICENSE.txt create README.rdoc create .document create lib create lib/fluent-plugin-hoop.rb create test create test/helper.rb create test/test_fluent-plugin-hoop.rb
ããã§å¿ è¦ãªãã¡ã¤ã«ã²ã¨ã¨ããããããããã®æç¹ã§githubã¸ã®pushãèªåçã«è¡ããã¦ããã
ãã ãããã 㨠fluentd ã®ãã©ã°ã¤ã³ç¨ã®ãã£ã¬ã¯ããªæ§æã«ãªã£ã¦ããªãã®ã§ã以ä¸ã®ããã«ã³ãã³ããå©ãã¦åé ç½®ããã
mkdir -p lib/fluent/plugin git mv lib/fluent-plugin-hoop.rb lib/fluent/plugin/out_hoop.rb mkdir -p test/plugin git mv test/test_fluent-plugin-hoop.rb test/plugin/test_out_hoop.rb git commit -m 'replace for fluentd plugin style' -a
ã¾ãããã«ããã㦠test/helper.rb ã®ä¸èº«ã1è¡ã ãæ¸ãæããã
@@ -12,7 +12,7 @@ require 'shoulda' $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) $LOAD_PATH.unshift(File.dirname(__FILE__)) -require 'fluent-plugin-hoop' +require 'fluent/plugin/out_hoop' class Test::Unit::TestCase end
fluentãæã£ã¦ãã
fluentdã®ã³ã¼ãã¯å¤§å¤é »ç¹ã«ã¢ãããã¼ãããã¦ããã®ã§ããã©ã°ã¤ã³ãæ¸ãä¸ã§ã¯å¸¸ã«ææ°çãåç §ã§ããããã«ãã¦ããã®ããããããã¨ãããã¨ã§ git submodule ã使ã£ã¦ãã©ã°ã¤ã³ã®ããªã¼ä¸ã«ãã£ã¦ããã
git submodule add git://github.com/fluent/fluentd.git vendor/fluentd git commit -m 'add fluentd as submodule' -a
ãã¨ã®ä½æ¥ã®ããã«ããã§gemspecãä½ã£ã¦ãããããªãrvmã使ã£ã¦ããå ´å vendor/fluentd ã«è¡ãã¨ããã«ãã .rvmrc ã使ããã¨èãããããå¥ã«ãããªãã®ã§ No ã«ãã¦ããã
cd vendor/fluentd rake gemspec cd ../..
Gemfile ã rake -T ããã³ bundle install
ããã§ããããã« rake -T ãã¦ã¿ãã¨ããªãã足ããªãã¨ãè¨ãããã
$ rake -T (in /Users/tagomoris/Documents/fluent-plugin-hoop) Could not find gem 'shoulda (>= 0)' in any of the gem sources listed in your Gemfile. Run `bundle install` to install missing gems
Gemfileãã®ããã¦ã¿ã㨠shoulda ã¨ãããã®ããããããããã¤ãã§ã«Gemfileã«fluentdã足ãã¦ãããã
source "http://rubygems.org" # Add dependencies required to use your gem here. # Example: # gem "activesupport", ">= 2.3.5" # Add dependencies to develop your gem here. # Include everything needed to run rake, tests, features, etc. group :development do gem "shoulda", ">= 0" gem "bundler", "~> 1.0.0" gem "jeweler", "~> 1.6.4" gem "rcov", ">= 0" end gem "fluentd", :path => 'vendor/fluentd' if RUBY_VERSION >= "1.9.2"
ãã㧠bundle install ããã
$ bundle install Using rake (0.9.2.2) Using bundler (1.0.18) Using iobuffer (1.0.0) Using cool.io (1.0.0) Using http_parser.rb (0.5.2) Using json (1.6.1) Using msgpack (0.4.6) Using yajl-ruby (1.0.0) Using fluentd (0.10.6) from source at vendor/fluentd Using git (1.2.5) Using jeweler (1.6.4) Using rcov (0.9.11) Using shoulda (2.11.3) Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.
Gemfileãcommitãã¦ããã
git commit -m 'add fluentd' Gemfile
AUTHORS ãä½ã LICENSE.txt 㨠.gitignore ãæ´æ°ã VERSION ãä½ã
ã¨ããããèªåã®ååã¨ã¡ã¼ã«ã¢ãã¬ã¹ãå ¥ãã¦é£çµ¡ãããã¤ãããã«ãã¦ãããã
echo 'TAGOMORI Satoshi <tagomoris _at_ gmail.com>' > ./AUTHORS git add AUTHORS
ãã¨LICENSE.txtã¯ä¿®æ£BSDã©ã¤ã»ã³ã¹ã§ä½ããã¦ããããã ãã¾ããã®ã¾ã¾ã§ãããã£ã¡ããããã ãã© fluentd ã Apache License v2 ãªã®ã§ããã«ãããã¦ãããã¾ãã¦ãã¨ãã«ã³ãããããªãããã¨ããããã
ãã㨠.gitignore ãç·¨éãã¦ãããããã©ã«ãã§è²ã ãªã¨ãã£ã¿å¯¾çã®è¨è¿°ãããããããã«å ã㦠vendor ãã£ã¬ã¯ããªã«å ¥ã£ããã®ãcommitããªãããã«ããªã©ããã£ã¦ããã
$ cat .gitignore # rcov generated coverage # rdoc generated rdoc # yard generated doc .yardoc # bundler .bundle # jeweler generated pkg # For MacOS .DS_Store # For TextMate, emacs, vim *.tmproj tmtags *~ \#* .\#* *.swp # not to lock gems version, and for bundler Gemfile.lock vendor
ã¨ããããããã§VERSIONãã¡ã¤ã«ãä½ã£ã¨ããï¼
$ rake version:write Updated version: 0.0.0 $ ls AUTHORS Gemfile.lock README.rdoc VERSION test Gemfile LICENSE.txt Rakefile lib vendor $ cat VERSION 0.0.0
ããã¾ã§ãã£ã¦commitããããã£ã¹ã¯ãã¯ã©ãã·ã¥ããã¨æ³£ãã¡ããã®ã§pushããã¦ãããã
git commit -m 'update for this plugin' -a git push -u origin master
ãã©ã°ã¤ã³ã®éª¨çµã¿ãã¤ãã
ãã®ã¾ã¾ããããã« rake ã¨ãå®è¡ããã¨ãªããè¨ãããã
$ rake WARNING: 'require 'rake/rdoctask'' is deprecated. Please use 'require 'rdoc/task' (in RDoc 2.4.2+)' instead. at /Users/tagomoris/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/rdoctask.rb /Users/tagomoris/.rvm/rubies/ruby-1.9.2-p290/bin/ruby -I"lib:lib:test" -I"/Users/tagomoris/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib" "/Users/tagomoris/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/rake_test_loader.rb" "test/**/test_*.rb" Loaded suite /Users/tagomoris/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/rake_test_loader Started F Finished in 0.001525 seconds. 1) Failure: test: FluentPluginHoop should probably rename this file and start testing for real. (TestFluentPluginHoop) [/Users/tagomoris/Documents/fluent-plugin-hoop/test/plugin/test_out_hoop.rb:5]: hey buddy, you should probably rename this file and start testing for real 1 tests, 1 assertions, 1 failures, 0 errors, 0 skips Test run options: --seed 34610 rake aborted! Command failed with status (1): [/Users/tagomoris/.rvm/rubies/ruby-1.9.2-p2...] Tasks: TOP => test (See full trace by running task with --trace)
ã¨ãããã Rakefile ã® require 'rake/rdoctask' ã¨æ¸ãã¦ããã¨ããã require 'rdoc/task' ã«å¤ã㦠Gemfile ã« gem "rdoc" ã¨è¿½å ããã
rake ããã¨ãæ£å¸¸ã«ãªã£ã¦ããããã ã
$ rake /Users/tagomoris/.rvm/rubies/ruby-1.9.2-p290/bin/ruby -I"lib:lib:test" -I"/Users/tagomoris/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib" "/Users/tagomoris/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/rake_test_loader.rb" "test/**/test_*.rb" Loaded suite /Users/tagomoris/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/rake_test_loader Started F Finished in 0.001340 seconds. 1) Failure: test: FluentPluginHoop should probably rename this file and start testing for real. (TestFluentPluginHoop) [/Users/tagomoris/Documents/fluent-plugin-hoop/test/plugin/test_out_hoop.rb:5]: hey buddy, you should probably rename this file and start testing for real 1 tests, 1 assertions, 1 failures, 0 errors, 0 skips Test run options: --seed 37798 rake aborted! Command failed with status (1): [/Users/tagomoris/.rvm/rubies/ruby-1.9.2-p2...] Tasks: TOP => default => test (See full trace by running task with --trace)
ãã¦ãæ¸ã対象ã®ãã©ã°ã¤ã³ã¢ã¸ã¥ã¼ã«ã®ä½è£ãããã¯æ´ããªãã¨TDDãã§ããªããã®ã§ãæ¸ã対象ã®ãã©ã°ã¤ã³ãã¤ãããæ£ç¢ºã«è¨ãã¨ä»¥ä¸ã®ãã¼ã¸ããã¢ã¸ã¥ã¼ã«åã ãå¤ã㦠lib/fluent/plugin/out_hoge.rb ã«ã³ããããã
http://fluentd.org/doc/devel.html
ããã¯BufferedOutputãã©ã°ã¤ã³ã®ä¾ãããããªãããããªã¼ãå
¬å¼ã®ä¾ã ã¨MessagePackãoptionalã¿ãããªæãã«ãªã£ã¦ããã©ãæ®éã«MessagePack使ãå½¢ã§æ¸ãã°ããã¨æããJSONã«ããã»ããããã±ã¼ã¹ã£ã¦ããã®ããªãJSONããã®ã¾ã¾åºåãããã±ã¼ã¹ããããã®ããããªã®ãããã®ããªã
class Fluent::HoopOutput < Fluent::BufferedOutput Fluent::Plugin.register_output('hoop', self) include Fluent::SetTagKeyMixin config_set_default :include_tag_key, false include Fluent::SetTimeKeyMixin config_set_default :include_time_key, true # config_param :hoge, :string, :default => 'hoge' def initialize super # require 'hogepos' end def configure(conf) super # @path = conf['path'] end def start super # init end def shutdown super # destroy end def format(tag, time, record) [tag, time, record].to_msgpack end def write(chunk) records = [] chunk.msgpack_each { |record| # records << record } # write records end end
ç¶ãã¦ãã¹ãã®éª¨çµãä½ã£ã¦ãã¾ããããã¥ã¡ã³ãâ¦â¦ã«ã¯æ®å¿µãªãããªãã®ã§ fluentd æ¬å®¶ã®ãã¹ãã³ã¼ãããæ çµã¿ãã±ãã£ã¦ãã¦ä»¥ä¸ã®ã³ã¼ãã test/plugin/test_out_hoge.rb ã«ã³ããããããã©ã°ã¤ã³ç¨ã®ãã¹ããã©ã¤ãã®ã³ã¼ãä¾ã¯ãªãã¨å¿ããããªã®ã§ã³ã¡ã³ãã¢ã¦ããã¦ããé¨åã¯æ®ãã¦ããããã(èªåã¯ã)
require 'helper' # require 'time' class HoopOutputTest < Test::Unit::TestCase # TMP_DIR = File.dirname(__FILE__) + "/../tmp" def setup Fluent::Test.setup # FileUtils.rm_rf(TMP_DIR) # FileUtils.mkdir_p(TMP_DIR) end CONFIG = %[ ] # CONFIG = %[ # path #{TMP_DIR}/out_file_test # compress gz # utc # ] def create_driver(conf = CONFIG) Fluent::Test::BufferedOutputTestDriver.new(Fluent::HoopOutput).configure(conf) end def test_configure #### set configurations # d = create_driver %[ # path test_path # compress gz # ] #### check configurations # assert_equal 'test_path', d.instance.path # assert_equal :gz, d.instance.compress end def test_format d = create_driver # time = Time.parse("2011-01-02 13:14:15 UTC").to_i # d.emit({"a"=>1}, time) # d.emit({"a"=>2}, time) # d.expect_format %[2011-01-02T13:14:15Z\ttest\t{"a":1}\n] # d.expect_format %[2011-01-02T13:14:15Z\ttest\t{"a":2}\n] # d.run end def test_write d = create_driver # time = Time.parse("2011-01-02 13:14:15 UTC").to_i # d.emit({"a"=>1}, time) # d.emit({"a"=>2}, time) # ### FileOutput#write returns path # path = d.run # expect_path = "#{TMP_DIR}/out_file_test._0.log.gz" # assert_equal expect_path, path # data = Zlib::GzipReader.open(expect_path) {|f| f.read } # assert_equal %[2011-01-02T13:14:15Z\ttest\t{"a":1}\n] + # %[2011-01-02T13:14:15Z\ttest\t{"a":2}\n], # data end end
ã¾ã test/helper.rb ã«ãå¿ è¦ãªè¨è¿°ã追å ããã
@@ -12,6 +12,7 @@ require 'shoulda' $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) $LOAD_PATH.unshift(File.dirname(__FILE__)) +require 'fluent/test' require 'fluent/plugin/out_hoop' class Test::Unit::TestCase
ããã§ããããããï¼ ã¨æºãæã㦠rake test ãã£ããéãã¾ããï¼ ãã£ããï¼*2
$ rake test /Users/tagomoris/.rvm/rubies/ruby-1.9.2-p290/bin/ruby -I"lib:lib:test" -I"/Users/tagomoris/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib" "/Users/tagomoris/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/rake_test_loader.rb" "test/**/test_*.rb" 2011-11-18 16:39:49 +0900: registered output plugin 'hoop' Loaded suite /Users/tagomoris/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/rake_test_loader Started 2011-11-18 16:39:49 +0900: registered buffer plugin 'file' 2011-11-18 16:39:49 +0900: registered buffer plugin 'memory' 2011-11-18 16:39:49 +0900: registered input plugin 'exec' 2011-11-18 16:39:49 +0900: registered input plugin 'forward' 2011-11-18 16:39:49 +0900: registered input plugin 'http' 2011-11-18 16:39:49 +0900: registered input plugin 'tcp' 2011-11-18 16:39:49 +0900: registered input plugin 'unix' 2011-11-18 16:39:49 +0900: registered input plugin 'syslog' 2011-11-18 16:39:49 +0900: registered input plugin 'tail' 2011-11-18 16:39:49 +0900: registered output plugin 'copy' 2011-11-18 16:39:49 +0900: registered output plugin 'exec' 2011-11-18 16:39:49 +0900: registered output plugin 'exec_filter' 2011-11-18 16:39:49 +0900: registered output plugin 'file' 2011-11-18 16:39:49 +0900: registered output plugin 'forward' 2011-11-18 16:39:49 +0900: registered output plugin 'null' 2011-11-18 16:39:49 +0900: registered output plugin 'roundrobin' 2011-11-18 16:39:49 +0900: registered output plugin 'stdout' 2011-11-18 16:39:49 +0900: registered output plugin 'tcp' 2011-11-18 16:39:49 +0900: registered output plugin 'unix' 2011-11-18 16:39:49 +0900: registered output plugin 'test' ... Finished in 0.108051 seconds. 3 tests, 0 assertions, 0 failures, 0 errors, 0 skips Test run options: --seed 4553
ããã§ãããã ãã©ããã¹ããç¹°ãè¿ãã¦ãã¨fluentdã®åºããã°ãã¡ãã£ã¨ãããæããªã®ã§ã以ä¸ã®ããã«ãã¦æå¶ããã
diff --git a/test/helper.rb b/test/helper.rb index bc0a6c3..ffeccdf 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -12,7 +12,19 @@ require 'shoulda' $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) $LOAD_PATH.unshift(File.dirname(__FILE__)) +require 'fluent/test' require 'fluent/plugin/out_test_counter' +if ENV['FLUENT_TEST_DEBUG'] == 'TRUE' + nulllogger = Object.new + nulllogger.instance_eval {|obj| + def method_missing(method, *args) + # pass + end + } + $log = nulllogger +end + + class Test::Unit::TestCase end diff --git a/Rakefile b/Rakefile index 3f33bf8..212228c 100644 --- a/Rakefile +++ b/Rakefile @@ -27,6 +27,9 @@ Jeweler::RubygemsDotOrgTasks.new require 'rake/testtask' Rake::TestTask.new(:test) do |test| + unless ENV['DEBUG'] + ENV['FLUENT_TEST_DEBUG'] = 'TRUE' + end test.libs << 'lib' << 'test' test.pattern = 'test/**/test_*.rb' test.verbose = true
ãããã¨ãã¨æ®éã®ãã¹ãå®è¡æã«ã¯fluentdã®ãã°ãåºã¦ããªãããã©ã°ã¤ã³ã®ãã¼ãã¾ãããªã©ã§æªãããããã°è¦ãããªã¼ã¨ããã¨ãã¯ãªãã·ã§ã³å¼æ°ãä¸ããã°åºã¦ããã
$ rake test DEBUG=true
ãã£ããï¼ããã§æºåã¯å®äºãªã®ã§ã¾ã commit & push ãã¦ããã
git commit -m 'plugin initialized' -a git push
ãã¨ã¯å®å¦çãæ¸ãã¦ãªãªã¼ã¹
ããã¾ã§æ¥ãããã¨ã¯ãã¹ãæ¸ãã¦ã³ã¼ãæ¸ãã¦ãã¹ãæ¸ãã¦ã³ã¼ãæ¸ãã¦ãå®æããããªãªã¼ã¹ãã®ã¯ãã
ã¾ããªãªã¼ã¹ã«ã¾ãã²ã¨æ¶çããããã ããããã¯ã³ã¼ãæ¸ãã¦ããå¿é
ããã°ããã®ããªã¼ã¨æãããã°ããå
ã®è©±ã
ããæ¸ããã¼ï¼
*1:ã¨ãããCPANã¨ãããªãããªã«ããªããè¨èª(ã®ããã±ã¼ã¸ãªãã¸ããª)ãã¨ã«ç§ä¼ãããå²ã¨é »ç¹ã«ã¢ãããã¼ãããã¦ãã¦ãããããããªãã
*2:ãã¡ããæåã¯ãã¾ããããªãã¦ä¸ç¥ã¨ããç¶æ ã ã£ãããä¸ã«ã³ãããã¦ããã³ã¼ããªã大ä¸å¤«ãã®ã¯ãï¼