fluent-plugin-flowcounter 0.4.3 → 1.0.0

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: 8e19ecb9672a7f5b42584af6344941594f39e790
4
- data.tar.gz: f8d1c5957950a8bc7f342e3c257bbeda53722fbe
3
+ metadata.gz: 873629b9804e92822b8a2b854a5df3da2798bf45
4
+ data.tar.gz: f3d79ae17a63763f9dc0ca8073982022d8b0759e
5
5
  SHA512:
6
- metadata.gz: 42681b5d601e6862247cd7e81d4b5ccf604d4213b11f08ef6d5888d81017b516808dbd8b641d69d4c89961cce01dfa7d556342daf035d301fea2bd9d60ab6169
7
- data.tar.gz: f1bb4e7bae3ede0f43c7c8cb08311b9d4892b5cff9a3b4b98a940549b4c48df294b7f7bb9f2bc3a046fb039cf5ef971740046d826f95f2ea324fd4d667048d6e
6
+ metadata.gz: 9b92f7be19ad17f125244c10efab034df307f0581f6db4ba82d06551eee513e3002453080221494b8ec5e746601ee3a55a5540f87e93ded866e9222df1391d33
7
+ data.tar.gz: dd56f20d75dfb69f309170fdb59a520a69da0fca58e5188c46cc98106c8448e1c20d7c00e79ea4fbf98aeccda6835d98ca3caddfe322cb440ea26f8a83958b9f
data/.travis.yml CHANGED
@@ -4,3 +4,4 @@ rvm:
4
4
  - 2.1
5
5
  - 2.2
6
6
  - 2.3.0
7
+ - 2.4.1
data/README.md CHANGED
@@ -25,7 +25,7 @@ If you want to count only records, omit `count_keys` configuration.
25
25
 
26
26
  ## Configuration
27
27
 
28
- Counts from fields 'field1' and 'field2', per minute(default), aggregates per tags(default), output with tag 'flowcount'(default).
28
+ Counts from fields 'field1' and 'field2', per minute(default), aggregates per tags(default), output with tag 'flowcount'(default). It is strongly recommended to specify `@label` to control event stream routing.
29
29
 
30
30
  <match **>
31
31
  @type copy
@@ -34,13 +34,16 @@ Counts from fields 'field1' and 'field2', per minute(default), aggregates per ta
34
34
  </store>
35
35
  <store>
36
36
  @type flowcounter
37
+ @label @counts
37
38
  count_keys field1,field2
38
39
  </store>
39
40
  </match>
40
41
 
41
- <match flowcount>
42
- # output configurations where to send count results
43
- </match>
42
+ <label @counts>
43
+ <match flowcount>
44
+ # output configurations where to send count results
45
+ </match>
46
+ </label>
44
47
 
45
48
  Counts from field 'message', per hour, aggregates all tags, output with tag 'fluentd.traffic'.
46
49
 
@@ -51,6 +54,7 @@ Counts from field 'message', per hour, aggregates all tags, output with tag 'flu
51
54
  </store>
52
55
  <store>
53
56
  @type flowcounter
57
+ @label @counts
54
58
  count_keys message
55
59
  unit hour
56
60
  aggregate all
@@ -58,9 +62,11 @@ Counts from field 'message', per hour, aggregates all tags, output with tag 'flu
58
62
  </store>
59
63
  </match>
60
64
 
61
- <match fluentd.traffic>
62
- # output configurations where to send count results
63
- </match>
65
+ <label @counts>
66
+ <match fluentd.traffic>
67
+ # output configurations where to send count results
68
+ </match>
69
+ </label>
64
70
 
65
71
  To count with all fields in messages, specify 'count_keys *'.
66
72
 
