åã«èªåã§æ¸ãã fluentdのためのプラグインをイチから書く手順 - tagomorisのメモ置き場 ã¯ããã¸ãéå®ãã¦ããã®ã ããæ¸ãããããå¾ã«ãªã£ã¦å®ã¯ç¾å¨ãã§ã« bundle gem ã³ãã³ãã使ããããããè¯ãããã ã¨ãããã¨ãããã£ã¦ãã¾ã£ããã°ãã°ããã¦ã¦ç§»è¡ãã¦ãªãã£ãã
ã§ãã¾ãã²ã¨ã¤ãã©ã°ã¤ã³ãæ¸ããã¨ã«ããã®ã§ã¤ãã§ã« bundle ã使ã£ãæé ããã£ããã¾ã¨ãã¦ããã以ä¸ã®ã¨ã³ããªãããã¸ãåèã«ããã¦ããã£ãã
T-POINTを取得するスクリプトをGistから移動, Bundlerを使ったGem作成メモ (自分用) - ただのにっき(2012-02-18)
æºåã¨ãã£ã¬ã¯ããªããªã¼ã®ä½æ
bundler ã¯å¿ è¦ãªã®ã§ããªã«ã¯ãªãã¨ãå ¥ãã¦ãããã
gem install bundler
ããã¦ãã©ã°ã¤ã³ç¨ãã£ã¬ã¯ããªããªã¼ãä½æãããä»å㯠DataCounterOutput ã¨ãããã©ã°ã¤ã³ãä½ããã¨ã«ãã¦ãããã±ã¼ã¸å㯠fluent-plugin-datacounter ã«ããã
$ bundle gem fluent-plugin-datacounter
create fluent-plugin-datacounter/Gemfile
create fluent-plugin-datacounter/Rakefile
create fluent-plugin-datacounter/.gitignore
create fluent-plugin-datacounter/fluent-plugin-datacounter.gemspec
create fluent-plugin-datacounter/lib/fluent-plugin-datacounter.rb
create fluent-plugin-datacounter/lib/fluent-plugin-datacounter/version.rb
Initializating git repo in /Users/tagomoris/Documents/fluent-plugin-datacounter
ãã¡ã¤ã«é ç½®ã fluentd plugin ã½ããªãã®ã§ä¿®æ£ããããã«ã³ãã³ããå©ãããã¨ãã¼ã¸ã§ã³ç®¡çã« version.rb ã使ãã®ã¯ rake build ã¨ãããã¨ãè²ã é¢åã ã£ãã®ã§åé¤ããã¼ã¸ã§ã³çªå·ã¯ gemspec ã«ç´æ¥æ¸ããã¨ã«ããã
$ cd fluent-plugin-datacounter/ $ mkdir -p lib/fluent/plugin $ mv lib/fluent-plugin-datacounter.rb lib/fluent/plugin/out_datacounter.rb $ rm lib/fluent-plugin-datacounter/version.rb $ rmdir lib/fluent-plugin-datacounter $ mkdir -p test/plugin $ touch test/plugin/test_out_datacounter.rb
out_datacounteræ¬ä½ã®ã¢ã¸ã¥ã¼ã«åã ãã¨ããããæ´æ°ãrequireã®ãã¹ã¨ã¢ã¸ã¥ã¼ã«åã ãæ¸ãæãã¦ãã(ãã¨ã§ã¡ããã¨ç´ã)ã
module Fluent class DataCounterOutput < Fluent::BufferedOutput # Your code goes here... end end
ããã«ããã㦠fluent-plugin-flowcounter.gemspec ãæ´æ°ãversionãhomepage, summary, descriptionãé©å½ã«å¤æ´ãããã¾ã version.rb ãrequireãã¦ããè¡ãåé¤ããã
# -*- encoding: utf-8 -*- $:.push File.expand_path("../lib", __FILE__) Gem::Specification.new do |s| s.name = "fluent-plugin-datacounter" s.version = "0.0.1" s.authors = ["TAGOMORI Satoshi"] s.email = ["[email protected]"] s.homepage = "https://github.com/tagomoris/fluent-plugin-datacounter" s.summary = %q{Output filter plugin to count messages that matches specified conditions} s.description = %q{Output filter plugin to count messages that matches specified conditions} s.rubyforge_project = "fluent-plugin-datacounter" # ... s.add_development_dependency "rake" s.add_runtime_dependency "fluentd" end
åºæ¬çã«ã¯ããã§ããã¯ããgemspecã«ä¾åã¢ã¸ã¥ã¼ã«ãæ¸ãã¦ãã Gemfile ã¯gemspecãèªã¿è¾¼ãã§ãã®ã§ bundle install ããã°å¿ è¦ãªã¢ã¸ã¥ã¼ã«(ããã§ã¯rake, fluentdã¨ãã®ä¾åã¢ã¸ã¥ã¼ã«ã ã)ã¯ã¤ã³ã¹ãã¼ã«ãããã
ãªãå㯠vendor/fluentd ã«submoduleãã¦ããã©ãæè¿ã¯ãããã«ãããããªãã¨ããªãã¦ããããªã¼ã¨æã£ã¦ã¦ãå²ã¨ãã£ãããã®ã¾ã¾ãªãªã¼ã¹çã®gemããfluentdãå ¥ãã¦ããã®ã§ããã®ã¸ãã¯çç¥ã
ã¤ãã§ã«ã©ã¤ã»ã³ã¹ãã©ãããã決ã㦠LICENSE.txt ã§ãç¨æãã¦æ¸ãã¦ãããfluentd ã Apache License v2.0 ãªã®ã§ããããã¦ãããªããã®ã¸ãã®æé¢ãçªã£è¾¼ãã§ããã°ããã
ã¾ã .gitignore ã«æä½éã®ãªã¹ãããããã©ãã¨ãã£ã¿ã®ããã¯ã¢ãããã¡ã¤ã«ãªã©ã¯å¿
è¦ã«å¿ãã¦è¿½è¨ãã¦ãããèªåã¯jewelerãä½ã£ã¦ãããã®ããé©å½ã«ã³ãã¼ãã¦ãã¦ãããªæãã
*.gem .bundle Gemfile.lock pkg/* # For TextMate, emacs, vim *.tmproj tmtags *~ \#* .\#* *.swp
ããã¾ã§ãã£ããã¨ããããå ¨é¨ commit ãã¦pushããã(pushããåã«githubå´ã§ãªãã¸ããªãä½ã£ã¦ãããã¨ã)
$ git add lib/fluent $ git add test $ git commit -m 'init tree' -a $ git remote add origin [email protected]:tagomoris/fluent-plugin-datacounter.git $ git push -u origin master
ãã©ã°ã¤ã³ã®éª¨çµã¿ãã¤ãã
ã¨ããããã©ã°ã¤ã³ã¨ãã¦æä½éã®ä½è£ãæ´ãã¦ãã¹ããèµ°ãããã«ãããããããªæãã«ãã¦ãããã¾ã out_datacounter.rb æ¬ä½ã®æ¹ã
class Fluent::DataCounterOutput < Fluent::BufferedOutput Fluent::Plugin.register_output('datacounter', self) # 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
ãã¨ãã¹ããã¾ã test/helper.rb ãä½ã£ã¦ãããããã«æ¸ãã fluent/test ã®èªã¿è¾¼ã¿ããªã㨠fluentd ã®TestDriverãªã©ãèªã¿è¾¼ã¾ããããã¹ããèµ°ããªããã¾ãããããæ¸ããã©ã°ã¤ã³ãã¡ããã¨æ¸ãã¦ãããã¾ããã¹ãèµ°è¡æã« fluentd ã®ãã°ãã³ã³ã½ã¼ã«ã«åºåãããªãããã« logger ãã´ãã§ã´ãã§ããã(VERBOSE=1 rake test ããã°åºã¦ããããã«ãããã)
require 'rubygems' require 'bundler' begin Bundler.setup(:default, :development) rescue Bundler::BundlerError => e $stderr.puts e.message $stderr.puts "Run `bundle install` to install missing gems" exit e.status_code end require 'test/unit' $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) $LOAD_PATH.unshift(File.dirname(__FILE__)) require 'fluent/test' unless ENV.has_key?('VERBOSE') nulllogger = Object.new nulllogger.instance_eval {|obj| def method_missing(method, *args) # pass end } $log = nulllogger end require 'fluent/plugin/out_datacounter' class Test::Unit::TestCase end
ã§ããã¹ãã®éª¨çµã¿ã test/plugin/test_out_datacounter.rb ã«ãcreate_driver ã«å¼æ°ã追å ã BufferedOutputTestDriver.new ã®å¼æ°ã«ãã©ã°ã¤ã³ã¯ã©ã¹ã®ä»ã«ã¿ã°ã渡ãããã«ãã¦ãããããã§ãã¹ãå 㧠'test' 以å¤ã®ã¿ã°ãæ±ããããªã£ã¦ã対å¿ã§ããã
require 'helper' class DataCounterOutputTest < Test::Unit::TestCase def setup Fluent::Test.setup end CONFIG = %[ ] # CONFIG = %[ # path #{TMP_DIR}/out_file_test # compress gz # utc # ] def create_driver(conf = CONFIG, tag='test') Fluent::Test::BufferedOutputTestDriver.new(Fluent::DataCounterOutput, tag).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 end end
Rakefileã«ãã¹ãç¨ã®è¨è¿°ã足ãã
diff --git a/Rakefile b/Rakefile index 2995527..f0f33ef 100644 --- a/Rakefile +++ b/Rakefile @@ -1 +1,11 @@ require "bundler/gem_tasks" + +require 'rake/testtask' +Rake::TestTask.new(:test) do |test| + test.libs << 'lib' << 'test' + test.pattern = 'test/**/test_*.rb' + test.verbose = true +end + +task :default => :test
ããã¾ã§ã§ããããã¹ããèµ°ãã¯ãã試ãã¦ã¿ããã
$ 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" /Users/tagomoris/.rvm/gems/ruby-1.9.2-p290/gems/fluentd-0.10.12/lib/fluent/plugin.rb:156: warning: already initialized constant Plugin 2012-02-21 18:17:36 +0900: registered output plugin 'datacounter' Loaded suite /Users/tagomoris/.rvm/gems/ruby-1.9.2-p290/gems/rake-0.9.2.2/lib/rake/rake_test_loader Started 2012-02-21 18:17:36 +0900: registered buffer plugin 'file' 2012-02-21 18:17:36 +0900: registered buffer plugin 'memory' 2012-02-21 18:17:36 +0900: registered input plugin 'exec' 2012-02-21 18:17:36 +0900: registered input plugin 'forward' 2012-02-21 18:17:36 +0900: registered input plugin 'http' 2012-02-21 18:17:36 +0900: registered input plugin 'tcp' 2012-02-21 18:17:36 +0900: registered input plugin 'unix' 2012-02-21 18:17:36 +0900: registered input plugin 'syslog' 2012-02-21 18:17:36 +0900: registered input plugin 'tail' 2012-02-21 18:17:36 +0900: registered output plugin 'copy' 2012-02-21 18:17:36 +0900: registered output plugin 'exec' 2012-02-21 18:17:36 +0900: registered output plugin 'exec_filter' 2012-02-21 18:17:36 +0900: registered output plugin 'file' 2012-02-21 18:17:36 +0900: registered output plugin 'forward' 2012-02-21 18:17:36 +0900: registered output plugin 'null' 2012-02-21 18:17:36 +0900: registered output plugin 'roundrobin' 2012-02-21 18:17:36 +0900: registered output plugin 'stdout' 2012-02-21 18:17:36 +0900: registered output plugin 'tcp' 2012-02-21 18:17:36 +0900: registered output plugin 'unix' 2012-02-21 18:17:36 +0900: registered output plugin 'test' ... Finished in 0.059279 seconds. 3 tests, 0 assertions, 0 failures, 0 errors, 0 skips Test run options: --seed 34276
ãã£ããã£ãï¼ ã¨ãããããããã¡ã© commit & push ãã¨ãã
$ git add test/helper.rb $ git commit -m 'write skeleton of plugin and its tests' -a
éçºããã¹ãããªãªã¼ã¹
éçºã¨ãã¹ãã¯ãã¾ããªãã ãé å¼µããéçºä¸ã«ãã®ãªãã¸ããªããgemãä½ããããªã£ãã rake build ãã¦ããããã¤ã³ã¹ãã¼ã«ããå ´å㯠rake install ããã°ãã(ããã)ã
ãªãªã¼ã¹ã¯ gemspec ã«æ¸ãã¦ãããã¼ã¸ã§ã³ãæ´æ°ããrubygems.org ã«ã¢ã«ã¦ã³ãããããªããã®ã¾ã¾ rake release ã§çµããã
ãã¤ãããã¾ã§ããï¼