fluent-plugin-datacounter 0.2.2 → 0.3.0
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/README.rdoc +14 -0
- data/fluent-plugin-datacounter.gemspec +1 -1
- data/lib/fluent/plugin/out_datacounter.rb +19 -5
- data/test/plugin/test_out_datacounter.rb +55 -1
- metadata +3 -3
data/README.rdoc
CHANGED
@@ -62,6 +62,20 @@ HTTP status code patterns.
|
|
62
62
|
pattern5 5xx ^5\d\d$
|
63
63
|
</match>
|
64
64
|
|
65
|
+
If you want not to include 'unmatched' counts into percentage, use 'outcast_unmatched' configuration:
|
66
|
+
|
67
|
+
<match accesslog.**>
|
68
|
+
type datacounter
|
69
|
+
count_key status
|
70
|
+
# patternX: X(1-20)
|
71
|
+
pattern1 2xx ^2\d\d$
|
72
|
+
pattern2 3xx ^3\d\d$
|
73
|
+
pattern3 4xx ^4\d\d$
|
74
|
+
pattern4 5xx ^5\d\d$
|
75
|
+
outcast_unmatched yes # '*_percentage' fields culculated without 'unmatched' counts, and
|
76
|
+
# 'unmatched_percentage' field will not be produced
|
77
|
+
</match>
|
78
|
+
|
65
79
|
== TODO
|
66
80
|
|
67
81
|
- consider what to do next
|
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "fluent-plugin-datacounter"
|
6
|
-
s.version = "0.
|
6
|
+
s.version = "0.3.0"
|
7
7
|
s.authors = ["TAGOMORI Satoshi"]
|
8
8
|
s.email = ["tagomoris@gmail.com"]
|
9
9
|
s.homepage = "https://github.com/tagomoris/fluent-plugin-datacounter"
|
@@ -9,6 +9,7 @@ class Fluent::DataCounterOutput < Fluent::Output
|
|
9
9
|
config_param :tag, :string, :default => 'datacount'
|
10
10
|
config_param :input_tag_remove_prefix, :string, :default => nil
|
11
11
|
config_param :count_key, :string
|
12
|
+
config_param :outcast_unmatched, :bool, :default => false
|
12
13
|
|
13
14
|
# pattern0 reserved as unmatched counts
|
14
15
|
config_param :pattern1, :string # string: NAME REGEXP
|
@@ -120,24 +121,37 @@ class Fluent::DataCounterOutput < Fluent::Output
|
|
120
121
|
def generate_output(counts, step)
|
121
122
|
output = {}
|
122
123
|
if @aggregate == :all
|
123
|
-
|
124
|
+
# index 0 is unmatched
|
125
|
+
sum = if @outcast_unmatched
|
126
|
+
counts['all'][1..-1].inject(:+)
|
127
|
+
else
|
128
|
+
counts['all'].inject(:+)
|
129
|
+
end
|
124
130
|
counts['all'].each_with_index do |count,i|
|
125
131
|
name = @patterns[i][1]
|
126
132
|
output[name + '_count'] = count
|
127
133
|
output[name + '_rate'] = ((count * 100.0) / (1.00 * step)).floor / 100.0
|
128
|
-
|
134
|
+
unless i == 0 and @outcast_unmatched
|
135
|
+
output[name + '_percentage'] = count * 100.0 / (1.00 * sum) if sum > 0
|
136
|
+
end
|
129
137
|
end
|
130
138
|
return output
|
131
139
|
end
|
132
140
|
|
133
141
|
counts.keys.each do |tag|
|
134
142
|
t = stripped_tag(tag)
|
135
|
-
sum =
|
143
|
+
sum = if @outcast_unmatched
|
144
|
+
counts[tag][1..-1].inject(:+)
|
145
|
+
else
|
146
|
+
counts[tag].inject(:+)
|
147
|
+
end
|
136
148
|
counts[tag].each_with_index do |count,i|
|
137
149
|
name = @patterns[i][1]
|
138
150
|
output[t + '_' + name + '_count'] = count
|
139
151
|
output[t + '_' + name + '_rate'] = ((count * 100.0) / (1.00 * step)).floor / 100.0
|
140
|
-
|
152
|
+
unless i == 0 and @outcast_unmatched
|
153
|
+
output[t + '_' + name + '_percentage'] = count * 100.0 / (1.00 * sum) if sum > 0
|
154
|
+
end
|
141
155
|
end
|
142
156
|
end
|
143
157
|
output
|
@@ -177,7 +191,7 @@ class Fluent::DataCounterOutput < Fluent::Output
|
|
177
191
|
value = record[@count_key]
|
178
192
|
next if value.nil?
|
179
193
|
|
180
|
-
value = value.to_s
|
194
|
+
value = value.to_s.force_encoding('ASCII-8BIT')
|
181
195
|
matched = false
|
182
196
|
@patterns.each do |index, name, regexp|
|
183
197
|
next unless regexp and regexp.match(value)
|
@@ -64,6 +64,7 @@ class DataCounterOutputTest < Test::Unit::TestCase
|
|
64
64
|
assert_nil d.instance.input_tag_remove_prefix
|
65
65
|
assert_equal 'field', d.instance.count_key
|
66
66
|
assert_equal 'ok ^2\d\d$', d.instance.pattern1
|
67
|
+
assert_equal false, d.instance.outcast_unmatched
|
67
68
|
|
68
69
|
d1 = create_driver %[
|
69
70
|
unit minute
|
@@ -95,8 +96,10 @@ class DataCounterOutputTest < Test::Unit::TestCase
|
|
95
96
|
count_interval 30s
|
96
97
|
count_key field
|
97
98
|
pattern1 ok ^2\\d\\d$
|
99
|
+
outcast_unmatched yes
|
98
100
|
]
|
99
101
|
assert_equal 30, d.instance.tick
|
102
|
+
assert_equal true, d.instance.outcast_unmatched
|
100
103
|
end
|
101
104
|
|
102
105
|
def test_count_initialized
|
@@ -272,6 +275,57 @@ class DataCounterOutputTest < Test::Unit::TestCase
|
|
272
275
|
assert_equal 0, data[2]['unmatched_count']
|
273
276
|
assert_equal 0.0, data[2]['unmatched_rate']
|
274
277
|
assert_equal 0.0, data[2]['unmatched_percentage']
|
275
|
-
end
|
276
278
|
|
279
|
+
d3 = create_driver(%[
|
280
|
+
count_key target
|
281
|
+
input_tag_remove_prefix test
|
282
|
+
pattern1 ok 2\\d\\d
|
283
|
+
pattern2 redirect 3\\d\\d
|
284
|
+
outcast_unmatched yes
|
285
|
+
], 'test.tag2')
|
286
|
+
d3.run do
|
287
|
+
60.times do
|
288
|
+
d3.emit({'target' => '200'})
|
289
|
+
d3.emit({'target' => '300'})
|
290
|
+
d3.emit({'target' => '400'})
|
291
|
+
end
|
292
|
+
end
|
293
|
+
d3.instance.flush_emit(180)
|
294
|
+
emits = d3.emits
|
295
|
+
assert_equal 1, emits.length
|
296
|
+
data = emits[0]
|
297
|
+
assert_equal 'datacount', data[0] # tag
|
298
|
+
assert_equal 60, data[2]['tag2_unmatched_count']
|
299
|
+
assert_nil data[2]['tag2_unmatched_percentage']
|
300
|
+
assert_equal 60, data[2]['tag2_ok_count']
|
301
|
+
assert_equal 50.0, data[2]['tag2_ok_percentage']
|
302
|
+
assert_equal 60, data[2]['tag2_redirect_count']
|
303
|
+
assert_equal 50.0, data[2]['tag2_redirect_percentage']
|
304
|
+
|
305
|
+
d3 = create_driver(%[
|
306
|
+
aggregate all
|
307
|
+
count_key target
|
308
|
+
pattern1 ok 2\\d\\d
|
309
|
+
pattern2 redirect 3\\d\\d
|
310
|
+
outcast_unmatched true
|
311
|
+
], 'test.tag2')
|
312
|
+
d3.run do
|
313
|
+
60.times do
|
314
|
+
d3.emit({'target' => '200'})
|
315
|
+
d3.emit({'target' => '300'})
|
316
|
+
d3.emit({'target' => '400'})
|
317
|
+
end
|
318
|
+
end
|
319
|
+
d3.instance.flush_emit(180)
|
320
|
+
emits = d3.emits
|
321
|
+
assert_equal 1, emits.length
|
322
|
+
data = emits[0]
|
323
|
+
assert_equal 'datacount', data[0] # tag
|
324
|
+
assert_equal 60, data[2]['unmatched_count']
|
325
|
+
assert_nil data[2]['unmatched_percentage']
|
326
|
+
assert_equal 60, data[2]['ok_count']
|
327
|
+
assert_equal 50.0, data[2]['ok_percentage']
|
328
|
+
assert_equal 60, data[2]['redirect_count']
|
329
|
+
assert_equal 50.0, data[2]['redirect_percentage']
|
330
|
+
end
|
277
331
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-datacounter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-04-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: fluentd
|
@@ -80,7 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
80
80
|
version: '0'
|
81
81
|
requirements: []
|
82
82
|
rubyforge_project: fluent-plugin-datacounter
|
83
|
-
rubygems_version: 1.8.
|
83
|
+
rubygems_version: 1.8.21
|
84
84
|
signing_key:
|
85
85
|
specification_version: 3
|
86
86
|
summary: Output filter plugin to count messages that matches specified conditions
|