fluent-plugin-conditional_filter 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6cc5c490e9566041f5cd52dcdbccaa2e37db1477
4
- data.tar.gz: bd5605aeb0b2ed35045020e9b1a45ab0e9206146
3
+ metadata.gz: 4e96a9f324a32ecb3745e54e5d249407cea733ce
4
+ data.tar.gz: 853c3cbe3440a42d81b7a72f3642f2592ac16646
5
5
  SHA512:
6
- metadata.gz: 9cda736e9cdbddc4e0d4cdec38f9c5e913bec91817c3d4085209d07d0be6164abb11615679e29bdd4b2e326b965ea5ad5bc30ce01c9aba078dde35db84926dca
7
- data.tar.gz: d5d9fef02572bc606b5877382b045f1ede9975682a425d314b2d91423da8ab767308512c03b019eda1aac89e7afe677e31ea244ea6e913f63244f8b486df9694
6
+ metadata.gz: eec6a1bae7039cbdd952e0cd772b584f59e22b4cf9182eff13bcd551383c3d0a880a67954a66f25aeacb811a395c2cb1bd14aed07fe5badfffd299b7d107a7b0
7
+ data.tar.gz: 0a3dc292804cde6c81b3b19572170ba39eaeca7ff42b83ab0ac2b61eb8eeb75839204fc34e15dbfd9e8af1ce93669abeb709b4d1b66e9c8c572a75263be12cb7
data/README.md CHANGED
@@ -2,6 +2,57 @@
2
2
 
3
3
  ## Component
4
4
 
5
+ ### ConditionalFilter
6
+
7
+ fluent-plugin-conditional_filter provides a simple filter that filters out key/value pairs that don't satisfy a given condition. This is the filter version of [ConditionalFilterOutput](#conditionalfilteroutput).
8
+
9
+ ## Usage
10
+
11
+ ### Synopsis
12
+
13
+ If there's such a configuration as below:
14
+
15
+ ```
16
+ <filter test.**>
17
+ type conditional
18
+ key_pattern @example\.com$
19
+ condition 10
20
+ filter numeric_upward
21
+ </filter>
22
+ ```
23
+
24
+ When the log below reaches:
25
+
26
+ ```
27
+ 'test' => {
28
+ 'foo@example.com' => 5,
29
+ 'bar@example.com' => 15,
30
+ 'baz@baz.com' => 12,
31
+ }
32
+ ```
33
+
34
+ key/value pairs that don't match either `key_pattern` or the condition designated by `condition` and `filter` are filtered out.
35
+
36
+ ```
37
+ 'filtered.test' => {
38
+ 'bar@example.com' => 15,
39
+ }
40
+ ```
41
+
42
+ ### Params
43
+
44
+ #### `key_pattern` (required)
45
+
46
+ Key pattern to check.
47
+
48
+ #### `condition` (required)
49
+
50
+ Condition for the filter below.
51
+
52
+ #### `filter` (required)
53
+
54
+ Set filtering strategy.
55
+
5
56
  ### ConditionalFilterOutput
6
57
 
7
58
  fluent-plugin-conditional_filter provides a simple filter that filters out key/value pairs that don't satisfy a given condition.
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = 'fluent-plugin-conditional_filter'
7
- spec.version = '0.0.3'
7
+ spec.version = '0.0.4'
8
8
  spec.authors = ['Kentaro Kuribayashi']
9
9
  spec.email = ['kentarok@gmail.com']
10
10
  spec.description = %q{A fluent plugin that provides conditional filters}
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
17
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
18
  spec.require_paths = ['lib']
19
19
 
20
- spec.add_runtime_dependency 'fluentd'
20
+ spec.add_runtime_dependency 'fluentd', [">= 0.14.0", "< 2"]
21
21
 
22
22
  spec.add_development_dependency 'bundler'
23
23
  spec.add_development_dependency 'rake'
