fluent-plugin-datacounter 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.2.2"
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
- sum = counts['all'].inject(:+)
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
- output[name + '_percentage'] = count * 100.0 / (1.00 * sum) if sum > 0
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 = counts[tag].inject(:+)
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
- output[t + '_' + name + '_percentage'] = count * 100.0 / (1.00 * sum) if sum > 0
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.2.2
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-03-29 00:00:00.000000000 Z
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.19
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