fluent-plugin-filter-list 0.7.0 → 0.7.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +8 -0
- data/.rubocop.yml +7 -5
- data/.travis.yml +3 -3
- data/Gemfile +1 -1
- data/README.md +1 -1
- data/fluent-plugin-out_filter_list.gemspec +1 -0
- data/lib/fluent/plugin/out_filter_list/version.rb +1 -1
- data/lib/fluent/plugin/out_filter_list.rb +3 -7
- data/lib/matcher.rb +190 -46
- metadata +8 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e248391649cea2b7fa1ef396a5ae5bcdae45959775296b58dd845d334709993
|
4
|
+
data.tar.gz: 7ca0d518e0aae01a31a218f20613952202ec07eace82152393f3f186d896d9cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 386303ab0eee0b66080c20db661f8498baafd99fd5f1c76fab156c001dd32228a096bbe6e3caa74d0ece4889f2a23390b4bb407c2850ba6c48d0118871cfeff9
|
7
|
+
data.tar.gz: af54b9cb60bfa64207e8281a4b8c2219dc6c63f8e83413b9707f68555036165fe17eb4aa43fa0c92994faf8ed8022808c9674a1994f12a3aed15693e6c8700b0
|
data/.rubocop.yml
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
AllCops:
|
2
|
-
TargetRubyVersion: 2.
|
2
|
+
TargetRubyVersion: 2.5
|
3
|
+
NewCops: enable
|
4
|
+
|
3
5
|
|
4
6
|
Naming/MethodParameterName:
|
5
7
|
Enabled: false
|
@@ -12,7 +14,7 @@ Style/FormatStringToken:
|
|
12
14
|
Style/StringLiterals:
|
13
15
|
Enabled: false
|
14
16
|
Metrics/MethodLength:
|
15
|
-
Max:
|
17
|
+
Max: 25
|
16
18
|
Style/Documentation:
|
17
19
|
Enabled: false
|
18
20
|
Style/FrozenStringLiteralComment:
|
@@ -38,7 +40,7 @@ Metrics/PerceivedComplexity:
|
|
38
40
|
Style/GlobalVars:
|
39
41
|
Exclude:
|
40
42
|
- 'test/test_helper.rb'
|
41
|
-
|
43
|
+
Lint/MissingSuper:
|
42
44
|
Exclude:
|
43
45
|
- 'test/test_helper.rb'
|
44
46
|
Style/MissingRespondToMissing:
|
@@ -48,7 +50,7 @@ Style/TernaryParentheses:
|
|
48
50
|
Enabled: false
|
49
51
|
Style/BlockDelimiters:
|
50
52
|
AutoCorrect: false
|
51
|
-
Style/BracesAroundHashParameters:
|
52
|
-
Enabled: false
|
53
53
|
Layout/FirstHashElementIndentation:
|
54
54
|
EnforcedStyle: consistent
|
55
|
+
Style/RedundantSelfAssignment:
|
56
|
+
Enabled: false
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# fluent-plugin-filter-list
|
2
2
|
|
3
|
-
[![Build Status](https://travis-ci.
|
3
|
+
[![Build Status](https://travis-ci.com/yanana/fluent-plugin-filter-list.svg?branch=master)](https://travis-ci.com/yanana/fluent-plugin-filter-list)
|
4
4
|
|
5
5
|
Want to filter fluentd messages containing black-listed words in the list effectively? Use the _fluent-plugin-filter-list_ plugin. The plugin enables you to filter messages in the list of words you provide. You can either discard such messages simply, or process them in a different flow by retagging them.
|
6
6
|
|
@@ -8,6 +8,7 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = Fluent::Plugin::FilterList::VERSION
|
9
9
|
spec.authors = ['Shun Yanaura']
|
10
10
|
spec.email = ['metroplexity@gmail.com']
|
11
|
+
spec.required_ruby_version = '>= 2.5.0'
|
11
12
|
|
12
13
|
spec.summary = 'A fluentd output plugin to filter keywords from messages'
|
13
14
|
spec.description = 'A fluentd output plugin to filter keywords from messages'
|
@@ -31,10 +31,6 @@ module Fluent
|
|
31
31
|
config_param :add_prefix, :string, default: nil
|
32
32
|
end
|
33
33
|
|
34
|
-
def initialize
|
35
|
-
super
|
36
|
-
end
|
37
|
-
|
38
34
|
def validate(retag)
|
39
35
|
return unless retag
|
40
36
|
raise Fluent::ConfigError, "missing tag and add_prefix" unless retag.tag || retag.add_prefix
|
@@ -42,9 +38,9 @@ module Fluent
|
|
42
38
|
end
|
43
39
|
|
44
40
|
def configure_prefixes
|
45
|
-
@prefix_for_filtered_tag = @retag_for_filtered.add_prefix
|
46
|
-
@prefix_for_filtered_tag = @retag_for_filtered&.add_prefix ? @retag_for_filtered.add_prefix
|
47
|
-
@prefix = @retag&.add_prefix ? @retag.add_prefix
|
41
|
+
@prefix_for_filtered_tag = "#{@retag_for_filtered.add_prefix}." if @retag_for_filtered&.add_prefix
|
42
|
+
@prefix_for_filtered_tag = @retag_for_filtered&.add_prefix ? "#{@retag_for_filtered.add_prefix}." : ''
|
43
|
+
@prefix = @retag&.add_prefix ? "#{@retag.add_prefix}." : ''
|
48
44
|
end
|
49
45
|
|
50
46
|
def configure(conf)
|
data/lib/matcher.rb
CHANGED
@@ -7,22 +7,25 @@ module Matchers
|
|
7
7
|
|
8
8
|
def initialize(patterns)
|
9
9
|
patterns = (patterns || []).compact.reject(&:empty?)
|
10
|
-
@
|
10
|
+
@machine = ACAutomaton.new patterns
|
11
11
|
end
|
12
12
|
|
13
13
|
def matches?(text)
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
false
|
14
|
+
return false if text.nil? || text == ''
|
15
|
+
|
16
|
+
@machine.matches? text.to_s
|
17
|
+
end
|
18
|
+
|
19
|
+
def find(text)
|
20
|
+
return false if text.nil? || text == ''
|
21
|
+
|
22
|
+
@machine.find(text)
|
21
23
|
end
|
22
24
|
end
|
23
25
|
|
24
26
|
class IPMatcher
|
25
27
|
attr_reader :trie
|
28
|
+
|
26
29
|
include IP
|
27
30
|
|
28
31
|
def initialize(patterns)
|
@@ -39,45 +42,44 @@ module Matchers
|
|
39
42
|
end
|
40
43
|
|
41
44
|
class Trie
|
45
|
+
class Node
|
46
|
+
attr_reader :children
|
47
|
+
|
48
|
+
def initialize
|
49
|
+
@children = {}
|
50
|
+
@children.default = nil
|
51
|
+
end
|
52
|
+
|
53
|
+
def insert(char)
|
54
|
+
@children[char] = Node.new unless @children.key?(char)
|
55
|
+
@children[char]
|
56
|
+
end
|
57
|
+
|
58
|
+
def forward(str)
|
59
|
+
children = @children
|
60
|
+
child = nil
|
61
|
+
str.chars.each do |char|
|
62
|
+
child = children[char]
|
63
|
+
children = child.children
|
64
|
+
end
|
65
|
+
child
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
42
69
|
attr_reader :root
|
70
|
+
|
43
71
|
def initialize(patterns)
|
44
72
|
@root = Node.new
|
45
73
|
@root.children.default = @root
|
46
74
|
patterns.each do |pattern|
|
47
75
|
insert(pattern)
|
48
76
|
end
|
49
|
-
build
|
50
77
|
end
|
51
78
|
|
52
79
|
def insert(pattern = '')
|
53
80
|
current_node = @root
|
54
|
-
pattern.chars.
|
81
|
+
pattern.chars.each do |char|
|
55
82
|
current_node = current_node.insert(char)
|
56
|
-
current_node.output = pattern if i == pattern.length - 1
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def new_queue
|
61
|
-
q = Queue.new
|
62
|
-
@root.children.values.each do |child|
|
63
|
-
q.push(child)
|
64
|
-
child.failure = @root # set root on root's children's failure
|
65
|
-
end
|
66
|
-
q
|
67
|
-
end
|
68
|
-
|
69
|
-
def build
|
70
|
-
# Update failure on each node.
|
71
|
-
# Search longest matching suffix (which becomes failure) by BFS. In case no matching suffix, root becomes failure.
|
72
|
-
q = new_queue
|
73
|
-
until q.empty?
|
74
|
-
cur_node = q.pop
|
75
|
-
cur_node.children.each do |char, child|
|
76
|
-
q.push(child)
|
77
|
-
detect_node = cur_node.failure || @root
|
78
|
-
detect_node = detect_node.failure while detect_node.children[char].nil?
|
79
|
-
child.failure = detect_node.children[char]
|
80
|
-
end
|
81
83
|
end
|
82
84
|
end
|
83
85
|
|
@@ -95,20 +97,162 @@ module Matchers
|
|
95
97
|
end
|
96
98
|
end
|
97
99
|
|
98
|
-
|
99
|
-
|
100
|
-
|
100
|
+
# An AC automaton.
|
101
|
+
# Based on https://www.cs.uku.fi/~kilpelai/BSA05/lectures/slides04.pdf.
|
102
|
+
class ACAutomaton
|
103
|
+
class Node
|
104
|
+
# Manages the goto as a character -> node ID mapping.
|
105
|
+
attr_reader :goto
|
106
|
+
# Uniquely (in an automaton) assigned ID of the Node.
|
107
|
+
attr_reader :id
|
108
|
+
attr_accessor :failure
|
109
|
+
# Stores out of AC, that is the index of the patterns.
|
110
|
+
attr_accessor :out
|
111
|
+
|
112
|
+
def initialize(id: 0, goto: {}, failure: 0, out: [])
|
113
|
+
@id = id
|
114
|
+
@goto = goto
|
115
|
+
@failure = failure
|
116
|
+
@out = out
|
117
|
+
end
|
118
|
+
|
119
|
+
def root?
|
120
|
+
@id.zero?
|
121
|
+
end
|
101
122
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
123
|
+
def g(char)
|
124
|
+
if (next_node = @goto[char])
|
125
|
+
return next_node
|
126
|
+
end
|
127
|
+
return 0 if root?
|
128
|
+
|
129
|
+
nil
|
130
|
+
end
|
131
|
+
|
132
|
+
def to_s
|
133
|
+
"id: #{@id}, goto: #{@goto}, failure: #{@failure}, out: #{@out}"
|
134
|
+
end
|
135
|
+
|
136
|
+
def ==(other)
|
137
|
+
@id == other.id && @goto == other.goto && @failure == other.failure && @out == other.out
|
138
|
+
end
|
107
139
|
end
|
140
|
+
# Nodes are managed in an array. The indices are
|
141
|
+
attr_reader :nodes, :patterns
|
108
142
|
|
109
|
-
def
|
110
|
-
@
|
111
|
-
@
|
143
|
+
def initialize(patterns)
|
144
|
+
@nodes = []
|
145
|
+
@patterns = patterns || []
|
146
|
+
build(@patterns)
|
147
|
+
end
|
148
|
+
|
149
|
+
# Creates a new node and returns the id.
|
150
|
+
# This method is not thread safe.
|
151
|
+
def new_node
|
152
|
+
id = @nodes.size
|
153
|
+
node = Node.new(id: id)
|
154
|
+
@nodes.push(node)
|
155
|
+
id
|
156
|
+
end
|
157
|
+
|
158
|
+
def build(patterns)
|
159
|
+
build_goto(patterns)
|
160
|
+
build_failure
|
161
|
+
end
|
162
|
+
|
163
|
+
def build_goto(patterns)
|
164
|
+
root = new_node
|
165
|
+
patterns.each_with_index do |pattern, i|
|
166
|
+
q = root
|
167
|
+
pattern.chars.each do |char|
|
168
|
+
next_q = @nodes[q].goto[char]
|
169
|
+
if next_q
|
170
|
+
q = next_q
|
171
|
+
else
|
172
|
+
new_q = new_node
|
173
|
+
@nodes[q].goto[char] = new_q
|
174
|
+
q = new_q
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
@nodes[q].out.push(i)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def build_failure
|
183
|
+
queue = [0]
|
184
|
+
until queue.empty?
|
185
|
+
n = queue.shift
|
186
|
+
node = @nodes[n]
|
187
|
+
@nodes[n].goto.each do |c, next_node|
|
188
|
+
queue.push(next_node)
|
189
|
+
|
190
|
+
next if n.zero?
|
191
|
+
|
192
|
+
failure = node.failure
|
193
|
+
failure = @nodes[failure].failure while @nodes[failure].g(c).nil?
|
194
|
+
@nodes[next_node].failure = @nodes[failure].g(c)
|
195
|
+
@nodes[next_node].out.concat(@nodes[@nodes[next_node].failure].out)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def find(text)
|
201
|
+
return [] if text.nil? || text == ''
|
202
|
+
|
203
|
+
find_id(text).map do |id|
|
204
|
+
@patterns[id]
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
# Finds and retuns matched pattens' indices.
|
209
|
+
def find_id(text)
|
210
|
+
return [] if text.nil? || text == ''
|
211
|
+
|
212
|
+
q = 0
|
213
|
+
result = []
|
214
|
+
text.chars.each_with_index do |c, _i|
|
215
|
+
loop do
|
216
|
+
node = @nodes[q]
|
217
|
+
if (to_go_next = node.goto[c])
|
218
|
+
q = to_go_next
|
219
|
+
break
|
220
|
+
end
|
221
|
+
break if q.zero?
|
222
|
+
|
223
|
+
q = node.failure
|
224
|
+
end
|
225
|
+
|
226
|
+
out = @nodes[q].out
|
227
|
+
result.concat(out) unless out.empty?
|
228
|
+
end
|
229
|
+
|
230
|
+
result
|
231
|
+
end
|
232
|
+
|
233
|
+
# Returns true if the text matches any pattern, otherwise false.
|
234
|
+
def matches?(text)
|
235
|
+
return false if text.nil?
|
236
|
+
|
237
|
+
q = 0
|
238
|
+
text.chars.each do |c|
|
239
|
+
loop do
|
240
|
+
node = @nodes[q]
|
241
|
+
if (to_go_next = node.goto[c])
|
242
|
+
q = to_go_next
|
243
|
+
break
|
244
|
+
end
|
245
|
+
break if q.zero?
|
246
|
+
|
247
|
+
q = node.failure
|
248
|
+
end
|
249
|
+
|
250
|
+
out = @nodes[q].out
|
251
|
+
|
252
|
+
return true unless out.empty?
|
253
|
+
end
|
254
|
+
|
255
|
+
false
|
112
256
|
end
|
113
257
|
end
|
114
258
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-filter-list
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shun Yanaura
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-09-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -95,6 +95,7 @@ executables:
|
|
95
95
|
extensions: []
|
96
96
|
extra_rdoc_files: []
|
97
97
|
files:
|
98
|
+
- ".github/dependabot.yml"
|
98
99
|
- ".gitignore"
|
99
100
|
- ".rubocop.yml"
|
100
101
|
- ".travis.yml"
|
@@ -116,7 +117,7 @@ homepage: https://github.com/yanana/fluent-plugin-filter-list
|
|
116
117
|
licenses:
|
117
118
|
- MIT
|
118
119
|
metadata: {}
|
119
|
-
post_install_message:
|
120
|
+
post_install_message:
|
120
121
|
rdoc_options: []
|
121
122
|
require_paths:
|
122
123
|
- lib
|
@@ -124,15 +125,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
124
125
|
requirements:
|
125
126
|
- - ">="
|
126
127
|
- !ruby/object:Gem::Version
|
127
|
-
version:
|
128
|
+
version: 2.5.0
|
128
129
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
130
|
requirements:
|
130
131
|
- - ">="
|
131
132
|
- !ruby/object:Gem::Version
|
132
133
|
version: '0'
|
133
134
|
requirements: []
|
134
|
-
rubygems_version: 3.
|
135
|
-
signing_key:
|
135
|
+
rubygems_version: 3.1.6
|
136
|
+
signing_key:
|
136
137
|
specification_version: 4
|
137
138
|
summary: A fluentd output plugin to filter keywords from messages
|
138
139
|
test_files: []
|