@@ -0,0 +1,30 @@
1
+ require 'fluent/output'
2
+
3
+ module Fluent
4
+ module ConditionalFilterRule
5
+ def filter_record(tag, time, record, plugin)
6
+ super(tag, time, record) if plugin.is_a?(Fluent::Output)
7
+ case @filter
8
+ when 'numeric_upward'
9
+ filter_record = record.select do |key, value|
10
+ key.match(@key_pattern_regexp) &&
11
+ record[key].to_f >= @condition.to_f
12
+ end
13
+ when 'numeric_downward'
14
+ filter_record = record.select do |key, value|
15
+ key.match(@key_pattern_regexp) &&
16
+ record[key].to_f <= @condition.to_f
17
+ end
18
+ when 'string_match'
19
+ filter_record = record.select do |key, value|
20
+ key.match(@key_pattern_regexp) &&
21
+ record[key].match(Regexp.new(@condition))
22
+ end
23
+ else
24
+ raise ArgumentError.new("[conditional_filter_rule] no such filter: #{filter}")
25
+ end
26
+
27
+ filter_record
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,24 @@
1
+ require 'fluent/plugin/conditional_filter_rule'
2
+ require 'fluent/plugin/filter'
3
+
4
+ class Fluent::Plugin::ConditionalFilter < Fluent::Plugin::Filter
5
+ Fluent::Plugin.register_filter('conditional', self)
6
+
7
+ include Fluent::ConditionalFilterRule
8
+
9
+ config_param :key_pattern, :string
10
+ config_param :condition, :string
11
+ config_param :filter, :string
12
+
13
+ def configure(conf)
14
+ super
15
+
16
+ @key_pattern_regexp = Regexp.new(key_pattern)
17
+ end
18
+
19
+ def filter(tag, time, record)
20
+ record = filter_record(tag, time, record, self)
21
+
22
+ record if record.any?
23
+ end
24
+ end
@@ -1,3 +1,4 @@
1
+ require 'fluent/plugin/conditional_filter_rule'
1
2
  class Fluent::ConditionalFilterOutput < Fluent::Output
2
3
  Fluent::Plugin.register_output('conditional_filter', self)
3
4
 
@@ -7,6 +8,7 @@ class Fluent::ConditionalFilterOutput < Fluent::Output
7
8
  end
8
9
 
9
10
  include Fluent::HandleTagNameMixin
11
+ include Fluent::ConditionalFilterRule
10
12
 
11
13
  config_param :key_pattern, :string
12
14
  config_param :condition, :string
@@ -28,7 +30,7 @@ class Fluent::ConditionalFilterOutput < Fluent::Output
28
30
  def emit(tag, es, chain)
29
31
  es.each do |time, record|
30
32
  t = tag.dup
31
- record = filter_record(t, time, record)
33
+ record = filter_record(t, time, record, self)
32
34
 
33
35
  if record.any?
34
36
  router.emit(t, time, record)
@@ -37,33 +39,4 @@ class Fluent::ConditionalFilterOutput < Fluent::Output
37
39
 
38
40
  chain.next
39
41
  end
40
-
41
- private
42
-
43
- def filter_record(tag, time, record)
44
- super
45
- case filter
46
- when 'numeric_upward'
47
- filter_record = record.select do |key, value|
48
- key.match(@key_pattern_regexp) &&
49
- record[key].to_f >= condition.to_f
50
- end
51
- when 'numeric_downward'
52
- filter_record = record.select do |key, value|
53
- key.match(@key_pattern_regexp) &&
54
- record[key].to_f <= condition.to_f
55
- end
56
- when 'string_match'
57
- filter_record = record.select do |key, value|
58
- key.match(@key_pattern_regexp) &&
59
- record[key].match(Regexp.new(condition))
60
- end
61
- else
62
- raise ArgumentError.new("[out_conditional_filter] no such filter: #{filter}")
63
- end
64
-
65
- filter_record
66
- end
67
42
  end