@@ -81,27 +87,31 @@ To count records only (without bytes), omit `count_keys` (it runs in better perf
81
87
  tag fluentd.traffic
82
88
  </match>
83
89
 
84
- Use '${hostname}' if you want your hostname in tag.
90
+ Counts active tag, stop count records if the tag message stoped(when aggragates per tag).
85
91
 
86
92
  <match target.**>
87
93
  @type flowcounter
88
94
  count_keys *
89
- tag fluentd.node.${hostname}
95
+ aggregate tag
96
+ delete_idle true
90
97
  </match>
91
98
 
92
- Counts active tag, stop count records if the tag message stoped(when aggragates per tag).
99
+ ### Embedding Hostname
100
+
101
+ The current version of this plugin doesn't support `${hostname}` placeholders. Use ruby code embedding for such purpose:
93
102
 
94
103
  <match target.**>
95
104
  @type flowcounter
96
105
  count_keys *
97
- aggregate tag
98
- delete_idle true
106
+ tag "fluentd.node.#{Socket.gethostname}"
99
107
  </match>
100
108
 
109
+ See [Fluentd document page](https://docs.fluentd.org/articles/config-file#embedded-ruby-code) for further details.
110
+
101
111
  ## TODO
102
112
 
103
- * consider what to do next
104
- * patches welcome!
113
+ * Support Counter API when it's supported in Fluentd core
114
+ * Patches welcome!
105
115
 
106
116
  ## Copyright
107
117
 
@@ -1,7 +1,7 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  Gem::Specification.new do |gem|
3
3
  gem.name = "fluent-plugin-flowcounter"
4
- gem.version = "0.4.3"
4
+ gem.version = "1.0.0"
5
5
  gem.authors = ["TAGOMORI Satoshi"]
6
6
  gem.email = ["tagomoris@gmail.com"]
7
7
  gem.summary = %q{Fluent plugin to count message flow}
@@ -16,6 +16,5 @@ Gem::Specification.new do |gem|
16
16
 
17
17
  gem.add_development_dependency "rake"
18
18
  gem.add_development_dependency "test-unit"
19
- gem.add_runtime_dependency "fluentd", ['>= 0.10.59', "< 0.14.0"]
20
- gem.add_runtime_dependency "fluent-mixin-config-placeholders", ">= 0.3.0"
19
+ gem.add_runtime_dependency "fluentd", "~> 0.14.0"
21
20
  end
@@ -1,29 +1,19 @@
1
- require 'fluent/mixin/config_placeholders'
1
+ require 'fluent/plugin/output'
2
2
 
3
- class Fluent::FlowCounterOutput < Fluent::Output
3
+ class Fluent::Plugin::FlowCounterOutput < Fluent::Plugin::Output
4
4
  Fluent::Plugin.register_output('flowcounter', self)
5
5
 
6
- # Define `log` method for v0.10.42 or earlier
7
- unless method_defined?(:log)
8
- define_method("log") { $log }
9
- end
10
-
11
- # Define `router` method of v0.12 to support v0.10 or earlier
12
- unless method_defined?(:router)
13
- define_method("router") { ::Fluent::Engine }
14
- end
6
+ helpers :event_emitter, :timer
15
7
 
16
- config_param :unit, :string, default: 'minute'
17
- config_param :aggregate, :string, default: 'tag'
18
- config_param :output_style, :string, default: 'joined'
8
+ config_param :unit, :enum, list: [:second, :minute, :hour, :day], default: :minute
9
+ config_param :aggregate, :enum, list: [:tag, :all], default: :tag
10
+ config_param :output_style, :enum, list: [:joined, :tagged], default: :joined
19
11
  config_param :tag, :string, default: 'flowcount'
20
12
  config_param :input_tag_remove_prefix, :string, default: nil
21
13
  config_param :count_keys, :string, default: nil
22
14
  config_param :delimiter, :string, default: '_'
23
15
  config_param :delete_idle, :bool, default: false
24
16
 
25
- include Fluent::Mixin::ConfigPlaceholders
26
-
27
17
  attr_accessor :counts
28
18
  attr_accessor :last_checked
29
19
  attr_accessor :count_all
@@ -32,14 +22,6 @@ class Fluent::FlowCounterOutput < Fluent::Output
32
22
  def configure(conf)
33
23
  super
34
24
 
35
- @unit = case @unit
36
- when 'second' then :second
37
- when 'minute' then :minute
38
- when 'hour' then :hour
39
- when 'day' then :day
40
- else
41
- raise Fluent::ConfigError, "flowcounter unit allows second/minute/hour/day"
42
- end
43
25
  @tick = case @unit
44
26
  when :second then 1
45
27
  when :minute then 60
@@ -48,18 +30,6 @@ class Fluent::FlowCounterOutput < Fluent::Output
48
30
  else
49
31
  raise Fluent::ConfigError, "flowcounter unit allows second/minute/hour/day"
50
32
  end
51
- @aggregate = case @aggregate
52
- when 'tag' then :tag
53
- when 'all' then :all
54
- else
55
- raise Fluent::ConfigError, "flowcounter aggregate allows tag/all"
56
- end
57
- @output_style = case @output_style
58
- when 'joined' then :joined
59
- when 'tagged' then :tagged
60
- else
61
- raise Fluent::ConfigError, "flowcounter output_style allows joined/tagged"
62
- end
63
33
  if @output_style == :tagged and @aggregate != :tag
64
34
  raise Fluent::ConfigError, "flowcounter aggregate must be 'tag' when output_style is 'tagged'"
65
35
  end
@@ -67,6 +37,7 @@ class Fluent::FlowCounterOutput < Fluent::Output
67
37
  @removed_prefix_string = @input_tag_remove_prefix + '.'
68
38
  @removed_length = @removed_prefix_string.length
69
39
  end
40
+ @count_all = false
70
41
  if @count_keys
71
42
  @count_keys = @count_keys.split(',').map(&:strip)
72
43
  @count_all = (@count_keys == ['*'])
@@ -84,12 +55,6 @@ class Fluent::FlowCounterOutput < Fluent::Output
84
55
  start_watch
85
56
  end
86
57
 
87
- def shutdown
88
- super
89
- @watcher.terminate
90
- @watcher.join
91
- end
92
-
93
58
  def count_initialized(keys=nil)
94
59
  if @aggregate == :all
95
60
  if @count_bytes
@@ -160,26 +125,22 @@ class Fluent::FlowCounterOutput < Fluent::Output
160
125
  end
161
126
 
162
127
  def start_watch
128
+ @last_checked = Fluent::Engine.now
163
129
  # for internal, or tests only
164
- @watcher = Thread.new(&method(:watch))
130
+ timer_execute(:out_flowcounter_watcher, 0.5, &method(:watch))
165
131
  end
166
132
 
167
133
  def watch
168
- # instance variable, and public accessable, for test
169
- @last_checked = Fluent::Engine.now
170
- while true
171
- sleep 0.5
172
- if Fluent::Engine.now - @last_checked >= @tick
173
- now = Fluent::Engine.now
174
- flush_emit(now - @last_checked)
175
- @last_checked = now
176
- end
134
+ if Fluent::Engine.now - @last_checked >= @tick
135
+ now = Fluent::Engine.now
136
+ flush_emit(now - @last_checked)
137
+ @last_checked = now
177
138
  end
178
139
  end
179
140
 
180
141
  FOR_MISSING = ''
181
142
 
182
- def emit(tag, es, chain)
143
+ def process(tag, es)
183
144
  name = tag
184
145
  if @input_tag_remove_prefix and
185
146
  ( (tag.start_with?(@removed_prefix_string) and tag.length > @removed_length) or tag == @input_tag_remove_prefix)
@@ -198,7 +159,5 @@ class Fluent::FlowCounterOutput < Fluent::Output
198
159
  }
199
160
  end
200
161
  countup(name, c, b)
201
-
202
- chain.next
203
162
  end
204
163
  end
data/test/helper.rb CHANGED
@@ -12,6 +12,7 @@ require 'test/unit'
12
12
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
13
13
  $LOAD_PATH.unshift(File.dirname(__FILE__))
14
14
  require 'fluent/test'
15
+ require 'fluent/test/driver/output'
15
16
  require 'fluent/plugin/out_flowcounter'
16
17
 
17
18
  class Test::Unit::TestCase
@@ -13,8 +13,8 @@ input_tag_remove_prefix test
13
13
  count_keys message
14
14
  ]
