fluent-plugin-conditional_filter 0.0.3 → 0.0.4

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.
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