68
-
69
-
@@ -0,0 +1,220 @@
1
+ require 'spec_helper'
2
+
3
+ describe Fluent::Plugin::ConditionalFilter do
4
+ describe '#configure' do
5
+
6
+ context "success" do
7
+ let(:conf) {
8
+ %[
9
+ key_pattern @example\.com$
10
+ condition 10
11
+ filter numeric_upward
12
+ ]
13
+ }
14
+
15
+ let(:driver) { Fluent::Test::Driver::Filter.new(described_class).configure(conf) }
16
+ subject {
17
+ driver
18
+ }
19
+
20
+ it {
21
+ expect(subject.instance).to be_an_instance_of described_class
22
+ expect(subject.instance.key_pattern).to be == "@example\.com$"
23
+ expect(subject.instance.instance_variable_get(:@key_pattern_regexp)).to be == /@example.com$/
24
+ }
25
+ end
26
+
27
+ context "failure" do
28
+ context 'key_pattern not set' do
29
+ let(:conf) {
30
+ %[
31
+ condition 10
32
+ filter numeric_upward
33
+ ]
34
+ }
35
+
36
+ it {
37
+ expect {
38
+ Fluent::Test::Driver::Filter.new(described_class).configure(conf)
39
+ }.to raise_error(Fluent::ConfigError)
40
+ }
41
+ end
42
+
43
+ context 'condition not set' do
44
+ let(:conf) {
45
+ %[
46
+ key_pattern @example.com$
47
+ filter numeric_upward
48
+ ]
49
+ }
50
+
51
+ it {
52
+ expect {
53
+ Fluent::Test::Driver::Filter.new(described_class).configure(conf)
54
+ }.to raise_error(Fluent::ConfigError)
55
+ }
56
+ end
57
+
58
+ context 'filter not set' do
59
+ let(:conf) {
60
+ %[
61
+ key_pattern @example.com$
62
+ condition 10
63
+ ]
64
+ }
65
+
66
+ it {
67
+ expect {
68
+ Fluent::Test::Driver::Filter.new(described_class).configure(conf)
69
+ }.to raise_error(Fluent::ConfigError)
70
+ }
71
+ end
72
+ end
73
+ end
74
+
75
+ describe "#filter" do
76
+ context('numeric_upward') do
77
+ let(:conf) {
78
+ %[
79
+ key_pattern @example.com$
80
+ condition 10
81
+ filter numeric_upward
82
+ ]
83
+ }
84
+
85
+ let(:driver) { Fluent::Test::Driver::Filter.new(described_class).configure(conf) }
86
+
87
+ context('with 0 matched key/value pair') do
88
+ before {
89
+ driver.run(default_tag: 'test') {
90
+ driver.feed('foo@example.com' => 8, 'bar@example.com' => 6, 'baz@baz.com' => 15)
91
+ }
92
+ }
93
+
94
+ it {
95
+ expect(driver.filtered[0]).to be_nil
96
+ }
97
+ end
98
+
99
+ context('with 1 matched key/value pair') do
100
+ before {
101
+ driver.run(default_tag: 'test') {
102
+ driver.feed('foo@example.com' => 12, 'bar@example.com' => 6, 'baz@baz.com' => 15)
103
+ }
104
+ }
105
+
106
+ it {
107
+ expect(driver.filtered[0][1].keys.length).to be == 1
108
+ }
109
+ end
110
+
111
+ context('with 2 matched key/value pairs') do
112
+ before {
113
+ driver.run(default_tag: 'test') {
114
+ driver.feed('foo@example.com' => 12, 'bar@example.com' => 10, 'baz@baz.com' => 15)
115
+ }
116
+ }
117
+
118
+ it {
119
+ expect(driver.filtered[0][1].keys.length).to be == 2
120
+ }
121
+ end
122
+ end
123
+
124
+ context('numeric_downward') do
125
+ let(:conf) {
126
+ %[
127
+ key_pattern @example.com$
128
+ condition 10
129
+ filter numeric_downward
130
+ ]
131
+ }
132
+
133
+ let(:driver) { Fluent::Test::Driver::Filter.new(described_class).configure(conf) }
134
+
135
+ context('with 0 matched key/value pair') do
136
+ before {
137
+ driver.run(default_tag: 'test') {
138
+ driver.feed('foo@example.com' => 18, 'bar@example.com' => 26, 'baz@baz.com' => 15)
139
+ }
140
+ }
141
+
142
+ it {
143
+ expect(driver.filtered[0]).to be_nil
144
+ }
145
+ end
146
+
147
+ context('with 1 matched key/value pair') do
148
+ before {
149
+ driver.run(default_tag: 'test') {
150
+ driver.feed('foo@example.com' => 11, 'bar@example.com' => 6, 'baz@baz.com' => 5)
151
+ }
152
+ }
153
+
154
+ it {
155
+ expect(driver.filtered[0][1].keys.length).to be == 1
156
+ }
157
+ end
158
+
159
+ context('with 2 matched key/value pairs') do
160
+ before {
161
+ driver.run(default_tag: 'test') {
162
+ driver.feed('foo@example.com' => 10, 'bar@example.com' => 5, 'baz@baz.com' => 5)
163
+ }
164
+ }
165
+
166
+ it {
167
+ expect(driver.filtered[0][1].keys.length).to be == 2
168
+ }
169
+ end
170
+ end
171
+
172
+ context('string_match') do
173
+ let(:conf) {
174
+ %[
175
+ key_pattern @example.com$
176
+ condition (staff|user)
177
+ filter string_match
178
+ ]
179
+ }
180
+
181
+ let(:driver) { Fluent::Test::Driver::Filter.new(described_class).configure(conf) }
182
+
183
+ context('with 0 matched key/value pair') do
184
+ before {
185
+ driver.run(default_tag: 'test') {
186
+ driver.feed('foo@example.com' => 'guest', 'bar@example.com' => 'guest', 'baz@baz.com' => 'staff')
187
+ }
188
+ }
189
+
190
+ it {
191
+ expect(driver.filtered[0]).to be_nil
192
+ }
193
+ end
194
+
195
+ context('with 1 matched key/value pair') do
196
+ before {
197
+ driver.run(default_tag: 'test') {
198
+ driver.feed('foo@example.com' => 'staff', 'bar@example.com' => 'guest', 'baz@baz.com' => 'user')
199
+ }
200
+ }
201
+
202
+ it {
203
+ expect(driver.filtered[0][1].keys.length).to be == 1
204
+ }
205
+ end
206
+
207
+ context('with 2 matched key/value pairs') do
208
+ before {
209
+ driver.run(default_tag: 'test') {
210
+ driver.feed('foo@example.com' => 'staff', 'bar@example.com' => 'user', 'baz@baz.com' => 'staff')
211
+ }
212
+ }
213
+
214
+ it {
215
+ expect(driver.filtered[0][1].keys.length).to be == 2
216
+ }
217
+ end
218
+ end
219
+ end
220
+ end
@@ -1,5 +1,7 @@
1
1
  require 'fluent/test'