15
15
 
16
- def create_driver(conf=CONFIG,tag='test')
17
- Fluent::Test::OutputTestDriver.new(Fluent::FlowCounterOutput, tag).configure(conf)
16
+ def create_driver(conf=CONFIG)
17
+ Fluent::Test::Driver::Output.new(Fluent::Plugin::FlowCounterOutput).configure(conf)
18
18
  end
19
19
 
20
20
  def test_configure
@@ -128,15 +128,6 @@ count_keys message
128
128
  assert d.instance.count_all
129
129
  end
130
130
 
131
- def test_configure_placeholders
132
- d = create_driver %[
133
- hostname testing.node.local
134
- tag test.flowcount.${hostname}
135
- count_keys *
136
- ]
137
- assert_equal 'test.flowcount.testing.node.local', d.instance.tag
138
- end
139
-
140
131
  def test_count_initialized
141
132
  d = create_driver %[
142
133
  aggregate all
@@ -203,13 +194,13 @@ count_keys message
203
194
  end
204
195
 
205
196
  def test_emit
206
- d1 = create_driver(CONFIG, 'test.tag1')
197
+ d1 = create_driver(CONFIG)
207
198
  time = Time.parse("2012-01-02 13:14:15").to_i
208
- d1.run do
199
+ d1.run(default_tag: 'test.tag1') do
209
200
  3600.times do
210
- d1.emit({'message'=> 'a' * 100})
211
- d1.emit({'message'=> 'b' * 100})
212
- d1.emit({'message'=> 'c' * 100})
201
+ d1.feed(time, {'message'=> 'a' * 100})
202
+ d1.feed(time, {'message'=> 'b' * 100})
203
+ d1.feed(time, {'message'=> 'c' * 100})
213
204
  end
214
205
  end
215
206
  r1 = d1.instance.flush(3600 * 24)
@@ -223,11 +214,11 @@ count_keys message
223
214
  aggregate all
224
215
  tag flow
225
216
  count_keys f1,f2,f3
226
- ], 'test.tag1')
217
+ ])
227
218
  time = Time.parse("2012-01-02 13:14:15").to_i
