fluent-plugin-suppress 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,19 @@
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
18
+ *~
19
+ .#*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fluent-plugin-suppress.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2012 FUJIWARA Shunichiro
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
data/README.rdoc ADDED
@@ -0,0 +1,52 @@
1
+ = fluent-plugin-suppress
2
+
3
+ == Component
4
+
5
+ === SuppressOutout
6
+
7
+ Fluentd plugin to suppress same messages.
8
+
9
+ == Configuration
10
+
11
+ === SuppressOutput
12
+
13
+ fluentd.conf
14
+
15
+ <match foo.**>
16
+ type suppress
17
+ interval 10
18
+ num 2
19
+ attr_keys host,message
20
+ add_tag_prefix sp.
21
+ </match>
22
+
23
+ In [interval] sec, [num] messages which grouped by attr_keys value, add tag prefix "sp" and pass. Other messages will be removed.
24
+
25
+ Input messages:
26
+
27
+ 2012-11-22T11:22:33 foo.info {"id":1,"host":"web01","message":"error!!"}
28
+ 2012-11-22T11:22:34 foo.info {"id":2,"host":"web01","message":"error!!"}
29
+ * 2012-11-22T11:22:35 foo.info {"id":3,"host":"web01","message":"error!!"}
30
+ * 2012-11-22T11:22:36 foo.info {"id":4,"host":"web01","message":"error!!"}
31
+ 2012-11-22T11:22:37 foo.info {"id":5,"host":"app01","message":"error!!"}
32
+ * 2012-11-22T11:22:38 foo.info {"id":6,"host":"web01","message":"error!!"}
33
+ * 2012-11-22T11:22:39 foo.info {"id":7,"host":"web01","message":"error!!"}
34
+ * 2012-11-22T11:22:40 foo.info {"id":8,"host":"web01","message":"error!!"}
35
+ 2012-11-22T11:22:45 foo.info {"id":9,"host":"web01","message":"error!!"}
36
+ (* = suppressed)
37
+
38
+ Output messages:
39
+
40
+ 2012-11-22T11:22:33 sp.foo.info {"id":1,"host":"web01","message":"error!!"}
41
+ 2012-11-22T11:22:34 sp.foo.info {"id":2,"host":"web01","message":"error!!"}
42
+ 2012-11-22T11:22:37 sp.foo.info {"id":5,"host":"app01","message":"error!!"}
43
+ 2012-11-22T11:22:45 sp.foo.info {"id":9,"host":"web01","message":"error!!"}
44
+
45
+ == TODO
46
+
47
+ - patches welcome!
48
+
49
+ == Copyright
50
+
51
+ Copyright:: Copyright (c) 2012- FUJIWARA Shunichiro
52
+ License:: Apache License, Version 2.0
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env rake
2
+ # -*- mode:ruby -*-
3
+ require "bundler/gem_tasks"
4
+
5
+ require 'rake/testtask'
6
+ Rake::TestTask.new(:test) do |test|
7
+ test.libs << 'lib' << 'test'
8
+ test.pattern = 'test/**/test_*.rb'
9
+ test.verbose = true
10
+ end
11
+
12
+ task :default => :test
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # -*- mode:ruby -*-
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["FUJIWARA Shunichiro"]
6
+ gem.email = ["fujiwara.shunichiro@gmail.com"]
7
+ gem.description = %q{Fluentd plugin to suppress same messages}
8
+ gem.summary = %q{Fluentd plugin to suppress same messages}
9
+ gem.homepage = "https://github.com/fujiwara/fluent-plugin-suppress"
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-suppress"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = "0.0.1"
17
+
18
+ gem.add_development_dependency "fluentd"
19
+ gem.add_runtime_dependency "fluentd"
20
+ end
@@ -0,0 +1,65 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Fluent
3
+ class SuppressOutput < Output
4
+ Fluent::Plugin.register_output('suppress', self)
5
+
6
+ include Fluent::HandleTagNameMixin
7
+
8
+ config_param :attr_keys, :string, :default => nil
9
+ config_param :num, :integer, :default => 3
10
+ config_param :interval, :integer, :default => 300
11
+
12
+ def configure(conf)
13
+ super
14
+
15
+ unless @attr_keys
16
+ raise ConfigError, "out_suppress: attr_keys is required."
17
+ end
18
+
19
+ if ( !@remove_tag_prefix and !@remove_tag_suffix and !@add_tag_prefix and !@add_tag_suffix )
20
+ raise ConfigError, "out_suppress: Set remove_tag_prefix, remove_tag_suffix, add_tag_prefix or add_tag_suffix."
21
+ end
22
+
23
+ @keys = @attr_keys.split(/ *, */)
24
+ @slots = {}
25
+ end
26
+
27
+ def start
28
+ super
29
+ end
30
+
31
+ def shutdown
32
+ super
33
+ end
34
+
35
+ def emit(tag, es, chain)
36
+ es.each do |time, record|
37
+ key = @keys.map{|k| record[k]}.join("\0")
38
+ key = tag + "\0" + key
39
+ slot = @slots[key] ||= []
40
+
41
+ # expire old records time
42
+ expired = time.to_f - @interval
43
+ while slot.first and slot.first <= expired
44
+ slot.shift
45
+ end
46
+
47
+ if slot.length >= @num
48
+ $log.debug "suppressed record: #{record.to_json}"
49
+ break
50
+ end
51
+
52
+ slot.push(time.to_f)
53
+ _tag = tag.clone
54
+ filter_record(_tag, time, record)
55
+ if tag != _tag
56
+ Engine.emit(_tag, time, record)
57
+ else
58
+ $log.warn "Drop record #{record} tag '#{tag}' was not replaced. Can't emit record, cause infinity looping. Set remove_tag_prefix, remove_tag_suffix, add_tag_prefix or add_tag_suffix correctly."
59
+ end
60
+ end
61
+
62
+ chain.next
63
+ end
64
+ end
65
+ 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_suppress'
26
+
27
+ class Test::Unit::TestCase
28
+ end
@@ -0,0 +1,43 @@
1
+ require 'helper'
2
+
3
+ class SuppressOutputTest < Test::Unit::TestCase
4
+ def setup
5
+ Fluent::Test.setup
6
+ end
7
+
8
+ CONFIG = %[
9
+ interval 10
10
+ num 2
11
+ attr_keys host, message
12
+ add_tag_prefix sp.
13
+ ]
14
+
15
+ def create_driver(conf = CONFIG, tag='test.info')
16
+ Fluent::Test::OutputTestDriver.new(Fluent::SuppressOutput, tag).configure(conf)
17
+ end
18
+
19
+ def test_emit
20
+ d = create_driver
21
+
22
+ time = Time.parse("2012-11-22 11:22:33 UTC").to_i
23
+ d.run do
24
+ d.emit({"id" => 1, "host" => "web01", "message" => "error!!"}, time + 1)
25
+ d.emit({"id" => 2, "host" => "web01", "message" => "error!!"}, time + 2)
26
+ d.emit({"id" => 3, "host" => "web01", "message" => "error!!"}, time + 3)
27
+ d.emit({"id" => 4, "host" => "web01", "message" => "error!!"}, time + 4)
28
+ d.emit({"id" => 5, "host" => "app01", "message" => "error!!"}, time + 4)
29
+ d.emit({"id" => 6, "host" => "web01", "message" => "error!!"}, time + 12)
30
+ d.emit({"id" => 7, "host" => "web01", "message" => "error!!"}, time + 13)
31
+ d.emit({"id" => 8, "host" => "web01", "message" => "error!!"}, time + 14)
32
+ end
33
+
34
+ emits = d.emits
35
+ assert_equal 5, emits.length
36
+ assert_equal ["sp.test.info", time + 1, {"id"=>1, "host"=>"web01", "message"=>"error!!"}], emits[0]
37
+ assert_equal ["sp.test.info", time + 2, {"id"=>2, "host"=>"web01", "message"=>"error!!"}], emits[1]
38
+ assert_equal ["sp.test.info", time + 4, {"id"=>5, "host"=>"app01", "message"=>"error!!"}], emits[2]
39
+ assert_equal ["sp.test.info", time + 12, {"id"=>6, "host"=>"web01", "message"=>"error!!"}], emits[3]
40
+ assert_equal ["sp.test.info", time + 13, {"id"=>7, "host"=>"web01", "message"=>"error!!"}], emits[4]
41
+
42
+ end
43
+ end
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-suppress
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - FUJIWARA Shunichiro
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-22 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'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: fluentd
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '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: '0'
46
+ description: Fluentd plugin to suppress same messages
47
+ email:
48
+ - fujiwara.shunichiro@gmail.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .gitignore
54
+ - Gemfile
55
+ - LICENSE
56
+ - README.rdoc
57
+ - Rakefile
58
+ - fluent-plugin-supress.gemspec
59
+ - lib/fluent/plugin/out_suppress.rb
60
+ - test/helper.rb
61
+ - test/plugin/test_out_suppress.rb
62
+ homepage: https://github.com/fujiwara/fluent-plugin-suppress
63
+ licenses: []
64
+ post_install_message:
65
+ rdoc_options: []
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ! '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ! '>='
78
+ - !ruby/object:Gem::Version
79
+ version: '0'
80
+ requirements: []
81
+ rubyforge_project:
82
+ rubygems_version: 1.8.23
83
+ signing_key:
84
+ specification_version: 3
85
+ summary: Fluentd plugin to suppress same messages
86
+ test_files:
87
+ - test/helper.rb
88
+ - test/plugin/test_out_suppress.rb