2
+ require 'fluent/test/driver/filter'
2
3
  require 'fluent/plugin/out_conditional_filter'
4
+ require 'fluent/plugin/filter_conditional'
3
5
 
4
6
  RSpec.configure do |config|
5
7
  config.before(:all) do
@@ -24,4 +26,3 @@ unless ENV.has_key?('VERBOSE')
24
26
  }
25
27
  $log = nulllogger
26
28
  end
27
-
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-conditional_filter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kentaro Kuribayashi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-04 00:00:00.000000000 Z
11
+ date: 2017-10-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd
@@ -16,14 +16,20 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
19
+ version: 0.14.0
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '2'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
27
  - - ">="
25
28
  - !ruby/object:Gem::Version
26
- version: '0'
29
+ version: 0.14.0
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '2'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: bundler
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -94,7 +100,10 @@ files:
94
100
  - README.md
95
101
  - Rakefile
96
102
  - fluent-plugin-conditional_filter.gemspec
103
+ - lib/fluent/plugin/conditional_filter_rule.rb
104
+ - lib/fluent/plugin/filter_conditional.rb
97
105
  - lib/fluent/plugin/out_conditional_filter.rb
106
+ - spec/lib/filter_conditional_spec.rb
98
107
  - spec/lib/out_conditional_filter_spec.rb
99
108
  - spec/spec_helper.rb
100
109
  homepage: http://github.com/kentaro/fluent-plugin-conditional_filter
@@ -122,5 +131,6 @@ signing_key:
122
131
  specification_version: 4
123
132
  summary: A fluent plugin that provides conditional filters
124
133
  test_files:
134
+ - spec/lib/filter_conditional_spec.rb
125
135
  - spec/lib/out_conditional_filter_spec.rb
126
136
  - spec/spec_helper.rb