228
- d3.run do
219
+ d3.run(default_tag: 'test.tag1') do
229
220
  60.times do
230
- d3.emit({'f1'=>'1'*10, 'f2'=>'2'*20, 'f3'=>'3'*10})
221
+ d3.feed({'f1'=>'1'*10, 'f2'=>'2'*20, 'f3'=>'3'*10})
231
222
  end
232
223
  end
233
224
  r3 = d3.instance.flush(60)
@@ -244,21 +235,21 @@ count_keys message
244
235
  tag flowcount
245
236
  input_tag_remove_prefix test
246
237
  count_keys f1,f2,f3
247
- ], 'test.tag2')
238
+ ])
248
239
  time = Time.now.to_i
249
- d2.run do
240
+ d2.run(default_tag: 'test.tag2') do
250
241
  60.times do
251
- d2.emit({'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
252
- d2.emit({'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
253
- d2.emit({'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
254
- d2.emit({'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
255
- d2.emit({'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
242
+ d2.feed(time, {'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
243
+ d2.feed(time, {'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
244
+ d2.feed(time, {'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
245
+ d2.feed(time, {'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
246
+ d2.feed(time, {'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
256
247
  end
248
+ d2.instance.flush_emit(60)
257
249
  end
258
- d2.instance.flush_emit(60)
259
- emits = d2.emits
260
- assert_equal 1, emits.length
261
- data = emits[0]
250
+ events = d2.events
251
+ assert_equal 1, events.length
252
+ data = events[0]
262
253
  assert_equal 'flowcount', data[0] # tag
263
254
  assert_equal 60*5, data[2]['count']
264
255
  assert_equal 60*5*20, data[2]['bytes']
@@ -271,21 +262,21 @@ count_keys message
271
262
  tag flowcount
272
263
  input_tag_remove_prefix test
273
264
  count_keys *
274
- ], 'test.tag3')
265
+ ])
275
266
  time = Time.now.to_i
276
- d3.run do
267
+ d3.run(default_tag: 'test.tag3') do
277
268
  60.times do
278
- d3.emit({'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
279
- d3.emit({'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
280
- d3.emit({'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
281
- d3.emit({'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
282
- d3.emit({'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
269
+ d3.feed(time, {'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
270
+ d3.feed(time, {'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
271
+ d3.feed(time, {'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
272
+ d3.feed(time, {'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
273
+ d3.feed(time, {'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
283
274
  end
275
+ d3.instance.flush_emit(60)
284
276
  end
285
- d3.instance.flush_emit(60)
286
- emits = d3.emits
287
- assert_equal 1, emits.length
288
- data = emits[0]
277
+ events = d3.events
278
+ assert_equal 1, events.length
279
+ data = events[0]
289
280
  assert_equal 'flowcount', data[0] # tag
290
281
  assert_equal 60*5, data[2]['count']
291
282
  msgpack_size = {'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'}.to_msgpack.bytesize * 5 * 60
@@ -300,11 +291,11 @@ count_keys message
300
291
  tag flow
301
292
  input_tag_remove_prefix test
302
293
  count_keys *
303
- ], 'test.tag1')
294
+ ])
304
295
  time = Time.parse("2012-01-02 13:14:15").to_i
305
- d1.run do
296
+ d1.run(default_tag: 'test.tag1') do
306
297
  60.times do
307
- d1.emit({'message'=> 'hello'})
298
+ d1.feed(time, {'message'=> 'hello'})
308
299
  end
309
300
  end
310
301
  r1 = d1.instance.tagged_flush(60)
@@ -322,16 +313,17 @@ count_keys message
322
313
  aggregate tag
323
314
  tag flowcount
324
315
  input_tag_remove_prefix test
325
- ], 'test.tag1')
316
+ ])
326
317
  time = Time.parse("2012-01-02 13:14:15").to_i
327
- d1.run do
318
+ r1 = {}
319
+ d1.run(default_tag: 'test.tag1') do
328
320
  3600.times do
329
- d1.emit({'message'=> 'a' * 100})
330
- d1.emit({'message'=> 'b' * 100})
331
- d1.emit({'message'=> 'c' * 100})
321
+ d1.feed(time, {'message'=> 'a' * 100})
322
+ d1.feed(time, {'message'=> 'b' * 100})
323
+ d1.feed(time, {'message'=> 'c' * 100})
332
324
  end
325
+ r1 = d1.instance.flush(3600 * 24)
333
326
  end
334
- r1 = d1.instance.flush(3600 * 24)
335
327
  assert_equal 3600*3, r1['tag1_count']
336
328
  assert_nil r1['tag1_bytes']
337
329
  assert_equal (300/24.0).floor / 100.0, r1['tag1_count_rate'] # 3 * 3600 / (60 * 60 * 24) as xx.xx
@@ -341,11 +333,11 @@ count_keys message
341
333
  unit minute
342
334
  aggregate all
343
335
  tag flow
344
- ], 'test.tag1')
336
+ ])
345
337
  time = Time.parse("2012-01-02 13:14:15").to_i
346
- d3.run do
338
+ d3.run(default_tag: 'test.tag1') do
347
339
  60.times do
348
- d3.emit({'f1'=>'1'*10, 'f2'=>'2'*20, 'f3'=>'3'*10})
340
+ d3.feed({'f1'=>'1'*10, 'f2'=>'2'*20, 'f3'=>'3'*10})
349
341
  end
350
342
  end
351
343
  r3 = d3.instance.flush(60)
@@ -362,21 +354,21 @@ count_keys message
362
354
  tag flowcount
363
355
  input_tag_remove_prefix test
364
356
  count_keys f4
365
- ], 'test.tag4')
357
+ ])
366
358
  time = Time.now.to_i
367
- d3.run do
359
+ d3.run(default_tag: 'test.tag4', expect_emits: 1) do
368
360
  60.times do
369
- d3.emit({'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
370
- d3.emit({'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
371
- d3.emit({'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
372
- d3.emit({'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
373
- d3.emit({'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
361
+ d3.feed(time, {'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
362
+ d3.feed(time, {'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
363
+ d3.feed(time, {'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
364
+ d3.feed(time, {'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
365
+ d3.feed(time, {'f1' => 'abcde', 'f2' => 'vwxyz', 'f3' => '0123456789'})
374
366
  end
367
+ d3.instance.flush_emit(60)
375
368
  end
376
- d3.instance.flush_emit(60)
377
- emits = d3.emits
378
- assert_equal 1, emits.length
379
- data = emits[0]
369
+ events = d3.events
370
+ assert_equal 1, events.length
371
+ data = events[0]
380
372
  assert_equal 'flowcount', data[0]
381
373
  assert_equal 60*5, data[2]['count']
382
374
  assert_equal 0, data[2]['bytes']
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-flowcounter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - TAGOMORI Satoshi
@@ -42,36 +42,16 @@ dependencies:
42
42
  name: fluentd
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: 0.10.59
48
- - - "<"
45
+ - - "~>"
49
46
  - !ruby/object:Gem::Version
50
47
  version: 0.14.0
51
48
  type: :runtime
52
49
  prerelease: false
53
50
  version_requirements: !ruby/object:Gem::Requirement
54
51
  requirements:
55
- - - ">="
56
- - !ruby/object:Gem::Version
57
- version: 0.10.59
58
- - - "<"
52
+ - - "~>"
59
53
  - !ruby/object:Gem::Version
60
54
  version: 0.14.0
61
- - !ruby/object:Gem::Dependency
62
- name: fluent-mixin-config-placeholders
63
- requirement: !ruby/object:Gem::Requirement
64
- requirements:
65
- - - ">="
66
- - !ruby/object:Gem::Version
67
- version: 0.3.0
68
- type: :runtime
69
- prerelease: false
70
- version_requirements: !ruby/object:Gem::Requirement
71
- requirements:
72
- - - ">="
73
- - !ruby/object:Gem::Version
74
- version: 0.3.0
75
55
  description: Plugin to counts messages/bytes that matches, per minutes/hours/days
76
56
  email:
77
57
  - tagomoris@gmail.com