diff --git a/README.md b/README.md index 54f94f8..d4e822e 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,9 @@ Fluentd output plugin to post message to xymon Install gem - fluent-gem install fluent-plugin-xymon +```` +fluent-gem install fluent-plugin-xymon +```` ## config @@ -14,10 +16,57 @@ Install gem config_param :xymon_server, :string config_param :xymon_port, :string, :default => '1984' config_param :color, :string, :default => 'green' - config_param :host, :string - config_param :column, :string + config_param :hostname, :string + config_param :testname, :string config_param :name_key, :string + config_param :custom_determine_color_code, :string, :default => nil +```` + +### example + + + type xymon + xymon_server 127.0.0.1 + xymon_port 1984 + color green + hostname web-server-01 + testname CPU + name_key CPUUtilization + custom_determine_color_code if value.to_i > 90; 'red'; else 'green'; end + + +## config_param :custom_determine_color_code + +set ruby code of determinate color to custom_determine_color_code. + +### Parameter + +time, record, value + +### Example + +#### everytime 'green' + +```` +custom_determine_color_code return 'green' +```` + +#### if value > 90 then 'red' else 'green' + +```` +custom_determine_color_code if value > 90; 'red'; else 'green'; end ```` +### config_param :color + +ignore :color if custom_determine_color_code is exist and valid. +use :color if custom_determine_color_code is noting or invalid + +### If raise some exception + +server didn't respond + +- use config color value +- write warn log ## Contributing @@ -26,3 +75,7 @@ Install gem 3. Commit your changes (`git commit -am 'Add some feature'`) 4. Push to the branch (`git push origin my-new-feature`) 5. Create new Pull Request + +## releases +2013/08/09 0.0.0 1st release +2013/08/10 0.0.1 https://github.com/bash0C7/fluent-plugin-xymon/pull/1 diff --git a/fluent-plugin-xymon.gemspec b/fluent-plugin-xymon.gemspec index bce303f..9a09da0 100644 --- a/fluent-plugin-xymon.gemspec +++ b/fluent-plugin-xymon.gemspec @@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) Gem::Specification.new do |spec| spec.name = "fluent-plugin-xymon" - spec.version = '0.0.0' + spec.version = '0.0.1' spec.authors = ["bash0C7"] spec.email = ["koshiba+github@4038nullpointer.com"] spec.description = "Fluentd output plugin to post message to xymon" diff --git a/lib/fluent/plugin/out_xymon.rb b/lib/fluent/plugin/out_xymon.rb index 4359995..f927f42 100644 --- a/lib/fluent/plugin/out_xymon.rb +++ b/lib/fluent/plugin/out_xymon.rb @@ -10,12 +10,21 @@ def initialize config_param :xymon_server, :string config_param :xymon_port, :string, :default => '1984' config_param :color, :string, :default => 'green' - config_param :host, :string - config_param :column, :string + config_param :hostname, :string + config_param :testname, :string config_param :name_key, :string + config_param :custom_determine_color_code, :string, :default => nil def configure(conf) super + + @custom_determine_color = nil + begin + @custom_determine_color = eval("lambda {|time, record, value| #{@custom_determine_color_code}}") if @custom_determine_color_code + rescue Exception + raise Fluent::ConfigError, "custom_determine_color_code: #{$!.class}, '#{$!.message}'" + end + end def start @@ -31,7 +40,7 @@ def emit(tag, es, chain) es.each {|time,record| next unless value = record[@name_key] - messages.push build_message(time, value) + messages.push build_message(time, record, value) } messages.each do |message| post(message) @@ -40,9 +49,16 @@ def emit(tag, es, chain) chain.next end - def build_message time, value + def build_message time, record, value + begin + color = @custom_determine_color.call(time, record, value) if @custom_determine_color + rescue Exception + $log.warn "raises exception: #{$!.class}, '#{$!.message}', '#{@custom_determine_color_code}', '#{time}', '#{record}', '#{value}'" + end + + color ||= @color body = "#{@name_key}=#{value}" - message = "status #{@host}.#{@column} #{@color} #{Time.at(time)} #{@column} #{body}\n\n#{body}" + message = "status #{@hostname}.#{@testname} #{color} #{Time.at(time)} #{@testname} #{body}\n\n#{body}" message end @@ -61,4 +77,4 @@ def post(message) end end -end \ No newline at end of file +end diff --git a/spec/lib/fluent/plugin/out_xymon_spec.rb b/spec/lib/fluent/plugin/out_xymon_spec.rb index 184d54a..41d2eb3 100644 --- a/spec/lib/fluent/plugin/out_xymon_spec.rb +++ b/spec/lib/fluent/plugin/out_xymon_spec.rb @@ -1,88 +1,209 @@ require 'spec_helper' describe do - let(:config) { - %[ + let(:driver) {Fluent::Test::OutputTestDriver.new(Fluent::XymonOutput, 'test.metrics').configure(config)} + let(:instance) {driver.instance} + + describe 'config' do + let(:config) { + %[ xymon_server 127.0.0.1 xymon_port 1984 - color red - host host1 - column column1 + color red + hostname host1 + testname column1 name_key field1 - ] - } - - let(:driver) { - Fluent::Test::OutputTestDriver.new(Fluent::XymonOutput, 'test.metrics').configure(config) - } - - describe 'config' do + ] + } + context do - subject {driver.instance.xymon_server} + subject {instance.xymon_server} it{should == '127.0.0.1'} end context do - subject {driver.instance.xymon_port} + subject {instance.xymon_port} it{should == '1984'} end context do - subject {driver.instance.color} + subject {instance.color} it{should == 'red'} end context do - subject {driver.instance.host} + subject {instance.hostname} it{should == 'host1'} end context do - subject {driver.instance.column} + subject {instance.testname} it{should == 'column1'} end context do - subject {driver.instance.name_key} + subject {instance.name_key} it{should == 'field1'} end + describe 'custom_determine_color_code' do + context 'not_exist' do + let(:config) { + %[ + xymon_server 127.0.0.1 + xymon_port 1984 + color red + hostname host1 + testname column1 + name_key field1 + ] + } + + subject {instance.custom_determine_color_code} + it{should be_nil} + end + + context 'exist custom_determine_color_code' do + let(:config) { + %[ + xymon_server 127.0.0.1 + xymon_port 1984 + color red + hostname host1 + testname column1 + name_key field1 + custom_determine_color_code #{custom_determine_color_code} + ] + } + context 'valid syntax' do + let(:custom_determine_color_code) {"return 'green'"} + + subject {instance.custom_determine_color_code} + it{should == custom_determine_color_code} + end + + context 'invalid syntax' do + let(:custom_determine_color_code) {"(><)"} + + subject {lambda{instance.custom_determine_color_code}} + it{should raise_error(Fluent::ConfigError)} + end + end + end end describe 'build_message' do - context do - subject {driver.instance.build_message(0, 50)} - it{should == "status #{driver.instance.host}.#{driver.instance.column} #{driver.instance.color} #{Time.at(0)} #{driver.instance.column} #{driver.instance.name_key}=50\n\n#{driver.instance.name_key}=50"} + let(:name_key) {'field1'} + + let(:record) {{ name_key => 50, 'otherfield' => 99}} + let(:time) {0} + let(:value) {record[name_key]} + + let(:built) {instance.build_message(time, record, value)} + context 'empty custom_determine_color_code' do + let(:config) { + %[ + xymon_server 127.0.0.1 + xymon_port 1984 + color red + hostname host1 + testname column1 + name_key field1 + ] + } + + subject {built} + it{should == "status #{instance.hostname}.#{instance.testname} #{instance.color} #{Time.at(0)} #{instance.testname} #{instance.name_key}=50\n\n#{instance.name_key}=50"} + end + + context 'exist custom_determine_color_code' do + let(:config) { + %[ + xymon_server 127.0.0.1 + xymon_port 1984 + color red + hostname host1 + testname column1 + name_key #{name_key} + custom_determine_color_code #{custom_determine_color_code} + ] + } + + context 'valid custom_determine_color_code' do + let(:custom_determine_color_code) {"if value.to_i > 90; 'red'; else 'green'; end"} + + subject {built} + it{should == "status #{instance.hostname}.#{instance.testname} #{'green'} #{Time.at(time)} #{instance.testname} #{instance.name_key}=#{value}\n\n#{instance.name_key}=#{value}"} + end + + context 'invalid syntax custom_determine_color_code' do + let(:custom_determine_color_code) {'Fluent::XymonOutput::UNDEFINED_CONST'} + + subject { + mock($log).warn("raises exception: NameError, 'uninitialized constant #{custom_determine_color_code}', 'Fluent::XymonOutput::UNDEFINED_CONST', '#{time}', '#{record.to_s}', '#{record[name_key]}'").times 1 + built + } + it{should == "status #{instance.hostname}.#{instance.testname} #{instance.color} #{Time.at(time)} #{instance.testname} #{instance.name_key}=#{value}\n\n#{instance.name_key}=#{value}"} + end end end describe 'emit' do - + let(:record) {{ 'field1' => 50, 'otherfield' => 99}} + let(:time) {0} let(:posted) { d = driver mock(IO).popen("nc '#{d.instance.xymon_server}' '#{d.instance.xymon_port}'", 'w').times 1 - d.emit({ 'field1' => 50, 'otherfield' => 99}) - d.run + d.emit(record, Time.at(time)) + d.run } - context do + context 'empty custom_determine_color_code' do + let(:config) { + %[ + xymon_server 127.0.0.1 + xymon_port 1984 + color red + hostname host1 + testname column1 + name_key field1 + ] + } + subject {posted} it{should_not be_nil} end - # context do - # subject {posted[:data][:message]} - # it{should =~ "status #{driver.instance.host}.#{driver.instance.column} #{driver.instance.color} [^\n]+\n\n#{driver.instance.name_key}=50"} - # end - # - # context do - # subject {posted[:data][:xymon_server]} - # it{should == driver.instance.xymon_server} - # end - # - # context do - # subject {posted[:data][:xymon_port]} - # it{should == driver.instance.xymon_port} - # end + context 'exist custom_determine_color_code' do + let(:name_key) {'field1'} + let(:config) { + %[ + xymon_server 127.0.0.1 + xymon_port 1984 + color red + hostname host1 + testname column1 + name_key #{name_key} + custom_determine_color_code #{custom_determine_color_code} + ] + } + + context 'valid code' do + let(:custom_determine_color_code) {"if value.to_i > 90; 'red'; else 'green'; end"} + + subject {posted} + it{should_not be_nil} + end + + context 'runtime error' do + let(:custom_determine_color_code) {'Fluent::XymonOutput::UNDEFINED_CONST'} + + subject { + mock($log).warn("raises exception: NameError, 'uninitialized constant Fluent::XymonOutput::UNDEFINED_CONST', 'Fluent::XymonOutput::UNDEFINED_CONST', '#{time}', '#{record.to_s}', '#{record[name_key]}'").times 1 + posted + } + it{should_not be_nil} + end + end end -end +end \ No newline at end of file